diff --git a/config_example.json b/config_example.json index 59ab748..c67bd3f 100644 --- a/config_example.json +++ b/config_example.json @@ -14,6 +14,7 @@ }, "allowedModes": [ "sfw", "nsfw", "untagged", "all" ], "allowedMimes": [ "audio", "image", "video" ], + "nsfp": [], "websrv": { "port": "8080", "paths": { diff --git a/src/inc/lib.mjs b/src/inc/lib.mjs index d320541..ab701d7 100644 --- a/src/inc/lib.mjs +++ b/src/inc/lib.mjs @@ -63,7 +63,7 @@ export default new class { const link = []; if(env.tag) link.push("tag", env.tag); if(env.user) link.push("user", env.user, env.type ?? 'f0cks'); - if(env.mime.length > 2) link.push(env.mime); + if(env.mime?.length > 2) link.push(env.mime); let tmp = link.length === 0 ? '/' : link.join('/'); if(!tmp.endsWith('/')) diff --git a/src/inc/routeinc/f0cklib.mjs b/src/inc/routeinc/f0cklib.mjs index 836ecfb..93654b9 100644 --- a/src/inc/routeinc/f0cklib.mjs +++ b/src/inc/routeinc/f0cklib.mjs @@ -4,166 +4,80 @@ import cfg from "../config.mjs"; import fs from "fs"; import url from "url"; +const globalfilter = cfg.nsfp.map(n => `tag_id = ${n}`).join(' or '); + export default { - getf0cks: async (o = { user, tag, mime, page, mode, fav }) => { + getf0cks: async (o = { user, tag, mime, page, mode, fav, session }) => { const user = o.user ? decodeURI(o.user) : null; const tag = lib.parseTag(o.tag ?? null); - const mime = (o.mime ?? ""); + const mime = o.mime ?? null; const page = +(o.page ?? 1); const smime = cfg.allowedMimes.includes(mime) ? mime + "/%" : mime === "" ? "%" : "%"; - const tmp = { user, tag, mime, smime, page }; - + const tmp = { user, tag, mime, smime, page, mode: o.mode }; const modequery = mime == "audio" ? lib.getMode(0) : lib.getMode(o.mode ?? 0); - - let data; - let total; - if(tag) { - if(tag.match(/sfw/) || tag.length <= 2) - return { - success: false, - message: "nope." - }; + const total = (await db` + select distinct on (items.id) + count(items.id) as total + from items + left join tags_assign on tags_assign.item_id = items.id + left join tags on tags.id = tags_assign.tag_id + left join favorites on favorites.item_id = items.id + left join "user" on "user".id = favorites.user_id + where + ${ db.unsafe(modequery) } + ${ tag ? db`and tags.normalized ilike ${'%'+tag+'%'}` : db`` } + ${ o.fav ? db`and "user".user ilike ${'%'+user+'%'}` : db`` } + ${ user ? db`and items.username ilike ${'%'+user+'%'}` : db`` } + ${ mime ? db`and items.mime ilike ${smime}` : db`` } + ${ !o.session ? db`and items.id not in (select item_id from tags_assign where item_id = items.id and (${db.unsafe(globalfilter)}))` : db`` } + group by items.id, tags.tag + `)?.length || 0; - total = await db` - select count(*) as total - from items - inner join ( - select tags_assign.item_id, tags.tag - from tags - left join tags_assign on tags_assign.tag_id = tags.id - where tags.tag ilike ${'%' + (tag ? tag : '') + '%'} - group by tags_assign.item_id, tags.tag - ) as st on st.item_id = items.id - where ${db.unsafe(modequery)} - group by st.tag, st.item_id`; - - total = total?.length; - } - else { - if(!o.fav) { - total = await db` - select count(*) as total - from items - where ${db.unsafe(modequery)} - and items.mime ilike ${smime} - and items.username ilike ${user ? user : '%'} - `; - total = total[0].total; - } - else { - total = await db` - select count(*) as total - from "favorites" - left join "user" on "user".id = "favorites".user_id - left join "tags_assign" on "tags_assign".item_id = "favorites".item_id - left join "tags" on "tags".id = "tags_assign".tag_id - left join "items" on "items".id = "favorites".item_id - where ${db.unsafe(modequery)} - and "items".mime ilike ${smime} - and "user".user ilike ${user} - group by "items".id - `; - total = total[0]?.total ?? 0; - } - } - - if(!total || total.length === 0) + if(!total || total === 0) { return { success: false, message: "404 - no f0cks given" }; - + } + 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); - let rows; + const rows = await db` + select distinct on (items.id) + items.id, + items.mime, + tags.tag, + ta.tag_id + from items + left join tags_assign on tags_assign.item_id = items.id + left join tags on tags.id = tags_assign.tag_id + left join favorites on favorites.item_id = items.id + left join "user" on "user".id = favorites.user_id + left join tags_assign ta on ta.item_id = items.id and (ta.tag_id = 1 or ta.tag_id = 2) + where + ${ db.unsafe(modequery) } + ${ tag ? db`and tags.normalized ilike ${'%'+tag+'%'}` : db`` } + ${ o.fav ? db`and "user".user ilike ${'%'+user+'%'}` : db`` } + ${ user ? db`and items.username ilike ${'%'+user+'%'}` : db`` } + ${ mime ? db`and items.mime ilike ${smime}` : db`` } + ${ !o.session ? db`and items.id not in (select item_id from tags_assign where item_id = items.id and (${db.unsafe(globalfilter)}))` : db`` } + group by items.id, tags.tag, ta.tag_id + order by items.id desc + offset ${offset} + limit ${cfg.websrv.eps} + `; - if(!o.fav) { - rows = db` - select "items".id, "items".mime, "tags_assign".tag_id - from "items" - left join "tags_assign" on "tags_assign".item_id = "items".id and ("tags_assign".tag_id = 1 or "tags_assign".tag_id = 2) - ${tag - ? db` - inner join ( - select "tags_assign".item_id, "tags".tag - from "tags" - left join "tags_assign" on "tags_assign".tag_id = "tags".id - where "tags".tag ilike ${'%' + tag + '%'} - group by "tags_assign".item_id, "tags".tag - ) as st on st.item_id = "items".id - ` - : db`` - } - where ${db.unsafe(modequery)} - and "items".mime ilike ${smime} - and "items".username ilike ${user ? user : '%'} - ${tag - ? db`group by st.item_id, "items".id, "tags_assign".tag_id` - : db`` - } - order by "items".id desc - offset ${offset} - limit ${cfg.websrv.eps} - `; - } - else { - rows = db` - select "items".id, "items".mime, ta.tag_id - from "favorites" - left join "user" on "user".id = "favorites".user_id - left join "tags_assign" on "tags_assign".item_id = "favorites".item_id - left join "tags" on "tags".id = "tags_assign".tag_id - left join "items" on "items".id = "favorites".item_id - left join "tags_assign" as ta on ta.item_id = "items".id and (ta.tag_id = 1 or ta.tag_id = 2) - ${ tag - ? db` - inner join ( - select "tags_assign".item_id, "tags".tag - from "tags" - left join "tags_assign" on "tags_assign".tag_id = "tags".id - where "tags".tag ilike ${'%' + tag + '%'} - group by "tags_assign".item_id, "tags".tag - ) as st on st.item_id = "items".id` - : db`` - } - where ${db.unsafe(modequery)} - and "items".mime ilike ${smime} - and "user".user ilike ${user} - ${tag - ? db`group by st.item_id, "items".id, "tags_assign".tag_id` - : db`` - } - group by "items".id, ta.tag_id - order by "items".id desc - offset ${offset} - limit ${cfg.websrv.eps} - `; - } - - rows = await rows; - - if(rows.length === 0) - return { - success: false, - message: "oopsi woopsi" - }; - - /*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, type: o.fav ? 'favs' : 'f0cks', path: 'p/' }); - data = { + return { success: true, items: rows, pagination: { @@ -177,9 +91,8 @@ export default { link, tmp }; - return data; }, - getf0ck: async (o = ({ user, tag, mime, itemid, mode })) => { + getf0ck: async (o = ({ user, tag, mime, itemid, mode, session })) => { const user = o.user ? decodeURI(o.user) : null; const tag = lib.parseTag(o.tag ?? null); const mime = (o.mime ?? ""); @@ -197,75 +110,26 @@ export default { }; } - let items; - - if(o.fav) { - items = db` - select "items".* - from "favorites" - left join "items" on "items".id = "favorites".item_id - left join "user" on "user".id = "favorites".user_id - ${ tag - ? db` - inner join ( - select "tags_assign".item_id, "tags".tag - from "tags" - left join "tags_assign" on "tags_assign".tag_id = "tags".id - where "tags".tag ilike ${'%' + tag + '%'} - group by "tags_assign".item_id, "tags".tag - ) as st on st.item_id = "items".id` - : db`` - } - where ${db.unsafe(modequery)} - and "user".user ilike ${user} - ${ mime - ? db`and "items".mime ilike ${mime + '/%'}` - : db`` - } - ${ tag - ? db`group by st.tag, st.item_id, "items".id` - : db`group by "items".id, "favorites".user_id, "favorites".item_id, "user".id` - } - order by "items".id desc - `; - } - else { - items = db` - select "items".* - from "items" - ${ tag - ? db` - inner join ( - select "tags_assign".item_id, "tags_assign".tag_id, "tags".tag - from "tags" - left join "tags_assign" on "tags_assign".tag_id = "tags".id - where "tags".tag ilike ${'%' + tag + '%'} - group by "tags_assign".item_id, "tags".tag, "tags_assign".tag_id - ) as st on st.item_id = "items".id` - : db`` - } - where ${db.unsafe(modequery)} - ${ user - ? db`and "items".username ilike ${'%' + user + '%'}` - : db`` - } - ${ mime - ? db`and "items".mime ilike ${mime + '/%'}` - : db`` - } - ${ tag - ? db`group by st.item_id, "items".id, st.tag_id` - : db`group by "items".id` - } - order by "items".id desc - `; - } + const items = await db` + select distinct on (items.id) + items.* + from items + left join tags_assign on tags_assign.item_id = items.id + left join tags on tags.id = tags_assign.tag_id + left join favorites on favorites.item_id = items.id + left join "user" on "user".id = favorites.user_id + left join tags_assign ta on ta.item_id = items.id and (ta.tag_id = 1 or ta.tag_id = 2) + where + ${ db.unsafe(modequery) } + ${ tag ? db`and tags.normalized ilike ${'%'+tag+'%'}` : db`` } + ${ o.fav ? db`and "user".user ilike ${'%'+user+'%'}` : db`` } + ${ user ? db`and items.username ilike ${'%'+user+'%'}` : db`` } + ${ mime ? db`and items.mime ilike ${smime}` : db`` } + ${ !o.session ? db`and items.id not in (select item_id from tags_assign where item_id = items.id and (${db.unsafe(globalfilter)}))` : db`` } + group by items.id, tags.tag, ta.tag_id + order by items.id desc + `; - items = await items; - - if(tag) - items = items.filter((v, i, s) => i === s.findIndex(t => t.id === v.id)); - const item = items.findIndex(i => i.id === itemid); const actitem = items[item]; @@ -334,71 +198,33 @@ export default { }; return data; }, - getRandom: async (o = ({ user, tag, mime, mode })) => { + getRandom: async (o = ({ user, tag, mime, mode, session })) => { const user = o.user ? decodeURI(o.user) : null; const tag = lib.parseTag(o.tag ?? null); const mime = (o.mime ?? ""); + const smime = cfg.allowedMimes.includes(mime) ? mime + "/%" : mime === "" ? "%" : "%"; const modequery = mime == "audio" ? lib.getMode(0) : lib.getMode(o.mode ?? 0); - let item; - if(o.fav) { // dood lol - item = db` - select "items".* - from "favorites" - left join "items" on "items".id = "favorites".item_id - left join "user" on "user".id = "favorites".user_id - ${ tag - ? db` - inner join ( - select "tags_assign".item_id, "tags".tag - from "tags" - left join "tags_assign" on "tags_assign".tag_id = "tags".id - where "tags".tag ilike ${'%' + tag + '%'} - group by "tags_assign".item_id, "tags".tag - ) as st on st.item_id = "items".id` - : db`` - } - where ${db.unsafe(modequery)} - and "user".user ilike ${user} - ${ mime - ? db`and "items".mime ilike ${mime + '/%'}` - : db`` - } - order by random() - limit 1 - `; - } - else { - item = db` - select * - from "items" - ${ tag - ? db` - inner join ( - select "tags_assign".item_id, "tags".tag - from "tags" - left join "tags_assign" on "tags_assign".tag_id = "tags".id - where "tags".tag ilike ${'%' + tag + '%'} - group by "tags_assign".item_id, "tags".tag - ) as st on st.item_id = "items".id` - : db`` - } - where ${db.unsafe(modequery)} - ${ user - ? db`and "items".username ilike ${'%' + user + '%'}` - : db`` - } - ${ mime - ? db`and "items".mime ilike ${mime + '/%'}` - : db`` - } - order by random() - limit 1 - `; - } - - item = await item; + const item = await db` + select + items.id + from items + left join tags_assign on tags_assign.item_id = items.id + left join tags on tags.id = tags_assign.tag_id + left join favorites on favorites.item_id = items.id + left join "user" on "user".id = favorites.user_id + where + ${ db.unsafe(modequery) } + ${ tag ? db`and tags.normalized ilike ${'%'+tag+'%'}` : db`` } + ${ o.fav ? db`and "user".user ilike ${'%'+user+'%'}` : db`` } + ${ user ? db`and items.username ilike ${'%'+user+'%'}` : db`` } + ${ mime ? db`and items.mime ilike ${smime}` : db`` } + ${ !o.session ? db`and items.id not in (select item_id from tags_assign where item_id = items.id and (${db.unsafe(globalfilter)}))` : db`` } + group by items.id, tags.tag + order by random() + limit 1 + `; if(item.length === 0) { return { diff --git a/src/inc/routes/index.mjs b/src/inc/routes/index.mjs index 324f32f..5e5a6cc 100644 --- a/src/inc/routes/index.mjs +++ b/src/inc/routes/index.mjs @@ -34,12 +34,14 @@ export default (router, tpl) => { const f0cks = await f0cklib.getf0cks({ user: user, mode: req.session.mode, - fav: false + fav: false, + session: !!req.session }); const favs = await f0cklib.getf0cks({ user: user, mode: req.session.mode, - fav: true + fav: true, + session: !!req.session }); if('items' in f0cks) @@ -66,7 +68,8 @@ export default (router, tpl) => { page: req.params.page, itemid: req.params.itemid, fav: req.params.mode == 'favs', - mode: req.session.mode + mode: req.session.mode, + session: !!req.session }); if(!data.success) { return res.reply({ diff --git a/src/inc/routes/random.mjs b/src/inc/routes/random.mjs index c4917ae..6af00c1 100644 --- a/src/inc/routes/random.mjs +++ b/src/inc/routes/random.mjs @@ -19,7 +19,8 @@ export default (router, tpl) => { mime: opts.mime, page: opts.page, fav: opts.mode == 'favs', - mode: req.session.mode + mode: req.session.mode, + session: !!req.session }); if(!data.success) {