def convert(path: str, ds: datastore) -> et.ElementTree: """Convert old XML into the new format.""" old_tree = xml.open_file(path, 'project') new_root = et.Element('gtgData') new_root.set('appVersion', '0.5') new_root.set('xmlVersion', '2') taglist, searches = convert_tags(old_tree) new_root.append(taglist) new_root.append(searches) tasklist = et.SubElement(new_root, 'tasklist') for task in old_tree.iter('task'): # Keep a map of old style IDs to UUIDs for later tid = task.attrib['id'] try: new_tid = task.attrib['uuid'] except KeyError: new_tid = str(uuid4()) tid_cache[tid] = new_tid for task in old_tree.iter('task'): new_task = convert_task(task, ds) if new_task is not None: tasklist.append(new_task) return et.ElementTree(new_root)
def this_is_the_first_run(self, _) -> None: """ Called upon the very first GTG startup. This function is needed only in this backend, because it can be used as default one. The xml parameter is an object containing GTG default tasks. It will be saved to a file, and the backend will be set as default. @param xml: an xml object containing the default tasks. """ filepath = self.get_path() if versioning.is_required(filepath): log.warning('Found old file. Running versioning code.') old_path = os.path.join(DATA_DIR, 'gtg_tasks.xml') tree = versioning.convert(old_path, self.datastore) xml.save_file(filepath, tree) else: root = firstrun_tasks.generate() xml.create_dirs(self.get_path()) xml.save_file(self.get_path(), root) self._parameters[self.KEY_DEFAULT_BACKEND] = True # Load the newly created file self.data_tree = xml.open_file(self.get_path(), 'gtgData') self.task_tree = self.data_tree.find('tasklist') self.tag_tree = self.data_tree.find('taglist') xml.backup_used = None
def initialize(self): """ This is called when a backend is enabled """ super(Backend, self).initialize() filepath = self.get_path() if versioning.is_required(filepath): log.warning('Found old file. Running versioning code.') old_path = os.path.join(DATA_DIR, 'gtg_tasks.xml') tree = versioning.convert(old_path, self.datastore) xml.save_file(filepath, tree) elif not os.path.isfile(filepath): root = firstrun_tasks.generate() xml.create_dirs(self.get_path()) xml.save_file(self.get_path(), root) self.data_tree = xml.open_file(filepath, 'gtgData') self.task_tree = self.data_tree.find('tasklist') self.tag_tree = self.data_tree.find('taglist') self.search_tree = self.data_tree.find('searchlist') self.datastore.load_tag_tree(self.tag_tree) self.datastore.load_search_tree(self.search_tree) # Make safety daily backup after loading xml.save_file(self.get_path(), self.data_tree) xml.write_backups(self.get_path())
def load_tag_tree(self): """ Loads the tag tree from a xml file """ xmlstore = xml.open_file(TAGS_XMLFILE, TAG_XMLROOT) for t in xmlstore.getroot(): tagname = t.get('name') parent = t.get('parent') tag_attr = {} for key, value in t.attrib.items(): if key not in ('name', 'parent'): tag_attr[key] = value if parent == SEARCH_TAG: query = t.attrib.get('query') tag = self.new_search_tag(tagname, query, tag_attr) else: tag = self.new_tag(tagname, tag_attr) if parent: tag.set_parent(parent) self.tagfile_loaded = True
def convert_tags(old_tree: et.Element) -> Tuple[et.Element, et.Element]: """Convert old tags for the new format.""" old_file = os.path.join(DATA_DIR, 'tags.xml') tree = xml.open_file(old_file, 'tagstore') taglist = et.Element('taglist') searchlist = et.Element('searchlist') for tag in tree.iter('tag'): name = tag.get('name') parent = tag.get('parent') nonactionable = tag.get('nonworkview') color = tag.get('color') tid = str(uuid4()) if tag.get('query'): new_tag = et.SubElement(searchlist, 'savedSearch') new_tag.set('name', name) query = tag.get('query') new_tag.set('query', query) else: new_tag = et.SubElement(taglist, 'tag') # Remove @ in name new_tag.set('name', name[1:]) tags_cache[name] = tid if parent: new_tag.set('parent', parent[1:]) if nonactionable: new_tag.set('nonactionable', nonactionable) new_tag.set('id', tid) # Remove # in color hex if color: new_tag.set('color', color[1:].upper()) # In older versions not all tags were saved in the tag file # Some were just saved in the tasks, so we need to loop # through the tasks to make sure we get *all* tags and have # their IDs ready for task conversion. for task in old_tree.iter('task'): for tag_name in task.get('tags').split(','): if tag_name and tag_name not in tags_cache: new_tag = et.SubElement(taglist, 'tag') tid = str(uuid4()) new_tag.set('id', tid) new_tag.set('name', tag_name[1:]) tags_cache[tag_name] = tid return taglist, searchlist
def _read_backend_configuration_file(self): """ Reads the file describing the current backend configuration (project.xml) and returns a list of dictionaries, each containing: - the xml object defining the backend characteristics under "xmlobject" - the name of the backend under "module" """ # Read configuration file, if it does not exist, create one doc = xml.open_file(PROJECTS_XMLFILE, "config") xmlproject = doc.xpath('//backend') # collect configured backends return [{'xmlobject': xp, 'module': xp.attrib['module']} for xp in xmlproject]
def this_is_the_first_run(self, _) -> None: """ Called upon the very first GTG startup. This function is needed only in this backend, because it can be used as default one. The xml parameter is an object containing GTG default tasks. It will be saved to a file, and the backend will be set as default. @param xml: an xml object containing the default tasks. """ self._parameters[self.KEY_DEFAULT_BACKEND] = True root = firstrun_tasks.generate() xml.write_xml(self.get_path(), root) # Load the newly created file self.task_tree = xml.open_file(self.get_path(), 'project') xml.backup_used = None
def __init__(self, parameters: Dict): """ Instantiates a new backend. @param parameters: A dictionary of parameters, generated from _static_parameters. A few parameters are added to those, the list of these is in the "DefaultBackend" class, look for the KEY_* constants. The backend should take care if one expected value is None or does not exist in the dictionary. """ super().__init__(parameters) if self.KEY_DEFAULT_BACKEND not in parameters: parameters[self.KEY_DEFAULT_BACKEND] = True self.task_tree = xml.open_file(self.get_path(), 'project') self.backup_used = None # Make safety daily backup after loading xml.save_file(self.get_path(), self.task_tree) xml.write_backups(self.get_path())
def initialize(self): """ This is called when a backend is enabled """ super(Backend, self).initialize() self.task_tree = xml.open_file(self.get_path(), 'project')