VirtualMailManager/domain.py
branchv0.6.x
changeset 539 5806fb74130b
parent 534 6a27c7529cd7
child 568 14abdd04ddf5
equal deleted inserted replaced
538:1f9ea5658627 539:5806fb74130b
    29 
    29 
    30 
    30 
    31 class Domain(object):
    31 class Domain(object):
    32     """Class to manage e-mail domains."""
    32     """Class to manage e-mail domains."""
    33     __slots__ = ('_directory', '_gid', '_name', '_qlimit', '_services',
    33     __slots__ = ('_directory', '_gid', '_name', '_qlimit', '_services',
    34                  '_transport', '_dbh', '_new')
    34                  '_transport', '_note', '_dbh', '_new')
    35 
    35 
    36     def __init__(self, dbh, domainname):
    36     def __init__(self, dbh, domainname):
    37         """Creates a new Domain instance.
    37         """Creates a new Domain instance.
    38 
    38 
    39         Loads all relevant data from the database, if the domain could be
    39         Loads all relevant data from the database, if the domain could be
    55         self._gid = 0
    55         self._gid = 0
    56         self._qlimit = None
    56         self._qlimit = None
    57         self._services = None
    57         self._services = None
    58         self._transport = None
    58         self._transport = None
    59         self._directory = None
    59         self._directory = None
       
    60         self._note = None
    60         self._new = True
    61         self._new = True
    61         self._load()
    62         self._load()
    62 
    63 
    63     def _load(self):
    64     def _load(self):
    64         """Load information from the database and checks if the domain name
    65         """Load information from the database and checks if the domain name
    66 
    67 
    67         Raises a DomainError if Domain._name isn't the primary name of the
    68         Raises a DomainError if Domain._name isn't the primary name of the
    68         domain.
    69         domain.
    69         """
    70         """
    70         dbc = self._dbh.cursor()
    71         dbc = self._dbh.cursor()
    71         dbc.execute('SELECT dd.gid, qid, ssid, tid, domaindir, is_primary '
    72         dbc.execute('SELECT dd.gid, qid, ssid, tid, domaindir, is_primary, '
       
    73                     'note '
    72                     'FROM domain_data dd, domain_name dn WHERE domainname = '
    74                     'FROM domain_data dd, domain_name dn WHERE domainname = '
    73                     '%s AND dn.gid = dd.gid', (self._name,))
    75                     '%s AND dn.gid = dd.gid', (self._name,))
    74         result = dbc.fetchone()
    76         result = dbc.fetchone()
    75         dbc.close()
    77         dbc.close()
    76         if result:
    78         if result:
    79                              self._name, DOMAIN_ALIAS_EXISTS)
    81                              self._name, DOMAIN_ALIAS_EXISTS)
    80             self._gid, self._directory = result[0], result[4]
    82             self._gid, self._directory = result[0], result[4]
    81             self._qlimit = QuotaLimit(self._dbh, qid=result[1])
    83             self._qlimit = QuotaLimit(self._dbh, qid=result[1])
    82             self._services = ServiceSet(self._dbh, ssid=result[2])
    84             self._services = ServiceSet(self._dbh, ssid=result[2])
    83             self._transport = Transport(self._dbh, tid=result[3])
    85             self._transport = Transport(self._dbh, tid=result[3])
       
    86             self._note = result[6]
    84             self._new = False
    87             self._new = False
    85 
    88 
    86     def _set_gid(self):
    89     def _set_gid(self):
    87         """Sets the ID of the domain - if not set yet."""
    90         """Sets the ID of the domain - if not set yet."""
    88         assert self._gid == 0
    91         assert self._gid == 0
   125                          NO_SUCH_DOMAIN)
   128                          NO_SUCH_DOMAIN)
   126         elif not must_exist and not self._new:
   129         elif not must_exist and not self._new:
   127             raise DomErr(_(u"The domain '%s' already exists.") % self._name,
   130             raise DomErr(_(u"The domain '%s' already exists.") % self._name,
   128                          DOMAIN_EXISTS)
   131                          DOMAIN_EXISTS)
   129 
   132 
   130     def _update_tables(self, column, value, force=False):
   133     def _update_tables(self, column, value):
       
   134         """Update table columns in the domain_data table."""
       
   135         dbc = self._dbh.cursor()
       
   136         dbc.execute('UPDATE domain_data SET %s = %%s WHERE gid = %%s' % column,
       
   137                     (value, self._gid))
       
   138         if dbc.rowcount > 0:
       
   139             self._dbh.commit()
       
   140         dbc.close()
       
   141 
       
   142     def _update_tables_ref(self, column, value, force=False):
   131         """Update various columns in the domain_data table. When *force* is
   143         """Update various columns in the domain_data table. When *force* is
   132         `True`, the corresponding column in the users table will be reset to
   144         `True`, the corresponding column in the users table will be reset to
   133         NULL.
   145         NULL.
   134 
   146 
   135         Arguments:
   147         Arguments:
   141         `force` : bool
   153         `force` : bool
   142           reset existing users. Default: `False`
   154           reset existing users. Default: `False`
   143         """
   155         """
   144         if column not in ('qid', 'ssid', 'tid'):
   156         if column not in ('qid', 'ssid', 'tid'):
   145             raise ValueError('Unknown column: %r' % column)
   157             raise ValueError('Unknown column: %r' % column)
   146         dbc = self._dbh.cursor()
   158         self._update_tables(column, value)
   147         dbc.execute('UPDATE domain_data SET %s = %%s WHERE gid = %%s' % column,
       
   148                     (value, self._gid))
       
   149         if dbc.rowcount > 0:
       
   150             self._dbh.commit()
       
   151         if force:
   159         if force:
       
   160             dbc = self._dbh.cursor()
   152             dbc.execute('UPDATE users SET %s = NULL WHERE gid = %%s' % column,
   161             dbc.execute('UPDATE users SET %s = NULL WHERE gid = %%s' % column,
   153                         (self._gid,))
   162                         (self._gid,))
   154             if dbc.rowcount > 0:
   163             if dbc.rowcount > 0:
   155                 self._dbh.commit()
   164                 self._dbh.commit()
   156         dbc.close()
   165             dbc.close()
   157 
   166 
   158     @property
   167     @property
   159     def gid(self):
   168     def gid(self):
   160         """The GID of the Domain."""
   169         """The GID of the Domain."""
   161         return self._gid
   170         return self._gid
   182 
   191 
   183     @property
   192     @property
   184     def transport(self):
   193     def transport(self):
   185         """The Domain's transport."""
   194         """The Domain's transport."""
   186         return self._transport
   195         return self._transport
       
   196 
       
   197     @property
       
   198     def note(self):
       
   199         """The Domain's note."""
       
   200         return self._note
   187 
   201 
   188     def set_directory(self, basedir):
   202     def set_directory(self, basedir):
   189         """Set the path value of the Domain's directory, inside *basedir*.
   203         """Set the path value of the Domain's directory, inside *basedir*.
   190 
   204 
   191         Argument:
   205         Argument:
   233         """
   247         """
   234         self._chk_state(False)
   248         self._chk_state(False)
   235         assert isinstance(transport, Transport)
   249         assert isinstance(transport, Transport)
   236         self._transport = transport
   250         self._transport = transport
   237 
   251 
       
   252     def set_note(self, note):
       
   253         """Set the domain's (optional) note.
       
   254 
       
   255         Argument:
       
   256 
       
   257         `note` : basestring or None
       
   258           The note, or None to remove
       
   259         """
       
   260         self._chk_state(False)
       
   261         assert note is None or isinstance(note, basestring)
       
   262         self._note = note
       
   263 
   238     def save(self):
   264     def save(self):
   239         """Stores the new domain in the database."""
   265         """Stores the new domain in the database."""
   240         self._chk_state(False)
   266         self._chk_state(False)
   241         assert all((self._directory, self._qlimit, self._services,
   267         assert all((self._directory, self._qlimit, self._services,
   242                     self._transport))
   268                     self._transport))
   243         dbc = self._dbh.cursor()
   269         dbc = self._dbh.cursor()
   244         dbc.execute('INSERT INTO domain_data (gid, qid, ssid, tid, domaindir) '
   270         dbc.execute('INSERT INTO domain_data (gid, qid, ssid, tid, domaindir, '
   245                     'VALUES (%s, %s, %s, %s, %s)', (self._gid,
   271                     'note) '
       
   272                     'VALUES (%s, %s, %s, %s, %s, %s)', (self._gid,
   246                     self._qlimit.qid, self._services.ssid, self._transport.tid,
   273                     self._qlimit.qid, self._services.ssid, self._transport.tid,
   247                     self._directory))
   274                     self._directory, self._note))
   248         dbc.execute('INSERT INTO domain_name (domainname, gid, is_primary) '
   275         dbc.execute('INSERT INTO domain_name (domainname, gid, is_primary) '
   249                     'VALUES (%s, %s, TRUE)', (self._name, self._gid))
   276                     'VALUES (%s, %s, TRUE)', (self._name, self._gid))
   250         self._dbh.commit()
   277         self._dbh.commit()
   251         dbc.close()
   278         dbc.close()
   252         self._new = False
   279         self._new = False
   297                              u'Dovecot >= v1.1.2.'), VMM_ERROR)
   324                              u'Dovecot >= v1.1.2.'), VMM_ERROR)
   298         self._chk_state()
   325         self._chk_state()
   299         assert isinstance(quotalimit, QuotaLimit)
   326         assert isinstance(quotalimit, QuotaLimit)
   300         if not force and quotalimit == self._qlimit:
   327         if not force and quotalimit == self._qlimit:
   301             return
   328             return
   302         self._update_tables('qid', quotalimit.qid, force)
   329         self._update_tables_ref('qid', quotalimit.qid, force)
   303         self._qlimit = quotalimit
   330         self._qlimit = quotalimit
   304 
   331 
   305     def update_serviceset(self, serviceset, force=False):
   332     def update_serviceset(self, serviceset, force=False):
   306         """Assign a different set of services to the Domain,
   333         """Assign a different set of services to the Domain,
   307 
   334 
   317         """
   344         """
   318         self._chk_state()
   345         self._chk_state()
   319         assert isinstance(serviceset, ServiceSet)
   346         assert isinstance(serviceset, ServiceSet)
   320         if not force and serviceset == self._services:
   347         if not force and serviceset == self._services:
   321             return
   348             return
   322         self._update_tables('ssid', serviceset.ssid, force)
   349         self._update_tables_ref('ssid', serviceset.ssid, force)
   323         self._services = serviceset
   350         self._services = serviceset
   324 
   351 
   325     def update_transport(self, transport, force=False):
   352     def update_transport(self, transport, force=False):
   326         """Sets a new transport for the Domain.
   353         """Sets a new transport for the Domain.
   327 
   354 
   338         """
   365         """
   339         self._chk_state()
   366         self._chk_state()
   340         assert isinstance(transport, Transport)
   367         assert isinstance(transport, Transport)
   341         if not force and transport == self._transport:
   368         if not force and transport == self._transport:
   342             return
   369             return
   343         self._update_tables('tid', transport.tid, force)
   370         self._update_tables_ref('tid', transport.tid, force)
   344         self._transport = transport
   371         self._transport = transport
       
   372 
       
   373     def update_note(self, note):
       
   374         """Sets a new note for the Domain.
       
   375 
       
   376         Arguments:
       
   377 
       
   378         `transport` : basestring or None
       
   379           the new note
       
   380         """
       
   381         self._chk_state()
       
   382         assert note is None or isinstance(note, basestring)
       
   383         if note == self._note:
       
   384             return
       
   385         self._update_tables('note', note)
       
   386         self._note = note
   345 
   387 
   346     def get_info(self):
   388     def get_info(self):
   347         """Returns a dictionary with information about the domain."""
   389         """Returns a dictionary with information about the domain."""
   348         self._chk_state()
   390         self._chk_state()
   349         dbc = self._dbh.cursor()
   391         dbc = self._dbh.cursor()
   366         if services:
   408         if services:
   367             services.sort()
   409             services.sort()
   368         else:
   410         else:
   369             services.append('None')
   411             services.append('None')
   370         info['active services'] = ' '.join(services)
   412         info['active services'] = ' '.join(services)
       
   413         info['note'] = self._note
   371         return info
   414         return info
   372 
   415 
   373     def get_accounts(self):
   416     def get_accounts(self):
   374         """Returns a list with all accounts of the domain."""
   417         """Returns a list with all accounts of the domain."""
   375         self._chk_state()
   418         self._chk_state()