Mercurial > libervia-backend
comparison sat/tools/utils.py @ 3028:ab2696e34d29
Python 3 port:
/!\ this is a huge commit
/!\ starting from this commit, SàT is needs Python 3.6+
/!\ SàT maybe be instable or some feature may not work anymore, this will improve with time
This patch port backend, bridge and frontends to Python 3.
Roughly this has been done this way:
- 2to3 tools has been applied (with python 3.7)
- all references to python2 have been replaced with python3 (notably shebangs)
- fixed files not handled by 2to3 (notably the shell script)
- several manual fixes
- fixed issues reported by Python 3 that where not handled in Python 2
- replaced "async" with "async_" when needed (it's a reserved word from Python 3.7)
- replaced zope's "implements" with @implementer decorator
- temporary hack to handle data pickled in database, as str or bytes may be returned,
to be checked later
- fixed hash comparison for password
- removed some code which is not needed anymore with Python 3
- deactivated some code which needs to be checked (notably certificate validation)
- tested with jp, fixed reported issues until some basic commands worked
- ported Primitivus (after porting dependencies like urwid satext)
- more manual fixes
author | Goffi <goffi@goffi.org> |
---|---|
date | Tue, 13 Aug 2019 19:08:41 +0200 |
parents | 181735d1b062 |
children | d62fceccff22 |
comparison
equal
deleted
inserted
replaced
3027:ff5bcb12ae60 | 3028:ab2696e34d29 |
---|---|
1 #!/usr/bin/env python2 | 1 #!/usr/bin/env python3 |
2 # -*- coding: utf-8 -*- | 2 # -*- coding: utf-8 -*- |
3 | 3 |
4 # SAT: a jabber client | 4 # SAT: a jabber client |
5 # Copyright (C) 2009-2019 Jérôme Poisson (goffi@goffi.org) | 5 # Copyright (C) 2009-2019 Jérôme Poisson (goffi@goffi.org) |
6 | 6 |
34 from sat.core.log import getLogger | 34 from sat.core.log import getLogger |
35 | 35 |
36 log = getLogger(__name__) | 36 log = getLogger(__name__) |
37 | 37 |
38 | 38 |
39 NO_REPOS_DATA = u"repository data unknown" | 39 NO_REPOS_DATA = "repository data unknown" |
40 repos_cache_dict = None | 40 repos_cache_dict = None |
41 repos_cache = None | 41 repos_cache = None |
42 | 42 |
43 | 43 |
44 def clean_ustr(ustr): | 44 def clean_ustr(ustr): |
97 the string returned by this method is valid with RFC 3339 | 97 the string returned by this method is valid with RFC 3339 |
98 @param timestamp(None, float): posix timestamp. If None current time will be used | 98 @param timestamp(None, float): posix timestamp. If None current time will be used |
99 @param with_time(bool): if True include the time | 99 @param with_time(bool): if True include the time |
100 @return(unicode): XEP-0082 formatted date and time | 100 @return(unicode): XEP-0082 formatted date and time |
101 """ | 101 """ |
102 template_date = u"%Y-%m-%d" | 102 template_date = "%Y-%m-%d" |
103 template_time = u"%H:%M:%SZ" | 103 template_time = "%H:%M:%SZ" |
104 template = ( | 104 template = ( |
105 u"{}T{}".format(template_date, template_time) if with_time else template_date | 105 "{}T{}".format(template_date, template_time) if with_time else template_date |
106 ) | 106 ) |
107 return datetime.datetime.utcfromtimestamp( | 107 return datetime.datetime.utcfromtimestamp( |
108 time.time() if timestamp is None else timestamp | 108 time.time() if timestamp is None else timestamp |
109 ).strftime(template) | 109 ).strftime(template) |
110 | 110 |
117 @return (unicode): generated password | 117 @return (unicode): generated password |
118 """ | 118 """ |
119 random.seed() | 119 random.seed() |
120 if vocabulary is None: | 120 if vocabulary is None: |
121 vocabulary = [ | 121 vocabulary = [ |
122 chr(i) for i in range(0x30, 0x3A) + range(0x41, 0x5B) + range(0x61, 0x7B) | 122 chr(i) for i in list(range(0x30, 0x3A)) + list(range(0x41, 0x5B)) + list(range(0x61, 0x7B)) |
123 ] | 123 ] |
124 return u"".join([random.choice(vocabulary) for i in range(15)]) | 124 return "".join([random.choice(vocabulary) for i in range(15)]) |
125 | 125 |
126 | 126 |
127 def getRepositoryData(module, as_string=True, is_path=False): | 127 def getRepositoryData(module, as_string=True, is_path=False): |
128 """Retrieve info on current mecurial repository | 128 """Retrieve info on current mecurial repository |
129 | 129 |
155 if repos_cache_dict is not None: | 155 if repos_cache_dict is not None: |
156 return repos_cache_dict | 156 return repos_cache_dict |
157 | 157 |
158 if sys.platform == "android": | 158 if sys.platform == "android": |
159 # FIXME: workaround to avoid trouble on android, need to be fixed properly | 159 # FIXME: workaround to avoid trouble on android, need to be fixed properly |
160 repos_cache = u"Cagou android build" | 160 repos_cache = "Cagou android build" |
161 return repos_cache | 161 return repos_cache |
162 | 162 |
163 KEYS = ("node", "node_short", "branch", "date", "tag", "distance") | 163 KEYS = ("node", "node_short", "branch", "date", "tag", "distance") |
164 ori_cwd = os.getcwd() | 164 ori_cwd = os.getcwd() |
165 | 165 |
169 repos_root = os.path.abspath(os.path.dirname(module.__file__)) | 169 repos_root = os.path.abspath(os.path.dirname(module.__file__)) |
170 | 170 |
171 try: | 171 try: |
172 hg_path = procutils.which("hg")[0] | 172 hg_path = procutils.which("hg")[0] |
173 except IndexError: | 173 except IndexError: |
174 log.warning(u"Can't find hg executable") | 174 log.warning("Can't find hg executable") |
175 hg_path = None | 175 hg_path = None |
176 hg_data = {} | 176 hg_data = {} |
177 | 177 |
178 if hg_path is not None: | 178 if hg_path is not None: |
179 os.chdir(repos_root) | 179 os.chdir(repos_root) |
189 "{node|short}\n" | 189 "{node|short}\n" |
190 "{branch}\n" | 190 "{branch}\n" |
191 "{date|isodate}\n" | 191 "{date|isodate}\n" |
192 "{latesttag}\n" | 192 "{latesttag}\n" |
193 "{latesttagdistance}", | 193 "{latesttagdistance}", |
194 ] | 194 ], |
195 text=True | |
195 ) | 196 ) |
196 except subprocess.CalledProcessError: | 197 except subprocess.CalledProcessError: |
197 hg_data = {} | 198 hg_data = {} |
198 else: | 199 else: |
199 hg_data = dict(zip(KEYS, hg_data_raw.split("\n"))) | 200 hg_data = dict(list(zip(KEYS, hg_data_raw.split("\n")))) |
200 try: | 201 try: |
201 hg_data["modified"] = "+" in subprocess.check_output(["hg", "id", "-i"]) | 202 hg_data["modified"] = "+" in subprocess.check_output(["hg", "id", "-i"], text=True) |
202 except subprocess.CalledProcessError: | 203 except subprocess.CalledProcessError: |
203 pass | 204 pass |
204 else: | 205 else: |
205 hg_data = {} | 206 hg_data = {} |
206 | 207 |
207 if not hg_data: | 208 if not hg_data: |
208 # .hg/dirstate method | 209 # .hg/dirstate method |
209 log.debug(u"trying dirstate method") | 210 log.debug("trying dirstate method") |
210 if is_path: | 211 if is_path: |
211 os.chdir(repos_root) | 212 os.chdir(repos_root) |
212 else: | 213 else: |
213 os.chdir(os.path.abspath(os.path.dirname(repos_root))) | 214 os.chdir(os.path.abspath(os.path.dirname(repos_root))) |
214 try: | 215 try: |
215 with open(".hg/dirstate") as hg_dirstate: | 216 with open(".hg/dirstate") as hg_dirstate: |
216 hg_data["node"] = hg_dirstate.read(20).encode("hex") | 217 hg_data["node"] = hg_dirstate.read(20).encode("hex") |
217 hg_data["node_short"] = hg_data["node"][:12] | 218 hg_data["node_short"] = hg_data["node"][:12] |
218 except IOError: | 219 except IOError: |
219 log.debug(u"Can't access repository data") | 220 log.debug("Can't access repository data") |
220 | 221 |
221 # we restore original working dir | 222 # we restore original working dir |
222 os.chdir(ori_cwd) | 223 os.chdir(ori_cwd) |
223 | 224 |
224 if not hg_data: | 225 if not hg_data: |
225 log.debug(u"Mercurial not available or working, trying package version") | 226 log.debug("Mercurial not available or working, trying package version") |
226 try: | 227 try: |
227 import pkg_resources | 228 import pkg_resources |
228 | 229 |
229 pkg_version = pkg_resources.get_distribution(C.APP_NAME_FILE).version | 230 pkg_version = pkg_resources.get_distribution(C.APP_NAME_FILE).version |
230 version, local_id = pkg_version.split("+", 1) | 231 version, local_id = pkg_version.split("+", 1) |
232 log.warning("pkg_resources not available, can't get package data") | 233 log.warning("pkg_resources not available, can't get package data") |
233 except pkg_resources.DistributionNotFound: | 234 except pkg_resources.DistributionNotFound: |
234 log.warning("can't retrieve package data") | 235 log.warning("can't retrieve package data") |
235 except ValueError: | 236 except ValueError: |
236 log.info( | 237 log.info( |
237 u"no local version id in package: {pkg_version}".format( | 238 "no local version id in package: {pkg_version}".format( |
238 pkg_version=pkg_version | 239 pkg_version=pkg_version |
239 ) | 240 ) |
240 ) | 241 ) |
241 else: | 242 else: |
242 version = version.replace(".dev0", "D") | 243 version = version.replace(".dev0", "D") |
257 | 258 |
258 if as_string: | 259 if as_string: |
259 if not hg_data: | 260 if not hg_data: |
260 repos_cache = NO_REPOS_DATA | 261 repos_cache = NO_REPOS_DATA |
261 else: | 262 else: |
262 strings = [u"rev", hg_data["node_short"]] | 263 strings = ["rev", hg_data["node_short"]] |
263 try: | 264 try: |
264 if hg_data["modified"]: | 265 if hg_data["modified"]: |
265 strings.append(u"[M]") | 266 strings.append("[M]") |
266 except KeyError: | 267 except KeyError: |
267 pass | 268 pass |
268 try: | 269 try: |
269 strings.extend([u"({branch} {date})".format(**hg_data)]) | 270 strings.extend(["({branch} {date})".format(**hg_data)]) |
270 except KeyError: | 271 except KeyError: |
271 pass | 272 pass |
272 try: | 273 try: |
273 strings.extend([u"+{distance}".format(**hg_data)]) | 274 strings.extend(["+{distance}".format(**hg_data)]) |
274 except KeyError: | 275 except KeyError: |
275 pass | 276 pass |
276 repos_cache = u" ".join(strings) | 277 repos_cache = " ".join(strings) |
277 return repos_cache | 278 return repos_cache |
278 else: | 279 else: |
279 return hg_data | 280 return hg_data |