1
0
forked from w0bm/f0bm

Compare commits

1 Commits

Author SHA1 Message Date
4a2925b141 revert a4f9c48e13
revert various fixes to get it working for myself
2026-01-23 13:24:43 +00:00
9 changed files with 164 additions and 207 deletions

View File

@@ -1,15 +0,0 @@
import db from "../src/inc/sql.mjs";
(async () => {
try {
const item = (await db`select * from items order by id desc limit 1`)?.[0];
console.log("Last Item:", item);
if (item) {
const tags = await db`select * from tags_assign where item_id = ${item.id}`;
console.log("Tags:", tags);
}
} catch (err) {
console.error(err);
}
process.exit(0);
})();

View File

@@ -6,14 +6,13 @@ import { promises as fs } from "fs";
network: "console", network: "console",
message: _args.join(" "), message: _args.join(" "),
args: _args.slice(1), args: _args.slice(1),
channel: "#w0bm", channel: "console",
user: { user: {
prefix: "console!console@console", prefix: "console!console@console",
nick: "console", nick: "console",
username: "console", username: "console",
account: "console" account: "console"
}, },
raw: {},
reply: (...args) => console.log(args), reply: (...args) => console.log(args),
replyAction: (...args) => console.log(args), replyAction: (...args) => console.log(args),
replyNotice: (...args) => console.log(args) replyNotice: (...args) => console.log(args)
@@ -25,14 +24,11 @@ import { promises as fs } from "fs";
)).filter(t => t[0].call.test(_e.message)).map(t => ({ name: t[0].name, f: t[0].f })); )).filter(t => t[0].call.test(_e.message)).map(t => ({ name: t[0].name, f: t[0].f }));
try { try {
if (trigger.length === 0) if(trigger.length === 0)
return console.error("no matches"); return console.error("no matches");
for (const t of trigger) { console.log(`triggered > ${trigger[0].name} (${_e.message})`);
console.log(`triggered > ${t.name} (${_e.message})`); await trigger[0].f(_e);
await t.f(_e); } catch(err) {
}
} catch (err) {
console.error(err); console.error(err);
} }
process.exit(0);
})(); })();

View File

@@ -1,3 +0,0 @@
#!/bin/bash
npm i
npm start

View File

@@ -130,12 +130,12 @@
return false; return false;
} }
renderTags(res.tags); renderTags(res.tags);
if (span.parentElement) span.parentElement.removeChild(span); span.parentElement.removeChild(span);
testList.innerText = ""; testList.innerText = "";
addtagClick(); addtagClick();
} }
else if (e.key === "Escape") { else if (e.key === "Escape") {
if (span.parentElement) span.parentElement.removeChild(span); span.parentElement.removeChild(span);
testList.innerText = ""; testList.innerText = "";
} }
else { else {

View File

@@ -208,10 +208,10 @@ window.requestAnimFrame = (function () {
return; return;
} }
const link = e.target.closest('#next, #prev, #random, #nav-random, .id-link, .nav-next, .nav-prev'); const link = e.target.closest('#next, #prev, #random, .id-link, .nav-next, .nav-prev');
if (link && link.href && link.hostname === window.location.hostname && !e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey) { if (link && link.href && link.hostname === window.location.hostname && !e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey) {
// Special check for random // Special check for random
if (link.id === 'random' || link.id === 'nav-random') { if (link.id === 'random') {
e.preventDefault(); e.preventDefault();
const nav = document.querySelector("nav.navbar"); const nav = document.querySelector("nav.navbar");
if (nav) nav.classList.add("pbwork"); if (nav) nav.classList.add("pbwork");
@@ -240,10 +240,7 @@ window.requestAnimFrame = (function () {
window.location.href = link.href; window.location.href = link.href;
} }
}) })
.catch((err) => { .catch(() => window.location.href = link.href);
console.error("Random fetch failed:", err);
window.location.href = link.href;
});
return; return;
} }
@@ -264,7 +261,7 @@ window.requestAnimFrame = (function () {
"a": clickOnElementBinding("#next"), "a": clickOnElementBinding("#next"),
"ArrowRight": clickOnElementBinding("#prev"), "ArrowRight": clickOnElementBinding("#prev"),
"d": clickOnElementBinding("#prev"), "d": clickOnElementBinding("#prev"),
"r": clickOnElementBinding("#random, #nav-random"), "r": clickOnElementBinding("#random"),
" ": clickOnElementBinding("#f0ck-image") " ": clickOnElementBinding("#f0ck-image")
}; };
document.addEventListener("keydown", e => { document.addEventListener("keydown", e => {
@@ -544,13 +541,10 @@ function init() {
window.addEventListener('load', init); window.addEventListener('load', init);
const sbtForm = document.getElementById('sbtForm'); document.getElementById('sbtForm').addEventListener('submit', (e) => {
if (sbtForm) { e.preventDefault();
sbtForm.addEventListener('submit', (e) => { const input = document.getElementById('sbtInput').value.trim();
e.preventDefault(); if (input) {
const input = document.getElementById('sbtInput').value.trim(); window.location.href = `/tag/${encodeURIComponent(input)}`;
if (input) { }
window.location.href = `/tag/${encodeURIComponent(input)}`; });
}
});
}

View File

@@ -1,10 +1,10 @@
const Cookie = { const Cookie = {
get: name => { get: name => {
const c = document.cookie.match(`(?:(?:^|.*; *)${name} *= *([^;]*).*$)|^.*$`)[1]; const c = document.cookie.match(`(?:(?:^|.*; *)${name} *= *([^;]*).*$)|^.*$`)[1];
if (c) return decodeURIComponent(c); if(c) return decodeURIComponent(c);
}, },
set: (name, value, opts = {}) => { set: (name, value, opts = {}) => {
if (opts.days) { if(opts.days) {
opts['max-age'] = opts.days * 60 * 60 * 24; opts['max-age'] = opts.days * 60 * 60 * 24;
delete opts.days; delete opts.days;
} }
@@ -17,11 +17,8 @@ const Cookie = {
(() => { (() => {
const acttheme = Cookie.get('theme') ?? "w0bm"; const acttheme = Cookie.get('theme') ?? "w0bm";
const themecontainer = document.querySelector("li#themes > ul.dropdown-menu"); const themecontainer = document.querySelector("li#themes > ul.dropdown-menu");
if (!themecontainer) return; // Theme menu not present on this page
const themes = [...themecontainer.querySelectorAll("li > a")].map(t => t.innerText.toLowerCase()); const themes = [...themecontainer.querySelectorAll("li > a")].map(t => t.innerText.toLowerCase());
if (acttheme !== document.documentElement.getAttribute("theme") && themes.includes(acttheme)) if(acttheme !== document.documentElement.getAttribute("theme") && themes.includes(acttheme))
document.documentElement.setAttribute("theme", acttheme); document.documentElement.setAttribute("theme", acttheme);
[...themecontainer.querySelectorAll("li > a")].forEach(t => t.addEventListener("click", e => { [...themecontainer.querySelectorAll("li > a")].forEach(t => t.addEventListener("click", e => {
e.preventDefault(); e.preventDefault();
@@ -33,15 +30,15 @@ const Cookie = {
})); }));
document.addEventListener("keydown", e => { document.addEventListener("keydown", e => {
if (e.target.tagName === "INPUT" || e.target.tagName === "TEXTAREA") if(e.target.tagName === "INPUT" || e.target.tagName === "TEXTAREA")
return; return;
const acttheme = Cookie.get('theme') ?? "w0bm"; const acttheme = Cookie.get('theme') ?? "w0bm";
const themes = [...themecontainer.querySelectorAll("li > a")].map(t => t.innerText.toLowerCase()); const themes = [...themecontainer.querySelectorAll("li > a")].map(t => t.innerText.toLowerCase());
const k = e.key; const k = e.key;
if (k === "t") { if(k === "t") {
e.preventDefault(); e.preventDefault();
let i = themes.indexOf(acttheme); let i = themes.indexOf(acttheme);
if (++i >= themes.length) if(++i >= themes.length)
i = 0; i = 0;
document.documentElement.setAttribute("theme", themes[i]); document.documentElement.setAttribute("theme", themes[i]);
document.querySelector("#themes > a").setAttribute("content", themes[i]); document.querySelector("#themes > a").setAttribute("content", themes[i]);
@@ -49,10 +46,10 @@ const Cookie = {
} }
}); });
if (tbuttonfull = document.querySelector('svg#a_tfull')) { if(tbuttonfull = document.querySelector('svg#a_tfull')) {
tbuttonfull.addEventListener('click', e => { tbuttonfull.addEventListener('click', e => {
let f = Cookie.get('fullscreen'); let f = Cookie.get('fullscreen');
if (f == 1) { if(f == 1) {
Cookie.set('fullscreen', 0); Cookie.set('fullscreen', 0);
document.querySelector('html').setAttribute('res', ''); document.querySelector('html').setAttribute('res', '');
tbuttonfull.innerHTML = `<use href="/s/img/iconset.svg#window-maximize"></use>`; tbuttonfull.innerHTML = `<use href="/s/img/iconset.svg#window-maximize"></use>`;

View File

@@ -3,7 +3,7 @@ import db from '../../sql.mjs';
import lib from '../../lib.mjs'; import lib from '../../lib.mjs';
import search from '../../routeinc/search.mjs'; import search from '../../routeinc/search.mjs';
const allowedMimes = ["audio", "image", "video", "%"]; const allowedMimes = [ "audio", "image", "video", "%" ];
export default router => { export default router => {
router.group(/^\/api\/v2/, group => { router.group(/^\/api\/v2/, group => {
group.get(/$/, (req, res) => { group.get(/$/, (req, res) => {
@@ -13,28 +13,24 @@ export default router => {
group.get(/\/random(\/user\/.+|\/image|\/video|\/audio)?$/, async (req, res) => { group.get(/\/random(\/user\/.+|\/image|\/video|\/audio)?$/, async (req, res) => {
const user = req.url.split[3] === "user" ? req.url.split[4] : "%"; const user = req.url.split[3] === "user" ? req.url.split[4] : "%";
const mime = (allowedMimes.filter(n => req.url.split[3]?.startsWith(n))[0] ? req.url.split[3] : "") + "%"; const mime = (allowedMimes.filter(n => req.url.split[3]?.startsWith(n))[0] ? req.url.split[3] : "") + "%";
const tag = req.url.qs.tag || null;
const rows = await db` const rows = await db`
select "items".* select *
from "items" from "items"
left join tags_assign on tags_assign.item_id = items.id
left join tags on tags.id = tags_assign.tag_id
where where
mime ilike ${mime} and mime ilike ${mime} and
username ilike ${user} and username ilike ${user} and
active = 'true' active = 'true'
${tag ? db`and tags.normalized ilike ${'%' + tag + '%'}` : db``}
order by random() order by random()
limit 1 limit 1
`; `;
return res.json({ return res.json({
success: rows.length > 0, success: rows.length > 0,
items: rows.length > 0 ? rows[0] : [] items: rows.length > 0 ? rows[0] : []
}); });
}); });
group.get(/\/items\/get/, async (req, res) => { group.get(/\/items\/get/, async (req, res) => {
let eps = 150; let eps = 150;
@@ -55,15 +51,17 @@ export default router => {
where where
${db.unsafe(modequery)} and ${db.unsafe(modequery)} and
active = 'true' active = 'true'
${opt.older ${
? db`and id <= ${opt.older}` opt.older
: opt.newer ? db`and id <= ${opt.older}`
? db`and id >= ${opt.newer}` : opt.newer
: db`` ? db`and id >= ${opt.newer}`
} : db``
order by id ${opt.newer }
? db`asc` order by id ${
: db`desc` opt.newer
? db`asc`
: db`desc`
} }
limit ${eps} limit ${eps}
`).sort((a, b) => b.id - a.id); `).sort((a, b) => b.id - a.id);
@@ -75,10 +73,10 @@ export default router => {
items: rows items: rows
}, 200); }, 200);
}); });
group.get(/\/item\/[0-9]+$/, async (req, res) => { group.get(/\/item\/[0-9]+$/, async (req, res) => {
const id = +req.url.split[3]; const id = +req.url.split[3];
const item = await db` const item = await db`
select * select *
from "items" from "items"
@@ -99,14 +97,14 @@ export default router => {
order by id desc order by id desc
limit 1 limit 1
`; `;
if (item.length === 0) { if(item.length === 0) {
return res.json({ return res.json({
success: false, success: false,
msg: 'no items found' msg: 'no items found'
}); });
} }
const rows = { const rows = {
...item[0], ...item[0],
...{ ...{
@@ -120,11 +118,11 @@ export default router => {
rows rows
}); });
}); });
group.get(/\/user\/.*(\/\d+)?$/, async (req, res) => { group.get(/\/user\/.*(\/\d+)?$/, async (req, res) => {
const user = req.url.split[3]; const user = req.url.split[3];
const eps = +req.url.split[4] || 50; const eps = +req.url.split[4] || 50;
const rows = db` const rows = db`
select id, mime, size, src, stamp, userchannel, username, usernetwork select id, mime, size, src, stamp, userchannel, username, usernetwork
from "items" from "items"
@@ -132,7 +130,7 @@ export default router => {
order by stamp desc order by stamp desc
limit ${+eps} limit ${+eps}
`; `;
return res.json({ return res.json({
success: rows.length > 0, success: rows.length > 0,
items: rows.length > 0 ? rows : [] items: rows.length > 0 ? rows : []
@@ -142,7 +140,7 @@ export default router => {
// tags lol // tags lol
group.put(/\/admin\/tags\/(?<tagname>.*)/, lib.loggedin, async (req, res) => { group.put(/\/admin\/tags\/(?<tagname>.*)/, lib.loggedin, async (req, res) => {
if (!req.params.tagname || !req.post.newtag) { if(!req.params.tagname || !req.post.newtag) {
return res.json({ return res.json({
success: false, success: false,
msg: 'missing tagname or newtag', msg: 'missing tagname or newtag',
@@ -156,7 +154,7 @@ export default router => {
const tagname = decodeURIComponent(req.params.tagname); const tagname = decodeURIComponent(req.params.tagname);
const newtag = req.post.newtag; const newtag = req.post.newtag;
if (['sfw', 'nsfw'].includes(tagname) || ['sfw', 'nsfw'].includes(newtag)) { if(['sfw', 'nsfw'].includes(tagname) || ['sfw', 'nsfw'].includes(newtag)) {
return res.json({ return res.json({
msg: 'f0ck you' msg: 'f0ck you'
}, 405); // method not allowed }, 405); // method not allowed
@@ -168,8 +166,8 @@ export default router => {
where tag = ${tagname} where tag = ${tagname}
limit 1 limit 1
`)[0]; `)[0];
if (!tmptag) { if(!tmptag) {
return res.json({ return res.json({
success: false, success: false,
msg: 'no tag found' msg: 'no tag found'
@@ -177,9 +175,10 @@ export default router => {
} }
const q = (await db` const q = (await db`
update "tags" set ${db({ update "tags" set ${
tag: newtag db({
}, 'tag') tag: newtag
}, 'tag')
} }
where tag = ${tagname} where tag = ${tagname}
returning * returning *
@@ -196,7 +195,7 @@ export default router => {
const searchString = req.url.qs.q; const searchString = req.url.qs.q;
if (searchString?.length <= 1) { if(searchString?.length <= 1) {
reply.error = 'too short lol'; reply.error = 'too short lol';
return res.json(reply); return res.json(reply);
} }
@@ -213,7 +212,7 @@ export default router => {
`; `;
reply.success = true; reply.success = true;
reply.suggestions = search(q, searchString); reply.suggestions = search(q, searchString);
} catch (err) { } catch(err) {
reply.error = err.msg; reply.error = err.msg;
} }
@@ -221,7 +220,7 @@ export default router => {
}); });
group.post(/\/admin\/deletepost$/, lib.auth, async (req, res) => { group.post(/\/admin\/deletepost$/, lib.auth, async (req, res) => {
if (!req.post.postid) { if(!req.post.postid) {
return res.json({ return res.json({
success: false, success: false,
msg: 'no postid' msg: 'no postid'
@@ -229,7 +228,7 @@ export default router => {
} }
const id = +req.post.postid; const id = +req.post.postid;
if (id <= 1) { if(id <= 1) {
return res.json({ return res.json({
success: false success: false
}); });
@@ -244,7 +243,7 @@ export default router => {
limit 1 limit 1
`; `;
if (f0ck.length === 0) { if(f0ck.length === 0) {
return res.json({ return res.json({
success: false, success: false,
msg: `f0ck ${id}: f0ck not found` msg: `f0ck ${id}: f0ck not found`
@@ -252,15 +251,15 @@ export default router => {
} }
await db`update "items" set active = 'false' where id = ${id}`; await db`update "items" set active = 'false' where id = ${id}`;
await fs.copyFile(`./public/b/${f0ck[0].dest}`, `./deleted/b/${f0ck[0].dest}`).catch(_=>{});
await fs.copyFile(`./public/t/${id}.webp`, `./deleted/t/${id}.webp`).catch(_=>{});
await fs.unlink(`./public/b/${f0ck[0].dest}`).catch(_=>{});
await fs.unlink(`./public/t/${id}.webp`).catch(_=>{});
await fs.copyFile(`./public/b/${f0ck[0].dest}`, `./deleted/b/${f0ck[0].dest}`).catch(_ => { }); if(f0ck[0].mime.startsWith('audio')) {
await fs.copyFile(`./public/t/${id}.webp`, `./deleted/t/${id}.webp`).catch(_ => { }); await fs.copyFile(`./public/ca/${id}.webp`, `./deleted/ca/${id}.webp`).catch(_=>{});
await fs.unlink(`./public/b/${f0ck[0].dest}`).catch(_ => { }); await fs.unlink(`./public/ca/${id}.webp`).catch(_=>{});
await fs.unlink(`./public/t/${id}.webp`).catch(_ => { });
if (f0ck[0].mime.startsWith('audio')) {
await fs.copyFile(`./public/ca/${id}.webp`, `./deleted/ca/${id}.webp`).catch(_ => { });
await fs.unlink(`./public/ca/${id}.webp`).catch(_ => { });
} }
res.json({ res.json({
@@ -270,14 +269,14 @@ export default router => {
group.post(/\/admin\/togglefav$/, lib.loggedin, async (req, res) => { group.post(/\/admin\/togglefav$/, lib.loggedin, async (req, res) => {
const postid = +req.post.postid; const postid = +req.post.postid;
let favs = await db` let favs = await db`
select user_id select user_id
from "favorites" from "favorites"
where item_id = ${+postid} where item_id = ${+postid}
`; `;
if (Object.values(favs).filter(u => u.user_id === req.session.id)[0]) { if(Object.values(favs).filter(u => u.user_id === req.session.id)[0]) {
// del fav // del fav
await db` await db`
delete from "favorites" delete from "favorites"
@@ -288,10 +287,11 @@ export default router => {
else { else {
// add fav // add fav
await db` await db`
insert into "favorites" ${db({ insert into "favorites" ${
item_id: +postid, db({
user_id: +req.session.id item_id: +postid,
}, 'item_id', 'user_id') user_id: +req.session.id
}, 'item_id', 'user_id')
} }
`; `;
} }
@@ -310,7 +310,7 @@ export default router => {
favs favs
}); });
}); });
}); });
return router; return router;

View File

@@ -9,8 +9,8 @@ import fs from "fs";
import path from "path"; import path from "path";
const regex = { const regex = {
all: /https?:\/\/([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])?/gi, all: /https?:\/\/([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])?/gi,
yt: /(?:youtube\.com\/\S*(?:(?:\/e(?:mbed))?\/|watch\/?\?(?:\S*?&?v\=))|youtu\.be\/)([a-zA-Z0-9_-]{6,11})/gi, yt: /(?:youtube\.com\/\S*(?:(?:\/e(?:mbed))?\/|watch\/?\?(?:\S*?&?v\=))|youtu\.be\/)([a-zA-Z0-9_-]{6,11})/gi,
imgur: /(?:https?:)?\/\/(\w+\.)?imgur\.com\/(\S*)(\..{3,4})/i, imgur: /(?:https?:)?\/\/(\w+\.)?imgur\.com\/(\S*)(\..{3,4})/i,
fourchan: /https?:\/\/i\.4cdn\.org\/(\w+)\/(\d+)\.(\w{3,4})/i, fourchan: /https?:\/\/i\.4cdn\.org\/(\w+)\/(\d+)\.(\w{3,4})/i,
instagram: /(?:https?:\/\/www\.)?instagram\.com\S*?\/(?:p|reel)\/(\w{11})\/?/im instagram: /(?:https?:\/\/www\.)?instagram\.com\S*?\/(?:p|reel)\/(\w{11})\/?/im
@@ -23,35 +23,35 @@ export default async bot => {
name: "parser", name: "parser",
call: regex.all, call: regex.all,
active: true, active: true,
f: async e => { f: e => {
const links = e.message.match(regex.all)?.filter(link => !link.includes(cfg.main.url.domain)) || []; const links = e.message.match(regex.all)?.filter(link => !link.includes(cfg.main.url.domain)) || [];
let repost; let repost;
if (e.media) if(e.media)
links.push(e.media); links.push(e.media);
if (links.length === 0) if(links.length === 0)
return false; return false;
if (e.message.match(/\!i(gnore)?\b/)) if(e.message.match(/\!i(gnore)?\b/))
return false; return false;
if (!e.channel.includes("w0bm") && (!e.message.match(/\!w(0bm)?\b/i) && (typeof e.raw.forward_from == 'undefined'))) if(!e.channel.includes("w0bm") && (!e.message.match(/\!w(0bm)?\b/i) && (typeof e.raw.forward_from == 'undefined')))
return false; return false;
if (e.type === 'tg' && // proto: tg if(e.type === 'tg' && // proto: tg
!e.message.match(/\!w(0bm)?\b/i) && // !w / !w0bm !e.message.match(/\!w(0bm)?\b/i) && // !w / !w0bm
!e.raw.forward_date && // is forwarded? !e.raw.forward_date && // is forwarded?
!mediagroupids.has(e.raw.media_group_id) // prepared mediagroup? !mediagroupids.has(e.raw.media_group_id) // prepared mediagroup?
) { ) {
return false; return false;
} }
else if (e.raw.media_group_id && e.message.match(/\!w(0bm)?\b/i)) { else if(e.raw.media_group_id && e.message.match(/\!w(0bm)?\b/i)) {
mediagroupids.add(e.raw.media_group_id); mediagroupids.add(e.raw.media_group_id);
} }
console.log(`parsing ${links.length} link${links.length > 1 ? "s" : ""}...`); console.log(`parsing ${links.length} link${links.length > 1 ? "s" : ""}...`);
for (const link of links) { links.forEach(async link => {
//if(regex.imgur.test(link)) //if(regex.imgur.test(link))
// return await e.reply(`fuck imgur... seriously`); // return await e.reply(`fuck imgur... seriously`);
@@ -63,7 +63,7 @@ export default async bot => {
// check repost (link) // check repost (link)
repost = await queue.checkrepostlink(link); repost = await queue.checkrepostlink(link);
if (repost) if(repost)
return await e.reply(`repost motherf0cker (link): ${cfg.main.url.full}/${repost}`); return await e.reply(`repost motherf0cker (link): ${cfg.main.url.full}/${repost}`);
// generate uuid // generate uuid
@@ -73,41 +73,39 @@ export default async bot => {
// read metadata // read metadata
let ext; let ext;
const proxyArgs = cfg.main.socks ? `--proxy ${cfg.main.socks}` : ''; if(link.match(regex.instagram)) {
if (link.match(regex.instagram)) {
// is instagram // is instagram
try { try {
// @flummi -> is there a variable for the actual work directory so it doesn't have to be hardcoded? // @flummi -> is there a variable for the actual work directory so it doesn't have to be hardcoded?
const meta = JSON.parse((await queue.exec(`yt-dlp ${proxyArgs} -f 'bv*[height<=720]+ba/b[height<=720] / wv*+ba/w' --skip-download --dump-json "${link}"`)).stdout); const meta = JSON.parse((await queue.exec(`yt-dlp --proxy ${cfg.main.socks} -f 'bv*[height<=720]+ba/b[height<=720] / wv*+ba/w' --skip-download --dump-json "${link}"`)).stdout);
ext = meta.ext; ext = meta.ext;
} catch (err) { } catch(err) {
const tmphead = (await fetch(link, { method: "HEAD" })).headers["content-type"]; const tmphead = (await fetch(link, { method: "HEAD" })).headers["content-type"];
// this can be undefined for unsupported mime types, but will be caught in the general mime check below // this can be undefined for unsupported mime types, but will be caught in the general mime check below
ext = cfg.mimes[tmphead]; ext = cfg.mimes[tmphead];
} }
} }
else if (link.match(regex.imgur)) { else if(link.match(regex.imgur)) {
// imghure // imghure
ext = link.split('.').pop(); ext = link.split('.').pop();
} }
else if (link.match(regex.yt)) { else if(link.match(regex.yt)) {
//yt - fuck anti bot protection //yt - fuck anti bot protection
try { try {
const meta = JSON.parse((await queue.exec(`yt-dlp ${proxyArgs} -f 'bv*[height<=720]+ba/b[height<=720] / wv*+ba/w' -I 1 --skip-download --dump-json "${link}"`)).stdout); const meta = JSON.parse((await queue.exec(`yt-dlp --proxy ${cfg.main.socks} -f 'bv*[height<=720]+ba/b[height<=720] / wv*+ba/w' -I 1 --skip-download --dump-json "${link}"`)).stdout);
ext = meta.ext; ext = meta.ext;
} catch (err) { } catch(err) {
console.error("YT-DLP Error:", err);
const tmphead = (await fetch(link, { method: "HEAD" })).headers["content-type"]; const tmphead = (await fetch(link, { method: "HEAD" })).headers["content-type"];
// this can be undefined for unsupported mime types, but will be caught in the general mime check below // this can be undefined for unsupported mime types, but will be caught in the general mime check below
ext = cfg.mimes[tmphead]; ext = cfg.mimes[tmphead];
} }
} }
else if (link.match(regex.fourchan)) { else if(link.match(regex.fourchan)) {
//4chan - fuck cloudflare :) //4chan - fuck cloudflare :)
try { try {
const meta = JSON.parse((await queue.exec(`yt-dlp ${proxyArgs} -f 'bv*[height<=720]+ba/b[height<=720] / wv*+ba/w' --skip-download --dump-json "${link}"`)).stdout); const meta = JSON.parse((await queue.exec(`yt-dlp --proxy ${cfg.main.socks} -f 'bv*[height<=720]+ba/b[height<=720] / wv*+ba/w' --skip-download --dump-json "${link}"`)).stdout);
ext = meta.ext; ext = meta.ext;
} catch (err) { } catch(err) {
const tmphead = (await fetch(link, { method: "HEAD" })).headers["content-type"]; const tmphead = (await fetch(link, { method: "HEAD" })).headers["content-type"];
// this can be undefined for unsupported mime types, but will be caught in the general mime check below // this can be undefined for unsupported mime types, but will be caught in the general mime check below
ext = cfg.mimes[tmphead]; ext = cfg.mimes[tmphead];
@@ -119,15 +117,14 @@ export default async bot => {
try { try {
const meta = JSON.parse((await queue.exec(`yt-dlp -f 'bv*[height<=720]+ba/b[height<=720] / wv*+ba/w' --skip-download --dump-json "${link}"`)).stdout); const meta = JSON.parse((await queue.exec(`yt-dlp -f 'bv*[height<=720]+ba/b[height<=720] / wv*+ba/w' --skip-download --dump-json "${link}"`)).stdout);
ext = meta.ext; ext = meta.ext;
} catch (err) { } catch(err) {
console.error('err:', err); const tmphead = (await fetch(link, { method: "HEAD" })).headers["content-type"];
if (e.type == 'tg') // this can be undefined for unsupported mime types, but will be caught in the general mime check below
return await e.editMessageText(msg.result.chat.id, msg.result.message_id, err); ext = cfg.mimes[tmphead];
return await e.reply('something went wrong lol / check maxfilesize?');
} }
} }
if (!Object.values(cfg.mimes).includes(ext?.toLowerCase())) { if(!Object.values(cfg.mimes).includes(ext?.toLowerCase())) {
return console.log('mime schmime ' + ext); return console.log('mime schmime ' + ext);
} }
@@ -139,44 +136,44 @@ export default async bot => {
const start = new Date(); const start = new Date();
let source; let source;
if (link.match(regex.instagram)) { if(link.match(regex.instagram)) {
try { try {
// add --cookies <path-to-cookies-file> on local instance if you want to avoid getting rate limited or optionally use a socks proxy from a network that is not being detected as a public network // add --cookies <path-to-cookies-file> on local instance if you want to avoid getting rate limited or optionally use a socks proxy from a network that is not being detected as a public network
source = (await queue.exec(`yt-dlp ${proxyArgs} -f 'bv*[height<=1080]+ba/b[height<=1080] / wv*+ba/w' "${link}" --max-filesize ${maxfilesize / 1024}k --postprocessor-args "ffmpeg:-bitexact" -o "./tmp/${uuid}.%(ext)s" --print after_move:filepath --merge-output-format "mp4"`)).stdout.trim(); source = (await queue.exec(`yt-dlp --proxy ${cfg.main.socks} -f 'bv*[height<=1080]+ba/b[height<=1080] / wv*+ba/w' "${link}" --max-filesize ${maxfilesize / 1024}k --postprocessor-args "ffmpeg:-bitexact" -o "./tmp/${uuid}.%(ext)s" --print after_move:filepath --merge-output-format "mp4"`)).stdout.trim();
} catch (err) { } catch(err) {
if (e.type == 'tg') if(e.type == 'tg')
return await e.editMessageText(msg.result.chat.id, msg.result.message_id, "instagram dl error"); return await e.editMessageText(msg.result.chat.id, msg.result.message_id, "instagram dl error");
return await e.reply("instagram dl error", err); return await e.reply("instagram dl error", err);
} }
} }
else if (link.match(regex.imgur)) { else if(link.match(regex.imgur)) {
// imghure via torsocks // needs torsocks setup so this is optional // imghure via torsocks // needs torsocks setup so this is optional
try { try {
await queue.exec(`torsocks wget ${link} -O ./tmp/${uuid}.${ext}`); await queue.exec(`torsocks wget ${link} -O ./tmp/${uuid}.${ext}`);
source = `./tmp/${uuid}.${ext}`; source = `./tmp/${uuid}.${ext}`;
} catch (err) { } catch(err) {
console.error('err:', err); console.error('err:', err);
if (e.type == 'tg') if(e.type == 'tg')
return await e.editMessageText(msg.result.chat.id, msg.result.message_id, err); return await e.editMessageText(msg.result.chat.id, msg.result.message_id, err);
return await e.reply('something went wrong lol'); return await e.reply('something went wrong lol');
} }
} }
else if (link.match(regex.yt)) { else if(link.match(regex.yt)) {
try { try {
// add --cookies <path-to-cookies-file> on local instance if you want to avoid getting rate limited or optionally use a socks proxy from a network that is not being detected as a public network // add --cookies <path-to-cookies-file> on local instance if you want to avoid getting rate limited or optionally use a socks proxy from a network that is not being detected as a public network
source = (await queue.exec(`yt-dlp ${proxyArgs} -f 'bv*[height<=720]+ba/b[height<=720] / wv*+ba/w' "${link}" -I 1 --max-filesize ${maxfilesize / 1024}k --postprocessor-args "ffmpeg:-bitexact" -o "./tmp/${uuid}.%(ext)s" --print after_move:filepath --merge-output-format "mp4"`)).stdout.trim(); source = (await queue.exec(`yt-dlp --proxy ${cfg.main.socks} -f 'bv*[height<=720]+ba/b[height<=720] / wv*+ba/w' "${link}" -I 1 --max-filesize ${maxfilesize / 1024}k --postprocessor-args "ffmpeg:-bitexact" -o "./tmp/${uuid}.%(ext)s" --print after_move:filepath --merge-output-format "mp4"`)).stdout.trim();
} catch (err) { } catch(err) {
if (e.type == 'tg') if(e.type == 'tg')
return await e.editMessageText(msg.result.chat.id, msg.result.message_id, "yt dl error"); return await e.editMessageText(msg.result.chat.id, msg.result.message_id, "yt dl error");
return await e.reply("yt dl error", err); return await e.reply("yt dl error", err);
} }
} }
else if (link.match(regex.fourchan)) { else if(link.match(regex.fourchan)) {
// 4chan via proxy - fuck cloudflare // 4chan via proxy - fuck cloudflare
try { try {
source = (await queue.exec(`yt-dlp ${proxyArgs} -f 'bv*[height<=720]+ba/b[height<=720] / wv*+ba/w' "${link}" --max-filesize ${maxfilesize / 1024}k --postprocessor-args "ffmpeg:-bitexact" -o "./tmp/${uuid}.%(ext)s" --print after_move:filepath --merge-output-format "mp4"`)).stdout.trim(); source = (await queue.exec(`yt-dlp --proxy ${cfg.main.socks} -f 'bv*[height<=720]+ba/b[height<=720] / wv*+ba/w' "${link}" --max-filesize ${maxfilesize / 1024}k --postprocessor-args "ffmpeg:-bitexact" -o "./tmp/${uuid}.%(ext)s" --print after_move:filepath --merge-output-format "mp4"`)).stdout.trim();
} catch (err) { } catch(err) {
if (e.type == 'tg') if(e.type == 'tg')
return await e.editMessageText(msg.result.chat.id, msg.result.message_id, "yt dl error"); return await e.editMessageText(msg.result.chat.id, msg.result.message_id, "yt dl error");
return await e.reply("yt dl error", err); return await e.reply("yt dl error", err);
} }
@@ -185,23 +182,23 @@ export default async bot => {
// everything except the exceptions // everything except the exceptions
try { try {
source = (await queue.exec(`yt-dlp -f 'bv*[height<=720]+ba/b[height<=720] / wv*+ba/w' "${link}" --max-filesize ${maxfilesize / 1024}k --postprocessor-args "ffmpeg:-bitexact" -o "./tmp/${uuid}.%(ext)s" --print after_move:filepath --merge-output-format "mp4"`)).stdout.trim(); source = (await queue.exec(`yt-dlp -f 'bv*[height<=720]+ba/b[height<=720] / wv*+ba/w' "${link}" --max-filesize ${maxfilesize / 1024}k --postprocessor-args "ffmpeg:-bitexact" -o "./tmp/${uuid}.%(ext)s" --print after_move:filepath --merge-output-format "mp4"`)).stdout.trim();
} catch (err) { } catch(err) {
console.error('err:', err); console.error('err:', err);
if (e.type == 'tg') if(e.type == 'tg')
return await e.editMessageText(msg.result.chat.id, msg.result.message_id, err); return await e.editMessageText(msg.result.chat.id, msg.result.message_id, err);
return await e.reply('something went wrong lol / check maxfilesize?'); return await e.reply('something went wrong lol / check maxfilesize?');
} }
} }
// </download data> // </download data>
if (!source) { if(!source) {
if (e.type == 'tg') if(e.type == 'tg')
return await e.editMessageText(msg.result.chat.id, msg.result.message_id, "something went wrong lol"); return await e.editMessageText(msg.result.chat.id, msg.result.message_id, "something went wrong lol");
return await e.reply("something went wrong lol"); return await e.reply("something went wrong lol");
} }
if (source.match(/larger than/)) { if(source.match(/larger than/)) {
if (e.type == 'tg') if(e.type == 'tg')
return await e.editMessageText(msg.result.chat.id, msg.result.message_id, "too large lol"); return await e.editMessageText(msg.result.chat.id, msg.result.message_id, "too large lol");
return await e.reply("too large lol"); return await e.reply("too large lol");
} }
@@ -209,38 +206,38 @@ export default async bot => {
// filesize check // filesize check
const size = fs.statSync(source).size; const size = fs.statSync(source).size;
if (size > maxfilesize) { if(size > maxfilesize) {
await fs.promises.unlink(source).catch(_ => { }); await fs.promises.unlink(source).catch(_=>{});
if (e.type == 'tg') if(e.type == 'tg')
return await e.editMessageText(msg.result.chat.id, msg.result.message_id, `too large lol. (${lib.formatSize(size)} / ${lib.formatSize(maxfilesize)})`); return await e.editMessageText(msg.result.chat.id, msg.result.message_id, `too large lol. (${lib.formatSize(size)} / ${lib.formatSize(maxfilesize)})`);
return await e.reply(`too large lol. (${lib.formatSize(size)} / ${lib.formatSize(maxfilesize)})`); return await e.reply(`too large lol. (${lib.formatSize(size)} / ${lib.formatSize(maxfilesize)})`);
} }
// mime check // mime check
let mime = (await queue.exec(`file --mime-type -b ${source}`)).stdout.trim(); let mime = (await queue.exec(`file --mime-type -b ${source}`)).stdout.trim();
try { try {
if (mime == 'video/x-matroska') { // mkv failsafe if(mime == 'video/x-matroska') { // mkv failsafe
await queue.exec(`ffmpeg -i ./tmp/${uuid}.mkv -codec copy ./tmp/${uuid}.mp4`); await queue.exec(`ffmpeg -i ./tmp/${uuid}.mkv -codec copy ./tmp/${uuid}.mp4`);
await fs.promises.unlink(source).catch(_ => { }); await fs.promises.unlink(source).catch(_=>{});
source = source.replace(/\.mkv$/, '.mp4'); source = source.replace(/\.mkv$/, '.mp4');
mime = 'video/mp4'; mime = 'video/mp4';
} }
if (source.match(/\.opus$/)) { // opus failsafe if(source.match(/\.opus$/)) { // opus failsafe
await queue.exec(`ffmpeg -i ./tmp/${uuid}.opus -codec copy ./tmp/${uuid}.ogg`); await queue.exec(`ffmpeg -i ./tmp/${uuid}.opus -codec copy ./tmp/${uuid}.ogg`);
await fs.promises.unlink(source); await fs.promises.unlink(source);
source = source.replace(/\.opus$/, '.ogg'); source = source.replace(/\.opus$/, '.ogg');
mime = 'audio/ogg'; mime = 'audio/ogg';
} }
} catch (err) { } catch(err) {
await fs.promises.unlink(source).catch(_ => { }); await fs.promises.unlink(source).catch(_=>{});
if (e.type == 'tg') if(e.type == 'tg')
return await e.editMessageText(msg.result.chat.id, msg.result.message_id, "something went wrong lol"); return await e.editMessageText(msg.result.chat.id, msg.result.message_id, "something went wrong lol");
return await e.reply("something went wrong lol"); return await e.reply("something went wrong lol");
} }
if (!Object.keys(cfg.mimes).includes(mime)) { if(!Object.keys(cfg.mimes).includes(mime)) {
await fs.promises.unlink(source).catch(_ => { }); await fs.promises.unlink(source).catch(_=>{});
if (e.type == 'tg') if(e.type == 'tg')
return await e.editMessageText(msg.result.chat.id, msg.result.message_id, `lol, go f0ck yourself (${mime})`); return await e.editMessageText(msg.result.chat.id, msg.result.message_id, `lol, go f0ck yourself (${mime})`);
return await e.reply(`lol, go f0ck yourself (${mime})`); return await e.reply(`lol, go f0ck yourself (${mime})`);
} }
@@ -250,9 +247,9 @@ export default async bot => {
// check repost (checksum) // check repost (checksum)
repost = await queue.checkrepostsum(checksum); repost = await queue.checkrepostsum(checksum);
if (repost) { if(repost) {
await fs.promises.unlink(source).catch(_ => { }); await fs.promises.unlink(source).catch(_=>{});
if (e.type == 'tg') if(e.type == 'tg')
return await e.editMessageText(msg.result.chat.id, msg.result.message_id, `repost motherf0cker (checksum): ${cfg.main.url.full}/${repost}`); return await e.editMessageText(msg.result.chat.id, msg.result.message_id, `repost motherf0cker (checksum): ${cfg.main.url.full}/${repost}`);
return await e.reply(`repost motherf0cker (checksum): ${cfg.main.url.full}/${repost}`); return await e.reply(`repost motherf0cker (checksum): ${cfg.main.url.full}/${repost}`);
} }
@@ -260,7 +257,7 @@ export default async bot => {
const filename = path.basename(source); const filename = path.basename(source);
await fs.promises.copyFile(source, `./public/b/${filename}`); await fs.promises.copyFile(source, `./public/b/${filename}`);
await fs.promises.unlink(source).catch(_ => { }); await fs.promises.unlink(source).catch(_=>{});
// user alias // user alias
let username = e.user.nick || e.user.username; let username = e.user.nick || e.user.username;
@@ -271,42 +268,33 @@ export default async bot => {
where lower(user_alias.alias) ilike ${username} where lower(user_alias.alias) ilike ${username}
limit 1 limit 1
`)?.[0]?.user; `)?.[0]?.user;
if (alias) { if(alias) {
username = alias; username = alias;
} }
await db` await db`
insert into items ${db({ insert into items ${
src: e.media ? "" : link, db({
dest: filename, src: e.media ? "" : link,
mime: mime, dest: filename,
size: size, mime: mime,
checksum: checksum, size: size,
username: username, checksum: checksum,
userchannel: e.channel, username: username,
usernetwork: e.network, userchannel: e.channel,
stamp: ~~(new Date() / 1000), usernetwork: e.network,
active: true stamp: ~~(new Date() / 1000),
}, 'src', 'dest', 'mime', 'size', 'checksum', 'username', 'userchannel', 'usernetwork', 'stamp', 'active') active: true
}, 'src', 'dest', 'mime', 'size', 'checksum', 'username', 'userchannel', 'usernetwork', 'stamp', 'active')
} }
`; `;
const itemid = await queue.getItemID(filename); const itemid = await queue.getItemID(filename);
// auto-tag sfw
await db`
insert into tags_assign ${db({
item_id: itemid,
tag_id: 1, // sfw
user_id: 2 // f0ck
}, 'item_id', 'tag_id', 'user_id')
}
`;
// generate thumbnail // generate thumbnail
try { try {
await queue.genThumbnail(filename, mime, itemid, link); await queue.genThumbnail(filename, mime, itemid, link);
} catch (err) { } catch(err) {
await queue.exec(`magick ./mugge.png ./public/t/${itemid}.webp`); await queue.exec(`magick ./mugge.png ./public/t/${itemid}.webp`);
} }
@@ -327,13 +315,13 @@ export default async bot => {
let outputmsgirc = `[f0cked] link: ${cfg.main.url.full}/${itemid} | size: ${lib.formatSize(size)} | speed: ${speed}`; let outputmsgirc = `[f0cked] link: ${cfg.main.url.full}/${itemid} | size: ${lib.formatSize(size)} | speed: ${speed}`;
let outputmsgtg = `[f0cked] size: ${lib.formatSize(size)} | speed: ${speed}`; let outputmsgtg = `[f0cked] size: ${lib.formatSize(size)} | speed: ${speed}`;
if (tags?.length > 0) { if(tags?.length > 0) {
const tagstr = tags.join(', '); const tagstr = tags.join(', ');
outputmsgirc += ` | tags: ${tagstr}`; outputmsgirc += ` | tags: ${tagstr}`;
outputmsgtg += ` | tags: ${tagstr}`; outputmsgtg += ` | tags: ${tagstr}`;
} }
if (e.type == 'tg') { if(e.type == 'tg') {
await e.deleteMessage(msg.result.chat.id, msg.result.message_id); await e.deleteMessage(msg.result.chat.id, msg.result.message_id);
await e.reply(outputmsgtg, { await e.reply(outputmsgtg, {
reply_markup: JSON.stringify({ reply_markup: JSON.stringify({
@@ -351,7 +339,7 @@ export default async bot => {
else { else {
await e.reply(outputmsgirc); await e.reply(outputmsgirc);
} }
} });
} }
}]; }];
}; };

View File

@@ -8,7 +8,7 @@
<a href="/tags">tags</a> <a href="/tags">tags</a>
<a href="/about">about</a> <a href="/about">about</a>
@if(!/^\/\d$/.test(url.pathname)) @if(!/^\/\d$/.test(url.pathname))
<a href="/random" id="nav-random">rand</a> <a href="/random">rand</a>
@endif @endif
</ol> </ol>
</div> </div>
@@ -33,7 +33,7 @@
<a href="/tags">tags</a> <a href="/tags">tags</a>
<a href="/about">about</a> <a href="/about">about</a>
@if(!/^\/\d$/.test(url.pathname)) @if(!/^\/\d$/.test(url.pathname))
<a href="/random" id="nav-random">rand</a> <a href="/random">rand</a>
@endif @endif
</ol> </ol>
</div> </div>