Coder Social home page Coder Social logo

org-clock-export's Introduction

org-clock-export.el

Fully customizable export of org-clock data into a CSV file.

Usage

Install dependencies:

org-ql
https://github.com/alphapapa/org-ql

Installation

Clone this repository into your load path.

git clone https://github.com/legalnonsense/org-clock-export.git

Then:

(use-package org-clock-export)
;; or
(require 'org-clock-export)

Or, use this use-package declaration with all custom variables set to the default values:

(use-package org-clock-export
  :config
  (setq org-clock-export-org-ql-query nil
        org-clock-export-files nil
        org-clock-export-export-file-name (concat user-emacs-directory "clock-export.csv")
        org-clock-export-buffer "*ORG-CLOCK-EXPORT CSV*"
        org-clock-export-delimiter ","
        org-clock-export-data-format '("date" (concat start-month "/" start-day "/" start-year)
                                       "hours" total-hours
                                       "minutes" total-minutes
                                       "description" (org-entry-get (point) "ITEM")
                                       "hourly rate" (or (org-entry-get (point) "HOURLY-RATE") "325"))))

Usage

org-clock-export-data does the heavy lifting. You must set this variable yourself. The default value, shown here, is an example.

It is in the style of a plist:

(setq org-clock-export-data '( "date" (concat start-month "/" start-day "/" start-year)
                               "hours" total-hours
                               "minutes" total-minutes
                               "description" (org-entry-get (point) "ITEM")
                               "hourly rate" (or (org-entry-get (point) "HOURLY-RATE") "325")))

The rules are:

  1. The first element is a string to describe the category of data
  2. The following sexp is evaluated at each org heading containing a clock line
  3. Each sexp can use the following variables, which are bound to values based on each clock-line. The following should be self-explanatory:
    • start-year
    • start-month
    • start-day
    • start-dow [day of week]
    • start-hour
    • start-minute
    • end-year
    • end-month
    • end-day
    • end-dow
    • end-hour
    • end-minute
    • total-hours
    • total-minutes
  4. The sexp be any code that will be run at each heading containing a clock line. For example, you can use org-entry-get (or any other function) to grab data from the heading and put it into the CSV.
  5. The sexp can be a string if you want one field to be constant and not depend on the heading or the clock data.
  6. The only rules for these sexps are that they must return a string, and that they must not move the point (i.e., you should save any excursion).
  7. The order of the data in org-clock-export-data reflects the order it will appear in the CSV

If you call org-clock-export with a prefix (i.e., press C-u before calling the command), the csv file will be saved to the location specified by org-clock-export-export-file-name.

If you call it with two prefixes, you will be prompted to select the export file.

Example

Consider the following file org file:

* Checking if co-coworker did any work :Gus:
:PROPERTIES:
:HOURLY-RATE: 250
:END:
:LOGBOOK:
CLOCK: [2021-03-01 Mon 16:40]--[2021-03-01 Mon 16:50] =>  0:10
CLOCK: [2021-03-01 Mon 15:45]--[2021-03-01 Mon 15:50] =>  0:05
:END:
* Sending an email to a non-responsive co-worker :email:Gus:
:PROPERTIES:
:HOURLY-RATE: 125
:END:
:LOGBOOK:
CLOCK: [2021-03-01 Mon 16:05]--[2021-03-01 Mon 16:17] =>  0:12
:END:
* Doing the co-coworker’s work for them :Gus:
:LOGBOOK:
CLOCK: [2021-03-01 Mon 16:17]--[2021-03-01 Mon 16:30] =>  0:13
:END:
* Talking about mindless drivel with customer :Abby:
:LOGBOOK:
CLOCK: [2021-02-28 Sun 16:19]--[2021-02-28 Sun 17:19] =>  1:00
:END:

org-clock-export will produce the following:

date,hours,minutes,description,hourly rate
03/01/2021,0,10,Checking if co-coworker did any work,250
03/01/2021,0,05,Checking if co-coworker did any work,250
03/01/2021,0,12,Sending an email to a non-responsive co-worker,125
03/01/2021,0,13,Doing the co-coworker’s work for them,325
02/28/2021,1,00,Talking about mindless drivel with customer,325

A few notes:

  1. Note that for the hourly rate line, we ensure a string (and not nil) is returned. If a heading does not have an HOURLY-RATE property, org-entry-get will return nil. Hence the need to set a default of 325.
  2. If a heading has more than one clock line (here, Checking if co-coworker did any work), then the CSV file will contain an entry for each clock line.

Restricting exported data

What if you only want to export clock data for certain headings, or for a certain time? Then you use the variable org-clock-export-org-ql-query. This will require you to understand how to use org-ql. The variable must be a query acceptable to org-ql-select. For example, suppose you only wanted to export time entries from headings tagged with :Abby:. Then:

(setq org-clock-export-org-ql-query '(tags "Abby"))

And now the output is:

date,hours,minutes,description,hourly rate
02/28/2021,1,00,Talking about mindless drivel with customer,325

You can use org-clock-export-org-ql-query to restrict to certain tags, dates, times, and otherwise harness the full power of org-ql. For example, if you only want to export entries for a given date with the tag “Gus”, use:

(setq org-clock-export-org-ql-query '(and (clocked :on today) (tags "Gus")))

And you’ll get:

date,hours,minutes,description,hourly rate
03/01/2021,0,10,Checking if co-coworker did any work,250
03/01/2021,0,05,Checking if co-coworker did any work,250
03/01/2021,0,12,Sending an email to a non-responsive co-worker,125
03/01/2021,0,13,Doing the co-coworker’s work for them,325

Final example

This should all be pretty easy to follow. If not, here’s a final arbitrary example:

  (setq org-clock-export-org-ql-query nil)
  (setq org-clock-export-data '( "name" "Jack Jackson"
                                 "date" (concat start-month "/" start-day "/" start-year)
                                 "start time" (concat start-hour ":" start-minute)
                                 "end time" (concat end-hour ":" end-minute)
                                 "total time" (concat total-hours ":" total-minutes)
                                 ;; The headline enclosed in quotes (in case there are commas)
                                 "description" (concat "\"" (org-entry-get (point) "ITEM") "\"")
                                 "file name" (buffer-file-name)
                                 "hourly rate" (or (org-entry-get (point) "HOURLY-RATE") "325")))
(org-clock-export)

Results:

name,date,start time,end time,total time,description,file name,hourly rate
Jack Jackson,03/01/2021,16:40,16:50,0:10,"Checking if co-coworker did any work",/home/jeff/.emacs.d/lisp/org-clock-export/test.org,250
Jack Jackson,03/01/2021,15:45,15:50,0:05,"Checking if co-coworker did any work",/home/jeff/.emacs.d/lisp/org-clock-export/test.org,250
Jack Jackson,03/01/2021,16:05,16:17,0:12,"Sending an email to a non-responsive co-worker",/home/jeff/.emacs.d/lisp/org-clock-export/test.org,125
Jack Jackson,03/01/2021,16:17,16:30,0:13,"Doing the co-coworker’s work for them",/home/jeff/.emacs.d/lisp/org-clock-export/test.org,325
Jack Jackson,02/28/2021,16:19,17:19,1:00,"Talking about mindless drivel with customer",/home/jeff/.emacs.d/lisp/org-clock-export/test.org,325

Other custom variables

NameDescriptionDefault value
org-clock-export-bufferBuffer used to export CSV data*ORG-CLOCK-EXPORT CSV*
org-clock-export-export-file-nameFile to export data to(concat user-emacs-directory "clock-export.csv")
org-clock-export-delimiterDelimiter (a string) used in the CSV output,
org-clock-export-org-ql-querySee abovenil
org-clock-export-filesIf nil, use `org-agenda-files’. Otherwise, specify a file or list of filesnil
org-clock-export-dataSee above

Overriding default values

You can override any of the default values by using keywords in the call to org-clock-export. The keywords are:

org-files
org-ql-query
csv-data-format
output-file
delimiter
output-buffer

If you omit any of the keywords, the default value is used. If you set any of the keywords to nil, then nil is used instead of the default value. Example:

(org-clock-export

 ;; Only export anything with a category of "Jones"
 :org-ql-query nil
 :csv-data-format '("matter" (org-entry-get (point) "SOME-PROPERTY" t)
                    "date" (concat start-month "/" start-day "/" start-year)
                    "activity_description" (concat "\"" (s-trim (replace-regexp-in-string "\\[.+\\]" "" (org-entry-get (point) "ITEM"))) "\"")
                    "note" (concat "\"" (s-trim (replace-regexp-in-string "\\[.+\\]" "" (org-entry-get (point) "ITEM"))) "\"")
                    "price" "425"
                    "quantity" (concat total-hours "." (substring (cadr (split-string (format "%f" (/ (string-to-number total-minutes) 60.0)) "\\.")) 0 2))
                    "type" "TimeEntry")
 :output-file "~/path/to/file.csv"
 :delimiter ",")

A note about escaping characters

Since there is no standard for CSV files, you will need to ensure the strings returned by org-clock-export-data are appropriately escaped.

Other efforts

org-clock-csv
https://github.com/atheriel/org-clock-csv. This did not allow me to export my time data in the way I needed and so I wrote this.

org-clock-export's People

Contributors

legalnonsense avatar tubo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.