Blog in development

This commit is contained in:
bingus_violet 2024-07-07 23:33:16 -05:00
parent 2b724bc2db
commit 7e52727bf0
12 changed files with 389 additions and 10 deletions

55
api.js
View file

@ -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()
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()

Binary file not shown.

33
assets/html/blog.html Normal file
View file

@ -0,0 +1,33 @@
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" type="text/css" href="../style.css">
<script src="../jquery.js"></script>
<script src="../main.js"></script>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{BLOG_TITLE}</title>
<meta name="darkreader-lock">
<meta content="{BLOG_TITLE}" property="og:title" />
<meta content="{BLOG_DESC}" property="og:description" />
<meta content="https://api.violets-purgatory.dev/v1/pfp" property="og:image" />
<meta content="#a200ff" data-react-helmet="true" name="theme-color" />
</head>
<body>
{WEATHER_MODIFIER}
{TOPBAR}
<h1>Blog<hr></h1>
<div class="mainDiv">
{BLOG_POST}
</div>
</body>
</html>

33
blog.js Normal file
View file

@ -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()
}
})

View file

@ -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) => {

39
package-lock.json generated
View file

@ -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",

View file

@ -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"
}

View file

@ -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 +=
`<div class="post">
<a style="text-decoration: none;" href="./${post.folder}">
<h2>${post.title}</h2>
<p style="color: white; font-size: 1rem;">${post.desc}</p>
<p style="color: darkgray; font-size: 1rem;">Path: <span class="noHighlight">/${post.folder}/</span></p>
</a>
</div>`
}
if (!api.blogConnected) {
addedHTML += "<p>Not connected to blog server :(</p>"
} else if (addedHTML.length < 10) {
addedHTML += "<p>No blog posts found... <br>wait <br> huh ??? <br>what???????<br> how ???????????????<br> WHY ?!<br> Violet must've fucked up like. REALLY bad. <br> We're so cooked</p>"
}
return addedHTML
}
}
var realtimeReplacers = {
@ -389,14 +422,13 @@ module.exports = {
}
res.send(data)
} else {
res.status(404).send(`
<link rel="stylesheet" href="/style.css">
<h1>404</h1>
<p>Uh oh... I think your lost? There's nothing here :P</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()

37
static/blog/index.html Normal file
View file

@ -0,0 +1,37 @@
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" type="text/css" href="style.css">
<script src="../jquery.js"></script>
<script src="../main.js"></script>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Blog - Violet's Purgatory</title>
<meta name="darkreader-lock">
<meta content="Blog - Violet's Purgatory" property="og:title" />
<meta content="My blog, where I talk about random hyperfixations!" property="og:description" />
<meta content="https://api.violets-purgatory.dev/v1/pfp" property="og:image" />
<meta content="#a200ff" data-react-helmet="true" name="theme-color" />
</head>
<body>
{WEATHER_MODIFIER}
{TOPBAR}
<main>
<h1>Blog</h1>
<p>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!</p>
<div class="mainDiv">
<hr>
{BLOG_POSTS}
</div>
</main>
</body>
</html>

147
static/blog/style.css Normal file
View file

@ -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;
}

View file

@ -58,7 +58,7 @@
<a class="chip" href="./stats">Stats</a>
<a class="chip" href="./faq">Nerd FAQ</a>
<a class="chip" href="https://{BRANCH_SUB}violets-purgatory.dev">{BRANCH_NAME} site</a>
<a class="chip" href="https://blog.violets-purgatory.dev">Blog</a>
<a class="chip" href="./blog">Blog</a>
<a class="chip" href="https://fs.violets-purgatory.dev">FileShare</a>
</div>
<div class="customStatus">