summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--askbot/__init__.py2
-rw-r--r--askbot/const/__init__.py2
-rw-r--r--askbot/management/commands/send_email_alerts.py11
-rw-r--r--askbot/models/__init__.py10
-rw-r--r--askbot/setup_templates/settings.py1
-rw-r--r--askbot/tests/page_load_tests.py24
-rw-r--r--askbot/urls.py28
-rw-r--r--askbot/utils/http.py5
-rw-r--r--askbot/views/users.py14
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)