views.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. from django.core.urlresolvers import reverse as django_reverse
  2. from django.db.models import Q
  3. from django.utils.translation import ugettext as _
  4. from mptt.forms import TreeNodeChoiceField
  5. from misago.admin import site
  6. from misago.admin.widgets import *
  7. from misago.utils import slugify
  8. from misago.forums.forms import CategoryForm, ForumForm, RedirectForm, DeleteForm
  9. from misago.forums.models import Forum
  10. def reverse(route, target=None):
  11. if target:
  12. return django_reverse(route, kwargs={'target': target.pk, 'slug': target.slug})
  13. return django_reverse(route)
  14. """
  15. Views
  16. """
  17. class List(ListWidget):
  18. admin = site.get_action('forums')
  19. id = 'list'
  20. columns=(
  21. ('forum', _("Forum")),
  22. )
  23. nothing_checked_message = _('You have to select at least one forum.')
  24. actions=(
  25. ('resync', _("Resynchronise forums")),
  26. ('prune', _("Prune forums"), _("Are you sure you want to delete all content from selected forums?")),
  27. )
  28. empty_message = _('No forums are currently defined.')
  29. def get_items(self):
  30. return self.admin.model.objects.get(token='root').get_descendants()
  31. def sort_items(self, page_items, sorting_method):
  32. return page_items.order_by('lft')
  33. def get_item_actions(self, item):
  34. if item.type == 'category':
  35. return (
  36. self.action('chevron-up', _("Move Category Up"), reverse('admin_forums_up', item), post=True),
  37. self.action('chevron-down', _("Move Category Down"), reverse('admin_forums_down', item), post=True),
  38. self.action('pencil', _("Edit Category"), reverse('admin_forums_edit', item)),
  39. self.action('remove', _("Delete Category"), reverse('admin_forums_delete', item)),
  40. )
  41. if item.type == 'forum':
  42. return (
  43. self.action('chevron-up', _("Move Forum Up"), reverse('admin_forums_up', item), post=True),
  44. self.action('chevron-down', _("Move Forum Down"), reverse('admin_forums_down', item), post=True),
  45. self.action('pencil', _("Edit Forum"), reverse('admin_forums_edit', item)),
  46. self.action('remove', _("Delete Forum"), reverse('admin_forums_delete', item)),
  47. )
  48. return (
  49. self.action('chevron-up', _("Move Redirect Up"), reverse('admin_forums_up', item), post=True),
  50. self.action('chevron-down', _("Move Redirect Down"), reverse('admin_forums_down', item), post=True),
  51. self.action('pencil', _("Edit Redirect"), reverse('admin_forums_edit', item)),
  52. self.action('remove', _("Delete Redirect"), reverse('admin_forums_delete', item)),
  53. )
  54. def action_resync(self, items, checked):
  55. return Message(_('Selected forums have been resynchronised successfully.'), 'success'), reverse('admin_forums')
  56. def action_prune(self, items, checked):
  57. return Message(_('Selected forums have been pruned successfully.'), 'success'), reverse('admin_forums')
  58. class NewCategory(FormWidget):
  59. admin = site.get_action('forums')
  60. id = 'new_category'
  61. fallback = 'admin_forums'
  62. form = CategoryForm
  63. submit_button = _("Save Category")
  64. def get_new_url(self, model):
  65. return reverse('admin_forums_new_category')
  66. def get_edit_url(self, model):
  67. return reverse('admin_forums_edit', model)
  68. def submit_form(self, form, target):
  69. new_forum = Forum(
  70. name=form.cleaned_data['name'],
  71. slug=slugify(form.cleaned_data['name']),
  72. type='category',
  73. style=form.cleaned_data['style'],
  74. closed=form.cleaned_data['closed'],
  75. )
  76. new_forum.set_description(form.cleaned_data['description'])
  77. new_forum.insert_at(form.cleaned_data['parent'], position='last-child', save=True)
  78. if form.cleaned_data['perms']:
  79. new_forum.copy_permissions(form.cleaned_data['perms'])
  80. self.request.monitor['acl_version'] = int(self.request.monitor['acl_version']) + 1
  81. return new_forum, Message(_('New Category has been created.'), 'success')
  82. class NewForum(FormWidget):
  83. admin = site.get_action('forums')
  84. id = 'new_forum'
  85. fallback = 'admin_forums'
  86. form = ForumForm
  87. submit_button = _("Save Forum")
  88. def get_new_url(self, model):
  89. return reverse('admin_forums_new_forum')
  90. def get_edit_url(self, model):
  91. return reverse('admin_forums_edit', model)
  92. def submit_form(self, form, target):
  93. new_forum = Forum(
  94. name=form.cleaned_data['name'],
  95. slug=slugify(form.cleaned_data['name']),
  96. type='forum',
  97. style=form.cleaned_data['style'],
  98. closed=form.cleaned_data['closed'],
  99. prune_start=form.cleaned_data['prune_start'],
  100. prune_last=form.cleaned_data['prune_last'],
  101. )
  102. new_forum.set_description(form.cleaned_data['description'])
  103. new_forum.insert_at(form.cleaned_data['parent'], position='last-child', save=True)
  104. if form.cleaned_data['perms']:
  105. new_forum.copy_permissions(form.cleaned_data['perms'])
  106. self.request.monitor['acl_version'] = int(self.request.monitor['acl_version']) + 1
  107. return new_forum, Message(_('New Forum has been created.'), 'success')
  108. def __call__(self, request):
  109. if self.admin.model.objects.get(token='root').get_descendants().count() == 0:
  110. request.messages.set_flash(Message(_("You have to create at least one category before you will be able to create forums.")), 'error', self.admin.id)
  111. return redirect(self.get_fallback_url())
  112. return super(NewForum, self).__call__(request)
  113. class NewRedirect(FormWidget):
  114. admin = site.get_action('forums')
  115. id = 'new_redirect'
  116. fallback = 'admin_forums'
  117. form = RedirectForm
  118. submit_button = _("Save Forum")
  119. def get_new_url(self, model):
  120. return reverse('admin_forums_new_redirect')
  121. def get_edit_url(self, model):
  122. return reverse('admin_forums_edit', model)
  123. def submit_form(self, form, target):
  124. new_forum = Forum(
  125. name=form.cleaned_data['name'],
  126. slug=slugify(form.cleaned_data['name']),
  127. redirect=form.cleaned_data['redirect'],
  128. style=form.cleaned_data['style'],
  129. type='redirect',
  130. )
  131. new_forum.set_description(form.cleaned_data['description'])
  132. new_forum.insert_at(form.cleaned_data['parent'], position='last-child', save=True)
  133. if form.cleaned_data['perms']:
  134. new_forum.copy_permissions(form.cleaned_data['perms'])
  135. self.request.monitor['acl_version'] = int(self.request.monitor['acl_version']) + 1
  136. return new_forum, Message(_('New Redirect has been created.'), 'success')
  137. def __call__(self, request):
  138. if self.admin.model.objects.get(token='root').get_descendants().count() == 0:
  139. request.messages.set_flash(Message(_("You have to create at least one category before you will be able to create redirects.")), 'error', self.admin.id)
  140. return redirect(self.get_fallback_url())
  141. return super(NewRedirect, self).__call__(request)
  142. class Up(ButtonWidget):
  143. admin = site.get_action('forums')
  144. id = 'up'
  145. fallback = 'admin_forums'
  146. notfound_message = _('Requested Forum could not be found.')
  147. def action(self, target):
  148. previous_sibling = target.get_previous_sibling()
  149. if previous_sibling:
  150. target.move_to(previous_sibling, 'left')
  151. return Message(_('Forum "%(name)s" has been moved up.') % {'name': target.name}, 'success'), False
  152. return Message(_('Forum "%(name)s" is first child of its parent node and cannot be moved up.') % {'name': target.name}, 'info'), False
  153. class Down(ButtonWidget):
  154. admin = site.get_action('forums')
  155. id = 'down'
  156. fallback = 'admin_forums'
  157. notfound_message = _('Requested Forum could not be found.')
  158. def action(self, target):
  159. next_sibling = target.get_next_sibling()
  160. if next_sibling:
  161. target.move_to(next_sibling, 'right')
  162. return Message(_('Forum "%(name)s" has been moved down.') % {'name': target.name}, 'success'), False
  163. return Message(_('Forum "%(name)s" is last child of its parent node and cannot be moved down.') % {'name': target.name}, 'info'), False
  164. class Edit(FormWidget):
  165. admin = site.get_action('forums')
  166. id = 'edit'
  167. name = _("Edit Forum")
  168. fallback = 'admin_forums'
  169. form = ForumForm
  170. target_name = 'name'
  171. notfound_message = _('Requested Forum could not be found.')
  172. submit_fallback = True
  173. def get_url(self, model):
  174. return reverse('admin_forums_edit', model)
  175. def get_edit_url(self, model):
  176. return self.get_url(model)
  177. def get_form(self, target):
  178. if target.type == 'category':
  179. self.name= _("Edit Category")
  180. self.form = CategoryForm
  181. if target.type == 'redirect':
  182. self.name= _("Edit Redirect")
  183. self.form = RedirectForm
  184. # Remove invalid targets from parent select
  185. valid_targets = Forum.tree.get(token='root').get_descendants(include_self=target.type == 'category').exclude(Q(lft__gte=target.lft) & Q(rght__lte=target.rght))
  186. self.form.base_fields['parent'] = TreeNodeChoiceField(queryset=valid_targets,level_indicator=u'- - ')
  187. return self.form
  188. def get_initial_data(self, model):
  189. initial = {
  190. 'parent': model.parent,
  191. 'name': model.name,
  192. 'description': model.description,
  193. }
  194. if model.type == 'redirect':
  195. initial['redirect'] = model.redirect
  196. else:
  197. initial['style'] = model.style
  198. initial['closed'] = model.closed
  199. if model.type == 'forum':
  200. initial['prune_start'] = model.prune_start
  201. initial['prune_last'] = model.prune_last
  202. return initial
  203. def submit_form(self, form, target):
  204. target.name = form.cleaned_data['name']
  205. target.set_description(form.cleaned_data['description'])
  206. if target.type == 'redirect':
  207. target.redirect = form.cleaned_data['redirect']
  208. else:
  209. target.style = form.cleaned_data['style']
  210. target.closed = form.cleaned_data['closed']
  211. if target.type == 'forum':
  212. target.prune_start = form.cleaned_data['prune_start']
  213. target.prune_last = form.cleaned_data['prune_last']
  214. if form.cleaned_data['parent'].pk != target.parent.pk:
  215. target.move_to(form.cleaned_data['parent'], 'last-child')
  216. self.request.monitor['acl_version'] = int(self.request.monitor['acl_version']) + 1
  217. target.save(force_update=True)
  218. if form.cleaned_data['perms']:
  219. target.copy_permissions(form.cleaned_data['perms'])
  220. if form.cleaned_data['parent'].pk != target.parent.pk or form.cleaned_data['perms']:
  221. self.request.monitor['acl_version'] = int(self.request.monitor['acl_version']) + 1
  222. return target, Message(_('Changes in forum "%(name)s" have been saved.') % {'name': self.original_name}, 'success')
  223. class Delete(FormWidget):
  224. admin = site.get_action('forums')
  225. id = 'delete'
  226. name = _("Delete Forum")
  227. fallback = 'admin_forums'
  228. template = 'delete'
  229. form = DeleteForm
  230. target_name = 'name'
  231. notfound_message = _('Requested Forum could not be found.')
  232. submit_fallback = True
  233. def get_url(self, model):
  234. return reverse('admin_forums_delete', model)
  235. def get_form(self, target):
  236. if target.type == 'category':
  237. self.name= _("Delete Category")
  238. if target.type == 'redirect':
  239. self.name= _("Delete Redirect")
  240. # Remove invalid targets from parent select
  241. valid_targets = Forum.tree.get(token='root').get_descendants(include_self=target.type == 'category').exclude(Q(lft__gte=target.lft) & Q(rght__lte=target.rght))
  242. self.form.base_fields['parent'] = TreeNodeChoiceField(queryset=valid_targets,required=False,empty_label=_("Remove with forum"),level_indicator=u'- - ')
  243. return self.form
  244. def submit_form(self, form, target):
  245. new_parent = form.cleaned_data['parent']
  246. if new_parent:
  247. target.move_content(new_parent)
  248. for child in target.get_descendants():
  249. child.move_to(new_parent, 'last-child')
  250. child.save(force_update=True)
  251. else:
  252. for child in target.get_descendants():
  253. child.delete()
  254. target.delete()
  255. return target, Message(_('Forum "%(name)s" has been deleted.') % {'name': self.original_name}, 'success')