views.py 13 KB

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