Random improvements

This commit is contained in:
Marc Aymerich 2014-11-14 15:51:18 +00:00
parent d2b96dac40
commit 4d9feb690f
9 changed files with 104 additions and 48 deletions

View File

@ -177,3 +177,4 @@ Remember that, as always with QuerySets, any subsequent chained methods which im
* ServiceBackend.validate() : used for server paths validation
* ServiceBackend.grant_access() : used for granting access
* bottom line: allow arbitrary backend methods (underscore method names that are not to be executed?)
* HowTo?? Signals ? what?

View File

@ -39,8 +39,7 @@ class ChangeListDefaultFilter(object):
defaults.append(key)
# hack response cl context in order to hook default filter awaearness
# into search_form.html template
response = super(ChangeListDefaultFilter, self).changelist_view(request,
extra_context=extra_context)
response = super(ChangeListDefaultFilter, self).changelist_view(request, extra_context)
if hasattr(response, 'context_data') and 'cl' in response.context_data:
response.context_data['cl'].default_changelist_filters = defaults
return response
@ -100,7 +99,7 @@ class ChangeViewActionsMixin(object):
kwargs['extra_context'] = {}
obj = self.get_object(request, unquote(object_id))
kwargs['extra_context']['object_tools_items'] = [
action.__dict__ for action in self.get_change_view_actions(obj=obj)
action.__dict__ for action in self.get_change_view_actions(obj)
]
return super(ChangeViewActionsMixin, self).change_view(request, object_id, **kwargs)
@ -116,11 +115,11 @@ class ChangeAddFieldsMixin(object):
def get_prepopulated_fields(self, request, obj=None):
if not obj:
return super(ChangeAddFieldsMixin, self).get_prepopulated_fields(request, obj=obj)
return super(ChangeAddFieldsMixin, self).get_prepopulated_fields(request, obj)
return {}
def get_readonly_fields(self, request, obj=None):
fields = super(ChangeAddFieldsMixin, self).get_readonly_fields(request, obj=obj)
fields = super(ChangeAddFieldsMixin, self).get_readonly_fields(request, obj)
if obj:
return fields + self.change_readonly_fields
return fields
@ -131,7 +130,7 @@ class ChangeAddFieldsMixin(object):
return self.add_fieldsets
elif self.add_fields:
return [(None, {'fields': self.add_fields})]
return super(ChangeAddFieldsMixin, self).get_fieldsets(request, obj=obj)
return super(ChangeAddFieldsMixin, self).get_fieldsets(request, obj)
def get_inline_instances(self, request, obj=None):
""" add_inlines and inline.parent_object """
@ -139,7 +138,7 @@ class ChangeAddFieldsMixin(object):
self.inlines = type(self).inlines
else:
self.inlines = self.add_inlines or self.inlines
inlines = super(ChangeAddFieldsMixin, self).get_inline_instances(request, obj=obj)
inlines = super(ChangeAddFieldsMixin, self).get_inline_instances(request, obj)
for inline in inlines:
inline.parent_object = obj
return inlines
@ -200,7 +199,7 @@ class ChangePasswordAdminMixin(object):
related.append(rel)
if request.method == 'POST':
form = self.change_password_form(user, request.POST, related=related)
form = self.change_password_form(user, request.POST, related)
if form.is_valid():
form.save()
change_message = self.construct_change_message(request, form, None)
@ -210,7 +209,7 @@ class ChangePasswordAdminMixin(object):
update_session_auth_hash(request, form.user) # This is safe
return HttpResponseRedirect('..')
else:
form = self.change_password_form(user, related=related)
form = self.change_password_form(user, related)
fieldsets = [
(user._meta.verbose_name.capitalize(), {

View File

@ -3,6 +3,7 @@ from rest_framework.response import Response
from rest_framework.reverse import reverse
from .. import settings
from ..core import services, accounts
class APIRoot(views.APIView):
@ -15,6 +16,10 @@ class APIRoot(views.APIView):
'<%s>; rel="%s"' % (root_url, 'api-root'),
'<%s>; rel="%s"' % (token_url, 'api-get-auth-token'),
]
body = {
'accountancy': [],
'services': [],
}
if not request.user.is_anonymous():
list_name = '{basename}-list'
detail_name = '{basename}-detail'
@ -30,17 +35,34 @@ class APIRoot(views.APIView):
kwargs = {}
url = reverse(url_name, request=request, format=format, kwargs=kwargs)
links.append('<%s>; rel="%s"' % (url, url_name))
model = viewset.model
group = None
if model in services:
group = 'services'
menu = services[model].menu
elif model in accounts:
group = 'accountancy'
menu = accounts[model].menu
if group and menu:
body[group].append({
'url': url,
'name': basename,
'verbose_name': model._meta.verbose_name,
'verbose_name_plural': model._meta.verbose_name_plural,
})
headers = {
'Link': ', '.join(links)
}
body = {
name.lower(): getattr(settings, name, None) for name in self.names
}
body.update({
name.lower(): getattr(settings, name, None)
for name in self.names
})
return Response(body, headers=headers)
def metadata(self, request):
ret = super(APIRoot, self).metadata(request)
ret['settings'] = {
name.lower(): getattr(settings, name, None) for name in self.names
name.lower(): getattr(settings, name, None)
for name in self.names
}
return ret

View File

@ -11,11 +11,15 @@ from . import settings, validators, utils
class Domain(models.Model):
name = models.CharField(_("name"), max_length=256, unique=True,
validators=[validators.validate_domain_name, validators.validate_allowed_domain],
help_text=_("Domain or subdomain name."))
account = models.ForeignKey('accounts.Account', verbose_name=_("Account"),
related_name='domains', blank=True, help_text=_("Automatically selected for subdomains."))
top = models.ForeignKey('domains.Domain', null=True, related_name='subdomain_set', editable=False)
help_text=_("Domain or subdomain name."),
validators=[
validators.validate_domain_name,
validators.validate_allowed_domain
])
account = models.ForeignKey('accounts.Account', verbose_name=_("Account"), blank=True,
related_name='domains', help_text=_("Automatically selected for subdomains."))
top = models.ForeignKey('domains.Domain', null=True, related_name='subdomain_set',
editable=False)
serial = models.IntegerField(_("serial"), default=utils.generate_zone_serial,
help_text=_("Serial number"))
@ -88,17 +92,24 @@ class Domain(models.Model):
# Update serial and insert at 0
value = record.value.split()
value[2] = str(self.serial)
records.insert(0,
AttrDict(type=record.SOA, ttl=record.get_ttl(), value=' '.join(value))
)
records.insert(0, AttrDict(
type=record.SOA,
ttl=record.get_ttl(),
value=' '.join(value)
))
else:
records.append(
AttrDict(type=record.type, ttl=record.get_ttl(), value=record.value)
)
records.append(AttrDict(
type=record.type,
ttl=record.get_ttl(),
value=record.value
))
if self.is_top:
if Record.NS not in types:
for ns in settings.DOMAINS_DEFAULT_NS:
records.append(AttrDict(type=Record.NS, value=ns))
records.append(AttrDict(
type=Record.NS,
value=ns
))
if Record.SOA not in types:
soa = [
"%s." % settings.DOMAINS_DEFAULT_NAME_SERVER,
@ -109,27 +120,42 @@ class Domain(models.Model):
settings.DOMAINS_DEFAULT_EXPIRATION,
settings.DOMAINS_DEFAULT_MIN_CACHING_TIME
]
records.insert(0, AttrDict(type=Record.SOA, value=' '.join(soa)))
records.insert(0, AttrDict(
type=Record.SOA,
value=' '.join(soa)
))
is_a = not types or Record.A in types or Record.AAAA in types
if Record.MX not in types and is_a:
for mx in settings.DOMAINS_DEFAULT_MX:
records.append(AttrDict(type=Record.MX, value=mx))
records.append(AttrDict(
type=Record.MX,
value=mx
))
if (Record.A not in types and Record.AAAA not in types) and is_a:
records.append(AttrDict(type=Record.A, value=settings.DOMAINS_DEFAULT_A))
records.append(AttrDict(
type=Record.A,
value=settings.DOMAINS_DEFAULT_A
))
result = ''
for record in records:
name = '{name}.{spaces}'.format(
name=self.name, spaces=' ' * (37-len(self.name))
name=self.name,
spaces=' ' * (37-len(self.name))
)
ttl = record.get('ttl', settings.DOMAINS_DEFAULT_TTL)
ttl = '{spaces}{ttl}'.format(
spaces=' ' * (7-len(ttl)), ttl=ttl
spaces=' ' * (7-len(ttl)),
ttl=ttl
)
type = '{type} {spaces}'.format(
type=record.type, spaces=' ' * (7-len(record.type))
type=record.type,
spaces=' ' * (7-len(record.type))
)
result += '{name} {ttl} IN {type} {value}\n'.format(
name=name, ttl=ttl, type=type, value=record.value
name=name,
ttl=ttl,
type=type,
value=record.value
)
return result

View File

@ -39,13 +39,7 @@ class DomainSerializer(AccountSerializerMixin, HyperlinkedModelSerializer):
""" Checks if everything is consistent """
instance = super(DomainSerializer, self).full_clean(instance)
if instance and instance.name:
records = self.init_data['records']
records = self.init_data.get('records', [])
domain = domain_for_validation(instance, records)
try:
validators.validate_zone(domain.render_zone())
except ValidationError as err:
self._errors = {
'all': err.message
}
return None
return instance

View File

@ -51,7 +51,7 @@ class Miscellaneous(models.Model):
verbose_name_plural = _("miscellaneous")
def __unicode__(self):
return self.identifier or str(self.service)
return self.identifier or self.description[:32] or str(self.service)
@cached_property
def active(self):

View File

@ -21,7 +21,9 @@ from .models import SystemUser
class SystemUserAdmin(ChangePasswordAdminMixin, SelectAccountAdminMixin, ExtendedModelAdmin):
list_display = ('username', 'account_link', 'shell', 'display_home', 'display_active', 'display_main')
list_display = (
'username', 'account_link', 'shell', 'display_home', 'display_active', 'display_main'
)
list_filter = ('is_active', 'shell', IsMainListFilter)
fieldsets = (
(None, {

View File

@ -24,8 +24,9 @@ class SystemUser(models.Model):
""" System users """
username = models.CharField(_("username"), max_length=64, unique=True,
help_text=_("Required. 64 characters or fewer. Letters, digits and ./-/_ only."),
validators=[validators.RegexValidator(r'^[\w.-]+$',
_("Enter a valid username."), 'invalid')])
validators=[
validators.RegexValidator(r'^[\w.-]+$', _("Enter a valid username."))
])
password = models.CharField(_("password"), max_length=128)
account = models.ForeignKey('accounts.Account', verbose_name=_("Account"),
related_name='systemusers')
@ -82,7 +83,10 @@ class SystemUser(models.Model):
return settings.SYSTEMUSERS_HOME % context
def get_home(self):
return os.path.join(self.home or self.get_base_home(), self.directory)
return os.path.join(
self.home or self.get_base_home(),
self.directory
)
services.register(SystemUser)

View File

@ -1,3 +1,6 @@
from ..utils.python import AttrDict
class Register(object):
def __init__(self):
self._registry = {}
@ -5,17 +8,22 @@ class Register(object):
def __contains__(self, key):
return key in self._registry
def __getitem__(self, key):
return self._registry[key]
def register(self, model, **kwargs):
if model in self._registry:
raise KeyError("%s already registered" % str(model))
plural = kwargs.get('verbose_name_plural', model._meta.verbose_name_plural)
self._registry[model] = {
self._registry[model] = AttrDict(**{
'verbose_name': kwargs.get('verbose_name', model._meta.verbose_name),
'verbose_name_plural': plural,
'menu': kwargs.get('menu', True)
}
})
def get(self):
def get(self, *args):
if args:
return self._registry[arg[0]]
return self._registry