VirtualMailManager/common.py
author Pascal Volk <neverseen@users.sourceforge.net>
Sat, 12 Feb 2011 17:19:43 +0000
branchv0.6.x
changeset 399 fb22773f7a85
parent 396 7f931c1ca059
child 414 ae1a8428298c
permissions -rw-r--r--
VMM/common: Reworked human_size() once more. Return bytes w/o prefix. Use translatable $FOO_bibyte prefixes, e.g., MiB.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
262
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
     1
# -*- coding: UTF-8 -*-
366
d6573da35b5f Updated copyright notices to include the year 2011.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 350
diff changeset
     2
# Copyright (c) 2010 - 2011, Pascal Volk
262
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
     3
# See COPYING for distribution information.
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
     4
"""
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
     5
    VirtualMailManager.common
320
011066435e6f VMM/*: Made all modules names lowercase, adjusted imports.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 316
diff changeset
     6
    ~~~~~~~~~~~~~~~~~~~~~~~~~
262
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
     7
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
     8
    Some common functions
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
     9
"""
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    10
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    11
import os
263
07fdc93dde9f VMM/common: improved version_hex() in order to convert also
Pascal Volk <neverseen@users.sourceforge.net>
parents: 262
diff changeset
    12
import re
326
8f8d9c4c8332 VMM/common: Replaced function is_dir() by lisdir().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 320
diff changeset
    13
import stat
262
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    14
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    15
from VirtualMailManager import ENCODING
328
85972d3ba936 VMM/common: Removed unused import.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 326
diff changeset
    16
from VirtualMailManager.constants import NOT_EXECUTABLE, NO_SUCH_BINARY
262
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    17
from VirtualMailManager.errors import VMMError
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    18
265
3c0173418d5d VMM/{Account,common,maillocation}: Dovecot version (check) fixes.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 263
diff changeset
    19
347
586367ee042b VMM/common: Made the version re pattern object accessible as VERSION_RE.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 328
diff changeset
    20
VERSION_RE = re.compile(r'^(\d+)\.(\d+)\.(?:(\d+)|(alpha|beta|rc)(\d+))$')
586367ee042b VMM/common: Made the version re pattern object accessible as VERSION_RE.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 328
diff changeset
    21
266
e14c345b44a1 VMM/{Account,common,Handler}: Improved version_hex().
Tobias Berling <t-obi@users.sourceforge.net>
parents: 265
diff changeset
    22
_version_level = dict(alpha=0xA, beta=0xB, rc=0xC)
273
77fc7138ef6a VMM/common: added a caching dict for version_hex()/version_str()
Pascal Volk <neverseen@users.sourceforge.net>
parents: 266
diff changeset
    23
_version_cache = {}
262
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    24
_ = lambda msg: msg
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    25
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    26
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    27
def expand_path(path):
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    28
    """Expands paths, starting with ``.`` or ``~``, to an absolute path."""
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    29
    if path.startswith('.'):
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    30
        return os.path.abspath(path)
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    31
    if path.startswith('~'):
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    32
        return os.path.expanduser(path)
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    33
    return path
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    34
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    35
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    36
def get_unicode(string):
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    37
    """Converts `string` to `unicode`, if necessary."""
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    38
    if isinstance(string, unicode):
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    39
        return string
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    40
    return unicode(string, ENCODING, 'replace')
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    41
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    42
326
8f8d9c4c8332 VMM/common: Replaced function is_dir() by lisdir().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 320
diff changeset
    43
def lisdir(path):
8f8d9c4c8332 VMM/common: Replaced function is_dir() by lisdir().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 320
diff changeset
    44
    """Checks if `path` is a directory.  Doesn't follow symbolic links.
8f8d9c4c8332 VMM/common: Replaced function is_dir() by lisdir().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 320
diff changeset
    45
    Returns bool.
262
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    46
    """
326
8f8d9c4c8332 VMM/common: Replaced function is_dir() by lisdir().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 320
diff changeset
    47
    try:
8f8d9c4c8332 VMM/common: Replaced function is_dir() by lisdir().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 320
diff changeset
    48
        lstat = os.lstat(path)
8f8d9c4c8332 VMM/common: Replaced function is_dir() by lisdir().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 320
diff changeset
    49
    except OSError:
8f8d9c4c8332 VMM/common: Replaced function is_dir() by lisdir().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 320
diff changeset
    50
        return False
8f8d9c4c8332 VMM/common: Replaced function is_dir() by lisdir().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 320
diff changeset
    51
    return stat.S_ISDIR(lstat.st_mode)
262
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    52
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    53
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    54
def exec_ok(binary):
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    55
    """Checks if the `binary` exists and if it is executable.
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    56
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    57
    Throws a `VMMError` if the `binary` isn't a file or is not
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    58
    executable.
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    59
    """
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    60
    binary = expand_path(binary)
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    61
    if not os.path.isfile(binary):
350
b7a4d7828608 VMM/common: Reformulated error message in exec_ok.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 347
diff changeset
    62
        raise VMMError(_(u"No such file: '%s'") % get_unicode(binary),
262
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    63
                       NO_SUCH_BINARY)
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    64
    if not os.access(binary, os.X_OK):
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    65
        raise VMMError(_(u"File is not executable: '%s'") %
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    66
                       get_unicode(binary), NOT_EXECUTABLE)
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    67
    return binary
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    68
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
    69
393
fb2ba1456bc5 VMM/common: Added function human_size().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 383
diff changeset
    70
def human_size(size):
fb2ba1456bc5 VMM/common: Added function human_size().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 383
diff changeset
    71
    """Converts the `size` in bytes in human readable format."""
396
7f931c1ca059 VMM/common: human_size() size argument can be also a string.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 395
diff changeset
    72
    if not isinstance(size, (long, int)):
7f931c1ca059 VMM/common: human_size() size argument can be also a string.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 395
diff changeset
    73
        try:
7f931c1ca059 VMM/common: human_size() size argument can be also a string.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 395
diff changeset
    74
            size = long(size)
7f931c1ca059 VMM/common: human_size() size argument can be also a string.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 395
diff changeset
    75
        except ValueError:
7f931c1ca059 VMM/common: human_size() size argument can be also a string.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 395
diff changeset
    76
            raise TypeError("'size' must be a positive long or int.")
7f931c1ca059 VMM/common: human_size() size argument can be also a string.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 395
diff changeset
    77
    if size < 0:
7f931c1ca059 VMM/common: human_size() size argument can be also a string.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 395
diff changeset
    78
        raise ValueError("'size' must be a positive long or int.")
399
fb22773f7a85 VMM/common: Reworked human_size() once more. Return bytes w/o
Pascal Volk <neverseen@users.sourceforge.net>
parents: 396
diff changeset
    79
    if size < 1024:
fb22773f7a85 VMM/common: Reworked human_size() once more. Return bytes w/o
Pascal Volk <neverseen@users.sourceforge.net>
parents: 396
diff changeset
    80
        return str(size)
fb22773f7a85 VMM/common: Reworked human_size() once more. Return bytes w/o
Pascal Volk <neverseen@users.sourceforge.net>
parents: 396
diff changeset
    81
    prefix_multiply = ((_(u'TiB'), 1 << 40), (_(u'GiB'), 1 << 30),
fb22773f7a85 VMM/common: Reworked human_size() once more. Return bytes w/o
Pascal Volk <neverseen@users.sourceforge.net>
parents: 396
diff changeset
    82
                       (_(u'MiB'), 1 << 20), (_(u'KiB'), 1 << 10))
fb22773f7a85 VMM/common: Reworked human_size() once more. Return bytes w/o
Pascal Volk <neverseen@users.sourceforge.net>
parents: 396
diff changeset
    83
    for prefix, multiply in prefix_multiply:
fb22773f7a85 VMM/common: Reworked human_size() once more. Return bytes w/o
Pascal Volk <neverseen@users.sourceforge.net>
parents: 396
diff changeset
    84
        if size >= multiply:
fb22773f7a85 VMM/common: Reworked human_size() once more. Return bytes w/o
Pascal Volk <neverseen@users.sourceforge.net>
parents: 396
diff changeset
    85
            # TP: e.g.: '%(size).2f %(prefix)s' -> '118.30 MiB'
fb22773f7a85 VMM/common: Reworked human_size() once more. Return bytes w/o
Pascal Volk <neverseen@users.sourceforge.net>
parents: 396
diff changeset
    86
            return _(u'%(size).2f %(prefix)s') % {
fb22773f7a85 VMM/common: Reworked human_size() once more. Return bytes w/o
Pascal Volk <neverseen@users.sourceforge.net>
parents: 396
diff changeset
    87
                    'size': float(size) / multiply,
fb22773f7a85 VMM/common: Reworked human_size() once more. Return bytes w/o
Pascal Volk <neverseen@users.sourceforge.net>
parents: 396
diff changeset
    88
                    'prefix': prefix}
393
fb2ba1456bc5 VMM/common: Added function human_size().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 383
diff changeset
    89
fb2ba1456bc5 VMM/common: Added function human_size().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 383
diff changeset
    90
383
ac5ac03b58da VMM/common: Added function size_in_bytes().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 366
diff changeset
    91
def size_in_bytes(size):
ac5ac03b58da VMM/common: Added function size_in_bytes().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 366
diff changeset
    92
    """Converts the string `size` to a long (size in bytes).
ac5ac03b58da VMM/common: Added function size_in_bytes().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 366
diff changeset
    93
ac5ac03b58da VMM/common: Added function size_in_bytes().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 366
diff changeset
    94
    The string `size` can be suffixed with *b* (bytes), *k* (kilobytes),
ac5ac03b58da VMM/common: Added function size_in_bytes().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 366
diff changeset
    95
    *M* (megabytes) or *G* (gigabytes).
ac5ac03b58da VMM/common: Added function size_in_bytes().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 366
diff changeset
    96
    """
ac5ac03b58da VMM/common: Added function size_in_bytes().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 366
diff changeset
    97
    if not isinstance(size, basestring) or not size:
ac5ac03b58da VMM/common: Added function size_in_bytes().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 366
diff changeset
    98
        raise TypeError('size must be a non empty string.')
ac5ac03b58da VMM/common: Added function size_in_bytes().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 366
diff changeset
    99
    if size[-1].upper() in ('B', 'K', 'M', 'G'):
ac5ac03b58da VMM/common: Added function size_in_bytes().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 366
diff changeset
   100
        try:
ac5ac03b58da VMM/common: Added function size_in_bytes().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 366
diff changeset
   101
            num = int(size[:-1])
ac5ac03b58da VMM/common: Added function size_in_bytes().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 366
diff changeset
   102
        except ValueError:
ac5ac03b58da VMM/common: Added function size_in_bytes().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 366
diff changeset
   103
            raise ValueError('Not a valid integer value: %r' % size[:-1])
ac5ac03b58da VMM/common: Added function size_in_bytes().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 366
diff changeset
   104
        unit = size[-1].upper()
ac5ac03b58da VMM/common: Added function size_in_bytes().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 366
diff changeset
   105
        if unit == 'B':
ac5ac03b58da VMM/common: Added function size_in_bytes().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 366
diff changeset
   106
            return num
ac5ac03b58da VMM/common: Added function size_in_bytes().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 366
diff changeset
   107
        elif unit == 'K':
ac5ac03b58da VMM/common: Added function size_in_bytes().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 366
diff changeset
   108
            return num << 10L
ac5ac03b58da VMM/common: Added function size_in_bytes().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 366
diff changeset
   109
        elif unit == 'M':
ac5ac03b58da VMM/common: Added function size_in_bytes().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 366
diff changeset
   110
            return num << 20L
ac5ac03b58da VMM/common: Added function size_in_bytes().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 366
diff changeset
   111
        else:
ac5ac03b58da VMM/common: Added function size_in_bytes().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 366
diff changeset
   112
            return num << 30L
ac5ac03b58da VMM/common: Added function size_in_bytes().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 366
diff changeset
   113
    else:
ac5ac03b58da VMM/common: Added function size_in_bytes().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 366
diff changeset
   114
        try:
ac5ac03b58da VMM/common: Added function size_in_bytes().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 366
diff changeset
   115
            num = int(size)
ac5ac03b58da VMM/common: Added function size_in_bytes().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 366
diff changeset
   116
        except ValueError:
ac5ac03b58da VMM/common: Added function size_in_bytes().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 366
diff changeset
   117
            raise ValueError('Not a valid size value: %r' % size)
ac5ac03b58da VMM/common: Added function size_in_bytes().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 366
diff changeset
   118
        return num
ac5ac03b58da VMM/common: Added function size_in_bytes().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 366
diff changeset
   119
ac5ac03b58da VMM/common: Added function size_in_bytes().
Pascal Volk <neverseen@users.sourceforge.net>
parents: 366
diff changeset
   120
262
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   121
def version_hex(version_string):
266
e14c345b44a1 VMM/{Account,common,Handler}: Improved version_hex().
Tobias Berling <t-obi@users.sourceforge.net>
parents: 265
diff changeset
   122
    """Converts a Dovecot version, e.g.: '1.2.3' or '2.0.beta4', to an int.
265
3c0173418d5d VMM/{Account,common,maillocation}: Dovecot version (check) fixes.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 263
diff changeset
   123
    Raises a `ValueError` if the *version_string* has the wrongâ„¢ format.
263
07fdc93dde9f VMM/common: improved version_hex() in order to convert also
Pascal Volk <neverseen@users.sourceforge.net>
parents: 262
diff changeset
   124
266
e14c345b44a1 VMM/{Account,common,Handler}: Improved version_hex().
Tobias Berling <t-obi@users.sourceforge.net>
parents: 265
diff changeset
   125
    version_hex('1.2.3') -> 270548736
e14c345b44a1 VMM/{Account,common,Handler}: Improved version_hex().
Tobias Berling <t-obi@users.sourceforge.net>
parents: 265
diff changeset
   126
    hex(version_hex('1.2.3')) -> '0x10203f00'
262
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   127
    """
347
586367ee042b VMM/common: Made the version re pattern object accessible as VERSION_RE.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 328
diff changeset
   128
    global _version_cache
273
77fc7138ef6a VMM/common: added a caching dict for version_hex()/version_str()
Pascal Volk <neverseen@users.sourceforge.net>
parents: 266
diff changeset
   129
    if version_string in _version_cache:
77fc7138ef6a VMM/common: added a caching dict for version_hex()/version_str()
Pascal Volk <neverseen@users.sourceforge.net>
parents: 266
diff changeset
   130
        return _version_cache[version_string]
263
07fdc93dde9f VMM/common: improved version_hex() in order to convert also
Pascal Volk <neverseen@users.sourceforge.net>
parents: 262
diff changeset
   131
    version = 0
347
586367ee042b VMM/common: Made the version re pattern object accessible as VERSION_RE.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 328
diff changeset
   132
    version_mo = VERSION_RE.match(version_string)
265
3c0173418d5d VMM/{Account,common,maillocation}: Dovecot version (check) fixes.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 263
diff changeset
   133
    if not version_mo:
3c0173418d5d VMM/{Account,common,maillocation}: Dovecot version (check) fixes.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 263
diff changeset
   134
        raise ValueError('Invalid version string: %r' % version_string)
3c0173418d5d VMM/{Account,common,maillocation}: Dovecot version (check) fixes.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 263
diff changeset
   135
    major, minor, patch, level, serial = version_mo.groups()
266
e14c345b44a1 VMM/{Account,common,Handler}: Improved version_hex().
Tobias Berling <t-obi@users.sourceforge.net>
parents: 265
diff changeset
   136
    major = int(major)
e14c345b44a1 VMM/{Account,common,Handler}: Improved version_hex().
Tobias Berling <t-obi@users.sourceforge.net>
parents: 265
diff changeset
   137
    minor = int(minor)
265
3c0173418d5d VMM/{Account,common,maillocation}: Dovecot version (check) fixes.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 263
diff changeset
   138
    if patch:
266
e14c345b44a1 VMM/{Account,common,Handler}: Improved version_hex().
Tobias Berling <t-obi@users.sourceforge.net>
parents: 265
diff changeset
   139
        patch = int(patch)
265
3c0173418d5d VMM/{Account,common,maillocation}: Dovecot version (check) fixes.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 263
diff changeset
   140
    if serial:
266
e14c345b44a1 VMM/{Account,common,Handler}: Improved version_hex().
Tobias Berling <t-obi@users.sourceforge.net>
parents: 265
diff changeset
   141
        serial = int(serial)
e14c345b44a1 VMM/{Account,common,Handler}: Improved version_hex().
Tobias Berling <t-obi@users.sourceforge.net>
parents: 265
diff changeset
   142
e14c345b44a1 VMM/{Account,common,Handler}: Improved version_hex().
Tobias Berling <t-obi@users.sourceforge.net>
parents: 265
diff changeset
   143
    if major > 0xFF or minor > 0xFF or \
e14c345b44a1 VMM/{Account,common,Handler}: Improved version_hex().
Tobias Berling <t-obi@users.sourceforge.net>
parents: 265
diff changeset
   144
      patch and patch > 0xFF or serial and serial > 0xFF:
e14c345b44a1 VMM/{Account,common,Handler}: Improved version_hex().
Tobias Berling <t-obi@users.sourceforge.net>
parents: 265
diff changeset
   145
        raise ValueError('Invalid version string: %r' % version_string)
e14c345b44a1 VMM/{Account,common,Handler}: Improved version_hex().
Tobias Berling <t-obi@users.sourceforge.net>
parents: 265
diff changeset
   146
e14c345b44a1 VMM/{Account,common,Handler}: Improved version_hex().
Tobias Berling <t-obi@users.sourceforge.net>
parents: 265
diff changeset
   147
    version += major << 28
e14c345b44a1 VMM/{Account,common,Handler}: Improved version_hex().
Tobias Berling <t-obi@users.sourceforge.net>
parents: 265
diff changeset
   148
    version += minor << 20
e14c345b44a1 VMM/{Account,common,Handler}: Improved version_hex().
Tobias Berling <t-obi@users.sourceforge.net>
parents: 265
diff changeset
   149
    if patch:
e14c345b44a1 VMM/{Account,common,Handler}: Improved version_hex().
Tobias Berling <t-obi@users.sourceforge.net>
parents: 265
diff changeset
   150
        version += patch << 12
e14c345b44a1 VMM/{Account,common,Handler}: Improved version_hex().
Tobias Berling <t-obi@users.sourceforge.net>
parents: 265
diff changeset
   151
    version += _version_level.get(level, 0xF) << 8
e14c345b44a1 VMM/{Account,common,Handler}: Improved version_hex().
Tobias Berling <t-obi@users.sourceforge.net>
parents: 265
diff changeset
   152
    if serial:
e14c345b44a1 VMM/{Account,common,Handler}: Improved version_hex().
Tobias Berling <t-obi@users.sourceforge.net>
parents: 265
diff changeset
   153
        version += serial
e14c345b44a1 VMM/{Account,common,Handler}: Improved version_hex().
Tobias Berling <t-obi@users.sourceforge.net>
parents: 265
diff changeset
   154
273
77fc7138ef6a VMM/common: added a caching dict for version_hex()/version_str()
Pascal Volk <neverseen@users.sourceforge.net>
parents: 266
diff changeset
   155
    _version_cache[version_string] = version
263
07fdc93dde9f VMM/common: improved version_hex() in order to convert also
Pascal Volk <neverseen@users.sourceforge.net>
parents: 262
diff changeset
   156
    return version
262
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   157
266
e14c345b44a1 VMM/{Account,common,Handler}: Improved version_hex().
Tobias Berling <t-obi@users.sourceforge.net>
parents: 265
diff changeset
   158
e14c345b44a1 VMM/{Account,common,Handler}: Improved version_hex().
Tobias Berling <t-obi@users.sourceforge.net>
parents: 265
diff changeset
   159
def version_str(version):
e14c345b44a1 VMM/{Account,common,Handler}: Improved version_hex().
Tobias Berling <t-obi@users.sourceforge.net>
parents: 265
diff changeset
   160
    """Converts a Dovecot version previously converted with version_hex back to
e14c345b44a1 VMM/{Account,common,Handler}: Improved version_hex().
Tobias Berling <t-obi@users.sourceforge.net>
parents: 265
diff changeset
   161
    a string.
e14c345b44a1 VMM/{Account,common,Handler}: Improved version_hex().
Tobias Berling <t-obi@users.sourceforge.net>
parents: 265
diff changeset
   162
    Raises a `TypeError` if *version* is not an int/long.
e14c345b44a1 VMM/{Account,common,Handler}: Improved version_hex().
Tobias Berling <t-obi@users.sourceforge.net>
parents: 265
diff changeset
   163
    Raises a `ValueError` if *version* is an incorrect int version.
e14c345b44a1 VMM/{Account,common,Handler}: Improved version_hex().
Tobias Berling <t-obi@users.sourceforge.net>
parents: 265
diff changeset
   164
    """
347
586367ee042b VMM/common: Made the version re pattern object accessible as VERSION_RE.
Pascal Volk <neverseen@users.sourceforge.net>
parents: 328
diff changeset
   165
    global _version_cache
273
77fc7138ef6a VMM/common: added a caching dict for version_hex()/version_str()
Pascal Volk <neverseen@users.sourceforge.net>
parents: 266
diff changeset
   166
    if version in _version_cache:
77fc7138ef6a VMM/common: added a caching dict for version_hex()/version_str()
Pascal Volk <neverseen@users.sourceforge.net>
parents: 266
diff changeset
   167
        return _version_cache[version]
266
e14c345b44a1 VMM/{Account,common,Handler}: Improved version_hex().
Tobias Berling <t-obi@users.sourceforge.net>
parents: 265
diff changeset
   168
    if not isinstance(version, (int, long)):
e14c345b44a1 VMM/{Account,common,Handler}: Improved version_hex().
Tobias Berling <t-obi@users.sourceforge.net>
parents: 265
diff changeset
   169
        raise TypeError('Argument is not a int/long: %r', version)
e14c345b44a1 VMM/{Account,common,Handler}: Improved version_hex().
Tobias Berling <t-obi@users.sourceforge.net>
parents: 265
diff changeset
   170
    major = (version >> 28) & 0xFF
e14c345b44a1 VMM/{Account,common,Handler}: Improved version_hex().
Tobias Berling <t-obi@users.sourceforge.net>
parents: 265
diff changeset
   171
    minor = (version >> 20) & 0xFF
e14c345b44a1 VMM/{Account,common,Handler}: Improved version_hex().
Tobias Berling <t-obi@users.sourceforge.net>
parents: 265
diff changeset
   172
    patch = (version >> 12) & 0xFF
e14c345b44a1 VMM/{Account,common,Handler}: Improved version_hex().
Tobias Berling <t-obi@users.sourceforge.net>
parents: 265
diff changeset
   173
    level = (version >> 8) & 0x0F
e14c345b44a1 VMM/{Account,common,Handler}: Improved version_hex().
Tobias Berling <t-obi@users.sourceforge.net>
parents: 265
diff changeset
   174
    serial = version & 0xFF
e14c345b44a1 VMM/{Account,common,Handler}: Improved version_hex().
Tobias Berling <t-obi@users.sourceforge.net>
parents: 265
diff changeset
   175
e14c345b44a1 VMM/{Account,common,Handler}: Improved version_hex().
Tobias Berling <t-obi@users.sourceforge.net>
parents: 265
diff changeset
   176
    levels = dict(zip(_version_level.values(), _version_level.keys()))
e14c345b44a1 VMM/{Account,common,Handler}: Improved version_hex().
Tobias Berling <t-obi@users.sourceforge.net>
parents: 265
diff changeset
   177
    if level == 0xF and not serial:
e14c345b44a1 VMM/{Account,common,Handler}: Improved version_hex().
Tobias Berling <t-obi@users.sourceforge.net>
parents: 265
diff changeset
   178
        version_string = '%u.%u.%u' % (major, minor, patch)
e14c345b44a1 VMM/{Account,common,Handler}: Improved version_hex().
Tobias Berling <t-obi@users.sourceforge.net>
parents: 265
diff changeset
   179
    elif level in levels and not patch:
e14c345b44a1 VMM/{Account,common,Handler}: Improved version_hex().
Tobias Berling <t-obi@users.sourceforge.net>
parents: 265
diff changeset
   180
        version_string = '%u.%u.%s%u' % (major, minor, levels[level], serial)
e14c345b44a1 VMM/{Account,common,Handler}: Improved version_hex().
Tobias Berling <t-obi@users.sourceforge.net>
parents: 265
diff changeset
   181
    else:
e14c345b44a1 VMM/{Account,common,Handler}: Improved version_hex().
Tobias Berling <t-obi@users.sourceforge.net>
parents: 265
diff changeset
   182
        raise ValueError('Invalid version: %r' % hex(version))
e14c345b44a1 VMM/{Account,common,Handler}: Improved version_hex().
Tobias Berling <t-obi@users.sourceforge.net>
parents: 265
diff changeset
   183
273
77fc7138ef6a VMM/common: added a caching dict for version_hex()/version_str()
Pascal Volk <neverseen@users.sourceforge.net>
parents: 266
diff changeset
   184
    _version_cache[version] = version_string
266
e14c345b44a1 VMM/{Account,common,Handler}: Improved version_hex().
Tobias Berling <t-obi@users.sourceforge.net>
parents: 265
diff changeset
   185
    return version_string
e14c345b44a1 VMM/{Account,common,Handler}: Improved version_hex().
Tobias Berling <t-obi@users.sourceforge.net>
parents: 265
diff changeset
   186
262
6eea85d8b91d VMM: moved some non-init functions to the new common module.
Pascal Volk <neverseen@users.sourceforge.net>
parents:
diff changeset
   187
del _