From 819bee1253b9267dbdc13fca5407088201c2cfbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20H=C3=B6rist?= Date: Sat, 11 Feb 2017 18:08:52 +0100 Subject: [PATCH 1/9] Handle some commandline options only locally --- src/application.py | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/application.py b/src/application.py index 4ab29f3be..242e27ba7 100644 --- a/src/application.py +++ b/src/application.py @@ -224,6 +224,11 @@ class GajimApplication(Gtk.Application): 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 + if options.contains('separate'): + self.profile_separation = True + if options.contains('config-path'): + self.config_path = options.lookup_value('config-path').get_string() return -1 def do_command_line(self, command_line: Gio.ApplicationCommandLine) -> int: @@ -231,19 +236,10 @@ class GajimApplication(Gtk.Application): options = command_line.get_options_dict() if options.contains('quiet'): logging_helpers.set_quiet() - if options.contains('separate'): - self.profile_separation = True if options.contains('verbose'): logging_helpers.set_verbose() - if options.contains('profile'): - variant = options.lookup_value('profile') - self.profile = variant.get_string() if options.contains('loglevel'): - variant = options.lookup_value('loglevel') - string = variant.get_string() + string = options.lookup_value('loglevel').get_string() logging_helpers.set_loglevels(string) - if options.contains('config-path'): - variant = options.lookup_value('config-path') - self.config_path = variant.get_string() self.activate() return 0 From e30527f8cec508f937badedd46c1048a767ff7ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20H=C3=B6rist?= Date: Sat, 11 Feb 2017 19:38:45 +0100 Subject: [PATCH 2/9] Move Gajim startup code into do_startup --- src/application.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/application.py b/src/application.py index 242e27ba7..98bd38f26 100644 --- a/src/application.py +++ b/src/application.py @@ -44,6 +44,7 @@ class GajimApplication(Gtk.Application): def __init__(self): Gtk.Application.__init__(self, application_id='org.gajim.Gajim', flags=Gio.ApplicationFlags.HANDLES_COMMAND_LINE) + self.add_main_option('version', ord('V'), GLib.OptionFlags.NONE, GLib.OptionArg.NONE, _('Show the application\'s version')) @@ -85,15 +86,6 @@ class GajimApplication(Gtk.Application): def do_startup(self): Gtk.Application.do_startup(self) - def do_activate(self): - # If a second instance starts do_activate() is called - # We bringt the Roster window to the front, GTK exits afterwards. - if self.interface: - self.interface.roster.window.present() - return - - Gtk.Application.do_activate(self) - import gtkexcepthook gtkexcepthook.init() @@ -205,6 +197,14 @@ class GajimApplication(Gtk.Application): self.interface = Interface() self.interface.run(self) + def do_activate(self): + Gtk.Application.do_activate(self) + # If a second instance starts do_activate() is called + # We bringt the Roster window to the front, GTK exits afterwards. + if self.interface: + self.interface.roster.window.present() + return + def do_shutdown(self, *args): Gtk.Application.do_shutdown(self) # Save the entropy from OpenSSL PRNG From f9269d5ce076944ceb2c16d5d488d86f2a43adba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20H=C3=B6rist?= Date: Sat, 11 Feb 2017 20:57:03 +0100 Subject: [PATCH 3/9] Save log file into config dir when frozen --- src/application.py | 40 ++++++++++++++++++++++++++++++++++++---- src/gajim.py | 39 --------------------------------------- 2 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/application.py b/src/application.py index 98bd38f26..1d46b2e1b 100644 --- a/src/application.py +++ b/src/application.py @@ -59,10 +59,6 @@ class GajimApplication(Gtk.Application): GLib.OptionArg.NONE, _('Print XML stanzas and other debug ' 'information')) - self.add_main_option('windev', ord('w'), GLib.OptionFlags.NONE, - GLib.OptionArg.NONE, - _('Print stdout/stderr to the console ' - 'on Windows')) self.add_main_option('profile', ord('p'), GLib.OptionFlags.NONE, GLib.OptionArg.STRING, _('Use defined profile in configuration ' @@ -93,6 +89,10 @@ class GajimApplication(Gtk.Application): import common.configpaths common.configpaths.gajimpaths.init( self.config_path, self.profile, self.profile_separation) + + if hasattr(sys, 'frozen'): + self.frozen_logging(common.configpaths.gajimpaths.config_root) + from common import gajim from common import check_paths from common import exceptions @@ -243,3 +243,35 @@ class GajimApplication(Gtk.Application): logging_helpers.set_loglevels(string) self.activate() return 0 + + def frozen_logging(self, path): + import warnings + if not os.path.exists(path): + os.mkdir(path, 0o700) + + class MyStd(object): + _file = None + _error = None + log_file = os.path.join(path, 'gajim.log') + + def write(self, text): + if self._file is None and self._error is None: + try: + self._file = open(self.log_file, 'a') + except Exception as details: + self._error = details + if self._file is not None: + self._file.write(text) + self._file.flush() + + def flush(self): + if self._file is not None: + self._file.flush() + + def isatty(self): + return False + + outerr = MyStd() + sys.stdout = outerr + sys.stderr = outerr + warnings.filterwarnings(action='ignore') diff --git a/src/gajim.py b/src/gajim.py index 5560a9207..4f2002a25 100644 --- a/src/gajim.py +++ b/src/gajim.py @@ -36,51 +36,12 @@ ## import sys -import os if '--version' in sys.argv or '-V' in sys.argv: from common.defs import version print(version) sys.exit(0) -WINDEV = False -if '--windev' in sys.argv or '-w' in sys.argv: - WINDEV = True - -if os.name == 'nt' and not WINDEV: - import warnings - log_path = os.path.join(os.environ['APPDATA'], 'Gajim') - if not os.path.exists(log_path): - os.mkdir(log_path, 0o700) - log_file = os.path.join(log_path, 'gajim.log') - - class MyStd(object): - _file = None - _error = None - - def write(self, text): - if self._file is None and self._error is None: - try: - self._file = open(log_file, 'a') - except Exception as details: - self._error = details - if self._file is not None: - self._file.write(text) - self._file.flush() - - def flush(self): - if self._file is not None: - self._file.flush() - - def isatty(self): - return False - - outerr = MyStd() - sys.stdout = outerr - sys.stderr = outerr - warnings.filterwarnings(action='ignore') - - # Test here for all required versions so we dont have to # test multiple times in every module. nbxmpp also needs GLib. import gi From 4bf65a40395e8ff0d58f9ea7ae00ecf1e74d4235 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20H=C3=B6rist?= Date: Sat, 11 Feb 2017 21:09:31 +0100 Subject: [PATCH 4/9] Handle version option in Gtk.Application --- src/application.py | 4 ++++ src/gajim.py | 5 ----- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/application.py b/src/application.py index 1d46b2e1b..901412887 100644 --- a/src/application.py +++ b/src/application.py @@ -229,6 +229,10 @@ class GajimApplication(Gtk.Application): self.profile_separation = True if options.contains('config-path'): self.config_path = options.lookup_value('config-path').get_string() + if options.contains('version'): + from common.defs import version + print(version) + return 0 return -1 def do_command_line(self, command_line: Gio.ApplicationCommandLine) -> int: diff --git a/src/gajim.py b/src/gajim.py index 4f2002a25..f1c0aa324 100644 --- a/src/gajim.py +++ b/src/gajim.py @@ -37,11 +37,6 @@ import sys -if '--version' in sys.argv or '-V' in sys.argv: - from common.defs import version - print(version) - sys.exit(0) - # Test here for all required versions so we dont have to # test multiple times in every module. nbxmpp also needs GLib. import gi From 2ea30b3d559e0a8bd64148f86aba4f6769b7e01c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20H=C3=B6rist?= Date: Sat, 11 Feb 2017 21:18:10 +0100 Subject: [PATCH 5/9] Move nbxmpp import test into do_startup --- src/application.py | 14 ++++++++++++++ src/gajim.py | 13 ------------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/application.py b/src/application.py index 901412887..d18a1d824 100644 --- a/src/application.py +++ b/src/application.py @@ -37,6 +37,8 @@ except ImportError: logging_helpers.init(sys.stderr.isatty()) log = logging.getLogger('gajim.gajim') +MIN_NBXMPP_VER = "0.5.3" + class GajimApplication(Gtk.Application): '''Main class handling activation and command line.''' @@ -85,6 +87,18 @@ class GajimApplication(Gtk.Application): import gtkexcepthook gtkexcepthook.init() + try: + import nbxmpp + except ImportError: + print('Gajim needs python-nbxmpp to run. Quitting…') + sys.exit(1) + + from distutils.version import LooseVersion as V + if V(nbxmpp.__version__) < V(MIN_NBXMPP_VER): + print('Gajim needs python-nbxmpp >= %s to run. ' + 'Quitting…' % MIN_NBXMPP_VER) + sys.exit(1) + # Create and initialize Application Paths & Databases import common.configpaths common.configpaths.gajimpaths.init( diff --git a/src/gajim.py b/src/gajim.py index f1c0aa324..94e071765 100644 --- a/src/gajim.py +++ b/src/gajim.py @@ -47,19 +47,6 @@ gi.require_version('Gdk', '3.0') gi.require_version('GObject', '2.0') gi.require_version('Pango', '1.0') -MIN_NBXMPP_VER = "0.5.3" - -try: - import nbxmpp -except ImportError: - print('Gajim needs python-nbxmpp to run. Quiting…') - sys.exit(1) - -from distutils.version import LooseVersion as V -if V(nbxmpp.__version__) < V(MIN_NBXMPP_VER): - print('Gajim needs python-nbxmpp >= %s to run. Quiting…' % MIN_NBXMPP_VER) - sys.exit(1) - from application import GajimApplication app = GajimApplication() From 5215641c057dd87938823020755aa3c27d186c85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20H=C3=B6rist?= Date: Sat, 11 Feb 2017 21:25:43 +0100 Subject: [PATCH 6/9] Move GajimApplication into gajim.py --- src/application.py | 295 --------------------------------------------- src/gajim.py | 278 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 274 insertions(+), 299 deletions(-) delete mode 100644 src/application.py diff --git a/src/application.py b/src/application.py deleted file mode 100644 index d18a1d824..000000000 --- a/src/application.py +++ /dev/null @@ -1,295 +0,0 @@ -# -*- coding:utf-8 -*- -## src/application.py -## -## Copyright (C) 2016 Emmanuel Gil Peyrot -## -## This file is part of Gajim. -## -## Gajim is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published -## by the Free Software Foundation; version 3 only. -## -## Gajim is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Gajim. If not, see . -## - -import sys -import os -import logging -import signal -import locale -from gi.repository import GLib, Gio, Gtk -from common import i18n -from common import logging_helpers -from common import crypto -try: - PYOPENSSL_PRNG_PRESENT = True - import OpenSSL.rand -except ImportError: - print('PyOpenSSL not available, impossible to generate entropy', file=sys.stderr) - PYOPENSSL_PRNG_PRESENT = False - -logging_helpers.init(sys.stderr.isatty()) -log = logging.getLogger('gajim.gajim') - -MIN_NBXMPP_VER = "0.5.3" - - -class GajimApplication(Gtk.Application): - '''Main class handling activation and command line.''' - - def __init__(self): - Gtk.Application.__init__(self, application_id='org.gajim.Gajim', - flags=Gio.ApplicationFlags.HANDLES_COMMAND_LINE) - - self.add_main_option('version', ord('V'), GLib.OptionFlags.NONE, - GLib.OptionArg.NONE, - _('Show the application\'s version')) - self.add_main_option('quiet', ord('q'), GLib.OptionFlags.NONE, - GLib.OptionArg.NONE, - _('Show only critical errors')) - self.add_main_option('separate', ord('s'), GLib.OptionFlags.NONE, - GLib.OptionArg.NONE, - _('Separate profile files completely (even ' - 'history db and plugins)')) - self.add_main_option('verbose', ord('v'), GLib.OptionFlags.NONE, - GLib.OptionArg.NONE, - _('Print XML stanzas and other debug ' - 'information')) - self.add_main_option('profile', ord('p'), GLib.OptionFlags.NONE, - GLib.OptionArg.STRING, - _('Use defined profile in configuration ' - 'directory'), 'NAME') - self.add_main_option('config-path', ord('c'), GLib.OptionFlags.NONE, - GLib.OptionArg.STRING, - _('Set configuration directory'), 'PATH') - self.add_main_option('loglevel', ord('l'), GLib.OptionFlags.NONE, - GLib.OptionArg.STRING, - _('Configure logging system'), 'LEVEL') - - self.profile = '' - self.config_path = None - self.profile_separation = False - self.interface = None - self.rng_seed = None - - GLib.set_prgname('gajim') - GLib.set_application_name('Gajim') - - def do_startup(self): - Gtk.Application.do_startup(self) - - import gtkexcepthook - gtkexcepthook.init() - - try: - import nbxmpp - except ImportError: - print('Gajim needs python-nbxmpp to run. Quitting…') - sys.exit(1) - - from distutils.version import LooseVersion as V - if V(nbxmpp.__version__) < V(MIN_NBXMPP_VER): - print('Gajim needs python-nbxmpp >= %s to run. ' - 'Quitting…' % MIN_NBXMPP_VER) - sys.exit(1) - - # Create and initialize Application Paths & Databases - import common.configpaths - common.configpaths.gajimpaths.init( - self.config_path, self.profile, self.profile_separation) - - if hasattr(sys, 'frozen'): - self.frozen_logging(common.configpaths.gajimpaths.config_root) - - from common import gajim - from common import check_paths - from common import exceptions - from common import logger - from common import caps_cache - try: - gajim.logger = logger.Logger() - caps_cache.initialize(gajim.logger) - check_paths.check_and_possibly_create_paths() - except exceptions.DatabaseMalformed: - dlg = Gtk.MessageDialog( - None, - Gtk.DialogFlags.DESTROY_WITH_PARENT | Gtk.DialogFlags.MODAL, - Gtk.MessageType.ERROR, - Gtk.ButtonsType.OK, - _('Database Error')) - dlg.format_secondary_text( - _('The database file (%s) cannot be read. Try to repair it ' - '(see http://trac.gajim.org/wiki/DatabaseBackup) or remove it ' - '(all history will be lost).') % gajim.gajimpaths['LOG_DB']) - dlg.run() - dlg.destroy() - sys.exit() - - if os.name == 'nt': - import gettext - # needed for docutils - sys.path.append('.') - APP = 'gajim' - DIR = '../po' - lang, enc = locale.getdefaultlocale() - os.environ['LANG'] = lang - gettext.bindtextdomain(APP, DIR) - gettext.textdomain(APP) - gettext.install(APP, DIR) - - # This is for Windows translation which is currently not - # working on GTK 3.18.9 - # locale.setlocale(locale.LC_ALL, '') - # import ctypes - # import ctypes.util - # libintl_path = ctypes.util.find_library('intl') - # if libintl_path == None: - # local_intl = os.path.join('gtk', 'bin', 'intl.dll') - # if os.path.exists(local_intl): - # libintl_path = local_intl - # if libintl_path == None: - # raise ImportError('intl.dll library not found') - # 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_USER'], 'locale').encode(locale.getpreferredencoding()) - # libintl.bindtextdomain('gajim_plugins', plugins_locale_dir) - # libintl.bind_textdomain_codeset('gajim_plugins', 'UTF-8') - - if Gtk.Widget.get_default_direction() == Gtk.TextDirection.RTL: - i18n.direction_mark = '\u200F' - - from ctypes import CDLL - from ctypes.util import find_library - import platform - - sysname = platform.system() - if sysname in ('Linux', 'FreeBSD', 'OpenBSD', 'NetBSD'): - libc = CDLL(find_library('c')) - - # The constant defined in which is used to set the name - # of the process. - PR_SET_NAME = 15 - - if sysname == 'Linux': - libc.prctl(PR_SET_NAME, 'gajim') - elif sysname in ('FreeBSD', 'OpenBSD', 'NetBSD'): - libc.setproctitle('gajim') - - # Seed the OpenSSL pseudo random number generator from file and initialize - if PYOPENSSL_PRNG_PRESENT: - self.rng_seed = gajim.gajimpaths['RNG_SEED'] - # Seed from file - try: - OpenSSL.rand.load_file(self.rng_seed) - except TypeError: - OpenSSL.rand.load_file(self.rng_seed.encode('utf-8')) - crypto.add_entropy_sources_OpenSSL() - try: - OpenSSL.rand.write_file(self.rng_seed) - except TypeError: - OpenSSL.rand.write_file(self.rng_seed.encode('utf-8')) - - def sigint_cb(num, stack): - print('SIGINT/SIGTERM received') - self.quit() - # ^C exits the application normally - signal.signal(signal.SIGINT, sigint_cb) - signal.signal(signal.SIGTERM, sigint_cb) - - log.info("Encodings: d:%s, fs:%s, p:%s", sys.getdefaultencoding(), - sys.getfilesystemencoding(), locale.getpreferredencoding()) - - from gui_interface import Interface - self.interface = Interface() - self.interface.run(self) - - def do_activate(self): - Gtk.Application.do_activate(self) - # If a second instance starts do_activate() is called - # We bringt the Roster window to the front, GTK exits afterwards. - if self.interface: - self.interface.roster.window.present() - return - - def do_shutdown(self, *args): - Gtk.Application.do_shutdown(self) - # Save the entropy from OpenSSL PRNG - if PYOPENSSL_PRNG_PRESENT and self.rng_seed: - try: - OpenSSL.rand.write_file(self.rng_seed) - except TypeError: - OpenSSL.rand.write_file(self.rng_seed.encode('utf-8')) - # Shutdown GUI and save config - if hasattr(self.interface, 'roster') and self.interface.roster: - self.interface.roster.prepare_quit() - - def do_handle_local_options(self, options: GLib.VariantDict) -> int: - 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 - if options.contains('separate'): - self.profile_separation = True - if options.contains('config-path'): - self.config_path = options.lookup_value('config-path').get_string() - if options.contains('version'): - from common.defs import version - print(version) - return 0 - return -1 - - def do_command_line(self, command_line: Gio.ApplicationCommandLine) -> int: - Gtk.Application.do_command_line(self, command_line) - options = command_line.get_options_dict() - if options.contains('quiet'): - logging_helpers.set_quiet() - if options.contains('verbose'): - logging_helpers.set_verbose() - if options.contains('loglevel'): - string = options.lookup_value('loglevel').get_string() - logging_helpers.set_loglevels(string) - self.activate() - return 0 - - def frozen_logging(self, path): - import warnings - if not os.path.exists(path): - os.mkdir(path, 0o700) - - class MyStd(object): - _file = None - _error = None - log_file = os.path.join(path, 'gajim.log') - - def write(self, text): - if self._file is None and self._error is None: - try: - self._file = open(self.log_file, 'a') - except Exception as details: - self._error = details - if self._file is not None: - self._file.write(text) - self._file.flush() - - def flush(self): - if self._file is not None: - self._file.flush() - - def isatty(self): - return False - - outerr = MyStd() - sys.stdout = outerr - sys.stderr = outerr - warnings.filterwarnings(action='ignore') diff --git a/src/gajim.py b/src/gajim.py index 94e071765..4605b95e6 100644 --- a/src/gajim.py +++ b/src/gajim.py @@ -36,9 +36,10 @@ ## import sys - -# Test here for all required versions so we dont have to -# test multiple times in every module. nbxmpp also needs GLib. +import os +import logging +import signal +import locale import gi gi.require_version('GLib', '2.0') gi.require_version('Gio', '2.0') @@ -46,8 +47,277 @@ gi.require_version('Gtk', '3.0') gi.require_version('Gdk', '3.0') gi.require_version('GObject', '2.0') gi.require_version('Pango', '1.0') +from gi.repository import GLib, Gio, Gtk +from common import i18n +from common import logging_helpers +from common import crypto +try: + PYOPENSSL_PRNG_PRESENT = True + import OpenSSL.rand +except ImportError: + print('PyOpenSSL not available, impossible to generate entropy', file=sys.stderr) + PYOPENSSL_PRNG_PRESENT = False + +logging_helpers.init(sys.stderr.isatty()) +log = logging.getLogger('gajim.gajim') + +MIN_NBXMPP_VER = "0.5.3" + + +class GajimApplication(Gtk.Application): + '''Main class handling activation and command line.''' + + def __init__(self): + Gtk.Application.__init__(self, application_id='org.gajim.Gajim', + flags=Gio.ApplicationFlags.HANDLES_COMMAND_LINE) + + self.add_main_option('version', ord('V'), GLib.OptionFlags.NONE, + GLib.OptionArg.NONE, + _('Show the application\'s version')) + self.add_main_option('quiet', ord('q'), GLib.OptionFlags.NONE, + GLib.OptionArg.NONE, + _('Show only critical errors')) + self.add_main_option('separate', ord('s'), GLib.OptionFlags.NONE, + GLib.OptionArg.NONE, + _('Separate profile files completely (even ' + 'history db and plugins)')) + self.add_main_option('verbose', ord('v'), GLib.OptionFlags.NONE, + GLib.OptionArg.NONE, + _('Print XML stanzas and other debug ' + 'information')) + self.add_main_option('profile', ord('p'), GLib.OptionFlags.NONE, + GLib.OptionArg.STRING, + _('Use defined profile in configuration ' + 'directory'), 'NAME') + self.add_main_option('config-path', ord('c'), GLib.OptionFlags.NONE, + GLib.OptionArg.STRING, + _('Set configuration directory'), 'PATH') + self.add_main_option('loglevel', ord('l'), GLib.OptionFlags.NONE, + GLib.OptionArg.STRING, + _('Configure logging system'), 'LEVEL') + + self.profile = '' + self.config_path = None + self.profile_separation = False + self.interface = None + self.rng_seed = None + + GLib.set_prgname('gajim') + GLib.set_application_name('Gajim') + + def do_startup(self): + Gtk.Application.do_startup(self) + + import gtkexcepthook + gtkexcepthook.init() + + try: + import nbxmpp + except ImportError: + print('Gajim needs python-nbxmpp to run. Quitting…') + sys.exit(1) + + from distutils.version import LooseVersion as V + if V(nbxmpp.__version__) < V(MIN_NBXMPP_VER): + print('Gajim needs python-nbxmpp >= %s to run. ' + 'Quitting…' % MIN_NBXMPP_VER) + sys.exit(1) + + # Create and initialize Application Paths & Databases + import common.configpaths + common.configpaths.gajimpaths.init( + self.config_path, self.profile, self.profile_separation) + + if hasattr(sys, 'frozen'): + self.frozen_logging(common.configpaths.gajimpaths.config_root) + + from common import gajim + from common import check_paths + from common import exceptions + from common import logger + from common import caps_cache + try: + gajim.logger = logger.Logger() + caps_cache.initialize(gajim.logger) + check_paths.check_and_possibly_create_paths() + except exceptions.DatabaseMalformed: + dlg = Gtk.MessageDialog( + None, + Gtk.DialogFlags.DESTROY_WITH_PARENT | Gtk.DialogFlags.MODAL, + Gtk.MessageType.ERROR, + Gtk.ButtonsType.OK, + _('Database Error')) + dlg.format_secondary_text( + _('The database file (%s) cannot be read. Try to repair it ' + '(see http://trac.gajim.org/wiki/DatabaseBackup) or remove it ' + '(all history will be lost).') % gajim.gajimpaths['LOG_DB']) + dlg.run() + dlg.destroy() + sys.exit() + + if os.name == 'nt': + import gettext + # needed for docutils + sys.path.append('.') + APP = 'gajim' + DIR = '../po' + lang, enc = locale.getdefaultlocale() + os.environ['LANG'] = lang + gettext.bindtextdomain(APP, DIR) + gettext.textdomain(APP) + gettext.install(APP, DIR) + + # This is for Windows translation which is currently not + # working on GTK 3.18.9 + # locale.setlocale(locale.LC_ALL, '') + # import ctypes + # import ctypes.util + # libintl_path = ctypes.util.find_library('intl') + # if libintl_path == None: + # local_intl = os.path.join('gtk', 'bin', 'intl.dll') + # if os.path.exists(local_intl): + # libintl_path = local_intl + # if libintl_path == None: + # raise ImportError('intl.dll library not found') + # 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_USER'], 'locale').encode(locale.getpreferredencoding()) + # libintl.bindtextdomain('gajim_plugins', plugins_locale_dir) + # libintl.bind_textdomain_codeset('gajim_plugins', 'UTF-8') + + if Gtk.Widget.get_default_direction() == Gtk.TextDirection.RTL: + i18n.direction_mark = '\u200F' + + from ctypes import CDLL + from ctypes.util import find_library + import platform + + sysname = platform.system() + if sysname in ('Linux', 'FreeBSD', 'OpenBSD', 'NetBSD'): + libc = CDLL(find_library('c')) + + # The constant defined in which is used to set the name + # of the process. + PR_SET_NAME = 15 + + if sysname == 'Linux': + libc.prctl(PR_SET_NAME, 'gajim') + elif sysname in ('FreeBSD', 'OpenBSD', 'NetBSD'): + libc.setproctitle('gajim') + + # Seed the OpenSSL pseudo random number generator from file and initialize + if PYOPENSSL_PRNG_PRESENT: + self.rng_seed = gajim.gajimpaths['RNG_SEED'] + # Seed from file + try: + OpenSSL.rand.load_file(self.rng_seed) + except TypeError: + OpenSSL.rand.load_file(self.rng_seed.encode('utf-8')) + crypto.add_entropy_sources_OpenSSL() + try: + OpenSSL.rand.write_file(self.rng_seed) + except TypeError: + OpenSSL.rand.write_file(self.rng_seed.encode('utf-8')) + + def sigint_cb(num, stack): + print('SIGINT/SIGTERM received') + self.quit() + # ^C exits the application normally + signal.signal(signal.SIGINT, sigint_cb) + signal.signal(signal.SIGTERM, sigint_cb) + + log.info("Encodings: d:%s, fs:%s, p:%s", sys.getdefaultencoding(), + sys.getfilesystemencoding(), locale.getpreferredencoding()) + + from gui_interface import Interface + self.interface = Interface() + self.interface.run(self) + + def do_activate(self): + Gtk.Application.do_activate(self) + # If a second instance starts do_activate() is called + # We bringt the Roster window to the front, GTK exits afterwards. + if self.interface: + self.interface.roster.window.present() + return + + def do_shutdown(self, *args): + Gtk.Application.do_shutdown(self) + # Save the entropy from OpenSSL PRNG + if PYOPENSSL_PRNG_PRESENT and self.rng_seed: + try: + OpenSSL.rand.write_file(self.rng_seed) + except TypeError: + OpenSSL.rand.write_file(self.rng_seed.encode('utf-8')) + # Shutdown GUI and save config + if hasattr(self.interface, 'roster') and self.interface.roster: + self.interface.roster.prepare_quit() + + def do_handle_local_options(self, options: GLib.VariantDict) -> int: + 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 + if options.contains('separate'): + self.profile_separation = True + if options.contains('config-path'): + self.config_path = options.lookup_value('config-path').get_string() + if options.contains('version'): + from common.defs import version + print(version) + return 0 + return -1 + + def do_command_line(self, command_line: Gio.ApplicationCommandLine) -> int: + Gtk.Application.do_command_line(self, command_line) + options = command_line.get_options_dict() + if options.contains('quiet'): + logging_helpers.set_quiet() + if options.contains('verbose'): + logging_helpers.set_verbose() + if options.contains('loglevel'): + string = options.lookup_value('loglevel').get_string() + logging_helpers.set_loglevels(string) + self.activate() + return 0 + + def frozen_logging(self, path): + import warnings + if not os.path.exists(path): + os.mkdir(path, 0o700) + + class MyStd(object): + _file = None + _error = None + log_file = os.path.join(path, 'gajim.log') + + def write(self, text): + if self._file is None and self._error is None: + try: + self._file = open(self.log_file, 'a') + except Exception as details: + self._error = details + if self._file is not None: + self._file.write(text) + self._file.flush() + + def flush(self): + if self._file is not None: + self._file.flush() + + def isatty(self): + return False + + outerr = MyStd() + sys.stdout = outerr + sys.stderr = outerr + warnings.filterwarnings(action='ignore') -from application import GajimApplication app = GajimApplication() app.run(sys.argv) From 271af7088579d064c722b7632b5f8e2779db8aad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20H=C3=B6rist?= Date: Sat, 11 Feb 2017 21:32:13 +0100 Subject: [PATCH 7/9] Update Authors --- src/gajim.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gajim.py b/src/gajim.py index 4605b95e6..f9eaebe70 100644 --- a/src/gajim.py +++ b/src/gajim.py @@ -1,7 +1,7 @@ # -*- coding:utf-8 -*- ## src/gajim.py ## -## Copyright (C) 2003-2014 Yann Leboulanger +## Copyright (C) 2003-2017 Yann Leboulanger ## Copyright (C) 2004-2005 Vincent Hanquez ## Copyright (C) 2005 Alex Podaras ## Norman Rasmussen @@ -19,6 +19,8 @@ ## Julien Pivotto ## Stephan Erb ## Copyright (C) 2008 Jonathan Schleifer +## Copyright (C) 2016-2017 Emmanuel Gil Peyrot +## Philipp Hörist ## ## This file is part of Gajim. ## From 5789c8a8702b7f719b01bd004bff9100bd3f9beb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20H=C3=B6rist?= Date: Sat, 11 Feb 2017 23:31:06 +0100 Subject: [PATCH 8/9] Start Interface after remote cmdline handling Because otherwise we would lose log information from Interface, because logging levels are set after startup --- src/gajim.py | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/src/gajim.py b/src/gajim.py index f9eaebe70..d39d54e0f 100644 --- a/src/gajim.py +++ b/src/gajim.py @@ -230,20 +230,14 @@ class GajimApplication(Gtk.Application): signal.signal(signal.SIGINT, sigint_cb) signal.signal(signal.SIGTERM, sigint_cb) - log.info("Encodings: d:%s, fs:%s, p:%s", sys.getdefaultencoding(), - sys.getfilesystemencoding(), locale.getpreferredencoding()) - - from gui_interface import Interface - self.interface = Interface() - self.interface.run(self) + print("Encodings: d:{}, fs:{}, p:{}".format(sys.getdefaultencoding(), + sys.getfilesystemencoding(), locale.getpreferredencoding())) def do_activate(self): Gtk.Application.do_activate(self) - # If a second instance starts do_activate() is called - # We bringt the Roster window to the front, GTK exits afterwards. - if self.interface: - self.interface.roster.window.present() - return + from gui_interface import Interface + self.interface = Interface() + self.interface.run(self) def do_shutdown(self, *args): Gtk.Application.do_shutdown(self) @@ -285,7 +279,8 @@ class GajimApplication(Gtk.Application): if options.contains('loglevel'): string = options.lookup_value('loglevel').get_string() logging_helpers.set_loglevels(string) - self.activate() + if not command_line.get_is_remote(): + self.activate() return 0 def frozen_logging(self, path): From 33c9a1c58432927eae63df8f6eef5e9c8cd32f3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20H=C3=B6rist?= Date: Sat, 11 Feb 2017 23:40:42 +0100 Subject: [PATCH 9/9] Simplify module import --- src/gajim.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gajim.py b/src/gajim.py index d39d54e0f..76a43a024 100644 --- a/src/gajim.py +++ b/src/gajim.py @@ -126,12 +126,12 @@ class GajimApplication(Gtk.Application): sys.exit(1) # Create and initialize Application Paths & Databases - import common.configpaths - common.configpaths.gajimpaths.init( + from common import configpaths + configpaths.gajimpaths.init( self.config_path, self.profile, self.profile_separation) if hasattr(sys, 'frozen'): - self.frozen_logging(common.configpaths.gajimpaths.config_root) + self.frozen_logging(configpaths.gajimpaths.config_root) from common import gajim from common import check_paths