emacs-wiki-discuss
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[emacs-wiki-discuss] Patch to planner-timeclock-summary: added filtering


From: Chris Parsons
Subject: [emacs-wiki-discuss] Patch to planner-timeclock-summary: added filtering and plan-page summaries
Date: Thu, 16 Dec 2004 22:15:21 +0000
User-agent: Gnus/5.110003 (No Gnus v0.3) Emacs/21.3 (windows-nt)

Hi all,

Another patch to planner-timeclock-summary.el - this one allows
filtering by regexp on the task string. My timesheets look lovely now -
next thing, once this is safely integrated, is to allow grouping of
tasks with the same prefix under one total.

A nice side effect of this work is that it wasn't hard to add support
for automatic updating of a Timeclock section in the plan page. Assuming
you've run planner-timeclock-summary-insinuate, just add '* Timeclock'
(or your own string if you've customized it) to a plan page and it'll
'just work'.

Plan page summaries will also include 'sub pages' if you turn the new
custom variable planner-timeclock-summary-include-sub-plan-pages
on. Read the documentation on the variable for more info.

Hope this is useful to someone else too, certainly is for me... :)

Chris

diff -u "c:/Program 
Files/emacs-21.3/site-lisp/planner/planner-timeclock-summary.el.orig" 
"c:/Program Files/emacs-21.3/site-lisp/planner/planner-timeclock-summary.el"
--- c:/Program 
Files/emacs-21.3/site-lisp/planner/planner-timeclock-summary.el.orig     
2004-12-16 20:29:58.659756800 +0000
+++ c:/Program Files/emacs-21.3/site-lisp/planner/planner-timeclock-summary.el  
2004-12-16 22:08:55.075904000 +0000
@@ -90,8 +90,22 @@
   :type 'string
   :group 'planner-timeclock-summary)
 
+(defcustom planner-timeclock-summary-include-sub-plan-pages nil
+  "Include 'sub plan pages' when doing plan page reports?
+
+If non-nil, when updating timeclock reports on plan pages we will
+also include plan pages which have this page's name as a prefix. If
+nil, only exact matches will be included.
+
+For example: if nil, on a plan page called 'Personal' we would only
+include timeclock data marked as 'Personal' (this is the default
+behaviour). If non-nil, we would additionally include
+'PersonalHomework', 'PersonalYodeling' etc."
+  :type 'boolean
+  :group 'planner-timeclock-summary)
+
 (defcustom planner-timeclock-summary-summary-string 
-           "\n\nDay begined: %B, Day ended: %E\nTime elapsed: %S, \
+           "\n\nDay began: %B, Day ended: %E\nTime elapsed: %S, \
 Time clocked: %C\nTime clocked ratio: %R\n"
   "The string below the report table.
 
@@ -135,16 +149,16 @@
   (save-excursion
     (save-restriction
       (when (planner-narrow-to-section planner-timeclock-summary-section)
-       (if (string-match planner-date-regexp (planner-page-name))
-           (progn
              (delete-region (point-min) (point-max))
+                               (let ((thepage (planner-page-name)))
              (insert "* " planner-timeclock-summary-section "\n\n"
-                     (planner-timeclock-summary-make-text-table-day
-                      (replace-in-string (planner-page-name) "\\." "/" t))
-                     " \n")
-             nil)
-         (message "Timeclock summary in plan pages are not supported yet. I
-welcome your patches!"))))))
+                                        (if (string-match planner-date-regexp 
thepage)
+                                                        
(planner-timeclock-summary-make-text-table-day
+                                                               
(replace-in-string thepage "\\." "/" t))
+                                                
(planner-timeclock-summary-make-text-table-day
+                                                       nil nil (concat "^" 
thepage 
+                                                                               
                                        (unless 
planner-timeclock-summary-include-sub-plan-pages ":")) t))
+                     " \n"))))))
 
 ;;;###autoload
 (defun planner-timeclock-summary-show (&optional date)
@@ -153,8 +167,26 @@
   (interactive (list (planner-read-date)))
   (planner-timeclock-summary-show-range date date))
 
-(defun planner-timeclock-summary-show-range (start-date end-date)
+;;;###autoload
+(defun planner-timeclock-summary-show-filter (filter-regexp date)
+       (interactive 
+        (list 
+               (read-string "Filter (regexp): " nil 'regexp-history) 
+               (planner-read-date)))
+       (planner-timeclock-summary-show-range date date filter-regexp))
+
+;;;###autoload
+(defun planner-timeclock-summary-show-range-filter (filter-regexp start-date 
end-date)
+       (interactive 
+        (list 
+               (read-string "Filter (regexp): " nil 'regexp-history) 
+               (planner-read-date "Start")
+               (planner-read-date "End")))
+       (planner-timeclock-summary-show-range start-date end-date 
filter-regexp))
+
+(defun planner-timeclock-summary-show-range (start-date end-date &optional 
filter-regexp)
   "Display a buffer with the timeclock summary for the DATE range START-DATE 
to END-DATE.
+Takes an optional parameter which runs each entry through a regexp to ensure 
it matches before using the data
 Dates are strings in the form YYYY.MM.DD."
   (interactive (list (planner-read-date "Start") (planner-read-date "End")))
   (switch-to-buffer (get-buffer-create planner-timeclock-summary-buffer))
@@ -167,7 +199,8 @@
             "\n\n"
            (planner-timeclock-summary-make-text-table-day
             (replace-in-string start-date "\\." "/" t)
-             (replace-in-string end-date "\\." "/" t)))
+                        (replace-in-string end-date "\\." "/" t)
+                        filter-regexp))
     (planner-mode))
   (goto-char (point-min)))
 
@@ -241,12 +274,12 @@
                                                    entry-task-name)) t)))))
     target-data))
 
-(defun planner-timeclock-summary-calculate-ratio-day (start-date &optional 
end-date)
-  "Calculate time ratio for DATE."
+(defun planner-timeclock-summary-calculate-ratio-day (start-date &optional 
end-date filter-regexp)
+  "Calculate time ratio for START-DATE."
   (when (not end-date)
     (setq end-date start-date))
   (setq target-data (planner-timeclock-summary-extract-data 
-                     (cdr (planner-timeclock-day-range-entry start-date 
end-date))))
+                     (cdr (planner-timeclock-day-range-entry start-date 
end-date filter-regexp))))
   (let ((total (car target-data))
        (projects (cdr target-data)))
     (while projects
@@ -260,11 +293,17 @@
        (setq projects (cdr projects)))))
   target-data)
 
-(defun planner-timeclock-summary-make-text-table-day (start-date &optional 
end-date)
-  "Make the summary table for DATE using plain text."
+(defun planner-timeclock-summary-make-text-table-day (start-date &optional 
end-date filter-regexp hide-summary)
+  "Make the summary table for START-DATE using plain text. Takes an optional 
END-DATE 
+(which if provided makes a table for a range of dates from START-DATE to 
END-DATE) and FILTER-REGEXP 
+(which if provided includes a timeclock entry only if the plan-page matches 
the regexp)
+
+If START-DATE is nil, then it will ignore the date information and return data 
for everything 
+(optionally filtered by filter-regexp)"
+
   (unless end-date (setq end-date start-date))
   (setq source-list (planner-timeclock-summary-calculate-ratio-day
-                    start-date end-date))
+                    start-date end-date filter-regexp))
   (let ((projects (cdr source-list))
        (total (car source-list)))
     (if total
@@ -313,19 +352,20 @@
                            (length planner-timeclock-summary-empty-cell-string)
                            (aref " " 0))))
          (goto-char (point-max))
-         (insert (planner-timeclock-summary-make-summary-string-range 
start-date end-date total))
+         (unless hide-summary 
+        (insert (planner-timeclock-summary-make-summary-string-range 
start-date end-date total filter-regexp)))
          (buffer-string))
       "")))
 
 (defun planner-timeclock-summary-make-summary-string (date total)
        (planner-timeclock-summary-make-summary-string-range date date total))
 
-(defun planner-timeclock-summary-make-summary-string-range (start-date 
end-date total)
+(defun planner-timeclock-summary-make-summary-string-range (start-date 
end-date total &optional filter-regexp)
   "Use `planner-timeclock-summary-summary-string' to make the summary for DATE.
 Date is in format YYYY/MM/DD. TOTAL is the total time clocked
 today, in seconds."
   (let ((target-string planner-timeclock-summary-summary-string)
-       (data (planner-timeclock-day-range-entry start-date end-date))
+       (data (planner-timeclock-day-range-entry start-date end-date 
filter-regexp))
        begin end last span2 span)
     (setq begin (timeclock-day-begin data))
     (setq last (timeclock-day-end data))
@@ -386,19 +426,23 @@
        (setq task-name task-fullname)))
     (list project-name task-name task-length)))
 
-(defun planner-timeclock-day-range-entry (start-date end-date)
+(defun planner-timeclock-day-range-entry (start-date end-date &optional 
filter-regexp)
   "Return the data between START-DATE and END-DATE (inclusive)
 START-DATE and END-DATE should be strings of the form YYYY/MM/DD.
 Use the format specified in timeclock.el."
   (let ((day-list (timeclock-day-alist))
-       entry-list)
+                               entry-list)
     (while day-list
       (let ((theday (pop day-list)))
-                               (when (planner-timeclock-within-date-range 
start-date end-date (car theday))
+                               (when (or (not start-date)
+                                                                       
(planner-timeclock-within-date-range start-date end-date (car theday)))
                                        (setq entry-list (append (cddr theday) 
entry-list)))))
-    (if (string= start-date end-date)
-                               (cons start-date entry-list)
-                       (cons (concat start-date " - " end-date) entry-list))))
+               (when (and filter-regexp (not (string= filter-regexp "")))
+                       (setq entry-list (delete-if-not (lambda(x) 
(string-match filter-regexp (nth 2 x)))
+                                                                               
 entry-list)))
+               (push (cond ((not start-date) filter-regexp)
+                                                                               
                                                 ((string= start-date end-date) 
start-date)
+                                                                               
                                                 (t (concat start-date " - " 
end-date))) entry-list)))
 
 (defun planner-timeclock-within-date-range (start-date end-date test-date)
        "Return non-nil if DATE-TEST is within the date range START-DATE to 
END-DATE."

Diff finished at Thu Dec 16 22:09:06
-- 
Chris Parsons
address@hidden





reply via email to

[Prev in Thread] Current Thread [Next in Thread]