[Top][All Lists]
[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
- [emacs-wiki-discuss] Patch to planner-timeclock-summary: added filtering and plan-page summaries,
Chris Parsons <=