forked from rc/aircox
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:
@ -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",
|
||||
|
@ -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",)
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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")
|
||||
|
@ -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:
|
||||
|
@ -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")
|
||||
|
||||
|
Reference in New Issue
Block a user