Function
This commit is contained in:
parent
444316d4b0
commit
9d632c07be
13 changed files with 1412 additions and 0 deletions
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"vscord.app.privacyMode.enable": true
|
||||
}
|
8
constants.js
Normal file
8
constants.js
Normal file
|
@ -0,0 +1,8 @@
|
|||
import * as path from "path"
|
||||
import { fileURLToPath } from "url"
|
||||
|
||||
export const flavors = ["#reflectivedetective", "#alearfred"]
|
||||
export const variety = 200
|
||||
export const PORT = process.env.PORT || 8080
|
||||
export const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
||||
export const staticPath = path.join(__dirname, "static")
|
12
frontend.js
Normal file
12
frontend.js
Normal file
|
@ -0,0 +1,12 @@
|
|||
import { PORT, staticPath } from "./constants.js"
|
||||
import express from "express"
|
||||
import { middleware } from "./pageUpdater.js"
|
||||
|
||||
export const app = express()
|
||||
|
||||
app.use(middleware)
|
||||
app.use(express.static(staticPath))
|
||||
|
||||
app.listen(PORT, () => {
|
||||
console.log("THE AWESOMEST YAOI GENERATOR OF ALL TIME is now listening on port: " + PORT)
|
||||
})
|
1
index.js
Normal file
1
index.js
Normal file
|
@ -0,0 +1 @@
|
|||
import "./frontend.js"
|
1113
package-lock.json
generated
Normal file
1113
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
20
package.json
Normal file
20
package.json
Normal file
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"name": "dandys-world-yaoi-spinner",
|
||||
"version": "1.0.0",
|
||||
"description": "Bruhh where am I???",
|
||||
"main": "index.js",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"start": "node index.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://git.viois.gay/Violet/Dandys-World-Yaoi-Spinner"
|
||||
},
|
||||
"author": "Violet",
|
||||
"license": "Unlicense",
|
||||
"dependencies": {
|
||||
"@the-convocation/twitter-scraper": "^0.14.1",
|
||||
"express": "^4.21.2"
|
||||
}
|
||||
}
|
54
pageUpdater.js
Normal file
54
pageUpdater.js
Normal file
|
@ -0,0 +1,54 @@
|
|||
import * as path from "path"
|
||||
import * as fs from "fs"
|
||||
import { staticPath } from "./constants.js"
|
||||
import { flavors, variety } from "./constants.js"
|
||||
import { getYaoi } from "./scraper.js"
|
||||
|
||||
export async function middleware(req, res, next) {
|
||||
var filePath = (req.baseUrl + req.path).trim()
|
||||
|
||||
if (!filePath.includes(".")) {
|
||||
if (filePath.charAt(filePath.length - 1) != '/') {
|
||||
res.redirect(filePath + '/')
|
||||
return
|
||||
}
|
||||
filePath = path.join(filePath, '/index.html')
|
||||
}
|
||||
|
||||
filePath = path.join(staticPath, filePath || 'index.html')
|
||||
if (fs.existsSync(filePath) && filePath.includes(".html")) {
|
||||
var data = fs.readFileSync(filePath).toString()
|
||||
|
||||
res.contentType(path.basename(filePath))
|
||||
|
||||
data = await converter(data)
|
||||
|
||||
res.send(data)
|
||||
}
|
||||
else {
|
||||
next()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export async function converter(html) {
|
||||
var replacers = {
|
||||
"FLAVOR_COUNT": flavors.length,
|
||||
"VARIETY": variety,
|
||||
"FLAVORS": flavors.join(", ").replace(/,(?=[^,]+$)/, ' &'),
|
||||
"SPIN_BUTTON": `<a href="/spin" id="yaoiButton"><div>S</div><div>P</div><div>I</div><div>N</div></a>`,
|
||||
"YAOI": () => {
|
||||
var yaoi = getYaoi()
|
||||
|
||||
if (yaoi) {
|
||||
return `<div class="post">${yaoi.html}</div>`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var key in replacers) {
|
||||
html = html.replaceAll(`{${key}}`, replacers[key])
|
||||
}
|
||||
|
||||
return html
|
||||
}
|
29
scraper.js
Normal file
29
scraper.js
Normal file
|
@ -0,0 +1,29 @@
|
|||
import { Scraper } from "@the-convocation/twitter-scraper"
|
||||
import { flavors, variety } from "./constants.js"
|
||||
|
||||
const scraper = new Scraper({
|
||||
})
|
||||
|
||||
await scraper.login(process.env.USERNAME, process.env.PASSWORD)
|
||||
|
||||
export async function scrapeYaoi() {
|
||||
var finalArray = []
|
||||
for (let flavor of flavors) {
|
||||
console.log(flavor)
|
||||
var search = scraper.searchTweets(flavor, variety, "media")
|
||||
|
||||
for await (var value of search) {
|
||||
if (value.html.includes("img")) {
|
||||
finalArray.push(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
return finalArray
|
||||
}
|
||||
|
||||
export var yaoiList = await scrapeYaoi()
|
||||
export function getYaoi() {
|
||||
var yaoi = yaoiList[Math.floor(Math.random() * yaoiList.length)]
|
||||
|
||||
return yaoi
|
||||
}
|
BIN
static/fonts/rubik-v28-latin-600.woff2
Normal file
BIN
static/fonts/rubik-v28-latin-600.woff2
Normal file
Binary file not shown.
BIN
static/fonts/rubik-v28-latin-regular.woff2
Normal file
BIN
static/fonts/rubik-v28-latin-regular.woff2
Normal file
Binary file not shown.
17
static/index.html
Normal file
17
static/index.html
Normal file
|
@ -0,0 +1,17 @@
|
|||
<!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="style.css">
|
||||
|
||||
<title>Yaoi Spinner</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>The Yaoi Spinner</h1>
|
||||
<p>Welcome to the awesomest Yaoi Spinner ever. You can gamble yaoi. Yup. #imstraight</p>
|
||||
{SPIN_BUTTON}
|
||||
<p>All Yaoi is sourced from Twitter. Randomly chosen from a mix of {FLAVOR_COUNT} different searches! Currently searches for {VARIETY} posts each of {FLAVORS}</p>
|
||||
</body>
|
||||
</html>
|
17
static/spin/index.html
Normal file
17
static/spin/index.html
Normal file
|
@ -0,0 +1,17 @@
|
|||
<!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="../style.css">
|
||||
|
||||
<title>Yaoi Spinner</title>
|
||||
</head>
|
||||
<body>
|
||||
<!-- <h1>The Yaoi Spinner</h1> -->
|
||||
{YAOI}
|
||||
{SPIN_BUTTON}
|
||||
<p>All Yaoi is sourced from Twitter. Randomly chosen from a mix of {FLAVOR_COUNT} different searches! Currently searches for {VARIETY} posts each of {FLAVORS}</p>
|
||||
</body>
|
||||
</html>
|
138
static/style.css
Normal file
138
static/style.css
Normal file
|
@ -0,0 +1,138 @@
|
|||
:root {
|
||||
--gay-erasure: 1
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-display: swap;
|
||||
font-family: 'RubikBold';
|
||||
font-style: bold;
|
||||
font-weight: 600;
|
||||
src: url('./fonts/rubik-v28-latin-600.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');
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: rgb(20, 20, 60);
|
||||
/* background: linear-gradient(145deg, rgb(30, 30, 80), rgb(0, 0, 0)); */
|
||||
|
||||
padding: 5px calc(5px + 5%);
|
||||
|
||||
color: white;
|
||||
text-align: center;
|
||||
font-family: "Rubik", Verdana, Geneva, Tahoma, sans-serif;
|
||||
}
|
||||
|
||||
html {
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 3rem;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
#yaoiButton {
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
rgba(255, 0, 0, var(--gay-erasure)) 0%,
|
||||
rgba(255, 154, 0, var(--gay-erasure)) 10%,
|
||||
rgba(208, 222, 33, var(--gay-erasure)) 20%,
|
||||
rgba(79, 220, 74, var(--gay-erasure)) 30%,
|
||||
rgba(63, 218, 216, var(--gay-erasure)) 40%,
|
||||
rgba(47, 201, 226, var(--gay-erasure)) 50%,
|
||||
rgba(28, 127, 238, var(--gay-erasure)) 60%,
|
||||
rgba(95, 21, 242, var(--gay-erasure)) 70%,
|
||||
rgba(186, 12, 248, var(--gay-erasure)) 80%,
|
||||
rgba(251, 7, 217, var(--gay-erasure)) 90%,
|
||||
rgba(255, 0, 0, var(--gay-erasure)) 100%
|
||||
);
|
||||
background-size: 300px auto;
|
||||
background-position-x: 0px;
|
||||
/* border: 2px white solid;
|
||||
padding: 10px; */
|
||||
display: inline-block;
|
||||
-webkit-text-stroke: white 3px;
|
||||
font-size: 5rem;
|
||||
animation-name: slidebg;
|
||||
animation-duration: 2.5s;
|
||||
animation-timing-function: linear;
|
||||
animation-iteration-count: infinite;
|
||||
font-weight: bold;
|
||||
|
||||
background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
transition: transform 2s cubic-bezier(0.075, 0.82, 0.165, 1);
|
||||
}
|
||||
|
||||
#yaoiButton:hover {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
#yaoiButton > div {
|
||||
display: inline-block;
|
||||
|
||||
animation-name: float;
|
||||
animation-duration: 1s;
|
||||
animation-iteration-count: infinite;
|
||||
animation-direction: alternate;
|
||||
animation-timing-function: cubic-bezier(0.445, 0.05, 0.55, 0.95);
|
||||
animation-fill-mode: both;
|
||||
}
|
||||
|
||||
#yaoiButton > div:nth-child(2) {
|
||||
animation-delay: 0.25s;
|
||||
}
|
||||
|
||||
#yaoiButton > div:nth-child(3) {
|
||||
animation-delay: 0.5s;
|
||||
}
|
||||
|
||||
#yaoiButton > div:nth-child(4) {
|
||||
animation-delay: 0.75s;
|
||||
}
|
||||
|
||||
.post {
|
||||
background-color: black;
|
||||
border: 2px gray solid;
|
||||
text-align: left;
|
||||
padding: 5px 16px;
|
||||
width: 600px;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
border-radius: 16px;
|
||||
margin: 16px auto;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
@keyframes float {
|
||||
from {
|
||||
transform: translateY(-5px);
|
||||
}
|
||||
|
||||
to {
|
||||
transform: translateY(5px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slidebg {
|
||||
from {
|
||||
background-position-x: 0px;
|
||||
}
|
||||
|
||||
to {
|
||||
background-position-x: 300px;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue