-
Notifications
You must be signed in to change notification settings - Fork 68
/
gulpfile.js
170 lines (158 loc) · 6.47 KB
/
gulpfile.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
var gulp = require('gulp');
var jsonlint = require("gulp-jsonlint");
var transform = require('gulp-transform');
var rename = require('gulp-rename');
var jsonSchema = require("gulp-json-schema");
var hashCode = function (str) {
var hash = 0;
if (str.length === 0) return hash;
for (var i = 0; i < str.length; i++) {
var char = str.charCodeAt(i);
hash = ((hash << 5) - hash) + char;
hash = hash & hash; // Convert to 32bit integer
}
return Math.abs(hash);
};
var entityMap = {
"&": "&",
"<": "<",
">": ">",
'"': '"',
"'": ''',
"/": '/'
};
/**
* Escape a HTML string.
* @param string
* @returns {string}
*/
function escapeHTML(string) {
return String(string).replace(/[&<>"'\/]/g, function (s) {
return entityMap[s];
});
}
/**
* Validate the events.json file against a schema.
*
* This task will emit the errors and WILL NOT fail if there is any not defined structure. But it will emit emit a warning
* if a structure ist not defined.
*/
gulp.task('validate-events', function () {
return gulp.src("./events.json")
.pipe(jsonlint())
.pipe(jsonlint.failOnError())
.pipe(jsonSchema({
schema: "./events.schema.json",
missing: "warn",
emitError: true,
}));
});
/**
* Generate the xml file based on the events.
*/
gulp.task('generate-xml', gulp.series('validate-events', function () {
return gulp.src("./events.json")
.pipe(jsonlint())
.pipe(jsonlint.failOnError())
.pipe(jsonlint.reporter())
.pipe(transform(function (contents) {
var today = new Date();
today = new Date(today.setHours(0, 0, 0));
var events = JSON.parse(contents);
console.log('found ' + events.length + ' events');
var xml = [];
xml.push("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
xml.push("<rss version=\"2.0\">");
xml.push("<channel>");
xml.push("<title>Hackergarten Events</title>");
xml.push("<link>https://hackergarten.net</link>");
xml.push("<language>en-en</language>");
for (var i = 0; i < events.length; i++) {
var event = events[i];
var hash = hashCode(event.date + event.location);
if (new Date(event.date) >= today) {
// This code is duplicated in eventlist.js
if (event.title && event.location) { // old JSON format without venue and address
event.title = "on " + event.date + " at " + event.title + " in " + event.location;
} else if (event.venue && event.address) { // new JSON format with venue and address
event.title = "on " + event.date + " at " + event.venue + ", " + event.address;
} else { // fallback with title and date
event.title += " on " + event.date;
}
xml.push("<item>");
xml.push("<title>" + escapeHTML("Hackergarten " + event.title) + "</title>");
xml.push("<link>https://hackergarten.net/#event-" + hash + "</link>");
xml.push("<guid>" + hash + "</guid>");
xml.push("</item>\n");
}
}
xml.push("</channel>");
xml.push("</rss>");
return xml.join('');
}))
.pipe(rename("feed.xml"))
.pipe(gulp.dest('.'));
}));
/**
* Generate the HTML file containing the top contributed projects.
*/
gulp.task('generate-projects', gulp.series('validate-events', function () {
let projects = new Map();
function addProject(project, url) {
let value = projects.get(project) || {url: url, count: 0};
value.count++;
projects.set(project, value);
}
return gulp.src("./events.json")
.pipe(jsonlint())
.pipe(jsonlint.failOnError())
.pipe(jsonlint.reporter())
.pipe(transform(function(contents) {
let events = JSON.parse(contents);
let html = [];
html.push('<!DOCTYPE html>');
html.push('<html lang="en">');
html.push('<head>');
html.push('<meta charset="utf-8"/>');
html.push('<title>Top Contributed Projects</title>');
html.push('<link href="https://cdn.jsdelivr.net/bootstrap/3.3.0/css/bootstrap.min.css" rel="stylesheet"/>');
html.push('<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>');
html.push('<script src="https://cdn.jsdelivr.net/bootstrap/3.3.0/js/bootstrap.min.js"></script>');
html.push('</head>');
html.push('<body>');
html.push('<table class="table table-striped"><tr><th>#</th><th>Project</th><th>Count</th></tr>');
for (let i = 0; i < events.length; i++) {
let event = events[i];
if (event.achievements) {
for (let j = 0; j < event.achievements.length; j++) {
let achievement = event.achievements[j];
if (achievement.url) {
if (achievement.url.startsWith("https://github.com/")) {
let urlParts = achievement.url.split("/");
let project = urlParts[4];
let url = 'https://github.com/' + urlParts[3] + '/' + urlParts[4];
if (project !== undefined) addProject(project, url);
}
}
}
}
}
let sortedProjects = new Map([...projects].sort((a, b) =>
a[1].count === b[1].count ? 0 : a[1].count < b[1].count ? 1 : -1));
let i = 1;
sortedProjects.forEach((value, project) => {
html.push('<tr>');
html.push('<td>' + i++ + '</td>');
html.push('<td><a href="' + value.url + '" target="_top">' + project + '</a></td>');
html.push('<td>' + value.count + '</td>');
html.push('</tr>');
});
html.push('</table>');
html.push('</body>');
html.push('</html>');
return html.join('');
}))
.pipe(rename("projects.html"))
.pipe(gulp.dest('.'));
}));
gulp.task('default', gulp.series('generate-xml', 'generate-projects'));