From 6b22f44c53cf0d72a7b2b068f51cae01e1129e23 Mon Sep 17 00:00:00 2001 From: hernani Date: Mon, 28 Jun 2010 04:00:20 +0000 Subject: [PATCH] Adds user based question listings and context sensitive rss feeds. git-svn-id: http://svn.osqa.net/svnroot/osqa/trunk@452 0cfe37f9-358a-4d5e-be75-b63607b5c754 --- forum/feed.py | 53 ++++++++--------- forum/models/user.py | 12 ++++ forum/skins/default/templates/questions.html | 2 +- .../skins/default/templates/users/stats.html | 26 ++++++++- forum/urls.py | 12 ++-- forum/views/decorators.py | 6 ++ forum/views/readers.py | 57 +++++++++++++++++-- 7 files changed, 126 insertions(+), 42 deletions(-) diff --git a/forum/feed.py b/forum/feed.py index e74e80e..e00f33b 100644 --- a/forum/feed.py +++ b/forum/feed.py @@ -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 -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 + 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): - return self.link + item.get_absolute_url() + return item.get_absolute_url() 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 Question.objects.filter_state(deleted=False).order_by('-last_activity_at')[:30] - -def main(): - pass - -if __name__ == '__main__': - main() + return self._question_list[:30] diff --git a/forum/models/user.py b/forum/models/user.py index a1481b3..53f9044 100644 --- a/forum/models/user.py +++ b/forum/models/user.py @@ -175,6 +175,18 @@ class User(BaseModel, DjangoUser): 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'%s' % (self.get_profile_url(), self.username) return mark_safe(profile_link) diff --git a/forum/skins/default/templates/questions.html b/forum/skins/default/templates/questions.html index ccd7d83..16ba09f 100644 --- a/forum/skins/default/templates/questions.html +++ b/forum/skins/default/templates/questions.html @@ -14,7 +14,7 @@ {% block content %}
{% question_list_title %} - + {% question_sort_tabs sort_context %}
{% for question in questions %} diff --git a/forum/skins/default/templates/users/stats.html b/forum/skins/default/templates/users/stats.html index 9f12493..35c344a 100644 --- a/forum/skins/default/templates/users/stats.html +++ b/forum/skins/default/templates/users/stats.html @@ -6,11 +6,21 @@ {% 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 %} {% spaceless %}

- {% blocktrans count questions|length as counter %} + {% blocktrans count question_count as counter %} 1 Question {% plural %} {{counter}} Questions @@ -21,12 +31,17 @@ {% for question in questions %} {% question_list_item question favorite_count=yes signature_type=badges %} {% endfor %} + {% if show_more_questions_link %} + + {% endif %}


{% spaceless %}

- {% blocktrans count answers|length as counter %} + {% blocktrans count answer_count as counter %} 1 Answer {% plural %} {{counter}} Answers @@ -50,8 +65,13 @@ {% endfor %} + {% if show_more_answers_link %} + + {% endif %} -
+
{% spaceless %}

diff --git a/forum/urls.py b/forum/urls.py index 1d8b213..c14fa92 100644 --- a/forum/urls.py +++ b/forum/urls.py @@ -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 forum.feed import RssLastestQuestionsFeed from forum.sitemap import QuestionsSitemap from django.utils.translation import ugettext as _ import logging admin.autodiscover() -feeds = { - 'rss': RssLastestQuestionsFeed -} + sitemaps = { 'questions': QuestionsSitemap } @@ -63,6 +60,9 @@ urlpatterns += patterns('', name='related_questions'), url(r'^%s%s$' % (_('questions/'), _('unanswered/')), app.readers.unanswered, name='unanswered'), + url(r'^%s(?P[\w-]+)/(?P\d+)/(?P.+)/$' % _('questions/'), app.readers.user_questions, name="user_questions"), + + url(r'^%s(?P\d+)/%s$' % (_('questions/'), _('edit/')), app.writers.edit_question, name='edit_question'), url(r'^%s(?P\d+)/%s$' % (_('questions/'), _('close/')), app.commands.close, @@ -135,8 +135,6 @@ urlpatterns += patterns('', url(r'^%s(?P\d+)/(?P.+)$' % _('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.*)/$', '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'), @@ -194,7 +192,7 @@ urlpatterns += patterns('', url(r'^%s%s(?P\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.+)$', app.meta.page, name="static_page") ) diff --git a/forum/views/decorators.py b/forum/views/decorators.py index bae9712..4eb832a 100644 --- a/forum/views/decorators.py +++ b/forum/views/decorators.py @@ -13,6 +13,9 @@ def render(template=None, tab=None, tab_title='', weight=500, tabbed=True): def decorated(request, *args, **kwargs): context = func(request, *args, **kwargs) + if isinstance(context, HttpResponse): + return context + if tab is not None: context['tab'] = tab @@ -32,6 +35,9 @@ def list(paginate, default_page_size): def decorated(request, *args, **kwargs): context = func(request, *args, **kwargs) + if isinstance(context, HttpResponse): + return context + pagesize = request.utils.page_size(default_page_size) page = int(request.GET.get('page', 1)) diff --git a/forum/views/readers.py b/forum/views/readers.py index 3d353f1..7a73856 100644 --- a/forum/views/readers.py +++ b/forum/views/readers.py @@ -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 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.http_responses import HttpResponseUnauthorized +from forum.feed import RssQuestionFeed import decorators # used in index page @@ -40,12 +42,21 @@ QUESTIONS_PAGE_SIZE = 30 # 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'), - 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): @@ -67,16 +78,46 @@ def tag(request, tag): mark_safe(_('questions tagged %(tag)s') % {'tag': tag}), request.utils.set_sort_method('active'), None, - mark_safe(_('Questions Tagged With %(tag)s') % {'tag': tag}), + mark_safe(_('Questions Tagged With %(tag)s') % {'tag': tag}), 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"), - allowIgnoreTags=True): + allowIgnoreTags=True, + feed_url=None): questions = initial.filter_state(deleted=False) @@ -97,6 +138,9 @@ def question_list(request, initial, 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() @@ -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") + if not feed_url: + feed_url = request.path + "?type=rss" + 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", + 'feed_url': feed_url, } -- 2.39.5