diff --git a/orchestra/contrib/accounts/forms.py b/orchestra/contrib/accounts/forms.py index 285b868c..4a7dcc6b 100644 --- a/orchestra/contrib/accounts/forms.py +++ b/orchestra/contrib/accounts/forms.py @@ -35,7 +35,7 @@ def create_account_creation_form(): initial=True, required=False, label=label, help_text=help_text) create_related.append((model, key, kwargs, help_text)) - def clean(self): + def clean(self, create_related=create_related): """ unique usernames between accounts and system users """ cleaned_data = UserCreationForm.clean(self) try: @@ -51,7 +51,6 @@ def create_account_creation_form(): if systemuser_model.objects.filter(username=account.username).exists(): errors['username'] = _("A system user with this name already exists.") for model, key, related_kwargs, __ in create_related: - model = apps.get_model(model) kwargs = { key: eval(related_kwargs[key], {'account': account}) } diff --git a/orchestra/contrib/bills/actions.py b/orchestra/contrib/bills/actions.py index 6204ef3f..f288b4b0 100644 --- a/orchestra/contrib/bills/actions.py +++ b/orchestra/contrib/bills/actions.py @@ -287,6 +287,7 @@ def amend_bills(modeladmin, request, queryset): tax=tax ) amend_ids.append(amend.pk) + modeladmin.log_change(request, bill, 'Amended, amend id is %i' % amend.id) num = len(amend_ids) if num == 1: amend_url = reverse('admin:bills_bill_change', args=amend_ids) diff --git a/orchestra/contrib/bills/models.py b/orchestra/contrib/bills/models.py index 2f5acdc0..3b29356d 100644 --- a/orchestra/contrib/bills/models.py +++ b/orchestra/contrib/bills/models.py @@ -441,15 +441,15 @@ class BillLine(models.Model): def get_verbose_period(self): from django.template.defaultfilters import date date_format = "N 'y" - if self.start_on.day != 1 or self.end_on.day != 1: + if self.start_on.day != 1 or (self.end_on and self.end_on.day != 1): date_format = "N j, 'y" end = date(self.end_on, date_format) - else: + elif self.end_on: end = date((self.end_on - datetime.timedelta(days=1)), date_format) ini = date(self.start_on, date_format).capitalize() - end = end.capitalize() if not self.end_on: return ini + end = end.capitalize() if ini == end: return ini return "{ini} / {end}".format(ini=ini, end=end) diff --git a/orchestra/contrib/domains/admin.py b/orchestra/contrib/domains/admin.py index 25e799fa..6458768e 100644 --- a/orchestra/contrib/domains/admin.py +++ b/orchestra/contrib/domains/admin.py @@ -1,5 +1,6 @@ from django.contrib import admin from django.core.urlresolvers import reverse +from django.db import models from django.db.models.functions import Concat, Coalesce from django.templatetags.static import static from django.utils.translation import ugettext, ugettext_lazy as _ @@ -51,11 +52,13 @@ class DomainInline(admin.TabularInline): class DomainAdmin(AccountAdminMixin, ExtendedModelAdmin): list_display = ( - 'structured_name', 'display_is_top', 'display_websites', 'account_link' + 'structured_name', 'display_is_top', 'display_websites', 'display_addresses', 'account_link' ) add_fields = ('name', 'account') - fields = ('name', 'account_link', 'display_websites') - readonly_fields = ('account_link', 'top_link', 'display_websites', 'implicit_records') + fields = ('name', 'account_link', 'display_websites', 'display_addresses') + readonly_fields = ( + 'account_link', 'top_link', 'display_websites', 'display_addresses', 'implicit_records' + ) inlines = (RecordInline, DomainInline) list_filter = (TopDomainListFilter, HasWebsiteFilter, HasAddressFilter) change_readonly_fields = ('name', 'serial') @@ -93,17 +96,38 @@ class DomainAdmin(AccountAdminMixin, ExtendedModelAdmin): admin_url, title, website.name, site_link) links.append(link) return '
'.join(links) - add_url = reverse('admin:websites_website_add') - add_url += '?account=%i&domains=%i' % (domain.account_id, domain.pk) - image = '' % static('orchestra/images/add.png') - add_link = '%s' % ( - add_url, _("Add website"), image - ) - return _("No website %s") % (add_link) + add_url = reverse('admin:websites_website_add') + add_url += '?account=%i&domains=%i' % (domain.account_id, domain.pk) + image = '' % static('orchestra/images/add.png') + add_link = '%s' % ( + add_url, _("Add website"), image + ) + return _("No website %s") % (add_link) + return '---' display_websites.admin_order_field = 'websites__name' display_websites.short_description = _("Websites") display_websites.allow_tags = True + def display_addresses(self, domain): + if apps.isinstalled('orchestra.contrib.mailboxes'): + add_url = reverse('admin:mailboxes_address_add') + add_url += '?account=%i&domain=%i' % (domain.account_id, domain.pk) + image = '' % static('orchestra/images/add.png') + add_link = '%s' % ( + add_url, _("Add address"), image + ) + addresses = domain.addresses.all() + if addresses: + url = reverse('admin:mailboxes_address_changelist') + url += '?domain=%i' % addresses[0].domain_id + title = '\n'.join([address.email for address in addresses]) + return '%s %s' % (url, title, len(addresses), add_link) + return _("No address %s") % (add_link) + return '---' + display_addresses.short_description = _("Addresses") + display_addresses.admin_order_field = 'addresses__count' + display_addresses.allow_tags = True + def implicit_records(self, domain): defaults = [] types = set(domain.records.values_list('type', flat=True)) @@ -169,6 +193,8 @@ class DomainAdmin(AccountAdminMixin, ExtendedModelAdmin): ).order_by('-structured_id', 'structured_name') if apps.isinstalled('orchestra.contrib.websites'): qs = qs.prefetch_related('websites__domains') + if apps.isinstalled('orchestra.contrib.mailboxes'): + qs = qs.annotate(models.Count('addresses')) return qs def save_model(self, request, obj, form, change): diff --git a/orchestra/contrib/issues/models.py b/orchestra/contrib/issues/models.py index f5529291..f2a75f27 100644 --- a/orchestra/contrib/issues/models.py +++ b/orchestra/contrib/issues/models.py @@ -65,11 +65,13 @@ class Ticket(models.Model): ) creator = models.ForeignKey(djsettings.AUTH_USER_MODEL, verbose_name=_("created by"), - related_name='tickets_created', null=True) + related_name='tickets_created', null=True, on_delete=models.SET_NULL) creator_name = models.CharField(_("creator name"), max_length=256, blank=True) owner = models.ForeignKey(djsettings.AUTH_USER_MODEL, null=True, blank=True, + on_delete=models.SET_NULL, related_name='tickets_owned', verbose_name=_("assigned to")) - queue = models.ForeignKey(Queue, related_name='tickets', null=True, blank=True) + queue = models.ForeignKey(Queue, related_name='tickets', null=True, blank=True, + on_delete=models.SET_NULL) subject = models.CharField(_("subject"), max_length=256) description = models.TextField(_("description")) priority = models.CharField(_("priority"), max_length=32, choices=PRIORITIES, default=MEDIUM) diff --git a/orchestra/contrib/lists/backends.py b/orchestra/contrib/lists/backends.py index 2873f28d..92d2b73d 100644 --- a/orchestra/contrib/lists/backends.py +++ b/orchestra/contrib/lists/backends.py @@ -134,7 +134,7 @@ class MailmanController(MailmanVirtualDomainController): echo "${aliases}" >> %(virtual_alias)s UPDATED_VIRTUAL_ALIAS=1 else - existing=$(grep -E '^\s*(%(address_name)s|%(name)s)@%(address_domain)s\s\s*%(name)s\s*$' %(virtual_alias)s|wc -l) + existing=$({ grep -E '^\s*(%(address_name)s|%(name)s)@%(address_domain)s\s\s*%(name)s\s*$' %(virtual_alias)s || test $? -lt 2; }|wc -l) if [[ $existing -ne %(num_entries)s ]]; then sed -i -e '/^.*\s%(name)s\(%(suffixes_regex)s\)\s*$/d' \\ -e 'N; /^\s*\\n\s*$/d; P; D' %(virtual_alias)s diff --git a/orchestra/contrib/payments/models.py b/orchestra/contrib/payments/models.py index 1dc27c43..8d08e3f5 100644 --- a/orchestra/contrib/payments/models.py +++ b/orchestra/contrib/payments/models.py @@ -111,7 +111,7 @@ class Transaction(models.Model): bill = models.ForeignKey('bills.bill', verbose_name=_("bill"), related_name='transactions') - source = models.ForeignKey(PaymentSource, null=True, blank=True, + source = models.ForeignKey(PaymentSource, null=True, blank=True, on_delete=models.SET_NULL, verbose_name=_("source"), related_name='transactions') process = models.ForeignKey('payments.TransactionProcess', null=True, blank=True, on_delete=models.SET_NULL, verbose_name=_("process"), related_name='transactions') diff --git a/orchestra/contrib/resources/models.py b/orchestra/contrib/resources/models.py index d2767ccc..9ebd92b9 100644 --- a/orchestra/contrib/resources/models.py +++ b/orchestra/contrib/resources/models.py @@ -63,7 +63,7 @@ class Resource(models.Model): disable_trigger = models.BooleanField(_("disable trigger"), default=True, help_text=_("Disables monitors exeeded and recovery triggers")) crontab = models.ForeignKey('djcelery.CrontabSchedule', verbose_name=_("crontab"), - null=True, blank=True, + null=True, blank=True, on_delete=models.SET_NULL, help_text=_("Crontab for periodic execution. " "Leave it empty to disable periodic monitoring")) monitors = fields.MultiSelectField(_("monitors"), max_length=256, blank=True, diff --git a/orchestra/contrib/webapps/backends/php.py b/orchestra/contrib/webapps/backends/php.py index 47f76cbb..88395db9 100644 --- a/orchestra/contrib/webapps/backends/php.py +++ b/orchestra/contrib/webapps/backends/php.py @@ -156,7 +156,7 @@ class PHPController(WebAppServiceMixin, ServiceController): fi counter=$(($counter+1)) done - state="$(grep -v "$BACKEND" /dev/shm/reload.apache2.locked)" || is_last=1 + state="$(grep -v -E "^$BACKEND($|\s)" /dev/shm/reload.apache2.locked)" || is_last=1 [[ $is_last -eq 0 ]] && { echo "$state" | grep -v ' RELOAD$' || is_last=1 } @@ -171,7 +171,7 @@ class PHPController(WebAppServiceMixin, ServiceController): fi rm /dev/shm/reload.apache2.locked else - echo -n "$state" > /dev/shm/reload.apache2.locked + echo "$state" > /dev/shm/reload.apache2.locked if [[ $UPDATED_APACHE -eq 1 ]]; then echo -e "[DEBUG]: Apache will be reloaded by another backend:\\n${state}" echo "$BACKEND RELOAD" >> /dev/shm/reload.apache2.locked diff --git a/orchestra/contrib/websites/backends/apache.py b/orchestra/contrib/websites/backends/apache.py index ed3da854..90e9d8be 100644 --- a/orchestra/contrib/websites/backends/apache.py +++ b/orchestra/contrib/websites/backends/apache.py @@ -160,7 +160,7 @@ class Apache2Controller(ServiceController): counter=$(($counter+1)) sleep 0.1; done - state="$(grep -v "$BACKEND" /dev/shm/reload.apache2.locked)" || is_last=1 + state="$(grep -v -E "^$BACKEND($|\s)" /dev/shm/reload.apache2.locked)" || is_last=1 [[ $is_last -eq 0 ]] && { echo "$state" | grep -v ' RELOAD$' || is_last=1 } @@ -175,7 +175,7 @@ class Apache2Controller(ServiceController): fi rm /dev/shm/reload.apache2.locked else - echo -n "$state" > /dev/shm/reload.apache2.locked + echo "$state" > /dev/shm/reload.apache2.locked if [[ $UPDATED_APACHE -eq 1 ]]; then echo -e "[DEBUG]: Apache will be reloaded by another backend:\\n${state}" echo "$BACKEND RELOAD" >> /dev/shm/reload.apache2.locked