Add 'timesheet' command

This commit is contained in:
Nikolay Puzanov 2014-11-15 17:46:54 +03:00
parent c91cf1d41a
commit cd8f142f46
5 changed files with 134 additions and 68 deletions

View File

@ -1,5 +1,6 @@
Программа написана на [Scheme](http://www.schemers.org/) (реализация - [GNU Guile](http://www.gnu.org/software/guile/)) и предназначена для учета Программа написана на [Scheme](http://www.schemers.org/) (реализация -
рабочего времени. Применяется следующим образом: [GNU Guile](http://www.gnu.org/software/guile/)) и предназначена для
учета рабочего времени. Применяется следующим образом:
Usage: timer [command] Usage: timer [command]
Commands: Commands:
@ -14,6 +15,11 @@
deadline clear [TASK] Remove deadline for project (or for last task) deadline clear [TASK] Remove deadline for project (or for last task)
deadline [TASK] Show deadline for project deadline [TASK] Show deadline for project
deadline all Show all deadlines deadline all Show all deadlines
timesheet Show all raw events
timesheet day [DATE] Show raw events for today or DATE
timesheet week [DATE] Show raw events for current week or week of DATE
timesheet month [DATE] Show raw events for current month or month of DATE
timesheet TASK Show raw events
refresh Refresh worksheet file after manual edit refresh Refresh worksheet file after manual edit
(no command) Show running task and timer (no command) Show running task and timer
@ -63,10 +69,8 @@
Команда `report` может иметь параметры: Команда `report` может иметь параметры:
- `day [DATE]` - отчет по текущему дню или по дате DATE; - `day [DATE]` - отчет по текущему дню или по дате DATE;
- `week [DATE]` - отчет по текущей неделе или по неделе, в которую входит день - `week [DATE]` - отчет по текущей неделе или по неделе, в которую входит день
DATE; DATE;
- `month [DATE]` - отчет по текущему месяцу или по месяцу, в который входит день - `month [DATE]` - отчет по текущему месяцу или по месяцу, в который входит день
DATE; DATE;
@ -109,6 +113,10 @@
останется еще 40 минут. Это может быть удобно при планировании времени на останется еще 40 минут. Это может быть удобно при планировании времени на
день/неделю/месяц. день/неделю/месяц.
Для того, чтобы посмотреть историю работы, можно воспользоваться командой
`timesheet`. Эта команда показывает выполнявшиеся задачи в таком виде, в котором
они сохраняются на диск. Параметры команды такие-же, как у команды `report`.
# Автодополнение для zsh # Автодополнение для zsh
Для включения автодополнения в zsh скопируйте файл `zsh-completion/_timer` в Для включения автодополнения в zsh скопируйте файл `zsh-completion/_timer` в

View File

@ -9,8 +9,8 @@
рабочего времени. Применяется следующим образом: рабочего времени. Применяется следующим образом:
#+begin_src text #+begin_src text
Usage: timer [command] Usage: timer [command]
Commands: Commands:
start [TASK] Start new task. If no task, use last runned task start [TASK] Start new task. If no task, use last runned task
stop Stop task stop Stop task
report Show report report Show report
@ -22,6 +22,11 @@ Commands:
deadline clear [TASK] Remove deadline for project (or for last task) deadline clear [TASK] Remove deadline for project (or for last task)
deadline [TASK] Show deadline for project deadline [TASK] Show deadline for project
deadline all Show all deadlines deadline all Show all deadlines
timesheet Show all raw events
timesheet day [DATE] Show raw events for today or DATE
timesheet week [DATE] Show raw events for current week or week of DATE
timesheet month [DATE] Show raw events for current month or month of DATE
timesheet TASK Show raw events
refresh Refresh worksheet file after manual edit refresh Refresh worksheet file after manual edit
(no command) Show running task and timer (no command) Show running task and timer
#+end_src #+end_src
@ -130,6 +135,10 @@ Commands:
останется еще 40 минут. Это может быть удобно при планировании времени на останется еще 40 минут. Это может быть удобно при планировании времени на
день/неделю/месяц. день/неделю/месяц.
Для того, чтобы посмотреть историю работы, можно воспользоваться командой
=timesheet=. Эта команда показывает выполнявшиеся задачи в таком виде, в котором
они сохраняются на диск. Параметры команды такие-же, как у команды =report=.
** Автодополнение для zsh ** Автодополнение для zsh
Для включения автодополнения в zsh скопируйте файл =zsh-completion/_timer= в Для включения автодополнения в zsh скопируйте файл =zsh-completion/_timer= в
=~/.zsh-completion/=, и добавте в файл =~/.zshrc= строки =~/.zsh-completion/=, и добавте в файл =~/.zshrc= строки

View File

@ -5,7 +5,7 @@ _timer()
case "$COMP_CWORD" in case "$COMP_CWORD" in
1) 1)
# Commands # Commands
COMPREPLY=( $(compgen -W "start stop report deadline refresh help" -- $uncomplete) ) COMPREPLY=( $(compgen -W "start stop report deadline refresh timesheet help" -- $uncomplete) )
;; ;;
2) 2)
# Command argument 1 # Command argument 1
@ -14,7 +14,7 @@ _timer()
local tasklist=$(timer tasklist) local tasklist=$(timer tasklist)
COMPREPLY=( $(compgen -W "$tasklist" -- $uncomplete)) COMPREPLY=( $(compgen -W "$tasklist" -- $uncomplete))
;; ;;
report) report|timesheet)
local tasklist=$(timer tasklist) local tasklist=$(timer tasklist)
COMPREPLY=( $(compgen -W "day week month $tasklist" -- $uncomplete)) COMPREPLY=( $(compgen -W "day week month $tasklist" -- $uncomplete))
;; ;;
@ -27,7 +27,7 @@ _timer()
3) 3)
# Command argument 2 # Command argument 2
case "${COMP_WORDS[1]}" in case "${COMP_WORDS[1]}" in
report) report|timesheet)
case "${COMP_WORDS[2]}" in case "${COMP_WORDS[2]}" in
day) day)
local d=$(date +"%Y-%m-%d") local d=$(date +"%Y-%m-%d")

View File

@ -197,6 +197,12 @@
(let ((jd (date->julian-day date))) (let ((jd (date->julian-day date)))
(+ jd (- 7 (remainder-and-rest jd 7))))))) (+ jd (- 7 (remainder-and-rest jd 7)))))))
;;; Returns n-th element of list l, or NUL if list is shorter than n
(define (nth-maybe n l)
(if (null? l) '()
(if (zero? n) (car l)
(nth-maybe (- n 1) (cdr l)))))
;;; ========================= PROJECT SPECIFIC HELPERS ========================= ;;; ========================= PROJECT SPECIFIC HELPERS =========================
;;; Find task or deadline by path ;;; Find task or deadline by path
@ -509,6 +515,60 @@
(walk l (+ level 2))) (walk l (+ level 2)))
(cdddr tree))))) (cdddr tree)))))
;;; Filter sheet by qualis and range.
;;; Qualis is string "day", "week", "month" or task name.
;;; Range is the date string. Both qualis and range may be nil.
;;;
;;; Function returns values of filtered sheet and string
;;; with description of filtering range.
(define (filter-sheet sheet qualis range)
(if (null? qualis)
(values sheet '())
(let ((date (catch #t
(lambda () (string->date range date-format))
(lambda (key . args) (current-date)))))
(let-values (((description filter-lambda)
(cond
;; Filter records by day
((string-ci= qualis "day")
(values
(format #f "DAY ~a" (date->string date "~Y-~m-~d"))
(lambda (x) (same-day? date (cadr x)))))
;; Filter records by month
((string-ci= qualis "month")
(values
(format #f "MONTH ~a" (date->string date "~Y-~m"))
(lambda (x) (same-month? date (cadr x)))))
;; Filter records by week
((string-ci= qualis "week")
(let ((beg (monday-of-week date))
(end (monday-of-next-week date)))
(values
(format #f "WEEK [~a - ~a)"
(date->string beg date-format)
(date->string end date-format))
(lambda (x) (date-in-range? (cadr x) beg end)))))
;; Filter records by path
(else
(values
(format #f "PROJECT ~a" qualis)
(let ((rep-path (path-split qualis)))
(lambda (x)
(let loop ((path (car x))
(rep-path rep-path))
(if (or
(null? path)
(null? rep-path)) #t
(if (string-ci= (car path) (car rep-path))
(loop (cdr path) (cdr rep-path))
#f))))))))))
(values
(filter filter-lambda sheet)
description)))))
;;; ================================ COMMANDS ================================== ;;; ================================ COMMANDS ==================================
;;; Start new task. Returns new sheet with started task or #f if nothing started. ;;; Start new task. Returns new sheet with started task or #f if nothing started.
@ -545,50 +605,18 @@
;;; Print report ;;; Print report
(define (cmd-report sheet deadlines . params) (define (cmd-report sheet deadlines . params)
(format #t "--- REPORT") (format #t "--- REPORT")
(let ((sheet (let ((qualis (nth-maybe 0 params))
(if (null? params) sheet (range (nth-maybe 1 params)))
(let* ((interval (car params)) (let-values (((sheet description)
(report-date (catch #t (filter-sheet sheet qualis range)))
(lambda () (string->date (cadr params) date-format)) (when (not (null? description))
(lambda (key . args) (current-date))))) (display ". ")
(filter (cond (display description))
;; Filter records by day
((string-ci= interval "day")
(format #t ". DAY ~a" (date->string report-date "~Y-~m-~d"))
(lambda (x) (same-day? report-date (cadr x))))
;; Filter records by month
((string-ci= interval "month")
(format #t ". MONTH ~a" (date->string report-date "~Y-~m"))
(lambda (x) (same-month? report-date (cadr x))))
;; Filter records by week
((string-ci= interval "week")
(let ((beg (monday-of-week report-date))
(end (monday-of-next-week report-date)))
(format #t ". WEEK [~a - ~a)"
(date->string beg date-format)
(date->string end date-format))
(lambda (x) (date-in-range? (cadr x) beg end))))
;; Filter records by path
(else
(format #t ". PROJECT ~a" interval)
(let ((rep-path (path-split interval)))
(lambda (x)
(let loop ((path (car x))
(rep-path rep-path))
(if (or
(null? path)
(null? rep-path)) #t
(if (string-ci= (car path) (car rep-path))
(loop (cdr path) (cdr rep-path))
#f)))))))
sheet)))))
(newline) (newline)
(print-report (print-report
(add-deadlines-to-report! (add-deadlines-to-report!
(make-report sheet) deadlines))) (make-report sheet) deadlines))))
(let ((last (last-task sheet))) (let ((last (last-task sheet)))
(when last (when last
(format #t "\n--- ~a TASK\n" (format #t "\n--- ~a TASK\n"
@ -680,6 +708,20 @@
(values sheet deadlines) (values sheet deadlines)
(values #f #f)))) (values #f #f))))
;;; Events
(define (cmd-timesheet sheet deadlines . params)
(format #t "--- TIMESHEET")
(let ((qualis (nth-maybe 0 params))
(range (nth-maybe 1 params)))
(let-values (((sheet description)
(filter-sheet sheet qualis range)))
(when (not (null? description))
(display ". ")
(display description))
(newline)
(print-timerecords sheet)))
(values #f #f))
;;; ================================ MAIN FUNCTION ================================== ;;; ================================ MAIN FUNCTION ==================================
(define (main cmdl) (define (main cmdl)
@ -724,6 +766,8 @@
((string= command "report") cmd-report) ((string= command "report") cmd-report)
((string= command "refresh") (lambda (s d . p) (values s d))) ((string= command "refresh") (lambda (s d . p) (values s d)))
((string= command "deadline") cmd-deadline) ((string= command "deadline") cmd-deadline)
((string= command "timesheet") cmd-timesheet)
;; Service commands
((string= command "tasklist") cmd-tasklist) ((string= command "tasklist") cmd-tasklist)
((string= command "deadlist") cmd-deadlist) ((string= command "deadlist") cmd-deadlist)
@ -744,6 +788,11 @@
(format #t " deadline clear [TASK] Remove deadline for project (or for last task)\n") (format #t " deadline clear [TASK] Remove deadline for project (or for last task)\n")
(format #t " deadline [TASK] Show deadline for project\n") (format #t " deadline [TASK] Show deadline for project\n")
(format #t " deadline all Show all deadlines\n") (format #t " deadline all Show all deadlines\n")
(format #t " timesheet Show all raw events\n")
(format #t " timesheet day [DATE] Show raw events for today or DATE\n")
(format #t " timesheet week [DATE] Show raw events for current week or week of DATE\n")
(format #t " timesheet month [DATE] Show raw events for current month or month of DATE\n")
(format #t " timesheet TASK Show raw events\n")
(format #t " refresh Refresh worksheet file after manual edit\n") (format #t " refresh Refresh worksheet file after manual edit\n")
(format #t " (no command) Show running task and timer\n\n") (format #t " (no command) Show running task and timer\n\n")
(format #t "DATE format: YYYY-mm-dd\n") (format #t "DATE format: YYYY-mm-dd\n")

View File

@ -13,7 +13,7 @@ _timer() {
case "$state" in case "$state" in
(command) (command)
# Commands # Commands
_arguments '1:commands:(start stop report deadline refresh help)' _arguments '1:commands:(start stop report deadline refresh timesheet help)'
;; ;;
(arg1) (arg1)
@ -22,7 +22,7 @@ _timer() {
(start) (start)
compadd $(timer tasklist) compadd $(timer tasklist)
;; ;;
(report) (report|timesheet)
compadd day week month $(timer tasklist) compadd day week month $(timer tasklist)
;; ;;
(deadline) (deadline)
@ -34,7 +34,7 @@ _timer() {
(arg2) (arg2)
# Command argument 2 # Command argument 2
case $words[2] in case $words[2] in
(report) (report|timesheet)
case $words[3] in case $words[3] in
(day) (day)
compadd $(date +"%Y-%m-%d") compadd $(date +"%Y-%m-%d")