Browse Source

Search posts, reports and private threads. #36

Ralfp 12 years ago
parent
commit
7113610ce7

+ 2 - 2
misago/acl/permissions/threads.py

@@ -178,9 +178,9 @@ class ThreadsACL(BaseACL):
             forum_role = self.acl[forum.pk]
             forum_role = self.acl[forum.pk]
             if not forum_role['can_approve']:
             if not forum_role['can_approve']:
                 if request.user.is_authenticated():
                 if request.user.is_authenticated():
-                    queryset = queryset.filter(Q(moderated=0) | Q(start_poster=request.user))
+                    queryset = queryset.filter(Q(moderated=False) | Q(start_poster=request.user))
                 else:
                 else:
-                    queryset = queryset.filter(moderated=0)
+                    queryset = queryset.filter(moderated=False)
             if forum_role['can_read_threads'] == 1:
             if forum_role['can_read_threads'] == 1:
                 queryset = queryset.filter(Q(weight=2) | Q(start_poster_id=request.user.id))
                 queryset = queryset.filter(Q(weight=2) | Q(start_poster_id=request.user.id))
             if not forum_role['can_delete_threads']:
             if not forum_role['can_delete_threads']:

+ 3 - 2
misago/apps/privatethreads/search.py

@@ -5,6 +5,7 @@ from misago.apps.search.views import do_search, results
 
 
 def allow_search(f):
 def allow_search(f):
     def decorator(*args, **kwargs):
     def decorator(*args, **kwargs):
+        request = args[0]
         if not (request.acl.private_threads.can_participate()
         if not (request.acl.private_threads.can_participate()
                 and request.settings['enable_private_threads']):
                 and request.settings['enable_private_threads']):
             return error404()
             return error404()
@@ -22,5 +23,5 @@ def search_private_threads(request):
 
 
 @block_crawlers
 @block_crawlers
 @allow_search
 @allow_search
-def show_private_threads_results(request):
-    return results(request, 'private_threads')
+def show_private_threads_results(request, page=0):
+    return results(request, page, 'private_threads')

+ 2 - 1
misago/apps/privatethreads/urls.py

@@ -39,5 +39,6 @@ urlpatterns = patterns('misago.apps.privatethreads',
     url(r'^(?P<slug>(\w|-)+)-(?P<thread>\d+)/(?P<post>\d+)/changelog/(?P<change>\d+)/revert/$', 'changelog.ChangelogRevertView', name="private_thread_changelog_revert"),
     url(r'^(?P<slug>(\w|-)+)-(?P<thread>\d+)/(?P<post>\d+)/changelog/(?P<change>\d+)/revert/$', 'changelog.ChangelogRevertView', name="private_thread_changelog_revert"),
     # Extra search routes
     # Extra search routes
     url(r'^search/$', 'search.search_private_threads', name="private_threads_search"),
     url(r'^search/$', 'search.search_private_threads', name="private_threads_search"),
-    url(r'^search/results/$', 'search.show_private_threads_results', name="private_threads_search_results"),
+    url(r'^search/results/$', 'search.show_private_threads_results', name="private_threads_results"),
+    url(r'^search/results/(?P<page>[1-9]([0-9]+)?)/$', 'search.show_private_threads_results', name="private_threads_results"),
 )
 )

+ 3 - 2
misago/apps/reports/search.py

@@ -5,6 +5,7 @@ from misago.apps.search.views import do_search, results
 
 
 def allow_search(f):
 def allow_search(f):
     def decorator(*args, **kwargs):
     def decorator(*args, **kwargs):
+        request = args[0]
         if not request.acl.reports.can_handle():
         if not request.acl.reports.can_handle():
             return error404()
             return error404()
         return f(*args, **kwargs)
         return f(*args, **kwargs)
@@ -20,5 +21,5 @@ def search_reports(request):
 
 
 @block_crawlers
 @block_crawlers
 @allow_search
 @allow_search
-def show_reports_results(request):
-    return results(request, 'reports')
+def show_reports_results(request, page=0):
+    return results(request, page, 'reports')

+ 2 - 1
misago/apps/reports/urls.py

@@ -31,5 +31,6 @@ urlpatterns = patterns('misago.apps.reports',
     url(r'^(?P<slug>(\w|-)+)-(?P<thread>\d+)/(?P<post>\d+)/changelog/(?P<change>\d+)/revert/$', 'changelog.ChangelogRevertView', name="report_changelog_revert"),
     url(r'^(?P<slug>(\w|-)+)-(?P<thread>\d+)/(?P<post>\d+)/changelog/(?P<change>\d+)/revert/$', 'changelog.ChangelogRevertView', name="report_changelog_revert"),
     # Extra search routes
     # Extra search routes
     url(r'^search/$', 'search.search_reports', name="reports_search"),
     url(r'^search/$', 'search.search_reports', name="reports_search"),
-    url(r'^search/results/$', 'search.show_reports_results', name="reports_search_results"),
+    url(r'^search/results/$', 'search.show_reports_results', name="reports_results"),
+    url(r'^search/results/(?P<page>[1-9]([0-9]+)?)/$', 'search.show_reports_results', name="reports_results"),
 )
 )

+ 1 - 0
misago/apps/search/urls.py

@@ -3,4 +3,5 @@ from django.conf.urls import patterns, url
 urlpatterns = patterns('misago.apps.search.views',
 urlpatterns = patterns('misago.apps.search.views',
     url(r'^$', 'search', name="search"),
     url(r'^$', 'search', name="search"),
     url(r'^results/$', 'show_results', name="search_results"),
     url(r'^results/$', 'show_results', name="search_results"),
+    url(r'^results/(?P<page>[1-9]([0-9]+)?)/$', 'show_results', name="search_results"),
 )
 )

+ 15 - 5
misago/apps/search/views.py

@@ -1,4 +1,5 @@
 from django.core.urlresolvers import reverse
 from django.core.urlresolvers import reverse
+from django.http import Http404
 from django.shortcuts import redirect
 from django.shortcuts import redirect
 from django.template import RequestContext
 from django.template import RequestContext
 from django.utils import timezone
 from django.utils import timezone
@@ -8,6 +9,7 @@ from misago.decorators import block_crawlers
 from misago.forms import FormFields
 from misago.forms import FormFields
 from misago.models import Forum, Thread, Post, User
 from misago.models import Forum, Thread, Post, User
 from misago.search import SearchException
 from misago.search import SearchException
+from misago.utils.pagination import make_pagination
 from misago.apps.errors import error403, error404
 from misago.apps.errors import error403, error404
 from misago.apps.profiles.views import list as users_list
 from misago.apps.profiles.views import list as users_list
 from misago.apps.search.forms import QuickSearchForm
 from misago.apps.search.forms import QuickSearchForm
@@ -51,7 +53,7 @@ def do_search(request, queryset, search_route=None):
                 request.POST['username'] = form.target
                 request.POST['username'] = form.target
                 return users_list(request)
                 return users_list(request)
             sqs = RelatedSearchQuerySet().auto_query(form.cleaned_data['search_query']).order_by('-id').load_all()
             sqs = RelatedSearchQuerySet().auto_query(form.cleaned_data['search_query']).order_by('-id').load_all()
-            sqs = sqs.load_all_queryset(Post, queryset.select_related('thread', 'forum'))[:24]
+            sqs = sqs.load_all_queryset(Post, queryset.filter(deleted=False).filter(moderated=False).select_related('thread', 'forum'))[:120]
             request.user.last_search = timezone.now()
             request.user.last_search = timezone.now()
             request.user.save(force_update=True)
             request.user.save(force_update=True)
             if not sqs:
             if not sqs:
@@ -75,11 +77,11 @@ def do_search(request, queryset, search_route=None):
 
 
 
 
 @block_crawlers
 @block_crawlers
-def show_results(request):
-    return results(request)
+def show_results(request, page=0):
+    return results(request, page)
 
 
 
 
-def results(request, search_route=None):
+def results(request, page=0, search_route=None):
     if not request.acl.search.can_search():
     if not request.acl.search.can_search():
         return error403(request, _("You don't have permission to search community."))
         return error403(request, _("You don't have permission to search community."))
 
 
@@ -96,14 +98,22 @@ def results(request, search_route=None):
                                                 },
                                                 },
                                                 context_instance=RequestContext(request))
                                                 context_instance=RequestContext(request))
 
 
+    queryset = Post.objects.filter(id__in=result['search_results'])
+    items_total = queryset.count();
+    try:
+        pagination = make_pagination(page, items_total, 12)
+    except Http404:
+        return redirect(reverse('%s_results' % search_route))
+
     form = QuickSearchForm(request=request, initial={'search_query': result['search_query']})
     form = QuickSearchForm(request=request, initial={'search_query': result['search_query']})
     return request.theme.render_to_response('search/results.html',
     return request.theme.render_to_response('search/results.html',
                                             {
                                             {
                                              'form': FormFields(form),
                                              'form': FormFields(form),
                                              'search_route': search_route,
                                              'search_route': search_route,
                                              'search_query': result['search_query'],
                                              'search_query': result['search_query'],
-                                             'results': Post.objects.filter(id__in=result['search_results']).select_related('thread', 'forum', 'user'),
+                                             'results': queryset.select_related('thread', 'forum', 'user')[pagination['start']:pagination['stop']],
                                              'disable_search': True,
                                              'disable_search': True,
+                                             'pagination': pagination,
                                             },
                                             },
                                             context_instance=RequestContext(request))
                                             context_instance=RequestContext(request))
 
 

+ 1 - 1
static/cranefly/css/cranefly.css

@@ -852,6 +852,7 @@ a.label:hover,a.label:focus,a.badge:hover,a.badge:focus{color:#ffffff;text-decor
 .header-primary .breadcrumb li a:hover,.header-primary .breadcrumb li a:active{color:#333333;}
 .header-primary .breadcrumb li a:hover,.header-primary .breadcrumb li a:active{color:#333333;}
 .header-primary .breadcrumb li .divider{padding-left:0px;padding-right:0px;}.header-primary .breadcrumb li .divider i{opacity:0.2;filter:alpha(opacity=20);position:relative;bottom:1px;}
 .header-primary .breadcrumb li .divider{padding-left:0px;padding-right:0px;}.header-primary .breadcrumb li .divider i{opacity:0.2;filter:alpha(opacity=20);position:relative;bottom:1px;}
 .header-primary h1{color:#555555;font-size:35px;font-weight:normal;}
 .header-primary h1{color:#555555;font-size:35px;font-weight:normal;}
+.header-primary.header-search h1{float:left;}.header-primary.header-search h1 form{float:right;margin:0px;}.header-primary.header-search h1 form input{margin-left:21px;-webkit-box-shadow:0px 0px 0px 3px #eeeeee;-moz-box-shadow:0px 0px 0px 3px #eeeeee;box-shadow:0px 0px 0px 3px #eeeeee;font-size:17.5px;}.header-primary.header-search h1 form input:focus,.header-primary.header-search h1 form input:active{border-color:#4dc3ff;-webkit-box-shadow:0px 0px 0px 3px #b3e5ff;-moz-box-shadow:0px 0px 0px 3px #b3e5ff;box-shadow:0px 0px 0px 3px #b3e5ff;}
 .header-primary .header-stats{overflow:visible;margin-bottom:0px;color:#999999;}.header-primary .header-stats li{float:left;margin-right:14px;}.header-primary .header-stats li>a{color:#999999;}.header-primary .header-stats li>a:hover,.header-primary .header-stats li>a:active{color:#333333;}
 .header-primary .header-stats{overflow:visible;margin-bottom:0px;color:#999999;}.header-primary .header-stats li{float:left;margin-right:14px;}.header-primary .header-stats li>a{color:#999999;}.header-primary .header-stats li>a:hover,.header-primary .header-stats li>a:active{color:#333333;}
 .header-primary .header-stats li>i{opacity:0.5;filter:alpha(opacity=50);}
 .header-primary .header-stats li>i{opacity:0.5;filter:alpha(opacity=50);}
 .header-primary .header-stats li.stats-form{float:right;}.header-primary .header-stats li.stats-form form{margin:0px;margin-bottom:-12px;padding:0px;}.header-primary .header-stats li.stats-form form button{position:relative;bottom:12px;}.header-primary .header-stats li.stats-form form button>i{position:relative;top:0px;}
 .header-primary .header-stats li.stats-form{float:right;}.header-primary .header-stats li.stats-form form{margin:0px;margin-bottom:-12px;padding:0px;}.header-primary .header-stats li.stats-form form button{position:relative;bottom:12px;}.header-primary .header-stats li.stats-form form button>i{position:relative;top:0px;}
@@ -1218,7 +1219,6 @@ a.btn-link:hover,a.btn-link:active,a.btn-link:focus{opacity:0.9;filter:alpha(opa
 .reports-list .thread-name .report-id{color:#999999 !important;}
 .reports-list .thread-name .report-id{color:#999999 !important;}
 .reports-list .thread-name,.reports-list .thread-details{margin-left:0px !important;}
 .reports-list .thread-name,.reports-list .thread-details{margin-left:0px !important;}
 .reports-list .thread-icon{display:none !important;float:none;}
 .reports-list .thread-icon{display:none !important;float:none;}
-.search-header h1{float:left;}.search-header h1 form{float:right;margin:0px;}.search-header h1 form input{margin-left:21px;-webkit-box-shadow:0px 0px 0px 3px #eeeeee;-moz-box-shadow:0px 0px 0px 3px #eeeeee;box-shadow:0px 0px 0px 3px #eeeeee;font-size:17.5px;}.search-header h1 form input:focus,.search-header h1 form input:active{border-color:#4dc3ff;-webkit-box-shadow:0px 0px 0px 3px #b3e5ff;-moz-box-shadow:0px 0px 0px 3px #b3e5ff;box-shadow:0px 0px 0px 3px #b3e5ff;}
 .search-resume .muted{color:#7b7b7b;}.search-resume .muted a{color:#333333;}
 .search-resume .muted{color:#7b7b7b;}.search-resume .muted a{color:#333333;}
 .search-results .results-list .result{border-bottom:1px solid #eeeeee;margin-bottom:10px;padding-bottom:10px;}.search-results .results-list .result h3{margin:0px;line-height:20px;}.search-results .results-list .result h3 a:link,.search-results .results-list .result h3 a:visited{color:#555555;font-weight:normal;font-size:18.2px;text-decoration:underline;}
 .search-results .results-list .result{border-bottom:1px solid #eeeeee;margin-bottom:10px;padding-bottom:10px;}.search-results .results-list .result h3{margin:0px;line-height:20px;}.search-results .results-list .result h3 a:link,.search-results .results-list .result h3 a:visited{color:#555555;font-weight:normal;font-size:18.2px;text-decoration:underline;}
 .search-results .results-list .result h3 a:hover,.search-results .results-list .result h3 a:active{color:#333333;}
 .search-results .results-list .result h3 a:hover,.search-results .results-list .result h3 a:active{color:#333333;}

+ 23 - 0
static/cranefly/css/cranefly/header.less

@@ -46,6 +46,29 @@
     font-weight: normal;
     font-weight: normal;
   }
   }
 
 
+  &.header-search {
+    h1 {
+      float: left;
+
+      form {
+        float: right;
+        margin: 0px;
+
+        input {
+          margin-left: @baseFontSize * 1.5;
+          .box-shadow(0px 0px 0px 3px darken(@bodyBackground, 5%));
+
+          font-size: @fontSizeLarge;
+
+          &:focus, &:active {
+            border-color: lighten(@linkColor, 25%);
+            .box-shadow(0px 0px 0px 3px lighten(@linkColor, 45%));
+          }
+        }
+      }
+    }  
+  }
+
   .header-stats {
   .header-stats {
     overflow: visible;
     overflow: visible;
     margin-bottom: 0px;
     margin-bottom: 0px;

+ 0 - 23
static/cranefly/css/cranefly/search.less

@@ -1,29 +1,6 @@
 // Search forum
 // Search forum
 // ------------------------
 // ------------------------
 
 
-.search-header {
-  h1 {
-    float: left;
-
-    form {
-      float: right;
-      margin: 0px;
-
-      input {
-        margin-left: @baseFontSize * 1.5;
-        .box-shadow(0px 0px 0px 3px darken(@bodyBackground, 5%));
-
-        font-size: @fontSizeLarge;
-
-        &:focus, &:active {
-          border-color: lighten(@linkColor, 25%);
-          .box-shadow(0px 0px 0px 3px lighten(@linkColor, 45%));
-        }
-      }
-    }
-  }
-}
-
 .search-resume {
 .search-resume {
   .muted {
   .muted {
     color: lighten(@gray, 15%);
     color: lighten(@gray, 15%);

+ 1 - 0
templates/cranefly/popular_threads.html

@@ -63,6 +63,7 @@
     </div>
     </div>
     {% endfor %}
     {% endfor %}
   </div>
   </div>
+  {{ pager() }}
   {% else %}
   {% else %}
   <p class="lead">{% trans %}Looks like there are no popular threads... yet!{% endtrans %}</p>
   <p class="lead">{% trans %}Looks like there are no popular threads... yet!{% endtrans %}</p>
   {% endif %}
   {% endif %}

+ 6 - 2
templates/cranefly/private_threads/list.html

@@ -9,11 +9,15 @@
 {%- endblock %}
 {%- endblock %}
 
 
 {% block container %}
 {% block container %}
-<div class="page-header header-primary">
+<div class="page-header header-primary header-search">
   <div class="container">
   <div class="container">
     {{ messages_list(messages) }}
     {{ messages_list(messages) }}
     <ul class="breadcrumb" {{ macros.itemprop_bread() }}>
     <ul class="breadcrumb" {{ macros.itemprop_bread() }}>
-      {{ self.breadcrumb() }}</li>
+      {{ self.breadcrumb() }} <form action="{% url 'private_threads_search' %}" class="form-inline" method="post">
+       <input type="hidden" name="{{ csrf_id }}" value="{{ csrf_token }}">
+       <input maxlength="255" type="text" name="search_query" class="span4">
+       <button type="submit" class="btn btn-primary">{% trans %}Search{% endtrans %}</button>
+    </form></li>
     </ul>
     </ul>
     <h1>{% trans %}Private Threads{% endtrans %}</h1>
     <h1>{% trans %}Private Threads{% endtrans %}</h1>
   </div>
   </div>

+ 6 - 2
templates/cranefly/reports/list.html

@@ -9,13 +9,17 @@
 {%- endblock %}
 {%- endblock %}
 
 
 {% block container %}
 {% block container %}
-<div class="page-header header-primary">
+<div class="page-header header-primary header-search">
   <div class="container">
   <div class="container">
     {{ messages_list(messages) }}
     {{ messages_list(messages) }}
     <ul class="breadcrumb" {{ macros.itemprop_bread() }}>
     <ul class="breadcrumb" {{ macros.itemprop_bread() }}>
       {{ self.breadcrumb() }}</li>
       {{ self.breadcrumb() }}</li>
     </ul>
     </ul>
-    <h1>{% trans %}Reported Posts{% endtrans %}</h1>
+    <h1>{% trans %}Reported Posts{% endtrans %} <form action="{% url 'reports_search' %}" class="form-inline" method="post">
+       <input type="hidden" name="{{ csrf_id }}" value="{{ csrf_token }}">
+       <input maxlength="255" type="text" name="search_query" class="span4">
+       <button type="submit" class="btn btn-primary">{% trans %}Search{% endtrans %}</button>
+    </form></h1>
   </div>
   </div>
 </div>
 </div>
 
 

+ 1 - 1
templates/cranefly/search/home.html

@@ -13,5 +13,5 @@
 {% endblock %}
 {% endblock %}
 
 
 {% macro style_query(query) -%}
 {% macro style_query(query) -%}
-<a href="{{ ('%s_results'.format(search_route))|url }}">{{ query }}</a></strong>
+<a href="{{ ('%s_results'|format(search_route))|url }}">{{ query }}</a>
 {%- endmacro %}
 {%- endmacro %}

+ 1 - 1
templates/cranefly/search/layout.html

@@ -5,7 +5,7 @@
 {% block title %}{{ macros.page_title(title=_('Search Community')) }}{% endblock %}
 {% block title %}{{ macros.page_title(title=_('Search Community')) }}{% endblock %}
 
 
 {% block container %}
 {% block container %}
-<div class="page-header header-primary search-header">
+<div class="page-header header-primary header-search">
   <div class="container">
   <div class="container">
     <h1>{% trans %}Search{% endtrans %} <form action="{{ search_route|url() }}" class="form-inline" method="post">
     <h1>{% trans %}Search{% endtrans %} <form action="{{ search_route|url() }}" class="form-inline" method="post">
        <input type="hidden" name="{{ csrf_id }}" value="{{ csrf_token }}">
        <input type="hidden" name="{{ csrf_id }}" value="{{ csrf_token }}">

+ 14 - 1
templates/cranefly/search/results.html

@@ -12,10 +12,11 @@
       <div class="result">
       <div class="result">
         <h3><a href="{{ result.forum.thread_link('find')|url(thread=result.thread_id, slug=result.thread.slug, post=result.pk) }}">{{ result.thread.name }}</a></h3>
         <h3><a href="{{ result.forum.thread_link('find')|url(thread=result.thread_id, slug=result.thread.slug, post=result.pk) }}">{{ result.thread.name }}</a></h3>
         <p class="post-extra">{% trans forum=forum(result.forum), user=username(result), date=result.date|reltimesince|low %}In {{ forum }} by {{ user }} {{ date }}{% endtrans %}</p>
         <p class="post-extra">{% trans forum=forum(result.forum), user=username(result), date=result.date|reltimesince|low %}In {{ forum }} by {{ user }} {{ date }}{% endtrans %}</p>
-        <p class="post-preview">{{ result.post_clean|highlight(search_query)|safe }}</p>
+        <p class="post-preview">{{ result.post_clean|highlight(search_query, 320)|safe }}</p>
       </div>
       </div>
       {% endfor %}
       {% endfor %}
     </div>
     </div>
+    {{ pager() }}
     {% else %}
     {% else %}
     <p class="lead">{% trans %}Looks like your search has expired. Please try searching again.{% endtrans %}</p>
     <p class="lead">{% trans %}Looks like your search has expired. Please try searching again.{% endtrans %}</p>
     {% endif %}
     {% endif %}
@@ -33,3 +34,15 @@
 {{ post.user_name }}
 {{ post.user_name }}
 {%- endif %}
 {%- endif %}
 {%- endmacro %}
 {%- endmacro %}
+
+{% macro pager() -%}
+{% if items_total > 0 and pagination['total'] > 1 %}
+<div class="pagination">
+  <ul>
+    <li class="count">{{ macros.pager_label(pagination) }}</li>
+    {%- if pagination['prev'] > 0 %}<li><a href="{%- if pagination['prev'] > 1 %}{{ ('%s_results'|format(search_route))|url(page=pagination['prev']) }}{% else %}{{ ('%s_results'|format(search_route))|url() }}{% endif %}" class="tooltip-top" title="{% trans %}Newer Posts{% endtrans %}"><i class="icon-chevron-left"></i></a></li>{% endif -%}
+    {%- if pagination['next'] > 0 %}<li><a href="{{ ('%s_results'|format(search_route))|url(page=pagination['next']) }}" class="tooltip-top" title="{% trans %}Older Posts{% endtrans %}"><i class="icon-chevron-right"></i></a></li>{% endif -%}
+  </ul>
+</div>
+{% endif %}
+{%- endmacro %}