1
Fork 0

Merge pull request #1 from RealOrangeOne/rewrite

Rewrite as hacky static site
This commit is contained in:
Jake Howard 2019-07-01 21:08:33 +01:00 committed by GitHub
commit 53085be4f4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 7186 additions and 128 deletions

17
.circleci/config.yml Normal file
View file

@ -0,0 +1,17 @@
version: 2.0
jobs:
build:
docker:
- image: circleci/node:10
steps:
- checkout
- run:
name: Install dependencies
command: npm install
- run:
name: Build Project
command: npm run build
- run:
name: Run tests
command: npm test

30
.gitignore vendored
View file

@ -1,20 +1,6 @@
# Created by https://www.gitignore.io/api/node,hugo
# Edit at https://www.gitignore.io/?templates=node,hugo
### Hugo ###
### Hugo ###
# gitginore template for Hugo projects
# website: https://gohugo.io
# generated files by hugo
/public/
/resources/_gen/
# executable may be added to repository
hugo.exe
hugo.darwin
hugo.linux
# Created by https://www.gitignore.io/api/node
# Edit at https://www.gitignore.io/?templates=node
### Node ###
# Logs
@ -23,6 +9,10 @@ logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
@ -35,6 +25,7 @@ lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
@ -58,6 +49,9 @@ jspm_packages/
# TypeScript v1 declaration files
typings/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
@ -98,6 +92,6 @@ typings/
# DynamoDB Local files
.dynamodb/
# End of https://www.gitignore.io/api/node,hugo
# End of https://www.gitignore.io/api/node
static/build
build/

4
.prettierrc Normal file
View file

@ -0,0 +1,4 @@
{
"singleQuote": true,
"trailingComma": "es5"
}

View file

@ -1,3 +1,4 @@
# Give money to me
[![Netlify Status](https://api.netlify.com/api/v1/badges/1945adf5-cda6-4ac8-86b2-c19ede389ae8/deploy-status)](https://app.netlify.com/sites/give-money-to-me/deploys)
[![CircleCI](https://circleci.com/gh/RealOrangeOne/givemoneyto.me.svg?style=svg)](https://circleci.com/gh/RealOrangeOne/givemoneyto.me)

7
accounts.yml Normal file
View file

@ -0,0 +1,7 @@
PayPal:
image: https://upload.wikimedia.org/wikipedia/commons/thumb/b/b7/PayPal_Logo_Icon_2014.svg/887px-PayPal_Logo_Icon_2014.svg.png
link: https://www.paypal.me/TheOrangeOne
Monzo:
image: https://upload.wikimedia.org/wikipedia/en/thumb/a/a3/Monzo_logo.svg/1920px-Monzo_logo.svg.png
link: https://monzo.me/jakehoward

View file

@ -1,16 +0,0 @@
baseURL: "https://givemoneyto.me/"
title: "Give money to me"
staticDir: static/build
assetDir: static/build
disableKinds:
- sitemap
- taxonomyTerm
- 404
outputs:
home:
- html
page:
- html

View file

@ -1,3 +0,0 @@
---
title: Give Money To Me
---

View file

@ -1,5 +0,0 @@
---
title: Monzo
image: https://upload.wikimedia.org/wikipedia/en/thumb/a/a3/Monzo_logo.svg/1920px-Monzo_logo.svg.png
link: https://monzo.me/jakehoward
---

View file

@ -1,5 +0,0 @@
---
title: PayPal
image: https://upload.wikimedia.org/wikipedia/commons/thumb/b/b7/PayPal_Logo_Icon_2014.svg/887px-PayPal_Logo_Icon_2014.svg.png
link: https://www.paypal.me/TheOrangeOne
---

147
index.ts Normal file
View file

@ -0,0 +1,147 @@
import { readFileSync, writeFileSync } from 'fs';
import glob from 'glob';
import Handlebars from 'handlebars';
import jsyaml from 'js-yaml';
import mkdirp from 'mkdirp';
import Bundler from 'parcel-bundler';
import { dirname, join } from 'path';
import ProgressBar from 'progress';
import rimraf from 'rimraf';
import { mapObject, range } from 'underscore';
interface Account {
image: string;
link: string;
}
interface Redirect {
src: string;
dest: string;
}
const BUILD_DIR = join(__dirname, 'build');
const SRC_DIR = join(__dirname, 'src');
const PROGRESS_BAR_FORMAT = '[:bar] :rate/ps :percent :current/:total';
const MAX_VALUE = process.env.MAX_VALUE
? parseInt(process.env.MAX_VALUE, 10)
: 2;
const BUNDLER_OPTIONS = {
outDir: BUILD_DIR,
watch: false,
minify: true,
};
const NEW_LINES_RE = /(\r\n|\n|\r)/gm;
function readAccounts(): ReadonlyArray<Account> {
const rawAccounts: object = jsyaml.safeLoad(
readFileSync(join(__dirname, 'accounts.yml')).toString()
);
return Object.values(
mapObject(rawAccounts, (val, key) => {
return {
...val,
name: key,
};
})
);
}
function statusOutput(message: string) {
console.log('> ' + message + '...');
}
function isPrecision(value: number, precision: number) {
return value.toFixed(precision) === value.toString();
}
function writeTemplate(
template: HandlebarsTemplateDelegate,
value: string,
context: any
) {
const outputFile = join(BUILD_DIR, value, 'index.html');
mkdirp.sync(dirname(outputFile));
writeFileSync(outputFile, template(context).replace(NEW_LINES_RE, ''));
}
function writeRedirects(redirects: ReadonlyArray<Redirect>) {
const template = Handlebars.compile(
readFileSync(join(SRC_DIR, 'redirects.txt')).toString()
);
writeFileSync(join(BUILD_DIR, '_redirects'), template({ redirects }));
}
function humanize(value: number) {
if (isPrecision(value, 0)) {
return value.toString();
}
return value.toFixed(2);
}
(async function() {
rimraf.sync(BUILD_DIR);
statusOutput('Reading accounts');
const accounts = readAccounts();
statusOutput('Creating template');
const bundler = new Bundler(join(SRC_DIR, 'template.html'), BUNDLER_OPTIONS);
await bundler.bundle();
statusOutput('Compiling HTML template');
Handlebars.registerPartial(
'accounts',
readFileSync(join(SRC_DIR, 'accounts.html')).toString()
);
const template = Handlebars.compile(
readFileSync(join(BUILD_DIR, 'template.html')).toString()
);
const possibleValues = range(0, MAX_VALUE, 0.01);
const bar = new ProgressBar(PROGRESS_BAR_FORMAT, {
total: possibleValues.length,
width: 40,
});
const baseContext = {
accounts,
};
const redirects: Redirect[] = [];
statusOutput('Generating pages');
possibleValues.forEach(i => {
if (i) {
const value = parseFloat(i.toFixed(2));
const context = {
...baseContext,
displayValue: '£' + humanize(value),
value: humanize(value),
};
writeTemplate(template, value.toString(), context);
if (isPrecision(value, 1)) {
redirects.push({
src: value.toString() + '0',
dest: value.toString(),
});
// writeTemplate(template, value.toString() + '0', context);
}
if (isPrecision(value, 0)) {
redirects.push({
src: value.toString() + '.00',
dest: value.toString(),
});
redirects.push({
src: value.toString() + '.0',
dest: value.toString(),
});
// writeTemplate(template, value.toString() + '.00', context);
}
}
bar.tick();
});
writeTemplate(template, '', { ...baseContext, displayValue: 'money' });
const filesOutput = glob.sync(join(BUILD_DIR, '**/index.html')).length;
console.log(`Generated ${filesOutput} files.`);
writeRedirects(redirects);
})();

View file

@ -1,10 +0,0 @@
<html>
<head>
<title>Redirecting to {{ .Params.link }}</title>
<link rel="canonical" href="{{ .Params.link }}">
<meta http-equiv="refresh" content="0; url={{ .Params.link }}">
</head>
<body>
<p>Redirecting to {{ .Params.link }}...</p>
</body>
</html>

View file

@ -1,36 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>{{ .Title }}</title>
{{ partial "style.html" "css/font-awesome.css" }}
{{ partial "style.html" "css/animate.css" }}
{{ partial "style.html" "scss/index.scss" }}
</head>
<body>
<div class="jumbotron mb-0 jumbotron-fluid text-center vertical-center">
<div class="container">
<h1 class="display-1">{{ .Site.Title }}</h1>
<p class="lead">You should give me money. Here's how:</p>
<h1>
<i class="fas fa-chevron-down mt-5 animated infinite slideInDown"></i>
</h1>
</div>
</div>
<div class="jumbotron mb-0 jumbotron-fluid">
<div class="container">
<div class="card-deck">
{{ range .Pages.ByTitle }}
<div class="card text-center mx-5">
<a href="{{ .Permalink }}" class="colour-invert">
<img src="{{ .Params.image }}" class="card-img-top my-3 mx-3" alt="{{ .Title }} logo" style="max-width:40%" />
</a>
</div>
{{ end }}
</div>
</div>
</div>
{{ partial "script.html" "js/bootstrap.js" }}
</body>
</html>

View file

@ -1,2 +0,0 @@
{{ $script := resources.Get . | minify | fingerprint }}
<script type="text/javascript" src="{{ $script.RelPermalink }}" integrity="{{ $script.Data.Integrity }}"></script>

View file

@ -1,2 +0,0 @@
{{ $style := resources.Get . | toCSS | minify | fingerprint }}
<link rel="stylesheet" href="{{ $style.RelPermalink }}" integrity="{{ $style.Data.Integrity }}" />

View file

@ -1,9 +1,8 @@
[build]
publish = "public"
command = "./scripts/build.sh"
publish = "build"
command = "npm run build"
[build.environment]
HUGO_VERSION = "0.52"
NODE_ENV = "production"
NPM_CONFIG_PRODUCTION = "false"

6878
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -2,7 +2,13 @@
"name": "givemoneyto.me",
"version": "1.0.0",
"main": "index.js",
"scripts": {},
"scripts": {
"build": "ts-node index.ts",
"lint": "tsc --noEmit --project tsconfig.json && tslint --project tsconfig.json index.ts",
"prettier": "prettier --write index.ts",
"start": "http-server build/ -c-1",
"test": "npm run lint && npm run prettier -- --check"
},
"repository": {
"type": "git",
"url": "git+https://github.com/RealOrangeOne/givemoneyto.me.git"
@ -13,9 +19,34 @@
},
"homepage": "https://github.com/RealOrangeOne/givemoneyto.me#readme",
"dependencies": {
"@fortawesome/fontawesome-free": "^5.7.1",
"animate.css": "^3.7.0",
"bootstrap": "4.2.1"
"@fortawesome/fontawesome-free": "5.7.1",
"@types/js-yaml": "^3.12.1",
"@types/mkdirp": "^0.5.2",
"@types/node": "^12.0.10",
"@types/parcel-bundler": "^1.12.0",
"@types/progress": "^2.0.3",
"@types/rimraf": "^2.0.2",
"@types/underscore": "^1.9.1",
"animate.css": "3.7.0",
"bootstrap": "^4.2.1",
"glob": "^7.1.4",
"handlebars": "^4.1.2",
"http-server": "^0.11.1",
"jquery": "^3.4.1",
"js-yaml": "^3.13.1",
"mkdirp": "^0.5.1",
"parcel-bundler": "1.12.3",
"popper.js": "^1.15.0",
"prettier": "^1.18.2",
"progress": "^2.0.3",
"rimraf": "^2.6.3",
"sass": "^1.22.1",
"ts-node": "8.3.0",
"typescript": "3.5.2",
"underscore": "^1.9.1"
},
"devDependencies": {}
"devDependencies": {
"tslint-config-dabapps": "github:dabapps/tslint-config-dabapps#v0.5.1",
"tslint": "5.18.0"
}
}

View file

@ -1,16 +0,0 @@
#!/usr/bin/env bash
set -e
rm -rf public/
mkdir -p static/build/js static/build/css
cp -r static/src/* static/build
cp node_modules/bootstrap/dist/js/bootstrap.bundle.min.js static/build/js/bootstrap.js
cp node_modules/animate.css/animate.min.css static/build/css/animate.css
cp -r node_modules/@fortawesome/fontawesome-free/css/all.min.css static/build/css/font-awesome.css
cp -r node_modules/@fortawesome/fontawesome-free/webfonts static/build
hugo -v --stepAnalysis --gc

View file

@ -1,7 +0,0 @@
#!/usr/bin/env bash
set -e
bash ./scripts/build.sh
hugo server --noHTTPCache --disableFastRender --gc

13
src/accounts.html Normal file
View file

@ -0,0 +1,13 @@
<div class="jumbotron mb-0 jumbotron-fluid">
<div class="container">
<div class="card-deck">
{{#each accounts }}
<div class="card text-center mx-5">
<a href="{{ link }}/{{ ../value }}" class="colour-invert">
<img src="{{ image }}" class="card-img-top my-3 mx-3" alt="{{ name }} logo" style="max-width:40%" />
</a>
</div>
{{/each}}
</div>
</div>
</div>

12
src/fathom.js Normal file
View file

@ -0,0 +1,12 @@
(function(f, a, t, h, o, m){
a[h]=a[h]||function(){
(a[h].q=a[h].q||[]).push(arguments)
};
o=f.createElement('script'),
m=f.getElementsByTagName('script')[0];
o.async=1; o.src=t; o.id='fathom-script';
m.parentNode.insertBefore(o,m)
})(document, window, '//fathom.theorangeone.net/tracker.js', 'fathom');
fathom('set', 'siteId', 'GOWOM');
fathom('trackPageview');

3
src/redirects.txt Normal file
View file

@ -0,0 +1,3 @@
{{#each redirects }}
/{{src}} /{{dest}} 200
{{/each}}

25
src/template.html Normal file
View file

@ -0,0 +1,25 @@
<html>
<head>
<link rel="stylesheet" href="../node_modules/@fortawesome/fontawesome-free/css/all.min.css" />
<link rel="stylesheet" href="../node_modules/animate.css/animate.min.css" />
<link rel="stylesheet" href="./index.scss" />
<title>Give {{ displayValue }} to me</title>
</head>
<body>
<div class="jumbotron mb-0 jumbotron-fluid text-center vertical-center">
<div class="container">
<h1 class="display-1">Give {{ displayValue }} to me</h1>
<p class="lead">You should give me {{ displayValue }}. Here's how:</p>
<h1>
<i class="fas fa-chevron-down mt-5 animated infinite slideInDown"></i>
</h1>
</div>
</div>
{{> accounts }}
<script type="text/javascript" src="../node_modules/bootstrap/js/src/index.js"></script>
<script type="text/javascript" src="./fathom.js"></script>
</body>
</html>

20
tsconfig.json Normal file
View file

@ -0,0 +1,20 @@
{
"compilerOptions": {
"noImplicitAny": true,
"skipLibCheck": true,
"pretty": true,
"strict": true,
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"allowJs": false,
"checkJs": false,
"noUnusedLocals": true,
"noUnusedParameters": true,
"moduleResolution": "node",
"target": "es6",
"baseUrl": "./",
"typeRoots" : [
"node_modules/@types/"
]
},
}

9
tslint.json Normal file
View file

@ -0,0 +1,9 @@
{
"extends": [
"tslint-config-dabapps"
],
"rules": {
"no-console": false,
"only-arrow-functions": false
}
}