feat(filename): add provider traceability tags

This commit is contained in:
zarzet
2026-08-17 20:51:27 +07:00
parent efc03db308
commit 2e115308b7
13 changed files with 201 additions and 5 deletions
@@ -690,6 +690,8 @@ class DownloadQueueNotifier extends Notifier<DownloadQueueState> {
return DownloadRequestPayload(
isrc: track.isrc ?? '',
service: item.service,
downloadProvider: item.service,
providerTrackId: _knownProviderTrackId(track, item.service),
spotifyId: payloadSpotifyId,
trackName: track.name,
artistName: track.artistName,
@@ -340,6 +340,8 @@ extension _DownloadQueuePaths on DownloadQueueNotifier {
filenameFormat,
_filenameMetadataForTrack(
track,
provider: item.service,
providerTrackId: _knownProviderTrackId(track, item.service),
quality: quality,
qualityVariant: qualityVariant,
playlistPosition: _validPlaylistPosition(item),
@@ -717,6 +719,8 @@ extension _DownloadQueuePaths on DownloadQueueNotifier {
Map<String, dynamic> _filenameMetadataForTrack(
Track track, {
required String provider,
required String providerTrackId,
required String quality,
String qualityVariant = '',
int playlistPosition = 0,
@@ -729,10 +733,34 @@ extension _DownloadQueuePaths on DownloadQueueNotifier {
'disc': track.discNumber ?? 0,
'year': _extractYear(track.releaseDate) ?? '',
'date': track.releaseDate ?? '',
'isrc': track.isrc ?? '',
'provider': provider,
'provider_id': providerTrackId,
'playlist_position': playlistPosition,
'playlistPosition': playlistPosition,
'quality': quality,
'quality_variant': qualityVariant,
};
}
String _knownProviderTrackId(Track track, String provider) {
final normalizedProvider = provider.trim().toLowerCase();
final normalizedSource = track.source?.trim().toLowerCase() ?? '';
final rawId = track.id.trim();
if (rawId.isEmpty) return '';
if (normalizedSource == normalizedProvider && normalizedSource.isNotEmpty) {
final separator = rawId.indexOf(':');
return separator >= 0 && separator + 1 < rawId.length
? rawId.substring(separator + 1)
: rawId;
}
final separator = rawId.indexOf(':');
if (separator > 0 &&
rawId.substring(0, separator).toLowerCase() == normalizedProvider) {
return rawId.substring(separator + 1);
}
return '';
}
}
@@ -938,6 +938,9 @@ class _FilenameFormatEditorSheetState
'{playlist_position}',
];
static const _advancedTags = [
'{isrc}',
'{provider}',
'{provider_id}',
'{track_raw}',
'{track:02}',
'{track:1}',
@@ -957,7 +960,7 @@ class _FilenameFormatEditorSheetState
super.initState();
_controller = TextEditingController(text: widget.initialText);
_showAdvancedTags = RegExp(
r'\{(?:track_raw|disc_raw|track:\d+|disc:\d+|date:[^}]+)\}',
r'\{(?:isrc|provider|platform|provider_id|id|track_raw|disc_raw|track:\d+|disc:\d+|date:[^}]+)\}',
caseSensitive: false,
).hasMatch(widget.initialText);
}
@@ -4,6 +4,8 @@ class DownloadRequestPayload {
final int contractVersion;
final String isrc;
final String service;
final String downloadProvider;
final String providerTrackId;
final String spotifyId;
final String trackName;
final String artistName;
@@ -60,6 +62,8 @@ class DownloadRequestPayload {
this.contractVersion = nativeWorkerContractVersion,
this.isrc = '',
this.service = '',
this.downloadProvider = '',
this.providerTrackId = '',
this.spotifyId = '',
required this.trackName,
required this.artistName,
@@ -118,6 +122,8 @@ class DownloadRequestPayload {
'contract_version': contractVersion,
'isrc': isrc,
'service': service,
'download_provider': downloadProvider,
'provider_track_id': providerTrackId,
'spotify_id': spotifyId,
'track_name': trackName,
'artist_name': artistName,
@@ -180,6 +186,8 @@ class DownloadRequestPayload {
contractVersion: contractVersion,
isrc: isrc,
service: service,
downloadProvider: downloadProvider,
providerTrackId: providerTrackId,
spotifyId: spotifyId,
trackName: trackName,
artistName: artistName,