diff --git a/gajim/common/app.py b/gajim/common/app.py index e8e3c7ec5..8cbadf655 100644 --- a/gajim/common/app.py +++ b/gajim/common/app.py @@ -36,7 +36,6 @@ from distutils.version import LooseVersion as V from collections import namedtuple import gi import nbxmpp -import hashlib from gi.repository import GLib @@ -63,24 +62,26 @@ glog = logging.getLogger('gajim') logger = None +# For backwards compatibility needed +# some plugins use that gajimpaths = configpaths.gajimpaths -VCARD_PATH = gajimpaths['VCARD'] -AVATAR_PATH = gajimpaths['AVATAR'] -MY_EMOTS_PATH = gajimpaths['MY_EMOTS'] -MY_ICONSETS_PATH = gajimpaths['MY_ICONSETS'] -MY_MOOD_ICONSETS_PATH = gajimpaths['MY_MOOD_ICONSETS'] -MY_ACTIVITY_ICONSETS_PATH = gajimpaths['MY_ACTIVITY_ICONSETS'] -MY_CACERTS = gajimpaths['MY_CACERTS'] -MY_PEER_CERTS_PATH = gajimpaths['MY_PEER_CERTS'] -TMP = gajimpaths['TMP'] -DATA_DIR = gajimpaths['DATA'] -ICONS_DIR = gajimpaths['ICONS'] -HOME_DIR = gajimpaths['HOME'] -PLUGINS_DIRS = [gajimpaths['PLUGINS_BASE'], - gajimpaths['PLUGINS_USER']] -PLUGINS_CONFIG_DIR = gajimpaths['PLUGINS_CONFIG_DIR'] -MY_CERT_DIR = gajimpaths['MY_CERT'] +VCARD_PATH = configpaths.get('VCARD') +AVATAR_PATH = configpaths.get('AVATAR') +MY_EMOTS_PATH = configpaths.get('MY_EMOTS') +MY_ICONSETS_PATH = configpaths.get('MY_ICONSETS') +MY_MOOD_ICONSETS_PATH = configpaths.get('MY_MOOD_ICONSETS') +MY_ACTIVITY_ICONSETS_PATH = configpaths.get('MY_ACTIVITY_ICONSETS') +MY_CACERTS = configpaths.get('MY_CACERTS') +MY_PEER_CERTS_PATH = configpaths.get('MY_PEER_CERTS') +TMP = configpaths.get('TMP') +DATA_DIR = configpaths.get('DATA') +ICONS_DIR = configpaths.get('ICONS') +HOME_DIR = configpaths.get('HOME') +PLUGINS_DIRS = [configpaths.get('PLUGINS_BASE'), + configpaths.get('PLUGINS_USER')] +PLUGINS_CONFIG_DIR = configpaths.get('PLUGINS_CONFIG_DIR') +MY_CERT_DIR = configpaths.get('MY_CERT') RecentGroupchat = namedtuple('RecentGroupchat', ['room', 'server', 'nickname']) diff --git a/gajim/common/check_paths.py b/gajim/common/check_paths.py index 5e9f1b05a..4f2a6f850 100644 --- a/gajim/common/check_paths.py +++ b/gajim/common/check_paths.py @@ -188,9 +188,8 @@ def check_and_possibly_move_config(): vars['MY_MOOD_ICONSETS_PATH'] = app.MY_MOOD_ICONSETS_PATH vars['MY_ACTIVITY_ICONSETS_PATH'] = app.MY_ACTIVITY_ICONSETS_PATH from gajim.common import configpaths - MY_DATA = configpaths.gajimpaths['MY_DATA'] - MY_CONFIG = configpaths.gajimpaths['MY_CONFIG'] - MY_CACHE = configpaths.gajimpaths['MY_CACHE'] + MY_DATA = configpaths.get('MY_DATA') + MY_CONFIG = configpaths.get('MY_CONFIG') if os.path.exists(LOG_DB_PATH): # File already exists @@ -273,11 +272,11 @@ def check_and_possibly_create_paths(): VCARD_PATH = app.VCARD_PATH AVATAR_PATH = app.AVATAR_PATH from gajim.common import configpaths - MY_DATA = configpaths.gajimpaths['MY_DATA'] - MY_CONFIG = configpaths.gajimpaths['MY_CONFIG'] - MY_CACHE = configpaths.gajimpaths['MY_CACHE'] - XTLS_CERTS = configpaths.gajimpaths['MY_PEER_CERTS'] - LOCAL_XTLS_CERTS = configpaths.gajimpaths['MY_CERT'] + MY_DATA = configpaths.get('MY_DATA') + MY_CONFIG = configpaths.get('MY_CONFIG') + MY_CACHE = configpaths.get('MY_CACHE') + XTLS_CERTS = configpaths.get('MY_PEER_CERTS') + LOCAL_XTLS_CERTS = configpaths.get('MY_CERT') PLUGINS_CONFIG_PATH = app.PLUGINS_CONFIG_DIR diff --git a/gajim/common/configpaths.py b/gajim/common/configpaths.py index 7a8c2c780..83b17efb3 100644 --- a/gajim/common/configpaths.py +++ b/gajim/common/configpaths.py @@ -27,31 +27,13 @@ import sys import tempfile from enum import Enum, unique + @unique class Type(Enum): CONFIG = 0 CACHE = 1 DATA = 2 -# Note on path and filename encodings: -# -# In general it is very difficult to do this correctly. -# We may pull information from environment variables, and what encoding that is -# in is anyone's guess. Any information we request directly from the file -# system will be in filesystemencoding, and (parts of) paths that we write in -# this source code will be in whatever encoding the source is in. (I hereby -# declare this file to be UTF-8 encoded.) -# -# To make things more complicated, modern Windows filesystems use UTF-16, but -# the API tends to hide this from us. -# -# I tried to minimize problems by passing Unicode strings to OS functions as -# much as possible. Hopefully this makes the function return an Unicode string -# as well. If not, we get an 8-bit string in filesystemencoding, which we can -# happily pass to functions that operate on files and directories, so we can -# just leave it as is. Since these paths are meant to be internal to Gajim and -# not displayed to the user, Unicode is not really necessary here. - def windowsify(s): if os.name == 'nt': @@ -60,29 +42,41 @@ def windowsify(s): def get(key): - return gajimpaths[key] + return _paths[key] + + +def set_separation(active: bool): + _paths.profile_separation = active + + +def set_profile(profile: str): + _paths.profile = profile + + +def set_config_root(config_root: str): + _paths.config_root = config_root + + +def init(): + _paths.init() class ConfigPaths: def __init__(self): - # {'name': (type, path), } type can be Type.CONFIG, Type.CACHE, Type.DATA - # or None self.paths = {} + self.profile = '' + self.profile_separation = False + self.config_root = None if os.name == 'nt': try: # Documents and Settings\[User Name]\Application Data\Gajim - - # How are we supposed to know what encoding the environment - # variable 'appdata' is in? Assuming it to be in filesystem - # encoding. self.config_root = self.cache_root = self.data_root = \ os.path.join(os.environ['appdata'], 'Gajim') except KeyError: # win9x, in cwd self.config_root = self.cache_root = self.data_root = '.' - else: # Unices - # Pass in an Unicode string, and hopefully get one back. + else: expand = os.path.expanduser base = os.getenv('XDG_CONFIG_HOME') if base is None or base[0] != '/': @@ -128,40 +122,45 @@ class ConfigPaths: for key in self.paths.keys(): yield (key, self[key]) - def init(self, root=None, profile='', profile_separation=False): - if root is not None: - self.config_root = self.cache_root = self.data_root = root + def init(self): + if self.config_root is not None: + self.cache_root = self.data_root = self.config_root - self.init_profile(profile) + self.add('CONFIG_ROOT', None, self.config_root) + self.add('CACHE_ROOT', None, self.cache_root) + self.add('DATA_ROOT', None, self.data_root) - if len(profile) > 0 and profile_separation: - profile = u'.' + profile + self.init_profile(self.profile) + + if len(self.profile) > 0 and self.profile_separation: + self.profile = u'.' + self.profile else: - profile = '' + self.profile = '' d = {'LOG_DB': 'logs.db', 'MY_CACERTS': 'cacerts.pem', - 'MY_EMOTS': 'emoticons', 'MY_ICONSETS': 'iconsets', - 'MY_MOOD_ICONSETS': 'moods', 'MY_ACTIVITY_ICONSETS': 'activities', - 'PLUGINS_USER': 'plugins'} + 'MY_EMOTS': 'emoticons', 'MY_ICONSETS': 'iconsets', + 'MY_MOOD_ICONSETS': 'moods', 'MY_ACTIVITY_ICONSETS': 'activities', + 'PLUGINS_USER': 'plugins'} for name in d: - d[name] += profile + d[name] += self.profile self.add(name, Type.DATA, windowsify(d[name])) - if len(profile): + if len(self.profile): self.add('MY_DATA', Type.DATA, 'data.dir') else: self.add('MY_DATA', Type.DATA, '') - d = {'CACHE_DB': 'cache.db', 'VCARD': 'vcards', - 'AVATAR': 'avatars'} + d = {'CACHE_DB': 'cache.db', + 'VCARD': 'vcards', + 'AVATAR': 'avatars'} for name in d: - d[name] += profile + d[name] += self.profile self.add(name, Type.CACHE, windowsify(d[name])) - if len(profile): + if len(self.profile): self.add('MY_CACHE', Type.CACHE, 'cache.dir') else: self.add('MY_CACHE', Type.CACHE, '') - if len(profile): + if len(self.profile): self.add('MY_CONFIG', Type.CONFIG, 'config.dir') else: self.add('MY_CONFIG', Type.CONFIG, '') @@ -169,8 +168,8 @@ class ConfigPaths: try: self.add('TMP', None, tempfile.gettempdir()) except IOError as e: - print('Error opening tmp folder: %s\nUsing %s' % (str(e), - os.path.expanduser('~')), file=sys.stderr) + print('Error opening tmp folder: %s\nUsing %s' % ( + str(e), os.path.expanduser('~')), file=sys.stderr) self.add('TMP', None, os.path.expanduser('~')) def init_profile(self, profile): @@ -193,4 +192,9 @@ class ConfigPaths: self.add('PLUGINS_CONFIG_DIR', Type.CONFIG, pluginsconfdir) self.add('MY_CERT', Type.CONFIG, localcertsdir) -gajimpaths = ConfigPaths() + +_paths = ConfigPaths() + +# For backwards compatibility needed +# some plugins use that +gajimpaths = _paths diff --git a/gajim/common/helpers.py b/gajim/common/helpers.py index 970058386..c1c88f9ad 100644 --- a/gajim/common/helpers.py +++ b/gajim/common/helpers.py @@ -853,8 +853,7 @@ def play_sound(event): path_to_soundfile = app.config.get_per('soundevents', event, 'path') play_sound_file(path_to_soundfile) -def check_soundfile_path(file_, dirs=(app.gajimpaths.data_root, -app.DATA_DIR)): +def check_soundfile_path(file_, dirs=None): """ Check if the sound file exists @@ -863,6 +862,10 @@ app.DATA_DIR)): (eg: ~/.gajim/sounds/, DATADIR/sounds...). :return the path to file or None if it doesn't exists. """ + if dirs is None: + dirs = [app.configpaths.get('DATA_ROOT'), + app.DATA_DIR] + if not file_: return None elif os.path.exists(file_): @@ -874,8 +877,7 @@ app.DATA_DIR)): return d return None -def strip_soundfile_path(file_, dirs=(app.gajimpaths.data_root, -app.DATA_DIR), abs=True): +def strip_soundfile_path(file_, dirs=None, abs=True): """ Remove knowns paths from a sound file @@ -888,6 +890,10 @@ app.DATA_DIR), abs=True): if not file_: return None + if dirs is None: + dirs = [app.configpaths.get('DATA_ROOT'), + app.DATA_DIR] + name = os.path.basename(file_) for d in dirs: d = os.path.join(d, 'sounds', name) diff --git a/gajim/common/jingle_ft.py b/gajim/common/jingle_ft.py index f0033702f..3317c2211 100644 --- a/gajim/common/jingle_ft.py +++ b/gajim/common/jingle_ft.py @@ -120,7 +120,7 @@ class JingleFileTransfer(JingleContent): } if jingle_xtls.PYOPENSSL_PRESENT: - cert_name = os.path.join(configpaths.gajimpaths['MY_CERT'], + cert_name = os.path.join(configpaths.get('MY_CERT'), jingle_xtls.SELF_SIGNED_CERTIFICATE) if not (os.path.exists(cert_name + '.cert') and os.path.exists(cert_name + '.pkey')): diff --git a/gajim/common/logger.py b/gajim/common/logger.py index f8e932e21..657874d38 100644 --- a/gajim/common/logger.py +++ b/gajim/common/logger.py @@ -42,12 +42,13 @@ from enum import IntEnum, unique from gajim.common import exceptions from gajim.common import app +from gajim.common import configpaths import sqlite3 as sqlite -LOG_DB_PATH = app.gajimpaths['LOG_DB'] +LOG_DB_PATH = configpaths.get('LOG_DB') LOG_DB_FOLDER, LOG_DB_FILE = os.path.split(LOG_DB_PATH) -CACHE_DB_PATH = app.gajimpaths['CACHE_DB'] +CACHE_DB_PATH = configpaths.get('CACHE_DB') import logging log = logging.getLogger('gajim.c.logger') diff --git a/gajim/gajim.py b/gajim/gajim.py index 05a520da7..090b93269 100644 --- a/gajim/gajim.py +++ b/gajim/gajim.py @@ -53,6 +53,7 @@ gi.require_version('Pango', '1.0') from gi.repository import GLib, Gio, Gtk from gajim.common import i18n +from gajim.common import configpaths from gajim.common import logging_helpers MIN_NBXMPP_VER = "0.6.4" @@ -112,9 +113,6 @@ class GajimApplication(Gtk.Application): self.connect('startup', self._startup) self.connect('activate', self._activate) - self.profile = '' - self.config_path = None - self.profile_separation = False self.interface = None GLib.set_prgname('gajim') @@ -157,10 +155,6 @@ class GajimApplication(Gtk.Application): sys.exit(1) # Create and initialize Application Paths & Databases - from gajim.common import configpaths - configpaths.gajimpaths.init( - self.config_path, self.profile, self.profile_separation) - from gajim.common import app from gajim.common import check_paths from gajim.common import exceptions @@ -209,7 +203,7 @@ class GajimApplication(Gtk.Application): # libintl = ctypes.cdll.LoadLibrary(libintl_path) # libintl.bindtextdomain(APP, DIR) # libintl.bind_textdomain_codeset(APP, 'UTF-8') - # plugins_locale_dir = os.path.join(common.configpaths.gajimpaths[ + # plugins_locale_dir = os.path.join(common.configpaths[ # 'PLUGINS_USER'], 'locale').encode(locale.getpreferredencoding()) # libintl.bindtextdomain('gajim_plugins', plugins_locale_dir) # libintl.bind_textdomain_codeset('gajim_plugins', 'UTF-8') @@ -345,23 +339,22 @@ class GajimApplication(Gtk.Application): def _handle_local_options(self, application, options: GLib.VariantDict) -> int: # Parse all options that have to be executed before ::startup - logging_helpers.init() - if options.contains('profile'): # Incorporate profile name into application id # to have a single app instance for each profile. profile = options.lookup_value('profile').get_string() app_id = '%s.%s' % (self.get_application_id(), profile) self.set_application_id(app_id) - self.profile = profile + configpaths.set_profile(profile) if options.contains('separate'): - self.profile_separation = True + configpaths.set_separation(True) if options.contains('config-path'): - self.config_path = options.lookup_value('config-path').get_string() - if options.contains('version'): - from gajim import __version__ - print(__version__) - return 0 + path = options.lookup_value('config-path').get_string() + configpaths.set_config_root(path) + + configpaths.init() + logging_helpers.init() + if options.contains('quiet'): logging_helpers.set_quiet() if options.contains('verbose'): diff --git a/gajim/gui_interface.py b/gajim/gui_interface.py index 6502cfa94..7a7821108 100644 --- a/gajim/gui_interface.py +++ b/gajim/gui_interface.py @@ -107,11 +107,10 @@ from threading import Thread from gajim.common import ged from gajim.common.caps_cache import muc_caps_cache -from gajim.common.configpaths import gajimpaths -config_filename = gajimpaths['CONFIG_FILE'] +from gajim.common import configpaths from gajim.common import optparser -parser = optparser.OptionsParser(config_filename) +parser = optparser.OptionsParser(configpaths.get('CONFIG_FILE')) import logging log = logging.getLogger('gajim.interface') diff --git a/gajim/history_manager.py b/gajim/history_manager.py index 2fda801c5..4020d278a 100644 --- a/gajim/history_manager.py +++ b/gajim/history_manager.py @@ -67,8 +67,9 @@ def parseOpts(): config_path = parseOpts() del parseOpts -import gajim.common.configpaths -gajim.common.configpaths.gajimpaths.init(config_path) +from gajim.common import configpaths +configpaths.set_config_root(config_path) +configpaths.init() del config_path from gajim.common import app from gajim import gtkgui_helpers diff --git a/gajim/htmltextview.py b/gajim/htmltextview.py index 29776571b..78a089378 100644 --- a/gajim/htmltextview.py +++ b/gajim/htmltextview.py @@ -48,8 +48,8 @@ import urllib if __name__ == '__main__': from gajim.common import i18n - import gajim.common.configpaths - gajim.common.configpaths.gajimpaths.init(None) + from gajim.common import configpaths + configpaths.init() from gajim.common import app from gajim import gtkgui_helpers from gajim.gtkgui_helpers import get_icon_pixmap diff --git a/gajim/secrets.py b/gajim/secrets.py index 9594752b6..3c85d31fb 100644 --- a/gajim/secrets.py +++ b/gajim/secrets.py @@ -19,7 +19,7 @@ ## along with Gajim. If not, see . ## -from gajim.common.configpaths import gajimpaths +from gajim.common import configpaths import Crypto from gajim.common import crypto @@ -28,9 +28,10 @@ from gajim.common import exceptions import os import pickle -secrets_filename = gajimpaths['SECRETS_FILE'] +secrets_filename = configpaths.get('SECRETS_FILE') secrets_cache = None + class Secrets(): def __init__(self, filename): self.filename = filename diff --git a/test/lib/__init__.py b/test/lib/__init__.py index 78a2602c2..7ddd20216 100644 --- a/test/lib/__init__.py +++ b/test/lib/__init__.py @@ -37,8 +37,9 @@ def setup_env(): os.mkdir(configdir) os.mkdir(pluginsconfigdir) - import gajim.common.configpaths - gajim.common.configpaths.gajimpaths.init(configdir) + from gajim.common import configpaths + configpaths.set_config_root(configdir) + configpaths.init() # for some reason gajim.common.app needs to be imported before xmpppy? from gajim.common import app diff --git a/test/test_pluginmanager.py b/test/test_pluginmanager.py index 50b9c0392..ee0c59f59 100644 --- a/test/test_pluginmanager.py +++ b/test/test_pluginmanager.py @@ -49,8 +49,9 @@ if os.path.isdir(configdir): os.mkdir(configdir) -import gajim.common.configpaths -gajim.common.configpaths.gajimpaths.init(configdir) +from gajim.common import configpaths +configpaths.set_config_root(configdir) +configpaths.init() # for some reason common.app needs to be imported before xmpppy? from gajim.common import app