Skip to content

/ Zope / gocept svn checkins / Archive / 2010 / 2010-02 / SVN: r30610 - gtimelog/trunk/src/gocept/gtimelog

[ << ] [ >> ]

[ SVN: r30604 - gocept.download/trunk / Thomas ... ] [ SVN: r30616 - gtimelog/tags/0.1.3 / Christian ... ]

SVN: r30610 - gtimelog/trunk/src/gocept/gtimelog
Christian Theune <ct(at)gocept.com>
2010-02-18 19:45:09 [ FULL ]
Author: ctheune
Date: Thu Feb 18 19:45:07 2010
New Revision: 30610

Log:
Code cleanup to fit PEP 8.



Modified:
   gtimelog/trunk/src/gocept/gtimelog/gtimelog.py

Modified: gtimelog/trunk/src/gocept/gtimelog/gtimelog.py
==============================================================================
--- gtimelog/trunk/src/gocept/gtimelog/gtimelog.py	(original)
+++ gtimelog/trunk/src/gocept/gtimelog/gtimelog.py	Thu Feb 18 19:45:07 2010
(at)(at) -34,6 +34,7 (at)(at)
     """Calculates duration and returns tuple (h, m)"""
     return divmod((duration.days * 24 * 60 + duration.seconds // 60), 60)
 
+
 def format_duration(duration):
     """Format a datetime.timedelta with minute precision."""
     return '%d h %d min' % calc_duration(duration)
(at)(at) -74,7 +75,8 (at)(at)
 
 
 def strftime_emulate_percent_V(timestamp):
-    """M$ Windows does not know %V as strftime option, so we have to emulate
it.
+    """M$ Windows does not know %V as strftime option, so we have to emulate
+       it.
 
     Manual of strftime:
      %V    is replaced by the week number of the year (Monday as the first day
(at)(at) -98,6 +100,7 (at)(at)
         delta = 0
     return str(int(timestamp.strftime('%W')) + delta)
 
+
 def virtual_day(dt, virtual_midnight):
     """Return the "virtual day" of a timestamp.
 
(at)(at) -252,7 +255,7 (at)(at)
         Slacking entries are identified by finding two asterisks in the
         title.
         The holidays are indicated by '$$$'.
-        For entries ending with '/2' half is counted as work and other half is

+        For entries ending with '/2' half is counted as work and other half is
         counted as slacking.
         Entry lists are sorted, and contain (start, entry, duration)
         tuples.
(at)(at) -299,7 +302,7 (at)(at)
         title. Holidays are identified by three $ symbols by the end of
         the entry.
 
-        For entries ending with '/2' is half of the time is counted as work 
+        For entries ending with '/2' is half of the time is counted as work
         and the other half is counted as slacking.
 
         Assuming that
(at)(at) -339,7 +342,7 (at)(at)
         try:
             import socket
             idhost = socket.getfqdn()
-        except: # can it actually ever fail?
+        except:  # can it actually ever fail?
             idhost = 'localhost'
         dtstamp = datetime.datetime.utcnow().strftime("%Y%m%dT%H%M%SZ")
         for start, stop, duration, entry in self.all_entries():
(at)(at) -424,7 +427,7 (at)(at)
             work.sort()
             for entry, duration in work:
                 if not duration:
-                    continue # skip empty "arrival" entries
+                    continue  # skip empty "arrival" entries
                 entry = entry[:1].upper() + entry[1:]
                 if estimated_column:
                     print >> output, ("%-46s  %-14s  %s" %
(at)(at) -458,14 +461,14 (at)(at)
         self.history = []
         self.window = TimeWindow(self.filename, min, max,
                                  self.virtual_midnight,
-                                 callback=self.history.append, 
+                                 callback=self.history.append,
                                  settings=self.settings)
         self.need_space = not self.window.items
 
     def window_for(self, min, max):
         """Return a TimeWindow for a specified time interval."""
         return TimeWindow(self.filename, min, max,
-                          self.virtual_midnight, 
+                          self.virtual_midnight,
                           settings=self.settings)
 
     def raw_append(self, line):
(at)(at) -530,7 +533,8 (at)(at)
             return False
 
     def get_mtime(self):
-        """Return the mtime of self.filename, or None if the file doesn't
exist."""
+        """Return the mtime of self.filename, or None if the file doesn't
+        exist."""
         try:
             return os.stat(self.filename).st_mtime
         except OSError:
(at)(at) -551,7 +555,7 (at)(at)
                     group, task = self.other_title, line
                 groups.setdefault(group, []).append(task)
         except IOError:
-            pass # the file's not there, so what?
+            pass  # the file's not there, so what?
         self.groups = groups.items()
         self.groups.sort()
 
(at)(at) -574,7 +578,7 (at)(at)
         self.first_time = True
 
         self.hours = hours.HourTracker(settings)
-        
+
     def check_reload(self):
         """Check whether the task list needs to be reloaded.
 
(at)(at) -622,9 +626,10 (at)(at)
                 for task in  file(self.filename):
                     if not task or task.startswith('#'):
                         continue
-                    groups.setdefault(project, []).append('
'.join(task.split()[1:]))
+                    groups.setdefault(project, []).append(
+                        ' '.join(task.split()[1:]))
         except IOError:
-            pass # the file's not there, so what?
+            pass  # the file's not there, so what?
         self.groups = groups.items()
         self.groups.sort()
 
(at)(at) -761,7 +766,7 (at)(at)
         self.collmex_employee_id = config.get('collmex', 'employee_id')
         self.collmex_username = config.get('collmex', 'username')
         self.collmex_password = config.get('collmex', 'password')
-        self.collmex_task_language= config.get('collmex', 'task_language')
+        self.collmex_task_language = config.get('collmex', 'task_language')
 
         self.hours_url = config.get('hours', 'url')
         self.hours_username = config.get('hours', 'username')
(at)(at) -795,8 +800,8 (at)(at)
         try:
             import egg.trayicon
         except ImportError:
-            return # nothing to do here, move along
-                   # or install python-gnome2-extras
+            return  # nothing to do here, move along
+                    # or install python-gnome2-extras
         self.tooltips = gtk.Tooltips()
         self.eventbox = gtk.EventBox()
         hbox = gtk.HBox()
(at)(at) -837,9 +842,9 (at)(at)
             return
         main_window = self.gtimelog_window.main_window
         if main_window.get_property("visible"):
-           main_window.hide()
+            main_window.hide()
         else:
-           main_window.present()
+            main_window.present()
 
     def entry_added(self, entry):
         """An entry has been added."""
(at)(at) -848,20 +853,21 (at)(at)
     def tick(self, force_update=False):
         """Tick every second."""
         now = datetime.datetime.now().replace(second=0, microsecond=0)
-        if now != self.last_tick or force_update: # Do not eat CPU too much
+        if now != self.last_tick or force_update:  # Do not eat CPU too much
             self.last_tick = now
             last_time = self.timelog.window.last_time()
             if last_time is None:
                 self.time_label.set_text(now.strftime("%H:%M"))
             else:
-                self.time_label.set_text(format_duration_short(now -
last_time))
+                self.time_label.set_text(
+                    format_duration_short(now - last_time))
         self.tooltips.set_tip(self.trayicon, self.tip())
         return True
 
     def tip(self):
         """Compute tooltip text."""
         current_task = self.gtimelog_window.task_entry.get_text()
-        if not current_task: 
+        if not current_task:
             current_task = "nothing"
         tip = "GTimeLog: working on %s" % current_task
         total_work, total_slacking, total_holidays = (
(at)(at) -945,7 +951,7 (at)(at)
     def get_clicked_calendar_day(self):
         if self.calendar_dialog.run() == gtk.RESPONSE_OK:
             y, m1, d = self.calendar.get_date()
-            date = datetime.date(y, m1+1, d)
+            date = datetime.date(y, m1 + 1, d)
         else:
             date = None
         self.calendar_dialog.hide()
(at)(at) -953,7 +959,7 (at)(at)
 
     def get_timeframe(self):
         """Returns from dates and to dates used for calulating the
-           weekly time-window. Addtionally the number of weeks is 
+           weekly time-window. Addtionally the number of weeks is
            returned.
 
            Returns (min, max, weekcount)
(at)(at) -1096,7 +1102,7 (at)(at)
         if self.chronological:
             for item in self.timelog.window.all_entries():
                 self.write_item(item)
-        else:
+        elif self.grouped:
             work, slack, hold = self.timelog.window.grouped_entries()
             for start, entry, duration in work + slack:
                 self.write_group(entry, duration)
(at)(at) -1309,7 +1315,7 (at)(at)
         """
         if self.calendar_dialog.run() == gtk.RESPONSE_OK:
             y, m1, d = self.calendar.get_date()
-            day = datetime.date(y, m1+1, d)
+            day = datetime.date(y, m1 + 1, d)
         else:
             day = None
         self.calendar_dialog.hide()
(at)(at) -1352,7 +1358,7 (at)(at)
         try:
             collmex = gocept.gtimelog.collmex.Collmex(self.settings)
             collmex.report(window.all_entries())
-        except Exception,err:
+        except Exception, err:
             message = "Collmex: %s" % err
         else:
             message = "Collmex: success "
(at)(at) -1372,7 +1378,7 (at)(at)
             tracker.loadWeek(week, year)
             tracker.setHours(window.all_entries())
             tracker.saveWeek()
-        except Exception,err:
+        except Exception, err:
             message = "HT: %s" % err
         else:
             message = "HT: success "
(at)(at) -1384,7 +1390,7 (at)(at)
             redupdate = redmine.RedmineTimelogUpdater(self.settings)
             redupdate.update(window)
             message = " Redmine: success"
-        except Exception,err:
+        except Exception, err:
             message = " Redmine: %s" % err
         return message
 
(at)(at) -1398,7 +1404,7 (at)(at)
 
     def mail(self, write_draft):
         """Send an email."""
-        draftfn = tempfile.mktemp(suffix='gtimelog') # XXX unsafe!
+        draftfn = tempfile.mktemp(suffix='gtimelog')  # XXX unsafe!
         draft = open(draftfn, 'w')
         write_draft(draft, self.settings.email, self.settings.name)
         draft.close()
(at)(at) -1564,7 +1570,7 (at)(at)
         argv = sys.argv
     configdir = os.path.expanduser('~/.gtimelog')
     try:
-        os.makedirs(configdir) # create it if it doesn't exist
+        os.makedirs(configdir)  # create it if it doesn't exist
     except OSError:
         pass
     settings = Settings()
(at)(at) -1593,7 +1599,6 (at)(at)
     logging.root.setLevel(settings.log_level)
     print 'Logging is set to level %s' % settings.log_level
 
-
     # start gtimelog hidden to tray
     if "--start-hidden" in argv:
         main_window.on_hide_activate("")
(at)(at) -1606,4 +1611,3 (at)(at)
 
 if __name__ == '__main__':
     main()
-

SVN: r30611 - gtimelog/trunk/src/gocept/gtimelog
Christian Theune <ct(at)gocept.com>
2010-02-18 19:45:45 [ FULL ]
Author: ctheune
Date: Thu Feb 18 19:45:45 2010
New Revision: 30611

Log:
Revert part of last checkin: a not-yet ready code change sneaked in.



Modified:
   gtimelog/trunk/src/gocept/gtimelog/gtimelog.py

Modified: gtimelog/trunk/src/gocept/gtimelog/gtimelog.py
==============================================================================
--- gtimelog/trunk/src/gocept/gtimelog/gtimelog.py	(original)
+++ gtimelog/trunk/src/gocept/gtimelog/gtimelog.py	Thu Feb 18 19:45:45 2010
(at)(at) -1102,7 +1102,7 (at)(at)
         if self.chronological:
             for item in self.timelog.window.all_entries():
                 self.write_item(item)
-        elif self.grouped:
+        else:
             work, slack, hold = self.timelog.window.grouped_entries()
             for start, entry, duration in work + slack:
                 self.write_group(entry, duration)

SVN: r30612 - gtimelog/trunk/src/gocept/gtimelog
Christian Theune <ct(at)gocept.com>
2010-02-18 19:55:50 [ FULL ]
Author: ctheune
Date: Thu Feb 18 19:55:49 2010
New Revision: 30612

Log:
Make display mode more flexible.



Modified:
   gtimelog/trunk/src/gocept/gtimelog/gtimelog.py

Modified: gtimelog/trunk/src/gocept/gtimelog/gtimelog.py
==============================================================================
--- gtimelog/trunk/src/gocept/gtimelog/gtimelog.py	(original)
+++ gtimelog/trunk/src/gocept/gtimelog/gtimelog.py	Thu Feb 18 19:55:49 2010
(at)(at) -996,7 +996,7 (at)(at)
 class MainWindow(object):
     """Main application window."""
 
-    chronological = True
+    view = 'chronological'
     footer_mark = None
 
     # Try to prevent timer routines mucking with the buffer while we're
(at)(at) -1099,7 +1099,7 (at)(at)
                             self.timelog.virtual_midnight)
         today = today.strftime('%A, %Y-%m-%d (week %V)')
         self.w(today + '\n\n', 'today')
-        if self.chronological:
+        if self.view == 'chronological':
             for item in self.timelog.window.all_entries():
                 self.write_item(item)
         else:
(at)(at) -1281,13 +1281,11 (at)(at)
         self.about_dialog.show()
 
     def on_chronological_activate(self, widget):
-        """View -> Chronological"""
-        self.chronological = True
+        self.view = 'chronological'
         self.populate_log()
 
     def on_grouped_activate(self, widget):
-        """View -> Grouped"""
-        self.chronological = False
+        self.view = 'grouped'
         self.populate_log()
 
     def on_daily_report_activate(self, widget):

SVN: r30613 - gtimelog/trunk/src/gocept/gtimelog
Christian Theune <ct(at)gocept.com>
2010-02-18 20:02:06 [ FULL ]
Author: ctheune
Date: Thu Feb 18 20:02:05 2010
New Revision: 30613

Log:
- Start working on weekly review mode.
- Fix initial status of view mode radio buttons: only enable first one.




Modified:
   gtimelog/trunk/src/gocept/gtimelog/gtimelog.glade
   gtimelog/trunk/src/gocept/gtimelog/gtimelog.py

Modified: gtimelog/trunk/src/gocept/gtimelog/gtimelog.glade
==============================================================================
--- gtimelog/trunk/src/gocept/gtimelog/gtimelog.glade	(original)
+++ gtimelog/trunk/src/gocept/gtimelog/gtimelog.glade	Thu Feb 18 20:02:05 2010
(at)(at) -291,11 +291,23 (at)(at)
 		      <property name="visible">True</property>
 		      <property name="label"
translatable="yes">_Grouped</property>
 		      <property name="use_underline">True</property>
-		      <property name="active">True</property>
+		      <property name="active">False</property>
 		      <property name="group">chronological</property>
 		      <signal name="activate" handler="on_grouped_activate"
last_modification_time="Fri, 03 Sep 2004 18:56:59 GMT"/>
 		      <accelerator key="2" modifiers="GDK_MOD1_MASK"
signal="activate"/>
 		    </widget>
+      </child>
+
+		  <child>
+		    <widget class="GtkRadioMenuItem" id="weekly_review">
+		      <property name="visible">True</property>
+		      <property name="label" translatable="yes">_Weekly
review</property>
+		      <property name="use_underline">True</property>
+		      <property name="active">False</property>
+		      <property name="group">chronological</property>
+		      <signal name="activate" handler="on_weekly_activate"
last_modification_time="Fri, 03 Sep 2004 18:56:59 GMT"/>
+		      <accelerator key="3" modifiers="GDK_MOD1_MASK"
signal="activate"/>
+		    </widget>
 		  </child>
 
 		  <child>

Modified: gtimelog/trunk/src/gocept/gtimelog/gtimelog.py
==============================================================================
--- gtimelog/trunk/src/gocept/gtimelog/gtimelog.py	(original)
+++ gtimelog/trunk/src/gocept/gtimelog/gtimelog.py	Thu Feb 18 20:02:05 2010
(at)(at) -1288,6 +1288,10 (at)(at)
         self.view = 'grouped'
         self.populate_log()
 
+    def on_weekly_activate(self, widget):
+        self.view = 'weekly'
+        self.populate_log()
+
     def on_daily_report_activate(self, widget):
         """File -> Daily Report"""
         window = self.timelog.window

SVN: r30614 - gtimelog/trunk/src/gocept/gtimelog
Christian Theune <ct(at)gocept.com>
2010-02-18 20:35:59 [ FULL ]
Author: ctheune
Date: Thu Feb 18 20:35:57 2010
New Revision: 30614

Log:
Implement another view: weekly review.

It shows how much time you spend in which project and the percentage.



Modified:
   gtimelog/trunk/src/gocept/gtimelog/gtimelog.py

Modified: gtimelog/trunk/src/gocept/gtimelog/gtimelog.py
==============================================================================
--- gtimelog/trunk/src/gocept/gtimelog/gtimelog.py	(original)
+++ gtimelog/trunk/src/gocept/gtimelog/gtimelog.py	Thu Feb 18 20:35:57 2010
(at)(at) -1102,7 +1102,31 (at)(at)
         if self.view == 'chronological':
             for item in self.timelog.window.all_entries():
                 self.write_item(item)
-        else:
+        elif self.view == 'weekly':
+            window = self.weekly_window()
+            entries = iter(window.all_entries())
+            entries.next()  # ignore first
+            projects = {}
+            for start, stop, dur, entry in entries:
+                if '**' in entry:
+                    continue
+                project = entry.split(':')[0].lower()
+                duration = projects.setdefault(project, datetime.timedelta())
+                projects[project] = duration + dur
+            total = sum(projects.values(), datetime.timedelta())
+            total_seconds = (total.days * 24 * 60 * 60) + total.seconds
+            for project, duration in sorted(
+                    projects.items(), key=lambda x: x[1], reverse=True):
+                if duration == datetime.timedelta():
+                    continue
+                duration_seconds = float(duration.days * 24 * 60 * 60 +
+                                         duration.seconds)
+                self.w(format_duration(duration), 'duration')
+                self.w('\t')
+                self.w('%0.2i%%' % ((duration_seconds / total_seconds) * 100),
+                       'time')
+                self.w('\t%s\n' % project)
+        elif self.view == 'grouped':
             work, slack, hold = self.timelog.window.grouped_entries()
             for start, entry, duration in work + slack:
                 self.write_group(entry, duration)
(at)(at) -1531,7 +1555,7 (at)(at)
             return
         self.add_history(entry)
         self.timelog.append(entry)
-        if self.chronological:
+        if self.view == 'chronological':
             self.delete_footer()
             self.write_item(self.timelog.window.last_entry())
             self.add_footer()

SVN: r30615 - gtimelog/trunk
Christian Theune <ct(at)gocept.com>
2010-02-19 11:36:55 [ FULL ]
Author: ctheune
Date: Fri Feb 19 11:36:52 2010
New Revision: 30615

Log:
Preparing release 0.1.3


Modified:
   gtimelog/trunk/CHANGES.txt
   gtimelog/trunk/setup.py

Modified: gtimelog/trunk/CHANGES.txt
==============================================================================
--- gtimelog/trunk/CHANGES.txt	(original)
+++ gtimelog/trunk/CHANGES.txt	Fri Feb 19 11:36:52 2010
(at)(at) -2,7 +2,7 (at)(at)
 =========
 
 
-0.1.3 (unreleased)
+0.1.3 (2010-02-19)
 ------------------
 
 - Nothing changed yet.

Modified: gtimelog/trunk/setup.py
==============================================================================
--- gtimelog/trunk/setup.py	(original)
+++ gtimelog/trunk/setup.py	Fri Feb 19 11:36:52 2010
(at)(at) -14,7 +14,7 (at)(at)
 
 setup(
     name=name,
-    version = '0.1.3dev',
+    version = '0.1.3',
     license='ZPL 2.1',
     description='gocept fork of gtimelog.',
     long_description = (read('README.txt')),

SVN: r30627 - gtimelog/trunk/src/gocept/gtimelog
Christian Theune <ct(at)gocept.com>
2010-02-26 10:46:36 [ FULL ]
Author: ctheune
Date: Fri Feb 26 10:46:35 2010
New Revision: 30627

Log:
Make autocompletion more relaxed: support splitted matching, unordered and
arbitrary sub-strings.



Modified:
   gtimelog/trunk/src/gocept/gtimelog/gtimelog.py

Modified: gtimelog/trunk/src/gocept/gtimelog/gtimelog.py
==============================================================================
--- gtimelog/trunk/src/gocept/gtimelog/gtimelog.py	(original)
+++ gtimelog/trunk/src/gocept/gtimelog/gtimelog.py	Fri Feb 26 10:46:35 2010
(at)(at) -1268,6 +1268,17 (at)(at)
         completion = gtk.EntryCompletion()
         completion.set_model(self.completion_choices)
         completion.set_text_column(0)
+
+        def match_func(completion, key, iter):
+            model = completion.get_model()
+            text = model.get_value(iter, 0)
+            for k in key.split():
+                if k not in text:
+                    break
+            else:
+                return True
+            return False
+        completion.set_match_func(match_func)
         self.task_entry.set_completion(completion)
 
     def add_history(self, entry):

SVN: r30632 - in gtimelog/trunk: . src/gocept/gtimelog
Christian Theune <ct(at)gocept.com>
2010-02-26 11:06:23 [ FULL ]
Author: ctheune
Date: Fri Feb 26 11:06:22 2010
New Revision: 30632

Log:
Avoid duplicate entries in auto completion from persistent history.



Modified:
   gtimelog/trunk/CHANGES.txt
   gtimelog/trunk/src/gocept/gtimelog/gtimelog.py

Modified: gtimelog/trunk/CHANGES.txt
==============================================================================
--- gtimelog/trunk/CHANGES.txt	(original)
+++ gtimelog/trunk/CHANGES.txt	Fri Feb 26 11:06:22 2010
(at)(at) -5,7 +5,8 (at)(at)
 0.1.5 (unreleased)
 ------------------
 [...]

SVN: r30640 - gtimelog/trunk/src/gocept/gtimelog
Christian Theune <ct(at)gocept.com>
2010-02-26 13:08:13 [ FULL ]
Author: ctheune
Date: Fri Feb 26 13:08:11 2010
New Revision: 30640

Log:
More effort on keeping a clean autocompletion list.



Modified:
   gtimelog/trunk/src/gocept/gtimelog/gtimelog.py

Modified: gtimelog/trunk/src/gocept/gtimelog/gtimelog.py
==============================================================================
--- gtimelog/trunk/src/gocept/gtimelog/gtimelog.py	(original)
+++ gtimelog/trunk/src/gocept/gtimelog/gtimelog.py	Fri Feb 26 13:08:11 2010
(at)(at) -1253,7 +1253,18 (at)(at)
         for entry in rev_history:
             if entry not in history:
                 history.insert(0, entry)
-        for entry in set(history):
+        self.completion_source = set(history)
+        self._update_completion_choices()
+
+    def _update_completion_choices(self):
+        total = set()
+        for line in self.completion_source:
+            line = line.lower()
+            if line.endswith(' **'):
+                line = line.replace(' **', '**')
+            total.add(line)
+        self.completion_choices.clear()
+        for entry in sorted(total):
             self.completion_choices.append([entry])
 
     def set_up_completion(self):
(at)(at) -1287,8 +1298,8 (at)(at)
         self.history_pos = 0
         if not self.have_completion:
             return
-        if entry not in [row[0] for row in self.completion_choices]:
-            self.completion_choices.append([entry])
+        self.completion_source.add(entry)
+        self._update_completion_choices()
 
     def delete_event(self, widget, data=None):
         """Try to close the window."""

MailBoxer