From ccd4df566ab0fd66e547f03b1f058be460ff7867 Mon Sep 17 00:00:00 2001 From: Antoine Nguyen Date: Wed, 17 Sep 2014 13:53:06 +0200 Subject: [PATCH] No more foreign key between admin_mailbox and admin_quota. see #603 --- modoboa/extensions/admin/fixtures/demo.json | 6 ++-- modoboa/extensions/admin/models/mailbox.py | 37 ++++++++++++++++++--- modoboa/extensions/admin/views/identity.py | 10 ++++-- 3 files changed, 41 insertions(+), 12 deletions(-) diff --git a/modoboa/extensions/admin/fixtures/demo.json b/modoboa/extensions/admin/fixtures/demo.json index 36ac1cf2f..1d3150f57 100644 --- a/modoboa/extensions/admin/fixtures/demo.json +++ b/modoboa/extensions/admin/fixtures/demo.json @@ -213,8 +213,7 @@ "quota": 10, "user": 2, "domain": 1, - "address": "admin", - "quota_value": "admin@demo.local" + "address": "admin" } }, { @@ -225,8 +224,7 @@ "quota": 10, "user": 4, "domain": 1, - "address": "user", - "quota_value": "user@demo.local" + "address": "user" } }, { diff --git a/modoboa/extensions/admin/models/mailbox.py b/modoboa/extensions/admin/models/mailbox.py index 6b137358c..ae4a04756 100644 --- a/modoboa/extensions/admin/models/mailbox.py +++ b/modoboa/extensions/admin/models/mailbox.py @@ -17,8 +17,9 @@ from .domain import Domain class Quota(models.Model): - """Mailbox current quota usage. - """ + + """Keeps track of Mailbox current quota.""" + username = models.EmailField(primary_key=True, max_length=254) bytes = models.BigIntegerField(default=0) messages = models.IntegerField(default=0) @@ -29,6 +30,8 @@ class Quota(models.Model): class MailboxManager(Manager): + """Custom manager for Mailbox.""" + def get_for_admin(self, admin, squery=None): """Return the mailboxes that belong to this admin. @@ -44,9 +47,15 @@ class MailboxManager(Manager): parts = squery.split('@') addrfilter = '@'.join(parts[:-1]) domfilter = parts[-1] - qf = Q(address__contains=addrfilter) & Q(domain__name__contains=domfilter) + qf = ( + Q(address__contains=addrfilter) & + Q(domain__name__contains=domfilter) + ) else: - qf = Q(address__contains=squery) | Q(domain__name__contains=squery) + qf = ( + Q(address__contains=squery) | + Q(domain__name__contains=squery) + ) ids = admin.objectaccess_set \ .filter(content_type=ContentType.objects.get_for_model(Mailbox)) \ .values_list('object_id', flat=True) @@ -58,13 +67,15 @@ class MailboxManager(Manager): class Mailbox(AdminObject): + + """User mailbox.""" + address = models.CharField( ugettext_lazy('address'), max_length=252, help_text=ugettext_lazy("Mailbox address (without the @domain.tld part)") ) quota = models.PositiveIntegerField() use_domain_quota = models.BooleanField(default=False) - quota_value = models.OneToOneField(Quota, to_field="username") domain = models.ForeignKey(Domain) user = models.ForeignKey(User) @@ -137,6 +148,22 @@ class Mailbox(AdminObject): aliases += [alias.full_address] return aliases + @property + def quota_value(self): + """Retrieve the ``Quota`` instance associated to this mailbox.""" + if not hasattr(self, "_quota_value"): + try: + self._quota_value = Quota.objects.get( + username=self.full_address) + except Quota.DoesNotExist: + return None + return self._quota_value + + @quota_value.setter + def quota_value(self, instance): + """Set the ``Quota`` for this mailbox.""" + self._quota_value = instance + def rename_dir(self, old_mail_home): hm = parameters.get_admin("HANDLE_MAILBOXES", raise_error=False) if hm is None or hm == "no": diff --git a/modoboa/extensions/admin/views/identity.py b/modoboa/extensions/admin/views/identity.py index a5af940ce..48388b831 100644 --- a/modoboa/extensions/admin/views/identity.py +++ b/modoboa/extensions/admin/views/identity.py @@ -90,14 +90,18 @@ def list_quotas(request, tplname="admin/quotas.html"): if sort_order in ["address", "quota", "quota_value__bytes"]: mboxes = mboxes.order_by("%s%s" % (sort_dir, sort_order)) elif sort_order == "quota_usage": - if db_type() == "postgres": + where = "admin_mailbox.address||'@'||admin_domain.name" + db_type = db_type() + if db_type == "postgres": select = '(admin_quota.bytes::float / (CAST(admin_mailbox.quota AS BIGINT) * 1048576)) * 100' else: select = 'admin_quota.bytes / (admin_mailbox.quota * 1048576) * 100' + if db_type == "mysql": + where = "CONCAT(admin_mailbox.address,'@',admin_domain.name)" mboxes = mboxes.extra( select={'quota_usage': select}, - where=["admin_quota.mbox_id=admin_mailbox.id"], - tables=["admin_quota"], + where=["admin_quota.username=%s" % where], + tables=["admin_quota", "admin_domain"], order_by=["%s%s" % (sort_dir, sort_order)] ) else: