def __init__(self): """ Conduit application class Parses command line arguments. Sets up the views and models; restores application settings, shows the splash screen and the UI Notes: 1) If conduit is launched without --console switch then the gui and the console interfaces are started 2) If launched with --console and then later via the gui then set up the gui and connect all the appropriate signal handlers """ self.splash = None self.gui = None self.statusIcon = None self.guiSyncSet = None self.uiLib = None gobject.set_application_name("Conduit") self.settingsFile = os.path.join(conduit.USER_DIR, "settings.xml") self.dbFile = os.path.join(conduit.USER_DIR, "mapping.db") #initialize application settings conduit.GLOBALS.settings = Settings() #command line parsing parser = optparse.OptionParser( prog="conduit", version="%%prog %s" % conduit.VERSION, description=_("Conduit is a synchronization application.")) parser.add_option( "-c", "--console", dest="build_gui", action="store_false", default=True, help=_("Launch without GUI. [default: %default]")) parser.add_option( "-f", "--config-file", metavar="FILE", default=self.settingsFile, help=_("Save dataprovider configuration to FILE. [default: %default]")) parser.add_option( "-i", "--iconify", action="store_true", default=False, help=_("Iconify on startup. [default: %default]")) parser.add_option( "-u", "--ui", metavar="NAME", default="gtk", help=_("Run with the specified UI. [default: %default]")) parser.add_option( "-w", "--with-modules", metavar="mod1,mod2", help=_("Only load modules in the named files. [default: load all modules]")) parser.add_option( "-x", "--without-modules", metavar="mod1,mod2", help=_("Do not load modules in the named files. [default: load all modules]")) parser.add_option( "-e", "--settings", metavar="key=val,key=val", help=_("Explicitly set internal Conduit settings (keys) to the given values for this session. [default: do not set]")) parser.add_option( "-U", "--enable-unsupported", action="store_true", default=False, help=_("Enable loading of unfinished or unsupported dataproviders. [default: %default]")) parser.add_option( "-d", "--debug", action="store_true", default=False, help=_("Generate more debugging information. [default: %default]")) parser.add_option( "-q", "--quiet", action="store_true", default=False, help=_("Generate less debugging information. [default: %default]")) parser.add_option( "-s", "--silent", action="store_true", default=False, help=_("Generate no debugging information. [default: %default]")) options, args = parser.parse_args() whitelist = None blacklist = None settings = {} if options.settings: for i in options.settings.split(','): k,v = i.split('=') settings[k] = v if options.with_modules: whitelist = options.with_modules.split(",") if options.without_modules: blacklist = options.without_modules.split(",") self.ui = options.ui self.settingsFile = os.path.abspath(options.config_file) if options.debug or not conduit.IS_INSTALLED: Logging.enable_debugging() if options.quiet: Logging.disable_debugging() if options.silent: Logging.disable_logging() log.info("Conduit v%s Installed: %s" % (conduit.VERSION, conduit.IS_INSTALLED)) log.info("Python: %s" % sys.version) log.info("Platform Implementations: %s,%s" % (conduit.BROWSER_IMPL, conduit.SETTINGS_IMPL)) if settings: log.info("Settings have been overridden: %s" % settings) #Make conduit single instance. If conduit is already running then #make the original process build or show the gui sessionBus = dbus.SessionBus() if Utils.dbus_service_available(APPLICATION_DBUS_IFACE, sessionBus): log.info("Conduit is already running") obj = sessionBus.get_object(APPLICATION_DBUS_IFACE, "/activate") conduitApp = dbus.Interface(obj, APPLICATION_DBUS_IFACE) if options.build_gui: if conduitApp.HasGUI(): conduitApp.ShowGUI() else: conduitApp.ImportGUI() conduitApp.ShowSplash() conduitApp.ShowStatusIcon() conduitApp.BuildGUI() conduitApp.ShowGUI() conduitApp.HideSplash() sys.exit(0) # Initialise dbus stuff here as any earlier will interfere # with Conduit already running check. bus_name = dbus.service.BusName(APPLICATION_DBUS_IFACE, bus=sessionBus) dbus.service.Object.__init__(self, bus_name, "/activate") #Throw up a splash screen ASAP. Dont show anything if launched via --console. if options.build_gui: log.info("Using UI: %s" % self.ui) self.ImportGUI() if not options.iconify: self.ShowSplash() self.ShowStatusIcon() #Dynamically load all datasources, datasinks and converters dirs_to_search = [ conduit.SHARED_MODULE_DIR, os.path.join(conduit.USER_DIR, "modules") ] if options.enable_unsupported: dirs_to_search.append(os.path.join(conduit.SHARED_MODULE_DIR, "UNSUPPORTED")) #Initialize all globals variables conduit.GLOBALS.app = self conduit.GLOBALS.moduleManager = ModuleManager(dirs_to_search) conduit.GLOBALS.moduleManager.load_all(whitelist, blacklist) conduit.GLOBALS.typeConverter = TypeConverter(conduit.GLOBALS.moduleManager) conduit.GLOBALS.syncManager = SyncManager(conduit.GLOBALS.typeConverter) conduit.GLOBALS.mappingDB = MappingDB(self.dbFile) conduit.GLOBALS.mainloop = gobject.MainLoop() #Build both syncsets and put on the bus as early as possible self.guiSyncSet = SyncSet( moduleManager=conduit.GLOBALS.moduleManager, syncManager=conduit.GLOBALS.syncManager, xmlSettingFilePath=self.settingsFile ) #Dbus view... conduit.GLOBALS.dbus = DBusInterface( conduitApplication=self, moduleManager=conduit.GLOBALS.moduleManager, typeConverter=conduit.GLOBALS.typeConverter, syncManager=conduit.GLOBALS.syncManager, guiSyncSet=self.guiSyncSet ) #Set the view models if options.build_gui: self.BuildGUI() if not options.iconify: self.ShowGUI() if self.statusIcon: dbusSyncSet = conduit.GLOBALS.dbus.get_syncset() dbusSyncSet.connect("conduit-added", self.statusIcon.on_conduit_added) dbusSyncSet.connect("conduit-removed", self.statusIcon.on_conduit_removed) #hide the splash screen self.HideSplash() try: conduit.GLOBALS.mainloop.run() except KeyboardInterrupt: self.Quit()
def __init__(self): """ Conduit application class Parses command line arguments. Sets up the views and models; restores application settings, shows the splash screen and the UI Notes: 1) If conduit is launched without --console switch then the gui and the console interfaces are started 2) If launched with --console and then later via the gui then set up the gui and connect all the appropriate signal handlers """ self.splash = None self.gui = None self.statusIcon = None self.dbus = None self.guiSyncSet = None self.dbusSyncSet = None self.uiLib = None gobject.set_application_name("Conduit") self.settingsFile = os.path.join(conduit.USER_DIR, "settings.xml") self.dbFile = os.path.join(conduit.USER_DIR, "mapping.db") # initialize application settings conduit.GLOBALS.settings = Settings() # command line parsing parser = optparse.OptionParser( prog="conduit", version="%%prog %s" % conduit.VERSION, description="Conduit is a synchronization application.", ) parser.add_option( "-c", "--console", dest="build_gui", action="store_false", default=True, help="Launch without GUI. [default: %default]", ) parser.add_option( "-f", "--config-file", metavar="FILE", default=self.settingsFile, help="Save dataprovider configuration to FILE. [default: %default]", ) parser.add_option( "-i", "--iconify", action="store_true", default=False, help="Iconify on startup. [default: %default]" ) parser.add_option( "-u", "--ui", metavar="NAME", default="gtk", help="Run with the specified UI. [default: %default]" ) parser.add_option( "-w", "--with-modules", metavar="mod1,mod2", help="Only load modules in the named files. [default: load all modules]", ) parser.add_option( "-x", "--without-modules", metavar="mod1,mod2", help="Do not load modules in the named files. [default: load all modules]", ) parser.add_option( "-s", "--settings", metavar="key=val,key=val", help="Explicitly set internal Conduit settings (keys) to the given values for this session. [default: do not set]", ) parser.add_option( "-U", "--enable-unsupported", action="store_true", default=False, help="Enable loading of unfinished or unsupported dataproviders. [default: %default]", ) options, args = parser.parse_args() whitelist = None blacklist = None settings = {} if options.settings: for i in options.settings.split(","): k, v = i.split("=") settings[k] = v if options.with_modules: whitelist = options.with_modules.split(",") if options.without_modules: blacklist = options.without_modules.split(",") self.ui = options.ui self.settingsFile = os.path.abspath(options.config_file) log.info("Conduit v%s Installed: %s" % (conduit.VERSION, conduit.IS_INSTALLED)) log.info("Python: %s" % sys.version) log.info( "Platform Implementations: %s,%s,%s" % (conduit.FILE_IMPL, conduit.BROWSER_IMPL, conduit.SETTINGS_IMPL) ) if settings: log.info("Settings have been overridden: %s" % settings) # Make conduit single instance. If conduit is already running then # make the original process build or show the gui sessionBus = dbus.SessionBus() if Utils.dbus_service_available(APPLICATION_DBUS_IFACE, sessionBus): log.info("Conduit is already running") obj = sessionBus.get_object(APPLICATION_DBUS_IFACE, "/activate") conduitApp = dbus.Interface(obj, APPLICATION_DBUS_IFACE) if options.build_gui: if conduitApp.HasGUI(): conduitApp.ShowGUI() else: conduitApp.ImportGUI() conduitApp.ShowSplash() conduitApp.ShowStatusIcon() conduitApp.BuildGUI() conduitApp.ShowGUI() conduitApp.HideSplash() sys.exit(0) # Initialise dbus stuff here as any earlier will interfere # with Conduit already running check. bus_name = dbus.service.BusName(APPLICATION_DBUS_IFACE, bus=sessionBus) dbus.service.Object.__init__(self, bus_name, "/activate") # Throw up a splash screen ASAP. Dont show anything if launched via --console. if options.build_gui: log.info("Using UI: %s" % self.ui) self.ImportGUI() if not options.iconify: self.ShowSplash() self.ShowStatusIcon() # Dynamically load all datasources, datasinks and converters dirs_to_search = [conduit.SHARED_MODULE_DIR, os.path.join(conduit.USER_DIR, "modules")] if options.enable_unsupported: dirs_to_search.append(os.path.join(conduit.SHARED_MODULE_DIR, "UNSUPPORTED")) # Initialize all globals variables conduit.GLOBALS.app = self conduit.GLOBALS.moduleManager = ModuleManager(dirs_to_search) conduit.GLOBALS.moduleManager.load_all(whitelist, blacklist) conduit.GLOBALS.typeConverter = TypeConverter(conduit.GLOBALS.moduleManager) conduit.GLOBALS.syncManager = SyncManager(conduit.GLOBALS.typeConverter) conduit.GLOBALS.mappingDB = MappingDB(self.dbFile) conduit.GLOBALS.mainloop = gobject.MainLoop() # Build both syncsets and put on the bus as early as possible self.guiSyncSet = SyncSet( moduleManager=conduit.GLOBALS.moduleManager, syncManager=conduit.GLOBALS.syncManager, xmlSettingFilePath=self.settingsFile, ) self.dbusSyncSet = SyncSet(moduleManager=conduit.GLOBALS.moduleManager, syncManager=conduit.GLOBALS.syncManager) # Set the view models if options.build_gui: self.BuildGUI() if not options.iconify: self.ShowGUI() # Dbus view... self.dbus = DBusInterface( conduitApplication=self, moduleManager=conduit.GLOBALS.moduleManager, typeConverter=conduit.GLOBALS.typeConverter, syncManager=conduit.GLOBALS.syncManager, guiSyncSet=self.guiSyncSet, dbusSyncSet=self.dbusSyncSet, ) if self.statusIcon: self.dbusSyncSet.connect("conduit-added", self.statusIcon.on_conduit_added) self.dbusSyncSet.connect("conduit-removed", self.statusIcon.on_conduit_removed) # hide the splash screen self.HideSplash() try: conduit.GLOBALS.mainloop.run() except KeyboardInterrupt: self.Quit()
class Application(dbus.service.Object): def __init__(self): """ Conduit application class Parses command line arguments. Sets up the views and models; restores application settings, shows the splash screen and the UI Notes: 1) If conduit is launched without --console switch then the gui and the console interfaces are started 2) If launched with --console and then later via the gui then set up the gui and connect all the appropriate signal handlers """ self.splash = None self.gui = None self.statusIcon = None self.guiSyncSet = None self.uiLib = None gobject.set_application_name("Conduit") self.settingsFile = os.path.join(conduit.USER_DIR, "settings.xml") self.dbFile = os.path.join(conduit.USER_DIR, "mapping.db") #initialize application settings conduit.GLOBALS.settings = Settings() #command line parsing parser = optparse.OptionParser( prog="conduit", version="%%prog %s" % conduit.VERSION, description=_("Conduit is a synchronization application.")) parser.add_option( "-c", "--console", dest="build_gui", action="store_false", default=True, help=_("Launch without GUI. [default: %default]")) parser.add_option( "-f", "--config-file", metavar="FILE", default=self.settingsFile, help=_("Save dataprovider configuration to FILE. [default: %default]")) parser.add_option( "-i", "--iconify", action="store_true", default=False, help=_("Iconify on startup. [default: %default]")) parser.add_option( "-u", "--ui", metavar="NAME", default="gtk", help=_("Run with the specified UI. [default: %default]")) parser.add_option( "-w", "--with-modules", metavar="mod1,mod2", help=_("Only load modules in the named files. [default: load all modules]")) parser.add_option( "-x", "--without-modules", metavar="mod1,mod2", help=_("Do not load modules in the named files. [default: load all modules]")) parser.add_option( "-e", "--settings", metavar="key=val,key=val", help=_("Explicitly set internal Conduit settings (keys) to the given values for this session. [default: do not set]")) parser.add_option( "-U", "--enable-unsupported", action="store_true", default=False, help=_("Enable loading of unfinished or unsupported dataproviders. [default: %default]")) parser.add_option( "-d", "--debug", action="store_true", default=False, help=_("Generate more debugging information. [default: %default]")) parser.add_option( "-q", "--quiet", action="store_true", default=False, help=_("Generate less debugging information. [default: %default]")) parser.add_option( "-s", "--silent", action="store_true", default=False, help=_("Generate no debugging information. [default: %default]")) options, args = parser.parse_args() whitelist = None blacklist = None settings = {} if options.settings: for i in options.settings.split(','): k,v = i.split('=') settings[k] = v if options.with_modules: whitelist = options.with_modules.split(",") if options.without_modules: blacklist = options.without_modules.split(",") self.ui = options.ui self.settingsFile = os.path.abspath(options.config_file) if options.debug or not conduit.IS_INSTALLED: Logging.enable_debugging() if options.quiet: Logging.disable_debugging() if options.silent: Logging.disable_logging() log.info("Conduit v%s Installed: %s" % (conduit.VERSION, conduit.IS_INSTALLED)) log.info("Python: %s" % sys.version) log.info("Platform Implementations: %s,%s" % (conduit.BROWSER_IMPL, conduit.SETTINGS_IMPL)) if settings: log.info("Settings have been overridden: %s" % settings) #Make conduit single instance. If conduit is already running then #make the original process build or show the gui sessionBus = dbus.SessionBus() if Utils.dbus_service_available(APPLICATION_DBUS_IFACE, sessionBus): log.info("Conduit is already running") obj = sessionBus.get_object(APPLICATION_DBUS_IFACE, "/activate") conduitApp = dbus.Interface(obj, APPLICATION_DBUS_IFACE) if options.build_gui: if conduitApp.HasGUI(): conduitApp.ShowGUI() else: conduitApp.ImportGUI() conduitApp.ShowSplash() conduitApp.ShowStatusIcon() conduitApp.BuildGUI() conduitApp.ShowGUI() conduitApp.HideSplash() sys.exit(0) # Initialise dbus stuff here as any earlier will interfere # with Conduit already running check. bus_name = dbus.service.BusName(APPLICATION_DBUS_IFACE, bus=sessionBus) dbus.service.Object.__init__(self, bus_name, "/activate") #Throw up a splash screen ASAP. Dont show anything if launched via --console. if options.build_gui: log.info("Using UI: %s" % self.ui) self.ImportGUI() if not options.iconify: self.ShowSplash() self.ShowStatusIcon() #Dynamically load all datasources, datasinks and converters dirs_to_search = [ conduit.SHARED_MODULE_DIR, os.path.join(conduit.USER_DIR, "modules") ] if options.enable_unsupported: dirs_to_search.append(os.path.join(conduit.SHARED_MODULE_DIR, "UNSUPPORTED")) #Initialize all globals variables conduit.GLOBALS.app = self conduit.GLOBALS.moduleManager = ModuleManager(dirs_to_search) conduit.GLOBALS.moduleManager.load_all(whitelist, blacklist) conduit.GLOBALS.typeConverter = TypeConverter(conduit.GLOBALS.moduleManager) conduit.GLOBALS.syncManager = SyncManager(conduit.GLOBALS.typeConverter) conduit.GLOBALS.mappingDB = MappingDB(self.dbFile) conduit.GLOBALS.mainloop = gobject.MainLoop() #Build both syncsets and put on the bus as early as possible self.guiSyncSet = SyncSet( moduleManager=conduit.GLOBALS.moduleManager, syncManager=conduit.GLOBALS.syncManager, xmlSettingFilePath=self.settingsFile ) #Dbus view... conduit.GLOBALS.dbus = DBusInterface( conduitApplication=self, moduleManager=conduit.GLOBALS.moduleManager, typeConverter=conduit.GLOBALS.typeConverter, syncManager=conduit.GLOBALS.syncManager, guiSyncSet=self.guiSyncSet ) #Set the view models if options.build_gui: self.BuildGUI() if not options.iconify: self.ShowGUI() if self.statusIcon: dbusSyncSet = conduit.GLOBALS.dbus.get_syncset() dbusSyncSet.connect("conduit-added", self.statusIcon.on_conduit_added) dbusSyncSet.connect("conduit-removed", self.statusIcon.on_conduit_removed) #hide the splash screen self.HideSplash() try: conduit.GLOBALS.mainloop.run() except KeyboardInterrupt: self.Quit() def get_syncset(self): return self.guiSyncSet @dbus.service.method(APPLICATION_DBUS_IFACE, in_signature='', out_signature='b') def HasGUI(self): return self.gui != None @dbus.service.method(APPLICATION_DBUS_IFACE, in_signature='', out_signature='') def BuildGUI(self): self.gui = self.uiLib.MainWindow( conduitApplication=self, moduleManager=conduit.GLOBALS.moduleManager, typeConverter=conduit.GLOBALS.typeConverter, syncManager=conduit.GLOBALS.syncManager ) #reload the saved sync set self.guiSyncSet.restore_from_xml() self.gui.set_model(self.guiSyncSet) if self.statusIcon: self.guiSyncSet.connect("conduit-added", self.statusIcon.on_conduit_added) self.guiSyncSet.connect("conduit-removed", self.statusIcon.on_conduit_removed) @dbus.service.method(APPLICATION_DBUS_IFACE, in_signature='', out_signature='') def ImportGUI(self): if self.uiLib == None: self.uiLib = __import__("conduit.%sui.UI" % self.ui, {}, {}, ['UI']) @dbus.service.method(APPLICATION_DBUS_IFACE, in_signature='', out_signature='') def ShowGUI(self): self.gui.present() @dbus.service.method(APPLICATION_DBUS_IFACE, in_signature='', out_signature='') def ShowStatusIcon(self): #The status icon is shared between the GUI and the Dbus iface if conduit.GLOBALS.settings.get("show_status_icon") == True: self.statusIcon = self.uiLib.StatusIcon(self) @dbus.service.method(APPLICATION_DBUS_IFACE, in_signature='', out_signature='') def ShowSplash(self): if conduit.GLOBALS.settings.get("show_splashscreen") == True: self.splash = self.uiLib.SplashScreen() self.splash.show() @dbus.service.method(APPLICATION_DBUS_IFACE, in_signature='', out_signature='') def HideSplash(self): if self.splash != None: self.splash.destroy() @dbus.service.method(APPLICATION_DBUS_IFACE, in_signature='', out_signature='') def IconifyGUI(self): self.gui.minimize_to_tray() @dbus.service.method(APPLICATION_DBUS_IFACE, in_signature='', out_signature='') def Quit(self): #Hide the GUI first, so we feel responsive log.info("Closing application") if self.gui != None: self.gui.mainWindow.hide() if conduit.GLOBALS.settings.get("save_on_exit") == True: self.gui.save_settings(None) #Cancel all syncs self.Cancel() #give the dataprovider factories time to shut down log.info("Closing dataprovider factories") conduit.GLOBALS.moduleManager.quit() #unitialize all dataproviders log.info("Unitializing dataproviders") for ss in conduit.GLOBALS.get_all_syncsets(): ss.quit() #Close any open DBus resources. Typically calling syncset.quit() will be #sufficient, except if a nasty DBus user has been creating Conduits #that are not included in any syncset. In that case they #will not be freed when syncset.quit() is called. dbus.quit() #calls quit() on all such conduits log.info("Closing DBus interface") conduit.GLOBALS.dbus.quit() #Save the mapping DB conduit.GLOBALS.mappingDB.save() conduit.GLOBALS.mappingDB.close() #Save the application settings conduit.GLOBALS.settings.save() log.info("Main Loop Quitting") conduit.GLOBALS.mainloop.quit() @dbus.service.method(APPLICATION_DBUS_IFACE, in_signature='', out_signature='') def Synchronize(self): for cond in self.guiSyncSet.get_all_conduits(): if cond.datasource is not None and len(cond.datasinks) > 0: conduit.GLOBALS.syncManager.sync_conduit(cond) else: log.info("Conduit must have a datasource and a datasink") @dbus.service.method(APPLICATION_DBUS_IFACE, in_signature='', out_signature='') def Cancel(self): #flag the global cancellation object log.info("Setting global cancel flag") conduit.GLOBALS.cancelled = True #cancel all conduits log.info("Stopping Synchronization threads") conduit.GLOBALS.syncManager.cancel_all()