Permalink
Browse files

added anonymous posting, per-question subscription and fixes by Pothe…

…rs and some more, see development.log
  • Loading branch information...
1 parent b1e66ad commit 56f02677940a00f04780cfb361fc65950e910bf8 @evgenyfadeev evgenyfadeev committed Aug 6, 2009
Showing with 3,134 additions and 1,958 deletions.
  1. +33 −2 context.py
  2. +34 −1 development.log
  3. +45 −37 django_authopenid/forms.py
  4. +1 −1 django_authopenid/middleware.py
  5. +4 −1 django_authopenid/urls.py
  6. +185 −23 django_authopenid/views.py
  7. +4 −1 forum/admin.py
  8. +7 −7 forum/feed.py
  9. +29 −13 forum/forms.py
  10. +1 −0 forum/management/commands/once_award_badges.py
  11. +154 −5 forum/models.py
  12. +2 −2 forum/templatetags/extra_tags.py
  13. +0 −1 forum/user.py
  14. +194 −67 forum/views.py
  15. BIN locale/en/LC_MESSAGES/django.mo
  16. +913 −862 locale/en/LC_MESSAGES/django.po
  17. BIN locale/es/LC_MESSAGES/django.mo
  18. +807 −522 locale/es/LC_MESSAGES/django.po
  19. BIN locale/zh_CN/LC_MESSAGES/django.mo
  20. +26 −7 locale/zh_CN/LC_MESSAGES/django.po
  21. +11 −4 settings.py
  22. +3 −3 settings_local.py
  23. +1 −1 templates/404.html
  24. +2 −2 templates/500.html
  25. +1 −1 templates/answer_edit.html
  26. +1 −1 templates/answer_edit_tips.html
  27. +21 −31 templates/ask.html
  28. +73 −27 templates/authopenid/changeemail.html
  29. +2 −0 templates/authopenid/changeopenid.html
  30. +2 −0 templates/authopenid/changepw.html
  31. +9 −8 templates/authopenid/complete.html
  32. +9 −8 templates/authopenid/confirm_email.txt
  33. +2 −0 templates/authopenid/delete.html
  34. +2 −1 templates/authopenid/failure.html
  35. +2 −0 templates/authopenid/sendpw.html
  36. +9 −9 templates/authopenid/sendpw_email.txt
  37. +2 −0 templates/authopenid/settings.html
  38. +102 −22 templates/authopenid/signin.html
  39. +2 −0 templates/authopenid/signup.html
  40. +1 −1 templates/badge.html
  41. +8 −7 templates/badges.html
  42. +15 −14 templates/base.html
  43. +16 −11 templates/base_content.html
  44. +1 −1 templates/book.html
  45. +1 −1 templates/close.html
  46. +5 −3 templates/content/js/com.cnprog.i18n.js
  47. +19 −4 templates/content/js/com.cnprog.post.js
  48. +1 −1 templates/content/js/com.cnprog.utils.js
  49. +1 −1 templates/content/style/openid.css
  50. +143 −69 templates/content/style/style.css
  51. +129 −94 templates/faq.html
  52. +1 −1 templates/footer.html
  53. +18 −19 templates/header.html
  54. +6 −4 templates/index.html
  55. +2 −2 templates/logout.html
  56. +2 −0 templates/pagesize.html
  57. +14 −7 templates/question.html
  58. +1 −1 templates/question_edit.html
  59. +11 −14 templates/question_retag.html
  60. +18 −10 templates/questions.html
  61. +1 −1 templates/revisions_answer.html
  62. +1 −2 templates/revisions_question.html
  63. +1 −1 templates/unanswered.html
  64. +2 −4 templates/user.html
  65. +1 −1 templates/user_edit.html
  66. +1 −1 templates/user_favorites.html
  67. +2 −0 templates/user_info.html
  68. +9 −6 templates/user_preferences.html
  69. +1 −1 templates/user_recent.html
  70. +1 −1 templates/user_reputation.html
  71. +1 −1 templates/user_responses.html
  72. +1 −1 templates/user_stats.html
  73. +0 −2 templates/user_tabs.html
  74. +1 −1 templates/user_votes.html
  75. +3 −0 urls.py
View
@@ -1,9 +1,40 @@
from django.conf import settings
def application_settings(context):
- return {
+ my_settings = {
'APP_TITLE' : settings.APP_TITLE,
'APP_URL' : settings.APP_URL,
'APP_KEYWORDS' : settings.APP_KEYWORDS,
'APP_DESCRIPTION' : settings.APP_DESCRIPTION,
- 'APP_INTRO' : settings.APP_INTRO
+ 'APP_INTRO' : settings.APP_INTRO,
+ 'EMAIL_VALIDATION': settings.EMAIL_VALIDATION,
+ 'LANGUAGE_CODE': settings.LANGUAGE_CODE,
+ 'GOOGLE_SITEMAP_CODE':settings.GOOGLE_SITEMAP_CODE,
+ 'GOOGLE_ANALYTICS_KEY':settings.GOOGLE_ANALYTICS_KEY,
}
+ return {'settings':my_settings}
+
+def auth_processor(request):
+ """
+ Returns context variables required by apps that use Django's authentication
+ system.
+
+ If there is no 'user' attribute in the request, uses AnonymousUser (from
+ django.contrib.auth).
+ """
+ if hasattr(request, 'user'):
+ user = request.user
+ if user.is_authenticated():
+ messages = user.message_set.all()
+ else:
+ messages = None
+ else:
+ from django.contrib.auth.models import AnonymousUser
+ user = AnonymousUser()
+ messages = None
+
+ from django.core.context_processors import PermWrapper
+ return {
+ 'user': user,
+ 'messages': messages,
+ 'perms': PermWrapper(user),
+ }
View
@@ -1,4 +1,37 @@
-# development
+==Aug 5, 2009 Evgeny==
+===Interface changes===
+Merged in my code that:
+* allows anonymous posting of Q&A and then login
+* per-question email notifications via 'send_email_alerts' command
+* allows space character in username
+* improves openid login
+* makes notification messages sticky - have to click "x" to dismiss
+* unanswered questions are now those with no accepted answer
+* added following setting parameters:
+
+settings.MIN_USERNAME_LENGTH = 1
+settings.EMAIL_UNIQUE = True|False
+settings.EMAIL_VALIDATION = 'on'|'off' #thought of maybe adding other options so type is string
+settings.GOOGLE_SITEMAP_CODE = <string>
+settings.GOOGLE_ANALYTICS_KEY = <string>
+
+===Fixes===
+* fixed incorrect answer count issue in question.html
+* translated Twittwer stuff in user_preferences.html
+* translated question_retag.html, except one phrase
+* added Adolfo's python2.4 fix
+* fixed template debugging comments so that they don't break page layout
+* reorganized header template so that it takes less vertical space
+
+===Code changes===
+* wrapped template context settings into a single settings dictionary
+* on login anonymous session is recorded so that anonymously posted questions (if any) could be found later
+* added models: AnonymousQuestion, AnonymousAnswer, EmailFeed (for notifications)
+* User model has two new fields email_key - 32 byte hex hash and email_isvalid - boolean
+ file sql_scripts/update_2009_07_05_EF.sql will make upgrade to the live database
+* added auth_processor to context.py which loads notification messages without deleting them
+ NOTE: default django auth processor must be removed!
+* added ajax actions questionSubscribeUpdates/questionUnsubscribeUpdates
==Aug 4 2009, Evgeny==
===Changes===
@@ -158,7 +158,7 @@ def clean_username(self):
raise forms.ValidationError(_('invalid user name'))
if self.cleaned_data['username'] in RESERVED_NAMES:
raise forms.ValidationError(_('sorry, this name can not be used, please try another'))
- if len(self.cleaned_data['username']) < 3:
+ if len(self.cleaned_data['username']) < settings.MIN_USERNAME_LENGTH:
raise forms.ValidationError(_('username too short'))
try:
user = User.objects.get(
@@ -171,19 +171,22 @@ def clean_username(self):
raise forms.ValidationError(_('this name is already in use - please try anoter'))
def clean_email(self):
- """For security reason one unique email in database"""
+ """Optionally, for security reason one unique email in database"""
if 'email' in self.cleaned_data:
- try:
- user = User.objects.get(email = self.cleaned_data['email'])
- except User.DoesNotExist:
+ if settings.EMAIL_UNIQUE == True:
+ try:
+ user = User.objects.get(email = self.cleaned_data['email'])
+ except User.DoesNotExist:
+ return self.cleaned_data['email']
+ except User.MultipleObjectsReturned:
+ raise forms.ValidationError(u'There is already more than one \
+ account registered with that e-mail address. Please try \
+ another.')
+ raise forms.ValidationError(_("This email is already \
+ registered in our database. Please choose another."))
+ else:
return self.cleaned_data['email']
- except User.MultipleObjectsReturned:
- raise forms.ValidationError(u'There is already more than one \
- account registered with that e-mail address. Please try \
- another.')
- raise forms.ValidationError(_("This email is already \
- registered in our database. Please choose another."))
-
+ #what if not???
class OpenidVerifyForm(forms.Form):
""" openid verify form (associate an openid with an account) """
@@ -204,8 +207,7 @@ def clean_username(self):
""" validate username """
if 'username' in self.cleaned_data:
if not username_re.search(self.cleaned_data['username']):
- raise forms.ValidationError(_("Usernames can only contain \
- letters, numbers and underscores"))
+ raise forms.ValidationError(_('invalid user name'))
try:
user = User.objects.get(
username__exact = self.cleaned_data['username']
@@ -241,7 +243,7 @@ def get_user(self):
attrs_dict = { 'class': 'required' }
-username_re = re.compile(r'^\w+$')
+username_re = re.compile(r'^[\w ]+$')
class RegistrationForm(forms.Form):
""" legacy registration form """
@@ -286,17 +288,20 @@ def clean_email(self):
""" validate if email exist in database
:return: raise error if it exist """
if 'email' in self.cleaned_data:
- try:
- user = User.objects.get(email = self.cleaned_data['email'])
- except User.DoesNotExist:
+ if settings.EMAIL_UNIQUE == True:
+ try:
+ user = User.objects.get(email = self.cleaned_data['email'])
+ except User.DoesNotExist:
+ return self.cleaned_data['email']
+ except User.MultipleObjectsReturned:
+ raise forms.ValidationError(u'There is already more than one \
+ account registered with that e-mail address. Please try \
+ another.')
+ raise forms.ValidationError(u'This email is already registered \
+ in our database. Please choose another.')
+ else:
return self.cleaned_data['email']
- except User.MultipleObjectsReturned:
- raise forms.ValidationError(u'There is already more than one \
- account registered with that e-mail address. Please try \
- another.')
- raise forms.ValidationError(u'This email is already registered \
- in our database. Please choose another.')
- return self.cleaned_data['email']
+ #what if not?
def clean_password2(self):
"""
@@ -361,18 +366,21 @@ def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None, \
def clean_email(self):
""" check if email don't exist """
if 'email' in self.cleaned_data:
- if self.user.email != self.cleaned_data['email']:
- try:
- user = User.objects.get(email = self.cleaned_data['email'])
- except User.DoesNotExist:
- return self.cleaned_data['email']
- except User.MultipleObjectsReturned:
- raise forms.ValidationError(u'There is already more than one \
- account registered with that e-mail address. Please try \
- another.')
- raise forms.ValidationError(u'This email is already registered \
- in our database. Please choose another.')
- return self.cleaned_data['email']
+ if settings.EMAIL_UNIQUE == True:
+ if self.user.email != self.cleaned_data['email']:
+ try:
+ user = User.objects.get(email = self.cleaned_data['email'])
+ except User.DoesNotExist:
+ return self.cleaned_data['email']
+ except User.MultipleObjectsReturned:
+ raise forms.ValidationError(u'There is already more than one \
+ account registered with that e-mail address. Please try \
+ another.')
+ raise forms.ValidationError(u'This email is already registered \
+ in our database. Please choose another.')
+ else:
+ return self.cleaned_data['email']
+ #what if not?
def clean_password(self):
@@ -21,4 +21,4 @@ def process_response(self, request, response):
mimeparse.best_match(['text/html', 'application/xrds+xml'],
request.META['HTTP_ACCEPT']) == 'application/xrds+xml':
return HttpResponseRedirect(reverse('yadis_xrdf'))
- return response
+ return response
@@ -7,6 +7,8 @@
url(r'^yadis.xrdf$', 'xrdf', name='yadis_xrdf'),
# manage account registration
url(r'^%s$' % _('signin/'), 'signin', name='user_signin'),
+ url(r'^%s%s$' % (_('signin/'),_('newquestion/')), 'signin', kwargs = {'newquestion':True}),
+ url(r'^%s%s$' % (_('signin/'),_('newanswer/')), 'signin', kwargs = {'newanswer':True}),
url(r'^%s$' % _('signout/'), 'signout', name='user_signout'),
url(r'^%s%s$' % (_('signin/'), _('complete/')), 'complete_signin',
name='user_complete_signin'),
@@ -21,7 +23,8 @@
# manage account settings
#url(r'^$', 'account_settings', name='user_account_settings'),
#url(r'^%s$' % _('password/'), 'changepw', name='user_changepw'),
- #url(r'^%s$' % _('email/'), 'changeemail', name='user_changeemail'),
+ url(r'^%s$' % 'email/', 'changeemail', name='user_changeemail',kwargs = {'action':'change'}),
+ url(r'^%s%s$' % ('email/','validate/'), 'changeemail', name='user_changeemail',kwargs = {'action':'validate'}),
#url(r'^%s$' % _('openid/'), 'changeopenid', name='user_changeopenid'),
url(r'^%s$' % _('delete/'), 'delete', name='user_delete'),
)
Oops, something went wrong. Retry.

0 comments on commit 56f0267

Please sign in to comment.