def __init__(self): """ Creates a dictionary of the currently available backend modules """ super().__init__() if hasattr(self, "backend_modules"): # This object has already been constructed return self.backend_modules = {} backend_files = self._find_backend_files() # Create module names module_names = [f.replace(".py", "") for f in backend_files] log.debug("Backends found: " + str(module_names)) # Load backend modules for module_name in module_names: extended_module_name = "GTG.backends." + module_name try: __import__(extended_module_name) except ImportError as exception: # Something is wrong with this backend, skipping log.warning("Backend %s could not be loaded: %s" % (module_name, str(exception))) continue except Exception as exception: # Other exception log as errors log.error("Malformated backend %s: %s" % (module_name, str(exception))) continue self.backend_modules[module_name] = \ sys.modules[extended_module_name]
def get_configuration(self): try: return datetime.time(int(self.config.get('hour')), int(self.config.get('min'))) except (ValueError): log.error("Invalid time values: %s:%s", self.config.get('hour'), self.config.get('min')) return datetime.time(0, 0)
def _when_taking_too_long(self): """ Function that is executed when the Dbus connection seems to be hanging. It disables the backend and signals the error to the user. """ log.error("Dbus connection is taking too long for the Tomboy/Gnote" "backend!") BackendSignals().backend_failed(self.backend.get_id(), BackendSignals.ERRNO_DBUS) self.backend.quit(disable=True)
def _login(self): """ Tries to establish a connection to rtm with a token got from the authentication process """ try: self.rtm = createRTM(self.PUBLIC_KEY, self.PRIVATE_KEY, self.token) self.timeline = self.rtm.timelines.create().timeline return True except (RTMError, RTMAPIError) as e: log.error("RTM ERROR" + str(e)) return False
def callMethod(self, aname, rargs, oargs, **params): # Sanity checks for requiredArg in rargs: if requiredArg not in params: raise TypeError('Required parameter (%s) missing' % requiredArg) for param in params: if param not in rargs + oargs: log.error('Invalid parameter (%s)' % param) return self.rtm.get(method=aname, auth_token=self.rtm.authInfo.get('token'), **params)
def __load_icon(self): """ Loads emblem icons from the current icon theme Sometimes an icon can't be loaded because of a bug in system libraries, e.g. bug #1079587. Gracefuly degradate and skip the loading of a corrupted icon. """ self.symbol_model = Gtk.ListStore(GdkPixbuf.Pixbuf, str) for icon in Gtk.IconTheme.get_default().list_icons(context="Emblems"): try: img = Gtk.IconTheme.get_default().load_icon(icon, 16, 0) self.symbol_model.append([img, icon]) except GObject.GError: log.error("Failed to load icon '%s'" % icon) self.symbol_iv.set_model(self.symbol_model) self.loaded = True
def save(self, quit=False): """ Saves the backends parameters. @param quit: If quit is true, backends are shut down """ try: self.start_get_tasks_thread.join() except Exception: pass doc, xmlconfig = cleanxml.emptydoc("config") # we ask all the backends to quit first. if quit: # we quit backends in parallel threads_dic = {} for b in self.get_all_backends(): thread = threading.Thread(target=b.quit) threads_dic[b.get_id()] = thread thread.start() for backend_id, thread in threads_dic.items(): # after 20 seconds, we give up thread.join(20) if thread.isAlive(): log.error("The %s backend stalled while quitting", backend_id) # we save the parameters for b in self.get_all_backends(disabled=True): t_xml = doc.createElement("backend") for key, value in b.get_parameters().items(): if key in ["backend", "xmlobject"]: # We don't want parameters, backend, xmlobject: # we'll create them at next startup continue param_type = b.get_parameter_type(key) value = b.cast_param_type_to_string(param_type, value) t_xml.setAttribute(str(key), value) # Saving all the projects at close xmlconfig.appendChild(t_xml) cleanxml.savexml(PROJECTS_XMLFILE, doc, backup=True) # Saving the tagstore self.save_tagtree()
def register_backend(self, backend_dic): """ Registers a TaskSource as a backend for this DataStore @param backend_dic: Dictionary object containing all the parameters to initialize the backend (filename...). It should also contain the backend class (under "backend"), and its unique id (under "pid") """ if "backend" in backend_dic: if "pid" not in backend_dic: log.error("registering a backend without pid.") return None backend = backend_dic["backend"] # Checking that is a new backend if backend.get_id() in self.backends: log.error("registering already registered backend") return None # creating the TaskSource which will wrap the backend, # filtering the tasks that should hit the backend. source = TaskSource(requester=self.requester, backend=backend, datastore=self.filtered_datastore) self.backends[backend.get_id()] = source # we notify that a new backend is present self._backend_signals.backend_added(backend.get_id()) # saving the backend in the correct dictionary (backends for # enabled backends, disabled_backends for the disabled ones) # this is useful for retro-compatibility if GenericBackend.KEY_ENABLED not in backend_dic: source.set_parameter(GenericBackend.KEY_ENABLED, True) if GenericBackend.KEY_DEFAULT_BACKEND not in backend_dic: source.set_parameter(GenericBackend.KEY_DEFAULT_BACKEND, True) # if it's enabled, we initialize it if source.is_enabled() and \ (self.is_default_backend_loaded or source.is_default()): source.initialize(connect_signals=False) # Filling the backend # Doing this at start is more efficient than # after the GUI is launched source.start_get_tasks() return source else: log.error("Tried to register a backend without a pid")
def _load_pickled_file(self, path, default_value=None): """ A helper function to load some object from a file. @param path: the relative path of the file @param default_value: the value to return if the file is missing or corrupt @returns object: the needed object, or default_value """ path = os.path.join(SYNC_DATA_DIR, path) if not os.path.exists(path): return default_value with open(path, 'rb') as file: try: return pickle.load(file) except Exception: log.error("Pickle file for backend '%s' is damaged" % self.get_name()) # Loading file failed, trying backups for i in range(1, PICKLE_BACKUP_NBR + 1): backup_file = "%s.bak.%d" % (path, i) if os.path.exists(backup_file): with open(backup_file, 'rb') as file: try: data = pickle.load(file) log.info("Succesfully restored backup #%d for '%s'" % (i, self.get_name())) return data except Exception: log.error("Backup #%d for '%s' is damaged as well" % (i, self.get_name())) # Data could not be loaded, degrade to default data log.error("There is no suitable backup for '%s', " "loading default data" % self.get_name()) return default_value
def openxmlfile(zefile, root): """ Open an XML file in a robust way If file could not be opened, try: - file__ - file.bak.0 - file.bak.1 - .... until BACKUP_NBR If file doesn't exist, create a new file """ # reset _USED_BACKUP and _BACKUP_FILE_INFO global _USED_BACKUP global _BACKUP_FILE_INFO _USED_BACKUP = False _BACKUP_FILE_INFO = "" tmpfile = zefile + '__' try: if os.path.exists(zefile): return _try_openxmlfile(zefile, root) elif os.path.exists(tmpfile): log.warning("Something happened to %s. Using backup" % zefile) os.rename(tmpfile, zefile) _USED_BACKUP = True _BACKUP_FILE_INFO = "Recovered from backup made on: " + \ datetime.datetime.fromtimestamp( os.path.getmtime(tmpfile)).strftime('%Y-%m-%d') return _try_openxmlfile(zefile, root) except IOError as msg: print(msg) sys.exit(1) except xml.parsers.expat.ExpatError as msg: errormsg = "Error parsing XML file %s: %s" % (zefile, msg) log.error(errormsg) if os.path.exists(tmpfile): log.warning("Something happened to %s. Using backup" % zefile) os.rename(tmpfile, zefile) _USED_BACKUP = True _BACKUP_FILE_INFO = "Recovered from backup made on: " + \ datetime.datetime.fromtimestamp( os.path.getmtime(tmpfile)).strftime('%Y-%m-%d') # Ok, try one more time now try: return _try_openxmlfile(zefile, root) except Exception as msg: log.warning('Failed with reason: %s' % msg) # Try to revert to backup backup_name = _get_backup_name(zefile) for i in range(BACKUP_NBR): backup_file = "%s.bak.%d" % (backup_name, i) if os.path.exists(backup_file): log.info("Trying to restore backup file %s" % backup_file) _USED_BACKUP = True _BACKUP_FILE_INFO = "Recovered from backup made on: " + \ datetime.datetime.fromtimestamp( os.path.getmtime(backup_file)).strftime('%Y-%m-%d') try: return _try_openxmlfile(backup_file, root) except Exception as msg: log.warning('Failed with reason: %s' % msg) log.info("No suitable backup was found") # Creating empty file doc, xmlproject = emptydoc(root) newfile = savexml(zefile, doc) if not newfile: log.error("Could not create a new file %s" % zefile) sys.exit(1) # set _USED_BACKUP even if there's a failure to notify about the same _USED_BACKUP = True _BACKUP_FILE_INFO = "No backups found. Created a new file" return _try_openxmlfile(zefile, root) # exit if execution reached this statement sys.exit(1)
def do_render(self, cr, widget, background_area, cell_area, flags): vw_tags = self.__count_viewable_tags() count = 0 # Select source if self.tag_list is not None: tags = self.tag_list elif self.tag is not None: tags = [self.tag] else: return # Drawing context gdkcontext = cr gdkcontext.set_antialias(cairo.ANTIALIAS_NONE) # Coordinates of the origin point x_align = self.get_property("xalign") y_align = self.get_property("yalign") padding = self.PADDING orig_x = cell_area.x + int( (cell_area.width - 16 * vw_tags - padding * 2 * (vw_tags - 1)) * x_align) orig_y = cell_area.y + int((cell_area.height - 16) * y_align) # We draw the icons & squares for my_tag in tags: my_tag_icon = my_tag.get_attribute("icon") my_tag_color = my_tag.get_attribute("color") rect_x = orig_x + self.PADDING * 2 * count + 16 * count rect_y = orig_y if my_tag_icon: try: pixbuf = Gtk.IconTheme.get_default().load_icon( my_tag_icon, 16, 0) Gdk.cairo_set_source_pixbuf(gdkcontext, pixbuf, rect_x, rect_y) gdkcontext.paint() count = count + 1 except GLib.GError: # In some rare cases an icon could not be found # (e.g. wrong set icon path, missing icon) # Raising an exception breaks UI and signal catcher badly log.error("Can't load icon '%s'" % my_tag_icon) elif my_tag_color: # Draw rounded rectangle my_color = Gdk.color_parse(my_tag_color) Gdk.cairo_set_source_color(gdkcontext, my_color) self.__roundedrec(gdkcontext, rect_x, rect_y, 16, 16, 8) gdkcontext.fill() count = count + 1 # Outer line Gdk.cairo_set_source_rgba(gdkcontext, Gdk.RGBA(0, 0, 0, 0.20)) gdkcontext.set_line_width(1.0) self.__roundedrec(gdkcontext, rect_x, rect_y, 16, 16, 8) gdkcontext.stroke() if self.tag and my_tag: my_tag_icon = my_tag.get_attribute("icon") my_tag_color = my_tag.get_attribute("color") if not my_tag_icon and not my_tag_color: # Draw rounded rectangle Gdk.cairo_set_source_rgba(gdkcontext, Gdk.RGBA(0.95, 0.95, 0.95, 1)) self.__roundedrec(gdkcontext, rect_x, rect_y, 16, 16, 8) gdkcontext.fill() # Outer line Gdk.cairo_set_source_rgba(gdkcontext, Gdk.RGBA(0, 0, 0, 0.20)) gdkcontext.set_line_width(1.0) self.__roundedrec(gdkcontext, rect_x, rect_y, 16, 16, 8) gdkcontext.stroke()