summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MANIFEST.in1
-rw-r--r--askbot/__init__.py2
-rw-r--r--askbot/conf/site_settings.py19
-rw-r--r--askbot/const/__init__.py1
-rw-r--r--askbot/const/message_keys.py9
-rw-r--r--askbot/context.py4
-rw-r--r--askbot/doc/source/changelog.rst8
-rw-r--r--askbot/doc/source/contributors.rst2
-rw-r--r--askbot/forms.py31
-rw-r--r--askbot/locale/en/LC_MESSAGES/django.po10
-rw-r--r--askbot/middleware/anon_user.py42
-rw-r--r--askbot/models/__init__.py3
-rw-r--r--askbot/models/meta.py4
-rw-r--r--askbot/skins/default/templates/blocks/bottom_scripts.html2
-rw-r--r--askbot/skins/default/templates/macros.html14
-rw-r--r--askbot/skins/default/templates/user_profile/user_inbox.html4
-rw-r--r--askbot/skins/default/templates/user_profile/user_recent.html2
-rw-r--r--askbot/skins/default/templates/user_profile/user_votes.html2
-rw-r--r--askbot/tests/page_load_tests.py33
-rw-r--r--askbot/utils/mail.py7
20 files changed, 131 insertions, 69 deletions
diff --git a/MANIFEST.in b/MANIFEST.in
index 484f6b67..7d503fb7 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -4,6 +4,7 @@ include LICENSE
include AUTHORS
include COPYING
include README.rst
+include askbot_requirements.txt
recursive-include askbot *
recursive-exclude askbot *.pyc
recursive-exclude .git
diff --git a/askbot/__init__.py b/askbot/__init__.py
index 8133c74f..5ced4ca1 100644
--- a/askbot/__init__.py
+++ b/askbot/__init__.py
@@ -9,7 +9,7 @@ import smtplib
import sys
import logging
-VERSION = (0, 7, 22)
+VERSION = (0, 7, 23)
#necessary for interoperability of django and coffin
try:
diff --git a/askbot/conf/site_settings.py b/askbot/conf/site_settings.py
index 376c65c0..0cab800b 100644
--- a/askbot/conf/site_settings.py
+++ b/askbot/conf/site_settings.py
@@ -5,8 +5,6 @@ keywords
from askbot.conf.settings_wrapper import settings
from askbot.deps import livesettings
from django.utils.translation import ugettext as _
-from django.utils.html import escape
-from askbot import const
QA_SITE_SETTINGS = livesettings.ConfigurationGroup(
'QA_SITE_SETTINGS',
@@ -74,19 +72,16 @@ settings.register(
settings.register(
livesettings.StringValue(
QA_SITE_SETTINGS,
- 'GREETING_URL',
- default='/' + _('faq/'),#cannot reverse url here, must be absolute also
- hidden=True,
+ 'GREETING_FOR_ANONYMOUS_USER',
+ default='First time here? Check out the FAQ!',
+ hidden=False,
description=_(
- 'Link shown in the greeting message '
+ 'Text shown in the greeting message '
'shown to the anonymous user'
),
- help_text=_('If you change this url from the default - '
- 'then you will also probably want to adjust translation of '
- 'the following string: ') + '"'
- + escape(const.GREETING_FOR_ANONYMOUS_USER + '"'
- ' You can find this string in your locale django.po file'
- )
+ help_text=_(
+ 'Use HTML to format the message '
+ )
)
)
diff --git a/askbot/const/__init__.py b/askbot/const/__init__.py
index d1449dd8..73c71800 100644
--- a/askbot/const/__init__.py
+++ b/askbot/const/__init__.py
@@ -263,6 +263,7 @@ DEPENDENCY_URLS = {
'facebook-apps': 'http://www.facebook.com/developers/createapp.php',
'google-webmaster-tools': 'https://www.google.com/webmasters/tools/home',
'identica-apps': 'http://identi.ca/settings/oauthapps',
+ 'noscript': 'https://www.google.com/support/bin/answer.py?answer=23852',
'linkedin-apps': 'https://www.linkedin.com/secure/developer',
'mathjax': 'http://www.mathjax.org/resources/docs/?installation.html',
'recaptcha': 'http://google.com/recaptcha',
diff --git a/askbot/const/message_keys.py b/askbot/const/message_keys.py
index f7115009..12fa0766 100644
--- a/askbot/const/message_keys.py
+++ b/askbot/const/message_keys.py
@@ -9,14 +9,7 @@ _ = lambda v:v
#NOTE: all strings must be explicitly put into this dictionary,
#because you don't want to import _ from here with import *
-__all__ = ['GREETING_FOR_ANONYMOUS_USER', ]
-
-#this variable is shown in settings, because
-#the url within is configurable, the default is reverse('faq')
-#if user changes url they will have to be able to fix the
-#message translation too
-GREETING_FOR_ANONYMOUS_USER = \
- _('First time here? Check out the <a href="%s">FAQ</a>!')
+__all__ = []
#messages loaded in the templates via direct _ calls
_('most relevant questions')
diff --git a/askbot/context.py b/askbot/context.py
index 5a174585..6dc38f79 100644
--- a/askbot/context.py
+++ b/askbot/context.py
@@ -5,6 +5,7 @@ and the application available for the templates
from django.conf import settings
import askbot
from askbot import api
+from askbot import const
from askbot.conf import settings as askbot_settings
from askbot.skins.loaders import get_skin
from askbot.utils import url_utils
@@ -22,5 +23,6 @@ def application_settings(request):
return {
'settings': my_settings,
'skin': get_skin(request),
- 'moderation_items': api.get_info_on_moderation_items(request.user)
+ 'moderation_items': api.get_info_on_moderation_items(request.user),
+ 'noscript_url': const.DEPENDENCY_URLS['noscript'],
}
diff --git a/askbot/doc/source/changelog.rst b/askbot/doc/source/changelog.rst
index c1eaa158..7bbd734c 100644
--- a/askbot/doc/source/changelog.rst
+++ b/askbot/doc/source/changelog.rst
@@ -1,16 +1,18 @@
Changes in Askbot
=================
-Development version
+0.7.23 (Current Version)
-------------------
+* 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)
* Added noscript message (Arun SAG)
* Support for url shortening with TinyUrl on link sharing (Rtnpro)
* Allowed logging in with password and email in the place of login name (Evgeny)
* Added config settings allowing adjust license information (Evgeny)
-0.7.22 (Current Version)
-------------------------
+0.7.22
+------
* Media resource revision is now incremented
automatically any time when media is updated (Adolfo Fitoria, Evgeny Fadeev)
* First user automatically becomes site administrator (Adolfo Fitoria)
diff --git a/askbot/doc/source/contributors.rst b/askbot/doc/source/contributors.rst
index ea7ee34e..35c02be1 100644
--- a/askbot/doc/source/contributors.rst
+++ b/askbot/doc/source/contributors.rst
@@ -15,10 +15,12 @@ Programming and documentation
* Andy Knotts
* Benoit Lavine (with Windriver Software, Inc.)
* Jeff Madynski
+* `Hrishi <https://github.com/stultus>`_
* Andrei Mamoutkine
* Ramiro Morales (with Machinalis)
* `NoahY <https://github.com/NoahY>`_
* `Gael Pasgrimaud <http://www.gawel.org/>`_ (bearstech)
+* `Rag Sagar <https://github.com/ragsagar>`_
* Alex Robbins (celery support)
* `Tomasz Szynalski <http://antimoon.com>`_
diff --git a/askbot/forms.py b/askbot/forms.py
index b13abe0c..afef2cc5 100644
--- a/askbot/forms.py
+++ b/askbot/forms.py
@@ -968,19 +968,26 @@ class EmailFeedSettingField(forms.ChoiceField):
class EditUserEmailFeedsForm(forms.Form):
FORM_TO_MODEL_MAP = {
- 'all_questions':'q_all',
- 'asked_by_me':'q_ask',
- 'answered_by_me':'q_ans',
- 'individually_selected':'q_sel',
- 'mentions_and_comments':'m_and_c',
- }
+ 'all_questions':'q_all',
+ 'asked_by_me':'q_ask',
+ 'answered_by_me':'q_ans',
+ 'individually_selected':'q_sel',
+ 'mentions_and_comments':'m_and_c',
+ }
NO_EMAIL_INITIAL = {
- 'all_questions':'n',
- 'asked_by_me':'n',
- 'answered_by_me':'n',
- 'individually_selected':'n',
- 'mentions_and_comments':'n',
- }
+ 'all_questions':'n',
+ 'asked_by_me':'n',
+ 'answered_by_me':'n',
+ 'individually_selected':'n',
+ 'mentions_and_comments':'n',
+ }
+ INSTANT_EMAIL_INITIAL = {
+ 'all_questions':'i',
+ 'asked_by_me':'i',
+ 'answered_by_me':'i',
+ 'individually_selected':'i',
+ 'mentions_and_comments':'i',
+ }
asked_by_me = EmailFeedSettingField(
label=_('Asked by me')
diff --git a/askbot/locale/en/LC_MESSAGES/django.po b/askbot/locale/en/LC_MESSAGES/django.po
index 5bb75eca..4d6cd0ba 100644
--- a/askbot/locale/en/LC_MESSAGES/django.po
+++ b/askbot/locale/en/LC_MESSAGES/django.po
@@ -499,7 +499,7 @@ msgstr ""
#: conf/email.py:22
msgid "Prefix for the email subject line"
-msgstr "Welcome to the Q&A forum"
+msgstr ""
#: conf/email.py:24
msgid ""
@@ -1600,10 +1600,10 @@ msgstr ""
msgid "bronze"
msgstr ""
-#: const/message_keys.py:19
-#, python-format
-msgid "First time here? Check out the <a href=\"%s\">FAQ</a>!"
-msgstr ""
+
+
+
+
#: const/message_keys.py:22 skins/default/templates/main_page/tab_bar.html:27
msgid "most relevant questions"
diff --git a/askbot/middleware/anon_user.py b/askbot/middleware/anon_user.py
index 06e9dfd0..d1e223b7 100644
--- a/askbot/middleware/anon_user.py
+++ b/askbot/middleware/anon_user.py
@@ -1,13 +1,25 @@
-from django.utils.translation import ugettext as _
+"""middleware that allows anonymous users
+receive messages using the now deprecated `message_set()`
+interface of the user objects.
+
+To allow anonymous users accept messages, a special
+message manager is defined here, and :meth:`__deepcopy__()` method
+added to the :class:`AnonymousUser` so that user could be pickled.
+
+Secondly, it sends greeting message to anonymous users.
+"""
from askbot.user_messages import create_message, get_and_delete_messages
from askbot.conf import settings as askbot_settings
-from askbot import const
class AnonymousMessageManager(object):
+ """message manager for the anonymous user"""
def __init__(self, request):
self.request = request
+
def create(self, message=''):
+ """send message to anonymous user"""
create_message(self.request, message)
+
def get_and_delete(self):
messages = get_and_delete_messages(self.request)
return messages
@@ -19,18 +31,34 @@ def dummy_deepcopy(*arg):
return None
class ConnectToSessionMessagesMiddleware(object):
+ """middleware that attaches messages to anonymous users"""
def process_request(self, request):
if not request.user.is_authenticated():
#plug on deepcopy which may be called by django db "driver"
- request.user.__deepcopy__ = dummy_deepcopy
+ request.user.__deepcopy__ = dummy_deepcopy
#here request is linked to anon user
- request.user.message_set = AnonymousMessageManager(request)
+ request.user.message_set = AnonymousMessageManager(request)
request.user.get_and_delete_messages = \
request.user.message_set.get_and_delete
#also set the first greeting one time per session only
- if 'greeting_set' not in request.session:
+ if 'greeting_set' not in request.session and \
+ 'askbot_visitor' not in request.COOKIES:
request.session['greeting_set'] = True
- msg = _(const.GREETING_FOR_ANONYMOUS_USER) \
- % askbot_settings.GREETING_URL
+ 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. """
+ if request.user.is_authenticated() and \
+ 'askbot_visitor' not in request.COOKIES :
+ #import datetime
+ #max_age = 365*24*60*60
+ #expires = datetime.datetime.strftime\
+ # (datetime.datetime.utcnow() +
+ # datetime.timedelta(seconds=max_age),\
+ # "%a, %d-%b-%Y %H:%M:%S GMT")
+ response.set_cookie('askbot_visitor', False)
+ return response
+
diff --git a/askbot/models/__init__.py b/askbot/models/__init__.py
index 85533ece..17723ce5 100644
--- a/askbot/models/__init__.py
+++ b/askbot/models/__init__.py
@@ -1202,6 +1202,8 @@ def user_post_question(
is_anonymous = False,
timestamp = None
):
+ """makes an assertion whether user can post the question
+ then posts it and returns the question object"""
self.assert_can_post_question()
@@ -2230,7 +2232,6 @@ def format_instant_notification_email(
'origin_post_title': origin_post.title,
'user_subscriptions_url': user_subscriptions_url,
}
- subject_line = mail.prefix_the_subject_line(subject_line)
return subject_line, template.render(Context(update_data))
#todo: action
diff --git a/askbot/models/meta.py b/askbot/models/meta.py
index 463db0cc..9022a7ec 100644
--- a/askbot/models/meta.py
+++ b/askbot/models/meta.py
@@ -159,9 +159,9 @@ class Comment(base.MetaContent, base.UserContent):
return self.user
def get_updated_activity_data(self, created = False):
- if self.content_object.__class__.__name__ == 'Question':
+ if self.content_object.post_type == 'question':
return const.TYPE_ACTIVITY_COMMENT_QUESTION, self
- elif self.content_object.__class__.__name__ == 'Answer':
+ elif self.content_object.post_type == 'answer':
return const.TYPE_ACTIVITY_COMMENT_ANSWER, self
def get_response_receivers(self, exclude_list = None):
diff --git a/askbot/skins/default/templates/blocks/bottom_scripts.html b/askbot/skins/default/templates/blocks/bottom_scripts.html
index 6fbd6adc..771c13a4 100644
--- a/askbot/skins/default/templates/blocks/bottom_scripts.html
+++ b/askbot/skins/default/templates/blocks/bottom_scripts.html
@@ -4,7 +4,7 @@
#}
<div id="no-javascript">
<noscript class="noscript">
- {% trans app_name = settings.APP_SHORT_NAME %}Please note: {{app_name}} requires javascript to work properly, please enable javascript in your browser{% endtrans %}
+ {% trans app_name = settings.APP_SHORT_NAME %}Please note: {{app_name}} requires javascript to work properly, please enable javascript in your browser, <a href="{{noscript_url}}">here is how</a>{% endtrans %}
</noscript>
</div>
<script type="text/javascript">
diff --git a/askbot/skins/default/templates/macros.html b/askbot/skins/default/templates/macros.html
index 7ddbd70f..afa7b264 100644
--- a/askbot/skins/default/templates/macros.html
+++ b/askbot/skins/default/templates/macros.html
@@ -246,9 +246,9 @@ poor design of the data or methods on data objects #}
<div class='post-update-info'>
{% if is_wiki %}
<p>
- {%- if post.__class__.__name__ == 'Question' -%}
+ {%- if post.post_type == 'question' -%}
{%- trans %}asked{% endtrans %}
- {% elif post.__class__.__name__ == 'Answer' %}
+ {% elif post.post_type == 'answer' %}
{%- trans %}answered{% endtrans %}
{% else %}
{%- trans %}posted{% endtrans %}
@@ -265,9 +265,9 @@ poor design of the data or methods on data objects #}
{% else %}
<p style="line-height:12px;">
{# todo: access to class names needs to be removed here #}
- {% if post.__class__.__name__=="Question" %}
+ {% if post.post_type == 'question' %}
{% trans %}asked{% endtrans %}
- {% elif post.__class__.name__=="Answer" %}
+ {% elif post.post_type == 'answer' %}
{% trans %}answered{% endtrans %}
{% else %}
{% trans %}posted{% endtrans %}
@@ -282,11 +282,11 @@ poor design of the data or methods on data objects #}
{% endif %}
</div>
{% elif contributor_type=="last_updater" %}
- {% if post.__class__.__name__ 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.__class__.__name__ in ('QuestionRevision', 'AnswerRevision') %}
+ {% elif post.post_type 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 #}
<div class='post-update-info'>
<p style="line-height:12px;">
<a
- {% if post.__class__.__name__ == 'Question' %}
+ {% if post.post_type == 'Question' %}
href="{% url question_revisions post.id %}"
{% else %}
href="{% url answer_revisions post.id %}"
diff --git a/askbot/skins/default/templates/user_profile/user_inbox.html b/askbot/skins/default/templates/user_profile/user_inbox.html
index 4743a4c1..e7e3dbfe 100644
--- a/askbot/skins/default/templates/user_profile/user_inbox.html
+++ b/askbot/skins/default/templates/user_profile/user_inbox.html
@@ -70,7 +70,7 @@ inbox_section - forum|flags
<a style="font-size:12px" href="{{ response.user.get_absolute_url() }}">{{ response.user.username }}</a>
<a style="text-decoration:none;" href="{{ response.response_url }}">
{{ response.response_type }}
- ({{ response.timestamp|diff_date(3, True) }}):<br/>
+ ({{ response.timestamp|diff_date(True) }}):<br/>
{{ response.response_snippet}}
</a>
</div>
@@ -84,7 +84,7 @@ inbox_section - forum|flags
<a style="font-size:12px" href="{{ nested_response.user.get_absolute_url() }}">{{ nested_response.user.username }}</a>
<a style="text-decoration:none;" href="{{ nested_response.response_url }}">
{{ nested_response.response_type }}
- ({{ nested_response.timestamp|diff_date(3, True) }}):<br/>
+ ({{ nested_response.timestamp|diff_date(True) }}):<br/>
{{ nested_response.response_snippet}}
</a>
</div>
diff --git a/askbot/skins/default/templates/user_profile/user_recent.html b/askbot/skins/default/templates/user_profile/user_recent.html
index 9239196a..cbd59202 100644
--- a/askbot/skins/default/templates/user_profile/user_recent.html
+++ b/askbot/skins/default/templates/user_profile/user_recent.html
@@ -7,7 +7,7 @@
<div style="padding-top:5px;font-size:13px;">
{% for act in activities %}
<div style="clear:both;line-height:20px" >
- <div style="width:180px;float:left">{{ act.time|diff_date(3) }}</div>
+ <div style="width:180px;float:left">{{ act.time|diff_date(True) }}</div>
<div style="width:150px;float:left">
<span class="user-action-{{ act.type_id }}">{{ act.type }}</span>
</div>
diff --git a/askbot/skins/default/templates/user_profile/user_votes.html b/askbot/skins/default/templates/user_profile/user_votes.html
index b6fe784b..d5e469ae 100644
--- a/askbot/skins/default/templates/user_profile/user_votes.html
+++ b/askbot/skins/default/templates/user_profile/user_votes.html
@@ -7,7 +7,7 @@
<div style="padding-top:5px;font-size:13px;">
{% for vote in votes %}
<div style="clear:both;line-height:20px" >
- <div style="width:150px;float:left">{{vote.voted_at|diff_date(3)}}</div>
+ <div style="width:150px;float:left">{{vote.voted_at|diff_date(True)}}</div>
<div style="width:30px;float:left">
{% if vote.vote==1 %}
<img src="{{"/images/vote-arrow-up-on.png"|media}}" title="{% trans %}upvote{% endtrans %}">
diff --git a/askbot/tests/page_load_tests.py b/askbot/tests/page_load_tests.py
index 58ca7537..9c107112 100644
--- a/askbot/tests/page_load_tests.py
+++ b/askbot/tests/page_load_tests.py
@@ -49,11 +49,22 @@ class PageLoadTestCase(TestCase):
if template:
if isinstance(r.template, coffin.template.Template):
self.assertEqual(r.template.name, template)
- else:
+ elif isinstance(r.template, list):
#asuming that there is more than one template
template_names = ','.join([t.name for t in r.template])
print 'templates are %s' % template_names
+ if follow == False:
+ self.fail(
+ ('Have issue accessing %s. '
+ 'This should not have happened, '
+ 'since you are not expecting a redirect '
+ 'i.e. follow == False, there should be only '
+ 'one template') % url
+ )
+
self.assertEqual(r.template[0].name, template)
+ else:
+ raise Exception('unexpected error while runnig test')
class PageLoadTests(PageLoadTestCase):
fixtures = ['tmp/fixture2.json', ]
@@ -313,6 +324,26 @@ class PageLoadTests(PageLoadTestCase):
)
self.client.logout()
+ def test_inbox_page(self):
+ asker = models.User.objects.get(id = 2)
+ question = asker.post_question(
+ title = 'How can this happen?',
+ body_text = 'This is the body of my question',
+ tags = 'question answer test',
+ )
+ responder = models.User.objects.get(id = 3)
+ responder.post_answer(
+ question = question,
+ body_text = 'this is the answer text'
+ )
+ self.client.login(method = 'force', user_id = asker.id)
+ self.try_url(
+ 'user_profile',
+ kwargs={'id': asker.id, 'slug': slugify(asker.username)},
+ data={'sort':'inbox'},
+ template='user_profile/user_inbox.html',
+ )
+
class AvatarTests(AskbotTestCase):
def test_avatar_for_two_word_user_works(self):
diff --git a/askbot/utils/mail.py b/askbot/utils/mail.py
index ae655f4c..3eb9e97d 100644
--- a/askbot/utils/mail.py
+++ b/askbot/utils/mail.py
@@ -15,9 +15,9 @@ def prefix_the_subject_line(subject):
EMAIL_SUBJECT_LINE_PREFIX either from
from live settings, which take default from django
"""
- prefix = askbot_settings.EMAIL_SUBJECT_PREFIX.strip()
+ prefix = askbot_settings.EMAIL_SUBJECT_PREFIX
if prefix != '':
- subject = prefix + ' ' + subject
+ subject = prefix.strip() + ' ' + subject.strip()
return subject
def extract_first_email_address(text):
@@ -89,10 +89,9 @@ def send_mail(
if raise_on_failure is True, exceptions.EmailNotSent is raised
"""
- prefix = askbot_settings.EMAIL_SUBJECT_PREFIX.strip() + ' '
try:
assert(subject_line is not None)
- subject_line = prefix + subject_line
+ subject_line = prefix_the_subject_line(subject_line)
msg = mail.EmailMessage(
subject_line,
body_text,