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