github_api 0.3.9 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md ADDED
@@ -0,0 +1,331 @@
1
+ # GithubAPI
2
+ [![Build Status](https://secure.travis-ci.org/peter-murach/github.png?branch=master)][travis] [![Dependency Status](https://gemnasium.com/peter-murach/github.png?travis)][gemnasium]
3
+
4
+ [travis]: http://travis-ci.org/peter-murach/github
5
+ [gemnasium]: https://gemnasium.com/peter-murach/github
6
+
7
+ [Wiki](https://github.com/peter-murach/github/wiki) | [RDocs](http://rubydoc.info/github/peter-murach/github/master/frames)
8
+
9
+ A Ruby wrapper for the GitHub REST API v3.
10
+
11
+ Supports all the API methods(nearly 200). It's build in a modular way, that is, you can either instantiate the whole api wrapper Github.new or use parts of it e.i. Github::Repos.new if working solely with repositories is your main concern.
12
+
13
+ ## Installation
14
+
15
+ Install the gem by issuing
16
+
17
+ ```ruby
18
+ gem install github_api
19
+ ```
20
+
21
+ or put it in your Gemfile and run `bundle install`</tt>
22
+
23
+ ```ruby
24
+ gem "github_api"
25
+ ```
26
+
27
+ ## Usage
28
+
29
+ Create a new client instance
30
+
31
+ ```ruby
32
+ @github = Github.new
33
+ ```
34
+
35
+ At this stage you can also supply various configuration parameters, such as `:user`,`:repo`, `:org`, `:oauth_token`, `:login`, `:password` or `:basic_auth` which are used throughout the API
36
+
37
+ ```ruby
38
+ @github = Github.new :user => 'peter-murach', :repo => 'github-api'
39
+ ```
40
+
41
+ or
42
+
43
+ ```ruby
44
+ @github = Github.new do |opts|
45
+ opts.user = 'peter-murach'
46
+ opts.repo = 'github-api'
47
+ end
48
+ ```
49
+
50
+ You can authenticate either using OAuth authentication convenience methods(see section OAuth) or through basic authentication by passing your login and password credentials
51
+
52
+ ```ruby
53
+ @github = Github.new :login => 'peter-murach', :password => '...'
54
+ ```
55
+
56
+ or use convenience method:
57
+
58
+ ```ruby
59
+ @github = Github.new :basic_auth => 'login:password'
60
+ ```
61
+
62
+ You can interact with GitHub interface, for example repositories, by issueing following calls
63
+ ```ruby
64
+ @github.repos.commits
65
+ @github.repos.branches
66
+ @github.repos.contributors
67
+ ```
68
+ The code base is modular and allows for you to work specifically with a given part of GitHub API e.g. repositories
69
+
70
+ ```ruby
71
+ @repos = Github::Repos.new
72
+ @repos.branches 'peter-murach', 'github'
73
+
74
+ or
75
+
76
+ @repos = Github::Repos.new :user => 'peter-murach', :repo => 'github'
77
+ @repos.branches
78
+ ```
79
+
80
+ The response is of type [Hashie::Mash] and allows to traverse all the json response attributes like method calls e.i.
81
+
82
+ ```ruby
83
+ @repos = Github::Repos.new :user => 'peter-murach', :repo => 'github'
84
+ @repos.branches do |branch|
85
+ puts branch.name
86
+ end
87
+ ```
88
+
89
+ ## API
90
+
91
+ Main API methods are grouped into the following classes that can be instantiated on their own
92
+
93
+ ```ruby
94
+ Github - full API access
95
+ Github::Gists
96
+ Github::GitData
97
+ Github::Issues
98
+ Github::Orgs
99
+ Github::PullRequests
100
+ Github::Repos
101
+ Github::Users
102
+ Github::Events
103
+ Github::Authorizations
104
+ ```
105
+
106
+ Some parts of GitHub API v3 require you to be autheticated, for instance the following are examples of APIs only for the authenticated user
107
+
108
+ ```ruby
109
+ Github::Users::Emails
110
+ Github::Users::Keys
111
+ ```
112
+
113
+ All method calls form ruby like sentences and allow for intuitive api navigation, for instance
114
+
115
+ ```ruby
116
+ @github = Github.new :oauth_token => '...'
117
+ @github.users.following 'wycats' # => returns users that 'wycats' is following
118
+ @github.users.following 'wycats' # => returns true if following, otherwise false
119
+ ```
120
+
121
+ For specification on all available methods go to http://developer.github.com/v3/ or
122
+ read the rdoc, all methods are documented there with examples of usage.
123
+
124
+ ## Inputs
125
+
126
+ Some API methods apart from required parameters such as username, repository name
127
+ or organisation name, allow you to switch the way the data is returned to you, for instance
128
+
129
+ ```ruby
130
+ @github = Github.new
131
+ @github.git_data.tree 'peter-murach', 'github', 'c18647b75d72f19c1e0cc8af031e5d833b7f12ea' # => gets a tree
132
+
133
+ @github.git_data.tree 'peter-murach', 'github', 'c18647b75d72f19c1e0cc8af031e5d833b7f12ea', :recursive => true # => gets a whole tree recursively
134
+
135
+ by passing a block you can iterate over the file tree
136
+
137
+ @github.git_data.tree 'peter-murach', 'github', 'c18647b75d72f19c1e0cc8af031e5d833b7f12ea', :recursive => true do |file|
138
+ puts file.path
139
+ end
140
+ ```
141
+
142
+ ## OAuth
143
+
144
+ In order to authenticate the user through OAuth2 on GitHub you need to
145
+
146
+ * visit https://github.com/account/applications/ and register your app
147
+
148
+ * authorize your credentials https://github.com/login/oauth/authorize
149
+ You can use convenience methods to help you achieve this that come with this gem:
150
+
151
+ ```ruby
152
+ @github = Github.new :client_id => '...', :client_secret => '...'
153
+ @github.authorize_url :redirect_uri => 'http://localhost', :scope => 'repo'
154
+ # => "https://github.com/login/oauth/authorize?scope=repo&response_type=code&client_id='...'&redirect_uri=http%3A%2F%2Flocalhost"
155
+ ```
156
+ After you get your authorization code, call to receive your access_token
157
+
158
+ ```ruby
159
+ token = github.get_token( authorization_code )
160
+ ```
161
+
162
+ Once you have your access token, configure your github instance following instructions under Configuration.
163
+
164
+ Alternatively you can use OAuth Authorizations API. For instance, to create access token through GitHub API do following
165
+
166
+ ```ruby
167
+ @github = Github.new :basic_auth => 'login:password'
168
+ @github.oauth.create_authorization 'scopes' => ['repo']
169
+ ```
170
+
171
+ You can add more than one scope from the <tt>user</tt>, <tt>public_repo</tt>, <tt>repo</tt>, <tt>gist</tt> or leave the scopes parameter out, in which case, the default read-only access will be assumed(includes public user profile info, public repo info, and gists).
172
+
173
+ ## MIME Types
174
+
175
+ Issues, PullRequests and few other API leverage custom mime types which are <tt>:json</tt>, <tt>:blob</tt>, <tt>:raw</tt>, <tt>:text</tt>, <tt>:html</tt>, <tt>:full</tt>. By default <tt>:raw</tt> is used.
176
+
177
+ In order to pass a mime type with your request do
178
+
179
+ ```ruby
180
+ @github = Github.new
181
+ @github.pull_requests.pull_requests 'peter-murach', 'github', :mime_type => :full
182
+ ```
183
+
184
+ Your header will contain 'Accept: "application/vnd.github-pull.full+json"' which in turn returns raw, text and html representations in response body.
185
+
186
+ ## Configuration
187
+
188
+ Certain methods require authentication. To get your GitHub OAuth v2 credentials,
189
+ register an app at https://github.com/account/applications/
190
+
191
+ ```ruby
192
+ Github.configure do |config|
193
+ config.oauth_token = YOUR_OAUTH_ACCESS_TOKEN
194
+ config.basic_auth = 'login:password'
195
+ end
196
+
197
+ or
198
+
199
+ Github.new(:oauth_token => YOUR_OAUTH_TOKEN)
200
+ Github.new(:basic_auth => 'login:password)
201
+ ```
202
+
203
+ All parameters can be overwirtten as per method call. By passing parameters hash...
204
+
205
+ ## Caching
206
+
207
+ Each `get` request by default is not going to be cached. In order to set the cache do... If no cache type is provided a default memoization is done.
208
+
209
+ Github.cache do...
210
+
211
+ ## Pagination
212
+
213
+ Any request that returns multiple items will be paginated to 30 items by default. You can specify custom <tt>:page</tt> and <tt>:per_page</tt> query parameters to alter default behavior. For instance:
214
+
215
+ ```ruby
216
+ res = Github::Repos.new.repos :user => 'wycats', :per_page => 10
217
+ ```
218
+
219
+ Then you can query pagination information included in the link header by:
220
+
221
+ ```ruby
222
+ res.links.first # Shows the URL of the first page of results.
223
+ res.links.next # Shows the URL of the immediate next page of results.
224
+ res.links.prev # Shows the URL of the immediate previous page of results.
225
+ res.links.last # Shows the URL of the last page of results.
226
+ ```
227
+
228
+ In order to iterate through the entire result set page by page, you can use convenience methods:
229
+
230
+ ```ruby
231
+ res.each_page do |page_set|
232
+ page_set.each do |repo|
233
+ puts repo.name
234
+ end
235
+ end
236
+ ```
237
+
238
+ or use `has_next_page?` and `next_page` like in the following:
239
+
240
+ ```ruby
241
+ while res.has_next_page?
242
+ ... process response ...
243
+ res.next_page
244
+ end
245
+ ```
246
+
247
+ One can also navigate straight to specific page by:
248
+
249
+ ```ruby
250
+ res.page 5 # Requests given page if it exists, nil otherwise
251
+ res.first_page
252
+ res.prev_page
253
+ res.last_page
254
+ ```
255
+
256
+ ## Response Message
257
+
258
+ Each response comes packaged with methods allowing for inspection of HTTP start line and headers. For example to check for rate limits and status code issue
259
+
260
+ ```ruby
261
+ res = Github::Repos.new.branches 'peter-murach', 'github'
262
+ res.ratelimit_limit # "5000"
263
+ res.ratelimit_remainig # "4999"
264
+ res.status # "200"
265
+ ```
266
+
267
+ ## Examples
268
+
269
+ Some api methods require input parameters, these are added simply as a hash properties, for instance
270
+
271
+ ```ruby
272
+ @issues = Github::Issues.new :user => 'peter-murach', :repo => 'github-api'
273
+ @issues.milestones :state => 'open', :sort => 'due_date', :direction => 'asc'
274
+ ```
275
+
276
+ Other methods may require inputs as an array of strings
277
+
278
+ ```ruby
279
+ @users = Github::Users.new :oauth_token => '...'
280
+ @users.add_email 'email1', 'email2', ..., 'emailn' # => Adds emails to the authenticated user
281
+ ```
282
+
283
+ If a method returns a collection, you can iterator over it by supplying a block parameter,
284
+
285
+ ```ruby
286
+ @issues = Github::Issues.new :user => 'peter-murach', :repo => 'github-api'
287
+ @issues.events do |event|
288
+ puts event.actor.login
289
+ end
290
+ ```
291
+
292
+ Query requests instead of http responses return boolean values
293
+
294
+ ```ruby
295
+ @github = Github.new
296
+ @github.orgs.public_member? 'github', 'technoweenie' # => true
297
+ ```
298
+
299
+ ## Rails Example
300
+
301
+ A Rails controller that allows a user to authorize their GitHub account and then perform request.
302
+
303
+ ```ruby
304
+ class GithubController < ApplicationController
305
+
306
+ def authorize
307
+ github = Github.new :client_id => '...', :client_secret => '...'
308
+ address = github.authorize_url :redirect_uri => 'http://...', :scope => 'repo'
309
+ redirect_to address
310
+ end
311
+
312
+ def callback
313
+ authorization_code = params[:code]
314
+ token = github.get_token authorization_code
315
+ access_token = token.token
316
+ end
317
+ end
318
+ ```
319
+
320
+ ## TODO
321
+
322
+ * Add request caching - local filestore?, http caching?.
323
+ * Add live api tests
324
+
325
+ ## Development
326
+
327
+ Questions or problems? Please post them on the [issue tracker](https://github.com/peter-murach/github/issues). You can contribute changes by forking the project and submitting a pull request. You can ensure the tests are passing by running `bundle` and `rake`.
328
+
329
+ ## Copyright
330
+
331
+ Copyright (c) 2011-2012 Piotr Murach. See LICENSE.txt for further details.
@@ -0,0 +1,26 @@
1
+ = GithubAPI
2
+
3
+ == Running the specs and features
4
+
5
+ To run the specs first run the +bundle+ command to install the necessary gems and then +rake+ command to run the specs.
6
+
7
+ bundle
8
+ rake
9
+
10
+ The specs currently require Ruby 1.9.x.
11
+
12
+ In order to run only features
13
+
14
+ rake features
15
+
16
+ == Coverage
17
+
18
+ GithubAPI will run coverage only on demand and to run it do
19
+
20
+ COVERAGE=true rake
21
+
22
+ == Automation
23
+
24
+ You can also run specs and features when you do file modifications by typing
25
+
26
+ COVERAGE=true guard
@@ -0,0 +1,79 @@
1
+ ---
2
+ - !ruby/struct:VCR::HTTPInteraction
3
+ request: !ruby/struct:VCR::Request
4
+ method: :get
5
+ uri: https://api.github.com:443/repos/'peter-murach'/'github'/branches
6
+ body:
7
+ headers:
8
+ accept-encoding:
9
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
10
+ response: !ruby/struct:VCR::Response
11
+ status: !ruby/struct:VCR::ResponseStatus
12
+ code: 404
13
+ message: Not Found
14
+ headers:
15
+ server:
16
+ - nginx/1.0.4
17
+ date:
18
+ - Tue, 03 Jan 2012 16:08:04 GMT
19
+ content-type:
20
+ - application/json; charset=utf-8
21
+ transfer-encoding:
22
+ - chunked
23
+ connection:
24
+ - keep-alive
25
+ status:
26
+ - 404 Not Found
27
+ x-ratelimit-limit:
28
+ - "5000"
29
+ etag:
30
+ - "\"e66a7a6c91e2c26803f3f49feb7a883f\""
31
+ x-ratelimit-remaining:
32
+ - "4999"
33
+ content-encoding:
34
+ - gzip
35
+ body: !binary |
36
+ H4sIAAAAAAAAA6tWyk0tLk5MT1WyUvLLL1Fwyy/NS1GqBQB8+Ys1FwAAAA==
37
+
38
+ http_version: "1.1"
39
+ - !ruby/struct:VCR::HTTPInteraction
40
+ request: !ruby/struct:VCR::Request
41
+ method: :get
42
+ uri: https://api.github.com:443/repos/peter-murach/github/branches
43
+ body:
44
+ headers:
45
+ accept-encoding:
46
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
47
+ response: !ruby/struct:VCR::Response
48
+ status: !ruby/struct:VCR::ResponseStatus
49
+ code: 200
50
+ message: OK
51
+ headers:
52
+ server:
53
+ - nginx/1.0.4
54
+ date:
55
+ - Tue, 03 Jan 2012 16:08:44 GMT
56
+ content-type:
57
+ - application/json; charset=utf-8
58
+ transfer-encoding:
59
+ - chunked
60
+ connection:
61
+ - keep-alive
62
+ status:
63
+ - 200 OK
64
+ x-ratelimit-limit:
65
+ - "5000"
66
+ etag:
67
+ - "\"e411402de4b873fc7b44e19852543a26\""
68
+ x-ratelimit-remaining:
69
+ - "4998"
70
+ content-encoding:
71
+ - gzip
72
+ body: !binary |
73
+ H4sIAAAAAAAAA62OQQ6DIBRE78LaCigCepWmi88HiklpjeDKcPeSmrRbF13P
74
+ vJl33ckToiMTiZCyW0lD8BXjnMm0k2191CDkvKSJUljm9j7nsJm2Vujqllei
75
+ i6vQJW4rYKBHSo+BRLnjZhysFBqF7BQKkMbzDtFooRnrtDW9t0rWzxSgPp0G
76
+ Smm+3h+Pv2oP2BmUWjM0DLkbRsm9UhyEAwT0QlnojfI/7bNAKbc3V8RUs3AB
77
+ AAA=
78
+
79
+ http_version: "1.1"
@@ -0,0 +1,167 @@
1
+ ---
2
+ - !ruby/struct:VCR::HTTPInteraction
3
+ request: !ruby/struct:VCR::Request
4
+ method: :get
5
+ uri: https://api.github.com:443/repos/peter-murach/github/teams
6
+ body:
7
+ headers:
8
+ accept-encoding:
9
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
10
+ response: !ruby/struct:VCR::Response
11
+ status: !ruby/struct:VCR::ResponseStatus
12
+ code: 404
13
+ message: Not Found
14
+ headers:
15
+ server:
16
+ - nginx/1.0.4
17
+ date:
18
+ - Tue, 03 Jan 2012 16:21:26 GMT
19
+ content-type:
20
+ - application/json; charset=utf-8
21
+ transfer-encoding:
22
+ - chunked
23
+ connection:
24
+ - keep-alive
25
+ status:
26
+ - 404 Not Found
27
+ x-ratelimit-limit:
28
+ - "5000"
29
+ etag:
30
+ - "\"e66a7a6c91e2c26803f3f49feb7a883f\""
31
+ x-ratelimit-remaining:
32
+ - "4987"
33
+ content-encoding:
34
+ - gzip
35
+ body: !binary |
36
+ H4sIAAAAAAAAA6tWyk0tLk5MT1WyUvLLL1Fwyy/NS1GqBQB8+Ys1FwAAAA==
37
+
38
+ http_version: "1.1"
39
+ - !ruby/struct:VCR::HTTPInteraction
40
+ request: !ruby/struct:VCR::Request
41
+ method: :get
42
+ uri: https://api.github.com:443/repos/peter-murach/github/tags
43
+ body:
44
+ headers:
45
+ accept-encoding:
46
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
47
+ response: !ruby/struct:VCR::Response
48
+ status: !ruby/struct:VCR::ResponseStatus
49
+ code: 200
50
+ message: OK
51
+ headers:
52
+ server:
53
+ - nginx/1.0.4
54
+ date:
55
+ - Tue, 03 Jan 2012 16:21:40 GMT
56
+ content-type:
57
+ - application/json; charset=utf-8
58
+ transfer-encoding:
59
+ - chunked
60
+ connection:
61
+ - keep-alive
62
+ status:
63
+ - 200 OK
64
+ x-ratelimit-limit:
65
+ - "5000"
66
+ etag:
67
+ - "\"6fce6d04509cf0003c528b9c75d705b1\""
68
+ x-ratelimit-remaining:
69
+ - "4986"
70
+ content-encoding:
71
+ - gzip
72
+ body: !binary |
73
+ H4sIAAAAAAAAA63WwW7bMAwG4HfxuUskUSKlvMowDCQlLgGaNUjSHVb03Sej
74
+ QdYaO3iorkF+mv5Aif76Mv0+nIQfH78/nx+n3bS/Xk+X3Xb743DdP8tGn47b
75
+ U7u285fj85l1f/t9ewttf7kNbPL0MF35/P9VbqG/VfrjjofrtHuZPnbDp8Pm
76
+ XUfndnq6/LOvtwKXrSVwDiqJcYGUiV0qrpbAxkyKQq1pSqi988ue+3uvDrw+
77
+ TD/52Hrk9u6vDyMMyxDDucoww5QlO+8qgoYWqXKsqlIzWw7RIIQGouLsbrg6
78
+ sDAs0xhDP8RwrjLMsIBgLJ4YPVSJiT2rz0ktYHbMztVcKtb5BL3N4erAwtAP
79
+ MgxDDOcqwwybEVJuIVg2ACFALuQZSsotK/XTDQSF6G64OrAwDIMMYYjhXGWY
80
+ oWoH1MYRinhonIyEog+OY67SEgnX/ge+G64OLAxhkGEcYjhXGWaIGtFLKhHZ
81
+ ecU+kDma8+bFCfqgmLWhuvn+eDvLqwMLwzjIMA0xnKsMM6QWUFoMEtkpasoF
82
+ nMcY2CepoWFS6Rsn4t1wdWBhmAYZzp18/ttmrjLMENVaAmvYF3BOSZKlWlIR
83
+ MDKoSLFS9Y3ruzlcGVgY4hDDEVt56E5OVLN4M2CfizNo0i9Bctx3iy8WPVgs
84
+ tbDc/VYHPviN2sjzXvv8BM5Vhk1gIsgVTRS9ldqU+hYWtn4Hai5U+/dhCbVP
85
+ 5jvBlYHFBNL0+u0Pc7n/vKMMAAA=
86
+
87
+ http_version: "1.1"
88
+ - !ruby/struct:VCR::HTTPInteraction
89
+ request: !ruby/struct:VCR::Request
90
+ method: :get
91
+ uri: https://api.github.com:443/users/peter-murach/repos
92
+ body:
93
+ headers:
94
+ accept-encoding:
95
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
96
+ response: !ruby/struct:VCR::Response
97
+ status: !ruby/struct:VCR::ResponseStatus
98
+ code: 200
99
+ message: OK
100
+ headers:
101
+ server:
102
+ - nginx/1.0.4
103
+ date:
104
+ - Tue, 03 Jan 2012 16:25:33 GMT
105
+ content-type:
106
+ - application/json; charset=utf-8
107
+ transfer-encoding:
108
+ - chunked
109
+ connection:
110
+ - keep-alive
111
+ status:
112
+ - 200 OK
113
+ x-ratelimit-limit:
114
+ - "5000"
115
+ etag:
116
+ - "\"7be13ab6007576b15b8f5d0d907a3fb2\""
117
+ x-ratelimit-remaining:
118
+ - "4985"
119
+ content-encoding:
120
+ - gzip
121
+ body: !binary |
122
+ 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
166
+
167
+ http_version: "1.1"