views.py 4.6 KB

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