Compare commits

...

101 Commits

Author SHA1 Message Date
1a9df45e55 Added advice from Josh Clark
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2025-05-10 17:14:00 +01:00
d5d7f74fd0 Added some advice from lobste.rs
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2025-05-03 07:11:07 +01:00
934c4f4de3 Added advice from Aaron Patterson
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2025-05-03 07:04:38 +01:00
1ff611b3ed Added advice from Márk Sági-Kazár
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2025-05-01 14:23:58 +01:00
e2372b378a Fix typo
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2025-05-01 09:53:36 +01:00
c4d3194a7f Added toilet tip to speaking post
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2025-05-01 08:03:25 +01:00
252f5143d1 Added talk on public speaking
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2025-04-30 20:08:25 +01:00
9a0cf62882 Updated profile image
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2025-02-17 16:38:29 +00:00
c267ec35a4 Added Node-RED bot post
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2025-02-09 09:08:03 +00:00
fd867c7262 Updarte social share image
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2025-02-02 08:28:23 +00:00
3bdc78303d Added LinkedIn API post
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2025-02-02 07:47:52 +00:00
4aafc98be9 Fix strikethrough
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2025-01-17 15:37:51 +00:00
84bae3759d Updated post with cloudflare details
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2025-01-17 15:14:51 +00:00
98ff90f460 Update cloud native now post
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2025-01-14 13:40:12 +00:00
ab55d75296 Added Cloud Native Now post
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2025-01-14 11:51:50 +00:00
f69df643f7 Added og:article:author meta tag
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2025-01-05 19:51:27 +00:00
2e328133cc Updated social links
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2025-01-04 16:06:54 +00:00
ac1744869d Added Bootstrapping a Civo cluster with OpenTofu and Flux
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2025-01-03 11:08:19 +00:00
68e1e77843 Added fediverse creator meta tag
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2024-07-03 09:25:04 +01:00
675f56d9c5 Added link to Michaels post
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2024-06-24 14:49:01 +01:00
7bf40c1263 Typo
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2024-06-24 14:46:12 +01:00
3586eeb6bf Updated resources
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2024-06-24 13:03:33 +01:00
ee9a16865e Added kubernetes resources post
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2024-06-24 11:38:31 +01:00
a1533640cf Added EMF Camp post
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2024-06-07 16:24:06 +01:00
d48d4dcb14 Update broken links
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2024-05-21 15:24:06 +01:00
bdd2e8c79a Update blocked routes
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2023-10-10 09:46:15 +01:00
b36d394308 Added post about renovate custom datasources
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2023-10-03 21:59:45 +01:00
a8295a7321 Fixed broken links
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2023-09-23 20:33:19 +01:00
a3f0a74535 Update list of filtered routes
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2023-09-04 12:19:16 +01:00
0e5cce4a52 Added redis data migration post
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2023-09-04 10:07:25 +01:00
2007c280c8 Added Ian tweet
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2023-03-03 08:43:47 +00:00
03aadb59fe Replaced tweet images while still possible
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2023-02-03 14:47:58 +00:00
0f90c7c0d0 Update filter routes 2022-07-22 18:38:12 +00:00
fbf3657b77 Remove draft post
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2022-07-21 08:02:32 +01:00
21f1d9216c Updated redirect rules
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2022-07-21 07:03:17 +01:00
0bd69bd3f3 Handle more missing icons
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2022-07-19 07:08:25 +01:00
de146693aa Added missing image
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2022-07-19 07:05:32 +01:00
57bd0f0fcc Updated favicons
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2022-07-19 06:55:41 +01:00
41e4d4dab0 Added tweet from Ian about nsenter
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2022-07-15 21:05:18 +01:00
176a5855de Fixed redirect
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2022-07-05 07:23:58 +01:00
1b2e0d7501 Added redirect logic
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2022-07-05 05:41:52 +01:00
db94ace86e fixed typo in title 2022-07-05 04:04:16 +00:00
60babf9451 Fixed typo
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2022-07-04 09:13:46 +01:00
b5d6232b59 Added managing kubernetes post
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2022-07-04 06:50:57 +01:00
3a123ab8ee Include pico.css in src
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2022-06-22 20:13:42 +01:00
652cee0e2e Migrated T.I.L. posts to blog
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2022-06-22 20:04:49 +01:00
080912401b Updated docker image location
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2022-05-29 17:25:41 +01:00
8acfafab45 Updated index title
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2022-05-29 17:12:18 +01:00
0e97c82aa1 Fixed typo issue
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2022-05-29 17:10:29 +01:00
6307509542 Updated mastodon link 2022-05-14 22:06:37 +00:00
118c8f89c0 Longer initial glitch
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2022-05-03 07:03:56 +01:00
1a4c18cce0 Lessen glitch effect
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2022-05-03 06:36:44 +01:00
0aaf47909f Updated description
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2022-05-02 14:36:57 +01:00
186bdde093 Glitch theme
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2022-05-02 14:29:27 +01:00
f99cd77e20 Use smaller image
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2022-05-01 12:32:41 +01:00
c4dc1d26d2 Updated favicons
Signed-off-by: Marcus Noble <github@marcusnoble.co.uk>
2022-05-01 11:34:18 +01:00
2bf4389d37 Added cluster-admin permissions post 2022-01-20 10:37:19 +00:00
f1a7bd7dff Merge branch 'master' of https://git.cluster.fun/averagemarcus/blog 2021-09-14 18:51:44 +00:00
8d1aec32f6 Fixed typos 2021-09-14 18:51:25 +00:00
Marcus Noble
b631a8e782 Merge pull request #14 from thianpengter-wf/patch-1
Correct typo
2021-09-10 20:11:19 +01:00
Thian-Peng Ter
cc792b244b Correct typo
Podman machine currently has now (correction: no) support for mounting volumes from the host machine (your Mac) into the container on the virtual machine
2021-09-10 08:36:18 -06:00
0b0c028954 Added section about podman GUI 2021-09-05 07:49:00 +01:00
d01a3f227c Cleaned up some unneccisary redirects 2021-09-05 07:48:49 +01:00
36a58be0f1 Added note about volume mounts 2021-09-04 17:02:11 +01:00
c8f30073d9 More podman updates 2021-09-04 16:27:38 +01:00
b0e84f281d Added section about podman on windows 2021-09-04 16:01:27 +01:00
c10c858988 Handle some 404's better 2021-09-03 07:02:57 +01:00
eeebcd3472 Added resources to job hunting post 2021-09-02 14:50:08 +00:00
04e9e1fd14 Fixed links 2021-09-02 14:26:53 +00:00
fb419d0bea Added Go resources post 2021-09-02 14:13:37 +00:00
193625958a Fix typos 2021-09-02 13:34:48 +00:00
d7ccad274c Post restructuring (headings) 2021-09-01 20:08:22 +01:00
de320346e3 Added section about port forwarding bug 2021-09-01 20:02:50 +01:00
1a1c1217e9 Added note about socket bug PR 2021-09-01 18:51:26 +01:00
b0941cad68 Updated profile picture 2021-09-01 15:41:12 +01:00
f98a090095 Fix: replaced missing unicode char with emoji 2021-09-01 14:59:05 +01:00
61a40d9471 Added Podman post 2021-09-01 14:52:09 +01:00
007724b8b1 Added border to images 2021-08-31 19:11:24 +01:00
15f34154f1 Added post about job hunting 2021-08-09 12:12:37 +01:00
fe4de971a3 fix images 2021-08-09 05:09:58 +01:00
e44e92e156 Fixed code snippet 2021-08-08 20:14:11 +00:00
c1df167726 Added latency info to multi-cloud post 2021-08-08 19:46:12 +01:00
ea6045be45 added Kosmos post 2021-08-08 09:39:34 +01:00
44c1727846 fix: broken image markdown 2021-08-08 08:31:34 +01:00
204f1d3a1b Merge branch 'master' of https://git.cluster.fun/AverageMarcus/blog 2021-07-31 06:22:36 +01:00
569cee1c5e Updated blackhole to point to infinite redirect 2021-07-13 05:49:44 +00:00
0a3b59f764 Updated filtering routes 2021-06-22 20:17:07 +01:00
88e9ee5d33 Filter more routes 2021-06-21 04:22:39 +01:00
2380008894 Fixed broken link 2021-06-21 04:19:33 +01:00
1d093f3dfb Filter gz files 2021-06-21 04:19:01 +01:00
58b92b4628 Added /healthz endpoint 2021-06-15 04:57:09 +01:00
8f13ad501d Added opengraph image to posts 2021-05-12 09:27:51 +01:00
ce108e696d More bot blocks 2021-02-05 21:59:58 +00:00
ede7d2a77f Added more blackhole routes 2021-01-30 15:48:32 +00:00
bd66550ccc Added sitemap 2021-01-29 22:45:22 +00:00
004b41a6a1 Update 'filterRoutes.js' 2021-01-28 14:14:04 +00:00
955d28ccd1 Updated list of blocked paths 2021-01-28 14:08:09 +00:00
cb6c8919b4 Redirect invalid feed requests 2020-11-21 20:22:43 +00:00
d6a5a30d32 Update 'src/posts/2020-05-27-unicode-support-in-go.md' 2020-11-20 14:34:35 +00:00
7485ae74b1 Remove Google Analytics 🎉 2020-11-20 14:20:52 +00:00
8c3245d36d More bot filtering 2020-11-20 08:08:51 +00:00
209 changed files with 7899 additions and 620 deletions

2
.nvmrc
View File

@@ -1 +1 @@
8 16

View File

@@ -1,9 +1,14 @@
FROM node:12-alpine FROM node:16.17-alpine
RUN apk update && apk add python3 make gcc g++
WORKDIR /app
ADD package.json .
RUN npm install
ADD . . ADD . .
RUN npm install
EXPOSE 8000 EXPOSE 8000
CMD ["npm", "start"] CMD ["npm", "start"]

View File

@@ -1,6 +1,6 @@
.DEFAULT_GOAL := default .DEFAULT_GOAL := default
IMAGE ?= docker.cloud.cluster.fun/averagemarcus/blog:latest IMAGE ?= rg.fr-par.scw.cloud/averagemarcus/blog:latest
.PHONY: test # Run all tests, linting and format checks .PHONY: test # Run all tests, linting and format checks
test: lint check-format run-tests test: lint check-format run-tests
@@ -38,8 +38,8 @@ docker-publish:
@docker push $(IMAGE) @docker push $(IMAGE)
.PHONY: run # Run the application .PHONY: run # Run the application
run: run: docker-build
@npm start @docker run --rm -it -p 8000:8000 $(IMAGE)
.PHONY: ci # Perform CI specific tasks to perform on a pull request .PHONY: ci # Perform CI specific tasks to perform on a pull request
ci: ci:
@@ -47,7 +47,7 @@ ci:
.PHONY: release # Release the latest version of the application .PHONY: release # Release the latest version of the application
release: release:
@kubectl --namespace blog set image deployment blog web=docker.cluster.fun/averagemarcus/blog:$(SHA) @kubectl --namespace blog set image deployment blog web=rg.fr-par.scw.cloud/averagemarcus/blog:$(SHA)
.PHONY: help # Show this list of commands .PHONY: help # Show this list of commands
help: help:

62
app.js
View File

@@ -15,26 +15,62 @@ const define = require('metalsmith-define');
const feed = require('metalsmith-feed'); const feed = require('metalsmith-feed');
const sass = require('metalsmith-sass'); const sass = require('metalsmith-sass');
const date = require('metalsmith-build-date'); const date = require('metalsmith-build-date');
const sitemap = require('metalsmith-sitemap');
const Handlebars = require('handlebars'); const Handlebars = require('handlebars');
const emoji = require('markdown-it-emoji'); const emoji = require('markdown-it-emoji');
const moment = require('moment'); const moment = require('moment');
const striptags = require('striptags'); const striptags = require('striptags');
const port = process.env.PORT || 8000; const port = process.env.PORT || 8000;
const oneDay = 86400000;
app.disable('x-powered-by');
app.use(compress()); app.use(compress());
app.use(express.static(__dirname + '/build')); app.use(express.static(__dirname + '/build'));
// Lets try and slow down some of those exploit crawlers // Lets try and slow down some of those exploit crawlers
app.use("/", require('./filterRoutes')) app.use("/", require('./filterRoutes'));
app.get("/robots.txt", function(reg, res) { // Redirects
res.send("User-agent: * Disallow: ") app.use("/", require('./redirects'));
// Handle some iOS icon 404s
app.get("/apple-touch-icon*", function(req, res) {
res.sendFile(__dirname + '/build/images/favico/' + req.url, () => {
res.sendFile(__dirname + '/build/images/favico/apple-touch-icon.png');
});
});
app.get("/images/favico/*.png", function(req, res) {
res.sendFile(__dirname + '/build/images/favico/apple-touch-icon.png');
});
app.get("/favicon.png", function(req, res) {
res.sendFile(__dirname + '/build/images/favico/apple-touch-icon.png');
});
app.get("/robots.txt", function(req, res) {
res.send("User-agent: * Disallow: ");
}) })
app.get(/(\/(feeds?|rss|atom)\/?|feed.xml|rss.xml|index.rss|feed.rss)$/, function(req, res) {
res.redirect(301, '/feed.xml');
});
app.get(/.+\/manifest.json$/, function(req, res) {
res.redirect(301, '/manifest.json');
});
app.get("/healthz", function(req, res) {
res.sendStatus(200);
});
var md = markdown({html: true}); var md = markdown({html: true});
md.parser.use(emoji); md.parser.use(emoji);
const proxy = (tokens, idx, options, env, self) => self.renderToken(tokens, idx, options);
const defaultTableOpenRenderer = md.parser.renderer.rules.table_open || proxy;
md.parser.renderer.rules.table_open = function(tokens, idx, options, env, self) {
tokens[idx].attrJoin("role", "grid");
return defaultTableOpenRenderer(tokens, idx, options, env, self)
};
Handlebars.registerHelper('markdown', function(text) { Handlebars.registerHelper('markdown', function(text) {
if(!text) return; if(!text) return;
@@ -52,13 +88,18 @@ Handlebars.registerHelper("buildTitle", function(title, siteTitle){
} }
return title; return title;
}); });
Handlebars.registerHelper("jointags", function(tags){
return (tags || '').split(' ').join(',');
});
Handlebars.registerHelper("encodetitle", function(str){
return (str || '').replaceAll(' ', '%2B');
});
Metalsmith(__dirname) Metalsmith(__dirname)
.use(define({ .use(define({
site: { site: {
title: 'Marcus Noble', title: 'Marcus Noble',
description: 'Awesomeness with a side of geek', description: 'The blog of Marcus Noble, self-described tinkerer, platform engineer and all round average guy!',
url: 'https://marcusnoble.co.uk' url: 'https://marcusnoble.co.uk'
} }
})) }))
@@ -79,11 +120,6 @@ Metalsmith(__dirname)
}, },
pages: { pages: {
pattern: 'pages/*' pattern: 'pages/*'
},
experience: {
pattern: 'experience/*',
sortBy: 'start',
reverse: true
} }
})) }))
.use(inplace({ .use(inplace({
@@ -110,6 +146,10 @@ Metalsmith(__dirname)
collection: 'posts', collection: 'posts',
destination: 'feed.xml' destination: 'feed.xml'
})) }))
.use(sitemap({
hostname: 'https://marcusnoble.co.uk',
modifiedProperty: 'date'
}))
.use(pagination({ .use(pagination({
'collections.posts': { 'collections.posts': {
perPage: 5, perPage: 5,

View File

@@ -1,10 +1,88 @@
const express = require('express'); const express = require('express');
const router = express.Router(); const router = express.Router();
router.all('(/*)?/wp-admin/', function (req, res) {}); const blackHole = function (req, res) {
router.all('*?/xmlrpc.php', function (req, res) {}); res.redirect("https://crawler-test.com/redirects/infinite_redirect");
router.all('(/*)?/wp-includes/(*)?', function (req, res) {}); };
router.all('/.git/*?', function (req, res) {});
router.all('/wp-login.php', function (req, res) {}); // Specifically allow, but mark as not-found, any `/.well-known/` paths
router.all(/^\/\.well-known\//, function(req, res) {
res.sendStatus(404);
});
// Block access to any root-level dot files
router.all(/^\/\./, blackHole);
// Block access to file types I don't use
router.all(/.*\.php$/, blackHole);
router.all(/.*\.asp$/, blackHole);
router.all(/.*\.aspx$/, blackHole);
router.all(/.*\.gz$/, blackHole);
router.all(/.*\.bz2$/, blackHole);
router.all(/.*\.tar$/, blackHole);
router.all(/.*\.sql$/, blackHole);
router.all(/.*\.env$/, blackHole);
router.all(/.*\.ini$/, blackHole);
router.all(/.*\.pem$/, blackHole);
router.all(/.*\.key$/, blackHole);
router.all(/.*\.crt$/, blackHole);
router.all(/.*\.properties$/, blackHole);
// Block access to any .git folders
router.all(/.*\/\.git\/.*/, blackHole);
// Block attempts to navigate up directories
router.all(/.*\.\.\/.*/, blackHole);
// Block access to special Mac folder
router.all('/__MACOSX/*?', blackHole);
// Block access to Workdpress files
router.all('(/*)?/wp-admin/', blackHole);
router.all('(/*)?/wp-includes/?(*)?', blackHole);
router.all('(/*)?/wp-content/?(*)?', blackHole);
router.all('/wordpress/', blackHole);
router.all('/wp(2)?/', blackHole);
// Block access to possible databases
router.all('/database/', blackHole);
router.all('/db/', blackHole);
router.all('/db-backup/', blackHole);
router.all('/db_backup/', blackHole);
router.all('/sql-backup/', blackHole);
router.all('/sql/', blackHole);
router.all('/pma/', blackHole);
router.all('/phpmyadmin/', blackHole);
router.all('/mysqladmin/', blackHole);
router.all('/mysql/', blackHole);
router.all('/myadmin/', blackHole);
// Block access to possible backups and uploads
router.all('/backup/', blackHole);
router.all('/uploads/', blackHole);
router.all('/test/', blackHole);
router.all('/temp/', blackHole);
router.all(/.*\/dbbackup\/.*/, blackHole);
router.all('/bak/', blackHole);
router.all('archive.zip', blackHole);
// Block access to possible credentials
router.all('/env.test', blackHole);
router.all('/admin(/.*)?', blackHole)
router.all('/credentials(/*)?', blackHole);
router.all(/.*credentials\.json$/, blackHole);
router.all(/.*keys\.json$/, blackHole);
router.all(/.*secrets\.json$/, blackHole);
// Block system paths
router.all('/etc/*', blackHole);
router.all('/var/*', blackHole);
router.all('/usr/*', blackHole);
router.all('/user/*', blackHole);
// Block misc stuff
router.all('/data/owncloud.log', blackHole);
router.all('/autodiscover/autodiscover.xml', blackHole)
router.all('/.well-known/autoconfig(/*)?', blackHole)
router.all('/sites/default/files/', blackHole);
router.all(/.*\/mail\/config-.+\.xml/, blackHole);
router.all('/bitnami/*', blackHole)
router.all('/aws/*', blackHole)
// Block methods I don't support
router.post('*', blackHole);
router.put('*', blackHole);
router.delete('*', blackHole);
module.exports = router module.exports = router

View File

@@ -20,14 +20,16 @@
"metalsmith-markdownit": "^0.3.0", "metalsmith-markdownit": "^0.3.0",
"metalsmith-pagination": "^1.4.0", "metalsmith-pagination": "^1.4.0",
"metalsmith-permalinks": "^0.5.0", "metalsmith-permalinks": "^0.5.0",
"metalsmith-sass": "^1.7.0", "metalsmith-sass": "^2.0.0",
"metalsmith-sitemap": "^1.2.2",
"moment": "^2.13.0", "moment": "^2.13.0",
"node-sass": "^6.0.0",
"striptags": "^2.1.1" "striptags": "^2.1.1"
}, },
"devDependencies": { "devDependencies": {
"nodemon": "^1.12.1" "nodemon": "^1.12.1"
}, },
"engines": { "engines": {
"node": "8" "node": "16"
} }
} }

8
redirects.js Normal file
View File

@@ -0,0 +1,8 @@
const express = require('express');
const router = express.Router();
router.get('/2022-07-04-managing-kubernetes-without-loosing-your-cool(/)?', function(req, res) {
return res.redirect("/2022-07-04-managing-kubernetes-without-losing-your-cool/")
});
module.exports = router

View File

@@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<browserconfig><msapplication><tile><square70x70logo src="/images/favico/ms-icon-70x70.png"/><square150x150logo src="/images/favico/ms-icon-150x150.png"/><square310x310logo src="/images/favico/ms-icon-310x310.png"/><TileColor>#ffffff</TileColor></tile></msapplication></browserconfig>

101
src/css/_glitch.scss Normal file
View File

@@ -0,0 +1,101 @@
.glitch-image:hover, .glitch:hover, a:hover {
animation-iteration-count: infinite;
}
.glitch-image {
animation: shift 3s ease-in-out .2s alternate 5;
}
.glitch, a:hover {
position: relative;
text-shadow: 0.05em 0 0 var(--primary-hover), -0.03em -0.04em 0 var(--primary), 0.025em 0.04em 0 var(--primary-inverse);
animation: glitch 2s ease alternate 5, shift 2s ease alternate 5;
&::before, &::after {
position: absolute;
top: 0;
left: 0;
}
&::before {
animation: glitch 1s infinite;
clip-path: polygon(0 0, 100% 0, 100% 35%, 0 35%);
transform: translate(-0.04em, -0.03em);
opacity: 0.75;
}
&::after {
animation: glitch .5s infinite;
clip-path: polygon(0 65%, 100% 65%, 100% 100%, 0 100%);
transform: translate(0.04em, 0.03em);
opacity: 0.75;
}
}
@keyframes glitch {
0% {
text-shadow: 0.05em 0 0 var(--primary-hover), -0.03em -0.04em 0 var(--primary),
0.025em 0.04em 0 var(--primary-inverse);
}
15% {
text-shadow: 0.05em 0 0 var(--primary-hover), -0.03em -0.04em 0 var(--primary),
0.025em 0.04em 0 var(--primary-inverse);
}
16% {
text-shadow: -0.05em -0.025em 0 var(--primary-hover), 0.025em 0.035em 0 var(--primary),
-0.05em -0.05em 0 var(--primary-inverse);
}
49% {
text-shadow: -0.05em -0.025em 0 var(--primary-hover), 0.025em 0.035em 0 var(--primary),
-0.05em -0.05em 0 var(--primary-inverse);
}
50% {
text-shadow: 0.05em 0.035em 0 var(--primary-hover), 0.03em 0 0 var(--primary),
0 -0.04em 0 var(--primary-inverse);
}
99% {
text-shadow: 0.05em 0.035em 0 var(--primary-hover), 0.03em 0 0 var(--primary),
0 -0.04em 0 var(--primary-inverse);
}
100% {
text-shadow: -0.05em 0 0 var(--primary-hover), -0.025em -0.04em 0 var(--primary),
-0.04em -0.025em 0 var(--primary-inverse);
}
}
@keyframes shift {
0%,40%, 44%, 58%, 61%, 65%,69%,73%,100% {
transform: skewX(0deg);
filter: invert(0%);
fill: var(--text-color);
}
41% {
transform: skewX(50deg);
fill: var(--primary);
}
42% {
transform: skewX(-20deg);
filter: invert(40%);
}
59% {
transform: skewX(50deg);
fill: var(--primary-hover);
}
60% {
transform: skewX(-40deg);
filter: invert(10%);
}
63% {
transform: skewX(10deg);
filter: invert(30%);
fill: var(--primary-hover);
}
70% {
transform: skewX(-30deg);
fill: var(--primary);
}
71% {
transform: skewX(15deg);
filter: invert(100%);
}
}

View File

@@ -1,64 +0,0 @@
@mixin textShadowToCropUnderline($color) {
text-shadow:
.01em 0 $color,
-.01em 0 $color,
0 .01em $color,
0 -.01em $color,
.06em 0 $color,
-.06em 0 $color,
.09em 0 $color,
-.09em 0 $color,
.12em 0 $color,
-.12em 0 $color,
.15em 0 $color,
-.15em 0 $color;
}
@mixin linkUnderlines($background, $color, $hoverColor) {
color: $color;
text-decoration: none;
@include textShadowToCropUnderline($background);
background-image:
linear-gradient($background, $background),
linear-gradient($background, $background),
linear-gradient($color, $color);
background-size:
.05em 2px,
.05em 2px,
2px 2px;
background-repeat:
no-repeat,
no-repeat,
repeat-x;
background-position: 0% 1.02em, 100% 1.02em, 0% 1.04em;
&::selection {
@include textShadowToCropUnderline($selectionColor);
background-color: $selectionColor;
}
&::-moz-selection {
@include textShadowToCropUnderline($selectionColor);
background-color: $selectionColor;
}
&:before,
&:after,
*,
*:before,
*:after {
text-shadow: none;
}
&:visited {
color: $color;
}
&:hover {
color: $hoverColor;
background-image:
linear-gradient($background, $background),
linear-gradient($background, $background),
linear-gradient($hoverColor, $hoverColor);
}
}

7
src/css/_utils.scss Normal file
View File

@@ -0,0 +1,7 @@
.center {
text-align: center;
}
.hide {
display: none;
}

View File

@@ -1,250 +0,0 @@
$link-color: #AD4E4E;
$selectionColor: #D2D2D2;
$background-color: #FFF;
@import "_underlines.scss";
body {
margin: 0;
padding: 0;
overflow: none;
}
* {
&::selection {
background-color: $selectionColor;
}
&::-moz-selection {
background-color: $selectionColor;
}
}
a {
color: $link-color;
transition: color ease .3s;
&:hover {
color: $link-color;
text-decoration: none;
}
&+img {
border-bottom: none;
}
}
.center {
text-align: center;
}
header {
font-family: 'Lucida Grande', Arial, sans-serif;
font-size: .8em;
a:not(.social) {
@include linkUnderlines($background-color, #4a4a4a, $link-color);
}
h1 {
font-weight: normal;
margin: .8em 0 .8em 8px;
img {
height: 1.2em;
float: left;
border-radius: 20px;
}
a {
color: #000 !important;
text-decoration: none;
margin: 0;
}
.social {
text-decoration: none;
svg {
height: 20px;
}
&:hover svg path,
&:hover svg rect {
fill: $link-color !important;
}
}
}
hr {
margin: 0 auto;
width: 95%;
height: 1px;
background-color: rgba(0, 0, 0, .2);
}
}
pre code {
overflow-x: auto;
overflow-y: auto;
padding-bottom: 15px;
font-size: 0.85em;
}
p > code {
background-color: #3f3f3f;
color: #dcdcdc;
font-size: 0.9em;
padding: 2px 5px;
}
blockquote {
border-left: 8px solid rgba(121, 130, 139, 0.52);
margin-left: 0;
padding-left: 1em;
color: #79828B;
}
figure {
max-width: 100%;
margin: 0 auto;
img {
max-width: 100%;
}
p {
margin: 0;
}
}
iframe {
max-width: 100%;
border: 0;
overflow: scroll;
}
hr {
border: 0;
height: 2px;
background: rgba(121, 130, 139, 0.52);
width: 80%;
}
.emoji {
display: inline !important;
margin: 0 !important;
}
.container {
max-width: 1020px;
margin: 0 auto;
}
.post-list {
list-style: none;
padding: 0;
}
.post-preview {
opacity: 0.6;
}
.pagination {
text-align: center;
}
.pagination a {
font-size: 1.4mem;
color: #000;
}
.post {
font-family: 'Lucida Grande', Arial, sans-serif;
font-size: 18px;
line-height: 28px;
padding: 2px 8px;
a {
@include linkUnderlines($background-color, #4a4a4a, $link-color);
}
.post-title {
color: #000;
font-size: 32px;
line-height: 34px;
margin: 21px 0 0;
font-weight: 700;
a {
color: #000;
text-decoration: none;
margin: 0;
}
}
.full-post-link {
font-style: italic;
font-size: 0.9em;
}
.post-meta {
color: #3d4145;
font-size: 15px;
line-height: 17px;
margin: 0 0 12px 0;
}
}
footer {
margin: 20px 0 10px;
color: #79828B;
text-align: center;
}
.social-icons {
a {
text-decoration: none !important;
background: none !important;
text-shadow: none !important;
}
a svg {
height: 40px;
}
}
.share {
background: transparent;
border: none;
display: none;
cursor: pointer;
&.show {
display: initial;
}
&:hover, &:active {
fill: $link-color;
color: $link-color;
}
svg {
height: 20px;
vertical-align: bottom;
}
}
table {
width: 100%;
border-spacing: 0;
border-collapse: collapse;
&, tr, td, th, tbody, thead {
margin: 0;
padding: 0;
}
th, td {
padding: 5px;
border: 1px solid #3d4145;
}
}

5
src/css/pico.min.css vendored Normal file

File diff suppressed because one or more lines are too long

228
src/css/style.scss Normal file
View File

@@ -0,0 +1,228 @@
/* Light Theme */
[data-theme="light"],
:root:not([data-theme="dark"]) {
--primary: #fd7e0b;
--primary-hover: #326ce5;
--primary-focus: #fefefe;
--primary-inverse: #d6efff;
--color: #131b23;
--text-color: #131b23;
}
/* Dark Theme */
@media only screen and (prefers-color-scheme: dark) {
:root:not([data-theme="light"]) {
--primary: #fd7e0b;
--primary-hover: #326ce5;
--primary-focus: #131b23;
--primary-inverse: #d6efff;
--color: #fefefe;
--text-color: #fefefe;
}
}
[data-theme="dark"] {
--primary: #fd7e0b;
--primary-hover: #326ce5;
--primary-focus: #131b23;
--primary-inverse: #d6efff;
--color: #fefefe;
--text-color: #fefefe;
}
:root:not([data-theme="dark"]),
:root:not([data-theme="light"]){
--form-element-active-border-color: var(--primary);
--form-element-focus-color: var(--primary-focus);
--switch-color: var(--primary-inverse);
--switch-checked-background-color: var(--primary);
--blockquote-border-color: var(--primary-hover);
--font-family: 'Orkney', system-ui, -apple-system, "Segoe UI", "Roboto", "Ubuntu",
"Cantarell", "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji",
"Segoe UI Symbol", "Noto Color Emoji";
}
h2 {
margin-bottom: 10px;
}
// Links
h1 a, h2 a, h3 a, h4 a, h5 a, h6 a {
color: var(--text-color)
}
a:hover {
color: var(--primary);
}
@media only screen and (prefers-color-scheme: light) {
a.social {
svg {
opacity: 0.5;
}
}
}
[data-theme="light"] {
a.social {
svg {
opacity: 0.5;
}
}
}
a.social {
svg {
margin: 4px;
fill: #fff !important;
}
&:hover {
text-decoration: none;
svg {
animation: shift 1.5s ease-in-out infinite;
}
}
}
// Layout
header {
display: flex;
flex-direction: column;
align-items: center;
padding: 2em 0 !important;
& + main {
padding-top: 0;
}
}
footer {
display: flex;
flex-direction: column;
align-items: center;
padding: 1em 0 !important;
}
article {
margin-top: 0;
padding-top: 1.5em;
blockquote, dl, figure, form, ol, p, pre, table, ul {
font-size: calc(var(--font-size) + 2px) !important;
}
a {
display: inline-block;
}
}
figure p,
blockquote p,
blockquote ul {
margin: 0;
}
figure a:hover {
text-shadow: initial;
animation: none;
}
details {
font-size: 0.8em;
border: 1px dashed #79828B;
padding: 2px 8px;
summary {
cursor: pointer;
&::after {
float: unset;
display: inline-block;
height: 10px;
}
}
p {
margin: 0;
}
}
code, kbd, pre {
color: #dcdcdc;
background-color: #3f3f3f;
}
hr {
margin: 1em auto;
padding: 0;
border: 0;
border-top: solid 3px #57688d;
text-align: center;
width: 60%;
position: relative;
&::after {
content: "";
display: inline-block;
position: absolute;
top: -0.7em;
padding: 0 5px;
font-size: 2rem;
filter: grayscale(70%);
transform: translateX(-50%);
}
&::before {
content: ' ';
background-color: var(--background-color);
display: inline-block;
position: absolute;
top: -1.2em;
padding: 0;
width: 50px;
height: 50px;
border-radius: 23px;
transform: translateX(-50%);
article & {
background-color: var(--card-background-color) !important;
}
}
}
section:last-of-type hr {
display: none;
}
// Custom Classes
.site-logo {
display: flex;
flex-direction: column;
align-items: center;
}
.post-meta {
font-size: 0.7em;
font-family: 'OrkneyLight';
vertical-align: text-bottom;
margin-bottom: 0.5em;
&::before {
content: "📆 ";
filter: grayscale(70%);
}
}
.pagination {
display: flex;
flex-direction: row;
justify-content: space-evenly;
}
@import "_utils.scss";
@import "_glitch.scss";

View File

@@ -1,11 +0,0 @@
---
title: Elsevier
url: https://www.elsevier.com
role: Full Stack Software Engineer
start: 2016-02-15
end:
---
<small>Responsibilities include</small>
Building an ecommerce platform with involvement at all levels of development from infrastructure to front-end design. Contributing design and development ideas to advance the project. Working on Node.js and TypeScript projects.

View File

@@ -1,15 +0,0 @@
---
title: Science and technology Facilities Council
url: http://www.stfc.ac.uk/
role: Software Developer (Student Placement)
start: 2011-07-01
end: 2012-09-01
---
<small>Responsibilities included</small>
Being involved at all stages of development for ASP .NET and Java web applications. Providing user supports to systems maintained by our team. Providing maintenance, updates and bug fixes to existing systems and services. Maintain and develop Oracle and Microsoft SQL servers. Communicating with users within and external to the company to resolve issues.
<small>Highlights</small>
I was awarded a Staff Recognition Award for my contribution to a project

View File

@@ -1,11 +0,0 @@
---
title: Science and technology Facilities Council
url: http://www.stfc.ac.uk/
role: Software Developer
start: 2013-06-10
end: 2016-02-15
---
<small>Responsibilities included</small>
Being involved at all stages of development for ASP .NET and Java web applications. Providing user supports to systems maintained by our team. Providing maintenance, updates and bug fixes to existing systems and services. Maintain and develop Oracle and Microsoft SQL servers. Communicating with users within and external to the company to resolve issues.

View File

@@ -1,11 +0,0 @@
---
title: The University of Derby
url: http://www.derby.ac.uk/
role: BSc Computer Science
start: 2009-09-01
end: 2013-06-01
---
<small>Modules included</small>
Software Development, Web Development, Multi-user Database Systems, Mobile Devices, Operating Systems, Systems Analysis, Language Design and Implementation, Distributed Systems, Systems Programming &amp; Enterprise Systems

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
src/images/emf-airfryer.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 KiB

BIN
src/images/emf-food.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

BIN
src/images/emf-jo.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

BIN
src/images/emf-jsoxford.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

BIN
src/images/emf-lasers.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

BIN
src/images/emf-terence.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

BIN
src/images/emf-van.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 307 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 780 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 176 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="192.000000pt" height="192.000000pt" viewBox="0 0 192.000000 192.000000"
preserveAspectRatio="xMidYMid meet">
<metadata>
Created by potrace 1.14, written by Peter Selinger 2001-2017
</metadata>
<g transform="translate(0.000000,192.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none">
<path d="M1055 1592 c-45 -10 -154 -99 -169 -137 -4 -11 -10 -45 -12 -75 -5
-64 -7 -76 -22 -112 -11 -26 -9 -51 8 -118 5 -19 11 -47 14 -63 3 -15 11 -40
18 -55 29 -60 4 -115 -57 -125 -11 -2 -35 -11 -52 -20 -18 -10 -33 -15 -33
-11 0 4 -6 2 -12 -4 -7 -5 -29 -13 -48 -17 -45 -10 -121 -48 -140 -72 -41 -49
-72 -93 -65 -93 4 0 2 -7 -5 -15 -7 -8 -9 -15 -6 -15 4 0 2 -9 -4 -20 -6 -11
-13 -38 -15 -60 -2 -22 -9 -58 -15 -80 -6 -23 -13 -58 -16 -78 -2 -20 -7 -50
-10 -67 -12 -57 -15 -90 -17 -223 l-2 -132 706 0 706 0 -3 58 c-4 90 -12 149
-28 201 -8 27 -12 52 -9 55 3 3 2 13 -2 23 -5 10 -9 24 -11 30 -1 7 -9 32 -17
55 -19 54 -41 128 -58 196 -7 28 -17 52 -21 52 -5 0 -7 4 -3 9 3 5 1 12 -5 16
-5 3 -17 22 -26 41 -15 30 -89 94 -110 94 -4 0 -26 9 -48 20 -23 11 -50 21
-61 23 -11 2 -33 9 -48 15 -16 7 -31 12 -34 12 -16 0 -93 45 -93 54 0 13 52
166 73 215 9 21 12 44 7 60 -4 14 -6 64 -4 111 3 101 -8 130 -68 187 -60 57
-123 79 -183 65z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
src/images/k9s.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Some files were not shown because too many files have changed in this diff Show More