-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathindex.js
195 lines (163 loc) · 5.47 KB
/
index.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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
var request = require('request'),
cheerio = require('cheerio');
/**
* List of contributons, latest commit, streak etc.
*
* @param {string} url - URL to the github repo
* @param {function} callback - Receives the data
*/
exports.scrapeContributionDataAndStats = function(url, callback) {
var returnObj = {};
getRequest(url, function(html) {
scrapeContributionData(html, function(contributionData) {
returnObj = formatReturnData(contributionData, deriveContributionStats(contributionData));
callback(returnObj);
});
});
};
/**
* Derive the streak
*
* @param {object} contributionData - Contribution data
* @return {object} - Stats derived from the contribution data
*/
function deriveContributionStats(contributionData) {
// Some variables
var longestStreak = 0;
var currentStreak = 0;
var lastDay = '0-0-0';
// Reduce the total number of contributions to a single integer
const totalContributions = contributionData.reduce(function (last, current, index) {
// Calculate the exptected day to continue the streak
var expectedDay = new Date(lastDay);
expectedDay.setDate(expectedDay.getDate() + 1); // Increment day by 1
const year = expectedDay.getFullYear();
var month = expectedDay.getMonth() + 1; // The month starts from zero
var day = expectedDay.getDate();
// Left-pad for noobs
if (month < 10) { month = '0' + month; }
if (day < 10) { day = '0' + day; }
expectedDay = (
year + '-' +
month + '-' +
day
);
// If the streak was continued, increment, else reset
if (expectedDay === current.dataDate) {
currentStreak++;
} else {
currentStreak = 0;
}
if (currentStreak > longestStreak) {
longestStreak = currentStreak;
}
// Update the last day
lastDay = current.dataDate;
return last + current.dataContributionCount;
}, 0);
return {
totalContributions: totalContributions,
longestStreak: longestStreak + 1,
currentStreak: currentStreak + 1
};
}
/**
* Neatly formats contributionData and statsData
*
* @param {object} contributionData
* @param {object} statsData
* @return {object} - Returns null if no commits have happened today
*/
function formatReturnData(contributionData, statsData) {
var commitsToday = getCommitsToday(contributionData);
var returnData = {contributionData: contributionData, statsData: statsData, commitsToday: commitsToday};
return commitsToday == null ? null : returnData;
};
/**
* Returns the amount of contributions that happened on the current day
*
* @param {object} contributionData
* @return {integer} - Amount of contributions in the current day
*/
function getCommitsToday(contributionData) {
if (!contributionData) {
return null;
}
// Grab latest commit data
var latestCommits = contributionData[contributionData.length - 1];
var latestCommitsDate = dayOfYear(latestCommits.dataDate);
var today = new Date();
var todaysDate = dayOfYear(today.getFullYear()+'-'+(today.getMonth()+1)+'-'+today.getDate());
// Check if the lastest commit data is from today or not
if (latestCommitsDate === todaysDate) {
return latestCommits.dataContributionCount;
}
return 0;
};
/**
* Returns an object containing contribution data
*
* @param {string} html - HTML of the github page
* @param {function} callback - Receives contribution data
*/
function scrapeContributionData(html, callback) {
$ = cheerio.load(html);
var commitDataArray = [];
$('rect').each(function(index, commitData) {
// Look for our contribtion data
var dataContributionCount = parseInt(commitData.attribs['data-count']),
dataDate = commitData.attribs['data-date'],
commitDataObj = {};
// Validate it contains data
if (dataContributionCount && dataDate) {
commitDataObj.dataContributionCount = dataContributionCount;
commitDataObj.dataDate = dataDate;
commitDataArray.push(commitDataObj);
}
});
// Validate it contains data before sending
if (commitDataArray.length > 0) {
callback(commitDataArray);
} else {
// If it fails validation return null
callback(null);
}
};
/**
* Opiniated get request
*
* @param {string} gitUrl
* @param {function} callback3
*/
function getRequest(gitUrl, callback) {
var options = {
url: gitUrl
};
request.get(options, function(error, response, body) {
if(!error) {
callback(body);
}
return error;
});
};
/**
* Returns the day of the year
*
* @param {string, date} date - Can be a string or a timestamp
* @return {integer} The day of the year
*/
function dayOfYear(date) {
var now = new Date(date);
var start = new Date(now.getFullYear(), 0, 0);
var diff = now - start;
var oneDay = 1000 * 60 * 60 * 24;
var day = Math.floor(diff / oneDay);
return day;
}
// Deprecated warnings
exports.scrapeContributionData = function() {
console.log('Deprecation warning: scrapeContributionData has been deprecated in favor of just using scrapeContributionDataAndStats.');
};
exports.scrapeContributionStats = function() {
console.log('Deprecation warning: scrapeContributionData has been deprecated in favor of just using scrapeContributionDataAndStats.');
};