Updated web script to generate landing page
Prioritized webber over builder to make sure it never times out. Prioritized the index page over the rest of the pages as it takes long due to api calls.
This commit is contained in:
@ -10,8 +10,8 @@ before_install:
|
||||
script:
|
||||
- npm run tagger
|
||||
- npm run linter
|
||||
- npm run builder
|
||||
- npm run webber
|
||||
- npm run builder
|
||||
- npm run packager
|
||||
- npm run tester
|
||||
after_success:
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<link rel="stylesheet" href="./mini.css">
|
||||
<title>30 seconds of code - Beginner Section</title>
|
||||
<title>Snippets for Beginners - 30 seconds of code</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="description" content="Curated collection of useful Javascript snippets that you can understand in 30 seconds or less.">
|
||||
<meta name="keywords" content="javascript, snippets, code, programming">
|
||||
|
||||
2336
docs/index.html
2336
docs/index.html
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -760,3 +760,7 @@ button.next {
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
body {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
@ -62,6 +62,15 @@ const optimizeNodes = (data, regexp, replacer) => {
|
||||
} while (count > 0);
|
||||
return output;
|
||||
};
|
||||
// Randomizes the order of the values of an array, returning a new array.
|
||||
const shuffle = ([...arr]) => {
|
||||
let m = arr.length;
|
||||
while (m) {
|
||||
const i = Math.floor(Math.random() * m--);
|
||||
[arr[m], arr[i]] = [arr[i], arr[m]];
|
||||
}
|
||||
return arr;
|
||||
};
|
||||
// Capitalizes the first letter of a string
|
||||
const capitalize = (str, lowerRest = false) =>
|
||||
str.slice(0, 1).toUpperCase() + (lowerRest ? str.slice(1).toLowerCase() : str.slice(1));
|
||||
@ -69,4 +78,4 @@ const capitalize = (str, lowerRest = false) =>
|
||||
const isTravisCI = () => 'TRAVIS' in process.env && 'CI' in process.env;
|
||||
// Creates a hash for a value using the SHA-256 algorithm.
|
||||
const hashData = val => crypto.createHash('sha256').update(val).digest('hex');
|
||||
module.exports = {readSnippets, readTags, optimizeNodes, capitalize, objectFromPairs, isTravisCI, hashData};
|
||||
module.exports = {readSnippets, readTags, optimizeNodes, capitalize, objectFromPairs, isTravisCI, hashData, shuffle};
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
*/
|
||||
// Load modules
|
||||
const fs = require('fs-extra'),
|
||||
https = require('https'),
|
||||
path = require('path'),
|
||||
chalk = require('chalk'),
|
||||
md = require('markdown-it')(),
|
||||
@ -58,6 +59,7 @@ let snippets = {},
|
||||
beginnerStartPart = '',
|
||||
beginnerEndPart = '',
|
||||
beginnerOutput = '',
|
||||
indexStaticFile = '',
|
||||
pagesOutput = [];
|
||||
tagDbData = {};
|
||||
// Start the timer of the script
|
||||
@ -65,13 +67,15 @@ console.time('Webber');
|
||||
// Synchronously read all snippets and sort them as necessary (case-insensitive)
|
||||
snippets = util.readSnippets(snippetsPath);
|
||||
|
||||
// Load static parts for the index.html file
|
||||
// Load static parts for all pages
|
||||
try {
|
||||
startPart = fs.readFileSync(path.join(staticPartsPath, 'page-start.html'), 'utf8');
|
||||
endPart = fs.readFileSync(path.join(staticPartsPath, 'page-end.html'), 'utf8');
|
||||
|
||||
beginnerStartPart = fs.readFileSync(path.join(staticPartsPath, 'beginner-page-start.html'), 'utf8');
|
||||
beginnerEndPart = fs.readFileSync(path.join(staticPartsPath, 'beginner-page-end.html'), 'utf8');
|
||||
|
||||
indexStaticFile = fs.readFileSync(path.join(staticPartsPath, 'index.html'), 'utf8');
|
||||
} catch (err) {
|
||||
// Handle errors (hopefully not!)
|
||||
console.log(`${chalk.red('ERROR!')} During static part loading: ${err}`);
|
||||
@ -79,7 +83,67 @@ try {
|
||||
}
|
||||
// Load tag data from the database
|
||||
tagDbData = util.readTags();
|
||||
// Create the output for the index.html file
|
||||
// Create the output for the index.html file (only locally or on Travis CRON or custom job)
|
||||
if(!util.isTravisCI() || (util.isTravisCI() && (process.env['TRAVIS_EVENT_TYPE'] === 'cron' || process.env['TRAVIS_EVENT_TYPE'] === 'api'))) {
|
||||
try {
|
||||
// Shuffle the array of snippets, pick 3
|
||||
let indexDailyPicks = '';
|
||||
let shuffledSnippets = util.shuffle(Object.keys(snippets)).slice(0,3);
|
||||
const dailyPicks = Object.keys(snippets)
|
||||
.filter(key => shuffledSnippets.includes(key))
|
||||
.reduce((obj, key) => {
|
||||
obj[key] = snippets[key];
|
||||
return obj;
|
||||
}, {});
|
||||
|
||||
// Generate the html for the picked snippets
|
||||
for (let snippet of Object.entries(dailyPicks))
|
||||
indexDailyPicks +=
|
||||
'<div class="card fluid pick">' +
|
||||
md
|
||||
.render(`\n${snippets[snippet[0]]}`)
|
||||
.replace(/<h3/g, `<h3 id="${snippet[0].toLowerCase()}" class="section double-padded"`)
|
||||
.replace(/<\/h3>/g, `${snippet[1].includes('advanced')?'<mark class="tag">advanced</mark>':''}</h3>`)
|
||||
.replace(/<\/h3>/g, '</h3><div class="section double-padded">')
|
||||
.replace(/<pre><code class="language-js">([^\0]*?)<\/code><\/pre>/gm, (match, p1) => `<pre class="language-js">${Prism.highlight(unescapeHTML(p1), Prism.languages.javascript)}</pre>`)
|
||||
.replace(/<\/pre>\s+<pre/g, '</pre><label class="collapse">Show examples</label><pre') +
|
||||
'<button class="primary clipboard-copy">📋 Copy to clipboard</button>' +
|
||||
'</div></div>';
|
||||
// Select the first snippet from today's picks
|
||||
indexDailyPicks = indexDailyPicks.replace('card fluid pick', 'card fluid pick selected');
|
||||
// Optimize punctuation nodes
|
||||
indexDailyPicks = util.optimizeNodes(indexDailyPicks, /<span class="token punctuation">([^\0<]*?)<\/span>([\n\r\s]*)<span class="token punctuation">([^\0]*?)<\/span>/gm, (match, p1, p2, p3) => `<span class="token punctuation">${p1}${p2}${p3}</span>`);
|
||||
// Optimize operator nodes
|
||||
indexDailyPicks = util.optimizeNodes(indexDailyPicks, /<span class="token operator">([^\0<]*?)<\/span>([\n\r\s]*)<span class="token operator">([^\0]*?)<\/span>/gm, (match, p1, p2, p3) => `<span class="token operator">${p1}${p2}${p3}</span>`);
|
||||
// Optimize keyword nodes
|
||||
indexDailyPicks = util.optimizeNodes(indexDailyPicks, /<span class="token keyword">([^\0<]*?)<\/span>([\n\r\s]*)<span class="token keyword">([^\0]*?)<\/span>/gm, (match, p1, p2, p3) => `<span class="token keyword">${p1}${p2}${p3}</span>`);
|
||||
// Put the daily picks into the page
|
||||
indexStaticFile = indexStaticFile.replace('$daily-picks',indexDailyPicks);
|
||||
// Use the Github API to get the needed data
|
||||
const githubApi = 'api.github.com';
|
||||
const headers = { 'User-Agent' : '30-seconds-of-code'};
|
||||
// Send requests and wait for responses, write to the page
|
||||
https.get({host: githubApi, path: '/repos/chalarangelo/30-seconds-of-code/commits?per_page=1', headers: headers}, resCommits =>{
|
||||
https.get({host: githubApi, path: '/repos/chalarangelo/30-seconds-of-code/contributors?per_page=1', headers: headers}, resContributors => {
|
||||
https.get({host: githubApi, path: '/repos/chalarangelo/30-seconds-of-code/stargazers?per_page=1', headers: headers}, resStars => {
|
||||
let commits = resCommits.headers.link.split('&').slice(-1)[0].replace(/[^\d]/g,''),
|
||||
contribs = resContributors.headers.link.split('&').slice(-1)[0].replace(/[^\d]/g,''),
|
||||
stars = resStars.headers.link.split('&').slice(-1)[0].replace(/[^\d]/g,'');
|
||||
indexStaticFile = indexStaticFile.replace(/\$snippet-count/g, Object.keys(snippets).length).replace(/\$commit-count/g,commits).replace(/\$contrib-count/g,contribs).replace(/\$star-count/g,stars);
|
||||
// Generate 'index.html' file
|
||||
fs.writeFileSync(path.join(docsPath, 'index.html'), indexStaticFile);
|
||||
console.log(`${chalk.green('SUCCESS!')} index.html file generated!`);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
} catch (err) {
|
||||
console.log(`${chalk.red('ERROR!')} During index.html generation: ${err}`);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Create the output for individual category pages
|
||||
try {
|
||||
// Add the start static part
|
||||
output += `${startPart + '\n'}`;
|
||||
@ -125,6 +189,7 @@ try {
|
||||
'</div></div>';
|
||||
// Add the ending static part
|
||||
localOutput += `\n${endPart + '\n'}`;
|
||||
// Optimize punctuation nodes
|
||||
localOutput = util.optimizeNodes(localOutput, /<span class="token punctuation">([^\0<]*?)<\/span>([\n\r\s]*)<span class="token punctuation">([^\0]*?)<\/span>/gm, (match, p1, p2, p3) => `<span class="token punctuation">${p1}${p2}${p3}</span>`);
|
||||
// Optimize operator nodes
|
||||
localOutput = util.optimizeNodes(localOutput, /<span class="token operator">([^\0<]*?)<\/span>([\n\r\s]*)<span class="token operator">([^\0]*?)<\/span>/gm, (match, p1, p2, p3) => `<span class="token operator">${p1}${p2}${p3}</span>`);
|
||||
@ -153,8 +218,6 @@ try {
|
||||
fs.writeFileSync(path.join(docsPath, page.tag+'.html'), page.content);
|
||||
console.log(`${chalk.green('SUCCESS!')} ${page.tag}.html file generated!`);
|
||||
})
|
||||
// Write to the index.html file
|
||||
//fs.writeFileSync(path.join(docsPath, 'index.html'), output);
|
||||
} catch (err) {
|
||||
// Handle errors (hopefully not!)
|
||||
console.log(`${chalk.red('ERROR!')} During category page generation: ${err}`);
|
||||
@ -162,7 +225,6 @@ try {
|
||||
}
|
||||
|
||||
// Create the output for the beginner.html file
|
||||
|
||||
try {
|
||||
// Add the static part
|
||||
beginnerOutput += `${beginnerStartPart + '\n'}`;
|
||||
@ -190,6 +252,7 @@ try {
|
||||
'<button class="primary clipboard-copy">📋 Copy to clipboard</button>' +
|
||||
'</div></div></div></div>';
|
||||
|
||||
// Optimize punctuation nodes
|
||||
beginnerOutput = util.optimizeNodes(beginnerOutput, /<span class="token punctuation">([^\0<]*?)<\/span>([\n\r\s]*)<span class="token punctuation">([^\0]*?)<\/span>/gm, (match, p1, p2, p3) => `<span class="token punctuation">${p1}${p2}${p3}</span>`);
|
||||
// Optimize operator nodes
|
||||
beginnerOutput = util.optimizeNodes(beginnerOutput, /<span class="token operator">([^\0<]*?)<\/span>([\n\r\s]*)<span class="token operator">([^\0]*?)<\/span>/gm, (match, p1, p2, p3) => `<span class="token operator">${p1}${p2}${p3}</span>`);
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<link rel="stylesheet" href="./mini.css">
|
||||
<title>30 seconds of code - Beginner Section</title>
|
||||
<title>Snippets for Beginners - 30 seconds of code</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="description" content="Curated collection of useful Javascript snippets that you can understand in 30 seconds or less.">
|
||||
<meta name="keywords" content="javascript, snippets, code, programming">
|
||||
|
||||
@ -24,19 +24,19 @@
|
||||
<div class="row">
|
||||
<div class="col-sm-3 no-padding" style="text-align: center">
|
||||
<svg version="1.1" width="24" height="24" viewBox="0 0 14 16" class="octicon octicon-code" aria-hidden="true"><path fill-rule="evenodd" d="M9.5 3L8 4.5 11.5 8 8 11.5 9.5 13 14 8 9.5 3zm-5 0L0 8l4.5 5L6 11.5 2.5 8 6 4.5 4.5 3z"/></svg>
|
||||
<p><span id="snippet-count">295</span><br/>snippets</p>
|
||||
<p><span id="snippet-count">$snippet-count</span><br/>snippets</p>
|
||||
</div>
|
||||
<div class="col-sm-3 no-padding" style="text-align: center">
|
||||
<svg version="1.1" width="24" height="24" viewBox="0 0 16 16" class="octicon octicon-organization" aria-hidden="true"><path fill-rule="evenodd" d="M16 12.999c0 .439-.45 1-1 1H7.995c-.539 0-.994-.447-.995-.999H1c-.54 0-1-.561-1-1 0-2.634 3-4 3-4s.229-.409 0-1c-.841-.621-1.058-.59-1-3 .058-2.419 1.367-3 2.5-3s2.442.58 2.5 3c.058 2.41-.159 2.379-1 3-.229.59 0 1 0 1s1.549.711 2.42 2.088A6.78 6.78 0 0 1 10 8.999s.229-.409 0-1c-.841-.62-1.058-.59-1-3 .058-2.419 1.367-3 2.5-3s2.437.581 2.495 3c.059 2.41-.158 2.38-1 3-.229.59 0 1 0 1s3.005 1.366 3.005 4z"/></svg>
|
||||
<p><span id="contrib-count">114</span><br/>contributors</p>
|
||||
<p><span id="contrib-count">$contrib-count</span><br/>contributors</p>
|
||||
</div>
|
||||
<div class="col-sm-3 no-padding" style="text-align: center">
|
||||
<svg version="1.1" width="24" height="24" viewBox="0 0 10 16" class="octicon octicon-git-branch" aria-hidden="true"><path fill-rule="evenodd" d="M10 5c0-1.11-.89-2-2-2a1.993 1.993 0 0 0-1 3.72v.3c-.02.52-.23.98-.63 1.38-.4.4-.86.61-1.38.63-.83.02-1.48.16-2 .45V4.72a1.993 1.993 0 0 0-1-3.72C.88 1 0 1.89 0 3a2 2 0 0 0 1 1.72v6.56c-.59.35-1 .99-1 1.72 0 1.11.89 2 2 2 1.11 0 2-.89 2-2 0-.53-.2-1-.53-1.36.09-.06.48-.41.59-.47.25-.11.56-.17.94-.17 1.05-.05 1.95-.45 2.75-1.25S8.95 7.77 9 6.73h-.02C9.59 6.37 10 5.73 10 5zM2 1.8c.66 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2C1.35 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2zm0 12.41c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm6-8c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z"/></svg>
|
||||
<p><span id="commit-count">3028</span><br/>commits</p>
|
||||
<p><span id="commit-count">$commit-count</span><br/>commits</p>
|
||||
</div>
|
||||
<div class="col-sm-3 no-padding" style="text-align: center">
|
||||
<svg version="1.1" width="24" height="24" viewBox="0 0 14 16" class="octicon octicon-star" aria-hidden="true"><path fill-rule="evenodd" d="M14 6l-4.9-.64L7 1 4.9 5.36 0 6l3.6 3.26L2.67 14 7 11.67 11.33 14l-.93-4.74L14 6z"/></svg>
|
||||
<p><span id="star-count">19459</span><br/>stars</p>
|
||||
<p><span id="star-count">$star-count</span><br/>stars</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -65,16 +65,7 @@
|
||||
<div id="pick-slider">
|
||||
<button class="next"><svg version="1.1" width="8" height="16" viewBox="0 0 8 16" class="octicon octicon-chevron-right" aria-hidden="true"><path fill-rule="evenodd" d="M7.5 8l-5 5L1 11.5 4.75 8 1 4.5 2.5 3l5 5z"/></svg></button>
|
||||
<button class="previous"><svg version="1.1" width="8" height="16" viewBox="0 0 8 16" class="octicon octicon-chevron-left" aria-hidden="true"><path fill-rule="evenodd" d="M6 3l1.5 1.5L3.75 8l3.75 3.5L6 13 1 8l5-5z"/></svg></button>
|
||||
<div class="card fluid pick selected">
|
||||
<h3 id="bottomvisible" class="section double-padded">bottomVisible</h3><div class="section double-padded"><p>Returns <code>true</code> if the bottom of the page is visible, <code>false</code> otherwise.</p><p>Use <code>scrollY</code>, <code>scrollHeight</code> and <code>clientHeight</code> to determine if the bottom of the page is visible.</p><pre class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">bottomVisible</span> <span class="token operator">=</span> <span class="token punctuation">()</span> <span class="token operator">=></span>
|
||||
document<span class="token punctuation">.</span>documentElement<span class="token punctuation">.</span>clientHeight <span class="token operator">+</span> window<span class="token punctuation">.</span>scrollY <span class="token operator">>=</span>
|
||||
<span class="token punctuation">(</span>document<span class="token punctuation">.</span>documentElement<span class="token punctuation">.</span>scrollHeight <span class="token operator">||</span> document<span class="token punctuation">.</span>documentElement<span class="token punctuation">.</span>clientHeight<span class="token punctuation">);</span>
|
||||
</pre><label class="collapse">Show examples</label><pre class="language-js"><span class="token function">bottomVisible</span><span class="token punctuation">();</span> <span class="token comment">// true</span>
|
||||
</pre></div></div>
|
||||
<div class="card fluid pick"><h3 id="ary" class="section double-padded">ary</h3><div class="section double-padded"><p>Creates a function that accepts up to <code>n</code> arguments, ignoring any additional arguments.</p><p>Call the provided function, <code>fn</code>, with up to <code>n</code> arguments, using <code>Array.slice(0,n)</code> and the spread operator (<code>...</code>).</p><pre class="language-js"><span class="token keyword">const</span> <span class="token function-variable function">ary</span> <span class="token operator">=</span> <span class="token punctuation">(</span>fn<span class="token punctuation">,</span> n<span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token operator">...</span>args<span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">fn</span><span class="token punctuation">(</span><span class="token operator">...</span>args<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> n<span class="token punctuation">));</span>
|
||||
</pre><label class="collapse">Show examples</label><pre class="language-js"><span class="token keyword">const</span> firstTwoMax <span class="token operator">=</span> <span class="token function">ary</span><span class="token punctuation">(</span>Math<span class="token punctuation">.</span>max<span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">);
|
||||
[[</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">,</span> <span class="token string">'a'</span><span class="token punctuation">], [</span><span class="token number">8</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">], [</span><span class="token number">10</span><span class="token punctuation">]].</span><span class="token function">map</span><span class="token punctuation">(</span>x <span class="token operator">=></span> <span class="token function">firstTwoMax</span><span class="token punctuation">(</span><span class="token operator">...</span>x<span class="token punctuation">));</span> <span class="token comment">// [6, 8, 10]</span>
|
||||
</pre></div></div>
|
||||
$daily-picks
|
||||
<br/>
|
||||
</div>
|
||||
</div>
|
||||
@ -191,7 +182,7 @@
|
||||
<script>
|
||||
window.onload = function(){
|
||||
let counters = ['#snippet-count', '#contrib-count', '#commit-count', '#star-count'];
|
||||
let values = [295,114,3028,19459];
|
||||
let values = [$snippet-count,$contrib-count,$commit-count,$star-count];
|
||||
let steps = [1,1,8,42];
|
||||
runCounter(counters[0],0,values[0],steps[0]);
|
||||
runCounter(counters[1],0,values[1],steps[1]);
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user