views.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. from django.contrib import messages
  2. from django.db.models import ObjectDoesNotExist
  3. from django.shortcuts import redirect
  4. from django.urls import reverse
  5. from django.utils.translation import gettext, gettext_lazy as _
  6. from ...themes.models import Theme
  7. from ..views import generic
  8. from .forms import ThemeForm, UploadCssForm, UploadMediaForm
  9. class ThemeAdmin(generic.AdminBaseMixin):
  10. root_link = "misago:admin:appearance:themes:index"
  11. model = Theme
  12. form = ThemeForm
  13. templates_dir = "misago/admin/themes"
  14. message_404 = _("Requested theme does not exist.")
  15. class ThemesList(ThemeAdmin, generic.ListView):
  16. pass
  17. class NewTheme(ThemeAdmin, generic.ModelFormView):
  18. message_submit = _('New theme "%(name)s" has been saved.')
  19. def initialize_form(self, form, request, _):
  20. if request.method == "POST":
  21. return form(request.POST, request.FILES)
  22. try:
  23. initial = {"parent": int(request.GET.get("parent"))}
  24. except (TypeError, ValueError):
  25. initial = {}
  26. return form(initial=initial)
  27. class EditTheme(ThemeAdmin, generic.ModelFormView):
  28. message_submit = _('Theme "%(name)s" has been updated.')
  29. def check_permissions(self, request, target):
  30. if target.is_default:
  31. return gettext("Default theme can't be edited.")
  32. class DeleteTheme(ThemeAdmin, generic.ModelFormView):
  33. message_submit = _('Theme "%(name)s" has been deleted.')
  34. def check_permissions(self, request, target):
  35. if target.is_default:
  36. return gettext("Default theme can't be deleted.")
  37. class ActivateTheme(ThemeAdmin, generic.ButtonView):
  38. def button_action(self, request, target):
  39. set_theme_as_active(request, target)
  40. message = gettext('Active theme has been changed to "%(name)s".')
  41. messages.success(request, message % {"name": target})
  42. def set_theme_as_active(request, theme):
  43. Theme.objects.update(is_active=False)
  44. Theme.objects.filter(pk=theme.pk).update(is_active=True)
  45. class ThemeAssetsAdmin(ThemeAdmin):
  46. def check_permissions(self, request, theme):
  47. if theme.is_default:
  48. return gettext("Default theme assets can't be edited.")
  49. def redirect_to_theme_assets(self, theme):
  50. link = reverse("misago:admin:appearance:themes:assets", kwargs={"pk": theme.pk})
  51. return redirect(link)
  52. class ThemeAssets(ThemeAssetsAdmin, generic.TargetedView):
  53. template = "assets/list.html"
  54. def real_dispatch(self, request, theme):
  55. return self.render(request, {"theme": theme})
  56. class ThemeAssetsActionAdmin(ThemeAssetsAdmin):
  57. def real_dispatch(self, request, theme):
  58. if request.method == "POST":
  59. self.action(request, theme)
  60. return self.redirect_to_theme_assets(theme)
  61. def action(self, request, theme):
  62. raise NotImplementedError(
  63. "action method must be implemented in inheriting class"
  64. )
  65. class UploadThemeAssets(ThemeAssetsActionAdmin, generic.TargetedView):
  66. message_partial_success = _(
  67. "Some css files could not have been added to the theme."
  68. )
  69. message_submit = None
  70. form = None
  71. def action(self, request, theme):
  72. form = self.form( # pylint: disable=not-callable
  73. request.POST, request.FILES, instance=theme
  74. )
  75. if not form.is_valid():
  76. if form.cleaned_data.get("assets"):
  77. messages.info(request, self.message_partial_success)
  78. for error in form.errors["assets"]:
  79. messages.error(request, error)
  80. if form.cleaned_data.get("assets"):
  81. form.save()
  82. messages.success(request, self.message_success)
  83. class UploadThemeCss(UploadThemeAssets):
  84. message_success = _("New CSS files have been added to the theme.")
  85. form = UploadCssForm
  86. class UploadThemeMedia(UploadThemeAssets):
  87. message_success = _("New media files have been added to the theme.")
  88. form = UploadMediaForm
  89. class DeleteThemeAssets(ThemeAssetsActionAdmin, generic.TargetedView):
  90. message_submit = None
  91. queryset_attr = None
  92. def action(self, request, theme):
  93. items = self.clean_items_list(request)
  94. if items:
  95. queryset = getattr(theme, self.queryset_attr)
  96. for item in items:
  97. self.delete_asset(queryset, item)
  98. messages.success(request, self.message_submit)
  99. def clean_items_list(self, request):
  100. try:
  101. return {int(i) for i in request.POST.getlist("item")[:20]}
  102. except (ValueError, TypeError):
  103. pass
  104. def delete_asset(self, queryset, item):
  105. try:
  106. queryset.get(pk=item).delete()
  107. except ObjectDoesNotExist:
  108. pass
  109. class DeleteThemeCss(DeleteThemeAssets):
  110. message_submit = _("Selected CSS files have been deleted.")
  111. queryset_attr = "css"
  112. class DeleteThemeMedia(DeleteThemeAssets):
  113. message_submit = _("Selected media have been deleted.")
  114. queryset_attr = "media"