mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-09-01 05:27:34 +08:00
feat(music): 支持多源识别与刮削交互
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
import { isMusicMediaSource, isValidMediaSourceId } from '@/utils/mediaId'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
describe('media source identity utils', () => {
|
||||
it.each(['musicbrainz', 'theaudiodb', 'doubanmusic'] as const)('recognizes %s as a music source', source => {
|
||||
expect(isMusicMediaSource(source)).toBe(true)
|
||||
})
|
||||
|
||||
it('uses UUIDs for MusicBrainz and numeric IDs for alternate music sources', () => {
|
||||
expect(isValidMediaSourceId('977e6978-139d-425c-bb98-6b0c62d1e45e', 'musicbrainz')).toBe(true)
|
||||
expect(isValidMediaSourceId('32793500', 'theaudiodb')).toBe(true)
|
||||
expect(isValidMediaSourceId('1401853', 'doubanmusic')).toBe(true)
|
||||
expect(isValidMediaSourceId('not-a-number', 'theaudiodb')).toBe(false)
|
||||
})
|
||||
})
|
||||
@@ -1,8 +1,14 @@
|
||||
import type { MediaDataSource } from '@/api/types'
|
||||
|
||||
const MUSICBRAINZ_ID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i
|
||||
export const MUSIC_MEDIA_SOURCES = ['musicbrainz', 'theaudiodb', 'doubanmusic'] as const
|
||||
|
||||
/** 按媒体数据源校验原生 ID,MusicBrainz 使用 UUID,其它现有来源使用数字 ID。 */
|
||||
/** 判断当前请求来源是否为内置音乐元数据源。 */
|
||||
export function isMusicMediaSource(source?: MediaDataSource): boolean {
|
||||
return MUSIC_MEDIA_SOURCES.includes(source as (typeof MUSIC_MEDIA_SOURCES)[number])
|
||||
}
|
||||
|
||||
/** 按媒体数据源校验原生 ID,MusicBrainz 使用 UUID,其它内置来源使用数字 ID。 */
|
||||
export function isValidMediaSourceId(value: string | number | null | undefined, source?: MediaDataSource): boolean {
|
||||
const normalized = value?.toString().trim()
|
||||
if (!normalized) return true
|
||||
|
||||
@@ -62,6 +62,16 @@ export function getMusicSource(item: MusicRouteTarget): string | undefined {
|
||||
return item.source || item.media_source
|
||||
}
|
||||
|
||||
/** 返回内置音乐元数据源的用户可见名称。 */
|
||||
export function getMusicSourceLabel(source?: string, translate?: (key: string) => string): string {
|
||||
const labels: Record<string, string> = {
|
||||
musicbrainz: 'MusicBrainz',
|
||||
theaudiodb: 'TheAudioDB',
|
||||
doubanmusic: translate?.('setting.cache.recognitionSource.doubanmusic') || '豆瓣音乐',
|
||||
}
|
||||
return (source && labels[source]) || source || 'MusicBrainz'
|
||||
}
|
||||
|
||||
/** 返回音乐候选在列表和状态缓存中的稳定身份。 */
|
||||
export function getMusicKey(item: MusicRouteTarget): string {
|
||||
const source = getMusicSource(item) || 'music'
|
||||
|
||||
Reference in New Issue
Block a user