github_api 0.3.9 → 0.4.0

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.
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"