diff options
-rw-r--r-- | askbot/__init__.py | 2 | ||||
-rw-r--r-- | askbot/const/__init__.py | 2 | ||||
-rw-r--r-- | askbot/management/commands/send_email_alerts.py | 11 | ||||
-rw-r--r-- | askbot/models/__init__.py | 10 | ||||
-rw-r--r-- | askbot/setup_templates/settings.py | 1 | ||||
-rw-r--r-- | askbot/tests/page_load_tests.py | 24 | ||||
-rw-r--r-- | askbot/urls.py | 28 | ||||
-rw-r--r-- | askbot/utils/http.py | 5 | ||||
-rw-r--r-- | askbot/views/users.py | 14 |
9 files changed, 72 insertions, 25 deletions
diff --git a/askbot/__init__.py b/askbot/__init__.py index 5d245db7..a54b83c1 100644 --- a/askbot/__init__.py +++ b/askbot/__init__.py @@ -9,7 +9,7 @@ import smtplib import sys import logging -VERSION = (0, 6, 96) +VERSION = (0, 6, 98) #necessary for interoperability of django and coffin try: diff --git a/askbot/const/__init__.py b/askbot/const/__init__.py index 0006714d..8b6fc9bd 100644 --- a/askbot/const/__init__.py +++ b/askbot/const/__init__.py @@ -215,7 +215,7 @@ NOTIFICATION_DELIVERY_SCHEDULE_CHOICES= ( ) USERS_PAGE_SIZE = 28#todo: move it to settings? -USERNAME_REGEX_STRING = r'^[\w \-]+$' +USERNAME_REGEX_STRING = r'^[\w \-.@+\']+$' #chars that can go before or after @mention TWITTER_STYLE_MENTION_TERMINATION_CHARS = '\n ;:,.!?<>"\'' diff --git a/askbot/management/commands/send_email_alerts.py b/askbot/management/commands/send_email_alerts.py index f92aff63..330e1cc9 100644 --- a/askbot/management/commands/send_email_alerts.py +++ b/askbot/management/commands/send_email_alerts.py @@ -1,5 +1,6 @@ import datetime from django.core.management.base import NoArgsCommand +from django.core.urlresolvers import reverse from django.db import connection from django.db.models import Q, F from askbot.models import User, Question, Answer, Tag, QuestionRevision @@ -14,6 +15,7 @@ from django.utils.datastructures import SortedDict from django.contrib.contenttypes.models import ContentType from askbot import const from askbot.utils import mail +from askbot.utils.slug import slugify DEBUG_THIS_COMMAND = False @@ -476,7 +478,14 @@ class Command(NoArgsCommand): 'before - due to a technicality that will eventually go away. ' ) - link = url_prefix + user.get_profile_url() + '?sort=email_subscriptions' + link = url_prefix + reverse( + 'user_subscriptions', + kwargs = { + 'id': user.id, + 'slug': slugify(user.username) + } + ) + text += _( 'go to %(email_settings_link)s to change ' 'frequency of email updates or ' diff --git a/askbot/models/__init__.py b/askbot/models/__init__.py index 8fa01fd2..6c25aaa5 100644 --- a/askbot/models/__init__.py +++ b/askbot/models/__init__.py @@ -2033,8 +2033,14 @@ def format_instant_notification_email( site_url = askbot_settings.APP_URL origin_post = post.get_origin_post() #todo: create a better method to access "sub-urls" in user views - user_subscriptions_url = site_url + to_user.get_absolute_url() + \ - '?sort=email_subscriptions' + user_subscriptions_url = site_url + \ + reverse( + 'user_subscriptions', + kwargs = { + 'id': to_user.id, + 'slug': slugify(to_user.username) + } + ) if update_type == 'question_comment': assert(isinstance(post, Comment)) diff --git a/askbot/setup_templates/settings.py b/askbot/setup_templates/settings.py index 9a976e16..24ecb374 100644 --- a/askbot/setup_templates/settings.py +++ b/askbot/setup_templates/settings.py @@ -205,6 +205,7 @@ LOGIN_URL = '/%s%s%s' % (ASKBOT_URL,_('account/'),_('signin/')) #also, this url must not have the leading slash ASKBOT_UPLOADED_FILES_URL = '%s%s' % (ASKBOT_URL, 'upfiles/') ALLOW_UNICODE_SLUGS = False +ASKBOT_USE_STACKEXCHANGE_URLS = False #mimic url scheme of stackexchange #Celery Settings BROKER_BACKEND = "djkombu.transport.DatabaseTransport" diff --git a/askbot/tests/page_load_tests.py b/askbot/tests/page_load_tests.py index 36f65c71..7dce9cf8 100644 --- a/askbot/tests/page_load_tests.py +++ b/askbot/tests/page_load_tests.py @@ -270,8 +270,8 @@ class PageLoadTests(PageLoadTestCase): 'user_profile', kwargs={'id': 2, 'slug': name_slug}, data={'sort':'inbox'}, - status_code=404, - template='404.html' + template='authopenid/signin.html', + follow=True ) self.try_url( 'user_profile', @@ -283,8 +283,8 @@ class PageLoadTests(PageLoadTestCase): 'user_profile', kwargs={'id': 2, 'slug': name_slug}, data={'sort':'votes'}, - status_code=404, - template='404.html' + template='authopenid/signin.html', + follow = True ) self.try_url( 'user_profile', @@ -296,6 +296,18 @@ class PageLoadTests(PageLoadTestCase): 'user_profile', kwargs={'id': 2, 'slug': name_slug}, data={'sort':'email_subscriptions'}, - status_code=404, - template='404.html' + template='authopenid/signin.html', + follow = True ) + + def test_user_urls_logged_in(self): + user = models.User.objects.get(id=2) + name_slug = slugify(user.username) + #works only with builtin django_authopenid + self.client.login(method = 'force', user_id = 2) + self.try_url( + 'user_subscriptions', + kwargs = {'id': 2, 'slug': name_slug}, + template = 'user_profile/user_email_subscriptions.html' + ) + self.client.logout() diff --git a/askbot/urls.py b/askbot/urls.py index 714ce4ca..f6c5e937 100644 --- a/askbot/urls.py +++ b/askbot/urls.py @@ -126,12 +126,6 @@ urlpatterns = patterns('', views.readers.get_comment, name='get_comment' ), - #place general question item in the end of other operations - url( - r'^%s(?P<id>\d+)/' % _('question/'), - views.readers.question, - name='question' - ), url( r'^%s$' % _('tags/'), views.readers.tags, @@ -192,6 +186,15 @@ urlpatterns = patterns('', name='edit_user' ), url( + r'^%s(?P<id>\d+)/(?P<slug>.+)/%s$' % ( + _('users/'), + _('subscriptions/'), + ), + views.users.user, + kwargs = {'tab_name': 'email_subscriptions'}, + name = 'user_subscriptions' + ), + url( r'^%s(?P<id>\d+)/(?P<slug>.+)/$' % _('users/'), views.users.user, name='user_profile' @@ -258,6 +261,19 @@ urlpatterns = patterns('', ), ) +if getattr(settings, 'ASKBOT_USE_STACKEXCHANGE_URLS', False): + urlpatterns += (url( + r'^%s(?P<id>\d+)/' % _('questions/'), + views.readers.question, + name='question' + ),) +else: + urlpatterns += (url( + r'^%s(?P<id>\d+)/' % _('question/'), + views.readers.question, + name='question' + ),) + if 'askbot.deps.django_authopenid' in settings.INSTALLED_APPS: urlpatterns += ( url(r'^%s' % _('account/'), include('askbot.deps.django_authopenid.urls')), diff --git a/askbot/utils/http.py b/askbot/utils/http.py index 8a3ccd22..2c45b248 100644 --- a/askbot/utils/http.py +++ b/askbot/utils/http.py @@ -41,5 +41,8 @@ def get_request_info(request): data = hide_passwords(copy(data)) info += 'data: %s\n' % str(data) info += 'host: %s\n' % request.get_host() - info += 'user: %s\n' % request.user + if request.user.is_authenticated(): + info += 'user ID: %d\n' % request.user.id + else: + info += 'user is anonymous\n' return info diff --git a/askbot/views/users.py b/askbot/views/users.py index 94b3e997..cbcbe185 100644 --- a/askbot/views/users.py +++ b/askbot/views/users.py @@ -60,7 +60,8 @@ def owner_or_moderator_required(f): elif request.user.is_authenticated() and request.user.can_moderate_user(profile_owner): pass else: - raise Http404 #todo: change to access forbidden? + params = '?next=%s' % request.path + return HttpResponseRedirect(reverse('user_signin') + params) return f(request, profile_owner, context) return wrapped_func @@ -941,7 +942,7 @@ user_view_call_table = { 'moderation': user_moderate, } #todo: rename this function - variable named user is everywhere -def user(request, id, slug=None): +def user(request, id, slug=None, tab_name=None): """Main user view function that works as a switchboard id - id of the profile owner @@ -949,12 +950,12 @@ def user(request, id, slug=None): todo: decide what to do with slug - it is not used in the code in any way """ - profile_owner = get_object_or_404(models.User, id = id) - #sort CGI parameter tells us which tab in the user - #profile to show, the default one is 'stats' - tab_name = request.GET.get('sort', 'stats') + if tab_name is None: + #sort CGI parameter tells us which tab in the user + #profile to show, the default one is 'stats' + tab_name = request.GET.get('sort', 'stats') if tab_name in user_view_call_table: #get the actual view function @@ -966,5 +967,4 @@ def user(request, id, slug=None): 'view_user': profile_owner, 'user_follow_feature_on': ('followit' in django_settings.INSTALLED_APPS), } - return user_view_func(request, profile_owner, context) |