diff --git a/TODO.md b/TODO.md
index b470c465..f72179e1 100644
--- a/TODO.md
+++ b/TODO.md
@@ -294,15 +294,3 @@ https://code.djangoproject.com/ticket/24576
# TODO orchestra related services code reload: celery/uwsgi reloading find aonther way without root and implement reload
# insert settings on dashboard dynamically
-# rename "edit settings" -> change settings
-
-# View settings file
-contrib/orders/models.py: if type(instance) in services:
-contrib/orders/models.py: if type(instance) in services:
-contrib/orders/helpers.py: if type(node) in services:
-contrib/bills/admin.py: return [inline for inline in inlines if type(inline) is not BillLineInline]
-contrib/bills/admin.py: return [inline for inline in inlines if type(inline) is not ClosedBillLineInline]
-contrib/accounts/actions.py.save: if type(service) in registered_services:
-contrib/accounts/actions.py: if type(service) in registered_services:
-permissions/options.py: for func in inspect.getmembers(type(self), predicate=inspect.ismethod):
-
diff --git a/orchestra/admin/menu.py b/orchestra/admin/menu.py
index bb1e1c75..93b11000 100644
--- a/orchestra/admin/menu.py
+++ b/orchestra/admin/menu.py
@@ -60,7 +60,7 @@ def get_accounts():
def get_administration_items():
childrens = []
if isinstalled('orchestra.contrib.settings'):
- url = reverse('admin:settings_edit_settings')
+ url = reverse('admin:settings_setting_change')
childrens.append(items.MenuItem(_("Settings"), url))
if isinstalled('orchestra.contrib.services'):
url = reverse('admin:services_service_changelist')
diff --git a/orchestra/contrib/bills/admin.py b/orchestra/contrib/bills/admin.py
index 648940a1..478d7db8 100644
--- a/orchestra/contrib/bills/admin.py
+++ b/orchestra/contrib/bills/admin.py
@@ -259,8 +259,8 @@ class BillAdmin(AccountAdminMixin, ExtendedModelAdmin):
def get_inline_instances(self, request, obj=None):
inlines = super(BillAdmin, self).get_inline_instances(request, obj)
if obj and not obj.is_open:
- return [inline for inline in inlines if type(inline) is not BillLineInline]
- return [inline for inline in inlines if type(inline) is not ClosedBillLineInline]
+ return [inline for inline in inlines if not isinstance(inline, BillLineInline)]
+ return [inline for inline in inlines if not isinstance(inline, ClosedBillLineInline)]
def formfield_for_dbfield(self, db_field, **kwargs):
""" Make value input widget bigger """
diff --git a/orchestra/contrib/domains/settings.py b/orchestra/contrib/domains/settings.py
index 4d112655..2c20a7b9 100644
--- a/orchestra/contrib/domains/settings.py
+++ b/orchestra/contrib/domains/settings.py
@@ -87,10 +87,10 @@ DOMAINS_DEFAULT_NS = Setting('DOMAINS_DEFAULT_NS', (
DOMAINS_FORBIDDEN = Setting('DOMAINS_FORBIDDEN', '',
help_text=(
- "This setting prevents users from providing random domain names, i.e. google.com"
- "You can generate a 5K forbidden domains list from Alexa's top 1M"
- "wget http://s3.amazonaws.com/alexa-static/top-1m.csv.zip -O /tmp/top-1m.csv.zip"
- "unzip -p /tmp/top-1m.csv.zip | head -n 5000 | sed 's/^.*,//' > forbidden_domains.list"
+ "This setting prevents users from providing random domain names, i.e. google.com
"
+ "You can generate a 5K forbidden domains list from Alexa's top 1M:
"
+ " wget http://s3.amazonaws.com/alexa-static/top-1m.csv.zip -O /tmp/top-1m.csv.zip && "
+ "unzip -p /tmp/top-1m.csv.zip | head -n 5000 | sed 's/^.*,//' > forbidden_domains.list
"
"'%(site_dir)s/forbidden_domains.list')"
)
)
diff --git a/orchestra/contrib/saas/settings.py b/orchestra/contrib/saas/settings.py
index 79221eee..6bc2ba0f 100644
--- a/orchestra/contrib/saas/settings.py
+++ b/orchestra/contrib/saas/settings.py
@@ -14,7 +14,7 @@ SAAS_ENABLED_SERVICES = Setting('SAAS_ENABLED_SERVICES', (
'orchestra.contrib.saas.services.seafile.SeaFileService',
),
# lazy loading
- choices=lambda : ((s.get_class_path(), s.get_class_path()) for s in saas.services.SoftwareService.get_plugins()),
+ choices=lambda: ((s.get_class_path(), s.get_class_path()) for s in saas.services.SoftwareService.get_plugins()),
multiple=True,
)
@@ -25,7 +25,7 @@ SAAS_WORDPRESS_ADMIN_PASSWORD = Setting('SAAS_WORDPRESSMU_ADMIN_PASSWORD',
SAAS_WORDPRESS_BASE_URL = Setting('SAAS_WORDPRESS_BASE_URL',
- 'http://blogs.{}/'.format(ORCHESTRA_BASE_DOMAIN)
+ 'https://blogs.{}/'.format(ORCHESTRA_BASE_DOMAIN)
)
diff --git a/orchestra/contrib/settings/admin.py b/orchestra/contrib/settings/admin.py
index 52785c0d..9fd3edbf 100644
--- a/orchestra/contrib/settings/admin.py
+++ b/orchestra/contrib/settings/admin.py
@@ -3,7 +3,7 @@ from functools import partial
from django.contrib import admin, messages
from django.db import models
-from django.views.generic.edit import FormView
+from django.views import generic
from django.utils.translation import ngettext, ugettext_lazy as _
from orchestra.settings import Setting
@@ -13,7 +13,7 @@ from . import parser
from .forms import SettingFormSet
-class SettingView(FormView):
+class SettingView(generic.edit.FormView):
template_name = 'admin/settings/change_form.html'
form_class = SettingFormSet
success_url = '.'
@@ -38,10 +38,8 @@ class SettingView(FormView):
'default': setting.default,
'type': type(setting.default),
'value': setting.value,
- 'choices': setting.choices,
+ 'setting': setting,
'app': app,
- 'editable': setting.editable,
- 'multiple': setting.multiple,
}
if app == 'ORCHESTRA':
initial_data.insert(account, initial)
@@ -79,11 +77,28 @@ class SettingView(FormView):
_("%s changes successfully applied, the orchestra is going to be restarted...") % n,
n)
)
- # TODO find aonther way without root and implement reload
-# sys.run('echo { sleep 2 && python3 %s/manage.py reload; } &' % paths.get_site_dir(), async=True)
+ sys.run('{ sleep 2 && touch %s/wsgi.py; } &' % paths.get_project_dir(), async=True)
else:
messages.success(self.request, _("No changes have been detected."))
return super(SettingView, self).form_valid(form)
-admin.site.register_url(r'^settings/setting/$', SettingView.as_view(), 'settings_edit_settings')
+class SettingFileView(generic.TemplateView):
+ template_name = 'admin/settings/view.html'
+
+ def get_context_data(self, **kwargs):
+ context = super(SettingFileView, self).get_context_data(**kwargs)
+ settings_file = parser.get_settings_file()
+ with open(settings_file, 'r') as handler:
+ content = handler.read()
+ context.update({
+ 'title': _("Settings file content"),
+ 'settings_file': settings_file,
+ 'content': content,
+ })
+ return context
+
+
+admin.site.register_url(r'^settings/setting/view/$', SettingFileView.as_view(), 'settings_setting_view')
+admin.site.register_url(r'^settings/setting/$', SettingView.as_view(), 'settings_setting_change')
+
diff --git a/orchestra/contrib/settings/forms.py b/orchestra/contrib/settings/forms.py
index c5110f1d..515087db 100644
--- a/orchestra/contrib/settings/forms.py
+++ b/orchestra/contrib/settings/forms.py
@@ -48,14 +48,16 @@ class SettingForm(ReadOnlyFormMixin, forms.Form):
initial = kwargs.get('initial')
if initial:
self.setting_type = initial['type']
+ self.setting = initial['setting']
+ setting = self.setting
serialized_value = parser.serialize(initial['value'])
serialized_default = parser.serialize(initial['default'])
- if not initial['editable'] or isinstance(serialized_value, parser.NotSupported):
+ if not setting.editable or isinstance(serialized_value, parser.NotSupported):
field = self.NON_EDITABLE
else:
- choices = initial.get('choices')
+ choices = setting.choices
field = forms.ChoiceField
- multiple = initial['multiple']
+ multiple = setting.multiple
if multiple:
field = partial(forms.MultipleChoiceField, widget=forms.CheckboxSelectMultiple)
if choices:
@@ -68,26 +70,25 @@ class SettingForm(ReadOnlyFormMixin, forms.Form):
else:
field = self.FORMFIELD_FOR_SETTING_TYPE.get(self.setting_type, self.NON_EDITABLE)
field = deepcopy(field)
- value = initial['value']
- default = initial['default']
real_field = field
while isinstance(real_field, partial):
real_field = real_field.func
# Do not serialize following form types
+ value = initial['value']
+ default = initial['default']
+ self.changed = bool(value != default)
if real_field not in (forms.MultipleChoiceField, forms.BooleanField):
value = serialized_value
- if real_field is not forms.BooleanField:
default = serialized_default
initial['value'] = value
initial['default'] = default
super(SettingForm, self).__init__(*args, **kwargs)
if initial:
- self.changed = bool(value != default)
self.fields['value'] = field(label=_("value"))
if isinstance(self.fields['value'].widget, forms.Textarea):
rows = math.ceil(len(value)/65)
self.fields['value'].widget.attrs['rows'] = rows
- self.fields['name'].help_text = initial['help_text']
+ self.fields['name'].help_text = mark_safe(setting.help_text)
self.fields['name'].widget.attrs['readonly'] = True
self.app = initial['app']
@@ -101,11 +102,10 @@ class SettingForm(ReadOnlyFormMixin, forms.Form):
value = eval(value, parser.get_eval_context())
except Exception as exc:
raise ValidationError(str(exc))
+ self.setting.validate_value(value)
if not isinstance(value, self.setting_type):
if self.setting_type in (tuple, list) and isinstance(value, (tuple, list)):
value = self.setting_type(value)
- else:
- raise ValidationError("Please provide a %s." % self.setting_type.__name__)
return value
diff --git a/orchestra/contrib/settings/templates/admin/settings/change_form.html b/orchestra/contrib/settings/templates/admin/settings/change_form.html
index ed935ad6..930ee8cc 100644
--- a/orchestra/contrib/settings/templates/admin/settings/change_form.html
+++ b/orchestra/contrib/settings/templates/admin/settings/change_form.html
@@ -17,8 +17,15 @@
{% endblock %}
-
{% block content %}
+
Current {{ settings_file }} content.
+ {% endblocktrans %} +{{ content }}+