forked from rc/aircox
103 lines
3.3 KiB
Python
103 lines
3.3 KiB
Python
import math
|
|
|
|
from django.contrib import admin
|
|
from django.utils.safestring import mark_safe
|
|
from django.utils.translation import gettext_lazy as _
|
|
|
|
from adminsortable2.admin import SortableAdminBase, SortableInlineAdminMixin
|
|
|
|
from ..models import Sound, Track
|
|
|
|
|
|
class TrackInline(SortableInlineAdminMixin, admin.TabularInline):
|
|
template = 'admin/aircox/playlist_inline.html'
|
|
model = Track
|
|
extra = 0
|
|
fields = ('position', 'artist', 'title', 'tags', 'album', 'year', 'info')
|
|
|
|
list_display = ['artist', 'album', 'title', 'tags', 'related']
|
|
list_filter = ['artist', 'album', 'title', 'tags']
|
|
|
|
|
|
class SoundTrackInline(TrackInline):
|
|
fields = TrackInline.fields + ('timestamp',)
|
|
|
|
|
|
class SoundInline(admin.TabularInline):
|
|
model = Sound
|
|
fields = ['type', 'name', 'audio', 'duration', 'is_good_quality',
|
|
'is_public', 'is_downloadable']
|
|
readonly_fields = ['type', 'audio', 'duration', 'is_good_quality']
|
|
extra = 0
|
|
max_num = 0
|
|
|
|
def audio(self, obj):
|
|
return mark_safe('<audio src="{}" controls></audio>'
|
|
.format(obj.file.url))
|
|
audio.short_description = _('Audio')
|
|
|
|
def get_queryset(self, request):
|
|
return super().get_queryset(request).available()
|
|
|
|
|
|
@admin.register(Sound)
|
|
class SoundAdmin(SortableAdminBase, admin.ModelAdmin):
|
|
fields = None
|
|
list_display = ['id', 'name', 'related',
|
|
'type', 'duration', 'is_public', 'is_good_quality',
|
|
'is_downloadable', 'audio']
|
|
list_filter = ('type', 'is_good_quality', 'is_public')
|
|
list_editable = ['name', 'is_public', 'is_downloadable']
|
|
|
|
search_fields = ['name', 'program__title']
|
|
fieldsets = [
|
|
(None, {'fields': ['name', 'file', 'type', 'program', 'episode']}),
|
|
(None, {'fields': ['duration', 'is_public', 'is_downloadable',
|
|
'is_good_quality', 'mtime']}),
|
|
]
|
|
readonly_fields = ('file', 'duration', 'type')
|
|
inlines = [SoundTrackInline]
|
|
|
|
def related(self, obj):
|
|
# TODO: link to episode or program edit
|
|
return obj.episode.title if obj.episode else\
|
|
obj.program.title if obj.program else ''
|
|
related.short_description = _('Program / Episode')
|
|
|
|
def audio(self, obj):
|
|
return mark_safe('<audio src="{}" controls></audio>'
|
|
.format(obj.file.url)) \
|
|
if obj.type != Sound.TYPE_REMOVED else ''
|
|
audio.short_description = _('Audio')
|
|
|
|
|
|
@admin.register(Track)
|
|
class TrackAdmin(admin.ModelAdmin):
|
|
def tag_list(self, obj):
|
|
return u", ".join(o.name for o in obj.tags.all())
|
|
|
|
list_display = ['pk', 'artist', 'title', 'tag_list', 'episode',
|
|
'sound', 'ts']
|
|
list_editable = ['artist', 'title']
|
|
list_filter = ['artist', 'title', 'tags']
|
|
|
|
search_fields = ['artist', 'title']
|
|
fieldsets = [
|
|
(_('Playlist'), {'fields': ['episode', 'sound', 'position',
|
|
'timestamp']}),
|
|
(_('Info'), {'fields': ['artist', 'title', 'info', 'tags']}),
|
|
]
|
|
|
|
# TODO on edit: readonly_fields = ['episode', 'sound']
|
|
|
|
def ts(self, obj):
|
|
ts = obj.timestamp
|
|
if ts is None:
|
|
return ''
|
|
h = math.floor(ts / 3600)
|
|
m = math.floor((ts - h) / 60)
|
|
s = ts-h*3600-m*60
|
|
return '{:0>2}:{:0>2}:{:0>2}'.format(h, m, s)
|
|
|
|
ts.short_description = _('timestamp')
|