harvested 0.5.3 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +2 -3
- data/HISTORY +2 -0
- data/Rakefile +1 -4
- data/VERSION +1 -1
- data/harvested.gemspec +5 -8
- data/lib/harvest/client.rb +6 -19
- data/lib/harvest/contact.rb +3 -15
- data/lib/harvest/expense.rb +3 -21
- data/lib/harvest/expense_category.rb +3 -12
- data/lib/harvest/invoice.rb +13 -45
- data/lib/harvest/invoice_category.rb +4 -13
- data/lib/harvest/line_item.rb +2 -10
- data/lib/harvest/model.rb +29 -18
- data/lib/harvest/project.rb +4 -41
- data/lib/harvest/rate_limit_status.rb +5 -11
- data/lib/harvest/task.rb +3 -14
- data/lib/harvest/task_assignment.rb +3 -16
- data/lib/harvest/time_entry.rb +8 -29
- data/lib/harvest/user.rb +4 -41
- data/lib/harvest/user_assignment.rb +9 -20
- data/spec/functional/reporting_spec.rb +6 -6
- data/spec/functional/time_tracking_spec.rb +13 -13
- data/spec/functional/users_spec.rb +16 -15
- data/spec/spec_helper.rb +7 -15
- data/spec/support/harvested_helpers.rb +10 -10
- metadata +8 -24
data/Gemfile
CHANGED
@@ -6,10 +6,9 @@ gem 'json'
|
|
6
6
|
|
7
7
|
group :development, :test do
|
8
8
|
gem "rspec", "~> 2"
|
9
|
-
gem 'ruby-debug', :platform => [:mri_18, :jruby]
|
10
|
-
gem 'ruby-debug19', :platform => :mri_19, :require => 'ruby-debug'
|
11
9
|
gem 'jruby-openssl', :platform => [:jruby], :require => false
|
12
10
|
gem "webmock"
|
13
11
|
gem "vcr"
|
14
12
|
gem 'jeweler', :require => false
|
15
|
-
|
13
|
+
gem 'debugger'
|
14
|
+
end
|
data/HISTORY
CHANGED
data/Rakefile
CHANGED
@@ -21,7 +21,7 @@ end
|
|
21
21
|
require 'rspec/core/rake_task'
|
22
22
|
RSpec::Core::RakeTask.new(:spec)
|
23
23
|
|
24
|
-
task :default => %w(spec
|
24
|
+
task :default => %w(spec)
|
25
25
|
|
26
26
|
begin
|
27
27
|
require 'yard'
|
@@ -38,6 +38,3 @@ task 'clean_remote' do
|
|
38
38
|
require "spec/support/harvested_helpers"
|
39
39
|
HarvestedHelpers.clean_remote
|
40
40
|
end
|
41
|
-
|
42
|
-
task :foo do
|
43
|
-
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.6.0
|
data/harvested.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "harvested"
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.6.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Zach Moazeni"]
|
12
|
-
s.date = "2012-08-
|
12
|
+
s.date = "2012-08-23"
|
13
13
|
s.description = "Harvested wraps the Harvest API concisely without the use of Rails dependencies. More information about the Harvest API can be found on their website (http://www.getharvest.com/api). For support hit up the Mailing List (http://groups.google.com/group/harvested)"
|
14
14
|
s.email = "zach.moazeni@gmail.com"
|
15
15
|
s.extra_rdoc_files = [
|
@@ -113,35 +113,32 @@ Gem::Specification.new do |s|
|
|
113
113
|
s.add_runtime_dependency(%q<hashie>, ["~> 1"])
|
114
114
|
s.add_runtime_dependency(%q<json>, [">= 0"])
|
115
115
|
s.add_development_dependency(%q<rspec>, ["~> 2"])
|
116
|
-
s.add_development_dependency(%q<ruby-debug>, [">= 0"])
|
117
|
-
s.add_development_dependency(%q<ruby-debug19>, [">= 0"])
|
118
116
|
s.add_development_dependency(%q<jruby-openssl>, [">= 0"])
|
119
117
|
s.add_development_dependency(%q<webmock>, [">= 0"])
|
120
118
|
s.add_development_dependency(%q<vcr>, [">= 0"])
|
121
119
|
s.add_development_dependency(%q<jeweler>, [">= 0"])
|
120
|
+
s.add_development_dependency(%q<debugger>, [">= 0"])
|
122
121
|
else
|
123
122
|
s.add_dependency(%q<httparty>, [">= 0"])
|
124
123
|
s.add_dependency(%q<hashie>, ["~> 1"])
|
125
124
|
s.add_dependency(%q<json>, [">= 0"])
|
126
125
|
s.add_dependency(%q<rspec>, ["~> 2"])
|
127
|
-
s.add_dependency(%q<ruby-debug>, [">= 0"])
|
128
|
-
s.add_dependency(%q<ruby-debug19>, [">= 0"])
|
129
126
|
s.add_dependency(%q<jruby-openssl>, [">= 0"])
|
130
127
|
s.add_dependency(%q<webmock>, [">= 0"])
|
131
128
|
s.add_dependency(%q<vcr>, [">= 0"])
|
132
129
|
s.add_dependency(%q<jeweler>, [">= 0"])
|
130
|
+
s.add_dependency(%q<debugger>, [">= 0"])
|
133
131
|
end
|
134
132
|
else
|
135
133
|
s.add_dependency(%q<httparty>, [">= 0"])
|
136
134
|
s.add_dependency(%q<hashie>, ["~> 1"])
|
137
135
|
s.add_dependency(%q<json>, [">= 0"])
|
138
136
|
s.add_dependency(%q<rspec>, ["~> 2"])
|
139
|
-
s.add_dependency(%q<ruby-debug>, [">= 0"])
|
140
|
-
s.add_dependency(%q<ruby-debug19>, [">= 0"])
|
141
137
|
s.add_dependency(%q<jruby-openssl>, [">= 0"])
|
142
138
|
s.add_dependency(%q<webmock>, [">= 0"])
|
143
139
|
s.add_dependency(%q<vcr>, [">= 0"])
|
144
140
|
s.add_dependency(%q<jeweler>, [">= 0"])
|
141
|
+
s.add_dependency(%q<debugger>, [">= 0"])
|
145
142
|
end
|
146
143
|
end
|
147
144
|
|
data/lib/harvest/client.rb
CHANGED
@@ -10,26 +10,13 @@ module Harvest
|
|
10
10
|
# [+active?+] true|false on whether the client is active
|
11
11
|
# [+highrise_id+] (READONLY) the highrise id associated with this client
|
12
12
|
# [+update_at+] (READONLY) the last modification timestamp
|
13
|
-
class Client < Hashie::
|
13
|
+
class Client < Hashie::Mash
|
14
14
|
include Harvest::Model
|
15
|
-
|
15
|
+
|
16
16
|
api_path '/clients'
|
17
|
-
|
18
17
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
property :details
|
23
|
-
property :currency
|
24
|
-
property :currency_symbol
|
25
|
-
property :cache_version
|
26
|
-
property :created_at
|
27
|
-
property :updated_at
|
28
|
-
property :highrise_id
|
29
|
-
property :default_invoice_timeframe
|
30
|
-
property :last_invoice_kind
|
31
|
-
|
32
|
-
alias_method :active?, :active
|
33
|
-
alias_method :is_active=, :active=
|
18
|
+
def is_active=(val)
|
19
|
+
self.active = val
|
20
|
+
end
|
34
21
|
end
|
35
|
-
end
|
22
|
+
end
|
data/lib/harvest/contact.rb
CHANGED
@@ -11,21 +11,9 @@ module Harvest
|
|
11
11
|
# [+phone_office+] the office phone number of the contact
|
12
12
|
# [+phone_moble+] the moble phone number of the contact
|
13
13
|
# [+fax+] the fax number of the contact
|
14
|
-
class Contact < Hashie::
|
14
|
+
class Contact < Hashie::Mash
|
15
15
|
include Harvest::Model
|
16
|
-
|
16
|
+
|
17
17
|
api_path '/contacts'
|
18
|
-
|
19
|
-
property :id
|
20
|
-
property :client_id
|
21
|
-
property :email
|
22
|
-
property :first_name
|
23
|
-
property :last_name
|
24
|
-
property :phone_office
|
25
|
-
property :phone_mobile
|
26
|
-
property :fax
|
27
|
-
property :title
|
28
|
-
property :created_at
|
29
|
-
property :updated_at
|
30
18
|
end
|
31
|
-
end
|
19
|
+
end
|
data/lib/harvest/expense.rb
CHANGED
@@ -1,24 +1,10 @@
|
|
1
1
|
module Harvest
|
2
|
-
class Expense < Hashie::
|
2
|
+
class Expense < Hashie::Mash
|
3
3
|
include Harvest::Model
|
4
4
|
|
5
5
|
api_path '/expenses'
|
6
|
-
|
7
|
-
|
8
|
-
property :notes
|
9
|
-
property :units
|
10
|
-
property :total_cost
|
11
|
-
property :project_id
|
12
|
-
property :expense_category_id
|
13
|
-
property :user_id
|
14
|
-
property :spent_at
|
15
|
-
property :created_at
|
16
|
-
property :updated_at
|
17
|
-
property :is_billed
|
18
|
-
property :is_closed
|
19
|
-
property :invoice_id
|
20
|
-
property :has_receipt
|
21
|
-
property :receipt_url
|
6
|
+
delegate_methods(:billed? => :is_billed,
|
7
|
+
:closed? => :is_closed)
|
22
8
|
|
23
9
|
def initialize(args = {})
|
24
10
|
args = args.stringify_keys
|
@@ -37,9 +23,5 @@ module Harvest
|
|
37
23
|
hash[json_root].delete("receipt_url")
|
38
24
|
end
|
39
25
|
end
|
40
|
-
|
41
|
-
alias_method :billed?, :is_billed
|
42
|
-
alias_method :closed?, :is_closed
|
43
|
-
alias_method :has_receipt?, :has_receipt
|
44
26
|
end
|
45
27
|
end
|
@@ -1,19 +1,10 @@
|
|
1
1
|
module Harvest
|
2
|
-
class ExpenseCategory < Hashie::
|
2
|
+
class ExpenseCategory < Hashie::Mash
|
3
3
|
include Harvest::Model
|
4
4
|
api_path '/expense_categories'
|
5
|
-
|
6
|
-
property :id
|
7
|
-
property :name
|
8
|
-
property :unit_name
|
9
|
-
property :unit_price
|
10
|
-
property :deactivated
|
11
|
-
property :created_at
|
12
|
-
property :updated_at
|
13
|
-
property :cache_version
|
14
|
-
|
5
|
+
|
15
6
|
def active?
|
16
7
|
!deactivated
|
17
8
|
end
|
18
9
|
end
|
19
|
-
end
|
10
|
+
end
|
data/lib/harvest/invoice.rb
CHANGED
@@ -1,46 +1,14 @@
|
|
1
1
|
module Harvest
|
2
|
-
class Invoice < Hashie::
|
2
|
+
class Invoice < Hashie::Mash
|
3
3
|
include Harvest::Model
|
4
|
-
|
4
|
+
|
5
5
|
api_path '/invoices'
|
6
|
-
|
6
|
+
|
7
7
|
attr_reader :line_items
|
8
|
-
|
9
|
-
property :id
|
10
|
-
property :subject
|
11
|
-
property :number
|
12
|
-
property :created_at
|
13
|
-
property :updated_at
|
14
|
-
property :issued_at
|
15
|
-
property :due_at
|
16
|
-
property :due_at_human_format
|
17
|
-
property :due_amount
|
18
|
-
property :notes
|
19
|
-
property :recurring_invoice_id
|
20
|
-
property :period_start
|
21
|
-
property :period_end
|
22
|
-
property :discount
|
23
|
-
property :discount_amount
|
24
|
-
property :client_key
|
25
|
-
property :amount
|
26
|
-
property :tax
|
27
|
-
property :tax2
|
28
|
-
property :tax_amount
|
29
|
-
property :tax2_amount
|
30
|
-
property :csv_line_items
|
31
|
-
property :client_id
|
32
|
-
property :estimate_id
|
33
|
-
property :purchase_order
|
34
|
-
property :retainer_id
|
35
|
-
property :currency
|
36
|
-
property :state
|
37
|
-
property :kind
|
38
|
-
property :import_hours
|
39
|
-
property :import_expenses
|
40
|
-
|
8
|
+
|
41
9
|
def self.json_root; "doc"; end
|
42
10
|
# skip_json_root true
|
43
|
-
|
11
|
+
|
44
12
|
def initialize(args = {})
|
45
13
|
@line_items = []
|
46
14
|
args = args.stringify_keys
|
@@ -48,7 +16,7 @@ module Harvest
|
|
48
16
|
self.line_items = args.delete("line_items")
|
49
17
|
super
|
50
18
|
end
|
51
|
-
|
19
|
+
|
52
20
|
def line_items=(raw_or_rich)
|
53
21
|
unless raw_or_rich.nil?
|
54
22
|
@line_items = case raw_or_rich
|
@@ -59,13 +27,13 @@ module Harvest
|
|
59
27
|
end
|
60
28
|
end
|
61
29
|
end
|
62
|
-
|
30
|
+
|
63
31
|
def as_json(*options)
|
64
32
|
json = super(*options)
|
65
33
|
json[json_root]["csv_line_items"] = encode_csv(@line_items)
|
66
34
|
json
|
67
35
|
end
|
68
|
-
|
36
|
+
|
69
37
|
private
|
70
38
|
def decode_csv(string)
|
71
39
|
csv = CSV.parse(string)
|
@@ -73,19 +41,19 @@ module Harvest
|
|
73
41
|
csv.map! {|row| headers.zip(row) }
|
74
42
|
csv.map {|row| row.inject({}) {|h, tuple| h.update(tuple[0] => tuple[1]) } }
|
75
43
|
end
|
76
|
-
|
44
|
+
|
77
45
|
def encode_csv(line_items)
|
78
46
|
if line_items.empty?
|
79
47
|
""
|
80
48
|
else
|
81
49
|
header = %w(kind description quantity unit_price amount taxed taxed2 project_id)
|
82
|
-
|
50
|
+
|
83
51
|
# writing this in stdlib so we don't force 1.8 users to install FasterCSV and make gem dependencies wierd
|
84
52
|
if RUBY_VERSION =~ /1.8/
|
85
53
|
csv_data = ""
|
86
54
|
CSV.generate_row(header, header.size, csv_data)
|
87
55
|
line_items.each do |item|
|
88
|
-
row_data = header.inject([]) {|row, attr| row << item[attr] }
|
56
|
+
row_data = header.inject([]) {|row, attr| row << item[attr] }
|
89
57
|
CSV.generate_row(row_data, row_data.size, csv_data)
|
90
58
|
end
|
91
59
|
csv_data
|
@@ -93,11 +61,11 @@ module Harvest
|
|
93
61
|
CSV.generate do |csv|
|
94
62
|
csv << header
|
95
63
|
line_items.each do |item|
|
96
|
-
csv << header.inject([]) {|row, attr| row << item[attr] }
|
64
|
+
csv << header.inject([]) {|row, attr| row << item[attr] }
|
97
65
|
end
|
98
66
|
end
|
99
67
|
end
|
100
68
|
end
|
101
69
|
end
|
102
70
|
end
|
103
|
-
end
|
71
|
+
end
|
@@ -1,18 +1,9 @@
|
|
1
1
|
module Harvest
|
2
|
-
class InvoiceCategory < Hashie::
|
2
|
+
class InvoiceCategory < Hashie::Mash
|
3
3
|
include Harvest::Model
|
4
|
-
|
4
|
+
|
5
5
|
api_path '/invoice_item_categories'
|
6
6
|
def self.json_root; "category"; end
|
7
|
-
|
8
|
-
property :id
|
9
|
-
property :name
|
10
|
-
property :created_at
|
11
|
-
property :updated_at
|
12
|
-
property :use_as_expense
|
13
|
-
property :use_as_service
|
14
|
-
|
15
|
-
alias_method :use_as_expense?, :use_as_expense
|
16
|
-
alias_method :use_as_service?, :use_as_service
|
7
|
+
|
17
8
|
end
|
18
|
-
end
|
9
|
+
end
|
data/lib/harvest/line_item.rb
CHANGED
@@ -1,12 +1,4 @@
|
|
1
1
|
module Harvest
|
2
|
-
class LineItem < Hashie::
|
3
|
-
property :kind
|
4
|
-
property :description
|
5
|
-
property :quantity
|
6
|
-
property :unit_price
|
7
|
-
property :amount
|
8
|
-
property :taxed
|
9
|
-
property :taxed2
|
10
|
-
property :project_id
|
2
|
+
class LineItem < Hashie::Mash
|
11
3
|
end
|
12
|
-
end
|
4
|
+
end
|
data/lib/harvest/model.rb
CHANGED
@@ -4,12 +4,12 @@ module Harvest
|
|
4
4
|
base.send :include, InstanceMethods
|
5
5
|
base.send :extend, ClassMethods
|
6
6
|
end
|
7
|
-
|
7
|
+
|
8
8
|
module InstanceMethods
|
9
9
|
def to_json(*args)
|
10
10
|
as_json(*args).to_json(*args)
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
def as_json(args = {})
|
14
14
|
inner_json = self.to_hash.stringify_keys
|
15
15
|
inner_json.delete("cache_version")
|
@@ -19,13 +19,13 @@ module Harvest
|
|
19
19
|
{ self.class.json_root => inner_json }
|
20
20
|
end
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
def to_i; id; end
|
24
|
-
|
24
|
+
|
25
25
|
def ==(other)
|
26
26
|
id == other.id
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
def impersonated_user_id
|
30
30
|
if respond_to?(:of_user) && respond_to?(:user_id)
|
31
31
|
of_user || user_id
|
@@ -35,41 +35,41 @@ module Harvest
|
|
35
35
|
of_user
|
36
36
|
end
|
37
37
|
end
|
38
|
-
|
38
|
+
|
39
39
|
def json_root
|
40
40
|
self.class.json_root
|
41
41
|
end
|
42
42
|
end
|
43
|
-
|
43
|
+
|
44
44
|
module ClassMethods
|
45
45
|
# This sets the API path so the API collections can use them in an agnostic way
|
46
46
|
# @return [void]
|
47
47
|
def api_path(path = nil)
|
48
48
|
@_api_path ||= path
|
49
49
|
end
|
50
|
-
|
50
|
+
|
51
51
|
def skip_json_root(skip = nil)
|
52
52
|
@_skip_json_root ||= skip
|
53
53
|
end
|
54
|
-
|
54
|
+
|
55
55
|
def skip_json_root?
|
56
56
|
@_skip_json_root == true
|
57
57
|
end
|
58
|
-
|
58
|
+
|
59
59
|
def parse(json)
|
60
60
|
parsed = String === json ? JSON.parse(json) : json
|
61
61
|
Array.wrap(parsed).map {|attrs| skip_json_root? ? new(attrs) : new(attrs[json_root])}
|
62
62
|
end
|
63
|
-
|
63
|
+
|
64
64
|
def json_root
|
65
65
|
Harvest::Model::Utility.underscore(
|
66
66
|
Harvest::Model::Utility.demodulize(to_s)
|
67
67
|
)
|
68
68
|
end
|
69
|
-
|
69
|
+
|
70
70
|
def wrap(model_or_attrs)
|
71
71
|
case model_or_attrs
|
72
|
-
when Hashie::
|
72
|
+
when Hashie::Mash
|
73
73
|
model_or_attrs
|
74
74
|
when Hash
|
75
75
|
new(model_or_attrs)
|
@@ -77,13 +77,24 @@ module Harvest
|
|
77
77
|
model_or_attrs
|
78
78
|
end
|
79
79
|
end
|
80
|
+
|
81
|
+
def delegate_methods(options)
|
82
|
+
raise "no methods given" if options.empty?
|
83
|
+
options.each do |source, dest|
|
84
|
+
class_eval <<-EOV
|
85
|
+
def #{source}
|
86
|
+
#{dest}
|
87
|
+
end
|
88
|
+
EOV
|
89
|
+
end
|
90
|
+
end
|
80
91
|
end
|
81
|
-
|
92
|
+
|
82
93
|
module Utility
|
83
94
|
class << self
|
84
|
-
|
95
|
+
|
85
96
|
# Both methods are shamelessly ripped from https://github.com/rails/rails/blob/master/activesupport/lib/active_support/inflector/inflections.rb
|
86
|
-
|
97
|
+
|
87
98
|
# Removes the module part from the expression in the string.
|
88
99
|
#
|
89
100
|
# Examples:
|
@@ -92,7 +103,7 @@ module Harvest
|
|
92
103
|
def demodulize(class_name_in_module)
|
93
104
|
class_name_in_module.to_s.gsub(/^.*::/, '')
|
94
105
|
end
|
95
|
-
|
106
|
+
|
96
107
|
# Makes an underscored, lowercase form from the expression in the string.
|
97
108
|
#
|
98
109
|
# Changes '::' to '/' to convert namespaces to paths.
|
@@ -117,4 +128,4 @@ module Harvest
|
|
117
128
|
end
|
118
129
|
end
|
119
130
|
end
|
120
|
-
end
|
131
|
+
end
|
data/lib/harvest/project.rb
CHANGED
@@ -22,58 +22,21 @@ module Harvest
|
|
22
22
|
# [+active_task_assignments_count+] (READONLY) the number of active task assignments
|
23
23
|
# [+created_at+] (READONLY) when the project was created
|
24
24
|
# [+updated_at+] (READONLY) when the project was updated
|
25
|
-
class Project < Hashie::
|
25
|
+
class Project < Hashie::Mash
|
26
26
|
include Harvest::Model
|
27
27
|
|
28
28
|
api_path '/projects'
|
29
29
|
|
30
|
-
property :id
|
31
|
-
property :client_id
|
32
|
-
property :name
|
33
|
-
property :code
|
34
|
-
property :notes
|
35
|
-
property :fees
|
36
|
-
property :active
|
37
|
-
property :billable
|
38
|
-
property :budget
|
39
|
-
property :budget_by
|
40
|
-
property :hourly_rate
|
41
|
-
property :bill_by
|
42
|
-
property :created_at
|
43
|
-
property :updated_at
|
44
|
-
property :notify_when_over_budget
|
45
|
-
property :over_budget_notification_percentage
|
46
|
-
property :show_budget_to_all
|
47
|
-
property :basecamp_id
|
48
|
-
property :highrise_deal_id
|
49
|
-
property :active_task_assignments_count
|
50
|
-
property :over_budget_notified_at
|
51
|
-
property :earliest_record_at
|
52
|
-
property :cost_budget
|
53
|
-
property :cost_budget_include_expenses
|
54
|
-
property :latest_record_at
|
55
|
-
property :estimate_by
|
56
|
-
property :hint_earliest_record_at
|
57
|
-
property :hint_latest_record_at
|
58
|
-
property :active_user_assignments_count
|
59
|
-
property :cache_version
|
60
|
-
property :estimate
|
61
|
-
|
62
|
-
alias_method :active?, :active
|
63
|
-
alias_method :billable?, :billable
|
64
|
-
alias_method :notify_when_over_budget?, :notify_when_over_budget
|
65
|
-
alias_method :show_budget_to_all?, :show_budget_to_all
|
66
|
-
|
67
30
|
def as_json(args = {})
|
68
31
|
super(args).tap do |json|
|
69
32
|
json[json_root].delete("hint_earliest_record_at")
|
70
33
|
json[json_root].delete("hint_latest_record_at")
|
71
34
|
end
|
72
35
|
end
|
73
|
-
|
36
|
+
|
74
37
|
def self.parse(json)
|
75
38
|
json = String === json ? JSON.parse(json) : json
|
76
|
-
Array.wrap(json).each do |attrs|
|
39
|
+
Array.wrap(json).each do |attrs|
|
77
40
|
# need to cleanup some attributes
|
78
41
|
project_attrs = attrs[json_root] || {}
|
79
42
|
project_attrs["hint_latest_record_at"] = project_attrs.delete("hint-latest-record-at")
|
@@ -82,4 +45,4 @@ module Harvest
|
|
82
45
|
super(json)
|
83
46
|
end
|
84
47
|
end
|
85
|
-
end
|
48
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module Harvest
|
2
|
-
|
2
|
+
|
3
3
|
# The model that contains the information about the user's rate limit
|
4
4
|
#
|
5
5
|
# == Fields
|
@@ -8,17 +8,11 @@ module Harvest
|
|
8
8
|
# [+timeframe_limit+] The amount of seconds before a rate limit refresh occurs
|
9
9
|
# [+max_calls+] The number of requests you can make within the +timeframe_limit+
|
10
10
|
# [+lockout_seconds+] If you exceed the rate limit, how long you will be locked out from Harvest
|
11
|
-
class RateLimitStatus < Hashie::
|
11
|
+
class RateLimitStatus < Hashie::Mash
|
12
12
|
include Harvest::Model
|
13
|
-
|
13
|
+
|
14
14
|
skip_json_root true
|
15
|
-
|
16
|
-
property :last_access_at
|
17
|
-
property :count
|
18
|
-
property :timeframe_limit
|
19
|
-
property :max_calls
|
20
|
-
property :lockout_seconds
|
21
|
-
|
15
|
+
|
22
16
|
# Returns true if the user is over their rate limit
|
23
17
|
# @return [Boolean]
|
24
18
|
# @see http://www.getharvest.com/api
|
@@ -26,4 +20,4 @@ module Harvest
|
|
26
20
|
count > max_calls
|
27
21
|
end
|
28
22
|
end
|
29
|
-
end
|
23
|
+
end
|
data/lib/harvest/task.rb
CHANGED
@@ -9,25 +9,14 @@ module Harvest
|
|
9
9
|
# [+deactivated+] whether the task is deactivated
|
10
10
|
# [+hourly_rate+] what the default hourly rate for the task is
|
11
11
|
# [+default?+] whether to add this task to new projects by default
|
12
|
-
class Task < Hashie::
|
12
|
+
class Task < Hashie::Mash
|
13
13
|
include Harvest::Model
|
14
14
|
|
15
15
|
api_path '/tasks'
|
16
|
+
delegate_methods :default? => :is_default
|
16
17
|
|
17
|
-
property :id
|
18
|
-
property :name
|
19
|
-
property :billable_by_default
|
20
|
-
property :deactivated
|
21
|
-
property :default_hourly_rate
|
22
|
-
property :is_default
|
23
|
-
property :created_at
|
24
|
-
property :updated_at
|
25
|
-
property :cache_version
|
26
|
-
|
27
18
|
def active?
|
28
19
|
!deactivated
|
29
20
|
end
|
30
|
-
|
31
|
-
alias_method :default?, :is_default
|
32
21
|
end
|
33
|
-
end
|
22
|
+
end
|
@@ -1,25 +1,14 @@
|
|
1
1
|
module Harvest
|
2
|
-
class TaskAssignment < Hashie::
|
2
|
+
class TaskAssignment < Hashie::Mash
|
3
3
|
include Harvest::Model
|
4
4
|
|
5
|
-
property :id
|
6
|
-
property :task_id
|
7
|
-
property :project_id
|
8
|
-
property :billable
|
9
|
-
property :deactivated
|
10
|
-
property :hourly_rate
|
11
|
-
property :budget
|
12
|
-
property :estimate
|
13
|
-
property :created_at
|
14
|
-
property :updated_at
|
15
|
-
|
16
5
|
def initialize(args = {})
|
17
6
|
args = args.stringify_keys
|
18
7
|
self.task = args.delete("task") if args["task"]
|
19
8
|
self.project = args.delete("project") if args["project"]
|
20
9
|
super
|
21
10
|
end
|
22
|
-
|
11
|
+
|
23
12
|
def task=(task)
|
24
13
|
self["task_id"] = task.to_i
|
25
14
|
end
|
@@ -35,7 +24,5 @@ module Harvest
|
|
35
24
|
def task_as_json
|
36
25
|
{"task" => {"id" => task_id}}
|
37
26
|
end
|
38
|
-
|
39
|
-
alias_method :billable?, :billable
|
40
27
|
end
|
41
|
-
end
|
28
|
+
end
|
data/lib/harvest/time_entry.rb
CHANGED
@@ -1,46 +1,25 @@
|
|
1
1
|
module Harvest
|
2
|
-
class TimeEntry < Hashie::
|
2
|
+
class TimeEntry < Hashie::Mash
|
3
3
|
include Harvest::Model
|
4
|
-
|
5
|
-
property :id
|
6
|
-
property :client
|
7
|
-
property :hours
|
8
|
-
property :notes
|
9
|
-
|
10
|
-
property :project_id
|
11
|
-
property :task_id
|
12
|
-
property :project
|
13
|
-
property :task
|
14
|
-
property :spent_at
|
15
|
-
property :created_at
|
16
|
-
property :updated_at
|
17
|
-
property :user_id
|
18
|
-
property :of_user
|
19
|
-
property :is_closed
|
20
|
-
property :is_billed
|
21
|
-
property :timer_started_at
|
22
|
-
property :adjustment_record
|
23
|
-
property :hours_without_timer
|
24
|
-
|
4
|
+
|
25
5
|
skip_json_root true
|
26
|
-
|
6
|
+
delegate_methods(:closed? => :is_closed,
|
7
|
+
:billed? => :is_billed)
|
8
|
+
|
27
9
|
def initialize(args = {})
|
28
10
|
args = args.stringify_keys
|
29
11
|
self.spent_at = args.delete("spent_at") if args["spent_at"]
|
30
12
|
super
|
31
13
|
end
|
32
|
-
|
14
|
+
|
33
15
|
def spent_at=(date)
|
34
16
|
self["spent_at"] = (String === date ? Time.parse(date) : date)
|
35
17
|
end
|
36
|
-
|
18
|
+
|
37
19
|
def as_json(args = {})
|
38
|
-
super(args).stringify_keys.tap do |hash|
|
20
|
+
super(args).stringify_keys.tap do |hash|
|
39
21
|
hash.update("spent_at" => (spent_at.nil? ? nil : spent_at.to_time.xmlschema))
|
40
22
|
end
|
41
23
|
end
|
42
|
-
|
43
|
-
alias_method :closed?, :is_closed
|
44
|
-
alias_method :billed?, :is_billed
|
45
24
|
end
|
46
25
|
end
|
data/lib/harvest/user.rb
CHANGED
@@ -15,51 +15,14 @@ module Harvest
|
|
15
15
|
# [+contractor?+] whether the user is a contractor
|
16
16
|
# [+contractor?+] whether the user is a contractor
|
17
17
|
# [+timezone+] the timezone for the user.
|
18
|
-
class User < Hashie::
|
18
|
+
class User < Hashie::Mash
|
19
19
|
include Harvest::Model
|
20
20
|
|
21
21
|
api_path '/people'
|
22
|
-
property :id
|
23
|
-
property :email
|
24
|
-
property :first_name
|
25
|
-
property :last_name
|
26
|
-
property :has_access_to_all_future_projects
|
27
|
-
property :default_hourly_rate
|
28
|
-
property :is_active
|
29
|
-
property :is_admin
|
30
|
-
property :is_contractor
|
31
|
-
property :telephone
|
32
|
-
property :department
|
33
|
-
property :timezone
|
34
|
-
property :password
|
35
|
-
property :first_timer
|
36
|
-
property :wants_newsletter
|
37
|
-
property :preferred_project_status_reports_screen
|
38
|
-
property :preferred_approval_screen
|
39
|
-
property :created_at
|
40
|
-
property :updated_at
|
41
|
-
property :twitter_username
|
42
|
-
property :preferred_entry_method
|
43
|
-
property :default_time_project_id
|
44
|
-
property :default_task_id
|
45
|
-
property :default_expense_category_id
|
46
|
-
property :opensocial_identifier
|
47
|
-
property :duplicate_timesheet_wants_notes
|
48
|
-
property :wants_timesheet_duplication
|
49
|
-
property :cache_version
|
50
|
-
property :email_after_submit
|
51
|
-
property :default_expense_project_id
|
52
|
-
property :identity_url
|
53
|
-
property :timestamp_timers
|
54
|
-
property :weekly_digest_sent_on
|
55
|
-
property :wants_weekly_digest
|
56
|
-
property :password_change_required
|
57
|
-
property :has_timesheet_2012_beta
|
58
|
-
property :timesheet_2012_beta_control_group
|
59
22
|
|
60
|
-
|
61
|
-
|
62
|
-
|
23
|
+
delegate_methods(:active? => :is_active,
|
24
|
+
:admin? => :is_admin,
|
25
|
+
:contractor? => :is_contractor)
|
63
26
|
|
64
27
|
def initialize(args = {})
|
65
28
|
args = args.stringify_keys
|
@@ -1,41 +1,30 @@
|
|
1
1
|
module Harvest
|
2
|
-
class UserAssignment < Hashie::
|
2
|
+
class UserAssignment < Hashie::Mash
|
3
3
|
include Harvest::Model
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
property :project_id
|
8
|
-
property :deactivated
|
9
|
-
property :is_project_manager
|
10
|
-
property :hourly_rate
|
11
|
-
property :created_at
|
12
|
-
property :updated_at
|
13
|
-
property :budget
|
14
|
-
property :estimate
|
15
|
-
|
4
|
+
|
5
|
+
delegate_methods :project_manager? => :is_project_manager
|
6
|
+
|
16
7
|
def initialize(args = {})
|
17
8
|
args = args.stringify_keys
|
18
9
|
self.user = args.delete("user") if args["user"]
|
19
10
|
self.project = args.delete("project") if args["project"]
|
20
11
|
super
|
21
12
|
end
|
22
|
-
|
13
|
+
|
23
14
|
def user=(user)
|
24
15
|
self["user_id"] = user.to_i
|
25
16
|
end
|
26
|
-
|
17
|
+
|
27
18
|
def project=(project)
|
28
19
|
self["project_id"] = project.to_i
|
29
20
|
end
|
30
|
-
|
21
|
+
|
31
22
|
def active?
|
32
23
|
!deactivated
|
33
24
|
end
|
34
|
-
|
25
|
+
|
35
26
|
def user_as_json
|
36
27
|
{"user" => {"id" => user_id}}
|
37
28
|
end
|
38
|
-
|
39
|
-
alias_method :project_manager?, :is_project_manager
|
40
29
|
end
|
41
|
-
end
|
30
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe 'harvest reporting' do
|
3
|
+
describe 'harvest reporting' do
|
4
4
|
it 'allows project and people entry reporting' do
|
5
5
|
cassette("reports1") do
|
6
6
|
user = harvest.users.create(
|
@@ -20,8 +20,8 @@ describe 'harvest reporting' do
|
|
20
20
|
harvest.user_assignments.create("project" => project1, "user" => user)
|
21
21
|
harvest.user_assignments.create("project" => project2, "user" => user)
|
22
22
|
|
23
|
-
entry1 = harvest.time.create("notes" => "billable entry1", "hours" => 3, "spent_at" => "12/28
|
24
|
-
entry2 = harvest.time.create("notes" => "non billable entry2", "hours" => 6, "spent_at" => "12/28
|
23
|
+
entry1 = harvest.time.create("notes" => "billable entry1", "hours" => 3, "spent_at" => "2009/12/28", "task_id" => task1.id, "project_id" => project1.id, "of_user" => user.id)
|
24
|
+
entry2 = harvest.time.create("notes" => "non billable entry2", "hours" => 6, "spent_at" => "2009/12/28", "task_id" => task2.id, "project_id" => project2.id, "of_user" => user.id)
|
25
25
|
|
26
26
|
harvest.reports.time_by_project(project1, Time.utc(2009, 12, 20), Time.utc(2009,12,30)).first.should == entry1
|
27
27
|
|
@@ -40,7 +40,7 @@ describe 'harvest reporting' do
|
|
40
40
|
|
41
41
|
harvest.reports.time_by_user(user, Time.utc(2009, 12, 20), Time.utc(2009,12,30), :billable => true).first.should == entry1
|
42
42
|
harvest.reports.time_by_user(user, Time.utc(2009, 12, 20), Time.utc(2009,12,30), :billable => false).first.should == entry2
|
43
|
-
|
43
|
+
|
44
44
|
client2 = harvest.clients.create("name" => "Phil's Sandwich Shop")
|
45
45
|
harvest.reports.projects_by_client(client).map(&:id).to_set.should == [project1, project2].map(&:id).to_set
|
46
46
|
harvest.reports.projects_by_client(client2).should == []
|
@@ -69,9 +69,9 @@ describe 'harvest reporting' do
|
|
69
69
|
"project_id" => project.id,
|
70
70
|
"user_id" => user.id
|
71
71
|
)
|
72
|
-
|
72
|
+
|
73
73
|
harvest.reports.expenses_by_user(user, Time.utc(2009, 12, 20), Time.utc(2009,12,30)).first.should == expense
|
74
|
-
|
74
|
+
|
75
75
|
my_user = harvest.users.all.detect {|u| u.email == credentials["username"]}
|
76
76
|
my_user.should_not be_nil
|
77
77
|
harvest.reports.expenses_by_user(my_user, Time.utc(2009, 12, 20), Time.utc(2009,12,30)).should == []
|
@@ -7,23 +7,23 @@ describe 'harvest time tracking' do
|
|
7
7
|
project = harvest.projects.create("name" => "Tracking Project", "client_id" => client.id)
|
8
8
|
harvest.projects.create_task(project, "A billable task")
|
9
9
|
task = harvest.tasks.all.detect {|t| t.name == "A billable task"}
|
10
|
-
|
11
|
-
entry = harvest.time.create("notes" => "Test api support", "hours" => 3, "spent_at" => "12/28
|
10
|
+
|
11
|
+
entry = harvest.time.create("notes" => "Test api support", "hours" => 3, "spent_at" => "2009/12/28", "task_id" => task.id, "project_id" => project.id)
|
12
12
|
entry.notes.should == "Test api support"
|
13
|
-
|
13
|
+
|
14
14
|
entry.notes = "Upgraded to JSON"
|
15
15
|
entry = harvest.time.update(entry)
|
16
16
|
entry.notes.should == "Upgraded to JSON"
|
17
|
-
|
17
|
+
|
18
18
|
harvest.time.delete(entry)
|
19
19
|
harvest.time.all(Time.utc(2009, 12, 28)).should == []
|
20
20
|
end
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
it 'allows you to save entries for a different user' do
|
24
24
|
cassette("time_tracking2") do
|
25
25
|
user = harvest.users.create(
|
26
|
-
"email" => "frank@example.com",
|
26
|
+
"email" => "frank@example.com",
|
27
27
|
"first_name" => "Frank",
|
28
28
|
"last_name" => "Doe",
|
29
29
|
"password" => "secure"
|
@@ -33,21 +33,21 @@ describe 'harvest time tracking' do
|
|
33
33
|
harvest.user_assignments.create("project" => project, "user" => user)
|
34
34
|
harvest.projects.create_task(project, "A billable task for tuxes")
|
35
35
|
task = harvest.tasks.all.detect {|t| t.name == "A billable task for tuxes"}
|
36
|
-
|
37
|
-
entry = harvest.time.create("notes" => "Test api support", "hours" => 3, "spent_at" => "12/28
|
36
|
+
|
37
|
+
entry = harvest.time.create("notes" => "Test api support", "hours" => 3, "spent_at" => "2009/12/28", "task_id" => task.id, "project_id" => project.id, "of_user" => user.id)
|
38
38
|
harvest.time.all(Time.utc(2009, 12, 28), user).should == [entry]
|
39
|
-
|
39
|
+
|
40
40
|
entry.notes = "Updating notes"
|
41
41
|
entry = harvest.time.update(entry, user)
|
42
42
|
entry.notes.should == "Updating notes"
|
43
|
-
|
43
|
+
|
44
44
|
entry = harvest.time.find(entry, user)
|
45
45
|
entry.notes.should == "Updating notes"
|
46
|
-
|
46
|
+
|
47
47
|
harvest.time.delete(entry, user)
|
48
48
|
harvest.time.all(Time.utc(2009, 12, 28), user).should == []
|
49
49
|
end
|
50
50
|
end
|
51
|
-
|
51
|
+
|
52
52
|
it 'allows toggling of timers'
|
53
|
-
end
|
53
|
+
end
|
@@ -7,60 +7,61 @@ describe 'harvest users' do
|
|
7
7
|
"first_name" => "Edgar",
|
8
8
|
"last_name" => "Ruth",
|
9
9
|
"email" => "edgar@ruth.com",
|
10
|
-
"password" => "mypassword",
|
11
10
|
"timezone" => "cst",
|
12
11
|
"is_admin" => "false",
|
13
12
|
"telephone" => "444-4444"
|
14
13
|
)
|
15
|
-
user.id.should_not
|
16
|
-
|
14
|
+
user.id.should_not be_nil
|
15
|
+
|
17
16
|
user.first_name = "Joey"
|
18
17
|
user = harvest.users.update(user)
|
19
18
|
user.first_name.should == "Joey"
|
20
|
-
|
19
|
+
|
21
20
|
id = harvest.users.delete(user)
|
22
21
|
harvest.users.all.map(&:id).should_not include(id)
|
23
22
|
end
|
24
23
|
end
|
25
|
-
|
24
|
+
|
26
25
|
it "allows activating and deactivating users" do
|
27
26
|
cassette("users2") do
|
28
27
|
user = harvest.users.create(
|
29
28
|
"first_name" => "John",
|
30
29
|
"last_name" => "Ruth",
|
31
30
|
"email" => "john@ruth.com",
|
32
|
-
"password" => "mypassword",
|
33
31
|
"timezone" => "cst",
|
34
32
|
"is_admin" => "false",
|
35
33
|
"telephone" => "444-4444"
|
36
34
|
)
|
37
35
|
user.should be_active
|
38
|
-
|
36
|
+
|
39
37
|
user = harvest.users.deactivate(user)
|
40
38
|
user.should_not be_active
|
41
|
-
|
39
|
+
|
42
40
|
user = harvest.users.activate(user)
|
43
41
|
user.should be_active
|
42
|
+
|
43
|
+
harvest.users.delete(user)
|
44
44
|
end
|
45
45
|
end
|
46
|
-
|
46
|
+
|
47
47
|
it "allows password resets" do
|
48
48
|
cassette("users3") do
|
49
|
+
pending "Something is wrong with resetting passwords"
|
49
50
|
user = harvest.users.create(
|
50
51
|
"first_name" => "Timmy",
|
51
52
|
"last_name" => "Ruth",
|
52
53
|
"email" => "timmy@ruth.com",
|
53
|
-
"password" => "mypassword",
|
54
54
|
"timezone" => "cst",
|
55
55
|
"is_admin" => "false",
|
56
56
|
"telephone" => "444-4444"
|
57
57
|
)
|
58
58
|
user.should be_active
|
59
|
-
|
59
|
+
|
60
60
|
harvest.users.reset_password(user) # nothing else to assert
|
61
|
+
harvest.users.delete(user)
|
61
62
|
end
|
62
63
|
end
|
63
|
-
|
64
|
+
|
64
65
|
context "assignments" do
|
65
66
|
it "allows adding, updating, and removing users from projects" do
|
66
67
|
cassette('users4') do
|
@@ -85,10 +86,10 @@ describe 'harvest users' do
|
|
85
86
|
"is_admin" => "false",
|
86
87
|
"telephone" => "444-4444"
|
87
88
|
)
|
88
|
-
|
89
|
+
|
89
90
|
|
90
91
|
assignment = harvest.user_assignments.create("project" => project, "user" => user)
|
91
|
-
|
92
|
+
|
92
93
|
assignment.hourly_rate = 100
|
93
94
|
assignment = harvest.user_assignments.update(assignment)
|
94
95
|
assignment.hourly_rate.should == "100.0"
|
@@ -99,4 +100,4 @@ describe 'harvest users' do
|
|
99
100
|
end
|
100
101
|
end
|
101
102
|
end
|
102
|
-
end
|
103
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -4,36 +4,28 @@ require 'vcr'
|
|
4
4
|
|
5
5
|
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require File.expand_path(f) }
|
6
6
|
|
7
|
-
VCR.
|
7
|
+
VCR.configure do |c|
|
8
8
|
c.cassette_library_dir = '.cassettes'
|
9
|
-
c.
|
9
|
+
c.hook_into :webmock
|
10
10
|
end
|
11
11
|
|
12
|
+
FileUtils.rm(Dir["#{VCR.configuration.cassette_library_dir}/*"]) if ENV['VCR_REFRESH'] == 'true'
|
13
|
+
|
12
14
|
RSpec.configure do |config|
|
13
15
|
config.include HarvestedHelpers
|
14
|
-
|
16
|
+
|
15
17
|
config.before(:suite) do
|
16
18
|
WebMock.allow_net_connect!
|
17
19
|
cassette("clean") do
|
18
20
|
HarvestedHelpers.clean_remote
|
19
21
|
end
|
20
22
|
end
|
21
|
-
|
23
|
+
|
22
24
|
config.before(:each) do
|
23
25
|
WebMock.allow_net_connect!
|
24
26
|
end
|
25
|
-
|
27
|
+
|
26
28
|
def cassette(*args)
|
27
|
-
if ENV['CACHE'] == "false"
|
28
|
-
if args.last.is_a?(Hash)
|
29
|
-
last = args.pop
|
30
|
-
last[:record] = :all
|
31
|
-
args << last
|
32
|
-
else
|
33
|
-
args << {:record => :all}
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
29
|
VCR.use_cassette(*args) do
|
38
30
|
yield
|
39
31
|
end
|
@@ -4,33 +4,33 @@ module HarvestedHelpers
|
|
4
4
|
@credentials ||= YAML.load_file("#{File.dirname(__FILE__)}/harvest_credentials.yml")
|
5
5
|
end
|
6
6
|
def credentials; HarvestedHelpers.credentials; end
|
7
|
-
|
7
|
+
|
8
8
|
def self.simple_harvest
|
9
9
|
Harvest.client(credentials["subdomain"], credentials["username"], credentials["password"], :ssl => true)
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
# def connect_to_harvest
|
13
13
|
# @harvest = Harvest.hardy_client(credentials["subdomain"], credentials["username"], credentials["password"], :ssl => true)
|
14
14
|
# end
|
15
|
-
|
15
|
+
|
16
16
|
# def harvest; @harvest; end
|
17
17
|
def harvest; @harvest ||= HarvestedHelpers.simple_harvest; end
|
18
|
-
|
18
|
+
|
19
19
|
def hardy_harvest
|
20
20
|
Harvest.hardy_client(credentials["subdomain"], credentials["username"], credentials["password"], :ssl => true)
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
def self.clean_remote
|
24
24
|
harvest = simple_harvest
|
25
25
|
harvest.users.all.each do |u|
|
26
|
-
harvest.reports.expenses_by_user(u, Time.utc(2000, 1, 1), Time.utc(
|
26
|
+
harvest.reports.expenses_by_user(u, Time.utc(2000, 1, 1), Time.utc(2013, 6,21)).each do |expense|
|
27
27
|
harvest.expenses.delete(expense, u)
|
28
28
|
end
|
29
|
-
|
30
|
-
harvest.reports.time_by_user(u, Time.utc(2000, 1, 1), Time.utc(
|
29
|
+
|
30
|
+
harvest.reports.time_by_user(u, Time.utc(2000, 1, 1), Time.utc(2013, 6,21)).each do |time|
|
31
31
|
harvest.time.delete(time, u)
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
34
|
harvest.users.delete(u) if u.email != credentials["username"]
|
35
35
|
end
|
36
36
|
|
@@ -41,4 +41,4 @@ module HarvestedHelpers
|
|
41
41
|
harvest.send(collection).all.each {|m| harvest.send(collection).delete(m) }
|
42
42
|
end
|
43
43
|
end
|
44
|
-
end
|
44
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: harvested
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-08-
|
12
|
+
date: 2012-08-23 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: httparty
|
@@ -76,23 +76,7 @@ dependencies:
|
|
76
76
|
- !ruby/object:Gem::Version
|
77
77
|
version: '2'
|
78
78
|
- !ruby/object:Gem::Dependency
|
79
|
-
name:
|
80
|
-
requirement: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
|
-
requirements:
|
83
|
-
- - ! '>='
|
84
|
-
- !ruby/object:Gem::Version
|
85
|
-
version: '0'
|
86
|
-
type: :development
|
87
|
-
prerelease: false
|
88
|
-
version_requirements: !ruby/object:Gem::Requirement
|
89
|
-
none: false
|
90
|
-
requirements:
|
91
|
-
- - ! '>='
|
92
|
-
- !ruby/object:Gem::Version
|
93
|
-
version: '0'
|
94
|
-
- !ruby/object:Gem::Dependency
|
95
|
-
name: ruby-debug19
|
79
|
+
name: jruby-openssl
|
96
80
|
requirement: !ruby/object:Gem::Requirement
|
97
81
|
none: false
|
98
82
|
requirements:
|
@@ -108,7 +92,7 @@ dependencies:
|
|
108
92
|
- !ruby/object:Gem::Version
|
109
93
|
version: '0'
|
110
94
|
- !ruby/object:Gem::Dependency
|
111
|
-
name:
|
95
|
+
name: webmock
|
112
96
|
requirement: !ruby/object:Gem::Requirement
|
113
97
|
none: false
|
114
98
|
requirements:
|
@@ -124,7 +108,7 @@ dependencies:
|
|
124
108
|
- !ruby/object:Gem::Version
|
125
109
|
version: '0'
|
126
110
|
- !ruby/object:Gem::Dependency
|
127
|
-
name:
|
111
|
+
name: vcr
|
128
112
|
requirement: !ruby/object:Gem::Requirement
|
129
113
|
none: false
|
130
114
|
requirements:
|
@@ -140,7 +124,7 @@ dependencies:
|
|
140
124
|
- !ruby/object:Gem::Version
|
141
125
|
version: '0'
|
142
126
|
- !ruby/object:Gem::Dependency
|
143
|
-
name:
|
127
|
+
name: jeweler
|
144
128
|
requirement: !ruby/object:Gem::Requirement
|
145
129
|
none: false
|
146
130
|
requirements:
|
@@ -156,7 +140,7 @@ dependencies:
|
|
156
140
|
- !ruby/object:Gem::Version
|
157
141
|
version: '0'
|
158
142
|
- !ruby/object:Gem::Dependency
|
159
|
-
name:
|
143
|
+
name: debugger
|
160
144
|
requirement: !ruby/object:Gem::Requirement
|
161
145
|
none: false
|
162
146
|
requirements:
|
@@ -277,7 +261,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
277
261
|
version: '0'
|
278
262
|
segments:
|
279
263
|
- 0
|
280
|
-
hash: -
|
264
|
+
hash: -3859920276334034236
|
281
265
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
282
266
|
none: false
|
283
267
|
requirements:
|