basecamp 0.0.9 → 0.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.rdoc +56 -0
- data/lib/basecamp.rb +1 -0
- data/lib/basecamp/active_resource.rb +23 -0
- data/lib/basecamp/base.rb +29 -7
- data/lib/basecamp/connection.rb +4 -2
- data/lib/basecamp/resources/time_entry.rb +1 -1
- data/lib/basecamp/resources/todo_item.rb +0 -2
- metadata +96 -125
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6a4aed33709e1c506d03f74ea93caa37b20e28f6
|
4
|
+
data.tar.gz: 724ac3904f5e834266ab001891f7bc270fe358f4
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 38d4ff046a943c7e16ca6852cd14ba098505b7ef5a7c1d6a1924433c98dc116b2d9811a398ee3e3b9106220e023251e1d10284864ccb06d82ebbab394440295e
|
7
|
+
data.tar.gz: c795d56445d90fadb6937d3f102ecae247fa4dc0e841f94515070fd64f6ed47d002c027ccd9512a204ae944c4afcf63b0e74e90545234b947f69c162ba8497ea
|
data/README.rdoc
CHANGED
@@ -43,10 +43,16 @@ requires your Basecamp site address and your login credentials or API token.
|
|
43
43
|
|
44
44
|
Basecamp.establish_connection!('yoururl.basecamphq.com', 'APITOKEN', 'X')
|
45
45
|
|
46
|
+
=== Using OAuth access token
|
47
|
+
|
48
|
+
Basecamp.establish_oauth_connection!('yoururl.basecamphq.com', 'oauth_access_token')
|
49
|
+
|
46
50
|
=== With a Basecamp account that use SSL (https://yoururl.basecamphq.com)
|
47
51
|
|
48
52
|
Basecamp.establish_connection!('yoururl.basecamphq.com', 'APITOKEN', 'X', true)
|
49
53
|
|
54
|
+
Basecamp.establish_oauth_connection!('yoururl.basecamphq.com', 'oauth_access_token', true)
|
55
|
+
|
50
56
|
This is the same whether you're accessing using the ActiveResource interface,
|
51
57
|
or the legacy interface.
|
52
58
|
|
@@ -59,6 +65,22 @@ information on working with ActiveResource, see:
|
|
59
65
|
* http://api.rubyonrails.org/files/activeresource/README.html
|
60
66
|
* http://api.rubyonrails.org/classes/ActiveResource/Base.html
|
61
67
|
|
68
|
+
== Basecamp API rate limit and app identification
|
69
|
+
|
70
|
+
If your app creates a lot of requests, you may hit the (new) basecamp rate limit. ({read more here about rate limiting}[https://github.com/basecamp/basecamp-classic-api#rate-limiting]).
|
71
|
+
|
72
|
+
To raise your limit you can send a custom user-agent to basecamp with your identifying information ({read more here}[https://github.com/basecamp/basecamp-classic-api#rate-limiting]).
|
73
|
+
|
74
|
+
For this you need to create an initializer in your rails application, for example: +config/inititalizer/basecamp_user_agent.rb+ with the following line:
|
75
|
+
|
76
|
+
ActiveResource::Base.headers["User-Agent"] = "Fabian's Ingenious Integration (fabian@example.com)"
|
77
|
+
|
78
|
+
This initializer ensures that all requests made through ActiveResource (which this gem uses) are identifiable with your information.
|
79
|
+
|
80
|
+
**NOTE**: If you are using ActiveResource for accessing multiple APIs at once and not only basecamp's, you will need the following initializer instead:
|
81
|
+
|
82
|
+
Basecamp::Resource.headers["User-Agent"] = "Fabian's Ingenious Integration (fabian@example.com)"
|
83
|
+
|
62
84
|
=== Finding a Resource
|
63
85
|
|
64
86
|
Find a specific resource using the +find+ method. Attributes of the resource
|
@@ -196,6 +218,40 @@ By default the wrapper will use :xml for the active record connection but you ca
|
|
196
218
|
|
197
219
|
Note: We recommend using xml. There are some API calls that don't behave well with json.
|
198
220
|
|
221
|
+
= Access active resource response object
|
222
|
+
|
223
|
+
You can acces the last response object:
|
224
|
+
|
225
|
+
Basecamp::Message.find(:all, params => { :project_id => 1037 })
|
226
|
+
Basecamp::Message.connection.response["status"] # => "200 OK"
|
227
|
+
|
228
|
+
= Using the raw response body
|
229
|
+
|
230
|
+
This is useful for example to get pagination data to access all comments in a commentable resource: https://github.com/37signals/basecamp-classic-api/blob/master/sections/comments.md#get-recent-comments-for-a-commentable-resource
|
231
|
+
|
232
|
+
def get_threshold
|
233
|
+
# Get the last response object
|
234
|
+
response = Basecamp::Comment.connection.response
|
235
|
+
# Parse the xml
|
236
|
+
xml = XmlSimple.xml_in(response.body)
|
237
|
+
# continued-at is an attribute specifying the path where the next oldest 75 comments can be retrieved
|
238
|
+
if continued_at = xml["continued-at"]
|
239
|
+
# There are more comments
|
240
|
+
# We need to extract the threshold parameter from the continued-at url
|
241
|
+
hash = CGI::parse(URI.parse(continued_at).query)
|
242
|
+
hash["threshold"].first
|
243
|
+
else
|
244
|
+
# We're done
|
245
|
+
nil
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
comments = Basecamp::Comment.find(:all, :params => { :post_id => 1037 })
|
250
|
+
if threshold = get_threshold
|
251
|
+
# Get the next set of comments using the threshold
|
252
|
+
Basecamp::Comment.find(:all, :params => { :post_id => 1037, :threshold => threshold })
|
253
|
+
end
|
254
|
+
|
199
255
|
== Contributors
|
200
256
|
|
201
257
|
* jamesarosen
|
data/lib/basecamp.rb
CHANGED
@@ -0,0 +1,23 @@
|
|
1
|
+
# ActiveResource connection patch to let users access the last response object and the headers.
|
2
|
+
#
|
3
|
+
# Example:
|
4
|
+
# >> Basecamp::Message.find(:all, params => { :project_id => 1037 })
|
5
|
+
# >> Basecamp::Message.connection.response["status"]
|
6
|
+
# => "200 OK"
|
7
|
+
class ActiveResource::Connection
|
8
|
+
alias_method :original_handle_response, :handle_response
|
9
|
+
alias :static_default_header :default_header
|
10
|
+
|
11
|
+
def handle_response(response)
|
12
|
+
Thread.current[:active_resource_connection_headers] = response
|
13
|
+
original_handle_response(response)
|
14
|
+
end
|
15
|
+
|
16
|
+
def response
|
17
|
+
Thread.current[:active_resource_connection_headers]
|
18
|
+
end
|
19
|
+
|
20
|
+
def set_header(key, value)
|
21
|
+
default_header.update(key => value)
|
22
|
+
end
|
23
|
+
end
|
data/lib/basecamp/base.rb
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
module Basecamp
|
2
2
|
class << self
|
3
3
|
attr_accessor :use_xml
|
4
|
-
attr_reader :site, :user, :password, :use_ssl
|
4
|
+
attr_reader :site, :user, :password, :use_ssl, :use_oauth, :access_token
|
5
5
|
|
6
6
|
def establish_connection!(site, user, password, use_ssl = false, use_xml = true)
|
7
|
-
@site
|
8
|
-
@user
|
9
|
-
@password
|
10
|
-
@use_ssl
|
11
|
-
@use_xml
|
7
|
+
@site = site
|
8
|
+
@user = user
|
9
|
+
@password = password
|
10
|
+
@use_ssl = use_ssl
|
11
|
+
@use_xml = use_xml
|
12
|
+
@use_oauth = false
|
12
13
|
|
13
14
|
Resource.user = user
|
14
15
|
Resource.password = password
|
@@ -18,6 +19,20 @@ module Basecamp
|
|
18
19
|
@connection = Connection.new(self)
|
19
20
|
end
|
20
21
|
|
22
|
+
def establish_oauth_connection!(site, access_token, use_ssl = false, use_xml = true)
|
23
|
+
@site = site
|
24
|
+
@use_ssl = use_ssl
|
25
|
+
@use_xml = use_xml
|
26
|
+
@use_oauth = true
|
27
|
+
@access_token = access_token
|
28
|
+
|
29
|
+
Resource.site = (use_ssl ? "https" : "http") + "://" + site
|
30
|
+
Resource.format = (use_xml ? :xml : :json)
|
31
|
+
Resource.connection.set_header('Authorization', "Bearer #{access_token}")
|
32
|
+
|
33
|
+
@connection = Connection.new(self)
|
34
|
+
end
|
35
|
+
|
21
36
|
def connection
|
22
37
|
@connection || raise('No connection established')
|
23
38
|
end
|
@@ -25,9 +40,16 @@ module Basecamp
|
|
25
40
|
# Make a raw web-service request to Basecamp. This will return a Hash of
|
26
41
|
# Arrays of the response, and may seem a little odd to the uninitiated.
|
27
42
|
def request(path, parameters = {})
|
28
|
-
|
43
|
+
headers = { "Content-Type" => content_type }
|
44
|
+
headers.merge!('Authorization' => "Bearer #{@access_token}") if @use_oauth
|
45
|
+
if parameters.empty?
|
46
|
+
response = Basecamp.connection.get(path, headers)
|
47
|
+
else
|
48
|
+
response = Basecamp.connection.post(path, StringIO.new(convert_body(parameters)), headers)
|
49
|
+
end
|
29
50
|
|
30
51
|
if response.code.to_i / 100 == 2
|
52
|
+
return {} if response.body.blank?
|
31
53
|
result = XmlSimple.xml_in(response.body, 'keeproot' => true, 'contentkey' => '__content__', 'forcecontent' => true)
|
32
54
|
typecast_value(result)
|
33
55
|
else
|
data/lib/basecamp/connection.rb
CHANGED
@@ -8,7 +8,8 @@ module Basecamp; class Connection
|
|
8
8
|
|
9
9
|
def post(path, iostream, headers = {})
|
10
10
|
request = Net::HTTP::Post.new(path, headers.merge('Accept' => 'application/xml'))
|
11
|
-
request.basic_auth(@master.user, @master.password)
|
11
|
+
request.basic_auth(@master.user, @master.password) unless @master.use_oauth
|
12
|
+
request.initialize_http_header(@master.class.headers)
|
12
13
|
request.body_stream = iostream
|
13
14
|
request.content_length = iostream.size
|
14
15
|
@connection.request(request)
|
@@ -16,7 +17,8 @@ module Basecamp; class Connection
|
|
16
17
|
|
17
18
|
def get(path, headers = {})
|
18
19
|
request = Net::HTTP::Get.new(path, headers.merge('Accept' => 'application/xml'))
|
19
|
-
request.
|
20
|
+
request.initialize_http_header(@master.class.headers)
|
21
|
+
request.basic_auth(@master.user, @master.password) unless @master.use_oauth
|
20
22
|
@connection.request(request)
|
21
23
|
end
|
22
24
|
end; end
|
metadata
CHANGED
@@ -1,139 +1,123 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: basecamp
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 0
|
9
|
-
- 9
|
10
|
-
version: 0.0.9
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.10
|
11
5
|
platform: ruby
|
12
|
-
authors:
|
6
|
+
authors:
|
13
7
|
- Anibal Cucco
|
14
8
|
- James A. Rosen
|
15
9
|
autorequire:
|
16
10
|
bindir: bin
|
17
11
|
cert_chain: []
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
dependencies:
|
22
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2014-11-03 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
23
15
|
name: oauth2
|
24
|
-
|
25
|
-
|
26
|
-
none: false
|
27
|
-
requirements:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
28
18
|
- - ">="
|
29
|
-
- !ruby/object:Gem::Version
|
30
|
-
|
31
|
-
segments:
|
32
|
-
- 0
|
33
|
-
version: "0"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '0'
|
34
21
|
type: :runtime
|
35
|
-
version_requirements: *id001
|
36
|
-
- !ruby/object:Gem::Dependency
|
37
|
-
name: xml-simple
|
38
22
|
prerelease: false
|
39
|
-
|
40
|
-
|
41
|
-
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '0'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: xml-simple
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
42
32
|
- - ">="
|
43
|
-
- !ruby/object:Gem::Version
|
44
|
-
|
45
|
-
segments:
|
46
|
-
- 0
|
47
|
-
version: "0"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
48
35
|
type: :runtime
|
49
|
-
version_requirements: *id002
|
50
|
-
- !ruby/object:Gem::Dependency
|
51
|
-
name: activeresource
|
52
36
|
prerelease: false
|
53
|
-
|
54
|
-
|
55
|
-
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: activeresource
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
56
46
|
- - ">="
|
57
|
-
- !ruby/object:Gem::Version
|
58
|
-
hash: 3
|
59
|
-
segments:
|
60
|
-
- 2
|
61
|
-
- 3
|
62
|
-
- 0
|
47
|
+
- !ruby/object:Gem::Version
|
63
48
|
version: 2.3.0
|
64
49
|
type: :runtime
|
65
|
-
version_requirements: *id003
|
66
|
-
- !ruby/object:Gem::Dependency
|
67
|
-
name: rake
|
68
50
|
prerelease: false
|
69
|
-
|
70
|
-
|
71
|
-
requirements:
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
72
53
|
- - ">="
|
73
|
-
- !ruby/object:Gem::Version
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: 2.3.0
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: rake
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
78
63
|
type: :development
|
79
|
-
version_requirements: *id004
|
80
|
-
- !ruby/object:Gem::Dependency
|
81
|
-
name: mg
|
82
64
|
prerelease: false
|
83
|
-
|
84
|
-
|
85
|
-
requirements:
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
86
67
|
- - ">="
|
87
|
-
- !ruby/object:Gem::Version
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: mg
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
93
76
|
version: 0.0.8
|
94
77
|
type: :development
|
95
|
-
version_requirements: *id005
|
96
|
-
- !ruby/object:Gem::Dependency
|
97
|
-
name: rspec
|
98
78
|
prerelease: false
|
99
|
-
|
100
|
-
|
101
|
-
requirements:
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
102
81
|
- - ">="
|
103
|
-
- !ruby/object:Gem::Version
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: 0.0.8
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: rspec
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
109
90
|
version: 1.3.0
|
110
91
|
type: :development
|
111
|
-
version_requirements: *id006
|
112
|
-
- !ruby/object:Gem::Dependency
|
113
|
-
name: webmock
|
114
92
|
prerelease: false
|
115
|
-
|
116
|
-
|
117
|
-
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: 1.3.0
|
98
|
+
- !ruby/object:Gem::Dependency
|
99
|
+
name: webmock
|
100
|
+
requirement: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
118
102
|
- - ">="
|
119
|
-
- !ruby/object:Gem::Version
|
120
|
-
hash: 27
|
121
|
-
segments:
|
122
|
-
- 1
|
123
|
-
- 2
|
124
|
-
- 2
|
103
|
+
- !ruby/object:Gem::Version
|
125
104
|
version: 1.2.2
|
126
105
|
type: :development
|
127
|
-
|
106
|
+
prerelease: false
|
107
|
+
version_requirements: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - ">="
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: 1.2.2
|
128
112
|
description: Basecamp API wrapper.
|
129
113
|
email: nobody@gmail.com
|
130
114
|
executables: []
|
131
|
-
|
132
115
|
extensions: []
|
133
|
-
|
134
116
|
extra_rdoc_files: []
|
135
|
-
|
136
|
-
|
117
|
+
files:
|
118
|
+
- README.rdoc
|
119
|
+
- lib/basecamp.rb
|
120
|
+
- lib/basecamp/active_resource.rb
|
137
121
|
- lib/basecamp/base.rb
|
138
122
|
- lib/basecamp/connection.rb
|
139
123
|
- lib/basecamp/hash.rb
|
@@ -151,41 +135,28 @@ files:
|
|
151
135
|
- lib/basecamp/resources/todo_item.rb
|
152
136
|
- lib/basecamp/resources/todo_list.rb
|
153
137
|
- lib/basecamp/symbol.rb
|
154
|
-
- lib/basecamp.rb
|
155
|
-
- README.rdoc
|
156
|
-
has_rdoc: true
|
157
138
|
homepage: http://github.com/anibalcucco/basecamp-wrapper
|
158
139
|
licenses: []
|
159
|
-
|
140
|
+
metadata: {}
|
160
141
|
post_install_message:
|
161
142
|
rdoc_options: []
|
162
|
-
|
163
|
-
require_paths:
|
143
|
+
require_paths:
|
164
144
|
- lib
|
165
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
166
|
-
|
167
|
-
requirements:
|
145
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
146
|
+
requirements:
|
168
147
|
- - ">="
|
169
|
-
- !ruby/object:Gem::Version
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
version: "0"
|
174
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
175
|
-
none: false
|
176
|
-
requirements:
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '0'
|
150
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
151
|
+
requirements:
|
177
152
|
- - ">="
|
178
|
-
- !ruby/object:Gem::Version
|
179
|
-
|
180
|
-
segments:
|
181
|
-
- 0
|
182
|
-
version: "0"
|
153
|
+
- !ruby/object:Gem::Version
|
154
|
+
version: '0'
|
183
155
|
requirements: []
|
184
|
-
|
185
156
|
rubyforge_project:
|
186
|
-
rubygems_version:
|
157
|
+
rubygems_version: 2.4.2
|
187
158
|
signing_key:
|
188
|
-
specification_version:
|
159
|
+
specification_version: 4
|
189
160
|
summary: Basecamp API wrapper.
|
190
161
|
test_files: []
|
191
|
-
|
162
|
+
has_rdoc:
|