public
Description: Ruby wrapper around the Harvest API (http://www.getharvest.com/api)
Clone URL: git://github.com/bricooke/harvest-ruby.git
Search Repo:
initial checkin.
bricooke (author)
Mon Apr 14 12:33:04 -0700 2008
commit  5a5ef6d1f57704f4dec654dd2555c4e9ddf1cbd9
tree    54af3bb24a02b14d2a94e8d1b6f046534781a143
...
 
 
...
1
2
0
@@ -0,0 +1,2 @@
0
+pkg
0
+coverage
...
 
 
 
 
 
 
...
1
2
3
4
5
6
0
@@ -0,0 +1,6 @@
0
+=== 1.0.0 / 2008-04-14
0
+
0
+* 1 major enhancement
0
+
0
+ * Birthday!
0
+
...
 
 
 
 
 
 
 
...
1
2
3
4
5
6
7
0
@@ -0,0 +1,7 @@
0
+History.txt
0
+Manifest.txt
0
+README.txt
0
+Rakefile
0
+lib/harvest.rb
0
+lib/harvest_entry.rb
0
+spec/harvest_spec.rb
...
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
0
@@ -0,0 +1,75 @@
0
+= harvest-ruby
0
+
0
+http://github.com/bricooke/harvest-ruby
0
+
0
+== DESCRIPTION:
0
+
0
+Ruby wrapper around the Harvest API
0
+http://www.getharvest.com/api
0
+
0
+== SYNOPSIS:
0
+
0
+harvest = Harvest.new("company.harvestapp.com", "email@example.com", "password")
0
+
0
+harvest.users[0].last_name
0
+=> "email@example.com"
0
+
0
+harvest.users[0].created_at
0
+=> "Fri May 11 15:00:08 EDT 2007"
0
+
0
+harvest.projects[0].name
0
+=> "Best Project Ever"
0
+
0
+harvest.tasks[0].name
0
+=> "Project Management"
0
+
0
+harvest.tasks(59273).name
0
+=> "Project Management"
0
+
0
+Fetch all entries and expenses for a project:
0
+harvest.report(5.years.ago, Time.now, :project_id => 6)
0
+
0
+or to filter on person:
0
+harvest.report(5.years.ago, Time.now, :person_id => 555)
0
+
0
+or to filter on both:
0
+harvest.report(5.years.ago, Time.now, :person_id => 555, :project_id => 6)
0
+
0
+
0
+== REQUIREMENTS:
0
+
0
+activesupport xml-simple
0
+
0
+== INSTALL:
0
+
0
+sudo gem install harvest-ruby
0
+
0
+== TODO:
0
+
0
+* Specs
0
+* Document the public API for rdocs
0
+
0
+== LICENSE:
0
+
0
+(The MIT License)
0
+
0
+Copyright (c) 2008 Brian Cooke
0
+
0
+Permission is hereby granted, free of charge, to any person obtaining
0
+a copy of this software and associated documentation files (the
0
+'Software'), to deal in the Software without restriction, including
0
+without limitation the rights to use, copy, modify, merge, publish,
0
+distribute, sublicense, and/or sell copies of the Software, and to
0
+permit persons to whom the Software is furnished to do so, subject to
0
+the following conditions:
0
+
0
+The above copyright notice and this permission notice shall be
0
+included in all copies or substantial portions of the Software.
0
+
0
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
0
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
0
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
0
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
0
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
0
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
0
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
...
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
0
@@ -0,0 +1,22 @@
0
+# -*- ruby -*-
0
+
0
+require 'rubygems'
0
+require 'hoe'
0
+require './lib/harvest.rb'
0
+require 'spec/rake/spectask'
0
+
0
+
0
+Hoe.new('harvest-ruby', Harvest::VERSION) do |p|
0
+ p.rubyforge_name = 'harvest-ruby' # if different than lowercase project name
0
+ p.developer('Brian Cooke', 'bcooke@roobasoft.com')
0
+end
0
+
0
+
0
+desc "Run specifications"
0
+Spec::Rake::SpecTask.new('spec') do |t|
0
+ t.spec_opts = ["--format", "specdoc", "--colour"]
0
+ t.spec_files = './spec/**/*_spec.rb'
0
+end
0
+
0
+
0
+# vim: syntax=Ruby
...
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
0
@@ -0,0 +1,57 @@
0
+require 'rubygems'
0
+require 'net/http'
0
+require 'xmlsimple'
0
+require 'activesupport'
0
+require File.dirname(__FILE__) + '/harvest_entry'
0
+
0
+class Harvest
0
+ VERSION = '0.1.0'
0
+
0
+ def initialize(domain, email, password)
0
+ @domain = domain
0
+ @email = email
0
+ @password = password
0
+ end
0
+
0
+ def users(params={})
0
+ request("/people", params).users
0
+ end
0
+
0
+ def projects
0
+ request("/projects").projects
0
+ end
0
+
0
+ def report(from, to, project_and_or_person_id)
0
+ entries = []
0
+ if project_and_or_person_id.has_key?(:project_id)
0
+ entries += request("/projects/#{project_and_or_person_id[:project_id]}/entries?from=#{from.strftime("%Y%m%d")}&to=#{to.strftime("%Y%m%d")}").day_entries
0
+ end
0
+
0
+ if project_and_or_person_id.has_key?(:person_id)
0
+ entries += request("/people/#{project_and_or_person_id[:person_id]}/entries?from=#{from.strftime("%Y%m%d")}&to=#{to.strftime("%Y%m%d")}").day_entries
0
+ end
0
+
0
+ entries
0
+ end
0
+
0
+ def tasks(task_id=nil)
0
+ if task_id.nil?
0
+ request("/tasks").tasks
0
+ else
0
+ request("/tasks/#{task_id}")
0
+ end
0
+ end
0
+
0
+private
0
+ def request(path, params={})
0
+ request = Net::HTTP::Get.new(path, { "Accept" => "application/xml"})
0
+ request.basic_auth(@email, @password)
0
+ request.content_type = "application/xml"
0
+ ret = nil
0
+ Net::HTTP.new(@domain).start {|http|
0
+ response = http.request(request)
0
+ ret = HarvestEntry.new(XmlSimple.xml_in(response.body))
0
+ }
0
+ ret
0
+ end
0
+end
0
\ No newline at end of file
...
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
0
@@ -0,0 +1,37 @@
0
+class HarvestEntry
0
+ def initialize(parsed)
0
+ @hash = parsed
0
+ end
0
+
0
+ def id
0
+ self.method_missing(:id)
0
+ end
0
+
0
+ def empty?
0
+ if @hash["type"] == "array" && @hash["content"] == "\n"
0
+ true
0
+ else
0
+ false
0
+ end
0
+ end
0
+
0
+ def method_missing(method, *args)
0
+ method = method.to_s.gsub("_", "-").to_sym
0
+
0
+ if @hash.has_key?(method.to_s.singularize)
0
+ entry = @hash[method.to_s.singularize]
0
+ if method.to_s.pluralize == method.to_s && entry.class == Array
0
+ return entry.collect {|e| HarvestEntry.new(e)}
0
+ else
0
+ return entry[0] unless entry[0].class == Hash && entry[0].has_key?("content")
0
+ return entry[0]["content"]
0
+ end
0
+ elsif @hash.has_key?(method.to_s)
0
+ entry = @hash[method.to_s]
0
+ return entry[0] unless entry[0].class == Hash && entry[0].has_key?("content")
0
+ return entry[0]["content"]
0
+ else
0
+ super
0
+ end
0
+ end
0
+end
...
 
 
 
 
 
 
...
1
2
3
4
5
6
0
@@ -0,0 +1,6 @@
0
+require './lib/harvest'
0
+
0
+describe "Harvest" do
0
+ it "should do some things"
0
+end
0
+

Comments

    No one has commented yet.