diff options
-rw-r--r-- | django_authopenid/views.py | 9 | ||||
-rw-r--r-- | forum/admin.py | 3 | ||||
-rw-r--r-- | forum/const/__init__.py | 137 | ||||
-rw-r--r-- | forum/const/message_keys.py | 19 | ||||
-rw-r--r-- | forum/context.py | 26 | ||||
-rw-r--r-- | forum/doc/HOW_TO_DEBUG (renamed from forum/documentation/HOW_TO_DEBUG) | 0 | ||||
-rw-r--r-- | forum/doc/INSTALL (renamed from forum/documentation/INSTALL) | 0 | ||||
-rw-r--r-- | forum/doc/INSTALL.pip (renamed from forum/documentation/INSTALL.pip) | 0 | ||||
-rw-r--r-- | forum/doc/INSTALL.webfaction (renamed from forum/documentation/INSTALL.webfaction) | 0 | ||||
-rw-r--r-- | forum/doc/ROADMAP.rst (renamed from forum/documentation/ROADMAP.rst) | 0 | ||||
-rw-r--r-- | forum/doc/TODO.rst (renamed from forum/documentation/TODO.rst) | 0 | ||||
-rw-r--r-- | forum/doc/UPGRADE (renamed from forum/documentation/UPGRADE) | 0 | ||||
-rw-r--r-- | forum/doc/WISH_LIST (renamed from forum/documentation/WISH_LIST) | 0 | ||||
-rw-r--r-- | forum/doc/askbot-requirements.txt (renamed from forum/documentation/askbot-requirements.txt) | 0 | ||||
-rw-r--r-- | forum/doc/scratch (renamed from forum/documentation/scratch) | 0 | ||||
-rw-r--r-- | forum/feed.py | 8 | ||||
-rw-r--r-- | forum/forms.py | 9 | ||||
-rw-r--r-- | forum/management/commands/send_email_alerts.py | 21 | ||||
-rw-r--r-- | forum/middleware/anon_user.py | 4 | ||||
-rw-r--r-- | forum/models/__init__.py | 2 | ||||
-rw-r--r-- | forum/models/conf/README | 5 | ||||
-rw-r--r-- | forum/models/conf/__init__.py (renamed from forum/conf/__init__.py) | 5 | ||||
-rw-r--r-- | forum/models/conf/email.py | 20 | ||||
-rw-r--r-- | forum/models/conf/external_keys.py | 88 | ||||
-rw-r--r-- | forum/models/conf/flatpages.py | 38 | ||||
-rw-r--r-- | forum/models/conf/forum_data_rules.py | 53 | ||||
-rw-r--r-- | forum/models/conf/minimum_reputation.py (renamed from forum/conf/minimum_reputation.py) | 0 | ||||
-rw-r--r-- | forum/models/conf/reputation_changes.py (renamed from forum/conf/reputation_changes.py) | 0 | ||||
-rw-r--r-- | forum/models/conf/settings_wrapper.py (renamed from forum/conf/settings_wrapper.py) | 0 | ||||
-rw-r--r-- | forum/models/conf/site_settings.py | 81 | ||||
-rw-r--r-- | forum/models/conf/vote_rules.py (renamed from forum/conf/vote_rules.py) | 0 | ||||
-rw-r--r-- | forum/models/question.py | 13 | ||||
-rw-r--r-- | forum/search/state_manager.py | 3 | ||||
-rw-r--r-- | forum/settings.py | 1 | ||||
-rw-r--r-- | forum/skins/default/templates/about.html | 20 | ||||
-rw-r--r-- | forum/skins/default/templates/base.html | 4 | ||||
-rw-r--r-- | forum/skins/default/templates/base_content.html | 4 | ||||
-rw-r--r-- | forum/skins/default/templates/footer.html | 2 | ||||
-rw-r--r-- | forum/skins/default/templates/header.html | 75 | ||||
-rw-r--r-- | forum/skins/default/templates/privacy.html | 27 | ||||
-rw-r--r-- | forum/skins/default/templates/question.html | 6 | ||||
-rw-r--r-- | forum/templatetags/extra_tags.py | 7 | ||||
-rw-r--r-- | settings.py | 3 |
43 files changed, 552 insertions, 141 deletions
diff --git a/django_authopenid/views.py b/django_authopenid/views.py index 4f7d3efa..c12017b2 100644 --- a/django_authopenid/views.py +++ b/django_authopenid/views.py @@ -35,6 +35,7 @@ from django.http import HttpResponseRedirect, get_host, Http404, \ from django.shortcuts import render_to_response from django.template import RequestContext, loader, Context from django.conf import settings +from forum.conf import settings as forum_settings from django.contrib.auth.models import User from django.contrib.auth.decorators import login_required from django.contrib.auth import authenticate @@ -616,7 +617,7 @@ def signup(request): 'authopenid/confirm_email.txt' ) message_context = Context({ - 'signup_url': settings.APP_URL + reverse('user_signin'), + 'signup_url': forum_settings.APP_URL + reverse('user_signin'), 'username': username, 'password': password, }) @@ -760,7 +761,7 @@ def _send_email_key(user): message_template = loader.get_template('authopenid/email_validation.txt') import settings message_context = Context({ - 'validation_link': settings.APP_URL + reverse('user_verifyemail', kwargs={'id':user.id,'key':user.email_key}) + 'validation_link': forum_settings.APP_URL + reverse('user_verifyemail', kwargs={'id':user.id,'key':user.email_key}) }) message = message_template.render(message_context) send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, [user.email]) @@ -1118,10 +1119,10 @@ def sendpw(request): subject = _("Request for new password") message_template = loader.get_template( 'authopenid/sendpw_email.txt') - key_link = settings.APP_URL + reverse('user_confirmchangepw') + '?key=' + confirm_key + key_link = forum_settings.APP_URL + reverse('user_confirmchangepw') + '?key=' + confirm_key logging.debug('emailing new password for %s' % form.user_cache.username) message_context = Context({ - 'site_url': settings.APP_URL + reverse('index'), + 'site_url': forum_settings.APP_URL + reverse('index'), 'key_link': key_link, 'username': form.user_cache.username, 'password': new_pw, diff --git a/forum/admin.py b/forum/admin.py index 3afa2241..41b68b9a 100644 --- a/forum/admin.py +++ b/forum/admin.py @@ -1,7 +1,6 @@ # -*- coding: utf-8 -*- - from django.contrib import admin -from models import * +from forum.models import * class AnonymousQuestionAdmin(admin.ModelAdmin): """AnonymousQuestion admin class""" diff --git a/forum/const/__init__.py b/forum/const/__init__.py new file mode 100644 index 00000000..50676189 --- /dev/null +++ b/forum/const/__init__.py @@ -0,0 +1,137 @@ +# encoding:utf-8 +from django.utils.translation import ugettext as _ +""" +All constants could be used in other modules +For reasons that models, views can't have unicode text in this project, all unicode text go here. +""" +CLOSE_REASONS = ( + (1, _('duplicate question')), + (2, _('question is off-topic or not relevant')), + (3, _('too subjective and argumentative')), + (4, _('not a real question')), + (5, _('the question is answered, right answer was accepted')), + (6, _('question is not relevant or outdated')), + (7, _('question contains offensive or malicious remarks')), + (8, _('spam or advertising')), + (9, _('too localized')), +) + +TYPE_REPUTATION = ( + (1, 'gain_by_upvoted'), + (2, 'gain_by_answer_accepted'), + (3, 'gain_by_accepting_answer'), + (4, 'gain_by_downvote_canceled'), + (5, 'gain_by_canceling_downvote'), + (-1, 'lose_by_canceling_accepted_answer'), + (-2, 'lose_by_accepted_answer_cancled'), + (-3, 'lose_by_downvoted'), + (-4, 'lose_by_flagged'), + (-5, 'lose_by_downvoting'), + (-6, 'lose_by_flagged_lastrevision_3_times'), + (-7, 'lose_by_flagged_lastrevision_5_times'), + (-8, 'lose_by_upvote_canceled'), +) + +#do not translate these!!! +POST_SORT_METHODS = ( + ('latest', _('newest')), + ('oldest', _('oldest')), + ('active', _('active')), + ('inactive', _('inactive')), + ('hottest', _('hottest')), + ('coldest', _('coldest')), + ('mostvoted', _('most voted')), + ('leastvoted', _('least voted')), + ('relevant', _('relevance')), + ) +#todo: add assertion here that all sort methods are unique +#because they are keys to the hash used in implementations of Q.run_advanced_search + +DEFAULT_POST_SORT_METHOD = 'active' +POST_SCOPE_LIST = ( + ('all', _('all')), + ('unanswered', _('unanswered')), + ('favorite', _('favorite')), + ) +DEFAULT_POST_SCOPE = 'all' +PAGE_SIZE_CHOICES = (('10','10',),('30','30',),('50','50',),) + +UNANSWERED_QUESTION_MEANING_CHOICES = ( + ('NO_ANSWERS', _('Question has no answers')), + ('NO_ACCEPTED_ANSWERS', _('Question has no accepted answers')), +) +#todo: implement this +# ('NO_UPVOTED_ANSWERS',), +#) + +#todo: +#this probably needs to be language-specific +#and selectable/changeable from the admin interface +#however it will be hard to expect that people will type +#correct regexes - plus this must be an anchored regex +#to do full string match +TAG_REGEX = r'^[a-z0-9\+\.\-]+$' +TAG_SPLIT_REGEX = r'[ ,]+' + +TYPE_ACTIVITY_ASK_QUESTION=1 +TYPE_ACTIVITY_ANSWER=2 +TYPE_ACTIVITY_COMMENT_QUESTION=3 +TYPE_ACTIVITY_COMMENT_ANSWER=4 +TYPE_ACTIVITY_UPDATE_QUESTION=5 +TYPE_ACTIVITY_UPDATE_ANSWER=6 +TYPE_ACTIVITY_PRIZE=7 +TYPE_ACTIVITY_MARK_ANSWER=8 +TYPE_ACTIVITY_VOTE_UP=9 +TYPE_ACTIVITY_VOTE_DOWN=10 +TYPE_ACTIVITY_CANCEL_VOTE=11 +TYPE_ACTIVITY_DELETE_QUESTION=12 +TYPE_ACTIVITY_DELETE_ANSWER=13 +TYPE_ACTIVITY_MARK_OFFENSIVE=14 +TYPE_ACTIVITY_UPDATE_TAGS=15 +TYPE_ACTIVITY_FAVORITE=16 +TYPE_ACTIVITY_USER_FULL_UPDATED = 17 +TYPE_ACTIVITY_QUESTION_EMAIL_UPDATE_SENT = 18 +#TYPE_ACTIVITY_EDIT_QUESTION=17 +#TYPE_ACTIVITY_EDIT_ANSWER=18 + +TYPE_ACTIVITY = ( + (TYPE_ACTIVITY_ASK_QUESTION, _('question')), + (TYPE_ACTIVITY_ANSWER, _('answer')), + (TYPE_ACTIVITY_COMMENT_QUESTION, _('commented question')), + (TYPE_ACTIVITY_COMMENT_ANSWER, _('commented answer')), + (TYPE_ACTIVITY_UPDATE_QUESTION, _('edited question')), + (TYPE_ACTIVITY_UPDATE_ANSWER, _('edited answer')), + (TYPE_ACTIVITY_PRIZE, _('received award')), + (TYPE_ACTIVITY_MARK_ANSWER, _('marked best answer')), + (TYPE_ACTIVITY_VOTE_UP, _('upvoted')), + (TYPE_ACTIVITY_VOTE_DOWN, _('downvoted')), + (TYPE_ACTIVITY_CANCEL_VOTE, _('canceled vote')), + (TYPE_ACTIVITY_DELETE_QUESTION, _('deleted question')), + (TYPE_ACTIVITY_DELETE_ANSWER, _('deleted answer')), + (TYPE_ACTIVITY_MARK_OFFENSIVE, _('marked offensive')), + (TYPE_ACTIVITY_UPDATE_TAGS, _('updated tags')), + (TYPE_ACTIVITY_FAVORITE, _('selected favorite')), + (TYPE_ACTIVITY_USER_FULL_UPDATED, _('completed user profile')), + (TYPE_ACTIVITY_QUESTION_EMAIL_UPDATE_SENT, _('email update sent to user')), +) + +TYPE_RESPONSE = { + 'QUESTION_ANSWERED' : _('question_answered'), + 'QUESTION_COMMENTED': _('question_commented'), + 'ANSWER_COMMENTED' : _('answer_commented'), + 'ANSWER_ACCEPTED' : _('answer_accepted'), +} + +CONST = { + 'closed' : _('[closed]'), + 'deleted' : _('[deleted]'), + 'default_version' : _('initial version'), + 'retagged' : _('retagged'), +} + +#how to filter questions by tags in email digests? +TAG_EMAIL_FILTER_CHOICES = (('ignored', _('exclude ignored tags')),('interesting',_('allow only selected tags'))) +USERS_PAGE_SIZE = 28#todo: move it to settings? + +#an exception import * because that file has only strings +from forum.const.message_keys import * diff --git a/forum/const/message_keys.py b/forum/const/message_keys.py new file mode 100644 index 00000000..c52b9353 --- /dev/null +++ b/forum/const/message_keys.py @@ -0,0 +1,19 @@ +""" +This file must hold keys for translatable messages +that are used as variables +it is important that a dummy _() function is used here +this way message key will be pulled into django.po +and can still be used as a variable in python files +""" +_ = 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>!') diff --git a/forum/context.py b/forum/context.py index 043af81d..daa1ee21 100644 --- a/forum/context.py +++ b/forum/context.py @@ -1,21 +1,23 @@ from django.conf import settings +from forum.conf import settings as forum_settings def application_settings(context): my_settings = { - 'APP_TITLE' : settings.APP_TITLE, - 'APP_SHORT_NAME' : settings.APP_SHORT_NAME, - 'APP_URL' : settings.APP_URL, - 'APP_KEYWORDS' : settings.APP_KEYWORDS, - 'APP_DESCRIPTION' : settings.APP_DESCRIPTION, - 'APP_INTRO' : settings.APP_INTRO, + 'WIKI_ON':forum_settings.WIKI_ON, + 'APP_TITLE' : forum_settings.APP_TITLE, + 'APP_URL' : forum_settings.APP_URL, + 'APP_KEYWORDS' : forum_settings.APP_KEYWORDS, + 'APP_DESCRIPTION': forum_settings.APP_DESCRIPTION, + 'APP_COPYRIGHT': forum_settings.APP_COPYRIGHT, + 'FEEDBACK_SITE_URL': forum_settings.FEEDBACK_SITE_URL, + 'FORUM_ABOUT': forum_settings.FORUM_ABOUT, + 'FORUM_PRIVACY': forum_settings.FORUM_PRIVACY, + 'GOOGLE_SITEMAP_CODE':forum_settings.GOOGLE_VERIFICATION_CODE, + 'GOOGLE_ANALYTICS_KEY':forum_settings.GOOGLE_ANALYTICS_KEY, + 'RESOURCE_REVISION':settings.RESOURCE_REVISION, + 'ASKBOT_SKIN':settings.ASKBOT_DEFAULT_SKIN, 'EMAIL_VALIDATION': settings.EMAIL_VALIDATION, - 'FEEDBACK_SITE_URL': settings.FEEDBACK_SITE_URL, 'FORUM_SCRIPT_ALIAS': settings.FORUM_SCRIPT_ALIAS, 'LANGUAGE_CODE': settings.LANGUAGE_CODE, - 'GOOGLE_SITEMAP_CODE':settings.GOOGLE_SITEMAP_CODE, - 'GOOGLE_ANALYTICS_KEY':settings.GOOGLE_ANALYTICS_KEY, - 'WIKI_ON':settings.WIKI_ON, - 'RESOURCE_REVISION':settings.RESOURCE_REVISION, - 'ASKBOT_SKIN':settings.ASKBOT_DEFAULT_SKIN, 'EDITABLE_SCREEN_NAME':settings.EDITABLE_SCREEN_NAME, } return {'settings':my_settings} diff --git a/forum/documentation/HOW_TO_DEBUG b/forum/doc/HOW_TO_DEBUG index fbbdb1f7..fbbdb1f7 100644 --- a/forum/documentation/HOW_TO_DEBUG +++ b/forum/doc/HOW_TO_DEBUG diff --git a/forum/documentation/INSTALL b/forum/doc/INSTALL index 73714566..73714566 100644 --- a/forum/documentation/INSTALL +++ b/forum/doc/INSTALL diff --git a/forum/documentation/INSTALL.pip b/forum/doc/INSTALL.pip index 2f817ff8..2f817ff8 100644 --- a/forum/documentation/INSTALL.pip +++ b/forum/doc/INSTALL.pip diff --git a/forum/documentation/INSTALL.webfaction b/forum/doc/INSTALL.webfaction index a449ffe6..a449ffe6 100644 --- a/forum/documentation/INSTALL.webfaction +++ b/forum/doc/INSTALL.webfaction diff --git a/forum/documentation/ROADMAP.rst b/forum/doc/ROADMAP.rst index c79e0ae4..c79e0ae4 100644 --- a/forum/documentation/ROADMAP.rst +++ b/forum/doc/ROADMAP.rst diff --git a/forum/documentation/TODO.rst b/forum/doc/TODO.rst index b89013b0..b89013b0 100644 --- a/forum/documentation/TODO.rst +++ b/forum/doc/TODO.rst diff --git a/forum/documentation/UPGRADE b/forum/doc/UPGRADE index 538b75a0..538b75a0 100644 --- a/forum/documentation/UPGRADE +++ b/forum/doc/UPGRADE diff --git a/forum/documentation/WISH_LIST b/forum/doc/WISH_LIST index 2b53662c..2b53662c 100644 --- a/forum/documentation/WISH_LIST +++ b/forum/doc/WISH_LIST diff --git a/forum/documentation/askbot-requirements.txt b/forum/doc/askbot-requirements.txt index 66a37fbe..66a37fbe 100644 --- a/forum/documentation/askbot-requirements.txt +++ b/forum/doc/askbot-requirements.txt diff --git a/forum/documentation/scratch b/forum/doc/scratch index 948055fa..948055fa 100644 --- a/forum/documentation/scratch +++ b/forum/doc/scratch diff --git a/forum/feed.py b/forum/feed.py index e4b929e9..3d3a3241 100644 --- a/forum/feed.py +++ b/forum/feed.py @@ -1,7 +1,7 @@ #!/usr/bin/env python #encoding:utf-8 #------------------------------------------------------------------------------- -# Name: Syndication feed class for subsribtion +# Name: Syndication feed class for subscription # Purpose: # # Author: Mike @@ -13,10 +13,10 @@ from django.contrib.syndication.feeds import Feed, FeedDoesNotExist from django.utils.translation import ugettext as _ from models import Question -from django.conf import settings +from forum.conf import settings class RssLastestQuestionsFeed(Feed): - title = settings.APP_TITLE + _(' - ')+ _('latest questions') - link = settings.APP_URL #+ '/' + _('question/') + title = settings.ASKBOT_FORUM_TITLE + _(' - ')+ _('latest questions') + link = settings.APP_URL description = settings.APP_DESCRIPTION #ttl = 10 copyright = settings.APP_COPYRIGHT diff --git a/forum/forms.py b/forum/forms.py index e9781dc9..52cf00cc 100644 --- a/forum/forms.py +++ b/forum/forms.py @@ -11,6 +11,7 @@ from django.contrib.contenttypes.models import ContentType from forum.utils.forms import NextUrlField, UserNameField, SetPasswordForm from recaptcha_django import ReCaptchaField from django.conf import settings +from forum.conf import settings as forum_settings import logging @@ -65,7 +66,7 @@ class TagNamesField(forms.CharField): tag_strings = split_re.split(data) out_tag_list = [] tag_count = len(tag_strings) - if tag_count > const.MAX_TAGS_PER_POST: + if tag_count > forum_settings.MAX_TAGS_PER_POST: msg = ungettext( 'please use %(tag_count)d tag or less',#odd but have to use to pluralize 'please use %(tag_count)d tags or less', @@ -73,7 +74,7 @@ class TagNamesField(forms.CharField): raise forms.ValidationError(msg) for tag in tag_strings: tag_length = len(tag) - if tag_length > const.MAX_TAG_LENGTH: + if tag_length > forum_settings.MAX_TAG_LENGTH: #singular form is odd in english, but required for pluralization #in other languages msg = ungettext('each tag must be shorter than %(max_chars)d character',#odd but added for completeness @@ -97,7 +98,7 @@ class WikiField(forms.BooleanField): self.label = _('community wiki') self.help_text = _('if you choose community wiki option, the question and answer do not generate points and name of author will not be shown') def clean(self,value): - return value and settings.WIKI_ON + return value and forum_settings.WIKI_ON class EmailNotifyField(forms.BooleanField): def __init__(self, *args, **kwargs): @@ -231,7 +232,7 @@ class AnswerForm(forms.Form): def __init__(self, question, user, *args, **kwargs): super(AnswerForm, self).__init__(*args, **kwargs) self.fields['email_notify'].widget.attrs['id'] = 'question-subscribe-updates'; - if question.wiki and settings.WIKI_ON: + if question.wiki and forum_settings.WIKI_ON: self.fields['wiki'].initial = True if user.is_authenticated(): if user in question.followed_by.all(): diff --git a/forum/management/commands/send_email_alerts.py b/forum/management/commands/send_email_alerts.py index 42a6b3b3..2691a217 100644 --- a/forum/management/commands/send_email_alerts.py +++ b/forum/management/commands/send_email_alerts.py @@ -1,13 +1,14 @@ from django.core.management.base import NoArgsCommand from django.db import connection from django.db.models import Q, F -from forum.models import * -from forum import const +from forum.models import User, Question, Answer, Tag, QuestionRevision +from forum.models import AnswerRevision, Activity, EmailFeedSetting from django.core.mail import EmailMessage from django.utils.translation import ugettext as _ from django.utils.translation import ungettext import datetime from django.conf import settings +from forum.conf import settings as forum_settings import logging from forum.utils.odict import OrderedDict from django.contrib.contenttypes.models import ContentType @@ -18,7 +19,7 @@ def extend_question_list(src, dst, limit=False): or None dst - is an ordered dictionary """ - if limit and len(dst.keys()) >= const.MAX_ALERTS_PER_EMAIL: + if limit and len(dst.keys()) >= forum_settings.MAX_ALERTS_PER_EMAIL: return if src is None:#is not QuerySet return #will not do anything if subscription of this type is not used @@ -110,16 +111,16 @@ class Command(NoArgsCommand): q_ask_B = Q_set_B.filter(author=user) q_ask_B.cutoff_time = cutoff_time elif feed.feed_type == 'q_ans': - q_ans_A = Q_set_A.filter(answers__author=user)[:const.MAX_ALERTS_PER_EMAIL] + q_ans_A = Q_set_A.filter(answers__author=user)[:forum_settings.MAX_ALERTS_PER_EMAIL] q_ans_A.cutoff_time = cutoff_time - q_ans_B = Q_set_B.filter(answers__author=user)[:const.MAX_ALERTS_PER_EMAIL] + q_ans_B = Q_set_B.filter(answers__author=user)[:forum_settings.MAX_ALERTS_PER_EMAIL] q_ans_B.cutoff_time = cutoff_time elif feed.feed_type == 'q_all': if user.tag_filter_setting == 'ignored': ignored_tags = Tag.objects.filter(user_selections__reason='bad', \ user_selections__user=user) - q_all_A = Q_set_A.exclude( tags__in=ignored_tags )[:const.MAX_ALERTS_PER_EMAIL] - q_all_B = Q_set_B.exclude( tags__in=ignored_tags )[:const.MAX_ALERTS_PER_EMAIL] + q_all_A = Q_set_A.exclude( tags__in=ignored_tags )[:forum_settings.MAX_ALERTS_PER_EMAIL] + q_all_B = Q_set_B.exclude( tags__in=ignored_tags )[:forum_settings.MAX_ALERTS_PER_EMAIL] else: selected_tags = Tag.objects.filter(user_selections__reason='good', \ user_selections__user=user) @@ -232,7 +233,7 @@ class Command(NoArgsCommand): else: num_q += 1 if num_q > 0: - url_prefix = settings.APP_URL + url_prefix = forum_settings.APP_URL subject = _('email update message subject') print 'have %d updated questions for %s' % (num_q, user.username) text = ungettext('%(name)s, this is an update message header for a question', @@ -246,7 +247,7 @@ class Command(NoArgsCommand): act_list = [] if meta_data['skip']: continue - if items_added >= const.MAX_ALERTS_PER_EMAIL: + if items_added >= forum_settings.MAX_ALERTS_PER_EMAIL: items_unreported = num_q - items_added #may be inaccurate actually, but it's ok else: @@ -261,7 +262,7 @@ class Command(NoArgsCommand): % (url_prefix + q.get_absolute_url(), q.title, act_token) text += '</ul>' text += '<p></p>' - #if len(q_list.keys()) >= const.MAX_ALERTS_PER_EMAIL: + #if len(q_list.keys()) >= forum_settings.MAX_ALERTS_PER_EMAIL: # text += _('There may be more questions updated since ' # 'you have logged in last time as this list is ' # 'abridged for your convinience. Please visit ' diff --git a/forum/middleware/anon_user.py b/forum/middleware/anon_user.py index 866734da..e0e4eb51 100644 --- a/forum/middleware/anon_user.py +++ b/forum/middleware/anon_user.py @@ -2,7 +2,6 @@ from django.http import HttpResponseRedirect from forum.utils.forms import get_next_url from django.utils.translation import ugettext as _ from forum.user_messages import create_message, get_and_delete_messages -from django.conf import settings from django.core.urlresolvers import reverse import logging @@ -29,7 +28,8 @@ class ConnectToSessionMessagesMiddleware(object): request.user.get_and_delete_messages = request.user.message_set.get_and_delete #also set the first greeting one time per session only + from forum.conf import settings if 'greeting_set' not in request.session: request.session['greeting_set'] = True - msg = _('First time here? Check out the <a href="%s">FAQ</a>!') % reverse('faq') + msg = _(const.GREETING_FOR_ANONYMOUS_USER) % settings.GREETING_URL request.user.message_set.create(message=msg) diff --git a/forum/models/__init__.py b/forum/models/__init__.py index 07d34402..5140f9e1 100644 --- a/forum/models/__init__.py +++ b/forum/models/__init__.py @@ -408,7 +408,7 @@ def record_user_full_updated(instance, **kwargs): def post_stored_anonymous_content(sender,user,session_key,signal,*args,**kwargs): aq_list = AnonymousQuestion.objects.filter(session_key = session_key) aa_list = AnonymousAnswer.objects.filter(session_key = session_key) - import settings + from django.conf import settings if settings.EMAIL_VALIDATION == 'on':#add user to the record for aq in aq_list: aq.author = user diff --git a/forum/models/conf/README b/forum/models/conf/README new file mode 100644 index 00000000..4dd62329 --- /dev/null +++ b/forum/models/conf/README @@ -0,0 +1,5 @@ +this directory contains +forum site configurations for livesettings + +they need to be imported in models so made this a part of +models module diff --git a/forum/conf/__init__.py b/forum/models/conf/__init__.py index 6625ca5e..f30617a1 100644 --- a/forum/conf/__init__.py +++ b/forum/models/conf/__init__.py @@ -1,5 +1,6 @@ import os from livesettings import ConfigurationGroup, IntegerValue, config_register, SortedDotDict +from forum import models INSTALLED_APPS = ['forum'] @@ -52,6 +53,10 @@ def setup_django_settings(settings): import forum.conf.minimum_reputation import forum.conf.vote_rules import forum.conf.reputation_changes +import forum.conf.email +import forum.conf.forum_data_rules +import forum.conf.flatpages +import forum.conf.external_keys #import main settings object from forum.conf.settings_wrapper import settings diff --git a/forum/models/conf/email.py b/forum/models/conf/email.py new file mode 100644 index 00000000..ca66d4ae --- /dev/null +++ b/forum/models/conf/email.py @@ -0,0 +1,20 @@ +""" +Email related settings +""" +from forum.conf.settings_wrapper import settings +from livesettings import ConfigurationGroup, IntegerValue +from django.utils.translation import ugettext as _ + +EMAIL = ConfigurationGroup( + 'EMAIL', + _('Email and email alert settings'), + ) + +settings.register( + IntegerValue( + EMAIL, + 'MAX_ALERTS_PER_EMAIL', + default=7, + description=_('Maximum number of news entries in an email alert') + ) +) diff --git a/forum/models/conf/external_keys.py b/forum/models/conf/external_keys.py new file mode 100644 index 00000000..5d0d47e4 --- /dev/null +++ b/forum/models/conf/external_keys.py @@ -0,0 +1,88 @@ +""" +External service key settings +""" +from forum.conf.settings_wrapper import settings +from livesettings import ConfigurationGroup, IntegerValue +from django.utils.translation import ugettext as _ + +EXTERNAL_KEYS = ConfigurationGroup( + 'EXTERNAL_KEYS', + _('Keys to connect the site with external services like Facebook, etc.') + ) + +settings.register( + StringValue( + EXTERNAL_KEYS, + 'GOOGLE_SITEMAP_CODE', + description=_('Google site verification key'), + help_text=_( + 'This key helps google index your site ' + 'please obtain is at ' + '<a href="%(google_webmasters_tools_url)s">' + 'google webmasters tools site</a>' + ) % {'google_webmasters_tools_url': + 'https://www.google.com/webmasters/tools/home?hl=' \ + + django_settings.LANGUAGE_CODE} + ) +) + +settings.register( + StringValue( + EXTERNAL_KEYS, + 'GOOGLE_ANALYTICS_KEY', + description=_('Google Analytics key'), + help_text=_( + 'Obtain is at <a href="%(ga_site)s>' + 'Google Analytics</a> site, if you ' + 'wish to use Google Analytics to monitor ' + 'your site' + ) % {'ga_site':'http://www.google.com/intl/%s/analytics/' \ + % django_settings.LANGUAGE_CODE } + ) +) + +settings.register( + StringValue( + EXERNAL_KEYS, + 'RECAPTCHA_PRIVATE_KEY' + description=_('Recaptcha private key') + ' - does not work yet'), + help_text=_( + 'Recaptcha is a tool that helps distinguish ' + 'real people from annoying spam robots. ' + 'Please get this and a public key at ' + 'the <a href="http://recaptcha.net">recaptcha.net</a>' + ) + ) +) + +settings.register( + StringValue( + EXTERNAL_KEYS, + 'RECAPTCHA_PUBLIC_KEY', + description=_('Recaptcha public key') + ' - does not work yet') + ) +) + +settings.register( + StringValue( + EXTERNAL_KEYS, + 'FB_API_KEY', + description=_('Facebook public API key') + ' - does not work yet', + help_text=_( + 'Facebook API key and Facebook secret ' + 'allow to use Facebook Connect login method ' + 'at your site. Please obtain these keys ' + 'at <a href="http://www.facebook.com/developers/createapp.php>' + 'facebook create app</a> site' + ) + ) + +) + +settings.register( + StringValue( + EXTERNAL_KEYS, + 'FB_SECRET', + description=_('Facebook secret key') + ' - does not work yet' + ) +) diff --git a/forum/models/conf/flatpages.py b/forum/models/conf/flatpages.py new file mode 100644 index 00000000..acbf9951 --- /dev/null +++ b/forum/models/conf/flatpages.py @@ -0,0 +1,38 @@ +""" +Q&A forum flatpages (about, etc.) +""" +from forum.conf.settings_wrapper import settings +from livesettings import ConfigurationGroup, LongStringValue +from django.utils.translation import ugettext as _ +from django.core.urlresolvers import reverse + +FLATPAGES = ConfigurationGroup( + 'FLATPAGES', + _('Flatpages - about, privacy policy, etc.') + ) + +settings.register( + LongStringValue( + FLATPAGES, + 'FORUM_ABOUT', + description=_('Text the Q&A forum About page (html format)'), + help_text=\ + _( + 'Save, then <a href="http://validator.w3.org/check?uri=%(url)s">' + 'validate HTML</a>' + ) % {'url':reverse('about')} + ) +) + +settings.register( + LongStringValue( + FLATPAGES, + 'FORUM_PRIVACY', + description=_('Text the Q&A forum Privacy Policy (html format)'), + help_text=\ + _( + 'Save, then <a href="http://validator.w3.org/check?uri=%(url)s">' + 'validate HTML</a>' + ) % {'url':reverse('privacy')} + ) +) diff --git a/forum/models/conf/forum_data_rules.py b/forum/models/conf/forum_data_rules.py new file mode 100644 index 00000000..fcce0987 --- /dev/null +++ b/forum/models/conf/forum_data_rules.py @@ -0,0 +1,53 @@ +""" +Settings for forum data display and entry +""" +from forum.conf.settings_wrapper import settings +from livesettings import ConfigurationGroup, BooleanValue, IntegerValue +from livesettings import StringValue +from django.utils.translation import ugettext as _ +from forum import const + +FORUM_DATA_RULES = ConfigurationGroup( + 'FORUM_DATA_RULES', + _('Settings for forum data entry and display') + ) + +settings.register( + BooleanValue( + FORUM_DATA_RULES, + 'WIKI_ON', + default=True, + description=_('Enable/disable community wiki feature') + ) +) + +settings.register( + IntegerValue( + FORUM_DATA_RULES, + 'MAX_TAG_LENGTH', + default=20, + description=_('Maximum length of tag (number of characters)') + ) +) + +#todo: looks like there is a bug in livesettings +#that does not allow Integer values with defaults and choices +settings.register( + StringValue( + FORUM_DATA_RULES, + 'DEFAULT_QUESTIONS_PAGE_SIZE', + choices=const.PAGE_SIZE_CHOICES, + default='30', + description=_('Number of questions to list by default') + ) +) + +settings.register( + StringValue( + FORUM_DATA_RULES, + 'UNANSWERED_QUESTION_MEANING', + choices=const.UNANSWERED_QUESTION_MEANING_CHOICES, + default='NO_ACCEPTED_ANSWERS', + description=_('What should "unanswered question" mean?') + ) +) diff --git a/forum/conf/minimum_reputation.py b/forum/models/conf/minimum_reputation.py index a83d94fd..a83d94fd 100644 --- a/forum/conf/minimum_reputation.py +++ b/forum/models/conf/minimum_reputation.py diff --git a/forum/conf/reputation_changes.py b/forum/models/conf/reputation_changes.py index cef177f5..cef177f5 100644 --- a/forum/conf/reputation_changes.py +++ b/forum/models/conf/reputation_changes.py diff --git a/forum/conf/settings_wrapper.py b/forum/models/conf/settings_wrapper.py index abf49e5f..abf49e5f 100644 --- a/forum/conf/settings_wrapper.py +++ b/forum/models/conf/settings_wrapper.py diff --git a/forum/models/conf/site_settings.py b/forum/models/conf/site_settings.py new file mode 100644 index 00000000..e3eb2023 --- /dev/null +++ b/forum/models/conf/site_settings.py @@ -0,0 +1,81 @@ +""" +Q&A website settings - title, desctiption, basic urls +keywords +""" +from forum.conf.settings_wrapper import settings +from livesettings import ConfigurationGroup, StringValue +from django.utils.translation import ugettext as _ +from django.conf import settings as django_settings +from forum import const +from django.core.urlresolvers import reverse + +QA_SITE_SETTINGS = ConfigurationGroup( + 'QA_SITE_SETTINGS', + _('Q&A forum website parameters and urls') + ) + +settings.register( + StringValue( + QA_SITE_SETTINGS, + 'APP_TITLE', + default=u'ASKBOT: Open Source Q&A Forum', + description=_('Site title for the Q&A forum') + ) +) + +settings.register( + StringValue( + QA_SITE_SETTINGS, + 'APP_KEYWORDS', + default=u'ASKBOT,CNPROG,forum,community', + description=_('Comma separated list of Q&A site keywords') + ) +) + +settings.register( + StringValue( + QA_SITE_SETTINGS, + 'APP_COPYRIGHT', + default='Copyright ASKBOT, 2010. Some rights reserved under creative commons license.', + description=_('Copyright message to show in the footer') + ) +) + +settings.register( + StringValue( + QA_SITE_SETTINGS, + 'APP_DESCRIPTION', + default='Open source question and answer forum written in Python and Django', + description=_('Site description for the search engines') + ) +) + +settings.register( + StringValue( + QA_SITE_SETTINGS, + 'APP_URL', + default='http://askbot.org', + description=_('Base URL for your Q&A forum, must start with http or https'), + ) +) + +settings.register( + StringValue( + QA_SITE_SETTINGS, + 'GREETING_URL', + default=reverse('faq'), + description=_('Link shown in the greeting message shown to the anonymous user'), + help_text=_('If you change this url from the default - ' + 'then you wil have to adjust translation of ' + 'the following string: ') + const.GREETING_FOR_ANONYMOUS_USER + ) +) + +settings.register( + StringValue( + QA_SITE_SETTINGS, + 'FEEBACK_SITE_URL' + description=_('Feedback site URL'), + help_text=_('If left empty, a simple internal feedback form will be used instead') + ) +) diff --git a/forum/conf/vote_rules.py b/forum/models/conf/vote_rules.py index f249ef53..f249ef53 100644 --- a/forum/conf/vote_rules.py +++ b/forum/models/conf/vote_rules.py diff --git a/forum/models/question.py b/forum/models/question.py index 4d3154b0..1d387ab7 100644 --- a/forum/models/question.py +++ b/forum/models/question.py @@ -96,16 +96,19 @@ class QuestionManager(models.Manager): params=['%' + search_query + '%'] ) + #have to import this at run time, otherwise there + #a circular import dependency... + from forum.conf import settings as forum_settings if scope_selector: if scope_selector == 'unanswered': - if const.UNANSWERED_MEANING == 'NO_ANSWERS': + if forum_settings.UNANSWERED_QUESTION_MEANING == 'NO_ANSWERS': qs = qs.filter(answer_count=0)#todo: expand for different meanings of this - elif const.UNANSWERED_MEANING == 'NO_ACCEPTED_ANSWERS': + elif forum_settings.UNANSWERED_QUESTION_MEANING == 'NO_ACCEPTED_ANSWERS': qs = qs.filter(answer_accepted=False) - elif const.UNANSWERED_MEANING == 'NO_UPVOTED_ANSWERS': + elif forum_settings.UNANSWERED_QUESTION_MEANING == 'NO_UPVOTED_ANSWERS': raise NotImplementedError() else: - raise Exception('UNANSWERED_MEANING setting is wrong') + raise Exception('UNANSWERED_QUESTION_MEANING setting is wrong') elif scope_selector == 'favorite': qs = qs.filter(favorited_by = request_user) @@ -513,7 +516,7 @@ class Question(Content, DeletableContent): out.append(_('%(people)s commented answers') % {'people':people}) else: out.append(_('%(people)s commented an answer') % {'people':people}) - url = settings.APP_URL + self.get_absolute_url() + url = forum_settings.APP_URL + self.get_absolute_url() retval = '<a href="%s">%s</a>:<br>\n' % (url,self.title) out = map(lambda x: '<li>' + x + '</li>',out) retval += '<ul>' + '\n'.join(out) + '</ul><br>\n' diff --git a/forum/search/state_manager.py b/forum/search/state_manager.py index 6a38a7a2..ac3f7014 100644 --- a/forum/search/state_manager.py +++ b/forum/search/state_manager.py @@ -2,6 +2,7 @@ #that lives in the session and takes care of the state #persistece during the search session from forum import const +from forum.conf import settings import logging ACTIVE_COMMANDS = ( @@ -24,7 +25,7 @@ class SearchState(object): self.tags = None self.author = None self.sort = const.DEFAULT_POST_SORT_METHOD - self.page_size = const.DEFAULT_QUESTIONS_PAGE_SIZE + self.page_size = int(settings.DEFAULT_QUESTIONS_PAGE_SIZE) self.page = 1 self.logged_in = False logging.debug('new search state initialized') diff --git a/forum/settings.py b/forum/settings.py index 4147be8c..6e31634f 100644 --- a/forum/settings.py +++ b/forum/settings.py @@ -1,3 +1,4 @@ +#todo: this file is currently not in use import os from livesettings import ConfigurationGroup, IntegerValue, config_register diff --git a/forum/skins/default/templates/about.html b/forum/skins/default/templates/about.html index 686141b3..d091725b 100644 --- a/forum/skins/default/templates/about.html +++ b/forum/skins/default/templates/about.html @@ -12,25 +12,7 @@ </div> <div class="content"> - <p class="strong">Please customize file templates/about.html</p> - - <p>Here you can <strong>ask</strong> and <strong>answer</strong> questions, <strong>comment</strong> - and <strong>vote</strong> for the questions of others and their answers. Both questions and answers - <strong>can be revised</strong> and improved. Questions can be <strong>tagged</strong> with - the relevant keywords to simplify future access and organize the accumulated material. - </p> - - <p>This <span class="orange">Q&A</span> site is moderated by its members, hopefully - including yourself! - Moderation rights are gradually assigned to the site users based on the accumulated <strong>"reputation"</strong> - points. These points are added to the users account when others vote for his/her questions or answers. - These points (very) roughly reflect the level of trust of the community. - </p> - <p>No points are necessary to ask or answer the questions - so please - - <strong><a href="{% url user_signin %}">join us!</a></strong> - </p> - <p> - If you would like to find out more about this site - please see <strong><a href="{% url faq %}">frequently asked questions</a></strong>. - </p> + {{settings.FORUM_ABOUT|safe}} </div> {% endblock %} <!-- end template about.html --> diff --git a/forum/skins/default/templates/base.html b/forum/skins/default/templates/base.html index a4e4ceed..94d3392d 100644 --- a/forum/skins/default/templates/base.html +++ b/forum/skins/default/templates/base.html @@ -9,8 +9,12 @@ <title>{% block title %}{% endblock %} - {{ settings.APP_TITLE }}</title> {% spaceless %} {% block meta %}{% endblock %} + {% block meta_description %} + <meta name="description" content="{{settings.APP_DESCRIPTION}}" /> + {% endblock %} {% endspaceless %} <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta name="keywords" content="{%block keywords%}{%endblock%},{{settings.APP_KEYWORDS}}" /> {% if settings.GOOGLE_SITEMAP_CODE %} <meta name="google-site-verification" content="{{settings.GOOGLE_SITEMAP_CODE}}" /> {% endif %} diff --git a/forum/skins/default/templates/base_content.html b/forum/skins/default/templates/base_content.html index 284007d8..7b49d9ba 100644 --- a/forum/skins/default/templates/base_content.html +++ b/forum/skins/default/templates/base_content.html @@ -6,6 +6,10 @@ <head> <title>{% block title %}{% endblock %} - {{ settings.APP_TITLE }}</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta name="keywords" content="{%block keywords%}{%endblock%},{{settings.APP_KEYWORDS}}" /> + {% block meta_description %} + <meta name="description" content="{{settings.APP_DESCRIPTION}}" /> + {% endblock %} {% if settings.GOOGLE_SITEMAP_CODE %} <meta name="google-site-verification" content="{{ settings.GOOGLE_SITEMAP_CODE }}" /> {% endif %} diff --git a/forum/skins/default/templates/footer.html b/forum/skins/default/templates/footer.html index 9b7c5d98..a28a1980 100644 --- a/forum/skins/default/templates/footer.html +++ b/forum/skins/default/templates/footer.html @@ -23,7 +23,7 @@ <p> <a href="http://askbot.org" target="_blank"> powered by ASKBOT - </a> + </a><br/>{{settings.APP_COPYRIGHT}} </p> </div> <div id="licenseLogo"> diff --git a/forum/skins/default/templates/header.html b/forum/skins/default/templates/header.html index 0a1a3296..f2eaa3ac 100644 --- a/forum/skins/default/templates/header.html +++ b/forum/skins/default/templates/header.html @@ -2,46 +2,37 @@ {% load extra_tags %} {% load smart_if %} {% load i18n %} - <div id="roof"> - <div id="navBar"> - <div id="top"> - {% if request.user.is_authenticated %} - <a href="{% url user_profile id=request.user.id,slug=request.user.username|slugify %}">{{ request.user.username }}</a> {% get_score_badge request.user %} - <a href="{% url logout %}">{% trans "logout" %}</a> - {% else %} - <a href="{% url user_signin %}">{% trans "login" %}</a> - {% endif %} - <a href="{% url about %}">{% trans "about" %}</a> - <a href="{% url faq %}">{% trans "faq" %}</a> - </div> - <table border="0" cellspacing="0" cellpadding="0"> - <tr> - <td id="logoContainer"> - <div id="logo"> - <a href="{% url questions %}?start_over=true"><img - src="{% media "/media/images/logo.gif" %}" title="{% trans "back to home page" %}" alt="{{settings.APP_TITLE}} logo"/></a> - </div> - </td> - <td id="navTabContainer" valign="bottom" align="left"> - <div class="nav"> - <a id="nav_questions" href="{% url questions %}" >{% trans "questions" %}</a> - <a id="nav_tags" href="{% url tags %}">{% trans "tags" %}</a> - <a id="nav_users" href="{% url users %}">{% trans "users" %}</a> - {% if settings.BOOKS_ON %} - <a id="nav_books" href="{% url books %}">{% trans "books" %}</a> - {% endif %} - <a id="nav_badges" href="{% url badges %}">{% trans "badges" %}</a> - <a id="nav_ask" href="{% url ask %}" class="special">{% trans "ask a question" %}</a> - {% comment %} - <a id="nav_unanswered" href="{% url unanswered %}">{% trans "unanswered questions" %}</a> - <div class="focus"> - <a id="nav_ask" href="{% url ask %}" class="special">{% trans "ask a question" %}</a> - </div> - {% endcomment %} - </div> - </td> - </tr> - </table> - </div> - </div> +<div id="roof"> + <div id="navBar"> + <div id="top"> + {% if request.user.is_authenticated %} + <a href="{% url user_profile id=request.user.id,slug=request.user.username|slugify %}">{{ request.user.username }}</a> {% get_score_badge request.user %} + <a href="{% url logout %}">{% trans "logout" %}</a> + {% else %} + <a href="{% url user_signin %}">{% trans "login" %}</a> + {% endif %} + <a href="{% url about %}">{% trans "about" %}</a> + <a href="{% url faq %}">{% trans "faq" %}</a> + </div> + <table border="0" cellspacing="0" cellpadding="0"> + <tr> + <td id="logoContainer"> + <div id="logo"> + <a href="{% url questions %}?start_over=true"><img + src="{% media "/media/images/logo.gif" %}" title="{% trans "back to home page" %}" alt="{{settings.APP_TITLE}} logo"/></a> + </div> + </td> + <td id="navTabContainer" valign="bottom" align="left"> + <div class="nav"> + <a id="nav_questions" href="{% url questions %}" >{% trans "questions" %}</a> + <a id="nav_tags" href="{% url tags %}">{% trans "tags" %}</a> + <a id="nav_users" href="{% url users %}">{% trans "users" %}</a> + <a id="nav_badges" href="{% url badges %}">{% trans "badges" %}</a> + <a id="nav_ask" href="{% url ask %}" class="special">{% trans "ask a question" %}</a> + </div> + </td> + </tr> + </table> + </div> +</div> <!-- end template header.html --> diff --git a/forum/skins/default/templates/privacy.html b/forum/skins/default/templates/privacy.html index e66086dd..fe074491 100644 --- a/forum/skins/default/templates/privacy.html +++ b/forum/skins/default/templates/privacy.html @@ -11,32 +11,7 @@ {% trans "Privacy policy" %} </div> <div id="main-body" style="width:100%"> - <p> - {% trans "general message about privacy" %} - </p> - - <h3 class="subtitle">{% trans "Site Visitors" %}</h3> - <p> - {% trans "what technical information is collected about visitors" %} - </p> - - <h3 class="subtitle">{% trans "Personal Information" %}</h3> - <p> - {% trans "details on personal information policies" %} - </p> - - <h3 class="subtitle">{% trans "Other Services" %}</h3> - <p> - {% trans "details on sharing data with third parties" %} - </p> - - <h3 class="subtitle">Cookies</h3> - <p> - {% trans "cookie policy details" %} - </p> - <h3 class="subtitle">{% trans "Policy Changes" %}</h3> - <p>{% trans "how privacy policies can be changed" %} - </p> + {{settings.FORUM_PRIVACY|safe}} </div> {% endblock %} <!-- end privacy.html --> diff --git a/forum/skins/default/templates/question.html b/forum/skins/default/templates/question.html index 48b6d719..84ef9978 100644 --- a/forum/skins/default/templates/question.html +++ b/forum/skins/default/templates/question.html @@ -7,9 +7,11 @@ {% load i18n %}
{% load cache %}
{% block title %}{% spaceless %}{{ question.get_question_title }}{% endspaceless %}{% endblock %}
-{% block forejs %}
+{% block meta_description %}
<meta name="description" content="{{question.summary}}" />
- <meta name="keywords" content="{{question.tagname_meta_generator}}" />
+{% endblock %}
+{% block keywords %}{{question.tagname_meta_generator}}{% endblock %}
+{% block forejs %}
<link rel="canonical" href="{{settings.APP_URL}}{{question.get_absolute_url}}" />
{% if not question.closed %}
<script type='text/javascript' src='{% media "/media/js/com.cnprog.editor.js" %}'></script>
diff --git a/forum/templatetags/extra_tags.py b/forum/templatetags/extra_tags.py index 86f2e9df..36de4ec5 100644 --- a/forum/templatetags/extra_tags.py +++ b/forum/templatetags/extra_tags.py @@ -13,6 +13,7 @@ from forum.models import Question, Answer, QuestionRevision, AnswerRevision from django.utils.translation import ugettext as _ from django.utils.translation import ungettext from django.conf import settings +from forum.conf import settings as forum_settings from django.template.defaulttags import url as default_url from django.template.defaultfilters import slugify from django.core.urlresolvers import reverse @@ -146,7 +147,7 @@ def post_contributor_info(post,contributor_type='original_author'): return { 'post':post, 'post_type':post_type, - 'wiki_on':settings.WIKI_ON, + 'wiki_on':forum_settings.WIKI_ON, 'contributor_type':contributor_type } @@ -395,7 +396,7 @@ class FullUrlNode(template.Node): self.default_node = default_node def render(self, context): - domain = settings.APP_URL + domain = forum_settings.APP_URL #protocol = getattr(settings, "PROTOCOL", "http") path = self.default_node.render(context) return "%s%s" % (domain, path) @@ -407,7 +408,7 @@ def fullurl(parser, token): @register.simple_tag def fullmedia(url): - domain = settings.APP_URL + domain = forum_settings.APP_URL #protocol = getattr(settings, "PROTOCOL", "http") path = media(url) return "%s%s" % (domain, path) diff --git a/settings.py b/settings.py index 97d80e97..98555997 100644 --- a/settings.py +++ b/settings.py @@ -89,9 +89,6 @@ INSTALLED_APPS = ( AUTHENTICATION_BACKENDS = ('django.contrib.auth.backends.ModelBackend',) -if USE_FB_CONNECT: - INSTALLED_APPS += ('fbconnect',) - #this needs to go if 'USE_EXTERNAL_LEGACY_LOGIN' in locals() and USE_EXTERNAL_LEGACY_LOGIN: INSTALLED_APPS += (EXTERNAL_LEGACY_LOGIN_MODULE,) |