From f67ed6b73eb18750acb921d08f414b5d6af78ef6 Mon Sep 17 00:00:00 2001 From: Sayan Chowdhury Date: Wed, 28 Sep 2011 08:36:14 +0530 Subject: added rss feed for particular question --- askbot/feed.py | 48 +++++++++++++++++++++++++++- askbot/skins/default/templates/question.html | 6 ++++ askbot/urls.py | 5 +-- 3 files changed, 56 insertions(+), 3 deletions(-) diff --git a/askbot/feed.py b/askbot/feed.py index 23416677..61fd0d3a 100644 --- a/askbot/feed.py +++ b/askbot/feed.py @@ -14,8 +14,54 @@ #encoding:utf-8 from django.contrib.syndication.feeds import Feed from django.utils.translation import ugettext as _ -from askbot.models import Question +from django.core.exceptions import ObjectDoesNotExist +from askbot.models import Question, Answer, Comment from askbot.conf import settings as askbot_settings +import itertools + +class RssParticularQuestionFeed(Feed): + """rss feed class for particular questions + """ + title = askbot_settings.APP_TITLE + _(' - ')+ _('Particular Question') + link = askbot_settings.APP_URL + description = askbot_settings.APP_DESCRIPTION + copyright = askbot_settings.APP_COPYRIGHT + + def get_object(self, bits): + if len(bits) != 1: + raise ObjectDoesNotExist + return Question.objects.get(id__exact = bits[0]) + + def item_link(self, item): + """get full url to the item + """ + return self.link + item.get_absolute_url() + + def item_pubdate(self, item): + """get date of creation for the item + """ + return item.added_at + + def items(self, item): + """get questions for the feed + """ + results = itertools.chain( + Question.objects.filter(id = item.id), + Answer.objects.filter(question = item.id), + Comment.objects.filter(question = item.id), + ) + return results + + def item_title(self, item): + title = item + if item.__class__.__name__ == "Question": + self.title = item + if item.__class__.__name__ == "Answer": + title = "Answer for %s " %self.title + elif item.__class__.__name__ == "Comment": + title = "Comment for %s" %self.title + return title + class RssLastestQuestionsFeed(Feed): """rss feed class for the latest questions """ diff --git a/askbot/skins/default/templates/question.html b/askbot/skins/default/templates/question.html index 06cd1332..376cd058 100644 --- a/askbot/skins/default/templates/question.html +++ b/askbot/skins/default/templates/question.html @@ -12,6 +12,12 @@ {% endblock %} {% block content %}

{{ question.get_question_title() }}

+

+ ({% trans %}rss feed{% endtrans %}) +

diff --git a/askbot/urls.py b/askbot/urls.py index 54c50d96..8b435c56 100644 --- a/askbot/urls.py +++ b/askbot/urls.py @@ -8,7 +8,7 @@ from django.conf.urls.defaults import handler500, handler404 from django.contrib import admin from django.utils.translation import ugettext as _ from askbot import views -from askbot.feed import RssLastestQuestionsFeed +from askbot.feed import RssLastestQuestionsFeed, RssParticularQuestionFeed from askbot.sitemap import QuestionsSitemap from askbot.skins.utils import update_media_revision @@ -16,7 +16,8 @@ admin.autodiscover() update_media_revision()#needs to be run once, so put it here feeds = { - 'rss': RssLastestQuestionsFeed + 'rss': RssLastestQuestionsFeed, + 'question':RssParticularQuestionFeed } sitemaps = { 'questions': QuestionsSitemap -- cgit v1.2.3-1-g7c22 From a822dec80256a53ba9770be2c9e5cf8ce48bfca1 Mon Sep 17 00:00:00 2001 From: Sayan Chowdhury Date: Wed, 28 Sep 2011 12:12:57 +0530 Subject: added item description in rss feed and changed the format in rss feed of particular question --- askbot/feed.py | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/askbot/feed.py b/askbot/feed.py index 61fd0d3a..c4257ab9 100644 --- a/askbot/feed.py +++ b/askbot/feed.py @@ -53,14 +53,26 @@ class RssParticularQuestionFeed(Feed): return results def item_title(self, item): + """returns the title for the item + """ title = item if item.__class__.__name__ == "Question": self.title = item - if item.__class__.__name__ == "Answer": - title = "Answer for %s " %self.title + elif item.__class__.__name__ == "Answer": + title = "Answer by %s for %s " %(item.author,self.title) elif item.__class__.__name__ == "Comment": - title = "Comment for %s" %self.title + title = "Comment by %s for %s" %(item.user,self.title) return title + + def item_description(self,item): + """returns the description for the item + """ + if item.__class__.__name__ == "Question": + return item.text + if item.__class__.__name__ == "Answer": + return item.text + elif item.__class__.__name__ == "Comment": + return item.comment class RssLastestQuestionsFeed(Feed): """rss feed class for the latest questions @@ -96,6 +108,11 @@ class RssLastestQuestionsFeed(Feed): because the slug can change """ return self.link + item.get_absolute_url(no_slug = True) + + def item_description(self, item): + """returns the desciption for the item + """ + return item.text def items(self, item): """get questions for the feed -- cgit v1.2.3-1-g7c22 From f0a889b97eba513f576ad61c850ce08b3d580859 Mon Sep 17 00:00:00 2001 From: Raghu Udiyar Date: Thu, 29 Sep 2011 03:17:52 +0530 Subject: Greeting for anonymous users can be disabled from live settings --- askbot/conf/site_settings.py | 9 +++++++++ askbot/middleware/anon_user.py | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/askbot/conf/site_settings.py b/askbot/conf/site_settings.py index 0cab800b..30a033ca 100644 --- a/askbot/conf/site_settings.py +++ b/askbot/conf/site_settings.py @@ -69,6 +69,15 @@ settings.register( ) ) +settings.register( + livesettings.BooleanValue( + QA_SITE_SETTINGS, + 'GREETING_FOR_ANON_USER_ON', + default = True, + description = _('Check to enable greeting for anonymous user') + ) +) + settings.register( livesettings.StringValue( QA_SITE_SETTINGS, diff --git a/askbot/middleware/anon_user.py b/askbot/middleware/anon_user.py index d1e223b7..4b72ab4a 100644 --- a/askbot/middleware/anon_user.py +++ b/askbot/middleware/anon_user.py @@ -43,7 +43,8 @@ class ConnectToSessionMessagesMiddleware(object): #also set the first greeting one time per session only if 'greeting_set' not in request.session and \ - 'askbot_visitor' not in request.COOKIES: + 'askbot_visitor' not in request.COOKIES and \ + askbot_settings.GREETING_FOR_ANON_USER_ON: request.session['greeting_set'] = True msg = askbot_settings.GREETING_FOR_ANONYMOUS_USER request.user.message_set.create(message=msg) -- cgit v1.2.3-1-g7c22 From 028a0456080a903b8d8cc81a260be792d800e42e Mon Sep 17 00:00:00 2001 From: Evgeny Fadeev Date: Mon, 3 Oct 2011 17:25:01 -0300 Subject: pylinted the anonymous user middleware and renamed the setting enabling the anonymous user greeting --- askbot/conf/site_settings.py | 2 +- askbot/db | 0 askbot/middleware/anon_user.py | 24 +++++++++++++++++------- 3 files changed, 18 insertions(+), 8 deletions(-) create mode 100644 askbot/db diff --git a/askbot/conf/site_settings.py b/askbot/conf/site_settings.py index 30a033ca..e1f54d39 100644 --- a/askbot/conf/site_settings.py +++ b/askbot/conf/site_settings.py @@ -72,7 +72,7 @@ settings.register( settings.register( livesettings.BooleanValue( QA_SITE_SETTINGS, - 'GREETING_FOR_ANON_USER_ON', + 'ENABLE_GREETING_FOR_ANON_USER', default = True, description = _('Check to enable greeting for anonymous user') ) diff --git a/askbot/db b/askbot/db new file mode 100644 index 00000000..e69de29b diff --git a/askbot/middleware/anon_user.py b/askbot/middleware/anon_user.py index 4b72ab4a..adaf6fd2 100644 --- a/askbot/middleware/anon_user.py +++ b/askbot/middleware/anon_user.py @@ -21,6 +21,8 @@ class AnonymousMessageManager(object): create_message(self.request, message) def get_and_delete(self): + """returns messages sent to the anonymous user + via session, and removes messages from the session""" messages = get_and_delete_messages(self.request) return messages @@ -31,9 +33,17 @@ def dummy_deepcopy(*arg): return None class ConnectToSessionMessagesMiddleware(object): - """middleware that attaches messages to anonymous users""" + """Middleware that attaches messages to anonymous users, and + makes sure that anonymous user greeting is shown just once. + Middleware does not do anything if the anonymous user greeting + is disabled. + """ def process_request(self, request): - if not request.user.is_authenticated(): + """Enables anonymous users to receive messages + the same way as authenticated users, and sets + the anonymous user greeting, if it should be shown""" + if request.user.is_anonymous(): + #1) Attach the ability to receive messages #plug on deepcopy which may be called by django db "driver" request.user.__deepcopy__ = dummy_deepcopy #here request is linked to anon user @@ -41,17 +51,18 @@ class ConnectToSessionMessagesMiddleware(object): request.user.get_and_delete_messages = \ request.user.message_set.get_and_delete - #also set the first greeting one time per session only + #2) set the first greeting one time per session only if 'greeting_set' not in request.session and \ 'askbot_visitor' not in request.COOKIES and \ - askbot_settings.GREETING_FOR_ANON_USER_ON: + askbot_settings.ENABLE_GREETING_FOR_ANON_USER: request.session['greeting_set'] = True msg = askbot_settings.GREETING_FOR_ANONYMOUS_USER request.user.message_set.create(message=msg) def process_response(self, request, response): - """ Adds the ``'askbot_visitor'``key to cookie if user ever authenticates so - that the anonymous user message won't be shown. """ + """Adds the ``'askbot_visitor'``key to cookie if user ever + authenticates so that the anonymous user message won't + be shown after the user logs out""" if request.user.is_authenticated() and \ 'askbot_visitor' not in request.COOKIES : #import datetime @@ -62,4 +73,3 @@ class ConnectToSessionMessagesMiddleware(object): # "%a, %d-%b-%Y %H:%M:%S GMT") response.set_cookie('askbot_visitor', False) return response - -- cgit v1.2.3-1-g7c22 From a203bac98a4b035c26d2b19c0c09c28a55a7d102 Mon Sep 17 00:00:00 2001 From: Evgeny Fadeev Date: Mon, 3 Oct 2011 17:37:20 -0300 Subject: updated the docs and added raags to the list of contributors --- askbot/doc/source/changelog.rst | 1 + askbot/doc/source/contributors.rst | 1 + 2 files changed, 2 insertions(+) diff --git a/askbot/doc/source/changelog.rst b/askbot/doc/source/changelog.rst index 33a0199c..769654e2 100644 --- a/askbot/doc/source/changelog.rst +++ b/askbot/doc/source/changelog.rst @@ -3,6 +3,7 @@ Changes in Askbot Development version (not released yet) -------------------------------------- +* Made it possible to disable the anonymous user greeting alltogether (Raghu Udiyar) * Added annotations for the meanings of user levels on the "moderation" page. (Jishnu) * Auto-link patterns - e.g. to bug databases - are configurable from settings. (Arun SAG) diff --git a/askbot/doc/source/contributors.rst b/askbot/doc/source/contributors.rst index fb8d9690..41e7d9a5 100644 --- a/askbot/doc/source/contributors.rst +++ b/askbot/doc/source/contributors.rst @@ -24,6 +24,7 @@ Programming and documentation * `Rag Sagar `_ * Alex Robbins (celery support) * `Tomasz Szynalski `_ +* `Raghu Udiyar `_ Translations ------------ -- cgit v1.2.3-1-g7c22 From d95fc57baed664bce87bc7c233cf58ab66c58123 Mon Sep 17 00:00:00 2001 From: Evgeny Fadeev Date: Mon, 3 Oct 2011 17:51:54 -0300 Subject: hopefully fixed a bug reported at http://askbot.org/en/question/666/askbot-0722-to-0723-update-issue --- askbot/skins/default/templates/macros.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/askbot/skins/default/templates/macros.html b/askbot/skins/default/templates/macros.html index afa7b264..c56d1cc4 100644 --- a/askbot/skins/default/templates/macros.html +++ b/askbot/skins/default/templates/macros.html @@ -282,11 +282,11 @@ poor design of the data or methods on data objects #} {% endif %} {% elif contributor_type=="last_updater" %} - {% if post.post_type in ('Question', 'Answer') %} + {% if post.post_type in ('question', 'answer') %} {% set last_edited_at = post.last_edited_at %} {% set original_author = post.author %} {% set update_author = post.last_edited_by %} - {% elif post.post_type in ('QuestionRevision', 'AnswerRevision') %} + {% elif post.__class__.__name__ in ('QuestionRevision', 'AnswerRevision') %} {% set last_edited_at = post.revised_at %} {% set original_author = None %}{# fake value to force display widget in the revision views #} {% set update_author = post.author %} @@ -295,7 +295,7 @@ poor design of the data or methods on data objects #}

Date: Mon, 3 Oct 2011 19:20:27 -0300 Subject: incremented a version and fixed a bug the comment editing --- askbot/__init__.py | 2 +- askbot/doc/source/changelog.rst | 8 ++++---- askbot/views/writers.py | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/askbot/__init__.py b/askbot/__init__.py index 5ced4ca1..b4889f92 100644 --- a/askbot/__init__.py +++ b/askbot/__init__.py @@ -9,7 +9,7 @@ import smtplib import sys import logging -VERSION = (0, 7, 23) +VERSION = (0, 7, 24) #necessary for interoperability of django and coffin try: diff --git a/askbot/doc/source/changelog.rst b/askbot/doc/source/changelog.rst index 769654e2..1ee5b197 100644 --- a/askbot/doc/source/changelog.rst +++ b/askbot/doc/source/changelog.rst @@ -1,14 +1,14 @@ Changes in Askbot ================= -Development version (not released yet) --------------------------------------- +0.7.24 (Current Version) +------------------------ * Made it possible to disable the anonymous user greeting alltogether (Raghu Udiyar) * Added annotations for the meanings of user levels on the "moderation" page. (Jishnu) * Auto-link patterns - e.g. to bug databases - are configurable from settings. (Arun SAG) -0.7.23 (Current Version) ------------------------- +0.7.23 +------ * Greeting for anonymuos users can be changed from live settings (Hrishi) * Greeting for anonymous users is shown only once (Rag Sagar) * Added support for Akismet spam detection service (Adolfo Fitoria) diff --git a/askbot/views/writers.py b/askbot/views/writers.py index fcc98761..d64c9c02 100644 --- a/askbot/views/writers.py +++ b/askbot/views/writers.py @@ -604,7 +604,7 @@ def post_comments(request):#generic ajax handler to load comments to an object raise Http404 @decorators.ajax_only -@decorators.check_spam('text') +@decorators.check_spam('comment') def edit_comment(request): if request.user.is_authenticated(): comment_id = int(request.POST['comment_id']) -- cgit v1.2.3-1-g7c22 From c07b6b3a05778c5739a0f974e4e1822fff843910 Mon Sep 17 00:00:00 2001 From: Evgeny Fadeev Date: Mon, 3 Oct 2011 21:20:10 -0300 Subject: modified the individiual question feature, added Sayan Chowdhury to the list of contributors --- askbot/doc/source/changelog.rst | 4 ++ askbot/doc/source/contributors.rst | 7 +-- askbot/feed.py | 72 ++++++++++++++++++---------- askbot/skins/default/media/style/style.css | 12 +++++ askbot/skins/default/templates/question.html | 28 +++++------ askbot/urls.py | 23 +++++++-- 6 files changed, 98 insertions(+), 48 deletions(-) diff --git a/askbot/doc/source/changelog.rst b/askbot/doc/source/changelog.rst index 1ee5b197..77ff4a45 100644 --- a/askbot/doc/source/changelog.rst +++ b/askbot/doc/source/changelog.rst @@ -1,6 +1,10 @@ Changes in Askbot ================= +Development version (Not yet released) +-------------------------------------- +* RSS feed for individual question (Sayan Chowdhury) + 0.7.24 (Current Version) ------------------------ * Made it possible to disable the anonymous user greeting alltogether (Raghu Udiyar) diff --git a/askbot/doc/source/contributors.rst b/askbot/doc/source/contributors.rst index 41e7d9a5..c372977d 100644 --- a/askbot/doc/source/contributors.rst +++ b/askbot/doc/source/contributors.rst @@ -11,18 +11,19 @@ Programming and documentation * Mike Chen & Sailing Cai - original authors of CNPROG forum * Evgeny Fadeev - founder of askbot * `Adolfo Fitoria `_ -* `Arun SAG `_ +* `Sayan Chowdhury `_ * Andy Knotts * Benoit Lavine (with Windriver Software, Inc.) * Jeff Madynski * `Jishnu `_ * `Hrishi `_ * Andrei Mamoutkine -* Ramiro Morales (with Machinalis) +* `Ramiro Morales `_ (with Machinalis) * `NoahY `_ * `Gael Pasgrimaud `_ (bearstech) +* `Arun SAG `_ * `Rag Sagar `_ -* Alex Robbins (celery support) +* `Alex Robbins `_ * `Tomasz Szynalski `_ * `Raghu Udiyar `_ diff --git a/askbot/feed.py b/askbot/feed.py index c4257ab9..e0c69454 100644 --- a/askbot/feed.py +++ b/askbot/feed.py @@ -13,16 +13,17 @@ #!/usr/bin/env python #encoding:utf-8 from django.contrib.syndication.feeds import Feed +from django.contrib.contenttypes.models import ContentType from django.utils.translation import ugettext as _ from django.core.exceptions import ObjectDoesNotExist from askbot.models import Question, Answer, Comment from askbot.conf import settings as askbot_settings import itertools -class RssParticularQuestionFeed(Feed): +class RssIndividualQuestionFeed(Feed): """rss feed class for particular questions """ - title = askbot_settings.APP_TITLE + _(' - ')+ _('Particular Question') + title = askbot_settings.APP_TITLE + _(' - ')+ _('Individual question feed') link = askbot_settings.APP_URL description = askbot_settings.APP_DESCRIPTION copyright = askbot_settings.APP_COPYRIGHT @@ -43,35 +44,54 @@ class RssParticularQuestionFeed(Feed): return item.added_at def items(self, item): - """get questions for the feed - """ - results = itertools.chain( - Question.objects.filter(id = item.id), - Answer.objects.filter(question = item.id), - Comment.objects.filter(question = item.id), - ) - return results + """get content items for the feed + ordered as: question, question comments, + then for each answer - the answer itself, then + answer comments + """ + + chain_elements = list() + chain_elements.append([item,]) + chain_elements.append( + Comment.objects.filter( + object_id = item.id, + content_type = ContentType.objects.get_for_model(Question) + ) + ) + + answer_content_type = ContentType.objects.get_for_model(Answer) + answers = Answer.objects.filter(question = item.id) + for answer in answers: + chain_elements.append([answer,]) + chain_elements.append( + Comment.objects.filter( + object_id = answer.id, + content_type = answer_content_type + ) + ) + + return itertools.chain(*chain_elements) def item_title(self, item): - """returns the title for the item - """ + """returns the title for the item + """ title = item - if item.__class__.__name__ == "Question": + if item.post_type == "question": self.title = item - elif item.__class__.__name__ == "Answer": - title = "Answer by %s for %s " %(item.author,self.title) - elif item.__class__.__name__ == "Comment": - title = "Comment by %s for %s" %(item.user,self.title) + elif item.post_type == "answer": + title = "Answer by %s for %s " % (item.author, self.title) + elif item.post_type == "comment": + title = "Comment by %s for %s" % (item.user, self.title) return title - def item_description(self,item): - """returns the description for the item - """ - if item.__class__.__name__ == "Question": + def item_description(self, item): + """returns the description for the item + """ + if item.post_type == "question": return item.text - if item.__class__.__name__ == "Answer": + if item.post_type == "answer": return item.text - elif item.__class__.__name__ == "Comment": + elif item.post_type == "comment": return item.comment class RssLastestQuestionsFeed(Feed): @@ -110,9 +130,9 @@ class RssLastestQuestionsFeed(Feed): return self.link + item.get_absolute_url(no_slug = True) def item_description(self, item): - """returns the desciption for the item - """ - return item.text + """returns the desciption for the item + """ + return item.text def items(self, item): """get questions for the feed diff --git a/askbot/skins/default/media/style/style.css b/askbot/skins/default/media/style/style.css index 1431135f..478f5116 100644 --- a/askbot/skins/default/media/style/style.css +++ b/askbot/skins/default/media/style/style.css @@ -792,6 +792,18 @@ p.rss a { background: url(../images/feed-icon-small.png) no-repeat; } +.question-page p.rss { + float:none; + clear:both; + padding: 3px 0 0 1px; + font-size: 14px; +} + +.question-page p.rss a { + padding-left: 18px; + vertical-align: top; +} + /* badges */ a.medal { font-size: 14px; diff --git a/askbot/skins/default/templates/question.html b/askbot/skins/default/templates/question.html index 376cd058..91287bdb 100644 --- a/askbot/skins/default/templates/question.html +++ b/askbot/skins/default/templates/question.html @@ -12,12 +12,6 @@ {% endblock %} {% block content %}

{{ question.get_question_title() }}

-

- ({% trans %}rss feed{% endtrans %}) -

@@ -412,14 +406,20 @@ {% trans count=follower_count %}{{count}} follower{% pluralize %}{{count}} followers{% endtrans %} {% endif %} -
- {%if request.user.is_authenticated() %} - - - {%else%} - - - {%endif%} +
+ {%if request.user.is_authenticated() %} + + + {%else%} + + + {%endif%} +

+ {% trans %}subsribe to rss feed{% endtrans %} +

{% cache 0 "questions_tags" questions_tags question.id language_code %} diff --git a/askbot/urls.py b/askbot/urls.py index 8b435c56..c79f4f83 100644 --- a/askbot/urls.py +++ b/askbot/urls.py @@ -8,7 +8,7 @@ from django.conf.urls.defaults import handler500, handler404 from django.contrib import admin from django.utils.translation import ugettext as _ from askbot import views -from askbot.feed import RssLastestQuestionsFeed, RssParticularQuestionFeed +from askbot.feed import RssLastestQuestionsFeed, RssIndividualQuestionFeed from askbot.sitemap import QuestionsSitemap from askbot.skins.utils import update_media_revision @@ -17,7 +17,7 @@ update_media_revision()#needs to be run once, so put it here feeds = { 'rss': RssLastestQuestionsFeed, - 'question':RssParticularQuestionFeed + 'question':RssIndividualQuestionFeed } sitemaps = { 'questions': QuestionsSitemap @@ -40,7 +40,12 @@ urlpatterns = patterns('', url( r'^%s(?P.*)$' % settings.ASKBOT_UPLOADED_FILES_URL, 'django.views.static.serve', - {'document_root': os.path.join(settings.PROJECT_ROOT, 'askbot', 'upfiles').replace('\\','/')}, + {'document_root': os.path.join( + settings.PROJECT_ROOT, + 'askbot', + 'upfiles' + ).replace('\\','/') + }, name='uploaded_file', ), #no translation for this url!! @@ -299,8 +304,16 @@ if 'avatar' in settings.INSTALLED_APPS: #use jinja2 templates urlpatterns += ( url('^avatar/add/$', views.avatar_views.add, name='avatar_add'), - url('^avatar/change/$', views.avatar_views.change, name='avatar_change'), - url('^avatar/delete/$', views.avatar_views.delete, name='avatar_delete'), + url( + '^avatar/change/$', + views.avatar_views.change, + name='avatar_change' + ), + url( + '^avatar/delete/$', + views.avatar_views.delete, + name='avatar_delete' + ), url(#this urs we inherit from the original avatar app '^avatar/render_primary/(?P[\+\d]+)/(?P[\d]+)/$', views.avatar_views.render_primary, -- cgit v1.2.3-1-g7c22