def test_spaces(self): # cf. issue #114 fact = Fact("11:00 12:00 BPC-261 - Task title@Project#code") self.assertEqual(fact.activity, "BPC-261 - Task title") self.assertEqual(fact.category, "Project") self.assertEqual(fact.description, None) self.assertEqual(fact.tags, ["code"]) # space between category and tag fact2 = Fact("11:00 12:00 BPC-261 - Task title@Project #code") self.assertEqual(fact.serialized(), fact2.serialized())
def update_suggestions(self, text=""): """ * from previous activity | set time | minutes ago | start now * to ongoing | set time * activity * [@category] * #tags, #tags, #tags * we will leave description for later all our magic is space separated, strictly, start-end can be just dash phases: [start_time] | [-end_time] | activity | [@category] | [#tag] """ # list of tuples (description, variant) variants = [] if self.original_fact: # editing an existing fact if self.original_fact.end_time is None: description = "stop now" now = dt.datetime.now() variant_fact = Fact(initial_fact=self.original_fact, end_time=now) else: # FIXME: that one should be available only for the last entry description = "keep up (caveat: is it the last entry ?)" # Do not use Fact(..., end_time=None): it would be a no-op variant_fact = Fact(initial_fact=self.original_fact) variant_fact.end_time = None variant = variant_fact.serialized(prepend_date=False) variants.append((description, variant)) else: # brand new fact description = "start now" now = dt.datetime.now() variant = now.strftime("%H:%M ") variants.append((description, variant)) prev_fact = self.todays_facts[-1] if self.todays_facts else None if prev_fact and prev_fact.end_time: since = stuff.format_duration(now - prev_fact.end_time) description = "from previous activity, %s ago" % since variant = prev_fact.end_time.strftime("%H:%M ") variants.append((description, variant)) description = "start activity -n minutes ago (1 or 3 digits allowed)" variant = "-" variants.append((description, variant)) text = text.strip() if text: description = "clear" variant = "" variants.append((description, variant)) res = [] for (description, variant) in variants: res.append(DataRow(variant, description=description)) fact = Fact(text) # figure out what we are looking for # time -> activity[@category] -> tags -> description # presence of an attribute means that we are not looking for the previous one # we still might be looking for the current one though looking_for = "start_time" fields = ["start_time", "end_time", "activity", "category", "tags", "description", "done"] for field in reversed(fields): if getattr(fact, field, None): looking_for = field if text[-1] == " ": looking_for = fields[fields.index(field)+1] break fragments = [f for f in re.split("[\s|#]", text)] current_fragment = fragments[-1] if fragments else "" search = extract_search(text) matches = [] for match, score in self.suggestions: if search in match: if match.startswith(search): score += 10**8 # boost beginnings matches.append((match, score)) # need to limit these guys, sorry matches = sorted(matches, key=lambda x: x[1], reverse=True)[:7] for match, score in matches: label = (fact.start_time or now).strftime("%H:%M") if fact.end_time: label += fact.end_time.strftime("-%H:%M") markup_label = label + " " + (stuff.escape_pango(match).replace(search, "<b>%s</b>" % search) if search else match) label += " " + match res.append(DataRow(markup_label, match, label)) self.complete_tree.set_rows(res)