def _evo_task_is_syncable(self, evo_task): ''' Returns True if this Evolution task should be synced into GTG tasks. @param evo_task: an Evolution task @returns Boolean ''' attached_tags = set(self.get_attached_tags()) if GenericBackend.ALLTASKS_TAG in attached_tags: return True evo_tags = set(extract_tags_from_text(evo_task.get_description())) return evo_task.is_disjoint(attached_tags)
def test_extract_tags_from_text(self): """ Test for extracting tags from a string """ tests = ( ("@mamma mia", ["@mamma"]), ("vive le @roy", ["@roy"]), ("hey @mr. jack!", ["@mr"]), ("no @emails allowed: [email protected]", ["@emails"]), ("and no @@diff stuff", []), ("@we @do @love @tags!", ["@we", "@do", "@love", "@tags"]), ) for text, tags in tests: self.assertEqual(extract_tags_from_text(text), tags)
def set_complex_title(self, text, tags=[]): if tags: assert (isinstance(tags[0], str)) due_date = Date.no_date() defer_date = Date.no_date() if text: # Get tags in the title for match in extract_tags_from_text(text): tags.append(match) # Get attributes regexp = r'([\s]*)([\w-]+):\s*([^\s]+)' matches = re.findall(regexp, text, re.UNICODE) for spaces, attribute, args in matches: valid_attribute = True if attribute.lower() in ["tags", _("tags"), "tag", _("tag")]: for tag in args.split(","): if not tag.strip() == "@" and not tag.strip() == "": if not tag.startswith("@"): tag = "@" + tag tags.append(tag) elif attribute.lower() in [ "defer", _("defer"), "start", _("start") ]: try: defer_date = Date.parse(args) except ValueError: valid_attribute = False elif attribute.lower() == "due" or \ attribute.lower() == _("due"): try: due_date = Date.parse(args) except: valid_attribute = False else: # attribute is unknown valid_attribute = False if valid_attribute: # remove valid attribute from the task title text = \ text.replace("%s%s:%s" % (spaces, attribute, args), "") for t in tags: self.add_tag(t) if text != "": self.set_title(text.strip()) self.set_to_keep() self.set_due_date(due_date) self.set_start_date(defer_date)
def set_complex_title(self, text, tags=[]): if tags: assert(isinstance(tags[0], str)) due_date = Date.no_date() defer_date = Date.no_date() if text: # Get tags in the title for match in extract_tags_from_text(text): tags.append(match) # Get attributes regexp = r'([\s]*)([\w-]+):\s*([^\s]+)' matches = re.findall(regexp, text, re.UNICODE) for spaces, attribute, args in matches: valid_attribute = True if attribute.lower() in ["tags", _("tags"), "tag", _("tag")]: for tag in args.split(","): if not tag.strip() == "@" and not tag.strip() == "": if not tag.startswith("@"): tag = "@" + tag tags.append(tag) elif attribute.lower() in ["defer", _("defer"), "start", _("start")]: try: defer_date = Date.parse(args) except ValueError: valid_attribute = False elif attribute.lower() == "due" or \ attribute.lower() == _("due"): try: due_date = Date.parse(args) except: valid_attribute = False else: # attribute is unknown valid_attribute = False if valid_attribute: # remove valid attribute from the task title text = \ text.replace("%s%s:%s" % (spaces, attribute, args), "") for t in tags: self.add_tag(t) if text != "": self.set_title(text.strip()) self.set_to_keep() self.set_due_date(due_date) self.set_start_date(defer_date)
def addtask(doc, ze_id, title, text, children): """Initialize GTG tasks in order to display them at first run.""" t_xml = doc.createElement("task") t_xml.setAttribute("id", ze_id) t_xml.setAttribute("status", "Active") tags = extract_tags_from_text(text) t_xml.setAttribute("tags", ",".join(tags)) cleanxml.addTextNode(doc, t_xml, "title", title) for child in children: cleanxml.addTextNode(doc, t_xml, "subtask", child) cleanxml.addTextNode(doc, t_xml, "content", text) return t_xml
def _populate_task(self, task, evo_task): ''' Updates the attributes of a GTG task copying the ones of an Evolution task ''' task.set_title(evo_task.get_summary()) text = evo_task.get_description() if text is None: text = "" task.set_text(text) due_date_timestamp = evo_task.get_due() if isinstance(due_date_timestamp, (int, float)): due_date = self.__date_from_evo_to_gtg(due_date_timestamp) else: due_date = Date.no_date() task.set_due_date(due_date) status = evo_task.get_status() if task.get_status() != _EVOLUTION_TO_GTG_STATUS[status]: task.set_status(_EVOLUTION_TO_GTG_STATUS[status]) task.set_only_these_tags(extract_tags_from_text(text))
def _populate_task(self, task, note): ''' Copies the content of a Tomboy note into a task. @param task: a GTG Task @param note: a Tomboy note ''' # add tags objects (it's not enough to have @tag in the text to add a # tag with self.TomboyConnection(self, *self.BUS_ADDRESS) as tomboy: with self.DbusWatchdog(self): content = tomboy.GetNoteContents(note) # update the tags list task.set_only_these_tags(extract_tags_from_text(content)) # extract title and text [title, text] = self._tomboy_split_title_and_text(str(content)) # Tomboy speaks unicode, we don't title = unicodedata.normalize('NFKD', title) text = unicodedata.normalize('NFKD', text) task.set_title(title) task.set_text(text) task.add_remote_id(self.get_id(), note)
def populate_from_single_line_of_text(self, text, tags=[]): if tags: assert (isinstance(tags[0], str)) # TODO: We expect one line, without tabs, so... a bit of paranoia for pasted text? # Reduce multiple spaces text = string.replace(text, ' ', ' ').strip() text = string.replace(text, ' ', ' ') if not text: print("populate_from_single_line_of_text: empty/whitespace") return due_date = Date.no_date() defer_date = Date.no_date() # Extract/remove tags from the title, but only if doing so would not make it empty. for match in extract_tags_from_text(text): tags.append(match) without_tag = string.replace(text, match, '') without_tag = string.replace(without_tag, ' ', ' ').strip() if without_tag: text = without_tag # Get key-value attributes of the form "key:value" regexp = r'([\s]*)([\w-]+):\s*([^\s]+)' matches = re.findall(regexp, text, re.UNICODE) for spaces, attribute, args in matches: valid_attribute = True if attribute.lower() in ["tags", _("tags"), "tag", _("tag")]: for tag in args.split(","): if not tag.strip() == "@" and not tag.strip() == "": if not tag.startswith("@"): tag = "@" + tag tags.append(tag) elif attribute.lower() in [ "defer", _("defer"), "start", _("start") ]: try: defer_date = Date.parse(args) except ValueError: valid_attribute = False elif attribute.lower() == "due" or \ attribute.lower() == _("due"): try: due_date = Date.parse(args) except: valid_attribute = False else: # attribute is unknown valid_attribute = False if valid_attribute: # remove valid attribute from the task title text = \ text.replace("%s%s:%s" % (spaces, attribute, args), "") for t in tags: self.add_tag(t) if text != "": self.set_title(text.strip()) self.set_to_keep() self.set_due_date(due_date) self.set_start_date(defer_date) self._has_been_modified()
def assertTags(self, text, expected_tags): tag_list = extract_tags_from_text(text) self.assertEqual(expected_tags, tag_list)