{"id":15389019,"url":"https://github.com/olange/hamster-to-harvest","last_synced_at":"2025-03-27T23:17:58.563Z","repository":{"id":36076589,"uuid":"40376404","full_name":"olange/hamster-to-harvest","owner":"olange","description":"A utility script written in Clojure to migrate Hamster time tracking entries, in XML format, to the Harvest time tracking web service, in CSV format","archived":false,"fork":false,"pushed_at":"2015-08-22T17:18:21.000Z","size":468,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-02T01:24:36.972Z","etag":null,"topics":["clojure","csv-format","csv-importer","export-xml","hamster","harvest","xml-format"],"latest_commit_sha":null,"homepage":"","language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/olange.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-08-07T19:03:12.000Z","updated_at":"2018-03-12T12:40:14.000Z","dependencies_parsed_at":"2022-09-03T11:01:56.124Z","dependency_job_id":null,"html_url":"https://github.com/olange/hamster-to-harvest","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/olange%2Fhamster-to-harvest","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/olange%2Fhamster-to-harvest/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/olange%2Fhamster-to-harvest/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/olange%2Fhamster-to-harvest/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/olange","download_url":"https://codeload.github.com/olange/hamster-to-harvest/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245938228,"owners_count":20697008,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clojure","csv-format","csv-importer","export-xml","hamster","harvest","xml-format"],"created_at":"2024-10-01T14:58:53.970Z","updated_at":"2025-03-27T23:17:58.542Z","avatar_url":"https://github.com/olange.png","language":"Clojure","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Hamster to Harvest\n\nA utility script written in [Clojure](http://clojure.org) to migrate\n[Hamster](http://projecthamster.wordpress.com/about/) time tracking entries\nto the [Harvest](https://www.getharvest.com) time tracking web service,\nfrom an XML export to a CSV file -- which you can then import online.\n\n## Status\n\nWorking executable 0.3.1 released. I used it to migrate a dozen of Hamster projects\nto Harvest. Defining the mapping requires hacking the sources (see below).\n\nLook at the [develop](https://github.com/olange/hamster-to-harvest/tree/develop)\nbranch for the latest state of the sources.\n\n## Usage\n\n```bash\n$ ./hamster-to-harvest hamster.xml --output harvest.csv\n                       [--append] [--filter:name PROJNAME]\n                       [--config hamster-to-harvest.conf]\n```\n\n## Examples\n\nAll activities at once:\n\n```bash\n$ ./hamster-to-harvest hamster.xml --output harvest-bsa.csv\n```\n\nIncrementally, project by project:\n\n```bash\n$ ./hamster-to-harvest hamster.xml --filter:name PROJNAME1 --output harvest.csv\n$ ./hamster-to-harvest hamster.xml --filter:name PROJNAME2 --output harvest.csv --append\n```\n\n## Migration process\n\n1. Export the activites from Hamster in XML format.\n\n\u003cimg src=\"doc/images/hamster-export-xml.png\" height=\"175\"\n     title=\"Hamster Save As... (XML) dialog\" /\u003e\n\n2. Adjust the configuration to your needs:\n\n    ```bash\n    $ vi hamster-to-harvest.conf\n    ```\n\n3. Convert them to Harvest time tracking entries in CSV format (see usage below for more options):\n\n    ```bash\n    $ ./hamster-to-harvest hamster.xml --output harvest.csv\n                                      [--append] [--filter:name PROJNAME]\n    ```\n\n4. Upload the resulting CSV file to your Harvest account; from the web interface:\n\n   * _Company Settings_ › _Import Data into Harvest_ › _Import Timesheets From CSV_\n   * select your `harvest.csv` file, and click _Upload and Import_\n\n5. You'll shortly receive an e-mail from Harvest, with a link to the results of the import:\n\n\u003cimg src=\"doc/images/harvest-import-confirm.png\" height=\"175\"\n     title=\"Successful CSV import e-mail notification\" /\u003e\n\n## Caveat\n\nThe _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.\n\nWrite 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.\n\n## Mapping\n\nThe mapping happens currently in the source code. Everything is handled within\nthe [mapping.clj](src/hamster_to_harvest/mapping.clj) script.\n\nI believe you should be able to adjust the mapping to your requirements, even\nif you do not know the [Clojure](http://clojure.org) language, but have experience\nwith another scripting language.\n\nHopefully you'll find sample idiomatic code within the script, which you can augment\nand tweek. See the [Clojure Docs](https://clojuredocs.org) for a description of\nClojure built-in functions.\n\n### Source XML format\n\nActivities in Hamster are exported in the following XML structure:\n\n```xml\n\u003c?xml version=\"1.0\" ?\u003e\n\u003cactivities\u003e\n  \u003cactivity name=\"ZENwebdev\"\n            category=\"offert\"\n            tags=\"Publication\"\n            description=\"Actualisé page d'accueil selon demandes AM des 09.12 et 21.12.2010\"\n            duration_minutes=\"20\"\n            start_time=\"2011-01-03 00:45:00\"\n            end_time=\"2011-01-03 01:05:00\" /\u003e\n\n  \u003cactivity name=\"RZOhomepage\"\n            category=\"work\"\n            tags=\"Design graphique, facturé\"\n            description=\"Etude nouvelle mise en forme homepage\"\n            duration_minutes=\"120\"\n            start_time=\"2011-01-07 09:00:00\"\n            end_time=\"2011-01-07 11:00:00\" /\u003e\n\u003c/activities\u003e\n```\n\n### Target CSV format\n\nThe Harvest CSV importer requires time entries in the following CSV format and\nstructure; the mapping should yield values for each of the following fields:\n\n```csv\n\"Date\",\"Client\",\"Project\",\"Task\",\"Notes\",\"Hours\",\"First name\",\"Last name\"\n2011-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\"\n2011-01-07,\"Client RZO\",\"Refonte homepage\",\"Conception graphique\",\"Etude nouvelle mise en forme homepage [transcrit de Hamster]\",2,\"Olivier\",\"Lange\"\n…\n```\n\n## Compiling and assembling\n\nIf you're new to Clojure, here's how to get started hacking this project.\nThese instruction should be everything you need to adjust the mapping in\nthe sources.\n\nPrerequisites:\n\n* you'll need [Git](https://git-scm.com/downloads)\n* a [Java SDK](http://www.oracle.com/technetwork/java/javase/downloads/index.html) (1.6+)\n* and [Leiningen](http://leiningen.org/#install) installed on your computer.\n\n### All at once\n\nCheckout the sources:\n\n```bash\n$ git clone git@github.com:olange/hamster-to-harvest.git\n```\n\nand create a console executable, that will be placed in the root folder\nof the sources (working on Mac OS X, Linux and Windows):\n\n```bash\n$ lein bin\nCompiling hamster-to-harvest.core\nCompiling hamster-to-harvest.hamster\nCompiling hamster-to-harvest.harvest\nCompiling hamster-to-harvest.mapping\nCreated …/hamster-to-harvest-csv/target/uberjar+uberjar/hamster-to-harvest-0.3.1.jar\nCreated …/hamster-to-harvest-csv/target/uberjar/hamster-to-harvest-0.3.1-standalone.jar\nCreating standalone executable: …/hamster-to-harvest-csv/target/base+system+user+dev/hamster-to-harvest\nCopying binary to ./\n```\n\nThis single command will:\n\n1. download required dependencies;\n2. compile the sources and package them in an executable [JAR](https://en.wikipedia.org/wiki/JAR_(file_format));\n3. bundle this JAR and its dependencies in a self-contained executable UberJAR;\n4. and wrap this executable UberJAR in a standalone console executable.\n\n### In separate steps\n\nTo download all required dependencies (needed once only) and compile the sources:\n\n```bash\n$ lein deps\n$ lein compile\n```\n\nTo run the application from the command-line (which would also download the\ndependencies and compile the sources, if this had not be done before):\n\n```bash\n$ lein run -- --help\n$ lein run -- hamster.xml -o harvest.csv\n```\n\nTo package the application as a self-contained JAR file (in the `target/` sub-folder):\n\n```bash\n$ lein uberjar\n```\n\nTo hack from the REPL:\n\n```clojure\n$ lein repl\nhamster-to-harvest.core=\u003e (require '[hamster-to-harvest.core] :reload-all)\nhamster-to-harvest.core=\u003e (-main \"hamster.xml\" \"-o\" \"harvest.csv\")\n```\n\nRunning the tests:\n\n```clojure\n$ lein test\n\nlein test hamster-to-harvest.core-test\nConverting Hamster activities from 'resources/hamster-sample.xml'\nto Harvest time tracking entries into 'resources/harvest-sample.test.csv'\n\nlein test hamster-to-harvest.mapping-test\n\nRan 6 tests containing 8 assertions.\n0 failures, 0 errors.\n```\n\n## License\n\n\u003ca rel=\"license\" href=\"http://creativecommons.org/licenses/by-sa/4.0/\"\u003e\u003cimg alt=\"Creative Commons License\" style=\"border-width:0\" src=\"https://i.creativecommons.org/l/by-sa/4.0/88x31.png\" /\u003e\u003c/a\u003e\n\u003cbr /\u003e\u003cspan xmlns:dct=\"http://purl.org/dc/terms/\" property=\"dct:title\"\u003eHamster to Harvest (CSV)\u003c/span\u003e by \u003ca xmlns:cc=\"http://creativecommons.org/ns#\" href=\"http://github.com/olange\" property=\"cc:attributionName\" rel=\"cc:attributionURL\"\u003eOlivier Lange\u003c/a\u003e is licensed under a \u003ca rel=\"license\" href=\"http://creativecommons.org/licenses/by-sa/4.0/\"\u003eCreative Commons Attribution-ShareAlike 4.0 International License\u003c/a\u003e.\nPermissions beyond the scope of this license may be available at \u003ca xmlns:cc=\"http://creativecommons.org/ns#\" href=\"https://github.com/olange/hamster-to-harvest-csv/issues/new\" rel=\"cc:morePermissions\"\u003egithub.com/hamster-to-harvest-csv/issues\u003c/a\u003e.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Folange%2Fhamster-to-harvest","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Folange%2Fhamster-to-harvest","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Folange%2Fhamster-to-harvest/lists"}