summaryrefslogtreecommitdiff
path: root/includes
diff options
context:
space:
mode:
Diffstat (limited to 'includes')
-rw-r--r--includes/external/jobs/index.js26
-rw-r--r--includes/external/matrix/index.js40
-rw-r--r--includes/fragments/metadata.inc228
-rw-r--r--includes/util/functions.inc6
4 files changed, 260 insertions, 40 deletions
diff --git a/includes/external/jobs/index.js b/includes/external/jobs/index.js
index 39b7de5..0f44cc9 100644
--- a/includes/external/jobs/index.js
+++ b/includes/external/jobs/index.js
@@ -1,13 +1,21 @@
const fs = require('fs');
const child_process = require('child_process');
-let jobs = require('../../data/jobs.json');
+let jobsList = [];
+let jobs = [];
let history = require('../../data/history.json');
+fs.writeFileSync("../../data/running.json", "null");
+
setInterval(() => {
- if (JSON.stringify(JSON.parse(fs.readFileSync("../../data/jobs.json").toString())) !== JSON.stringify(jobs)) {
+ if (JSON.stringify(fs.readdirSync("../../data/jobs")) !== JSON.stringify(jobsList)) {
console.log("Updating the jobs list...");
- jobs = JSON.parse(fs.readFileSync("../../data/jobs.json").toString());
+ jobs = fs.readdirSync("../../data/jobs").map((i) => {
+ let obj = JSON.parse(fs.readFileSync("../../data/jobs/" + i).toString());
+ obj["_id"] = i;
+ return obj;
+ });
+ jobsList = fs.readdirSync("../../data/jobs");
}
}, 1000);
@@ -20,11 +28,13 @@ setTimeout(() => {
console.log("\nRunning jobs:");
for (let job of jobs) {
- console.log(" " + job.name);
+ console.log(" " + job.name + " [" + job._id + "]");
let output;
let start;
let end;
+ fs.writeFileSync("../../data/running.json", JSON.stringify(job._id));
+
try {
start = new Date();
output = child_process.execFileSync("php", [job.name + ".php", JSON.stringify(job.options)], { cwd: "../../jobs" });
@@ -37,8 +47,7 @@ setTimeout(() => {
description = "," + name + "=" + JSON.stringify(job.options[name]);
}
- jobs.splice(jobs.indexOf(job), 1);
- fs.writeFileSync("../../data/jobs.json", JSON.stringify(jobs));
+ fs.unlinkSync("../../data/jobs/" + job._id);
history.unshift({
completed: true,
@@ -58,6 +67,7 @@ setTimeout(() => {
history = history.slice(0, 200);
fs.writeFileSync("../../data/history.json", JSON.stringify(history));
+ fs.writeFileSync("../../data/running.json", "null");
} catch (e) {
end = start ? new Date() : null;
console.log(" Failed to process job");
@@ -70,8 +80,7 @@ setTimeout(() => {
description = "," + name + "=" + JSON.stringify(job.options[name]);
}
- jobs.splice(jobs.indexOf(job), 1);
- fs.writeFileSync("../../data/jobs.json", JSON.stringify(jobs));
+ fs.unlinkSync("../../data/jobs/" + job._id);
history.unshift({
completed: false,
@@ -91,6 +100,7 @@ setTimeout(() => {
history = history.slice(0, 200);
fs.writeFileSync("../../data/history.json", JSON.stringify(history));
+ fs.writeFileSync("../../data/running.json", "null");
}
}
diff --git a/includes/external/matrix/index.js b/includes/external/matrix/index.js
index 5149005..1bfb8d4 100644
--- a/includes/external/matrix/index.js
+++ b/includes/external/matrix/index.js
@@ -1,5 +1,6 @@
const user = process.argv[2];
const info = require('../../app.json')['matrix'][user];
+const fs = require('fs');
if (typeof info !== "object") throw new Error("Unable to find info");
@@ -7,6 +8,7 @@ const token = info.token;
const sdk = require("matrix-js-sdk");
const axios = require("axios");
+const child_process = require("child_process");
const client = sdk.createClient({
baseUrl: "https://chat.equestria.dev",
accessToken: token,
@@ -24,13 +26,16 @@ client.once("sync", async function (state, prevState, res) {
console.log(fronters.members.length + " member(s) at front");
let name = system.name;
- let avatar = system.avatar_url;
+ let avatar1 = system.avatar_url;
+ let avatar2 = null;
- if (fronters.members.length === 1) {
+ if (fronters.members.length === 1 || (fronters.members.length === 2 && (fronters.members[0].name === "scootaloo" && fronters.members[1].name === "rainbowdash"))) {
name = fronters.members[0].display_name ?? fronters.members[0].name;
- avatar = fronters.members[0].avatar_url ?? avatar;
- } else if (fronters.members.length >= 2) {
+ avatar1 = fronters.members[0].avatar_url ?? avatar1;
+ } else if (fronters.members.length >= 2 && !(fronters.members[0].name === "scootaloo" && fronters.members[1].name === "rainbowdash")) {
name = (fronters.members[0].display_name ?? fronters.members[0].name) + " and " + (fronters.members[1].display_name ?? fronters.members[1].name);
+ avatar1 = fronters.members[0].avatar_url ?? avatar1;
+ avatar2 = fronters.members[1].avatar_url ?? avatar2;
}
await client.setDeviceDetails(info.device, {
@@ -52,7 +57,32 @@ client.once("sync", async function (state, prevState, res) {
});
console.log("Uploading avatar");
- let res = await client.uploadContent((await axios.get(avatar, {responseType: "arraybuffer"})).data);
+ let pfp;
+
+ if (avatar2) {
+ let img1 = (await axios.get(avatar1, {responseType: "arraybuffer"})).data;
+ let img2 = (await axios.get(avatar2, {responseType: "arraybuffer"})).data;
+
+ fs.writeFileSync("/tmp/chm-" + user + "-1", img1);
+ fs.writeFileSync("/tmp/chm-" + user + "-2", img2);
+
+ child_process.execSync("convert /tmp/chm-" + user + "-1 -gravity center -crop 50%x100% /tmp/chm-" + user + "-1.webp");
+ child_process.execSync("convert /tmp/chm-" + user + "-2 -gravity center -crop 50%x100% /tmp/chm-" + user + "-2.webp");
+ child_process.execSync("montage -mode concatenate -tile x1 /tmp/chm-" + user + "-1.webp /tmp/chm-" + user + "-2.webp /tmp/chm-" + user + ".webp");
+
+ pfp = fs.readFileSync("/tmp/chm-" + user + ".webp");
+
+ fs.unlinkSync("/tmp/chm-" + user + "-1");
+ fs.unlinkSync("/tmp/chm-" + user + "-2");
+ fs.unlinkSync("/tmp/chm-" + user + "-1.webp");
+ fs.unlinkSync("/tmp/chm-" + user + "-2.webp");
+ fs.unlinkSync("/tmp/chm-" + user + ".webp");
+ } else {
+ pfp = (await axios.get(avatar1, {responseType: "arraybuffer"})).data;
+ }
+
+ let res = await client.uploadContent(pfp);
+
await axios.put("https://chat.equestria.dev/_matrix/client/r0/profile/%40" + user + "%3Aequestria.dev/avatar_url", {
avatar_url: res.content_uri
}, {
diff --git a/includes/fragments/metadata.inc b/includes/fragments/metadata.inc
index 0d2187c..719abbc 100644
--- a/includes/fragments/metadata.inc
+++ b/includes/fragments/metadata.inc
@@ -6,9 +6,51 @@ if (file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/metadata/" . $member
?>
+<style>
+ .modal-header {
+ border-bottom: 1px solid #353738;
+ }
+
+ .modal-content {
+ border: 1px solid rgba(255, 255, 255, .2);
+ background-color: #111;
+ }
+
+ .btn-close {
+ filter: invert(1);
+ }
+
+ .list-group-item {
+ color: #fff;
+ background-color: #222;
+ border: 1px solid rgba(255, 255, 255, .125);
+ }
+
+ .list-group-item.disabled {
+ color: #fff;
+ background-color: #222;
+ border-color: rgba(255, 255, 255, .125);
+ opacity: .75;
+ }
+
+ .list-group-item:hover {
+ background-color: #252525;
+ color: #ddd;
+ }
+
+ .list-group-item:active, .list-group-item:focus {
+ background-color: #272727;
+ color: #bbb;
+ }
+
+ .member-link, .list-group-item-action {
+ cursor: pointer !important;
+ }
+</style>
+
<br>
-<div class="container" id="page-content">
- <h2><a href="/<?= $memberData["name"] ?>"><?= $memberData["display_name"] ?? $memberData["name"] ?></a></h2>
+<div class="container">
+ <h2 id="page-content"><a href="/<?= $memberData["name"] ?>"><?= $memberData["display_name"] ?? $memberData["name"] ?></a></h2>
<?php if (file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/metadata/" . $memberID . ".json")): ?>
<form>
<input name="submit" type="hidden">
@@ -94,28 +136,166 @@ if (file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/metadata/" . $member
<h3>Relationships</h3>
- <?php if ($systemID !== $app["other"]["id"]): ?>
- <p>
- <b>Sexfriends (full IDs, comma-separated)</b><br>
- <input name="sexfriends" class="form-control" style="filter: invert(1) hue-rotate(180deg);" type="text" value="<?= implode(", ", $metadata["sexfriends"]) ?>">
- </p>
- <?php endif; ?>
- <p>
- <b>Marefriends (full IDs, comma-separated)</b><br>
- <input name="marefriends" class="form-control" style="filter: invert(1) hue-rotate(180deg);" type="text" value="<?= implode(", ", $metadata["marefriends"]) ?>">
- </p>
- <p>
- <b>Sisters (full IDs, comma-separated)</b><br>
- <input name="sisters" class="form-control" style="filter: invert(1) hue-rotate(180deg);" type="text" value="<?= implode(", ", $metadata["sisters"]) ?>">
- </p>
- <p>
- <b>Caretakers (full IDs, comma-separated)</b><br>
- <input name="caretakers" class="form-control" style="filter: invert(1) hue-rotate(180deg);" type="text" value="<?= implode(", ", $metadata["caretakers"]) ?>">
- </p>
- <p>
- <b>Friends (full IDs, comma-separated)</b><br>
- <input name="friends" class="form-control" style="filter: invert(1) hue-rotate(180deg);" type="text" value="<?= implode(", ", $metadata["friends"] ?? []) ?>">
- </p>
+ <div class="modal" id="new-relation" data-bs-backdrop="static" data-bs-keyboard="false">
+ <div class="modal-dialog">
+ <div class="modal-content">
+
+ <div class="modal-header">
+ <h4 class="modal-title">Add a new <span id="new-relation-type">-</span> for <?= $memberData["display_name"] ?? $memberData["name"] ?></h4>
+ <button id="new-fronter-close" type="button" class="btn-close" data-bs-dismiss="modal"></button>
+ </div>
+
+ <div class="modal-body">
+ <input type="text" placeholder="Search for a pony..." class="form-control" style="margin-bottom:15px;color:white;background:#111;border-color:#222;" id="search">
+
+ <div id="list">
+ <div class="list-group">
+ <?php foreach (scoreOrderGlobal() as $member): ?>
+ <a id="list-pony-<?= $member['id'] ?>" onclick="confirmAdd('<?= $member['system'] ?>/<?= $member['id'] ?>');" class="new-fronter-link list-group-item list-group-item-action"><img src="<?= getAsset($member["system"], $member["id"], "heads") ?>" style="width:24px;"> <?= $member["display_name"] ?? $member["name"] ?></a>
+ <?php endforeach; ?>
+ </div>
+ </div>
+
+ <div id="search-results" class="list-group"></div>
+ </div>
+
+ </div>
+ </div>
+ </div>
+
+ <script src="/assets/editor/fuse.js"></script>
+ <script>
+ window.modal = new bootstrap.Modal(document.getElementById("new-relation"));
+ window.currentSelectedValue = null;
+
+ function openAddDialog(value, text) {
+ modal.show();
+ window.currentSelectedValue = value;
+ document.getElementById("new-relation-type").innerText = text;
+ document.getElementById("search").value = ""; search({});
+ document.getElementById("search").focus();
+ }
+
+ window.poniesList = JSON.parse(atob(`<?= base64_encode(json_encode(array_values(scoreOrderGlobal()))) ?>`));
+ window.avatars = JSON.parse(atob(`<?php
+
+ $avatars = [];
+
+ foreach (scoreOrderGlobal() as $pony) {
+ $avatars[$pony["system"] . "/" . $pony["id"]] = getAsset($pony["system"], $pony["id"]);
+ }
+
+ echo(base64_encode(json_encode($avatars))); ?>`))
+
+ const fuse = new Fuse(window.poniesList, {
+ includeScore: true,
+ keys: [
+ {
+ name: 'name',
+ weight: 1
+ },
+ {
+ name: 'display_name',
+ weight: 1
+ },
+ {
+ name: 'id',
+ weight: 0.7
+ },
+ {
+ name: 'species',
+ weight: 0.5
+ }
+ ]
+ })
+
+ function search(event) {
+ if (event.key === "Enter") {
+ return;
+ }
+
+ let query = document.getElementById("search").value;
+ let results = fuse.search(query).map((i) => {
+ return {
+ id: i.item.id,
+ score: i.score
+ };
+ });
+
+ let unfiltered = results;
+
+ results = results.filter((i) => {
+ return i.score < 0.7;
+ });
+
+ console.log("Before:", unfiltered, "After:", results);
+
+ document.getElementById("list").style.display = "none";
+ document.getElementById("search-results").style.display = "block";
+ document.getElementById("search-results").innerHTML = "";
+
+ for (let result of results) {
+ if (document.getElementById("list-pony-" + result.id)) document.getElementById("search-results").innerHTML += document.getElementById("list-pony-" + result.id).outerHTML;
+ }
+
+ console.log(results);
+
+ if (query.trim() === "") {
+ document.getElementById("list").style.display = "block";
+ document.getElementById("search-results").style.display = "none";
+ }
+ }
+
+ document.getElementById("search").onchange = document.getElementById("search").onkeyup = document.getElementById("search").onkeydown = search;
+
+ document.getElementById("search").addEventListener("keydown", (event) => {
+ if (event.key === "Enter") {
+ document.querySelector("#search-results .new-fronter-link").click();
+ event.preventDefault();
+ }
+ });
+
+ function update(type) {
+ document.getElementById(type + "-list").innerHTML = document.getElementsByName(type)[0].value.split(",").map(i => i.trim()).filter(i => i && i.trim() !== "").map(i => `
+ <a style="margin-top: 4px;" class="btn btn-dark" onclick="deleteRelation('${type}', '${i}');">
+ <img src="${window.avatars[i]}" style="width: 24px; vertical-align: middle; border-radius: 999px;">
+ <span style="vertical-align: middle; margin-left: 5px;">${window.poniesList.filter(j => j.id === i.split("/")[1])[0]['display_name'] ?? window.poniesList.filter(j => j.id === i.split("/")[1])[0]['name']}</span>
+ </a>
+ `).join("");
+ }
+
+ function confirmAdd(item) {
+ document.getElementsByName(window.currentSelectedValue)[0].value += ", " + item;
+ update(window.currentSelectedValue);
+ window.currentSelectedValue = null;
+ modal.hide();
+ }
+
+ function deleteRelation(type, relation) {
+ let relations = document.getElementsByName(type)[0].value.split(",").map(i => i.trim()).filter(i => i && i !== "");
+ relations = relations.filter(i => i !== relation);
+ document.getElementsByName(type)[0].value = relations.join(", ");
+ update(type);
+ }
+ </script>
+
+ <?php foreach ([
+ $systemID !== $app["other"]["id"] ? [ "sexfriends", "Sexfriends" ] : null,
+ [ "marefriends", "Marefriends", "marefriend" ],
+ [ "sisters", "Sisters", "sister" ],
+ [ "caretakers", "Caretakers", "caretaker" ],
+ [ "friends", "Friends", "friend" ],
+ ] as $relations): if (isset($relations)): ?>
+ <p>
+ <b><?= $relations[1] ?></b><br>
+ <input name="<?= $relations[0] ?>" type="hidden" value="<?= implode(", ", $metadata[$relations[0]] ?? []) ?>">
+ <span id="<?= $relations[0] ?>-list"></span>
+ <a style="margin-top: 4px;" class="btn btn-secondary" onclick="openAddDialog('<?= $relations[0] ?>', '<?= $relations[2] ?>')">+</a>
+ <script>
+ update('<?= $relations[0] ?>');
+ </script>
+ </p>
+ <?php endif; endforeach; ?>
<hr>
diff --git a/includes/util/functions.inc b/includes/util/functions.inc
index 79a47c6..fe97980 100644
--- a/includes/util/functions.inc
+++ b/includes/util/functions.inc
@@ -3,17 +3,17 @@
require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/util/score.inc";
require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/util/bitset.inc";
require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/util/homepage.inc";
+require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/util/random.inc";
if (!function_exists("createJob")) {
function createJob($title, $options) {
- $jobs = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/jobs.json"), true);
- $jobs[] = [
+ $job = [
"name" => $title,
"options" => $options,
"date" => date('c')
];
- file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/jobs.json", json_encode($jobs));
+ file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/jobs/" . round(microtime(true) * 1000) . "-" . random() . ".json", json_encode($job));
}
}