Skip to content

Commit

Permalink
migrate to python3
Browse files Browse the repository at this point in the history
Hopefully, fix utf-8 related issues projecthamster#153, projecthamster#239, projecthamster#317

Co-authored-by: Nikita Kazeev
Thanks for showing the way in PR projecthamster#174 !
  • Loading branch information
ederag committed Aug 21, 2018
1 parent d2061d5 commit 78c2867
Show file tree
Hide file tree
Showing 28 changed files with 165 additions and 155 deletions.
22 changes: 21 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,28 @@ but has not been thouroughly tested.
Backup `hamster.db` first,
and keep track of activities on a text file too for some days !

To use the development version:
```
pkill -f hamster-service
pkill -f hamster-windows-service
src/hamster-service &
src/hamster-windows-service &
src/hamster-cli
```

To install, python2 is still necessary (for waf).
Adapt the paths below to your system,
`sudo rm/mv` commands, beware !
```
./waf configure build --prefix=/usr && sudo ./waf install
sudo rm -rf /usr/lib/python3.6/site-packages/hamster
sudo mv /usr/lib/python2.7/site-packages/hamster /usr/lib/python3.6/site-packages/
```


*[README from the original repo below]*

**IMPORTANT [note from the original repo]**
**IMPORTANT**
Project Hamster is undergoing a period of major transition. Unless someone
steps up to the task, this repository will remain unmaintained as the
majority of our resources are directed to a rewrite (repositories:
Expand Down
48 changes: 24 additions & 24 deletions src/hamster-cli
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# - coding: utf-8 -

# Copyright (C) 2010 Matías Ribecky <matias at mribecky.com.ar>
Expand Down Expand Up @@ -142,7 +142,7 @@ class HamsterClient(object):
"/org/gnome/Hamster/WindowServer")
getattr(server, window_name)()
else:
print "Running in devel mode"
print("Running in devel mode")
from gi.repository import Gtk as gtk
from hamster.lib.configuration import dialogs
getattr(dialogs, window_name).show()
Expand Down Expand Up @@ -173,7 +173,7 @@ class HamsterClient(object):
formats = "html tsv xml ical".split()
chosen = sys.argv[-1]
formats = [f for f in formats if not chosen or f.startswith(chosen)]
print "\n".join(formats)
print("\n".join(formats))


def toggle(self):
Expand All @@ -187,7 +187,7 @@ class HamsterClient(object):
def start(self, *args):
'''Start a new activity.'''
if not args:
print "Error: please specify activity"
print("Error: please specify activity")
return

activity = args[0]
Expand Down Expand Up @@ -216,7 +216,7 @@ class HamsterClient(object):
facts = self.storage.get_facts(start_time, end_time)

writer = reports.simple(facts, start_time, end_time, export_format)
print writer.export()
print(writer.export())


def _activities(self, search=""):
Expand All @@ -225,24 +225,24 @@ class HamsterClient(object):
activity, category = search.split("@")
for cat in self.storage.get_categories():
if not category or cat['name'].lower().startswith(category.lower()):
print "%s@%s" % (activity.encode("utf8"), cat['name'].encode("utf8"))
print("{}@{}".format(activity, cat['name']))
else:
for activity in self.storage.get_activities(search):
print activity['name'].encode('utf8')
print(activity['name'])
if activity['category']:
print '%s@%s' % (activity['name'].encode('utf8'), activity['category'].encode('utf8'))
print("{}@{}".format(activity['name'], activity['category']))


def activities(self, *args):
'''Print the names of all the activities.'''
search = args[0] if args else ""
for activity in self.storage.get_activities(search):
print '%s@%s' % (activity['name'].encode('utf8'), activity['category'].encode('utf8'))
print("{}@{}".format(activity['name'], activity['category']))

def categories(self, *args):
'''Print the names of all the categories.'''
for category in self.storage.get_categories():
print category['name'].encode('utf8')
print(category['name'])


def list(self, *times):
Expand All @@ -258,10 +258,10 @@ class HamsterClient(object):
"""prints current activity. kinda minimal right now"""
facts = self.storage.get_todays_facts()
if facts and not facts[-1].end_time:
print "%s %s" % (unicode(facts[-1]).encode("utf-8").strip(),
stuff.format_duration(facts[-1].delta, human=False))
print("{} {}".format(str(facts[-1]).strip(),
stuff.format_duration(facts[-1].delta, human=False)))
else:
print _("No activity")
print((_("No activity")))


def search(self, *args):
Expand Down Expand Up @@ -307,11 +307,11 @@ class HamsterClient(object):
cols = ["{{{col}: <{len}}}".format(col=col, len=widths[col]) for col in cols]
fact_line = " | ".join(cols)

row_width = sum([val + 3 for val in widths.values()])
row_width = sum(val + 3 for val in list(widths.values()))

print
print fact_line.format(**headers)
print "-" * min(row_width, 80)
print()
print(fact_line.format(**headers))
print("-" * min(row_width, 80))

by_cat = {}
for fact in facts:
Expand All @@ -320,26 +320,26 @@ class HamsterClient(object):
by_cat[cat] += fact.delta

pretty_fact = fact_dict(fact, print_with_date)
print fact_line.format(**pretty_fact)
print(fact_line.format(**pretty_fact))

if pretty_fact['description']:
for line in word_wrap(pretty_fact['description'], 76):
print " %s" % line
print(" {}".format(line))

if pretty_fact['tags']:
for line in word_wrap(pretty_fact['tags'], 76):
print " %s" % line
print(" {}".format(line))

print "-" * min(row_width, 80)
print("-" * min(row_width, 80))

cats = []
for cat, duration in sorted(by_cat.iteritems(), key=lambda x: x[1], reverse=True):
for cat, duration in sorted(by_cat.items(), key=lambda x: x[1], reverse=True):
cats.append("%s: %s" % (cat, "%.1fh" % (stuff.duration_minutes(duration) / 60.0)))

for line in word_wrap(", ".join(cats), 80):
print line
print(line)

print
print()



Expand Down
8 changes: 4 additions & 4 deletions src/hamster-service
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# nicked off gwibber

from gi.repository import GObject as gobject
Expand All @@ -13,7 +13,7 @@ DBusGMainLoop(set_as_default=True)
loop = gobject.MainLoop()

if "org.gnome.Hamster" in dbus.SessionBus().list_names():
print "Found hamster-service already running, exiting"
print("Found hamster-service already running, exiting")
quit()

from hamster.lib import i18n
Expand Down Expand Up @@ -88,7 +88,7 @@ class Storage(db.Storage, dbus.service.Object):
# anyway. should make updating simpler
def _on_us_change(self, monitor, gio_file, event_uri, event):
if event == gio.FileMonitorEvent.CHANGES_DONE_HINT:
print "`%s` has changed. Quitting!" % __file__
print("`{}` has changed. Quitting!".format(__file__))
self.Quit()

@dbus.service.signal("org.gnome.Hamster")
Expand Down Expand Up @@ -301,6 +301,6 @@ class Storage(db.Storage, dbus.service.Object):


if __name__ == '__main__':
print "hamster-service up"
print("hamster-service up")
storage = Storage(loop)
loop.run()
8 changes: 4 additions & 4 deletions src/hamster-windows-service
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env python2
#!/usr/bin/env python3
# nicked off hamster-service

from gi.repository import GObject as gobject
Expand All @@ -10,7 +10,7 @@ DBusGMainLoop(set_as_default=True)
loop = gobject.MainLoop()

if "org.gnome.Hamster.WindowServer" in dbus.SessionBus().list_names():
print "Found hamster-window-service already running, exiting"
print("Found hamster-window-service already running, exiting")
quit()


Expand Down Expand Up @@ -54,11 +54,11 @@ if __name__ == '__main__':
from hamster.lib import i18n
i18n.setup_i18n()

glib.set_prgname(unicode(_("hamster-windows-service")).encode("utf-8"))
glib.set_prgname(str(_("hamster-windows-service")))

from hamster.lib.configuration import runtime, dialogs, conf, load_ui_file
window_server = WindowServer(loop)

print "hamster-window-service up"
print("hamster-window-service up")

loop.run()
4 changes: 2 additions & 2 deletions src/hamster/about.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ def __init__(self, parent = None):
"program-name" : _("Time Tracker"),
"name" : _("Time Tracker"), #this should be deprecated in gtk 2.10
"version" : runtime.version,
"comments" : _(u"Project Hamster — track your time"),
"copyright" : _(u"Copyright © 2007–2010 Toms Bauģis and others"),
"comments" : _("Project Hamster — track your time"),
"copyright" : _("Copyright © 2007–2010 Toms Bauģis and others"),
"website" : "http://projecthamster.wordpress.com/",
"website-label" : _("Project Hamster Website"),
"title": _("About Time Tracker"),
Expand Down
8 changes: 4 additions & 4 deletions src/hamster/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@ class Storage(gobject.GObject):
The rest is hopefully obvious. But if not, please file bug reports!
"""
__gsignals__ = {
"tags-changed": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
"facts-changed": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
"activities-changed": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
"toggle-called": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
"tags-changed": (gobject.SignalFlags.RUN_LAST, gobject.TYPE_NONE, ()),
"facts-changed": (gobject.SignalFlags.RUN_LAST, gobject.TYPE_NONE, ()),
"activities-changed": (gobject.SignalFlags.RUN_LAST, gobject.TYPE_NONE, ()),
"toggle-called": (gobject.SignalFlags.RUN_LAST, gobject.TYPE_NONE, ()),
}

def __init__(self):
Expand Down
7 changes: 3 additions & 4 deletions src/hamster/edit_activity.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@
""" TODO: hook into notifications and refresh our days if some evil neighbour
edit fact window has dared to edit facts
"""
import widgets
from hamster import widgets
from hamster.lib.configuration import runtime, conf, load_ui_file
from hamster.lib.stuff import datetime_to_hamsterday
from lib import Fact
from hamster.lib import Fact

class CustomFactController(gobject.GObject):
__gsignals__ = {
Expand Down Expand Up @@ -106,8 +106,7 @@ def show(self):

def figure_description(self):
buf = self.get_widget('description').get_buffer()
description = buf.get_text(buf.get_start_iter(), buf.get_end_iter(), 0)\
.decode("utf-8")
description = buf.get_text(buf.get_start_iter(), buf.get_end_iter(), 0)
return description.strip()


Expand Down
2 changes: 1 addition & 1 deletion src/hamster/external.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,6 @@ def get_eds_tasks():
if task.get_status() in [ecal.ICAL_STATUS_NONE, ecal.ICAL_STATUS_INPROCESS]:
tasks.append({'name': task.get_summary(), 'category' : category})
return tasks
except Exception, e:
except Exception as e:
logging.warn(e)
return []
10 changes: 5 additions & 5 deletions src/hamster/lib/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def figure_time(str_time):
# 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)
numbers = [x for x in numbers if x!=""]

hours, minutes = None, None

Expand Down Expand Up @@ -87,7 +87,7 @@ def __init__(self, activity="", category = "", description = "", tags = "",
self.activity_id = activity_id

phase = "start_time" if date else "date"
for key, val in parse_fact(activity, phase, {}, date).iteritems():
for key, val in parse_fact(activity, phase, {}, date).items():
setattr(self, key, val)

# override implicit with explicit
Expand All @@ -109,11 +109,11 @@ def __iter__(self):
'description': self.description,
'tags': [tag.encode("utf-8").strip() for tag in self.tags],
'date': calendar.timegm(date.timetuple()) if date else "",
'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 "",
'start_time': self.start_time if isinstance(self.start_time, str) else calendar.timegm(self.start_time.timetuple()),
'end_time': self.end_time if isinstance(self.end_time, str) else calendar.timegm(self.end_time.timetuple()) if self.end_time else "",
'delta': self.delta.seconds + self.delta.days * 24 * 60 * 60 if self.delta else "" #duration in seconds
}
return iter(keys.items())
return keys.items()


@property
Expand Down
2 changes: 1 addition & 1 deletion src/hamster/lib/charting.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from gi.repository import Pango as pango
import datetime as dt
import time
import graphics, stuff
from hamster.lib import graphics, stuff
import locale

class Bar(graphics.Sprite):
Expand Down
6 changes: 3 additions & 3 deletions src/hamster/lib/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@

class Controller(gobject.GObject):
__gsignals__ = {
"on-close": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
"on-close": (gobject.SignalFlags.RUN_LAST, gobject.TYPE_NONE, ()),
}

def __init__(self, parent=None, ui_file=""):
Expand Down Expand Up @@ -132,7 +132,7 @@ def __init__(self, get_dialog_class):
self.dialog_close_handlers = {}

def on_close_window(self, dialog):
for key, assoc_dialog in list(self.dialogs.iteritems()):
for key, assoc_dialog in list(self.dialogs.items()):
if dialog == assoc_dialog:
del self.dialogs[key]

Expand Down Expand Up @@ -215,7 +215,7 @@ class GConfStore(gobject.GObject, Singleton):
}

__gsignals__ = {
"conf-changed": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT))
"conf-changed": (gobject.SignalFlags.RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT))
}
def __init__(self):
gobject.GObject.__init__(self)
Expand Down
6 changes: 3 additions & 3 deletions src/hamster/lib/desktop.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def check_hamster(self):
todays_facts = self.storage._Storage__get_todays_facts()
self.check_user(todays_facts)
trophies.check_ongoing(todays_facts)
except Exception, e:
except Exception as e:
logging.error("Error while refreshing: %s" % e)
finally: # we want to go on no matter what, so in case of any error we find out about it sooner
return True
Expand All @@ -79,13 +79,13 @@ def check_user(self, todays_facts):
duration = delta.seconds / 60

if duration and duration % interval == 0:
message = _(u"Working on %s") % last_activity['name']
message = _("Working on %s") % last_activity['name']
self.notify_user(message)

elif self.conf_notify_on_idle:
#if we have no last activity, let's just calculate duration from 00:00
if (now.minute + now.hour * 60) % interval == 0:
self.notify_user(_(u"No activity"))
self.notify_user(_("No activity"))


def notify_user(self, summary="", details=""):
Expand Down
Loading

0 comments on commit 78c2867

Please sign in to comment.