import cfg from "../config.mjs"; 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(/^\/?(?:user\/(?[a-zA-Z0-9\[\]\-\_\{\}\\`\|]+))?(?:\/(?image|audio|video))?(?:\/p\/(?\d+))?(?:\/(?\d+))?$/, async (req, res) => { router.get(/^\/?(?:tag\/(?.+?))?(?:user\/(?.+?))?(?:\/(?image|audio|video))?(?:\/p\/(?\d+))?(?:\/(?\d+))?$/, async (req, res) => { const user = req.params.user ?? null; let tag = req.params.tag ?? null; const mime = (req.params.mime ?? ""); const smime = allowedMimes.includes(mime) ? mime + "/%" : mime === "" ? "%" : "%"; const page = +(req.params.page ?? 1); const itemid = +(req.params.itemid ?? null); if(tag) tag = lib.parseTag(tag); const output = { user, tag, mime, smime, page, itemid }; const mode = itemid > 0 ? "item" : "index"; const modequery = mime == "audio" ? lib.getMode(0) : lib.getMode(req.session.mode ?? 0); let data; if(user && (await sql("items").where("username", "like", user).count("* as total"))[0].total === 0) return res.end("200 - user not found lol"); if(mode === "item") { // item! if(itemid == 404) return res.end("404 - lol"); let query = (await sql("items") .whereRaw(modequery) .andWhere("id", itemid) .andWhere("mime", "like", smime) .andWhere("username", "like", user ? user : "%") .limit(1))[0]; if(!query?.id) { // same query with sfw-mode query = (await sql("items") .whereRaw(lib.getMode(0)) .andWhere("id", itemid) .andWhere("mime", "like", smime) .andWhere("username", "like", user ? user : "%") .limit(1) )[0]; if(!query?.id) return res.end("Sorry, this f0ck either doesn't exist (yet) or hasn't been tagged yet, please remain patient, a support assistant will be shortly with you."); } const tags = await sql("tags_assign") .leftJoin("tags", "tags.id", "tags_assign.tag_id") .where("tags_assign.item_id", itemid); const qmin = await sql("items") .select("id") .whereRaw(modequery) .andWhere("mime", "like", smime) .andWhere("username", "like", user ? user : "%") .orderBy("id") .limit(1); const qmax = await sql("items") .select("id") .whereRaw(modequery) .andWhere("mime", "like", smime) .andWhere("username", "like", user ? user : "%") .orderBy("id", "desc") .limit(1); const qnext = (await sql("items") .select("id") .whereRaw(modequery) .andWhere("id", ">", itemid) .andWhere("mime", "like", smime) .andWhere("username", "like", user ? user : "%") .orderBy("id") .limit(3) ).reverse(); const qprev = await sql("items") .select("id") .whereRaw(modequery) .andWhere("id", "<", itemid) .andWhere("mime", "like", smime) .andWhere("username", "like", user ? user : "%") .orderBy("id", "desc") .limit(3); const cheat = qnext.concat([{ id: itemid }].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; const link = lib.genLink({ user, mime, act_page: query.id }); for(let t = 0; t < tags.length; t++) tags[t].tag = tags[t].tag.replace(/[\u00A0-\u9999<>\&]/g, i => '&#'+i.charCodeAt(0)+';'); data = { user: { name: query.username, channel: query.usernetwork == "Telegram" && query.userchannel !== "f0ck.me" ? "anonymous" : 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: link, uff: true }, link: link, tmp: output }; } else { // page! let total, rows; if(tag) { total = (await sql("tags") .leftJoin("tags_assign", "tags_assign.tag_id", "tags.id") .leftJoin("items", "items.id", "tags_assign.item_id") .whereRaw(modequery) .andWhere("items.mime", "like", smime) .andWhere("tags.tag", "like", '%'+tag+'%') .groupBy("items.id") .count("* as total") )[0]?.total; } else { total = (await sql("items") .whereRaw(modequery) .andWhere("items.mime", "like", smime) .andWhere("items.username", "like", user ? user : "%") .count("* as total") )[0]?.total; } if(!total || total.length === 0) return res.end("no f0cks given lol"); const pages = +Math.ceil(total / cfg.websrv.eps); const act_page = Math.min(pages, page || 1); const offset = Math.max(0, (act_page - 1) * cfg.websrv.eps); if(tag) { rows = await sql("tags") .select("items.id", "items.mime", "tags_assign.tag_id") .leftJoin("tags_assign", "tags_assign.tag_id", "tags.id") .leftJoin("items", "items.id", "tags_assign.item_id") .whereRaw(modequery) .andWhere("items.mime", "like", smime) .andWhere("tags.tag", "like", '%'+tag+'%') .orderBy("items.id", "desc") .groupBy("items.id") .offset(offset) .limit(cfg.websrv.eps); } else { 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(modequery) .andWhere("items.mime", "like", smime) .andWhere("items.username", "like", user ? user : "%") .orderBy("items.id", "desc") .offset(offset) .limit(cfg.websrv.eps); } if(rows.length === 0) return res.end("oops"); rows.forEach(e => { if(!fs.existsSync(`public/t/${e.id}.png`)) fs.copyFileSync("public/s/img/broken.png", `public/t/${e.id}.png`); }); const cheat = []; for(let i = Math.max(1, act_page - 3); i <= Math.min(act_page + 3, pages); i++) cheat.push(i); const link = lib.genLink({ user, tag, mime, act_page }); data = { items: rows, pagination: { start: 1, end: pages, prev: (act_page > 1) ? act_page - 1 : null, next: (act_page < pages) ? act_page + 1 : null, page: act_page, cheat: cheat, link: link, uff: false }, last: rows[rows.length - 1].id, link: link, tmp: output }; } res.reply({ body: tpl.render(mode, data, req) }); }); router.get(/^\/(about)$/, (req, res) => { res.reply({ body: tpl.render(req.url.split[0], { tmp: null }, req) }); }); router.get(/^\/mode\/(\d)/, auth, async (req, res) => { const mode = +req.url.split[1]; let referertmp = req.headers.referer; let referer = ""; if(referertmp.match(/f0ck\.me/)) referer = referertmp.split("/").slice(3).join("/"); 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; };