VirtualMailManager/quotalimit.py
branchv0.6.x
changeset 385 0cae9989395b
child 400 0512d940918f
equal deleted inserted replaced
384:d3a97f7fb98a 385:0cae9989395b
       
     1 # -*- coding: UTF-8 -*-
       
     2 # Copyright (c) 2011, Pascal Volk
       
     3 # See COPYING for distribution information.
       
     4 """
       
     5     VirtualMailManager.quotalimit
       
     6     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
       
     7 
       
     8     Virtual Mail Manager's QuotaLimit class to manage quota limits
       
     9     for domains and accounts.
       
    10 """
       
    11 
       
    12 from VirtualMailManager.constants import VMM_ERROR
       
    13 from VirtualMailManager.errors import VMMError
       
    14 from VirtualMailManager.pycompat import all
       
    15 
       
    16 _ = lambda msg: msg
       
    17 
       
    18 
       
    19 class QuotaLimit(object):
       
    20     """Class to handle quota limit specific data."""
       
    21     __slots__ = ('_dbh', '_qid', '_bytes', '_messages')
       
    22     _kwargs = ('qid', 'bytes', 'messages')
       
    23 
       
    24     def __init__(self, dbh, **kwargs):
       
    25         """Create a new QuotaLimit instance.
       
    26 
       
    27         Either the `qid` keyword or the `bytes` and `messages` keywords
       
    28         must be specified.
       
    29 
       
    30         Arguments:
       
    31 
       
    32         `dbh` : pyPgSQL.PgSQL.Connection || psycopg2._psycopg.connection
       
    33           A database connection for the database access.
       
    34 
       
    35         Keyword arguments:
       
    36 
       
    37         `qid` : int
       
    38           The id of a quota limit
       
    39         `bytes` : long
       
    40           The quota limit in bytes.
       
    41         `messages` : int
       
    42           The quota limit in number of messages
       
    43         """
       
    44         self._dbh = dbh
       
    45         self._qid = 0
       
    46         self._bytes = 0
       
    47         self._messages = 0
       
    48 
       
    49         for key in kwargs.iterkeys():
       
    50             if key not in self.__class__._kwargs:
       
    51                 raise ValueError('unrecognized keyword: %r' % key)
       
    52         qid = kwargs.get('qid')
       
    53         if qid is not None:
       
    54             assert isinstance(qid, (int, long))
       
    55             self._load_by_qid(qid)
       
    56         else:
       
    57             bytes_, msgs = kwargs.get('bytes'), kwargs.get('messages')
       
    58             assert all(isinstance(i, (int, long)) for i in (bytes_, msgs))
       
    59             if bytes_ < 0:
       
    60                 self._bytes = -bytes_
       
    61             else:
       
    62                 self._bytes = bytes_
       
    63             if msgs < 0:
       
    64                 self._messages = -msgs
       
    65             else:
       
    66                 self._messages = msgs
       
    67             self._load_by_limit()
       
    68 
       
    69     @property
       
    70     def bytes(self):
       
    71         """Quota limit in bytes."""
       
    72         return self._bytes
       
    73 
       
    74     @property
       
    75     def messages(self):
       
    76         """Quota limit in number of messages."""
       
    77         return self._messages
       
    78 
       
    79     @property
       
    80     def qid(self):
       
    81         """The quota limit's unique ID."""
       
    82         return self._qid
       
    83 
       
    84     def __eq__(self, other):
       
    85         if isinstance(other, self.__class__):
       
    86             return self._qid == other._qid
       
    87         return NotImplemented
       
    88 
       
    89     def __ne__(self, other):
       
    90         if isinstance(other, self.__class__):
       
    91             return self._qid != other._qid
       
    92         return NotImplemented
       
    93 
       
    94     def _load_by_limit(self):
       
    95         """Load the quota limit by limit values from the database."""
       
    96         dbc = self._dbh.cursor()
       
    97         dbc.execute('SELECT qid FROM quotalimit WHERE bytes = %s AND '
       
    98                     'messages = %s', (self._bytes, self._messages))
       
    99         res = dbc.fetchone()
       
   100         dbc.close()
       
   101         if res:
       
   102             self._qid = res[0]
       
   103         else:
       
   104             self._save()
       
   105 
       
   106     def _load_by_qid(self, qid):
       
   107         """Load the quota limit by its unique ID from the database."""
       
   108         dbc = self._dbh.cursor()
       
   109         dbc.execute('SELECT bytes, messages FROM quotalimit WHERE qid = %s',
       
   110                     (qid,))
       
   111         res = dbc.fetchone()
       
   112         dbc.close()
       
   113         if not res:
       
   114             raise VMMError(_(u'Unknown quota limit id specified.'), VMM_ERROR)
       
   115         self._qid = qid
       
   116         self._bytes, self._messages = res
       
   117 
       
   118     def _save(self):
       
   119         """Store a new quota limit in the database."""
       
   120         dbc = self._dbh.cursor()
       
   121         dbc.execute("SELECT nextval('quotalimit_id')")
       
   122         self._qid = dbc.fetchone()[0]
       
   123         dbc.execute('INSERT INTO quotalimit (qid, bytes, messages) VALUES '
       
   124                     '(%s, %s, %s)', (self._qid, self._bytes, self._messages))
       
   125         self._dbh.commit()
       
   126         dbc.close()
       
   127 
       
   128 del _