diff --git a/api.js b/api.js index ab08787..8605a92 100644 --- a/api.js +++ b/api.js @@ -14,6 +14,9 @@ module.exports = { "connected": false, "lastLanyardUpdate": Date.now(), + "blogConnected": false, + "blogPosts": undefined, + "events": events, "spins": 0, @@ -69,4 +72,54 @@ function socketeer() { }) } -socketeer() \ No newline at end of file +socketeer() + +function blogSocket() { + var blog = new WebSocket('https://blog.violets-purgatory.dev') + + blog.on("error", (error) => { + console.log(error) + }) + + blog.on("close", () => { + console.log("Connection Closed. Attempting Reconnect in 30 seconds.") + module.exports.blogConnected = false + setTimeout(() => { + blogSocket() + }, 30000); + }) + + function ping(dur) { + blog.send(JSON.stringify({ + type: "ping" + })) + setTimeout(() => { + ping(dur) + if (Date.now() - lastPong > 120000) { + blog.close() + console.log("Max duration since last pong exceeded- Closing socket.") + } + }, dur); + } + + blog.addEventListener("message", async (res) => { + var data = JSON.parse(res.data) + if (data.type == "init") { + console.log("Connected to Blog Websocket!") + module.exports.blogConnected = true + ping(30000) + lastPong = Date.now() + events.emit("blogConnect") + } else if (data.type == "ping") { + lastPong = Date.now() + } else if (data.type == "allPosts") { + console.log("Recieved posts!") + module.exports.blogPosts = data.data + events.emit("blogUpdate") + } else { + console.log(data) + } + }) +} + +blogSocket() \ No newline at end of file diff --git a/assets/fonts/encode-sans-expanded-v11-latin-regular.woff2 b/assets/fonts/encode-sans-expanded-v11-latin-regular.woff2 new file mode 100644 index 0000000..dbdfceb Binary files /dev/null and b/assets/fonts/encode-sans-expanded-v11-latin-regular.woff2 differ diff --git a/assets/fonts/source-code-pro-v23-latin-regular.woff2 b/assets/fonts/source-code-pro-v23-latin-regular.woff2 new file mode 100644 index 0000000..b62bc79 Binary files /dev/null and b/assets/fonts/source-code-pro-v23-latin-regular.woff2 differ diff --git a/assets/html/blog.html b/assets/html/blog.html new file mode 100644 index 0000000..57e28fe --- /dev/null +++ b/assets/html/blog.html @@ -0,0 +1,33 @@ + + + + + + + + + + + + + {BLOG_TITLE} + + + + + + + + + + + {WEATHER_MODIFIER} + + {TOPBAR} +

Blog

+
+ {BLOG_POST} +
+ + + \ No newline at end of file diff --git a/blog.js b/blog.js new file mode 100644 index 0000000..9c182ed --- /dev/null +++ b/blog.js @@ -0,0 +1,33 @@ +const api = require("./api.js"), +app = require("./expressHandler.js").app, +showdown = require("showdown"), +pageUpdater = require("./pageUpdater.js"), +fs = require("fs"), +path = require("path") +mkhtml = new showdown.Converter() + +mkhtml.setFlavor("github") + +app.use((req, res, next) => { + if (req.path.includes("blog") && api.blogPosts) { + var postName = decodeURIComponent(req.path.substring(6, req.path.length - 1)) + for (var i = 0; i < api.blogPosts.length; i++) { + var post = api.blogPosts[i] + + if (post.folder == postName || post.folder == decodeURIComponent(post.title)) { + var mkdwn = post.data + var html = mkhtml.makeHtml(mkdwn) + + html = fs.readFileSync(path.join(__dirname, "assets/html/blog.html")).toString().replace("{BLOG_POST}", html) + + html = pageUpdater.converter(html, false) + + res.send(html) + return + } + } + next() + } else { + next() + } +}) \ No newline at end of file diff --git a/index.js b/index.js index f18948c..a68365e 100644 --- a/index.js +++ b/index.js @@ -2,6 +2,8 @@ const fs = require("fs") require("./fileHandler.js") require('./expressHandler.js') +require("./pageUpdater.js") +require("./blog.js") // require("./imageEmbedder.js") process.on('uncaughtException', (err, origin) => { diff --git a/package-lock.json b/package-lock.json index 86c401b..be0ecd7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,7 @@ "glob": "^10.4.2", "himalaya": "^1.1.0", "minify-html": "^0.0.2", + "showdown": "^2.1.0", "ws": "^8.16.0", "youtubei.js": "^9.0.2" } @@ -282,6 +283,15 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, + "node_modules/commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || >=14" + } + }, "node_modules/content-disposition": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", @@ -1235,6 +1245,22 @@ "node": ">=8" } }, + "node_modules/showdown": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/showdown/-/showdown-2.1.0.tgz", + "integrity": "sha512-/6NVYu4U819R2pUIk79n67SYgJHWCce0a5xTP979WbNp0FL9MN1I1QK662IDU1b6JzKTvmhgI7T7JYIxBi3kMQ==", + "license": "MIT", + "dependencies": { + "commander": "^9.0.0" + }, + "bin": { + "showdown": "bin/showdown.js" + }, + "funding": { + "type": "individual", + "url": "https://www.paypal.me/tiviesantos" + } + }, "node_modules/side-channel": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", @@ -1802,6 +1828,11 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, + "commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==" + }, "content-disposition": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", @@ -2470,6 +2501,14 @@ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" }, + "showdown": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/showdown/-/showdown-2.1.0.tgz", + "integrity": "sha512-/6NVYu4U819R2pUIk79n67SYgJHWCce0a5xTP979WbNp0FL9MN1I1QK662IDU1b6JzKTvmhgI7T7JYIxBi3kMQ==", + "requires": { + "commander": "^9.0.0" + } + }, "side-channel": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", diff --git a/package.json b/package.json index 1c7cf98..7b4a677 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "glob": "^10.4.2", "himalaya": "^1.1.0", "minify-html": "^0.0.2", + "showdown": "^2.1.0", "ws": "^8.16.0", "youtubei.js": "^9.0.2" } diff --git a/pageUpdater.js b/pageUpdater.js index 249f48d..498cfe5 100644 --- a/pageUpdater.js +++ b/pageUpdater.js @@ -89,7 +89,20 @@ function highlighter(json, full = true) { var element = json[i] if (element.type == "element") { if (element.children.length > 0) { - element.children = highlighter(element.children, full) + if (element.attributes) { + var valid = true + for (var x in element.attributes) { + var attribute = element.attributes[x] + if (attribute.key == "class" && attribute.value == "value") { + valid = false + break + } + } + } + + if (valid) { + element.children = highlighter(element.children, full) + } } } else if (element.type == "text") { var index = 0 @@ -291,6 +304,26 @@ function converter(html, dynamic = true) { } return html }, + "BLOG_POSTS": () => { + var addedHTML = "" + for (var i in api.blogPosts) { + var post = api.blogPosts[i] + addedHTML += + `
+ +

${post.title}

+

${post.desc}

+

Path: /${post.folder}/

+
+
` + } + if (!api.blogConnected) { + addedHTML += "

Not connected to blog server :(

" + } else if (addedHTML.length < 10) { + addedHTML += "

No blog posts found...
wait
huh ???
what???????
how ???????????????
WHY ?!
Violet must've fucked up like. REALLY bad.
We're so cooked

" + } + return addedHTML + } } var realtimeReplacers = { @@ -389,14 +422,13 @@ module.exports = { } res.send(data) - } else { - res.status(404).send(` - -

404

-

Uh oh... I think your lost? There's nothing here :P

- `) + } + else { + next() } - } + }, + + converter: converter } async function updateCommits() { @@ -438,6 +470,8 @@ pregenerate() api.events.on("lanyardConnect", pregenerate) +api.events.on("blogUpdate", pregenerate) + api.events.on("lanyardUpdate", async () => { if (!api.lanyard.activityChanged) { pregenerate() diff --git a/static/blog/index.html b/static/blog/index.html new file mode 100644 index 0000000..e1d2226 --- /dev/null +++ b/static/blog/index.html @@ -0,0 +1,37 @@ + + + + + + + + + + + + + Blog - Violet's Purgatory + + + + + + + + + + + {WEATHER_MODIFIER} + + {TOPBAR} +
+

Blog

+

Welcome to my blog! Where I go on nonsensical rants about uninteresting and unimportant topics. The blog just went through a MAJOR rewrite, so expect bugs!

+
+
+ {BLOG_POSTS} +
+
+ + + \ No newline at end of file diff --git a/static/blog/style.css b/static/blog/style.css new file mode 100644 index 0000000..af27a20 --- /dev/null +++ b/static/blog/style.css @@ -0,0 +1,147 @@ +@font-face { + font-display: swap; + font-family: 'Source Code Pro'; + font-style: normal; + font-weight: 400; + src: url('../fonts/source-code-pro-v23-latin-regular.woff2') format('woff2'); +} + +@font-face { + font-display: swap; + font-family: 'Rubik'; + font-style: normal; + font-weight: 400; + src: url('../fonts/rubik-v28-latin-regular.woff2') format('woff2'); +} + +@font-face { + font-display: swap; + font-family: 'Encode Sans Expanded'; + font-style: normal; + font-weight: 400; + src: url('../fonts/encode-sans-expanded-v11-latin-regular.woff2') format('woff2'); +} + +* { + font-family: "Encode Sans Expanded", "Rubik", Verdana, Geneva, Tahoma, sans-serif; + padding: 0; + /* text-align: center; */ +} + +h1 { + color: rgb(0, 255, 0); + font-size: 2.5rem; + text-align: center; +} + +h2 { + color: rgb(0, 255, 0); +} + +li, +h3, h4, h5, h6 { + color: white; +} + +h3 { + font-size: 1.5rem; +} + +body, +html { + margin: auto; + background-color: rgb(10, 10, 10); + margin: 0; + padding: 0; +} + +a { + color: rgb(175, 225, 255); + display: inline-block; + transition: 1.5s all cubic-bezier(0.075, 0.82, 0.165, 1); +} + +.textBlock { + color: rgb(255, 255, 255); + white-space: pre-wrap; + background-color: rgb(20, 20, 20); + border: 2px lightgray solid; + padding: 0 10px; + font-style: italic; + font-family: 'Source Code Pro', sans-serif; + text-align: center; +} + +.post { + color: rgb(240, 240, 240); + background-color: rgb(5, 5, 5); + border: 2px gray solid; + padding: 10px; + padding-top: 0; + margin: 25px 10px; + text-align: center; +} + +a:hover { + color: white; + transition: 0.5s all cubic-bezier(0.075, 0.82, 0.165, 1); +} + +p, li { + color: white; + font-size: 1.2rem; + padding: 0; + margin: 10px; + line-height: 2rem; +} + +img { + width: 100%; + max-width: 135px; + transition: all 2s cubic-bezier(0.075, 0.82, 0.165, 1); +} + +hr { + color: white; + opacity: 0.25; + border-width: 2px; + margin: 15px 10%; +} + +ol, ul { + display: block; + width: 80%; + margin: auto; +} + +#topbar { + background-color: rgb(50, 125, 50, 0.5); + width: 100%; + padding: 0.5vh 0px; + margin-bottom: 1vh; + /* position: sticky; */ + left: 0px; + top: 0px; + z-index: 10; + /* opacity: 0.5; */ + transform: scale(1); + transition: all 2s cubic-bezier(0.075, 0.82, 0.165, 1); +} + +#topbar > * > * { + text-align: center; + display: inline-block; + margin: auto; + padding: 0 2%; +} + +#topbar > h3 { + display: block; + text-align: center; +} + +main:nth-of-type(1), .mainDiv { + width: 95%; + max-width: 1000px; + margin: auto; +} \ No newline at end of file diff --git a/static/index.html b/static/index.html index ffa41d8..688a5ba 100644 --- a/static/index.html +++ b/static/index.html @@ -58,7 +58,7 @@ Stats Nerd FAQ {BRANCH_NAME} site - Blog + Blog FileShare