mostly finish custom music
This commit is contained in:
@ -4,4 +4,8 @@ HCAPTCHA_SECRET=hcaptcha
|
||||
ANNOUNCEMENT_KEY=text.
|
||||
GROQ_API_KEY=["groq_api"]
|
||||
NTFY_ALERT=ntfy_channel
|
||||
DATA_PATH=where_to_store_data
|
||||
DATA_PATH=where_to_store_data
|
||||
NODE_ENV=production
|
||||
DISCORD_AI_WEBHOOK=discord_webhook_url
|
||||
PROCESSING_SERVER=https://git.ceres.rip/selenite/processing
|
||||
PROCESSING_SERVER_SECRET=secret
|
@ -9,30 +9,16 @@ async function search(query) {
|
||||
let data = sc.search(query);
|
||||
return data;
|
||||
}
|
||||
async function download(url, res) {
|
||||
if (!url) {
|
||||
return res.status(400).send('Please provide a SoundCloud track URL as ?url=')
|
||||
}
|
||||
|
||||
async function download(url) {
|
||||
try {
|
||||
const info = await sc.getByUrl(url)
|
||||
const info = await sc.getByUrl(url);
|
||||
|
||||
if (info.type !== 'track') {
|
||||
return res.status(400).send('URL is not a SoundCloud track')
|
||||
}
|
||||
const { stream } = await info.getStream();
|
||||
|
||||
const { stream, mimeType, sizeBytes } = await info.getStream()
|
||||
|
||||
res.setHeader('Content-Type', mimeType)
|
||||
if (sizeBytes) {
|
||||
res.setHeader('Content-Length', sizeBytes.toString())
|
||||
}
|
||||
res.setHeader('Cache-Control', 'no-cache')
|
||||
|
||||
stream.pipe(res)
|
||||
return stream.path;
|
||||
} catch (err) {
|
||||
console.error('Stream error:', err)
|
||||
res.status(500).send(err.message || 'Failed to stream track')
|
||||
return(err.message || 'Failed to stream track')
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,7 @@ import sanitizeHtml from "sanitize-html";
|
||||
import sharp from "sharp";
|
||||
import { accs } from "../database.js";
|
||||
import { getUserFromCookie, isBanned, decryptCookie, verifyCookie } from "./manage.js";
|
||||
import { download } from "./music.js";
|
||||
|
||||
import dayjs from "dayjs";
|
||||
import relativeTime from "dayjs/plugin/relativeTime.js";
|
||||
@ -208,6 +209,31 @@ async function editProfile(body, token, admin) {
|
||||
updateAccount.get({ $url: url, $user: user });
|
||||
}
|
||||
}
|
||||
if (body.artist) {
|
||||
let path = await download(body.url);
|
||||
console.log("exit download");
|
||||
let file = Bun.file(path);
|
||||
let request = new Request({
|
||||
url: process.env.PROCESSING_SERVER + "/process",
|
||||
method: "POST",
|
||||
body: await file.arrayBuffer(),
|
||||
headers: {
|
||||
"X-Authentication": process.env.PROCESSING_SERVER_SECRET
|
||||
}
|
||||
});
|
||||
console.log("created request");
|
||||
let oggFile = await fetch(request);
|
||||
console.log("finished request");
|
||||
let filePath = `/data/${existingAccount.id}/${crypto.randomUUID()}.ogg`;
|
||||
await Bun.write(process.env.DATA_PATH + filePath, oggFile);
|
||||
const updateAccount = accs.query(`UPDATE accounts SET music = $music WHERE username = $user`)
|
||||
updateAccount.get({ $music: JSON.stringify({
|
||||
path: filePath,
|
||||
name: body.title,
|
||||
artist: body.artist
|
||||
}), $user: user });
|
||||
console.log("database");
|
||||
}
|
||||
|
||||
return { success: true };
|
||||
}
|
||||
@ -228,6 +254,7 @@ async function generateAccountPage(name, cookie, admin) {
|
||||
}
|
||||
|
||||
let modifiedHTML = rawProfileHTML;
|
||||
let songData = JSON.parse(userData.music) || false;
|
||||
modifiedHTML = modifiedHTML.replaceAll("{{ name }}", sanitizeHtml(userData.name, allowNone));
|
||||
modifiedHTML = modifiedHTML.replaceAll("{{ join_date }}", dayjs(userData.createdAt).fromNow());
|
||||
modifiedHTML = modifiedHTML.replaceAll("{{ about }}", sanitizeHtml(userData.about, sanitizeConfig) || "No about me available..");
|
||||
@ -236,6 +263,14 @@ async function generateAccountPage(name, cookie, admin) {
|
||||
modifiedHTML = modifiedHTML.replaceAll("{{ custom_css }}", userData.custom_css || "");
|
||||
modifiedHTML = modifiedHTML.replaceAll("{{ online_time }}", dayjs(userData.last_login).fromNow());
|
||||
modifiedHTML = modifiedHTML.replaceAll("{{ username }}", sanitizeHtml(userData.username, allowNone));
|
||||
if(songData) {
|
||||
modifiedHTML = modifiedHTML.replaceAll("{{ song_title }}", sanitizeHtml(songData.name, allowNone));
|
||||
modifiedHTML = modifiedHTML.replaceAll("{{ song_artist }}", sanitizeHtml(songData.artist, allowNone));
|
||||
modifiedHTML = modifiedHTML.replaceAll("{{ song_url }}", sanitizeHtml(songData.path, allowNone));
|
||||
modifiedHTML = modifiedHTML.replaceAll("{{ is_music }}", "true");
|
||||
} else {
|
||||
modifiedHTML = modifiedHTML.replaceAll("{{ is_music }}", "false");
|
||||
}
|
||||
let badges_html = "";
|
||||
|
||||
if (userData.badges !== null) {
|
||||
@ -269,7 +304,6 @@ async function generateAccountPage(name, cookie, admin) {
|
||||
modifiedHTML = modifiedHTML.replaceAll("{{ url_gen }}", `https://selenite.cc/u/${userData.username}`);
|
||||
modifiedHTML = modifiedHTML.replaceAll("{{ online_time }}", dayjs(userData.last_login).fromNow());
|
||||
modifiedHTML = modifiedHTML.replaceAll("{{ css_edit }}", (userData.badges ? userData.badges.length : 0) > 0 ? '<img src="/img/edit.svg" id="edit" />' : "");
|
||||
modifiedHTML = modifiedHTML.replaceAll("{{ played_games }}", buildGameHTML(userData));
|
||||
let badges_html = "";
|
||||
|
||||
if (userData.badges !== null) {
|
||||
@ -282,43 +316,7 @@ async function generateAccountPage(name, cookie, admin) {
|
||||
return modifiedHTML;
|
||||
}
|
||||
}
|
||||
function buildGameHTML(existingAccount) {
|
||||
if (existingAccount.playedgames) {
|
||||
let games = JSON.parse(existingAccount.playedgames);
|
||||
let sortedGames = Object.keys(games).sort((a, b) => games[b] - games[a]);
|
||||
let return_data = [];
|
||||
if (Object.keys(games).length < 10) {
|
||||
for (let i = 0; i < sortedGames.length; i++) {
|
||||
try {
|
||||
let origin = gamesExceptions[sortedGames[i]] ? "sppa" : "semag";
|
||||
sortedGames[i] = gamesExceptions[sortedGames[i]] ? gamesExceptions[sortedGames[i]] : sortedGames[i];
|
||||
return_data[i] = { name: profileReadyJSON[sortedGames[i]].name, image: profileReadyJSON[sortedGames[i]].image, path: sortedGames[i], origin: origin, valid: true };
|
||||
} catch (e) {
|
||||
return_data[i] = { valid: false };
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (let i = 0; i < 10; i++) {
|
||||
try {
|
||||
let origin = gamesExceptions[sortedGames[i]] ? "sppa" : "semag";
|
||||
sortedGames[i] = gamesExceptions[sortedGames[i]] ? gamesExceptions[sortedGames[i]] : sortedGames[i];
|
||||
return_data[i] = { name: profileReadyJSON[sortedGames[i]].name, image: profileReadyJSON[sortedGames[i]].image, path: sortedGames[i], origin: origin, valid: true };
|
||||
} catch (e) {
|
||||
return_data[i] = { valid: false };
|
||||
}
|
||||
}
|
||||
}
|
||||
let return_html = "";
|
||||
for (let i = 0; i < Object.keys(return_data).length; i++) {
|
||||
if (return_data[i].valid) {
|
||||
return_html += `<div class="played-game"><img src="/${return_data[i].origin}/${return_data[i].path}/${return_data[i].image}"/><p>${return_data[i].name}</p></div>`;
|
||||
}
|
||||
}
|
||||
return return_html;
|
||||
} else {
|
||||
return "<h3>Play some games to view things appear here!</h3>";
|
||||
}
|
||||
}
|
||||
|
||||
async function getUsers(page, search) {
|
||||
let amount = 12;
|
||||
if (!page) {
|
||||
|
@ -48,9 +48,9 @@
|
||||
<script>
|
||||
let audioObject;
|
||||
document.addEventListener("DOMContentLoaded", ()=>{
|
||||
let music = true; // {{ is_music }}
|
||||
let music = {{ is_music }};
|
||||
if(music) {
|
||||
let url = "/api/music/download?url=https://soundcloud.com/archive5077/fostered-alcoholism-grayskies"; // {{ music_url }}
|
||||
let url = "{{ song_url }}";
|
||||
let audioObject = new Audio(url);
|
||||
document.getElementById("enter").addEventListener("click", async ()=>{
|
||||
document.getElementById("enter").style.backgroundColor = "#00000000"
|
||||
@ -59,8 +59,11 @@
|
||||
setTimeout( () => {
|
||||
document.getElementById("enter").style.display = "none";
|
||||
audioObject.play();
|
||||
audioObject.loop = true;
|
||||
}, 700);
|
||||
});
|
||||
} else {
|
||||
document.getElementById("enter").style.display = "none";
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
@ -45,7 +45,7 @@
|
||||
<title>{{ name }}'s Profile | Selenite</title>
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-3415518411898563" crossorigin="anonymous"></script>
|
||||
<script>
|
||||
<!-- <script>
|
||||
let audioObject;
|
||||
document.addEventListener("DOMContentLoaded", ()=>{
|
||||
let music = false; // {{ is_music }}
|
||||
@ -63,10 +63,11 @@
|
||||
});
|
||||
}
|
||||
})
|
||||
</script>
|
||||
</script> -->
|
||||
<script>
|
||||
let username = "{{ username }}";
|
||||
let userData;
|
||||
let songData;
|
||||
(async () => {
|
||||
userData = await (await fetch("/u/raw")).json();
|
||||
})();
|
||||
@ -100,16 +101,8 @@
|
||||
console.log("promise finished");
|
||||
body = { pfp: fileData };
|
||||
console.log("body set");
|
||||
} else if (state == "pfp") {
|
||||
console.log("pfp");
|
||||
let file = document.getElementById("pfp_upload").files[0];
|
||||
if (file.size > 4000000) {
|
||||
file.input = "";
|
||||
return;
|
||||
}
|
||||
const fileData = await readFileAsDataURL(file);
|
||||
console.log("promise finished");
|
||||
body = { pfp: fileData };
|
||||
} else if (state == "song") {
|
||||
body = songData;
|
||||
console.log("body set");
|
||||
} else if (state == "clearpfp") {
|
||||
body = { pfp: "del" };
|
||||
@ -186,11 +179,20 @@
|
||||
for (let i = 0; i < storeNames.length; i++) {
|
||||
localStorage.setItem(storeNames[i], storage[storeNames[i]]);
|
||||
}
|
||||
} else if (state == song) {
|
||||
// create body
|
||||
}
|
||||
console.log("sending");
|
||||
body.username = username;
|
||||
document.getElementById("title").innerText = "processing...";
|
||||
document.getElementById("pfp_upload").style.display = "none";
|
||||
document.getElementById("pfp_reminder").style.display = "none";
|
||||
document.getElementById("body-text").style.display = "none";
|
||||
document.getElementById("clear").style.display = "none";
|
||||
document.getElementById("text").style.display = "none";
|
||||
document.getElementById("counter").style.display = "none";
|
||||
document.getElementById("submit").style.display = "none";
|
||||
document.getElementById("search").style.display = "none";
|
||||
document.querySelector("results").style.display = "none";
|
||||
document.getElementById("popup").style.display = "flex";
|
||||
await fetch("/api/profile/edit", {
|
||||
credentials: "include",
|
||||
headers: {
|
||||
@ -200,8 +202,6 @@
|
||||
method: "POST",
|
||||
mode: "cors",
|
||||
});
|
||||
console.log("sent");
|
||||
document.getElementById("popup").style.display = "none";
|
||||
location.reload();
|
||||
}
|
||||
document.addEventListener("DOMContentLoaded", async () => {
|
||||
@ -230,6 +230,8 @@
|
||||
document.getElementById("counter").style.display = "flex";
|
||||
document.getElementById("submit").style.display = "flex";
|
||||
document.getElementById("popup").style.display = "flex";
|
||||
document.getElementById("search").style.display = "none";
|
||||
document.querySelector("results").style.display = "none";
|
||||
} else if (e.target.parentElement.children[0].id == "bio") {
|
||||
state = "bio";
|
||||
document.getElementById("title").innerText = "change your about me";
|
||||
@ -244,6 +246,8 @@
|
||||
document.getElementById("counter").style.display = "flex";
|
||||
document.getElementById("submit").style.display = "flex";
|
||||
document.getElementById("popup").style.display = "flex";
|
||||
document.getElementById("search").style.display = "none";
|
||||
document.querySelector("results").style.display = "none";
|
||||
} else if (e.target.parentElement.children[0].id == "song") {
|
||||
state = "song";
|
||||
document.getElementById("title").innerText = "pick a song";
|
||||
@ -256,6 +260,8 @@
|
||||
document.getElementById("counter").style.display = "none";
|
||||
document.getElementById("submit").style.display = "none";
|
||||
document.getElementById("popup").style.display = "flex";
|
||||
document.getElementById("search").style.display = "flex";
|
||||
document.querySelector("results").style.display = "flex";
|
||||
} else if (e.target.parentElement.children[0].id == "pfp") {
|
||||
state = "pfp";
|
||||
document.getElementById("title").innerText = "upload a new profile picture";
|
||||
@ -267,6 +273,8 @@
|
||||
document.getElementById("counter").style.display = "none";
|
||||
document.getElementById("submit").style.display = "flex";
|
||||
document.getElementById("popup").style.display = "flex";
|
||||
document.getElementById("search").style.display = "none";
|
||||
document.querySelector("results").style.display = "none";
|
||||
}
|
||||
});
|
||||
});
|
||||
@ -326,8 +334,16 @@
|
||||
document.getElementById("submit").style.display = "flex";
|
||||
document.getElementById("popup").style.display = "flex";
|
||||
});
|
||||
document.querySelectorAll("results").forEach(async e => {
|
||||
e.addEventListener("click", await setProfile)
|
||||
document.querySelectorAll("result").forEach(async e => {
|
||||
e.addEventListener("click", async (element) => {
|
||||
songData = {
|
||||
url: e.getAttribute("data-url"),
|
||||
title: e.childNodes[0].innerText,
|
||||
artist: e.childNodes[1].innerText,
|
||||
}
|
||||
console.log(songData);
|
||||
await setProfile();
|
||||
})
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
112
index.js
112
index.js
@ -37,7 +37,6 @@ const wss = new WebSocketServer({ noServer: true });
|
||||
let openSockets = 0;
|
||||
wss.on("connection", function connection(ws, req, res) {
|
||||
openSockets++;
|
||||
sockets.set(openSockets);
|
||||
setInterval(() => {
|
||||
ws.send("ping");
|
||||
}, 30000);
|
||||
@ -185,110 +184,6 @@ app.get("/api/chat/recent", async (req, res) => {
|
||||
// get last 50 recent messages
|
||||
// offset by a page param
|
||||
})
|
||||
app.get("/api/infinite/get", async (req, res, next) => {
|
||||
if (req.query[1] && req.query[2]) {
|
||||
let success = false;
|
||||
let data;
|
||||
try {
|
||||
let search1Query = infdb.query(`SELECT * FROM caches WHERE 1 = $one AND 2 = $two`)
|
||||
let search1 = await search1Query.get({ $one: req.query[1], $two: req.query[2] });
|
||||
console.log(search1);
|
||||
if (search1 && search1.length > 0) {
|
||||
data = { item: search1[0].result_item, emoji: search1[0].result_emoji, new: false };
|
||||
success = true;
|
||||
} else {
|
||||
let search2Query = infdb.query(`SELECT * FROM caches WHERE 1 = $two AND 2 = $one`)
|
||||
let search2 = await search2Query.get({ $one: req.query[1], $two: req.query[2] });
|
||||
console.log(search2);
|
||||
if (search2 && search2.length > 0) {
|
||||
data = { item: search2[0].result_item, emoji: search2[0].result_emoji, new: false };
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
if (success) {
|
||||
console.log("success");
|
||||
res.send(data);
|
||||
return;
|
||||
}
|
||||
data = await infiniteCraft(req.query[1], req.query[2]);
|
||||
try {
|
||||
let parse = JSON.parse(data);
|
||||
let keys = Object.keys(parse);
|
||||
if (keys.indexOf("item") > -1 && keys.indexOf("emoji") > -1) {
|
||||
parse.new = true;
|
||||
data = parse;
|
||||
const createCached = infdb.query(`INSERT INTO caches (1, 2, result_item, result_emoji) VALUES ($one, $two, $item, $emoji)`)
|
||||
createCached.run({ $one: req.query[1], $two: req.query[2], $item: data.item, $emoji: data.emoji });
|
||||
res.send(data);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
data = { item: "N/A", emoji: "N/A" };
|
||||
res.send(data);
|
||||
}
|
||||
}
|
||||
});
|
||||
app.use("/semag/polytrack/data/", async (req, res, next) => {
|
||||
let path = req.path.substring(1, req.path.length);
|
||||
if(path == "user") {
|
||||
res.sendStatus(200);
|
||||
} else if(path == "leaderboard") {
|
||||
let data = {};
|
||||
|
||||
if(req.method == "POST") {
|
||||
req.body.split("&").forEach((item) => {
|
||||
data[item.split("=")[0]] = item.split("=")[1]
|
||||
});
|
||||
console.log(data);
|
||||
const getExistingRuns = polytrack.query(`SELECT * FROM polytrack WHERE userid = $usrid AND trackid = $trackid`);
|
||||
let existingRuns = getExistingRuns.all({ $usrid: data["userToken"], $trackid: data["trackId"] });
|
||||
let saveRun = true;
|
||||
if(existingRuns !== null) {
|
||||
existingRuns.forEach((item) => {
|
||||
if(saveRun) {
|
||||
if(data.frames > item.frames) {
|
||||
saveRun = false;
|
||||
} else {
|
||||
let deleteRun = polytrack.query(`DELETE FROM polytrack WHERE id = $id`);
|
||||
deleteRun.run({ $id: item.id })
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
if(saveRun) {
|
||||
const addRun = polytrack.query(`INSERT INTO polytrack (trackid, username, colors, recording, frames, userid) VALUES ($id, $usr, $clr, $record, $frames, $usrid)`)
|
||||
let runData = addRun.run({ $id: data["trackId"], $usr: data["name"], $clr: data["carColors"], $record: data["recording"], $usrid: data["userToken"], $frames: data["frames"] });
|
||||
console.log("run", runData);
|
||||
res.send(runData.lastInsertRowid);
|
||||
}
|
||||
} else {
|
||||
let leaderboard = polytrack.query(`SELECT * FROM polytrack WHERE trackid = $id LIMIT $limit OFFSET $offset`).all({ $id: req.query.trackId, $limit: req.query.amount, $offset: req.query.skip })
|
||||
console.log(leaderboard);
|
||||
let returnValue = {"total": leaderboard.length, "entries":[]}
|
||||
for(let i = 0; i<leaderboard.length;i++) {
|
||||
returnValue["entries"][i] = {};
|
||||
returnValue["entries"][i]["id"] = leaderboard[i]["id"];
|
||||
returnValue["entries"][i]["name"] = decodeURIComponent(leaderboard[i]["username"]);
|
||||
returnValue["entries"][i]["carColors"] = leaderboard[i]["colors"];
|
||||
returnValue["entries"][i]["frames"] = leaderboard[i]["frames"];
|
||||
returnValue["entries"][i]["verifiedState"] = true;
|
||||
returnValue["entries"][i]["isSelf"] = false;
|
||||
}
|
||||
res.send(returnValue);
|
||||
}
|
||||
} else if(path == "recording") {
|
||||
let recordingQuery = polytrack.query(`SELECT * FROM polytrack WHERE id = $id`).get({ $id: req.query.recordingId });
|
||||
res.send({
|
||||
"recording": recordingQuery.recording,
|
||||
"frames": recordingQuery.frames,
|
||||
"verifiedState": true,
|
||||
"carColors": recordingQuery.colors
|
||||
});
|
||||
}
|
||||
})
|
||||
app.use("/api/account/load", async (req, res, next) => {
|
||||
if (req.cookies.token && (await verifyCookie(req.cookies.token))) {
|
||||
let status = await retrieveData(req.cookies.token);
|
||||
@ -358,6 +253,9 @@ app.use("/data/:id/:file", async (req, res) => {
|
||||
if (mime.lookup(filePath) == "image/webp") {
|
||||
res.type("image/webp");
|
||||
res.status(200).send(image);
|
||||
} else if (mime.lookup(filePath) == "audio/ogg") {
|
||||
res.type("audio/ogg");
|
||||
res.status(200).send(image);
|
||||
} else {
|
||||
res.status(404).send("File not found");
|
||||
}
|
||||
@ -440,10 +338,6 @@ app.post("/api/admin/ban", async (req, res) => {
|
||||
app.use("/api/music/search", async (req, res, next) => {
|
||||
res.status(200).send(await search(req.query.q))
|
||||
});
|
||||
app.use("/api/music/download", async (req, res, next) => {
|
||||
await download(req.query.url, res);
|
||||
});
|
||||
|
||||
const server = app.listen(port, () => {
|
||||
console.log(log.success("Express is online."));
|
||||
console.log("- " + log.info("http://localhost:" + port));
|
||||
|
Reference in New Issue
Block a user