feat: Implement is_deleted flag for items, add new utility scripts, and refine UI styles.
This commit is contained in:
@@ -30,22 +30,21 @@ export default async bot => {
|
||||
f: async e => {
|
||||
logger.info(`${e.network} -> ${e.channel} -> ${e.user.nick}: ${e.message}`);
|
||||
|
||||
let [ cmd, id ] = e.opt.data.split(':');
|
||||
let [cmd, id] = e.opt.data.split(':');
|
||||
let f0ck;
|
||||
id = +id;
|
||||
|
||||
if(cmd.startsWith('b_settag_')) {
|
||||
if (cmd.startsWith('b_settag_')) {
|
||||
const tagid = +cmd.replace('b_settag_', '');
|
||||
|
||||
if(!(await lib.getTags(id)).filter(tag => tag.id == tagid).length) {
|
||||
if (!(await lib.getTags(id)).filter(tag => tag.id == tagid).length) {
|
||||
// insert
|
||||
await db`
|
||||
insert into "tags_assign" ${
|
||||
db({
|
||||
item_id: id,
|
||||
tag_id: tagid,
|
||||
user_id: 1
|
||||
})
|
||||
insert into "tags_assign" ${db({
|
||||
item_id: id,
|
||||
tag_id: tagid,
|
||||
user_id: 1
|
||||
})
|
||||
}
|
||||
`;
|
||||
}
|
||||
@@ -71,9 +70,9 @@ export default async bot => {
|
||||
});
|
||||
}
|
||||
|
||||
switch(cmd) {
|
||||
switch (cmd) {
|
||||
case "b_tags":
|
||||
if(!id)
|
||||
if (!id)
|
||||
return;
|
||||
|
||||
const keyboard = await tagkeyboard(id);
|
||||
@@ -87,9 +86,9 @@ export default async bot => {
|
||||
]]
|
||||
})
|
||||
});
|
||||
break;
|
||||
break;
|
||||
case "b_back":
|
||||
if(!id)
|
||||
if (!id)
|
||||
return;
|
||||
|
||||
await e.editMessageText(e.raw.chat.id, e.raw.message_id, e.message, {
|
||||
@@ -104,24 +103,23 @@ export default async bot => {
|
||||
]]
|
||||
})
|
||||
});
|
||||
break;
|
||||
break;
|
||||
case "b_sfw":
|
||||
|
||||
if(!id)
|
||||
|
||||
if (!id)
|
||||
return;
|
||||
|
||||
if(!await lib.hasTag(id, 1)) {
|
||||
if (!await lib.hasTag(id, 1)) {
|
||||
// insert
|
||||
await db`
|
||||
insert into "tags_assign" ${
|
||||
db({
|
||||
item_id: id,
|
||||
tag_id: 1, // sfw
|
||||
user_id: 1
|
||||
})
|
||||
insert into "tags_assign" ${db({
|
||||
item_id: id,
|
||||
tag_id: 1, // sfw
|
||||
user_id: 1
|
||||
})
|
||||
}
|
||||
`;
|
||||
if(await lib.hasTag(id, 2)) {
|
||||
if (await lib.hasTag(id, 2)) {
|
||||
await db`
|
||||
delete from "tags_assign"
|
||||
where tag_id = 2
|
||||
@@ -151,23 +149,22 @@ export default async bot => {
|
||||
})
|
||||
});
|
||||
|
||||
break;
|
||||
break;
|
||||
case "b_nsfw":
|
||||
if(!id)
|
||||
if (!id)
|
||||
return;
|
||||
|
||||
if(!await lib.hasTag(id, 2)) {
|
||||
if (!await lib.hasTag(id, 2)) {
|
||||
// insert
|
||||
await db`
|
||||
insert into "tags_assign" ${
|
||||
db({
|
||||
item_id: id,
|
||||
tag_id: 2, // nsfw
|
||||
user_id: 1
|
||||
})
|
||||
insert into "tags_assign" ${db({
|
||||
item_id: id,
|
||||
tag_id: 2, // nsfw
|
||||
user_id: 1
|
||||
})
|
||||
}
|
||||
`;
|
||||
if(await lib.hasTag(id, 1)) {
|
||||
if (await lib.hasTag(id, 1)) {
|
||||
await db`
|
||||
delete from "tags_assign"
|
||||
where tag_id = 1
|
||||
@@ -196,9 +193,9 @@ export default async bot => {
|
||||
]]
|
||||
})
|
||||
});
|
||||
break;
|
||||
break;
|
||||
case "b_delete":
|
||||
if(id <= 1)
|
||||
if (id <= 1)
|
||||
return;
|
||||
|
||||
e.user = {
|
||||
@@ -218,33 +215,33 @@ export default async bot => {
|
||||
`;
|
||||
const level = getLevel(e.user).level;
|
||||
|
||||
if(f0ck.length === 0) {
|
||||
if (f0ck.length === 0) {
|
||||
return await e.reply(`f0ck ${id}: f0ck not found`);
|
||||
}
|
||||
|
||||
if(
|
||||
|
||||
if (
|
||||
(f0ck[0].username !== (e.user.nick || e.user.username) ||
|
||||
f0ck[0].userchannel !== e.channel ||
|
||||
f0ck[0].usernetwork !== e.network) &&
|
||||
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) {
|
||||
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 db`update "items" set active = 'false', is_deleted = true 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(_ => { });
|
||||
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(_=>{});
|
||||
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, {
|
||||
@@ -259,9 +256,9 @@ export default async bot => {
|
||||
]]
|
||||
})
|
||||
});
|
||||
break;
|
||||
break;
|
||||
case "b_recover":
|
||||
if(id <= 1)
|
||||
if (id <= 1)
|
||||
return;
|
||||
|
||||
e.user = {
|
||||
@@ -270,7 +267,7 @@ export default async bot => {
|
||||
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"
|
||||
@@ -279,23 +276,23 @@ export default async bot => {
|
||||
active = 'false'
|
||||
limit 1
|
||||
`;
|
||||
|
||||
if(f0ck.length === 0) {
|
||||
|
||||
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 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: [[
|
||||
@@ -308,7 +305,7 @@ export default async bot => {
|
||||
]]
|
||||
})
|
||||
});
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
await e.reply('lol');
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ export default (router, tpl) => {
|
||||
});
|
||||
}
|
||||
|
||||
await db`update "items" set active = 'true' where id = ${id}`;
|
||||
await db`update "items" set active = 'true', is_deleted = false where id = ${id}`;
|
||||
|
||||
// Check if files need moving (if they are in deleted/)
|
||||
try {
|
||||
@@ -169,51 +169,56 @@ export default (router, tpl) => {
|
||||
const total = (await db`select count(*) as c from "items" where active = 'false'`)[0].c;
|
||||
const pages = Math.ceil(total / limit);
|
||||
|
||||
const _posts = await db`
|
||||
select id, mime, username, dest
|
||||
from "items"
|
||||
// Fetch Pending (not deleted)
|
||||
const pending = await db`
|
||||
select i.id, i.mime, i.username, i.dest, array_agg(t.tag) as tags
|
||||
from "items" i
|
||||
left join "tags_assign" ta on ta.item_id = i.id
|
||||
left join "tags" t on t.id = ta.tag_id
|
||||
where
|
||||
active = 'false'
|
||||
order by id desc
|
||||
limit ${limit} offset ${offset}
|
||||
i.active = 'false' and i.is_deleted = false
|
||||
group by i.id
|
||||
order by i.id desc
|
||||
`;
|
||||
|
||||
if (_posts.length === 0 && page > 1) {
|
||||
// if page empty, maybe redirect to last page or page 1?
|
||||
// Just render empty for now
|
||||
}
|
||||
// Fetch Trash (deleted)
|
||||
const trash = await db`
|
||||
select i.id, i.mime, i.username, i.dest, array_agg(t.tag) as tags
|
||||
from "items" i
|
||||
left join "tags_assign" ta on ta.item_id = i.id
|
||||
left join "tags" t on t.id = ta.tag_id
|
||||
where
|
||||
i.active = 'false' and i.is_deleted = true
|
||||
group by i.id
|
||||
order by i.id desc
|
||||
`;
|
||||
|
||||
if (_posts.length === 0) {
|
||||
return res.reply({
|
||||
body: tpl.render('admin/approve', { posts: [], pages: 0, page: 1, tmp: null }, req)
|
||||
});
|
||||
}
|
||||
|
||||
const posts = await Promise.all(_posts.map(async p => {
|
||||
// Try to get thumbnail from public or deleted
|
||||
let thumb;
|
||||
try {
|
||||
// Try public first
|
||||
thumb = (await fs.readFile(`./public/t/${p.id}.webp`)).toString('base64');
|
||||
} catch {
|
||||
// Helper to process thumbnails
|
||||
const processItems = async (items, isInTrash) => {
|
||||
return Promise.all(items.map(async p => {
|
||||
let thumb = '';
|
||||
const path = isInTrash ? 'deleted' : 'public';
|
||||
try {
|
||||
thumb = (await fs.readFile(`./deleted/t/${p.id}.webp`)).toString('base64');
|
||||
} catch {
|
||||
thumb = ""; // No thumbnail?
|
||||
}
|
||||
}
|
||||
return {
|
||||
...p,
|
||||
thumbnail: thumb
|
||||
};
|
||||
}));
|
||||
thumb = (await fs.readFile(`./${path}/t/${p.id}.webp`)).toString('base64');
|
||||
} catch { }
|
||||
return {
|
||||
...p,
|
||||
thumbnail: thumb,
|
||||
tags: p.tags.filter(t => t !== null)
|
||||
};
|
||||
}));
|
||||
};
|
||||
|
||||
const pendingProcessed = await processItems(pending, false);
|
||||
const trashProcessed = await processItems(trash, true);
|
||||
|
||||
res.reply({
|
||||
body: tpl.render('admin/approve', {
|
||||
posts,
|
||||
pending: pendingProcessed,
|
||||
trash: trashProcessed,
|
||||
page,
|
||||
pages,
|
||||
stats: { total: posts.length },
|
||||
stats: { total: pending.length + trash.length },
|
||||
tmp: null
|
||||
}, req)
|
||||
});
|
||||
|
||||
@@ -11,11 +11,11 @@ export default async bot => {
|
||||
f: async e => {
|
||||
let deleted = [];
|
||||
|
||||
for(let id of e.args) {
|
||||
for (let id of e.args) {
|
||||
id = +id;
|
||||
if(id <= 1)
|
||||
if (id <= 1)
|
||||
continue;
|
||||
|
||||
|
||||
const f0ck = await db`
|
||||
select dest, mime, username, userchannel, usernetwork
|
||||
from "items"
|
||||
@@ -26,36 +26,36 @@ export default async bot => {
|
||||
`;
|
||||
const level = getLevel(e.user).level;
|
||||
|
||||
if(f0ck.length === 0) {
|
||||
if (f0ck.length === 0) {
|
||||
await e.reply(`f0ck ${id}: f0ck not found`);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(
|
||||
|
||||
if (
|
||||
(f0ck[0].username !== (e.user.nick || e.user.username) ||
|
||||
f0ck[0].userchannel !== e.channel ||
|
||||
f0ck[0].usernetwork !== e.network) &&
|
||||
f0ck[0].userchannel !== e.channel ||
|
||||
f0ck[0].usernetwork !== e.network) &&
|
||||
level < 100
|
||||
) {
|
||||
await e.reply(`f0ck ${id}: insufficient permissions`);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(~~(new Date() / 1e3) >= (f0ck[0].stamp + 600) && level < 100) {
|
||||
if (~~(new Date() / 1e3) >= (f0ck[0].stamp + 600) && level < 100) {
|
||||
await e.reply(`f0ck ${id}: too late lol`);
|
||||
continue;
|
||||
}
|
||||
|
||||
await db`update "items" set active = 'false' where id = ${id}`;
|
||||
await db`update "items" set active = 'false', is_deleted = true 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(_ => { });
|
||||
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(_=>{});
|
||||
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(_ => { });
|
||||
}
|
||||
|
||||
deleted.push(id);
|
||||
@@ -71,11 +71,11 @@ export default async bot => {
|
||||
f: async e => {
|
||||
let recovered = [];
|
||||
|
||||
for(let id of e.args) {
|
||||
for (let id of e.args) {
|
||||
id = +id;
|
||||
if(id <= 1)
|
||||
if (id <= 1)
|
||||
continue;
|
||||
|
||||
|
||||
const f0ck = await db`
|
||||
select dest, mime
|
||||
from "items"
|
||||
@@ -85,19 +85,19 @@ export default async bot => {
|
||||
limit 1
|
||||
`;
|
||||
|
||||
if(f0ck.length === 0) {
|
||||
if (f0ck.length === 0) {
|
||||
await e.reply(`f0ck ${id}: f0ck not found`);
|
||||
continue;
|
||||
}
|
||||
|
||||
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(_=>{});
|
||||
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(_=>{});
|
||||
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}`;
|
||||
|
||||
Reference in New Issue
Block a user