]> git.openstreetmap.org Git - osqa.git/commitdiff
Adds user based question listings and context sensitive rss feeds.
authorhernani <hernani@0cfe37f9-358a-4d5e-be75-b63607b5c754>
Mon, 28 Jun 2010 04:00:20 +0000 (04:00 +0000)
committerhernani <hernani@0cfe37f9-358a-4d5e-be75-b63607b5c754>
Mon, 28 Jun 2010 04:00:20 +0000 (04:00 +0000)
git-svn-id: http://svn.osqa.net/svnroot/osqa/trunk@452 0cfe37f9-358a-4d5e-be75-b63607b5c754

forum/feed.py
forum/models/user.py
forum/skins/default/templates/questions.html
forum/skins/default/templates/users/stats.html
forum/urls.py
forum/views/decorators.py
forum/views/readers.py

index e74e80e4fdafef45e27181d1935e3f75e281c13d..e00f33b923f3c1eff83420d81a228c96ee14fa1c 100644 (file)
@@ -1,28 +1,35 @@
-#!/usr/bin/env python
-#encoding:utf-8
-#-------------------------------------------------------------------------------
-# Name:        Syndication feed class for subsribtion
-# Purpose:
-#
-# Author:      Mike
-#
-# Created:     29/01/2009
-# Copyright:   (c) CNPROG.COM 2009
-# Licence:     GPL V2
-#-------------------------------------------------------------------------------
-from django.contrib.syndication.feeds import Feed, FeedDoesNotExist
+try:
+    from django.contrib.syndication.views import Feed, FeedDoesNotExist
+    old_version = False
+except:
+    from django.contrib.syndication.feeds import Feed, FeedDoesNotExist
+    old_version = True
+
 from django.utils.translation import ugettext as _
 from models import Question
 from forum import settings
 from django.utils.translation import ugettext as _
 from models import Question
 from forum import settings
-class RssLastestQuestionsFeed(Feed):
-    title = settings.APP_TITLE + _(' - ')+ _('latest questions')
-    link = settings.APP_URL #+ '/' + _('question/')
-    description = settings.APP_DESCRIPTION
-    #ttl = 10
+
+
+class RssQuestionFeed(Feed):
     copyright = settings.APP_COPYRIGHT
 
     copyright = settings.APP_COPYRIGHT
 
+    def __init__(self, question_list, title, description, request):
+        self._title = title
+        self._description = description
+        self._question_list = question_list
+        self._url = request.path
+
+        if old_version:
+            super(Feed, self).__init__(request, '')
+
+    def title(self):
+        return self._title
+
+    def link(self):
+        return self._url
+
     def item_link(self, item):
     def item_link(self, item):
-        return self.link + item.get_absolute_url()
+        return item.get_absolute_url()
 
     def item_author_name(self, item):
         return item.author.username
 
     def item_author_name(self, item):
         return item.author.username
@@ -34,10 +41,4 @@ class RssLastestQuestionsFeed(Feed):
         return item.added_at
 
     def items(self, item):
         return item.added_at
 
     def items(self, item):
-       return Question.objects.filter_state(deleted=False).order_by('-last_activity_at')[:30]
-
-def main():
-    pass
-
-if __name__ == '__main__':
-    main()
+       return self._question_list[:30]
index a1481b3bce9b55f8d0d1a452080fbdbe336e9e39..53f90444c348314415e30b9bfc34a5a4c7f12c6b 100644 (file)
@@ -175,6 +175,18 @@ class User(BaseModel, DjangoUser):
     def get_absolute_url(self):
         return self.get_profile_url()
 
     def get_absolute_url(self):
         return self.get_profile_url()
 
+    @models.permalink
+    def get_asked_url(self):
+        return ('user_questions', (), {'mode': _('asked-by'), 'user': self.id, 'slug': slugify(self.username)})
+
+    @models.permalink
+    def get_answered_url(self):
+        return ('user_questions', (), {'mode': _('answered-by'), 'user': self.id, 'slug': slugify(self.username)})
+
+    @models.permalink
+    def get_subscribed_url(self):
+        return ('user_questions', (), {'mode': _('subscribed-by'), 'user': self.id, 'slug': slugify(self.username)})
+
     def get_profile_link(self):
         profile_link = u'<a href="%s">%s</a>' % (self.get_profile_url(), self.username)
         return mark_safe(profile_link)
     def get_profile_link(self):
         profile_link = u'<a href="%s">%s</a>' % (self.get_profile_url(), self.username)
         return mark_safe(profile_link)
index ccd7d8303df2a1db6a5f1bf5f54281673755fe72..16ba09f26efcb4ce65eca670e1dc67702100d382 100644 (file)
@@ -14,7 +14,7 @@
 {% block content %}\r
 <div class="tabBar">\r
     {% question_list_title %}\r
 {% block content %}\r
 <div class="tabBar">\r
     {% question_list_title %}\r
-    <a style="float:left" href="{% url latest_questions_feed %}" title="{% trans "subscribe to question RSS feed" %}"><img src="{% media "media/images/feed-icon-small.png" %}" alt=""></a>\r
+    <a style="float:left" href="{{ feed_url }}" title="{% trans "subscribe to question RSS feed" %}"><img src="{% media "media/images/feed-icon-small.png" %}" alt=""></a>\r
     {% question_sort_tabs sort_context %}\r
 </div>\r
 <div id="listA">{% for question in questions %}\r
     {% question_sort_tabs sort_context %}\r
 </div>\r
 <div id="listA">{% for question in questions %}\r
index 9f12493c8a9b680d7896999f9f48c0beeb77b886..35c344adc5bb1145a8a855858f34f6cacbd4896f 100644 (file)
@@ -6,11 +6,21 @@
 {% load humanize %}
 {% load question_list_tags %}
                {% block usercontent %}
 {% load humanize %}
 {% load question_list_tags %}
                {% block usercontent %}
+
+               {% declare %}
+                   question_count = questions.count()
+                   show_more_questions_link = question_count > 15
+                   questions = questions[:15]
+
+                   answer_count = answers.count()
+                   show_more_answers_link = answer_count > 30
+                   answers = answers[:30]
+               {% enddeclare %}
        
         <a name="questions"></a>
         {% spaceless %}
             <h2>
        
         <a name="questions"></a>
         {% spaceless %}
             <h2>
-                {% blocktrans count questions|length as counter %}
+                {% blocktrans count question_count as counter %}
                 <span class="count">1</span> Question
                 {% plural %}
                 <span class="count">{{counter}}</span> Questions
                 <span class="count">1</span> Question
                 {% plural %}
                 <span class="count">{{counter}}</span> Questions
                    {% for question in questions %}
                        {% question_list_item question favorite_count=yes signature_type=badges %}
                    {% endfor %}
                    {% for question in questions %}
                        {% question_list_item question favorite_count=yes signature_type=badges %}
                    {% endfor %}
+            {% if show_more_questions_link %}
+                <div class="short-summary"  style="text-align: right">
+                    <a href="{{ view_user.get_asked_url }}">{% blocktrans with view_user.username as username %}View all questions by {{ username }}{% endblocktrans %}</a>
+                </div>
+            {% endif %}
                </div>
                <br clear="all"/>
         <a name="answers"></a>
         {% spaceless %}
             <h2>
                </div>
                <br clear="all"/>
         <a name="answers"></a>
         {% spaceless %}
             <h2>
-                {% blocktrans count answers|length as counter %}
+                {% blocktrans count answer_count as counter %}
                 <span class="count">1</span> Answer
                 {% plural %}
                 <span class="count">{{counter}}</span> Answers
                 <span class="count">1</span> Answer
                 {% plural %}
                 <span class="count">{{counter}}</span> Answers
                 </div>
             </div>
             {% endfor %}
                 </div>
             </div>
             {% endfor %}
+            {% if show_more_answers_link %}
+                <div class="short-summary"  style="text-align: right">
+                    <a href="{{ view_user.get_answered_url }}">{% blocktrans with view_user.username as username %}View all questions answered by {{ username }}{% endblocktrans %}</a>
+                </div>
+            {% endif %}
         </div>
         </div>
-        <br/>
+        <br clear="all"/>
         <a name="votes"></a>
         {% spaceless %}
             <h2>
         <a name="votes"></a>
         {% spaceless %}
             <h2>
index 1d8b213e5b2f5d77ba134f3bb8170c05be71274a..c14fa92f4fb598f4362f5760f7ae70a64529db3a 100644 (file)
@@ -6,15 +6,12 @@ from django.conf.urls.defaults import *
 from django.conf import settings as djsettings
 from django.contrib import admin
 from forum import views as app
 from django.conf import settings as djsettings
 from django.contrib import admin
 from forum import views as app
-from forum.feed import RssLastestQuestionsFeed
 from forum.sitemap import QuestionsSitemap
 from django.utils.translation import ugettext as _
 import logging
 
 admin.autodiscover()
 from forum.sitemap import QuestionsSitemap
 from django.utils.translation import ugettext as _
 import logging
 
 admin.autodiscover()
-feeds = {
-    'rss': RssLastestQuestionsFeed
-}
+
 sitemaps = {
     'questions': QuestionsSitemap
 }
 sitemaps = {
     'questions': QuestionsSitemap
 }
@@ -63,6 +60,9 @@ urlpatterns += patterns('',
                             name='related_questions'),
 
                         url(r'^%s%s$' % (_('questions/'), _('unanswered/')), app.readers.unanswered, name='unanswered'),
                             name='related_questions'),
 
                         url(r'^%s%s$' % (_('questions/'), _('unanswered/')), app.readers.unanswered, name='unanswered'),
+                        url(r'^%s(?P<mode>[\w-]+)/(?P<user>\d+)/(?P<slug>.+)/$' % _('questions/'), app.readers.user_questions, name="user_questions"),
+
+
                         url(r'^%s(?P<id>\d+)/%s$' % (_('questions/'), _('edit/')), app.writers.edit_question,
                             name='edit_question'),
                         url(r'^%s(?P<id>\d+)/%s$' % (_('questions/'), _('close/')), app.commands.close,
                         url(r'^%s(?P<id>\d+)/%s$' % (_('questions/'), _('edit/')), app.writers.edit_question,
                             name='edit_question'),
                         url(r'^%s(?P<id>\d+)/%s$' % (_('questions/'), _('close/')), app.commands.close,
@@ -135,8 +135,6 @@ urlpatterns += patterns('',
                         url(r'^%s(?P<id>\d+)/(?P<slug>.+)$' % _('badges/'), app.meta.badge, name='badge'),
                         # (r'^admin/doc/' % _('admin/doc'), include('django.contrib.admindocs.urls')),
                         url(r'^%s(.*)' % _('nimda/'), admin.site.root, name='osqa_admin'),
                         url(r'^%s(?P<id>\d+)/(?P<slug>.+)$' % _('badges/'), app.meta.badge, name='badge'),
                         # (r'^admin/doc/' % _('admin/doc'), include('django.contrib.admindocs.urls')),
                         url(r'^%s(.*)' % _('nimda/'), admin.site.root, name='osqa_admin'),
-                        url(r'^feeds/(?P<url>.*)/$', 'django.contrib.syndication.views.feed', {'feed_dict': feeds},
-                            name='feeds'),
                         url(r'^%s$' % _('upload/'), app.writers.upload, name='upload'),
                         url(r'^%s$' % _('search/'), app.readers.search, name='search'),
                         url(r'^%s$' % _('contact/'), app.meta.feedback, name='feedback'),
                         url(r'^%s$' % _('upload/'), app.writers.upload, name='upload'),
                         url(r'^%s$' % _('search/'), app.readers.search, name='search'),
                         url(r'^%s$' % _('contact/'), app.meta.feedback, name='feedback'),
@@ -194,7 +192,7 @@ urlpatterns += patterns('',
                         url(r'^%s%s(?P<set_name>\w+)/$' % (_('admin/'), _('settings/')), app.admin.settings_set,
                             name="admin_set"),
 
                         url(r'^%s%s(?P<set_name>\w+)/$' % (_('admin/'), _('settings/')), app.admin.settings_set,
                             name="admin_set"),
 
-                        url(r'^feeds/rss/$', RssLastestQuestionsFeed, name="latest_questions_feed"),
+                        url(r'^feeds/rss/$', app.readers.feed, name="latest_questions_feed"),
 
                         url(r'^(?P<path>.+)$', app.meta.page, name="static_page")
                         )
 
                         url(r'^(?P<path>.+)$', app.meta.page, name="static_page")
                         )
index bae9712332e50a4dce652b0b6b1f996d54326c8f..4eb832a4ab1ea7d6e03c796bcf9d149eeaead29b 100644 (file)
@@ -13,6 +13,9 @@ def render(template=None, tab=None, tab_title='', weight=500, tabbed=True):
         def decorated(request, *args, **kwargs):\r
             context = func(request, *args, **kwargs)\r
 \r
         def decorated(request, *args, **kwargs):\r
             context = func(request, *args, **kwargs)\r
 \r
+            if isinstance(context, HttpResponse):\r
+                return context\r
+\r
             if tab is not None:\r
                 context['tab'] = tab\r
 \r
             if tab is not None:\r
                 context['tab'] = tab\r
 \r
@@ -32,6 +35,9 @@ def list(paginate, default_page_size):
         def decorated(request, *args, **kwargs):\r
             context = func(request, *args, **kwargs)\r
 \r
         def decorated(request, *args, **kwargs):\r
             context = func(request, *args, **kwargs)\r
 \r
+            if isinstance(context, HttpResponse):\r
+                return context\r
+\r
             pagesize = request.utils.page_size(default_page_size)\r
             page = int(request.GET.get('page', 1))\r
 \r
             pagesize = request.utils.page_size(default_page_size)\r
             page = int(request.GET.get('page', 1))\r
 \r
index 3d353f184552bdbb1ef19c7702f2b5395ed5ffdc..7a73856317486c23def9391a8c6a1462815e00b9 100644 (file)
@@ -20,12 +20,14 @@ 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.forms import *
 from forum.models import *
 from forum.forms import get_next_url
 from forum.actions import QuestionViewAction
 from forum.utils.diff import textDiff as htmldiff
 from forum.forms import *
 from forum.models import *
 from forum.forms import get_next_url
 from forum.actions import QuestionViewAction
+from forum.http_responses import HttpResponseUnauthorized
+from forum.feed import RssQuestionFeed
 import decorators
 
 # used in index page
 import decorators
 
 # used in index page
@@ -40,12 +42,21 @@ QUESTIONS_PAGE_SIZE = 30
 # used in answers
 ANSWERS_PAGE_SIZE = 10
 
 # used in answers
 ANSWERS_PAGE_SIZE = 10
 
+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', _('unanswered'), weight=400)
 def unanswered(request):
 
 @decorators.render('questions.html', 'unanswered', _('unanswered'), weight=400)
 def unanswered(request):
@@ -67,16 +78,46 @@ 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 With <span class="tag">%(tag)s</span>') % {'tag': tag}),
+                         mark_safe(_('Questions Tagged With %(tag)s') % {'tag': tag}),
                          False)
 
                          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
+
+
+    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)
+
+
 @decorators.list('questions', QUESTIONS_PAGE_SIZE)
 def question_list(request, initial,
                   list_description=_('questions'),
                   sort=None,
                   base_path=None,
                   page_title=_("All Questions"),
 @decorators.list('questions', QUESTIONS_PAGE_SIZE)
 def question_list(request, initial,
                   list_description=_('questions'),
                   sort=None,
                   base_path=None,
                   page_title=_("All Questions"),
-                  allowIgnoreTags=True):
+                  allowIgnoreTags=True,
+                  feed_url=None):
 
     questions = initial.filter_state(deleted=False)
 
 
     questions = initial.filter_state(deleted=False)
 
@@ -97,6 +138,9 @@ def question_list(request, initial,
     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()
@@ -104,17 +148,20 @@ def question_list(request, initial,
     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")
 
+    if not feed_url:
+        feed_url = request.path + "?type=rss"
+
     return {
     "questions" : questions,
     "questions_count" : questions.count(),
     "answer_count" : answer_count,
     "keywords" : keywords,
     return {
     "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,
     }
 
 
     }