VirtualMailManager/common.py
branchv0.6.x
changeset 266 e14c345b44a1
parent 265 3c0173418d5d
child 273 77fc7138ef6a
equal deleted inserted replaced
265:3c0173418d5d 266:e14c345b44a1
    16      NOT_EXECUTABLE, NO_SUCH_BINARY, NO_SUCH_DIRECTORY
    16      NOT_EXECUTABLE, NO_SUCH_BINARY, NO_SUCH_DIRECTORY
    17 from VirtualMailManager.errors import VMMError
    17 from VirtualMailManager.errors import VMMError
    18 
    18 
    19 
    19 
    20 _version_re = re.compile(r'^(\d+)\.(\d+)\.(?:(\d+)|(alpha|beta|rc)(\d+))$')
    20 _version_re = re.compile(r'^(\d+)\.(\d+)\.(?:(\d+)|(alpha|beta|rc)(\d+))$')
       
    21 _version_level = dict(alpha=0xA, beta=0xB, rc=0xC)
    21 _ = lambda msg: msg
    22 _ = lambda msg: msg
    22 
    23 
    23 
    24 
    24 def expand_path(path):
    25 def expand_path(path):
    25     """Expands paths, starting with ``.`` or ``~``, to an absolute path."""
    26     """Expands paths, starting with ``.`` or ``~``, to an absolute path."""
    64                        get_unicode(binary), NOT_EXECUTABLE)
    65                        get_unicode(binary), NOT_EXECUTABLE)
    65     return binary
    66     return binary
    66 
    67 
    67 
    68 
    68 def version_hex(version_string):
    69 def version_hex(version_string):
    69     """Convert a Dovecot version, e.g.: '1.2.3' or '2.0.beta4', to an int.
    70     """Converts a Dovecot version, e.g.: '1.2.3' or '2.0.beta4', to an int.
    70     Raises a `ValueError` if the *version_string* has the wrong™ format.
    71     Raises a `ValueError` if the *version_string* has the wrong™ format.
    71 
    72 
    72     version_hex('1.2.3') -> 16909296
    73     version_hex('1.2.3') -> 270548736
    73     hex(version_hex('1.2.3')) -> '0x10203f0'
    74     hex(version_hex('1.2.3')) -> '0x10203f00'
    74     """
    75     """
    75     version = 0
    76     version = 0
    76     version_level = dict(alpha=0xA, beta=0xB, rc=0xC)
       
    77     version_mo = _version_re.match(version_string)
    77     version_mo = _version_re.match(version_string)
    78     if not version_mo:
    78     if not version_mo:
    79         raise ValueError('Invalid version string: %r' % version_string)
    79         raise ValueError('Invalid version string: %r' % version_string)
    80     major, minor, patch, level, serial = version_mo.groups()
    80     major, minor, patch, level, serial = version_mo.groups()
    81     version += int(major) << 24
    81     major = int(major)
    82     version += int(minor) << 16
    82     minor = int(minor)
    83     if patch:
    83     if patch:
    84         version += int(patch) << 8
    84         patch = int(patch)
    85     version += version_level.get(level, 0xF) << 4
       
    86     if serial:
    85     if serial:
    87         version += int(serial)
    86         serial = int(serial)
       
    87 
       
    88     if major > 0xFF or minor > 0xFF or \
       
    89       patch and patch > 0xFF or serial and serial > 0xFF:
       
    90         raise ValueError('Invalid version string: %r' % version_string)
       
    91 
       
    92     version += major << 28
       
    93     version += minor << 20
       
    94     if patch:
       
    95         version += patch << 12
       
    96     version += _version_level.get(level, 0xF) << 8
       
    97     if serial:
       
    98         version += serial
       
    99 
    88     return version
   100     return version
    89 
   101 
       
   102 
       
   103 def version_str(version):
       
   104     """Converts a Dovecot version previously converted with version_hex back to
       
   105     a string.
       
   106     Raises a `TypeError` if *version* is not an int/long.
       
   107     Raises a `ValueError` if *version* is an incorrect int version.
       
   108     """
       
   109     if not isinstance(version, (int, long)):
       
   110         raise TypeError('Argument is not a int/long: %r', version)
       
   111     major = (version >> 28) & 0xFF
       
   112     minor = (version >> 20) & 0xFF
       
   113     patch = (version >> 12) & 0xFF
       
   114     level = (version >> 8) & 0x0F
       
   115     serial = version & 0xFF
       
   116 
       
   117     levels = dict(zip(_version_level.values(), _version_level.keys()))
       
   118     if level == 0xF and not serial:
       
   119         version_string = '%u.%u.%u' % (major, minor, patch)
       
   120     elif level in levels and not patch:
       
   121         version_string = '%u.%u.%s%u' % (major, minor, levels[level], serial)
       
   122     else:
       
   123         raise ValueError('Invalid version: %r' % hex(version))
       
   124 
       
   125     return version_string
       
   126 
    90 del _
   127 del _