From 5ec0ae6635bc9ece491c23b18507f2a558ce14e5 Mon Sep 17 00:00:00 2001 From: Evgeny Fadeev Date: Sun, 9 May 2010 00:57:43 -0400 Subject: broken commit. will transfer last bits of settings to livesettings tomorrow --- django_authopenid/views.py | 2 +- fbconnect/fb.py | 16 +-- fbconnect/urls.py | 10 +- forum/conf/README | 5 + forum/conf/__init__.py | 12 ++ forum/conf/email.py | 27 ++++ forum/conf/external_keys.py | 89 ++++++++++++ forum/conf/flatpages.py | 37 +++++ forum/conf/forum_data_rules.py | 53 ++++++++ forum/conf/minimum_reputation.py | 148 ++++++++++++++++++++ forum/conf/reputation_changes.py | 149 +++++++++++++++++++++ forum/conf/settings_wrapper.py | 59 ++++++++ forum/conf/site_settings.py | 89 ++++++++++++ forum/conf/skin_counter_settings.py | 24 ++++ forum/conf/skin_general_settings.py | 3 + forum/conf/user_settings.py | 2 + forum/conf/vote_rules.py | 69 ++++++++++ forum/context.py | 2 +- forum/feed.py | 2 +- forum/middleware/anon_user.py | 3 +- forum/models/conf/README | 5 - forum/models/conf/__init__.py | 62 --------- forum/models/conf/email.py | 20 --- forum/models/conf/external_keys.py | 88 ------------ forum/models/conf/flatpages.py | 38 ------ forum/models/conf/forum_data_rules.py | 53 -------- forum/models/conf/minimum_reputation.py | 148 -------------------- forum/models/conf/reputation_changes.py | 149 --------------------- forum/models/conf/settings_wrapper.py | 59 -------- forum/models/conf/site_settings.py | 81 ----------- forum/models/conf/vote_rules.py | 69 ---------- .../default/templates/fbconnect/xd_receiver.html | 2 +- livesettings/templatetags/config_tags.py | 2 + 33 files changed, 788 insertions(+), 789 deletions(-) create mode 100644 forum/conf/README create mode 100644 forum/conf/__init__.py create mode 100644 forum/conf/email.py create mode 100644 forum/conf/external_keys.py create mode 100644 forum/conf/flatpages.py create mode 100644 forum/conf/forum_data_rules.py create mode 100644 forum/conf/minimum_reputation.py create mode 100644 forum/conf/reputation_changes.py create mode 100644 forum/conf/settings_wrapper.py create mode 100644 forum/conf/site_settings.py create mode 100644 forum/conf/skin_counter_settings.py create mode 100644 forum/conf/skin_general_settings.py create mode 100644 forum/conf/user_settings.py create mode 100644 forum/conf/vote_rules.py delete mode 100644 forum/models/conf/README delete mode 100644 forum/models/conf/__init__.py delete mode 100644 forum/models/conf/email.py delete mode 100644 forum/models/conf/external_keys.py delete mode 100644 forum/models/conf/flatpages.py delete mode 100644 forum/models/conf/forum_data_rules.py delete mode 100644 forum/models/conf/minimum_reputation.py delete mode 100644 forum/models/conf/reputation_changes.py delete mode 100644 forum/models/conf/settings_wrapper.py delete mode 100644 forum/models/conf/site_settings.py delete mode 100644 forum/models/conf/vote_rules.py diff --git a/django_authopenid/views.py b/django_authopenid/views.py index c12017b2..0212955c 100644 --- a/django_authopenid/views.py +++ b/django_authopenid/views.py @@ -365,7 +365,7 @@ def signin(request,newquestion=False,newanswer=False): 'form2': form_signin, 'msg': request.GET.get('msg',''), 'sendpw_url': reverse('user_sendpw'), - 'fb_api_key': settings.FB_API_KEY, + 'fb_api_key': forum_settings.FB_API_KEY, }, context_instance=RequestContext(request)) def complete_signin(request): diff --git a/fbconnect/fb.py b/fbconnect/fb.py index afcd8210..8d41c3a2 100644 --- a/fbconnect/fb.py +++ b/fbconnect/fb.py @@ -1,4 +1,4 @@ -from django.conf import settings +from forum.conf import settings as forum_settings from time import time from datetime import datetime from urllib import urlopen, urlencode @@ -20,11 +20,11 @@ def generate_sig(values): for key in sorted(values.keys()): keys.append(key) - signature = ''.join(['%s=%s' % (key, values[key]) for key in keys]) + settings.FB_SECRET + signature = ''.join(['%s=%s' % (key, values[key]) for key in keys]) + forum_settings.FB_SECRET return hashlib.md5(signature).hexdigest() def check_cookies_signature(cookies): - API_KEY = settings.FB_API_KEY + API_KEY = forum_settings.FB_API_KEY values = {} @@ -37,10 +37,10 @@ def check_cookies_signature(cookies): def get_user_data(cookies): request_data = { 'method': 'Users.getInfo', - 'api_key': settings.FB_API_KEY, + 'api_key': forum_settings.FB_API_KEY, 'call_id': time(), 'v': '1.0', - 'uids': cookies[settings.FB_API_KEY + '_user'], + 'uids': cookies[forum_settings.FB_API_KEY + '_user'], 'fields': 'name,first_name,last_name', 'format': 'json', } @@ -52,7 +52,7 @@ def get_user_data(cookies): def delete_cookies(response): - API_KEY = settings.FB_API_KEY + API_KEY = forum_settings.FB_API_KEY response.delete_cookie(API_KEY + '_user') response.delete_cookie(API_KEY + '_session_key') @@ -62,7 +62,7 @@ def delete_cookies(response): response.delete_cookie('fbsetting_' + API_KEY) def check_session_expiry(cookies): - return datetime.fromtimestamp(float(cookies[settings.FB_API_KEY+'_expires'])) > datetime.now() + return datetime.fromtimestamp(float(cookies[forum_settings.FB_API_KEY+'_expires'])) > datetime.now() STATES = { 'FIRSTTIMER': 1, @@ -72,7 +72,7 @@ STATES = { } def get_user_state(request): - API_KEY = settings.FB_API_KEY + API_KEY = forum_settings.FB_API_KEY logging.debug('') if API_KEY in request.COOKIES: diff --git a/fbconnect/urls.py b/fbconnect/urls.py index bf2d4364..81b0cb0f 100644 --- a/fbconnect/urls.py +++ b/fbconnect/urls.py @@ -1,13 +1,15 @@ from django.conf.urls.defaults import * from django.utils.translation import ugettext as _ from django.views.generic.simple import direct_to_template -from django.conf import settings from views import signin, register urlpatterns = patterns('', - url(r'^xd_receiver$', direct_to_template, {'template': 'fbconnect/xd_receiver.html',\ - 'extra_context': {'APP_SHORT_NAME':settings.APP_SHORT_NAME}},\ - name='xd_receiver'), + url( + r'^xd_receiver$', + direct_to_template, + {'template': 'fbconnect/xd_receiver.html',}, + name='xd_receiver' + ), url(r'^%s$' % _('signin/'), signin, name="fb_signin"), url(r'^%s%s$' % (_('signin/'), _('newquestion/')), signin, {'newquestion': True}, name="fb_signin_new_question"), diff --git a/forum/conf/README b/forum/conf/README new file mode 100644 index 00000000..4dd62329 --- /dev/null +++ b/forum/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/conf/__init__.py new file mode 100644 index 00000000..0c0c3b1a --- /dev/null +++ b/forum/conf/__init__.py @@ -0,0 +1,12 @@ +#import these to compile code and install values +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.site_settings +import forum.conf.external_keys + +#import main settings object +from forum.conf.settings_wrapper import settings diff --git a/forum/conf/email.py b/forum/conf/email.py new file mode 100644 index 00000000..702a2a67 --- /dev/null +++ b/forum/conf/email.py @@ -0,0 +1,27 @@ +""" +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') + ) +) + +#todo: move email.py email_settings.py? + +EMAIL_VALIDATION = 'off' #string - on|off +EMAIL_UNIQUE = False +ANONYMOUS_USER_EMAIL = 'anonymous@askbot.org' + diff --git a/forum/conf/external_keys.py b/forum/conf/external_keys.py new file mode 100644 index 00000000..b92fa493 --- /dev/null +++ b/forum/conf/external_keys.py @@ -0,0 +1,89 @@ +""" +External service key settings +""" +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 + +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 ' + '' + 'google webmasters tools site' + ) % {'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 ' + 'Google Analytics 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( + EXTERNAL_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 recaptcha.net' + ) + ) +) + +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 ' + 'facebook create app site' + ) + ) + +) + +settings.register( + StringValue( + EXTERNAL_KEYS, + 'FB_SECRET', + description=_('Facebook secret key') + ' - does not work yet' + ) +) diff --git a/forum/conf/flatpages.py b/forum/conf/flatpages.py new file mode 100644 index 00000000..6544f9e3 --- /dev/null +++ b/forum/conf/flatpages.py @@ -0,0 +1,37 @@ +""" +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 _ + +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 ' + 'validate HTML' + ) % {'url':_('about/')} + ) +) + +settings.register( + LongStringValue( + FLATPAGES, + 'FORUM_PRIVACY', + description=_('Text the Q&A forum Privacy Policy (html format)'), + help_text=\ + _( + 'Save, then ' + 'validate HTML' + ) % {'url':_('privacy/')} + ) +) diff --git a/forum/conf/forum_data_rules.py b/forum/conf/forum_data_rules.py new file mode 100644 index 00000000..fcce0987 --- /dev/null +++ b/forum/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/conf/minimum_reputation.py new file mode 100644 index 00000000..a83d94fd --- /dev/null +++ b/forum/conf/minimum_reputation.py @@ -0,0 +1,148 @@ +""" +Settings for minimum reputation required for +a variety of actions on the askbot forum +""" +from forum.conf.settings_wrapper import settings +from livesettings import ConfigurationGroup, IntegerValue +from django.utils.translation import ugettext as _ + +MIN_REP = ConfigurationGroup( + 'MIN_REP', + _('Minimum reputation required to perform actions'), + ordering=0 + ) + +settings.register( + IntegerValue( + MIN_REP, + 'MIN_REP_TO_VOTE_UP', + default=15, + description=_('Upvote') + ) + ) + +settings.register( + IntegerValue( + MIN_REP, + 'MIN_REP_TO_VOTE_DOWN', + default=100, + description=_('Downvote') + ) + ) + +settings.register( + IntegerValue( + MIN_REP, + 'MIN_REP_TO_FLAG_OFFENSIVE', + default=15, + description=_('Flag offensive') + ) + ) + +settings.register( + IntegerValue( + MIN_REP, + 'MIN_REP_TO_LEAVE_COMMENTS', + default=50, + description=_('Leave comments') + ) + ) + +settings.register( + IntegerValue( + MIN_REP, + 'MIN_REP_TO_DELETE_OTHERS_COMMENTS', + default=2000, + description=_('Delete comments posted by others') + ) + ) + +settings.register( + IntegerValue( + MIN_REP, + 'MIN_REP_TO_UPLOAD_FILES', + default=60, + description=_('Upload files') + ) + ) + +settings.register( + IntegerValue( + MIN_REP, + 'MIN_REP_TO_CLOSE_OWN_QUESTIONS', + default=250, + description=_('Close own questions'), + ) + ) + +settings.register( + IntegerValue( + MIN_REP, + 'MIN_REP_TO_RETAG_OTHERS_QUESTIONS', + default=500, + description=_('Retag questions posted by other people') + ) + ) + +settings.register( + IntegerValue( + MIN_REP, + 'MIN_REP_TO_REOPEN_OWN_QUESTIONS', + default=500, + description=_('Reopen own questions') + ) + ) + +settings.register( + IntegerValue( + MIN_REP, + 'MIN_REP_TO_EDIT_WIKI', + default=750, + description=_('Edit community wiki posts') + ) + ) + +settings.register( + IntegerValue( + MIN_REP, + 'MIN_REP_TO_EDIT_OTHERS_POSTS', + default=2000, + description=_('Edit posts authored by other people') + ) + ) + +settings.register( + IntegerValue( + MIN_REP, + 'MIN_REP_TO_VIEW_OFFENSIVE_FLAGS', + default=2000, + description=_('View offensive flags') + ) + ) + +settings.register( + IntegerValue( + MIN_REP, + 'MIN_REP_TO_DISABLE_URL_NOFOLLOW', + default=2000, + description=_('Disable nofollow directive on links') + ) + ) + +settings.register( + IntegerValue( + MIN_REP, + 'MIN_REP_TO_CLOSE_OTHERS_QUESTIONS', + default=2000, + description=_('Close questions asked by others') + ) + ) + +settings.register( + IntegerValue( + MIN_REP, + 'MIN_REP_TO_LOCK_POSTS', + default=4000, + description=_('Lock posts') + ) + ) diff --git a/forum/conf/reputation_changes.py b/forum/conf/reputation_changes.py new file mode 100644 index 00000000..cef177f5 --- /dev/null +++ b/forum/conf/reputation_changes.py @@ -0,0 +1,149 @@ +""" +Settings for reputation changes that apply to +user in response to various actions by the same +users or others +""" +from forum.conf.settings_wrapper import settings +from livesettings import ConfigurationGroup, IntegerValue +from django.utils.translation import ugettext as _ + +REP_CHANGES = ConfigurationGroup( + 'REP_CHANGES', + _('Reputaion loss and gain rules'), + ordering=2 + ) + +settings.register( + IntegerValue( + REP_CHANGES, + 'MAX_REP_GAIN_PER_USER_PER_DAY', + default=200, + description=_('Maximum daily reputation gain per user') + ) +) + +settings.register( + IntegerValue( + REP_CHANGES, + 'REP_GAIN_FOR_RECEIVING_UPVOTE', + default=10, + description=_('Gain for receiving an upvote') + ) +) + +settings.register( + IntegerValue( + REP_CHANGES, + 'REP_GAIN_FOR_RECEIVING_ANSWER_ACCEPTANCE', + default=15, + description=_('Gain for the author of accepted answer') + ) +) + +settings.register( + IntegerValue( + REP_CHANGES, + 'REP_GAIN_FOR_ACCEPTING_ANSWER', + default=2, + description=_('Gain for accepting best answer') + ) +) + +settings.register( + IntegerValue( + REP_CHANGES, + 'REP_GAIN_FOR_RECEIVING_DOWNVOTE_CANCELATION', + default=2, + description=_('Gain for post owner on canceled downvote') + ) +) + +settings.register( + IntegerValue( + REP_CHANGES, + 'REP_GAIN_FOR_CANCELING_DOWNVOTE', + default=1, + description=_('Gain for voter on canceling downvote') + ) +) +#'gain_by_canceling_downvote', + +settings.register( + IntegerValue( + REP_CHANGES, + 'REP_LOSS_FOR_CANCELING_ANSWER_ACCEPTANCE', + default=-2, + description=_('Loss for voter for canceling of answer acceptance') + ) +) +#'lose_by_canceling_accepted_answer', + +settings.register( + IntegerValue( + REP_CHANGES, + 'REP_LOSS_FOR_RECEIVING_CANCELATION_OF_ANSWER_ACCEPTANCE', + default=-5, + description=_('Loss for author whose answer was "un-accepted"') + ) +) +#'lose_by_accepted_answer_cancled', + +settings.register( + IntegerValue( + REP_CHANGES, + 'REP_LOSS_FOR_DOWNVOTING', + default=-2, + description=_('Loss for giving a downvote') + ) +) +#'lose_by_downvoted', + +settings.register( + IntegerValue( + REP_CHANGES, + 'REP_LOSS_FOR_RECEIVING_FLAG', + default=-2, + description=_('Loss for owner of post that was flagged offensive') + ) +) +#'lose_by_flagged', + +settings.register( + IntegerValue( + REP_CHANGES, + 'REP_LOSS_FOR_RECEIVING_DOWNVOTE', + default=-1, + description=_('Loss for owner of post that was downvoted') + ) +) +#'lose_by_downvoting', + +settings.register( + IntegerValue( + REP_CHANGES, + 'REP_LOSS_FOR_RECEIVING_THREE_FLAGS_PER_REVISION', + default=-30, + description=_('Loss for owner of post that was flagged 3 times per same revision') + ) +) +#'lose_by_flagged_lastrevision_3_times', + +settings.register( + IntegerValue( + REP_CHANGES, + 'REP_LOSS_FOR_RECEIVING_FIVE_FLAGS_PER_REVISION', + default=-100, + description=_('Loss for owner of post that was flagged 5 times per same revision') + ) +) +#'lose_by_flagged_lastrevision_5_times', + +settings.register( + IntegerValue( + REP_CHANGES, + 'REP_LOSS_FOR_RECEIVING_UPVOTE_CANCELATION', + default=-10, + description=_('Loss for post owner when upvote is canceled') + ) +) +#'lose_by_upvote_canceled', diff --git a/forum/conf/settings_wrapper.py b/forum/conf/settings_wrapper.py new file mode 100644 index 00000000..abf49e5f --- /dev/null +++ b/forum/conf/settings_wrapper.py @@ -0,0 +1,59 @@ +""" +Definition of a Singleton wrapper class for livesettings +with interface similar to django.conf.settings +that is each setting has unique key and is accessible +via dotted lookup. + +for example to lookup value of setting BLAH you would do + +from forum.conf import settings + +settings.BLAH + +the value will be taken from livesettings database or cache +note that during compilation phase database is not accessible +for the most part, so actual values are reliably available only +at run time + +livesettings is a module developed for satchmo project +""" +from livesettings import SortedDotDict, config_register + +class ConfigSettings(object): + """A very simple Singleton wrapper for settings + a limitation is that all settings names using this class + must be distinct, even though they might belong + to different settings groups + """ + __instance = None + + def __init__(self): + """assigns SortedDotDict to self.__instance if not set""" + if ConfigSettings.__instance == None: + ConfigSettings.__instance = SortedDotDict() + self.__dict__['_ConfigSettings__instance'] = ConfigSettings.__instance + + def __getattr__(self, key): + """value lookup returns the actual value of setting + not the object - this way only very minimal modifications + will be required in code to convert an app + depending on django.conf.settings to livesettings + """ + return getattr(self.__instance, key).value + + def __setattr__(self, attr, value): + """ settings crutch is read-only in the program """ + raise Exception('ConfigSettings cannot be changed programmatically') + + def register(self, value): + """registers the setting + value must be a subclass of livesettings.Value + """ + key = value.key + if key in self.__instance: + raise Exception('setting %s is already registered' % key) + else: + self.__instance[key] = config_register(value) + +#settings instance to be used elsewhere in the project +settings = ConfigSettings() diff --git a/forum/conf/site_settings.py b/forum/conf/site_settings.py new file mode 100644 index 00000000..b6f7f0ab --- /dev/null +++ b/forum/conf/site_settings.py @@ -0,0 +1,89 @@ +""" +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 + +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_SHORT_NAME', + default=_('Askbot'), + description=_('Short name for your Q&A forum') + ) +) + +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=_('faq/'),#cannot reverse url here, unfortunately + 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, + 'FEEDBACK_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/skin_counter_settings.py b/forum/conf/skin_counter_settings.py new file mode 100644 index 00000000..7f612e93 --- /dev/null +++ b/forum/conf/skin_counter_settings.py @@ -0,0 +1,24 @@ +VOTE_COUNTER_EXPECTED_MAXIMUM = 3 +from forum_modules.grapefruit import Color +COLORS_VOTE_COUNTER_EMPTY_BG = 'white' +COLORS_VOTE_COUNTER_EMPTY_FG = 'gray' +COLORS_VOTE_COUNTER_MIN_BG = 'white' +COLORS_VOTE_COUNTER_MIN_FG = 'black' +COLORS_VOTE_COUNTER_MAX_BG = '#a9d0f5' +COLORS_VOTE_COUNTER_MAX_FG = Color.NewFromHtml(COLORS_VOTE_COUNTER_MAX_BG).DarkerColor(0.7).html +VIEW_COUNTER_EXPECTED_MAXIMUM = 100 +COLORS_VIEW_COUNTER_EMPTY_BG = 'gray' +COLORS_VIEW_COUNTER_EMPTY_FG = 'white' +COLORS_VIEW_COUNTER_MIN_BG = '#D0F5A9' +COLORS_VIEW_COUNTER_MIN_FG = Color.NewFromHtml(COLORS_VIEW_COUNTER_MIN_BG).DarkerColor(0.6).html +COLORS_VIEW_COUNTER_MAX_BG = '#FF8000'#'#F7BE81' +COLORS_VIEW_COUNTER_MAX_FG = Color.NewFromHtml(COLORS_VIEW_COUNTER_MAX_BG).DarkerColor(0.7).html +ANSWER_COUNTER_EXPECTED_MAXIMUM = 4 +COLORS_ANSWER_COUNTER_EMPTY_BG = Color.NewFromHtml('#a40000').Blend(Color.NewFromHtml('white'),0.8).html +COLORS_ANSWER_COUNTER_EMPTY_FG = 'yellow' +COLORS_ANSWER_COUNTER_MIN_BG = '#AEB404'#'#81F7F3'#'#A9D0F5'#'#045FB4' +COLORS_ANSWER_COUNTER_MIN_FG = 'white'#'#81F7F3' +COLORS_ANSWER_COUNTER_MAX_BG = Color.NewFromHtml('#61380B').Blend(Color.NewFromHtml('white'),0.75).html +COLORS_ANSWER_COUNTER_MAX_FG = '#ffff00' +COLORS_ANSWER_COUNTER_ACCEPTED_BG = Color.NewFromHtml('darkgreen').Blend(Color.NewFromHtml('white'),0.8).html +COLORS_ANSWER_COUNTER_ACCEPTED_FG = '#D0F5A9' diff --git a/forum/conf/skin_general_settings.py b/forum/conf/skin_general_settings.py new file mode 100644 index 00000000..14165587 --- /dev/null +++ b/forum/conf/skin_general_settings.py @@ -0,0 +1,3 @@ +#skin settings +RESOURCE_REVISION=4 +ASKBOT_DEFAULT_SKIN = 'default' diff --git a/forum/conf/user_settings.py b/forum/conf/user_settings.py new file mode 100644 index 00000000..62e7095c --- /dev/null +++ b/forum/conf/user_settings.py @@ -0,0 +1,2 @@ +EDITABLE_SCREEN_NAME = False#True or False - can user change screen name? +MIN_USERNAME_LENGTH = 1 diff --git a/forum/conf/vote_rules.py b/forum/conf/vote_rules.py new file mode 100644 index 00000000..f249ef53 --- /dev/null +++ b/forum/conf/vote_rules.py @@ -0,0 +1,69 @@ +""" +Forum configuration settings detailing rules on votes +and offensive flags. + +For example number of times a person can vote each day, etc. +""" +from forum.conf.settings_wrapper import settings +from livesettings import ConfigurationGroup, IntegerValue +from django.utils.translation import ugettext as _ + +VOTE_RULES = ConfigurationGroup( + 'VOTE_RULES', + _('Limits applicable to votes and moderation flags'), + ordering=1, + ) + +settings.register( + IntegerValue( + VOTE_RULES, + 'MAX_VOTES_PER_USER_PER_DAY', + default=30, + description=_('Number of votes a user can cast per day') + ) +) + +settings.register( + IntegerValue( + VOTE_RULES, + 'MAX_FLAGS_PER_USER_PER_DAY', + default=5, + description=_('Maximum number of flags per user per day') + ) +) + +settings.register( + IntegerValue( + VOTE_RULES, + 'VOTES_LEFT_WARNING_THRESHOLD', + default=5, + description=_('Threshold for warning about remaining daily votes') + ) +) + +settings.register( + IntegerValue( + VOTE_RULES, + 'MAX_DAYS_TO_CANCEL_VOTE', + default=1, + description=_('Number of days to allow canceling votes') + ) +) + +settings.register( + IntegerValue( + VOTE_RULES, + 'MIN_FLAGS_TO_HIDE_POST', + default=3, + description=_('Number of flags required to automatically hide posts') + ) +) + +settings.register( + IntegerValue( + VOTE_RULES, + 'MIN_FLAGS_TO_DELETE_POST', + default=5, + description=_('Number of flags required to automatically delete posts') + ) +) diff --git a/forum/context.py b/forum/context.py index daa1ee21..1cbb82ba 100644 --- a/forum/context.py +++ b/forum/context.py @@ -11,7 +11,7 @@ def application_settings(context): '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_SITEMAP_CODE':forum_settings.GOOGLE_SITEMAP_CODE, 'GOOGLE_ANALYTICS_KEY':forum_settings.GOOGLE_ANALYTICS_KEY, 'RESOURCE_REVISION':settings.RESOURCE_REVISION, 'ASKBOT_SKIN':settings.ASKBOT_DEFAULT_SKIN, diff --git a/forum/feed.py b/forum/feed.py index 3d3a3241..5d124eb9 100644 --- a/forum/feed.py +++ b/forum/feed.py @@ -15,7 +15,7 @@ from django.utils.translation import ugettext as _ from models import Question from forum.conf import settings class RssLastestQuestionsFeed(Feed): - title = settings.ASKBOT_FORUM_TITLE + _(' - ')+ _('latest questions') + title = settings.APP_TITLE + _(' - ')+ _('latest questions') link = settings.APP_URL description = settings.APP_DESCRIPTION #ttl = 10 diff --git a/forum/middleware/anon_user.py b/forum/middleware/anon_user.py index e0e4eb51..2d1dcd2d 100644 --- a/forum/middleware/anon_user.py +++ b/forum/middleware/anon_user.py @@ -3,6 +3,8 @@ 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.core.urlresolvers import reverse +from forum.conf import settings +from forum import const import logging class AnonymousMessageManager(object): @@ -28,7 +30,6 @@ 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 = _(const.GREETING_FOR_ANONYMOUS_USER) % settings.GREETING_URL diff --git a/forum/models/conf/README b/forum/models/conf/README deleted file mode 100644 index 4dd62329..00000000 --- a/forum/models/conf/README +++ /dev/null @@ -1,5 +0,0 @@ -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/models/conf/__init__.py b/forum/models/conf/__init__.py deleted file mode 100644 index f30617a1..00000000 --- a/forum/models/conf/__init__.py +++ /dev/null @@ -1,62 +0,0 @@ -import os -from livesettings import ConfigurationGroup, IntegerValue, config_register, SortedDotDict -from forum import models - -INSTALLED_APPS = ['forum'] - -MIDDLEWARE_CLASSES = [ - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.common.CommonMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'forum.middleware.anon_user.ConnectToSessionMessagesMiddleware', - 'forum.middleware.pagesize.QuestionsPageSizeMiddleware', - 'forum.middleware.cancel.CancelActionMiddleware', - 'django.middleware.transaction.TransactionMiddleware', -] - -TEMPLATE_LOADERS = [ - 'django.template.loaders.filesystem.load_template_source', - 'django.template.loaders.app_directories.load_template_source', - 'forum.modules.module_templates_loader', - 'forum.skins.load_template_source', -] - -TEMPLATE_CONTEXT_PROCESSORS = [ - 'django.core.context_processors.request', - 'forum.context.application_settings', - 'forum.user_messages.context_processors.user_messages', - 'django.core.context_processors.auth', -] - -TEMPLATE_DIRS = [ - os.path.join(os.path.dirname(__file__),'skins').replace('\\','/'), -] - -def setup_django_settings(settings): - - if (hasattr(settings, 'DEBUG') and getattr(settings, 'DEBUG')): - try: - import debug_toolbar - INSTALLED_APPS.append('debug_toolbar') - MIDDLEWARE_CLASSES.append('debug_toolbar.middleware.DebugToolbarMiddleware') - except: - pass - - - settings.INSTALLED_APPS = set(settings.INSTALLED_APPS) | set(INSTALLED_APPS) - settings.MIDDLEWARE_CLASSES = set(settings.MIDDLEWARE_CLASSES) | set(MIDDLEWARE_CLASSES) - settings.TEMPLATE_LOADERS = set(settings.TEMPLATE_LOADERS) | set(TEMPLATE_LOADERS) - settings.TEMPLATE_CONTEXT_PROCESSORS = set(settings.TEMPLATE_CONTEXT_PROCESSORS) | set(TEMPLATE_CONTEXT_PROCESSORS) - settings.TEMPLATE_DIRS = set(settings.TEMPLATE_DIRS) | set(TEMPLATE_DIRS) - -#import these to compile code and install values -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 deleted file mode 100644 index ca66d4ae..00000000 --- a/forum/models/conf/email.py +++ /dev/null @@ -1,20 +0,0 @@ -""" -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 deleted file mode 100644 index 5d0d47e4..00000000 --- a/forum/models/conf/external_keys.py +++ /dev/null @@ -1,88 +0,0 @@ -""" -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 ' - '' - 'google webmasters tools site' - ) % {'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 recaptcha.net' - ) - ) -) - -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 ' - 'validate HTML' - ) % {'url':reverse('about')} - ) -) - -settings.register( - LongStringValue( - FLATPAGES, - 'FORUM_PRIVACY', - description=_('Text the Q&A forum Privacy Policy (html format)'), - help_text=\ - _( - 'Save, then ' - 'validate HTML' - ) % {'url':reverse('privacy')} - ) -) diff --git a/forum/models/conf/forum_data_rules.py b/forum/models/conf/forum_data_rules.py deleted file mode 100644 index fcce0987..00000000 --- a/forum/models/conf/forum_data_rules.py +++ /dev/null @@ -1,53 +0,0 @@ -""" -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/models/conf/minimum_reputation.py b/forum/models/conf/minimum_reputation.py deleted file mode 100644 index a83d94fd..00000000 --- a/forum/models/conf/minimum_reputation.py +++ /dev/null @@ -1,148 +0,0 @@ -""" -Settings for minimum reputation required for -a variety of actions on the askbot forum -""" -from forum.conf.settings_wrapper import settings -from livesettings import ConfigurationGroup, IntegerValue -from django.utils.translation import ugettext as _ - -MIN_REP = ConfigurationGroup( - 'MIN_REP', - _('Minimum reputation required to perform actions'), - ordering=0 - ) - -settings.register( - IntegerValue( - MIN_REP, - 'MIN_REP_TO_VOTE_UP', - default=15, - description=_('Upvote') - ) - ) - -settings.register( - IntegerValue( - MIN_REP, - 'MIN_REP_TO_VOTE_DOWN', - default=100, - description=_('Downvote') - ) - ) - -settings.register( - IntegerValue( - MIN_REP, - 'MIN_REP_TO_FLAG_OFFENSIVE', - default=15, - description=_('Flag offensive') - ) - ) - -settings.register( - IntegerValue( - MIN_REP, - 'MIN_REP_TO_LEAVE_COMMENTS', - default=50, - description=_('Leave comments') - ) - ) - -settings.register( - IntegerValue( - MIN_REP, - 'MIN_REP_TO_DELETE_OTHERS_COMMENTS', - default=2000, - description=_('Delete comments posted by others') - ) - ) - -settings.register( - IntegerValue( - MIN_REP, - 'MIN_REP_TO_UPLOAD_FILES', - default=60, - description=_('Upload files') - ) - ) - -settings.register( - IntegerValue( - MIN_REP, - 'MIN_REP_TO_CLOSE_OWN_QUESTIONS', - default=250, - description=_('Close own questions'), - ) - ) - -settings.register( - IntegerValue( - MIN_REP, - 'MIN_REP_TO_RETAG_OTHERS_QUESTIONS', - default=500, - description=_('Retag questions posted by other people') - ) - ) - -settings.register( - IntegerValue( - MIN_REP, - 'MIN_REP_TO_REOPEN_OWN_QUESTIONS', - default=500, - description=_('Reopen own questions') - ) - ) - -settings.register( - IntegerValue( - MIN_REP, - 'MIN_REP_TO_EDIT_WIKI', - default=750, - description=_('Edit community wiki posts') - ) - ) - -settings.register( - IntegerValue( - MIN_REP, - 'MIN_REP_TO_EDIT_OTHERS_POSTS', - default=2000, - description=_('Edit posts authored by other people') - ) - ) - -settings.register( - IntegerValue( - MIN_REP, - 'MIN_REP_TO_VIEW_OFFENSIVE_FLAGS', - default=2000, - description=_('View offensive flags') - ) - ) - -settings.register( - IntegerValue( - MIN_REP, - 'MIN_REP_TO_DISABLE_URL_NOFOLLOW', - default=2000, - description=_('Disable nofollow directive on links') - ) - ) - -settings.register( - IntegerValue( - MIN_REP, - 'MIN_REP_TO_CLOSE_OTHERS_QUESTIONS', - default=2000, - description=_('Close questions asked by others') - ) - ) - -settings.register( - IntegerValue( - MIN_REP, - 'MIN_REP_TO_LOCK_POSTS', - default=4000, - description=_('Lock posts') - ) - ) diff --git a/forum/models/conf/reputation_changes.py b/forum/models/conf/reputation_changes.py deleted file mode 100644 index cef177f5..00000000 --- a/forum/models/conf/reputation_changes.py +++ /dev/null @@ -1,149 +0,0 @@ -""" -Settings for reputation changes that apply to -user in response to various actions by the same -users or others -""" -from forum.conf.settings_wrapper import settings -from livesettings import ConfigurationGroup, IntegerValue -from django.utils.translation import ugettext as _ - -REP_CHANGES = ConfigurationGroup( - 'REP_CHANGES', - _('Reputaion loss and gain rules'), - ordering=2 - ) - -settings.register( - IntegerValue( - REP_CHANGES, - 'MAX_REP_GAIN_PER_USER_PER_DAY', - default=200, - description=_('Maximum daily reputation gain per user') - ) -) - -settings.register( - IntegerValue( - REP_CHANGES, - 'REP_GAIN_FOR_RECEIVING_UPVOTE', - default=10, - description=_('Gain for receiving an upvote') - ) -) - -settings.register( - IntegerValue( - REP_CHANGES, - 'REP_GAIN_FOR_RECEIVING_ANSWER_ACCEPTANCE', - default=15, - description=_('Gain for the author of accepted answer') - ) -) - -settings.register( - IntegerValue( - REP_CHANGES, - 'REP_GAIN_FOR_ACCEPTING_ANSWER', - default=2, - description=_('Gain for accepting best answer') - ) -) - -settings.register( - IntegerValue( - REP_CHANGES, - 'REP_GAIN_FOR_RECEIVING_DOWNVOTE_CANCELATION', - default=2, - description=_('Gain for post owner on canceled downvote') - ) -) - -settings.register( - IntegerValue( - REP_CHANGES, - 'REP_GAIN_FOR_CANCELING_DOWNVOTE', - default=1, - description=_('Gain for voter on canceling downvote') - ) -) -#'gain_by_canceling_downvote', - -settings.register( - IntegerValue( - REP_CHANGES, - 'REP_LOSS_FOR_CANCELING_ANSWER_ACCEPTANCE', - default=-2, - description=_('Loss for voter for canceling of answer acceptance') - ) -) -#'lose_by_canceling_accepted_answer', - -settings.register( - IntegerValue( - REP_CHANGES, - 'REP_LOSS_FOR_RECEIVING_CANCELATION_OF_ANSWER_ACCEPTANCE', - default=-5, - description=_('Loss for author whose answer was "un-accepted"') - ) -) -#'lose_by_accepted_answer_cancled', - -settings.register( - IntegerValue( - REP_CHANGES, - 'REP_LOSS_FOR_DOWNVOTING', - default=-2, - description=_('Loss for giving a downvote') - ) -) -#'lose_by_downvoted', - -settings.register( - IntegerValue( - REP_CHANGES, - 'REP_LOSS_FOR_RECEIVING_FLAG', - default=-2, - description=_('Loss for owner of post that was flagged offensive') - ) -) -#'lose_by_flagged', - -settings.register( - IntegerValue( - REP_CHANGES, - 'REP_LOSS_FOR_RECEIVING_DOWNVOTE', - default=-1, - description=_('Loss for owner of post that was downvoted') - ) -) -#'lose_by_downvoting', - -settings.register( - IntegerValue( - REP_CHANGES, - 'REP_LOSS_FOR_RECEIVING_THREE_FLAGS_PER_REVISION', - default=-30, - description=_('Loss for owner of post that was flagged 3 times per same revision') - ) -) -#'lose_by_flagged_lastrevision_3_times', - -settings.register( - IntegerValue( - REP_CHANGES, - 'REP_LOSS_FOR_RECEIVING_FIVE_FLAGS_PER_REVISION', - default=-100, - description=_('Loss for owner of post that was flagged 5 times per same revision') - ) -) -#'lose_by_flagged_lastrevision_5_times', - -settings.register( - IntegerValue( - REP_CHANGES, - 'REP_LOSS_FOR_RECEIVING_UPVOTE_CANCELATION', - default=-10, - description=_('Loss for post owner when upvote is canceled') - ) -) -#'lose_by_upvote_canceled', diff --git a/forum/models/conf/settings_wrapper.py b/forum/models/conf/settings_wrapper.py deleted file mode 100644 index abf49e5f..00000000 --- a/forum/models/conf/settings_wrapper.py +++ /dev/null @@ -1,59 +0,0 @@ -""" -Definition of a Singleton wrapper class for livesettings -with interface similar to django.conf.settings -that is each setting has unique key and is accessible -via dotted lookup. - -for example to lookup value of setting BLAH you would do - -from forum.conf import settings - -settings.BLAH - -the value will be taken from livesettings database or cache -note that during compilation phase database is not accessible -for the most part, so actual values are reliably available only -at run time - -livesettings is a module developed for satchmo project -""" -from livesettings import SortedDotDict, config_register - -class ConfigSettings(object): - """A very simple Singleton wrapper for settings - a limitation is that all settings names using this class - must be distinct, even though they might belong - to different settings groups - """ - __instance = None - - def __init__(self): - """assigns SortedDotDict to self.__instance if not set""" - if ConfigSettings.__instance == None: - ConfigSettings.__instance = SortedDotDict() - self.__dict__['_ConfigSettings__instance'] = ConfigSettings.__instance - - def __getattr__(self, key): - """value lookup returns the actual value of setting - not the object - this way only very minimal modifications - will be required in code to convert an app - depending on django.conf.settings to livesettings - """ - return getattr(self.__instance, key).value - - def __setattr__(self, attr, value): - """ settings crutch is read-only in the program """ - raise Exception('ConfigSettings cannot be changed programmatically') - - def register(self, value): - """registers the setting - value must be a subclass of livesettings.Value - """ - key = value.key - if key in self.__instance: - raise Exception('setting %s is already registered' % key) - else: - self.__instance[key] = config_register(value) - -#settings instance to be used elsewhere in the project -settings = ConfigSettings() diff --git a/forum/models/conf/site_settings.py b/forum/models/conf/site_settings.py deleted file mode 100644 index e3eb2023..00000000 --- a/forum/models/conf/site_settings.py +++ /dev/null @@ -1,81 +0,0 @@ -""" -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/models/conf/vote_rules.py b/forum/models/conf/vote_rules.py deleted file mode 100644 index f249ef53..00000000 --- a/forum/models/conf/vote_rules.py +++ /dev/null @@ -1,69 +0,0 @@ -""" -Forum configuration settings detailing rules on votes -and offensive flags. - -For example number of times a person can vote each day, etc. -""" -from forum.conf.settings_wrapper import settings -from livesettings import ConfigurationGroup, IntegerValue -from django.utils.translation import ugettext as _ - -VOTE_RULES = ConfigurationGroup( - 'VOTE_RULES', - _('Limits applicable to votes and moderation flags'), - ordering=1, - ) - -settings.register( - IntegerValue( - VOTE_RULES, - 'MAX_VOTES_PER_USER_PER_DAY', - default=30, - description=_('Number of votes a user can cast per day') - ) -) - -settings.register( - IntegerValue( - VOTE_RULES, - 'MAX_FLAGS_PER_USER_PER_DAY', - default=5, - description=_('Maximum number of flags per user per day') - ) -) - -settings.register( - IntegerValue( - VOTE_RULES, - 'VOTES_LEFT_WARNING_THRESHOLD', - default=5, - description=_('Threshold for warning about remaining daily votes') - ) -) - -settings.register( - IntegerValue( - VOTE_RULES, - 'MAX_DAYS_TO_CANCEL_VOTE', - default=1, - description=_('Number of days to allow canceling votes') - ) -) - -settings.register( - IntegerValue( - VOTE_RULES, - 'MIN_FLAGS_TO_HIDE_POST', - default=3, - description=_('Number of flags required to automatically hide posts') - ) -) - -settings.register( - IntegerValue( - VOTE_RULES, - 'MIN_FLAGS_TO_DELETE_POST', - default=5, - description=_('Number of flags required to automatically delete posts') - ) -) diff --git a/forum/skins/default/templates/fbconnect/xd_receiver.html b/forum/skins/default/templates/fbconnect/xd_receiver.html index a03c61bc..60c02a22 100755 --- a/forum/skins/default/templates/fbconnect/xd_receiver.html +++ b/forum/skins/default/templates/fbconnect/xd_receiver.html @@ -2,7 +2,7 @@ {% load i18n %} - {% blocktrans %}Connect to {{APP_SHORT_NAME}} with Facebook!{% endblocktrans %} + <title>{% blocktrans %}Connect to {{settings.APP_SHORT_NAME}} with Facebook!{% endblocktrans %} </head> <body> <script src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/XdCommReceiver.js" type="text/javascript"></script> diff --git a/livesettings/templatetags/config_tags.py b/livesettings/templatetags/config_tags.py index 1fed730d..bcdded12 100644 --- a/livesettings/templatetags/config_tags.py +++ b/livesettings/templatetags/config_tags.py @@ -31,6 +31,8 @@ def force_space(value, chars=40): def break_at(value, chars=40): """Force spaces into long lines which don't have spaces""" + #todo: EF - lazy patch + return value chars = int(chars) value = unicode(value) -- cgit v1.2.3-1-g7c22