VirtualMailManager/common.py
branchv0.6.x
changeset 555 499c63f52462
parent 546 79f09cdd1a21
child 568 14abdd04ddf5
equal deleted inserted replaced
554:a93671970617 555:499c63f52462
    12 import os
    12 import os
    13 import re
    13 import re
    14 import stat
    14 import stat
    15 
    15 
    16 from VirtualMailManager import ENCODING
    16 from VirtualMailManager import ENCODING
    17 from VirtualMailManager.constants import NOT_EXECUTABLE, NO_SUCH_BINARY
    17 from VirtualMailManager.constants import NOT_EXECUTABLE, NO_SUCH_BINARY, \
       
    18      TYPE_ACCOUNT, TYPE_ALIAS, TYPE_RELOCATED
    18 from VirtualMailManager.errors import VMMError
    19 from VirtualMailManager.errors import VMMError
    19 
       
    20 
    20 
    21 VERSION_RE = re.compile(r'^(\d+)\.(\d+)\.(?:(\d+)|(alpha|beta|rc)(\d+))$')
    21 VERSION_RE = re.compile(r'^(\d+)\.(\d+)\.(?:(\d+)|(alpha|beta|rc)(\d+))$')
    22 
    22 
    23 _version_level = dict(alpha=0xA, beta=0xB, rc=0xC)
    23 _version_level = dict(alpha=0xA, beta=0xB, rc=0xC)
    24 _version_cache = {}
    24 _version_cache = {}
   188 
   188 
   189 def format_domain_default(domaindata):
   189 def format_domain_default(domaindata):
   190     """Format info output when the value displayed is the domain default."""
   190     """Format info output when the value displayed is the domain default."""
   191     return _(u'%s [domain default]') % domaindata
   191     return _(u'%s [domain default]') % domaindata
   192 
   192 
       
   193 
       
   194 def search_addresses(dbh, typelimit=None, lpattern=None, llike=False,
       
   195                      dpattern=None, dlike=False):
       
   196     """'Search' for addresses by *pattern* in the database.
       
   197 
       
   198     The search is limited by *typelimit*, a bitfield with values TYPE_ACCOUNT,
       
   199     TYPE_ALIAS, TYPE_RELOCATED, or a bitwise OR thereof. If no limit is
       
   200     specified, all types will be searched.
       
   201 
       
   202     *lpattern* may be a local part or a partial local part - starting and/or
       
   203     ending with a '%' sign.  When the *lpattern* starts or ends with a '%' sign
       
   204     *llike* has to be `True` to perform a wildcard search. To retrieve all
       
   205     available addresses use the arguments' default values.
       
   206 
       
   207     *dpattern* and *dlike* behave analogously for the domain part of an
       
   208     address, allowing for separate pattern matching: testuser%@example.%
       
   209 
       
   210     The return value of this function is a tuple. The first element is a list
       
   211     of domain IDs sorted alphabetically by the corresponding domain names. The
       
   212     second element is a dictionary indexed by domain ID, holding lists to
       
   213     associated addresses. Each address is itself actually a tuple of address,
       
   214     type, and boolean indicating whether the address stems from an alias
       
   215     domain.
       
   216     """
       
   217     if typelimit == None:
       
   218             typelimit = TYPE_ACCOUNT | TYPE_ALIAS | TYPE_RELOCATED
       
   219     queries = []
       
   220     if typelimit & TYPE_ACCOUNT:
       
   221         queries.append('SELECT gid, local_part, %d AS type FROM users'
       
   222                        % TYPE_ACCOUNT)
       
   223     if typelimit & TYPE_ALIAS:
       
   224         queries.append('SELECT gid, address as local_part, %d AS type '
       
   225                        'FROM alias' % TYPE_ALIAS)
       
   226     if typelimit & TYPE_RELOCATED:
       
   227         queries.append('SELECT gid, address as local_part, %d AS type '
       
   228                        'FROM relocated' % TYPE_RELOCATED)
       
   229     sql  = "SELECT gid, local_part || '@' || domainname AS address, "
       
   230     sql += 'type, NOT is_primary AS from_aliasdomain FROM ('
       
   231     sql += ' UNION '.join(queries)
       
   232     sql += ') a JOIN domain_name USING (gid)'
       
   233     nextkw = 'WHERE'
       
   234     sqlargs = []
       
   235     for like, field, pattern in ((dlike, 'domainname', dpattern),
       
   236                                  (llike, 'local_part', lpattern)):
       
   237         if like:
       
   238             match = 'LIKE'
       
   239         else:
       
   240             if not pattern: continue
       
   241             match = '='
       
   242         sql += ' %s %s %s %%s' % (nextkw, field, match)
       
   243         sqlargs.append(pattern)
       
   244         nextkw = 'AND'
       
   245     sql += ' ORDER BY domainname, local_part'
       
   246     dbc = dbh.cursor()
       
   247     dbc.execute(sql, sqlargs)
       
   248     result = dbc.fetchall()
       
   249     dbc.close()
       
   250 
       
   251     gids = []
       
   252     daddrs = {}
       
   253     lastgid = None
       
   254     for gid, address, addrtype, aliasdomain in result:
       
   255         if gid != lastgid:
       
   256             gids.append(gid)
       
   257             lastgid = gid
       
   258             daddrs[gid] = []
       
   259         daddrs[gid].append((address, addrtype, aliasdomain))
       
   260     return gids, daddrs
       
   261 
   193 del _
   262 del _