export interface Artist { id: number; name: string; } export interface MusicInfo { composers: Artist[]; dj: Artist[]; artists: Artist[]; with: Artist[]; conductor: Artist[]; remixedBy: Artist[]; producer: Artist[]; } export interface AlbumGroup { wikiBody: string; bbBody: string; wikiImage: string; id: number; name: string; year: number; recordLabel: string; catalogueNumber: string; releaseType: number; categoryId: number; categoryName: string; time: string; collages: unknown[] | null; personalCollages: unknown[] | null; vanityHouse: boolean; isBookmarked: boolean; musicInfo: MusicInfo; tags: string[]; } export interface TorrentFile { fileList: string; filePath: string; userId: number; username: string; id: number; infoHash: string; media: string; format: string; encoding: string; remastered: boolean; remasterYear: number; remasterTitle: string; remasterRecordLabel: string; remasterCatalogueNumber: string; scene: boolean; hasLog: boolean; hasCue: boolean; logScore: number; ripLogIds: unknown[]; fileCount: number; size: number; canUseToken: boolean; seeders: number; leechers: number; snatched: number; has_snatched: boolean; trumpable: boolean; trumpable_reasons: unknown[]; lossyWebApproved: boolean; lossyMasterApproved: boolean; freeTorrent: boolean; isNeutralleech: boolean; isFreeload: boolean; reported: boolean; time: string; description: string; } export interface AlbumResponse { group: AlbumGroup; torrent: TorrentFile; } export interface ApiResponse { status: string; response: T; } export interface Track { filename: string; title: string; trackNumber: string; length?: string; // Duration might be useful } export interface LocalAlbumData { path: string; artist: string; title: string; year: string; tracks: Track[]; coverArtPath?: string; } export interface AudioMetadata { format: { sampleRate?: number; bitsPerSample?: number; duration?: number; bitrate?: number; }; common: { title?: string; artist?: string; album?: string; track?: { no: number | null; of: number | null }; disk?: { no: number | null; of: number | null }; year?: number; date?: string; copyright?: string; barcode?: string; // UPC artists?: string[]; albumartist?: string; }; native?: { tidalUrl?: string; vorbis?: { id: string; value: any }[]; }; } export type AnalysisTrack = | { filename: string; path: string; error: string } | { filename: string; path: string; format: AudioMetadata['format']; common: AudioMetadata['common']; native?: AudioMetadata['native']; error?: never; fullPathLength?: number; }; export interface AnalysisResponse { albumPath: string; metadata: { artist: string; album: string; year?: number; upc?: string; label: string; tidalUrl?: string; additionalArtists?: string[]; releaseType: number; totalSize: number; }; tracks: AnalysisTrack[]; quality: { status: string; mixed: boolean; details: string; }; } export type TorrentCreationResponse = | { success: true; output: string; filename: string; data: string; } | { success: false; output: string; errorOutput: string; error: string; }; export interface SpectrogramResponse { results: Record; } export interface CopyResponse { success: boolean; destPath: string; } export interface RenameOperation { original: string; newName: string; } export interface RenameResult extends RenameOperation { success: boolean; } export interface BatchRenameResponse { success: boolean; results: RenameResult[]; errors?: string[]; } export interface TorrentInfo { hash: string; name: string; state: string; progress: number; size: number; added_on: number; completion_on: number; } export interface QbittorrentInjectResponse { success: boolean; hash: string; } export interface QbittorrentResumeResponse { success: boolean; } export interface QbittorrentStatusResponse { success: boolean; info: TorrentInfo; } export interface CheckMQAResponse { success: boolean; isMQA: boolean; output: string; } export interface CheckUpconvResponse { success: boolean; output: string; wastedBits: string; } export interface Album { name: string; path: string; hasCover: boolean; coverPath: string | null; } export interface RenameProposal { original: string; strategies: { remove_brackets: string | null; remove_parens: string | null; remove_both: string | null; truncate: string; }; } export interface ProposeRenameResponse { success: boolean; problematicFiles: RenameProposal[]; allFiles?: RenameProposal[]; maxFileLength: number; }