VMM/{Account,common,Handler}: Improved version_hex(). v0.6.x
authorTobias Berling <t-obi@users.sourceforge.net>
Tue, 27 Apr 2010 22:49:46 +0000
branchv0.6.x
changeset 266 e14c345b44a1
parent 265 3c0173418d5d
child 267 084300a00ee1
VMM/{Account,common,Handler}: Improved version_hex(). - common: version_hex() now supports 'serials' > 16. Added version_str() as counterpart to version_hex(). - Account, Handler: updated hardcoded Dovecot versions.
VirtualMailManager/Account.py
VirtualMailManager/Handler.py
VirtualMailManager/common.py
--- a/VirtualMailManager/Account.py	Mon Apr 26 02:15:36 2010 +0000
+++ b/VirtualMailManager/Account.py	Tue Apr 27 22:49:46 2010 +0000
@@ -94,7 +94,7 @@
         self._chk_state()
         if service not in (None, 'all', 'imap', 'pop3', 'sieve', 'smtp'):
             raise AErr(_(u"Unknown service: '%s'.") % service, UNKNOWN_SERVICE)
-        if dcvers >= 0x10200b2:
+        if dcvers >= 0x10200b02:
             sieve_col = 'sieve'
         else:
             sieve_col = 'managesieve'
@@ -230,7 +230,7 @@
                        ACCOUNT_MISSING_PASSWORD)
         assert all(isinstance(service, bool) for service in (smtp, pop3, imap,
                                                              sieve))
-        if dcvers >= 0x10200b2:
+        if dcvers >= 0x10200b02:
             sieve_col = 'sieve'
         else:
             sieve_col = 'managesieve'
@@ -291,7 +291,7 @@
           `dovecot --version`.
         """
         self._chk_state()
-        if dcvers >= 0x10200b2:
+        if dcvers >= 0x10200b02:
             sieve_col = 'sieve'
         else:
             sieve_col = 'managesieve'
--- a/VirtualMailManager/Handler.py	Mon Apr 26 02:15:36 2010 +0000
+++ b/VirtualMailManager/Handler.py	Tue Apr 27 22:49:46 2010 +0000
@@ -381,7 +381,7 @@
                 'LANMAN', 'NTLM', 'RPA']:
             cmd_args = [self._Cfg.dget('bin.dovecotpw'), '-s', self._scheme,
                         '-p', password]
-            if self._Cfg.dget('misc.dovecot_version') >= 0x20000a1:
+            if self._Cfg.dget('misc.dovecot_version') >= 0x20000a01:
                 cmd_args.insert(1, 'pw')
             return Popen(cmd_args, stdout=PIPE).communicate()[0][:-1]
         else:
--- a/VirtualMailManager/common.py	Mon Apr 26 02:15:36 2010 +0000
+++ b/VirtualMailManager/common.py	Tue Apr 27 22:49:46 2010 +0000
@@ -18,6 +18,7 @@
 
 
 _version_re = re.compile(r'^(\d+)\.(\d+)\.(?:(\d+)|(alpha|beta|rc)(\d+))$')
+_version_level = dict(alpha=0xA, beta=0xB, rc=0xC)
 _ = lambda msg: msg
 
 
@@ -66,25 +67,61 @@
 
 
 def version_hex(version_string):
-    """Convert a Dovecot version, e.g.: '1.2.3' or '2.0.beta4', to an int.
+    """Converts a Dovecot version, e.g.: '1.2.3' or '2.0.beta4', to an int.
     Raises a `ValueError` if the *version_string* has the wrong™ format.
 
-    version_hex('1.2.3') -> 16909296
-    hex(version_hex('1.2.3')) -> '0x10203f0'
+    version_hex('1.2.3') -> 270548736
+    hex(version_hex('1.2.3')) -> '0x10203f00'
     """
     version = 0
-    version_level = dict(alpha=0xA, beta=0xB, rc=0xC)
     version_mo = _version_re.match(version_string)
     if not version_mo:
         raise ValueError('Invalid version string: %r' % version_string)
     major, minor, patch, level, serial = version_mo.groups()
-    version += int(major) << 24
-    version += int(minor) << 16
+    major = int(major)
+    minor = int(minor)
     if patch:
-        version += int(patch) << 8
-    version += version_level.get(level, 0xF) << 4
+        patch = int(patch)
     if serial:
-        version += int(serial)
+        serial = int(serial)
+
+    if major > 0xFF or minor > 0xFF or \
+      patch and patch > 0xFF or serial and serial > 0xFF:
+        raise ValueError('Invalid version string: %r' % version_string)
+
+    version += major << 28
+    version += minor << 20
+    if patch:
+        version += patch << 12
+    version += _version_level.get(level, 0xF) << 8
+    if serial:
+        version += serial
+
     return version
 
+
+def version_str(version):
+    """Converts a Dovecot version previously converted with version_hex back to
+    a string.
+    Raises a `TypeError` if *version* is not an int/long.
+    Raises a `ValueError` if *version* is an incorrect int version.
+    """
+    if not isinstance(version, (int, long)):
+        raise TypeError('Argument is not a int/long: %r', version)
+    major = (version >> 28) & 0xFF
+    minor = (version >> 20) & 0xFF
+    patch = (version >> 12) & 0xFF
+    level = (version >> 8) & 0x0F
+    serial = version & 0xFF
+
+    levels = dict(zip(_version_level.values(), _version_level.keys()))
+    if level == 0xF and not serial:
+        version_string = '%u.%u.%u' % (major, minor, patch)
+    elif level in levels and not patch:
+        version_string = '%u.%u.%s%u' % (major, minor, levels[level], serial)
+    else:
+        raise ValueError('Invalid version: %r' % hex(version))
+
+    return version_string
+
 del _