A utility script written in Clojure to migrate Hamster time tracking entries to the Harvest time tracking web service, from an XML export to a CSV file -- which you can then import online.
Working executable 0.3.1 released. I used it to migrate a dozen of Hamster projects to Harvest. Defining the mapping requires hacking the sources (see below).
Look at the develop branch for the latest state of the sources.
## Usage
$ ./hamster-to-harvest hamster.xml --output harvest.csv
[--append] [--filter:name PROJNAME]
[--config hamster-to-harvest.conf]
All activities at once:
$ ./hamster-to-harvest hamster.xml --output harvest-bsa.csv
Incrementally, project by project:
$ ./hamster-to-harvest hamster.xml --filter:name PROJNAME1 --output harvest.csv
$ ./hamster-to-harvest hamster.xml --filter:name PROJNAME2 --output harvest.csv --append
- Export the activites from Hamster in XML format.
-
Adjust the configuration to your needs:
$ vi hamster-to-harvest.conf
-
Convert them to Harvest time tracking entries in CSV format (see usage below for more options):
$ ./hamster-to-harvest hamster.xml --output harvest.csv [--append] [--filter:name PROJNAME]
-
Upload the resulting CSV file to your Harvest account; from the web interface:
- Company Settings › Import Data into Harvest › Import Timesheets From CSV
- select your
harvest.csv
file, and click Upload and Import
-
You'll shortly receive an e-mail from Harvest, with a link to the results of the import:
The Started at, Ended at and Billed? fields of Harvest cannot be defined thru the CSV Import feature. So you'll loose the start_time
and end_time
fields of your Hamster activities.
Write to Harvest to ask them to include these valuable fields in the CSV importer; I did and they told they might consider adding them, if there was demand.
## Mapping
The mapping happens currently in the source code. Everything is handled within the mapping.clj script.
I believe you should be able to adjust the mapping to your requirements, even if you do not know the Clojure language, but have experience with another scripting language.
Hopefully you'll find sample idiomatic code within the script, which you can augment and tweek. See the Clojure Docs for a description of Clojure built-in functions.
### Source XML format
Activities in Hamster are exported in the following XML structure:
<?xml version="1.0" ?>
<activities>
<activity name="ZENwebdev"
category="offert"
tags="Publication"
description="Actualisé page d'accueil selon demandes AM des 09.12 et 21.12.2010"
duration_minutes="20"
start_time="2011-01-03 00:45:00"
end_time="2011-01-03 01:05:00" />
<activity name="RZOhomepage"
category="work"
tags="Design graphique, facturé"
description="Etude nouvelle mise en forme homepage"
duration_minutes="120"
start_time="2011-01-07 09:00:00"
end_time="2011-01-07 11:00:00" />
</activities>
The Harvest CSV importer requires time entries in the following CSV format and structure; the mapping should yield values for each of the following fields:
"Date","Client","Project","Task","Notes","Hours","First name","Last name"
2011-01-03,"Client ZEN","Site web","Actualisation du site","Actualisé page d'accueil selon demandes AM des 09.12 et 21.12.2010 [transcrit de Hamster]",0.3333333333333333,"Olivier","Lange"
2011-01-07,"Client RZO","Refonte homepage","Conception graphique","Etude nouvelle mise en forme homepage [transcrit de Hamster]",2,"Olivier","Lange"
…
If you're new to Clojure, here's how to get started hacking this project. These instruction should be everything you need to adjust the mapping in the sources.
Prerequisites:
Checkout the sources:
$ git clone git@github.com:olange/hamster-to-harvest.git
and create a console executable, that will be placed in the root folder of the sources (working on Mac OS X, Linux and Windows):
$ lein bin
Compiling hamster-to-harvest.core
Compiling hamster-to-harvest.hamster
Compiling hamster-to-harvest.harvest
Compiling hamster-to-harvest.mapping
Created …/hamster-to-harvest-csv/target/uberjar+uberjar/hamster-to-harvest-0.3.1.jar
Created …/hamster-to-harvest-csv/target/uberjar/hamster-to-harvest-0.3.1-standalone.jar
Creating standalone executable: …/hamster-to-harvest-csv/target/base+system+user+dev/hamster-to-harvest
Copying binary to ./
This single command will:
- download required dependencies;
- compile the sources and package them in an executable JAR;
- bundle this JAR and its dependencies in a self-contained executable UberJAR;
- and wrap this executable UberJAR in a standalone console executable.
To download all required dependencies (needed once only) and compile the sources:
$ lein deps
$ lein compile
To run the application from the command-line (which would also download the dependencies and compile the sources, if this had not be done before):
$ lein run -- --help
$ lein run -- hamster.xml -o harvest.csv
To package the application as a self-contained JAR file (in the target/
sub-folder):
$ lein uberjar
To hack from the REPL:
$ lein repl
hamster-to-harvest.core=> (require '[hamster-to-harvest.core] :reload-all)
hamster-to-harvest.core=> (-main "hamster.xml" "-o" "harvest.csv")
Running the tests:
$ lein test
lein test hamster-to-harvest.core-test
Converting Hamster activities from 'resources/hamster-sample.xml'
to Harvest time tracking entries into 'resources/harvest-sample.test.csv'
lein test hamster-to-harvest.mapping-test
Ran 6 tests containing 8 assertions.
0 failures, 0 errors.
## License
Hamster to Harvest (CSV) by Olivier Lange is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.
Permissions beyond the scope of this license may be available at github.com/hamster-to-harvest-csv/issues.