Mercurial > libervia-backend
comparison sat/core/constants.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 | ff5bcb12ae60 |
children | fee60f17ebac |
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 # SàT: a XMPP client | 4 # SàT: a XMPP 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 |
26 | 26 |
27 | 27 |
28 class Const(object): | 28 class Const(object): |
29 | 29 |
30 ## Application ## | 30 ## Application ## |
31 APP_NAME = u"Salut à Toi" | 31 APP_NAME = "Salut à Toi" |
32 APP_NAME_SHORT = u"SàT" | 32 APP_NAME_SHORT = "SàT" |
33 APP_NAME_FILE = u"sat" | 33 APP_NAME_FILE = "sat" |
34 APP_NAME_FULL = u"{name_short} ({name})".format( | 34 APP_NAME_FULL = "{name_short} ({name})".format( |
35 name_short=APP_NAME_SHORT, name=APP_NAME | 35 name_short=APP_NAME_SHORT, name=APP_NAME |
36 ) | 36 ) |
37 APP_VERSION = ( | 37 APP_VERSION = ( |
38 sat.__version__ | 38 sat.__version__ |
39 ) # Please add 'D' at the end of version in sat/VERSION for dev versions | 39 ) # Please add 'D' at the end of version in sat/VERSION for dev versions |
40 APP_RELEASE_NAME = u"La Cecília" | 40 APP_RELEASE_NAME = "La Cecília" |
41 APP_URL = u"https://salut-a-toi.org" | 41 APP_URL = "https://salut-a-toi.org" |
42 | 42 |
43 ## Runtime ## | 43 ## Runtime ## |
44 PLUGIN_EXT = "py" | 44 PLUGIN_EXT = "py" |
45 HISTORY_SKIP = u"skip" | 45 HISTORY_SKIP = "skip" |
46 | 46 |
47 ## Main config ## | 47 ## Main config ## |
48 DEFAULT_BRIDGE = "dbus" | 48 DEFAULT_BRIDGE = "dbus" |
49 | 49 |
50 ## Protocol ## | 50 ## Protocol ## |
120 MESS_TYPE_HEADLINE, | 120 MESS_TYPE_HEADLINE, |
121 MESS_TYPE_NORMAL, | 121 MESS_TYPE_NORMAL, |
122 ) | 122 ) |
123 MESS_TYPE_ALL = MESS_TYPE_STANDARD + (MESS_TYPE_INFO, MESS_TYPE_AUTO) | 123 MESS_TYPE_ALL = MESS_TYPE_STANDARD + (MESS_TYPE_INFO, MESS_TYPE_AUTO) |
124 | 124 |
125 MESS_EXTRA_INFO = u"info_type" | 125 MESS_EXTRA_INFO = "info_type" |
126 EXTRA_INFO_DECR_ERR = u"DECRYPTION_ERROR" | 126 EXTRA_INFO_DECR_ERR = "DECRYPTION_ERROR" |
127 EXTRA_INFO_ENCR_ERR = u"ENCRYPTION_ERROR" | 127 EXTRA_INFO_ENCR_ERR = "ENCRYPTION_ERROR" |
128 | 128 |
129 # encryption is a key for plugins | 129 # encryption is a key for plugins |
130 MESS_KEY_ENCRYPTION = u"ENCRYPTION" | 130 MESS_KEY_ENCRYPTION = "ENCRYPTION" |
131 # encrypted is a key for frontends | 131 # encrypted is a key for frontends |
132 MESS_KEY_ENCRYPTED = u"encrypted" | 132 MESS_KEY_ENCRYPTED = "encrypted" |
133 MESS_KEY_TRUSTED = u"trusted" | 133 MESS_KEY_TRUSTED = "trusted" |
134 | 134 |
135 ## Chat ## | 135 ## Chat ## |
136 CHAT_ONE2ONE = "one2one" | 136 CHAT_ONE2ONE = "one2one" |
137 CHAT_GROUP = "group" | 137 CHAT_GROUP = "group" |
138 | 138 |
160 IQ_SET = '/iq[@type="set"]' | 160 IQ_SET = '/iq[@type="set"]' |
161 | 161 |
162 ## Directories ## | 162 ## Directories ## |
163 | 163 |
164 # directory for components specific data | 164 # directory for components specific data |
165 COMPONENTS_DIR = u"components" | 165 COMPONENTS_DIR = "components" |
166 CACHE_DIR = u"cache" | 166 CACHE_DIR = "cache" |
167 # files in file dir are stored for long term | 167 # files in file dir are stored for long term |
168 # files dir is global, i.e. for all profiles | 168 # files dir is global, i.e. for all profiles |
169 FILES_DIR = u"files" | 169 FILES_DIR = "files" |
170 # FILES_LINKS_DIR is a directory where files owned by a specific profile | 170 # FILES_LINKS_DIR is a directory where files owned by a specific profile |
171 # are linked to the global files directory. This way the directory can be | 171 # are linked to the global files directory. This way the directory can be |
172 # shared per profiles while keeping global directory where identical files | 172 # shared per profiles while keeping global directory where identical files |
173 # shared between different profiles are not duplicated. | 173 # shared between different profiles are not duplicated. |
174 FILES_LINKS_DIR = u"files_links" | 174 FILES_LINKS_DIR = "files_links" |
175 # FILES_TMP_DIR is where profile's partially transfered files are put. | 175 # FILES_TMP_DIR is where profile's partially transfered files are put. |
176 # Once transfer is completed, they are moved to FILES_DIR | 176 # Once transfer is completed, they are moved to FILES_DIR |
177 FILES_TMP_DIR = u"files_tmp" | 177 FILES_TMP_DIR = "files_tmp" |
178 | |
179 ## Configuration ## | |
180 if ( | |
181 BaseDirectory | |
182 ): # skipped when xdg module is not available (should not happen in backend) | |
183 if "org.salutatoi.cagou" in BaseDirectory.__file__: | |
184 # FIXME: hack to make config read from the right location on Android | |
185 # TODO: fix it in a more proper way | |
186 | |
187 # we need to use Android API to get downloads directory | |
188 import os.path | |
189 from jnius import autoclass | |
190 | |
191 Environment = autoclass("android.os.Environment") | |
192 | |
193 BaseDirectory = None | |
194 DEFAULT_CONFIG = { | |
195 "local_dir": "/data/data/org.salutatoi.cagou/app", | |
196 "media_dir": "/data/data/org.salutatoi.cagou/files/app/media", | |
197 # FIXME: temporary location for downloads, need to call API properly | |
198 "downloads_dir": os.path.join( | |
199 Environment.getExternalStoragePublicDirectory( | |
200 Environment.DIRECTORY_DOWNLOADS | |
201 ).getAbsolutePath(), | |
202 APP_NAME_FILE, | |
203 ), | |
204 "pid_dir": "%(local_dir)s", | |
205 "log_dir": "%(local_dir)s", | |
206 } | |
207 CONFIG_FILES = [ | |
208 "/data/data/org.salutatoi.cagou/files/app/android/" | |
209 + APP_NAME_FILE | |
210 + ".conf" | |
211 ] | |
212 else: | |
213 import os | |
214 CONFIG_PATHS = ( | |
215 ["/etc/", "~/", "~/.", "", "."] | |
216 + [ | |
217 "%s/" % path | |
218 for path in list(BaseDirectory.load_config_paths(APP_NAME_FILE)) | |
219 ] | |
220 ) | |
221 | |
222 # on recent versions of Flatpak, FLATPAK_ID is set at run time | |
223 # it seems that this is not the case on older versions, | |
224 # but FLATPAK_SANDBOX_DIR seems set then | |
225 if os.getenv('FLATPAK_ID') or os.getenv('FLATPAK_SANDBOX_DIR'): | |
226 # for Flatpak, the conf can't be set in /etc or $HOME, so we have | |
227 # to add /app | |
228 CONFIG_PATHS.append('/app/') | |
229 | |
230 ## Configuration ## | |
231 DEFAULT_CONFIG = { | |
232 "media_dir": "/usr/share/" + APP_NAME_FILE + "/media", | |
233 "local_dir": BaseDirectory.save_data_path(APP_NAME_FILE), | |
234 "downloads_dir": "~/Downloads/" + APP_NAME_FILE, | |
235 "pid_dir": "%(local_dir)s", | |
236 "log_dir": "%(local_dir)s", | |
237 } | |
238 | |
239 # List of the configuration filenames sorted by ascending priority | |
240 CONFIG_FILES = [ | |
241 realpath(expanduser(path) + APP_NAME_FILE + ".conf") | |
242 for path in CONFIG_PATHS | |
243 ] | |
244 | 178 |
245 ## Templates ## | 179 ## Templates ## |
246 TEMPLATE_TPL_DIR = u"templates" | 180 TEMPLATE_TPL_DIR = "templates" |
247 TEMPLATE_THEME_DEFAULT = u"default" | 181 TEMPLATE_THEME_DEFAULT = "default" |
248 TEMPLATE_STATIC_DIR = u"static" | 182 TEMPLATE_STATIC_DIR = "static" |
249 KEY_LANG = u"lang" # templates i18n | 183 KEY_LANG = "lang" # templates i18n |
250 | 184 |
251 ## Plugins ## | 185 ## Plugins ## |
252 | 186 |
253 # PLUGIN_INFO keys | 187 # PLUGIN_INFO keys |
254 # XXX: we use PI instead of PLUG_INFO which would normally be used | 188 # XXX: we use PI instead of PLUG_INFO which would normally be used |
255 # to make the header more readable | 189 # to make the header more readable |
256 PI_NAME = u"name" | 190 PI_NAME = "name" |
257 PI_IMPORT_NAME = u"import_name" | 191 PI_IMPORT_NAME = "import_name" |
258 PI_MAIN = u"main" | 192 PI_MAIN = "main" |
259 PI_HANDLER = u"handler" | 193 PI_HANDLER = "handler" |
260 PI_TYPE = ( | 194 PI_TYPE = ( |
261 u"type" | 195 "type" |
262 ) # FIXME: should be types, and should handle single unicode type or tuple of types (e.g. "blog" and "import") | 196 ) # FIXME: should be types, and should handle single unicode type or tuple of types (e.g. "blog" and "import") |
263 PI_MODES = u"modes" | 197 PI_MODES = "modes" |
264 PI_PROTOCOLS = u"protocols" | 198 PI_PROTOCOLS = "protocols" |
265 PI_DEPENDENCIES = u"dependencies" | 199 PI_DEPENDENCIES = "dependencies" |
266 PI_RECOMMENDATIONS = u"recommendations" | 200 PI_RECOMMENDATIONS = "recommendations" |
267 PI_DESCRIPTION = u"description" | 201 PI_DESCRIPTION = "description" |
268 PI_USAGE = u"usage" | 202 PI_USAGE = "usage" |
269 | 203 |
270 # Types | 204 # Types |
271 PLUG_TYPE_XEP = "XEP" | 205 PLUG_TYPE_XEP = "XEP" |
272 PLUG_TYPE_MISC = "MISC" | 206 PLUG_TYPE_MISC = "MISC" |
273 PLUG_TYPE_EXP = "EXP" | 207 PLUG_TYPE_EXP = "EXP" |
385 ## action constants ## | 319 ## action constants ## |
386 META_TYPE_FILE = "file" | 320 META_TYPE_FILE = "file" |
387 META_TYPE_OVERWRITE = "overwrite" | 321 META_TYPE_OVERWRITE = "overwrite" |
388 | 322 |
389 ## HARD-CODED ACTIONS IDS (generated with uuid.uuid4) ## | 323 ## HARD-CODED ACTIONS IDS (generated with uuid.uuid4) ## |
390 AUTHENTICATE_PROFILE_ID = u"b03bbfa8-a4ae-4734-a248-06ce6c7cf562" | 324 AUTHENTICATE_PROFILE_ID = "b03bbfa8-a4ae-4734-a248-06ce6c7cf562" |
391 CHANGE_XMPP_PASSWD_ID = u"878b9387-de2b-413b-950f-e424a147bcd0" | 325 CHANGE_XMPP_PASSWD_ID = "878b9387-de2b-413b-950f-e424a147bcd0" |
392 | 326 |
393 ## Text values ## | 327 ## Text values ## |
394 BOOL_TRUE = "true" | 328 BOOL_TRUE = "true" |
395 BOOL_FALSE = "false" | 329 BOOL_FALSE = "false" |
396 | 330 |
397 ## Special values used in bridge methods calls ## | 331 ## Special values used in bridge methods calls ## |
398 HISTORY_LIMIT_DEFAULT = -1 | 332 HISTORY_LIMIT_DEFAULT = -1 |
399 HISTORY_LIMIT_NONE = -2 | 333 HISTORY_LIMIT_NONE = -2 |
400 | 334 |
401 ## Progress error special values ## | 335 ## Progress error special values ## |
402 PROGRESS_ERROR_DECLINED = u"declined" # session has been declined by peer user | 336 PROGRESS_ERROR_DECLINED = "declined" # session has been declined by peer user |
403 | 337 |
404 ## Files ## | 338 ## Files ## |
405 FILE_TYPE_DIRECTORY = "directory" | 339 FILE_TYPE_DIRECTORY = "directory" |
406 FILE_TYPE_FILE = "file" | 340 FILE_TYPE_FILE = "file" |
407 | 341 |
408 ## Permissions management ## | 342 ## Permissions management ## |
409 ACCESS_PERM_READ = u"read" | 343 ACCESS_PERM_READ = "read" |
410 ACCESS_PERM_WRITE = u"write" | 344 ACCESS_PERM_WRITE = "write" |
411 ACCESS_PERMS = {ACCESS_PERM_READ, ACCESS_PERM_WRITE} | 345 ACCESS_PERMS = {ACCESS_PERM_READ, ACCESS_PERM_WRITE} |
412 ACCESS_TYPE_PUBLIC = u"public" | 346 ACCESS_TYPE_PUBLIC = "public" |
413 ACCESS_TYPE_WHITELIST = u"whitelist" | 347 ACCESS_TYPE_WHITELIST = "whitelist" |
414 ACCESS_TYPES = (ACCESS_TYPE_PUBLIC, ACCESS_TYPE_WHITELIST) | 348 ACCESS_TYPES = (ACCESS_TYPE_PUBLIC, ACCESS_TYPE_WHITELIST) |
415 | 349 |
416 ## Common data keys ## | 350 ## Common data keys ## |
417 KEY_THUMBNAILS = u"thumbnails" | 351 KEY_THUMBNAILS = "thumbnails" |
418 KEY_PROGRESS_ID = u"progress_id" | 352 KEY_PROGRESS_ID = "progress_id" |
419 | 353 |
420 ## Common extra keys/values ## | 354 ## Common extra keys/values ## |
421 KEY_ORDER_BY = u"order_by" | 355 KEY_ORDER_BY = "order_by" |
422 | 356 |
423 ORDER_BY_CREATION = u'creation' | 357 ORDER_BY_CREATION = 'creation' |
424 ORDER_BY_MODIFICATION = u'modification' | 358 ORDER_BY_MODIFICATION = 'modification' |
425 | 359 |
426 # internationalisation | 360 # internationalisation |
427 DEFAULT_LOCALE = u"en_GB" | 361 DEFAULT_LOCALE = "en_GB" |
428 | 362 |
429 ## Misc ## | 363 ## Misc ## |
430 SAVEFILE_DATABASE = APP_NAME_FILE + ".db" | 364 SAVEFILE_DATABASE = APP_NAME_FILE + ".db" |
431 IQ_SET = '/iq[@type="set"]' | 365 IQ_SET = '/iq[@type="set"]' |
432 ENV_PREFIX = "SAT_" # Prefix used for environment variables | 366 ENV_PREFIX = "SAT_" # Prefix used for environment variables |
433 IGNORE = "ignore" | 367 IGNORE = "ignore" |
434 NO_LIMIT = -1 # used in bridge when a integer value is expected | 368 NO_LIMIT = -1 # used in bridge when a integer value is expected |
435 DEFAULT_MAX_AGE = 1209600 # default max age of cached files, in seconds | 369 DEFAULT_MAX_AGE = 1209600 # default max age of cached files, in seconds |
436 HASH_SHA1_EMPTY = "da39a3ee5e6b4b0d3255bfef95601890afd80709" | 370 HASH_SHA1_EMPTY = "da39a3ee5e6b4b0d3255bfef95601890afd80709" |
437 STANZA_NAMES = (u"iq", u"message", u"presence") | 371 STANZA_NAMES = ("iq", "message", "presence") |
438 | 372 |
439 # Stream Hooks | 373 # Stream Hooks |
440 STREAM_HOOK_SEND = u"send" | 374 STREAM_HOOK_SEND = "send" |
441 STREAM_HOOK_RECEIVE = u"receive" | 375 STREAM_HOOK_RECEIVE = "receive" |
442 | 376 |
443 @classmethod | 377 @classmethod |
444 def LOG_OPTIONS(cls): | 378 def LOG_OPTIONS(cls): |
445 """Return options checked for logs""" | 379 """Return options checked for logs""" |
446 # XXX: we use a classmethod so we can use Const inheritance to change default options | 380 # XXX: we use a classmethod so we can use Const inheritance to change default options |
454 ) | 388 ) |
455 | 389 |
456 @classmethod | 390 @classmethod |
457 def bool(cls, value): | 391 def bool(cls, value): |
458 """@return (bool): bool value for associated constant""" | 392 """@return (bool): bool value for associated constant""" |
459 assert isinstance(value, basestring) | 393 assert isinstance(value, str) |
460 return value.lower() in (cls.BOOL_TRUE, "1", "yes", "on") | 394 return value.lower() in (cls.BOOL_TRUE, "1", "yes", "on") |
461 | 395 |
462 @classmethod | 396 @classmethod |
463 def boolConst(cls, value): | 397 def boolConst(cls, value): |
464 """@return (str): constant associated to bool value""" | 398 """@return (str): constant associated to bool value""" |
465 assert isinstance(value, bool) | 399 assert isinstance(value, bool) |
466 return cls.BOOL_TRUE if value else cls.BOOL_FALSE | 400 return cls.BOOL_TRUE if value else cls.BOOL_FALSE |
401 | |
402 | |
403 | |
404 ## Configuration ## | |
405 if ( | |
406 BaseDirectory | |
407 ): # skipped when xdg module is not available (should not happen in backend) | |
408 if "org.salutatoi.cagou" in BaseDirectory.__file__: | |
409 # FIXME: hack to make config read from the right location on Android | |
410 # TODO: fix it in a more proper way | |
411 | |
412 # we need to use Android API to get downloads directory | |
413 import os.path | |
414 from jnius import autoclass | |
415 | |
416 Environment = autoclass("android.os.Environment") | |
417 | |
418 BaseDirectory = None | |
419 Const.DEFAULT_CONFIG = { | |
420 "local_dir": "/data/data/org.salutatoi.cagou/app", | |
421 "media_dir": "/data/data/org.salutatoi.cagou/files/app/media", | |
422 # FIXME: temporary location for downloads, need to call API properly | |
423 "downloads_dir": os.path.join( | |
424 Environment.getExternalStoragePublicDirectory( | |
425 Environment.DIRECTORY_DOWNLOADS | |
426 ).getAbsolutePath(), | |
427 Const.APP_NAME_FILE, | |
428 ), | |
429 "pid_dir": "%(local_dir)s", | |
430 "log_dir": "%(local_dir)s", | |
431 } | |
432 Const.CONFIG_FILES = [ | |
433 "/data/data/org.salutatoi.cagou/files/app/android/" | |
434 + Const.APP_NAME_FILE | |
435 + ".conf" | |
436 ] | |
437 else: | |
438 import os | |
439 Const.CONFIG_PATHS = ( | |
440 ["/etc/", "~/", "~/.", "", "."] | |
441 + [ | |
442 "%s/" % path | |
443 for path in list(BaseDirectory.load_config_paths(Const.APP_NAME_FILE)) | |
444 ] | |
445 ) | |
446 | |
447 # on recent versions of Flatpak, FLATPAK_ID is set at run time | |
448 # it seems that this is not the case on older versions, | |
449 # but FLATPAK_SANDBOX_DIR seems set then | |
450 if os.getenv('FLATPAK_ID') or os.getenv('FLATPAK_SANDBOX_DIR'): | |
451 # for Flatpak, the conf can't be set in /etc or $HOME, so we have | |
452 # to add /app | |
453 Const.CONFIG_PATHS.append('/app/') | |
454 | |
455 ## Configuration ## | |
456 Const.DEFAULT_CONFIG = { | |
457 "media_dir": "/usr/share/" + Const.APP_NAME_FILE + "/media", | |
458 "local_dir": BaseDirectory.save_data_path(Const.APP_NAME_FILE), | |
459 "downloads_dir": "~/Downloads/" + Const.APP_NAME_FILE, | |
460 "pid_dir": "%(local_dir)s", | |
461 "log_dir": "%(local_dir)s", | |
462 } | |
463 | |
464 # List of the configuration filenames sorted by ascending priority | |
465 Const.CONFIG_FILES = [ | |
466 realpath(expanduser(path) + Const.APP_NAME_FILE + ".conf") | |
467 for path in Const.CONFIG_PATHS | |
468 ] | |
469 |