import cfg from "../../../config.json" assert { type: "json" }; import sql from "../sql.mjs"; import lib from "../lib.mjs"; import fs from "fs"; import url from "url"; const allowedMimes = [ "audio", "image", "video", "%" ]; const auth = async (req, res, next) => { if(!req.session) return res.redirect("/login"); return next(); }; export default (router, tpl) => { router.get(/^\/(audio\/?|image\/?|video\/?)?(p\/\d+)?$/, async (req, res) => { const tmpmime = (allowedMimes.filter(n => req.url.split[0].startsWith(n))[0] ? req.url.split[0] : ""); const mime = tmpmime + "%"; const tmp = tmpmime == "audio" ? lib.getMode(0) : lib.getMode(req.session.mode ?? 0); const total = ( await sql("items") .whereRaw(tmp) .andWhere("items.mime", "like", mime) .count("* as total") )[0].total; const pages = +Math.ceil(total / cfg.websrv.eps); const page = Math.min(pages, +req.url.split[tmpmime.length > 0 ? 2 : 1] || 1); const offset = (page - 1) * cfg.websrv.eps; const rows = await sql("items") .select("items.id", "items.mime", "tags_assign.tag_id") .joinRaw("left join tags_assign on tags_assign.item_id = items.id and (tags_assign.tag_id = 1 or tags_assign.tag_id = 2)") .whereRaw(tmp) .andWhere("items.mime", "like", mime) .orderBy("items.id", "desc") .offset(offset) .limit(cfg.websrv.eps); let cheat = []; for(let i = Math.max(1, page - 3); i <= Math.min(page + 3, pages); i++) cheat.push(i); rows.forEach(e => { if(!fs.existsSync(`public/t/${e.id}.png`)) fs.copyFileSync("public/s/img/broken.png", `public/t/${e.id}.png`); }); const data = { items: rows, pagination: { start: 1, end: pages, prev: (page > 1) ? page - 1 : null, next: (page < pages) ? page + 1 : null, page: page, cheat: cheat, link: `/${tmpmime ? tmpmime + "/" : ""}p/` }, last: rows[rows.length - 1].id, filter: tmpmime ? tmpmime : undefined }; res.reply({ body: tpl.render("index", data, req) }); }); router.get(/^\/((audio\/|video\/|image\/)?[0-9]+)$/, async (req, res) => { let id = false; let mime = ""; let tmpmime = false; if(allowedMimes.filter(n => req.url.split[0].startsWith(n))[0] ? req.url.split[0] : "") { mime = tmpmime = req.url.split[0]; id = +req.url.split[1]; } else { mime = "%"; id = +req.url.split[0]; } mime += "/%"; let tmp = tmpmime == "audio" ? lib.getMode(0) : lib.getMode(req.session.mode ?? 0); if(id == 404) tmp = ""; const query = (await sql("items") .whereRaw(tmp) .andWhere("id", id) .andWhere("mime", "like", mime) .limit(1)) ?.shift(); if(!query?.id) return res.redirect("/404"); const tags = await sql("tags_assign").leftJoin("tags", "tags.id", "tags_assign.tag_id").where("tags_assign.item_id", id); const qmin = await sql("items").select("id").whereRaw(tmp).andWhere("mime", "like", mime).orderBy("id").limit(1); const qmax = await sql("items").select("id").whereRaw(tmp).andWhere("mime", "like", mime).orderBy("id", "desc").limit(1); const qnext = (await sql("items").select("id").whereRaw(tmp).andWhere("id", ">", id).andWhere("mime", "like", mime).orderBy("id").limit(3)).reverse(); const qprev = await sql("items").select("id").whereRaw(tmp).andWhere("id", "<", id).andWhere("mime", "like", mime).orderBy("id", "desc").limit(3); const cheat = qnext.concat([{ id: id }].concat(qprev)).map(e => +e.id); const next = qnext[qnext.length - 1] ? qnext[qnext.length - 1].id : false; const prev = qprev[0] ? qprev[0].id : false; for(let t = 0; t < tags.length; t++) tags[t].tag = tags[t].tag.replace(/[\u00A0-\u9999<>\&]/g, i => '&#'+i.charCodeAt(0)+';'); const data = { user: { name: query.username, channel: query.userchannel, network: query.usernetwork }, item: { id: query.id, src: { long: query.src, short: url.parse(query.src).hostname, }, thumbnail: `${cfg.websrv.paths.thumbnails}/${query.id}.png`, coverart: `${cfg.websrv.paths.coverarts}/${query.id}.png`, dest: `${cfg.websrv.paths.images}/${query.dest}`, mime: query.mime, size: lib.formatSize(query.size), timestamp: lib.timeAgo(new Date(query.stamp * 1e3).toISOString()), tags: tags }, title: `${query.id} - f0ck.me`, pagination: { start: qmax[0].id, end: qmin[0].id, prev: next, next: prev, page: query.id, cheat: cheat, link: `/${tmpmime ? tmpmime + "/" : ""}` }, filter: tmpmime ? tmpmime : undefined }; res.reply({ body: tpl.render("item", data, req) }); }); router.get(/^\/(about)$/, (req, res) => { res.reply({ body: tpl.render(req.url.split[0], {}, req) }); }); router.get(/^\/mode\/(\d)/, auth, async (req, res) => { const mode = +req.url.split[1]; let referertmp = req.headers.referer?.split("/"); let referer = ""; if(referertmp.length && ['image','audio','video'].includes(referertmp[3])) referer = referertmp[3]; if(cfg.allowedModes[mode]) { await sql("user_options") .insert({ user_id: req.session.id, mode: mode, theme: req.theme ?? "f0ck" }) .onConflict("user_id") .merge(); } res.redirect(`/${referer}`); }); return router; };