diff -r 5f7e9f778b29 -r 660b42391c8e VirtualMailManager/domain.py --- a/VirtualMailManager/domain.py Wed Feb 09 22:09:35 2011 +0000 +++ b/VirtualMailManager/domain.py Thu Feb 10 20:10:28 2011 +0000 @@ -16,7 +16,8 @@ ACCOUNT_AND_ALIAS_PRESENT, DOMAIN_ALIAS_EXISTS, DOMAIN_EXISTS, \ DOMAIN_INVALID, DOMAIN_TOO_LONG, NO_SUCH_DOMAIN from VirtualMailManager.errors import DomainError as DomErr -from VirtualMailManager.pycompat import any +from VirtualMailManager.pycompat import all, any +from VirtualMailManager.quotalimit import QuotaLimit from VirtualMailManager.transport import Transport @@ -27,7 +28,8 @@ class Domain(object): """Class to manage e-mail domains.""" - __slots__ = ('_directory', '_gid', '_name', '_transport', '_dbh', '_new') + __slots__ = ('_directory', '_gid', '_name', '_qlimit', '_transport', + '_dbh', '_new') def __init__(self, dbh, domainname): """Creates a new Domain instance. @@ -49,6 +51,7 @@ self._name = check_domainname(domainname) self._dbh = dbh self._gid = 0 + self._qlimit = None self._transport = None self._directory = None self._new = True @@ -62,17 +65,18 @@ domain. """ dbc = self._dbh.cursor() - dbc.execute('SELECT dd.gid, tid, domaindir, is_primary FROM ' + dbc.execute('SELECT dd.gid, qid, tid, domaindir, is_primary FROM ' 'domain_data dd, domain_name dn WHERE domainname = %s AND ' 'dn.gid = dd.gid', (self._name,)) result = dbc.fetchone() dbc.close() if result: - if not result[3]: + if not result[4]: raise DomErr(_(u"The domain '%s' is an alias domain.") % self._name, DOMAIN_ALIAS_EXISTS) - self._gid, self._directory = result[0], result[2] - self._transport = Transport(self._dbh, tid=result[1]) + self._gid, self._directory = result[0], result[3] + self._qlimit = QuotaLimit(self._dbh, qid=result[1]) + self._transport = Transport(self._dbh, tid=result[2]) self._new = False def _set_gid(self): @@ -109,6 +113,34 @@ raise DomErr(_(u"The domain '%s' doesn't exist.") % self._name, NO_SUCH_DOMAIN) + def _update_tables(self, column, value, force=False): + """Update various columns in the domain_data table. When *force* is + `True` also the corresponding column in the users table will be + updated. + + Arguments: + + `column` : basestring + Name of the table column. Currently: qid and tid + `value` : long + The referenced key + `force` : bool + enforce the new setting also for existing users. Default: `False` + """ + if column not in ('qid', 'tid'): + raise ValueError('Unknown column: %r' % column) + dbc = self._dbh.cursor() + dbc.execute('UPDATE domain_data SET %s = %%s WHERE gid = %%s' % column, + (value, self._gid)) + if dbc.rowcount > 0: + self._dbh.commit() + if force: + dbc.execute('UPDATE users SET %s = %%s WHERE gid = %%s' % column, + (value, self._gid)) + if dbc.rowcount > 0: + self._dbh.commit() + dbc.close() + @property def gid(self): """The GID of the Domain.""" @@ -124,6 +156,16 @@ """The Domain's directory.""" return self._directory + @property + def quotalimit(self): + """The Domain's quota limit.""" + return self._qlimit + + @property + def transport(self): + """The Domain's transport.""" + return self._transport + def set_directory(self, basedir): """Set the path value of the Domain's directory, inside *basedir*. @@ -140,10 +182,19 @@ self._directory = os.path.join(basedir, choice(MAILDIR_CHARS), str(self._gid)) - @property - def transport(self): - """The Domain's transport.""" - return self._transport + def set_quotalimit(self, quotalimit): + """Set the quota limit for the new Domain. + + Argument: + + `quotalimit` : VirtualMailManager.quotalimit.QuotaLimit + The quota limit of the new Domain. + """ + if not self._new: + raise DomErr(_(u"The domain '%s' already exists.") % self._name, + DOMAIN_EXISTS) + assert isinstance(quotalimit, QuotaLimit) + self._qlimit = quotalimit def set_transport(self, transport): """Set the transport for the new Domain. @@ -164,11 +215,11 @@ if not self._new: raise DomErr(_(u"The domain '%s' already exists.") % self._name, DOMAIN_EXISTS) - assert self._directory is not None and self._transport is not None + assert all((self._directory, self._qlimit, self._transport)) dbc = self._dbh.cursor() - dbc.execute('INSERT INTO domain_data (gid, tid, domaindir) VALUES ' - '(%s, %s, %s)', (self._gid, self._transport.tid, - self._directory)) + dbc.execute('INSERT INTO domain_data (gid, qid, tid, domaindir) ' + 'VALUES (%s, %s, %s, %s)', (self._gid, self._qlimit.qid, + self._transport.tid, self._directory)) dbc.execute('INSERT INTO domain_name (domainname, gid, is_primary) ' 'VALUES (%s, %s, TRUE)', (self._name, self._gid)) self._dbh.commit() @@ -198,9 +249,30 @@ self._dbh.commit() dbc.close() self._gid = 0 - self._directory = self._transport = None + self._directory = self._qlimit = self._transport = None self._new = True + def update_quotalimit(self, quotalimit, force=False): + """Update the quota limit of the Domain. + + If *force* is `True` the new *quotalimit* will be applied to + all existing accounts of the domain. Otherwise the *quotalimit* + will be only applied to accounts created from now on. + + Arguments: + + `quotalimit` : VirtualMailManager.quotalimit.QuotaLimit + the new quota limit of the domain. + `force` : bool + enforce new quota limit for all accounts, default `False` + """ + self._chk_state() + assert isinstance(quotalimit, QuotaLimit) + if quotalimit == self._qlimit: + return + self._update_tables('qid', quotalimit.qid, force) + self._qlimit = quotalimit + def update_transport(self, transport, force=False): """Sets a new transport for the Domain. @@ -219,17 +291,7 @@ assert isinstance(transport, Transport) if transport == self._transport: return - dbc = self._dbh.cursor() - dbc.execute("UPDATE domain_data SET tid = %s WHERE gid = %s", - (transport.tid, self._gid)) - if dbc.rowcount > 0: - self._dbh.commit() - if force: - dbc.execute("UPDATE users SET tid = %s WHERE gid = %s", - (transport.tid, self._gid)) - if dbc.rowcount > 0: - self._dbh.commit() - dbc.close() + self._update_tables('tid', transport.tid, force) self._transport = transport def get_info(self): @@ -237,12 +299,13 @@ self._chk_state() dbc = self._dbh.cursor() dbc.execute('SELECT gid, domainname, transport, domaindir, ' - 'aliasdomains, accounts, aliases, relocated FROM ' - 'vmm_domain_info WHERE gid = %s', (self._gid,)) + 'aliasdomains, accounts, aliases, relocated, bytes, ' + 'messages FROM vmm_domain_info WHERE gid = %s', + (self._gid,)) info = dbc.fetchone() dbc.close() keys = ('gid', 'domainname', 'transport', 'domaindir', 'aliasdomains', - 'accounts', 'aliases', 'relocated') + 'accounts', 'aliases', 'relocated', 'bytes', 'messages') return dict(zip(keys, info)) def get_accounts(self):