Browse Source

Fixed some crashes in frontend

Rafał Pitoń 12 years ago
parent
commit
3f9b5b2986

+ 58 - 59
misago/apps/privatethreads/thread.py

@@ -1,60 +1,59 @@
-from django.utils.translation import ugettext as _
-from misago.apps.threadtype.thread import ThreadBaseView, ThreadModeration, PostsModeration
-from misago.forms import FormFields
-from misago.models import Forum, Thread
-from misago.apps.privatethreads.mixins import TypeMixin
-from misago.apps.privatethreads.forms import InviteMemberForm
-
-class ThreadView(ThreadBaseView, ThreadModeration, PostsModeration, TypeMixin):
-    def posts_actions(self):
-        acl = self.request.acl.threads.get_role(self.thread.forum_id)
-        actions = []
-        try:
-            if acl['can_move_threads_posts']:
-                actions.append(('merge', _('Merge posts into one')))
-            if acl['can_protect_posts']:
-                actions.append(('protect', _('Protect posts')))
-                actions.append(('unprotect', _('Remove posts protection')))
-            if acl['can_delete_posts']:
-                if self.thread.replies_deleted > 0:
-                    actions.append(('undelete', _('Restore posts')))
-                actions.append(('soft', _('Hide posts')))
-            if acl['can_delete_posts'] == 2:
-                actions.append(('hard', _('Delete posts')))
-        except KeyError:
-            pass
-        return actions
-
-    def thread_actions(self):
-        acl = self.request.acl.threads.get_role(self.thread.forum_id)
-        actions = []
-        try:
-            if acl['can_close_threads']:
-                if self.thread.closed:
-                    actions.append(('open', _('Open this thread')))
-                else:
-                    actions.append(('close', _('Close this thread')))
-            if acl['can_delete_threads']:
-                if self.thread.deleted:
-                    actions.append(('undelete', _('Restore this thread')))
-                else:
-                    actions.append(('soft', _('Hide this thread')))
-            if acl['can_delete_threads'] == 2:
-                actions.append(('hard', _('Delete this thread')))
-        except KeyError:
-            pass
-        return actions
-
-    def template_vars(self, context):
-        context['participants'] = self.thread.participants.all().order_by('username_slug').prefetch_related('rank')
-        context['invite_form'] = FormFields(InviteMemberForm(request=self.request))
-        return context
-
-    def tracker_queryset(self):
-        return self.forum.thread_set.filter(participants__id=self.request.user.pk)
-
-    def tracker_update(self, last_post):
-        super(ThreadView, self).tracker_update(last_post)
-        unread = self.tracker.unread_count(self.forum.thread_set.filter(participants__id=self.request.user.pk))
-        self.request.user.sync_unread_pds(unread)
+from django.utils.translation import ugettext as _
+from misago.apps.threadtype.thread import ThreadBaseView, ThreadModeration, PostsModeration
+from misago.models import Forum, Thread
+from misago.apps.privatethreads.mixins import TypeMixin
+from misago.apps.privatethreads.forms import InviteMemberForm
+
+class ThreadView(ThreadBaseView, ThreadModeration, PostsModeration, TypeMixin):
+    def posts_actions(self):
+        acl = self.request.acl.threads.get_role(self.thread.forum_id)
+        actions = []
+        try:
+            if acl['can_move_threads_posts']:
+                actions.append(('merge', _('Merge posts into one')))
+            if acl['can_protect_posts']:
+                actions.append(('protect', _('Protect posts')))
+                actions.append(('unprotect', _('Remove posts protection')))
+            if acl['can_delete_posts']:
+                if self.thread.replies_deleted > 0:
+                    actions.append(('undelete', _('Restore posts')))
+                actions.append(('soft', _('Hide posts')))
+            if acl['can_delete_posts'] == 2:
+                actions.append(('hard', _('Delete posts')))
+        except KeyError:
+            pass
+        return actions
+
+    def thread_actions(self):
+        acl = self.request.acl.threads.get_role(self.thread.forum_id)
+        actions = []
+        try:
+            if acl['can_close_threads']:
+                if self.thread.closed:
+                    actions.append(('open', _('Open this thread')))
+                else:
+                    actions.append(('close', _('Close this thread')))
+            if acl['can_delete_threads']:
+                if self.thread.deleted:
+                    actions.append(('undelete', _('Restore this thread')))
+                else:
+                    actions.append(('soft', _('Hide this thread')))
+            if acl['can_delete_threads'] == 2:
+                actions.append(('hard', _('Delete this thread')))
+        except KeyError:
+            pass
+        return actions
+
+    def template_vars(self, context):
+        context['participants'] = self.thread.participants.all().order_by('username_slug').prefetch_related('rank')
+        context['invite_form'] = InviteMemberForm(request=self.request)
+        return context
+
+    def tracker_queryset(self):
+        return self.forum.thread_set.filter(participants__id=self.request.user.pk)
+
+    def tracker_update(self, last_post):
+        super(ThreadView, self).tracker_update(last_post)
+        unread = self.tracker.unread_count(self.forum.thread_set.filter(participants__id=self.request.user.pk))
+        self.request.user.sync_unread_pds(unread)
         self.request.user.save(force_update=True)
         self.request.user.save(force_update=True)

+ 103 - 104
misago/apps/profiles/views.py

@@ -1,105 +1,104 @@
-from django.core.urlresolvers import reverse
-from django.http import Http404
-from django.shortcuts import redirect
-from django.template import RequestContext
-from misago.apps.errors import error403, error404
-from misago.conf import settings
-from misago.forms import FormFields
-from misago.messages import Message
-from misago.models import Rank, User
-from misago.shortcuts import render_to_response
-from misago.utils.strings import slugify
-from misago.utils.pagination import make_pagination
-from misago.apps.profiles.forms import QuickFindUserForm
-
-def list(request, slug=None, page=0):
-    ranks = Rank.objects.filter(as_tab=1).order_by('order')
-
-    # Find active rank
-    default_rank = False
-    active_rank = None
-    if slug:
-        for rank in ranks:
-            if rank.slug == slug:
-                active_rank = rank
-        if not active_rank:
-            return error404(request)
-        if ranks and active_rank.slug == ranks[0].slug:
-            return redirect(reverse('users'))
-    elif ranks:
-        default_rank = True
-        active_rank = ranks[0]
-
-    # Empty Defaults
-    message = None
-    users = []
-    items_total = 0
-    pagination = None
-    in_search = False
-
-    # Users search?
-    if request.method == 'POST':
-        if not request.acl.users.can_search_users():
-            return error403(request)
-        in_search = True
-        active_rank = None
-        search_form = QuickFindUserForm(request.POST, request=request)
-        if search_form.is_valid():
-            # Direct hit?
-            username = search_form.cleaned_data['username']
-            try:
-                user = User.objects
-                if settings.PROFILE_EXTENSIONS_PRELOAD:
-                    user = user.select_related(*settings.PROFILE_EXTENSIONS_PRELOAD)
-                user = user.get(username__iexact=username)
-                return redirect(reverse('user', args=(user.username_slug, user.pk)))
-            except User.DoesNotExist:
-                pass
-
-            # Looks like well have to find near match
-            if len(username) > 6:
-                username = username[0:-3]
-            elif len(username) > 5:
-                username = username[0:-2]
-            elif len(username) > 4:
-                username = username[0:-1]
-            username = slugify(username.strip())
-
-            # Go for rought match
-            if len(username) > 0:
-                users = User.objects
-                if settings.PROFILE_EXTENSIONS_PRELOAD:
-                    users = users.select_related(*settings.PROFILE_EXTENSIONS_PRELOAD)
-                users = users.filter(username_slug__startswith=username).order_by('username_slug')[:10]
-        elif search_form.non_field_errors()[0] == 'form_contains_errors':
-            message = Message(_("To search users you have to enter username in search field."), 'error')
-        else:
-            message = Message(search_form.non_field_errors()[0], 'error')
-    else:
-        search_form = QuickFindUserForm(request=request)
-        if active_rank:
-            users = User.objects.filter(rank=active_rank)
-            items_total = users.count()
-            try:
-                pagination = make_pagination(page, items_total, settings.profiles_per_list)
-            except Http404:
-                if not default_rank and active_rank:
-                    return redirect(reverse('users', kwargs={'slug': active_rank.slug}))
-                return redirect(reverse('users'))
-            if settings.PROFILE_EXTENSIONS_PRELOAD:
-                users = users.select_related(*settings.PROFILE_EXTENSIONS_PRELOAD)
-            users = users.order_by('username_slug')[pagination['start']:pagination['stop']]
-
-    return render_to_response('profiles/list.html',
-                              {
-                              'message': message,
-                              'search_form': FormFields(search_form).fields,
-                              'in_search': in_search,
-                              'active_rank': active_rank,
-                              'default_rank': default_rank,
-                              'items_total': items_total,
-                              'ranks': ranks,
-                              'users': users,
-                              'pagination': pagination,
-                              },
+from django.core.urlresolvers import reverse
+from django.http import Http404
+from django.shortcuts import redirect
+from django.template import RequestContext
+from misago.apps.errors import error403, error404
+from misago.conf import settings
+from misago.messages import Message
+from misago.models import Rank, User
+from misago.shortcuts import render_to_response
+from misago.utils.strings import slugify
+from misago.utils.pagination import make_pagination
+from misago.apps.profiles.forms import QuickFindUserForm
+
+def list(request, slug=None, page=0):
+    ranks = Rank.objects.filter(as_tab=1).order_by('order')
+
+    # Find active rank
+    default_rank = False
+    active_rank = None
+    if slug:
+        for rank in ranks:
+            if rank.slug == slug:
+                active_rank = rank
+        if not active_rank:
+            return error404(request)
+        if ranks and active_rank.slug == ranks[0].slug:
+            return redirect(reverse('users'))
+    elif ranks:
+        default_rank = True
+        active_rank = ranks[0]
+
+    # Empty Defaults
+    message = None
+    users = []
+    items_total = 0
+    pagination = None
+    in_search = False
+
+    # Users search?
+    if request.method == 'POST':
+        if not request.acl.users.can_search_users():
+            return error403(request)
+        in_search = True
+        active_rank = None
+        search_form = QuickFindUserForm(request.POST, request=request)
+        if search_form.is_valid():
+            # Direct hit?
+            username = search_form.cleaned_data['username']
+            try:
+                user = User.objects
+                if settings.PROFILE_EXTENSIONS_PRELOAD:
+                    user = user.select_related(*settings.PROFILE_EXTENSIONS_PRELOAD)
+                user = user.get(username__iexact=username)
+                return redirect(reverse('user', args=(user.username_slug, user.pk)))
+            except User.DoesNotExist:
+                pass
+
+            # Looks like well have to find near match
+            if len(username) > 6:
+                username = username[0:-3]
+            elif len(username) > 5:
+                username = username[0:-2]
+            elif len(username) > 4:
+                username = username[0:-1]
+            username = slugify(username.strip())
+
+            # Go for rought match
+            if len(username) > 0:
+                users = User.objects
+                if settings.PROFILE_EXTENSIONS_PRELOAD:
+                    users = users.select_related(*settings.PROFILE_EXTENSIONS_PRELOAD)
+                users = users.filter(username_slug__startswith=username).order_by('username_slug')[:10]
+        elif search_form.non_field_errors()[0] == 'form_contains_errors':
+            message = Message(_("To search users you have to enter username in search field."), 'error')
+        else:
+            message = Message(search_form.non_field_errors()[0], 'error')
+    else:
+        search_form = QuickFindUserForm(request=request)
+        if active_rank:
+            users = User.objects.filter(rank=active_rank)
+            items_total = users.count()
+            try:
+                pagination = make_pagination(page, items_total, settings.profiles_per_list)
+            except Http404:
+                if not default_rank and active_rank:
+                    return redirect(reverse('users', kwargs={'slug': active_rank.slug}))
+                return redirect(reverse('users'))
+            if settings.PROFILE_EXTENSIONS_PRELOAD:
+                users = users.select_related(*settings.PROFILE_EXTENSIONS_PRELOAD)
+            users = users.order_by('username_slug')[pagination['start']:pagination['stop']]
+
+    return render_to_response('profiles/list.html',
+                              {
+                              'message': message,
+                              'search_form': search_form,
+                              'in_search': in_search,
+                              'active_rank': active_rank,
+                              'default_rank': default_rank,
+                              'items_total': items_total,
+                              'ranks': ranks,
+                              'users': users,
+                              'pagination': pagination,
+                              },
                               context_instance=RequestContext(request));
                               context_instance=RequestContext(request));

+ 191 - 192
misago/apps/search/views.py

@@ -1,193 +1,192 @@
-from django.core.urlresolvers import reverse
-from django.http import Http404
-from django.shortcuts import redirect
-from django.template import RequestContext
-from django.utils import timezone
-from django.utils.translation import ugettext as _
-from haystack.inputs import AutoQuery
-from haystack.query import SearchQuerySet, RelatedSearchQuerySet
-from misago.acl.exceptions import ACLError403, ACLError404
-from misago.conf import settings
-from misago.decorators import block_crawlers
-from misago.forms import FormFields
-from misago.models import Forum, Thread, Post, User
-from misago.search import SearchException
-from misago.shortcuts import render_to_response
-from misago.utils.pagination import make_pagination
-from misago.apps.errors import error403, error404
-from misago.apps.profiles.views import list as users_list
-from misago.apps.search.forms import QuickSearchForm
-
-class ViewBase(object):
-    search_route = 'search'
-
-    def check_acl(self):
-        pass
-
-    def make_query(self, search_query):
-        sqs = SearchQuerySet()
-        if self.request.POST.get('search_thread_titles'):
-            sqs = sqs.filter(thread_name=AutoQuery(search_query), start_post=1)
-        else:
-            sqs = sqs.auto_query(search_query)
-
-        if self.request.POST.get('search_in') == 'private':
-            if not (self.request.acl.private_threads.can_participate()
-                    and settings.enable_private_threads):
-                raise ACLError404()
-            sqs = sqs.filter(thread__in=[t.pk for t in self.request.user.private_thread_set.all()])
-        elif self.request.POST.get('search_in') == 'reports':
-            if not self.request.acl.reports.can_handle():
-                raise ACLError404()
-            sqs = sqs.filter(forum=Forum.objects.special_pk('reports'))
-        elif self.request.POST.get('search_in') == 'thread':
-            try:
-                thread_id = int(self.request.POST.get('search_thread'))
-                thread_clean = Thread.objects.get(id=thread_id)
-
-                readable_forums = Forum.objects.readable_forums(self.request.acl, True)
-                starter_readable_forums = Forum.objects.starter_readable_forums(self.request.acl)
-                if not thread_clean.forum_id in readable_forums:
-                    if not (thread_clean.forum_id in starter_readable_forums
-                            and thread_clean.start_poster_id
-                            and thread_clean.start_poster_id == self.request.user.id):
-                        raise ACLError404()
-                self.thread_clean = thread_clean
-                sqs = sqs.filter(thread=thread_clean.pk)
-            except (TypeError, Thread.DoesNotExist):
-                raise ACLError404()
-        else:
-            readable_forums = Forum.objects.readable_forums(self.request.acl)
-            starter_readable_forums = Forum.objects.starter_readable_forums(self.request.acl)
-            if not readable_forums and not readable_forums:
-                return error403(request, _("You cannot search any forums."))
-
-            if readable_forums and starter_readable_forums:
-                sqs = sqs.filter(forum__in=starter_readable_forums, thread_starter=self.request.user.id)
-                sqs = sqs.filter_or(forum__in=readable_forums)
-            elif starter_readable_forums:
-                if not self.request.user.is_authenticated():
-                    return error403(request, _("You cannot search any forums."))
-                sqs = sqs.filter(forum__in=starter_readable_forums, thread_starter=self.request.user.id)
-            else:
-                sqs = sqs.filter(forum__in=readable_forums)
-
-        if self.request.POST.get('search_author'):
-            sqs = sqs.filter(author__exact=self.request.POST.get('search_author'))
-
-        return sqs
-
-    def render_to_response(self, template, form, context):
-        for i in ('search_query', 'search_in', 'search_author', 'search_thread_titles'):
-            if self.request.POST.get(i):
-                context[i] = self.request.POST.get(i)
-        try:
-            context['search_thread'] = self.thread_clean
-        except AttributeError:
-            pass
-        return render_to_response('search/%s.html' % template,
-                                  context,
-                                  context_instance=RequestContext(self.request))
-
-    def __new__(cls, request, **kwargs):
-        obj = super(ViewBase, cls).__new__(cls)
-        return obj(request, **kwargs)
-
-    def __call__(self, request, **kwargs):
-        try:
-            if request.user.is_crawler():
-                raise ACLError404()
-            self.check_acl()
-            if not request.acl.search.can_search():
-                raise ACLError403(_("You don't have permission to search community."))
-            self.request = request
-            return self.call(**kwargs)
-        except ACLError403 as e:
-            return error403(request, unicode(e))
-        except ACLError404 as e:
-            return error404(request, unicode(e))
-
-
-class QuickSearchView(ViewBase):
-    def call(self, **kwargs):
-        form_type = QuickSearchForm
-        if self.request.method != "POST":
-            form = QuickSearchForm(request=self.request)
-            return self.render_to_response('home', form,
-                                           {'search_result': self.request.session.get('search_results')})
-        
-        try:
-            form = QuickSearchForm(self.request.POST, request=self.request)
-            if form.is_valid():
-                if form.mode == 'forum':
-                    jump_to = Forum.objects.forum_by_name(form.target, self.request.acl)
-                    if jump_to:
-                        if jump_to.level == 1:
-                            return redirect(reverse('index') + ('#%s' % jump_to.slug))
-                        return redirect(jump_to.url)
-                    else:
-                        raise SearchException(_('Forum "%(forum)s" could not be found.') % {'forum': form.target})
-                if form.mode == 'user':
-                    self.request.POST = self.request.POST.copy()
-                    self.request.POST['username'] = form.target
-                    return users_list(self.request)
-
-                sqs = self.make_query(form.cleaned_data['search_query']).load_all()[:60]
-
-                if self.request.user.is_authenticated():
-                    self.request.user.last_search = timezone.now()
-                    self.request.user.save(force_update=True)
-                if self.request.user.is_anonymous():
-                    self.request.session['last_search'] = timezone.now()
-
-                if not sqs:
-                    raise SearchException(_("Search returned no results. Change search query and try again."))
-
-                self.request.session['search_results'] = {
-                                                          'search_query': form.cleaned_data['search_query'],
-                                                          'search_in': self.request.POST.get('search_in'),
-                                                          'search_author': self.request.POST.get('search_author'),
-                                                          'search_thread_titles': self.request.POST.get('search_thread_titles'),
-                                                          'search_results': [p.object for p in sqs],
-                                                          }
-                try:
-                    self.request.session['search_results']['search_thread'] = self.thread_clean
-                except AttributeError:
-                    pass
-                return redirect(reverse('search_results'))
-            else:
-                if 'search_query' in form.errors:
-                    raise SearchException(form.errors['search_query'][0])
-                raise SearchException(form.errors['__all__'][0])
-        except SearchException as e:
-            return self.render_to_response('error', form,
-                                           {'message': unicode(e)})
-
-
-class SearchResultsView(ViewBase):
-    def call(self, **kwargs):
-        result = self.request.session.get('search_results')
-        if not result:
-            form = QuickSearchForm(request=self.request)
-            return self.render_to_response('error', form,  
-                                           {'message': _("No search results were found.")})
-
-        items = result['search_results']
-        items_total = len(items);
-        try:
-            pagination = make_pagination(kwargs.get('page', 0), items_total, 12)
-        except Http404:
-            return redirect(reverse('search_results'))
-
-        form = QuickSearchForm(request=self.request, initial={'search_query': result['search_query']})
-        return self.render_to_response('results', form,  
-                                       {
-                                        'search_query': result['search_query'],
-                                        'search_in': result.get('search_in'),
-                                        'search_author': result.get('search_author'),
-                                        'search_thread_titles': result.get('search_thread_titles'),
-                                        'search_thread': result.get('search_thread'),
-                                        'results': items[pagination['start']:pagination['stop']],
-                                        'items_total': items_total,
-                                        'pagination': pagination,
+from django.core.urlresolvers import reverse
+from django.http import Http404
+from django.shortcuts import redirect
+from django.template import RequestContext
+from django.utils import timezone
+from django.utils.translation import ugettext as _
+from haystack.inputs import AutoQuery
+from haystack.query import SearchQuerySet, RelatedSearchQuerySet
+from misago.acl.exceptions import ACLError403, ACLError404
+from misago.conf import settings
+from misago.decorators import block_crawlers
+from misago.models import Forum, Thread, Post, User
+from misago.search import SearchException
+from misago.shortcuts import render_to_response
+from misago.utils.pagination import make_pagination
+from misago.apps.errors import error403, error404
+from misago.apps.profiles.views import list as users_list
+from misago.apps.search.forms import QuickSearchForm
+
+class ViewBase(object):
+    search_route = 'search'
+
+    def check_acl(self):
+        pass
+
+    def make_query(self, search_query):
+        sqs = SearchQuerySet()
+        if self.request.POST.get('search_thread_titles'):
+            sqs = sqs.filter(thread_name=AutoQuery(search_query), start_post=1)
+        else:
+            sqs = sqs.auto_query(search_query)
+
+        if self.request.POST.get('search_in') == 'private':
+            if not (self.request.acl.private_threads.can_participate()
+                    and settings.enable_private_threads):
+                raise ACLError404()
+            sqs = sqs.filter(thread__in=[t.pk for t in self.request.user.private_thread_set.all()])
+        elif self.request.POST.get('search_in') == 'reports':
+            if not self.request.acl.reports.can_handle():
+                raise ACLError404()
+            sqs = sqs.filter(forum=Forum.objects.special_pk('reports'))
+        elif self.request.POST.get('search_in') == 'thread':
+            try:
+                thread_id = int(self.request.POST.get('search_thread'))
+                thread_clean = Thread.objects.get(id=thread_id)
+
+                readable_forums = Forum.objects.readable_forums(self.request.acl, True)
+                starter_readable_forums = Forum.objects.starter_readable_forums(self.request.acl)
+                if not thread_clean.forum_id in readable_forums:
+                    if not (thread_clean.forum_id in starter_readable_forums
+                            and thread_clean.start_poster_id
+                            and thread_clean.start_poster_id == self.request.user.id):
+                        raise ACLError404()
+                self.thread_clean = thread_clean
+                sqs = sqs.filter(thread=thread_clean.pk)
+            except (TypeError, Thread.DoesNotExist):
+                raise ACLError404()
+        else:
+            readable_forums = Forum.objects.readable_forums(self.request.acl)
+            starter_readable_forums = Forum.objects.starter_readable_forums(self.request.acl)
+            if not readable_forums and not readable_forums:
+                return error403(request, _("You cannot search any forums."))
+
+            if readable_forums and starter_readable_forums:
+                sqs = sqs.filter(forum__in=starter_readable_forums, thread_starter=self.request.user.id)
+                sqs = sqs.filter_or(forum__in=readable_forums)
+            elif starter_readable_forums:
+                if not self.request.user.is_authenticated():
+                    return error403(request, _("You cannot search any forums."))
+                sqs = sqs.filter(forum__in=starter_readable_forums, thread_starter=self.request.user.id)
+            else:
+                sqs = sqs.filter(forum__in=readable_forums)
+
+        if self.request.POST.get('search_author'):
+            sqs = sqs.filter(author__exact=self.request.POST.get('search_author'))
+
+        return sqs
+
+    def render_to_response(self, template, form, context):
+        for i in ('search_query', 'search_in', 'search_author', 'search_thread_titles'):
+            if self.request.POST.get(i):
+                context[i] = self.request.POST.get(i)
+        try:
+            context['search_thread'] = self.thread_clean
+        except AttributeError:
+            pass
+        return render_to_response('search/%s.html' % template,
+                                  context,
+                                  context_instance=RequestContext(self.request))
+
+    def __new__(cls, request, **kwargs):
+        obj = super(ViewBase, cls).__new__(cls)
+        return obj(request, **kwargs)
+
+    def __call__(self, request, **kwargs):
+        try:
+            if request.user.is_crawler():
+                raise ACLError404()
+            self.check_acl()
+            if not request.acl.search.can_search():
+                raise ACLError403(_("You don't have permission to search community."))
+            self.request = request
+            return self.call(**kwargs)
+        except ACLError403 as e:
+            return error403(request, unicode(e))
+        except ACLError404 as e:
+            return error404(request, unicode(e))
+
+
+class QuickSearchView(ViewBase):
+    def call(self, **kwargs):
+        form_type = QuickSearchForm
+        if self.request.method != "POST":
+            form = QuickSearchForm(request=self.request)
+            return self.render_to_response('home', form,
+                                           {'search_result': self.request.session.get('search_results')})
+        
+        try:
+            form = QuickSearchForm(self.request.POST, request=self.request)
+            if form.is_valid():
+                if form.mode == 'forum':
+                    jump_to = Forum.objects.forum_by_name(form.target, self.request.acl)
+                    if jump_to:
+                        if jump_to.level == 1:
+                            return redirect(reverse('index') + ('#%s' % jump_to.slug))
+                        return redirect(jump_to.url)
+                    else:
+                        raise SearchException(_('Forum "%(forum)s" could not be found.') % {'forum': form.target})
+                if form.mode == 'user':
+                    self.request.POST = self.request.POST.copy()
+                    self.request.POST['username'] = form.target
+                    return users_list(self.request)
+
+                sqs = self.make_query(form.cleaned_data['search_query']).load_all()[:60]
+
+                if self.request.user.is_authenticated():
+                    self.request.user.last_search = timezone.now()
+                    self.request.user.save(force_update=True)
+                if self.request.user.is_anonymous():
+                    self.request.session['last_search'] = timezone.now()
+
+                if not sqs:
+                    raise SearchException(_("Search returned no results. Change search query and try again."))
+
+                self.request.session['search_results'] = {
+                                                          'search_query': form.cleaned_data['search_query'],
+                                                          'search_in': self.request.POST.get('search_in'),
+                                                          'search_author': self.request.POST.get('search_author'),
+                                                          'search_thread_titles': self.request.POST.get('search_thread_titles'),
+                                                          'search_results': [p.object for p in sqs],
+                                                          }
+                try:
+                    self.request.session['search_results']['search_thread'] = self.thread_clean
+                except AttributeError:
+                    pass
+                return redirect(reverse('search_results'))
+            else:
+                if 'search_query' in form.errors:
+                    raise SearchException(form.errors['search_query'][0])
+                raise SearchException(form.errors['__all__'][0])
+        except SearchException as e:
+            return self.render_to_response('error', form,
+                                           {'message': unicode(e)})
+
+
+class SearchResultsView(ViewBase):
+    def call(self, **kwargs):
+        result = self.request.session.get('search_results')
+        if not result:
+            form = QuickSearchForm(request=self.request)
+            return self.render_to_response('error', form,  
+                                           {'message': _("No search results were found.")})
+
+        items = result['search_results']
+        items_total = len(items);
+        try:
+            pagination = make_pagination(kwargs.get('page', 0), items_total, 12)
+        except Http404:
+            return redirect(reverse('search_results'))
+
+        form = QuickSearchForm(request=self.request, initial={'search_query': result['search_query']})
+        return self.render_to_response('results', form,  
+                                       {
+                                        'search_query': result['search_query'],
+                                        'search_in': result.get('search_in'),
+                                        'search_author': result.get('search_author'),
+                                        'search_thread_titles': result.get('search_thread_titles'),
+                                        'search_thread': result.get('search_thread'),
+                                        'results': items[pagination['start']:pagination['stop']],
+                                        'items_total': items_total,
+                                        'pagination': pagination,
                                        })
                                        })

+ 0 - 2
misago/apps/watchedthreads/views.py

@@ -1,4 +1,3 @@
-import floppyforms as forms
 from django.core.urlresolvers import reverse
 from django.core.urlresolvers import reverse
 from django.db.models import Q, F
 from django.db.models import Q, F
 from django.http import Http404
 from django.http import Http404
@@ -8,7 +7,6 @@ from django.utils.translation import ugettext as _
 from misago.apps.errors import error403
 from misago.apps.errors import error403
 from misago.conf import settings
 from misago.conf import settings
 from misago.decorators import block_guest
 from misago.decorators import block_guest
-from misago.forms import Form, FormLayout, FormFields
 from misago.messages import Message
 from misago.messages import Message
 from misago.models import Forum, WatchedThread
 from misago.models import Forum, WatchedThread
 from misago.shortcuts import render_to_response
 from misago.shortcuts import render_to_response

+ 3 - 3
misago/forms/__init__.py

@@ -1,4 +1,4 @@
-from misago.forms.fields import ForumChoiceField, ReCaptchaField, QACaptchaField
-from misago.forms.forms import Form
-from misago.forms.layouts import FormLayout, FormFields, FormFieldsets
+from misago.forms.fields import ForumChoiceField, ReCaptchaField, QACaptchaField
+from misago.forms.forms import Form
+from misago.forms.layouts import FormLayout
 from misago.forms.widgets import ReCaptchaWidget, YesNoSwitch, ForumTOS
 from misago.forms.widgets import ReCaptchaWidget, YesNoSwitch, ForumTOS

+ 2 - 2
templates/cranefly/profiles/list.html

@@ -1,5 +1,5 @@
 {% extends "cranefly/layout.html" %}
 {% extends "cranefly/layout.html" %}
-{% import "_forms.html" as form_theme with context %}
+{% import "forms.html" as form_theme with context %}
 {% import "cranefly/macros.html" as macros with context %}
 {% import "cranefly/macros.html" as macros with context %}
 
 
 {% block title %}{% if in_search -%}
 {% block title %}{% if in_search -%}
@@ -23,7 +23,7 @@
       <li class="pull-right">
       <li class="pull-right">
         <form action="{{ url('users') }}" class="form-inline" method="post">
         <form action="{{ url('users') }}" class="form-inline" method="post">
           <input type="hidden" name="{{ csrf_id }}" value="{{ csrf_token }}">
           <input type="hidden" name="{{ csrf_id }}" value="{{ csrf_token }}">
-          {{ form_theme.field_widget(search_form.username, width=2, attrs={'placeholder': lang_find_user()}) }}
+          {{ form_theme.field(search_form.username, attrs={'class': 'span2', 'placeholder': lang_find_user()}) }}
           <button type="submit" class="btn btn-icon"><i class="icon-search"></i></button>
           <button type="submit" class="btn btn-icon"><i class="icon-search"></i></button>
         </form>
         </form>
       </li>
       </li>