This commit is contained in:
MeowcaTheoRange 2024-08-28 01:29:42 -05:00
parent d6038af33f
commit bad3eccbde
14 changed files with 1157 additions and 24 deletions

1
.gitignore vendored
View file

@ -1 +1,2 @@
node_modules node_modules
abtmtr.db

View file

@ -74,6 +74,21 @@ h1, h2, h3 {
font-weight: normal; font-weight: normal;
} }
h1 {
margin: 1em 0;
font-size: 2em;
}
h2 {
margin: 0.5em 0;
font-size: 2em;
}
h3 {
margin: 0.25em 0;
font-size: 1em;
}
section { section {
margin: 1em; margin: 1em;
} }
@ -164,6 +179,7 @@ hr {
vertical-align: middle; vertical-align: middle;
margin: 4px 0; margin: 4px 0;
text-decoration: none; text-decoration: none;
text-align: center;
/* text-overflow: ellipsis; /* text-overflow: ellipsis;
overflow: hidden; overflow: hidden;
padding: 0 8px; padding: 0 8px;

111
index.js
View file

@ -1,9 +1,23 @@
import express from "express"; import express from "express";
import { config } from "dotenv"; import { config } from "dotenv";
import path from "path"; import path from "path";
import SQLite from 'better-sqlite3';
import { Kysely, SqliteDialect } from 'kysely';
import { nanoid } from "nanoid";
import { JSDOM } from "jsdom";
const __dirname = import.meta.dirname; const __dirname = import.meta.dirname;
const rawDB = new SQLite('abtmtr.db');
const db = new Kysely({
dialect: new SqliteDialect({
database: rawDB,
})
});
rawDB.exec(`CREATE TABLE IF NOT EXISTS blurbs( 'id' TEXT, 'site' TEXT, 'blurb' TEXT, 'verified' INTEGER, 'time' INTEGER );`);
const app = express(); const app = express();
app.set('view engine', 'ejs'); app.set('view engine', 'ejs');
@ -80,6 +94,103 @@ app.get('/about', (req, res) => {
res.render('about/index'); res.render('about/index');
}); });
app.get('/blurbs', async (req, res) => {
const data = await db
.selectFrom('blurbs')
.selectAll()
.where('verified', '=', 1)
.execute();
res.render('blurbs/index', { data });
});
// brbrleibbghbelsbbsbuuebbuubsubss
async function cleanupBlurbles() {
const timeNow = Date.now() - 86400000;
await db
.deleteFrom('blurbs')
.where('time', '<', timeNow)
.execute()
}
app.get('/blurbs/send', async (req, res) => {
const body = req.query;
const errors = [];
if (body.site == null) errors.push("Site domain required");
else {
const status = await fetch(body.site).then(x => x.status).catch(_ => _);
if (status != 200) errors.push("Site must be online");
}
if (body.text == null) errors.push("Blurb text required");
else {
if (body.text.length < 1) errors.push("Blurb text must not be blank");
if (body.text.length > 140) errors.push("Blurb text must not exceed 140 characters");
}
if (errors.length > 0) return res.status(400).json({
error: "Bad Request",
message: errors.join(", ")
});
const postId = nanoid(32);
try {
await db.insertInto('blurbs')
.values({
id: postId,
site: body.site,
blurb: body.text,
verified: 0,
time: Date.now()
})
.executeTakeFirstOrThrow();
} catch (err) {
console.log(err)
return res.status(500).send('Internal Server Error');
}
cleanupBlurbles();
res.render('blurbs/sent', { id: postId });
});
app.get('/blurbs/check', async (req, res) => {
const body = req.query;
const blurbFromId = await db
.selectFrom('blurbs')
.selectAll()
.where('id', '=', body.id)
.executeTakeFirst();
if (blurbFromId == null) return res.redirect("/blurbs/");
const site = await fetch(blurbFromId.site).then(x => x.text()).catch(_ => _);
const dom = new JSDOM(site);
const relationLink = dom.window.document.querySelector(
`[rel=me][href="https://abtmtr.link/blurbs/#${blurbFromId.id}"]`
);
if (relationLink != null) await db
.updateTable('blurbs')
.set({
verified: 1
})
.where('id', '=', body.id)
.executeTakeFirst();
else {
await db
.updateTable('blurbs')
.set({
verified: 0
})
.where('id', '=', body.id)
.executeTakeFirst();
}
cleanupBlurbles();
res.redirect("/blurbs/");
});
app.get("/favicon.ico", (req, res) => { app.get("/favicon.ico", (req, res) => {
res.redirect("https://cdn.abtmtr.link/site_content/favicon.ico") res.redirect("https://cdn.abtmtr.link/site_content/favicon.ico")
}) })

905
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -7,7 +7,8 @@
}, },
"nodemonConfig": { "nodemonConfig": {
"ignore": [ "ignore": [
"node_modules/**" "node_modules/**",
"abtmtr.db"
], ],
"ext": "*" "ext": "*"
}, },
@ -16,10 +17,13 @@
"license": "SEE LICENSE IN LICENSE", "license": "SEE LICENSE IN LICENSE",
"description": "", "description": "",
"dependencies": { "dependencies": {
"better-sqlite3": "^11.2.1",
"dotenv": "^16.4.5", "dotenv": "^16.4.5",
"ejs": "^3.1.10", "ejs": "^3.1.10",
"express": "^4.19.2", "express": "^4.19.2",
"jsdom": "^25.0.0",
"kysely": "^0.27.4", "kysely": "^0.27.4",
"nanoid": "^5.0.7",
"pg": "^8.12.0" "pg": "^8.12.0"
}, },
"devDependencies": { "devDependencies": {

View file

@ -1,4 +1,11 @@
<div class="Aboutbox"> <div class="Aboutbox">
<div class="AboutboxElement">
<div class="AboutboxElementText">
<h1><a href="/blurbs/">BLURBS</a></h1>
<p>What are other sites saying about abtmtr.link?</p>
</div>
<img class="AboutboxElementImage" src="/assets/icons/friends.png" />
</div>
<div class="AboutboxElement"> <div class="AboutboxElement">
<div class="AboutboxElementText"> <div class="AboutboxElementText">
<h1><a href="/matkap/">MATKAP ZONE</a></h1> <h1><a href="/matkap/">MATKAP ZONE</a></h1>

View file

@ -1,9 +1,7 @@
<footer> <div class="fakemain">
<section> <section>
<h2>abtmtr.link v13</h2> <h2>buttons</h2>
<p>&copy; <a href="/about">MeowcaTheoRange</a> 2023-2024</p> <p>friends (<%= buttons.length %>)</p>
<p>Licensed under the <a href="https://cdn.abtmtr.link/licenses/kkpl/license-v2.2.txt">Karkat Public License</a>.</p>
<p>Git repository: <a href="https://git.abtmtr.link/MeowcaTheoRange/abtmtr-v13" target="_blank">MeowcaTheoRange/abtmtr-v13</a></p>
</section> </section>
<section style="text-align: center;"> <section style="text-align: center;">
<% buttons.forEach((button) => { %> <% buttons.forEach((button) => { %>
@ -14,6 +12,9 @@
<% } %> <% } %>
<% }) %> <% }) %>
</section> </section>
<section>
<p>following (<%= following.length %>)</p>
</section>
<section style="text-align: center;"> <section style="text-align: center;">
<% following.forEach((button) => { %> <% following.forEach((button) => { %>
<% if (button.img != null) { %> <% if (button.img != null) { %>
@ -23,4 +24,14 @@
<% } %> <% } %>
<% }) %> <% }) %>
</section> </section>
</footer> </div>
<div class="fakemain">
<footer>
<section>
<h2>abtmtr.link v13</h2>
<p>&copy; <a href="/about">MeowcaTheoRange</a> 2023-2024</p>
<p>Licensed under the <a href="https://cdn.abtmtr.link/licenses/kkpl/license-v2.2.txt">Karkat Public License</a>.</p>
<p>Git repository: <a href="https://git.abtmtr.link/MeowcaTheoRange/abtmtr-v13" target="_blank">MeowcaTheoRange/abtmtr-v13</a></p>
</section>
</footer>
</div>

View file

@ -37,9 +37,7 @@
</div> </div>
</section> </section>
</main> </main>
<div class="fakemain"> <%- include("../../components/footer.ejs") %>
<%- include("../../components/footer.ejs") %>
</div>
<script src="/assets/script.js"></script> <script src="/assets/script.js"></script>
</body> </body>

View file

@ -0,0 +1,54 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>abtmtr.link</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="/assets/style.css" />
</head>
<body>
<div class="fakemain">
<%- include("../../components/header.ejs") %>
</div>
<main>
<p class="tagline">What are other sites saying about abtmtr.link?</p>
<section>
<form action="/blurbs/send" method="get">
<p>
<label for="siteName">Website URL:</label>
<input type="url" name="site" id="siteName">
</p>
<p>
<label for="blurbText">Blurb:</label>
<input type="text" name="text" id="blurbText" maxlength="140" minlength="1">
</p>
<p>
<input type="submit" value="Submit Blurb">
</p>
<p style="opacity: 0.5;">by clicking this button and successfully submitting a blurb, you agree that your input may be displayed on this site and stored on abtmtr.link servers, even if the blurb is not verified. unverified blurbs will be marked for removal one day after creation.</p>
</form>
<ul>
<% data.forEach((blurb) => { %>
<li class="blurb"><a href="<%= blurb.site %>" target="_blank"><%= new URL(blurb.site).host %></a>: <%= blurb.blurb %> <a class="removePopup" href="/blurbs/check?id=<%= blurb.id %>">remove</a></li>
<% }) %>
</ul>
</section>
<style>
.blurb .removePopup {
visibility: hidden;
opacity: 0.5;
color: red;
}
.blurb:hover .removePopup {
visibility: visible;
}
</style>
</main>
<%- include("../../components/footer.ejs") %>
<script src="/assets/script.js"></script>
</body>
</html>

View file

@ -0,0 +1,36 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>abtmtr.link</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="/assets/style.css" />
</head>
<body>
<div class="fakemain">
<%- include("../../components/header.ejs") %>
</div>
<main>
<p class="tagline">congrations! you done it</p>
<section>
<p>make sure to add this to the page you have linked:</p>
<p style="background-color: black;color:white;padding: 0.5em;">&lt;link rel="me" href="https://abtmtr.link/blurbs/#<%= id %>"&gt;</p>
<p>you can remove the tag later. use this to remove your blurb from the site if you feel like it</p>
<p>do not leave this site until you have added the snippet! you can bookmark this page if you need to:</p>
<p style="background-color: black;color:white;padding: 0.5em;">https://abtmtr.link/blurbs/check/?id=<%= id %></p>
<p>then click this button (or visit the above bookmark) once you have added it. make sure your page has updated in your browser!</p>
<form action="/blurbs/check/" method="get">
<input type="hidden" value="<%= id %>" name="id">
<input type="submit" value="Done and added">
</form>
<p style="opacity: 0.5;">can't/don't want to add the snippet? <a href="/about" target="_blank">contact me</a>.</p>
</section>
</main>
<%- include("../../components/footer.ejs") %>
<script src="/assets/script.js"></script>
</body>
</html>

View file

@ -21,9 +21,7 @@
<% }) %> <% }) %>
</div> </div>
</main> </main>
<div class="fakemain"> <%- include("../../components/footer.ejs") %>
<%- include("../../components/footer.ejs") %>
</div>
<script src="/assets/script.js"></script> <script src="/assets/script.js"></script>
</body> </body>

View file

@ -24,9 +24,7 @@
<p class="tagline">abtmtr.link is a domain for all kinds of services, from web search to live-streaming.</p> <p class="tagline">abtmtr.link is a domain for all kinds of services, from web search to live-streaming.</p>
<%- include("../components/about-boxes.ejs") %> <%- include("../components/about-boxes.ejs") %>
</main> </main>
<div class="fakemain"> <%- include("../components/footer.ejs") %>
<%- include("../components/footer.ejs") %>
</div>
<script src="/assets/script.js"></script> <script src="/assets/script.js"></script>
</body> </body>

View file

@ -21,9 +21,7 @@
<% }) %> <% }) %>
</div> </div>
</main> </main>
<div class="fakemain"> <%- include("../../components/footer.ejs") %>
<%- include("../../components/footer.ejs") %>
</div>
<script src="/assets/script.js"></script> <script src="/assets/script.js"></script>
</body> </body>

View file

@ -21,9 +21,7 @@
<% }) %> <% }) %>
</div> </div>
</main> </main>
<div class="fakemain"> <%- include("../../components/footer.ejs") %>
<%- include("../../components/footer.ejs") %>
</div>
<script src="/assets/script.js"></script> <script src="/assets/script.js"></script>
</body> </body>