From db72b4bb903793a6b04ab26a70c7961258d345f8 Mon Sep 17 00:00:00 2001 From: hernani Date: Mon, 17 May 2010 12:30:57 +0000 Subject: [PATCH] Closing OSQA 201, Add a "site maintenance" switch and page. We can define some ips that are allowed to access the site normally, and also a message to display in the maintenance page. These settings can be adjusted (add/remove more ips, change the message) while in maintenance mode. git-svn-id: http://svn.osqa.net/svnroot/osqa/trunk@289 0cfe37f9-358a-4d5e-be75-b63607b5c754 --- forum/forms.py | 4 -- forum/middleware/request_utils.py | 14 +++++++ forum/settings/__init__.py | 2 + forum/settings/base.py | 9 ++++- forum/settings/forms.py | 32 ++++++++++++++++ forum/settings/repgain.py | 19 ---------- .../default/media/style/djstyle_admin.css | 6 +++ forum/skins/default/templates/410.html | 22 +++++++++++ .../templates/osqaadmin/djstyle_base.html | 9 +++-- .../templates/osqaadmin/maintenance.html | 25 +++++++++++++ forum/urls.py | 6 ++- forum/views/admin.py | 37 ++++++++++++++++--- 12 files changed, 150 insertions(+), 35 deletions(-) create mode 100644 forum/skins/default/templates/410.html create mode 100644 forum/skins/default/templates/osqaadmin/maintenance.html diff --git a/forum/forms.py b/forum/forms.py index b54d65b..509c125 100644 --- a/forum/forms.py +++ b/forum/forms.py @@ -251,7 +251,3 @@ class SubscriptionSettingsForm(forms.Form): notify_comments = forms.BooleanField(required=False, initial=False) notify_accepted = forms.BooleanField(required=False, initial=False) - -class AwardPointsForm(forms.Form): - points = forms.IntegerField(min_value=1, initial=50, label=_('Points to award')) - message = forms.CharField(widget=forms.Textarea(), label=_('Message'), required=False) diff --git a/forum/middleware/request_utils.py b/forum/middleware/request_utils.py index a96f372..6669565 100644 --- a/forum/middleware/request_utils.py +++ b/forum/middleware/request_utils.py @@ -1,3 +1,7 @@ +from forum.settings import MAINTAINANCE_MODE, APP_LOGO, APP_TITLE +from django.http import HttpResponseGone +from django.template.loader import render_to_string + class RequestUtils(object): def __init__(self): @@ -23,6 +27,16 @@ class RequestUtils(object): return int(pagesize) def process_request(self, request): + if MAINTAINANCE_MODE.value is not None and isinstance(MAINTAINANCE_MODE.value.get('allow_ips', None), list): + ip = request.META['REMOTE_ADDR'] + + if not ip in MAINTAINANCE_MODE.value['allow_ips']: + return HttpResponseGone(render_to_string('410.html', { + 'message': MAINTAINANCE_MODE.value.get('message', ''), + 'app_logo': APP_LOGO, + 'app_title': APP_TITLE + })) + self.request = request request.utils = self return None \ No newline at end of file diff --git a/forum/settings/__init__.py b/forum/settings/__init__.py index caf0eaf..95f2441 100644 --- a/forum/settings/__init__.py +++ b/forum/settings/__init__.py @@ -10,6 +10,8 @@ from django.utils.version import get_svn_revision OSQA_VERSION = "Development Build" SVN_REVISION = get_svn_revision(djsettings.SITE_SRC_ROOT) +MAINTAINANCE_MODE = Setting('MAINTAINANCE_MODE', None) + SETTINGS_PACK = Setting('SETTINGS_PACK', "default") DJSTYLE_ADMIN_INTERFACE = Setting('DJSTYLE_ADMIN_INTERFACE', True) diff --git a/forum/settings/base.py b/forum/settings/base.py index e160970..398ed11 100644 --- a/forum/settings/base.py +++ b/forum/settings/base.py @@ -71,7 +71,11 @@ class BaseSetting(object): return self.base_type(value) except: pass - return value + return value + +class AnyTypeSetting(BaseSetting): + def _parse(self, value): + return value class Setting(object): @@ -79,6 +83,9 @@ class Setting(object): sets = {} def __new__(cls, name, default, set=None, field_context=None): + if default is None: + return AnyTypeSetting(name, default, set, field_context) + deftype = type(default) if deftype in Setting.emulators: diff --git a/forum/settings/forms.py b/forum/settings/forms.py index a187683..27581d5 100644 --- a/forum/settings/forms.py +++ b/forum/settings/forms.py @@ -1,4 +1,5 @@ import os +import socket from string import strip from django import forms from base import Setting @@ -109,5 +110,36 @@ class CommaStringListWidget(forms.Textarea): return ', '.join(data[name]) +class IPListField(forms.CharField): + def clean(self, value): + ips = [ip.strip() for ip in value.strip().strip(',').split(',')] + iplist = [] + + if len(ips) < 1: + raise forms.ValidationError(_('Please input at least one ip address')) + + for ip in ips: + try: + socket.inet_aton(ip) + except socket.error: + raise forms.ValidationError(_('Invalid ip address: %s' % ip)) + + if not len(ip.split('.')) == 4: + raise forms.ValidationError(_('Please use the dotted quad notation for the ip addresses')) + + iplist.append(ip) + + return iplist + +class MaintenanceModeForm(forms.Form): + ips = IPListField(label=_('Allow ips'), + help_text=_('Comma separated list of ips allowed to access the site while in maintenance'), + required=True, + widget=forms.TextInput(attrs={'class': 'longstring'})) + + message = forms.CharField(label=_('Message'), + help_text=_('A message to display to your site visitors while in maintainance mode'), + widget=forms.Textarea) + diff --git a/forum/settings/repgain.py b/forum/settings/repgain.py index f78120d..cfb566b 100644 --- a/forum/settings/repgain.py +++ b/forum/settings/repgain.py @@ -15,10 +15,6 @@ REP_GAIN_BY_UPVOTED = Setting('REP_GAIN_BY_UPVOTED', 10, REP_GAIN_SET, dict( label = _("Rep gain by upvoted"), help_text = _("Reputation a user gains for having one of his posts up voted."))) -REP_LOST_BY_UPVOTE_CANCELED = Setting('REP_LOST_BY_UPVOTE_CANCELED', 10, REP_GAIN_SET, dict( -label = _("Rep lost bu upvote canceled"), -help_text = _("Reputation a user loses for having one of the upvotes on his posts canceled."))) - REP_LOST_BY_DOWNVOTED = Setting('REP_LOST_BY_DOWNVOTED', 2, REP_GAIN_SET, dict( label = _("Rep lost by downvoted"), help_text = _("Reputation a user loses for having one of his posts down voted."))) @@ -27,30 +23,15 @@ REP_LOST_BY_DOWNVOTING = Setting('REP_LOST_BY_DOWNVOTING', 1, REP_GAIN_SET, dict label = _("Rep lost by downvoting"), help_text = _("Reputation a user loses for down voting a post."))) -REP_GAIN_BY_DOWNVOTE_CANCELED = Setting('REP_GAIN_BY_DOWNVOTE_CANCELED', 2, REP_GAIN_SET, dict( -label = _("Rep gain by downvote canceled"), -help_text = _("Reputation a user gains for having one of the downvotes on his posts canceled."))) - -REP_GAIN_BY_CANCELING_DOWNVOTE = Setting('REP_GAIN_BY_CANCELING_DOWNVOTE', 1, REP_GAIN_SET, dict( -label = _("Rep gain by canceling downvote"), -help_text = _("Reputation a user gains for canceling a downvote."))) REP_GAIN_BY_ACCEPTED = Setting('REP_GAIN_BY_ACCEPTED', 15, REP_GAIN_SET, dict( label = _("Rep gain by accepted answer"), help_text = _("Reputation a user gains for having one of his answers accepted."))) -REP_LOST_BY_ACCEPTED_CANCELED = Setting('REP_LOST_BY_ACCEPTED_CANCELED', 15, REP_GAIN_SET, dict( -label = _("Rep lost by accepted canceled"), -help_text = _("Reputation a user loses for having one of his accepted answers canceled."))) - REP_GAIN_BY_ACCEPTING = Setting('REP_GAIN_BY_ACCEPTING', 2, REP_GAIN_SET, dict( label = _("Rep gain by accepting answer"), help_text = _("Reputation a user gains for accepting an answer to one of his questions."))) -REP_LOST_BY_CANCELING_ACCEPTED = Setting('REP_LOST_BY_CANCELING_ACCEPTED', 2, REP_GAIN_SET, dict( -label = _("Rep lost by canceling accepted"), -help_text = _("Reputation a user loses by canceling an accepted answer."))) - REP_LOST_BY_FLAGGED = Setting('REP_LOST_BY_FLAGGED', 2, REP_GAIN_SET, dict( label = _("Rep lost by post flagged"), help_text = _("Reputation a user loses by having one of his posts flagged."))) diff --git a/forum/skins/default/media/style/djstyle_admin.css b/forum/skins/default/media/style/djstyle_admin.css index 87fe341..e8e8573 100644 --- a/forum/skins/default/media/style/djstyle_admin.css +++ b/forum/skins/default/media/style/djstyle_admin.css @@ -47,3 +47,9 @@ input.longstring { position: relative; left: 612px; } + +.admin_message { + background-color: #ffffe0; + border: 3px double #b8860b; + padding: 4px; +} \ No newline at end of file diff --git a/forum/skins/default/templates/410.html b/forum/skins/default/templates/410.html new file mode 100644 index 0000000..8f1664c --- /dev/null +++ b/forum/skins/default/templates/410.html @@ -0,0 +1,22 @@ +{% load i18n %} + + + + + {% trans "System down for maintenance" %} + + + +
+ +

{{ app_title }}

+

{% trans "System down for maintenance" %}

+
+ {{ message }} +
+ + diff --git a/forum/skins/default/templates/osqaadmin/djstyle_base.html b/forum/skins/default/templates/osqaadmin/djstyle_base.html index c91218f..f9e941f 100644 --- a/forum/skins/default/templates/osqaadmin/djstyle_base.html +++ b/forum/skins/default/templates/osqaadmin/djstyle_base.html @@ -45,6 +45,9 @@
+ {% for message in user_messages %} +

{{ message }}

+ {% endfor %} {% block admincontent %}{% endblock %}
- {% comment %}
+ {% endcomment %} +