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 _version_level = dict(alpha=0xA, beta=0xB, rc=0xC) |
|
22 _version_cache = {} |
22 _ = lambda msg: msg |
23 _ = lambda msg: msg |
23 |
24 |
24 |
25 |
25 def expand_path(path): |
26 def expand_path(path): |
26 """Expands paths, starting with ``.`` or ``~``, to an absolute path.""" |
27 """Expands paths, starting with ``.`` or ``~``, to an absolute path.""" |
71 Raises a `ValueError` if the *version_string* has the wrong™ format. |
72 Raises a `ValueError` if the *version_string* has the wrong™ format. |
72 |
73 |
73 version_hex('1.2.3') -> 270548736 |
74 version_hex('1.2.3') -> 270548736 |
74 hex(version_hex('1.2.3')) -> '0x10203f00' |
75 hex(version_hex('1.2.3')) -> '0x10203f00' |
75 """ |
76 """ |
|
77 global _version_cache, _version_level, _version_re |
|
78 if version_string in _version_cache: |
|
79 return _version_cache[version_string] |
76 version = 0 |
80 version = 0 |
77 version_mo = _version_re.match(version_string) |
81 version_mo = _version_re.match(version_string) |
78 if not version_mo: |
82 if not version_mo: |
79 raise ValueError('Invalid version string: %r' % version_string) |
83 raise ValueError('Invalid version string: %r' % version_string) |
80 major, minor, patch, level, serial = version_mo.groups() |
84 major, minor, patch, level, serial = version_mo.groups() |
95 version += patch << 12 |
99 version += patch << 12 |
96 version += _version_level.get(level, 0xF) << 8 |
100 version += _version_level.get(level, 0xF) << 8 |
97 if serial: |
101 if serial: |
98 version += serial |
102 version += serial |
99 |
103 |
|
104 _version_cache[version_string] = version |
100 return version |
105 return version |
101 |
106 |
102 |
107 |
103 def version_str(version): |
108 def version_str(version): |
104 """Converts a Dovecot version previously converted with version_hex back to |
109 """Converts a Dovecot version previously converted with version_hex back to |
105 a string. |
110 a string. |
106 Raises a `TypeError` if *version* is not an int/long. |
111 Raises a `TypeError` if *version* is not an int/long. |
107 Raises a `ValueError` if *version* is an incorrect int version. |
112 Raises a `ValueError` if *version* is an incorrect int version. |
108 """ |
113 """ |
|
114 global _version_cache, _version_level |
|
115 if version in _version_cache: |
|
116 return _version_cache[version] |
109 if not isinstance(version, (int, long)): |
117 if not isinstance(version, (int, long)): |
110 raise TypeError('Argument is not a int/long: %r', version) |
118 raise TypeError('Argument is not a int/long: %r', version) |
111 major = (version >> 28) & 0xFF |
119 major = (version >> 28) & 0xFF |
112 minor = (version >> 20) & 0xFF |
120 minor = (version >> 20) & 0xFF |
113 patch = (version >> 12) & 0xFF |
121 patch = (version >> 12) & 0xFF |
120 elif level in levels and not patch: |
128 elif level in levels and not patch: |
121 version_string = '%u.%u.%s%u' % (major, minor, levels[level], serial) |
129 version_string = '%u.%u.%s%u' % (major, minor, levels[level], serial) |
122 else: |
130 else: |
123 raise ValueError('Invalid version: %r' % hex(version)) |
131 raise ValueError('Invalid version: %r' % hex(version)) |
124 |
132 |
|
133 _version_cache[version] = version_string |
125 return version_string |
134 return version_string |
126 |
135 |
127 del _ |
136 del _ |