From a16d90151874954a8824c1b9495392f599b70705 Mon Sep 17 00:00:00 2001
From: Evgeny Fadeev
Date: Sun, 5 Jun 2011 02:11:45 -0400
Subject: almost finished support of other login apps to be used with askbot
---
askbot/conf/forum_data_rules.py | 19 +++++-
askbot/context.py | 4 ++
askbot/deps/django_authopenid/urls.py | 2 -
askbot/deps/django_authopenid/views.py | 6 +-
askbot/doc/source/askbot-as-django-application.rst | 41 ++++++++++++
askbot/doc/source/index.rst | 1 +
.../commands/add_missing_subscriptions.py | 2 +-
.../management/commands/post_emailed_questions.py | 3 +-
askbot/management/commands/send_email_alerts.py | 2 +-
askbot/models/__init__.py | 76 +++++++++++++---------
.../default/templates/authopenid/complete.html | 2 +-
.../skins/default/templates/authopenid/signin.html | 2 +-
.../templates/authopenid/signup_with_password.html | 4 +-
.../default/templates/blocks/bottom_scripts.html | 2 +-
.../templates/blocks/header_meta_links.html | 4 +-
askbot/skins/default/templates/faq.html | 2 +-
askbot/skins/default/templates/question.html | 4 +-
.../default/templates/user_profile/user_info.html | 2 +-
askbot/tests/email_alert_tests.py | 4 +-
askbot/tests/page_load_tests.py | 1 -
askbot/urls.py | 4 +-
askbot/utils/url_utils.py | 32 +++++++++
askbot/views/commands.py | 3 +-
askbot/views/writers.py | 9 +--
24 files changed, 170 insertions(+), 61 deletions(-)
create mode 100644 askbot/doc/source/askbot-as-django-application.rst
create mode 100644 askbot/utils/url_utils.py
diff --git a/askbot/conf/forum_data_rules.py b/askbot/conf/forum_data_rules.py
index afbbf027..3392278b 100644
--- a/askbot/conf/forum_data_rules.py
+++ b/askbot/conf/forum_data_rules.py
@@ -8,7 +8,7 @@ from askbot import const
FORUM_DATA_RULES = livesettings.ConfigurationGroup(
'FORUM_DATA_RULES',
- _('Settings for askbot data entry and display')
+ _('Data entry and display')
)
settings.register(
@@ -46,6 +46,23 @@ settings.register(
)
)
+settings.register(
+ livesettings.BooleanValue(
+ FORUM_DATA_RULES,
+ 'ALLOW_POSTING_BEFORE_LOGGING_IN',
+ default = True,
+ description = _('Allow posting before logging in'),
+ help_text = _(
+ 'Check if you want to allow users start posting questions '
+ 'or answers before logging in. '
+ 'Enabling this may require adjustments in the '
+ 'user login system to check for pending posts '
+ 'every time the user logs in. The builtin Askbot login system '
+ 'supports this feature.'
+ )
+ )
+)
+
settings.register(
livesettings.IntegerValue(
FORUM_DATA_RULES,
diff --git a/askbot/context.py b/askbot/context.py
index f3419abd..5a174585 100644
--- a/askbot/context.py
+++ b/askbot/context.py
@@ -7,6 +7,7 @@ import askbot
from askbot import api
from askbot.conf import settings as askbot_settings
from askbot.skins.loaders import get_skin
+from askbot.utils import url_utils
def application_settings(request):
"""The context processor function"""
@@ -15,6 +16,9 @@ def application_settings(request):
my_settings['ASKBOT_URL'] = settings.ASKBOT_URL
my_settings['DEBUG'] = settings.DEBUG
my_settings['ASKBOT_VERSION'] = askbot.get_version()
+ my_settings['LOGIN_URL'] = url_utils.get_login_url()
+ my_settings['LOGOUT_URL'] = url_utils.get_logout_url()
+ my_settings['LOGOUT_REDIRECT_URL'] = url_utils.get_logout_redirect_url()
return {
'settings': my_settings,
'skin': get_skin(request),
diff --git a/askbot/deps/django_authopenid/urls.py b/askbot/deps/django_authopenid/urls.py
index a533f771..f51939ab 100644
--- a/askbot/deps/django_authopenid/urls.py
+++ b/askbot/deps/django_authopenid/urls.py
@@ -7,8 +7,6 @@ urlpatterns = patterns('askbot.deps.django_authopenid.views',
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}, name='user_signin_new_question'),
- url(r'^%s%s$' % (_('signin/'),_('newanswer/')), 'signin', kwargs = {'newanswer':True}, name='user_signin_new_answer'),
url(r'^%s$' % _('signout/'), 'signout', name='user_signout'),
#this view is "complete-openid" signin
url(r'^%s%s$' % (_('signin/'), _('complete/')), 'complete_signin',
diff --git a/askbot/deps/django_authopenid/views.py b/askbot/deps/django_authopenid/views.py
index f43c2dbe..787d7e53 100644
--- a/askbot/deps/django_authopenid/views.py
+++ b/askbot/deps/django_authopenid/views.py
@@ -267,11 +267,7 @@ def complete_oauth_signin(request):
#@not_authenticated
@csrf.csrf_protect
-def signin(
- request,
- newquestion = False,#todo: not needed
- newanswer = False,#todo: not needed
- ):
+def signin(request):
"""
signin page. It manages the legacy authentification (user/password)
and openid authentification
diff --git a/askbot/doc/source/askbot-as-django-application.rst b/askbot/doc/source/askbot-as-django-application.rst
new file mode 100644
index 00000000..09c0a81e
--- /dev/null
+++ b/askbot/doc/source/askbot-as-django-application.rst
@@ -0,0 +1,41 @@
+=====================================
+Askbot as reusable django application
+=====================================
+
+Askbot can be used both as as dedicated site and as an application
+within a larger site. There are still issues to resolve to make askbot
+a truly reusable app, but some are already solved.
+
+This page is a guide for using askbot as an independent app and it is
+somewhat technical.
+
+Using alternative login system
+==============================
+
+Askbot has a bundled application for user login and registration,
+but it can be replaced with any other.
+
+There are two caveats. If you want the "allow posting before logging in" feature
+(which can be enabled/disabled at
+"settings"->"data entry and display"->"allow posting before logging in"),
+you must either insure that your app calls ``user.post_anonymous_askbot_content()``
+right after the user logs in, or activate middleware
+``askbot.middleware.anon_posts.PublishAnonPostsMiddleware``.
+
+The middleware solution is not desirable, as it will cause additional
+database queries each time a logged in user loads any page on the site.
+
+Second thing to keep in mind is in askbot each user has records for
+email subscription settings, and these will be missing when user
+registers via some alternative login application. This is not a big problem
+and should not lead to errors, however some users may miss email notifications
+until their records complete.
+
+The email subscription settings complete automatically when certain pages
+are visited, but there is a way to accelerate this process by calling
+management command::
+
+ python manage.py add_missing_subscriptions
+
+Alternatively, you can insert the following call just after the new user
+account is created ``user.add_missing_askbot_subscriptions()``
diff --git a/askbot/doc/source/index.rst b/askbot/doc/source/index.rst
index fedc3913..5ab51397 100644
--- a/askbot/doc/source/index.rst
+++ b/askbot/doc/source/index.rst
@@ -23,6 +23,7 @@ at the forum_ or by email at admin@askbot.org
Appendix A: Maintenance procedures
Appendix B: Sending email to askbot
Appendix C: Optional modules
+ Appendix D: Askbot as Django application
Footnotes
Contributors
diff --git a/askbot/management/commands/add_missing_subscriptions.py b/askbot/management/commands/add_missing_subscriptions.py
index b30822d1..70b1590e 100644
--- a/askbot/management/commands/add_missing_subscriptions.py
+++ b/askbot/management/commands/add_missing_subscriptions.py
@@ -8,5 +8,5 @@ class Command(NoArgsCommand):
@transaction.commit_manually
def handle_noargs(self, **options):
for user in User.object.all():
- user.add_missing_subscriptions()
+ user.add_missing_askbot_subscriptions()
transaction.commit()
diff --git a/askbot/management/commands/post_emailed_questions.py b/askbot/management/commands/post_emailed_questions.py
index 73b5ed3e..0a038b62 100644
--- a/askbot/management/commands/post_emailed_questions.py
+++ b/askbot/management/commands/post_emailed_questions.py
@@ -27,6 +27,7 @@ from django.utils.translation import string_concat
from django.core.urlresolvers import reverse
from askbot.conf import settings as askbot_settings
from askbot.utils import mail
+from askbot.utils import url_utils
from askbot import models
from askbot.forms import AskByEmailForm
@@ -61,7 +62,7 @@ def bounce_email(email, subject, reason = None, body_text = None):
'by email, please register first
'
) % {
'site': askbot_settings.APP_SHORT_NAME,
- 'url': askbot_settings.APP_URL + reverse('user_signin')
+ 'url': url_utils.get_login_url()
}
elif reason == 'permission_denied':
error_message = _(
diff --git a/askbot/management/commands/send_email_alerts.py b/askbot/management/commands/send_email_alerts.py
index 53a5db46..f92aff63 100644
--- a/askbot/management/commands/send_email_alerts.py
+++ b/askbot/management/commands/send_email_alerts.py
@@ -388,7 +388,7 @@ class Command(NoArgsCommand):
#does not change the database, only sends the email
#todo: move this to template
for user in User.objects.all():
- user.add_missing_subscriptions()
+ user.add_missing_askbot_subscriptions()
#todo: q_list is a dictionary, not a list
q_list = self.get_updated_questions_for_user(user)
if len(q_list.keys()) == 0:
diff --git a/askbot/models/__init__.py b/askbot/models/__init__.py
index e4a1280e..3afcefef 100644
--- a/askbot/models/__init__.py
+++ b/askbot/models/__init__.py
@@ -861,6 +861,37 @@ def user_post_comment(
)
return comment
+def user_post_anonymous_askbot_content(user, session_key):
+ """posts any posts added just before logging in
+ the posts are identified by the session key, thus the second argument
+
+ this function is used by the signal handler with a similar name
+ """
+ aq_list = AnonymousQuestion.objects.filter(session_key = session_key)
+ aa_list = AnonymousAnswer.objects.filter(session_key = session_key)
+ #from askbot.conf import settings as askbot_settings
+ if askbot_settings.EMAIL_VALIDATION == True:#add user to the record
+ for aq in aq_list:
+ aq.author = user
+ aq.save()
+ for aa in aa_list:
+ aa.author = user
+ aa.save()
+ #maybe add pending posts message?
+ else:
+ if user.is_blocked():
+ msg = _('blocked users cannot post')
+ user.message_set.create(message = msg)
+ elif user.is_suspended():
+ msg = _('suspended users cannot post')
+ user.message_set.create(message = msg)
+ else:
+ for aq in aq_list:
+ aq.publish(user)
+ for aa in aa_list:
+ aa.publish(user)
+
+
def user_mark_tags(
self,
tagnames = None,
@@ -1320,7 +1351,7 @@ def user_set_admin_status(self):
self.is_staff = True
self.is_superuser = True
-def user_add_missing_subscriptions(self):
+def user_add_missing_askbot_subscriptions(self):
from askbot import forms#need to avoid circular dependency
form = forms.EditUserEmailFeedsForm()
need_feed_types = form.get_db_model_subscription_type_names()
@@ -1865,7 +1896,10 @@ def user_update_wildcard_tag_selections(
return new_tags
-User.add_to_class('add_missing_subscriptions', user_add_missing_subscriptions)
+User.add_to_class(
+ 'add_missing_askbot_subscriptions',
+ user_add_missing_askbot_subscriptions
+)
User.add_to_class('is_username_taken',classmethod(user_is_username_taken))
User.add_to_class(
'get_followed_question_alert_frequency',
@@ -1885,6 +1919,10 @@ User.add_to_class('edit_question', user_edit_question)
User.add_to_class('retag_question', user_retag_question)
User.add_to_class('post_answer', user_post_answer)
User.add_to_class('edit_answer', user_edit_answer)
+User.add_to_class(
+ 'post_anonymous_askbot_content',
+ user_post_anonymous_askbot_content
+)
User.add_to_class('post_comment', user_post_comment)
User.add_to_class('edit_comment', user_edit_comment)
User.add_to_class('delete_post', user_delete_post)
@@ -2384,7 +2422,7 @@ def complete_pending_tag_subscriptions(sender, request, *args, **kwargs):
message = _('Your tag subscription was saved, thanks!')
)
-def post_stored_anonymous_content(
+def post_anonymous_askbot_content(
sender,
request,
user,
@@ -2392,30 +2430,10 @@ def post_stored_anonymous_content(
signal,
*args,
**kwargs):
-
- aq_list = AnonymousQuestion.objects.filter(session_key = session_key)
- aa_list = AnonymousAnswer.objects.filter(session_key = session_key)
- #from askbot.conf import settings as askbot_settings
- if askbot_settings.EMAIL_VALIDATION == True:#add user to the record
- for aq in aq_list:
- aq.author = user
- aq.save()
- for aa in aa_list:
- aa.author = user
- aa.save()
- #maybe add pending posts message?
- else:
- if user.is_blocked():
- msg = _('blocked users cannot post')
- user.message_set.create(message = msg)
- elif user.is_suspended():
- msg = _('suspended users cannot post')
- user.message_set.create(message = msg)
- else:
- for aq in aq_list:
- aq.publish(user)
- for aa in aa_list:
- aa.publish(user)
+ """signal handler, unfortunately extra parameters
+ are necessary for the signal machinery, even though
+ they are not used in this function"""
+ user.post_anonymous_askbot_content(session_key)
def set_user_has_custom_avatar_flag(instance, created, **kwargs):
instance.user.update_has_custom_avatar()
@@ -2453,8 +2471,8 @@ signals.flag_offensive.connect(record_flag_offensive, sender=Question)
signals.flag_offensive.connect(record_flag_offensive, sender=Answer)
signals.tags_updated.connect(record_update_tags)
signals.user_updated.connect(record_user_full_updated, sender=User)
-signals.user_logged_in.connect(post_stored_anonymous_content)
-signals.user_logged_in.connect(complete_pending_tag_subscriptions)
+signals.user_logged_in.connect(complete_pending_tag_subscriptions)#todo: add this to fake onlogin middleware
+signals.user_logged_in.connect(post_anonymous_askbot_content)
signals.post_updated.connect(
record_post_update_activity,
sender=Comment
diff --git a/askbot/skins/default/templates/authopenid/complete.html b/askbot/skins/default/templates/authopenid/complete.html
index 40ec4ccc..969a173f 100644
--- a/askbot/skins/default/templates/authopenid/complete.html
+++ b/askbot/skins/default/templates/authopenid/complete.html
@@ -52,7 +52,7 @@ parameters:
{% elif login_type=='facebook' %}