diff --git a/.idea/deno.xml b/.idea/deno.xml new file mode 100644 index 0000000..2e4b145 --- /dev/null +++ b/.idea/deno.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.vim/coc-settings.json b/.vim/coc-settings.json new file mode 100644 index 0000000..c97e2f0 --- /dev/null +++ b/.vim/coc-settings.json @@ -0,0 +1,6 @@ +{ + "deno.enable": true, + "deno.lint": true, + "deno.unstable": true, + "tsserver.enable": false +} \ No newline at end of file diff --git a/assets/github-mark.svg b/assets/github-mark.svg index 37fa923..3a9b2ed 100644 --- a/assets/github-mark.svg +++ b/assets/github-mark.svg @@ -1 +1,5 @@ - \ No newline at end of file + + + \ No newline at end of file diff --git a/build.ts b/build.ts new file mode 100644 index 0000000..4f81f98 --- /dev/null +++ b/build.ts @@ -0,0 +1,23 @@ +import { startServer } from "./server.ts"; + +async function main() { + const server = startServer("localhost", 6969); + + const chromiumCmd = new Deno.Command("chromium", { + args: [ + "--headless", + "--print-to-pdf=./cv.pdf", + "--no-pdf-header-footer", + "http://localhost:6969/cv.html" + ] + }) + + const process = chromiumCmd.spawn() + await process.status + + await server.shutdown() +} + +if (import.meta.main) { + await main(); +} diff --git a/cv.html b/cv.html index 86077ae..3d1ce2d 100644 --- a/cv.html +++ b/cv.html @@ -17,7 +17,7 @@
- +

About Me

@@ -29,7 +29,7 @@

- +

Employment History

@@ -125,7 +125,7 @@
- +

Education

@@ -274,4 +274,4 @@ document.title = originalTitle; }); - \ No newline at end of file + diff --git a/cv.pdf b/cv.pdf new file mode 100644 index 0000000..1195297 Binary files /dev/null and b/cv.pdf differ diff --git a/deno.json b/deno.json new file mode 100644 index 0000000..de980d8 --- /dev/null +++ b/deno.json @@ -0,0 +1,6 @@ +{ + "imports": { + "@std/fs": "jsr:@std/fs@^1.0.5", + "@std/path": "jsr:@std/path@^1.0.7" + } +} diff --git a/deno.lock b/deno.lock new file mode 100644 index 0000000..d20412f --- /dev/null +++ b/deno.lock @@ -0,0 +1,17 @@ +{ + "version": "4", + "specifiers": { + "jsr:@std/path@^1.0.7": "1.0.7" + }, + "jsr": { + "@std/path@1.0.7": { + "integrity": "76a689e07f0e15dcc6002ec39d0866797e7156629212b28f27179b8a5c3b33a1" + } + }, + "workspace": { + "dependencies": [ + "jsr:@std/fs@^1.0.5", + "jsr:@std/path@^1.0.7" + ] + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..1cf4e50 --- /dev/null +++ b/package.json @@ -0,0 +1,12 @@ +{ + "name": "resume", + "version": "1.0.0", + "main": "index.js", + "repository": "gitea@git.botris.dev:john/resume.git", + "author": "john ", + "license": "MIT", + "private": true, + "scripts": { + "serve": "deno run --allow-read=. --allow-net server.ts" + } +} diff --git a/serve.ts b/serve.ts new file mode 100644 index 0000000..f78fe44 --- /dev/null +++ b/serve.ts @@ -0,0 +1,42 @@ + +let server: Deno.HttpServer | null = null; +async function runScript() { + if (server) { + await server.shutdown(); + } + + const { startServer } = await import((`./server.ts?cache_bust=${Date.now()}`)); + server = startServer("localhost", 6969); +} + +function debounced(fn: () => Promise) { + let timeoutId: ReturnType | null; + return () => { + if (timeoutId) { + clearTimeout(timeoutId); + } + + timeoutId = setTimeout(fn, 200); + }; +} + +// Watch for file changes +async function watchFiles(paths: string[], handler: () => void) { + const watcher = Deno.watchFs(paths); + for await (const event of watcher) { + if (event.kind === "modify" || event.kind === "create") { + handler(); + } + } +} + +async function startup() { + // Initial run + runScript(); + await watchFiles(["."], debounced(runScript)); +} + +if (import.meta.main) { + await startup() +} + diff --git a/server.ts b/server.ts new file mode 100644 index 0000000..5d18739 --- /dev/null +++ b/server.ts @@ -0,0 +1,44 @@ +import * as path from "@std/path" +export function startServer(hostname = "localhost", port = 6969) { + return Deno.serve( + { hostname, port }, + async (req) => { + const url = new URL(req.url); + const filepath = decodeURIComponent(url.pathname); + + try { + const file = await Deno.open("." + filepath, { read: true }); + const headers: [string, string][] = [ + ["Cache-Control", "no-cache"] + ] + + const extension = path.extname(filepath); + + const contentType = { + '.svg': "image/svg+xml", + '.png': "image/png", + '.jpeg': "image/jpeg", + '.woff2': "font/woff2", + '.ttf': "font/ttf", + '.css': "text/css", + ".html": "text/html" + }[extension] + + if (contentType) { + headers.push(["Content-Type", contentType]) + } + + return new Response(file.readable, { + headers + }); + } catch { + return new Response("404 Not Found", { status: 404 }); + } + }, + ); +} + + +if (import.meta.main) { + startServer("localhost", 6969) +} \ No newline at end of file