-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathgithub.js
100 lines (83 loc) · 2.47 KB
/
github.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/**
* Small wrapper for the Github API.
*/
function Github(opts) {
opts = opts || {};
this.baseUrl = 'https://api.github.com';
this.cacheNamespace = opts.cacheNamespace || 'ghapi';
}
/**
* Fetches repository information. Accepts a callback
* that receives a #Github.Repository object.
*/
Github.prototype.repo = function getRepo(repo, callback) {
var url = this.baseUrl+'/repos/'+repo;
this._requestOrReadCache(url, function(data) {
if (!data) {
throw new Error('No repository found for '+repo+' !');
}
return callback(new Github.Repository({
name: data.name,
fullName: data.full_name,
forks: data.forks_count,
description: data.description,
url: data.html_url,
stars: data.stargazers_count,
language: data.language
}));
});
return this;
};
/**
* Makes an API request, while using localStorage to cache API responses.
*/
Github.prototype._requestOrReadCache = function requestOrReadCache(url, callback) {
var keyPrefix = this.cacheNamespace+'-'+url+'-';
var etagKey = keyPrefix+'etag';
var contentKey = keyPrefix+'content';
var etag = localStorage.getItem(etagKey);
/**
* If an ETag has been cached, check it against to the API to
* see if the content has changed.
*/
if (etag) {
console.log('requesting '+url+' with etag '+etag);
Request.get(url, {'If-None-Match': etag}, function(res) {
if (res.status !== 304) {
console.log('cache for '+url+' expired!');
window.localStorage.removeItem(etagKey);
window.localStorage.removeItem(contentKey);
return this._requestOrReadCache(url, callback);
}
console.log('cache for '+url+' still valid!');
return callback(JSON.parse(localStorage.getItem(contentKey)));
}.bind(this));
return this;
}
/**
* Perform a full API request and cache the etag and body.
*/
Request.get(url, function(res) {
if (res.status !== 200) {
callback(null);
return;
}
window.localStorage.setItem(etagKey, res.headers.ETag);
window.localStorage.setItem(contentKey, JSON.stringify(res.body));
return callback(res.body);
});
return this;
};
/**
* Repository object to store repo information.
*/
Github.Repository = function Repository(opts) {
opts = opts || {};
this.name = opts.name;
this.fullName = opts.fullName;
this.description = opts.description;
this.forks = opts.forks;
this.language = opts.language;
this.url = opts.url;
this.stars = opts.stars;
};