Removed xo

This commit is contained in:
Kaustubh Ladiya 2020-01-12 15:08:32 +05:30
parent 566c7aea3a
commit ee3ccb26ab
No known key found for this signature in database
GPG Key ID: A77FFE5465BD4E7D
13 changed files with 478 additions and 469 deletions

18
.eslintrc.json Normal file
View File

@ -0,0 +1,18 @@
{
"env": {
"browser": true,
"es6": true,
"node": true
},
"extends": "eslint:recommended",
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parserOptions": {
"ecmaVersion": 2018,
"sourceType": "module"
},
"rules": {
}
}

View File

@ -2,4 +2,3 @@
[![Dependency Status](https://img.shields.io/david/k4ustu3h/gitfolio?style=for-the-badge)](https://david-dm.org/k4ustu3h/gitfolio) [![Dependency Status](https://img.shields.io/david/k4ustu3h/gitfolio?style=for-the-badge)](https://david-dm.org/k4ustu3h/gitfolio)
[![devDependencies Status](https://img.shields.io/david/dev/k4ustu3h/gitfolio?style=for-the-badge)](https://david-dm.org/k4ustu3h/gitfolio?type=dev) [![devDependencies Status](https://img.shields.io/david/dev/k4ustu3h/gitfolio?style=for-the-badge)](https://david-dm.org/k4ustu3h/gitfolio?type=dev)
[![Code Style: Prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=for-the-badge)](https://github.com/prettier/prettier) [![Code Style: Prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=for-the-badge)](https://github.com/prettier/prettier)
[![XO code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg?style=for-the-badge)](https://github.com/xojs/xo)

74
api.js
View File

@ -10,46 +10,46 @@ const got = require("got");
* @param {'desc' | 'asc'} [opts.order] * @param {'desc' | 'asc'} [opts.order]
*/ */
async function getRepos(username, opts = {}) { async function getRepos(username, opts = {}) {
let tempRepos; let tempRepos;
let page = 1; let page = 1;
let repos = []; let repos = [];
const {sort} = opts; const { sort } = opts;
const order = opts.order || (sort === "full_name" ? "asc" : "desc"); const order = opts.order || (sort === "full_name" ? "asc" : "desc");
const types = opts.types || []; const types = opts.types || [];
let type = "all"; let type = "all";
if ( if (
types.includes("all") || types.includes("all") ||
(types.includes("owner") && types.includes("member")) (types.includes("owner") && types.includes("member"))
) { ) {
type = "all"; type = "all";
} else if (types.includes("member")) { } else if (types.includes("member")) {
type = "member"; type = "member";
} }
do { do {
let requestUrl = `https://api.github.com/users/${username}/repos?per_page=100&page=${page++}&type=${type}`; let requestUrl = `https://api.github.com/users/${username}/repos?per_page=100&page=${page++}&type=${type}`;
if (sort && sort !== "star") { if (sort && sort !== "star") {
requestUrl += `&sort=${sort}&direction=${order}`; requestUrl += `&sort=${sort}&direction=${order}`;
} }
tempRepos = await got(requestUrl); tempRepos = await got(requestUrl);
tempRepos = JSON.parse(tempRepos.body); tempRepos = JSON.parse(tempRepos.body);
repos = repos.concat(tempRepos); repos = repos.concat(tempRepos);
} while (tempRepos.length === 100); } while (tempRepos.length === 100);
if (sort === "star") { if (sort === "star") {
repos = repos.sort((a, b) => { repos = repos.sort((a, b) => {
if (order === "desc") { if (order === "desc") {
return b.stargazers_count - a.stargazers_count; return b.stargazers_count - a.stargazers_count;
} }
return a.stargazers_count - b.stargazers_count; return a.stargazers_count - b.stargazers_count;
}); });
} }
return repos; return repos;
} }
/** /**
@ -57,11 +57,11 @@ async function getRepos(username, opts = {}) {
* @param {string} username * @param {string} username
*/ */
async function getUser(username) { async function getUser(username) {
const res = await got(`https://api.github.com/users/${username}`); const res = await got(`https://api.github.com/users/${username}`);
return JSON.parse(res.body); return JSON.parse(res.body);
} }
module.exports = { module.exports = {
getRepos, getRepos,
getUser getUser
}; };

View File

@ -1,42 +1,42 @@
importScripts( importScripts(
"https://storage.googleapis.com/workbox-cdn/releases/3.6.1/workbox-sw.js" "https://storage.googleapis.com/workbox-cdn/releases/3.6.1/workbox-sw.js"
); );
if (workbox) { if (workbox) {
workbox.setConfig({ workbox.setConfig({
debug: false debug: false
}); });
const defaultStrategy = workbox.strategies.networkFirst({ const defaultStrategy = workbox.strategies.networkFirst({
cacheName: "fallback", cacheName: "fallback",
plugins: [ plugins: [
new workbox.expiration.Plugin({ new workbox.expiration.Plugin({
maxEntries: 128, maxEntries: 128,
maxAgeSeconds: 7 * 24 * 60 * 60, // 1 week maxAgeSeconds: 7 * 24 * 60 * 60, // 1 week
purgeOnQuotaError: true // Opt-in to automatic cleanup purgeOnQuotaError: true // Opt-in to automatic cleanup
}), }),
new workbox.cacheableResponse.Plugin({ new workbox.cacheableResponse.Plugin({
statuses: [0, 200] // For opague requests statuses: [0, 200] // For opague requests
}) })
] ]
}); });
workbox.routing.setDefaultHandler(args => { workbox.routing.setDefaultHandler(args => {
if (args.event.request.method === "GET") { if (args.event.request.method === "GET") {
return defaultStrategy.handle(args); // Use default strategy return defaultStrategy.handle(args); // Use default strategy
} }
return null; return null;
}); });
workbox.routing.registerRoute( workbox.routing.registerRoute(
new RegExp(/.*\.(?:js|css)/g), new RegExp(/.*\.(?:js|css)/g),
workbox.strategies.networkFirst() workbox.strategies.networkFirst()
); );
workbox.routing.registerRoute( workbox.routing.registerRoute(
new RegExp(/.*\.(?:png|jpg|jpeg|svg|gif|webp)/g), new RegExp(/.*\.(?:png|jpg|jpeg|svg|gif|webp)/g),
workbox.strategies.cacheFirst() workbox.strategies.cacheFirst()
); );
} else { } else {
console.log("No workbox on this browser 😬"); console.log("No workbox on this browser 😬");
} }

View File

@ -5,63 +5,63 @@ const program = require("commander");
process.env.OUT_DIR = process.env.OUT_DIR || process.cwd(); process.env.OUT_DIR = process.env.OUT_DIR || process.cwd();
const {buildCommand} = require("../build"); const { buildCommand } = require("../build");
const {updateCommand} = require("../update"); const { updateCommand } = require("../update");
const {uiCommand} = require("../ui"); const { uiCommand } = require("../ui");
const {runCommand} = require("../run"); const { runCommand } = require("../run");
const {version} = require("../package.json"); const { version } = require("../package.json");
function collect(val, memo) { function collect(val, memo) {
memo.push(val); memo.push(val);
return memo; return memo;
} }
program program
.command("build <username>") .command("build <username>")
.description( .description(
"Build site with your GitHub username. This will be used to customize your site" "Build site with your GitHub username. This will be used to customize your site"
) )
.option("-t, --theme [theme]", "specify a theme to use", "light") .option("-t, --theme [theme]", "specify a theme to use", "light")
.option("-b, --background [background]", "set the background image") .option("-b, --background [background]", "set the background image")
.option("-f, --fork", "includes forks with repos") .option("-f, --fork", "includes forks with repos")
.option("-s, --sort [sort]", "set default sort for repository", "created") .option("-s, --sort [sort]", "set default sort for repository", "created")
.option("-o, --order [order]", "set default order on sort", "asc") .option("-o, --order [order]", "set default order on sort", "asc")
.option("-c, --codepen [username]", "specify codepen username") .option("-c, --codepen [username]", "specify codepen username")
.option("-d, --dev [username]", "specify dev username") .option("-d, --dev [username]", "specify dev username")
.option("-D, --dribbble [username]", "specify dribbble username") .option("-D, --dribbble [username]", "specify dribbble username")
.option("-e, --email [username]", "specify email") .option("-e, --email [username]", "specify email")
.option("-i, --instagram [username]", "specify instagram username") .option("-i, --instagram [username]", "specify instagram username")
.option("-r, --reddit [username]", "specify reddit username") .option("-r, --reddit [username]", "specify reddit username")
.option("-T, --telegram [username]", "specify telegram username") .option("-T, --telegram [username]", "specify telegram username")
.option("-w, --twitter [username]", "specify twitter username") .option("-w, --twitter [username]", "specify twitter username")
.action(buildCommand); .action(buildCommand);
program program
.command("update") .command("update")
.description("Update user and repository data") .description("Update user and repository data")
.action(updateCommand); .action(updateCommand);
program program
.command("ui") .command("ui")
.description("Create and Manage gitfolio with ease") .description("Create and Manage gitfolio with ease")
.action(uiCommand); .action(uiCommand);
program program
.command("run") .command("run")
.description("Run build files") .description("Run build files")
.option("-p, --port [port]", "provide a port for localhost, default is 3000") .option("-p, --port [port]", "provide a port for localhost, default is 3000")
.action(runCommand); .action(runCommand);
program.on("command:*", () => { program.on("command:*", () => {
console.log("Unknown Command: " + program.args.join(" ")); console.log("Unknown Command: " + program.args.join(" "));
program.help(); program.help();
}); });
program program
.version(version, "-v --version") .version(version, "-v --version")
.usage("<command> [options]") .usage("<command> [options]")
.parse(process.argv); .parse(process.argv);
if (program.args.length === 0) { if (program.args.length === 0) {
program.help(); program.help();
} }

126
build.js
View File

@ -6,8 +6,8 @@ const hbs = require("handlebars");
/* Creates promise-returning async functions /* Creates promise-returning async functions
from callback-passed async functions */ from callback-passed async functions */
const fs = bluebird.promisifyAll(require("fs")); const fs = bluebird.promisifyAll(require("fs"));
const {updateHTML} = require("./populate"); const { updateHTML } = require("./populate");
const {getConfig, outDir} = require("./utils"); const { getConfig, outDir } = require("./utils");
const assetDir = path.resolve(`${__dirname}/assets/`); const assetDir = path.resolve(`${__dirname}/assets/`);
const config = path.join(outDir, "config.json"); const config = path.join(outDir, "config.json");
@ -19,83 +19,83 @@ const config = path.join(outDir, "config.json");
* arguments. * arguments.
*/ */
async function populateCSS({ async function populateCSS({
theme = "light", theme = "light",
background = "https://source.unsplash.com/1280x720/?wallpaper" background = "https://source.unsplash.com/1280x720/?wallpaper"
} = {}) { } = {}) {
/* Get the theme the user requests. Defaults to 'light' */ /* Get the theme the user requests. Defaults to 'light' */
theme = `${theme}.css`; theme = `${theme}.css`;
const template = path.resolve(assetDir, "index.css"); const template = path.resolve(assetDir, "index.css");
const stylesheet = path.join(outDir, "index.css"); const stylesheet = path.join(outDir, "index.css");
try { try {
await fs.accessAsync(outDir, fs.constants.F_OK); await fs.accessAsync(outDir, fs.constants.F_OK);
} catch (error) { } catch (error) {
await fs.mkdirAsync(outDir); await fs.mkdirAsync(outDir);
} }
/* Copy over the template CSS stylesheet */ /* Copy over the template CSS stylesheet */
await fs.copyFileAsync(template, stylesheet); await fs.copyFileAsync(template, stylesheet);
/* Get an array of every available theme */ /* Get an array of every available theme */
const themes = await fs.readdirAsync(path.join(assetDir, "themes")); const themes = await fs.readdirAsync(path.join(assetDir, "themes"));
if (!themes.includes(theme)) { if (!themes.includes(theme)) {
console.error('Error: Requested theme not found. Defaulting to "light".'); console.error('Error: Requested theme not found. Defaulting to "light".');
theme = "light"; theme = "light";
} }
/* Read in the theme stylesheet */ /* Read in the theme stylesheet */
let themeSource = await fs.readFileSync(path.join(assetDir, "themes", theme)); let themeSource = await fs.readFileSync(path.join(assetDir, "themes", theme));
themeSource = themeSource.toString("utf-8"); themeSource = themeSource.toString("utf-8");
const themeTemplate = hbs.compile(themeSource); const themeTemplate = hbs.compile(themeSource);
const styles = themeTemplate({ const styles = themeTemplate({
background: `${background}` background: `${background}`
}); });
/* Add the user-specified styles to the new stylesheet */ /* Add the user-specified styles to the new stylesheet */
await fs.appendFileAsync(stylesheet, styles); await fs.appendFileAsync(stylesheet, styles);
/* Update the config file with the user's theme choice */ /* Update the config file with the user's theme choice */
const data = await getConfig(); const data = await getConfig();
data[0].theme = theme; data[0].theme = theme;
await fs.writeFileAsync(config, JSON.stringify(data, null, " ")); await fs.writeFileAsync(config, JSON.stringify(data, null, " "));
} }
async function populateConfig(opts) { async function populateConfig(opts) {
const data = await getConfig(); const data = await getConfig();
Object.assign(data[0], opts); Object.assign(data[0], opts);
await fs.writeFileAsync(config, JSON.stringify(data, null, " ")); await fs.writeFileAsync(config, JSON.stringify(data, null, " "));
} }
async function buildCommand(username, program) { async function buildCommand(username, program) {
await populateCSS(program); await populateCSS(program);
let types; let types;
if (!program.include || !program.include.length) { if (!program.include || !program.include.length) {
types = ["all"]; types = ["all"];
} else { } else {
types = program.include; types = program.include;
} }
const opts = { const opts = {
sort: program.sort, sort: program.sort,
order: program.order, order: program.order,
includeFork: Boolean(program.fork), includeFork: Boolean(program.fork),
types, types,
codepen: program.codepen, codepen: program.codepen,
dev: program.dev, dev: program.dev,
dribbble: program.dribbble, dribbble: program.dribbble,
email: program.email, email: program.email,
instagram: program.instagram, instagram: program.instagram,
reddit: program.reddit, reddit: program.reddit,
telegram: program.telegram, telegram: program.telegram,
twitter: program.twitter twitter: program.twitter
}; };
await populateConfig(opts); await populateConfig(opts);
updateHTML(("%s", username), opts); updateHTML(("%s", username), opts);
} }
module.exports = { module.exports = {
buildCommand, buildCommand,
populateCSS, populateCSS,
populateConfig populateConfig
}; };

24
package-lock.json generated
View File

@ -1278,9 +1278,9 @@
} }
}, },
"eslint": { "eslint": {
"version": "6.7.2", "version": "6.8.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-6.7.2.tgz", "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz",
"integrity": "sha512-qMlSWJaCSxDFr8fBPvJM9kJwbazrhNcBU3+DszDW1OlEwKBBRWsJc7NJFelvwQpanHCR14cOLD41x8Eqvo3Nng==", "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==",
"dev": true, "dev": true,
"requires": { "requires": {
"@babel/code-frame": "^7.0.0", "@babel/code-frame": "^7.0.0",
@ -1349,6 +1349,12 @@
"lodash.zip": "^4.2.0" "lodash.zip": "^4.2.0"
} }
}, },
"eslint-config-google": {
"version": "0.14.0",
"resolved": "https://registry.npmjs.org/eslint-config-google/-/eslint-config-google-0.14.0.tgz",
"integrity": "sha512-WsbX4WbjuMvTdeVL6+J3rK1RGhCTqjsFjX7UMSMgZiyxxaNLkoJENbrGExzERFeoTpGw3F3FypTiWAP9ZXzkEw==",
"dev": true
},
"eslint-config-prettier": { "eslint-config-prettier": {
"version": "6.9.0", "version": "6.9.0",
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.9.0.tgz", "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.9.0.tgz",
@ -2584,9 +2590,9 @@
"dev": true "dev": true
}, },
"inquirer": { "inquirer": {
"version": "7.0.1", "version": "7.0.3",
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.0.1.tgz", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.0.3.tgz",
"integrity": "sha512-V1FFQ3TIO15det8PijPLFR9M9baSlnRs9nL7zWu1MNVA2T9YVl9ZbrHJhYs7e9X8jeMZ3lr2JH/rdHFgNCBdYw==", "integrity": "sha512-+OiOVeVydu4hnCGLCSX+wedovR/Yzskv9BFqUNNKq9uU2qg7LCcCo3R86S2E7WLo0y/x2pnEZfZe1CoYnORUAw==",
"dev": true, "dev": true,
"requires": { "requires": {
"ansi-escapes": "^4.2.1", "ansi-escapes": "^4.2.1",
@ -4642,9 +4648,9 @@
} }
}, },
"rxjs": { "rxjs": {
"version": "6.5.3", "version": "6.5.4",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.3.tgz", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz",
"integrity": "sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA==", "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==",
"dev": true, "dev": true,
"requires": { "requires": {
"tslib": "^1.9.0" "tslib": "^1.9.0"

View File

@ -8,10 +8,7 @@
"cli": "OUT_DIR='./dist' node bin/gitfolio.js", "cli": "OUT_DIR='./dist' node bin/gitfolio.js",
"clean": "rm -rf ./dist/*", "clean": "rm -rf ./dist/*",
"prettier": "prettier --write \"./**/*.{js,jsx,json,html,css,md}\"", "prettier": "prettier --write \"./**/*.{js,jsx,json,html,css,md}\"",
"test": "xo && OUT_DIR='./dist' node bin/gitfolio.js build k4ustu3h --fork --theme dark --sort updated --twitter k4ustu3h_ --dribbble k4ustu3h --email k4ustu3h@gmail.com --codepen k4ustu3h --dev k4ustu3h --instagram k4ustu3h --telegram k4ustu3h --reddit kaustubhladiya" "test": "OUT_DIR='./dist' node bin/gitfolio.js build k4ustu3h --fork --theme dark --sort updated --twitter k4ustu3h_ --dribbble k4ustu3h --email k4ustu3h@gmail.com --codepen k4ustu3h --dev k4ustu3h --instagram k4ustu3h --telegram k4ustu3h --reddit kaustubhladiya"
},
"xo": {
"prettier": true
}, },
"author": { "author": {
"name": "@imfunniee and community", "name": "@imfunniee and community",
@ -46,6 +43,7 @@
"ncp": "^2.0.0" "ncp": "^2.0.0"
}, },
"devDependencies": { "devDependencies": {
"eslint": "^6.8.0",
"prettier": "1.19.1", "prettier": "1.19.1",
"xo": "^0.25.3" "xo": "^0.25.3"
} }

View File

@ -1,112 +1,106 @@
const fs = require("fs"); const fs = require("fs");
const emoji = require("github-emoji"); const emoji = require("github-emoji");
const jsdom = require("jsdom").JSDOM; const jsdom = require("jsdom").JSDOM,
const options = { options = {
resources: "usable" resources: "usable"
}; };
const {getConfig, outDir} = require("./utils"); const { getConfig, outDir } = require("./utils");
const {getRepos, getUser} = require("./api"); const { getRepos, getUser } = require("./api");
function convertToEmoji(text) { function convertToEmoji(text) {
if (text === null) { if (text == null) return;
return; text = text.toString();
} var pattern = /(?<=:\s*).*?(?=\s*:)/gs;
if (text.match(pattern) != null) {
text = text.toString(); var str = text.match(pattern);
const pattern = /(?<=:\s*).*?(?=\s*:)/gs; str = str.filter(function(arr) {
if (text.match(pattern) !== null) { return /\S/.test(arr);
let str = text.match(pattern); });
str = str.filter(arr => { for (i = 0; i < str.length; i++) {
return /\S/.test(arr); if (emoji.URLS[str[i]] != undefined) {
}); text = text.replace(
for (i = 0; i < str.length; i++) { `:${str[i]}:`,
if (emoji.URLS[str[i]] !== undefined) { `<img src="${emoji.URLS[str[i]]}" class="emoji">`
text = text.replace( );
`:${str[i]}:`, }
`<img src="${emoji.URLS[str[i]]}" class="emoji">` }
); return text;
} } else {
} return text;
}
return text;
}
return text;
} }
module.exports.updateHTML = (username, opts) => { module.exports.updateHTML = (username, opts) => {
const { const {
includeFork, includeFork,
codepen, codepen,
dev, dev,
dribbble, dribbble,
email, email,
instagram, instagram,
reddit, reddit,
telegram, telegram,
twitter twitter
} = opts; } = opts;
// add data to assets/index.html //add data to assets/index.html
jsdom jsdom
.fromFile(`${__dirname}/assets/index.html`, options) .fromFile(`${__dirname}/assets/index.html`, options)
.then(dom => { .then(function(dom) {
const {window} = dom; let window = dom.window,
const {document} = window; document = window.document;
(async () => { (async () => {
try { try {
console.log("Building HTML/CSS..."); console.log("Building HTML/CSS...");
const repos = await getRepos(username, opts); const repos = await getRepos(username, opts);
for (const element of repos) { for (var i = 0; i < repos.length; i++) {
let element; let element;
if (element.fork === false) { if (repos[i].fork == false) {
element = document.querySelector("#work_section"); element = document.getElementById("work_section");
} else if (includeFork === true) { } else if (includeFork == true) {
document.querySelector("#forks").style.display = "block"; document.getElementById("forks").style.display = "block";
element = document.querySelector("#forks_section"); element = document.getElementById("forks_section");
} else { } else {
continue; continue;
} }
element.innerHTML += `
element.innerHTML += ` <a href="${repos[i].html_url}" target="_blank">
<a href="${element.html_url}" target="_blank">
<section> <section>
<div class="section_title">${element.name}</div> <div class="section_title">${repos[i].name}</div>
<div class="about_section"> <div class="about_section">
<span style="display:${ <span style="display:${
element.description === undefined repos[i].description == undefined
? "none" ? "none"
: "block" : "block"
};">${convertToEmoji(element.description)}</span> };">${convertToEmoji(repos[i].description)}</span>
</div> </div>
<div class="bottom_section"> <div class="bottom_section">
<span style="display:${ <span style="display:${
element.language === null repos[i].language == null
? "none" ? "none"
: "inline-block" : "inline-block"
};"><i class="mdi mdi-code-tags"></i>&nbsp; ${ };"><i class="mdi mdi-code-tags"></i>&nbsp; ${
element.language repos[i].language
}</span> }</span>
<span><i class="mdi mdi-star"></i>&nbsp; ${ <span><i class="mdi mdi-star"></i>&nbsp; ${
element.stargazers_count repos[i].stargazers_count
}</span> }</span>
<span><i class="mdi mdi-source-branch"></i>&nbsp; ${ <span><i class="mdi mdi-source-branch"></i>&nbsp; ${
element.forks_count repos[i].forks_count
}</span> }</span>
</div> </div>
</section> </section>
</a>`; </a>`;
} }
const user = await getUser(username);
document.title = user.login;
var icon = document.createElement("link");
icon.setAttribute("rel", "icon");
icon.setAttribute("href", user.avatar_url);
icon.setAttribute("type", "image/png");
const user = await getUser(username); document.getElementsByTagName("head")[0].appendChild(icon);
document.title = user.login; document.getElementsByTagName("head")[0].innerHTML += `
const icon = document.createElement("link");
icon.setAttribute("rel", "icon");
icon.setAttribute("href", user.avatar_url);
icon.setAttribute("type", "image/png");
document.querySelectorAll("head")[0].append(icon);
document.querySelectorAll("head")[0].innerHTML += `
<meta name="description" content="${user.bio}" /> <meta name="description" content="${user.bio}" />
<meta property="og:image" content="${user.avatar_url}" /> <meta property="og:image" content="${user.avatar_url}" />
<meta property="og:type" content="profile" /> <meta property="og:type" content="profile" />
@ -118,95 +112,89 @@ module.exports.updateHTML = (username, opts) => {
<meta name="twitter:card" content="summary" /> <meta name="twitter:card" content="summary" />
<meta name="twitter:title" content="${user.login}" /> <meta name="twitter:title" content="${user.login}" />
<meta name="twitter:description" content="${user.bio}" />`; <meta name="twitter:description" content="${user.bio}" />`;
document.querySelector( document.getElementById(
"#username" "username"
).innerHTML = `<span id="text" style="display:${ ).innerHTML = `<span id="text" style="display:${
user.name === null || !user.name ? "none" : "block" user.name == null || !user.name ? "none" : "block"
};"></span><div class='console-underscore' id='console'>&#95;</div><br><a href="${ };"></span><div class='console-underscore' id='console'>&#95;</div><br><a href="${
user.html_url user.html_url
}">@${user.login}</a>`; }">@${user.login}</a>`;
// document.getElementById("github_link").href = `https://github.com/${user.login}`; //document.getElementById("github_link").href = `https://github.com/${user.login}`;
document.querySelector("#userbio").innerHTML = convertToEmoji( document.getElementById("userbio").innerHTML = convertToEmoji(
user.bio user.bio
); );
document.querySelector("#userbio").style.display = document.getElementById("userbio").style.display =
user.bio == null || !user.bio ? "none" : "block"; user.bio == null || !user.bio ? "none" : "block";
document.querySelector("#about").innerHTML = ` document.getElementById("about").innerHTML = `
<span style="display:${ <span style="display:${
user.company == null || !user.company ? "none" : "block" user.company == null || !user.company ? "none" : "block"
};"><i class="mdi-face"></i> &nbsp; ${user.company}</span> };"><i class="mdi-face"></i> &nbsp; ${user.company}</span>
<span style="display:${ <span style="display:${
user.email == null || !user.email ? "none" : "block" user.email == null || !user.email ? "none" : "block"
};"><i class="mdi mdi-email"></i> &nbsp; ${user.email}</span> };"><i class="mdi mdi-email"></i> &nbsp; ${user.email}</span>
<span style="display:${ <span style="display:${
user.location == null || !user.location ? "none" : "block" user.location == null || !user.location ? "none" : "block"
};"><i class="mdi mdi-map-marker"></i> &nbsp;&nbsp; ${ };"><i class="mdi mdi-map-marker"></i> &nbsp;&nbsp; ${
user.location user.location
}</span> }</span>
<span style="display:${ <span style="display:${
user.hireable == false || !user.hireable ? "none" : "block" user.hireable == false || !user.hireable ? "none" : "block"
};"><i class="mdi mdi-account-tie"></i> &nbsp;&nbsp; Available for hire</span> };"><i class="mdi mdi-account-tie"></i> &nbsp;&nbsp; Available for hire</span>
<div class="socials"> <div class="socials">
<span style="display:${ <span style="display:${
codepen == null ? "none !important" : "block" codepen == null ? "none !important" : "block"
};"><a href="https://codepen.io/${codepen}" target="_blank" class="socials"><i class="mdi mdi-codepen"></i></a></span> };"><a href="https://codepen.io/${codepen}" target="_blank" class="socials"><i class="mdi mdi-codepen"></i></a></span>
<span style="display:${ <span style="display:${
dev == null ? "none !important" : "block" dev == null ? "none !important" : "block"
};"><a href="https://dev.to/${dev}" target="_blank" class="socials"><i class="mdi mdi-dev-to"></i></a></span> };"><a href="https://dev.to/${dev}" target="_blank" class="socials"><i class="mdi mdi-dev-to"></i></a></span>
<span style="display:${ <span style="display:${
dribbble == null ? "none !important" : "block" dribbble == null ? "none !important" : "block"
};"><a href="https://www.dribbble.com/${dribbble}" target="_blank" class="socials"><i class="mdi mdi-dribbble"></i></a></span> };"><a href="https://www.dribbble.com/${dribbble}" target="_blank" class="socials"><i class="mdi mdi-dribbble"></i></a></span>
<span style="display:${ <span style="display:${
email == null ? "none !important" : "block" email == null ? "none !important" : "block"
};"><a href="mailto:${email}" target="_blank" class="socials"><i class="mdi mdi-email"></i></a></span> };"><a href="mailto:${email}" target="_blank" class="socials"><i class="mdi mdi-email"></i></a></span>
<span style="display:${ <span style="display:${
instagram == null ? "none !important" : "block" instagram == null ? "none !important" : "block"
};"><a href="https://www.instagram.com/${instagram}" target="_blank" class="socials"><i class="mdi mdi-instagram"></i></a></span> };"><a href="https://www.instagram.com/${instagram}" target="_blank" class="socials"><i class="mdi mdi-instagram"></i></a></span>
<span style="display:${ <span style="display:${
reddit == null ? "none !important" : "block" reddit == null ? "none !important" : "block"
};"><a href="https://www.reddit.com/u/${reddit}" target="_blank" class="socials"><i class="mdi mdi-reddit"></i></a></span> };"><a href="https://www.reddit.com/u/${reddit}" target="_blank" class="socials"><i class="mdi mdi-reddit"></i></a></span>
<span style="display:${ <span style="display:${
telegram == null ? "none !important" : "block" telegram == null ? "none !important" : "block"
};"><a href="https://t.me/${telegram}" target="_blank" class="socials"><i class="mdi mdi-telegram"></i></a></span> };"><a href="https://t.me/${telegram}" target="_blank" class="socials"><i class="mdi mdi-telegram"></i></a></span>
<span style="display:${ <span style="display:${
twitter == null ? "none !important" : "block" twitter == null ? "none !important" : "block"
};"><a href="https://www.twitter.com/${twitter}" target="_blank" class="socials"><i class="mdi mdi-twitter"></i></a></span> };"><a href="https://www.twitter.com/${twitter}" target="_blank" class="socials"><i class="mdi mdi-twitter"></i></a></span>
</div> </div>
`; `;
// add data to config.json //add data to config.json
const data = await getConfig(); const data = await getConfig();
data[0].username = user.login; data[0].username = user.login;
data[0].name = user.name; data[0].name = user.name;
data[0].userimg = user.avatar_url; data[0].userimg = user.avatar_url;
await fs.writeFile( await fs.writeFile(
`${outDir}/config.json`, `${outDir}/config.json`,
JSON.stringify(data, null, " "), JSON.stringify(data, null, " "),
err => { function(err) {
if (err) { if (err) throw err;
throw err; console.log("Config file updated.");
} }
);
console.log("Config file updated."); await fs.writeFile(
} `${outDir}/index.html`,
); "<!DOCTYPE html>" + window.document.documentElement.outerHTML,
await fs.writeFile( function(error) {
`${outDir}/index.html`, if (error) throw error;
"<!DOCTYPE html>" + window.document.documentElement.outerHTML, console.log(`Build Complete, Files can be Found @ ${outDir}\n`);
error => { }
if (error) { );
throw error; } catch (error) {
} console.log(error);
}
console.log(`Build Complete, Files can be Found @ ${outDir}\n`); })();
} })
); .catch(function(error) {
} catch (error) { console.log(error);
console.log(error); });
}
})();
})
.catch(error => {
console.log(error);
});
}; };

18
run.js
View File

@ -5,18 +5,18 @@ const app = express();
app.use(express.static(`${outDir}`)); app.use(express.static(`${outDir}`));
function runCommand(program) { function runCommand(program) {
const port = program.port ? program.port : 3000; const port = program.port ? program.port : 3000;
app.get("/", (req, res) => { app.get("/", (req, res) => {
res.sendFile("/index.html"); res.sendFile("/index.html");
}); });
app.listen(port); app.listen(port);
console.log( console.log(
`\nGitfolio running on port ${port}, Navigate to http://localhost:${port} in your browser\n` `\nGitfolio running on port ${port}, Navigate to http://localhost:${port} in your browser\n`
); );
} }
module.exports = { module.exports = {
runCommand runCommand
}; };

144
ui.js
View File

@ -2,25 +2,25 @@ const fs = require("fs");
const express = require("express"); const express = require("express");
const jsdom = require("jsdom").JSDOM; const jsdom = require("jsdom").JSDOM;
const options = { const options = {
resources: "usable" resources: "usable"
}; };
const {updateHTML} = require("./populate"); const { updateHTML } = require("./populate");
const {populateCSS, populateConfig} = require("./build"); const { populateCSS, populateConfig } = require("./build");
const {updateCommand} = require("./update"); const { updateCommand } = require("./update");
const app = express(); const app = express();
app.set("view engine", "ejs"); app.set("view engine", "ejs");
app.use(express.static(__dirname + "/views")); app.use(express.static(__dirname + "/views"));
app.set("views", __dirname + "/views"); app.set("views", __dirname + "/views");
app.use( app.use(
express.json({ express.json({
limit: "50mb" limit: "50mb"
}) })
); );
app.use( app.use(
express.urlencoded({ express.urlencoded({
limit: "50mb", limit: "50mb",
extended: true extended: true
}) })
); );
const port = 3000; const port = 3000;
@ -28,74 +28,74 @@ const port = 3000;
global.DOMParser = new jsdom().window.DOMParser; global.DOMParser = new jsdom().window.DOMParser;
function uiCommand() { function uiCommand() {
app.get("/", (req, res) => { app.get("/", (req, res) => {
res.render("index.ejs"); res.render("index.ejs");
}); });
app.get("/update", (req, res) => { app.get("/update", (req, res) => {
if (!fs.existsSync(`${outDir}/config.json`)) { if (!fs.existsSync(`${outDir}/config.json`)) {
return res.send( return res.send(
'You need to run build command before using update<br><a href="/">Go Back</a>' 'You need to run build command before using update<br><a href="/">Go Back</a>'
); );
} }
updateCommand(); updateCommand();
res.redirect("/"); res.redirect("/");
}); });
app.post("/build", (req, res) => { app.post("/build", (req, res) => {
const {username} = req.body; const { username } = req.body;
if (!username) { if (!username) {
return res.send("username can't be empty"); return res.send("username can't be empty");
} }
const sort = req.body.sort ? req.body.sort : "created"; const sort = req.body.sort ? req.body.sort : "created";
const order = req.body.order ? req.body.order : "asc"; const order = req.body.order ? req.body.order : "asc";
const includeFork = req.body.fork === "true"; const includeFork = req.body.fork === "true";
const types = ["owner"]; const types = ["owner"];
const codepen = req.body.codepen ? req.body.codepen : null; const codepen = req.body.codepen ? req.body.codepen : null;
const dev = req.body.dev ? req.body.dev : null; const dev = req.body.dev ? req.body.dev : null;
const dribbble = req.body.dribbble ? req.body.dribbble : null; const dribbble = req.body.dribbble ? req.body.dribbble : null;
const email = req.body.email ? req.body.email : null; const email = req.body.email ? req.body.email : null;
const instagram = req.body.instagram ? req.body.instagram : null; const instagram = req.body.instagram ? req.body.instagram : null;
const reddit = req.body.reddit ? req.body.reddit : null; const reddit = req.body.reddit ? req.body.reddit : null;
const telegram = req.body.telegram ? req.body.telegram : null; const telegram = req.body.telegram ? req.body.telegram : null;
const twitter = req.body.twitter ? req.body.twitter : null; const twitter = req.body.twitter ? req.body.twitter : null;
const background = req.body.background const background = req.body.background
? req.body.background ? req.body.background
: "https://source.unsplash.com/1280x720/?wallpaper"; : "https://source.unsplash.com/1280x720/?wallpaper";
const theme = req.body.theme === "on" ? "dark" : "light"; const theme = req.body.theme === "on" ? "dark" : "light";
const opts = { const opts = {
sort, sort,
order, order,
includeFork, includeFork,
types, types,
codepen, codepen,
dev, dev,
dribbble, dribbble,
email, email,
instagram, instagram,
reddit, reddit,
telegram, telegram,
twitter twitter
}; };
updateHTML(username, opts); updateHTML(username, opts);
populateCSS({ populateCSS({
background, background,
theme theme
}); });
populateConfig(opts); populateConfig(opts);
res.redirect("/"); res.redirect("/");
}); });
console.log("\nStarting..."); console.log("\nStarting...");
app.listen(port); app.listen(port);
console.log( console.log(
`The GUI is running on port ${port}, Navigate to http://localhost:${port} in your browser\n` `The GUI is running on port ${port}, Navigate to http://localhost:${port} in your browser\n`
); );
} }
module.exports = { module.exports = {
uiCommand uiCommand
}; };

View File

@ -1,33 +1,33 @@
const {getConfig} = require("./utils"); const { getConfig } = require("./utils");
const {updateHTML} = require("./populate"); const { updateHTML } = require("./populate");
async function updateCommand() { async function updateCommand() {
const data = await getConfig(); const data = await getConfig();
const {username} = data[0]; const { username } = data[0];
if (username === null) { if (username === null) {
console.log( console.log(
"username not found in config.json, please run build command before using update" "username not found in config.json, please run build command before using update"
); );
return; return;
} }
const opts = { const opts = {
sort: data[0].sort, sort: data[0].sort,
order: data[0].order, order: data[0].order,
includeFork: data[0].includeFork, includeFork: data[0].includeFork,
types: data[0].types, types: data[0].types,
codepen: data[0].codepen, codepen: data[0].codepen,
dev: data[0].dev, dev: data[0].dev,
dribbble: data[0].dribbble, dribbble: data[0].dribbble,
email: data[0].email, email: data[0].email,
instagram: data[0].instagram, instagram: data[0].instagram,
reddit: data[0].reddit, reddit: data[0].reddit,
telegram: data[0].telegram, telegram: data[0].telegram,
twitter: data[0].twitter twitter: data[0].twitter
}; };
updateHTML(username, opts); updateHTML(username, opts);
} }
module.exports = { module.exports = {
updateCommand updateCommand
}; };

View File

@ -12,22 +12,22 @@ const defaultConfigPath = path.resolve(`${__dirname}/default/config.json`);
* if not present returns default file contents * if not present returns default file contents
*/ */
async function getFileWithDefaults(file, defaultFile) { async function getFileWithDefaults(file, defaultFile) {
try { try {
await fs.accessAsync(file, fs.constants.F_OK); await fs.accessAsync(file, fs.constants.F_OK);
} catch (error) { } catch (error) {
const defaultData = await fs.readFileAsync(defaultFile); const defaultData = await fs.readFileAsync(defaultFile);
return JSON.parse(defaultData); return JSON.parse(defaultData);
} }
const data = await fs.readFileAsync(file); const data = await fs.readFileAsync(file);
return JSON.parse(data); return JSON.parse(data);
} }
async function getConfig() { async function getConfig() {
return getFileWithDefaults(configPath, defaultConfigPath); return getFileWithDefaults(configPath, defaultConfigPath);
} }
module.exports = { module.exports = {
outDir, outDir,
getConfig getConfig
}; };