def register(): global MODULES paths = [ os.path.join(get_config_dir(), 'plugins'), os.path.dirname(__file__), # py2exe os.path.join( os.path.abspath(os.path.normpath(os.path.dirname(sys.argv[0]))), 'plugins'), ] paths = filter(os.path.isdir, paths) imported = set() for path in paths: for plugin in os.listdir(path): module = os.path.splitext(plugin)[0] if module == '__init__' or module in imported: continue try: module = imp.load_module(module, *imp.find_module(module, [path])) MODULES.append(module) except ImportError: continue else: imported.add(module.__name__)
def register(): global MODULES paths = [ os.path.join(get_config_dir(), 'plugins'), os.path.join(CURRENT_DIR, 'plugins'), ] paths = list(filter(os.path.isdir, paths)) imported = set() for path in paths: finder = importlib.machinery.FileFinder( path, ( importlib.machinery.SourceFileLoader, importlib.machinery.SOURCE_SUFFIXES)) for plugin in os.listdir(path): module = os.path.splitext(plugin)[0] if (module.startswith('_') or module in imported): continue module = 'tryton.plugins.%s' % module spec = finder.find_spec(module) if not spec: continue module = importlib.util.module_from_spec(spec) try: spec.loader.exec_module(module) except ImportError: continue else: MODULES.append(module) imported.add(module.__name__)
def main(): CSS = b""" .readonly entry { background-color: @insensitive_bg_color; } .required entry { border-color: darker(@unfocused_borders); } .invalid entry, entry.invalid { border-color: @error_color; } """ screen = Gdk.Screen.get_default() style_context = Gtk.StyleContext() provider = Gtk.CssProvider() provider.load_from_data(CSS) style_context.add_provider_for_screen( screen, provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION) theme_path = os.path.join(get_config_dir(), 'theme.css') if os.path.exists(theme_path): provider = Gtk.CssProvider() provider.load_from_path(theme_path) style_context.add_provider_for_screen(screen, provider, Gtk.STYLE_PROVIDER_PRIORITY_USER) def excepthook(type_, value, traceback_): common.error(str(value), ''.join(traceback.format_tb(traceback_))) sys.excepthook = excepthook CONFIG.parse() if CONFIG.arguments: url = CONFIG.arguments[0] urlp = urlparse(url) if urlp.scheme == 'tryton': urlp = urlparse('http' + url[6:]) database, _ = (urlp.path[1:].split('/', 1) + [None])[:2] CONFIG['login.host'] = urlp.netloc CONFIG['login.db'] = database CONFIG['login.expanded'] = True else: CONFIG.arguments = [] translate.set_language_direction(CONFIG['client.language_direction']) translate.setlang(CONFIG['client.lang']) common.ICONFACTORY.load_client_icons() if CONFIG.arguments or DBLogin().run(): server = '%(hostname)s:%(port)s/%(database)s' % { 'hostname': common.get_hostname(CONFIG['login.host']), 'port': common.get_port(CONFIG['login.host']), 'database': CONFIG['login.db'], } server = hashlib.md5(server.encode('utf-8')).hexdigest() application_id = 'org.tryton._' + server app = gui.Main(application_id=application_id, flags=Gio.ApplicationFlags.HANDLES_COMMAND_LINE) app.run([sys.argv[0]] + CONFIG.arguments)
def __init__(self, hostname, port, database): if Server.instance: Server.instance.stop() self.hostname = hostname self.port = port self.database = database self.config = os.path.join(get_config_dir(), '%s@%s@%s' % (self.hostname, self.port, self.database)) self.tmpdir = tempfile.mkdtemp(prefix='.tryton') Server.instance = self
def __init__(self, hostname, port, database): from tryton.common import slugify if Server.instance: Server.instance.stop() self.hostname = slugify(hostname).lower() self.port = port self.database = slugify(database) self.config = os.path.join(get_config_dir(), '%s@%s@%s' % (self.hostname, self.port, self.database)) self.tmpdir = tempfile.mkdtemp(prefix='.tryton') Server.instance = self
def run(self): main = gui.Main(self) signal.signal(signal.SIGINT, lambda signum, frame: main.sig_quit()) signal.signal(signal.SIGTERM, lambda signum, frame: main.sig_quit()) if hasattr(signal, 'SIGQUIT'): signal.signal(signal.SIGQUIT, lambda signum, frame: main.sig_quit()) def excepthook(exctyp, exception, tb): import common import traceback from tryton.exceptions import TrytonServerError if (CONFIG['sentry.dsn'] and not isinstance(exception, TrytonServerError)): log = logging.getLogger(__name__) log.error(''.join( traceback.format_exception(exctyp, exception, tb)) + '\n' + str(exception)) sentry = Client(CONFIG['sentry.dsn']) sentry_id = sentry.captureException((exctyp, exception, tb)) else: sentry_id = None tb = ''.join(traceback.format_exception(exctyp, exception, tb)) common.process_exception(exception, tb=tb, sentry_id=sentry_id) sys.excepthook = excepthook if CONFIG['tip.autostart']: main.sig_tips() main.sig_login() if sys.platform == 'win32': # http://faq.pygtk.org/index.py?req=show&file=faq21.003.htp def sleeper(): time.sleep(.001) return 1 gobject.timeout_add(400, sleeper) try: if sys.platform == 'win32': while not self.quit_client.isSet(): with gtk.gdk.lock: gtk.main_iteration(True) else: gtk.main() except KeyboardInterrupt: CONFIG.save() gtk.accel_map_save(os.path.join(get_config_dir(), 'accel.map'))
def run(self): main = gui.Main(self) signal.signal(signal.SIGINT, lambda signum, frame: main.sig_quit()) signal.signal(signal.SIGTERM, lambda signum, frame: main.sig_quit()) if hasattr(signal, "SIGQUIT"): signal.signal(signal.SIGQUIT, lambda signum, frame: main.sig_quit()) def excepthook(exctyp, exception, tb): import common import traceback from tryton.exceptions import TrytonServerError if CONFIG["sentry.dsn"] and not isinstance(exception, TrytonServerError): log = logging.getLogger(__name__) log.error("".join(traceback.format_exception(exctyp, exception, tb)) + "\n" + str(exception)) sentry = Client(CONFIG["sentry.dsn"]) sentry_id = sentry.captureException((exctyp, exception, tb)) else: sentry_id = None tb = "".join(traceback.format_exception(exctyp, exception, tb)) common.process_exception(exception, tb=tb, sentry_id=sentry_id) sys.excepthook = excepthook if CONFIG["tip.autostart"]: main.sig_tips() main.sig_login() if sys.platform == "win32": # http://faq.pygtk.org/index.py?req=show&file=faq21.003.htp def sleeper(): time.sleep(0.001) return 1 gobject.timeout_add(400, sleeper) try: if sys.platform == "win32": while not self.quit_client.isSet(): with gtk.gdk.lock: gtk.main_iteration(True) else: gtk.main() except KeyboardInterrupt: CONFIG.save() gtk.accel_map_save(os.path.join(get_config_dir(), "accel.map"))
def run(self): main = gui.Main(self) signal.signal(signal.SIGINT, lambda signum, frame: main.sig_quit()) signal.signal(signal.SIGTERM, lambda signum, frame: main.sig_quit()) if hasattr(signal, 'SIGQUIT'): signal.signal(signal.SIGQUIT, lambda signum, frame: main.sig_quit()) def excepthook(exctyp, exception, tb): import common import traceback tb = '\n'.join(traceback.format_tb(tb)) common.process_exception(exception, tb=tb) sys.excepthook = excepthook if CONFIG['tip.autostart']: main.sig_tips() main.sig_login() #XXX psyco breaks report printing #try: # import psyco # psyco.full() #except ImportError: # pass if sys.platform == 'win32': # http://faq.pygtk.org/index.py?req=show&file=faq21.003.htp def sleeper(): time.sleep(.001) return 1 gobject.timeout_add(400, sleeper) try: if sys.platform == 'win32': while not self.quit_client.isSet(): with gtk.gdk.lock: gtk.main_iteration(True) else: gtk.main() except KeyboardInterrupt: CONFIG.save() if hasattr(gtk, 'accel_map_save'): gtk.accel_map_save(os.path.join(get_config_dir(), 'accel.map'))
def run(self): main = gui.Main(self) signal.signal(signal.SIGINT, lambda signum, frame: main.sig_quit()) signal.signal(signal.SIGTERM, lambda signum, frame: main.sig_quit()) if hasattr(signal, 'SIGQUIT'): signal.signal(signal.SIGQUIT, lambda signum, frame: main.sig_quit()) def excepthook(*args): import common import traceback detail = ''.join(traceback.format_exception(*args)) common.error(str(args[1]), detail) sys.excepthook = excepthook # Remove Tips # if CONFIG['tip.autostart']: # main.sig_tips() main.sig_login() if sys.platform == 'win32': # http://faq.pygtk.org/index.py?req=show&file=faq21.003.htp def sleeper(): time.sleep(.001) return 1 gobject.timeout_add(400, sleeper) try: if sys.platform == 'win32': while not self.quit_client.isSet(): with gtk.gdk.lock: gtk.main_iteration() else: gtk.main() except KeyboardInterrupt: CONFIG.save() gtk.accel_map_save(os.path.join(get_config_dir(), 'accel.map'))
def register(): global MODULES paths = [ os.path.join(get_config_dir(), 'plugins'), os.path.join(CURRENT_DIR, 'plugins'), ] paths = filter(os.path.isdir, paths) imported = set() for path in paths: for plugin in os.listdir(path): module = os.path.splitext(plugin)[0] if module == '__init__' or module in imported: continue try: module = imp.load_module(module, *imp.find_module(module, [path])) MODULES.append(module) except ImportError: continue else: imported.add(module.__name__)
def register(): global MODULES paths = [ os.path.join(get_config_dir(), 'plugins'), os.path.join(CURRENT_DIR, 'plugins'), ] paths = list(filter(os.path.isdir, paths)) imported = set() for path in paths: for plugin in os.listdir(path): module = os.path.splitext(plugin)[0] if module == '__init__' or module in imported: continue try: module = imp.load_module(module, *imp.find_module(module, [path])) MODULES.append(module) except ImportError: continue else: imported.add(module.__name__)
def register(): global MODULES paths = [ os.path.join(get_config_dir(), 'plugins'), os.path.join(CURRENT_DIR, 'plugins'), ] paths = list(filter(os.path.isdir, paths)) imported = set() for path in paths: for plugin in os.listdir(path): module = os.path.splitext(plugin)[0] if (module.startswith('_') or module in imported): continue module = 'tryton.plugins.%s' % module try: module = importlib.import_module(module) MODULES.append(module) except ImportError: continue else: imported.add(module.__name__)
def __init__(self): # Fake windows to avoid warning about Dialog without transient self._window = Gtk.Window() self.dialog = Gtk.Dialog(title="Tryton - " + _('Login'), modal=True) self.dialog.set_transient_for(self._window) self.dialog.set_icon(TRYTON_ICON) self.dialog.set_position(Gtk.WindowPosition.CENTER_ALWAYS) self.dialog.set_resizable(False) tooltips = common.Tooltips() button_cancel = Gtk.Button(label=_('_Cancel'), use_underline=True) tooltips.set_tip(button_cancel, _('Cancel connection to the Tryton server')) self.dialog.add_action_widget(button_cancel, Gtk.ResponseType.CANCEL) self.button_connect = Gtk.Button(label=_('C_onnect'), use_underline=True) self.button_connect.get_style_context().add_class( Gtk.STYLE_CLASS_SUGGESTED_ACTION) self.button_connect.set_can_default(True) tooltips.set_tip(self.button_connect, _('Connect the Tryton server')) self.dialog.add_action_widget(self.button_connect, Gtk.ResponseType.OK) self.dialog.set_default_response(Gtk.ResponseType.OK) alignment = Gtk.Alignment(yalign=0, yscale=0, xscale=1) grid = Gtk.Grid(column_spacing=3, row_spacing=3) alignment.add(grid) self.dialog.vbox.pack_start(alignment, expand=True, fill=True, padding=0) image = Gtk.Image() image.set_from_file(os.path.join(PIXMAPS_DIR, 'tryton.png')) image.set_valign(Gtk.Align.START) overlay = Gtk.Overlay() overlay.add(image) label = Gtk.Label(label='<span color="white">%s</span>' % __version__, use_markup=True) label.props.halign = Gtk.Align.END label.props.valign = Gtk.Align.START label.props.margin_right = 10 label.props.margin_top = 5 overlay.add_overlay(label) grid.attach(overlay, 0, 0, 3, 1) self.profile_store = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_BOOLEAN) self.combo_profile = Gtk.ComboBox(hexpand=True) cell = Gtk.CellRendererText() self.combo_profile.pack_start(cell, expand=True) self.combo_profile.add_attribute(cell, 'text', 0) self.combo_profile.add_attribute(cell, 'sensitive', 1) self.combo_profile.set_model(self.profile_store) self.combo_profile.connect('changed', self.profile_changed) self.profile_label = Gtk.Label(label=set_underline(_('Profile:')), use_underline=True, halign=Gtk.Align.END) self.profile_label.set_mnemonic_widget(self.combo_profile) self.profile_button = Gtk.Button(label=set_underline(_('Manage...')), use_underline=True) self.profile_button.connect('clicked', self.profile_manage) grid.attach(self.profile_label, 0, 1, 1, 1) grid.attach(self.combo_profile, 1, 1, 1, 1) grid.attach(self.profile_button, 2, 1, 1, 1) self.expander = Gtk.Expander() self.expander.set_label(_('Host / Database information')) self.expander.connect('notify::expanded', self.expand_hostspec) grid.attach(self.expander, 0, 2, 3, 1) self.label_host = Gtk.Label(label=set_underline(_('Host:')), use_underline=True, halign=Gtk.Align.END) self.entry_host = Gtk.Entry(hexpand=True) self.entry_host.connect_after('focus-out-event', self.clear_profile_combo) self.entry_host.set_activates_default(True) self.label_host.set_mnemonic_widget(self.entry_host) grid.attach(self.label_host, 0, 3, 1, 1) grid.attach(self.entry_host, 1, 3, 2, 1) self.label_database = Gtk.Label(label=set_underline(_('Database:')), use_underline=True, halign=Gtk.Align.END) self.entry_database = Gtk.Entry(hexpand=True) self.entry_database.connect_after('focus-out-event', self.clear_profile_combo) self.entry_database.set_activates_default(True) self.label_database.set_mnemonic_widget(self.entry_database) grid.attach(self.label_database, 0, 4, 1, 1) grid.attach(self.entry_database, 1, 4, 2, 1) self.entry_login = Gtk.Entry(hexpand=True) self.entry_login.set_activates_default(True) grid.attach(self.entry_login, 1, 5, 2, 1) label_username = Gtk.Label(label=set_underline(_("User name:")), use_underline=True, halign=Gtk.Align.END, margin=3) label_username.set_mnemonic_widget(self.entry_login) grid.attach(label_username, 0, 5, 1, 1) # Date stuff if CONFIG['login.date']: self.label_date = Gtk.Label(label=set_underline(_("Date:")), use_underline=True, halign=Gtk.Align.END) grid.attach(self.label_date, 0, 6, 1, 1) self.entry_date = Date() self.entry_date.props.format = '%d/%m/%Y' self.entry_date.props.value = datetime.date.today() grid.attach(self.entry_date, 1, 6, 2, 1) # Profile information self.profile_cfg = os.path.join(get_config_dir(), 'profiles.cfg') self.profiles = configparser.ConfigParser() if not os.path.exists(self.profile_cfg): short_version = '.'.join(__version__.split('.', 2)[:2]) name = 'demo%s.tryton.org' % short_version self.profiles.add_section(name) self.profiles.set(name, 'host', name) self.profiles.set(name, 'database', 'demo%s' % short_version) self.profiles.set(name, 'username', 'demo') else: try: self.profiles.read(self.profile_cfg) except configparser.ParsingError: logger.error("Fail to parse profiles.cfg", exc_info=True) for section in self.profiles.sections(): active = all( self.profiles.has_option(section, option) for option in ('host', 'database')) self.profile_store.append([section, active])
def __init__(self, hostname, port, database): self.hostname = hostname self.port = port self.database = database self.filename = os.path.join(get_config_dir(), '%s@%s@%s' % (hostname, port, database))
def do_shutdown(self): Gtk.Application.do_shutdown(self) common.Logout() CONFIG.save() Gtk.AccelMap.save(os.path.join(get_config_dir(), 'accel.map'))
def main(): CSS = b""" .readonly entry, .readonly text { background-color: @insensitive_bg_color; } .required entry, .required text { border-color: darker(@unfocused_borders); } .invalid entry, entry.invalid, .invalid text, text.invalid { border-color: @error_color; } label.required { font-weight: bold; } label.editable { font-style: italic; } .window-title, .wizard-title { background-color: white; font-size: large; font-weight: bold; } .window-title .status { font-size: medium; font-weight: normal; } """ screen = Gdk.Screen.get_default() style_context = Gtk.StyleContext() provider = Gtk.CssProvider() # the line below injects CSS with higher priority than the custom theme # -> it overrides Coog theme behavior # provider.load_from_data(CSS) style_context.add_provider_for_screen(screen, provider, Gtk.STYLE_PROVIDER_PRIORITY_USER) theme_path = os.path.join(get_config_dir(), 'theme.css') if os.path.exists(theme_path): provider = Gtk.CssProvider() provider.load_from_path(theme_path) style_context.add_provider_for_screen(screen, provider, Gtk.STYLE_PROVIDER_PRIORITY_USER) def excepthook(type_, value, traceback_): common.error(value, ''.join(traceback.format_tb(traceback_))) sys.excepthook = excepthook CONFIG.parse() if CONFIG.arguments: url = CONFIG.arguments[0] urlp = urlparse(url) if urlp.scheme == 'tryton': urlp = urlparse('http' + url[6:]) database, _ = (urlp.path[1:].split('/', 1) + [None])[:2] CONFIG['login.host'] = urlp.netloc CONFIG['login.db'] = database CONFIG['login.expanded'] = True else: CONFIG.arguments = [] translate.set_language_direction(CONFIG['client.language_direction']) translate.setlang(CONFIG['client.lang']) if CONFIG.arguments or DBLogin().run(): server = '%(hostname)s:%(port)s/%(database)s' % { 'hostname': common.get_hostname(CONFIG['login.host']), 'port': common.get_port(CONFIG['login.host']), 'database': CONFIG['login.db'], } server = hashlib.md5(server.encode('utf-8')).hexdigest() application_id = 'org.tryton._' + server app = gui.Main(application_id=application_id, flags=Gio.ApplicationFlags.HANDLES_COMMAND_LINE) app.run([sys.argv[0]] + CONFIG.arguments)
from tryton.config import get_config_dir from tryton.exceptions import TrytonServerError, TrytonServerUnavailable from tryton.config import CONFIG CONNECTION = None _USER = None _USERNAME = '' _HOST = '' _PORT = None _CLIENT_DATE = None _DATABASE = '' CONTEXT = {} _VIEW_CACHE = {} _TOOLBAR_CACHE = {} _KEYWORD_CACHE = {} _CA_CERTS = os.path.join(get_config_dir(), 'ca_certs') if not os.path.isfile(_CA_CERTS): _CA_CERTS = None _FINGERPRINTS = Fingerprints() ServerProxy = partial(ServerProxy, fingerprints=_FINGERPRINTS, ca_certs=_CA_CERTS) ServerPool = partial(ServerPool, fingerprints=_FINGERPRINTS, ca_certs=_CA_CERTS) def context_reset(): CONTEXT.clear() CONTEXT['client'] = bus.ID
# This file is part of Tryton. The COPYRIGHT file at the top level of # this repository contains the full copyright notices and license terms. import os import json import logging from threading import Lock from tryton.config import get_config_dir, CONFIG logger = logging.getLogger(__name__) COOKIES_PATH = os.path.join(get_config_dir(), 'device_cookies') _lock = Lock() def renew(): from tryton.common import common def set_cookie(new_cookie): try: new_cookie = new_cookie() except Exception: logger.error("Cannot renew device cookie", exc_info=True) else: _set(new_cookie) current_cookie = get() common.RPCExecute('model', 'res.user.device', 'renew', current_cookie,
from tryton.config import CONFIG CONNECTION = None _USER = None _USERNAME = '' _SESSION = '' _HOST = '' _PORT = None _DATABASE = '' CONTEXT = {} _VIEW_CACHE = {} _TOOLBAR_CACHE = {} _KEYWORD_CACHE = {} TIMEZONE = 'utc' _SEMAPHORE = Semaphore() _CA_CERTS = os.path.join(get_config_dir(), 'ca_certs') if not os.path.isfile(_CA_CERTS): _CA_CERTS = None _FINGERPRINTS = Fingerprints() ServerProxy = partial(ServerProxy, fingerprints=_FINGERPRINTS, ca_certs=_CA_CERTS) def db_list(host, port): try: connection = ServerProxy(host, port) logging.getLogger(__name__).info('common.db.list(None, None)') result = connection.common.db.list(None, None) logging.getLogger(__name__).debug(repr(result)) return result
def __init__(self): # GTK Stuffs self.parent = common.get_toplevel_window() self.dialog = gtk.Dialog(title=_('Login'), parent=self.parent, flags=gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT) self.dialog.set_position(gtk.WIN_POS_CENTER_ON_PARENT) self.dialog.set_has_separator(True) self.dialog.set_icon(TRYTON_ICON) tooltips = common.Tooltips() button_cancel = gtk.Button(_('_Cancel')) img_cancel = gtk.Image() img_cancel.set_from_stock('gtk-cancel', gtk.ICON_SIZE_BUTTON) button_cancel.set_image(img_cancel) tooltips.set_tip(button_cancel, _('Cancel connection to the Tryton server')) self.dialog.add_action_widget(button_cancel, gtk.RESPONSE_CANCEL) self.button_connect = gtk.Button(_('C_onnect')) img_connect = gtk.Image() img_connect.set_from_stock('tryton-connect', gtk.ICON_SIZE_BUTTON) self.button_connect.set_image(img_connect) self.button_connect.set_flags(gtk.CAN_DEFAULT) tooltips.set_tip(self.button_connect, _('Connect the Tryton server')) self.dialog.add_action_widget(self.button_connect, gtk.RESPONSE_OK) self.dialog.set_default_response(gtk.RESPONSE_OK) alignment = gtk.Alignment(yalign=0, yscale=0, xscale=1) self.table_main = gtk.Table(3, 3, False) self.table_main.set_border_width(0) self.table_main.set_row_spacings(3) self.table_main.set_col_spacings(3) alignment.add(self.table_main) self.dialog.vbox.pack_start(alignment, True, True, 0) image = gtk.Image() image.set_from_file(os.path.join(PIXMAPS_DIR, 'tryton.png')) image.set_alignment(0.5, 1) ebox = gtk.EventBox() ebox.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#1b2019")) ebox.add(image) self.table_main.attach(ebox, 0, 3, 0, 1, ypadding=2) self.profile_store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_BOOLEAN) self.combo_profile = gtk.ComboBox() cell = gtk.CellRendererText() self.combo_profile.pack_start(cell, True) self.combo_profile.add_attribute(cell, 'text', 0) self.combo_profile.add_attribute(cell, 'sensitive', 1) self.combo_profile.set_model(self.profile_store) self.combo_profile.connect('changed', self.profile_changed) self.profile_label = gtk.Label(_(u'Profile:')) self.profile_label.set_justify(gtk.JUSTIFY_RIGHT) self.profile_label.set_alignment(1, 0.5) self.profile_label.set_padding(3, 3) self.profile_button = gtk.Button(_('_Manage profiles')) self.profile_button.connect('clicked', self.profile_manage) self.table_main.attach(self.profile_label, 0, 1, 1, 2, xoptions=gtk.FILL) self.table_main.attach(self.combo_profile, 1, 2, 1, 2) self.table_main.attach(self.profile_button, 2, 3, 1, 2, xoptions=gtk.FILL) image = gtk.Image() image.set_from_stock('gtk-edit', gtk.ICON_SIZE_BUTTON) self.profile_button.set_image(image) self.expander = gtk.Expander(_('Host / Database information')) self.expander.connect('notify::expanded', self.expand_hostspec) self.table_main.attach(self.expander, 0, 3, 3, 4) self.label_host = gtk.Label(_('Host:')) self.label_host.set_justify(gtk.JUSTIFY_RIGHT) self.label_host.set_alignment(1, 0.5) self.label_host.set_padding(3, 3) self.entry_host = gtk.Entry() self.entry_host.connect_after('focus-out-event', self.clear_profile_combo) self.entry_host.set_activates_default(True) self.label_host.set_mnemonic_widget(self.entry_host) self.table_main.attach(self.label_host, 0, 1, 4, 5, xoptions=gtk.FILL) self.table_main.attach(self.entry_host, 1, 3, 4, 5) self.label_database = gtk.Label(_('Database:')) self.label_database.set_justify(gtk.JUSTIFY_RIGHT) self.label_database.set_alignment(1, 0.5) self.label_database.set_padding(3, 3) self.entry_database = gtk.Entry() self.entry_database.connect_after('focus-out-event', self.clear_profile_combo) self.entry_database.set_activates_default(True) self.label_database.set_mnemonic_widget(self.entry_database) self.table_main.attach(self.label_database, 0, 1, 5, 6, xoptions=gtk.FILL) self.table_main.attach(self.entry_database, 1, 3, 5, 6) self.entry_password = gtk.Entry() self.entry_password.set_visibility(False) self.entry_password.set_activates_default(True) self.table_main.attach(self.entry_password, 1, 3, 7, 8) self.entry_login = gtk.Entry() self.entry_login.set_activates_default(True) self.table_main.attach(self.entry_login, 1, 3, 6, 7) label_password = gtk.Label(str=_("Password:"******"User name:")) label_username.set_alignment(1, 0.5) label_username.set_padding(3, 3) label_username.set_mnemonic_widget(self.entry_login) self.table_main.attach(label_username, 0, 1, 6, 7, xoptions=gtk.FILL) # Date stuff if CONFIG['login.date']: self.label_date = gtk.Label(str=_('Date:')) self.label_date.set_justify(gtk.JUSTIFY_RIGHT) self.label_date.set_alignment(1, .5) self.label_date.set_padding(3, 3) self.table_main.attach(self.label_date, 0, 1, 8, 9, xoptions=gtk.FILL) self.date_entry = Date() self.date_entry.props.format = '%d/%m/%Y' self.date_entry.props.value = datetime.date.today() self.table_main.attach(self.date_entry, 1, 3, 8, 9) # Profile informations self.profile_cfg = os.path.join(get_config_dir(), 'profiles.cfg') self.profiles = ConfigParser.SafeConfigParser({'port': '8000'}) if not os.path.exists(self.profile_cfg) and False: short_version = '.'.join(__version__.split('.', 2)[:2]) name = 'demo%s.tryton.org' % short_version self.profiles.add_section(name) self.profiles.set(name, 'host', name) self.profiles.set(name, 'port', '8000') self.profiles.set(name, 'database', 'demo%s' % short_version) self.profiles.set(name, 'username', 'demo') else: self.profiles.read(self.profile_cfg) for section in self.profiles.sections(): active = all(self.profiles.has_option(section, option) for option in ('host', 'port', 'database')) self.profile_store.append([section, active])
} .required entry { border-color: darker(@unfocused_borders); } .invalid entry { border-color: @error_color; } """ screen = Gdk.Screen.get_default() style_context = Gtk.StyleContext() provider = Gtk.CssProvider() provider.load_from_data(CSS) style_context.add_provider_for_screen(screen, provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION) theme_path = os.path.join(get_config_dir(), 'theme.css') if os.path.exists(theme_path): provider = Gtk.CssProvider() provider.load_from_path(theme_path) style_context.add_provider_for_screen(screen, provider, Gtk.STYLE_PROVIDER_PRIORITY_USER) class TrytonClient(object): "Tryton client" def __init__(self): CONFIG.parse() if CONFIG.arguments: url, = CONFIG.arguments urlp = urlparse(url)
def __init__(self): # GTK Stuffs self.parent = common.get_toplevel_window() self.dialog = gtk.Dialog(title=_('Login'), parent=self.parent, flags=gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT) self.dialog.set_position(gtk.WIN_POS_CENTER_ON_PARENT) self.dialog.set_icon(GNUHEALTH_ICON) tooltips = common.Tooltips() button_cancel = gtk.Button(_('_Cancel'), use_underline=True) img_cancel = gtk.Image() img_cancel.set_from_stock('gtk-cancel', gtk.ICON_SIZE_BUTTON) button_cancel.set_image(img_cancel) tooltips.set_tip(button_cancel, _('Cancel connection to the GNU Health server')) self.dialog.add_action_widget(button_cancel, gtk.RESPONSE_CANCEL) self.button_connect = gtk.Button(_('C_onnect'), use_underline=True) img_connect = gtk.Image() img_connect.set_from_stock('tryton-connect', gtk.ICON_SIZE_BUTTON) self.button_connect.set_image(img_connect) self.button_connect.set_can_default(True) tooltips.set_tip(self.button_connect, _('Connect the GNU Health server')) self.dialog.add_action_widget(self.button_connect, gtk.RESPONSE_OK) self.dialog.set_default_response(gtk.RESPONSE_OK) alignment = gtk.Alignment(yalign=0, yscale=0, xscale=1) self.table_main = gtk.Table(3, 3, False) self.table_main.set_border_width(0) self.table_main.set_row_spacings(3) self.table_main.set_col_spacings(3) alignment.add(self.table_main) self.dialog.vbox.pack_start(alignment, True, True, 0) image = gtk.Image() # Use custom banner if set in the custom_banner param if (CONFIG['client.banner']): image.set_from_file(CONFIG['client.banner']) else: image.set_from_file(os.path.join(PIXMAPS_DIR, BANNER)) image.set_alignment(0.5, 1) ebox = gtk.EventBox() ebox.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#1b2019")) ebox.add(image) self.table_main.attach(ebox, 0, 3, 0, 1, ypadding=2) self.profile_store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_BOOLEAN) self.combo_profile = gtk.ComboBox() cell = gtk.CellRendererText() self.combo_profile.pack_start(cell, True) self.combo_profile.add_attribute(cell, 'text', 0) self.combo_profile.add_attribute(cell, 'sensitive', 1) self.combo_profile.set_model(self.profile_store) self.combo_profile.connect('changed', self.profile_changed) self.profile_label = gtk.Label(_(u'Profile:')) self.profile_label.set_justify(gtk.JUSTIFY_RIGHT) self.profile_label.set_alignment(1, 0.5) self.profile_label.set_padding(3, 3) self.profile_button = gtk.Button(_('_Manage profiles'), use_underline=True) self.profile_button.connect('clicked', self.profile_manage) self.table_main.attach(self.profile_label, 0, 1, 1, 2, xoptions=gtk.FILL) self.table_main.attach(self.combo_profile, 1, 2, 1, 2) self.table_main.attach(self.profile_button, 2, 3, 1, 2, xoptions=gtk.FILL) image = gtk.Image() image.set_from_stock('gtk-edit', gtk.ICON_SIZE_BUTTON) self.profile_button.set_image(image) self.expander = gtk.Expander() self.expander.set_label(_('Host / Database information')) self.expander.connect('notify::expanded', self.expand_hostspec) self.table_main.attach(self.expander, 0, 3, 3, 4) self.label_host = gtk.Label(_('Host:')) self.label_host.set_justify(gtk.JUSTIFY_RIGHT) self.label_host.set_alignment(1, 0.5) self.label_host.set_padding(3, 3) self.entry_host = gtk.Entry() self.entry_host.connect_after('focus-out-event', self.clear_profile_combo) self.entry_host.set_activates_default(True) self.label_host.set_mnemonic_widget(self.entry_host) self.table_main.attach(self.label_host, 0, 1, 4, 5, xoptions=gtk.FILL) self.table_main.attach(self.entry_host, 1, 3, 4, 5) self.label_database = gtk.Label(_('Database:')) self.label_database.set_justify(gtk.JUSTIFY_RIGHT) self.label_database.set_alignment(1, 0.5) self.label_database.set_padding(3, 3) self.entry_database = gtk.Entry() self.entry_database.connect_after('focus-out-event', self.clear_profile_combo) self.entry_database.set_activates_default(True) self.label_database.set_mnemonic_widget(self.entry_database) self.table_main.attach(self.label_database, 0, 1, 5, 6, xoptions=gtk.FILL) self.table_main.attach(self.entry_database, 1, 3, 5, 6) self.entry_login = gtk.Entry() self.entry_login.set_activates_default(True) self.table_main.attach(self.entry_login, 1, 3, 6, 7) label_username = gtk.Label(_("User name:")) label_username.set_alignment(1, 0.5) label_username.set_padding(3, 3) label_username.set_mnemonic_widget(self.entry_login) self.table_main.attach(label_username, 0, 1, 6, 7, xoptions=gtk.FILL) # Profile informations self.profile_cfg = os.path.join(get_config_dir(), 'profiles.cfg') self.profiles = ConfigParser.SafeConfigParser({'port': '8000'}) if not os.path.exists(self.profile_cfg): short_version = '.'.join(__version__.split('.', 2)[:2]) name = 'health.gnusolidario.org' self.profiles.add_section(name) self.profiles.set(name, 'host', name) self.profiles.set(name, 'port', '8000') self.profiles.set(name, 'database', 'health32') self.profiles.set(name, 'username', 'admin') else: self.profiles.read(self.profile_cfg) for section in self.profiles.sections(): active = all(self.profiles.has_option(section, option) for option in ('host', 'port', 'database')) self.profile_store.append([section, active])
def do_activate(self): if self.window: self.window.present() return self.window = Gtk.ApplicationWindow(application=self, title="Tryton") self.window.set_default_size(960, 720) self.window.maximize() self.window.set_position(Gtk.WindowPosition.CENTER) self.window.set_resizable(True) self.window.set_icon(TRYTON_ICON) self.window.connect("destroy", self.on_quit) self.window.connect("delete_event", self.on_quit) common.setup_window(self.window) self.header = Gtk.HeaderBar.new() self.header.set_show_close_button(True) self.window.set_titlebar(self.header) self.set_title() self.primary_menu = Gtk.MenuButton.new() self.primary_menu.set_menu_model(self._get_primary_menu()) self.header.pack_end(self.primary_menu) menu = Gtk.Button.new() menu.set_relief(Gtk.ReliefStyle.NONE) menu.set_image( common.IconFactory.get_image('tryton-menu', Gtk.IconSize.BUTTON)) menu.connect('clicked', self.menu_toggle) self.header.pack_start(menu) favorite = Gtk.MenuButton.new() favorite.set_relief(Gtk.ReliefStyle.NONE) favorite.set_image( common.IconFactory.get_image('tryton-bookmarks', Gtk.IconSize.BUTTON)) self.menu_favorite = Gtk.Menu.new() favorite.set_popup(self.menu_favorite) favorite.connect('button-press-event', self.favorite_set) self.header.pack_start(favorite) self.set_global_search() self.header.pack_start(self.global_search_entry) self.accel_group = Gtk.AccelGroup() self.window.add_accel_group(self.accel_group) Gtk.AccelMap.add_entry('<tryton>/Form/New', Gdk.KEY_N, Gdk.ModifierType.CONTROL_MASK) Gtk.AccelMap.add_entry('<tryton>/Form/Save', Gdk.KEY_S, Gdk.ModifierType.CONTROL_MASK) Gtk.AccelMap.add_entry( '<tryton>/Form/Duplicate', Gdk.KEY_D, Gdk.ModifierType.CONTROL_MASK | Gdk.ModifierType.SHIFT_MASK) Gtk.AccelMap.add_entry('<tryton>/Form/Delete', Gdk.KEY_D, Gdk.ModifierType.CONTROL_MASK) Gtk.AccelMap.add_entry('<tryton>/Form/Next', Gdk.KEY_Page_Down, 0) Gtk.AccelMap.add_entry('<tryton>/Form/Previous', Gdk.KEY_Page_Up, 0) Gtk.AccelMap.add_entry('<tryton>/Form/Switch View', Gdk.KEY_L, Gdk.ModifierType.CONTROL_MASK) Gtk.AccelMap.add_entry('<tryton>/Form/Close', Gdk.KEY_W, Gdk.ModifierType.CONTROL_MASK) Gtk.AccelMap.add_entry('<tryton>/Form/Reload', Gdk.KEY_R, Gdk.ModifierType.CONTROL_MASK) Gtk.AccelMap.add_entry( '<tryton>/Form/Attachments', Gdk.KEY_T, Gdk.ModifierType.CONTROL_MASK | Gdk.ModifierType.SHIFT_MASK) Gtk.AccelMap.add_entry( '<tryton>/Form/Notes', Gdk.KEY_O, Gdk.ModifierType.CONTROL_MASK | Gdk.ModifierType.SHIFT_MASK) Gtk.AccelMap.add_entry( '<tryton>/Form/Relate', Gdk.KEY_R, Gdk.ModifierType.CONTROL_MASK | Gdk.ModifierType.SHIFT_MASK) Gtk.AccelMap.add_entry('<tryton>/Form/Actions', Gdk.KEY_E, Gdk.ModifierType.CONTROL_MASK) Gtk.AccelMap.add_entry('<tryton>/Form/Report', Gdk.KEY_P, Gdk.ModifierType.CONTROL_MASK) Gtk.AccelMap.add_entry( '<tryton>/Form/Email', Gdk.KEY_E, Gdk.ModifierType.CONTROL_MASK | Gdk.ModifierType.SHIFT_MASK) Gtk.AccelMap.add_entry( '<tryton>/Form/Search', Gdk.KEY_F, Gdk.ModifierType.CONTROL_MASK | Gdk.ModifierType.SHIFT_MASK) Gtk.AccelMap.load(os.path.join(get_config_dir(), 'accel.map')) self.tooltips = common.Tooltips() self.vbox = Gtk.VBox() self.window.add(self.vbox) self.buttons = {} self.info = Gtk.VBox() self.vbox.pack_start(self.info, expand=False, fill=True, padding=0) if CONFIG['client.check_version']: common.check_version(self.info) GLib.timeout_add_seconds(int(CONFIG['download.frequency']), common.check_version, self.info) self.pane = Gtk.HPaned() self.vbox.pack_start(self.pane, expand=True, fill=True, padding=0) self.pane.set_position(int(CONFIG['menu.pane'])) self.menu_screen = None self.menu = Gtk.VBox() self.menu.set_vexpand(True) self.pane.add1(self.menu) self.notebook = Gtk.Notebook() self.notebook.popup_enable() self.notebook.set_scrollable(True) self.notebook.connect_after('switch-page', self._sig_page_changt) self.pane.add2(self.notebook) self.window.show_all() self.pages = [] self.previous_pages = {} self.current_page = 0 self.last_page = 0 self.dialogs = [] # Register plugins tryton.plugins.register() self.set_title() # Adds username/profile while password is asked try: common.Login() except Exception as exception: if (not isinstance(exception, TrytonError) or exception.faultCode != 'QueryCanceled'): common.error(exception, traceback.format_exc()) return self.quit() self.get_preferences()
def __init__(self): # Fake windows to avoid warning about Dialog without transient self._window = gtk.Window() self.dialog = gtk.Dialog(title=_('Login'), flags=gtk.DIALOG_MODAL) self.dialog.set_transient_for(self._window) self.dialog.set_icon(TRYTON_ICON) self.dialog.set_position(gtk.WIN_POS_CENTER_ALWAYS) tooltips = common.Tooltips() button_cancel = gtk.Button(_('_Cancel'), use_underline=True) tooltips.set_tip(button_cancel, _('Cancel connection to the Tryton server')) self.dialog.add_action_widget(button_cancel, gtk.RESPONSE_CANCEL) self.button_connect = gtk.Button(_('C_onnect'), use_underline=True) self.button_connect.get_style_context().add_class( Gtk.STYLE_CLASS_SUGGESTED_ACTION) self.button_connect.set_can_default(True) tooltips.set_tip(self.button_connect, _('Connect the Tryton server')) self.dialog.add_action_widget(self.button_connect, gtk.RESPONSE_OK) self.dialog.set_default_response(gtk.RESPONSE_OK) alignment = gtk.Alignment(yalign=0, yscale=0, xscale=1) self.table_main = gtk.Table(3, 3, False) self.table_main.set_border_width(0) self.table_main.set_row_spacings(3) self.table_main.set_col_spacings(3) alignment.add(self.table_main) self.dialog.vbox.pack_start(alignment, True, True, 0) image = gtk.Image() image.set_from_file(os.path.join(PIXMAPS_DIR, 'tryton.png')) image.set_alignment(0.5, 1) ebox = gtk.EventBox() ebox.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#1b2019")) ebox.add(image) self.table_main.attach(ebox, 0, 3, 0, 1, ypadding=2) self.profile_store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_BOOLEAN) self.combo_profile = gtk.ComboBox() cell = gtk.CellRendererText() self.combo_profile.pack_start(cell, True) self.combo_profile.add_attribute(cell, 'text', 0) self.combo_profile.add_attribute(cell, 'sensitive', 1) self.combo_profile.set_model(self.profile_store) self.combo_profile.connect('changed', self.profile_changed) self.profile_label = gtk.Label(set_underline(_('Profile:'))) self.profile_label.set_use_underline(True) self.profile_label.set_justify(gtk.JUSTIFY_RIGHT) self.profile_label.set_alignment(1, 0.5) self.profile_label.set_padding(3, 3) self.profile_label.set_mnemonic_widget(self.combo_profile) self.profile_button = gtk.Button(set_underline(_('Manage...')), use_underline=True) self.profile_button.connect('clicked', self.profile_manage) self.table_main.attach(self.profile_label, 0, 1, 1, 2, xoptions=gtk.FILL) self.table_main.attach(self.combo_profile, 1, 2, 1, 2) self.table_main.attach(self.profile_button, 2, 3, 1, 2, xoptions=gtk.FILL) self.expander = gtk.Expander() self.expander.set_label(_('Host / Database information')) self.expander.connect('notify::expanded', self.expand_hostspec) self.table_main.attach(self.expander, 0, 3, 3, 4) self.label_host = gtk.Label(set_underline(_('Host:'))) self.label_host.set_use_underline(True) self.label_host.set_justify(gtk.JUSTIFY_RIGHT) self.label_host.set_alignment(1, 0.5) self.label_host.set_padding(3, 3) self.entry_host = gtk.Entry() self.entry_host.connect_after('focus-out-event', self.clear_profile_combo) self.entry_host.set_activates_default(True) self.label_host.set_mnemonic_widget(self.entry_host) self.table_main.attach(self.label_host, 0, 1, 4, 5, xoptions=gtk.FILL) self.table_main.attach(self.entry_host, 1, 3, 4, 5) self.label_database = gtk.Label(set_underline(_('Database:'))) self.label_database.set_use_underline(True) self.label_database.set_justify(gtk.JUSTIFY_RIGHT) self.label_database.set_alignment(1, 0.5) self.label_database.set_padding(3, 3) self.entry_database = gtk.Entry() self.entry_database.connect_after('focus-out-event', self.clear_profile_combo) self.entry_database.set_activates_default(True) self.label_database.set_mnemonic_widget(self.entry_database) self.table_main.attach(self.label_database, 0, 1, 5, 6, xoptions=gtk.FILL) self.table_main.attach(self.entry_database, 1, 3, 5, 6) self.entry_login = gtk.Entry() self.entry_login.set_activates_default(True) self.table_main.attach(self.entry_login, 1, 3, 6, 7) label_username = gtk.Label(set_underline(_("User name:"))) label_username.set_use_underline(True) label_username.set_alignment(1, 0.5) label_username.set_padding(3, 3) label_username.set_mnemonic_widget(self.entry_login) self.table_main.attach(label_username, 0, 1, 6, 7, xoptions=gtk.FILL) # Date stuff if CONFIG['login.date']: self.label_date = gtk.Label() self.label_date.set_text('Date:') self.label_date.set_justify(gtk.JUSTIFY_RIGHT) self.label_date.set_alignment(1, .5) self.label_date.set_padding(3, 3) self.table_main.attach(self.label_date, 0, 1, 8, 9, xoptions=gtk.FILL) self.entry_date = Date() self.entry_date.props.format = '%d/%m/%Y' self.entry_date.props.value = datetime.date.today() self.table_main.attach(self.entry_date, 1, 3, 8, 9) # Profile informations self.profile_cfg = os.path.join(get_config_dir(), 'profiles.cfg') self.profiles = configparser.ConfigParser() if not os.path.exists(self.profile_cfg): short_version = '.'.join(__version__.split('.', 2)[:2]) name = 'demo%s.tryton.org' % short_version self.profiles.add_section(name) self.profiles.set(name, 'host', name) self.profiles.set(name, 'database', 'demo%s' % short_version) self.profiles.set(name, 'username', 'demo') else: try: self.profiles.read(self.profile_cfg) except configparser.ParsingError: logger.error("Fail to parse profiles.cfg", exc_info=True) for section in self.profiles.sections(): active = all(self.profiles.has_option(section, option) for option in ('host', 'database')) self.profile_store.append([section, active])
def do_activate(self): if self.window: self.window.present() return self.window = Gtk.ApplicationWindow(application=self, title="Tryton") self.window.set_default_size(960, 720) self.window.maximize() self.window.set_position(Gtk.WIN_POS_CENTER) self.window.set_resizable(True) self.window.set_icon(TRYTON_ICON) self.window.connect("destroy", self.on_quit) self.window.connect("delete_event", self.on_quit) self.header = Gtk.HeaderBar.new() self.header.set_show_close_button(True) self.window.set_titlebar(self.header) self.set_title() menu = Gtk.Button.new() menu.set_relief(Gtk.ReliefStyle.NONE) icon = Gtk.Image.new() icon.set_from_stock('gtk-home', Gtk.IconSize.BUTTON) menu.set_image(icon) menu.connect('clicked', self.menu_toggle) self.header.pack_start(menu) favorite = Gtk.MenuButton.new() favorite.set_relief(Gtk.ReliefStyle.NONE) icon = Gtk.Image.new() icon.set_from_stock('tryton-bookmark', Gtk.IconSize.BUTTON) favorite.set_image(icon) self.menu_favorite = Gtk.Menu.new() favorite.set_popup(self.menu_favorite) favorite.connect('clicked', self.favorite_set) self.header.pack_start(favorite) self.set_global_search() self.header.pack_start(self.global_search_entry) self.accel_group = Gtk.AccelGroup() self.window.add_accel_group(self.accel_group) gtk.accel_map_add_entry('<tryton>/Form/New', gtk.keysyms.I, gtk.gdk.CONTROL_MASK) gtk.accel_map_add_entry('<tryton>/Form/Save', gtk.keysyms.S, gtk.gdk.CONTROL_MASK) gtk.accel_map_add_entry('<tryton>/Form/Duplicate', gtk.keysyms.D, gtk.gdk.CONTROL_MASK | gtk.gdk.SHIFT_MASK) gtk.accel_map_add_entry('<tryton>/Form/Delete', gtk.keysyms.D, gtk.gdk.CONTROL_MASK) gtk.accel_map_add_entry('<tryton>/Form/Next', gtk.keysyms.Page_Down, 0) gtk.accel_map_add_entry('<tryton>/Form/Previous', gtk.keysyms.Page_Up, 0) gtk.accel_map_add_entry('<tryton>/Form/Switch View', gtk.keysyms.L, gtk.gdk.CONTROL_MASK) gtk.accel_map_add_entry('<tryton>/Form/Close', gtk.keysyms.W, gtk.gdk.CONTROL_MASK | gtk.gdk.SHIFT_MASK) gtk.accel_map_add_entry('<tryton>/Form/Reload', gtk.keysyms.R, gtk.gdk.CONTROL_MASK) gtk.accel_map_add_entry('<tryton>/Form/Attachments', gtk.keysyms.T, gtk.gdk.CONTROL_MASK | gtk.gdk.SHIFT_MASK) gtk.accel_map_add_entry('<tryton>/Form/Notes', gtk.keysyms.O, gtk.gdk.CONTROL_MASK | gtk.gdk.SHIFT_MASK) gtk.accel_map_add_entry('<tryton>/Form/Relate', gtk.keysyms.R, gtk.gdk.CONTROL_MASK | gtk.gdk.SHIFT_MASK) gtk.accel_map_add_entry('<tryton>/Form/Actions', gtk.keysyms.E, gtk.gdk.CONTROL_MASK) gtk.accel_map_add_entry('<tryton>/Form/Report', gtk.keysyms.P, gtk.gdk.CONTROL_MASK) gtk.accel_map_add_entry('<tryton>/Form/Search', gtk.keysyms.F, gtk.gdk.CONTROL_MASK) gtk.accel_map_load(os.path.join(get_config_dir(), 'accel.map')) self.tooltips = common.Tooltips() self.vbox = gtk.VBox() self.window.add(self.vbox) self.buttons = {} self.info = gtk.VBox() self.vbox.pack_start(self.info, expand=False) if CONFIG['client.check_version']: common.check_version(self.info) GLib.timeout_add_seconds(int(CONFIG['download.frequency']), common.check_version, self.info) self.pane = gtk.HPaned() self.vbox.pack_start(self.pane, True, True) self.pane.set_position(int(CONFIG['menu.pane'])) self.menu_screen = None self.menu = gtk.VBox() self.menu.set_vexpand(True) self.pane.add1(self.menu) self.notebook = gtk.Notebook() self.notebook.popup_enable() self.notebook.set_scrollable(True) self.notebook.connect_after('switch-page', self._sig_page_changt) self.pane.add2(self.notebook) self.window.show_all() self.pages = [] self.previous_pages = {} self.current_page = 0 self.last_page = 0 self.dialogs = [] # Register plugins tryton.plugins.register() self.set_title() # Adds username/profile while password is asked try: common.Login() except Exception as exception: if (not isinstance(exception, TrytonError) or exception.faultCode != 'QueryCanceled'): common.error(str(exception), traceback.format_exc()) return self.quit() self.get_preferences()
# This file is part of Tryton. The COPYRIGHT file at the top level of # this repository contains the full copyright notices and license terms. import os from tryton.config import get_config_dir KNOWN_HOSTS_PATH = os.path.join(get_config_dir(), 'known_hosts') class Fingerprints(dict): def __init__(self): super(Fingerprints, self).__init__() self.load() def load(self): if not os.path.isfile(KNOWN_HOSTS_PATH): return with open(KNOWN_HOSTS_PATH) as known_hosts: for line in known_hosts: line = line.strip() try: host, sha1 = line.split(' ') except ValueError: host, sha1 = line, '' self[host] = sha1 def save(self): with open(KNOWN_HOSTS_PATH, 'w') as known_hosts: known_hosts.writelines('%s %s' % (host, sha1) + os.linesep for host, sha1 in self.iteritems())