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:
@ -1,16 +1,62 @@
|
||||
import json
|
||||
import random
|
||||
|
||||
from django import template
|
||||
from django import template, forms
|
||||
from django.db import models
|
||||
from django.contrib.admin.templatetags.admin_urls import admin_urlname
|
||||
from django.template.loader import render_to_string
|
||||
from django.urls import reverse
|
||||
|
||||
from aircox.models import Diffusion, Log
|
||||
|
||||
|
||||
random.seed()
|
||||
register = template.Library()
|
||||
|
||||
|
||||
@register.simple_tag(name="form_field")
|
||||
def form_field(field, name=None, value=None, **kwargs):
|
||||
name = name or field.name
|
||||
return field.widget.render(name=name, value=value, **kwargs)
|
||||
|
||||
|
||||
@register.filter(name="admin_url")
|
||||
def admin_url(obj, action):
|
||||
meta = obj._meta
|
||||
return reverse(f"admin:{meta.app_label}_{meta.model_name}_{action}", args=[obj.id])
|
||||
|
||||
|
||||
@register.filter(name="model_label")
|
||||
def model_label(obj):
|
||||
if isinstance(obj, models.Model):
|
||||
obj = type(obj)
|
||||
return obj._meta.label_lower.replace(".", "-")
|
||||
|
||||
|
||||
@register.filter(name="object_id")
|
||||
def object_id(obj):
|
||||
return f"{model_label(obj)}-{obj.pk}"
|
||||
|
||||
|
||||
@register.simple_tag(name="page_widget", takes_context=True)
|
||||
def do_page_widget(context, widget, object, dir="aircox/widgets", **ctx):
|
||||
"""Render widget for the provided page and context."""
|
||||
ctx["request"] = context["request"]
|
||||
ctx["object"] = object
|
||||
ctx["widget"] = widget
|
||||
if object.pk and not ctx.get("tag_id"):
|
||||
model = type(object)._meta.model_name
|
||||
ctx["tag_id"] = f"{widget}_{model}_{object.pk}"
|
||||
ctx["widget_template"] = f"{dir}/{widget}.html"
|
||||
return render_to_string(object.get_template_name(widget), ctx)
|
||||
|
||||
|
||||
@register.filter(name="page_template")
|
||||
def do_page_template(self, page, component):
|
||||
"""For a provided page object and component name, return template name."""
|
||||
return page.get_template(component)
|
||||
|
||||
|
||||
@register.filter(name="admin_url")
|
||||
def do_admin_url(obj, arg, pass_id=True):
|
||||
"""Reverse admin url for object."""
|
||||
@ -29,11 +75,18 @@ def do_get_tracks(obj):
|
||||
return obj.track_set.all()
|
||||
|
||||
|
||||
@register.simple_tag(name="has_perm", takes_context=True)
|
||||
def do_has_perm(context, obj, perm, user=None):
|
||||
@register.filter(name="has_perm")
|
||||
def do_has_perm(user, perm):
|
||||
"""Return True if user has permission."""
|
||||
return user.has_perm(perm)
|
||||
|
||||
|
||||
@register.simple_tag(name="has_obj_perm", takes_context=True)
|
||||
def do_has_obj_perm(context, obj, perm, user=None):
|
||||
"""Return True if ``user.has_perm('[APP].[perm]_[MODEL]')``"""
|
||||
if user is None:
|
||||
user = context["request"].user
|
||||
user = user or context["request"].user
|
||||
if not obj:
|
||||
return False
|
||||
return user.has_perm("{}.{}_{}".format(obj._meta.app_label, perm, obj._meta.model_name))
|
||||
|
||||
|
||||
@ -43,6 +96,12 @@ def do_is_diffusion(obj):
|
||||
return isinstance(obj, Diffusion)
|
||||
|
||||
|
||||
@register.filter(name="is_log")
|
||||
def do_is_log(obj):
|
||||
"""Return True if object is a Diffusion."""
|
||||
return isinstance(obj, Log)
|
||||
|
||||
|
||||
@register.filter(name="json")
|
||||
def do_json(obj, fields=""):
|
||||
"""Return object as json."""
|
||||
@ -66,13 +125,25 @@ def do_player_live_attr(context):
|
||||
@register.simple_tag(name="nav_items", takes_context=True)
|
||||
def do_nav_items(context, menu, **kwargs):
|
||||
"""Render navigation items for the provided menu name."""
|
||||
if not getattr(context["request"], "station"):
|
||||
return []
|
||||
station, request = context["station"], context["request"]
|
||||
return [(item, item.render(request, **kwargs)) for item in station.navitem_set.filter(menu=menu)]
|
||||
|
||||
|
||||
@register.filter(name="nav_active")
|
||||
def do_nav_active(obj, request):
|
||||
if request.path.startswith(obj.get_url()):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
@register.simple_tag(name="update_query")
|
||||
def do_update_query(obj, **kwargs):
|
||||
"""Replace provided querydict's values with **kwargs."""
|
||||
"""Replace provided querydict's values with **kwargs.
|
||||
|
||||
Values set to ``None`` will be dropped.
|
||||
"""
|
||||
for k, v in kwargs.items():
|
||||
if v is not None:
|
||||
obj[k] = list(v) if hasattr(v, "__iter__") else [v]
|
||||
@ -85,4 +156,28 @@ def do_update_query(obj, **kwargs):
|
||||
def do_verbose_name(obj, plural=False):
|
||||
"""Return model's verbose name (singular or plural) or `obj` if it is a
|
||||
string (can act for default values)."""
|
||||
return obj if isinstance(obj, str) else obj._meta.verbose_name_plural if plural else obj._meta.verbose_name
|
||||
if isinstance(obj, str):
|
||||
return obj
|
||||
return obj._meta.verbose_name_plural if plural else obj._meta.verbose_name
|
||||
|
||||
|
||||
@register.filter(name="edit_view")
|
||||
def do_edit_view(obj):
|
||||
return "%s-edit" % obj.split("-")[0]
|
||||
|
||||
|
||||
@register.filter(name="detail_view")
|
||||
def do_detail_view(obj):
|
||||
return "%s-detail" % obj.split("-")[0]
|
||||
|
||||
|
||||
@register.filter(name="is_checkbox")
|
||||
def is_checkbox(field):
|
||||
"""Return True if field is a checkbox."""
|
||||
return isinstance(field.widget, forms.CheckboxInput)
|
||||
|
||||
|
||||
@register.filter(name="is_select")
|
||||
def is_select(field):
|
||||
"""Return True if field is a select."""
|
||||
return isinstance(field.widget, forms.Select)
|
||||
|
@ -3,10 +3,11 @@ import json
|
||||
from django import template
|
||||
from django.contrib import admin
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.utils.safestring import mark_safe
|
||||
|
||||
from aircox.serializers.admin import UserSettingsSerializer
|
||||
|
||||
__all__ = ("register", "do_get_admin_tools", "do_track_inline_data")
|
||||
__all__ = ("register", "do_get_admin_tools", "do_formset_inline_data", "do_inline_labels")
|
||||
|
||||
|
||||
register = template.Library()
|
||||
@ -17,26 +18,44 @@ def do_get_admin_tools():
|
||||
return admin.site.get_tools()
|
||||
|
||||
|
||||
@register.simple_tag(name="track_inline_data", takes_context=True)
|
||||
def do_track_inline_data(context, formset):
|
||||
"""Return initial data for playlist editor as dict. Keys are:
|
||||
@register.simple_tag(name="formset_inline_data", takes_context=True)
|
||||
def do_formset_inline_data(context, formset):
|
||||
"""Return initial data of formset as dict (used by TrackListEditor and
|
||||
PlaylistEditor). Keys are:
|
||||
|
||||
- ``items``: list of items. Extra keys:
|
||||
- ``__error__``: dict of form fields errors
|
||||
- ``settings``: user's settings
|
||||
- ``fields``: dict of field name and label
|
||||
"""
|
||||
|
||||
# --- get fields labels
|
||||
model = formset.form.Meta.model
|
||||
fields = {}
|
||||
for field_name in formset.form.Meta.fields:
|
||||
field = model._meta.get_field(field_name)
|
||||
fields[field_name] = str(field.verbose_name).capitalize()
|
||||
|
||||
# --- get items
|
||||
items = []
|
||||
for form in formset.forms:
|
||||
item = {name: form[name].value() for name in form.fields.keys()}
|
||||
item["__errors__"] = form.errors
|
||||
|
||||
# hack for sound list
|
||||
if duration := item.get("duration"):
|
||||
item["duration"] = duration.strftime("%H:%M")
|
||||
if sound := getattr(form.instance, "sound", None):
|
||||
item["name"] = sound.name
|
||||
fields["name"] = str(_("Sound")).capitalize()
|
||||
|
||||
# hack for playlist editor
|
||||
tags = item.get("tags")
|
||||
if tags and not isinstance(tags, str):
|
||||
item["tags"] = ", ".join(tag.name for tag in tags)
|
||||
items.append(item)
|
||||
|
||||
data = {"items": items}
|
||||
data = {"items": items, "fields": fields, "initial": formset.initial and formset.initial[0]}
|
||||
user = context["request"].user
|
||||
settings = getattr(user, "aircox_settings", None)
|
||||
data["settings"] = settings and UserSettingsSerializer(settings).data
|
||||
@ -44,22 +63,32 @@ def do_track_inline_data(context, formset):
|
||||
return source
|
||||
|
||||
|
||||
track_inline_labels_ = {
|
||||
"artist": _("Artist"),
|
||||
"album": _("Album"),
|
||||
"title": _("Title"),
|
||||
"tags": _("Tags"),
|
||||
"year": _("Year"),
|
||||
inline_labels_ = {
|
||||
# list editor
|
||||
"add_item": _("Add an item"),
|
||||
"remove_item": _("Remove"),
|
||||
"settings": _("Settings"),
|
||||
"save_settings": _("Save Settings"),
|
||||
"discard_changes": _("Discard changes"),
|
||||
"submit": _("Submit"),
|
||||
"delete": _("Delete"),
|
||||
# select file
|
||||
"upload": _("Upload"),
|
||||
"list": _("List"),
|
||||
"confirm_delete": _("Are you sure to remove this element from the server?"),
|
||||
"show_next": _("Show next"),
|
||||
"show_previous": _("Show previous"),
|
||||
"select_file": _("Select a file"),
|
||||
# track list
|
||||
"text": _("Text"),
|
||||
"columns": _("Columns"),
|
||||
"add_track": _("Add a track"),
|
||||
"remove_track": _("Remove"),
|
||||
"timestamp": _("Timestamp"),
|
||||
# sound list
|
||||
"add_sound": _("Add a sound"),
|
||||
}
|
||||
|
||||
|
||||
@register.simple_tag(name="track_inline_labels")
|
||||
def do_track_inline_labels():
|
||||
@register.simple_tag(name="inline_labels")
|
||||
def do_inline_labels():
|
||||
"""Return labels for columns in playlist editor as dict."""
|
||||
return json.dumps({k: str(v) for k, v in track_inline_labels_.items()})
|
||||
return mark_safe(json.dumps({k: str(v) for k, v in inline_labels_.items()}))
|
||||
|
Reference in New Issue
Block a user