aircox/aircox/admin/sound.py
2024-04-28 00:27:26 +02:00

159 lines
4.2 KiB
Python

import math
from adminsortable2.admin import SortableAdminBase
from django.contrib import admin
from django.utils.safestring import mark_safe
from django.utils.translation import gettext_lazy as _
from ..models import Sound, Track
class TrackInline(admin.TabularInline):
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 = [
"name",
"audio",
"duration",
"broadcast",
"is_good_quality",
"is_public",
"is_downloadable",
"is_removed",
]
readonly_fields = ["broadcast", "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")
@admin.register(Sound)
class SoundAdmin(SortableAdminBase, admin.ModelAdmin):
fields = None
list_display = [
"id",
"name",
# "related",
"broadcast",
"duration",
"is_public",
"is_good_quality",
"is_downloadable",
"audio",
]
list_filter = ("broadcast", "is_good_quality", "is_public")
list_editable = ["name", "is_public", "is_downloadable"]
search_fields = ["name", "program__title", "file"]
autocomplete_fields = ("program",)
fieldsets = [
(
None,
{
"fields": [
"name",
"file",
"broadcast",
"program",
]
},
),
(
None,
{
"fields": [
"duration",
"is_public",
"is_downloadable",
"is_good_quality",
"mtime",
]
},
),
]
readonly_fields = ("file", "duration", "is_removed")
inlines = [SoundTrackInline]
def related(self, obj):
# # TODO: link to episode or program edit
return obj.program.title if obj.program else ""
# return obj.episode.title if obj.episode else obj.program.title if obj.program else ""
related.short_description = _("Program")
def audio(self, obj):
return mark_safe('<audio src="{}" controls></audio>'.format(obj.file.url)) if not obj.is_removed else ""
audio.short_description = _("Audio")
def add_view(self, request, form_url="", context=None):
context = context or {}
context["init_app"] = True
context["init_el"] = "#inline-tracks"
context["track_timestamp"] = True
return super().add_view(request, form_url, context)
def change_view(self, request, object_id, form_url="", context=None):
context = context or {}
context["init_app"] = True
context["init_el"] = "#inline-tracks"
context["track_timestamp"] = True
return super().change_view(request, object_id, form_url, context)
@admin.register(Track)
class TrackAdmin(admin.ModelAdmin):
def tag_list(self, obj):
return ", ".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")