Philipp Hörist pushed to branch master at gajim / gajim

Commits:

2 changed files:

Changes:

  • src/application.py deleted
    1
    -# -*- coding:utf-8 -*-
    
    2
    -## src/application.py
    
    3
    -##
    
    4
    -## Copyright (C) 2016 Emmanuel Gil Peyrot <linkmauve AT linkmauve.fr>
    
    5
    -##
    
    6
    -## This file is part of Gajim.
    
    7
    -##
    
    8
    -## Gajim is free software; you can redistribute it and/or modify
    
    9
    -## it under the terms of the GNU General Public License as published
    
    10
    -## by the Free Software Foundation; version 3 only.
    
    11
    -##
    
    12
    -## Gajim is distributed in the hope that it will be useful,
    
    13
    -## but WITHOUT ANY WARRANTY; without even the implied warranty of
    
    14
    -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    
    15
    -## GNU General Public License for more details.
    
    16
    -##
    
    17
    -## You should have received a copy of the GNU General Public License
    
    18
    -## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
    
    19
    -##
    
    20
    -
    
    21
    -import sys
    
    22
    -import os
    
    23
    -import logging
    
    24
    -import signal
    
    25
    -import locale
    
    26
    -from gi.repository import GLib, Gio, Gtk
    
    27
    -from common import i18n
    
    28
    -from common import logging_helpers
    
    29
    -from common import crypto
    
    30
    -try:
    
    31
    -    PYOPENSSL_PRNG_PRESENT = True
    
    32
    -    import OpenSSL.rand
    
    33
    -except ImportError:
    
    34
    -    print('PyOpenSSL not available, impossible to generate entropy', file=sys.stderr)
    
    35
    -    PYOPENSSL_PRNG_PRESENT = False
    
    36
    -
    
    37
    -logging_helpers.init(sys.stderr.isatty())
    
    38
    -log = logging.getLogger('gajim.gajim')
    
    39
    -
    
    40
    -
    
    41
    -class GajimApplication(Gtk.Application):
    
    42
    -    '''Main class handling activation and command line.'''
    
    43
    -
    
    44
    -    def __init__(self):
    
    45
    -        Gtk.Application.__init__(self, application_id='org.gajim.Gajim',
    
    46
    -                                 flags=Gio.ApplicationFlags.HANDLES_COMMAND_LINE)
    
    47
    -        self.add_main_option('version', ord('V'), GLib.OptionFlags.NONE,
    
    48
    -                             GLib.OptionArg.NONE,
    
    49
    -                             _('Show the application\'s version'))
    
    50
    -        self.add_main_option('quiet', ord('q'), GLib.OptionFlags.NONE,
    
    51
    -                             GLib.OptionArg.NONE,
    
    52
    -                             _('Show only critical errors'))
    
    53
    -        self.add_main_option('separate', ord('s'), GLib.OptionFlags.NONE,
    
    54
    -                             GLib.OptionArg.NONE,
    
    55
    -                             _('Separate profile files completely (even '
    
    56
    -                               'history db and plugins)'))
    
    57
    -        self.add_main_option('verbose', ord('v'), GLib.OptionFlags.NONE,
    
    58
    -                             GLib.OptionArg.NONE,
    
    59
    -                             _('Print XML stanzas and other debug '
    
    60
    -                               'information'))
    
    61
    -        self.add_main_option('windev', ord('w'), GLib.OptionFlags.NONE,
    
    62
    -                             GLib.OptionArg.NONE,
    
    63
    -                             _('Print stdout/stderr to the console '
    
    64
    -                               'on Windows'))
    
    65
    -        self.add_main_option('profile', ord('p'), GLib.OptionFlags.NONE,
    
    66
    -                             GLib.OptionArg.STRING,
    
    67
    -                             _('Use defined profile in configuration '
    
    68
    -                               'directory'), 'NAME')
    
    69
    -        self.add_main_option('config-path', ord('c'), GLib.OptionFlags.NONE,
    
    70
    -                             GLib.OptionArg.STRING,
    
    71
    -                             _('Set configuration directory'), 'PATH')
    
    72
    -        self.add_main_option('loglevel', ord('l'), GLib.OptionFlags.NONE,
    
    73
    -                             GLib.OptionArg.STRING,
    
    74
    -                             _('Configure logging system'), 'LEVEL')
    
    75
    -
    
    76
    -        self.profile = ''
    
    77
    -        self.config_path = None
    
    78
    -        self.profile_separation = False
    
    79
    -        self.interface = None
    
    80
    -        self.rng_seed = None
    
    81
    -
    
    82
    -        GLib.set_prgname('gajim')
    
    83
    -        GLib.set_application_name('Gajim')
    
    84
    -
    
    85
    -    def do_startup(self):
    
    86
    -        Gtk.Application.do_startup(self)
    
    87
    -
    
    88
    -    def do_activate(self):
    
    89
    -        # If a second instance starts do_activate() is called
    
    90
    -        # We bringt the Roster window to the front, GTK exits afterwards.
    
    91
    -        if self.interface:
    
    92
    -            self.interface.roster.window.present()
    
    93
    -            return
    
    94
    -
    
    95
    -        Gtk.Application.do_activate(self)
    
    96
    -
    
    97
    -        import gtkexcepthook
    
    98
    -        gtkexcepthook.init()
    
    99
    -
    
    100
    -        # Create and initialize Application Paths & Databases
    
    101
    -        import common.configpaths
    
    102
    -        common.configpaths.gajimpaths.init(
    
    103
    -            self.config_path, self.profile, self.profile_separation)
    
    104
    -        from common import gajim
    
    105
    -        from common import check_paths
    
    106
    -        from common import exceptions
    
    107
    -        from common import logger
    
    108
    -        from common import caps_cache
    
    109
    -        try:
    
    110
    -            gajim.logger = logger.Logger()
    
    111
    -            caps_cache.initialize(gajim.logger)
    
    112
    -            check_paths.check_and_possibly_create_paths()
    
    113
    -        except exceptions.DatabaseMalformed:
    
    114
    -            dlg = Gtk.MessageDialog(
    
    115
    -                None,
    
    116
    -                Gtk.DialogFlags.DESTROY_WITH_PARENT | Gtk.DialogFlags.MODAL,
    
    117
    -                Gtk.MessageType.ERROR,
    
    118
    -                Gtk.ButtonsType.OK,
    
    119
    -                _('Database Error'))
    
    120
    -            dlg.format_secondary_text(
    
    121
    -                _('The database file (%s) cannot be read. Try to repair it '
    
    122
    -                  '(see http://trac.gajim.org/wiki/DatabaseBackup) or remove it '
    
    123
    -                  '(all history will be lost).') % gajim.gajimpaths['LOG_DB'])
    
    124
    -            dlg.run()
    
    125
    -            dlg.destroy()
    
    126
    -            sys.exit()
    
    127
    -
    
    128
    -        if os.name == 'nt':
    
    129
    -            import gettext
    
    130
    -            # needed for docutils
    
    131
    -            sys.path.append('.')
    
    132
    -            APP = 'gajim'
    
    133
    -            DIR = '../po'
    
    134
    -            lang, enc = locale.getdefaultlocale()
    
    135
    -            os.environ['LANG'] = lang
    
    136
    -            gettext.bindtextdomain(APP, DIR)
    
    137
    -            gettext.textdomain(APP)
    
    138
    -            gettext.install(APP, DIR)
    
    139
    -
    
    140
    -        # This is for Windows translation which is currently not
    
    141
    -        # working on GTK 3.18.9
    
    142
    -        #    locale.setlocale(locale.LC_ALL, '')
    
    143
    -        #    import ctypes
    
    144
    -        #    import ctypes.util
    
    145
    -        #    libintl_path = ctypes.util.find_library('intl')
    
    146
    -        #    if libintl_path == None:
    
    147
    -        #        local_intl = os.path.join('gtk', 'bin', 'intl.dll')
    
    148
    -        #        if os.path.exists(local_intl):
    
    149
    -        #            libintl_path = local_intl
    
    150
    -        #    if libintl_path == None:
    
    151
    -        #        raise ImportError('intl.dll library not found')
    
    152
    -        #    libintl = ctypes.cdll.LoadLibrary(libintl_path)
    
    153
    -        #    libintl.bindtextdomain(APP, DIR)
    
    154
    -        #    libintl.bind_textdomain_codeset(APP, 'UTF-8')
    
    155
    -        #    plugins_locale_dir = os.path.join(common.configpaths.gajimpaths[
    
    156
    -        #       'PLUGINS_USER'], 'locale').encode(locale.getpreferredencoding())
    
    157
    -        #    libintl.bindtextdomain('gajim_plugins', plugins_locale_dir)
    
    158
    -        #    libintl.bind_textdomain_codeset('gajim_plugins', 'UTF-8')
    
    159
    -
    
    160
    -        if Gtk.Widget.get_default_direction() == Gtk.TextDirection.RTL:
    
    161
    -            i18n.direction_mark = '\u200F'
    
    162
    -
    
    163
    -        from ctypes import CDLL
    
    164
    -        from ctypes.util import find_library
    
    165
    -        import platform
    
    166
    -
    
    167
    -        sysname = platform.system()
    
    168
    -        if sysname in ('Linux', 'FreeBSD', 'OpenBSD', 'NetBSD'):
    
    169
    -            libc = CDLL(find_library('c'))
    
    170
    -
    
    171
    -            # The constant defined in <linux/prctl.h> which is used to set the name
    
    172
    -            # of the process.
    
    173
    -            PR_SET_NAME = 15
    
    174
    -
    
    175
    -            if sysname == 'Linux':
    
    176
    -                libc.prctl(PR_SET_NAME, 'gajim')
    
    177
    -            elif sysname in ('FreeBSD', 'OpenBSD', 'NetBSD'):
    
    178
    -                libc.setproctitle('gajim')
    
    179
    -
    
    180
    -        # Seed the OpenSSL pseudo random number generator from file and initialize
    
    181
    -        if PYOPENSSL_PRNG_PRESENT:
    
    182
    -            self.rng_seed = gajim.gajimpaths['RNG_SEED']
    
    183
    -            # Seed from file
    
    184
    -            try:
    
    185
    -                OpenSSL.rand.load_file(self.rng_seed)
    
    186
    -            except TypeError:
    
    187
    -                OpenSSL.rand.load_file(self.rng_seed.encode('utf-8'))
    
    188
    -            crypto.add_entropy_sources_OpenSSL()
    
    189
    -            try:
    
    190
    -                OpenSSL.rand.write_file(self.rng_seed)
    
    191
    -            except TypeError:
    
    192
    -                OpenSSL.rand.write_file(self.rng_seed.encode('utf-8'))
    
    193
    -
    
    194
    -        def sigint_cb(num, stack):
    
    195
    -            print('SIGINT/SIGTERM received')
    
    196
    -            self.quit()
    
    197
    -        # ^C exits the application normally
    
    198
    -        signal.signal(signal.SIGINT, sigint_cb)
    
    199
    -        signal.signal(signal.SIGTERM, sigint_cb)
    
    200
    -
    
    201
    -        log.info("Encodings: d:%s, fs:%s, p:%s", sys.getdefaultencoding(),
    
    202
    -                 sys.getfilesystemencoding(), locale.getpreferredencoding())
    
    203
    -
    
    204
    -        from gui_interface import Interface
    
    205
    -        self.interface = Interface()
    
    206
    -        self.interface.run(self)
    
    207
    -
    
    208
    -    def do_shutdown(self, *args):
    
    209
    -        Gtk.Application.do_shutdown(self)
    
    210
    -        # Save the entropy from OpenSSL PRNG
    
    211
    -        if PYOPENSSL_PRNG_PRESENT and self.rng_seed:
    
    212
    -            try:
    
    213
    -                OpenSSL.rand.write_file(self.rng_seed)
    
    214
    -            except TypeError:
    
    215
    -                OpenSSL.rand.write_file(self.rng_seed.encode('utf-8'))
    
    216
    -        # Shutdown GUI and save config
    
    217
    -        if hasattr(self.interface, 'roster') and self.interface.roster:
    
    218
    -            self.interface.roster.prepare_quit()
    
    219
    -
    
    220
    -    def do_handle_local_options(self, options: GLib.VariantDict) -> int:
    
    221
    -        if options.contains('profile'):
    
    222
    -            # Incorporate profile name into application id
    
    223
    -            # to have a single app instance for each profile.
    
    224
    -            profile = options.lookup_value('profile').get_string()
    
    225
    -            app_id = '%s.%s' % (self.get_application_id(), profile)
    
    226
    -            self.set_application_id(app_id)
    
    227
    -        return -1
    
    228
    -
    
    229
    -    def do_command_line(self, command_line: Gio.ApplicationCommandLine) -> int:
    
    230
    -        Gtk.Application.do_command_line(self, command_line)
    
    231
    -        options = command_line.get_options_dict()
    
    232
    -        if options.contains('quiet'):
    
    233
    -            logging_helpers.set_quiet()
    
    234
    -        if options.contains('separate'):
    
    235
    -            self.profile_separation = True
    
    236
    -        if options.contains('verbose'):
    
    237
    -            logging_helpers.set_verbose()
    
    238
    -        if options.contains('profile'):
    
    239
    -            variant = options.lookup_value('profile')
    
    240
    -            self.profile = variant.get_string()
    
    241
    -        if options.contains('loglevel'):
    
    242
    -            variant = options.lookup_value('loglevel')
    
    243
    -            string = variant.get_string()
    
    244
    -            logging_helpers.set_loglevels(string)
    
    245
    -        if options.contains('config-path'):
    
    246
    -            variant = options.lookup_value('config-path')
    
    247
    -            self.config_path = variant.get_string()
    
    248
    -        self.activate()
    
    249
    -        return 0

  • src/gajim.py
    1 1
     # -*- coding:utf-8 -*-
    
    2 2
     ## src/gajim.py
    
    3 3
     ##
    
    4
    -## Copyright (C) 2003-2014 Yann Leboulanger <asterix AT lagaule.org>
    
    4
    +## Copyright (C) 2003-2017 Yann Leboulanger <asterix AT lagaule.org>
    
    5 5
     ## Copyright (C) 2004-2005 Vincent Hanquez <tab AT snarc.org>
    
    6 6
     ## Copyright (C) 2005 Alex Podaras <bigpod AT gmail.com>
    
    7 7
     ##                    Norman Rasmussen <norman AT rasmussen.co.za>
    
    ... ... @@ -19,6 +19,8 @@
    19 19
     ##                         Julien Pivotto <roidelapluie AT gmail.com>
    
    20 20
     ##                         Stephan Erb <steve-e AT h3c.de>
    
    21 21
     ## Copyright (C) 2008 Jonathan Schleifer <js-gajim AT webkeks.org>
    
    22
    +## Copyright (C) 2016-2017 Emmanuel Gil Peyrot <linkmauve AT linkmauve.fr>
    
    23
    +##                         Philipp Hörist <philipp AT hoerist.com>
    
    22 24
     ##
    
    23 25
     ## This file is part of Gajim.
    
    24 26
     ##
    
    ... ... @@ -37,52 +39,9 @@
    37 39
     
    
    38 40
     import sys
    
    39 41
     import os
    
    40
    -
    
    41
    -if '--version' in sys.argv or '-V' in sys.argv:
    
    42
    -    from common.defs import version
    
    43
    -    print(version)
    
    44
    -    sys.exit(0)
    
    45
    -
    
    46
    -WINDEV = False
    
    47
    -if '--windev' in sys.argv or '-w' in sys.argv:
    
    48
    -    WINDEV = True
    
    49
    -
    
    50
    -if os.name == 'nt' and not WINDEV:
    
    51
    -    import warnings
    
    52
    -    log_path = os.path.join(os.environ['APPDATA'], 'Gajim')
    
    53
    -    if not os.path.exists(log_path):
    
    54
    -        os.mkdir(log_path, 0o700)
    
    55
    -    log_file = os.path.join(log_path, 'gajim.log')
    
    56
    -
    
    57
    -    class MyStd(object):
    
    58
    -        _file = None
    
    59
    -        _error = None
    
    60
    -
    
    61
    -        def write(self, text):
    
    62
    -            if self._file is None and self._error is None:
    
    63
    -                try:
    
    64
    -                    self._file = open(log_file, 'a')
    
    65
    -                except Exception as details:
    
    66
    -                    self._error = details
    
    67
    -            if self._file is not None:
    
    68
    -                self._file.write(text)
    
    69
    -                self._file.flush()
    
    70
    -
    
    71
    -        def flush(self):
    
    72
    -            if self._file is not None:
    
    73
    -                self._file.flush()
    
    74
    -
    
    75
    -        def isatty(self):
    
    76
    -            return False
    
    77
    -
    
    78
    -    outerr = MyStd()
    
    79
    -    sys.stdout = outerr
    
    80
    -    sys.stderr = outerr
    
    81
    -    warnings.filterwarnings(action='ignore')
    
    82
    -
    
    83
    -
    
    84
    -# Test here for all required versions so we dont have to
    
    85
    -# test multiple times in every module. nbxmpp also needs GLib.
    
    42
    +import logging
    
    43
    +import signal
    
    44
    +import locale
    
    86 45
     import gi
    
    87 46
     gi.require_version('GLib', '2.0')
    
    88 47
     gi.require_version('Gio', '2.0')
    
    ... ... @@ -90,21 +49,272 @@ gi.require_version('Gtk', '3.0')
    90 49
     gi.require_version('Gdk', '3.0')
    
    91 50
     gi.require_version('GObject', '2.0')
    
    92 51
     gi.require_version('Pango', '1.0')
    
    52
    +from gi.repository import GLib, Gio, Gtk
    
    53
    +from common import i18n
    
    54
    +from common import logging_helpers
    
    55
    +from common import crypto
    
    56
    +try:
    
    57
    +    PYOPENSSL_PRNG_PRESENT = True
    
    58
    +    import OpenSSL.rand
    
    59
    +except ImportError:
    
    60
    +    print('PyOpenSSL not available, impossible to generate entropy', file=sys.stderr)
    
    61
    +    PYOPENSSL_PRNG_PRESENT = False
    
    62
    +
    
    63
    +logging_helpers.init(sys.stderr.isatty())
    
    64
    +log = logging.getLogger('gajim.gajim')
    
    93 65
     
    
    94 66
     MIN_NBXMPP_VER = "0.5.3"
    
    95 67
     
    
    96
    -try:
    
    97
    -    import nbxmpp
    
    98
    -except ImportError:
    
    99
    -    print('Gajim needs python-nbxmpp to run. Quiting…')
    
    100
    -    sys.exit(1)
    
    101 68
     
    
    102
    -from distutils.version import LooseVersion as V
    
    103
    -if V(nbxmpp.__version__) < V(MIN_NBXMPP_VER):
    
    104
    -    print('Gajim needs python-nbxmpp >= %s to run. Quiting…' % MIN_NBXMPP_VER)
    
    105
    -    sys.exit(1)
    
    69
    +class GajimApplication(Gtk.Application):
    
    70
    +    '''Main class handling activation and command line.'''
    
    71
    +
    
    72
    +    def __init__(self):
    
    73
    +        Gtk.Application.__init__(self, application_id='org.gajim.Gajim',
    
    74
    +                                 flags=Gio.ApplicationFlags.HANDLES_COMMAND_LINE)
    
    75
    +
    
    76
    +        self.add_main_option('version', ord('V'), GLib.OptionFlags.NONE,
    
    77
    +                             GLib.OptionArg.NONE,
    
    78
    +                             _('Show the application\'s version'))
    
    79
    +        self.add_main_option('quiet', ord('q'), GLib.OptionFlags.NONE,
    
    80
    +                             GLib.OptionArg.NONE,
    
    81
    +                             _('Show only critical errors'))
    
    82
    +        self.add_main_option('separate', ord('s'), GLib.OptionFlags.NONE,
    
    83
    +                             GLib.OptionArg.NONE,
    
    84
    +                             _('Separate profile files completely (even '
    
    85
    +                               'history db and plugins)'))
    
    86
    +        self.add_main_option('verbose', ord('v'), GLib.OptionFlags.NONE,
    
    87
    +                             GLib.OptionArg.NONE,
    
    88
    +                             _('Print XML stanzas and other debug '
    
    89
    +                               'information'))
    
    90
    +        self.add_main_option('profile', ord('p'), GLib.OptionFlags.NONE,
    
    91
    +                             GLib.OptionArg.STRING,
    
    92
    +                             _('Use defined profile in configuration '
    
    93
    +                               'directory'), 'NAME')
    
    94
    +        self.add_main_option('config-path', ord('c'), GLib.OptionFlags.NONE,
    
    95
    +                             GLib.OptionArg.STRING,
    
    96
    +                             _('Set configuration directory'), 'PATH')
    
    97
    +        self.add_main_option('loglevel', ord('l'), GLib.OptionFlags.NONE,
    
    98
    +                             GLib.OptionArg.STRING,
    
    99
    +                             _('Configure logging system'), 'LEVEL')
    
    100
    +
    
    101
    +        self.profile = ''
    
    102
    +        self.config_path = None
    
    103
    +        self.profile_separation = False
    
    104
    +        self.interface = None
    
    105
    +        self.rng_seed = None
    
    106
    +
    
    107
    +        GLib.set_prgname('gajim')
    
    108
    +        GLib.set_application_name('Gajim')
    
    109
    +
    
    110
    +    def do_startup(self):
    
    111
    +        Gtk.Application.do_startup(self)
    
    112
    +
    
    113
    +        import gtkexcepthook
    
    114
    +        gtkexcepthook.init()
    
    115
    +
    
    116
    +        try:
    
    117
    +            import nbxmpp
    
    118
    +        except ImportError:
    
    119
    +            print('Gajim needs python-nbxmpp to run. Quitting…')
    
    120
    +            sys.exit(1)
    
    121
    +
    
    122
    +        from distutils.version import LooseVersion as V
    
    123
    +        if V(nbxmpp.__version__) < V(MIN_NBXMPP_VER):
    
    124
    +            print('Gajim needs python-nbxmpp >= %s to run. '
    
    125
    +                  'Quitting…' % MIN_NBXMPP_VER)
    
    126
    +            sys.exit(1)
    
    127
    +
    
    128
    +        # Create and initialize Application Paths & Databases
    
    129
    +        from common import configpaths
    
    130
    +        configpaths.gajimpaths.init(
    
    131
    +            self.config_path, self.profile, self.profile_separation)
    
    132
    +
    
    133
    +        if hasattr(sys, 'frozen'):
    
    134
    +            self.frozen_logging(configpaths.gajimpaths.config_root)
    
    135
    +
    
    136
    +        from common import gajim
    
    137
    +        from common import check_paths
    
    138
    +        from common import exceptions
    
    139
    +        from common import logger
    
    140
    +        from common import caps_cache
    
    141
    +        try:
    
    142
    +            gajim.logger = logger.Logger()
    
    143
    +            caps_cache.initialize(gajim.logger)
    
    144
    +            check_paths.check_and_possibly_create_paths()
    
    145
    +        except exceptions.DatabaseMalformed:
    
    146
    +            dlg = Gtk.MessageDialog(
    
    147
    +                None,
    
    148
    +                Gtk.DialogFlags.DESTROY_WITH_PARENT | Gtk.DialogFlags.MODAL,
    
    149
    +                Gtk.MessageType.ERROR,
    
    150
    +                Gtk.ButtonsType.OK,
    
    151
    +                _('Database Error'))
    
    152
    +            dlg.format_secondary_text(
    
    153
    +                _('The database file (%s) cannot be read. Try to repair it '
    
    154
    +                  '(see http://trac.gajim.org/wiki/DatabaseBackup) or remove it '
    
    155
    +                  '(all history will be lost).') % gajim.gajimpaths['LOG_DB'])
    
    156
    +            dlg.run()
    
    157
    +            dlg.destroy()
    
    158
    +            sys.exit()
    
    159
    +
    
    160
    +        if os.name == 'nt':
    
    161
    +            import gettext
    
    162
    +            # needed for docutils
    
    163
    +            sys.path.append('.')
    
    164
    +            APP = 'gajim'
    
    165
    +            DIR = '../po'
    
    166
    +            lang, enc = locale.getdefaultlocale()
    
    167
    +            os.environ['LANG'] = lang
    
    168
    +            gettext.bindtextdomain(APP, DIR)
    
    169
    +            gettext.textdomain(APP)
    
    170
    +            gettext.install(APP, DIR)
    
    171
    +
    
    172
    +        # This is for Windows translation which is currently not
    
    173
    +        # working on GTK 3.18.9
    
    174
    +        #    locale.setlocale(locale.LC_ALL, '')
    
    175
    +        #    import ctypes
    
    176
    +        #    import ctypes.util
    
    177
    +        #    libintl_path = ctypes.util.find_library('intl')
    
    178
    +        #    if libintl_path == None:
    
    179
    +        #        local_intl = os.path.join('gtk', 'bin', 'intl.dll')
    
    180
    +        #        if os.path.exists(local_intl):
    
    181
    +        #            libintl_path = local_intl
    
    182
    +        #    if libintl_path == None:
    
    183
    +        #        raise ImportError('intl.dll library not found')
    
    184
    +        #    libintl = ctypes.cdll.LoadLibrary(libintl_path)
    
    185
    +        #    libintl.bindtextdomain(APP, DIR)
    
    186
    +        #    libintl.bind_textdomain_codeset(APP, 'UTF-8')
    
    187
    +        #    plugins_locale_dir = os.path.join(common.configpaths.gajimpaths[
    
    188
    +        #       'PLUGINS_USER'], 'locale').encode(locale.getpreferredencoding())
    
    189
    +        #    libintl.bindtextdomain('gajim_plugins', plugins_locale_dir)
    
    190
    +        #    libintl.bind_textdomain_codeset('gajim_plugins', 'UTF-8')
    
    191
    +
    
    192
    +        if Gtk.Widget.get_default_direction() == Gtk.TextDirection.RTL:
    
    193
    +            i18n.direction_mark = '\u200F'
    
    194
    +
    
    195
    +        from ctypes import CDLL
    
    196
    +        from ctypes.util import find_library
    
    197
    +        import platform
    
    198
    +
    
    199
    +        sysname = platform.system()
    
    200
    +        if sysname in ('Linux', 'FreeBSD', 'OpenBSD', 'NetBSD'):
    
    201
    +            libc = CDLL(find_library('c'))
    
    202
    +
    
    203
    +            # The constant defined in <linux/prctl.h> which is used to set the name
    
    204
    +            # of the process.
    
    205
    +            PR_SET_NAME = 15
    
    206
    +
    
    207
    +            if sysname == 'Linux':
    
    208
    +                libc.prctl(PR_SET_NAME, 'gajim')
    
    209
    +            elif sysname in ('FreeBSD', 'OpenBSD', 'NetBSD'):
    
    210
    +                libc.setproctitle('gajim')
    
    211
    +
    
    212
    +        # Seed the OpenSSL pseudo random number generator from file and initialize
    
    213
    +        if PYOPENSSL_PRNG_PRESENT:
    
    214
    +            self.rng_seed = gajim.gajimpaths['RNG_SEED']
    
    215
    +            # Seed from file
    
    216
    +            try:
    
    217
    +                OpenSSL.rand.load_file(self.rng_seed)
    
    218
    +            except TypeError:
    
    219
    +                OpenSSL.rand.load_file(self.rng_seed.encode('utf-8'))
    
    220
    +            crypto.add_entropy_sources_OpenSSL()
    
    221
    +            try:
    
    222
    +                OpenSSL.rand.write_file(self.rng_seed)
    
    223
    +            except TypeError:
    
    224
    +                OpenSSL.rand.write_file(self.rng_seed.encode('utf-8'))
    
    225
    +
    
    226
    +        def sigint_cb(num, stack):
    
    227
    +            print('SIGINT/SIGTERM received')
    
    228
    +            self.quit()
    
    229
    +        # ^C exits the application normally
    
    230
    +        signal.signal(signal.SIGINT, sigint_cb)
    
    231
    +        signal.signal(signal.SIGTERM, sigint_cb)
    
    232
    +
    
    233
    +        print("Encodings: d:{}, fs:{}, p:{}".format(sys.getdefaultencoding(),
    
    234
    +              sys.getfilesystemencoding(), locale.getpreferredencoding()))
    
    235
    +
    
    236
    +    def do_activate(self):
    
    237
    +        Gtk.Application.do_activate(self)
    
    238
    +        from gui_interface import Interface
    
    239
    +        self.interface = Interface()
    
    240
    +        self.interface.run(self)
    
    241
    +
    
    242
    +    def do_shutdown(self, *args):
    
    243
    +        Gtk.Application.do_shutdown(self)
    
    244
    +        # Save the entropy from OpenSSL PRNG
    
    245
    +        if PYOPENSSL_PRNG_PRESENT and self.rng_seed:
    
    246
    +            try:
    
    247
    +                OpenSSL.rand.write_file(self.rng_seed)
    
    248
    +            except TypeError:
    
    249
    +                OpenSSL.rand.write_file(self.rng_seed.encode('utf-8'))
    
    250
    +        # Shutdown GUI and save config
    
    251
    +        if hasattr(self.interface, 'roster') and self.interface.roster:
    
    252
    +            self.interface.roster.prepare_quit()
    
    253
    +
    
    254
    +    def do_handle_local_options(self, options: GLib.VariantDict) -> int:
    
    255
    +        if options.contains('profile'):
    
    256
    +            # Incorporate profile name into application id
    
    257
    +            # to have a single app instance for each profile.
    
    258
    +            profile = options.lookup_value('profile').get_string()
    
    259
    +            app_id = '%s.%s' % (self.get_application_id(), profile)
    
    260
    +            self.set_application_id(app_id)
    
    261
    +            self.profile = profile
    
    262
    +        if options.contains('separate'):
    
    263
    +            self.profile_separation = True
    
    264
    +        if options.contains('config-path'):
    
    265
    +            self.config_path = options.lookup_value('config-path').get_string()
    
    266
    +        if options.contains('version'):
    
    267
    +            from common.defs import version
    
    268
    +            print(version)
    
    269
    +            return 0
    
    270
    +        return -1
    
    271
    +
    
    272
    +    def do_command_line(self, command_line: Gio.ApplicationCommandLine) -> int:
    
    273
    +        Gtk.Application.do_command_line(self, command_line)
    
    274
    +        options = command_line.get_options_dict()
    
    275
    +        if options.contains('quiet'):
    
    276
    +            logging_helpers.set_quiet()
    
    277
    +        if options.contains('verbose'):
    
    278
    +            logging_helpers.set_verbose()
    
    279
    +        if options.contains('loglevel'):
    
    280
    +            string = options.lookup_value('loglevel').get_string()
    
    281
    +            logging_helpers.set_loglevels(string)
    
    282
    +        if not command_line.get_is_remote():
    
    283
    +            self.activate()
    
    284
    +        return 0
    
    285
    +
    
    286
    +    def frozen_logging(self, path):
    
    287
    +        import warnings
    
    288
    +        if not os.path.exists(path):
    
    289
    +            os.mkdir(path, 0o700)
    
    290
    +
    
    291
    +        class MyStd(object):
    
    292
    +            _file = None
    
    293
    +            _error = None
    
    294
    +            log_file = os.path.join(path, 'gajim.log')
    
    295
    +
    
    296
    +            def write(self, text):
    
    297
    +                if self._file is None and self._error is None:
    
    298
    +                    try:
    
    299
    +                        self._file = open(self.log_file, 'a')
    
    300
    +                    except Exception as details:
    
    301
    +                        self._error = details
    
    302
    +                if self._file is not None:
    
    303
    +                    self._file.write(text)
    
    304
    +                    self._file.flush()
    
    305
    +
    
    306
    +            def flush(self):
    
    307
    +                if self._file is not None:
    
    308
    +                    self._file.flush()
    
    309
    +
    
    310
    +            def isatty(self):
    
    311
    +                return False
    
    312
    +
    
    313
    +        outerr = MyStd()
    
    314
    +        sys.stdout = outerr
    
    315
    +        sys.stderr = outerr
    
    316
    +        warnings.filterwarnings(action='ignore')
    
    106 317
     
    
    107
    -from application import GajimApplication
    
    108 318
     
    
    109 319
     app = GajimApplication()
    
    110 320
     app.run(sys.argv)