Compare commits

..

No commits in common. "c54cc103eb0372e9244397586b7e2fb1a6fbd1e4" and "3f87946f89f9fb5770cf848550cfac6134ce5750" have entirely different histories.

27 changed files with 725 additions and 1042 deletions

2
.gitignore vendored
View file

@ -132,5 +132,3 @@ dist
# Violet's Purgatory
static/cached
cached
config

View file

@ -1,42 +1,23 @@
# Violets-Purgatory
Violet's Purgatory is a website filled to the brim with whatever I feel like adding! Currently, the stable version can be found at https://violets-purgatory.dev and the beta (based on the dev branch) can be found at https://beta.violets-purgatory.dev
Although beta probably *isn't* the right term, `dev.violets-purgatory.dev` is just kinda ugly :/
We also have an API, which can be located at https://api.violets-purgatory.dev, which is currently under developed, but will continue to have updates for features I see fit.
We also have an API, which can be located at https://api.violets-purgatory.dev, which is currently very under developed, but will continue to have updates for features I see fit.
# How it works
### The config
Although the code for it isn't nessacarily pretty, theres a few important things to go over with how it works.
The config.json file, soon to be renamed for a local config, contains constants for Violet's Purgatory. In the file, there are lots of important notable features, such as fallback activity images for the Discord Activity section, and words that are automatically highlighted.
### Word highlighting
Word highlighting is a feature that automatically sets the color of certain keywords, including but not limited to Violet being purple, Javascript being yellow, NodeJS being green, and Godot Engine being blue. This is nothing more than a fancy feature to reduce the amount of code required on the site.
These highlighted words ARE case senstive. You may notice certain things such as "Violet" at the top of the card are not highlighted despite being in the words list. To make a word in the highlight list not highlighted, simply add `{}` around it. E.G. for the title of the page, on the site it shows as `Violet`, but in the code is written as `{Violet}` to prevent highlighting.
To add new highlighted words, find the highlighted words section in config.json. The key is the word to highlight, and the value is the color.
### Dynamic HTML
Currently this system is extremely unsophisticated, adding new dynamic HTML isn't as streamlined as it should be. Basically, in the code, is a dictionary that specifies every keyword to look for. Then, it looks for those keywords, and replaces them with HTML.
A good example is the activity system. The keyword for the discord activities is `ACTIVITIES`. So, if you wanted to create another activity section, you would simply put `{ACTIVITIES}` in the HTML code.
There is also a `{PATH_[html file]}` keyword. Currently, this is not used much, but may be more useful in the future.
On the main page, you can find `{PATH_SOCIALS}`. This effectively "embeds" the socials page on the site. The part of the page that is used is based upon the `main` HTML tag.
For an easy to digest example, look at the socials section on the main page of [Violet's Purgatory](https://violets-purgatory.dev). Afterwards, look at the [*socials page*](https://violets-purgatory.dev/socials). You will notice they're the same, because in the code for the main page, I put {PATH_SOCIALS} which got the page at /socials.
# To-do
## Highlighter:
- [ ] Desperately need to rework the highlighting system.
- [ ] Make it ignore classes, IDs, inline-CSS attributes, etc
- [ ] Only index visible elements for words
- [x] Ignore text ouside the body
## Socials:
- [ ] Make it more easily findable on the site
- [ ] Add more content
## To-do
- [ ] Add more content to the socials page
- [ ] Pull latest Youtube video & display it
- [x] Display current Discord Activities
- [ ] Display current Discord Activities
- [ ] Display current steam game
## Activities
- [ ] Compress images to reduce space used and network usage (Probably using thumbor to prevent needing MORE packages TwT)
Completed:
- [x] Stop using Lanyard Web Socket Directly and proxy it through the API (Alternatively, self host the Lanyard API)
- [x] Cut the main CSS file into multiple so that only the nessacary CSS is loaded (Reduces traffic and loading times)
- [x] Add image caching instead of using image proxies (keeps the security benefit and decreases loading times)
- [x] Add code to automatically minify the HTML
- [x] Add random quotes
- [x] Seperate Values from the javascript into their own config for readability
- [x] Add a commit counter

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

View file

@ -1,3 +0,0 @@
{
"dailyVideoURL": ""
}

View file

@ -23,7 +23,10 @@
},
"quotes": [
"Remember the 14th commandment: Thou shalt always clean thy plate and not waste anything, whether thy stomach is full, or not.",
"Remember son, dying is gay!",
"Your friendly neighborhood queer",
"I hate javascript!!!",
"Don't fuck with this senator!",
"Happy 400 commits!",
"Play Cave Story!",
"Cave Story+ Sucks!",
@ -32,8 +35,9 @@
"IMAGE CACHING!!! THE IMAGE CACHING IS REAL!!!!",
"Is sharing your IP <em>reallyy</em> that bad?",
"The worst git user to exist",
"These birds are Pissing me off... I'm the original &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Starwalker",
"Fun fact: Did you know the <a href='./socials'>Socials section</a> is considered its own page?"
"no idea how branches work",
"Their ass is NOT listening",
"These birds are Pissing me off... I'm the original &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Starwalker"
],
"titles": [
"Boykisser",
@ -56,10 +60,6 @@
"NodeJS": "limegreen",
"Violet's": "rgb(200, 150, 255)",
"Violet": "rgb(200, 150, 255)",
"Asahi": "rgb(255, 175, 175)",
"Lunya": "rgb(255, 175, 175)",
"bisexual": "rgb(214, 2, 112)",
"enby": "rgb(252, 244, 52)",
"Purgatory": "rgb(200, 150, 255)",
"Youtube": "rgb(255, 0, 0)",
"Fedi": "rgb(175, 125, 200)",
@ -73,12 +73,6 @@
"Ko-fi": "rgb(255, 150, 150)",
"Revolt": "rgb(255, 50, 50)",
"Discord": "rgb(150, 150, 255)",
"SearXNG": "rgb(100, 100, 255)",
"Highlighting": "yellow",
"highlighted": "yellow",
"Forgejo": "orange",
"HTML": "orange",
"CSS": "rgb(50, 200, 255)",
"Thumbor": "rgb(225, 225, 255)"
"SearXNG": "rgb(100, 100, 255)"
}
}

View file

@ -1,43 +1,25 @@
const express = require('express'),
path = require('path'),
fs = require('fs'),
pageUpdater = require('./pageUpdater.js'),
WebSocket = require("ws")
pageUpdater = require('./pageUpdater.js')
var app = express()
const PORT = process.env.PORT || 8080
const staticpath = path.join(__dirname, 'static')
const cachePath = path.join(__dirname, 'cached')
const assetPath = path.join(__dirname, "assets")
const configPath = path.join(__dirname, 'config')
const configFile = path.join(configPath, "config.json")
const announcementFile = path.join(configPath, "announcement.html")
if (!fs.existsSync(configPath)) {
fs.mkdirSync(configPath)
}
if (!fs.existsSync(configFile)) {
fs.writeFileSync(configFile, fs.readFileSync(path.join(assetPath, "defaults/config.json")))
}
if (!fs.existsSync(announcementFile)) {
fs.writeFileSync(announcementFile, ``)
}
var constants = JSON.parse(fs.readFileSync(path.join(__dirname, 'constants.json')))
var config = JSON.parse(fs.readFileSync(path.join(__dirname, 'config.json')))
app.listen(PORT, () => {
console.log("Violet's Purgatory is now listening on port: " + PORT)
})
app.use("/fonts", express.static(path.join(assetPath, "fonts")))
var cachePath = path.join(staticpath, 'cached')
var fontPath = path.join(staticpath, "fonts")
app.use("/fonts", express.static(fontPath))
app.use("/cached", express.static(cachePath))
app.use("/imgs", express.static(path.join(assetPath, "Images")))
app.use("/snds", express.static(path.join(assetPath, "Sounds")))
if (!fs.existsSync(cachePath)) {
fs.mkdirSync(cachePath)
@ -49,10 +31,6 @@ if (!fs.existsSync(cachePath)) {
}
}
app.get("/discHTML", (req, res) => {
res.send(pageUpdater.getActivities())
})
app.use(pageUpdater.middleWare)
process.on('uncaughtException', (err, origin) => {

View file

@ -1,9 +1,9 @@
const path = require("path"),
fs = require("fs")
var constants = JSON.parse(fs.readFileSync(path.join(__dirname, 'constants.json')))
var config = JSON.parse(fs.readFileSync(path.join(__dirname, 'config.json')))
var activityImages = constants.activityImages
var activityImages = config.activityImages
function get_img_url(activity, size = "large_image") {
if ("assets" in activity) {
@ -85,9 +85,9 @@ module.exports = {
function get_img(activity, size = "large_image") {
if (cachedImages[get_img_url(activity, size)]) {
var fn = cachedImages[get_img_url(activity, size)]
var fp = path.join(__dirname, 'cached', fn)
var fp = path.join(__dirname, 'static/cached', fn)
} else {
return '/imgs/notFound.png'
return 'imgs/notFound.png'
}
return '/cached/' + fn

375
package-lock.json generated
View file

@ -11,7 +11,7 @@
"dependencies": {
"express": "^4.18.2",
"minify-html": "^0.0.2",
"ws": "^8.16.0",
"ws": "^8.14.2",
"youtubei.js": "^9.0.2"
}
},
@ -52,12 +52,12 @@
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
},
"node_modules/body-parser": {
"version": "1.20.2",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz",
"integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==",
"version": "1.20.1",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
"integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==",
"dependencies": {
"bytes": "3.1.2",
"content-type": "~1.0.5",
"content-type": "~1.0.4",
"debug": "2.6.9",
"depd": "2.0.0",
"destroy": "1.2.0",
@ -65,7 +65,7 @@
"iconv-lite": "0.4.24",
"on-finished": "2.4.1",
"qs": "6.11.0",
"raw-body": "2.5.2",
"raw-body": "2.5.1",
"type-is": "~1.6.18",
"unpipe": "1.0.0"
},
@ -83,18 +83,12 @@
}
},
"node_modules/call-bind": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
"integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
"integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
"dependencies": {
"es-define-property": "^1.0.0",
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"get-intrinsic": "^1.2.4",
"set-function-length": "^1.2.1"
},
"engines": {
"node": ">= 0.4"
"function-bind": "^1.1.1",
"get-intrinsic": "^1.0.2"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@ -120,9 +114,9 @@
}
},
"node_modules/cookie": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
"integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==",
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
"integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==",
"engines": {
"node": ">= 0.6"
}
@ -140,22 +134,6 @@
"ms": "2.0.0"
}
},
"node_modules/define-data-property": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
"integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
"dependencies": {
"es-define-property": "^1.0.0",
"es-errors": "^1.3.0",
"gopd": "^1.0.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/depd": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
@ -186,25 +164,6 @@
"node": ">= 0.8"
}
},
"node_modules/es-define-property": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz",
"integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==",
"dependencies": {
"get-intrinsic": "^1.2.4"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-errors": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/escape-html": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
@ -219,16 +178,16 @@
}
},
"node_modules/express": {
"version": "4.19.2",
"resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz",
"integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==",
"version": "4.18.2",
"resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz",
"integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==",
"dependencies": {
"accepts": "~1.3.8",
"array-flatten": "1.1.1",
"body-parser": "1.20.2",
"body-parser": "1.20.1",
"content-disposition": "0.5.4",
"content-type": "~1.0.4",
"cookie": "0.6.0",
"cookie": "0.5.0",
"cookie-signature": "1.0.6",
"debug": "2.6.9",
"depd": "2.0.0",
@ -293,57 +252,39 @@
}
},
"node_modules/function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
},
"node_modules/get-intrinsic": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz",
"integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==",
"dependencies": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"function-bind": "^1.1.1",
"has": "^1.0.3",
"has-proto": "^1.0.1",
"has-symbols": "^1.0.3",
"hasown": "^2.0.0"
"has-symbols": "^1.0.3"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
"dependencies": {
"function-bind": "^1.1.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/gopd": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
"integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
"dependencies": {
"get-intrinsic": "^1.1.3"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-property-descriptors": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
"integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
"dependencies": {
"es-define-property": "^1.0.0"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
"node": ">= 0.4.0"
}
},
"node_modules/has-proto": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz",
"integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==",
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz",
"integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==",
"engines": {
"node": ">= 0.4"
},
@ -362,17 +303,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/hasown": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
"dependencies": {
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/http-errors": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
@ -508,9 +438,9 @@
}
},
"node_modules/object-inspect": {
"version": "1.13.1",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz",
"integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==",
"version": "1.12.3",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz",
"integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
@ -574,9 +504,9 @@
}
},
"node_modules/raw-body": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
"integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
"integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
"dependencies": {
"bytes": "3.1.2",
"http-errors": "2.0.0",
@ -653,39 +583,19 @@
"node": ">= 0.8.0"
}
},
"node_modules/set-function-length": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
"integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
"dependencies": {
"define-data-property": "^1.1.4",
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"get-intrinsic": "^1.2.4",
"gopd": "^1.0.1",
"has-property-descriptors": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/setprototypeof": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
},
"node_modules/side-channel": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz",
"integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==",
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
"integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
"dependencies": {
"call-bind": "^1.0.7",
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.4",
"object-inspect": "^1.13.1"
},
"engines": {
"node": ">= 0.4"
"call-bind": "^1.0.0",
"get-intrinsic": "^1.0.2",
"object-inspect": "^1.9.0"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@ -754,9 +664,9 @@
"integrity": "sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA=="
},
"node_modules/undici": {
"version": "5.28.4",
"resolved": "https://registry.npmjs.org/undici/-/undici-5.28.4.tgz",
"integrity": "sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==",
"version": "5.28.3",
"resolved": "https://registry.npmjs.org/undici/-/undici-5.28.3.tgz",
"integrity": "sha512-3ItfzbrhDlINjaP0duwnNsKpDQk3acHI3gVJ1z4fmwMK31k5G9OVIAMLSIaP6w4FaGkaAkN6zaQO9LUvZ1t7VA==",
"dependencies": {
"@fastify/busboy": "^2.0.0"
},
@ -789,9 +699,9 @@
}
},
"node_modules/ws": {
"version": "8.16.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz",
"integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==",
"version": "8.14.2",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz",
"integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==",
"engines": {
"node": ">=10.0.0"
},
@ -848,12 +758,12 @@
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
},
"body-parser": {
"version": "1.20.2",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz",
"integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==",
"version": "1.20.1",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
"integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==",
"requires": {
"bytes": "3.1.2",
"content-type": "~1.0.5",
"content-type": "~1.0.4",
"debug": "2.6.9",
"depd": "2.0.0",
"destroy": "1.2.0",
@ -861,7 +771,7 @@
"iconv-lite": "0.4.24",
"on-finished": "2.4.1",
"qs": "6.11.0",
"raw-body": "2.5.2",
"raw-body": "2.5.1",
"type-is": "~1.6.18",
"unpipe": "1.0.0"
}
@ -872,15 +782,12 @@
"integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="
},
"call-bind": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
"integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
"integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
"requires": {
"es-define-property": "^1.0.0",
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"get-intrinsic": "^1.2.4",
"set-function-length": "^1.2.1"
"function-bind": "^1.1.1",
"get-intrinsic": "^1.0.2"
}
},
"content-disposition": {
@ -897,9 +804,9 @@
"integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA=="
},
"cookie": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
"integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw=="
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
"integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw=="
},
"cookie-signature": {
"version": "1.0.6",
@ -914,16 +821,6 @@
"ms": "2.0.0"
}
},
"define-data-property": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
"integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
"requires": {
"es-define-property": "^1.0.0",
"es-errors": "^1.3.0",
"gopd": "^1.0.1"
}
},
"depd": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
@ -944,19 +841,6 @@
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
"integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w=="
},
"es-define-property": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz",
"integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==",
"requires": {
"get-intrinsic": "^1.2.4"
}
},
"es-errors": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="
},
"escape-html": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
@ -968,16 +852,16 @@
"integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="
},
"express": {
"version": "4.19.2",
"resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz",
"integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==",
"version": "4.18.2",
"resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz",
"integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==",
"requires": {
"accepts": "~1.3.8",
"array-flatten": "1.1.1",
"body-parser": "1.20.2",
"body-parser": "1.20.1",
"content-disposition": "0.5.4",
"content-type": "~1.0.4",
"cookie": "0.6.0",
"cookie": "0.5.0",
"cookie-signature": "1.0.6",
"debug": "2.6.9",
"depd": "2.0.0",
@ -1030,56 +914,39 @@
"integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q=="
},
"function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
},
"get-intrinsic": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz",
"integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==",
"requires": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"function-bind": "^1.1.1",
"has": "^1.0.3",
"has-proto": "^1.0.1",
"has-symbols": "^1.0.3",
"hasown": "^2.0.0"
"has-symbols": "^1.0.3"
}
},
"gopd": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
"integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
"has": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
"requires": {
"get-intrinsic": "^1.1.3"
}
},
"has-property-descriptors": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
"integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
"requires": {
"es-define-property": "^1.0.0"
"function-bind": "^1.1.1"
}
},
"has-proto": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz",
"integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q=="
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz",
"integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg=="
},
"has-symbols": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
},
"hasown": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
"requires": {
"function-bind": "^1.1.2"
}
},
"http-errors": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
@ -1181,9 +1048,9 @@
"integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg=="
},
"object-inspect": {
"version": "1.13.1",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz",
"integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ=="
"version": "1.12.3",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz",
"integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g=="
},
"on-finished": {
"version": "2.4.1",
@ -1226,9 +1093,9 @@
"integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="
},
"raw-body": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
"integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
"integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
"requires": {
"bytes": "3.1.2",
"http-errors": "2.0.0",
@ -1284,33 +1151,19 @@
"send": "0.18.0"
}
},
"set-function-length": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
"integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
"requires": {
"define-data-property": "^1.1.4",
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"get-intrinsic": "^1.2.4",
"gopd": "^1.0.1",
"has-property-descriptors": "^1.0.2"
}
},
"setprototypeof": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
},
"side-channel": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz",
"integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==",
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
"integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
"requires": {
"call-bind": "^1.0.7",
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.4",
"object-inspect": "^1.13.1"
"call-bind": "^1.0.0",
"get-intrinsic": "^1.0.2",
"object-inspect": "^1.9.0"
}
},
"source-map": {
@ -1359,9 +1212,9 @@
}
},
"undici": {
"version": "5.28.4",
"resolved": "https://registry.npmjs.org/undici/-/undici-5.28.4.tgz",
"integrity": "sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==",
"version": "5.28.3",
"resolved": "https://registry.npmjs.org/undici/-/undici-5.28.3.tgz",
"integrity": "sha512-3ItfzbrhDlINjaP0duwnNsKpDQk3acHI3gVJ1z4fmwMK31k5G9OVIAMLSIaP6w4FaGkaAkN6zaQO9LUvZ1t7VA==",
"requires": {
"@fastify/busboy": "^2.0.0"
}
@ -1382,9 +1235,9 @@
"integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="
},
"ws": {
"version": "8.16.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz",
"integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==",
"version": "8.14.2",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz",
"integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==",
"requires": {}
},
"youtubei.js": {

View file

@ -19,7 +19,7 @@
"dependencies": {
"express": "^4.18.2",
"minify-html": "^0.0.2",
"ws": "^8.16.0",
"ws": "^8.14.2",
"youtubei.js": "^9.0.2"
}
}

View file

@ -2,51 +2,22 @@ const path = require('path'),
fs = require('fs'),
WebSocket = require('ws'),
minify = require('minify-html'),
activityToHTML = require("./overcomplicatedStatuses.js")
activityToHTML = require("./overcomplicatedStatuses.js"),
weatherGenerator = require("./weatherGenerator")
// weatherGenerator = require("./weatherGenerator")
var config = JSON.parse(fs.readFileSync(path.join(__dirname, 'config.json')))
var constants = JSON.parse(fs.readFileSync(path.join(__dirname, 'constants.json')))
var highlightedWords = config.highlightedWords
var quotes = config.quotes
var titles = config.titles
var highlightedWords = constants.highlightedWords
var quotes = constants.quotes
var titles = constants.titles
var globalSpins = 0
var commitCount = "500+"
var commitCount = "400+"
var lanyardData = undefined
var uptime = Date.now()
var reloads = 0
function firstToUpper(str) {
return str.charAt(0).toUpperCase() + str.slice(1)
}
var thumborURL = "https://thumbor.violets-purgatory.dev/unsafe/"
var imgExtension = "png"
var thumborArgs = `filters:format(${imgExtension})/`
function timeFormatter(seconds) {
seconds = Math.ceil(seconds)
var minutes = Math.ceil(seconds / 60)
var hours = Math.floor(minutes / 60)
if (seconds <= 60) {
return 'about ' + seconds + ' seconds'
} else if (minutes < 60) {
return `${minutes} Minutes`
}
return `${hours} hours and ${minutes % 60} minutes`
}
function converter(html, query) {
var config = JSON.parse(fs.readFileSync(path.join(__dirname, 'config/config.json')))
reloads += 1
var startTime = Date.now()
while (html.includes("{PATH_")) {
var pagePath = html.substring(html.indexOf("{PATH_"))
pagePath = pagePath.substring(6, pagePath.indexOf('}'))
@ -62,32 +33,20 @@ function converter(html, query) {
var statusText = ""
if (lanyardData) {
var statusData = constants.discStatuses[lanyardData.discord_status]
var statusData = config.discStatuses[lanyardData.discord_status]
var username = lanyardData.discord_user.username
if (lanyardData.activities[0] && lanyardData.activities[0].type == 4) {
var statusText = `<hr><p>${lanyardData.activities[0].state}</p>`
}
} else {
var statusData = constants.discStatuses.offline
var statusData = config.discStatuses.offline
var username = "bingus_violet"
}
var time = new Date(Date.now())
var bnchName = "Beta"
var bnchSub = "beta."
if (process.env.BRANCH == "dev") {
bnchName = "Stable"
bnchSub = ""
}
var replacers = {
"ALL_KEYWORDS": undefined,
"ALL_HIGHLIGHTS": Object.keys(highlightedWords).join(", "),
"BRANCH_NAME": bnchName,
"BRANCH_SUB": bnchSub,
"COMMIT_COUNT": commitCount,
"RANDOM_QUOTE": quotes[Math.floor(Math.random() * quotes.length)],
"QUOTE_COUNT": quotes.length,
@ -98,26 +57,9 @@ function converter(html, query) {
"UPTIME": uptime,
"TOPBAR": `<div id="topbar"><h3><a href="/socials">Socials</a></h3></div>`,
"DISCORD_USER": username,
"CUSTOM_STATUS": statusText,
"SELECTED_VIDEO": () => {
if (config.dailyVideoURL) {
return `<h2><hr>Random video!</h2><p>I would call it random <em>daily</em> video but its not at all daily...</p>
<br>
<video controls src="${config.dailyVideoURL}"></video>`
}
return ``
},
"SPINCOUNT": globalSpins,
"UPTIME": timeFormatter((Date.now() - uptime) / 1000),
"RELOAD_COUNT": reloads,
"WEATHER_MODIFIER": "",
"WEATHER_TEXT": "",
"ANNOUNCEMENT": fs.readFileSync(path.join(__dirname, "config/announcement.html")),
"CACHED_IMAGES": fs.readdirSync(path.join(__dirname, "cached")).length.toString()
"CUSTOM_STATUS": statusText
}
replacers.ALL_KEYWORDS = "{" + Object.keys(replacers).join("}{") + "} "
var rpTable = Object.keys(replacers)
for (let index = 0; index < rpTable.length; index++) {
@ -127,7 +69,6 @@ function converter(html, query) {
var bodyHTML = html.substring(html.indexOf("<body>") + 6, html.lastIndexOf("</body>"))
var highTable = Object.keys(highlightedWords)
for (let index = 0; index < highTable.length; index++) {
var term = highTable[index];
var replacement = `<span style="color: ${highlightedWords[term]}">${term}</span>`
@ -141,21 +82,41 @@ function converter(html, query) {
html = html.substring(0, html.indexOf("<body>")) + bodyHTML + html.substring(html.indexOf("</body>") + 7)
html = html.replaceAll("{LOAD_TIME}", (Date.now() - startTime).toString() + "ms")
var weathers = ["rain", "none"]
var weather = weathers[time.getDate() % weathers.length]
if (weather == "rain" || "rain" in query || "hardRain" in query) {
html = html.replaceAll("{WEATHER_MODIFIER}", weatherGenerator.makeRain("hardRain" in query))
html = html.replaceAll("{WEATHER_TEXT}", `The rain is so pretty... <a href="?hardRain">I wish I saw it more...</a>`)
} else {
html = html.replaceAll("{WEATHER_MODIFIER}", "")
html = html.replaceAll("{WEATHER_TEXT}", "")
}
return html
}
module.exports = {
getActivities: function () {
return minify.minify(activityToHTML.activitiesToHTML(lanyardData, cachedImages))
return activityToHTML.activitiesToHTML(lanyardData, cachedImages)
},
middleWare: function (req, res, next) {
var filePath = (req.baseUrl + req.path).trim()
if (!filePath.includes(".")) {
if (filePath.includes("cached") || filePath.includes("imgs")) {
filePath = path.join(__dirname, 'static', filePath)
res.send(fs.readFileSync(filePath))
return
}
if (filePath.includes(".")) {
} else {
if (filePath.charAt(filePath.length - 1) != '/') {
res.redirect(filePath + '/')
return
@ -166,24 +127,13 @@ module.exports = {
filePath = path.join(__dirname, 'static', filePath || 'index.html')
if (fs.existsSync(filePath)) {
var data = fs.readFileSync(filePath).toString()
res.contentType(path.basename(filePath))
// if (req.path.includes(".css")) {
// res.setHeader("Content-Type", "text/css")
// } else if (!req.path.includes(".woff2")) {
// data = converter(data, req.query)
// }
if (filePath.includes(".html")) {
if (req.path.includes(".css")) {
res.setHeader("Content-Type", "text/css")
} else if (!req.path.includes(".woff2")) {
data = converter(data, req.query)
}
if (!filePath.includes(".js")) {
data = minify.minify(data)
}
res.send(data)
res.send(minify.minify(data))
} else {
res.status(404).send(`
<link rel="stylesheet" href="/style.css">
@ -195,19 +145,10 @@ module.exports = {
}
async function updateCommits() {
var siteResponse = await (await fetch(`https://git.violets-purgatory.dev/bingus_violet/violets-purgatory/src/branch/${process.env.BRANCH || "origin"}`)).text()
var commits = siteResponse.substring(0, siteResponse.indexOf("Commits"))
var codebergResponse = await (await fetch(`https://codeberg.org/Bingus_Violet/Violets-Purgatory/src/branch/${process.env.BRANCH || "origin"}`)).text()
var commits = codebergResponse.substring(0, codebergResponse.indexOf("Commits"))
commits = commits.substring(commits.lastIndexOf("<b>") + 3, commits.lastIndexOf("</b>"))
// ^ this works for Forgejo (basically everything i use that isnt Github E.G. Codeberg)
// commits = commits.substring(commits.lastIndexOf(">") + 1)
// ^ This works for Github (fuck you Github)
commitCount = commits.toString()
if (process.env.BRANCH == "dev") {
commitCount += " | Beta site"
}
commitCount = commits
}
updateCommits()
@ -217,7 +158,7 @@ updateCommits()
var lastLanyardUpdate = Date.now()
var lastPong = 0
var activityImages = constants.activityImages
var activityImages = config.activityImages
var cachedImages = {}
function get_img_url(activity, size = "large_image") {
@ -255,7 +196,7 @@ function socketeer() {
console.log("Connection Closed. Attempting Reconnect in 30 seconds.")
setTimeout(() => {
socketeer()
}, 30000);
}, 3000);
})
function ping(dur) {
@ -289,11 +230,12 @@ function socketeer() {
if (get_img_url(activity)) {
var url = get_img_url(activity)
var fn = Math.ceil(Math.random() * 100_000_000_000).toString() + "." + imgExtension
var fp = path.join(__dirname, 'cached', fn)
var fn = Math.ceil(Math.random() * 100_000_000_000).toString()
var fp = path.join(__dirname, 'static/cached', fn)
if (!cachedImages[url]) {
const response = await (await fetch(thumborURL + "200x200/" + thumborArgs + url)).arrayBuffer()
const response = await (await fetch(url)).arrayBuffer()
fs.writeFileSync(fp, Buffer.from(response))
cachedImages[url] = fn
@ -302,11 +244,11 @@ function socketeer() {
if (get_img_url(activity, "small_image")) {
var url = get_img_url(activity, "small_image")
var fn = Math.ceil(Math.random() * 100_000_000_000).toString() + "." + imgExtension
var fp = path.join(__dirname, 'cached', fn)
var fn = Math.ceil(Math.random() * 100_000_000_000).toString()
var fp = path.join(__dirname, 'static/cached', fn)
if (!cachedImages[url]) {
const response = await (await fetch(thumborURL + "64x64/" + thumborArgs + url)).arrayBuffer()
const response = await (await fetch(url)).arrayBuffer()
fs.writeFileSync(fp, Buffer.from(response))
@ -315,8 +257,6 @@ function socketeer() {
}
}
} else if (data.op == 4) {
globalSpins = data.spins
}
})
}

19
resources/disc.html Normal file
View file

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/global.css">
<link rel="stylesheet" href="/root.css">
<link rel="stylesheet" href="/subpage.css">
<title>Dynamic Disc Status</title>
</head>
<body>
<main>
<br>
<h1>Dynamicly Updating Discord Status</h1>
<p>This page is basically the same as the one present on the site, but it updates in real time! It basically only exists to serve my brain rot :P</p>
<h2><hr>How does it work?</h2>
<p>Its a little big buggy- Pretty much, it just keeps writing html to the client, and telling it the HTML never finished. Yeah. Not great. Very easily could cause a data leak i think? Idk, what do you think I am, a programmer????</p>

View file

@ -1,88 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" type="text/css" href="/style.css">
<link rel="stylesheet" type="text/css" href="/root.css">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Violet's Purgatory</title>
<meta name="darkreader-lock">
<meta content="Violet's Purgatory" property="og:title" />
<meta
content="Hello this is tje asahi a uhm uuhhh uhm ummmm uhmmm uhhh uhmmm ummm uhhh um!"
property="og:description" />
<meta content="./pfp.png" property="og:image" />
<meta content="#a200ff" data-react-helmet="true" name="theme-color" />
</head>
<body>
{WEATHER_MODIFIER}
<h1 class="animatedTitle">Welcome to my<span class="mainTitle" style="color: rgb(200, 150, 255)">Humble Abode</span>
</h1>
<main class="animatedMain">
<p>nice seeing you here! while you're at it, why not check out my socials or about me?</p>
<hr>
<div id="card">
<h2>Asahi</h2>
<div style="display: flex; justify-content: center; align-items: center;">
<div style="width: 50%;">
<img src="/imgs/asahiPFP.png" class="pfp">
</div>
<div style="width: 50%;">
<div style="float: left;">
<p>They/Them</p>
<p>Marcy & Violet &lt;3</p>
</div>
<!-- <p>THIS TEXT IS THE EPIC EXTREME FILLER TO TEST THE SITE'S FORMATTING :fire:</p> -->
</div>
</div>
<hr>
<div>
<p style="padding: 10px;">
<br>hi! my name is Asahi Lunya :3 i'm a bisexual enby who's a very queer mess
<br>i have interests in tech, aerospace, trains, art, and music! i'm also a privacy/security
enthusiast
<br>i'm currently learning many new things in my life, expanding my knowledge
<br>i hope you got to know me a little ^^
</p>
<!-- <a class="chip" href="https://beta.violets-purgatory.dev">Beta site</a>
<a class="chip" href="https://blog.violets-purgatory.dev">Blog</a> -->
<!-- <a class="chip" href="https://fs.violets-purgatory.dev">FileShare</a> -->
</div>
</div>
<h2><hr>Disclaimer!</h2>
<p>
This is NOT Asahi's real site! Please find it <a href="https://asahixp.pages.gay">here</a> instead!
</p>
<h2><hr>Quotes:</h2>
<p style="white-space: pre-wrap;">“literally anything from the 1995 movie 'Hackers' will absolutely fit here” -tyberry
"ooooo you like boys, ur a boykisser" -Elodie
"asahi is twink-esk in spirit. aspirational." -Juniper
"cute huggable nice huggable cute cute" -marcy
"Petting Asahi makes the world better” -yassie
"meow meow meow mrrrp nya~" -gettie
"cute and queer catenby that functions as fedi's algorithm on the side" -7331
"sometimes this one still forgets how friendly some people are here… like Asahi, for instance!” -Ariadne
"Asahi wa sugoi desu ne?" -Bard
"this is a quote :3c" -Ukko
"best Asahi I've ever met (awww!)" -Kristina
"asahi is friend shaped and they have a good heart" -Drew
"10/10 will give loving headpats and will protect them!" -Natsura</p>
</main>
</body>
</html>

View file

@ -1,51 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" type="text/css" href="/style.css">
<link rel="stylesheet" type="text/css" href="/subpage.css">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Violet's Purgatory</title>
<meta name="darkreader-lock">
<meta content="FAQ - Violet's Purgatory" property="og:title" />
<meta content="Some not-so frequently asked questions with some not-so frequently answered answers!!!" 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}
<a href="../" class="chip">Home</a>
<a href="../socials" class="chip">Socials</a>
<a href="../stats" class="chip">Stats</a>
<h1>FAQ (and more!)</h1>
<div class="mainDiv">
<h2><br>1. Questions & Answers<hr></h2>
<main>
<h3>Why are so many words colored?</h3>
<p>I like the way it looks to have certain words be highlighted, makes it look fancier and easier to read (imo). So, when I remade this site, I went ahead and added an <em>Automatic Word Highlighting System!</em> This allows me have words automatically highlighted, on the server side, without having to do it in the code manually. Here's the current list of highlighted words:</p>
<p class="textBlock">{ALL_HIGHLIGHTS}</p>
<br>
<h3>I thought the site doesn't use Javascript? So why is it there?</h3>
<p>Originally, all my sites were completely Javascript free. As of late, though, I decided to add Javascript to this one. Javascript will <b><em>NEVER</em></b> be a requirement on this site. Javascript will ONLY be used where nessacary, and I will do everything possible to make the experience indistinguishable.</p>
</main>
<p>For example, things such as the song duration bar on my activities are pure HTML, using some mathy NodeJS-generated CSS animations! The only thing the site uses Javascript for right now, is setting the scroll to the top of the page on reload, and real time updating discord activities.</p>
<h3>Why are there 4 CSS files?</h3>
<p>Originally the idea was that I could organize the site with:</p>
<ol>
<li>CSS for the main page</li>
<li>CSS for the subsites</li>
<li>Global CSS</li>
</ol>
<p>Slowly, though, they're slowly all merging into one CSS file, so I can't be sure it'll stay this way for long.</p>
<p>As for the "unused" style.css, though, that exists for compatibility reasons- many of my older sites just grabbed CSS from the site for their css. This has been <b>mostly</b> fixed, but the FileShare still does, so it'll stay until I finally give the FileShare its own CSS.</p>
</div>
</body>
</html>

160
static/global.css Normal file
View file

@ -0,0 +1,160 @@
/*
This is the GLOBAL css file.
Any changes made in here, will apply to the ENTIRE site.
Only put changes here if you intend to put changes across
the whole site!
*/
@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-family: 'Rubik', Verdana, Geneva, Tahoma, sans-serif;
padding: 0;
margin: 0;
font-weight: 400;
text-align: center;
color: white;
}
#topbar {
background-color: rgb(75, 50, 125);
width: 100%;
padding: 1vh 0px;
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:hover {
opacity: 1;
transform: scale(1.05);
}
#topbar>* {
display: inline-block;
font-size: 1.5rem;
}
main:nth-of-type(1) {
width: 95%;
max-width: 1000px;
margin: auto;
}
body {
overflow-x: hidden;
background-color: rgb(55, 4, 75);
background: linear-gradient(rgb(40, 4, 75), black);
background-attachment: local;
min-height: 100vh;
animation: hideContent 2.5s;
}
a {
color: rgb(175, 225, 255);
display: inline-block;
transition: 1.5s all cubic-bezier(0.075, 0.82, 0.165, 1);
}
h3 {
font-size: 1.5rem;
padding: 10px;
}
@media screen and (min-width: 650px) {
.grid-container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-gap: 10px;
}
.grid-child {
margin: auto;
align-content: center;
/* border: 2px white solid; */
}
}
.chip {
position: relative;
z-index: 3;
font-size: 1.3rem;
border: 2px gray solid;
border-radius: 6px;
background-color: black;
padding: 8px;
margin: 3px;
display: inline-block;
transform: scale(0.95);
transition: transform 1.25s cubic-bezier(0.075, 0.82, 0.165, 1), background-color 2s cubic-bezier(0.075, 0.82, 0.165, 1);
}
a.chip {
text-decoration: none;
/* background-image: linear-gradient(rgb(175, 225, 255), rgb(175, 225, 255));
background-size: calc(100% - 15px) 2px;
background-position: 50% 87.5%;
background-repeat: no-repeat; */
}
.chip:hover {
background-color: rgb(10, 0, 25);
transform: scale(1);
/* font-size: 1.35rem; */
border-color: white;
transition: transform 0.75s cubic-bezier(0.075, 0.82, 0.165, 1), background-color 3s cubic-bezier(0.075, 0.82, 0.165, 1);
}
.chip:hover>.smallimg {
background-color: rgb(10, 0, 25);
}
hr {
color: white;
border: white solid;
opacity: 0.25;
border-width: 2px;
margin: 15px 10%;
/* background-color: none; */
}
p {
font-size: 1.25rem;
margin: 5px;
line-height: 2rem;
text-wrap: pretty;
}
img {
width: 100%;
/* max-width: 135px; */
transition: all 2s cubic-bezier(0.075, 0.82, 0.165, 1);
}
h2 {
font-size: 1.8rem;
}
.note {
color: darkgray;
font-size: 1rem;
}
.striked {
text-decoration: line-through;
text-decoration-color: white;
}

View file

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

View file

@ -2,13 +2,8 @@
<html lang="en">
<head>
<link rel="stylesheet" type="text/css" href="./style.css">
<link rel="stylesheet" type="text/css" href="./global.css">
<link rel="stylesheet" type="text/css" href="./root.css">
<noscript>
<link rel="stylesheet" href="./noScript.css">
</noscript>
<script src="./main.js"></script>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
@ -18,77 +13,50 @@
<meta name="darkreader-lock">
<meta content="Violet's Purgatory" property="og:title" />
<meta content="Hi, I'm Violet, a 15 year old web & game developer. My site has info about me, so please visit!" property="og:description" />
<meta content="Hi, I'm Violet, a 15 year old web developer. My site lists my projects, passions, and where you can find me, so please visit!" 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}
<h1 class="animatedTitle">Welcome to <span class="mainTitle">Violet's Purgatory</span><span class="note">Commit {COMMIT_COUNT}</span></h1>
<h1 class="animatedTitle">Welcome to <span class="mainTitle">Violet's Purgatory</span><span class="note">Commit {COMMIT_COUNT}</span><br></h1>
<main class="animatedMain">
<p>Make sure to check out this project on <a href="https://git.violets-purgatory.dev/bingus_violet/violets-purgatory">Forgejo</a>!</p>
<p>{RANDOM_QUOTE}</p>
<hr>
<div id="card">
<h2>{Violet}</h2>
<div style="display: flex; justify-content: center; align-items: center;">
<div style="width: 50%;">
<img draggable="false" src="https://api.violets-purgatory.dev/v1/pfp" class="pfp">
</div>
<div style="width: 50%;">
<div style="float: left;">
<p>They/Them</p>
<p>Developer</p>
<!-- <p>Dating Asahi &lt;3</p> -->
<p>{DISCORD_STATUS}</p>
<!-- <p>THIS TEXT IS THE EPIC EXTREME FILLER TO TEST THE SITE'S FORMATTING :fire:</p> -->
</div>
<img src="https://api.violets-purgatory.dev/v1/pfp" class="pfp">
<div>
<p>They/Them</p>
<p>Developer</p>
<p>{DISCORD_STATUS}</p>
</div>
</div>
<p class="noscript">Violet has been spun {SPINCOUNT} times!</p>
<p class="spinnyCount" style="display: none;">You have spun Violet <span class="localSpins">4</span> times!<br>
Everyone has spun Violet <span class="globalSpins">{SPINCOUNT}</span> times!</p>
<hr>
<div>
<p style="padding: 10px;">Hi! I'm Violet, a 15 year old web and game developer. I make server-sided dynamic websites, with no Javascript required! I'm currently making games in the Godot Engine, and my dynamic sites in NodeJS.</p>
<div class="linkContainer">
<a class="chip" href="./socials/">Socials</a>
<p style="padding: 10px;">Hi! I'm Violet, a 15 year old web and game developer. <br> I aspire to make fast and Javascript free websites! I'm currently learning the Godot Engine, but most of my time recently has been spent learning NodeJS.</p>
<a class="chip" href="https://beta.violets-purgatory.dev">Beta site</a>
<a class="chip" href="https://blog.violets-purgatory.dev">Blog</a>
<!-- <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://fs.violets-purgatory.dev">FileShare</a>
</div>
<!-- <a class="chip" href="https://fs.violets-purgatory.dev">FileShare</a> -->
{CUSTOM_STATUS}
</div>
</div>
<p>{RANDOM_QUOTE}</p>
<p>Make sure to check out this project on <a href="https://codeberg.org/bingus_violet/violets-purgatory">Codeberg</a>!</p>
<div id="activityHtml">
{ACTIVITIES}
</div>
{ANNOUNCEMENT}
{ACTIVITIES}
<h2><hr>Services</h2>
<p>List of services for public use hosted on Violet's Purgatory.</p>
<a href="https://sxng.violets-purgatory.dev" class="chip">SearXNG: sxng.violets-purgatory.dev</a>
<a class="chip">Matrix: matrix.violets-purgatory.dev</a>
<br>
<p class="chip">Matrix: matrix.violets-purgatory.dev</p>
<a href="https://element.violets-purgatory.dev" class="chip">Element: element.violets-purgatory.dev</a>
<a href="https://git.violets-purgatory.dev" class="chip">Forgejo: git.violets-purgatory.dev (contact me for an account)</a>
<a class="chip">Thumbor: thumbor.violets-purgatory.dev</a>
<hr>
<h1>Socials</h1>
{PATH_SOCIALS}
<br>
<h1><hr>FAQ</h1>
{PATH_FAQ}
{SELECTED_VIDEO}
{PATH_STATS}
<p>{WEATHER_TEXT}</p>
<br>
</main>

View file

@ -1,125 +0,0 @@
var catsOnMars = new Audio("/snds/cats on mars.mp3")
var whipLash = new Audio("/snds/johnny-test-whip-crack.mp3")
catsOnMars.loop = true
catsOnMars.volume = 0.25
whipLash.volume = 0.25
var sock
var spins = 1
var globalSpins = 0
var firsttimeDebounce = true
var spinWaiting = false
function spinLoop() {
spinWaiting = true
setTimeout(() => {
spinWaiting = false
var pfp = document.querySelector(".pfp")
if (!catsOnMars.paused) {
if (spins > 1) {
document.querySelector(".spinnyCount").style.display = "block"
document.querySelector(".localSpins").innerHTML = Math.ceil(spins - 1);
}
spins += 0.5
if (Math.round(spins) == spins && sock && sock.OPEN) {
document.querySelector(".pfp").src = "https://api.violets-purgatory.dev/v1/pfp?" + new Date().getTime()
sock.send(`{"op": 4}`)
console.log("Spin Sent!")
}
spinLoop()
}
}, 1000);
}
window.onbeforeunload = function () {
window.scrollTo(0, 0);
}
window.onload = function () {
window.scrollTo(0, 0);
var pfp = document.querySelector(".pfp")
pfp.addEventListener("mousedown", () => {
if (!spinWaiting) {
spinLoop();
}
catsOnMars.play()
pfp.style.animationName = "spinny"
pfp.style.scale = "1.1"
})
document.body.onmouseup = () => {
if (catsOnMars.currentTime != 0) {
catsOnMars.currentTime = 0
catsOnMars.pause()
whipLash.currentTime = 0
whipLash.play()
pfp.style.animationName = "unset"
pfp.style.scale = "1"
}
}
socketeer()
}
var lastPong = Date.now()
function ping(dur) {
sock.send(JSON.stringify({
op: 3
}))
setTimeout(() => {
ping(dur)
if (Date.now() - lastPong > 120000) {
sock.close()
console.log("Max duration since last pong exceeded- Closing socket.")
}
}, dur);
}
function socketeer() {
sock = new WebSocket('wss://api.violets-purgatory.dev')
sock.addEventListener("open", () => {
ping(30000)
})
sock.addEventListener("error", (error) => {
console.log(error)
})
sock.addEventListener("close", () => {
console.log("Connection Closed. Attempting Reconnect in 30 seconds.")
setTimeout(() => {
socketeer()
}, 30000);
})
sock.addEventListener("message", async(data) => {
data = data.data
data = JSON.parse(data)
if (data.op == 4) {
globalSpins = data.spins
if (firsttimeDebounce == true) {
firsttimeDebounce = false
document.querySelector(".globalSpins").innerHTML = globalSpins + 1;
} else {
document.querySelector(".globalSpins").innerHTML = globalSpins;
}
} else if (data.op == 0) {
var discFetch = await (await fetch("/discHTML")).text()
document.querySelector("#activityHtml").innerHTML = discFetch
} else if (data.op == 3) {
lastPong = Date.now()
} else {
console.log(data)
}
})
}

View file

@ -1,9 +0,0 @@
.pfp:active {
rotate: 7200deg;
transform: scale(1.15);
transition: all 5s cubic-bezier(0.445, 0.05, 0.55, 0.95) !important;
}
.noscript {
display: initial;
}

View file

@ -24,14 +24,6 @@
box-shadow: outset rgb(35, 20, 60) 0px 0px 20px;
}
.linkContainer {
display: flex;
flex-wrap: wrap;
max-width: 385px;
margin: auto;
justify-content: center;
}
.animatedTitle {
animation: mainText 2s cubic-bezier(0.075, 0.82, 0.165, 1);
margin: auto;
@ -48,21 +40,60 @@
.pfp {
border-radius: 15px;
border: darkgray 4px solid;
float: right;
width: 60%;
aspect-ratio: 1/1;
transform: scale(0.9);
border-radius: 50%;
rotate: 0deg;
user-select: none;
animation-duration: 2s;
animation-timing-function: linear;
animation-iteration-count: infinite;
}
.CLAlign {
display: inline-block;
.activity {
border-width: 3px;
border-radius: 10px;
overflow: hidden;
margin: auto;
padding: 0;
display: flex;
position: relative;
z-index: 3;
/* max-height: 200px; */
}
.activity>p {
width: 100%;
max-height: 100%;
overflow-wrap: anywhere;
text-overflow: ellipsis;
padding: 3px;
line-height: 1.5rem;
align-self: center;
}
.activity>img {
width: 40%;
aspect-ratio: 1/1;
object-fit: cover;
}
.activity>img:not(.smallimg) {
min-width: 150px;
max-width: 150px;
}
.activity>.smallimg {
width: 48px;
height: 48px;
position: absolute;
bottom: 0px;
left: 0px;
border-radius: 50px;
background: black;
padding: 5px;
/* border: 2px gray solid; */
transform: scale(0.9);
}
.activity>.smallimg:hover {
transform: scale(1);
}
img:not(.project-inner > div > img):not(.activity>img) {
@ -87,14 +118,25 @@ img:not(.project-inner > div > img):not(.activity>img) {
}
}
@keyframes spinny {
0% {
rotate: 0deg;
}
.lengthBar {
background-color: rgb(50, 40, 60);
display: inline-block;
width: 80%;
height: 10px;
padding: 0;
overflow: hidden;
border-radius: 5px;
margin-right: 1.9%;
}
100% {
rotate: 360deg;
}
.lengthBar>span {
margin: 0;
padding: 0;
width: 100%;
background-color: rgb(200, 200, 230);
height: 20px;
display: block;
position: relative;
}
@keyframes mainText {

View file

@ -2,9 +2,8 @@
<html lang="en">
<head>
<link rel="stylesheet" type="text/css" href="../style.css">
<link rel="stylesheet" type="text/css" href="../global.css">
<link rel="stylesheet" type="text/css" href="../subpage.css">
<script src="../main.js"></script>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
@ -14,43 +13,35 @@
<meta name="darkreader-lock">
<meta content="Socials - Violet's Purgatory" property="og:title" />
<meta content="This page lists all the platforms you can find me on!" property="og:description" />
<meta content="This page lists all the social media I use :3" 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}
<a href="../" class="chip">Home</a>
<a href="../faq" class="chip">FAQ</a>
<a href="../stats" class="chip">Stats</a>
<h1>Socials</h1>
<div class="mainDiv">
<hr>
<main>
<p>Here's most of the sites you can find me on-<br>if you needed that for some reason?</p>
<div class="grid-container">
<div class="grid-child">
<div>
<h3>Social Media</h3>
<a class="chip" href="https://floofy.city/@bingus_violet" rel="me">Fedi: bingus_violet&ZeroWidthSpace;@floofy.city</a>
<a class="chip" href="https://www.youtube.com/channel/UChcrBJNJLZucy3TPyGyAY2g">Youtube: {Violet}'s Fiasco</a>
<a class="chip" href="https://ko-fi.com/bingus_violet">Ko-fi: Bingus_{Violet}</a>
<a class="chip" href="https://void.lgbt/bingus_violet" rel="me">Fedi: bingus_violet&ZeroWidthSpace;@void.lgbt</a>
</div>
</div>
<div class="grid-child">
<div>
<h3>Chat</h3>
<a class="chip" href="https://matrix.to/#/@bingus_violet:matrix.violets-purgatory.dev">Matrix: @bingus_violet:&ZeroWidthSpace;matrix.violets-purgatory.dev</a>
<a class="chip">Discord: {DISCORD_USER}</a>
<a class="chip">Revolt: Bingus{Violet}#5573</a>
<p class="chip">Discord: {DISCORD_USER}</p>
<p class="chip">Revolt: Bingus{Violet}#5573</p>
</div>
</div>
<div class="grid-child">
<div>
<h3>Coding</h3>
<a class="chip" href="https://git.violets-purgatory.dev/bingus_violet/">Forgejo: bingus_violet (git.violets-purgatory.dev)</a>
<a class="chip" href="https://codeberg.org/Bingus_violet">Codeberg: bingus_violet</a>
<a class="chip" href="https://hub.docker.com/u/bingusviolet">Docker: bingusviolet</a>
<a class="chip" href="https://github.com/violets-puragtory">Github: violets-puragtory</a>
@ -64,13 +55,8 @@
</div>
</div>
<br>
<p class="note">Please note I am extremely unhinged and gay on Fedi, I don't use Github, and I barely understand Docker.</p>
</main>
<div id="activityHtml">
{ACTIVITIES}
</div>
{SELECTED_VIDEO}
</div>
</body>
</html>

View file

@ -1,52 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" type="text/css" href="../style.css">
<link rel="stylesheet" type="text/css" href="../subpage.css">
<script src="../main.js"></script>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Violet's Purgatory</title>
<meta name="darkreader-lock">
<meta content="Stats - Violet's Purgatory" property="og:title" />
<meta content="This page just does a semi-intensive speed test on the site, and displays related statistics." 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}
<a href="../" class="chip">Home</a>
<a href="../socials" class="chip">Socials</a>
<a href="../faq" class="chip">FAQ</a>
<h1>Stats</h1>
<p>This is the <em>full</em> stats page! This page exists for testing the speed of site generation, and contains every keyword on Violet's Purgatory in a hidden div.</p>
<div style="display: none">
{ALL_KEYWORDS} {ALL_KEYWORDS} {ALL_KEYWORDS} {ALL_KEYWORDS} {ALL_KEYWORDS}
</div>
<main>
<h1><hr>Stats</h1>
<br>
<ul>
<li>Page generation time: {LOAD_TIME}</li>
<li>Uptime: {UPTIME}</li>
<li>Total reloads: {RELOAD_COUNT} <sup>*1</sup></li>
<li>Cached Images: {CACHED_IMAGES} <sup>*2</sup></li>
</ul>
<br><br><br>
<ol class="noteList">
<li>Increments by 1 <em>EVERY</em> time <em>ANY</em> page is loaded.</li>
<li>Cached Images are cleared on server restart.</li>
</ul>
</main>
</div>
</body>
</html>

View file

@ -1,13 +1,10 @@
/*
This is the GLOBAL css file.
Any changes made in here, will apply to the ENTIRE site.
Only put changes here if you intend to put changes across
the whole site!
DO NOT MODIFY IF YOU ARE TRYING TO CHANGE THINGS ON THE SITE!!!
This exists for compatibility with services on Violet's purgatory
Soon, this will be removed, and replaced with a CDN or something...
*/
:root {
color-scheme: dark;
}
@import url("https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css");
@font-face {
font-display: swap;
@ -20,85 +17,68 @@
* {
font-family: 'Rubik', Verdana, Geneva, Tahoma, sans-serif;
padding: 0;
margin: 0;
font-weight: 400;
text-align: center;
}
h1 {
color: rgb(225, 215, 255);
font-size: 2.5rem;
}
h2 {
font-size: 2rem;
color: rgb(225, 215, 255)
}
h3 {
font-size: 1.65rem
}
h3,
li {
color: white;
}
#topbar {
background-color: rgb(75, 50, 125);
width: 100%;
padding: 1vh 0px;
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);
ul, ol {
display: inline-block
}
#topbar:hover {
opacity: 1;
transform: scale(1.05);
li {
font-size: 1.2rem;
text-align: left;
}
#topbar>* {
display: inline-block;
font-size: 1.5rem;
}
main:nth-of-type(1) {
width: 95%;
max-width: 1000px;
body,
html {
overflow-x: hidden;
margin: auto;
background-color: rgb(15, 4, 45);
background: linear-gradient(rgb(20, 4, 55), black);
width: 100vw;
height: 100vh;
margin: 0;
padding: 0;
background-attachment: local;
}
body {
overflow-x: hidden;
background-color: rgb(55, 4, 75);
background: linear-gradient(rgb(40, 4, 75), black);
background-attachment: local;
animation: hideContent 2.5s;
padding: 2.5%;
}
body, html {
min-height: 100%;
.fadediv {
animation-name: fade-in;
animation-duration: .75s;
animation-timing-function: cubic-bezier(0.165, 0.84, 0.44, 1);
margin: auto;
max-width: 1000px;
}
a {
color: rgb(175, 225, 255);
display: inline-block;
transition: 1.5s all cubic-bezier(0.075, 0.82, 0.165, 1);
}
a[href] {
color: rgb(175, 225, 255);
}
h3 {
font-size: 1.5rem;
padding: 10px;
}
@media screen and (min-width: 650px) {
.grid-container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-gap: 10px;
}
.grid-child {
margin: auto;
align-content: center;
/* border: 2px white solid; */
}
}
.chip {
position: relative;
z-index: 3;
@ -113,12 +93,9 @@ h3 {
transition: transform 1.25s cubic-bezier(0.075, 0.82, 0.165, 1), background-color 2s cubic-bezier(0.075, 0.82, 0.165, 1);
}
a.chip {
.chip,
.chip>* {
text-decoration: none;
/* background-image: linear-gradient(rgb(175, 225, 255), rgb(175, 225, 255));
background-size: calc(100% - 15px) 2px;
background-position: 50% 87.5%;
background-repeat: no-repeat; */
}
.chip:hover {
@ -129,47 +106,10 @@ a.chip {
transition: transform 0.75s cubic-bezier(0.075, 0.82, 0.165, 1), background-color 3s cubic-bezier(0.075, 0.82, 0.165, 1);
}
.chip:hover>.smallimg {
.chip:hover > .smallimg {
background-color: rgb(10, 0, 25);
}
hr {
color: white;
border: white solid;
opacity: 0.25;
border-width: 2px;
margin: 15px 10%;
/* background-color: none; */
}
p {
font-size: 1.25rem;
margin: 5px;
line-height: 2rem;
text-wrap: pretty;
}
img {
width: 100%;
/* max-width: 135px; */
}
h2 {
font-size: 1.8rem;
}
.note {
color: darkgray;
font-size: 1rem;
}
.striked {
text-decoration: line-through;
text-decoration-color: white;
}
.activity {
border-width: 3px;
border-radius: 10px;
@ -179,36 +119,25 @@ h2 {
display: flex;
position: relative;
z-index: 3;
/* max-height: 200px; */
}
.activity>p {
width: 100%;
max-height: 100%;
overflow-wrap: anywhere;
text-overflow: ellipsis;
padding: 3px;
line-height: 1.5rem;
align-self: center;
overflow-wrap: break-word;
}
.activity>img {
width: 40%;
width: 128px;
aspect-ratio: 1/1;
object-fit: cover;
}
.activity>img:not(.smallimg) {
min-width: 150px;
max-width: 150px;
}
.activity>.smallimg {
width: 48px;
height: 48px;
width: 64px;
height: 64px;
position: absolute;
bottom: 0px;
left: 0px;
left: 72px;
border-radius: 50px;
background: black;
padding: 5px;
@ -220,17 +149,101 @@ h2 {
transform: scale(1);
}
ul, ol {
display: inline-block
a:hover {
color: white;
transition: 0.5s all cubic-bezier(0.075, 0.82, 0.165, 1);
}
li {
p {
color: white;
font-size: 1.2rem;
text-align: left;
padding: 0;
margin: 10px;
}
.noscript {
display: none;
img:not(.project-inner > div > img) {
width: 100%;
max-width: 135px;
transition: all 2s cubic-bezier(0.075, 0.82, 0.165, 1);
}
.pfp {
border-radius: 15px;
border: darkgray 4px solid;
width: 60%;
aspect-ratio: 1/1;
transform: scale(0.9);
border-radius: 50%;
}
.pfp:hover {
transform: scale(1);
border-color: rgb(255, 200, 255);
object-fit: cover;
}
.emoji {
width: 32px;
border-radius: 10%;
/* border: 1px gray solid; */
}
hr {
color: white;
opacity: 0.25;
border-width: 2px;
margin: 15px 10%;
}
#card {
background-color: rgb(15, 5, 80);
padding: 15px;
border: 2px white solid;
margin: 20px auto;
width: 95%;
max-width: 800px;
z-index: 3;
position: relative;
}
.me {
border-color: limegreen;
}
.project {
background-color: rgba(35, 35, 35, 0.8);
padding: 15px;
border: 2px gray solid;
margin: 20px 0px;
border-radius: 15px;
}
.project-inner {
overflow: hidden;
padding: 0;
margin: auto;
z-index: 3;
}
.project-inner>div>img {
object-fit: cover;
border: 2px white solid;
width: 80%;
max-width: 500px;
margin: auto;
border-radius: 10px;
}
.project>p {
display: inline-block;
}
.minipfp {
width: 70px;
display: inline-block;
margin-right: 10px;
border: 2px lightgray solid;
border-radius: 5px;
}
.lengthBar {
@ -244,16 +257,6 @@ li {
margin-right: 1.9%;
}
.textBlock {
color: rgb(255, 255, 255);
white-space: pre-wrap;
background-color: rgb(20, 20, 20);
border: 2px lightgray solid;
padding: 15px;
/* font-family: 'Source Code Pro', sans-serif; */
text-align: center;
}
.lengthBar>span {
margin: 0;
padding: 0;
@ -264,29 +267,19 @@ li {
position: relative;
}
video {
width: 95%;
max-height: 90vh;
.note {
font-size: 0.95rem;
color: lightgray;
}
sup {
color: gray;
}
@keyframes fade-in {
0% {
opacity: 0;
transform: translateY(50vh);
}
.noteList {
list-style: none;
}
.noteList > * {
counter-increment: noteList;
color: gray;
font-size: 1rem;
}
.noteList > li::before {
content: "*" counter(noteList) ". ";
}
em {
color: inherit;
100% {
opacity: 1;
transform: none;
}
}

View file

@ -6,18 +6,14 @@
h1:nth-of-type(1) {
font-size: 2.5rem;
}
body {
padding: 5vh 0;
}
.mainDiv {
main {
animation: fadeUp 1s cubic-bezier(0.075, 0.82, 0.165, 1);
padding: 0 2.5vw;
max-width: 800px;
margin: auto;
}
@keyframes fadeUp {

103
weatherGenerator.js Normal file
View file

@ -0,0 +1,103 @@
module.exports = {
makeRain: function (hardRain) {
var html = ""
html += `<div class="rainStuff"><div class="rainContainer">`
html +=
`
<style>
#card {
background-color: rgba(50, 0, 90, 0.5);
backdrop-filter: blur(5px);
}
.rainStuff {
position: sticky;
top: 0;
height: 0;
z-index: -5;
}
.rainContainer {
height: 100vh;
width: 80vw;
top: 0px;
left: 10vw;
position: absolute;
overflow: hidden;
}
.rainDrop {
position: absolute;
width: 5px;
backdrop-filter: blur(5px);
background-color: rgba(0, 0, 255, 0.2);
height: 10vh;
visibility: hidden;
}
body {
background: linear-gradient(rgb(10, 10, 75), black);
}
</style>
`
var amount = 7
var iterationReducer = 3
if (hardRain) {
amount = 100
}
for (let index = 0; index < amount; index++) {
html += `<div class="rainDrop"></div>`
}
html += "<style>"
for (let index = 0; index < amount; index++) {
html += `
.rainDrop:nth-of-type(${index + 1}) {
animation: rainAnim${index} ${(Math.random() * 0.3) + (5 - iterationReducer)}s linear;
animation-iteration-count: infinite;
animation-delay: ${Math.round(Math.random() * 100) / 100}s;
}
`
var randos = []
for (let index = 0; index < 11; index++) {
randos.push(Math.round(Math.random() * 100))
}
html += `@keyframes rainAnim${index} { `
for (let index = 0; index < (iterationReducer * -3.5) + 14.5; index++) {
html += `
${index * iterationReducer}0% {
top: 110vh;
right: ${randos[index]}%;
visibility: hidden;
}
${index * iterationReducer}0.1% {
top: -10vh;
right: ${randos[index + 1]}%;
visibility: hidden;
}
${index * iterationReducer}0.2% {
visibility: visible;
}
`
}
// console.log(html)
html += `90.3% { visibility: hidden; }`
html += `}`
}
html += "</style>"
html += "</div></div>"
return html
}
}