Skip to content

Commit

Permalink
Made it a CLI app and fixed it to work with new FA versions
Browse files Browse the repository at this point in the history
Moved away from a webpage to a CLI app. Font Awesome updated the locations of the font files and css files, fixed to reflect those changes
  • Loading branch information
jonbarrow committed Jun 15, 2019
1 parent 2ea4e3b commit 359beb2
Show file tree
Hide file tree
Showing 9 changed files with 577 additions and 1,495 deletions.
38 changes: 38 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"env": {
"node": true,
"commonjs": true,
"es6": true
},
"parserOptions": {
"ecmaVersion": 2017
},
"extends": "eslint:recommended",
"rules": {
"no-case-declarations": "off",
"no-empty": "off",
"no-console": "off",
"linebreak-style": "off",
"prefer-const": "error",
"no-var": "error",
"one-var": [
"error",
"never"
],
"indent": [
"error",
"tab",
{
"SwitchCase": 1
}
],
"quotes": [
"error",
"single"
],
"semi": [
"error",
"always"
]
}
}
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,8 @@ typings/
.vuepress/dist

# Serverless directories
.serverless
.serverless

# Custom
t.js
*.zip
5 changes: 0 additions & 5 deletions config.json

This file was deleted.

172 changes: 70 additions & 102 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,127 +1,95 @@
const express = require('express');
const morgan = require('morgan');
const pug = require('pug');
const url = require('url');
const path = require('path');
const fs = require("fs");
const got = require('got');
const prompts = require('prompts');
const Spinnies = require('spinnies');
const AdmZip = require('adm-zip');
const app = express();
const router = express.Router();
const config = require('./config.json');
require('colors');
const async = require('async');

const FA_RELEASES_PAGE = 'https://github.com/FortAwesome/Font-Awesome/releases';
const spinnies = new Spinnies();

const DATA_SET = [
{
path: 'css/all',
extensions: ['css']
},
{
path: 'webfonts/fa-regular-400',
extensions: ['eot', 'svg', 'ttf', 'woff', 'woff2']
},
{
path: 'webfonts/fa-solid-900',
extensions: ['eot', 'svg', 'ttf', 'woff', 'woff2']
},
{
path: 'webfonts/fa-brands-400',
extensions: ['eot', 'svg', 'ttf', 'woff', 'woff2']
const GOT_OPTIONS = {
headers: {
Origin: 'https://fontawesome.com',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36'
}
];

// START APPLICATION
app.set('etag', false);
app.use(express.static(`${__dirname}/public`));
};

// Create router
app.use(morgan('dev'));
router.use(express.json());
router.use(express.urlencoded({
extended: true
}));
const FA_RELEASES_PAGE = 'https://github.com/FortAwesome/Font-Awesome/releases';
const FA_PRO_ASSET_BASE = 'https://kit-pro.fontawesome.com';

// Views
app.set('views', __dirname + '/views');
app.set('view engine', 'pug');
const fontUrlRegex = /url\((.*?)\)/gm;
const githubSpansRegex = /<div class="f1 flex-auto min-width-0 text-normal">(.+?)<\/div>/gms;
const githubReleasesRegex =/>(.*?)</;

app.engine('pug', pug.__express);
main();

app.get('/', async (request, response) => {
const versions = await getFA5Versions();
response.render('home', {
versions
});
});

app.get('/fapro', async (request, response) => {
const query = request.query;
async function main() {
spinnies.add('loading-versions', { text: 'Loading Font Awesome 5 versions' });
const versions = await getFA5Versions();
const latestVersion = versions[0];
spinnies.succeed('loading-versions', { text: 'Loaded Font Awesome 5 versions' });

const {version} = await prompts([
{
type: 'select',
name: 'version',
message: 'Select a version',
choices: versions.map(version => ({ title: `v${version}`, value: version })),
}
]);

if (!query.v || !versions.includes(query.v)) {
response.status(404);
return response.send();
}
if (!version) return;

spinnies.add('ripping-start', { text: `Ripping FA5 v${version}` });

const version = query.v.replace('Release ', '');
const zip = new AdmZip();
for (const file of DATA_SET) {
for (const extension of file.extensions) {
const file_name = `${file.path}.${extension}`;
const file_url = `https://pro.fontawesome.com/releases/v${version}/${file_name}`;
try {
const file_response = await got(file_url, {
encoding: null,
headers: {
Origin: 'https://fontawesome.com'
}
});
const data = file_response.body;

zip.addFile(file_name, data);

console.log(`Added file ${file_name} to zip`);
} catch (error) {
console.log(error);
}
}
}

response.write(zip.toBuffer(), 'binary');
response.end(null, 'binary');
});

// 404 handler
router.use((request, response) => {
response.status(404);
response.send();
});

// non-404 error handler
router.use((error, request, response) => {
const status = error.status || 500;
response.status(status);
response.json({
app: 'api',
status: status,
error: error.message
const css = await got.get(`${FA_PRO_ASSET_BASE}/releases/v${latestVersion}/css/pro.min.css`, GOT_OPTIONS);
GOT_OPTIONS.headers.Referer = `${FA_PRO_ASSET_BASE}/releases/v${latestVersion}/css/pro.min.css`;
GOT_OPTIONS.encoding = null;

const fontUrls = css.body
.match(fontUrlRegex).map(url => url.replace('url(', '').replace(')', '').replace('../../..', FA_PRO_ASSET_BASE))
.filter(url => url.includes(version));

const cssFile = css.body.replace(/https:\/\/kit-free.fontawesome.com\/algo\/1/g, '..').replace(/..\/..\/..\/algo\/1/g, '..');
zip.addFile('css/all.css', Buffer.from(cssFile));

async.each(fontUrls, (fontUrl, callback) => {

const fileName = path.basename(url.parse(fontUrl).pathname);
spinnies.add(fontUrl, { text: `Downloading ${fileName} from ${fontUrl}` });

got(fontUrl, GOT_OPTIONS)
.then(response => {;
const data = response.body;

zip.addFile(`fonts/${fileName}`, data);

spinnies.succeed(fontUrl, { text: `Added file ${fileName} to zip` });
callback();
})
.catch(() => {
spinnies.fail(fontUrl, { text: `Failed to add file ${fileName} to zip!` })
callback();
});
}, () => {
fs.writeFileSync(`${__dirname}/fa5-v${version}.zip`, zip.toBuffer());
spinnies.succeed('ripping-start', { text: `Ripped FA5 v${version}. Saved to ${__dirname}/fa5-v${version}.zip` });
});
});

// Starts the server
app.listen(config.http.port, () => {
console.log(('Started '.green + 'on port '.blue + new String(config.http.port).yellow).bold);
});
}

async function getFA5Versions() {

// I decided to use RegEx on HTML rather than use the API to try and get around ratelimits
// This will break if GH changes the html layout
const response = await got(FA_RELEASES_PAGE);
const html = response.body;

const spans = html.match(/<div class="f1 flex-auto min-width-0 text-normal">(.+?)<\/div>/gms);
const spans = html.match(githubSpansRegex);

const versions = spans.map(span => {
return span.match(/>(.*?)</)[1];
return span.match(githubReleasesRegex)[1].replace('Release', '').trim();
});

return versions;
Expand Down
Loading

0 comments on commit 359beb2

Please sign in to comment.