From 38b8178cce160b3d2e6c8b3256c7655f4d0a27cd Mon Sep 17 00:00:00 2001 From: "user@node5.net" Date: Mon, 15 Jun 2026 21:24:56 +0200 Subject: internalize needed files for starting the program --- src/blog.node5.net/motd.md | 47 ++ src/blog.node5.net/static/RobotoMono-Bold.ttf | Bin 0 -> 87392 bytes src/blog.node5.net/static/RobotoMono-Regular.ttf | Bin 0 -> 87236 bytes src/blog.node5.net/static/article.css | 21 + src/blog.node5.net/static/bg.webp | Bin 0 -> 24074 bytes src/blog.node5.net/static/comment_section.css | 20 + src/blog.node5.net/static/devicons.css | 787 +++++++++++++++++++++ src/blog.node5.net/static/folder.css | 54 ++ src/blog.node5.net/static/fonts/devicons.eot | Bin 0 -> 125648 bytes src/blog.node5.net/static/fonts/devicons.svg | 208 ++++++ src/blog.node5.net/static/fonts/devicons.ttf | Bin 0 -> 125484 bytes src/blog.node5.net/static/fonts/devicons.woff | Bin 0 -> 125560 bytes src/blog.node5.net/static/main.css | 212 ++++++ .../static/motd/C+++++++++++++++++++++++++++.png | Bin 0 -> 129008 bytes src/blog.node5.net/static/motd/code128.webp | Bin 0 -> 646 bytes .../static/motd/debian_stable_jurasic_park.webp | Bin 0 -> 3992 bytes .../static/pygmentize_code_highlight.css | 84 +++ src/blog.node5.net/templates/article.html | 10 + .../templates/article_meta_data.html | 9 + src/blog.node5.net/templates/base.html | 66 ++ src/blog.node5.net/templates/folder.html | 39 + src/blog_node5_net.py | 5 +- src/create_db.sql | 25 + src/db_handler.py | 14 +- 24 files changed, 1597 insertions(+), 4 deletions(-) create mode 100644 src/blog.node5.net/motd.md create mode 100644 src/blog.node5.net/static/RobotoMono-Bold.ttf create mode 100644 src/blog.node5.net/static/RobotoMono-Regular.ttf create mode 100644 src/blog.node5.net/static/article.css create mode 100644 src/blog.node5.net/static/bg.webp create mode 100644 src/blog.node5.net/static/comment_section.css create mode 100644 src/blog.node5.net/static/devicons.css create mode 100644 src/blog.node5.net/static/folder.css create mode 100755 src/blog.node5.net/static/fonts/devicons.eot create mode 100755 src/blog.node5.net/static/fonts/devicons.svg create mode 100755 src/blog.node5.net/static/fonts/devicons.ttf create mode 100755 src/blog.node5.net/static/fonts/devicons.woff create mode 100644 src/blog.node5.net/static/main.css create mode 100644 src/blog.node5.net/static/motd/C+++++++++++++++++++++++++++.png create mode 100644 src/blog.node5.net/static/motd/code128.webp create mode 100644 src/blog.node5.net/static/motd/debian_stable_jurasic_park.webp create mode 100644 src/blog.node5.net/static/pygmentize_code_highlight.css create mode 100644 src/blog.node5.net/templates/article.html create mode 100644 src/blog.node5.net/templates/article_meta_data.html create mode 100644 src/blog.node5.net/templates/base.html create mode 100644 src/blog.node5.net/templates/folder.html create mode 100644 src/create_db.sql (limited to 'src') diff --git a/src/blog.node5.net/motd.md b/src/blog.node5.net/motd.md new file mode 100644 index 0000000..f4c7579 --- /dev/null +++ b/src/blog.node5.net/motd.md @@ -0,0 +1,47 @@ +Hosted in a bunker, [no really](https://labitat.dk/wiki/Bunkers) +100% Biodegradable, contains 0 JavaScript +Available over legacy IP and [IPv6](https://howtodisableipv6.com/) +Available as a TOR hidden service, see [tor.node5.net](http://node5net2j2kvsepjjlbnovz6wwpcclur3ecuadmo36cikjriqxaucid.onion) +BTW I run Arch Debian NixOS +Hosted on Debian +Enriched by PostgreSQL +[Running Python Flask](https://git.node5.net/blog/blog.node5.net_flask/about/) +Self-hosted! +\#Instagram4nerds +[:%s/.\*\\cNotch.\*\n/](https://minecraft.wiki/w/Java_Edition_19w13a#General_2) +[ErhΓΆhter koffein-gehalt 20 mg/100ml](https://en.wikipedia.org/wiki/Club-Mate) +[[citation needed](https://en.wikipedia.org/wiki/Citation_needed)] +[09 F9 11 02 9D 74 E3 5B D8 41 56 C5 63 56 88 C0](https://en.wikipedia.org/wiki/Illegal_number) +Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. +HTTP Status code: `200` Body: `{"status_code": 500, "message": Internal Server Error"}` +[:( Your PC ran Windows](https://en.wikipedia.org/wiki/Blue_screen_of_death) +Any diode can be light emitting, if you put enough current through it +[And god proclaimed *640x480 16 colors*](https://en.wikipedia.org/wiki/TempleOS) +It’s now safe to turn off your computer +httpsπŸ˜•/node5.net +![C+++++++++++++++++++++++++++.png](/motd/C+++++++++++++++++++++++++++.png) +[502 Naughty Gateway](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/502) +Knock knock, Async, Who is there? +Data breach Decentralized surprise backup +[ \*\*\* ] A stop job is running for blog.node5.net.service (51s / no limit) +[Real men test in production](https://en.wikipedia.org/wiki/Titan_submersible_implosion) +[Mess with the best, die like the rest](https://en.wikipedia.org/wiki/Hackers_(film)) +[Just one more lane](https://en.wikipedia.org/wiki/Induced_demand) +[Remember to turn off your computer before 2038 19/01 03:14:08](https://en.wikipedia.org/wiki/Year_2038_problem) +Please insert disk labeled *Windows XP Professional CD-ROM* into [Drive A](https://superuser.com/questions/231273/what-are-the-windows-a-and-b-drives-used-for#answer-233284): +[developers developers developers πŸ‘ developers πŸ‘ developers πŸ‘ developers! πŸ‘ DEVELOPERS! πŸ‘ DEVELOPERS! πŸ‘ DEVELOPERS! πŸ‘ DEVELOPERS! πŸ‘ DEVELOPERS! πŸ‘ DEVELOPERS! πŸ‘ developers πŸ‘ developers, yes! πŸ₯΅ - Steve Balmer, CEO of Microsoft, year 2000](https://www.youtube.com/watch?v=hMLcKtVwF-A) +alarm chrono +unknown option -h type --help to see help +unknown option --help type -h to see help +stopped distro hopping, now i DE hop +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* +[Embrace, extend, extinguish](https://en.wikipedia.org/wiki/Embrace%2C_extend%2C_and_extinguish)
πŸŸ₯🟩
🟦🟨
+πŸŸ₯🟧🟨🟩🟦πŸŸͺ +CYBER +If you don't schedule maintainence, your equipment will do it for you +[Where do you get your vaccine information from? Personally i just get it from the kernel mailing list](https://lkml.org/lkml/2021/6/10/957) +Not hosted on [`us-east-1`](https://news.ycombinator.com/item?id=45640838) +How to generate random strings? Ask someone to exit vim +\[3410.304506] Kernel panic - not syncing: No init found. +![code128](/motd/code128.webp) +![Debian stable - Jurassic park logo](motd/debian_stable_jurasic_park.webp) diff --git a/src/blog.node5.net/static/RobotoMono-Bold.ttf b/src/blog.node5.net/static/RobotoMono-Bold.ttf new file mode 100644 index 0000000..d884128 Binary files /dev/null and b/src/blog.node5.net/static/RobotoMono-Bold.ttf differ diff --git a/src/blog.node5.net/static/RobotoMono-Regular.ttf b/src/blog.node5.net/static/RobotoMono-Regular.ttf new file mode 100644 index 0000000..6df2b25 Binary files /dev/null and b/src/blog.node5.net/static/RobotoMono-Regular.ttf differ diff --git a/src/blog.node5.net/static/article.css b/src/blog.node5.net/static/article.css new file mode 100644 index 0000000..d482ed4 --- /dev/null +++ b/src/blog.node5.net/static/article.css @@ -0,0 +1,21 @@ +img { + max-width: 100%; + height: auto; + max-height: 30em; +} + +.codehilite { + background: unset !important; +} + +blockquote>p:before { + content: "ℹ️"; + padding: 1em; +} + +blockquote { + border: white solid 1px; + border-left: var(--main-color) solid 5px; + padding-left: 1em; + padding-right: 1em; +} diff --git a/src/blog.node5.net/static/bg.webp b/src/blog.node5.net/static/bg.webp new file mode 100644 index 0000000..7360911 Binary files /dev/null and b/src/blog.node5.net/static/bg.webp differ diff --git a/src/blog.node5.net/static/comment_section.css b/src/blog.node5.net/static/comment_section.css new file mode 100644 index 0000000..7aa1727 --- /dev/null +++ b/src/blog.node5.net/static/comment_section.css @@ -0,0 +1,20 @@ +input, textarea, select { + background: transparent; + border: 1px solid #3e3e3e; + border-radius: 0.3em; + color:white; + padding: 0.5em; + margin: 0.3em; + width: 29%; +} + +textarea:focus, input:focus, select:focus { + outline: none; + border: 0.2em solid #00ffff; +} + +#comment { + width: 90%; + margin: 1em 0; +} + diff --git a/src/blog.node5.net/static/devicons.css b/src/blog.node5.net/static/devicons.css new file mode 100644 index 0000000..def7eb3 --- /dev/null +++ b/src/blog.node5.net/static/devicons.css @@ -0,0 +1,787 @@ +ο»Ώ/*! + * Devicons 1.8.0 made by Theodore Vorillas / http://vorillaz.com + */ +@font-face { + font-family: 'devicons'; + src: url("../fonts/devicons.eot?xqxft6"); + src: url("../fonts/devicons.eot?#iefixxqxft6") format("embedded-opentype"), url("../fonts/devicons.woff?xqxft6") format("woff"), url("../fonts/devicons.ttf?xqxft6") format("truetype"), url("../fonts/devicons.svg?xqxft6#devicons") format("svg"); + font-weight: normal; + font-style: normal; +} + +.devicons { + font-family: 'devicons'; + speak: none; + font-style: normal; + font-weight: normal; + font-variant: normal; + text-transform: none; + line-height: 1; + /* Better Font Rendering =========== */ + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.devicons-git:before { + content: "\e602"; +} + +.devicons-git_compare:before { + content: "\e628"; +} + +.devicons-git_branch:before { + content: "\e625"; +} + +.devicons-git_commit:before { + content: "\e629"; +} + +.devicons-git_pull_request:before { + content: "\e626"; +} + +.devicons-git_merge:before { + content: "\e627"; +} + +.devicons-bitbucket:before { + content: "\e603"; +} + +.devicons-github_alt:before { + content: "\e608"; +} + +.devicons-github_badge:before { + content: "\e609"; +} + +.devicons-github:before { + content: "\e60a"; +} + +.devicons-github_full:before { + content: "\e617"; +} + +.devicons-java:before { + content: "\e638"; +} + +.devicons-ruby:before { + content: "\e639"; +} + +.devicons-scala:before { + content: "\e637"; +} + +.devicons-python:before { + content: "\e63c"; +} + +.devicons-go:before { + content: "\e624"; +} + +.devicons-ruby_on_rails:before { + content: "\e63b"; +} + +.devicons-django:before { + content: "\e61d"; +} + +.devicons-markdown:before { + content: "\e63e"; +} + +.devicons-php:before { + content: "\e63d"; +} + +.devicons-mysql:before { + content: "\e604"; +} + +.devicons-streamline:before { + content: "\e605"; +} + +.devicons-database:before { + content: "\e606"; +} + +.devicons-laravel:before { + content: "\e63f"; +} + +.devicons-javascript:before { + content: "\e64e"; +} + +.devicons-angular:before { + content: "\e653"; +} + +.devicons-backbone:before { + content: "\e652"; +} + +.devicons-coffeescript:before { + content: "\e651"; +} + +.devicons-jquery:before { + content: "\e650"; +} + +.devicons-modernizr:before { + content: "\e620"; +} + +.devicons-jquery_ui:before { + content: "\e654"; +} + +.devicons-ember:before { + content: "\e61b"; +} + +.devicons-dojo:before { + content: "\e61c"; +} + +.devicons-nodejs:before { + content: "\e619"; +} + +.devicons-nodejs_small:before { + content: "\e618"; +} + +.devicons-javascript_shield:before { + content: "\e64f"; +} + +.devicons-bootstrap:before { + content: "\e647"; +} + +.devicons-sass:before { + content: "\e64b"; +} + +.devicons-css3_full:before { + content: "\e64a"; +} + +.devicons-css3:before { + content: "\e649"; +} + +.devicons-html5:before { + content: "\e636"; +} + +.devicons-html5_multimedia:before { + content: "\e632"; +} + +.devicons-html5_device_access:before { + content: "\e633"; +} + +.devicons-html5_3d_effects:before { + content: "\e635"; +} + +.devicons-html5_connectivity:before { + content: "\e634"; +} + +.devicons-ghost_small:before { + content: "\e614"; +} + +.devicons-ghost:before { + content: "\e61f"; +} + +.devicons-magento:before { + content: "\e640"; +} + +.devicons-joomla:before { + content: "\e641"; +} + +.devicons-jekyll_small:before { + content: "\e60d"; +} + +.devicons-drupal:before { + content: "\e642"; +} + +.devicons-wordpress:before { + content: "\e60b"; +} + +.devicons-grunt:before { + content: "\e64c"; +} + +.devicons-bower:before { + content: "\e64d"; +} + +.devicons-npm:before { + content: "\e61e"; +} + +.devicons-yahoo_small:before { + content: "\e62b"; +} + +.devicons-yahoo:before { + content: "\e615"; +} + +.devicons-bing_small:before { + content: "\e600"; +} + +.devicons-windows:before { + content: "\e60f"; +} + +.devicons-linux:before { + content: "\e612"; +} + +.devicons-ubuntu:before { + content: "\e63a"; +} + +.devicons-android:before { + content: "\e60e"; +} + +.devicons-apple:before { + content: "\e611"; +} + +.devicons-appstore:before { + content: "\e613"; +} + +.devicons-phonegap:before { + content: "\e630"; +} + +.devicons-blackberry:before { + content: "\e623"; +} + +.devicons-stackoverflow:before { + content: "\e610"; +} + +.devicons-techcrunch:before { + content: "\e62c"; +} + +.devicons-codrops:before { + content: "\e62f"; +} + +.devicons-css_tricks:before { + content: "\e601"; +} + +.devicons-smashing_magazine:before { + content: "\e62d"; +} + +.devicons-netmagazine:before { + content: "\e62e"; +} + +.devicons-codepen:before { + content: "\e616"; +} + +.devicons-cssdeck:before { + content: "\e62a"; +} + +.devicons-hackernews:before { + content: "\e61a"; +} + +.devicons-dropbox:before { + content: "\e607"; +} + +.devicons-google_drive:before { + content: "\e631"; +} + +.devicons-visualstudio:before { + content: "\e60c"; +} + +.devicons-unity_small:before { + content: "\e621"; +} + +.devicons-raspberry_pi:before { + content: "\e622"; +} + +.devicons-chrome:before { + content: "\e643"; +} + +.devicons-ie:before { + content: "\e644"; +} + +.devicons-firefox:before { + content: "\e645"; +} + +.devicons-opera:before { + content: "\e646"; +} + +.devicons-safari:before { + content: "\e648"; +} + +.devicons-swift:before { + content: "\e655"; +} + +.devicons-symfony:before { + content: "\e656"; +} + +.devicons-symfony_badge:before { + content: "\e657"; +} + +.devicons-less:before { + content: "\e658"; +} + +.devicons-stylus:before { + content: "\e659"; +} + +.devicons-trello:before { + content: "\e65a"; +} + +.devicons-atlassian:before { + content: "\e65b"; +} + +.devicons-jira:before { + content: "\e65c"; +} + +.devicons-envato:before { + content: "\e65d"; +} + +.devicons-snap_svg:before { + content: "\e65e"; +} + +.devicons-raphael:before { + content: "\e65f"; +} + +.devicons-google_analytics:before { + content: "\e660"; +} + +.devicons-compass:before { + content: "\e661"; +} + +.devicons-onedrive:before { + content: "\e662"; +} + +.devicons-gulp:before { + content: "\e663"; +} + +.devicons-atom:before { + content: "\e664"; +} + +.devicons-cisco:before { + content: "\e665"; +} + +.devicons-nancy:before { + content: "\e666"; +} + +.devicons-clojure:before { + content: "\e668"; +} + +.devicons-clojure_alt:before { + content: "\e66a"; +} + +.devicons-perl:before { + content: "\e669"; +} + +.devicons-celluloid:before { + content: "\e66b"; +} + +.devicons-w3c:before { + content: "\e66c"; +} + +.devicons-redis:before { + content: "\e66d"; +} + +.devicons-postgresql:before { + content: "\e66e"; +} + +.devicons-webplatform:before { + content: "\e66f"; +} + +.devicons-jenkins:before { + content: "\e667"; +} + +.devicons-requirejs:before { + content: "\e670"; +} + +.devicons-opensource:before { + content: "\e671"; +} + +.devicons-typo3:before { + content: "\e672"; +} + +.devicons-uikit:before { + content: "\e673"; +} + +.devicons-doctrine:before { + content: "\e674"; +} + +.devicons-groovy:before { + content: "\e675"; +} + +.devicons-nginx:before { + content: "\e676"; +} + +.devicons-haskell:before { + content: "\e677"; +} + +.devicons-zend:before { + content: "\e678"; +} + +.devicons-gnu:before { + content: "\e679"; +} + +.devicons-yeoman:before { + content: "\e67a"; +} + +.devicons-heroku:before { + content: "\e67b"; +} + +.devicons-debian:before { + content: "\e67d"; +} + +.devicons-travis:before { + content: "\e67e"; +} + +.devicons-dotnet:before { + content: "\e67f"; +} + +.devicons-codeigniter:before { + content: "\e680"; +} + +.devicons-javascript_badge:before { + content: "\e681"; +} + +.devicons-yii:before { + content: "\e682"; +} + +.devicons-msql_server:before { + content: "\e67c"; +} + +.devicons-composer:before { + content: "\e683"; +} + +.devicons-krakenjs_badge:before { + content: "\e684"; +} + +.devicons-krakenjs:before { + content: "\e685"; +} + +.devicons-mozilla:before { + content: "\e686"; +} + +.devicons-firebase:before { + content: "\e687"; +} + +.devicons-sizzlejs:before { + content: "\e688"; +} + +.devicons-creativecommons:before { + content: "\e689"; +} + +.devicons-creativecommons_badge:before { + content: "\e68a"; +} + +.devicons-mitlicence:before { + content: "\e68b"; +} + +.devicons-senchatouch:before { + content: "\e68c"; +} + +.devicons-bugsense:before { + content: "\e68d"; +} + +.devicons-extjs:before { + content: "\e68e"; +} + +.devicons-mootools_badge:before { + content: "\e68f"; +} + +.devicons-mootools:before { + content: "\e690"; +} + +.devicons-ruby_rough:before { + content: "\e691"; +} + +.devicons-komodo:before { + content: "\e692"; +} + +.devicons-coda:before { + content: "\e693"; +} + +.devicons-bintray:before { + content: "\e694"; +} + +.devicons-terminal:before { + content: "\e695"; +} + +.devicons-code:before { + content: "\e696"; +} + +.devicons-responsive:before { + content: "\e697"; +} + +.devicons-dart:before { + content: "\e698"; +} + +.devicons-aptana:before { + content: "\e699"; +} + +.devicons-mailchimp:before { + content: "\e69a"; +} + +.devicons-netbeans:before { + content: "\e69b"; +} + +.devicons-dreamweaver:before { + content: "\e69c"; +} + +.devicons-brackets:before { + content: "\e69d"; +} + +.devicons-eclipse:before { + content: "\e69e"; +} + +.devicons-cloud9:before { + content: "\e69f"; +} + +.devicons-scrum:before { + content: "\e6a0"; +} + +.devicons-prolog:before { + content: "\e6a1"; +} + +.devicons-terminal_badge:before { + content: "\e6a2"; +} + +.devicons-code_badge:before { + content: "\e6a3"; +} + +.devicons-mongodb:before { + content: "\e6a4"; +} + +.devicons-meteor:before { + content: "\e6a5"; +} + +.devicons-meteorfull:before { + content: "\e6a6"; +} + +.devicons-fsharp:before { + content: "\e6a7"; +} + +.devicons-rust:before { + content: "\e6a8"; +} + +.devicons-ionic:before { + content: "\e6a9"; +} + +.devicons-sublime:before { + content: "\e6aa"; +} + +.devicons-appcelerator:before { + content: "\e6ab"; +} + +.devicons-asterisk:before { + content: "\e6ac"; +} + +.devicons-aws:before { + content: "\e6ad"; +} + +.devicons-digital-ocean:before { + content: "\e6ae"; +} + +.devicons-dlang:before { + content: "\e6af"; +} + +.devicons-docker:before { + content: "\e6b0"; +} + +.devicons-erlang:before { + content: "\e6b1"; +} + +.devicons-google-cloud-platform:before { + content: "\e6b2"; +} + +.devicons-grails:before { + content: "\e6b3"; +} + +.devicons-illustrator:before { + content: "\e6b4"; +} + +.devicons-intellij:before { + content: "\e6b5"; +} + +.devicons-materializecss:before { + content: "\e6b6"; +} + +.devicons-openshift:before { + content: "\e6b7"; +} + +.devicons-photoshop:before { + content: "\e6b8"; +} + +.devicons-rackspace:before { + content: "\e6b9"; +} + +.devicons-react:before { + content: "\e6ba"; +} + +.devicons-redhat:before { + content: "\e6bb"; +} + +.devicons-scriptcs:before { + content: "\e6bc"; +} + +.devicons-sqllite:before { + content: "\e6c4"; +} + +.devicons-vim:before { + content: "\e6c5"; +} diff --git a/src/blog.node5.net/static/folder.css b/src/blog.node5.net/static/folder.css new file mode 100644 index 0000000..e72f886 --- /dev/null +++ b/src/blog.node5.net/static/folder.css @@ -0,0 +1,54 @@ +.entry { + display: flex; + flex-wrap: wrap; /* Allow title to flow to next line, in case of space constraints */ +} + +.entry > a { + text-decoration: none; + width: fix-content; +} + +.entry-text { + display: flex; + margin-left: 1em; + max-width: 70%; +} + +.description { + color: white; +} + +ol { + padding: 0; +} + +.entry img { + font-size: 4em; + width: 200px; + float: left; + text-align: center; + color: #fff7; /* Alt text document for no image less bright */ +} + +.entries > hr { + margin: 2em 0; + opacity: 0.06; +} + +/* Leave margin to HR for consistent spacing */ +h4 { + margin: 0; +} +h4 > p { + margin-bottom: 0; +} + +@media screen and (max-width: 50rem) { + .entry > * { + width: 100%; + } + .entry > a > img { + width: 100%; + margin-bottom: 0.5em; + } +} diff --git a/src/blog.node5.net/static/fonts/devicons.eot b/src/blog.node5.net/static/fonts/devicons.eot new file mode 100755 index 0000000..6eeaacb Binary files /dev/null and b/src/blog.node5.net/static/fonts/devicons.eot differ diff --git a/src/blog.node5.net/static/fonts/devicons.svg b/src/blog.node5.net/static/fonts/devicons.svg new file mode 100755 index 0000000..5149508 --- /dev/null +++ b/src/blog.node5.net/static/fonts/devicons.svg @@ -0,0 +1,208 @@ + + + +Generated by IcoMoon + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/blog.node5.net/static/fonts/devicons.ttf b/src/blog.node5.net/static/fonts/devicons.ttf new file mode 100755 index 0000000..b4980db Binary files /dev/null and b/src/blog.node5.net/static/fonts/devicons.ttf differ diff --git a/src/blog.node5.net/static/fonts/devicons.woff b/src/blog.node5.net/static/fonts/devicons.woff new file mode 100755 index 0000000..65bf160 Binary files /dev/null and b/src/blog.node5.net/static/fonts/devicons.woff differ diff --git a/src/blog.node5.net/static/main.css b/src/blog.node5.net/static/main.css new file mode 100644 index 0000000..8a61703 --- /dev/null +++ b/src/blog.node5.net/static/main.css @@ -0,0 +1,212 @@ +:root { + --main-color: #02e5e1; + --secondary-color: #0aee23; + --tertiary-color: #F40B36; + --quaternary-color: #FFBF00; +} + +.main-color { + color: var(--main-color); +} + +.secondary-color { + color: var(--secondary-color); +} + +.tertiary-color { + color: var(--tertiary-color); +} + +.glow { + text-shadow: 0 0 0.5em var(--main-color); +} + +.quaternary-color { + color: var(--quaternary-color); +} + +@font-face { + font-family: "RobotoMono-Regular"; + src: url("RobotoMono-Regular.ttf"); +} + +@font-face { + font-family: "RobotoMono-Bold"; + src: url("RobotoMono-Bold.ttf"); +} + +body { + font-family: "RobotoMono-Regular", monospace; + background: black; + color: white; +} + +#content { + padding: 1em; +} + +#root-container { + padding: 0 3em; +} + +/* Dynamic padding on sides based on page width, too wide text is hard to read */ + +@media screen and (max-width: 25rem) { + #root-container { + padding: 0!important; + } +} + +/* Phone */ +@media screen and (max-width: 40rem) { + #root-container { + padding: 0 2em; + } +} + +@media screen and (min-width: 70rem) { + #root-container { + padding: 0 15em; + } +} + +@media screen and (min-width: 100rem) { + #root-container { + padding: 0 25em; + } +} + +/* Ultra wide */ +@media screen and (min-width: 200rem) { + #root-container { + padding: 0 60em; + } +} + +#logo h1 { + font-family: "RobotoMono-Bold", monospace; + font-size: 2.5em; + margin: 0; + color: var(--main-color); +} + +.grey { + color: #777; +} + +.dark-grey { + color: #444; +} + +.inline { + display: inline-block; +} + +hr { + color: var(--main-color); +} + +a:link { + color: var(--main-color); + text-decoration: None; +} + +a:visited { + color: magenta; +} + +h1 { + color: var(--secondary-color); + margin: 0; + text-decoration: underline; + text-decoration-thickness: 0.1em; +} + +h2 { + color: var(--tertiary-color); +} + +h3 { + color: var(--quaternary-color); + margin: 0; +} + +table { + border-collapse: collapse; +} + +th, td { + border: 1px solid grey; +} + +tr:nth-child(even) { + background-color: #222; +} + +.entries { + padding: 0; + list-style: None; + margin: 0; +} + +label{ + font-size: 0.75em; +} + +.width-100{ + width: 100%; +} + +#motd { + margin-bottom: 2em; + rotate: 2deg; +} + +#motd img{ +max-height: 2em; +} + +img { + border-radius: 6px; +} + +/* Background blurred image */ +body:before { + content: ""; + position: fixed; /* Change to fixed to keep it in place during scroll */ + top: 0; /* Align to the top */ + left: 0; /* Align to the left */ + background: linear-gradient( + rgba(0, 0, 0, 0.7), + rgba(0, 0, 0, 0.7) + ), url(bg.webp); + background-size: cover; + z-index: -1; /* Keep the background behind the content */ + height: 100vh; /* Full viewport height */ + width: 100vw; /* Full viewport width */ + + /* don't forget to use the prefixes you need */ + transform: scale(1); /* Adjust scale as needed */ + filter: blur(0.25em); + background-position: center; +} + +/* Code highlight */ +pre:not(#comments) { + overflow: auto; + width: calc(100% - 2em); + padding: 1em; + border-radius: 0.5em; + display: inline-block; + background: #111; +} + +.container { + background-color: #050b11d4; + padding: 0.5em; +} + +::selection { + color: black; + background: var(--main-color); +} diff --git a/src/blog.node5.net/static/motd/C+++++++++++++++++++++++++++.png b/src/blog.node5.net/static/motd/C+++++++++++++++++++++++++++.png new file mode 100644 index 0000000..85413b2 Binary files /dev/null and b/src/blog.node5.net/static/motd/C+++++++++++++++++++++++++++.png differ diff --git a/src/blog.node5.net/static/motd/code128.webp b/src/blog.node5.net/static/motd/code128.webp new file mode 100644 index 0000000..9fb7108 Binary files /dev/null and b/src/blog.node5.net/static/motd/code128.webp differ diff --git a/src/blog.node5.net/static/motd/debian_stable_jurasic_park.webp b/src/blog.node5.net/static/motd/debian_stable_jurasic_park.webp new file mode 100644 index 0000000..2c62c23 Binary files /dev/null and b/src/blog.node5.net/static/motd/debian_stable_jurasic_park.webp differ diff --git a/src/blog.node5.net/static/pygmentize_code_highlight.css b/src/blog.node5.net/static/pygmentize_code_highlight.css new file mode 100644 index 0000000..26f039d --- /dev/null +++ b/src/blog.node5.net/static/pygmentize_code_highlight.css @@ -0,0 +1,84 @@ +pre { line-height: 125%; } +td.linenos .normal { color: #37474F; background-color: #263238; padding-left: 5px; padding-right: 5px; } +span.linenos { color: #37474F; background-color: #263238; padding-left: 5px; padding-right: 5px; } +td.linenos .special { color: #607A86; background-color: #263238; padding-left: 5px; padding-right: 5px; } +span.linenos.special { color: #607A86; background-color: #263238; padding-left: 5px; padding-right: 5px; } +.codehilite .hll { background-color: #2C3B41 } +.codehilite { background: #263238; color: #EFF } +.codehilite .c { color: #546E7A; font-style: italic } /* Comment */ +.codehilite .err { color: #FF5370 } /* Error */ +.codehilite .esc { color: #89DDFF } /* Escape */ +.codehilite .g { color: #EFF } /* Generic */ +.codehilite .k { color: #BB80B3 } /* Keyword */ +.codehilite .l { color: #C3E88D } /* Literal */ +.codehilite .n { color: #EFF } /* Name */ +.codehilite .o { color: #89DDFF } /* Operator */ +.codehilite .p { color: #89DDFF } /* Punctuation */ +.codehilite .ch { color: #546E7A; font-style: italic } /* Comment.Hashbang */ +.codehilite .cm { color: #546E7A; font-style: italic } /* Comment.Multiline */ +.codehilite .cp { color: #546E7A; font-style: italic } /* Comment.Preproc */ +.codehilite .cpf { color: #546E7A; font-style: italic } /* Comment.PreprocFile */ +.codehilite .c1 { color: #546E7A; font-style: italic } /* Comment.Single */ +.codehilite .cs { color: #546E7A; font-style: italic } /* Comment.Special */ +.codehilite .gd { color: #FF5370 } /* Generic.Deleted */ +.codehilite .ge { color: #89DDFF } /* Generic.Emph */ +.codehilite .ges { color: #FFCB6B } /* Generic.EmphStrong */ +.codehilite .gr { color: #FF5370 } /* Generic.Error */ +.codehilite .gh { color: #C3E88D } /* Generic.Heading */ +.codehilite .gi { color: #C3E88D } /* Generic.Inserted */ +.codehilite .go { color: #546E7A } /* Generic.Output */ +.codehilite .gp { color: #FFCB6B } /* Generic.Prompt */ +.codehilite .gs { color: #FF5370 } /* Generic.Strong */ +.codehilite .gu { color: #89DDFF } /* Generic.Subheading */ +.codehilite .gt { color: #FF5370 } /* Generic.Traceback */ +.codehilite .kc { color: #89DDFF } /* Keyword.Constant */ +.codehilite .kd { color: #BB80B3 } /* Keyword.Declaration */ +.codehilite .kn { color: #89DDFF; font-style: italic } /* Keyword.Namespace */ +.codehilite .kp { color: #89DDFF } /* Keyword.Pseudo */ +.codehilite .kr { color: #BB80B3 } /* Keyword.Reserved */ +.codehilite .kt { color: #BB80B3 } /* Keyword.Type */ +.codehilite .ld { color: #C3E88D } /* Literal.Date */ +.codehilite .m { color: #F78C6C } /* Literal.Number */ +.codehilite .s { color: #C3E88D } /* Literal.String */ +.codehilite .na { color: #BB80B3 } /* Name.Attribute */ +.codehilite .nb { color: #82AAFF } /* Name.Builtin */ +.codehilite .nc { color: #FFCB6B } /* Name.Class */ +.codehilite .no { color: #EFF } /* Name.Constant */ +.codehilite .nd { color: #82AAFF } /* Name.Decorator */ +.codehilite .ni { color: #89DDFF } /* Name.Entity */ +.codehilite .ne { color: #FFCB6B } /* Name.Exception */ +.codehilite .nf { color: #82AAFF } /* Name.Function */ +.codehilite .nl { color: #82AAFF } /* Name.Label */ +.codehilite .nn { color: #FFCB6B } /* Name.Namespace */ +.codehilite .nx { color: #EFF } /* Name.Other */ +.codehilite .py { color: #FFCB6B } /* Name.Property */ +.codehilite .nt { color: #FF5370 } /* Name.Tag */ +.codehilite .nv { color: #89DDFF } /* Name.Variable */ +.codehilite .ow { color: #89DDFF; font-style: italic } /* Operator.Word */ +.codehilite .pm { color: #89DDFF } /* Punctuation.Marker */ +.codehilite .w { color: #EFF } /* Text.Whitespace */ +.codehilite .mb { color: #F78C6C } /* Literal.Number.Bin */ +.codehilite .mf { color: #F78C6C } /* Literal.Number.Float */ +.codehilite .mh { color: #F78C6C } /* Literal.Number.Hex */ +.codehilite .mi { color: #F78C6C } /* Literal.Number.Integer */ +.codehilite .mo { color: #F78C6C } /* Literal.Number.Oct */ +.codehilite .sa { color: #BB80B3 } /* Literal.String.Affix */ +.codehilite .sb { color: #C3E88D } /* Literal.String.Backtick */ +.codehilite .sc { color: #C3E88D } /* Literal.String.Char */ +.codehilite .dl { color: #EFF } /* Literal.String.Delimiter */ +.codehilite .sd { color: #546E7A; font-style: italic } /* Literal.String.Doc */ +.codehilite .s2 { color: #C3E88D } /* Literal.String.Double */ +.codehilite .se { color: #EFF } /* Literal.String.Escape */ +.codehilite .sh { color: #C3E88D } /* Literal.String.Heredoc */ +.codehilite .si { color: #89DDFF } /* Literal.String.Interpol */ +.codehilite .sx { color: #C3E88D } /* Literal.String.Other */ +.codehilite .sr { color: #89DDFF } /* Literal.String.Regex */ +.codehilite .s1 { color: #C3E88D } /* Literal.String.Single */ +.codehilite .ss { color: #89DDFF } /* Literal.String.Symbol */ +.codehilite .bp { color: #89DDFF } /* Name.Builtin.Pseudo */ +.codehilite .fm { color: #82AAFF } /* Name.Function.Magic */ +.codehilite .vc { color: #89DDFF } /* Name.Variable.Class */ +.codehilite .vg { color: #89DDFF } /* Name.Variable.Global */ +.codehilite .vi { color: #89DDFF } /* Name.Variable.Instance */ +.codehilite .vm { color: #82AAFF } /* Name.Variable.Magic */ +.codehilite .il { color: #F78C6C } /* Literal.Number.Integer.Long */ diff --git a/src/blog.node5.net/templates/article.html b/src/blog.node5.net/templates/article.html new file mode 100644 index 0000000..da3b668 --- /dev/null +++ b/src/blog.node5.net/templates/article.html @@ -0,0 +1,10 @@ +{% extends "base.html" %} +{% block title_prefix %}{{article.name}} - {% endblock %} +{% block head %} + {{ super() }} + +{% endblock %} +{% block content %} +

{{ article.name }}

{% include 'article_meta_data.html' %} +{{ article.html|safe }} +{% endblock %} diff --git a/src/blog.node5.net/templates/article_meta_data.html b/src/blog.node5.net/templates/article_meta_data.html new file mode 100644 index 0000000..ba668d8 --- /dev/null +++ b/src/blog.node5.net/templates/article_meta_data.html @@ -0,0 +1,9 @@ +

{{ article.metadata.description }}

+
+ +πŸ—“οΈ Created: {{ article.metadata.created.strftime('%Y-%m-%d') }} + | + + Modified: {{ article.modified.strftime('%Y-%m-%d') }} + diff --git a/src/blog.node5.net/templates/base.html b/src/blog.node5.net/templates/base.html new file mode 100644 index 0000000..474584c --- /dev/null +++ b/src/blog.node5.net/templates/base.html @@ -0,0 +1,66 @@ + + + + {% block head %} + + + + + {% block title_prefix %}{% endblock %}{{title}} + + + + {% endblock %} + + +
+ {{ motd }} +
+ +
+ {% block content %} + {% endblock %} +
+ +
+ +
+

Comments

+ +
+ + + + + +
+ (Will await approval before becoming public) +
+ +
+ + {{ comments_sql | safe }} + {% if comments and comments|length > 0 %}
{{ comments }}
+
{% else %}*No comments*{% endif %} +
+ +
+ + + diff --git a/src/blog.node5.net/templates/folder.html b/src/blog.node5.net/templates/folder.html new file mode 100644 index 0000000..ae9456e --- /dev/null +++ b/src/blog.node5.net/templates/folder.html @@ -0,0 +1,39 @@ +{% extends "base.html" %} +{% block head %} + {{ super() }} + +{% endblock %} +{% block content %} +
    + {% for article in folder.articles %} +
  1. + + πŸ“„ +
    +
    +

    {{ article.name }}

    + + {% include 'article_meta_data.html' %} +
    +
    +
    +
  2. +
    + {% endfor %} +
+ + {% if folder.sub_folders|length > 0 %} +
+ +
    + {% for folder in folder.sub_folders.values() %} +
  1. + +

    πŸ“ {{ folder.name }}

    +
    +
  2. + {% endfor %} +
+ {% endif %} + +{% endblock %} diff --git a/src/blog_node5_net.py b/src/blog_node5_net.py index e7f7503..94a1872 100644 --- a/src/blog_node5_net.py +++ b/src/blog_node5_net.py @@ -52,8 +52,9 @@ stream_handler.setFormatter(CustomFormatter()) logger.root.addHandler(stream_handler) logger.info(f"Debug: {'en' if debug else 'dis'}abled") +src_path = pathlib.Path(__file__).parent articles_path = os.environ["ARTICLES_PATH"] if "ARTICLES_PATH" in os.environ else './blog.node5.net/articles/' -site_files_path = os.environ["SITE_FILES_PATH"] if "SITE_FILES_PATH" in os.environ else './blog.node5.net/' +site_files_path = os.environ["SITE_FILES_PATH"] if "SITE_FILES_PATH" in os.environ else os.path.join(src_path, 'blog.node5.net/') articles_repo_url = os.environ["ARTICLES_REPO_URL"] if "ARTICLES_REPO_URL" in os.environ else 'https://git.node5.net/blog/articles/' logger.debug(f'articles_path: {articles_path}') logger.debug(f'site_files_path: {site_files_path}') @@ -94,7 +95,7 @@ articles_by_url: typing.Dict[str, article.Article] = {} # DB init -db: db_handler.DBHandler = db_handler.DBHandler() +db: db_handler.DBHandler = db_handler.DBHandler(db_init_script_path=os.path.join(src_path, 'create_db.sql')) # Telegram init try: diff --git a/src/create_db.sql b/src/create_db.sql new file mode 100644 index 0000000..ee0f968 --- /dev/null +++ b/src/create_db.sql @@ -0,0 +1,25 @@ +CREATE TABLE comment ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + comment text NOT NULL, -- URL of the page the comment belongs to, this is the relation between the markdown and this database + page_url text, + visitor_url text, -- The website the user claims to be from, if they have their own self hosted website + nickname text, + show_visitor_url bool, + contact text, -- A means of contacting this person, email phone, or similar + show_contact bool, -- True: Publicly show the contact information, False: Site creators eyes only + public bool, -- Indicates if the comment is to be publicly viewable, or if it''s merely for the creator + approved bool DEFAULT FALSE, + created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP +); + +INSERT INTO comment (comment, page_url, nickname, visitor_url, show_visitor_url, contact, show_contact, public, approved) + VALUES ('Hello world!', '/', 'user@node5.net', 'https://blog.node5.net/', TRUE, 'Leave a comment on this blog', TRUE, TRUE, TRUE); + +INSERT INTO comment (comment, page_url, nickname, visitor_url, show_visitor_url, contact, show_contact, public, approved) + VALUES ('Test private means of contact', '/', NULL, NULL, TRUE, 'Death star plans', FALSE, TRUE, TRUE); + +INSERT INTO comment (comment, page_url, nickname, visitor_url, show_visitor_url, contact, show_contact, public, approved) + VALUES ('Test private comment', '/', NULL, NULL, TRUE, 'Don''t', TRUE, FALSE, TRUE); + +INSERT INTO comment (comment, page_url, nickname, visitor_url, show_visitor_url, contact, show_contact, public, approved) + VALUES ('Test unapproved comment', '/', NULL, NULL, TRUE, NULL, TRUE, TRUE, FALSE); diff --git a/src/db_handler.py b/src/db_handler.py index 471154a..b063692 100644 --- a/src/db_handler.py +++ b/src/db_handler.py @@ -1,13 +1,23 @@ import logging -from dataclasses import dataclass - import sqlite3 +import os logger = logging.getLogger(__name__) # Set the logger name, to the name of the module class DBHandler: + def __init__(self, db_init_script_path: os.PathLike, db_path: str = "blog.node5.net.db"): + self.db_init_script_path = db_init_script_path + self.db_path = db_path + if not os.path.exists(self.db_path): + script = open(self.db_init_script_path, "r", encoding="utf-8").read() + with self.con_factory() as con: + con.executescript(script) + con.commit() + logger.info("Database initialized from %s", self.db_init_script_path) + + def con_factory(self) -> sqlite3.Connection: con = sqlite3.connect("blog.node5.net.db") return con -- cgit v1.3.1