github-api-rails 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitmodules +3 -0
- data/README.md +10 -0
- data/github-api-rails.gemspec +18 -0
- data/lib/github-api-rails.rb +1 -0
- data/lib/github-api/rails.rb +4 -0
- data/lib/github-api/version.rb +9 -0
- data/vender/assets/javascripts/github.js +750 -0
- metadata +64 -0
data/.gitmodules
ADDED
data/README.md
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
$: << "lib"
|
2
|
+
require "github-api/version"
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "github-api-rails"
|
6
|
+
s.version = GithubAPI::VERSION::IS
|
7
|
+
s.summary = "Javascript bindings for the Github API"
|
8
|
+
s.description = <<-EOF
|
9
|
+
Javascript bindings for the Github API
|
10
|
+
EOF
|
11
|
+
|
12
|
+
s.authors = %w(fitzgen GutenYe)
|
13
|
+
s.email = %w(ywzhaifei@gmail.com)
|
14
|
+
s.homepage = "http://github.com/fitzgen/github-api-rails"
|
15
|
+
s.rubyforge_project = "xx"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'github-api/rails'
|
@@ -0,0 +1,750 @@
|
|
1
|
+
// ## Client-side Javascript API wrapper for GitHub
|
2
|
+
//
|
3
|
+
// Tries to map one-to-one with the GitHub API V2, but in a Javascripty manner.
|
4
|
+
|
5
|
+
(function (globals) {
|
6
|
+
|
7
|
+
// Before we implement the API methods, we will define all of our private
|
8
|
+
// variables and helper functions with one `var` statement.
|
9
|
+
var
|
10
|
+
|
11
|
+
// The username and authentication token of the library's user.
|
12
|
+
authUsername,
|
13
|
+
authToken,
|
14
|
+
|
15
|
+
// To save keystrokes when we make JSONP calls to the HTTP API, we will keep
|
16
|
+
// track of the root from which all V2 urls extend.
|
17
|
+
apiRoot = "https://github.com/api/v2/json/",
|
18
|
+
|
19
|
+
// Send a JSONP request to the Github API that calls `callback` with
|
20
|
+
// the `context` argument as `this`.
|
21
|
+
//
|
22
|
+
// The `url` parameter is concatenated with the apiRoot, for the reasons
|
23
|
+
// mentioned above. The way that we are supporting non-global, anonymous
|
24
|
+
// functions is by sticking them in the globally exposed
|
25
|
+
// `gh.__jsonp_callbacks` object with a "unique" `id` that is the current
|
26
|
+
// time in milliseconds. Once the callback is called, it is deleted from the
|
27
|
+
// object to prevent memory leaks.
|
28
|
+
jsonp = function (url, callback, context) {
|
29
|
+
var id = +new Date,
|
30
|
+
script = document.createElement("script");
|
31
|
+
|
32
|
+
while (gh.__jsonp_callbacks[id] !== undefined)
|
33
|
+
id += Math.random(); // Avoid slight possibility of id clashes.
|
34
|
+
|
35
|
+
gh.__jsonp_callbacks[id] = function () {
|
36
|
+
delete gh.__jsonp_callbacks[id];
|
37
|
+
callback.apply(context, arguments);
|
38
|
+
};
|
39
|
+
|
40
|
+
var prefix = "?";
|
41
|
+
if (url.indexOf("?") >= 0)
|
42
|
+
prefix = "&";
|
43
|
+
|
44
|
+
url += prefix + "callback=" + encodeURIComponent("gh.__jsonp_callbacks[" + id + "]");
|
45
|
+
if (authUsername && authToken) {
|
46
|
+
url += "&login=" + authUsername + "&authToken=" + authToken;
|
47
|
+
}
|
48
|
+
script.setAttribute("src", apiRoot + url);
|
49
|
+
|
50
|
+
document.getElementsByTagName('head')[0].appendChild(script);
|
51
|
+
},
|
52
|
+
|
53
|
+
// Send an HTTP POST. Unfortunately, it isn't possible to support a callback
|
54
|
+
// with the resulting data. (Please prove me wrong if you can!)
|
55
|
+
//
|
56
|
+
// This is implemented with a hack to get around the cross-domain
|
57
|
+
// restrictions on ajax calls. Basically, a form is created that will POST
|
58
|
+
// to the GitHub API URL, stuck inside an iframe so that it won't redirect
|
59
|
+
// this page, and then submitted.
|
60
|
+
post = function (url, vals) {
|
61
|
+
var
|
62
|
+
form = document.createElement("form"),
|
63
|
+
iframe = document.createElement("iframe"),
|
64
|
+
doc = iframe.contentDocument !== undefined ?
|
65
|
+
iframe.contentDocument :
|
66
|
+
iframe.contentWindow.document,
|
67
|
+
key, field;
|
68
|
+
vals = vals || {};
|
69
|
+
|
70
|
+
form.setAttribute("method", "post");
|
71
|
+
form.setAttribute("action", apiRoot + url);
|
72
|
+
for (key in vals) {
|
73
|
+
if (vals.hasOwnProperty(key)) {
|
74
|
+
field = document.createElement("input");
|
75
|
+
field.type = "hidden";
|
76
|
+
field.value = encodeURIComponent(vals[key]);
|
77
|
+
form.appendChild(field);
|
78
|
+
}
|
79
|
+
}
|
80
|
+
|
81
|
+
iframe.setAttribute("style", "display: none;");
|
82
|
+
doc.body.appendChild(form);
|
83
|
+
document.body.appendChild(iframe);
|
84
|
+
form.submit();
|
85
|
+
},
|
86
|
+
|
87
|
+
// This helper function will throw a TypeError if the library user is not
|
88
|
+
// properly authenticated. Otherwise, it silently returns.
|
89
|
+
authRequired = function (username) {
|
90
|
+
if (!authUsername || !authToken || authUsername !== username) {
|
91
|
+
throw new TypeError("gh: Must be authenticated to do that.");
|
92
|
+
}
|
93
|
+
},
|
94
|
+
|
95
|
+
// Convert an object to a url parameter string.
|
96
|
+
//
|
97
|
+
// paramify({foo:1, bar:3}) -> "foo=1&bar=3".
|
98
|
+
paramify = function (params) {
|
99
|
+
var str = "", key;
|
100
|
+
for (key in params) if (params.hasOwnProperty(key))
|
101
|
+
str += key + "=" + params[key] + "&";
|
102
|
+
return str.replace(/&$/, "");
|
103
|
+
},
|
104
|
+
|
105
|
+
// Get around how the GH team haven't migrated all the API to version 2, and
|
106
|
+
// how gists use a different api root.
|
107
|
+
withTempApiRoot = function (tempApiRoot, fn) {
|
108
|
+
return function () {
|
109
|
+
var oldRoot = apiRoot;
|
110
|
+
apiRoot = tempApiRoot;
|
111
|
+
fn.apply(this, arguments);
|
112
|
+
apiRoot = oldRoot;
|
113
|
+
};
|
114
|
+
},
|
115
|
+
|
116
|
+
// Expose the global `gh` variable, through which every API method is
|
117
|
+
// accessed, but keep a local variable around so we can reference it easily.
|
118
|
+
gh = globals.gh = {};
|
119
|
+
|
120
|
+
// Psuedo private home for JSONP callbacks (which are required to be global
|
121
|
+
// by the nature of JSONP, as discussed earlier).
|
122
|
+
gh.__jsonp_callbacks = {};
|
123
|
+
|
124
|
+
// Authenticate as a user. Does not try to validate at any point; that job
|
125
|
+
// is up to each individual method, which calls `authRequired` as needed.
|
126
|
+
gh.authenticate = function (username, token) {
|
127
|
+
authUsername = username;
|
128
|
+
authToken = token;
|
129
|
+
return this;
|
130
|
+
};
|
131
|
+
|
132
|
+
// ### Users
|
133
|
+
|
134
|
+
// The constructor for user objects. Just creating an instance of a user
|
135
|
+
// doesn't fetch any data from GitHub, you need to get explicit about what
|
136
|
+
// you want to do that.
|
137
|
+
//
|
138
|
+
// var huddlej = gh.user("huddlej");
|
139
|
+
gh.user = function (username) {
|
140
|
+
if ( !(this instanceof gh.user)) {
|
141
|
+
return new gh.user(username);
|
142
|
+
}
|
143
|
+
this.username = username;
|
144
|
+
};
|
145
|
+
|
146
|
+
// Show basic user info; you can get more info if you are authenticated as
|
147
|
+
// this user.
|
148
|
+
//
|
149
|
+
// gh.user("fitzgen").show(function (data) {
|
150
|
+
// console.log(data.user);
|
151
|
+
// });
|
152
|
+
gh.user.prototype.show = function (callback, context) {
|
153
|
+
jsonp("user/show/" + this.username, callback, context);
|
154
|
+
return this;
|
155
|
+
};
|
156
|
+
|
157
|
+
// Update a user's info. You must be authenticated as this user for this to
|
158
|
+
// succeed.
|
159
|
+
//
|
160
|
+
// TODO: example
|
161
|
+
gh.user.prototype.update = function (params) {
|
162
|
+
authRequired(this.username);
|
163
|
+
var key, postData = {
|
164
|
+
login: authUsername,
|
165
|
+
token: authToken
|
166
|
+
};
|
167
|
+
for (key in params) {
|
168
|
+
if (params.hasOwnProperty(key)) {
|
169
|
+
postData["values["+key+"]"] = encodeURIComponent(params[key]);
|
170
|
+
}
|
171
|
+
}
|
172
|
+
post("user/show/" + this.username, postData);
|
173
|
+
return this;
|
174
|
+
};
|
175
|
+
|
176
|
+
// Get a list of who this user is following.
|
177
|
+
//
|
178
|
+
// TODO: example
|
179
|
+
gh.user.prototype.following = function (callback, context) {
|
180
|
+
jsonp("user/show/" + this.username + "/following", callback, context);
|
181
|
+
};
|
182
|
+
|
183
|
+
// Find out what other users are following this user.
|
184
|
+
//
|
185
|
+
// TODO: example
|
186
|
+
gh.user.prototype.followers = function (callback, context) {
|
187
|
+
jsonp("user/show/" + this.username + "/followers", callback, context);
|
188
|
+
};
|
189
|
+
|
190
|
+
// Make this user follow some other user. You must be authenticated as this
|
191
|
+
// user for this to succeed.
|
192
|
+
//
|
193
|
+
// TODO: example
|
194
|
+
gh.user.prototype.follow = function (user) {
|
195
|
+
authRequired.call(this);
|
196
|
+
post("user/follow/" + user);
|
197
|
+
return this;
|
198
|
+
};
|
199
|
+
|
200
|
+
// Make this user quit following the given `user`. You must be authenticated
|
201
|
+
// as this user to succeed.
|
202
|
+
//
|
203
|
+
// TODO: example
|
204
|
+
gh.user.prototype.unfollow = function (user) {
|
205
|
+
authRequired.call(this);
|
206
|
+
post("user/unfollow/" + user);
|
207
|
+
return this;
|
208
|
+
};
|
209
|
+
|
210
|
+
// Get a list of repositories that this user is watching.
|
211
|
+
//
|
212
|
+
// TODO: example
|
213
|
+
gh.user.prototype.watching = function (callback, context) {
|
214
|
+
jsonp("repos/watched/" + this.username, callback, context);
|
215
|
+
return this;
|
216
|
+
};
|
217
|
+
|
218
|
+
// Get a list of this user's repositories, 30 per page
|
219
|
+
//
|
220
|
+
// gh.user("fitzgen").repos(function (data) {
|
221
|
+
// data.repositories.forEach(function (repo) {
|
222
|
+
// ...
|
223
|
+
// });
|
224
|
+
// });
|
225
|
+
gh.user.prototype.repos = function (callback, context, page) {
|
226
|
+
gh.repo.forUser(this.username, callback, context, page);
|
227
|
+
return this;
|
228
|
+
};
|
229
|
+
|
230
|
+
// Get a list of all repos for this user.
|
231
|
+
//
|
232
|
+
// gh.user("fitzgen").allRepos(function (data) {
|
233
|
+
// alert(data.repositories.length);
|
234
|
+
// });
|
235
|
+
gh.user.prototype.allRepos = function (callback, context) {
|
236
|
+
var repos = [],
|
237
|
+
username = this.username,
|
238
|
+
page = 1;
|
239
|
+
|
240
|
+
function exitCallback () {
|
241
|
+
callback.call(context, { repositories: repos });
|
242
|
+
}
|
243
|
+
|
244
|
+
function pageLoop (data) {
|
245
|
+
if (data.repositories.length == 0) {
|
246
|
+
exitCallback();
|
247
|
+
} else {
|
248
|
+
repos = repos.concat(data.repositories);
|
249
|
+
page += 1;
|
250
|
+
gh.repo.forUser(username, pageLoop, context, page);
|
251
|
+
}
|
252
|
+
}
|
253
|
+
|
254
|
+
gh.repo.forUser(username, pageLoop, context, page);
|
255
|
+
|
256
|
+
return this;
|
257
|
+
};
|
258
|
+
|
259
|
+
// Make this user fork the repo that lives at
|
260
|
+
// http://github.com/user/repo. You must be authenticated as this user for
|
261
|
+
// this to succeed.
|
262
|
+
//
|
263
|
+
// gh.user("fitzgen").forkRepo("brianleroux", "wtfjs");
|
264
|
+
gh.user.prototype.forkRepo = function (user, repo) {
|
265
|
+
authRequired(this.username);
|
266
|
+
post("repos/fork/" + user + "/" + repo);
|
267
|
+
return this;
|
268
|
+
};
|
269
|
+
|
270
|
+
// Get a list of all repos that this user can push to (including ones that
|
271
|
+
// they are just a collaborator on, and do not own). Must be authenticated
|
272
|
+
// as this user.
|
273
|
+
gh.user.prototype.pushable = function (callback, context) {
|
274
|
+
authRequired(authUsername);
|
275
|
+
jsonp("repos/pushable", callback, context);
|
276
|
+
};
|
277
|
+
|
278
|
+
gh.user.prototype.publicGists = withTempApiRoot(
|
279
|
+
"http://gist.github.com/api/v1/json/gists/",
|
280
|
+
function (callback, context) {
|
281
|
+
jsonp(this.username, callback, context);
|
282
|
+
return this;
|
283
|
+
}
|
284
|
+
);
|
285
|
+
|
286
|
+
// Search users for `query`.
|
287
|
+
gh.user.search = function (query, callback, context) {
|
288
|
+
jsonp("user/search/" + query, callback, context);
|
289
|
+
return this;
|
290
|
+
};
|
291
|
+
|
292
|
+
// ### Repositories
|
293
|
+
|
294
|
+
// This is the base constructor for creating repo objects. Note that this
|
295
|
+
// won't actually hit the GitHub API until you specify what data you want,
|
296
|
+
// or what action you wish to take via a prototype method.
|
297
|
+
gh.repo = function (user, repo) {
|
298
|
+
if ( !(this instanceof gh.repo)) {
|
299
|
+
return new gh.repo(user, repo);
|
300
|
+
}
|
301
|
+
this.repo = repo;
|
302
|
+
this.user = user;
|
303
|
+
};
|
304
|
+
|
305
|
+
// Get basic information on this repo.
|
306
|
+
//
|
307
|
+
// gh.repo("schacon", "grit").show(function (data) {
|
308
|
+
// console.log(data.repository.description);
|
309
|
+
// });
|
310
|
+
gh.repo.prototype.show = function (callback, context) {
|
311
|
+
jsonp("repos/show/" + this.user + "/" + this.repo, callback, context);
|
312
|
+
return this;
|
313
|
+
};
|
314
|
+
|
315
|
+
// Update the information for this repo. Must be authenticated as the
|
316
|
+
// repository owner. Params can include:
|
317
|
+
//
|
318
|
+
// * description
|
319
|
+
// * homepage
|
320
|
+
// * has_wiki
|
321
|
+
// * has_issues
|
322
|
+
// * has_downloads
|
323
|
+
gh.repo.prototype.update = function (params) {
|
324
|
+
authRequired(this.user);
|
325
|
+
var key, postData = {
|
326
|
+
login: authUsername,
|
327
|
+
token: authToken
|
328
|
+
};
|
329
|
+
for (key in params) {
|
330
|
+
if (params.hasOwnProperty(key)) {
|
331
|
+
postData["values["+key+"]"] = encodeURIComponent(params[key]);
|
332
|
+
}
|
333
|
+
}
|
334
|
+
post("repos/show/" + this.user + "/" + this.repo, postData);
|
335
|
+
return this;
|
336
|
+
};
|
337
|
+
|
338
|
+
// Get all tags for this repo.
|
339
|
+
gh.repo.prototype.tags = function (callback, context) {
|
340
|
+
jsonp("repos/show/" + this.user + "/" + this.repo + "/tags",
|
341
|
+
callback,
|
342
|
+
context);
|
343
|
+
return this;
|
344
|
+
};
|
345
|
+
|
346
|
+
// Get all branches in this repo.
|
347
|
+
gh.repo.prototype.branches = function (callback, context) {
|
348
|
+
jsonp("repos/show/" + this.user + "/" + this.repo + "/branches",
|
349
|
+
callback,
|
350
|
+
context);
|
351
|
+
return this;
|
352
|
+
};
|
353
|
+
|
354
|
+
// Gather line count information on the language(s) used in this repo.
|
355
|
+
gh.repo.prototype.languages = function (callback, context) {
|
356
|
+
jsonp("/repos/show/" + this.user + "/" + this.repo + "/languages",
|
357
|
+
callback,
|
358
|
+
context);
|
359
|
+
return this;
|
360
|
+
};
|
361
|
+
|
362
|
+
// Gather data on all the forks of this repo.
|
363
|
+
gh.repo.prototype.network = function (callback, context) {
|
364
|
+
jsonp("repos/show/" + this.user + "/" + this.repo + "/network",
|
365
|
+
callback,
|
366
|
+
context);
|
367
|
+
return this;
|
368
|
+
};
|
369
|
+
|
370
|
+
// All users who have contributed to this repo. Pass `true` to showAnon if you
|
371
|
+
// want to see the non-github contributors.
|
372
|
+
gh.repo.prototype.contributors = function (callback, context, showAnon) {
|
373
|
+
var url = "repos/show/" + this.user + "/" + this.repo + "/contributors";
|
374
|
+
if (showAnon)
|
375
|
+
url += "/anon";
|
376
|
+
jsonp(url,
|
377
|
+
callback,
|
378
|
+
context);
|
379
|
+
return this;
|
380
|
+
};
|
381
|
+
|
382
|
+
// Get all of the collaborators for this repo.
|
383
|
+
gh.repo.prototype.collaborators = function (callback, context) {
|
384
|
+
jsonp("repos/show/" + this.user + "/" + this.repo + "/collaborators",
|
385
|
+
callback,
|
386
|
+
context);
|
387
|
+
return this;
|
388
|
+
};
|
389
|
+
|
390
|
+
// Add a collaborator to this project. Must be authenticated.
|
391
|
+
gh.repo.prototype.addCollaborator = function (collaborator) {
|
392
|
+
authRequired(this.user);
|
393
|
+
post("repos/collaborators/" + this.repo + "/add/" + collaborator);
|
394
|
+
return this;
|
395
|
+
};
|
396
|
+
|
397
|
+
// Remove a collaborator from this project. Must be authenticated.
|
398
|
+
gh.repo.prototype.removeCollaborator = function (collaborator) {
|
399
|
+
authRequired(this.user);
|
400
|
+
post("repos/collaborators/" + this.repo + "/remove/" + collaborator);
|
401
|
+
return this;
|
402
|
+
};
|
403
|
+
|
404
|
+
// Make this repository private. Authentication required.
|
405
|
+
gh.repo.prototype.setPrivate = function () {
|
406
|
+
authRequired(this.user);
|
407
|
+
post("repo/set/private/" + this.repo);
|
408
|
+
return this;
|
409
|
+
};
|
410
|
+
|
411
|
+
// Make this repository public. Authentication required.
|
412
|
+
gh.repo.prototype.setPublic = function () {
|
413
|
+
authRequired(this.user);
|
414
|
+
post("repo/set/public/" + this.repo);
|
415
|
+
return this;
|
416
|
+
};
|
417
|
+
|
418
|
+
// Search for repositories. `opts` may include `start_page` or `language`,
|
419
|
+
// which must be capitalized.
|
420
|
+
gh.repo.search = function (query, opts, callback, context) {
|
421
|
+
var url = "repos/search/" + query.replace(" ", "+");
|
422
|
+
if (typeof opts === "function") {
|
423
|
+
opts = {};
|
424
|
+
callback = arguments[1];
|
425
|
+
context = arguments[2];
|
426
|
+
}
|
427
|
+
url += "?" + paramify(opts);
|
428
|
+
jsonp(url, callback, context);
|
429
|
+
return this;
|
430
|
+
};
|
431
|
+
|
432
|
+
// Get all the repos that are owned by `user`.
|
433
|
+
gh.repo.forUser = function (user, callback, context, page) {
|
434
|
+
if (!page)
|
435
|
+
page = 1;
|
436
|
+
|
437
|
+
jsonp("repos/show/" + user + '?page=' + page, callback, context);
|
438
|
+
return this;
|
439
|
+
};
|
440
|
+
|
441
|
+
// Create a repository. Must be authenticated.
|
442
|
+
gh.repo.create = function (name, opts) {
|
443
|
+
authRequired(authUsername);
|
444
|
+
opts.name = name;
|
445
|
+
post("repos/create", opts);
|
446
|
+
return this;
|
447
|
+
};
|
448
|
+
|
449
|
+
// Delete a repository. Must be authenticated.
|
450
|
+
gh.repo.del = function (name) {
|
451
|
+
authRequired(authUsername);
|
452
|
+
post("repos/delete/" + name);
|
453
|
+
return this;
|
454
|
+
};
|
455
|
+
|
456
|
+
// ### Commits
|
457
|
+
|
458
|
+
gh.commit = function (user, repo, sha) {
|
459
|
+
if ( !(this instanceof gh.commit) )
|
460
|
+
return new gh.commit(user, repo, sha);
|
461
|
+
this.user = user;
|
462
|
+
this.repo = repo;
|
463
|
+
this.sha = sha;
|
464
|
+
};
|
465
|
+
|
466
|
+
gh.commit.prototype.show = function (callback, context) {
|
467
|
+
jsonp("commits/show/" + this.user + "/" + this.repo + "/" + this.sha,
|
468
|
+
callback,
|
469
|
+
context);
|
470
|
+
return this;
|
471
|
+
};
|
472
|
+
|
473
|
+
// Get a list of all commits on a repos branch.
|
474
|
+
gh.commit.forBranch = function (user, repo, branch, callback, context) {
|
475
|
+
jsonp("commits/list/" + user + "/" + repo + "/" + branch,
|
476
|
+
callback,
|
477
|
+
context);
|
478
|
+
return this;
|
479
|
+
};
|
480
|
+
|
481
|
+
// Get a list of all commits on this path (file or dir).
|
482
|
+
gh.commit.forPath = function (user, repo, branch, path, callback, context) {
|
483
|
+
jsonp("commits/list/" + user + "/" + repo + "/" + branch + "/" + path,
|
484
|
+
callback,
|
485
|
+
context);
|
486
|
+
return this;
|
487
|
+
};
|
488
|
+
|
489
|
+
// ### Issues
|
490
|
+
|
491
|
+
gh.issue = function (user, repo, number) {
|
492
|
+
if ( !(this instanceof gh.issue) )
|
493
|
+
return new gh.commit(user, repo, number);
|
494
|
+
this.user = user;
|
495
|
+
this.repo = repo;
|
496
|
+
this.number = number;
|
497
|
+
};
|
498
|
+
|
499
|
+
// View this issue's info.
|
500
|
+
gh.issue.prototype.show = function (callback, context) {
|
501
|
+
jsonp("issues/show/" + this.user + "/" + this.repo + "/" + this.number,
|
502
|
+
callback,
|
503
|
+
context);
|
504
|
+
return this;
|
505
|
+
};
|
506
|
+
|
507
|
+
// Get a list of all comments on this issue.
|
508
|
+
gh.issue.prototype.comments = function (callback, context) {
|
509
|
+
jsonp("issues/comments/" + this.user + "/" + this.repo + "/" + this.number,
|
510
|
+
callback,
|
511
|
+
context);
|
512
|
+
return this;
|
513
|
+
};
|
514
|
+
|
515
|
+
// Close this issue.
|
516
|
+
gh.issue.prototype.close = function () {
|
517
|
+
authRequired(this.user);
|
518
|
+
post("issues/close/" + this.user + "/" + this.repo + "/" + this.number);
|
519
|
+
return this;
|
520
|
+
};
|
521
|
+
|
522
|
+
// Reopen this issue.
|
523
|
+
gh.issue.prototype.reopen = function () {
|
524
|
+
authRequired(this.user);
|
525
|
+
post("issues/reopen/" + this.user + "/" + this.repo + "/" + this.number);
|
526
|
+
return this;
|
527
|
+
};
|
528
|
+
|
529
|
+
// Reopen this issue.
|
530
|
+
gh.issue.prototype.update = function (title, body) {
|
531
|
+
authRequired(this.user);
|
532
|
+
post("issues/edit/" + this.user + "/" + this.repo + "/" + this.number, {
|
533
|
+
title: title,
|
534
|
+
body: body
|
535
|
+
});
|
536
|
+
return this;
|
537
|
+
};
|
538
|
+
|
539
|
+
// Add `label` to this issue. If the label is not yet in the system, it will
|
540
|
+
// be created.
|
541
|
+
gh.issue.prototype.addLabel = function (label) {
|
542
|
+
post("issues/label/add/" + this.user + "/" + this.repo + "/" + label + "/" + this.number);
|
543
|
+
return this;
|
544
|
+
};
|
545
|
+
|
546
|
+
// Remove a label from this issue.
|
547
|
+
gh.issue.prototype.removeLabel = function (label) {
|
548
|
+
post("issues/label/remove/" + this.user + "/" + this.repo + "/" + label + "/" + this.number);
|
549
|
+
return this;
|
550
|
+
};
|
551
|
+
|
552
|
+
// Comment on this issue as the user that is authenticated.
|
553
|
+
gh.issue.prototype.comment = function (comment) {
|
554
|
+
authRequired(authUsername);
|
555
|
+
post("/issues/comment/" + user + "/" + repo + "/" + this.number, {
|
556
|
+
comment: comment
|
557
|
+
});
|
558
|
+
return this;
|
559
|
+
};
|
560
|
+
|
561
|
+
// Get all issues' labels for the repo.
|
562
|
+
gh.issue.labels = function (user, repo) {
|
563
|
+
jsonp("issues/labels/" + user + "/" + repo,
|
564
|
+
callback,
|
565
|
+
context);
|
566
|
+
return this;
|
567
|
+
};
|
568
|
+
|
569
|
+
// Open an issue. Must be authenticated.
|
570
|
+
gh.issue.open = function (repo, title, body) {
|
571
|
+
authRequired(authUsername);
|
572
|
+
post("issues/open/" + authUsername + "/" + repo, {
|
573
|
+
title: title,
|
574
|
+
body: body
|
575
|
+
});
|
576
|
+
return this;
|
577
|
+
};
|
578
|
+
|
579
|
+
// Search a repository's issue tracker. `state` can be "open" or "closed".
|
580
|
+
gh.issue.search = function (user, repo, state, query, callback, context) {
|
581
|
+
jsonp("/issues/search/" + user + "/" + repo + "/" + state + "/" + query,
|
582
|
+
callback,
|
583
|
+
context);
|
584
|
+
return this;
|
585
|
+
};
|
586
|
+
|
587
|
+
// Get a list of issues for the given repo. `state` can be "open" or
|
588
|
+
// "closed".
|
589
|
+
gh.issue.list = function (user, repo, state, callback, context) {
|
590
|
+
jsonp("issues/list/" + user + "/" + repo + "/" + state,
|
591
|
+
callback,
|
592
|
+
context);
|
593
|
+
return this;
|
594
|
+
};
|
595
|
+
|
596
|
+
// ### Gists
|
597
|
+
|
598
|
+
gh.gist = function (id) {
|
599
|
+
if ( !(this instanceof gh.gist) ) {
|
600
|
+
return new gh.gist(id);
|
601
|
+
}
|
602
|
+
this.id = id;
|
603
|
+
};
|
604
|
+
|
605
|
+
gh.gist.prototype.show = withTempApiRoot(
|
606
|
+
"http://gist.github.com/api/v1/json/",
|
607
|
+
function (callback, context) {
|
608
|
+
jsonp(this.id, callback, cont);
|
609
|
+
return this;
|
610
|
+
}
|
611
|
+
);
|
612
|
+
|
613
|
+
gh.gist.prototype.file = withTempApiRoot(
|
614
|
+
"http://gist.github.com/raw/v1/json/",
|
615
|
+
function (filename, callback, context) {
|
616
|
+
jsonp(this.id + "/" + filename, callback, cont);
|
617
|
+
return this;
|
618
|
+
}
|
619
|
+
);
|
620
|
+
|
621
|
+
// ### Objects
|
622
|
+
|
623
|
+
gh.object = function (user, repo) {
|
624
|
+
if (!(this instanceof gh.object)) {
|
625
|
+
return new gh.object(user, repo);
|
626
|
+
}
|
627
|
+
this.user = user;
|
628
|
+
this.repo = repo;
|
629
|
+
};
|
630
|
+
|
631
|
+
// Get the contents of a tree by tree SHA
|
632
|
+
gh.object.prototype.tree = function (sha, callback, context) {
|
633
|
+
jsonp("tree/show/" + this.user + "/" + this.repo + "/" + sha,
|
634
|
+
callback,
|
635
|
+
context);
|
636
|
+
return this;
|
637
|
+
};
|
638
|
+
|
639
|
+
// Get the data about a blob by tree SHA and path
|
640
|
+
gh.object.prototype.blob = function (path, sha, callback, context) {
|
641
|
+
jsonp("blob/show/" + this.user + "/" + this.repo + "/" + sha + "/" + path,
|
642
|
+
callback,
|
643
|
+
context);
|
644
|
+
return this;
|
645
|
+
};
|
646
|
+
|
647
|
+
// Get only blob meta
|
648
|
+
gh.object.prototype.blobMeta = function (path, sha, callback, context) {
|
649
|
+
jsonp("blob/show/" + this.user + "/" + this.repo + "/" + sha + "/" + path + "?meta=1",
|
650
|
+
callback,
|
651
|
+
context);
|
652
|
+
return this;
|
653
|
+
};
|
654
|
+
|
655
|
+
// Get list of blobs
|
656
|
+
gh.object.prototype.blobAll = function (branch, callback, context) {
|
657
|
+
jsonp("blob/all/" + this.user + "/" + this.repo + "/" + branch,
|
658
|
+
callback,
|
659
|
+
context);
|
660
|
+
return this;
|
661
|
+
};
|
662
|
+
|
663
|
+
// Get meta of each blob in tree
|
664
|
+
gh.object.prototype.blobFull = function (sha, callback, context) {
|
665
|
+
jsonp("blob/full/" + this.user + "/" + this.repo + "/" + sha,
|
666
|
+
callback,
|
667
|
+
context);
|
668
|
+
return this;
|
669
|
+
};
|
670
|
+
|
671
|
+
// ### Network
|
672
|
+
|
673
|
+
gh.network = function(user, repo) {
|
674
|
+
if (!(this instanceof gh.network)) {
|
675
|
+
return new gh.network(user, repo);
|
676
|
+
}
|
677
|
+
this.user = user;
|
678
|
+
this.repo = repo;
|
679
|
+
};
|
680
|
+
|
681
|
+
gh.network.prototype.data = withTempApiRoot(
|
682
|
+
"http://github.com/",
|
683
|
+
function (nethash, start, end, callback, context) {
|
684
|
+
jsonp(this.user + "/" + this.repo + "/network_data_chunk?"
|
685
|
+
+ nethash + "&" + start + "&" + end,
|
686
|
+
callback,
|
687
|
+
context);
|
688
|
+
return this;
|
689
|
+
}
|
690
|
+
);
|
691
|
+
|
692
|
+
gh.network.prototype.meta = withTempApiRoot(
|
693
|
+
"http://github.com/",
|
694
|
+
function (callback, context) {
|
695
|
+
jsonp(this.user + "/" + this.repo + "/network_meta",
|
696
|
+
callback,
|
697
|
+
context);
|
698
|
+
return this;
|
699
|
+
}
|
700
|
+
);
|
701
|
+
|
702
|
+
// ### Pull Requests
|
703
|
+
|
704
|
+
gh.pulls = function(user, repo) {
|
705
|
+
if (!(this instanceof gh.pulls)) {
|
706
|
+
return new gh.pulls(user, repo);
|
707
|
+
}
|
708
|
+
this.user = user;
|
709
|
+
this.repo = repo;
|
710
|
+
};
|
711
|
+
|
712
|
+
// Get all pull requests for the repo
|
713
|
+
//
|
714
|
+
// gh.pulls("fitzgen", "github-api").allPulls(function (data) {
|
715
|
+
// data.pulls.forEach(function (pull) {
|
716
|
+
// console.log("Title: " + pull.title);
|
717
|
+
// });
|
718
|
+
// });
|
719
|
+
gh.pulls.prototype.allPulls = function (callback, context) {
|
720
|
+
jsonp("pulls/" + this.user + "/" + this.repo, callback, context);
|
721
|
+
return this;
|
722
|
+
};
|
723
|
+
|
724
|
+
// Get pull requests filtered by state. `state` can be "open" or "closed".
|
725
|
+
//
|
726
|
+
// gh.pulls("fitzgen", "github-api").forState("closed", function (data) {
|
727
|
+
// data.pulls.forEach(function (pull) {
|
728
|
+
// console.log("Title: " + pull.title + " State: " + pull.state);
|
729
|
+
// });
|
730
|
+
// });
|
731
|
+
gh.pulls.prototype.forState = function (state, callback, context) {
|
732
|
+
jsonp("pulls/" + this.user + "/" + this.repo + "/" + state, callback, context);
|
733
|
+
return this;
|
734
|
+
};
|
735
|
+
|
736
|
+
// Get pull requests by number
|
737
|
+
//
|
738
|
+
// Important: This call returns a single object called "pull" instead of multiple "pulls" objects!
|
739
|
+
//
|
740
|
+
// gh.pulls("fitzgen", "github-api").forNumber("1", function (data) {
|
741
|
+
// console.log("Title: " + data.pull.title + " Number: " + data.pull.number);
|
742
|
+
// });
|
743
|
+
gh.pulls.prototype.forNumber = function (number, callback, context) {
|
744
|
+
jsonp("pulls/" + this.user + "/" + this.repo + "/" + number, callback, context);
|
745
|
+
return this;
|
746
|
+
};
|
747
|
+
|
748
|
+
//TODO: Creating a Pull Request
|
749
|
+
|
750
|
+
}(window));
|
metadata
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: github-api-rails
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 1.0.0
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- fitzgen
|
9
|
+
- GutenYe
|
10
|
+
autorequire:
|
11
|
+
bindir: bin
|
12
|
+
cert_chain: []
|
13
|
+
|
14
|
+
date: 2011-08-24 00:00:00 Z
|
15
|
+
dependencies: []
|
16
|
+
|
17
|
+
description: |
|
18
|
+
Javascript bindings for the Github API
|
19
|
+
|
20
|
+
email:
|
21
|
+
- ywzhaifei@gmail.com
|
22
|
+
executables: []
|
23
|
+
|
24
|
+
extensions: []
|
25
|
+
|
26
|
+
extra_rdoc_files: []
|
27
|
+
|
28
|
+
files:
|
29
|
+
- .gitmodules
|
30
|
+
- README.md
|
31
|
+
- github-api-rails.gemspec
|
32
|
+
- lib/github-api-rails.rb
|
33
|
+
- lib/github-api/rails.rb
|
34
|
+
- lib/github-api/version.rb
|
35
|
+
- vender/assets/javascripts/github.js
|
36
|
+
homepage: http://github.com/fitzgen/github-api-rails
|
37
|
+
licenses: []
|
38
|
+
|
39
|
+
post_install_message:
|
40
|
+
rdoc_options: []
|
41
|
+
|
42
|
+
require_paths:
|
43
|
+
- lib
|
44
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
45
|
+
none: false
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: "0"
|
50
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: "0"
|
56
|
+
requirements: []
|
57
|
+
|
58
|
+
rubyforge_project: xx
|
59
|
+
rubygems_version: 1.8.5
|
60
|
+
signing_key:
|
61
|
+
specification_version: 3
|
62
|
+
summary: Javascript bindings for the Github API
|
63
|
+
test_files: []
|
64
|
+
|