Compare commits
128
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ac5a1fa803
|
||
|
|
8c005c889c
|
||
|
|
eceb031fe6
|
||
|
|
6f4e386e72
|
||
|
|
0c2ffb4311
|
||
|
|
71e0772682
|
||
|
|
2c1a718d5c
|
||
|
|
a798f58c7d
|
||
|
|
703de1a894
|
||
|
|
50fb6bee51
|
||
|
|
9b2fd9104d
|
||
|
|
ff984c7046
|
||
|
|
f5b7a30306
|
||
|
|
65faa97ba1
|
||
|
|
9c01bc5677
|
||
|
|
d744073420
|
||
|
|
f164d510d8
|
||
|
|
24a9a34a73
|
||
|
|
bfcd3f9c8f
|
||
|
|
cb77ed1a2d
|
||
|
|
4b9f9b301c | ||
|
|
61b3cb1500 | ||
|
|
b3fe972d0e | ||
|
|
266b6e0733 | ||
|
|
6ed757b81b | ||
|
|
12741a20c5 | ||
|
|
4cebaf550b | ||
|
|
04b41fa182 | ||
|
|
9e0d3954d2 | ||
|
|
2d6e087342 | ||
|
|
8d5e9c02ad | ||
|
|
a0eb56e115 | ||
|
|
6c31c8752d | ||
|
|
8e15354c2a | ||
|
|
3f888cbeb8 | ||
|
|
f82b6ba8f6 | ||
|
|
bf0b5448b6 | ||
|
|
6271fbb3b0 | ||
|
|
eff86a1f3e | ||
|
|
403fc9d5cb | ||
|
|
67b8a4f581 | ||
|
|
e9d50f1392 | ||
|
|
5d2fd6674f | ||
|
|
2a128f49ab | ||
|
|
b5403fbc0c | ||
|
|
39aff9d684 | ||
|
|
90eff2d619 | ||
|
|
1f7c52a37b | ||
|
|
277ec48ee6 | ||
|
|
cf4c84df5f | ||
|
|
a358896c03 | ||
|
|
3e0462b74b | ||
|
|
1fc48b52e3 | ||
|
|
0850426683 | ||
|
|
6c67113227 | ||
|
|
b8f41fe691 | ||
|
|
1ba2a430fe | ||
|
|
9d44aa5d4e | ||
|
|
4b0f683901 | ||
|
|
7a23117328 | ||
|
|
bd3782cd93 | ||
|
|
09ed207ab6 | ||
|
|
f3f90df38e | ||
|
|
dfe2436718 | ||
|
|
120d6b6941 | ||
|
|
b4440c8cc9 | ||
|
|
da9024548d | ||
|
|
bb923a69e7 | ||
|
|
faaf082c8b | ||
|
|
79c9398981 | ||
|
|
bc785a0077 | ||
|
|
1a5bc59a99 | ||
|
|
f4f9092fe8 | ||
|
|
3e85246344 | ||
|
|
740c584378 | ||
|
|
376f8099b9 | ||
|
|
c8789bc39e | ||
|
|
db3c56cfd8 | ||
|
|
25b90a3432 | ||
|
|
0cab1479f2 | ||
|
|
8acedc284b | ||
|
|
ec8bc54437 | ||
|
|
1904301eae | ||
|
|
b879a4d400 | ||
|
|
c096acdf7d | ||
|
|
b0cd041fd9 | ||
|
|
df3ff8f27c | ||
|
|
bb7e8f9c89 | ||
|
|
04957ad2fc | ||
|
|
914e700056 | ||
|
|
777339c3e1 | ||
|
|
62128bd65b | ||
|
|
d23db35657 | ||
|
|
d966729f7e | ||
|
|
1a42c6ef77 | ||
|
|
318ab4c6ca | ||
|
|
2c7f327892 | ||
|
|
7506909670 | ||
|
|
037c638427 | ||
|
|
78c7ef8809 | ||
|
|
a93722a356 | ||
|
|
a6bf99c945 | ||
|
|
a910feda62 | ||
|
|
cf1ef4257c | ||
|
|
fb5fc2ede2 | ||
|
|
ce4d17974b | ||
|
|
0c566af9a7 | ||
|
|
d6c920bf86 | ||
|
|
f9f9f7010c | ||
|
|
fd991f3dcc | ||
|
|
89e22861af | ||
|
|
3d93b6ddb8 | ||
|
|
418fc1fad4 | ||
|
|
7f0d95b870 | ||
|
|
a8736826bf | ||
|
|
1a76d0d426 | ||
|
|
09a5a7438c | ||
|
|
f948e833e9 | ||
|
|
494f5b5c07 | ||
|
|
760677ce90 | ||
|
|
ffe62b6380 | ||
|
|
dd4e2ca9fb | ||
|
|
aab9885242 | ||
|
|
d8b038dc9c | ||
|
|
43d28f7f6b | ||
|
|
4324e569ca | ||
|
|
56fffda0fe | ||
|
|
9fdbd1b6a1 |
@@ -1,4 +1,2 @@
|
||||
**/node_modules
|
||||
**/dist
|
||||
.git
|
||||
.gitignore
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
* text=auto
|
||||
eol=lf
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
name: Node.js CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master, beta ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
env:
|
||||
CLIENT_DIR: ./client
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [10.x, 12.x, 13.x]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- run: npm ci
|
||||
working-directory: ${{env.CLIENT_DIR}}
|
||||
- run: npm run build --if-present
|
||||
working-directory: ${{env.CLIENT_DIR}}
|
||||
- run: npm test
|
||||
working-directory: ${{env.CLIENT_DIR}}
|
||||
env:
|
||||
CI: true
|
||||
-22
@@ -1,22 +0,0 @@
|
||||
## Node ###
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
|
||||
# Build
|
||||
dist/
|
||||
@@ -0,0 +1,32 @@
|
||||
# Personal-Website
|
||||
[](https://github.com/circl-lastname/HyperLisp)
|
||||
|
||||
A nice introduction to my chaos
|
||||
|
||||
## Backstory
|
||||
Instead of calling it my Personal-Website, you could better call it my Personal-Playground.
|
||||
|
||||
This repo is an example of not being afraid to change a codebase around.
|
||||
It shows the journey of achieving code that fits the needs.
|
||||
|
||||
The posts started with pure excitement from building this site.
|
||||
Making my own content and having complete contol over the format thrilled me.
|
||||
For me, it is about making memorable content, something I can proudly look back on.
|
||||
|
||||
Sarcastic, serious and suprising content.
|
||||
Which becomes super silly stuff when looking back at it ;)
|
||||
|
||||
## Content
|
||||
Once in a while you can enjoy a new post on the website.
|
||||
The posts started talking about the website and all changes that came along.
|
||||
As the website is quite far in development, more focus is put into making relaxing content to read through.
|
||||
|
||||
## Experimentations
|
||||
|
||||
- Swapping QA page for a podcast page
|
||||
- Adding a code++ page: page with a collection of helpful code improvements I came across
|
||||
- Adding a portfolio
|
||||
|
||||
## Thank you
|
||||
Thanks for reading all of this!
|
||||
If you have any questions or sugestions, feel free to send an e-mail to me@raymon.dev.
|
||||
@@ -1,2 +0,0 @@
|
||||
**/node_modules
|
||||
**/dist
|
||||
@@ -0,0 +1,10 @@
|
||||
public/*.html
|
||||
public/error/*.html
|
||||
templates/*.html
|
||||
|
||||
public/assets/images/*
|
||||
|
||||
posts_custom/*
|
||||
!posts_custom/ExamplePostCustomFormat
|
||||
posts_org/*
|
||||
!posts_org/ExamplePostOrgFormat.org
|
||||
@@ -1,11 +1,3 @@
|
||||
FROM node:latest as build-stage
|
||||
WORKDIR /app
|
||||
COPY package*.json ./
|
||||
RUN npm install
|
||||
COPY ./ .
|
||||
RUN npm run build
|
||||
|
||||
FROM nginx as production-stage
|
||||
RUN mkdir /app
|
||||
COPY --from=build-stage /app/dist /app
|
||||
COPY nginx.conf /etc/nginx/nginx.conf
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
module.exports = {
|
||||
presets: ['@vue/cli-plugin-babel/preset'],
|
||||
}
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
# Templates will be filled by posts
|
||||
index_template = File.read!("./templates/post_index_page.html")
|
||||
post_template = File.read!("./templates/post_single_page.html")
|
||||
|
||||
post_feed_item_template = File.read!("./templates/post_item.xml")
|
||||
post_feed_template = File.read!("./templates/posts.xml")
|
||||
|
||||
# Converting handlebars in template to values
|
||||
fill_template = fn template, pairs ->
|
||||
~r/{{(.*)}}/U
|
||||
|> Regex.replace(template, fn _, key -> Map.get(pairs, String.to_atom(key)) end)
|
||||
end
|
||||
|
||||
fill_template_pretemplated = fn template -> &fill_template.(template, &1) end
|
||||
|
||||
filterCutFileExtension = fn files ->
|
||||
fn ext ->
|
||||
Enum.filter(files, &String.ends_with?(&1, "." <> ext))
|
||||
|> Enum.map(&String.replace_suffix(&1, "." <> ext, ""))
|
||||
|> (fn x -> %{String.to_atom(ext) => x} end).()
|
||||
end
|
||||
end
|
||||
|
||||
isMeta = &String.starts_with?(&1, "#+")
|
||||
|
||||
posts_org =
|
||||
File.ls!("./posts_org")
|
||||
|> Enum.reject(fn x -> String.starts_with?(x, ".") end)
|
||||
|> (fn files -> Enum.map(["org", "html"], filterCutFileExtension.(files)) end).()
|
||||
|> Enum.reduce(%{}, fn x, acc -> Map.merge(x, acc) end)
|
||||
|
||||
post_contents_org =
|
||||
Enum.filter(Map.get(posts_org, :org), fn el -> Enum.member?(Map.get(posts_org, :html), el) end)
|
||||
|> Enum.map(
|
||||
&(File.read!("./posts_org/" <> &1 <> ".org")
|
||||
|> (fn fileContent -> String.split(fileContent, "\n") end).()
|
||||
|> Enum.take_while(isMeta)
|
||||
|> Enum.map(fn metaOrg ->
|
||||
[head | tail] = String.split(metaOrg, ":")
|
||||
|
||||
%{
|
||||
(String.slice(head, 2..-1) |> String.downcase() |> String.to_atom()) =>
|
||||
String.slice(Enum.join(tail, ":"), 1..-1)
|
||||
}
|
||||
end)
|
||||
|> Enum.reduce(%{:content => File.read!("./posts_org/" <> &1 <> ".html")}, fn x, acc ->
|
||||
Map.merge(x, acc)
|
||||
end))
|
||||
)
|
||||
|
||||
months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
|
||||
|
||||
dateFolder = fn p ->
|
||||
Map.get(p, :date)
|
||||
|> String.slice(8..15)
|
||||
|> String.split(" ")
|
||||
|> (fn ([month, year]) -> year <> "/" <> Integer.to_string(Enum.find_index(months, &(&1 == month)) + 1) <> "/" end).()
|
||||
end
|
||||
normalize_title = fn title -> String.replace(String.downcase(title), " ", "-") end
|
||||
|
||||
constructLocalPath = fn p -> dateFolder.(p) <> normalize_title.(Map.get(p, :title)) end
|
||||
|
||||
post_contents = post_contents_org
|
||||
|> Enum.map(fn postMap -> Map.merge(postMap, %{localpath: (constructLocalPath.(postMap))}) end)
|
||||
|
||||
date_sort = fn post ->
|
||||
date = Map.get(post, :date)
|
||||
month = Enum.find_index(months, &(&1 == String.slice(date, 8..10)))
|
||||
day = elem(Integer.parse(String.slice(date, 5..6)), 0)
|
||||
32 * month + day
|
||||
end
|
||||
|
||||
index_file =
|
||||
post_contents
|
||||
|> Enum.sort_by(
|
||||
&(Map.get(&1, :date)
|
||||
|> String.slice(5..6)
|
||||
|> Integer.parse())
|
||||
)
|
||||
|> Enum.reverse()
|
||||
# Group by year
|
||||
|> Enum.group_by(fn m -> Map.get(m, :date) |> String.slice(12..15) end)
|
||||
|> Enum.sort_by(fn {d, _c} -> Integer.parse(d) end)
|
||||
|> Enum.reverse()
|
||||
|> Enum.map(fn {year, posts} -> "\n<h1>" <> "12," <> (year |> String.slice(1..3)) <> "</h1>\n<ul>" <> (posts |> Enum.sort_by(date_sort) |> Enum.reverse() |>
|
||||
Enum.map(fn post -> "<li class=\"post-link\">" <>
|
||||
"<time datetime=\""<> Map.get(post, :date) <> "\">" <> (Map.get(post, :date) |> String.slice(0..10)) <> "</time>" <>
|
||||
" - " <>
|
||||
"<a href=\"" <> Map.get(post, :localpath) <> ".html\">" <> Map.get(post, :title) <> "</a>" <>
|
||||
"</li>"
|
||||
end) |> Enum.join("\n")) end)
|
||||
|> Enum.join("\n</ul>")
|
||||
|> (fn v -> %{index: v} end).()
|
||||
|> fill_template_pretemplated.(index_template).()
|
||||
|
||||
File.open!("./public/gen/index.html", [:write])
|
||||
|> IO.binwrite(index_file)
|
||||
|> File.close()
|
||||
|
||||
|
||||
prepare_path = fn path ->
|
||||
File.mkdir_p!(Path.dirname(path))
|
||||
path
|
||||
end
|
||||
|
||||
post_contents
|
||||
|> Enum.each(fn post -> post
|
||||
|> (fn p -> "./public/gen/" <> Map.get(p, :localpath) <> ".html" end).()
|
||||
|> prepare_path.()
|
||||
|> File.open!([:write])
|
||||
|> IO.binwrite(fill_template.(post_template, post))
|
||||
|> File.close()
|
||||
end)
|
||||
|
||||
stripForRSS = fn content -> content
|
||||
|> String.replace("\n", " ")
|
||||
end
|
||||
|
||||
post_feed =
|
||||
post_contents
|
||||
|> Enum.map(fn m -> Map.update!(m, :content, stripForRSS) end)
|
||||
|> Enum.map(fill_template_pretemplated.(post_feed_item_template))
|
||||
|> Enum.join("\n")
|
||||
|> (fn v -> %{items: v} end).()
|
||||
|> fill_template_pretemplated.(post_feed_template).()
|
||||
|
||||
File.open!("./public/gen/rss.xml", [:write])
|
||||
|> IO.binwrite(post_feed)
|
||||
|> File.close()
|
||||
+15
-2
@@ -7,7 +7,7 @@ events {
|
||||
}
|
||||
http {
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||
'$status $body_bytes_sent "$http_referer" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||
@@ -20,8 +20,21 @@ http {
|
||||
location / {
|
||||
root /app;
|
||||
index index.html;
|
||||
try_files $uri $uri/ /index.html;
|
||||
try_files $uri $uri/ $uri.html $uri/index.html =404;
|
||||
}
|
||||
location /css {
|
||||
alias /app/assets/styling;
|
||||
}
|
||||
|
||||
location /posts {
|
||||
alias /app/gen/;
|
||||
}
|
||||
|
||||
error_page 404 /404.html;
|
||||
location = /404.html {
|
||||
root /app/error;
|
||||
}
|
||||
|
||||
error_page 500 502 503 504 /50x.html;
|
||||
location = /50x.html {
|
||||
root /usr/share/nginx/html;
|
||||
|
||||
Generated
-13023
File diff suppressed because it is too large
Load Diff
@@ -1,56 +0,0 @@
|
||||
{
|
||||
"name": "personal-website",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"description": "A nice introduction to my chaos",
|
||||
"main": "src/main.js",
|
||||
"scripts": {
|
||||
"build": "vue-cli-service build",
|
||||
"lint": "vue-cli-service lint",
|
||||
"serve": "vue-cli-service serve",
|
||||
"test": "node test_runner"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/Raymonzut/Personal-Website.git"
|
||||
},
|
||||
"author": "Raymonzut",
|
||||
"license": "ISC",
|
||||
"bugs": {
|
||||
"url": "https://github.com/Raymonzut/Personal-Website/issues"
|
||||
},
|
||||
"homepage": "https://github.com/Raymonzut/Personal-Website#readme",
|
||||
"dependencies": {
|
||||
"core-js": "^3.6.5",
|
||||
"vue": "^2.6.11",
|
||||
"vue-resource": "^1.5.1",
|
||||
"vue-router": "^3.1.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-eslint": "^10.0.3",
|
||||
"eslint": "^6.7.2",
|
||||
"eslint-plugin-vue": "^6.1.2",
|
||||
"@vue/cli-plugin-babel": "~4.2.0",
|
||||
"@vue/cli-plugin-eslint": "~4.2.0",
|
||||
"@vue/cli-service": "~4.2.0",
|
||||
"vue-template-compiler": "^2.6.11"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"root": true,
|
||||
"env": {
|
||||
"node": true
|
||||
},
|
||||
"extends": [
|
||||
"plugin:vue/essential",
|
||||
"eslint:recommended"
|
||||
],
|
||||
"parserOptions": {
|
||||
"parser": "babel-eslint"
|
||||
},
|
||||
"rules": {}
|
||||
},
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
"last 2 versions"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
#+TITLE: Example post for my new org-gen post page!
|
||||
#+DATE: Wed, 28 Apr 2021 11:25:00 GMT
|
||||
My new posts page is live, this post has been generated from an org file
|
||||
@@ -0,0 +1 @@
|
||||
gen/*
|
||||
@@ -0,0 +1,70 @@
|
||||
:root {
|
||||
--primary-color: #272736;
|
||||
--text-color: #ffffeb;
|
||||
|
||||
/* Overriding DP DS */
|
||||
--body-background: var(--primary-color);
|
||||
--body-color: var(--text-color);
|
||||
|
||||
--nav-color: var(--primary-color);
|
||||
--nav-background: var(--text-color);
|
||||
|
||||
--a-color: var(--text-color);
|
||||
}
|
||||
|
||||
nav {
|
||||
width: 100vw;
|
||||
border-bottom-left-radius: 5px;
|
||||
border-bottom-right-radius: 5px;
|
||||
}
|
||||
|
||||
main {
|
||||
padding-bottom: 12em;
|
||||
}
|
||||
|
||||
article {
|
||||
max-width: 1000px;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
pre {
|
||||
padding: 1em;
|
||||
padding-left: 2em;
|
||||
border: solid;
|
||||
border-radius: 1em;
|
||||
border-width: 1px;
|
||||
border-color: var(--text-color);
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
.figure > p {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.question {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2.0em;
|
||||
}
|
||||
|
||||
.post-link {
|
||||
font-family: monospace;
|
||||
font-size: 1.25em;
|
||||
margin: auto 0;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
--primary-color: #ffffeb;
|
||||
--text-color: #272736;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 420px) {
|
||||
#app {
|
||||
margin-left: 0vw;
|
||||
margin-right: 0vw;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,422 @@
|
||||
/* Variables */
|
||||
|
||||
:root {
|
||||
--body-color: rgb(250,250,250);
|
||||
--body-background: rgb(30,40,60);
|
||||
--body-font-family: 'Oxygen', sans-serif;
|
||||
--body-scrollbar-color: dark;
|
||||
--body-margin: 10vw;
|
||||
--body-max-width: 1920px;
|
||||
--body-div-margin: 0;
|
||||
--body-div-padding: 0;
|
||||
--body-div-max-width: none;
|
||||
|
||||
--a-color: white;
|
||||
--a-text-decoration-color: #09c5f4;
|
||||
|
||||
--code-color: white;
|
||||
--code-background: rgba(0,0,0,0.25);
|
||||
--code-font-family: 'Oxygen Mono', monospace;
|
||||
|
||||
--kbd-font-family: var(--code-font-family);
|
||||
--kbd-border: 1px solid white;
|
||||
|
||||
--var-font-family: var(--code-font-family);
|
||||
--var--color: orange;
|
||||
|
||||
--nav-color: black;
|
||||
--nav-background: rgba(255,255,255,0.75);
|
||||
--nav-padding: 1em 0.5em 1em 0.5em;
|
||||
|
||||
--details-background: rgba(0,0,0,0.25);
|
||||
--details-padding: .75em;
|
||||
|
||||
--mark-color: black;
|
||||
--mark-background: rgb(239,219,67);
|
||||
|
||||
--img-margin-left: auto;
|
||||
--img-margin-right: auto;
|
||||
|
||||
--table-max-width: 500px;
|
||||
--table-border: 1px solid white;
|
||||
--table-tr-even-background: rgba(255,255,255,0.1);
|
||||
|
||||
--select-border-color: white;
|
||||
--select-glyph: url('data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22292.4%22%20height%3D%22292.4%22%3E%3Cpath%20fill%3D%22%23FFFFFF%22%20d%3D%22M287%2069.4a17.6%2017.6%200%200%200-13-5.4H18.4c-5%200-9.3%201.8-12.9%205.4A17.6%2017.6%200%200%200%200%2082.2c0%205%201.8%209.3%205.4%2012.9l128%20127.9c3.6%203.6%207.8%205.4%2012.8%205.4s9.2-1.8%2012.8-5.4L287%2095c3.5-3.5%205.4-7.8%205.4-12.8%200-5-1.9-9.2-5.5-12.8z%22%2F%3E%3C%2Fsvg%3E');
|
||||
|
||||
--input-border: 1px solid white;
|
||||
--input-max-width: 500px;
|
||||
--input-font-size: 1em;
|
||||
--input-disabled-background: rgba(255,255,255,.1);
|
||||
|
||||
--button-background: #09c5f4;
|
||||
--button-color: white;
|
||||
}
|
||||
|
||||
/* Body */
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
margin-left: var(--body-margin);
|
||||
margin-right: var(--body-margin);
|
||||
max-width: var(--body-max-width);
|
||||
padding: 0;
|
||||
font-family: var(--body-font-family);
|
||||
color: var(--body-color);
|
||||
background: var(--body-background);
|
||||
scrollbar-color: var(--body-scrollbar-color);
|
||||
line-height: 1.5;
|
||||
text-rendering: optimizeLegibility;
|
||||
}
|
||||
|
||||
body > div {
|
||||
margin-left: var(--body-div-margin);
|
||||
margin-right: var(--body-div-margin);
|
||||
padding-left: var(--body-div-padding);
|
||||
padding-right: var(--body-div-padding);
|
||||
max-width: var(--body-max-width);
|
||||
}
|
||||
|
||||
@media (max-width: 960px) {
|
||||
body {
|
||||
margin-left: calc(var(--body-margin) / 2);
|
||||
margin-right: calc(var(--body-margin) / 2);
|
||||
}
|
||||
|
||||
body > div {
|
||||
margin-left: calc(var(--body-div-margin) / 2);
|
||||
margin-right: calc(var(--body-div-margin) / 2);
|
||||
}
|
||||
}
|
||||
|
||||
/* Text */
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {}
|
||||
|
||||
pre > code {
|
||||
padding: 10px;
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
code {
|
||||
user-select: all;
|
||||
background: var(--code-background);
|
||||
color: var(--code-color);
|
||||
font-size: 1em;
|
||||
font-family: var(--code-font-family);
|
||||
padding: 0.5em;
|
||||
border-radius: 5px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
kbd {
|
||||
font-family: var(--kbd-font-family);
|
||||
display: inline-block;
|
||||
user-select: all;
|
||||
padding: 0.5em;
|
||||
border-radius: 5px;
|
||||
border: var(--kbd-border);
|
||||
font-family: var(--body-font-family);
|
||||
}
|
||||
|
||||
var {
|
||||
color: var(--var-color);
|
||||
font-style: normal;
|
||||
font-family: var(--var-font-family);
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--a-color);
|
||||
scroll-behavior: smooth;
|
||||
text-decoration: underline;
|
||||
text-decoration-color: var(--a-text-decoration-color);
|
||||
transition: color .15s ease;
|
||||
text-decoration-skip: edges;
|
||||
text-decoration-skip-ink: auto;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: var(--a-text-decoration-color);
|
||||
}
|
||||
|
||||
textarea {
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
details {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
background-color: var(--details-background);
|
||||
padding: var(--details-padding) var(--details-padding) 0;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
border-radius: 5px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
details[open] {
|
||||
padding: var(--details-padding)
|
||||
}
|
||||
|
||||
details > :last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
details[open] summary {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
summary {
|
||||
display: list-item;
|
||||
padding: var(--details-padding);
|
||||
margin: calc(-1 * var(--details-padding)) calc(-1 * var(--details-padding)) 0;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
details > :not(summary) {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
mark {
|
||||
background: var(--mark-background);
|
||||
color: var(--mark-color);
|
||||
padding: 0.15em;
|
||||
}
|
||||
|
||||
/* Navigation */
|
||||
|
||||
nav {
|
||||
max-width: none;
|
||||
margin-left: calc(var(--body-margin) * -1);
|
||||
margin-right: calc(var(--body-margin) * -1);
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
color: var(--nav-color);
|
||||
background: var(--nav-background);
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
backdrop-filter: blur(10px);
|
||||
position: sticky;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
@media (max-width: 960px) {
|
||||
nav {
|
||||
margin-left: calc(var(--body-margin) * -1 / 2);
|
||||
margin-right: calc(var(--body-margin) * -1 / 2);
|
||||
}
|
||||
}
|
||||
|
||||
nav * {
|
||||
display: block;
|
||||
padding: var(--nav-padding);
|
||||
color: var(--nav-color);
|
||||
}
|
||||
|
||||
nav a {
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* Tables */
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
display: block;
|
||||
width: 100%;
|
||||
max-width: var(--table-max-width);
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
table > tbody > tr > td, table > tbody > tr > th {
|
||||
border: var(--table-border);
|
||||
text-align: left;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
table > tbody > tr:nth-child(even) {
|
||||
background: var(--table-tr-even-background);
|
||||
}
|
||||
|
||||
table > thead > tr > td, table > thead > tr > th, table > tfoot > tr > td, table > tfoot > tr > th {
|
||||
padding: 0.5em;
|
||||
border: none;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* Images */
|
||||
|
||||
img {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
margin-left: var(--img-margin-left);
|
||||
margin-right: var(--img-margin-right);
|
||||
}
|
||||
|
||||
/* Forms */
|
||||
|
||||
fieldset {
|
||||
border-radius: 5px;
|
||||
border: 1px solid white;
|
||||
margin-inline-start: 0;
|
||||
margin-inline-end: 0;
|
||||
padding-block-start: 0;
|
||||
padding-block-end: 0;
|
||||
padding-inline-start: 0;
|
||||
padding-inline-end: 0;
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
select {
|
||||
font-size: var(--input-font-size);
|
||||
display: inline-block;
|
||||
padding: .5em;
|
||||
width: 100%;
|
||||
max-width: 500px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
select option {
|
||||
background: var(--body-background);
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
select[multiple] {
|
||||
color: var(--body-color);
|
||||
display: inline-block;
|
||||
color: #444;
|
||||
padding: 0.5em;
|
||||
border-radius: 0;
|
||||
width: 100%;
|
||||
max-width: 250px;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid var(--select-border-color);
|
||||
background: rgba(0,0,0,.25);
|
||||
}
|
||||
|
||||
select[multiple] > option {
|
||||
color: var(--body-color);
|
||||
background: rgba(0,0,0,0);
|
||||
}
|
||||
|
||||
@supports(-webkit-appearance: none) or (-moz-appearance: none) or (appearance: none) {
|
||||
input[type='checkbox'], input[type='radio'] {
|
||||
appearance: none;
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
}
|
||||
|
||||
select {
|
||||
font-size: var(--input-font-size);
|
||||
display: inline-block;
|
||||
font-size: 1em;
|
||||
color: var(--body-color);
|
||||
padding: .5em;
|
||||
width: 100%;
|
||||
max-width: 500px;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid var(--select-border-color);
|
||||
box-shadow: none;
|
||||
border-radius: .5em;
|
||||
-moz-appearance: none;
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
background: rgba(0,0,0,.25);
|
||||
background-image: var(--select-glyph);
|
||||
background-repeat: no-repeat, repeat;
|
||||
background-position: right .7em top 50%, 0 0;
|
||||
background-size: .65em auto, 100%;
|
||||
}
|
||||
|
||||
select::-ms-expand {
|
||||
display: none;
|
||||
}
|
||||
|
||||
select[multiple] {
|
||||
color: var(--body-color);
|
||||
display: inline-block;
|
||||
color: #444;
|
||||
padding: 0.5em;
|
||||
border-radius: 0;
|
||||
width: 100%;
|
||||
max-width: 250px;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid var(--select-border-color);
|
||||
background: rgba(0,0,0,.25);
|
||||
}
|
||||
|
||||
select[multiple] > option {
|
||||
color: var(--body-color);
|
||||
}
|
||||
}
|
||||
|
||||
input:not([type="submit"]):not([type="checkbox"]):not([type="radio"]):not([type="range"]), textarea {
|
||||
font-size: var(--input-font-size);
|
||||
color: var(--body-color);
|
||||
font-family: var(--body-font-family);
|
||||
background: rgba(0,0,0,.25);
|
||||
padding: 0.5em;
|
||||
width: 100%;
|
||||
max-width: var(--input-max-width);
|
||||
margin-bottom: 1em;
|
||||
box-sizing: border-box;
|
||||
resize: none;
|
||||
border-radius: 0.5em;
|
||||
border: var(--input-border);
|
||||
}
|
||||
|
||||
input:disabled:not([type="submit"]):not([type="checkbox"]):not([type="radio"]):not([type="range"]) {
|
||||
background: var(--input-disabled-background);
|
||||
}
|
||||
|
||||
button, select, input[type='submit'], input[type='button'], input[type='checkbox'], input[type='range'], input[type='radio'] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
button, .button {
|
||||
display: inline-block;
|
||||
border: none;
|
||||
padding: 1rem 2rem;
|
||||
margin: 0;
|
||||
text-decoration: none;
|
||||
background: var(--button-background);
|
||||
color: var(--button-color);
|
||||
font-size: 1em;
|
||||
text-align: center;
|
||||
transition: background 250ms ease-in-out,
|
||||
transform 150ms ease;
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
appearance: none;
|
||||
}
|
||||
|
||||
button:hover, button:focus, .button:hover, .button:focus {
|
||||
background: #0053ba;
|
||||
}
|
||||
|
||||
button:focus, .button:focus {
|
||||
outline: 1px solid #fff;
|
||||
outline-offset: -4px;
|
||||
}
|
||||
|
||||
button:active, .button:active {
|
||||
transform: scale(0.99);
|
||||
}
|
||||
|
||||
/* Animations */
|
||||
|
||||
details[open] summary ~ * {
|
||||
animation: sweep 0.1s ease-in-out;
|
||||
}
|
||||
|
||||
@keyframes sweep {
|
||||
0% {opacity: 0; margin-top: -10px; margin-bottom: 10px;}
|
||||
90% {opacity: 1; margin-top: -1px; margin-bottom: 1px;}
|
||||
100% {opacity: 1; margin-top: 0px; margin-bottom: 0;}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
(html :lang 'en :dir 'ltr
|
||||
(head
|
||||
(meta :charset 'utf-8)
|
||||
(title "404"))
|
||||
(body
|
||||
"This page could not be found, sorry for the inconvenience"))
|
||||
@@ -1,18 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE-edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Personal Website</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<noscript>
|
||||
<strong>This site doesn't work properly without JavaScript enabled. Please enable to continue.</strong>
|
||||
</noscript>
|
||||
<div id="app"></div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,33 @@
|
||||
(html :lang 'en
|
||||
(head
|
||||
(meta :charset 'utf-8)
|
||||
(meta :name 'description
|
||||
:content "Raymon's personal website about his life and projects with a blog.")
|
||||
(meta :name 'viewport :content "width=device-width, initial-scale=1.0")
|
||||
(title "Raymon Zutekouw")
|
||||
|
||||
(link :defer '
|
||||
:rel 'stylesheet
|
||||
:href "/css/template.css"
|
||||
:media 'all)
|
||||
(link :defer '
|
||||
:rel 'stylesheet
|
||||
:href "/css/general.css"
|
||||
:media 'all))
|
||||
(body
|
||||
(main
|
||||
(nav
|
||||
(a :href "/" "Home") "|"
|
||||
(a :href "/posts" "Posts"))
|
||||
(article
|
||||
(header
|
||||
(h1 "Home"))
|
||||
(p "Hi there, good to see you on my website.
|
||||
My name is Raymon Zutekouw; Self-taught programmer by heart.")
|
||||
(p "Building software and exploring the wide variety of tools (or making them) is my passion.
|
||||
To see it in action, "
|
||||
(a :href "https://git.raymon.dev/raymon" "checkout the stuff I make here."))
|
||||
|
||||
(p "The projects that may be useful to others are open source; for inspiring others and improving each others work.
|
||||
That is why I am a huge fan of "
|
||||
(a :href "https://www.gnu.org/philosophy/free-sw.en.html" "free software"))))))
|
||||
Executable
+1
@@ -0,0 +1 @@
|
||||
User-agent: *
|
||||
@@ -1,28 +0,0 @@
|
||||
<template>
|
||||
<div id="app">
|
||||
<div id="nav">
|
||||
<router-link to="/">Home</router-link> |
|
||||
<router-link to="/posts">Posts</router-link> |
|
||||
<router-link to="/qa">QA</router-link>
|
||||
</div>
|
||||
<router-view />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: 'App',
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
#app {
|
||||
font-family: Avenir, Helvetica, Arial, sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
text-align: center;
|
||||
color: #2c3e50;
|
||||
margin-top: 60px;
|
||||
}
|
||||
</style>
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 6.7 KiB |
@@ -1,34 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<h2>Who am I?</h2>
|
||||
<p>
|
||||
Hi there, good to see you on my website.
|
||||
My name is Raymon Zutekouw({{ age }}).
|
||||
Building software and exploring the wide variety of tools (or making them) is my passion.
|
||||
To see it in action, checkout the stuff I make on
|
||||
<a href='https://github.com/Raymonzut'>GitHub</a>.
|
||||
The projects that may be useful to others are open source; for inspiring others and improving each others work.
|
||||
That is why I am a huge fan of
|
||||
<a href='https://www.gnu.org/philosophy/free-sw.en.html'>free software</a>.
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import me from '../me.js'
|
||||
|
||||
export default {
|
||||
name: 'AboutMe',
|
||||
computed: {
|
||||
age: me.age
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
p {
|
||||
--margin-side: 12vw;
|
||||
margin-left: var(--margin-side);
|
||||
margin-right: var(--margin-side);
|
||||
}
|
||||
</style>
|
||||
@@ -1,18 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
{{ a }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Answer',
|
||||
props: {
|
||||
a: {
|
||||
type: String,
|
||||
required: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
<template>
|
||||
<div id='qa'>
|
||||
<Question :q='q'></Question>
|
||||
<Answer :a='a'></Answer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Question from './Question.vue'
|
||||
import Answer from './Answer.vue'
|
||||
|
||||
export default {
|
||||
name: 'QA',
|
||||
components: {
|
||||
Question,
|
||||
Answer,
|
||||
},
|
||||
props: {
|
||||
q: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
a: {
|
||||
type: String,
|
||||
required: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
#qa {
|
||||
--block-spacing: 7.5em;
|
||||
|
||||
margin-top: var(--block-spacing);
|
||||
margin-bottom: var(--block-spacing);
|
||||
}
|
||||
</style>
|
||||
@@ -1,27 +0,0 @@
|
||||
<template>
|
||||
<div id='question_box'>
|
||||
{{ q }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Question',
|
||||
props: {
|
||||
q: {
|
||||
type: String,
|
||||
required: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
#question_box {
|
||||
--text-spacing: 0.75em;
|
||||
|
||||
font-style: italic;
|
||||
margin-top: var(--text-spacing);
|
||||
margin-bottom: var(--text-spacing);
|
||||
}
|
||||
</style>
|
||||
@@ -1,14 +0,0 @@
|
||||
import Vue from 'vue'
|
||||
import VueResource from 'vue-resource'
|
||||
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
|
||||
Vue.config.productionTip = false
|
||||
|
||||
Vue.use(VueResource)
|
||||
|
||||
new Vue({
|
||||
render: h => h(App),
|
||||
router,
|
||||
}).$mount('#app')
|
||||
@@ -1,21 +0,0 @@
|
||||
module.exports = {
|
||||
age: age,
|
||||
}
|
||||
|
||||
function age() {
|
||||
let birthdate = new Date(2002, 8, 29)
|
||||
let now = new Date()
|
||||
|
||||
let age = now.getFullYear() - birthdate.getFullYear()
|
||||
|
||||
if (now.getMonth() < birthdate.getMonth()) {
|
||||
age--
|
||||
}
|
||||
if (
|
||||
birthdate.getMonth() === now.getMonth() &&
|
||||
now.getDate() < birthdate.getDate()
|
||||
) {
|
||||
age--
|
||||
}
|
||||
return age
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
module.exports = {
|
||||
getPosts: function(id) {
|
||||
const BASE_URL = '/api/posts'
|
||||
const URL = BASE_URL + (id ? `/${id}` : '?sort=-1')
|
||||
|
||||
this.$http
|
||||
.get(URL)
|
||||
.then(res => {
|
||||
if (id) {
|
||||
if (res.body.length === 0) {
|
||||
throw Error("Response body empty")
|
||||
}
|
||||
this.post = res.body
|
||||
}
|
||||
else {
|
||||
this.posts = res.body
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(`Error: ${err}`)
|
||||
})
|
||||
},
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
import Vue from 'vue'
|
||||
import VueRouter from 'vue-router'
|
||||
import Home from '../views/Home.vue'
|
||||
import Posts from '../views/Posts.vue'
|
||||
import Post from '../views/Post.vue'
|
||||
import QAPage from '../views/QAPage'
|
||||
|
||||
Vue.use(VueRouter)
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path: "/",
|
||||
name: "Home",
|
||||
component: Home,
|
||||
},
|
||||
{
|
||||
path: "/posts",
|
||||
name: "Posts",
|
||||
component: Posts,
|
||||
},
|
||||
{
|
||||
path: "/posts/:id",
|
||||
name: "Post",
|
||||
component: Post,
|
||||
props: true,
|
||||
},
|
||||
{
|
||||
path: "/qa",
|
||||
name: "QA",
|
||||
component: QAPage
|
||||
},
|
||||
]
|
||||
|
||||
const exclude_routes = [
|
||||
{
|
||||
path: "/api"
|
||||
}
|
||||
]
|
||||
|
||||
const router = new VueRouter({
|
||||
mode: "history",
|
||||
base: process.env.BASE_URL,
|
||||
routes: routes.concat(exclude_routes),
|
||||
})
|
||||
|
||||
export default router
|
||||
@@ -1,19 +0,0 @@
|
||||
<template>
|
||||
<div id="home">
|
||||
<h1>Home</h1>
|
||||
<AboutMe></AboutMe>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import AboutMe from '@/components/AboutMe'
|
||||
|
||||
export default {
|
||||
name: "Home",
|
||||
components: {
|
||||
AboutMe
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -1,45 +0,0 @@
|
||||
<template>
|
||||
<div id="Post">
|
||||
<div v-if="Object.keys(post).length">
|
||||
<h1>{{ post.title }}</h1>
|
||||
<h5>Written on {{ post.date.substring(0,10)}}</h5>
|
||||
|
||||
<p v-for="(p, i) in post.content.split('\n')" :key="i">{{ p }}</p>
|
||||
</div>
|
||||
<h2 v-else>Waiting for post</h2>
|
||||
<br>
|
||||
Read other <a href="/posts">posts</a>
|
||||
<br>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getPosts } from '../remote'
|
||||
|
||||
export default {
|
||||
name: "Post",
|
||||
data() {
|
||||
return {
|
||||
post: {},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getPosts
|
||||
},
|
||||
mounted() {
|
||||
getPosts.call(this, this._props.id)
|
||||
},
|
||||
props: {
|
||||
id: {
|
||||
type: String,
|
||||
name: "id",
|
||||
validator: val => {
|
||||
const reg = /([0-9]|[a-f]){24}/
|
||||
return reg.test(val)
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -1,68 +0,0 @@
|
||||
<template>
|
||||
<div id="posts" v-if="months.length >= 0">
|
||||
<h3 class="month" v-for="(month, i) in months" :key="i">
|
||||
{{ month }}
|
||||
<div>
|
||||
<ul>
|
||||
<li v-for="(postItem, j) in getPostItems(month)" :key="j">
|
||||
{{ getPostItemDate(postItem) }} –
|
||||
<a :href="/posts/ + postItem._id">{{ postItem.title }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<br>
|
||||
</h3>
|
||||
</div>
|
||||
<h2 v-else>There are no posts yet, but don't worry they will be added soon</h2>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getPosts } from '../remote'
|
||||
|
||||
export default {
|
||||
name: "Posts",
|
||||
computed: {
|
||||
months: function () {
|
||||
const dates = this.posts.map(post => new Date(post.date))
|
||||
|
||||
// Contains the month followed by the year
|
||||
const months = dates.map(date => `${date.toLocaleString('default', { month: 'long' })} ${date.getFullYear()}`)
|
||||
const uniques = Array.from(new Set(months))
|
||||
|
||||
return uniques
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
posts: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getPosts,
|
||||
getPostItems: function (month) {
|
||||
const month_index = new Date(`1 ${month}`).getMonth()
|
||||
return this.posts.filter((post) => (new Date(post.date)).getMonth() === month_index)
|
||||
},
|
||||
getPostItemDate: function (postItem) {
|
||||
const date = new Date(postItem.date)
|
||||
return `${date.getFullYear()} ${date.toLocaleString('default', { month: 'short' })} ${date.getDate()}`
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
getPosts.call(this)
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
ul {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
@media (min-width: 420px) {
|
||||
.month {
|
||||
text-indent: 1em;
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,25 +0,0 @@
|
||||
<template>
|
||||
<div id="QAPage">
|
||||
<QA
|
||||
q="What is this site about? "
|
||||
a="This site is about me and the stuff I make "
|
||||
></QA>
|
||||
|
||||
<QA
|
||||
q="Why is it still so empty?"
|
||||
a="Because I am framework hopping "
|
||||
></QA>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import QA from '@/components/QA'
|
||||
|
||||
export default {
|
||||
name: "QAPAge",
|
||||
components: { QA }
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -0,0 +1,25 @@
|
||||
(html :lang 'en
|
||||
(head
|
||||
(meta :charset 'utf-8)
|
||||
(meta :name 'description
|
||||
:content "Raymon typing nonsense on his blog")
|
||||
(meta :name 'viewport :content "width=device-width, initial-scale=1.0")
|
||||
(title "Raymon Zutekouw")
|
||||
|
||||
(link :defer '
|
||||
:rel 'stylesheet
|
||||
:href "/css/template.css"
|
||||
:media 'all)
|
||||
(link :defer '
|
||||
:rel 'stylesheet
|
||||
:href "/css/general.css"
|
||||
:media 'all))
|
||||
(body
|
||||
(main
|
||||
(nav
|
||||
(a :href "/" "Home") "|"
|
||||
(a :href "/posts" "Posts"))
|
||||
(article
|
||||
(header
|
||||
(h1 "Post listing"))
|
||||
"{{index}}"))))
|
||||
@@ -0,0 +1,9 @@
|
||||
<item>
|
||||
<title>{{title}}</title>
|
||||
<link>https://raymon.dev/posts/{{localpath}}.html</link>
|
||||
<guid>https://raymon.dev/posts/{{localpath}}.html</guid>
|
||||
<pubDate>{{date}}</pubDate>
|
||||
<description><![CDATA[
|
||||
{{content}}
|
||||
]]></description>
|
||||
</item>
|
||||
@@ -0,0 +1,28 @@
|
||||
(html :lang 'en
|
||||
(head
|
||||
(meta :charset 'utf-8)
|
||||
(meta :name 'description
|
||||
:content "Raymon typing nonsense on his blog")
|
||||
(meta :name 'viewport :content "width=device-width, initial-scale=1.0")
|
||||
(title "{{title}} :: Raymon Zutekouw")
|
||||
|
||||
(link :defer '
|
||||
:rel 'stylesheet
|
||||
:href "/css/template.css"
|
||||
:media 'all)
|
||||
(link :defer '
|
||||
:rel 'stylesheet
|
||||
:href "/css/general.css"
|
||||
:media 'all))
|
||||
(body
|
||||
(main
|
||||
(nav
|
||||
(a :href "/" "Home") "|"
|
||||
(a :href "/posts" "Posts"))
|
||||
(article
|
||||
(header
|
||||
(h1 "{{title}}")
|
||||
(p (strong "For those using a RSS reader, subscribe here: ")
|
||||
(a :href "/posts/rss.xml" "rss.xml")))
|
||||
(time :datetime "{{date}}")
|
||||
"{{content}}"))))
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>Raymon Zutekouw</title>
|
||||
<description>Personal blog</description>
|
||||
<language>en-us</language>
|
||||
<link>https://raymon.dev</link>
|
||||
<atom:link href="https://raymon.dev/posts/rss.xml" rel="self" type="application/rss+xml" />
|
||||
{{items}}
|
||||
</channel>
|
||||
</rss>
|
||||
@@ -1,4 +0,0 @@
|
||||
const assert = require('assert').strict
|
||||
const me = require('../src/me')
|
||||
|
||||
assert(me.age() > 0, 'age should return a positive number')
|
||||
@@ -1,22 +0,0 @@
|
||||
const { spawn } = require('child_process')
|
||||
const fs = require('fs')
|
||||
|
||||
const dirs = ['./test', './tests']
|
||||
|
||||
if (!dirs.some(fs.existsSync)) {
|
||||
throw Error("Could not find any test directories, looked for: " + dirs)
|
||||
}
|
||||
|
||||
const test_dirs = dirs.filter(fs.existsSync)
|
||||
|
||||
test_dirs.forEach(test_dir => {
|
||||
const files = fs.readdirSync(test_dir)
|
||||
|
||||
if (files.length === 0) {
|
||||
throw Error("Could not find test files in " + test_dir)
|
||||
}
|
||||
|
||||
const childs = files.map(file =>
|
||||
spawn('node', [`${test_dir}/${file}`], { stdio: 'inherit' })
|
||||
)
|
||||
})
|
||||
Executable
+3
@@ -0,0 +1,3 @@
|
||||
rsync -avz public/assets/images/ raymon.dev:~/Personal-Website/client/public/assets/images
|
||||
rsync -avz public/gen/ raymon.dev:~/Personal-Website/client/public/gen/
|
||||
rsync -avz posts_org/ raymon.dev:~/Personal-Website/client/posts_org
|
||||
@@ -0,0 +1,8 @@
|
||||
version: "3.3"
|
||||
services:
|
||||
client:
|
||||
build: client/
|
||||
ports:
|
||||
- "5010:80"
|
||||
volumes:
|
||||
- "./client/public:/app:rw"
|
||||
@@ -1,3 +0,0 @@
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
@@ -1,2 +0,0 @@
|
||||
**/node_modules
|
||||
**/dist
|
||||
@@ -1,13 +0,0 @@
|
||||
FROM node:latest
|
||||
|
||||
WORKDIR /usr/src/server
|
||||
|
||||
COPY package*.json ./
|
||||
|
||||
RUN npm ci --only=production
|
||||
|
||||
COPY . .
|
||||
|
||||
CMD [ "node", "index.js" ]
|
||||
|
||||
EXPOSE 5000
|
||||
@@ -1,23 +0,0 @@
|
||||
const fastify = require('fastify')()
|
||||
|
||||
fastify.register(require('fastify-cors'))
|
||||
|
||||
const posts = require('./routes/api/posts')
|
||||
|
||||
// Assuming they are all get requests
|
||||
for (let [route, resolver] of posts.entries()) {
|
||||
fastify.get('/posts' + route, resolver)
|
||||
}
|
||||
|
||||
const port = process.env.PORT || 5000
|
||||
|
||||
const start = async () => {
|
||||
try {
|
||||
await fastify.listen(port, '0.0.0.0')
|
||||
console.log(`Launched on port ${port} 🚀`)
|
||||
} catch (err) {
|
||||
fastify.log.error(err)
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
start()
|
||||
Generated
-348
@@ -1,348 +0,0 @@
|
||||
{
|
||||
"name": "server",
|
||||
"version": "1.1.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"abstract-logging": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/abstract-logging/-/abstract-logging-2.0.0.tgz",
|
||||
"integrity": "sha512-/oA9z7JszpIioo6J6dB79LVUgJ3eD3cxkAmdCkvWWS+Y9tPtALs1rLqOekLUXUbYqM2fB9TTK0ibAyZJJOP/CA=="
|
||||
},
|
||||
"ajv": {
|
||||
"version": "6.12.2",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz",
|
||||
"integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==",
|
||||
"requires": {
|
||||
"fast-deep-equal": "^3.1.1",
|
||||
"fast-json-stable-stringify": "^2.0.0",
|
||||
"json-schema-traverse": "^0.4.1",
|
||||
"uri-js": "^4.2.2"
|
||||
}
|
||||
},
|
||||
"archy": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz",
|
||||
"integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA="
|
||||
},
|
||||
"atomic-sleep": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz",
|
||||
"integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ=="
|
||||
},
|
||||
"avvio": {
|
||||
"version": "6.4.1",
|
||||
"resolved": "https://registry.npmjs.org/avvio/-/avvio-6.4.1.tgz",
|
||||
"integrity": "sha512-jeZaUK+F7MuWSNT3VHfltskPJZKqVeTWQqBA4SDaDoLaQ0lb5TOgLeQT1BEuhTIUNISCDCGY3zjYyVmQQ48gKA==",
|
||||
"requires": {
|
||||
"archy": "^1.0.0",
|
||||
"debug": "^4.0.0",
|
||||
"fastq": "^1.6.0"
|
||||
}
|
||||
},
|
||||
"cookie": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz",
|
||||
"integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA=="
|
||||
},
|
||||
"debug": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
|
||||
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
|
||||
"requires": {
|
||||
"ms": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"deepmerge": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
|
||||
"integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg=="
|
||||
},
|
||||
"fast-decode-uri-component": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz",
|
||||
"integrity": "sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg=="
|
||||
},
|
||||
"fast-deep-equal": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz",
|
||||
"integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA=="
|
||||
},
|
||||
"fast-json-stable-stringify": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
|
||||
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
|
||||
},
|
||||
"fast-json-stringify": {
|
||||
"version": "1.20.1",
|
||||
"resolved": "https://registry.npmjs.org/fast-json-stringify/-/fast-json-stringify-1.20.1.tgz",
|
||||
"integrity": "sha512-PEPWrRZvKqI11fY2uDhLLuoapIda9wVQ2mzAj8rkBfVD7jWvOSIICL0Om1knoReIWKF5y/5bbR/GzcZANaaJfQ==",
|
||||
"requires": {
|
||||
"ajv": "^6.11.0",
|
||||
"deepmerge": "^4.2.2",
|
||||
"string-similarity": "^4.0.1"
|
||||
}
|
||||
},
|
||||
"fast-redact": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-2.0.0.tgz",
|
||||
"integrity": "sha512-zxpkULI9W9MNTK2sJ3BpPQrTEXFNESd2X6O1tXMFpK/XM0G5c5Rll2EVYZH2TqI3xRGK/VaJ+eEOt7pnENJpeA=="
|
||||
},
|
||||
"fast-safe-stringify": {
|
||||
"version": "2.0.7",
|
||||
"resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz",
|
||||
"integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA=="
|
||||
},
|
||||
"fastify": {
|
||||
"version": "2.14.1",
|
||||
"resolved": "https://registry.npmjs.org/fastify/-/fastify-2.14.1.tgz",
|
||||
"integrity": "sha512-nSL8AgIdFCpZmFwjqB5Zzv+3/1KpwwVtB/h88Q4Og8njYbkddKGpuQlQ2tHUULXPTJrLZ7wop6olzx6HEbHdpw==",
|
||||
"requires": {
|
||||
"abstract-logging": "^2.0.0",
|
||||
"ajv": "^6.12.0",
|
||||
"avvio": "^6.3.1",
|
||||
"fast-json-stringify": "^1.18.0",
|
||||
"find-my-way": "^2.2.2",
|
||||
"flatstr": "^1.0.12",
|
||||
"light-my-request": "^3.7.3",
|
||||
"middie": "^4.1.0",
|
||||
"pino": "^5.17.0",
|
||||
"proxy-addr": "^2.0.6",
|
||||
"readable-stream": "^3.6.0",
|
||||
"rfdc": "^1.1.2",
|
||||
"secure-json-parse": "^2.1.0",
|
||||
"tiny-lru": "^7.0.2"
|
||||
}
|
||||
},
|
||||
"fastify-cors": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/fastify-cors/-/fastify-cors-3.0.3.tgz",
|
||||
"integrity": "sha512-SDMa+GtyTTAU7pWZwY4fukb/VwCZ4c30p0oEaE7/d/+VCvceB1+NzW2udp2dSZZfWR7J1kUookCpw2dLmtAsSw==",
|
||||
"requires": {
|
||||
"fastify-plugin": "^1.6.0",
|
||||
"vary": "^1.1.2"
|
||||
}
|
||||
},
|
||||
"fastify-plugin": {
|
||||
"version": "1.6.1",
|
||||
"resolved": "https://registry.npmjs.org/fastify-plugin/-/fastify-plugin-1.6.1.tgz",
|
||||
"integrity": "sha512-APBcb27s+MjaBIerFirYmBLatoPCgmHZM6XP0K+nDL9k0yX8NJPWDY1RAC3bh6z+AB5ULS2j31BUfLMT3uaZ4A==",
|
||||
"requires": {
|
||||
"semver": "^6.3.0"
|
||||
}
|
||||
},
|
||||
"fastq": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.8.0.tgz",
|
||||
"integrity": "sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q==",
|
||||
"requires": {
|
||||
"reusify": "^1.0.4"
|
||||
}
|
||||
},
|
||||
"find-my-way": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/find-my-way/-/find-my-way-2.2.2.tgz",
|
||||
"integrity": "sha512-zk3eOsS1tABNQjII0vCbhkqgsX/COpRUxl0b5rlA41V2Ft7jWDr30LhYq4BZXLAlzw5yskg24XQG/U1wCT30vQ==",
|
||||
"requires": {
|
||||
"fast-decode-uri-component": "^1.0.0",
|
||||
"safe-regex2": "^2.0.0",
|
||||
"semver-store": "^0.3.0"
|
||||
}
|
||||
},
|
||||
"flatstr": {
|
||||
"version": "1.0.12",
|
||||
"resolved": "https://registry.npmjs.org/flatstr/-/flatstr-1.0.12.tgz",
|
||||
"integrity": "sha512-4zPxDyhCyiN2wIAtSLI6gc82/EjqZc1onI4Mz/l0pWrAlsSfYH/2ZIcU+e3oA2wDwbzIWNKwa23F8rh6+DRWkw=="
|
||||
},
|
||||
"forwarded": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
|
||||
"integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
},
|
||||
"ipaddr.js": {
|
||||
"version": "1.9.1",
|
||||
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
|
||||
"integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="
|
||||
},
|
||||
"json-schema-traverse": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
|
||||
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
|
||||
},
|
||||
"light-my-request": {
|
||||
"version": "3.8.0",
|
||||
"resolved": "https://registry.npmjs.org/light-my-request/-/light-my-request-3.8.0.tgz",
|
||||
"integrity": "sha512-cIOWmNsgoStysmkzcv2EwvLwMb2hEm6oqKMerG/b5ey9F0we2Qony8cAZgBktmGPYUvPyKsDCzMcYU6fXbpWew==",
|
||||
"requires": {
|
||||
"ajv": "^6.10.2",
|
||||
"cookie": "^0.4.0",
|
||||
"readable-stream": "^3.4.0",
|
||||
"set-cookie-parser": "^2.4.1"
|
||||
}
|
||||
},
|
||||
"middie": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/middie/-/middie-4.1.0.tgz",
|
||||
"integrity": "sha512-eylPpZA+K3xO9kpDjagoPkEUkNcWV3EAo5OEz0MqsekUpT7KbnQkk8HNZkh4phx2vvOAmNNZuLRWF9lDDHPpVQ==",
|
||||
"requires": {
|
||||
"path-to-regexp": "^4.0.0",
|
||||
"reusify": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
},
|
||||
"path-to-regexp": {
|
||||
"version": "4.0.5",
|
||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-4.0.5.tgz",
|
||||
"integrity": "sha512-l+fTaGG2N9ZRpCEUj5fG1VKdDLaiqwCIvPngpnxzREhcdobhZC4ou4w984HBu72DqAJ5CfcdV6tjqNOunfpdsQ=="
|
||||
},
|
||||
"pino": {
|
||||
"version": "5.17.0",
|
||||
"resolved": "https://registry.npmjs.org/pino/-/pino-5.17.0.tgz",
|
||||
"integrity": "sha512-LqrqmRcJz8etUjyV0ddqB6OTUutCgQULPFg2b4dtijRHUsucaAdBgSUW58vY6RFSX+NT8963F+q0tM6lNwGShA==",
|
||||
"requires": {
|
||||
"fast-redact": "^2.0.0",
|
||||
"fast-safe-stringify": "^2.0.7",
|
||||
"flatstr": "^1.0.12",
|
||||
"pino-std-serializers": "^2.4.2",
|
||||
"quick-format-unescaped": "^3.0.3",
|
||||
"sonic-boom": "^0.7.5"
|
||||
}
|
||||
},
|
||||
"pino-std-serializers": {
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-2.4.2.tgz",
|
||||
"integrity": "sha512-WaL504dO8eGs+vrK+j4BuQQq6GLKeCCcHaMB2ItygzVURcL1CycwNEUHTD/lHFHs/NL5qAz2UKrjYWXKSf4aMQ=="
|
||||
},
|
||||
"proxy-addr": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz",
|
||||
"integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==",
|
||||
"requires": {
|
||||
"forwarded": "~0.1.2",
|
||||
"ipaddr.js": "1.9.1"
|
||||
}
|
||||
},
|
||||
"punycode": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
|
||||
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
|
||||
},
|
||||
"quick-format-unescaped": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-3.0.3.tgz",
|
||||
"integrity": "sha512-dy1yjycmn9blucmJLXOfZDx1ikZJUi6E8bBZLnhPG5gBrVhHXx2xVyqqgKBubVNEXmx51dBACMHpoMQK/N/AXQ=="
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
|
||||
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
|
||||
"requires": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
"util-deprecate": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"ret": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/ret/-/ret-0.2.2.tgz",
|
||||
"integrity": "sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ=="
|
||||
},
|
||||
"reusify": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
|
||||
"integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw=="
|
||||
},
|
||||
"rfdc": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.1.4.tgz",
|
||||
"integrity": "sha512-5C9HXdzK8EAqN7JDif30jqsBzavB7wLpaubisuQIGHWf2gUXSpzy6ArX/+Da8RjFpagWsCn+pIgxTMAmKw9Zug=="
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
|
||||
},
|
||||
"safe-regex2": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/safe-regex2/-/safe-regex2-2.0.0.tgz",
|
||||
"integrity": "sha512-PaUSFsUaNNuKwkBijoAPHAK6/eM6VirvyPWlZ7BAQy4D+hCvh4B6lIG+nPdhbFfIbP+gTGBcrdsOaUs0F+ZBOQ==",
|
||||
"requires": {
|
||||
"ret": "~0.2.0"
|
||||
}
|
||||
},
|
||||
"secure-json-parse": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.1.0.tgz",
|
||||
"integrity": "sha512-GckO+MS/wT4UogDyoI/H/S1L0MCcKS1XX/vp48wfmU7Nw4woBmb8mIpu4zPBQjKlRT88/bt9xdoV4111jPpNJA=="
|
||||
},
|
||||
"semver": {
|
||||
"version": "6.3.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
||||
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
|
||||
},
|
||||
"semver-store": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/semver-store/-/semver-store-0.3.0.tgz",
|
||||
"integrity": "sha512-TcZvGMMy9vodEFSse30lWinkj+JgOBvPn8wRItpQRSayhc+4ssDs335uklkfvQQJgL/WvmHLVj4Ycv2s7QCQMg=="
|
||||
},
|
||||
"set-cookie-parser": {
|
||||
"version": "2.4.5",
|
||||
"resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.4.5.tgz",
|
||||
"integrity": "sha512-LkSDwseogN5l6TerqGzFzL9mUDTxSq3hX2b5AaynjC1nSCNWiDypEgHatfc0v6KcnfgV3/6F6h4ABh6igjzlQQ=="
|
||||
},
|
||||
"sonic-boom": {
|
||||
"version": "0.7.7",
|
||||
"resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-0.7.7.tgz",
|
||||
"integrity": "sha512-Ei5YOo5J64GKClHIL/5evJPgASXFVpfVYbJV9PILZQytTK6/LCwHvsZJW2Ig4p9FMC2OrBrMnXKgRN/OEoAWfg==",
|
||||
"requires": {
|
||||
"atomic-sleep": "^1.0.0",
|
||||
"flatstr": "^1.0.12"
|
||||
}
|
||||
},
|
||||
"string-similarity": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/string-similarity/-/string-similarity-4.0.1.tgz",
|
||||
"integrity": "sha512-v36MJzloekKVvKAsYi6O/qpn2mIuvwEFIT9Gx3yg4spkNjXYsk7yxc37g4ZTyMVIBvt/9PZGxnqEtme8XHK+Mw=="
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
|
||||
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
|
||||
"requires": {
|
||||
"safe-buffer": "~5.2.0"
|
||||
}
|
||||
},
|
||||
"tiny-lru": {
|
||||
"version": "7.0.2",
|
||||
"resolved": "https://registry.npmjs.org/tiny-lru/-/tiny-lru-7.0.2.tgz",
|
||||
"integrity": "sha512-cmc9OOwmnAJtyFBYaznKR3abypEhWecarFrvS5db6qwSgoaDUWV0JX+mdh6B9wN60Wux3+gE1vjzxkoqxFBjqw=="
|
||||
},
|
||||
"uri-js": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
|
||||
"integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
|
||||
"requires": {
|
||||
"punycode": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
|
||||
},
|
||||
"vary": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||
"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
{
|
||||
"name": "server",
|
||||
"version": "1.1.0",
|
||||
"description": "The API for the website",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"start": "node ./index.js",
|
||||
"dev": "nodemon server/index.js"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"fastify": "^2.14.1",
|
||||
"fastify-cors": "^3.0.3"
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
*.json
|
||||
@@ -1,6 +0,0 @@
|
||||
All the posts will be in here seperate in JSON format
|
||||
|
||||
post
|
||||
- title
|
||||
- date
|
||||
- content
|
||||
@@ -1,56 +0,0 @@
|
||||
const fs = require('fs')
|
||||
|
||||
const posts_dir = 'posts/'
|
||||
|
||||
const routes = new Map();
|
||||
|
||||
if (!fs.existsSync(posts_dir)) throw Error(`Missing ${posts_dir}`)
|
||||
|
||||
let posts = readPosts();
|
||||
|
||||
setInterval(() => posts = readPosts(), 1000 * 60 * 60)
|
||||
|
||||
function readPosts() {
|
||||
console.warn("reading all posts")
|
||||
const files = fs.readdirSync(posts_dir)
|
||||
|
||||
if (files.length === 0) throw Error(`Could not find posts in ${posts_dir}`)
|
||||
|
||||
return files.filter(file_name => file_name.endsWith('.json'))
|
||||
.map(file_name => `${posts_dir}${file_name}`)
|
||||
.map(readJSONAsObject)
|
||||
}
|
||||
|
||||
function readJSONAsObject(filename) {
|
||||
return JSON.parse(fs.readFileSync(filename, 'utf8'))
|
||||
}
|
||||
|
||||
function notFoundResponse(res) {
|
||||
res.status(404).send('Sorry, can not find that')
|
||||
}
|
||||
|
||||
routes.set('', async (req, res) => {
|
||||
if (req.query.sort === '-1' || req.query.sort === '1') {
|
||||
const posts_sorted = posts.sort((a, b) => {
|
||||
return new Date(a.date).getTime() - new Date(b.date).getTime()
|
||||
})
|
||||
|
||||
if (req.query.sort === '1') res.send(posts_sorted)
|
||||
else res.send(posts_sorted.reverse())
|
||||
}
|
||||
})
|
||||
|
||||
routes.set('/:id', async (req, res) => {
|
||||
const re = /[0-9A-Fa-f]{24}/g
|
||||
|
||||
if (!re.test(req.params.id)) {
|
||||
notFoundResponse(res)
|
||||
return
|
||||
}
|
||||
const results = posts.filter(post => post._id === req.params.id)
|
||||
|
||||
if (!results.length) notFoundResponse(res)
|
||||
else res.send(results[0])
|
||||
})
|
||||
|
||||
module.exports = routes
|
||||
Reference in New Issue
Block a user