def test_comparison(self): fact1 = Fact("12:25-13:25 case@cat, description #tag #bäg") fact2 = fact1.copy() self.assertEqual(fact1, fact2) fact2 = fact1.copy() fact2.activity = "abcd" self.assertNotEqual(fact1, fact2) fact2 = fact1.copy() fact2.category = "abcd" self.assertNotEqual(fact1, fact2) fact2 = fact1.copy() fact2.description = "abcd" self.assertNotEqual(fact1, fact2) import datetime as dt fact2 = fact1.copy() fact2.start_time = dt.datetime.now() self.assertNotEqual(fact1, fact2) fact2 = fact1.copy() fact2.end_time = dt.datetime.now() self.assertNotEqual(fact1, fact2) # wrong order fact2 = fact1.copy() fact2.tags = ["bäg", "tag"] self.assertNotEqual(fact1, fact2) # correct order fact2 = fact1.copy() fact2.tags = ["tag", "bäg"] self.assertEqual(fact1, fact2)
def localized_fact(self): """Make sure fact has the correct start_time.""" fact = Fact(self.activity.get_text()) if fact.start_time: fact.date = self.date else: fact.start_time = dt.datetime.now() return fact
def test_initial_fact(self): fact = Fact("12:25-13:25 case@cat, description #tag #bäg") fact_copy = Fact(initial_fact=fact) self.assertEqual(fact_copy.start_time.strftime("%H:%M"), "12:25") self.assertEqual(fact_copy.end_time.strftime("%H:%M"), "13:25") self.assertEqual(fact_copy.activity, "case") self.assertEqual(fact_copy.category, "cat") self.assertEqual(fact_copy.description, "description") self.assertEqual(set(fact_copy.tags), set(["bäg", "tag"]))
def test_serialized_name(self): '''testing serialized_name''' activity = Fact("case@cat") test1 = activity.serialized_name() test2 = "case@cat" self.assertEquals(test1, test2) activity = Fact("case@cat, description #tag #bag") test3 = activity.serialized_name() test4 = "case@cat,description #tag #bag" self.assertEquals(test3, test4)
def test_spaces(self): # cf. issue #114 fact = Fact.parse("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, "") self.assertEqual(fact.tags, ["code"]) # space between category and tag fact2 = Fact.parse("11:00 12:00 BPC-261 - Task title@Project #code") self.assertEqual(fact.serialized(), fact2.serialized())
def test_str(self): '''testing str''' #first, testing start_time only activity = Fact("12:35 with start time") t1 = "%s %s" % (activity.start_time.strftime(activity.STRINGFORMAT), activity.serialized_name()) t2 = str(activity) self.assertEquals(t1, t2) #now, testing both start_time and end_time activity = Fact("12:35-14:25 with start-end time") t1 = "%s - %s %s" % (activity.start_time.strftime(activity.STRINGFORMAT), activity.end_time.strftime(activity.TIMESTRINGFORMAT), activity.serialized_name()) t2 = str(activity)
def add_fact(self, fact, start_time, end_time, temporary = False): fact = Fact(fact, start_time = start_time, end_time = end_time) start_time = fact.start_time or dt.datetime.now().replace(second = 0, microsecond = 0) self.start_transaction() result = self.__add_fact(fact.serialized_name(), start_time, end_time, temporary) self.end_transaction() if result: self.facts_changed() return result
def test_decimal_in_activity(self): # cf. issue #270 fact = Fact("12:25-13:25 10.0@ABC, Two Words #tag #bäg") self.assertEqual(fact.activity, "10.0") self.assertEqual(fact.category, "ABC") self.assertEqual(fact.description, "Two Words") # should not pick up a time here fact = Fact("10.00@ABC, Two Words #tag #bäg") self.assertEqual(fact.activity, "10.00") self.assertEqual(fact.category, "ABC") self.assertEqual(fact.description, "Two Words")
def add_fact(self, fact, start_time=None, end_time=None, temporary=False): """Add fact. fact: either a Fact instance or a string that can be parsed through Fact.parse. note: start_time and end_time are used only when fact is a string, for backward compatibility. Passing fact as a string is deprecated and will be removed in a future version. Parsing should be done in the caller. """ if isinstance(fact, str): logger.info("Passing fact as a string is deprecated") fact = Fact.parse(fact) fact.start_time = start_time fact.end_time = end_time self.start_transaction() result = self.__add_fact(fact, temporary) self.end_transaction() if result: self.facts_changed() return result
def test_category(self): '''testing category syntax''' activity = Fact("just a simple case@hamster") self.assertEquals(activity.activity, "just a simple case") self.assertEquals(activity.category, "hamster") assert activity.start_time is None assert activity.end_time is None assert activity.description is None
def test_category(self): # plain activity name activity = Fact("just a simple case@hämster") self.assertEqual(activity.activity, "just a simple case") self.assertEqual(activity.category, "hämster") assert activity.start_time is None assert activity.end_time is None assert activity.description is None
def extract_search(text): fact = Fact(text) search = fact.activity or "" if fact.category: search += "@%s" % fact.category if fact.tags: search += " #%s" % (" #".join(fact.tags)) return search
def on_today_row_activated(self, tree, path, column): fact = tree.get_selected_fact() fact = Fact(fact.activity, category = fact.category, description = fact.description, tags = ", ".join(fact.tags)) if fact.activity: runtime.storage.add_fact(fact)
def test_plain_name(self): # plain activity name activity = Fact.parse("just a simple case with ütf-8") self.assertEqual(activity.activity, "just a simple case with ütf-8") assert activity.start_time is None assert activity.end_time is None assert not activity.category assert not activity.description
def test_full(self): '''testing full syntax''' activity = Fact("1225-1325 case@cat, description non-tag#ta #tag #bag") self.assertEquals(activity.start_time.strftime("%H:%M"), "12:25") self.assertEquals(activity.end_time.strftime("%H:%M"), "13:25") self.assertEquals(activity.activity, "case") self.assertEquals(activity.category, "cat") self.assertEquals(activity.description, "description non-tag#ta") self.assertEquals(set(activity.tags), set(["bag", "tag"]))
def test_tags(self): # plain activity name activity = Fact("case, with added #de description #and, #some #tägs") self.assertEqual(activity.activity, "case") self.assertEqual(activity.description, "with added #de description") self.assertEqual(set(activity.tags), set(["and", "some", "tägs"])) assert activity.category is None assert activity.start_time is None assert activity.end_time is None
def test_full(self): # plain activity name activity = Fact("1225-1325 case@cat, description #ta non-tag #tag #bäg") self.assertEqual(activity.start_time.strftime("%H:%M"), "12:25") self.assertEqual(activity.end_time.strftime("%H:%M"), "13:25") self.assertEqual(activity.activity, "case") self.assertEqual(activity.category, "cat") self.assertEqual(activity.description, "description #ta non-tag") self.assertEqual(set(activity.tags), set(["bäg", "tag"]))
def test_tags(self): '''testing tag syntax, making sure hashtags in description are not pulled as tags''' activity = Fact("case, with added#de description #and, #some #tags") self.assertEquals(activity.activity, "case") self.assertEquals(activity.description, "with added#de description") self.assertEquals(set(activity.tags), set(["and", "some", "tags"])) assert activity.category is None assert activity.start_time is None assert activity.end_time is None
def test_description(self): # plain activity name activity = Fact("case, with added descriptiön") self.assertEqual(activity.activity, "case") self.assertEqual(activity.description, "with added descriptiön") assert activity.category is None assert activity.start_time is None assert activity.end_time is None assert activity.category is None
def test_description(self): '''testing description syntax''' activity = Fact("case, with added description") self.assertEquals(activity.activity, "case") self.assertEquals(activity.description, "with added description") assert activity.category is None assert activity.start_time is None assert activity.end_time is None assert activity.category is None
def test_with_start_and_end_time(self): # with time activity = Fact("12:35-14:25 with start-end time") self.assertEqual(activity.activity, "with start-end time") self.assertEqual(activity.start_time.strftime("%H:%M"), "12:35") self.assertEqual(activity.end_time.strftime("%H:%M"), "14:25") #rest must be empty assert activity.category is None assert activity.description is None
def test_plain_name(self): ''' testing plain activity name''' activity = Fact("just a simple case") self.assertEquals(activity.activity, "just a simple case") assert activity.category is None assert activity.start_time is None assert activity.end_time is None assert activity.category is None assert activity.description is None
def test_with_start_time(self): '''testing start time syntax''' activity = Fact("12:35 with start time") self.assertEquals(activity.activity, "with start time") self.assertEquals(activity.start_time.strftime("%H:%M"), "12:35") #rest must be empty assert activity.category is None assert activity.end_time is None assert activity.description is None
def test_easteregg(self): '''testing the easter egg (ponies vs rainbows?)''' activity = Fact("bbq omg") self.assertEquals(activity.activity, "bbq omg") self.assertEquals(activity.ponies, True) self.assertEquals(activity.description, "[ponies = 1], [rainbows = 0]") assert activity.category is None assert activity.start_time is None assert activity.end_time is None
def _dbfact_to_libfact(self, db_fact): """Convert a db fact (coming from __group_facts) to Fact.""" return Fact(activity=db_fact["name"], category=db_fact["category"], description=db_fact["description"], tags=db_fact["tags"], start_time=db_fact["start_time"], end_time=db_fact["end_time"], id=db_fact["id"], activity_id=db_fact["activity_id"])
def test_with_start_time(self): # with time activity = Fact.parse("12:35 with start time") self.assertEqual(activity.activity, "with start time") self.assertEqual(activity.start_time.strftime("%H:%M"), "12:35") #rest must be empty assert not activity.category assert activity.end_time is None assert not activity.description
def test_explicitvsparse(self): '''testing whether explicit has precedence over standard syntax''' activity = Fact("1225-1325 case@cat, description non-tag#ta #tag #bag", description="true") self.assertEquals(activity.start_time.strftime("%H:%M"), "12:25") self.assertEquals(activity.end_time.strftime("%H:%M"), "13:25") self.assertEquals(activity.activity, "case") self.assertEquals(activity.category, "cat") self.assertEquals(activity.description, "true") self.assertEquals(set(activity.tags), set(["bag", "tag"]))
def complete_first(self): text = self.get_text() fact, search = Fact(text), extract_search(text) if not self.complete_tree.rows or not fact.activity: return text, None label = self.complete_tree.rows[0].data if label.startswith(search): return text, label[len(search):] return text, None
def on_switch_activity_clicked(self, widget): activity, temporary = self.new_name.get_value() fact = Fact(activity, tags = self.new_tags.get_text().decode("utf8", "replace")) if not fact.activity: return runtime.storage.add_fact(fact, temporary) self.new_name.set_text("") self.new_tags.set_text("")
def from_dbus_fact(dbus_fact): """unpack the struct into a proper dict""" return Fact(activity=dbus_fact[4], start_time=dt.datetime.utcfromtimestamp(dbus_fact[1]), end_time=dt.datetime.utcfromtimestamp(dbus_fact[2]) if dbus_fact[2] else None, description=dbus_fact[3], activity_id=dbus_fact[5], category=dbus_fact[6], tags=dbus_fact[7], id=dbus_fact[0])
def on_cmdline_changed(self, widget): if self.master_is_cmdline: fact = Fact.parse(self.cmdline.get_text(), date=self.date) previous_cmdline_fact = self.cmdline_fact # copy the entered fact before any modification self.cmdline_fact = fact.copy() if fact.start_time is None: fact.start_time = hamster_now() if fact.description == previous_cmdline_fact.description: # no change to description here, keep the main one fact.description = self.fact.description self.fact = fact self.update_fields()
def from_dbus_fact(fact): """unpack the struct into a proper dict""" return Fact(fact[4], start_time = dt.datetime.utcfromtimestamp(fact[1]), end_time = dt.datetime.utcfromtimestamp(fact[2]) if fact[2] else None, description = fact[3], activity_id = fact[5], category = fact[6], tags = fact[7], date = dt.datetime.utcfromtimestamp(fact[8]).date(), delta = dt.timedelta(days = fact[9] // (24 * 60 * 60), seconds = fact[9] % (24 * 60 * 60)), id = fact[0] )
def __solve_overlaps(self, start_time, end_time): """finds facts that happen in given interval and shifts them to make room for new fact """ if end_time is None or start_time is None: return # possible combinations and the OR clauses that catch them # (the side of the number marks if it catches the end or start time) # |----------------- NEW -----------------| # |--- old --- 1| |2 --- old --- 1| |2 --- old ---| # |3 ----------------------- big old ------------------------ 3| query = """ SELECT a.*, b.name, c.name as category FROM facts a LEFT JOIN activities b on b.id = a.activity_id LEFT JOIN categories c on b.category_id = c.id WHERE (end_time > ? and end_time < ?) OR (start_time > ? and start_time < ?) OR (start_time < ? and end_time > ?) ORDER BY start_time """ conflicts = self.fetchall(query, (start_time, end_time, start_time, end_time, start_time, end_time)) for fact in conflicts: # won't eliminate as it is better to have overlapping entries than loosing data if start_time < fact["start_time"] and end_time > fact["end_time"]: continue # split - truncate until beginning of new entry and create new activity for end if fact["start_time"] < start_time < fact["end_time"] and \ fact["start_time"] < end_time < fact["end_time"]: logging.info("splitting %s" % fact["name"]) # truncate until beginning of the new entry self.execute("""UPDATE facts SET end_time = ? WHERE id = ?""", (start_time, fact["id"])) fact_name = fact["name"] # create new fact for the end new_fact = Fact(fact["name"], category = fact["category"], description = fact["description"]) new_fact_id = self.__add_fact(new_fact.serialized_name(), end_time, fact["end_time"]) # copy tags tag_update = """INSERT INTO fact_tags(fact_id, tag_id) SELECT ?, tag_id FROM fact_tags WHERE fact_id = ?""" self.execute(tag_update, (new_fact_id, fact["id"])) #clone tags if trophies: trophies.unlock("split") # overlap start elif start_time < fact["start_time"] < end_time: logging.info("Overlapping start of %s" % fact["name"]) self.execute("UPDATE facts SET start_time=? WHERE id=?", (end_time, fact["id"])) # overlap end elif start_time < fact["end_time"] < end_time: logging.info("Overlapping end of %s" % fact["name"]) self.execute("UPDATE facts SET end_time=? WHERE id=?", (start_time, fact["id"]))