Random fixes
This commit is contained in:
parent
a1f8d32ac7
commit
553be610cb
2
TODO.md
2
TODO.md
|
@ -414,3 +414,5 @@ mkhomedir_helper or create ssh homes with bash.rc and such
|
|||
# warnings if some plugins are disabled, like make routes red
|
||||
|
||||
# replace show emails by https://docs.python.org/3/library/email.contentmanager.html#module-email.contentmanager
|
||||
|
||||
# SElect contact list breadcrumbs
|
||||
|
|
|
@ -5,6 +5,7 @@ from django.utils.translation import ugettext_lazy as _
|
|||
|
||||
from orchestra.admin import ExtendedModelAdmin
|
||||
from orchestra.admin.utils import admin_link, admin_date, admin_colored, display_mono, display_code
|
||||
from orchestra.plugins.admin import display_plugin_field
|
||||
|
||||
from . import settings, helpers
|
||||
from .backends import ServiceBackend
|
||||
|
@ -27,7 +28,8 @@ STATE_COLORS = {
|
|||
|
||||
class RouteAdmin(ExtendedModelAdmin):
|
||||
list_display = (
|
||||
'backend', 'host', 'match', 'display_model', 'display_actions', 'async', 'is_active'
|
||||
'display_backend', 'host', 'match', 'display_model', 'display_actions', 'async',
|
||||
'is_active'
|
||||
)
|
||||
list_editable = ('host', 'match', 'async', 'is_active')
|
||||
list_filter = ('host', 'is_active', 'async', 'backend')
|
||||
|
@ -41,6 +43,8 @@ class RouteAdmin(ExtendedModelAdmin):
|
|||
backend.get_name(): backend.default_route_match for backend in ServiceBackend.get_backends()
|
||||
}
|
||||
|
||||
display_backend = display_plugin_field('backend')
|
||||
|
||||
def display_model(self, route):
|
||||
try:
|
||||
return escape(route.backend_class.model)
|
||||
|
@ -60,7 +64,8 @@ class RouteAdmin(ExtendedModelAdmin):
|
|||
def formfield_for_dbfield(self, db_field, **kwargs):
|
||||
""" Provides dynamic help text on backend form field """
|
||||
if db_field.name == 'backend':
|
||||
kwargs['widget'] = RouteBackendSelect('this.id', self.BACKEND_HELP_TEXT, self.DEFAULT_MATCH)
|
||||
kwargs['widget'] = RouteBackendSelect(
|
||||
'this.id', self.BACKEND_HELP_TEXT, self.DEFAULT_MATCH)
|
||||
field = super(RouteAdmin, self).formfield_for_dbfield(db_field, **kwargs)
|
||||
if db_field.name == 'host':
|
||||
# Cache host choices
|
||||
|
@ -70,7 +75,6 @@ class RouteAdmin(ExtendedModelAdmin):
|
|||
request._host_choices_cache = choices = list(field.choices)
|
||||
field.choices = choices
|
||||
return field
|
||||
|
||||
|
||||
def get_form(self, request, obj=None, **kwargs):
|
||||
""" Include dynamic help text for existing objects """
|
||||
|
|
|
@ -1,14 +1,20 @@
|
|||
from django import forms
|
||||
from orchestra.forms.widgets import SpanWidget
|
||||
from orchestra.forms.widgets import paddingCheckboxSelectMultiple
|
||||
|
||||
from orchestra.forms.widgets import SpanWidget, paddingCheckboxSelectMultiple
|
||||
|
||||
|
||||
class RouteForm(forms.ModelForm):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(RouteForm, self).__init__(*args, **kwargs)
|
||||
if self.instance:
|
||||
self.fields['backend'].widget = SpanWidget()
|
||||
self.fields['backend'].required = False
|
||||
self.fields['async_actions'].widget = paddingCheckboxSelectMultiple(45)
|
||||
actions = self.instance.backend_class.actions
|
||||
self.fields['async_actions'].choices = ((action, action) for action in actions)
|
||||
try:
|
||||
backend_class = self.instance.backend_class
|
||||
except KeyError:
|
||||
self.fields['backend'].widget = SpanWidget(
|
||||
display='<span style="color:red">%s NOT AVAILABLE</span>' % self.instance.backend)
|
||||
else:
|
||||
self.fields['backend'].widget = SpanWidget()
|
||||
actions = backend_class.actions
|
||||
self.fields['async_actions'].widget = paddingCheckboxSelectMultiple(45)
|
||||
self.fields['async_actions'].choices = ((action, action) for action in actions)
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import logging
|
||||
import socket
|
||||
|
||||
from django.contrib.contenttypes.fields import GenericForeignKey
|
||||
|
@ -10,12 +11,14 @@ from django.utils.translation import ugettext_lazy as _
|
|||
|
||||
from orchestra.core.validators import validate_ip_address, ValidationError
|
||||
from orchestra.models.fields import NullableCharField, MultiSelectField
|
||||
#from orchestra.utils.apps import autodiscover
|
||||
|
||||
from . import settings
|
||||
from .backends import ServiceBackend
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Server(models.Model):
|
||||
""" Machine runing daemons (services) """
|
||||
name = models.CharField(_("name"), max_length=256, unique=True)
|
||||
|
@ -147,12 +150,17 @@ class RouteQuerySet(models.QuerySet):
|
|||
cache = kwargs.get('cache', {})
|
||||
if not cache:
|
||||
for route in self.filter(is_active=True).select_related('host'):
|
||||
for action in route.backend_class.get_actions():
|
||||
key = (route.backend, action)
|
||||
try:
|
||||
cache[key].append(route)
|
||||
except KeyError:
|
||||
cache[key] = [route]
|
||||
try:
|
||||
backend_class = route.backend_class
|
||||
except KeyError:
|
||||
logger.warning("Backed '%s' not installed." % route.backend)
|
||||
else:
|
||||
for action in backend_class.get_actions():
|
||||
key = (route.backend, action)
|
||||
try:
|
||||
cache[key].append(route)
|
||||
except KeyError:
|
||||
cache[key] = [route]
|
||||
routes = []
|
||||
backend_cls = operation.backend
|
||||
key = (backend_cls.get_name(), operation.action)
|
||||
|
@ -202,7 +210,13 @@ class Route(models.Model):
|
|||
if not self.match:
|
||||
self.match = 'True'
|
||||
if self.backend:
|
||||
backend_model = self.backend_class.model_class()
|
||||
try:
|
||||
backend_class = self.backend_class
|
||||
except KeyError:
|
||||
raise ValidationError({
|
||||
'backend': _("Backend '%s' is not installed.") % self.backend
|
||||
})
|
||||
backend_model = backend_class.model_class()
|
||||
try:
|
||||
obj = backend_model.objects.all()[0]
|
||||
except IndexError:
|
||||
|
|
|
@ -14,12 +14,12 @@ class MoodleMuBackend(ServiceController):
|
|||
Creates a Moodle site on a Moodle multisite installation
|
||||
|
||||
// config.php
|
||||
// map custom domains to sites
|
||||
$site_map = array(
|
||||
// "<HTTP_HOST>" => ["<SITE_NAME>", "<WWWROOT>"],
|
||||
);
|
||||
|
||||
$site = getenv("SITE");
|
||||
$wwwroot = "https://{$site}-courses.pangea.org";
|
||||
if ( $site == '' ) {
|
||||
$http_host = $_SERVER['HTTP_HOST'];
|
||||
if (array_key_exists($http_host, $site_map)) {
|
||||
|
@ -32,7 +32,16 @@ class MoodleMuBackend(ServiceController):
|
|||
$site = array_shift((explode(".", $http_host)));
|
||||
$wwwroot = "https://{$site}-courses.pangea.org";
|
||||
}
|
||||
} else {
|
||||
$wwwroot = "https://{$site}-courses.pangea.org";
|
||||
foreach ($site_map as $key => $value) {
|
||||
if ($value[0] == $site) {
|
||||
$wwwroot = $value[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$prefix = str_replace('-', '_', $site);
|
||||
$CFG->prefix = "${prefix}_";
|
||||
$CFG->wwwroot = $wwwroot;
|
||||
|
|
|
@ -9,7 +9,7 @@ from orchestra.admin.utils import change_url, get_modeladmin
|
|||
from orchestra.contrib.accounts.actions import list_accounts
|
||||
from orchestra.contrib.accounts.admin import AccountAdminMixin
|
||||
from orchestra.forms.widgets import DynamicHelpTextSelect
|
||||
from orchestra.plugins.admin import SelectPluginAdminMixin
|
||||
from orchestra.plugins.admin import SelectPluginAdminMixin, display_plugin_field
|
||||
from orchestra.utils.html import get_on_site_link
|
||||
|
||||
from .filters import HasWebsiteListFilter, PHPVersionListFilter
|
||||
|
@ -50,7 +50,7 @@ class WebAppOptionInline(admin.TabularInline):
|
|||
|
||||
|
||||
class WebAppAdmin(SelectPluginAdminMixin, AccountAdminMixin, ExtendedModelAdmin):
|
||||
list_display = ('name', 'type', 'display_detail', 'display_websites', 'account_link')
|
||||
list_display = ('name', 'display_type', 'display_detail', 'display_websites', 'account_link')
|
||||
list_filter = ('type', HasWebsiteListFilter, PHPVersionListFilter)
|
||||
inlines = [WebAppOptionInline]
|
||||
readonly_fields = ('account_link', )
|
||||
|
@ -62,6 +62,8 @@ class WebAppAdmin(SelectPluginAdminMixin, AccountAdminMixin, ExtendedModelAdmin)
|
|||
plugin_title = _("Web application type")
|
||||
actions = (list_accounts,)
|
||||
|
||||
display_type = display_plugin_field('type')
|
||||
|
||||
def display_websites(self, webapp):
|
||||
websites = []
|
||||
for content in webapp.content_set.all():
|
||||
|
@ -81,8 +83,12 @@ class WebAppAdmin(SelectPluginAdminMixin, AccountAdminMixin, ExtendedModelAdmin)
|
|||
display_websites.allow_tags = True
|
||||
|
||||
def display_detail(self, webapp):
|
||||
return webapp.type_instance.get_detail()
|
||||
try:
|
||||
return webapp.type_instance.get_detail()
|
||||
except KeyError:
|
||||
return "<span style='color:red;'>Not available</span>"
|
||||
display_detail.short_description = _("detail")
|
||||
display_detail.allow_tags = True
|
||||
|
||||
# def get_form(self, request, obj=None, **kwargs):
|
||||
# form = super(WebAppAdmin, self).get_form(request, obj, **kwargs)
|
||||
|
|
|
@ -15,8 +15,13 @@ class SelectPluginAdminMixin(object):
|
|||
|
||||
def get_form(self, request, obj=None, **kwargs):
|
||||
if obj:
|
||||
plugin = getattr(obj, '%s_instance' % self.plugin_field)
|
||||
self.form = getattr(plugin, 'get_change_form', plugin.get_form)()
|
||||
try:
|
||||
plugin = getattr(obj, '%s_instance' % self.plugin_field)
|
||||
except KeyError:
|
||||
plugin_name = getattr(obj, self.plugin_field)
|
||||
raise KeyError(_("Plugin '%s' is not available.") % plugin_name)
|
||||
else:
|
||||
self.form = getattr(plugin, 'get_change_form', plugin.get_form)()
|
||||
else:
|
||||
plugin = self.plugin.get(self.plugin_value)()
|
||||
self.form = plugin.get_form()
|
||||
|
@ -90,9 +95,12 @@ class SelectPluginAdminMixin(object):
|
|||
|
||||
def change_view(self, request, object_id, form_url='', extra_context=None):
|
||||
obj = self.get_object(request, unquote(object_id))
|
||||
plugin = getattr(obj, '%s_class' % self.plugin_field)
|
||||
try:
|
||||
verbose = getattr(obj, '%s_class' % self.plugin_field).verbose_name
|
||||
except KeyError:
|
||||
raise KeyError(_("Plugin '%s' is not available.") % getattr(obj, self.plugin_field))
|
||||
context = {
|
||||
'title': _("Change %s") % plugin.verbose_name,
|
||||
'title': _("Change %s") % verbose,
|
||||
}
|
||||
context.update(extra_context or {})
|
||||
return super(SelectPluginAdminMixin, self).change_view(
|
||||
|
@ -102,3 +110,17 @@ class SelectPluginAdminMixin(object):
|
|||
if not change:
|
||||
setattr(obj, self.plugin_field, self.plugin_value)
|
||||
obj.save()
|
||||
|
||||
|
||||
def display_plugin_field(field_name):
|
||||
def inner(modeladmin, obj, field_name=field_name):
|
||||
try:
|
||||
plugin_class = getattr(obj, '%s_class' % field_name)
|
||||
except KeyError:
|
||||
value = getattr(obj, field_name)
|
||||
return "<span style='color:red;' title='Not available'>%s</span>" % value
|
||||
return getattr(obj, 'get_%s_display' % field_name)()
|
||||
inner.short_description = field_name
|
||||
inner.admin_order_field = field_name
|
||||
inner.allow_tags = True
|
||||
return inner
|
||||
|
|
|
@ -1,22 +1,3 @@
|
|||
#from django.utils.importlib import import_module
|
||||
#from django.utils.module_loading import module_has_submodule
|
||||
|
||||
|
||||
#def autodiscover(module):
|
||||
# """ Auto-discover INSTALLED_APPS module.py """
|
||||
# from django.conf import settings
|
||||
# for app in settings.INSTALLED_APPS:
|
||||
# mod = import_module(app)
|
||||
# try:
|
||||
# import_module('%s.%s' % (app, module))
|
||||
# except ImportError:
|
||||
# # Decide whether to bubble up this error. If the app just
|
||||
# # doesn't have the module, we can ignore the error
|
||||
# # attempting to import it, otherwise we want it to bubble up.
|
||||
# if module_has_submodule(mod, module):
|
||||
# print '%s module caused this error:' % module
|
||||
# raise
|
||||
|
||||
def isinstalled(app):
|
||||
""" returns True if app is installed """
|
||||
from django.conf import settings
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
from django.http import Http404
|
||||
from django.contrib.admin.util import unquote
|
||||
from django.contrib.admin.utils import unquote
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from django.db.models import get_model
|
||||
from django.shortcuts import get_object_or_404
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
django==1.8.4
|
||||
django==1.8.5
|
||||
django-fluent-dashboard==0.5.3
|
||||
django-admin-tools==0.6.0
|
||||
django-extensions==1.5.2
|
||||
django-extensions==1.5.7
|
||||
django-celery==3.1.16
|
||||
celery==3.1.16
|
||||
kombu==3.0.23
|
||||
|
|
Loading…
Reference in a new issue