This commit is contained in:
Flummi 2023-04-28 07:04:06 +02:00
parent 44df4deea3
commit 8b6f68f2e9
11 changed files with 508 additions and 94 deletions

View File

@ -0,0 +1,265 @@
import logger from "../log.mjs";
import { getLevel } from "../../inc/admin.mjs";
import { promises as fs } from "fs";
import cfg from "../config.mjs";
import db from "../sql.mjs";
import lib from "../lib.mjs";
export default async bot => {
return [{
name: "callback_query",
listener: "callback_query",
f: async e => {
logger.info(`${e.network} -> ${e.channel} -> ${e.user.nick}: ${e.message}`);
let [ cmd, id ] = e.opt.data.split(':');
let f0ck;
id = +id;
switch(cmd) {
case "b_tags":
if(!id)
return;
const tags = [{
tag: 'music',
id: 115
}, {
tag: 'german',
id: 329
}, {
tag: 'cat',
id: 217
}, {
tag: 'doggo',
id: 5
}];
const keyboard = await Promise.all(tags.map(async t => ({ text: `${await lib.hasTag(id, t.id) ? '✓ ' : ''}${t.tag}`, callback_data: `b_${t.tag}:${id}` })));
await e.editMessageText(e.raw.chat.id, e.raw.message_id, e.message, {
reply_markup: JSON.stringify({
inline_keyboard: [[
...keyboard
], [
{ text: 'back', callback_data: `b_back:${id}` }
]]
})
});
break;
case "b_back":
if(!id)
return;
await e.editMessageText(e.raw.chat.id, e.raw.message_id, e.message, {
reply_markup: JSON.stringify({
inline_keyboard: [[
{ text: (await lib.hasTag(id, 1) ? '✓ ' : '') + 'sfw', callback_data: `b_sfw:${id}` },
{ text: (await lib.hasTag(id, 2) ? '✓ ' : '') + 'nsfw', callback_data: `b_nsfw:${id}` },
{ text: 'tags', callback_data: `b_tags:${id}` },
{ text: '❌ delete', callback_data: `b_delete:${id}` }
], [
{ text: `open f0ck #${id}`, url: `${cfg.main.url.full}/${id}` }
]]
})
});
break;
case "b_sfw":
if(!id)
return;
if(!(await lib.getTags(id)).filter(tag => [1,2].includes(tag.id)).length) {
// insert
await db`
insert into "tags_assign" ${
db({
item_id: id,
tag_id: 1, // sfw
user_id: 1
})
}
`;
}
else {
// update
await db`
update "tags_assign" set tag_id = 1
where
tag_id = 2 and
item_id = ${id}
`;
}
await e.editMessageText(e.raw.chat.id, e.raw.message_id, e.message, {
reply_markup: JSON.stringify({
inline_keyboard: [[
{ text: '✓ sfw', callback_data: `b_sfw:${id}` },
{ text: 'nsfw', callback_data: `b_nsfw:${id}` },
{ text: 'tags', callback_data: `b_tags:${id}` },
{ text: '❌ delete', callback_data: `b_delete:${id}` }
], [
{ text: `open f0ck #${id}`, url: `${cfg.main.url.full}/${id}` }
]]
})
});
break;
case "b_nsfw":
if(!id)
return;
if(!(await lib.getTags(id)).filter(tag => [1,2].includes(tag.id)).length) {
// insert
await db`
insert into "tags_assign" ${
db({
item_id: id,
tag_id: 2, // nsfw
user_id: 1
})
}
`;
}
else {
// update
await db`
update "tags_assign" set tag_id = 2
where
tag_id = 1 and
item_id = ${id}
`;
}
await e.editMessageText(e.raw.chat.id, e.raw.message_id, e.message, {
reply_markup: JSON.stringify({
inline_keyboard: [[
{ text: 'sfw', callback_data: `b_sfw:${id}` },
{ text: '✓ nsfw', callback_data: `b_nsfw:${id}` },
{ text: 'tags', callback_data: `b_tags:${id}` },
{ text: '❌ delete', callback_data: `b_delete:${id}` }
], [
{ text: `open f0ck #${id}`, url: `${cfg.main.url.full}/${id}` }
]]
})
});
break;
case "b_delete":
if(id <= 1)
return;
e.user = {
prefix: `${e.raw.reply_to_message.from.username}!${e.raw.reply_to_message.from.id}@${e.network}`,
nick: e.raw.reply_to_message.from.first_name,
username: e.raw.reply_to_message.from.username,
account: e.raw.reply_to_message.from.id.toString()
};
f0ck = await db`
select dest, mime, username, userchannel, usernetwork
from "items"
where
id = ${id} and
active = 'true'
limit 1
`;
const level = getLevel(e.user).level;
if(f0ck.length === 0) {
return await e.reply(`f0ck ${id}: f0ck not found`);
}
if(
(f0ck[0].username !== (e.user.nick || e.user.username) ||
f0ck[0].userchannel !== e.channel ||
f0ck[0].usernetwork !== e.network) &&
level < 100
) {
return await e.reply(`f0ck ${id}: insufficient permissions`);
}
if(~~(new Date() / 1e3) >= (f0ck[0].stamp + 600) && level < 100) {
return await e.reply(`f0ck ${id}: too late lol`);
}
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(_=>{});
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(_=>{});
}
await e.editMessageText(e.raw.chat.id, e.raw.message_id, e.message, {
reply_markup: JSON.stringify({
inline_keyboard: [[
{ text: (await lib.hasTag(id, 1) ? '✓ ' : '') + 'sfw', callback_data: `b_sfw:${id}` },
{ text: (await lib.hasTag(id, 2) ? '✓ ' : '') + 'nsfw', callback_data: `b_nsfw:${id}` },
{ text: 'tags', callback_data: `b_tags:${id}` },
{ text: 'recover', callback_data: `b_recover:${id}` }
], [
{ text: `open f0ck #${id}`, url: `${cfg.main.url.full}/${id}` }
]]
})
});
break;
case "b_recover":
if(id <= 1)
return;
e.user = {
prefix: `${e.raw.reply_to_message.from.username}!${e.raw.reply_to_message.from.id}@${e.network}`,
nick: e.raw.reply_to_message.from.first_name,
username: e.raw.reply_to_message.from.username,
account: e.raw.reply_to_message.from.id.toString()
};
f0ck = await db`
select dest, mime
from "items"
where
id = ${id} and
active = 'false'
limit 1
`;
if(f0ck.length === 0) {
return await e.reply(`f0ck ${id}: f0ck not found`);
}
await fs.copyFile(`./deleted/b/${f0ck[0].dest}`, `./public/b/${f0ck[0].dest}`).catch(_=>{});
await fs.copyFile(`./deleted/t/${id}.webp`, `./public/t/${id}.webp`).catch(_=>{});
await fs.unlink(`./deleted/b/${f0ck[0].dest}`).catch(_=>{});
await fs.unlink(`./deleted/t/${id}.webp`).catch(_=>{});
if(f0ck[0].mime.startsWith('audio')) {
await fs.copyFile(`./deleted/ca/${id}.webp`, `./public/ca/${id}.webp`).catch(_=>{});
await fs.unlink(`./deleted/ca/${id}.webp`).catch(_=>{});
}
await db`update "items" set active = 'true' where id = ${id}`;
await e.editMessageText(e.raw.chat.id, e.raw.message_id, e.message, {
reply_markup: JSON.stringify({
inline_keyboard: [[
{ text: (await lib.hasTag(id, 1) ? '✓ ' : '') + 'sfw', callback_data: `b_sfw:${id}` },
{ text: (await lib.hasTag(id, 2) ? '✓ ' : '') + 'nsfw', callback_data: `b_nsfw:${id}` },
{ text: 'tags', callback_data: `b_tags:${id}` },
{ text: '❌ delete', callback_data: `b_delete:${id}` }
], [
{ text: `open f0ck #${id}`, url: `${cfg.main.url.full}/${id}` }
]]
})
});
break;
default:
await e.reply('lol');
}
}
}];
};

View File

@ -40,7 +40,7 @@ export default async bot => {
} }
catch(err) { catch(err) {
console.error(err); console.error(err);
e.reply(`${t[0]}: An error occured.`); await e.reply(`${t[0]}: An error occured.`);
logger.error(`${e.network} -> ${e.channel} -> ${e.user.nick}: ${err.toString ? err : JSON.stringify(err)}`); logger.error(`${e.network} -> ${e.channel} -> ${e.user.nick}: ${err.toString ? err : JSON.stringify(err)}`);
} }
}); });

View File

@ -161,6 +161,17 @@ export default new class {
} }
return tags; 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) { async detectNSFW(dest) {
return false; return false;
const { stdout, stderr } = await exec( const { stdout, stderr } = await exec(

View File

@ -1,4 +1,5 @@
import { getLevel } from "../admin.mjs"; import { getLevel } from "../admin.mjs";
import lib from "../lib.mjs";
import fetch from "flumm-fetch"; import fetch from "flumm-fetch";
import vm from "vm"; import vm from "vm";
@ -19,16 +20,16 @@ export default async bot => {
name: "level", name: "level",
call: /^!level (.*)/i, call: /^!level (.*)/i,
active: true, active: true,
f: e => { f: async e => {
const user = e.message.trim().substring(7); const user = e.message.trim().substring(7);
e.reply( JSON.stringify( getLevel( e.self.user.get(user) || {} ) ) ); await e.reply( JSON.stringify( getLevel( e.self.user.get(user) || {} ) ) );
} }
}, { }, {
name: "self", name: "self",
call: /^!self$/i, call: /^!self$/i,
active: true, active: true,
f: e => { f: async e => {
e.reply( JSON.stringify( e.user ) ); await e.reply( JSON.stringify( e.user ) );
} }
}, { }, {
name: "sandbox_debug", name: "sandbox_debug",
@ -41,6 +42,7 @@ export default async bot => {
context.e = e; context.e = e;
context.bot = bot; context.bot = bot;
context.level = getLevel; context.level = getLevel;
context.hasTag = lib.hasTag;
context.a = null; context.a = null;
await new Promise(resolve => { await new Promise(resolve => {
@ -52,9 +54,9 @@ export default async bot => {
let output = JSON.stringify(context.a); let output = JSON.stringify(context.a);
if(output.length > maxoutput) if(output.length > maxoutput)
return e.reply(`fuggg, Ausgabe wäre viel zu lang! (${output.length} Zeichen :DDDDDD)`); return await e.reply(`fuggg, Ausgabe wäre viel zu lang! (${output.length} Zeichen :DDDDDD)`);
else else
return e.reply(output); return await e.reply(output);
} }
}]; }];
}; };

View File

@ -27,7 +27,7 @@ export default async bot => {
const level = getLevel(e.user).level; const level = getLevel(e.user).level;
if(f0ck.length === 0) { if(f0ck.length === 0) {
e.reply(`f0ck ${id}: f0ck not found`); await e.reply(`f0ck ${id}: f0ck not found`);
continue; continue;
} }
@ -37,12 +37,12 @@ export default async bot => {
f0ck[0].usernetwork !== e.network) && f0ck[0].usernetwork !== e.network) &&
level < 100 level < 100
) { ) {
e.reply(`f0ck ${id}: insufficient permissions`); await e.reply(`f0ck ${id}: insufficient permissions`);
continue; continue;
} }
if(~~(new Date() / 1e3) >= (f0ck[0].stamp + 600) && level < 100) { if(~~(new Date() / 1e3) >= (f0ck[0].stamp + 600) && level < 100) {
e.reply(`f0ck ${id}: too late lol`); await e.reply(`f0ck ${id}: too late lol`);
continue; continue;
} }
@ -61,7 +61,7 @@ export default async bot => {
deleted.push(id); deleted.push(id);
} }
e.reply(`deleted ${deleted.length}/${e.args.length} f0cks (${deleted.join(",")})`); await e.reply(`deleted ${deleted.length}/${e.args.length} f0cks (${deleted.join(",")})`);
} }
}, { }, {
name: "recover", name: "recover",
@ -86,7 +86,7 @@ export default async bot => {
`; `;
if(f0ck.length === 0) { if(f0ck.length === 0) {
e.reply(`f0ck ${id}: f0ck not found`); await e.reply(`f0ck ${id}: f0ck not found`);
continue; continue;
} }
@ -105,7 +105,7 @@ export default async bot => {
recovered.push(id); recovered.push(id);
} }
e.reply(`recovered ${recovered.length}/${e.args.length} f0cks (${recovered.join(",")})`); await e.reply(`recovered ${recovered.length}/${e.args.length} f0cks (${recovered.join(",")})`);
} }
}] }]
}; };

View File

@ -5,29 +5,6 @@ import cfg from "../config.mjs";
import db from "../sql.mjs"; import db from "../sql.mjs";
import lib from "../lib.mjs"; import lib from "../lib.mjs";
/*const cleanTags = async () => {
const tags = await db`
select *
from "tags"
left join "tags_assign" on "tags_assign".tag_id = "tags".id
where "tags_assign".item_id is null
`;
if(tags.length === 0)
return 0;
let deleteTag = sql("tags");
let dtags = 0;
tags.forEach(tag => {
if(["sfw", "nsfw"].includes(tag.tag.toLowerCase()))
return dtags;
deleteTag = deleteTag.orWhere("id", tag.id);
dtags++;
});
await deleteTag.del();
return dtags;
};*/
export default async bot => { export default async bot => {
return [{ return [{
@ -48,44 +25,40 @@ export default async bot => {
t: lib.formatSize((await Promise.all(dirs.t.map( async file => (await fs.stat(`./public/t/${file}`)).size)) ).reduce((a, b) => b + a)), t: lib.formatSize((await Promise.all(dirs.t.map( async file => (await fs.stat(`./public/t/${file}`)).size)) ).reduce((a, b) => b + a)),
ca: lib.formatSize((await Promise.all(dirs.ca.map(async file => (await fs.stat(`./public/ca/${file}`)).size))).reduce((a, b) => b + a)), ca: lib.formatSize((await Promise.all(dirs.ca.map(async file => (await fs.stat(`./public/ca/${file}`)).size))).reduce((a, b) => b + a)),
}; };
return e.reply(`${dirs.b.length} f0cks: ${sizes.b}, ${dirs.t.length} thumbnails: ${sizes.t}, ${dirs.ca.length} coverarts: ${sizes.ca}`); return await e.reply(`${dirs.b.length} f0cks: ${sizes.b}, ${dirs.t.length} thumbnails: ${sizes.t}, ${dirs.ca.length} coverarts: ${sizes.ca}`);
case "limit": case "limit":
return e.reply(`up to ${lib.formatSize(cfg.main.maxfilesize)} (${lib.formatSize(cfg.main.maxfilesize * cfg.main.adminmultiplier)} for admins)`); return await e.reply(`up to ${lib.formatSize(cfg.main.maxfilesize)} (${lib.formatSize(cfg.main.maxfilesize * cfg.main.adminmultiplier)} for admins)`);
case "thumb": case "thumb":
const rows = await db` const rows = await db`
select id select id
from "items" from "items"
`; `;
const dir = (await fs.readdir("./public/t")).filter(d => d.endsWith(".png")).map(e => +e.split(".")[0]); const dir = (await fs.readdir("./public/t")).filter(d => d.endsWith(".webp")).map(e => +e.split(".")[0]);
const tmp = []; const tmp = [];
for(let row of rows) for(let row of rows)
!dir.includes(row.id) ? tmp.push(row.id) : null; !dir.includes(row.id) ? tmp.push(row.id) : null;
e.reply(`${tmp.length}, ${rows.length}, ${dir.length}`); await e.reply(`${tmp.length}, ${rows.length}, ${dir.length}`);
break; break;
case "cache": case "cache":
cfg.websrv.cache = !cfg.websrv.cache; cfg.websrv.cache = !cfg.websrv.cache;
return e.reply(`Cache is ${cfg.websrv.cache ? "enabled" : "disabled"}`); return await e.reply(`Cache is ${cfg.websrv.cache ? "enabled" : "disabled"}`);
case "uptime": case "uptime":
exec('sudo systemctl status f0ck', (err, stdout) => { exec('sudo systemctl status f0ck', async (err, stdout) => {
if(!err) if(!err)
return e.reply(stdout.split('\n')[2].trim().replace("Active: active (running)", "i'm active")); return await e.reply(stdout.split('\n')[2].trim().replace("Active: active (running)", "i'm active"));
}); });
break; break;
case "restart": case "restart":
e.reply("hay hay patron, hemen!"); await e.reply("hay hay patron, hemen!");
exec("sudo systemctl restart f0ck"); exec("sudo systemctl restart f0ck");
break; break;
/*case "cleanTags":
const tags = await cleanTags();
e.reply(tags + " tags removed");
break;*/
case "clearTmp": case "clearTmp":
await Promise.all((await fs.readdir("./tmp")).filter(d => d !== ".empty").map(async d => fs.unlink(`./tmp/${d}`))); await Promise.all((await fs.readdir("./tmp")).filter(d => d !== ".empty").map(async d => fs.unlink(`./tmp/${d}`)));
e.reply("cleared lol"); await e.reply("cleared lol");
break; break;
case "status": case "status":
const tmpc = await lib.countf0cks(); const tmpc = await lib.countf0cks();
e.reply(`tagged: ${tmpc.tagged}; untagged: ${tmpc.untagged}; sfw: ${tmpc.sfw}; nsfw: ${tmpc.nsfw}; total: ${tmpc.total}`); await e.reply(`tagged: ${tmpc.tagged}; untagged: ${tmpc.untagged}; sfw: ${tmpc.sfw}; nsfw: ${tmpc.nsfw}; total: ${tmpc.total}`);
break; break;
case "autotagger": case "autotagger":
const body = { headers: { Authorization: `Basic ${cfg.tagger.btoa}` } }; const body = { headers: { Authorization: `Basic ${cfg.tagger.btoa}` } };
@ -93,7 +66,7 @@ export default async bot => {
if(res) { if(res) {
const processed = res.result.monthly_processed; const processed = res.result.monthly_processed;
const limit = res.result.monthly_limit; const limit = res.result.monthly_limit;
return e.reply(`autotagger: usage/limit: ${processed}/${limit}`); return await e.reply(`autotagger: usage/limit: ${processed}/${limit}`);
} }
return; return;
break; break;
@ -101,7 +74,7 @@ export default async bot => {
const origTag = e.args.slice(1).join(' '); const origTag = e.args.slice(1).join(' ');
if(origTag.length <= 1) if(origTag.length <= 1)
return e.reply("absichtliche Provokation!"); return await e.reply("absichtliche Provokation!");
const origTagID = (await sql('tags').where('tag', origTag))[0].id; const origTagID = (await sql('tags').where('tag', origTag))[0].id;
@ -116,10 +89,10 @@ export default async bot => {
.del() .del()
); );
e.reply(JSON.stringify({ affected, deleted })); await e.reply(JSON.stringify({ affected, deleted }));
break;*/ break;*/
case "help": case "help":
e.reply("cmds: stats, limit, thumb, cache, uptime, restart, cleanTags, clearTmp, status"); await e.reply("cmds: stats, limit, thumb, cache, uptime, restart, cleanTags, clearTmp, status");
break; break;
default: default:
return; return;

View File

@ -22,9 +22,9 @@ export default async bot => {
`; `;
if(rows.length === 0) if(rows.length === 0)
return e.reply("no f0cks given! lol D:"); return await e.reply("no f0cks given! lol D:");
e.reply([ await e.reply([
`${cfg.main.url.full}/${rows[0].id}`, `${cfg.main.url.full}/${rows[0].id}`,
`user: ${rows[0].username} @ ${rows[0].usernetwork} ${rows[0].userchannel}`, `user: ${rows[0].username} @ ${rows[0].usernetwork} ${rows[0].userchannel}`,
`~${lib.formatSize(rows[0].size)}`, `~${lib.formatSize(rows[0].size)}`,

View File

@ -33,19 +33,10 @@ export default async bot => {
order by random() order by random()
`; `;
console.log(`select id, mime, username, size
from "items"
where
${ args.map(a => a.charAt(0) === "!"
? `username not ilike ${a.slice(1)}`
: `username ilike ${a}`
).join(' and ')}
order by random()`);
if(rows.length === 0) if(rows.length === 0)
return e.reply("nothing found, f0cker"); return await e.reply("nothing found, f0cker");
return e.reply(`f0ckrnd: ${cfg.main.url.full}/${rows[0].id} by: ${rows[0].username} (${rows[0].mime}, ~${lib.formatSize(rows[0].size)})`); return await e.reply(`f0ckrnd: ${cfg.main.url.full}/${rows[0].id} by: ${rows[0].username} (${rows[0].mime}, ~${lib.formatSize(rows[0].size)})`);
} }
}]; }];
}; };

View File

@ -51,7 +51,7 @@ export default async bot => {
where src = ${link} where src = ${link}
`; `;
if(q_repost.length > 0) if(q_repost.length > 0)
return e.reply(`repost motherf0cker (link): ${cfg.main.url.full}/${q_repost[0].id}`); return await e.reply(`repost motherf0cker (link): ${cfg.main.url.full}/${q_repost[0].id}`);
// generate uuid // generate uuid
const uuid = (await db` const uuid = (await db`
@ -80,7 +80,9 @@ export default async bot => {
let filename = `${uuid}.${meta.ext}`; let filename = `${uuid}.${meta.ext}`;
e.reply(`[charging the f0cker] downloading: ${uuid}`); const msg = await e.reply(`[charging the f0cker] downloading: ${uuid}`, {
disable_notification: true
});
// download data // download data
const start = new Date(); const start = new Date();
@ -94,8 +96,11 @@ export default async bot => {
//change 720 to any other available resolution, higher = better quality but bigger filesize //change 720 to any other available resolution, higher = better quality but bigger filesize
} }
if(source.match(/larger than/)) if(source.match(/larger than/)) {
return e.reply("too large lol"); if(e.type == 'tg')
return await e.editMessageText(msg.result.chat.id, msg.result.message_id, "too large lol");
return await e.reply("too large lol");
}
const end = ~~((new Date() - start) / 1e3); const end = ~~((new Date() - start) / 1e3);
// generate checksum // generate checksum
@ -104,8 +109,11 @@ export default async bot => {
// mime check // mime check
const mime = (await exec(`file --mime-type -b ./tmp/${filename}`)).stdout.trim(); const mime = (await exec(`file --mime-type -b ./tmp/${filename}`)).stdout.trim();
if(!Object.keys(cfg.mimes).includes(mime)) if(!Object.keys(cfg.mimes).includes(mime)) {
return e.reply(`lol, go f0ck yourself (${mime})`); if(e.type == 'tg')
return e.editMessageText(msg.result.chat.id, msg.result.message_id, `lol, go f0ck yourself (${mime})`);
return await e.reply(`lol, go f0ck yourself (${mime})`);
}
if(!Object.values(cfg.mimes).includes(meta.ext.toLowerCase())) { if(!Object.values(cfg.mimes).includes(meta.ext.toLowerCase())) {
let tmpext = cfg.mimes[meta.ext.toLowerCase()]; let tmpext = cfg.mimes[meta.ext.toLowerCase()];
@ -119,8 +127,11 @@ export default async bot => {
from "items" from "items"
where checksum = ${checksum} where checksum = ${checksum}
`; `;
if(q_repostc.length > 0) if(q_repostc.length > 0) {
return e.reply(`repost motherf0cker (checksum): ${cfg.main.url.full}/${q_repostc[0].id}`); if(e.type == 'tg')
return e.editMessageText(msg.result.chat.id, msg.result.message_id, `repost motherf0cker (checksum): ${cfg.main.url.full}/${q_repostc[0].id}`);
return await e.reply(`repost motherf0cker (checksum): ${cfg.main.url.full}/${q_repostc[0].id}`);
}
await fs.promises.copyFile(`./tmp/${filename}`, `./public/b/${filename}`); await fs.promises.copyFile(`./tmp/${filename}`, `./public/b/${filename}`);
await fs.promises.unlink(`./tmp/${filename}`).catch(_=>{}); await fs.promises.unlink(`./tmp/${filename}`).catch(_=>{});
@ -240,15 +251,43 @@ export default async bot => {
} }
} catch(err) { } catch(err) {
console.error(err); console.error(err);
}*/ }
const outputmsg = `[f0cked] link: ${cfg.main.url.full}/${itemid} | size: ${lib.formatSize(size)} | speed: ${speed}` + (tags.length > 0 ? ` | tags: ${tags.join(', ')} (score: ${score.toFixed(2)})` : '');
*/
/*e.reply([ const outputmsgirc = `[f0cked] link: ${cfg.main.url.full}/${itemid} | size: ${lib.formatSize(size)} | speed: ${speed}`;
`[f0cked] link: ${cfg.main.url.full}/${itemid} | size: ${lib.formatSize(size)} | speed: ${speed}` + (tags.length > 0 ? ` | tags: ${tags.join(', ')} (score: ${score.toFixed(2)})` : '') const outputmsgtg = `[f0cked] size: ${lib.formatSize(size)} | speed: ${speed}`;
]);*/
e.reply([
`[f0cked] link: ${cfg.main.url.full}/${itemid} | size: ${lib.formatSize(size)} | speed: ${speed}`
]);
if(e.type == 'tg') {
await e.deleteMessage(msg.result.chat.id, msg.result.message_id);
await e.reply(outputmsgtg, {
reply_markup: JSON.stringify({
inline_keyboard: [[
{ text: 'sfw', callback_data: `b_sfw:${itemid}` },
{ text: 'nsfw', callback_data: `b_nsfw:${itemid}` },
{ text: 'tags', callback_data: `b_tags:${itemid}` },
{ text: '❌ delete', callback_data: `b_delete:${itemid}` }
], [
{ text: `open f0ck #${itemid}`, url: `${cfg.main.url.full}/${itemid}` }
]]
})
});
/*await e.editMessageText(msg.result.chat.id, msg.result.message_id, outputmsgtg, {
reply_markup: JSON.stringify({
inline_keyboard: [[
{ text: 'sfw', callback_data: `b_sfw:${itemid}` },
{ text: 'nsfw', callback_data: `b_nsfw:${itemid}` },
{ text: 'tags', callback_data: `b_tags:${itemid}` },
{ text: '❌ delete', callback_data: `b_delete:${itemid}` }
], [
{ text: `open f0ck #${itemid}`, url: `${cfg.main.url.full}/${itemid}` }
]]
})
});*/
}
else {
await e.reply(outputmsgirc);
}
}); });
} }
}]; }];

View File

@ -12,11 +12,11 @@ export default async bot => {
f: async e => { f: async e => {
const id = +e.args[1]; const id = +e.args[1];
if(!id) if(!id)
return e.reply("lol no"); return await e.reply("lol no");
const tags = (await lib.getTags(id)).map(t => t.tag); const tags = (await lib.getTags(id)).map(t => t.tag);
if(tags.length === 0) if(tags.length === 0)
return e.reply(`item ${cfg.main.url.full}/${id} has no tags!`); return await e.reply(`item ${cfg.main.url.full}/${id} has no tags!`);
return e.reply(`item ${cfg.main.url.full}/${id} is tagged as: ${tags.join(', ')}`); return await e.reply(`item ${cfg.main.url.full}/${id} is tagged as: ${tags.join(', ')}`);
} }
}, { }, {
name: "tags add", name: "tags add",
@ -26,7 +26,7 @@ export default async bot => {
f: async e => { f: async e => {
const id = +e.args[1]; const id = +e.args[1];
if(!id) if(!id)
return e.reply("lol no"); return await e.reply("lol no");
const tags = (await lib.getTags(id)).map(t => t.tag); const tags = (await lib.getTags(id)).map(t => t.tag);
@ -35,7 +35,7 @@ export default async bot => {
: e.args.splice(2)).filter(t => !tags.includes(t) && t.length > 0); : e.args.splice(2)).filter(t => !tags.includes(t) && t.length > 0);
if(newtags.length === 0) if(newtags.length === 0)
return e.reply("no (new) tags provided"); return await e.reply("no (new) tags provided");
await Promise.all(newtags.map(async ntag => { await Promise.all(newtags.map(async ntag => {
try { try {
@ -73,8 +73,8 @@ export default async bot => {
const ntags = (await lib.getTags(id)).map(t => t.tag); const ntags = (await lib.getTags(id)).map(t => t.tag);
if(ntags.length === 0) if(ntags.length === 0)
return e.reply(`item ${cfg.main.url.full}/${id} has no tags!`); return await e.reply(`item ${cfg.main.url.full}/${id} has no tags!`);
return e.reply(`item ${cfg.main.url.full}/${id} is now tagged as: ${ntags.join(', ')}`); return await e.reply(`item ${cfg.main.url.full}/${id} is now tagged as: ${ntags.join(', ')}`);
} }
}, { }, {
name: "tags remove", name: "tags remove",
@ -84,7 +84,7 @@ export default async bot => {
f: async e => { f: async e => {
const id = +e.args[1]; const id = +e.args[1];
if(!id) if(!id)
return e.reply("lol no"); return await e.reply("lol no");
const tags = await lib.getTags(id); const tags = await lib.getTags(id);
@ -93,7 +93,7 @@ export default async bot => {
: e.args.splice(2)).filter(t => t.length > 0); : e.args.splice(2)).filter(t => t.length > 0);
if(removetags.length === 0) if(removetags.length === 0)
return e.reply("no tags provided"); return await e.reply("no tags provided");
const res = await Promise.all(removetags.map(async rtag => { const res = await Promise.all(removetags.map(async rtag => {
const tagid = tags.filter(t => t.tag === rtag)[0]?.id ?? null; const tagid = tags.filter(t => t.tag === rtag)[0]?.id ?? null;
@ -122,12 +122,12 @@ export default async bot => {
}; };
})); }));
e.reply(JSON.stringify(res)); await e.reply(JSON.stringify(res));
const ntags = (await lib.getTags(id)).map(t => t.tag); const ntags = (await lib.getTags(id)).map(t => t.tag);
if(ntags.length === 0) if(ntags.length === 0)
return e.reply(`item ${cfg.main.url.full}/${id} has no tags!`); return await e.reply(`item ${cfg.main.url.full}/${id} has no tags!`);
return e.reply(`item ${cfg.main.url.full}/${id} is now tagged as: ${ntags.join(', ')}`); return await e.reply(`item ${cfg.main.url.full}/${id} is now tagged as: ${ntags.join(', ')}`);
} }
}] }]
}; };

133
views/snippets/navbar2.html Normal file
View File

@ -0,0 +1,133 @@
@if(session)
<nav class="navbar navbar-expand-lg">
<a class="navbar-brand" href="/"><span class="f0ck" width="" height="">F0CK</span></a>
<div class="navigation-links">
<ul class="navbar-nav">
<li class="nav-item dropdown">
<a class="nav-link" href="#" content="{{ session.user }}" data-toggle="dropdown">
<img src="@if(session.avatar)/t/{{ session.avatar }}.webp@else/s/img/ava/default.png@endif" class="avatar" /><span>{{ session.user }}</span>
</a>
<ul class="dropdown-menu">
<li><a href="/admin">adminpanel</a></li>
<li><a href="/user/{{ session.user.toLowerCase() }}/f0cks">my f0cks</a></li>
<li><a href="/user/{{ session.user.toLowerCase() }}/favs">my favs</a></li>
<li><a href="/settings">settings</a></li>
<li><a href="/search">search</a></li>
<li><a href="/about">About</a></li>
<li><a href="/ranking">Ranking</a></li>
<li><a href="/logout">logout</a></li>
</ul>
</li>
<li class="nav-item dropdown" id="themes">
<a class="nav-link ddcontent" href="#" content="{{ theme }}" data-toggle="dropdown">Themes</a>
<ul class="dropdown-menu">
@each(themes as t)
<li><a href="/theme/{{ t }}">{{ t }}</a></li>
@endeach
</ul>
</li>
<li class="nav-item dropdown">
<a class="nav-link ddcontent" href="#"@if(tmp?.mime) content="{{ tmp?.mime }}" data-toggle="dropdown"@endif>Filter@if(!tmp?.mime)&nbsp;&#9660;@endif</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="/@if(tmp?.user)user/{{ tmp?.user }}/@endif">All</a></li>
<li><a class="dropdown-item" href="/@if(tmp?.user)user/{{ tmp?.user }}/@endifaudio">Audio</a></li>
<li><a class="dropdown-item" href="/@if(tmp?.user)user/{{ tmp?.user }}/@endifvideo">Video</a></li>
<li><a class="dropdown-item" href="/@if(tmp?.user)user/{{ tmp?.user }}/@endifimage">Image</a></li>
</ul>
</li>
<li class="nav-item @if(session)dropdown@endif">
<a class="nav-link ddcontent" href="#"@if(typeof session.mode !== "undefined") content="{{ modes[session.mode] ?? 'sfw' }}" data-toggle="dropdown"@endif>Mode</a>
<ul class="dropdown-menu">
@for(let i = 0; i < modes.length; i++)
<li><a class="dropdown-item" href="/mode/{{ i }}">{{ modes[i] }}</a></li>
@endfor
</ul>
</li>
<li class="nav-item">
<a id="random" class="nav-link" href="/random">
<span class="nav-link-identifier">Random</span>
</a>
</li>
</ul>
</div>
<div class="collapse navbar-collapse show" id="navbarSupportedContent">
<div class="pagination-container-fluid">
<div class="pagination-wrapper">
@if(typeof pagination !== "undefined")
<nav class="pagination">
<a href="{{ link.main }}{{ link.path }}{{ pagination.start }}" class="page-item-1 btn start@if(!pagination.prev) disabled@endif">&laquo;</a>
<a href="{{ link.main }}{{ link.path }}{{ pagination.prev }}" class="page-item-2 btn prev@if(!pagination.prev) disabled@endif">&lsaquo;</a>
@each(pagination.cheat as i)
@if(i == pagination.page)
<span class="btn disabled">{{ i }}</span>
@else
<a href="{{ link.main }}{{ link.path }}{{ i }}" class="pagination-int-item btn">{{ i }}</a>
@endif
@endeach
<a href="{{ link.main }}{{ link.path }}{{ pagination.next }}" class="page-item-3 btn next@if(!pagination.next) disabled@endif">&rsaquo;</a>
<a href="{{ link.main }}{{ link.path }}{{ pagination.end }}" class="page-item-4 btn start@if(!pagination.next) disabled@endif">&raquo;</a>
</nav>
@endif
</div>
</div>
</div>
</nav>
@else
<nav class="navbar navbar-expand-lg">
<a class="navbar-brand" href="/"><span class="f0ck" width="" height="">F0CK</span></a>
<div class="navigation-links-guest">
<ul class="navbar-nav-guests">
<li class="nav-item dropdown">
<a class="nav-link" href="/about" data-toggle="dropdown">About</a>
<ul class="dropdown-menu">
<li><a href="/login">login</a></li>
</ul>
</li>
<li class="nav-item dropdown" id="themes">
<a class="nav-link ddcontent" href="#" content="{{ theme }}" data-toggle="dropdown">Themes</a>
<ul class="dropdown-menu">
@each(themes as t)
<li><a href="/theme/{{ t }}">{{ t }}</a></li>
@endeach
</ul>
</li>
<li class="nav-item dropdown">
<a class="nav-link ddcontent" href="#"@if(tmp?.mime) content="{{ tmp?.mime }}" data-toggle="dropdown"@endif>Filter@if(!tmp?.mime)&nbsp;&#9660;@endif</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="/@if(tmp?.user)user/{{ tmp?.user }}/@endif">All</a></li>
<li><a class="dropdown-item" href="/@if(tmp?.user)user/{{ tmp?.user }}/@endifaudio">Audio</a></li>
<li><a class="dropdown-item" href="/@if(tmp?.user)user/{{ tmp?.user }}/@endifvideo">Video</a></li>
<li><a class="dropdown-item" href="/@if(tmp?.user)user/{{ tmp?.user }}/@endifimage">Image</a></li>
</ul>
</li>
<li class="nav-item">
<a id="random" class="nav-link" href="/random">
<span class="nav-link-identifier">Random</span>
</a>
</li>
</ul>
</div>
<div class="collapse navbar-collapse show" id="navbarSupportedContent">
<div class="pagination-container-fluid">
<div class="pagination-wrapper">
@if(typeof pagination !== "undefined")
<nav class="pagination">
<a href="{{ link.main }}{{ link.path }}{{ pagination.start }}" class="page-item-1 btn start@if(!pagination.prev) disabled@endif">&laquo;</a>
<a href="{{ link.main }}{{ link.path }}{{ pagination.prev }}" class="page-item-2 btn prev@if(!pagination.prev) disabled@endif">&lsaquo;</a>
@each(pagination.cheat as i)
@if(i == pagination.page)
<span class="btn disabled">{{ i }}</span>
@else
<a href="{{ link.main }}{{ link.path }}{{ i }}" class="pagination-int-item btn">{{ i }}</a>
@endif
@endeach
<a href="{{ link.main }}{{ link.path }}{{ pagination.next }}" class="page-item-3 btn next@if(!pagination.next) disabled@endif">&rsaquo;</a>
<a href="{{ link.main }}{{ link.path }}{{ pagination.end }}" class="page-item-4 btn start@if(!pagination.next) disabled@endif">&raquo;</a>
</nav>
@endif
</div>
</div>
</div>
</nav>
@endif