76 '%s AND dn.gid = dd.gid', (self._name,)) |
76 '%s AND dn.gid = dd.gid', (self._name,)) |
77 result = dbc.fetchone() |
77 result = dbc.fetchone() |
78 dbc.close() |
78 dbc.close() |
79 if result: |
79 if result: |
80 if not result[5]: |
80 if not result[5]: |
81 raise DomErr(_(u"The domain '%s' is an alias domain.") % |
81 raise DomErr(_("The domain '%s' is an alias domain.") % |
82 self._name, DOMAIN_ALIAS_EXISTS) |
82 self._name, DOMAIN_ALIAS_EXISTS) |
83 self._gid, self._directory = result[0], result[4] |
83 self._gid, self._directory = result[0], result[4] |
84 self._qlimit = QuotaLimit(self._dbh, qid=result[1]) |
84 self._qlimit = QuotaLimit(self._dbh, qid=result[1]) |
85 self._services = ServiceSet(self._dbh, ssid=result[2]) |
85 self._services = ServiceSet(self._dbh, ssid=result[2]) |
86 self._transport = Transport(self._dbh, tid=result[3]) |
86 self._transport = Transport(self._dbh, tid=result[3]) |
111 result = dbc.fetchall() |
111 result = dbc.fetchall() |
112 dbc.close() |
112 dbc.close() |
113 result = result[0] |
113 result = result[0] |
114 if any(result): |
114 if any(result): |
115 keys = ('account_count', 'alias_count', 'relocated_count') |
115 keys = ('account_count', 'alias_count', 'relocated_count') |
116 raise DomErr(_(u'There are %(account_count)u accounts, ' |
116 raise DomErr(_('There are %(account_count)u accounts, ' |
117 u'%(alias_count)u aliases and %(relocated_count)u ' |
117 '%(alias_count)u aliases and %(relocated_count)u ' |
118 u'relocated users.') % dict(zip(keys, result)), |
118 'relocated users.') % dict(list(zip(keys, result))), |
119 ACCOUNT_AND_ALIAS_PRESENT) |
119 ACCOUNT_AND_ALIAS_PRESENT) |
120 |
120 |
121 def _chk_state(self, must_exist=True): |
121 def _chk_state(self, must_exist=True): |
122 """Checks the state of the Domain instance and will raise a |
122 """Checks the state of the Domain instance and will raise a |
123 VirtualMailManager.errors.DomainError: |
123 VirtualMailManager.errors.DomainError: |
124 - if *must_exist* is `True` and the domain doesn't exist |
124 - if *must_exist* is `True` and the domain doesn't exist |
125 - or *must_exist* is `False` and the domain exists |
125 - or *must_exist* is `False` and the domain exists |
126 """ |
126 """ |
127 if must_exist and self._new: |
127 if must_exist and self._new: |
128 raise DomErr(_(u"The domain '%s' does not exist.") % self._name, |
128 raise DomErr(_("The domain '%s' does not exist.") % self._name, |
129 NO_SUCH_DOMAIN) |
129 NO_SUCH_DOMAIN) |
130 elif not must_exist and not self._new: |
130 elif not must_exist and not self._new: |
131 raise DomErr(_(u"The domain '%s' already exists.") % self._name, |
131 raise DomErr(_("The domain '%s' already exists.") % self._name, |
132 DOMAIN_EXISTS) |
132 DOMAIN_EXISTS) |
133 |
133 |
134 def _update_tables(self, column, value): |
134 def _update_tables(self, column, value): |
135 """Update table columns in the domain_data table.""" |
135 """Update table columns in the domain_data table.""" |
136 dbc = self._dbh.cursor() |
136 dbc = self._dbh.cursor() |
261 |
261 |
262 `note` : basestring or None |
262 `note` : basestring or None |
263 The note, or None to remove |
263 The note, or None to remove |
264 """ |
264 """ |
265 self._chk_state(False) |
265 self._chk_state(False) |
266 assert note is None or isinstance(note, basestring) |
266 assert note is None or isinstance(note, str) |
267 self._note = note |
267 self._note = note |
268 |
268 |
269 def save(self): |
269 def save(self): |
270 """Stores the new domain in the database.""" |
270 """Stores the new domain in the database.""" |
271 self._chk_state(False) |
271 self._chk_state(False) |
323 the new quota limit of the domain. |
323 the new quota limit of the domain. |
324 `force` : bool |
324 `force` : bool |
325 enforce new quota limit for all accounts, default `False` |
325 enforce new quota limit for all accounts, default `False` |
326 """ |
326 """ |
327 if cfg_dget('misc.dovecot_version') < 0x10102f00: |
327 if cfg_dget('misc.dovecot_version') < 0x10102f00: |
328 raise VMMError(_(u'PostgreSQL-based dictionary quota requires ' |
328 raise VMMError(_('PostgreSQL-based dictionary quota requires ' |
329 u'Dovecot >= v1.1.2.'), VMM_ERROR) |
329 'Dovecot >= v1.1.2.'), VMM_ERROR) |
330 self._chk_state() |
330 self._chk_state() |
331 assert isinstance(quotalimit, QuotaLimit) |
331 assert isinstance(quotalimit, QuotaLimit) |
332 if not force and quotalimit == self._qlimit: |
332 if not force and quotalimit == self._qlimit: |
333 return |
333 return |
334 self._update_tables_ref('qid', quotalimit.qid, force) |
334 self._update_tables_ref('qid', quotalimit.qid, force) |
403 'FROM vmm_domain_info WHERE gid = %s', (self._gid,)) |
403 'FROM vmm_domain_info WHERE gid = %s', (self._gid,)) |
404 info = dbc.fetchone() |
404 info = dbc.fetchone() |
405 dbc.close() |
405 dbc.close() |
406 keys = ('alias domains', 'accounts', 'aliases', 'relocated', |
406 keys = ('alias domains', 'accounts', 'aliases', 'relocated', |
407 'catch-all dests') |
407 'catch-all dests') |
408 info = dict(zip(keys, info)) |
408 info = dict(list(zip(keys, info))) |
409 info['gid'] = self._gid |
409 info['gid'] = self._gid |
410 info['domain name'] = self._name |
410 info['domain name'] = self._name |
411 info['transport'] = self._transport.transport |
411 info['transport'] = self._transport.transport |
412 info['domain directory'] = self._directory |
412 info['domain directory'] = self._directory |
413 info['bytes'] = self._qlimit.bytes |
413 info['bytes'] = self._qlimit.bytes |
430 'local_part', (self._gid,)) |
430 'local_part', (self._gid,)) |
431 users = dbc.fetchall() |
431 users = dbc.fetchall() |
432 dbc.close() |
432 dbc.close() |
433 accounts = [] |
433 accounts = [] |
434 if users: |
434 if users: |
435 addr = u'@'.join |
435 addr = '@'.join |
436 _dom = self._name |
436 _dom = self._name |
437 accounts = [addr((account[0], _dom)) for account in users] |
437 accounts = [addr((account[0], _dom)) for account in users] |
438 return accounts |
438 return accounts |
439 |
439 |
440 def get_aliases(self): |
440 def get_aliases(self): |
445 'BY address', (self._gid,)) |
445 'BY address', (self._gid,)) |
446 addresses = dbc.fetchall() |
446 addresses = dbc.fetchall() |
447 dbc.close() |
447 dbc.close() |
448 aliases = [] |
448 aliases = [] |
449 if addresses: |
449 if addresses: |
450 addr = u'@'.join |
450 addr = '@'.join |
451 _dom = self._name |
451 _dom = self._name |
452 aliases = [addr((alias[0], _dom)) for alias in addresses] |
452 aliases = [addr((alias[0], _dom)) for alias in addresses] |
453 return aliases |
453 return aliases |
454 |
454 |
455 def get_relocated(self): |
455 def get_relocated(self): |
460 'address', (self._gid,)) |
460 'address', (self._gid,)) |
461 addresses = dbc.fetchall() |
461 addresses = dbc.fetchall() |
462 dbc.close() |
462 dbc.close() |
463 relocated = [] |
463 relocated = [] |
464 if addresses: |
464 if addresses: |
465 addr = u'@'.join |
465 addr = '@'.join |
466 _dom = self._name |
466 _dom = self._name |
467 relocated = [addr((address[0], _dom)) for address in addresses] |
467 relocated = [addr((address[0], _dom)) for address in addresses] |
468 return relocated |
468 return relocated |
469 |
469 |
470 def get_catchall(self): |
470 def get_catchall(self): |
499 |
499 |
500 """ |
500 """ |
501 if not RE_DOMAIN.match(domainname): |
501 if not RE_DOMAIN.match(domainname): |
502 domainname = domainname.encode('idna') |
502 domainname = domainname.encode('idna') |
503 if len(domainname) > 255: |
503 if len(domainname) > 255: |
504 raise DomErr(_(u'The domain name is too long'), DOMAIN_TOO_LONG) |
504 raise DomErr(_('The domain name is too long'), DOMAIN_TOO_LONG) |
505 if not RE_DOMAIN.match(domainname): |
505 if not RE_DOMAIN.match(domainname): |
506 raise DomErr(_(u"The domain name '%s' is invalid") % domainname, |
506 raise DomErr(_("The domain name '%s' is invalid") % domainname, |
507 DOMAIN_INVALID) |
507 DOMAIN_INVALID) |
508 return domainname |
508 return domainname |
509 |
509 |
510 |
510 |
511 def get_gid(dbh, domainname): |
511 def get_gid(dbh, domainname): |