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