f0ckv2/src/inc/lib.mjs
Flummi 63bd1104b7
All checks were successful
fetch npm modules / f0ck the f0cker (push) Successful in 37s
missing ids
2023-05-03 04:25:18 +02:00

223 lines
6.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import crypto from "crypto";
import util from "util";
import db from "./sql.mjs";
import { exec as _exec } from "child_process";
const exec = util.promisify(_exec);
const scrypt = util.promisify(crypto.scrypt);
const epochs = [
["year", 31536000],
["month", 2592000],
["day", 86400],
["hour", 3600],
["minute", 60],
["second", 1]
];
const getDuration = timeAgoInSeconds => {
for(let [name, seconds] of epochs) {
const interval = ~~(timeAgoInSeconds / seconds);
if(interval >= 1) return {
interval: interval,
epoch: name
};
}
};
export default new class {
formatSize(size, i = ~~(Math.log(size) / Math.log(1024))) {
return (size / Math.pow(1024, i)).toFixed(2) * 1 + " " + ["B", "kB", "MB", "GB", "TB"][i];
};
calcSpeed(b, s) {
return (Math.round((b * 8 / s / 1e6) * 1e4) / 1e4);
};
timeAgo(date) {
const { interval, epoch } = getDuration(~~((new Date() - new Date(date)) / 1e3));
return `${interval} ${epoch}${interval === 1 ? "" : "s"} ago`;
};
md5(str) {
return crypto.createHash('md5').update(str).digest("hex");
};
getMode(mode) {
let tmp;
switch(mode) {
case 1: // nsfw
tmp = "items.id in (select item_id from tags_assign where tag_id = 2 group by item_id)";
break;
case 2: // untagged
tmp = "items.id not in (select item_id from tags_assign group by item_id)";
break;
case 3: // all
tmp = "1 = 1";
break;
default: // sfw
tmp = "items.id in (select item_id from tags_assign where tag_id = 1 group by item_id)";
break;
}
return tmp;
};
createID() {
return crypto.randomBytes(16).toString("hex") + Date.now().toString(24);
};
genLink(env) {
const link = [];
if(env.tag) link.push("tag", env.tag);
if(env.user) link.push("user", env.user, env.type ?? 'f0cks');
if(env.mime?.length > 2) link.push(env.mime);
let tmp = link.length === 0 ? '/' : link.join('/');
if(!tmp.endsWith('/'))
tmp = tmp + '/';
if(!tmp.startsWith('/'))
tmp = '/' + tmp;
return {
main: tmp,
path: env.path ? env.path : ''
};
};
parseTag(tag) {
if(!tag)
return null;
return decodeURI(tag);
}
// async funcs
async countf0cks() {
const tagged = +(await db`
select count(*) as total
from "items"
where id in (select item_id from tags_assign group by item_id) and active = true
`)[0].total;
const untagged = +(await db`
select count(*) as total
from "items"
where id not in (select item_id from tags_assign group by item_id) and active = true
`)[0].total;
const sfw = +(await db`
select count(*) as total
from "items"
where id in (select item_id from tags_assign where tag_id = 1 group by item_id) and active = true
`)[0].total;
const nsfw = +(await db`
select count(*) as total
from "items"
where id in (select item_id from tags_assign where tag_id = 2 group by item_id) and active = true
`)[0].total;
const deleted = +(await db`
select count(*) as total
from "items"
where active = false
`)[0].total;
const lastf0ck = +(await db`
select max(id) as id
from "items"
`)[0].id;
return {
tagged,
untagged,
total: tagged + untagged,
deleted,
untracked: lastf0ck - (tagged + untagged + deleted),
sfw,
nsfw,
};
};
async hash(str) {
const salt = crypto.randomBytes(16).toString("hex");
const derivedKey = await scrypt(str, salt, 64);
return "$f0ck$" + salt + ":" + derivedKey.toString("hex");
};
async verify(str, hash) {
const [ salt, key ] = hash.substring(6).split(":");
const keyBuffer = Buffer.from(key, "hex");
const derivedKey = await scrypt(str, salt, 64);
return crypto.timingSafeEqual(keyBuffer, derivedKey);
};
async auth(req, res, next) {
if(!req.session) {
return res.reply({
code: 401,
body: "401 - Unauthorized"
});
}
return next();
};
async getTags(itemid) {
const tags = await db`
select "tags".id, "tags".tag, "tags".normalized, "user".user
from "tags_assign"
left join "tags" on "tags".id = "tags_assign".tag_id
left join "user" on "user".id = "tags_assign".user_id
where "tags_assign".item_id = ${+itemid}
order by "tags".id asc
`;
for(let t = 0; t < tags.length; t++) {
if(tags[t].tag.startsWith(">"))
tags[t].badge = "badge-greentext badge-light";
else if(tags[t].normalized === "ukraine")
tags[t].badge = "badge-ukraine badge-light";
else if(/[а-яё]/.test(tags[t].normalized) || tags[t].normalized === "russia")
tags[t].badge = "badge-russia badge-light";
else if(tags[t].normalized === "german")
tags[t].badge = "badge-german badge-light";
else if(tags[t].normalized === "dutch")
tags[t].badge = "badge-dutch badge-light";
else if(tags[t].normalized === "sfw")
tags[t].badge = "badge-success";
else if(tags[t].normalized === "nsfw")
tags[t].badge = "badge-danger";
else
tags[t].badge = "badge-light";
}
return tags;
};
async hasTag(itemid, tagid) {
const tag = (await db`
select *
from "tags_assign"
where
item_id = ${+itemid} and
tag_id = ${+tagid}
limit 1
`).length;
return !!tag;
};
async detectNSFW(dest) {
return false;
const { stdout, stderr } = await exec(
`python -c "import sys\nfrom nsfw_detector import predict\nmodel = predict.load_model('./nsfw_model.h5')\nprint(predict.classify(model, './public/b/${dest}'))"`
);
const res = JSON.parse(stdout.replace(/\'/g, '"').split('\n').slice(1, -1));
const tmp = Object.values(res)[0];
let nsfw = false;
if(tmp.neutral >= .7)
nsfw = false;
else if((tmp.sexy + tmp.porn + tmp.hentai) >= .7)
nsfw = true;
else if(tmp.drawings >= .4)
nsfw = false;
else
nsfw = false;
return {
isNSFW: nsfw,
score: tmp.sexy + tmp.porn + tmp.hentai,
scores: tmp
};
};
async getDefaultAvatar() {
return (await db`
select column_default as avatar
from "information_schema"."columns"
where
TABLE_SCHEMA='public' and
TABLE_NAME='user_options' and
COLUMN_NAME = 'avatar'
`)[0].avatar;
}
};