soundwave/backend/audio/admin_artwork.py

248 lines
6.9 KiB
Python
Raw Normal View History

"""Admin configuration for artwork and metadata"""
from django.contrib import admin
from audio.models_artwork import Artwork, MusicMetadata, ArtistInfo
@admin.register(Artwork)
class ArtworkAdmin(admin.ModelAdmin):
"""Admin for Artwork model"""
list_display = [
'id',
'audio',
'channel',
'artwork_type',
'source',
'priority',
'is_primary',
'has_local_file',
'created_at',
]
list_filter = [
'artwork_type',
'source',
'is_primary',
'created_at',
]
search_fields = [
'audio__audio_title',
'channel__channel_name',
'url',
]
readonly_fields = ['created_at']
ordering = ['-priority', '-created_at']
fieldsets = (
('Related Objects', {
'fields': ('audio', 'channel')
}),
('Artwork Details', {
'fields': ('artwork_type', 'source', 'url', 'local_path')
}),
('Image Properties', {
'fields': ('width', 'height', 'priority', 'is_primary')
}),
('Metadata', {
'fields': ('created_at',)
}),
)
def has_local_file(self, obj):
"""Check if artwork has local file"""
return bool(obj.local_path)
has_local_file.boolean = True
has_local_file.short_description = 'Local File'
actions = ['download_artwork', 'set_as_primary']
def download_artwork(self, request, queryset):
"""Download artwork from URLs"""
from audio.tasks_artwork import download_artwork
count = 0
for artwork in queryset:
if artwork.url:
download_artwork.delay(artwork.id)
count += 1
self.message_user(request, f'Queued {count} artwork downloads')
download_artwork.short_description = 'Download selected artwork'
def set_as_primary(self, request, queryset):
"""Set selected artwork as primary"""
count = 0
for artwork in queryset:
# Unset other primary
if artwork.audio:
Artwork.objects.filter(
audio=artwork.audio,
artwork_type=artwork.artwork_type
).update(is_primary=False)
elif artwork.channel:
Artwork.objects.filter(
channel=artwork.channel,
artwork_type=artwork.artwork_type
).update(is_primary=False)
artwork.is_primary = True
artwork.save()
count += 1
self.message_user(request, f'Set {count} artwork as primary')
set_as_primary.short_description = 'Set as primary'
@admin.register(MusicMetadata)
class MusicMetadataAdmin(admin.ModelAdmin):
"""Admin for MusicMetadata model"""
list_display = [
'id',
'audio',
'album_name',
'album_artist',
'genre',
'release_year',
'play_count',
'listeners',
'updated_at',
]
list_filter = [
'genre',
'release_year',
'updated_at',
]
search_fields = [
'audio__audio_title',
'album_name',
'album_artist',
'genre',
]
readonly_fields = ['created_at', 'updated_at']
ordering = ['-updated_at']
fieldsets = (
('Audio', {
'fields': ('audio',)
}),
('Album Information', {
'fields': (
'album_name',
'album_artist',
'release_year',
'track_number',
'disc_number',
)
}),
('Genre & Tags', {
'fields': ('genre', 'tags')
}),
('Last.fm Data', {
'fields': (
'lastfm_url',
'lastfm_mbid',
'play_count',
'listeners',
)
}),
('Fanart.tv IDs', {
'fields': ('fanart_artist_id', 'fanart_album_id')
}),
('Metadata', {
'fields': ('created_at', 'updated_at')
}),
)
actions = ['fetch_from_lastfm', 'update_id3_tags']
def fetch_from_lastfm(self, request, queryset):
"""Fetch metadata from Last.fm"""
from audio.tasks_artwork import fetch_metadata_for_audio
count = 0
for metadata in queryset:
fetch_metadata_for_audio.delay(metadata.audio.id)
count += 1
self.message_user(request, f'Queued {count} metadata fetches')
fetch_from_lastfm.short_description = 'Fetch from Last.fm'
def update_id3_tags(self, request, queryset):
"""Update ID3 tags in audio files"""
from audio.tasks_artwork import update_id3_tags_from_metadata
count = 0
for metadata in queryset:
update_id3_tags_from_metadata.delay(metadata.audio.id)
count += 1
self.message_user(request, f'Queued {count} ID3 tag updates')
update_id3_tags.short_description = 'Update ID3 tags'
@admin.register(ArtistInfo)
class ArtistInfoAdmin(admin.ModelAdmin):
"""Admin for ArtistInfo model"""
list_display = [
'id',
'channel',
'lastfm_listeners',
'lastfm_playcount',
'has_bio',
'tags_count',
'updated_at',
]
list_filter = [
'updated_at',
]
search_fields = [
'channel__channel_name',
'bio',
'tags',
]
readonly_fields = ['created_at', 'updated_at']
ordering = ['-updated_at']
fieldsets = (
('Channel', {
'fields': ('channel',)
}),
('Biography', {
'fields': ('bio', 'bio_summary')
}),
('Last.fm Data', {
'fields': (
'lastfm_url',
'lastfm_mbid',
'lastfm_listeners',
'lastfm_playcount',
)
}),
('Tags & Similar', {
'fields': ('tags', 'similar_artists')
}),
('Fanart.tv', {
'fields': ('fanart_id',)
}),
('Metadata', {
'fields': ('created_at', 'updated_at')
}),
)
def has_bio(self, obj):
"""Check if artist has bio"""
return bool(obj.bio)
has_bio.boolean = True
has_bio.short_description = 'Has Bio'
def tags_count(self, obj):
"""Get number of tags"""
return len(obj.tags) if obj.tags else 0
tags_count.short_description = 'Tags'
actions = ['fetch_from_lastfm']
def fetch_from_lastfm(self, request, queryset):
"""Fetch artist info from Last.fm"""
from audio.tasks_artwork import fetch_artist_info
count = 0
for artist_info in queryset:
fetch_artist_info.delay(artist_info.channel.id)
count += 1
self.message_user(request, f'Queued {count} artist info fetches')
fetch_from_lastfm.short_description = 'Fetch from Last.fm'