category.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. from django.http import Http404
  2. from misago.acl import add_acl
  3. from misago.categories.models import Category
  4. from misago.categories.permissions import allow_browse_category, allow_see_category
  5. from misago.categories.serializers import CategorySerializer
  6. from misago.core.shortcuts import validate_slug
  7. from misago.core.viewmodel import ViewModel as BaseViewModel
  8. from misago.threads.permissions import allow_use_private_threads
  9. __all__ = ['ThreadsRootCategory', 'ThreadsCategory', 'PrivateThreadsCategory']
  10. class ViewModel(BaseViewModel):
  11. def __init__(self, request, **kwargs):
  12. self._categories = self.get_categories(request)
  13. add_acl(request.user, self._categories)
  14. self._model = self.get_category(request, self._categories, **kwargs)
  15. self._subcategories = list(filter(self._model.has_child, self._categories))
  16. self._children = list(filter(lambda s: s.parent_id == self._model.pk, self._subcategories))
  17. @property
  18. def categories(self):
  19. return self._categories
  20. @property
  21. def subcategories(self):
  22. return self._subcategories
  23. @property
  24. def children(self):
  25. return self._children
  26. def get_categories(self, request):
  27. raise NotImplementedError('Category view model has to implement get_categories(request)')
  28. def get_category(self, request, categories, **kwargs):
  29. return categories[0]
  30. def get_frontend_context(self):
  31. return {'CATEGORIES': BasicCategorySerializer(self._categories, many=True).data}
  32. def get_template_context(self):
  33. return {'category': self._model, 'subcategories': self._children}
  34. class ThreadsRootCategory(ViewModel):
  35. def get_categories(self, request):
  36. return [Category.objects.root_category()] + list(
  37. Category.objects.all_categories().filter(
  38. id__in=request.user.acl_cache['browseable_categories'],
  39. ).select_related('parent')
  40. )
  41. class ThreadsCategory(ThreadsRootCategory):
  42. @property
  43. def level(self):
  44. return self._model.level
  45. def get_category(self, request, categories, **kwargs):
  46. for category in categories:
  47. if category.pk == int(kwargs['pk']):
  48. if not category.special_role:
  49. # don't check permissions for non-special category
  50. allow_see_category(request.user, category)
  51. allow_browse_category(request.user, category)
  52. if 'slug' in kwargs:
  53. validate_slug(category, kwargs['slug'])
  54. return category
  55. raise Http404()
  56. class PrivateThreadsCategory(ViewModel):
  57. def get_categories(self, request):
  58. return [Category.objects.private_threads()]
  59. def get_category(self, request, categories, **kwargs):
  60. allow_use_private_threads(request.user)
  61. return categories[0]
  62. BasicCategorySerializer = CategorySerializer.subset_fields(
  63. 'id',
  64. 'parent',
  65. 'name',
  66. 'description',
  67. 'is_closed',
  68. 'css_class',
  69. 'absolute_url',
  70. 'api_url',
  71. 'level',
  72. 'lft',
  73. 'rght',
  74. 'is_read',
  75. )