# HG changeset patch # User martin f. krafft # Date 1334351380 -7200 # Node ID cf3eb03c1c4f3608b49bc0aecc21bb867a2fae4d # Parent 95dd123b552e6a43607a80f2d99f84d05f98dfd1 Modify Account class to handle NULL references This patch modifies the Account class to defer to using the associated domain's tid/ssid/qid fields if the per-instance fields are None/NULL. diff -r 95dd123b552e -r cf3eb03c1c4f VirtualMailManager/account.py --- a/VirtualMailManager/account.py Fri Apr 13 17:49:14 2012 +0200 +++ b/VirtualMailManager/account.py Fri Apr 13 23:09:40 2012 +0200 @@ -59,9 +59,9 @@ self._addr.domainname, NO_SUCH_DOMAIN) self._uid = 0 self._mail = None - self._qlimit = self._domain.quotalimit - self._services = self._domain.serviceset - self._transport = self._domain.transport + self._qlimit = None + self._services = None + self._transport = None self._passwd = None self._new = True self._load() @@ -81,12 +81,19 @@ dbc.close() if result: self._uid, _mid, _qid, _ssid, _tid = result - if _qid != self._qlimit.qid: - self._qlimit = QuotaLimit(self._dbh, qid=_qid) - if _ssid != self._services.ssid: - self._services = ServiceSet(self._dbh, ssid=_ssid) - if _tid != self._transport.tid: - self._transport = Transport(self._dbh, tid=_tid) + + def load_helper(ctor, own, field, dbresult): + cur = None if own is None else getattr(own, field) + if cur != dbresult: + kwargs = { field : dbresult } + return None if dbresult is None \ + else ctor(self._dbh, **kwargs) + + self._qlimit = load_helper(QuotaLimit, self._qlimit, 'qid', _qid) + self._services = load_helper(ServiceSet, self._services, 'ssid', + _ssid) + self._transport = load_helper(Transport, self._transport, 'tid', + _tid) self._mail = MailLocation(self._dbh, mid=_mid) self._new = False @@ -223,8 +230,10 @@ 'qid, ssid, tid) VALUES (%s, %s, %s, %s, %s, %s, %s, %s)', (self._addr.localpart, pwhash(self._passwd, user=self._addr), self._uid, - self._domain.gid, self._mail.mid, self._qlimit.qid, - self._services.ssid, self._transport.tid)) + self._domain.gid, self._mail.mid, + self._qlimit.qid if self._qlimit else None, + self._services.ssid if self._services else None, + self._transport.tid if self._transport else None)) self._dbh.commit() dbc.close() self._new = False @@ -267,11 +276,13 @@ raise VMMError(_(u'PostgreSQL-based dictionary quota requires ' u'Dovecot >= v1.1.2.'), VMM_ERROR) self._chk_state() - assert isinstance(quotalimit, QuotaLimit) if quotalimit == self._qlimit: return - self._update_tables('qid', quotalimit.qid) self._qlimit = quotalimit + if quotalimit is not None: + assert isinstance(quotalimit, QuotaLimit) + quotalimit = quotalimit.qid + self._update_tables('qid', quotalimit) def update_serviceset(self, serviceset): """Assign a different set of services to the Account. @@ -282,11 +293,13 @@ the new service set. """ self._chk_state() - assert isinstance(serviceset, ServiceSet) if serviceset == self._services: return - self._update_tables('ssid', serviceset.ssid) self._services = serviceset + if serviceset is not None: + assert isinstance(serviceset, ServiceSet) + serviceset = serviceset.ssid + self._update_tables('ssid', serviceset) def update_transport(self, transport): """Sets a new transport for the Account. @@ -297,17 +310,39 @@ the new transport """ self._chk_state() - assert isinstance(transport, Transport) if transport == self._transport: return - if transport.transport.lower() in ('virtual', 'virtual:') and \ - not self._mail.postfix: - raise AErr(_(u"Invalid transport '%(transport)s' for mailbox " - u"format '%(mbfmt)s'.") % - {'transport': transport, 'mbfmt': self._mail.mbformat}, - INVALID_MAIL_LOCATION) - self._update_tables('tid', transport.tid) self._transport = transport + if transport is not None: + assert isinstance(transport, Transport) + if transport.transport.lower() in ('virtual', 'virtual:') and \ + not self._mail.postfix: + raise AErr(_(u"Invalid transport '%(transport)s' for mailbox " + u"format '%(mbfmt)s'.") % + {'transport': transport, 'mbfmt': self._mail.mbformat}, + INVALID_MAIL_LOCATION) + transport = transport.tid + self._update_tables('tid', transport) + + def _get_info_transport(self): + if self._transport: + return self._transport.transport + return format_domain_default(self._domain.transport.transport) + + def _get_info_serviceset(self): + if self._services: + services = self._services.services + fmt = lambda s: s + else: + services = self._domain.serviceset.services + fmt = format_domain_default + + ret = {} + for service, state in services.iteritems(): + # TP: A service (e.g. pop3 or imap) may be enabled/usable or + # disabled/unusable for a user. + ret[service] = fmt((_('disabled'), _('enabled'))[state]) + return ret def get_info(self): """Returns a dict with some information about the Account. @@ -326,10 +361,7 @@ dbc.close() if info: info = dict(zip(('name', 'uq_bytes', 'uq_messages'), info)) - for service, state in self._services.services.iteritems(): - # TP: A service (e.g. pop3 or imap) may be enabled/usable or - # disabled/unusable for a user. - info[service] = (_('disabled'), _('enabled'))[state] + info.update(self._get_info_serviceset()) info['address'] = self._addr info['gid'] = self._domain.gid info['home'] = '%s/%s' % (self._domain.directory, self._uid)