diff --git a/src/inc/routes/admin.mjs b/src/inc/routes/admin.mjs index 71f09d0..b2dfd60 100644 --- a/src/inc/routes/admin.mjs +++ b/src/inc/routes/admin.mjs @@ -12,7 +12,7 @@ import cfg from "../config.mjs"; import security from "../security.mjs"; import crypto from "crypto"; import path from "path"; -import { getManualApproval, setManualApproval, getMinTags, setMinTags, getRegistrationOpen, setRegistrationOpen, getTrustedUploads, setTrustedUploads, getEnablePdf, setEnablePdf, getLogUserIps, setLogUserIps, getHashUserIps, setHashUserIps, getEnableCleanup, setEnableCleanup, getCleanupStartDate, setCleanupStartDate, getCleanupEndDate, setCleanupEndDate, getShitpostMode } from "../settings.mjs"; +import { getManualApproval, setManualApproval, getMinTags, setMinTags, getRegistrationOpen, setRegistrationOpen, getTrustedUploads, setTrustedUploads, getEnablePdf, setEnablePdf, getLogUserIps, setLogUserIps, getHashUserIps, setHashUserIps, getEnableCleanup, setEnableCleanup, getCleanupStartDate, setCleanupStartDate, getCleanupEndDate, setCleanupEndDate, getCleanupIncludeEngaged, setCleanupIncludeEngaged, getShitpostMode } from "../settings.mjs"; export default (router, tpl) => { router.get(/^\/login(\/)?$/, async (req, res) => { @@ -661,6 +661,7 @@ export default (router, tpl) => { enable_cleanup: getEnableCleanup(), cleanup_start_date: getCleanupStartDate(), cleanup_end_date: getCleanupEndDate(), + cleanup_include_engaged: getCleanupIncludeEngaged(), totals: await lib.countf0cks(), tmp: null }; @@ -674,15 +675,18 @@ export default (router, tpl) => { try { const cleanup_start_date = req.post.cleanup_start_date || ''; const cleanup_end_date = req.post.cleanup_end_date || ''; + const cleanup_include_engaged = req.post.cleanup_include_engaged === 'true' || req.post.cleanup_include_engaged === 'on' || req.post.cleanup_include_engaged === '1'; await db`INSERT INTO site_settings (key, value) VALUES ('cleanup_start_date', ${cleanup_start_date}) ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value`; await db`INSERT INTO site_settings (key, value) VALUES ('cleanup_end_date', ${cleanup_end_date}) ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value`; + await db`INSERT INTO site_settings (key, value) VALUES ('cleanup_include_engaged', ${cleanup_include_engaged ? 'true' : 'false'}) ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value`; setCleanupStartDate(cleanup_start_date); setCleanupEndDate(cleanup_end_date); + setCleanupIncludeEngaged(cleanup_include_engaged); if (req.headers['x-requested-with'] === 'XMLHttpRequest') { - const body = JSON.stringify({ success: true, enable_cleanup: getEnableCleanup(), cleanup_start_date: getCleanupStartDate(), cleanup_end_date: getCleanupEndDate() }); + const body = JSON.stringify({ success: true, enable_cleanup: getEnableCleanup(), cleanup_start_date: getCleanupStartDate(), cleanup_end_date: getCleanupEndDate(), cleanup_include_engaged: getCleanupIncludeEngaged() }); return res.writeHead(200, { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(body) }).end(body); } @@ -701,17 +705,23 @@ export default (router, tpl) => { router.post(/^\/admin\/cleanup\/run\/?$/, lib.auth, async (req, res) => { try { // Ensure settings are synced from DB before execution - const settings = await db`SELECT key, value FROM site_settings WHERE key IN ('enable_cleanup', 'cleanup_start_date', 'cleanup_end_date')`; + const settings = await db`SELECT key, value FROM site_settings WHERE key IN ('enable_cleanup', 'cleanup_start_date', 'cleanup_end_date', 'cleanup_include_engaged')`; const settingsMap = Object.fromEntries(settings.map(s => [s.key, s.value])); const isEnabled = settingsMap['enable_cleanup'] !== undefined ? settingsMap['enable_cleanup'] === 'true' : getEnableCleanup(); const startDate = settingsMap['cleanup_start_date'] || ''; const endDate = settingsMap['cleanup_end_date'] || ''; + const reqEngaged = req.post?.include_engaged; + const includeEngaged = reqEngaged !== undefined + ? (reqEngaged === 'true' || reqEngaged === true || reqEngaged === 'on' || reqEngaged === '1') + : (settingsMap['cleanup_include_engaged'] === 'true' || getCleanupIncludeEngaged()); + // Update memory state setEnableCleanup(isEnabled); setCleanupStartDate(startDate); setCleanupEndDate(endDate); + setCleanupIncludeEngaged(includeEngaged); if (!isEnabled) { throw new Error('Cleanup is disabled in settings.'); @@ -721,7 +731,7 @@ export default (router, tpl) => { throw new Error('Please select both a Start Date and an End Date.'); } - console.log(`[ADMIN] Starting manual cleanup for period ${startDate} to ${endDate}...`); + console.log(`[ADMIN] Starting manual cleanup for period ${startDate} to ${endDate} (includeEngaged: ${includeEngaged})...`); const start_stamp = ~~(new Date(startDate).getTime() / 1000); const end_stamp = ~~(new Date(endDate).getTime() / 1000) + 86399; // Include full end day @@ -737,7 +747,7 @@ export default (router, tpl) => { AND i.is_pinned = false AND i.stamp >= ${start_stamp} AND i.stamp <= ${end_stamp} - AND ( + ${includeEngaged ? db`` : db`AND ( -- Case 1: Active posts with no engagement (ignoring automatic subscriptions) (i.active = true AND i.is_deleted = false AND NOT EXISTS (SELECT 1 FROM comments WHERE item_id = i.id) AND NOT EXISTS (SELECT 1 FROM favorites WHERE item_id = i.id)) OR @@ -746,7 +756,7 @@ export default (router, tpl) => { OR -- Case 3: Pending posts (not yet approved) that are old enough (i.active = false AND i.is_deleted = false) - ) + )`} `; const statsInfo = `(Total items: ${totalCleanable[0].c}, In range: ${withinRange[0].c})`; diff --git a/src/inc/settings.mjs b/src/inc/settings.mjs index 8c00f9c..f2109ad 100644 --- a/src/inc/settings.mjs +++ b/src/inc/settings.mjs @@ -14,6 +14,7 @@ let enable_pdf = false; let enable_cleanup = false; let cleanup_start_date = ''; let cleanup_end_date = ''; +let cleanup_include_engaged = false; export const getShitpostMode = () => !!cfg.websrv.shitpost_mode; export const setShitpostMode = (val) => {}; // No-op, strictly config-based @@ -29,6 +30,9 @@ export const setCleanupStartDate = (val) => cleanup_start_date = val || ''; export const getCleanupEndDate = () => cleanup_end_date; export const setCleanupEndDate = (val) => cleanup_end_date = val || ''; +export const getCleanupIncludeEngaged = () => cleanup_include_engaged; +export const setCleanupIncludeEngaged = (val) => cleanup_include_engaged = !!val; + export const getEnablePdf = () => enable_pdf; export const setEnablePdf = (val) => enable_pdf = !!val; diff --git a/src/index.mjs b/src/index.mjs index ff16314..ab7b592 100644 --- a/src/index.mjs +++ b/src/index.mjs @@ -20,7 +20,7 @@ import { handleMetaExtract } from "./meta_extract_handler.mjs"; import { handleMetaStrip } from "./meta_strip_handler.mjs"; import { handleCommentUpload, handleCommentUploadCancel } from "./comment_upload_handler.mjs"; import { handleDmAttachmentUpload, handleDmAttachmentDownload, handleDmAttachmentDelete } from "./dm_attachment_handler.mjs"; -import { getManualApproval, setManualApproval, getMinTags, setMinTags, getRegistrationOpen, setRegistrationOpen, getTrustedUploads, setTrustedUploads, getBypassDuplicateCheck, setBypassDuplicateCheck, getProtectFiles, setProtectFiles, getPrivateMessages, setPrivateMessages, getDmAttachments, setDmAttachments, getDmUnencrypted, setDmUnencrypted, getDefaultLayout, setDefaultLayout, getEnablePdf, setEnablePdf, getEnableCleanup, setEnableCleanup, getCleanupStartDate, setCleanupStartDate, getCleanupEndDate, setCleanupEndDate, getLogUserIps, setLogUserIps, getHashUserIps, setHashUserIps, getShitpostMode, setShitpostMode, getAllowCommentDeletion, setAllowCommentDeletion, getNsfpIds, setNsfpIds } from "./inc/settings.mjs"; +import { getManualApproval, setManualApproval, getMinTags, setMinTags, getRegistrationOpen, setRegistrationOpen, getTrustedUploads, setTrustedUploads, getBypassDuplicateCheck, setBypassDuplicateCheck, getProtectFiles, setProtectFiles, getPrivateMessages, setPrivateMessages, getDmAttachments, setDmAttachments, getDmUnencrypted, setDmUnencrypted, getDefaultLayout, setDefaultLayout, getEnablePdf, setEnablePdf, getEnableCleanup, setEnableCleanup, getCleanupStartDate, setCleanupStartDate, getCleanupEndDate, setCleanupEndDate, getCleanupIncludeEngaged, setCleanupIncludeEngaged, getLogUserIps, setLogUserIps, getHashUserIps, setHashUserIps, getShitpostMode, setShitpostMode, getAllowCommentDeletion, setAllowCommentDeletion, getNsfpIds, setNsfpIds } from "./inc/settings.mjs"; import { updateHallsCache, getHalls } from "./inc/halls_cache.mjs"; import { createI18n } from "./inc/i18n.mjs"; import security from "./inc/security.mjs"; @@ -1239,6 +1239,12 @@ process.on('uncaughtException', err => { setCleanupEndDate(endSetting[0].value); } console.log(`[BOOT] Cleanup End Date: ${getCleanupEndDate()}`); + + const engagedSetting = await db`SELECT value FROM site_settings WHERE key = 'cleanup_include_engaged' LIMIT 1`; + if (engagedSetting.length > 0) { + setCleanupIncludeEngaged(engagedSetting[0].value === 'true'); + } + console.log(`[BOOT] Cleanup Include Engaged: ${getCleanupIncludeEngaged()}`); } catch (e) { console.warn(`[BOOT] Cleanup settings fetch failed:`, e.message); setEnableCleanup(!!cfg.websrv.enable_cleanup); @@ -1392,6 +1398,7 @@ process.on('uncaughtException', err => { get enable_cleanup() { return getEnableCleanup(); }, get cleanup_start_date() { return getCleanupStartDate(); }, get cleanup_end_date() { return getCleanupEndDate(); }, + get cleanup_include_engaged() { return getCleanupIncludeEngaged(); }, matrix_enabled: cfg.clients.find(c => c.type === 'matrix')?.enabled || false, telegram_enabled: cfg.clients.find(c => c.type === 'tg')?.enabled || false, ts: Date.now(), diff --git a/views/admin/cleanup.html b/views/admin/cleanup.html index a91005b..a21e9eb 100644 --- a/views/admin/cleanup.html +++ b/views/admin/cleanup.html @@ -26,6 +26,14 @@ +