views.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  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 UploadThemeAssets(ThemeAssetsActionAdmin, generic.TargetedView):
  67. message_partial_success = _(
  68. "Some css files could not have been added to the style."
  69. )
  70. message_submit = None
  71. form = None
  72. def action(self, request, theme):
  73. form = self.form(request.POST, request.FILES, instance=theme)
  74. if not form.is_valid():
  75. if form.cleaned_data["assets"]:
  76. messages.info(request, self.message_partial_success)
  77. for error in form.errors["assets"]:
  78. messages.error(request, error)
  79. if form.cleaned_data["assets"]:
  80. form.save()
  81. messages.success(request, self.message_success)
  82. class UploadThemeCss(UploadThemeAssets):
  83. message_success = _("New CSS files have been added to the style.")
  84. form = UploadCssForm
  85. class UploadThemeImages(UploadThemeAssets):
  86. message_success = _("New media files have been added to the style.")
  87. form = UploadImagesForm
  88. class DeleteThemeAssets(ThemeAssetsActionAdmin, generic.TargetedView):
  89. message_submit = None
  90. queryset_attr = None
  91. def action(self, request, theme):
  92. items = self.clean_items_list(request)
  93. if items:
  94. queryset = getattr(theme, self.queryset_attr)
  95. for item in items:
  96. self.delete_item(queryset, item)
  97. messages.success(request, self.message_submit)
  98. def clean_items_list(self, request):
  99. try:
  100. return {int(i) for i in request.POST.getlist("item")}
  101. except (ValueError, TypeError):
  102. pass
  103. def delete_item(self, queryset, item):
  104. try:
  105. queryset.get(pk=item).delete()
  106. except ObjectDoesNotExist:
  107. pass
  108. class DeleteThemeCss(DeleteThemeAssets):
  109. message_submit = _("Selected css files have been deleted.")
  110. queryset_attr = "css"
  111. class DeleteThemeImages(DeleteThemeAssets):
  112. message_submit = _("Selected images have been deleted.")
  113. queryset_attr = "images"
  114. class DeleteThemeFonts(DeleteThemeAssets):
  115. message_submit = _("Selected font files have been deleted.")
  116. queryset_attr = "fonts"