#132 | #121: backoffice / dev-1.0-121 (#131)

cfr #121

Co-authored-by: Christophe Siraut <d@tobald.eu.org>
Co-authored-by: bkfox <thomas bkfox net>
Co-authored-by: Thomas Kairos <thomas@bkfox.net>
Reviewed-on: rc/aircox#131
Co-authored-by: Chris Tactic <ctactic@noreply.git.radiocampus.be>
Co-committed-by: Chris Tactic <ctactic@noreply.git.radiocampus.be>
This commit is contained in:
2024-04-28 22:02:09 +02:00
committed by Thomas Kairos
parent 1e17a1334a
commit 55123c386d
348 changed files with 124397 additions and 17879 deletions

View File

@ -4,7 +4,7 @@ from .diffusion import DiffusionAdmin
from .episode import EpisodeAdmin
from .log import LogAdmin
from .page import PageAdmin, StaticPageAdmin
from .program import ProgramAdmin, StreamAdmin
from .program import ProgramAdmin
from .schedule import ScheduleAdmin
from .sound import SoundAdmin, TrackAdmin
from .station import StationAdmin
@ -19,7 +19,6 @@ __all__ = (
"StaticPageAdmin",
"ProgramAdmin",
"ScheduleAdmin",
"StreamAdmin",
"SoundAdmin",
"TrackAdmin",
"StationAdmin",

View File

@ -30,12 +30,14 @@ class DiffusionAdmin(DiffusionBaseAdmin, admin.ModelAdmin):
end_date.short_description = _("end")
list_display = ("episode", "start_date", "end_date", "type", "initial")
list_display = ("episode", "start", "end", "type", "initial")
list_filter = ("type", "start", "program")
list_editable = ("type",)
list_editable = ("type", "start", "end")
ordering = ("-start", "id")
search_fields = ("program__title", "episode__title")
fields = ("type", "start", "end", "initial", "program", "schedule")
autocomplete_fields = ("episode", "program", "initial")
readonly_fields = ("schedule",)

View File

@ -2,12 +2,23 @@ from adminsortable2.admin import SortableAdminBase
from django.contrib import admin
from django.forms import ModelForm
from aircox.models import Episode
from .page import PageAdmin
from .sound import SoundInline, TrackInline
from aircox.models import Episode, EpisodeSound
from .page import ChildPageAdmin
from .sound import TrackInline
from .diffusion import DiffusionInline
class EpisodeSoundInline(admin.TabularInline):
model = EpisodeSound
extra = 0
fields = (
"sound",
"position",
"broadcast",
)
autocomplete_fields = ("sound",)
class EpisodeAdminForm(ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
@ -15,26 +26,14 @@ class EpisodeAdminForm(ModelForm):
@admin.register(Episode)
class EpisodeAdmin(SortableAdminBase, PageAdmin):
class EpisodeAdmin(SortableAdminBase, ChildPageAdmin):
form = EpisodeAdminForm
list_display = PageAdmin.list_display
list_filter = tuple(f for f in PageAdmin.list_filter if f != "pub_date") + (
list_display = ChildPageAdmin.list_display
list_filter = tuple(f for f in ChildPageAdmin.list_filter if f != "pub_date") + (
"diffusion__start",
"pub_date",
)
search_fields = PageAdmin.search_fields + ("parent__title",)
search_fields = ChildPageAdmin.search_fields + ("parent__title",)
# readonly_fields = ('parent',)
inlines = [TrackInline, SoundInline, DiffusionInline]
def add_view(self, request, object_id, form_url="", context=None):
context = context or {}
context["init_app"] = True
context["init_el"] = "#inline-tracks"
return super().change_view(request, object_id, 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"
return super().change_view(request, object_id, form_url, context)
inlines = (TrackInline, EpisodeSoundInline, DiffusionInline)

View File

@ -18,10 +18,11 @@ class CategoryAdmin(admin.ModelAdmin):
search_fields = ["title"]
fields = ["title", "slug"]
prepopulated_fields = {"slug": ("title",)}
ordering = ("title",)
class BasePageAdmin(admin.ModelAdmin):
list_display = ("cover_thumb", "title", "status", "parent")
list_display = ("cover_thumb", "title", "status")
list_display_links = ("cover_thumb", "title")
list_editable = ("status",)
list_filter = ("status",)
@ -42,15 +43,49 @@ class BasePageAdmin(admin.ModelAdmin):
(
_("Publication Settings"),
{
"fields": ["status", "parent"],
"fields": [
"status",
],
},
),
]
change_form_template = "admin/aircox/page_change_form.html"
def cover_thumb(self, obj):
return mark_safe('<img src="{}"/>'.format(obj.cover.icons["64"])) if obj.cover else ""
if obj.cover and obj.cover.thumbnails:
return mark_safe('<img src="{}"/>'.format(obj.cover.icons["64"]))
return ""
def _get_extra_context(self, query, **extra_context):
return extra_context
def add_view(self, request, form_url="", extra_context=None):
filters = QueryDict(request.GET.get("_changelist_filters", ""))
extra_context = self._get_extra_context(filters, **(extra_context or {}))
return super().add_view(request, form_url, extra_context)
def changelist_view(self, request, extra_context=None):
extra_context = self._get_extra_context(request.GET, **(extra_context or {}))
return super().changelist_view(request, extra_context)
@admin.register(Page)
class PageAdmin(BasePageAdmin):
list_display = BasePageAdmin.list_display + ("category",)
list_editable = BasePageAdmin.list_editable + ("category",)
list_filter = BasePageAdmin.list_filter + ("category", "pub_date")
search_fields = BasePageAdmin.search_fields + ("category__title",)
fieldsets = deepcopy(BasePageAdmin.fieldsets)
fieldsets[0][1]["fields"].insert(fieldsets[0][1]["fields"].index("slug") + 1, "category")
fieldsets[1][1]["fields"] += ("featured", "allow_comments")
class ChildPageAdmin(PageAdmin):
list_display = PageAdmin.list_display + ("parent",)
autocomplete_fields = ("parent",)
fieldsets = deepcopy(PageAdmin.fieldsets)
fieldsets[1][1]["fields"] += ("parent",)
def get_changeform_initial_data(self, request):
data = super().get_changeform_initial_data(request)
@ -58,45 +93,22 @@ class BasePageAdmin(admin.ModelAdmin):
data["parent"] = filters.get("parent", None)
return data
def _get_common_context(self, query, extra_context=None):
extra_context = extra_context or {}
def _get_extra_context(self, query, **extra_context):
parent = query.get("parent", None)
extra_context["parent"] = None if parent is None else Page.objects.get_subclass(id=parent)
return extra_context
return super()._get_extra_context(query, **extra_context)
def render_change_form(self, request, context, *args, **kwargs):
if context["original"] and "parent" not in context:
context["parent"] = context["original"].parent
return super().render_change_form(request, context, *args, **kwargs)
def add_view(self, request, form_url="", extra_context=None):
filters = QueryDict(request.GET.get("_changelist_filters", ""))
extra_context = self._get_common_context(filters, extra_context)
return super().add_view(request, form_url, extra_context)
def changelist_view(self, request, extra_context=None):
extra_context = self._get_common_context(request.GET, extra_context)
return super().changelist_view(request, extra_context)
class PageAdmin(BasePageAdmin):
change_list_template = "admin/aircox/page_change_list.html"
list_display = BasePageAdmin.list_display + ("category",)
list_editable = BasePageAdmin.list_editable + ("category",)
list_filter = BasePageAdmin.list_filter + ("category", "pub_date")
search_fields = BasePageAdmin.search_fields + ("category__title",)
fieldsets = deepcopy(BasePageAdmin.fieldsets)
fieldsets[0][1]["fields"].insert(fieldsets[0][1]["fields"].index("slug") + 1, "category")
fieldsets[1][1]["fields"] += ("featured", "allow_comments")
@admin.register(StaticPage)
class StaticPageAdmin(BasePageAdmin):
list_display = BasePageAdmin.list_display + ("attach_to",)
list_editable = BasePageAdmin.list_editable + ("attach_to",)
fieldsets = deepcopy(BasePageAdmin.fieldsets)
fieldsets[1][1]["fields"] += ("attach_to",)
@ -105,6 +117,7 @@ class CommentAdmin(admin.ModelAdmin):
list_display = ("page_title", "date", "nickname")
list_filter = ("date",)
search_fields = ("page__title", "nickname")
readonly_fields = ("page",)
def page_title(self, obj):
return obj.page.title

View File

@ -6,7 +6,10 @@ from .page import PageAdmin
from .schedule import ScheduleInline
__all__ = ("ProgramAdmin", "StreamInline", "StreamAdmin")
__all__ = (
"ProgramAdmin",
"StreamInline",
)
class StreamInline(admin.TabularInline):
@ -27,6 +30,7 @@ class ProgramAdmin(PageAdmin):
list_filter = PageAdmin.list_filter + ("station", "active")
prepopulated_fields = {"slug": ("title",)}
search_fields = ("title",)
ordering = ("title",)
inlines = [ScheduleInline, StreamInline]
@ -42,8 +46,3 @@ class ProgramAdmin(PageAdmin):
)
]
return fields
@admin.register(Stream)
class StreamAdmin(admin.ModelAdmin):
list_display = ("id", "program", "delay", "begin", "end")

View File

@ -22,6 +22,7 @@ class ScheduleInline(admin.TabularInline):
model = Schedule
form = ScheduleInlineForm
readonly_fields = ("timezone",)
autocomplete_fields = ("initial",)
extra = 1
@ -46,7 +47,10 @@ class ScheduleAdmin(admin.ModelAdmin):
"duration",
"initial",
]
list_editable = ["time", "duration", "initial"]
list_editable = ("time", "duration", "initial")
autocomplete_fields = ("initial",)
search_fields = ("program__title",)
ordering = ("program__title", "initial", "date")
def get_readonly_fields(self, request, obj=None):
if obj:

View File

@ -9,7 +9,6 @@ from ..models import Sound, Track
class TrackInline(admin.TabularInline):
template = "admin/aircox/playlist_inline.html"
model = Track
extra = 0
fields = ("position", "artist", "title", "tags", "album", "year", "info")
@ -25,15 +24,16 @@ class SoundTrackInline(TrackInline):
class SoundInline(admin.TabularInline):
model = Sound
fields = [
"type",
"name",
"audio",
"duration",
"broadcast",
"is_good_quality",
"is_public",
"is_downloadable",
"is_removed",
]
readonly_fields = ["type", "audio", "duration", "is_good_quality"]
readonly_fields = ["broadcast", "audio", "duration", "is_good_quality"]
extra = 0
max_num = 0
@ -42,9 +42,6 @@ class SoundInline(admin.TabularInline):
audio.short_description = _("Audio")
def get_queryset(self, request):
return super().get_queryset(request).available()
@admin.register(Sound)
class SoundAdmin(SortableAdminBase, admin.ModelAdmin):
@ -52,20 +49,31 @@ class SoundAdmin(SortableAdminBase, admin.ModelAdmin):
list_display = [
"id",
"name",
"related",
"type",
# "related",
"broadcast",
"duration",
"is_public",
"is_good_quality",
"is_downloadable",
"audio",
]
list_filter = ("type", "is_good_quality", "is_public")
list_filter = ("broadcast", "is_good_quality", "is_public")
list_editable = ["name", "is_public", "is_downloadable"]
search_fields = ["name", "program__title"]
search_fields = ["name", "program__title", "file"]
autocomplete_fields = ("program",)
fieldsets = [
(None, {"fields": ["name", "file", "type", "program", "episode"]}),
(
None,
{
"fields": [
"name",
"file",
"broadcast",
"program",
]
},
),
(
None,
{
@ -79,21 +87,19 @@ class SoundAdmin(SortableAdminBase, admin.ModelAdmin):
},
),
]
readonly_fields = ("file", "duration", "type")
readonly_fields = ("file", "duration", "is_removed")
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 ""
# # TODO: link to episode or program edit
return obj.program.title if obj.program else ""
related.short_description = _("Program / Episode")
# 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 obj.type != Sound.TYPE_REMOVED
else ""
)
return mark_safe('<audio src="{}" controls></audio>'.format(obj.file.url)) if not obj.is_removed else ""
audio.short_description = _("Audio")