master #50
|
@ -803,6 +803,10 @@ html[theme="f0ck95"] .badge-danger {
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
html[theme="f0ck95"] img.avatar {
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
html[theme="f0ck95"] ._204863 {
|
html[theme="f0ck95"] ._204863 {
|
||||||
content: " ";
|
content: " ";
|
||||||
background: -webkit-linear-gradient(left,#08216b,#a5cef7);
|
background: -webkit-linear-gradient(left,#08216b,#a5cef7);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import db from "../sql.mjs";
|
import db from "../sql.mjs";
|
||||||
import lib from "../lib.mjs";
|
import lib from "../lib.mjs";
|
||||||
import { exec } from "child_process";
|
import { exec } from "child_process";
|
||||||
|
import { promises as fs } from "fs";
|
||||||
|
|
||||||
const auth = async (req, res, next) => {
|
const auth = async (req, res, next) => {
|
||||||
if(!req.session) {
|
if(!req.session) {
|
||||||
|
@ -130,5 +131,61 @@ export default (router, tpl) => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
router.get(/^\/admin\/recover\/?/, auth, async (req, res) => {
|
||||||
|
if(req.url.qs?.id) {
|
||||||
|
const id = +req.url.qs.id;
|
||||||
|
const f0ck = await db`
|
||||||
|
select dest, mime
|
||||||
|
from "items"
|
||||||
|
where
|
||||||
|
id = ${id} and
|
||||||
|
active = 'false'
|
||||||
|
limit 1
|
||||||
|
`;
|
||||||
|
if(f0ck.length === 0) {
|
||||||
|
return res.reply({
|
||||||
|
body: `f0ck ${id}: f0ck not found`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
await db`update "items" set active = 'true' where id = ${id}`;
|
||||||
|
|
||||||
|
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(_=>{});
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.reply({
|
||||||
|
body: `f0ck ${id} recovered. <a href="/admin/recover">back</a>`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const _posts = await db`
|
||||||
|
select id, mime, username
|
||||||
|
from "items"
|
||||||
|
where
|
||||||
|
active = 'false'
|
||||||
|
`;
|
||||||
|
|
||||||
|
if(_posts.length === 0) {
|
||||||
|
return res.reply({
|
||||||
|
body: 'blah'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const posts = await Promise.all(_posts.map(async p => ({ ...p, thumbnail: (await fs.readFile(`./deleted/t/${p.id}.webp`)).toString('base64') })));
|
||||||
|
|
||||||
|
res.reply({
|
||||||
|
body: tpl.render('admin/recover', {
|
||||||
|
posts
|
||||||
|
}, req)
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
return router;
|
return router;
|
||||||
};
|
};
|
||||||
|
|
|
@ -137,7 +137,7 @@ export default async bot => {
|
||||||
userchannel: e.channel,
|
userchannel: e.channel,
|
||||||
usernetwork: e.network,
|
usernetwork: e.network,
|
||||||
stamp: ~~(new Date() / 1000),
|
stamp: ~~(new Date() / 1000),
|
||||||
active: 'true'
|
active: true
|
||||||
}, 'src', 'dest', 'mime', 'size', 'checksum', 'username', 'userchannel', 'usernetwork', 'stamp', 'active')
|
}, 'src', 'dest', 'mime', 'size', 'checksum', 'username', 'userchannel', 'usernetwork', 'stamp', 'active')
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
24
views/admin/recover.html
Normal file
24
views/admin/recover.html
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
@include(snippets/header_admin)
|
||||||
|
<table class="table" style="width: 100%">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td>ID</td>
|
||||||
|
<td>f0cker</td>
|
||||||
|
<td>mime</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
@each(posts as post)
|
||||||
|
<tr>
|
||||||
|
<td><img src="data:image/webp;base64,{{ post.thumbnail }}" /></td>
|
||||||
|
<td>{{ post.id }}</td>
|
||||||
|
<td>{{ post.username }}</td>
|
||||||
|
<td>{{ post.mime }}</td>
|
||||||
|
<td><a href="/admin/recover/?id={{ post.id }}">recover</a></td>
|
||||||
|
</tr>
|
||||||
|
@endeach
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
@include(snippets/footer)
|
|
@ -25,7 +25,7 @@
|
||||||
@endif
|
@endif
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item dropdown" id="themes">
|
<li class="nav-item dropdown" id="themes">
|
||||||
<a class="nav-link ddcontent" href="#" content="{{ theme }}" data-toggle="dropdown">Theme</a>
|
<a class="nav-link ddcontent" href="#" content="{{ theme }}" data-toggle="dropdown">Themes</a>
|
||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu">
|
||||||
@each(themes as t)
|
@each(themes as t)
|
||||||
<li><a href="/theme/{{ t }}">{{ t }}</a></li>
|
<li><a href="/theme/{{ t }}">{{ t }}</a></li>
|
||||||
|
|
|
@ -20,6 +20,11 @@
|
||||||
<span class="nav-link-identifier">Log</span>
|
<span class="nav-link-identifier">Log</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="/admin/recover">
|
||||||
|
<span class="nav-link-identifier">Recover</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" href="/logout">Logout</a>
|
<a class="nav-link" href="/logout">Logout</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user