Browse Source

Renamed "core" package to "apps" package

Ralfp 12 years ago
parent
commit
684880d96a
47 changed files with 593 additions and 68 deletions
  1. 2 2
      misago/admin.py
  2. 0 0
      misago/apps/__init__.py
  3. 0 0
      misago/apps/admin/__init__.py
  4. 0 0
      misago/apps/admin/clients/__init__.py
  5. 0 0
      misago/apps/admin/clients/forms.py
  6. 2 2
      misago/apps/admin/clients/views.py
  7. 0 0
      misago/apps/admin/forumroles/__init__.py
  8. 0 0
      misago/apps/admin/forumroles/forms.py
  9. 2 2
      misago/apps/admin/forumroles/views.py
  10. 0 0
      misago/apps/admin/forums/__init__.py
  11. 180 0
      misago/apps/admin/forums/forms.py
  12. 348 0
      misago/apps/admin/forums/views.py
  13. 0 0
      misago/apps/admin/home.py
  14. 0 0
      misago/apps/admin/index.py
  15. 0 0
      misago/apps/admin/online/__init__.py
  16. 0 0
      misago/apps/admin/online/forms.py
  17. 2 2
      misago/apps/admin/online/views.py
  18. 0 0
      misago/apps/admin/roles/__init__.py
  19. 0 0
      misago/apps/admin/roles/forms.py
  20. 2 2
      misago/apps/admin/roles/views.py
  21. 10 13
      misago/apps/admin/sections/__init__.py
  22. 5 5
      misago/apps/admin/sections/forums.py
  23. 4 4
      misago/apps/admin/sections/overview.py
  24. 2 2
      misago/apps/admin/sections/perms.py
  25. 2 2
      misago/apps/admin/sections/system.py
  26. 5 5
      misago/apps/admin/sections/users.py
  27. 0 0
      misago/apps/admin/settings/__init__.py
  28. 0 0
      misago/apps/admin/settings/forms.py
  29. 2 2
      misago/apps/admin/settings/views.py
  30. 0 0
      misago/apps/admin/stats/__init__.py
  31. 0 0
      misago/apps/admin/stats/forms.py
  32. 2 2
      misago/apps/admin/stats/views.py
  33. 1 1
      misago/apps/admin/team.py
  34. 0 0
      misago/apps/admin/widgets.py
  35. 0 0
      misago/apps/front/__init__.py
  36. 0 0
      misago/apps/front/index.py
  37. 0 0
      misago/apps/front/readall.py
  38. 0 0
      misago/apps/signin/__init__.py
  39. 0 0
      misago/apps/signin/forms.py
  40. 2 2
      misago/apps/signin/urls.py
  41. 1 1
      misago/apps/signin/views.py
  42. 0 0
      misago/apps/views.py
  43. 1 1
      misago/decorators.py
  44. 2 2
      misago/firewalls.py
  45. 1 1
      misago/models/forummodel.py
  46. 10 10
      misago/settings_base.py
  47. 5 5
      misago/urls.py

+ 2 - 2
misago/admin.py

@@ -147,13 +147,13 @@ class AdminSite(object):
         late_actions = []
         late_actions = []
 
 
         # Load default admin site
         # Load default admin site
-        from misago.core.admin.sections import ADMIN_SECTIONS
+        from misago.apps.admin.sections import ADMIN_SECTIONS
         for section in ADMIN_SECTIONS:
         for section in ADMIN_SECTIONS:
             self.sections.append(section)
             self.sections.append(section)
             self.sections_index[section.id] = section
             self.sections_index[section.id] = section
 
 
             # Loop section actions
             # Loop section actions
-            section_actions = import_module('misago.core.admin.sections.%s' % section.id)
+            section_actions = import_module('misago.apps.admin.sections.%s' % section.id)
             for action in section_actions.ADMIN_ACTIONS:
             for action in section_actions.ADMIN_ACTIONS:
                 self.actions_index[action.id] = action
                 self.actions_index[action.id] = action
                 if not action.after:
                 if not action.after:

+ 0 - 0
misago/core/__init__.py → misago/apps/__init__.py


+ 0 - 0
misago/core/admin/__init__.py → misago/apps/admin/__init__.py


+ 0 - 0
misago/core/admin/clients/__init__.py → misago/apps/admin/clients/__init__.py


+ 0 - 0
misago/core/admin/clients/forms.py → misago/apps/admin/clients/forms.py


+ 2 - 2
misago/core/admin/clients/views.py → misago/apps/admin/clients/views.py

@@ -2,11 +2,11 @@ from django.core.urlresolvers import reverse as django_reverse
 from django import forms
 from django import forms
 from django.utils.translation import ugettext as _
 from django.utils.translation import ugettext as _
 from misago.admin import site
 from misago.admin import site
-from misago.core.admin.widgets import *
+from misago.apps.admin.widgets import *
 from misago.forms import Form
 from misago.forms import Form
 from misago.models import ThemeAdjustment
 from misago.models import ThemeAdjustment
 from misago.utils.strings import slugify
 from misago.utils.strings import slugify
-from misago.core.admin.clients.forms import ThemeAdjustmentForm
+from misago.apps.admin.clients.forms import ThemeAdjustmentForm
 
 
 def reverse(route, target=None):
 def reverse(route, target=None):
     if target:
     if target:

+ 0 - 0
misago/core/admin/forumroles/__init__.py → misago/apps/admin/forumroles/__init__.py


+ 0 - 0
misago/core/admin/forumroles/forms.py → misago/apps/admin/forumroles/forms.py


+ 2 - 2
misago/core/admin/forumroles/views.py → misago/apps/admin/forumroles/views.py

@@ -3,11 +3,11 @@ from django.core.urlresolvers import reverse as django_reverse
 from django.utils.translation import ugettext as _
 from django.utils.translation import ugettext as _
 from misago.acl.builder import build_forum_form
 from misago.acl.builder import build_forum_form
 from misago.admin import site
 from misago.admin import site
-from misago.core.admin.widgets import *
+from misago.apps.admin.widgets import *
 from misago.forms import Form, YesNoSwitch
 from misago.forms import Form, YesNoSwitch
 from misago.models import ForumRole
 from misago.models import ForumRole
 from misago.utils.strings import slugify
 from misago.utils.strings import slugify
-from misago.core.admin.forumroles.forms import ForumRoleForm
+from misago.apps.admin.forumroles.forms import ForumRoleForm
 
 
 def reverse(route, target=None):
 def reverse(route, target=None):
     if target:
     if target:

+ 0 - 0
misago/core/admin/online/__init__.py → misago/apps/admin/forums/__init__.py


+ 180 - 0
misago/apps/admin/forums/forms.py

@@ -0,0 +1,180 @@
+from django.utils.translation import ugettext_lazy as _
+from django import forms
+from mptt.forms import TreeNodeChoiceField
+from misago.forms import Form, YesNoSwitch
+from misago.models import Forum
+from misago.validators import validate_sluggable
+
+class CategoryForm(Form):
+    parent = False
+    perms = False
+    name = forms.CharField(max_length=255, validators=[validate_sluggable(
+                                                                          _("Category name must be sluggable."),
+                                                                          _("Category name is too long.")
+                                                                          )])
+    description = forms.CharField(widget=forms.Textarea, required=False)
+    closed = forms.BooleanField(widget=YesNoSwitch, required=False)
+    style = forms.CharField(max_length=255, required=False)
+    attrs = forms.CharField(max_length=255, required=False)
+    show_details = forms.BooleanField(widget=YesNoSwitch, required=False, initial=True)
+
+    layout = (
+              (
+               _("Basic Options"),
+               (
+                ('parent', {'label': _("Category Parent")}),
+                ('perms', {'label': _("Copy Permissions from")}),
+                ('name', {'label': _("Category Name")}),
+                ('description', {'label': _("Category Description")}),
+                ('closed', {'label': _("Closed Category")}),
+                ),
+              ),
+              (
+               _("Display Options"),
+               (
+                ('attrs', {'label': _("Category Attributes"), 'help_text': _('Custom templates can check categories for predefined attributes that will change way they are rendered.')}),
+                ('show_details', {'label': _("Show Subforums Details"), 'help_text': _('Allows you to prevent this category subforums from displaying statistics, last post data, etc. ect. on forums lists.')}),
+                ('style', {'label': _("Category Style"), 'help_text': _('You can add custom CSS classess to this category, to change way it looks on board index.')}),
+                ),
+              ),
+             )
+
+    def finalize_form(self):
+        self.fields['parent'] = TreeNodeChoiceField(queryset=Forum.tree.get(token='root').get_descendants(include_self=True), level_indicator=u'- - ')
+        self.fields['perms'] = TreeNodeChoiceField(queryset=Forum.tree.get(token='root').get_descendants(), level_indicator=u'- - ', required=False, empty_label=_("Don't copy permissions"))
+
+    def clean_attrs(self):
+        clean = []
+        data = self.cleaned_data['attrs'].strip().split()
+        for i in data:
+            i = i.strip()
+            if not i in clean:
+                clean.append(i)
+        return ' '.join(clean)
+
+
+class ForumForm(Form):
+    parent = False
+    perms = False
+    name = forms.CharField(max_length=255, validators=[validate_sluggable(
+                                                                          _("Forum name must be sluggable."),
+                                                                          _("Forum name is too long.")
+                                                                          )])
+    description = forms.CharField(widget=forms.Textarea, required=False)
+    closed = forms.BooleanField(widget=YesNoSwitch, required=False)
+    style = forms.CharField(max_length=255, required=False)
+    prune_start = forms.IntegerField(min_value=0, initial=0)
+    prune_last = forms.IntegerField(min_value=0, initial=0)
+    attrs = forms.CharField(max_length=255, required=False)
+    show_details = forms.BooleanField(widget=YesNoSwitch, required=False, initial=True)
+
+    layout = (
+              (
+               _("Basic Options"),
+               (
+                ('parent', {'label': _("Forum Parent")}),
+                ('perms', {'label': _("Copy Permissions from")}),
+                ('name', {'label': _("Forum Name")}),
+                ('description', {'label': _("Forum Description")}),
+                ('closed', {'label': _("Closed Forum")}),
+                ),
+               ),
+              (
+               _("Prune Forum"),
+               (
+                ('prune_start', {'label': _("Delete threads with first post older than"), 'help_text': _('Enter number of days since thread start after which thread will be deleted or zero to don\'t delete threads.')}),
+                ('prune_last', {'label': _("Delete threads with last post older than"), 'help_text': _('Enter number of days since since last reply in thread after which thread will be deleted or zero to don\'t delete threads.')}),
+                ),
+               ),
+              (
+               _("Display Options"),
+               (
+                ('attrs', {'label': _("Subforums List Attributes"), 'help_text': _('Custom templates can check forums for predefined attributes that will change way subforums lists are rendered.')}),
+                ('show_details', {'label': _("Show Subforums Details"), 'help_text': _("Allows you to prevent this forum's subforums from displaying statistics, last post data, etc. ect. on subforums list.")}),
+                ('style', {'label': _("Forum Style"), 'help_text': _('You can add custom CSS classess to this forum to change way it looks on forums lists.')}),
+                ),
+               ),
+              )
+
+    def finalize_form(self):
+        self.fields['parent'] = TreeNodeChoiceField(queryset=Forum.tree.get(token='root').get_descendants(), level_indicator=u'- - ')
+        self.fields['perms'] = TreeNodeChoiceField(queryset=Forum.tree.get(token='root').get_descendants(), level_indicator=u'- - ', required=False, empty_label=_("Don't copy permissions"))
+
+    def clean_attrs(self):
+        clean = []
+        data = self.cleaned_data['attrs'].strip().split()
+        for i in data:
+            i = i.strip()
+            if not i in clean:
+                clean.append(i)
+        return ' '.join(clean)
+
+
+class RedirectForm(Form):
+    parent = False
+    perms = False
+    name = forms.CharField(max_length=255, validators=[validate_sluggable(
+                                                                          _("Redirect name must be sluggable."),
+                                                                          _("Redirect name is too long.")
+                                                                          )])
+    description = forms.CharField(widget=forms.Textarea, required=False)
+    redirect = forms.URLField(max_length=255)
+    style = forms.CharField(max_length=255, required=False)
+
+    layout = (
+              (
+               _("Basic Options"),
+               (
+                ('parent', {'label': _("Redirect Parent")}),
+                ('perms', {'label': _("Copy Permissions from")}),
+                ('name', {'label': _("Redirect Name")}),
+                ('redirect', {'label': _("Redirect URL")}),
+                ('description', {'label': _("Redirect Description")}),
+                ),
+               ),
+              (
+               _("Display Options"),
+               (
+                ('style', {'label': _("Redirect Style"), 'help_text': _('You can add custom CSS classess to this redirect to change way it looks on forums lists.')}),
+                ),
+               ),
+              )
+
+    def finalize_form(self):
+        self.fields['parent'] = TreeNodeChoiceField(queryset=Forum.tree.get(token='root').get_descendants(), level_indicator=u'- - ')
+        self.fields['perms'] = TreeNodeChoiceField(queryset=Forum.tree.get(token='root').get_descendants(), level_indicator=u'- - ', required=False, empty_label=_("Don't copy permissions"))
+
+
+class DeleteForm(Form):
+    layout = (
+              (
+               _("Delete Options"),
+               (
+                ('contents', {'label': _("Move threads to")}),
+                ('subforums', {'label': _("Move subforums to")}),
+                ),
+               ),
+              )
+
+    def __init__(self, *args, **kwargs):
+        self.forum = kwargs.pop('forum')
+        super(DeleteForm, self).__init__(*args, **kwargs)
+
+    def finalize_form(self):
+        self.fields['contents'] = TreeNodeChoiceField(queryset=Forum.tree.get(token='root').get_descendants(), required=False, empty_label=_("Remove with forum"), level_indicator=u'- - ')
+        self.fields['subforums'] = TreeNodeChoiceField(queryset=Forum.tree.get(token='root').get_descendants(), required=False, empty_label=_("Remove with forum"), level_indicator=u'- - ')
+
+    def clean_contents(self):
+        data = self.cleaned_data['contents']
+        if data:
+            if data.type == 'category':
+                raise forms.ValidationError(_("Categories cannot contain threads."))
+            if data.type == 'redirect':
+                raise forms.ValidationError(_("Redirects cannot contain threads."))
+        return data
+
+    def clean(self):
+        cleaned_data = super(DeleteForm, self).clean()
+        if self.forum.type == 'forum' and cleaned_data['contents'] and cleaned_data['contents'].lft > self.forum.lft and cleaned_data['contents'].rght < self.forum.rght and not cleaned_data['subforums']:
+            raise forms.ValidationError(_("Destination you want to move this forum's threads to will be deleted with this forum."))
+        return cleaned_data

+ 348 - 0
misago/apps/admin/forums/views.py

@@ -0,0 +1,348 @@
+import copy
+from django.core.urlresolvers import reverse as django_reverse
+from django.db.models import Q
+from django.utils.translation import ugettext as _
+from mptt.forms import TreeNodeChoiceField
+from misago.admin import site
+from misago.apps.admin.widgets import *
+from misago.models import Forum
+from misago.utils.strings import slugify
+from misago.apps.admin.forums.forms import CategoryForm, ForumForm, RedirectForm, DeleteForm
+
+def reverse(route, target=None):
+    if target:
+        return django_reverse(route, kwargs={'target': target.pk, 'slug': target.slug})
+    return django_reverse(route)
+
+
+"""
+Views
+"""
+class List(ListWidget):
+    admin = site.get_action('forums')
+    id = 'list'
+    columns = (
+               ('forum', _("Forum")),
+               )
+    nothing_checked_message = _('You have to select at least one forum.')
+    actions = (
+               ('resync', _("Resynchronise forums")),
+               ('prune', _("Prune forums"), _("Are you sure you want to delete all content from selected forums?")),
+               )
+    empty_message = _('No forums are currently defined.')
+
+    def get_items(self):
+        return self.admin.model.objects.get(token='root').get_descendants()
+
+    def sort_items(self, page_items, sorting_method):
+        return page_items.order_by('lft')
+
+    def get_item_actions(self, item):
+        if item.type == 'category':
+            return (
+                    self.action('chevron-up', _("Move Category Up"), reverse('admin_forums_up', item), post=True),
+                    self.action('chevron-down', _("Move Category Down"), reverse('admin_forums_down', item), post=True),
+                    self.action('pencil', _("Edit Category"), reverse('admin_forums_edit', item)),
+                    self.action('remove', _("Delete Category"), reverse('admin_forums_delete', item)),
+                    )
+
+        if item.type == 'forum':
+            return (
+                    self.action('chevron-up', _("Move Forum Up"), reverse('admin_forums_up', item), post=True),
+                    self.action('chevron-down', _("Move Forum Down"), reverse('admin_forums_down', item), post=True),
+                    self.action('pencil', _("Edit Forum"), reverse('admin_forums_edit', item)),
+                    self.action('remove', _("Delete Forum"), reverse('admin_forums_delete', item)),
+                    )
+
+        return (
+                self.action('chevron-up', _("Move Redirect Up"), reverse('admin_forums_up', item), post=True),
+                self.action('chevron-down', _("Move Redirect Down"), reverse('admin_forums_down', item), post=True),
+                self.action('pencil', _("Edit Redirect"), reverse('admin_forums_edit', item)),
+                self.action('remove', _("Delete Redirect"), reverse('admin_forums_delete', item)),
+                )
+
+    def action_resync(self, items, checked):
+        return Message(_('Selected forums have been resynchronised successfully.'), 'success'), reverse('admin_forums')
+
+    def action_prune(self, items, checked):
+        return Message(_('Selected forums have been pruned successfully.'), 'success'), reverse('admin_forums')
+
+
+class NewCategory(FormWidget):
+    admin = site.get_action('forums')
+    id = 'new_category'
+    fallback = 'admin_forums'
+    form = CategoryForm
+    submit_button = _("Save Category")
+
+    def get_new_url(self, model):
+        return reverse('admin_forums_new_category')
+
+    def get_edit_url(self, model):
+        return reverse('admin_forums_edit', model)
+
+    def submit_form(self, form, target):
+        new_forum = Forum(
+                          name=form.cleaned_data['name'],
+                          slug=slugify(form.cleaned_data['name']),
+                          type='category',
+                          attrs=form.cleaned_data['attrs'],
+                          show_details=form.cleaned_data['show_details'],
+                          style=form.cleaned_data['style'],
+                          closed=form.cleaned_data['closed'],
+                          )
+        new_forum.set_description(form.cleaned_data['description'])
+        new_forum.insert_at(form.cleaned_data['parent'], position='last-child', save=True)
+        Forum.objects.populate_tree(True)
+
+        if form.cleaned_data['perms']:
+            new_forum.copy_permissions(form.cleaned_data['perms'])
+            self.request.monitor['acl_version'] = int(self.request.monitor['acl_version']) + 1
+
+        return new_forum, Message(_('New Category has been created.'), 'success')
+
+
+class NewForum(FormWidget):
+    admin = site.get_action('forums')
+    id = 'new_forum'
+    fallback = 'admin_forums'
+    form = ForumForm
+    submit_button = _("Save Forum")
+
+    def get_new_url(self, model):
+        return reverse('admin_forums_new_forum')
+
+    def get_edit_url(self, model):
+        return reverse('admin_forums_edit', model)
+
+    def submit_form(self, form, target):
+        new_forum = Forum(
+                          name=form.cleaned_data['name'],
+                          slug=slugify(form.cleaned_data['name']),
+                          type='forum',
+                          attrs=form.cleaned_data['attrs'],
+                          show_details=form.cleaned_data['show_details'],
+                          style=form.cleaned_data['style'],
+                          closed=form.cleaned_data['closed'],
+                          prune_start=form.cleaned_data['prune_start'],
+                          prune_last=form.cleaned_data['prune_last'],
+                          )
+        new_forum.set_description(form.cleaned_data['description'])
+        new_forum.insert_at(form.cleaned_data['parent'], position='last-child', save=True)
+        Forum.objects.populate_tree(True)
+
+        if form.cleaned_data['perms']:
+            new_forum.copy_permissions(form.cleaned_data['perms'])
+            self.request.monitor['acl_version'] = int(self.request.monitor['acl_version']) + 1
+
+        return new_forum, Message(_('New Forum has been created.'), 'success')
+
+    def __call__(self, request):
+        if self.admin.model.objects.get(token='root').get_descendants().count() == 0:
+            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)
+            return redirect(self.get_fallback_url())
+        return super(NewForum, self).__call__(request)
+
+
+class NewRedirect(FormWidget):
+    admin = site.get_action('forums')
+    id = 'new_redirect'
+    fallback = 'admin_forums'
+    form = RedirectForm
+    submit_button = _("Save Forum")
+
+    def get_new_url(self, model):
+        return reverse('admin_forums_new_redirect')
+
+    def get_edit_url(self, model):
+        return reverse('admin_forums_edit', model)
+
+    def submit_form(self, form, target):
+        new_forum = Forum(
+                          name=form.cleaned_data['name'],
+                          slug=slugify(form.cleaned_data['name']),
+                          redirect=form.cleaned_data['redirect'],
+                          style=form.cleaned_data['style'],
+                          type='redirect',
+                          )
+        new_forum.set_description(form.cleaned_data['description'])
+        new_forum.insert_at(form.cleaned_data['parent'], position='last-child', save=True)
+        Forum.objects.populate_tree(True)
+
+        if form.cleaned_data['perms']:
+            new_forum.copy_permissions(form.cleaned_data['perms'])
+            self.request.monitor['acl_version'] = int(self.request.monitor['acl_version']) + 1
+
+        return new_forum, Message(_('New Redirect has been created.'), 'success')
+
+    def __call__(self, request):
+        if self.admin.model.objects.get(token='root').get_descendants().count() == 0:
+            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)
+            return redirect(self.get_fallback_url())
+        return super(NewRedirect, self).__call__(request)
+
+
+class Up(ButtonWidget):
+    admin = site.get_action('forums')
+    id = 'up'
+    fallback = 'admin_forums'
+    notfound_message = _('Requested Forum could not be found.')
+
+    def action(self, target):
+        previous_sibling = target.get_previous_sibling()
+        if previous_sibling:
+            target.move_to(previous_sibling, 'left')
+            return Message(_('Forum "%(name)s" has been moved up.') % {'name': target.name}, 'success'), False
+        return Message(_('Forum "%(name)s" is first child of its parent node and cannot be moved up.') % {'name': target.name}, 'info'), False
+
+
+class Down(ButtonWidget):
+    admin = site.get_action('forums')
+    id = 'down'
+    fallback = 'admin_forums'
+    notfound_message = _('Requested Forum could not be found.')
+
+    def action(self, target):
+        next_sibling = target.get_next_sibling()
+        if next_sibling:
+            target.move_to(next_sibling, 'right')
+            return Message(_('Forum "%(name)s" has been moved down.') % {'name': target.name}, 'success'), False
+        return Message(_('Forum "%(name)s" is last child of its parent node and cannot be moved down.') % {'name': target.name}, 'info'), False
+
+
+class Edit(FormWidget):
+    admin = site.get_action('forums')
+    id = 'edit'
+    name = _("Edit Forum")
+    fallback = 'admin_forums'
+    form = ForumForm
+    target_name = 'name'
+    notfound_message = _('Requested Forum could not be found.')
+    submit_fallback = True
+
+    def get_url(self, model):
+        return reverse('admin_forums_edit', model)
+
+    def get_edit_url(self, model):
+        return self.get_url(model)
+
+    def get_form(self, target):
+        if target.type == 'category':
+            self.name = _("Edit Category")
+            self.form = CategoryForm
+        if target.type == 'redirect':
+            self.name = _("Edit Redirect")
+            self.form = RedirectForm
+        return self.form
+
+    def get_form_instance(self, form, target, initial, post=False):
+        form_inst = super(Edit, self).get_form_instance(form, target, initial, post)
+        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))
+        form_inst.fields['parent'] = TreeNodeChoiceField(queryset=valid_targets, level_indicator=u'- - ')
+        return form_inst
+
+    def get_initial_data(self, model):
+        initial = {
+                   'parent': model.parent,
+                   'name': model.name,
+                   'description': model.description,
+                   }
+
+        if model.type == 'redirect':
+            initial['redirect'] = model.redirect
+        else:
+            initial['attrs'] = model.attrs
+            initial['show_details'] = model.show_details
+            initial['style'] = model.style
+            initial['closed'] = model.closed
+
+        if model.type == 'forum':
+            initial['prune_start'] = model.prune_start
+            initial['prune_last'] = model.prune_last
+
+        return initial
+
+    def submit_form(self, form, target):
+        target.name = form.cleaned_data['name']
+        target.slug = slugify(form.cleaned_data['name'])
+        target.set_description(form.cleaned_data['description'])
+        if target.type == 'redirect':
+            target.redirect = form.cleaned_data['redirect']
+        else:
+            target.attrs = form.cleaned_data['attrs']
+            target.show_details = form.cleaned_data['show_details']
+            target.style = form.cleaned_data['style']
+            target.closed = form.cleaned_data['closed']
+
+        if target.type == 'forum':
+            target.prune_start = form.cleaned_data['prune_start']
+            target.prune_last = form.cleaned_data['prune_last']
+
+        if form.cleaned_data['parent'].pk != target.parent.pk:
+            target.move_to(form.cleaned_data['parent'], 'last-child')
+            self.request.monitor['acl_version'] = int(self.request.monitor['acl_version']) + 1
+
+        target.save(force_update=True)
+        Forum.objects.populate_tree(True)
+
+        if form.cleaned_data['perms']:
+            target.copy_permissions(form.cleaned_data['perms'])
+
+        if form.cleaned_data['parent'].pk != target.parent.pk or form.cleaned_data['perms']:
+            self.request.monitor['acl_version'] = int(self.request.monitor['acl_version']) + 1
+
+        return target, Message(_('Changes in forum "%(name)s" have been saved.') % {'name': self.original_name}, 'success')
+
+
+class Delete(FormWidget):
+    admin = site.get_action('forums')
+    id = 'delete'
+    name = _("Delete Forum")
+    fallback = 'admin_forums'
+    template = 'delete'
+    form = DeleteForm
+    target_name = 'name'
+    notfound_message = _('Requested Forum could not be found.')
+    submit_fallback = True
+
+    def get_url(self, model):
+        return reverse('admin_forums_delete', model)
+
+    def get_form(self, target):
+        if target.type == 'category':
+            self.name = _("Delete Category")
+        if target.type == 'redirect':
+            self.name = _("Delete Redirect")
+        return self.form
+
+    def get_form_instance(self, form, target, initial, post=False):
+        if post:
+            form_inst = form(self.request.POST, forum=target, request=self.request, initial=self.get_initial_data(target))
+        else:
+            form_inst = form(forum=target, request=self.request, initial=self.get_initial_data(target))
+        if target.type != 'forum':
+            del form_inst.fields['contents']
+        valid_targets = Forum.tree.get(token='root').get_descendants().exclude(Q(lft__gte=target.lft) & Q(rght__lte=target.rght))
+        form_inst.fields['subforums'] = TreeNodeChoiceField(queryset=valid_targets, required=False, empty_label=_("Remove with forum"), level_indicator=u'- - ')
+        return form_inst
+
+    def submit_form(self, form, target):
+        if target.type == 'forum':
+            new_forum = form.cleaned_data['contents']
+            if new_forum:
+                target.move_content(new_forum)
+                new_forum.sync()
+                new_forum.save(force_update=True)
+        new_parent = form.cleaned_data['subforums']
+        if new_parent:
+            for child in target.get_descendants():
+                if child.parent_id == target.pk:
+                    child.move_to(new_parent, 'last-child')
+                    child.save(force_update=True)
+        else:
+            for child in target.get_descendants().order_by('-lft'):
+                Forum.objects.get(id=child.pk).delete()
+        Forum.objects.get(id=target.pk).delete()
+        Forum.objects.populate_tree(True)
+        self.request.monitor['acl_version'] = int(self.request.monitor['acl_version']) + 1
+        return target, Message(_('Forum "%(name)s" has been deleted.') % {'name': self.original_name}, 'success')

+ 0 - 0
misago/core/admin/home.py → misago/apps/admin/home.py


+ 0 - 0
misago/core/admin/index.py → misago/apps/admin/index.py


+ 0 - 0
misago/core/admin/roles/__init__.py → misago/apps/admin/online/__init__.py


+ 0 - 0
misago/core/admin/online/forms.py → misago/apps/admin/online/forms.py


+ 2 - 2
misago/core/admin/online/views.py → misago/apps/admin/online/views.py

@@ -1,7 +1,7 @@
 from django.utils.translation import ugettext as _
 from django.utils.translation import ugettext as _
 from misago.admin import site
 from misago.admin import site
-from misago.core.admin.widgets import ListWidget
-from misago.core.admin.online.forms import SearchSessionsForm
+from misago.apps.admin.widgets import ListWidget
+from misago.apps.admin.online.forms import SearchSessionsForm
 
 
 class List(ListWidget):
 class List(ListWidget):
     admin = site.get_action('online')
     admin = site.get_action('online')

+ 0 - 0
misago/core/admin/settings/__init__.py → misago/apps/admin/roles/__init__.py


+ 0 - 0
misago/core/admin/roles/forms.py → misago/apps/admin/roles/forms.py


+ 2 - 2
misago/core/admin/roles/views.py → misago/apps/admin/roles/views.py

@@ -4,11 +4,11 @@ from django.shortcuts import redirect
 from django.utils.translation import ugettext as _
 from django.utils.translation import ugettext as _
 from misago.acl.builder import build_form 
 from misago.acl.builder import build_form 
 from misago.admin import site
 from misago.admin import site
-from misago.core.admin.widgets import *
+from misago.apps.admin.widgets import *
 from misago.forms import Form, YesNoSwitch
 from misago.forms import Form, YesNoSwitch
 from misago.models import Forum, ForumRole, Role
 from misago.models import Forum, ForumRole, Role
 from misago.utils.strings import slugify
 from misago.utils.strings import slugify
-from misago.core.admin.roles.forms import RoleForm
+from misago.apps.admin.roles.forms import RoleForm
 
 
 def reverse(route, target=None):
 def reverse(route, target=None):
     if target:
     if target:

+ 10 - 13
misago/core/admin/sections/__init__.py → misago/apps/admin/sections/__init__.py

@@ -8,6 +8,16 @@ ADMIN_SECTIONS = (
                  icon='signal',
                  icon='signal',
                  ),
                  ),
     AdminSection(
     AdminSection(
+                 id='users',
+                 name=_("Users"),
+                 icon='user',
+                 ),
+    AdminSection(
+                 id='forums',
+                 name=_("Forums"),
+                 icon='comment',
+                 ),
+    AdminSection(
                  id='perms',
                  id='perms',
                  name=_("Permissions"),
                  name=_("Permissions"),
                  icon='adjust',
                  icon='adjust',
@@ -18,16 +28,3 @@ ADMIN_SECTIONS = (
                  icon='cog',
                  icon='cog',
                  ),
                  ),
 )
 )
-
-"""
-    AdminSection(
-                 id='users',
-                 name=_("Users"),
-                 icon='user',
-                 ),
-    AdminSection(
-                 id='forums',
-                 name=_("Forums"),
-                 icon='comment',
-                 ),
-"""

+ 5 - 5
misago/core/admin/sections/forums.py → misago/apps/admin/sections/forums.py

@@ -38,7 +38,7 @@ ADMIN_ACTIONS = (
                          },
                          },
                         ],
                         ],
                route='admin_forums',
                route='admin_forums',
-               urlpatterns=patterns('misago.forums.views',
+               urlpatterns=patterns('misago.apps.admin.forums.views',
                         url(r'^$', 'List', name='admin_forums'),
                         url(r'^$', 'List', name='admin_forums'),
                         url(r'^new/category/$', 'NewCategory', name='admin_forums_new_category'),
                         url(r'^new/category/$', 'NewCategory', name='admin_forums_new_category'),
                         url(r'^new/forum/$', 'NewForum', name='admin_forums_new_forum'),
                         url(r'^new/forum/$', 'NewForum', name='admin_forums_new_forum'),
@@ -56,7 +56,7 @@ ADMIN_ACTIONS = (
                help=_("Thread Labels allow you to group threads together within forums."),
                help=_("Thread Labels allow you to group threads together within forums."),
                icon='tags',
                icon='tags',
                route='admin_forums_labels',
                route='admin_forums_labels',
-               urlpatterns=patterns('misago.admin.views',
+               urlpatterns=patterns('misago.apps.admin.index',
                         url(r'^$', 'todo', name='admin_forums_labels'),
                         url(r'^$', 'todo', name='admin_forums_labels'),
                     ),
                     ),
                ),
                ),
@@ -67,7 +67,7 @@ ADMIN_ACTIONS = (
                help=_("Forbid usage of words in messages"),
                help=_("Forbid usage of words in messages"),
                icon='volume-off',
                icon='volume-off',
                route='admin_forums_badwords',
                route='admin_forums_badwords',
-               urlpatterns=patterns('misago.admin.views',
+               urlpatterns=patterns('misago.apps.admin.index',
                         url(r'^$', 'todo', name='admin_forums_badwords'),
                         url(r'^$', 'todo', name='admin_forums_badwords'),
                     ),
                     ),
                ),
                ),
@@ -78,7 +78,7 @@ ADMIN_ACTIONS = (
                help=_("Tests that new messages have to pass"),
                help=_("Tests that new messages have to pass"),
                icon='filter',
                icon='filter',
                route='admin_forums_tests',
                route='admin_forums_tests',
-               urlpatterns=patterns('misago.admin.views',
+               urlpatterns=patterns('misago.apps.admin.index',
                         url(r'^$', 'todo', name='admin_forums_tests'),
                         url(r'^$', 'todo', name='admin_forums_tests'),
                     ),
                     ),
                ),
                ),
@@ -89,7 +89,7 @@ ADMIN_ACTIONS = (
                help=_("Manage allowed attachment types."),
                help=_("Manage allowed attachment types."),
                icon='download-alt',
                icon='download-alt',
                route='admin_forums_attachments',
                route='admin_forums_attachments',
-               urlpatterns=patterns('misago.admin.views',
+               urlpatterns=patterns('misago.apps.admin.index',
                         url(r'^$', 'todo', name='admin_forums_attachments'),
                         url(r'^$', 'todo', name='admin_forums_attachments'),
                     ),
                     ),
                ),
                ),

+ 4 - 4
misago/core/admin/sections/overview.py → misago/apps/admin/sections/overview.py

@@ -11,7 +11,7 @@ ADMIN_ACTIONS = (
                help=_("Your forums right now"),
                help=_("Your forums right now"),
                icon='home',
                icon='home',
                route='admin_home',
                route='admin_home',
-               urlpatterns=patterns('misago.core.admin.index',
+               urlpatterns=patterns('misago.apps.admin.index',
                         url(r'^$', 'index', name='admin_home'),
                         url(r'^$', 'index', name='admin_home'),
                     ),
                     ),
                ),
                ),
@@ -22,7 +22,7 @@ ADMIN_ACTIONS = (
                help=_("Create Statistics Reports"),
                help=_("Create Statistics Reports"),
                icon='signal',
                icon='signal',
                route='admin_stats',
                route='admin_stats',
-               urlpatterns=patterns('misago.core.admin.stats.views',
+               urlpatterns=patterns('misago.apps.admin.stats.views',
                         url(r'^$', 'form', name='admin_stats'),
                         url(r'^$', 'form', name='admin_stats'),
                         url(r'^(?P<model>[a-z0-9]+)/(?P<date_start>[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9])/(?P<date_end>[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9])/(?P<precision>\w+)$', 'graph', name='admin_stats_graph'),
                         url(r'^(?P<model>[a-z0-9]+)/(?P<date_start>[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9])/(?P<date_end>[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9])/(?P<precision>\w+)$', 'graph', name='admin_stats_graph'),
                     ),
                     ),
@@ -43,7 +43,7 @@ ADMIN_ACTIONS = (
                          },
                          },
                         ],
                         ],
                route='admin_online',
                route='admin_online',
-               urlpatterns=patterns('misago.core.admin.online.views',
+               urlpatterns=patterns('misago.apps.admin.online.views',
                         url(r'^$', 'List', name='admin_online'),
                         url(r'^$', 'List', name='admin_online'),
                         url(r'^(?P<page>\d+)/$', 'List', name='admin_online'),
                         url(r'^(?P<page>\d+)/$', 'List', name='admin_online'),
                     ),
                     ),
@@ -64,7 +64,7 @@ ADMIN_ACTIONS = (
                          },
                          },
                         ],
                         ],
                route='admin_team',
                route='admin_team',
-               urlpatterns=patterns('misago.core.admin.team',
+               urlpatterns=patterns('misago.apps.admin.team',
                         url(r'^$', 'List', name='admin_team'),
                         url(r'^$', 'List', name='admin_team'),
                     ),
                     ),
                ),
                ),

+ 2 - 2
misago/core/admin/sections/perms.py → misago/apps/admin/sections/perms.py

@@ -26,7 +26,7 @@ ADMIN_ACTIONS = (
                          },
                          },
                         ],
                         ],
                route='admin_roles',
                route='admin_roles',
-               urlpatterns=patterns('misago.core.admin.roles.views',
+               urlpatterns=patterns('misago.apps.admin.roles.views',
                         url(r'^$', 'List', name='admin_roles'),
                         url(r'^$', 'List', name='admin_roles'),
                         url(r'^new/$', 'New', name='admin_roles_new'),
                         url(r'^new/$', 'New', name='admin_roles_new'),
                         url(r'^forums/(?P<slug>([a-z0-9]|-)+)-(?P<target>\d+)/$', 'Forums', name='admin_roles_masks'),
                         url(r'^forums/(?P<slug>([a-z0-9]|-)+)-(?P<target>\d+)/$', 'Forums', name='admin_roles_masks'),
@@ -57,7 +57,7 @@ ADMIN_ACTIONS = (
                          },
                          },
                         ],
                         ],
                route='admin_roles_forums',
                route='admin_roles_forums',
-               urlpatterns=patterns('misago.core.admin.forumroles.views',
+               urlpatterns=patterns('misago.apps.admin.forumroles.views',
                         url(r'^$', 'List', name='admin_roles_forums'),
                         url(r'^$', 'List', name='admin_roles_forums'),
                         url(r'^new/$', 'New', name='admin_roles_forums_new'),
                         url(r'^new/$', 'New', name='admin_roles_forums_new'),
                         url(r'^acl/(?P<slug>([a-z0-9]|-)+)-(?P<target>\d+)/$', 'ACL', name='admin_roles_forums_acl'),
                         url(r'^acl/(?P<slug>([a-z0-9]|-)+)-(?P<target>\d+)/$', 'ACL', name='admin_roles_forums_acl'),

+ 2 - 2
misago/core/admin/sections/system.py → misago/apps/admin/sections/system.py

@@ -11,7 +11,7 @@ ADMIN_ACTIONS = (
                help=_("Change your forum configuration"),
                help=_("Change your forum configuration"),
                icon='wrench',
                icon='wrench',
                route='admin_settings',
                route='admin_settings',
-               urlpatterns=patterns('misago.core.admin.settings.views',
+               urlpatterns=patterns('misago.apps.admin.settings.views',
                         url(r'^$', 'settings', name='admin_settings'),
                         url(r'^$', 'settings', name='admin_settings'),
                         url(r'^search/$', 'settings_search', name='admin_settings_search'),
                         url(r'^search/$', 'settings_search', name='admin_settings_search'),
                         url(r'^(?P<group_slug>([a-z0-9]|-)+)-(?P<group_id>\d+)/$', 'settings', name='admin_settings')
                         url(r'^(?P<group_slug>([a-z0-9]|-)+)-(?P<group_id>\d+)/$', 'settings', name='admin_settings')
@@ -39,7 +39,7 @@ ADMIN_ACTIONS = (
                          },
                          },
                         ],
                         ],
                route='admin_clients',
                route='admin_clients',
-               urlpatterns=patterns('misago.core.admin.clients.views',
+               urlpatterns=patterns('misago.apps.admin.clients.views',
                         url(r'^$', 'List', name='admin_clients'),
                         url(r'^$', 'List', name='admin_clients'),
                         url(r'^new/$', 'New', name='admin_clients_new'),
                         url(r'^new/$', 'New', name='admin_clients_new'),
                         url(r'^edit/(?P<slug>([a-z0-9]|-)+)-(?P<target>\d+)/$', 'Edit', name='admin_clients_edit'),
                         url(r'^edit/(?P<slug>([a-z0-9]|-)+)-(?P<target>\d+)/$', 'Edit', name='admin_clients_edit'),

+ 5 - 5
misago/core/admin/sections/users.py → misago/apps/admin/sections/users.py

@@ -26,7 +26,7 @@ ADMIN_ACTIONS = (
                          },
                          },
                         ],
                         ],
                route='admin_users',
                route='admin_users',
-               urlpatterns=patterns('misago.users.views',
+               urlpatterns=patterns('misago.apps.admin.users.views',
                         url(r'^$', 'List', name='admin_users'),
                         url(r'^$', 'List', name='admin_users'),
                         url(r'^(?P<page>\d+)/$', 'List', name='admin_users'),
                         url(r'^(?P<page>\d+)/$', 'List', name='admin_users'),
                         url(r'^inactive/$', 'inactive', name='admin_users_inactive'),
                         url(r'^inactive/$', 'inactive', name='admin_users_inactive'),
@@ -57,7 +57,7 @@ ADMIN_ACTIONS = (
                          },
                          },
                         ],
                         ],
                route='admin_ranks',
                route='admin_ranks',
-               urlpatterns=patterns('misago.ranks.views',
+               urlpatterns=patterns('misago.apps.admin.ranks.views',
                         url(r'^$', 'List', name='admin_ranks'),
                         url(r'^$', 'List', name='admin_ranks'),
                         url(r'^new/$', 'New', name='admin_ranks_new'),
                         url(r'^new/$', 'New', name='admin_ranks_new'),
                         url(r'^edit/(?P<slug>([a-z0-9]|-)+)-(?P<target>\d+)/$', 'Edit', name='admin_ranks_edit'),
                         url(r'^edit/(?P<slug>([a-z0-9]|-)+)-(?P<target>\d+)/$', 'Edit', name='admin_ranks_edit'),
@@ -86,7 +86,7 @@ ADMIN_ACTIONS = (
                          },
                          },
                         ],
                         ],
                route='admin_bans',
                route='admin_bans',
-               urlpatterns=patterns('misago.banning.views',
+               urlpatterns=patterns('misago.apps.admin.banning.views',
                         url(r'^$', 'List', name='admin_bans'),
                         url(r'^$', 'List', name='admin_bans'),
                         url(r'^(?P<page>\d+)/$', 'List', name='admin_bans'),
                         url(r'^(?P<page>\d+)/$', 'List', name='admin_bans'),
                         url(r'^new/$', 'New', name='admin_bans_new'),
                         url(r'^new/$', 'New', name='admin_bans_new'),
@@ -116,7 +116,7 @@ ADMIN_ACTIONS = (
                          },
                          },
                         ],
                         ],
                route='admin_prune_users',
                route='admin_prune_users',
-               urlpatterns=patterns('misago.prune.views',
+               urlpatterns=patterns('misago.apps.admin.prune.views',
                         url(r'^$', 'List', name='admin_prune_users'),
                         url(r'^$', 'List', name='admin_prune_users'),
                         url(r'^new/$', 'New', name='admin_prune_users_new'),
                         url(r'^new/$', 'New', name='admin_prune_users_new'),
                         url(r'^edit/(?P<target>\d+)/$', 'Edit', name='admin_prune_users_edit'),
                         url(r'^edit/(?P<target>\d+)/$', 'Edit', name='admin_prune_users_edit'),
@@ -146,7 +146,7 @@ ADMIN_ACTIONS = (
                          },
                          },
                         ],
                         ],
                route='admin_newsletters',
                route='admin_newsletters',
-               urlpatterns=patterns('misago.newsletters.views',
+               urlpatterns=patterns('misago.apps.admin.newsletters.views',
                         url(r'^$', 'List', name='admin_newsletters'),
                         url(r'^$', 'List', name='admin_newsletters'),
                         url(r'^(?P<page>\d+)/$', 'List', name='admin_newsletters'),
                         url(r'^(?P<page>\d+)/$', 'List', name='admin_newsletters'),
                         url(r'^new/$', 'New', name='admin_newsletters_new'),
                         url(r'^new/$', 'New', name='admin_newsletters_new'),

+ 0 - 0
misago/core/admin/stats/__init__.py → misago/apps/admin/settings/__init__.py


+ 0 - 0
misago/core/admin/settings/forms.py → misago/apps/admin/settings/forms.py


+ 2 - 2
misago/core/admin/settings/views.py → misago/apps/admin/settings/views.py

@@ -6,8 +6,8 @@ from misago.forms import Form, FormLayout, FormFields
 from misago.messages import Message
 from misago.messages import Message
 from misago.search import SearchQuery, SearchException
 from misago.search import SearchQuery, SearchException
 from misago.models import SettingsGroup, Setting
 from misago.models import SettingsGroup, Setting
-from misago.core.views import error404
-from misago.core.admin.settings.forms import SearchForm
+from misago.apps.views import error404
+from misago.apps.admin.settings.forms import SearchForm
 
 
 def settings(request, group_id=None, group_slug=None):
 def settings(request, group_id=None, group_slug=None):
     # Load groups and find selected group
     # Load groups and find selected group

+ 0 - 0
misago/core/front/__init__.py → misago/apps/admin/stats/__init__.py


+ 0 - 0
misago/core/admin/stats/forms.py → misago/apps/admin/stats/forms.py


+ 2 - 2
misago/core/admin/stats/views.py → misago/apps/admin/stats/views.py

@@ -8,8 +8,8 @@ from django.utils import timezone
 from django.utils.translation import ugettext as _
 from django.utils.translation import ugettext as _
 from misago.forms import FormLayout
 from misago.forms import FormLayout
 from misago.messages import Message
 from misago.messages import Message
-from misago.core.admin.stats.forms import GenerateStatisticsForm
-from misago.core.views import error404
+from misago.apps.admin.stats.forms import GenerateStatisticsForm
+from misago.apps.views import error404
 
 
 def form(request):
 def form(request):
     """
     """

+ 1 - 1
misago/core/admin/team.py → misago/apps/admin/team.py

@@ -1,6 +1,6 @@
 from django.utils.translation import ugettext as _
 from django.utils.translation import ugettext as _
 from misago.admin import site
 from misago.admin import site
-from misago.core.admin.widgets import ListWidget
+from misago.apps.admin.widgets import ListWidget
 
 
 class List(ListWidget):
 class List(ListWidget):
     admin = site.get_action('team')
     admin = site.get_action('team')

+ 0 - 0
misago/core/admin/widgets.py → misago/apps/admin/widgets.py


+ 0 - 0
misago/core/signin/__init__.py → misago/apps/front/__init__.py


+ 0 - 0
misago/core/front/index.py → misago/apps/front/index.py


+ 0 - 0
misago/core/front/readall.py → misago/apps/front/readall.py


+ 0 - 0
misago/apps/signin/__init__.py


+ 0 - 0
misago/core/signin/forms.py → misago/apps/signin/forms.py


+ 2 - 2
misago/core/signin/urls.py → misago/apps/signin/urls.py

@@ -1,13 +1,13 @@
 from django.conf.urls import patterns, url
 from django.conf.urls import patterns, url
 from misago.admin import ADMIN_PATH
 from misago.admin import ADMIN_PATH
 
 
-urlpatterns = patterns('misago.core.signin.views',
+urlpatterns = patterns('misago.apps.signin.views',
     url(r'^signin/$', 'signin', name="sign_in"),
     url(r'^signin/$', 'signin', name="sign_in"),
     url(r'^signout/$', 'signout', name="sign_out"),
     url(r'^signout/$', 'signout', name="sign_out"),
 )
 )
 
 
 # Include admin patterns
 # Include admin patterns
 if ADMIN_PATH:
 if ADMIN_PATH:
-    urlpatterns += patterns('misago.core.signin.views',
+    urlpatterns += patterns('misago.apps.signin.views',
         url(r'^' + ADMIN_PATH + 'signout/$', 'signout', name="admin_sign_out"),
         url(r'^' + ADMIN_PATH + 'signout/$', 'signout', name="admin_sign_out"),
     )
     )

+ 1 - 1
misago/core/signin/views.py → misago/apps/signin/views.py

@@ -11,7 +11,7 @@ from misago.auth import AuthException, auth_admin, auth_forum, sign_user_in
 from misago.decorators import (block_authenticated, block_banned, block_crawlers,
 from misago.decorators import (block_authenticated, block_banned, block_crawlers,
                             block_guest, block_jammed, check_csrf)
                             block_guest, block_jammed, check_csrf)
 from misago.models import SignInAttempt, Token
 from misago.models import SignInAttempt, Token
-from misago.core.signin.forms import SignInForm
+from misago.apps.signin.forms import SignInForm
 from misago.utils.strings import random_string
 from misago.utils.strings import random_string
 
 
 @block_crawlers
 @block_crawlers

+ 0 - 0
misago/core/views.py → misago/apps/views.py


+ 1 - 1
misago/decorators.py

@@ -1,6 +1,6 @@
 from django.utils.translation import ugettext as _
 from django.utils.translation import ugettext as _
 from misago.acl.exceptions import ACLError403, ACLError404
 from misago.acl.exceptions import ACLError403, ACLError404
-from misago.core.views import error403, error404, error_banned
+from misago.apps.views import error403, error404, error_banned
 
 
 def acl_errors(f):
 def acl_errors(f):
     def decorator(*args, **kwargs):
     def decorator(*args, **kwargs):

+ 2 - 2
misago/firewalls.py

@@ -2,8 +2,8 @@ from django.conf import settings
 from django.utils.translation import ugettext_lazy as _
 from django.utils.translation import ugettext_lazy as _
 from misago.admin import ADMIN_PATH
 from misago.admin import ADMIN_PATH
 from misago.messages import Message
 from misago.messages import Message
-from misago.core.views import error403, error404
-from misago.core.signin.views import signin
+from misago.apps.views import error403, error404
+from misago.apps.signin.views import signin
 
 
 class FirewallForum(object):
 class FirewallForum(object):
     admin = False
     admin = False

+ 1 - 1
misago/models/forummodel.py

@@ -169,7 +169,7 @@ class Forum(MPTTModel):
                 perms = role.permissions
                 perms = role.permissions
                 try:
                 try:
                     perms['forums'][self.pk] = perms['forums'][target.pk]
                     perms['forums'][self.pk] = perms['forums'][target.pk]
-                    role.set_permissions(perms)
+                    role.permissions = perms
                     role.save(force_update=True)
                     role.save(force_update=True)
                 except KeyError:
                 except KeyError:
                     pass
                     pass

+ 10 - 10
misago/settings_base.py

@@ -116,20 +116,20 @@ PERMISSION_PROVIDERS = (
 
 
 # List of UserCP extensions
 # List of UserCP extensions
 USERCP_EXTENSIONS = (
 USERCP_EXTENSIONS = (
-    'misago.core.front.usercp.options',
-    'misago.core.front.usercp.avatar',
-    'misago.core.front.usercp.signature',
-    'misago.core.front.usercp.credentials',
-    'misago.core.front.usercp.username',
+    'misago.apps.front.usercp.options',
+    'misago.apps.front.usercp.avatar',
+    'misago.apps.front.usercp.signature',
+    'misago.apps.front.usercp.credentials',
+    'misago.apps.front.usercp.username',
 )
 )
 
 
 # List of User Profile extensions
 # List of User Profile extensions
 PROFILE_EXTENSIONS = (
 PROFILE_EXTENSIONS = (
-    'misago.core.front.profiles.posts',
-    'misago.core.front.profiles.threads',
-    'misago.core.front.profiles.follows',
-    'misago.core.front.profiles.followers',
-    'misago.core.front.profiles.details',
+    'misago.apps.front.profiles.posts',
+    'misago.apps.front.profiles.threads',
+    'misago.apps.front.profiles.follows',
+    'misago.apps.front.profiles.followers',
+    'misago.apps.front.profiles.details',
 )
 )
 
 
 # List of Markdown Extensions
 # List of Markdown Extensions

+ 5 - 5
misago/urls.py

@@ -4,16 +4,16 @@ from django.contrib.staticfiles.urls import staticfiles_urlpatterns
 from misago.admin import ADMIN_PATH, site
 from misago.admin import ADMIN_PATH, site
 
 
 # Include frontend patterns
 # Include frontend patterns
-urlpatterns = patterns('misago.core.front',
+urlpatterns = patterns('misago.apps.front',
     url(r'^$', 'index.index', name="index"),
     url(r'^$', 'index.index', name="index"),
     url(r'^read-all/$', 'readall.read_all', name="read_all"),
     url(r'^read-all/$', 'readall.read_all', name="read_all"),
 )
 )
 
 
 # Include shared Sign-In action
 # Include shared Sign-In action
 urlpatterns += patterns('',
 urlpatterns += patterns('',
-    (r'^', include('misago.core.signin.urls')),
+    (r'^', include('misago.apps.signin.urls')),
     # Remove after ACP was refactored
     # Remove after ACP was refactored
-    url(r'^users/(?P<username>\w+)-(?P<user>\d+)/$', 'misago.core.admin.adminindex.todo', name="user"),    
+    url(r'^users/(?P<username>\w+)-(?P<user>\d+)/$', 'misago.apps.admin.adminindex.todo', name="user"),    
 )
 )
 
 
 """
 """
@@ -49,5 +49,5 @@ if settings.DEBUG:
     )
     )
 
 
 # Set error handlers
 # Set error handlers
-handler403 = 'misago.core.views.error403'
-handler404 = 'misago.core.views.error404'
+handler403 = 'misago.apps.views.error403'
+handler404 = 'misago.apps.views.error404'