]> git.openstreetmap.org Git - osqa.git/blobdiff - forum/views/readers.py
Adds fixed width to head and footer.
[osqa.git] / forum / views / readers.py
index f933a3bac889695525b54a481322a5568584d08b..ea555df0dafefdf2d6f0f6cb458b8356f7ecbc7d 100644 (file)
@@ -1,10 +1,10 @@
-# encoding:utf-8   
+# encoding:utf-8
 import datetime
 import logging
 from urllib import unquote
 from forum import settings as django_settings
 from django.shortcuts import render_to_response, get_object_or_404
 import datetime
 import logging
 from urllib import unquote
 from forum import settings as django_settings
 from django.shortcuts import render_to_response, get_object_or_404
-from django.http import HttpResponseRedirect, HttpResponse, HttpResponseForbidden, Http404, HttpResponsePermanentRedirect
+from django.http import HttpResponseRedirect, HttpResponse, Http404, HttpResponsePermanentRedirect
 from django.core.paginator import Paginator, EmptyPage, InvalidPage
 from django.template import RequestContext
 from django import template
 from django.core.paginator import Paginator, EmptyPage, InvalidPage
 from django.template import RequestContext
 from django import template
@@ -20,13 +20,15 @@ from django.utils.http import urlquote  as django_urlquote
 from django.template.defaultfilters import slugify
 from django.utils.safestring import mark_safe
 
 from django.template.defaultfilters import slugify
 from django.utils.safestring import mark_safe
 
-from forum.utils.html import sanitize_html
+from forum.utils.html import sanitize_html, hyperlink
 from forum.utils.diff import textDiff as htmldiff
 from forum.utils.diff import textDiff as htmldiff
+from forum.utils import pagination
 from forum.forms import *
 from forum.models import *
 from forum.forms import get_next_url
 from forum.actions import QuestionViewAction
 from forum.forms import *
 from forum.models import *
 from forum.forms import get_next_url
 from forum.actions import QuestionViewAction
-from forum.modules.decorators import decoratable
+from forum.http_responses import HttpResponseUnauthorized
+from forum.feed import RssQuestionFeed
 import decorators
 
 # used in index page
 import decorators
 
 # used in index page
@@ -41,23 +43,41 @@ QUESTIONS_PAGE_SIZE = 30
 # used in answers
 ANSWERS_PAGE_SIZE = 10
 
 # used in answers
 ANSWERS_PAGE_SIZE = 10
 
+class QuestionListPaginatorContext(pagination.PaginatorContext):
+    def __init__(self):
+        super (QuestionListPaginatorContext, self).__init__('QUESTIONS_LIST', sort_methods=(
+            (_('active'), pagination.SimpleSort(_('active'), '-last_activity_at', _("most recently updated questions"))),
+            (_('newest'), pagination.SimpleSort(_('newest'), '-added_at', _("most recently asked questions"))),
+            (_('hottest'), pagination.SimpleSort(_('hottest'), '-extra_count', _("hottest questions"))),
+            (_('mostvoted'), pagination.SimpleSort(_('most voted'), '-score', _("most voted questions"))),
+        ), pagesizes=(15, 30, 50))
+
+def feed(request):
+    return RssQuestionFeed(
+                Question.objects.filter_state(deleted=False).order_by('-last_activity_at'),
+                settings.APP_TITLE + _(' - ')+ _('latest questions'),
+                settings.APP_DESCRIPTION,
+                request)(request)
+
+
 @decorators.render('index.html')
 def index(request):
     return question_list(request,
                          Question.objects.all(),
                          sort=request.utils.set_sort_method('active'),
 @decorators.render('index.html')
 def index(request):
     return question_list(request,
                          Question.objects.all(),
                          sort=request.utils.set_sort_method('active'),
-                         base_path=reverse('questions'))
+                         base_path=reverse('questions'),
+                         feed_url=reverse('latest_questions_feed'))
 
 
-@decorators.render('questions.html', 'unanswered')
+@decorators.render('questions.html', 'unanswered', _('unanswered'), weight=400)
 def unanswered(request):
     return question_list(request,
                          Question.objects.filter(extra_ref=None),
                          _('open questions without an accepted answer'),
                          request.utils.set_sort_method('active'),
                          None,
 def unanswered(request):
     return question_list(request,
                          Question.objects.filter(extra_ref=None),
                          _('open questions without an accepted answer'),
                          request.utils.set_sort_method('active'),
                          None,
-                         _("Unanswered questions"))
+                         _("Unanswered Questions"))
 
 
-@decorators.render('questions.html', 'questions')
+@decorators.render('questions.html', 'questions', _('questions'), weight=0)
 def questions(request):
     return question_list(request, Question.objects.all(), _('questions'), request.utils.set_sort_method('active'))
 
 def questions(request):
     return question_list(request, Question.objects.all(), _('questions'), request.utils.set_sort_method('active'))
 
@@ -68,31 +88,57 @@ def tag(request, tag):
                          mark_safe(_('questions tagged <span class="tag">%(tag)s</span>') % {'tag': tag}),
                          request.utils.set_sort_method('active'),
                          None,
                          mark_safe(_('questions tagged <span class="tag">%(tag)s</span>') % {'tag': tag}),
                          request.utils.set_sort_method('active'),
                          None,
-                         mark_safe(_('questions tagged %(tag)s') % {'tag': tag}),
+                         mark_safe(_('Questions Tagged With %(tag)s') % {'tag': tag}),
                          False)
 
                          False)
 
-@decorators.list('questions', QUESTIONS_PAGE_SIZE)
-def question_list(request, initial, list_description=_('questions'), sort=None, base_path=None, page_title=None,
-                  allowIgnoreTags=True):
-    questions = initial.filter_state(deleted=False)
+@decorators.render('questions.html', 'questions', tabbed=False)
+def user_questions(request, mode, user, slug):
+    user = get_object_or_404(User, id=user)
+
+    if mode == _('asked-by'):
+        questions = Question.objects.filter(author=user)
+        description = _("Questions asked by %s")
+    elif mode == _('answered-by'):
+        questions = Question.objects.filter(children__author=user, children__node_type='answer').distinct()
+        description = _("Questions answered by %s")
+    elif mode == _('subscribed-by'):
+        if not (request.user.is_superuser or request.user == user):
+            return HttpResponseUnauthorized(request)
+        questions = user.subscriptions
+
+        if request.user == user:
+            description = _("Questions you subscribed %s")
+        else:
+            description = _("Questions subscribed by %s")
+    else:
+        raise Http404
 
 
-    if request.user.is_authenticated() and allowIgnoreTags:
-        questions = questions.filter(~Q(tags__id__in = request.user.marked_tags.filter(user_selections__reason = 'bad'))
-                                     )
 
 
-    if sort is not False:
-        if sort is None:
-            sort = request.utils.sort_method('latest')
-        else:
-            request.utils.set_sort_method(sort)
+    return question_list(request, questions,
+                         mark_safe(description % hyperlink(user.get_profile_url(), user.username)),
+                         request.utils.set_sort_method('active'),
+                         page_title=description % user.username)
 
 
-        view_dic = {"latest":"-added_at", "active":"-last_activity_at", "hottest":"-extra_count", "mostvoted":"-score" }
+def question_list(request, initial,
+                  list_description=_('questions'),
+                  sort=None,
+                  base_path=None,
+                  page_title=_("All Questions"),
+                  allowIgnoreTags=True,
+                  feed_url=None,
+                  paginator_context=None):
 
 
-        questions=questions.order_by(view_dic.get(sort, '-added_at'))
+    questions = initial.filter_state(deleted=False)
+
+    if request.user.is_authenticated() and allowIgnoreTags:
+        questions = questions.filter(~Q(tags__id__in = request.user.marked_tags.filter(user_selections__reason = 'bad')))
 
     if page_title is None:
         page_title = _("Questions")
 
 
     if page_title is None:
         page_title = _("Questions")
 
+    if request.GET.get('type', None) == 'rss':
+        return RssQuestionFeed(questions, page_title, list_description, request)(request)
+
     keywords =  ""
     if request.GET.get("q"):
         keywords = request.GET.get("q").strip()
     keywords =  ""
     if request.GET.get("q"):
         keywords = request.GET.get("q").strip()
@@ -100,18 +146,25 @@ def question_list(request, initial, list_description=_('questions'), sort=None,
     answer_count = Answer.objects.filter_state(deleted=False).filter(parent__in=questions).count()
     answer_description = _("answers")
 
     answer_count = Answer.objects.filter_state(deleted=False).filter(parent__in=questions).count()
     answer_description = _("answers")
 
-    return {
+    if not feed_url:
+        req_params = "&".join(["%s=%s" % (k, v) for k, v in request.GET.items() if not k in (_('page'), _('pagesize'), _('sort'))])
+        if req_params:
+            req_params = '&' + req_params
+
+        feed_url = mark_safe(request.path + "?type=rss" + req_params)
+
+    return pagination.paginated(request, 'questions', paginator_context or QuestionListPaginatorContext(), {
     "questions" : questions,
     "questions_count" : questions.count(),
     "answer_count" : answer_count,
     "keywords" : keywords,
     "questions" : questions,
     "questions_count" : questions.count(),
     "answer_count" : answer_count,
     "keywords" : keywords,
-    #"tags_autocomplete" : _get_tags_cache_json(),
     "list_description": list_description,
     "answer_description": answer_description,
     "base_path" : base_path,
     "page_title" : page_title,
     "tab" : "questions",
     "list_description": list_description,
     "answer_description": answer_description,
     "base_path" : base_path,
     "page_title" : page_title,
     "tab" : "questions",
-    }
+    'feed_url': feed_url,
+    })
 
 
 def search(request):
 
 
 def search(request):
@@ -132,13 +185,24 @@ def search(request):
 
 @decorators.render('questions.html')
 def question_search(request, keywords):
 
 @decorators.render('questions.html')
 def question_search(request, keywords):
-    initial = Question.objects.search(keywords)
+    can_rank, initial = Question.objects.search(keywords)
 
 
-    return question_list(request, initial, _("questions matching '%(keywords)s'") % {'keywords': keywords},
-                         base_path="%s?t=question&q=%s" % (reverse('search'), django_urlquote(keywords)), sort=False)
+    if can_rank:
+        paginator_context = QuestionListPaginatorContext()
+        paginator_context.sort_methods[_('ranking')] = pagination.SimpleSort(_('ranking'), '-ranking', _("most relevant questions"))
+    else:
+        paginator_context = None
+
+    return question_list(request, initial,
+                         _("questions matching '%(keywords)s'") % {'keywords': keywords},
+                         False,
+                         "%s?t=question&q=%s" % (reverse('search'),django_urlquote(keywords)),
+                         _("questions matching '%(keywords)s'") % {'keywords': keywords},
+                         paginator_context=paginator_context)
 
 
 
 
-def tags(request):#view showing a listing of available tags - plain list
+@decorators.render('tags.html', 'tags', _('tags'), weight=100)
+def tags(request):
     stag = ""
     is_paginated = True
     sortby = request.GET.get('sort', 'used')
     stag = ""
     is_paginated = True
     sortby = request.GET.get('sort', 'used')
@@ -162,22 +226,22 @@ def tags(request):#view showing a listing of available tags - plain list
     except (EmptyPage, InvalidPage):
         tags = objects_list.page(objects_list.num_pages)
 
     except (EmptyPage, InvalidPage):
         tags = objects_list.page(objects_list.num_pages)
 
-    return render_to_response('tags.html', {
-    "tags" : tags,
-    "stag" : stag,
-    "tab_id" : sortby,
-    "keywords" : stag,
-    "context" : {
-    'is_paginated' : is_paginated,
-    'pages': objects_list.num_pages,
-    'page': page,
-    'has_previous': tags.has_previous(),
-    'has_next': tags.has_next(),
-    'previous': tags.previous_page_number(),
-    'next': tags.next_page_number(),
-    'base_url' : reverse('tags') + '?sort=%s&' % sortby
+    return {
+        "tags" : tags,
+        "stag" : stag,
+        "tab_id" : sortby,
+        "keywords" : stag,
+        "context" : {
+            'is_paginated' : is_paginated,
+            'pages': objects_list.num_pages,
+            'page': page,
+            'has_previous': tags.has_previous(),
+            'has_next': tags.has_next(),
+            'previous': tags.previous_page_number(),
+            'next': tags.next_page_number(),
+            'base_url' : reverse('tags') + '?sort=%s&' % sortby
+        }
     }
     }
-    }, context_instance=RequestContext(request))
 
 def get_answer_sort_order(request):
     view_dic = {"latest":"-added_at", "oldest":"added_at", "votes":"-score" }
 
 def get_answer_sort_order(request):
     view_dic = {"latest":"-added_at", "oldest":"added_at", "votes":"-score" }
@@ -281,11 +345,10 @@ REVISION_TEMPLATE = template.loader.get_template('node/revision.html')
 def revisions(request, id):
     post = get_object_or_404(Node, id=id).leaf
     revisions = list(post.revisions.order_by('revised_at'))
 def revisions(request, id):
     post = get_object_or_404(Node, id=id).leaf
     revisions = list(post.revisions.order_by('revised_at'))
-
     rev_ctx = []
 
     for i, revision in enumerate(revisions):
     rev_ctx = []
 
     for i, revision in enumerate(revisions):
-        rev_ctx.append(dict(inst=revision, html=REVISION_TEMPLATE.render(template.Context({
+        rev_ctx.append(dict(inst=revision, html=template.loader.get_template('node/revision.html').render(template.Context({
         'title': revision.title,
         'html': revision.html,
         'tags': revision.tagname_list(),
         'title': revision.title,
         'html': revision.html,
         'tags': revision.tagname_list(),
@@ -301,6 +364,8 @@ def revisions(request, id):
         else:
             rev_ctx[i]['summary'] = revision.summary
 
         else:
             rev_ctx[i]['summary'] = revision.summary
 
+    rev_ctx.reverse()
+
     return render_to_response('revisions.html', {
     'post': post,
     'revisions': rev_ctx,
     return render_to_response('revisions.html', {
     'post': post,
     'revisions': rev_ctx,