Permalink
Browse files

move the Fact class into lib to decouple it from stuff which imports …

…pango and other bits not suitable for a clean lib
  • Loading branch information...
tstriker committed Dec 24, 2012
1 parent 96bc99d commit 9fe45183712404707abc515baeb162fc70630364
View
@@ -28,7 +28,7 @@ import re
import datetime as dt
from hamster import client, reports
-from hamster.lib import stuff
+from hamster.lib import Fact, stuff
def word_wrap(line, max_len):
@@ -184,7 +184,7 @@ class HamsterClient(object):
start_time, end_time = parse_datetime_range(" ".join(args[1:]))
start_time = start_time or dt.datetime.now()
- self.storage.add_fact(stuff.Fact(activity,
+ self.storage.add_fact(Fact(activity,
start_time = start_time,
end_time = end_time))
View
@@ -23,22 +23,23 @@
from calendar import timegm
import dbus, dbus.mainloop.glib
import gobject
-from lib import stuff, trophies
+from lib import Fact
+from lib import trophies
def from_dbus_fact(fact):
"""unpack the struct into a proper dict"""
- return stuff.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)),
+ 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]
)
@@ -26,7 +26,7 @@
"""
import widgets
from configuration import runtime, conf, load_ui_file
-from lib import stuff
+from lib import Fact
class CustomFactController(gtk.Object):
__gsignals__ = {
@@ -197,11 +197,11 @@ def on_save_button_clicked(self, button):
else:
end_time = self._get_datetime("end")
- fact = stuff.Fact(activity_name,
- description = self.figure_description(),
- tags = self.new_tags.get_text().decode('utf8'),
- start_time = self._get_datetime("start"),
- end_time = end_time)
+ fact = Fact(activity_name,
+ description = self.figure_description(),
+ tags = self.new_tags.get_text().decode('utf8'),
+ start_time = self._get_datetime("start"),
+ end_time = end_time)
if not fact.activity:
return False
View
@@ -0,0 +1,136 @@
+def figure_time(str_time):
+ if not str_time or not str_time.strip():
+ return None
+
+ # strip everything non-numeric and consider hours to be first number
+ # and minutes - second number
+ numbers = re.split("\D", str_time)
+ numbers = filter(lambda x: x!="", numbers)
+
+ hours, minutes = None, None
+
+ if len(numbers) == 1 and len(numbers[0]) == 4:
+ hours, minutes = int(numbers[0][:2]), int(numbers[0][2:])
+ else:
+ if len(numbers) >= 1:
+ hours = int(numbers[0])
+ if len(numbers) >= 2:
+ minutes = int(numbers[1])
+
+ if (hours is None or minutes is None) or hours > 24 or minutes > 60:
+ return None #no can do
+
+ return dt.datetime.now().replace(hour = hours, minute = minutes,
+ second = 0, microsecond = 0)
+
+
+class Fact(object):
+ def __init__(self, activity, category = "", description = "", tags = "",
+ start_time = None, end_time = None, id = None, delta = None,
+ date = None, activity_id = None):
+ """the category, description and tags can be either passed in explicitly
+ or by using the "activity@category, description #tag #tag" syntax.
+ explicitly stated values will take precedence over derived ones"""
+ self.original_activity = activity # unparsed version, mainly for trophies right now
+ self.activity = None
+ self.category = None
+ self.description = None
+ self.tags = []
+ self.start_time = None
+ self.end_time = None
+ self.id = id
+ self.ponies = False
+ self.delta = delta
+ self.date = date
+ self.activity_id = activity_id
+
+ # parse activity
+ input_parts = activity.strip().split(" ")
+ if len(input_parts) > 1 and re.match('^-?\d', input_parts[0]): #look for time only if there is more
+ potential_time = activity.split(" ")[0]
+ potential_end_time = None
+ if len(potential_time) > 1 and potential_time.startswith("-"):
+ #if starts with minus, treat as minus delta minutes
+ self.start_time = dt.datetime.now() + dt.timedelta(minutes = int(potential_time))
+
+ else:
+ if potential_time.find("-") > 0:
+ potential_time, potential_end_time = potential_time.split("-", 1)
+ self.end_time = figure_time(potential_end_time)
+
+ self.start_time = figure_time(potential_time)
+
+ #remove parts that worked
+ if self.start_time and potential_end_time and not self.end_time:
+ self.start_time = None #scramble
+ elif self.start_time:
+ activity = activity[activity.find(" ")+1:]
+
+ #see if we have description of activity somewhere here (delimited by comma)
+ if activity.find(",") > 0:
+ activity, self.description = activity.split(",", 1)
+
+ if " #" in self.description:
+ self.description, self.tags = self.description.split(" #", 1)
+ self.tags = [tag.strip(", ") for tag in self.tags.split("#") if tag.strip(", ")]
+
+ self.description = self.description.strip()
+
+ if activity.find("@") > 0:
+ activity, self.category = activity.split("@", 1)
+ self.category = self.category.strip()
+
+ #this is most essential
+ if any([b in activity for b in ("bbq", "barbeque", "barbecue")]) and "omg" in activity:
+ self.ponies = True
+ self.description = "[ponies = 1], [rainbows = 0]"
+
+ #only thing left now is the activity name itself
+ self.activity = activity.strip()
+
+ tags = tags or ""
+ if tags and isinstance(tags, basestring):
+ tags = [tag.strip() for tag in tags.split(",") if tag.strip()]
+
+ # override implicit with explicit
+ self.category = category.replace(",", "") or self.category or None
+ self.description = (description or "").replace(" #", " ") or self.description or None
+ self.tags = tags or self.tags or []
+ self.start_time = start_time or self.start_time or None
+ self.end_time = end_time or self.end_time or None
+
+
+ def __iter__(self):
+ keys = {
+ 'id': int(self.id),
+ 'activity': self.activity,
+ 'category': self.category,
+ 'description': self.description,
+ 'tags': [tag.encode("utf-8").strip() for tag in self.tags.split(",")],
+ 'date': calendar.timegm(self.date.timetuple()),
+ 'start_time': self.start_time if isinstance(self.start_time, basestring) else calendar.timegm(self.start_time.timetuple()),
+ 'end_time': self.end_time if isinstance(self.end_time, basestring) else calendar.timegm(self.end_time.timetuple()) if self.end_time else "",
+ 'delta': self.delta.seconds + self.delta.days * 24 * 60 * 60 #duration in seconds
+ }
+ return iter(keys.items())
+
+
+ def serialized_name(self):
+ res = self.activity
+
+ if self.category:
+ res += "@%s" % self.category
+
+ if self.description or self.tags:
+ res += ",%s %s" % (self.description or "",
+ " ".join(["#%s" % tag for tag in self.tags]))
+ return res
+
+ def __str__(self):
+ time = ""
+ if self.start_time:
+ self.start_time.strftime("%d-%m-%Y %H:%M")
+ if self.end_time:
+ time = "%s - %s" % (time, self.end_time.strftime("%H:%M"))
+ return "%s %s" % (time, self.serialized_name())
+
View
@@ -220,139 +220,3 @@ def escape_pango(text):
text = text.replace("<", "&lt;")
text = text.replace(">", "&gt;")
return text
-
-def figure_time(str_time):
- if not str_time or not str_time.strip():
- return None
-
- # strip everything non-numeric and consider hours to be first number
- # and minutes - second number
- numbers = re.split("\D", str_time)
- numbers = filter(lambda x: x!="", numbers)
-
- hours, minutes = None, None
-
- if len(numbers) == 1 and len(numbers[0]) == 4:
- hours, minutes = int(numbers[0][:2]), int(numbers[0][2:])
- else:
- if len(numbers) >= 1:
- hours = int(numbers[0])
- if len(numbers) >= 2:
- minutes = int(numbers[1])
-
- if (hours is None or minutes is None) or hours > 24 or minutes > 60:
- return None #no can do
-
- return dt.datetime.now().replace(hour = hours, minute = minutes,
- second = 0, microsecond = 0)
-
-
-class Fact(object):
- def __init__(self, activity, category = "", description = "", tags = "",
- start_time = None, end_time = None, id = None, delta = None,
- date = None, activity_id = None):
- """the category, description and tags can be either passed in explicitly
- or by using the "activity@category, description #tag #tag" syntax.
- explicitly stated values will take precedence over derived ones"""
- self.original_activity = activity # unparsed version, mainly for trophies right now
- self.activity = None
- self.category = None
- self.description = None
- self.tags = []
- self.start_time = None
- self.end_time = None
- self.id = id
- self.ponies = False
- self.delta = delta
- self.date = date
- self.activity_id = activity_id
-
- # parse activity
- input_parts = activity.strip().split(" ")
- if len(input_parts) > 1 and re.match('^-?\d', input_parts[0]): #look for time only if there is more
- potential_time = activity.split(" ")[0]
- potential_end_time = None
- if len(potential_time) > 1 and potential_time.startswith("-"):
- #if starts with minus, treat as minus delta minutes
- self.start_time = dt.datetime.now() + dt.timedelta(minutes = int(potential_time))
-
- else:
- if potential_time.find("-") > 0:
- potential_time, potential_end_time = potential_time.split("-", 1)
- self.end_time = figure_time(potential_end_time)
-
- self.start_time = figure_time(potential_time)
-
- #remove parts that worked
- if self.start_time and potential_end_time and not self.end_time:
- self.start_time = None #scramble
- elif self.start_time:
- activity = activity[activity.find(" ")+1:]
-
- #see if we have description of activity somewhere here (delimited by comma)
- if activity.find(",") > 0:
- activity, self.description = activity.split(",", 1)
-
- if " #" in self.description:
- self.description, self.tags = self.description.split(" #", 1)
- self.tags = [tag.strip(", ") for tag in self.tags.split("#") if tag.strip(", ")]
-
- self.description = self.description.strip()
-
- if activity.find("@") > 0:
- activity, self.category = activity.split("@", 1)
- self.category = self.category.strip()
-
- #this is most essential
- if any([b in activity for b in ("bbq", "barbeque", "barbecue")]) and "omg" in activity:
- self.ponies = True
- self.description = "[ponies = 1], [rainbows = 0]"
-
- #only thing left now is the activity name itself
- self.activity = activity.strip()
-
- tags = tags or ""
- if tags and isinstance(tags, basestring):
- tags = [tag.strip() for tag in tags.split(",") if tag.strip()]
-
- # override implicit with explicit
- self.category = category.replace(",", "") or self.category or None
- self.description = (description or "").replace(" #", " ") or self.description or None
- self.tags = tags or self.tags or []
- self.start_time = start_time or self.start_time or None
- self.end_time = end_time or self.end_time or None
-
-
- def __iter__(self):
- keys = {
- 'id': int(self.id),
- 'activity': self.activity,
- 'category': self.category,
- 'description': self.description,
- 'tags': [tag.encode("utf-8").strip() for tag in self.tags.split(",")],
- 'date': calendar.timegm(self.date.timetuple()),
- 'start_time': self.start_time if isinstance(self.start_time, basestring) else calendar.timegm(self.start_time.timetuple()),
- 'end_time': self.end_time if isinstance(self.end_time, basestring) else calendar.timegm(self.end_time.timetuple()) if self.end_time else "",
- 'delta': self.delta.seconds + self.delta.days * 24 * 60 * 60 #duration in seconds
- }
- return iter(keys.items())
-
-
- def serialized_name(self):
- res = self.activity
-
- if self.category:
- res += "@%s" % self.category
-
- if self.description or self.tags:
- res += ",%s %s" % (self.description or "",
- " ".join(["#%s" % tag for tag in self.tags]))
- return res
-
- def __str__(self):
- time = ""
- if self.start_time:
- self.start_time.strftime("%d-%m-%Y %H:%M")
- if self.end_time:
- time = "%s - %s" % (time, self.end_time.strftime("%H:%M"))
- return "%s %s" % (time, self.serialized_name())
@@ -30,6 +30,7 @@
except:
storage = None
+from ..lib import Fact
import stuff
import datetime as dt
@@ -107,7 +108,7 @@ def check_fact_based(self, fact):
return
# full plate - use all elements of syntax parsing
- derived_fact = stuff.Fact(fact.original_activity)
+ derived_fact = Fact(fact.original_activity)
if all((derived_fact.category, derived_fact.description,
derived_fact.tags, derived_fact.start_time, derived_fact.end_time)):
unlock("full_plate")
View
@@ -31,6 +31,7 @@
import widgets, reports
from configuration import runtime, conf, dialogs, load_ui_file
+from lib import Fact
from lib import stuff, trophies
from lib.i18n import C_
@@ -192,7 +193,7 @@ def on_conf_change(self, event, key, value):
def on_fact_selection_changed(self, tree):
""" enables and disables action buttons depending on selected item """
fact = tree.get_selected_fact()
- real_fact = fact is not None and isinstance(fact, stuff.Fact)
+ real_fact = fact is not None and isinstance(fact, Fact)
self.get_widget('remove').set_sensitive(real_fact)
self.get_widget('edit').set_sensitive(real_fact)
Oops, something went wrong.

0 comments on commit 9fe4518

Please sign in to comment.