feat(sync): implement sync functionality for delay profiles

- Added syncArrJob to handle syncing of PCD profiles and settings to arr instances.
- Created syncArr logic to process pending syncs and log results.
- Introduced BaseSyncer class for common sync operations and specific syncers for delay profiles
- Implemented fetch, transform, and push methods for delay profiles
- Added manual sync actions in the UI for delay profiles
- Enhanced logging for sync operations and error handling.
This commit is contained in:
Sam Chau
2025-12-29 05:37:55 +10:30
parent ea5c543647
commit 1e8fc7a42d
20 changed files with 1305 additions and 10 deletions

View File

@@ -1,5 +1,5 @@
import { BaseHttpClient } from '../http/client.ts';
import type { ArrSystemStatus } from './types.ts';
import type { ArrSystemStatus, ArrDelayProfile, ArrTag } from './types.ts';
import { logger } from '$logger/logger.ts';
/**
@@ -49,4 +49,61 @@ export class BaseArrClient extends BaseHttpClient {
return false;
}
}
// =========================================================================
// Delay Profiles
// =========================================================================
/**
* Get all delay profiles
*/
async getDelayProfiles(): Promise<ArrDelayProfile[]> {
return this.get<ArrDelayProfile[]>(`/api/${this.apiVersion}/delayprofile`);
}
/**
* Get a delay profile by ID
*/
async getDelayProfile(id: number): Promise<ArrDelayProfile> {
return this.get<ArrDelayProfile>(`/api/${this.apiVersion}/delayprofile/${id}`);
}
/**
* Create a new delay profile
*/
async createDelayProfile(profile: Omit<ArrDelayProfile, 'id' | 'order'>): Promise<ArrDelayProfile> {
return this.post<ArrDelayProfile>(`/api/${this.apiVersion}/delayprofile`, profile);
}
/**
* Update an existing delay profile
*/
async updateDelayProfile(id: number, profile: ArrDelayProfile): Promise<ArrDelayProfile> {
return this.put<ArrDelayProfile>(`/api/${this.apiVersion}/delayprofile/${id}`, profile);
}
/**
* Delete a delay profile
*/
async deleteDelayProfile(id: number): Promise<void> {
await this.delete(`/api/${this.apiVersion}/delayprofile/${id}`);
}
// =========================================================================
// Tags
// =========================================================================
/**
* Get all tags
*/
async getTags(): Promise<ArrTag[]> {
return this.get<ArrTag[]>(`/api/${this.apiVersion}/tag`);
}
/**
* Create a new tag
*/
async createTag(label: string): Promise<ArrTag> {
return this.post<ArrTag>(`/api/${this.apiVersion}/tag`, { label });
}
}

View File

@@ -198,6 +198,40 @@ export interface RadarrLibraryItem {
isProfilarrProfile: boolean; // true if profile name matches a Profilarr database profile
}
// =============================================================================
// Delay Profile Types (shared across arr apps)
// =============================================================================
/**
* Delay profile from /api/v3/delayprofile
* Schema is identical for Radarr and Sonarr
*/
export interface ArrDelayProfile {
id: number;
enableUsenet: boolean;
enableTorrent: boolean;
preferredProtocol: string; // 'usenet' | 'torrent' | 'unknown'
usenetDelay: number;
torrentDelay: number;
bypassIfHighestQuality: boolean;
bypassIfAboveCustomFormatScore: boolean;
minimumCustomFormatScore: number;
order: number;
tags: number[];
}
/**
* Tag from /api/v3/tag (shared across arr apps)
*/
export interface ArrTag {
id: number;
label: string;
}
// =============================================================================
// System Types
// =============================================================================
/**
* System status response from /api/v3/system/status
* Based on actual Radarr API response