MarseyWorld/files/helpers/actions.py

628 lines
20 KiB
Python
Raw Normal View History

[DO NOT MERGE] import detanglation (#442) * move Base definition to files.classes.__init__.py * fix ImportError * move userpage listing to users.py * don't import the app from classes * consts: set default values to avoid crashes consts: warn if the secret key is the default config value * card view: sneed (user db schema) * cloudflare: use DEFAULT_CONFIG_VALUE * const: set default values * decouple media.py from __main__ * pass database to avoid imports * import cleanup and import request not in const, but in the requests mega import * move asset_submissions site check to __init__ * asset submissions feature flag * flag * g.is_tor * don't import request where it's not needed * i think this is fine * mail: move to own routes and helper * wrappers * required wrappers move * unfuck wrappers a bit * move snappy quotes and marseys to stateful consts * marsify * :pepodrool: * fix missing import * import cache * ...and settings.py * and static.py * static needs cache * route * lmao all of the jinja shit was in feeds.py amazing * classes should only import what they need from flask * import Response * hdjbjdhbhjf * ... * dfdfdfdf * make get a non-required import * isort imports (mostly) * but actually * configs * reload config on import * fgfgfgfg * config * config * initialize snappy and test * cookie of doom debug * edfjnkf * xikscdfd * debug config * set session cookie domain, i think this fixes the can't login bug * sdfbgnhvfdsghbnjfbdvvfghnn * hrsfxgf * dump the entire config on a request * kyskyskyskyskyskyskyskyskys * duifhdskfjdfd * dfdfdfdfdfdfdfdfdfdfdfdf * dfdfdfdf * imoprt all of the consts beacuse fuck it * 😭 * dfdfdfdfdfdfsdasdf * print the entire session * rffdfdfjkfksj * fgbhffh * not the secret keys * minor bug fixes * be helpful in the warning * gfgfgfg * move warning lower * isort main imports (i hope this doesn't fuck something up) * test * session cookie domain redux * dfdfdfd * try only importing Flask * formkeys fix * y * :pepodrool: * route helper * remove before flight * dfdfdfdfdf * isort classes * isort helpers * move check_for_alts to routehelpers and also sort imports and get rid of unused ones * that previous commit but actkally * readd the cache in a dozen places they were implicitly imported * use g.is_tor instead of request.headers. bla bla bla * upgrade streamers to their own route file * get rid of unused imports in __main__ * fgfgf * don't pull in the entire ORM where we don't need it * features * explicit imports for the get helper * explicit imports for the get helper redux * testing allroutes * remove unused import * decouple flask from classes * syntax fix also remember these have side fx for some reason (why?) * move side effects out of the class * posts * testing on devrama * settings * reloading * settingssdsdsds * streamer features * site settings * testing settings on devrama * import * fix modlog * remove debug stuff * revert commit 67275b21ab6e2f2520819e84d10bfc1c746a15b6 * archiveorg to _archiveorg * skhudkfkjfd * fix cron for PCM * fix bugs that snekky wants me to * Fix call to realbody passing db, standardize kwarg * test * import check_for_alts from the right place * cloudflare * testing on devrama * fix cron i think * shadow properly * tasks * Remove print which will surely be annoying in prod. * v and create new session * use files.classes * make errors import little and fix rare 500 in /allow_nsfw * Revert "use files.classes" This reverts commit 98c10b876cf86ce058b7fb955cf1ec0bfb9996c6. * pass v to media functions rather than using g * fix * dfdfdfdfd * cleanup, py type checking is dumb so don't use it where it causes issues * Fix some merge bugs, add DEFAULT_RATELIMIT to main. * Fix imports on sqlalchemy expressions. * `from random import random` is an error. * Fix replies db param. * errors: fix missing import * fix rare 500: only send to GIFT_NOTIF_ID if it exists, and send them the right text * Fix signup formkey. * fix 2 500s * propagate db to submissions * fix replies * dfdfdfdf * Fix verifiedcolor. * is_manual * can't use getters outside of an app context * don't attempt to do gumroad on sites where it's not enabled * don't attempt to do gumraod on sites's where it's unnecessary * Revert "don't attempt to do gumroad on sites where it's not enabled" This reverts commit 6f8a6331878655492dfaf1907b27f8be513c14d3. * fix 500 * validate media type Co-authored-by: TLSM <duolsm@outlook.com>
2022-11-15 09:19:08 +00:00
import random
import time
from urllib.parse import quote
from sqlalchemy.sql import func
[DO NOT MERGE] import detanglation (#442) * move Base definition to files.classes.__init__.py * fix ImportError * move userpage listing to users.py * don't import the app from classes * consts: set default values to avoid crashes consts: warn if the secret key is the default config value * card view: sneed (user db schema) * cloudflare: use DEFAULT_CONFIG_VALUE * const: set default values * decouple media.py from __main__ * pass database to avoid imports * import cleanup and import request not in const, but in the requests mega import * move asset_submissions site check to __init__ * asset submissions feature flag * flag * g.is_tor * don't import request where it's not needed * i think this is fine * mail: move to own routes and helper * wrappers * required wrappers move * unfuck wrappers a bit * move snappy quotes and marseys to stateful consts * marsify * :pepodrool: * fix missing import * import cache * ...and settings.py * and static.py * static needs cache * route * lmao all of the jinja shit was in feeds.py amazing * classes should only import what they need from flask * import Response * hdjbjdhbhjf * ... * dfdfdfdf * make get a non-required import * isort imports (mostly) * but actually * configs * reload config on import * fgfgfgfg * config * config * initialize snappy and test * cookie of doom debug * edfjnkf * xikscdfd * debug config * set session cookie domain, i think this fixes the can't login bug * sdfbgnhvfdsghbnjfbdvvfghnn * hrsfxgf * dump the entire config on a request * kyskyskyskyskyskyskyskyskys * duifhdskfjdfd * dfdfdfdfdfdfdfdfdfdfdfdf * dfdfdfdf * imoprt all of the consts beacuse fuck it * 😭 * dfdfdfdfdfdfsdasdf * print the entire session * rffdfdfjkfksj * fgbhffh * not the secret keys * minor bug fixes * be helpful in the warning * gfgfgfg * move warning lower * isort main imports (i hope this doesn't fuck something up) * test * session cookie domain redux * dfdfdfd * try only importing Flask * formkeys fix * y * :pepodrool: * route helper * remove before flight * dfdfdfdfdf * isort classes * isort helpers * move check_for_alts to routehelpers and also sort imports and get rid of unused ones * that previous commit but actkally * readd the cache in a dozen places they were implicitly imported * use g.is_tor instead of request.headers. bla bla bla * upgrade streamers to their own route file * get rid of unused imports in __main__ * fgfgf * don't pull in the entire ORM where we don't need it * features * explicit imports for the get helper * explicit imports for the get helper redux * testing allroutes * remove unused import * decouple flask from classes * syntax fix also remember these have side fx for some reason (why?) * move side effects out of the class * posts * testing on devrama * settings * reloading * settingssdsdsds * streamer features * site settings * testing settings on devrama * import * fix modlog * remove debug stuff * revert commit 67275b21ab6e2f2520819e84d10bfc1c746a15b6 * archiveorg to _archiveorg * skhudkfkjfd * fix cron for PCM * fix bugs that snekky wants me to * Fix call to realbody passing db, standardize kwarg * test * import check_for_alts from the right place * cloudflare * testing on devrama * fix cron i think * shadow properly * tasks * Remove print which will surely be annoying in prod. * v and create new session * use files.classes * make errors import little and fix rare 500 in /allow_nsfw * Revert "use files.classes" This reverts commit 98c10b876cf86ce058b7fb955cf1ec0bfb9996c6. * pass v to media functions rather than using g * fix * dfdfdfdfd * cleanup, py type checking is dumb so don't use it where it causes issues * Fix some merge bugs, add DEFAULT_RATELIMIT to main. * Fix imports on sqlalchemy expressions. * `from random import random` is an error. * Fix replies db param. * errors: fix missing import * fix rare 500: only send to GIFT_NOTIF_ID if it exists, and send them the right text * Fix signup formkey. * fix 2 500s * propagate db to submissions * fix replies * dfdfdfdf * Fix verifiedcolor. * is_manual * can't use getters outside of an app context * don't attempt to do gumroad on sites where it's not enabled * don't attempt to do gumraod on sites's where it's unnecessary * Revert "don't attempt to do gumroad on sites where it's not enabled" This reverts commit 6f8a6331878655492dfaf1907b27f8be513c14d3. * fix 500 * validate media type Co-authored-by: TLSM <duolsm@outlook.com>
2022-11-15 09:19:08 +00:00
import gevent
import requests
2024-02-01 17:30:04 +00:00
import math
from flask import g
2023-06-23 16:49:23 +00:00
from files.classes.reports import Report
[DO NOT MERGE] import detanglation (#442) * move Base definition to files.classes.__init__.py * fix ImportError * move userpage listing to users.py * don't import the app from classes * consts: set default values to avoid crashes consts: warn if the secret key is the default config value * card view: sneed (user db schema) * cloudflare: use DEFAULT_CONFIG_VALUE * const: set default values * decouple media.py from __main__ * pass database to avoid imports * import cleanup and import request not in const, but in the requests mega import * move asset_submissions site check to __init__ * asset submissions feature flag * flag * g.is_tor * don't import request where it's not needed * i think this is fine * mail: move to own routes and helper * wrappers * required wrappers move * unfuck wrappers a bit * move snappy quotes and marseys to stateful consts * marsify * :pepodrool: * fix missing import * import cache * ...and settings.py * and static.py * static needs cache * route * lmao all of the jinja shit was in feeds.py amazing * classes should only import what they need from flask * import Response * hdjbjdhbhjf * ... * dfdfdfdf * make get a non-required import * isort imports (mostly) * but actually * configs * reload config on import * fgfgfgfg * config * config * initialize snappy and test * cookie of doom debug * edfjnkf * xikscdfd * debug config * set session cookie domain, i think this fixes the can't login bug * sdfbgnhvfdsghbnjfbdvvfghnn * hrsfxgf * dump the entire config on a request * kyskyskyskyskyskyskyskyskys * duifhdskfjdfd * dfdfdfdfdfdfdfdfdfdfdfdf * dfdfdfdf * imoprt all of the consts beacuse fuck it * 😭 * dfdfdfdfdfdfsdasdf * print the entire session * rffdfdfjkfksj * fgbhffh * not the secret keys * minor bug fixes * be helpful in the warning * gfgfgfg * move warning lower * isort main imports (i hope this doesn't fuck something up) * test * session cookie domain redux * dfdfdfd * try only importing Flask * formkeys fix * y * :pepodrool: * route helper * remove before flight * dfdfdfdfdf * isort classes * isort helpers * move check_for_alts to routehelpers and also sort imports and get rid of unused ones * that previous commit but actkally * readd the cache in a dozen places they were implicitly imported * use g.is_tor instead of request.headers. bla bla bla * upgrade streamers to their own route file * get rid of unused imports in __main__ * fgfgf * don't pull in the entire ORM where we don't need it * features * explicit imports for the get helper * explicit imports for the get helper redux * testing allroutes * remove unused import * decouple flask from classes * syntax fix also remember these have side fx for some reason (why?) * move side effects out of the class * posts * testing on devrama * settings * reloading * settingssdsdsds * streamer features * site settings * testing settings on devrama * import * fix modlog * remove debug stuff * revert commit 67275b21ab6e2f2520819e84d10bfc1c746a15b6 * archiveorg to _archiveorg * skhudkfkjfd * fix cron for PCM * fix bugs that snekky wants me to * Fix call to realbody passing db, standardize kwarg * test * import check_for_alts from the right place * cloudflare * testing on devrama * fix cron i think * shadow properly * tasks * Remove print which will surely be annoying in prod. * v and create new session * use files.classes * make errors import little and fix rare 500 in /allow_nsfw * Revert "use files.classes" This reverts commit 98c10b876cf86ce058b7fb955cf1ec0bfb9996c6. * pass v to media functions rather than using g * fix * dfdfdfdfd * cleanup, py type checking is dumb so don't use it where it causes issues * Fix some merge bugs, add DEFAULT_RATELIMIT to main. * Fix imports on sqlalchemy expressions. * `from random import random` is an error. * Fix replies db param. * errors: fix missing import * fix rare 500: only send to GIFT_NOTIF_ID if it exists, and send them the right text * Fix signup formkey. * fix 2 500s * propagate db to submissions * fix replies * dfdfdfdf * Fix verifiedcolor. * is_manual * can't use getters outside of an app context * don't attempt to do gumroad on sites where it's not enabled * don't attempt to do gumraod on sites's where it's unnecessary * Revert "don't attempt to do gumroad on sites where it's not enabled" This reverts commit 6f8a6331878655492dfaf1907b27f8be513c14d3. * fix 500 * validate media type Co-authored-by: TLSM <duolsm@outlook.com>
2022-11-15 09:19:08 +00:00
from files.classes.mod_logs import ModAction
from files.classes.notifications import Notification
2023-06-07 23:26:32 +00:00
from files.classes.polls import CommentOption, PostOption
from files.classes.award import AwardRelationship
from files.classes.hole_relationship import Exile
[DO NOT MERGE] import detanglation (#442) * move Base definition to files.classes.__init__.py * fix ImportError * move userpage listing to users.py * don't import the app from classes * consts: set default values to avoid crashes consts: warn if the secret key is the default config value * card view: sneed (user db schema) * cloudflare: use DEFAULT_CONFIG_VALUE * const: set default values * decouple media.py from __main__ * pass database to avoid imports * import cleanup and import request not in const, but in the requests mega import * move asset_submissions site check to __init__ * asset submissions feature flag * flag * g.is_tor * don't import request where it's not needed * i think this is fine * mail: move to own routes and helper * wrappers * required wrappers move * unfuck wrappers a bit * move snappy quotes and marseys to stateful consts * marsify * :pepodrool: * fix missing import * import cache * ...and settings.py * and static.py * static needs cache * route * lmao all of the jinja shit was in feeds.py amazing * classes should only import what they need from flask * import Response * hdjbjdhbhjf * ... * dfdfdfdf * make get a non-required import * isort imports (mostly) * but actually * configs * reload config on import * fgfgfgfg * config * config * initialize snappy and test * cookie of doom debug * edfjnkf * xikscdfd * debug config * set session cookie domain, i think this fixes the can't login bug * sdfbgnhvfdsghbnjfbdvvfghnn * hrsfxgf * dump the entire config on a request * kyskyskyskyskyskyskyskyskys * duifhdskfjdfd * dfdfdfdfdfdfdfdfdfdfdfdf * dfdfdfdf * imoprt all of the consts beacuse fuck it * 😭 * dfdfdfdfdfdfsdasdf * print the entire session * rffdfdfjkfksj * fgbhffh * not the secret keys * minor bug fixes * be helpful in the warning * gfgfgfg * move warning lower * isort main imports (i hope this doesn't fuck something up) * test * session cookie domain redux * dfdfdfd * try only importing Flask * formkeys fix * y * :pepodrool: * route helper * remove before flight * dfdfdfdfdf * isort classes * isort helpers * move check_for_alts to routehelpers and also sort imports and get rid of unused ones * that previous commit but actkally * readd the cache in a dozen places they were implicitly imported * use g.is_tor instead of request.headers. bla bla bla * upgrade streamers to their own route file * get rid of unused imports in __main__ * fgfgf * don't pull in the entire ORM where we don't need it * features * explicit imports for the get helper * explicit imports for the get helper redux * testing allroutes * remove unused import * decouple flask from classes * syntax fix also remember these have side fx for some reason (why?) * move side effects out of the class * posts * testing on devrama * settings * reloading * settingssdsdsds * streamer features * site settings * testing settings on devrama * import * fix modlog * remove debug stuff * revert commit 67275b21ab6e2f2520819e84d10bfc1c746a15b6 * archiveorg to _archiveorg * skhudkfkjfd * fix cron for PCM * fix bugs that snekky wants me to * Fix call to realbody passing db, standardize kwarg * test * import check_for_alts from the right place * cloudflare * testing on devrama * fix cron i think * shadow properly * tasks * Remove print which will surely be annoying in prod. * v and create new session * use files.classes * make errors import little and fix rare 500 in /allow_nsfw * Revert "use files.classes" This reverts commit 98c10b876cf86ce058b7fb955cf1ec0bfb9996c6. * pass v to media functions rather than using g * fix * dfdfdfdfd * cleanup, py type checking is dumb so don't use it where it causes issues * Fix some merge bugs, add DEFAULT_RATELIMIT to main. * Fix imports on sqlalchemy expressions. * `from random import random` is an error. * Fix replies db param. * errors: fix missing import * fix rare 500: only send to GIFT_NOTIF_ID if it exists, and send them the right text * Fix signup formkey. * fix 2 500s * propagate db to submissions * fix replies * dfdfdfdf * Fix verifiedcolor. * is_manual * can't use getters outside of an app context * don't attempt to do gumroad on sites where it's not enabled * don't attempt to do gumraod on sites's where it's unnecessary * Revert "don't attempt to do gumroad on sites where it's not enabled" This reverts commit 6f8a6331878655492dfaf1907b27f8be513c14d3. * fix 500 * validate media type Co-authored-by: TLSM <duolsm@outlook.com>
2022-11-15 09:19:08 +00:00
2023-02-24 06:48:30 +00:00
from files.helpers.alerts import send_repeatable_notification, push_notif
from files.helpers.config.const import *
from files.helpers.config.awards import AWARDS
[DO NOT MERGE] import detanglation (#442) * move Base definition to files.classes.__init__.py * fix ImportError * move userpage listing to users.py * don't import the app from classes * consts: set default values to avoid crashes consts: warn if the secret key is the default config value * card view: sneed (user db schema) * cloudflare: use DEFAULT_CONFIG_VALUE * const: set default values * decouple media.py from __main__ * pass database to avoid imports * import cleanup and import request not in const, but in the requests mega import * move asset_submissions site check to __init__ * asset submissions feature flag * flag * g.is_tor * don't import request where it's not needed * i think this is fine * mail: move to own routes and helper * wrappers * required wrappers move * unfuck wrappers a bit * move snappy quotes and marseys to stateful consts * marsify * :pepodrool: * fix missing import * import cache * ...and settings.py * and static.py * static needs cache * route * lmao all of the jinja shit was in feeds.py amazing * classes should only import what they need from flask * import Response * hdjbjdhbhjf * ... * dfdfdfdf * make get a non-required import * isort imports (mostly) * but actually * configs * reload config on import * fgfgfgfg * config * config * initialize snappy and test * cookie of doom debug * edfjnkf * xikscdfd * debug config * set session cookie domain, i think this fixes the can't login bug * sdfbgnhvfdsghbnjfbdvvfghnn * hrsfxgf * dump the entire config on a request * kyskyskyskyskyskyskyskyskys * duifhdskfjdfd * dfdfdfdfdfdfdfdfdfdfdfdf * dfdfdfdf * imoprt all of the consts beacuse fuck it * 😭 * dfdfdfdfdfdfsdasdf * print the entire session * rffdfdfjkfksj * fgbhffh * not the secret keys * minor bug fixes * be helpful in the warning * gfgfgfg * move warning lower * isort main imports (i hope this doesn't fuck something up) * test * session cookie domain redux * dfdfdfd * try only importing Flask * formkeys fix * y * :pepodrool: * route helper * remove before flight * dfdfdfdfdf * isort classes * isort helpers * move check_for_alts to routehelpers and also sort imports and get rid of unused ones * that previous commit but actkally * readd the cache in a dozen places they were implicitly imported * use g.is_tor instead of request.headers. bla bla bla * upgrade streamers to their own route file * get rid of unused imports in __main__ * fgfgf * don't pull in the entire ORM where we don't need it * features * explicit imports for the get helper * explicit imports for the get helper redux * testing allroutes * remove unused import * decouple flask from classes * syntax fix also remember these have side fx for some reason (why?) * move side effects out of the class * posts * testing on devrama * settings * reloading * settingssdsdsds * streamer features * site settings * testing settings on devrama * import * fix modlog * remove debug stuff * revert commit 67275b21ab6e2f2520819e84d10bfc1c746a15b6 * archiveorg to _archiveorg * skhudkfkjfd * fix cron for PCM * fix bugs that snekky wants me to * Fix call to realbody passing db, standardize kwarg * test * import check_for_alts from the right place * cloudflare * testing on devrama * fix cron i think * shadow properly * tasks * Remove print which will surely be annoying in prod. * v and create new session * use files.classes * make errors import little and fix rare 500 in /allow_nsfw * Revert "use files.classes" This reverts commit 98c10b876cf86ce058b7fb955cf1ec0bfb9996c6. * pass v to media functions rather than using g * fix * dfdfdfdfd * cleanup, py type checking is dumb so don't use it where it causes issues * Fix some merge bugs, add DEFAULT_RATELIMIT to main. * Fix imports on sqlalchemy expressions. * `from random import random` is an error. * Fix replies db param. * errors: fix missing import * fix rare 500: only send to GIFT_NOTIF_ID if it exists, and send them the right text * Fix signup formkey. * fix 2 500s * propagate db to submissions * fix replies * dfdfdfdf * Fix verifiedcolor. * is_manual * can't use getters outside of an app context * don't attempt to do gumroad on sites where it's not enabled * don't attempt to do gumraod on sites's where it's unnecessary * Revert "don't attempt to do gumroad on sites where it's not enabled" This reverts commit 6f8a6331878655492dfaf1907b27f8be513c14d3. * fix 500 * validate media type Co-authored-by: TLSM <duolsm@outlook.com>
2022-11-15 09:19:08 +00:00
from files.helpers.const_stateful import *
from files.helpers.get import *
2022-11-30 18:09:31 +00:00
from files.helpers.logging import log_file
from files.helpers.sanitize import *
2022-11-30 17:37:35 +00:00
from files.helpers.settings import get_setting
2022-11-07 00:08:50 +00:00
from files.helpers.slots import check_slots_command
from files.helpers.useractions import badge_grant
2023-07-25 16:42:16 +00:00
from files.routes.routehelpers import check_for_alts
[DO NOT MERGE] import detanglation (#442) * move Base definition to files.classes.__init__.py * fix ImportError * move userpage listing to users.py * don't import the app from classes * consts: set default values to avoid crashes consts: warn if the secret key is the default config value * card view: sneed (user db schema) * cloudflare: use DEFAULT_CONFIG_VALUE * const: set default values * decouple media.py from __main__ * pass database to avoid imports * import cleanup and import request not in const, but in the requests mega import * move asset_submissions site check to __init__ * asset submissions feature flag * flag * g.is_tor * don't import request where it's not needed * i think this is fine * mail: move to own routes and helper * wrappers * required wrappers move * unfuck wrappers a bit * move snappy quotes and marseys to stateful consts * marsify * :pepodrool: * fix missing import * import cache * ...and settings.py * and static.py * static needs cache * route * lmao all of the jinja shit was in feeds.py amazing * classes should only import what they need from flask * import Response * hdjbjdhbhjf * ... * dfdfdfdf * make get a non-required import * isort imports (mostly) * but actually * configs * reload config on import * fgfgfgfg * config * config * initialize snappy and test * cookie of doom debug * edfjnkf * xikscdfd * debug config * set session cookie domain, i think this fixes the can't login bug * sdfbgnhvfdsghbnjfbdvvfghnn * hrsfxgf * dump the entire config on a request * kyskyskyskyskyskyskyskyskys * duifhdskfjdfd * dfdfdfdfdfdfdfdfdfdfdfdf * dfdfdfdf * imoprt all of the consts beacuse fuck it * 😭 * dfdfdfdfdfdfsdasdf * print the entire session * rffdfdfjkfksj * fgbhffh * not the secret keys * minor bug fixes * be helpful in the warning * gfgfgfg * move warning lower * isort main imports (i hope this doesn't fuck something up) * test * session cookie domain redux * dfdfdfd * try only importing Flask * formkeys fix * y * :pepodrool: * route helper * remove before flight * dfdfdfdfdf * isort classes * isort helpers * move check_for_alts to routehelpers and also sort imports and get rid of unused ones * that previous commit but actkally * readd the cache in a dozen places they were implicitly imported * use g.is_tor instead of request.headers. bla bla bla * upgrade streamers to their own route file * get rid of unused imports in __main__ * fgfgf * don't pull in the entire ORM where we don't need it * features * explicit imports for the get helper * explicit imports for the get helper redux * testing allroutes * remove unused import * decouple flask from classes * syntax fix also remember these have side fx for some reason (why?) * move side effects out of the class * posts * testing on devrama * settings * reloading * settingssdsdsds * streamer features * site settings * testing settings on devrama * import * fix modlog * remove debug stuff * revert commit 67275b21ab6e2f2520819e84d10bfc1c746a15b6 * archiveorg to _archiveorg * skhudkfkjfd * fix cron for PCM * fix bugs that snekky wants me to * Fix call to realbody passing db, standardize kwarg * test * import check_for_alts from the right place * cloudflare * testing on devrama * fix cron i think * shadow properly * tasks * Remove print which will surely be annoying in prod. * v and create new session * use files.classes * make errors import little and fix rare 500 in /allow_nsfw * Revert "use files.classes" This reverts commit 98c10b876cf86ce058b7fb955cf1ec0bfb9996c6. * pass v to media functions rather than using g * fix * dfdfdfdfd * cleanup, py type checking is dumb so don't use it where it causes issues * Fix some merge bugs, add DEFAULT_RATELIMIT to main. * Fix imports on sqlalchemy expressions. * `from random import random` is an error. * Fix replies db param. * errors: fix missing import * fix rare 500: only send to GIFT_NOTIF_ID if it exists, and send them the right text * Fix signup formkey. * fix 2 500s * propagate db to submissions * fix replies * dfdfdfdf * Fix verifiedcolor. * is_manual * can't use getters outside of an app context * don't attempt to do gumroad on sites where it's not enabled * don't attempt to do gumraod on sites's where it's unnecessary * Revert "don't attempt to do gumroad on sites where it's not enabled" This reverts commit 6f8a6331878655492dfaf1907b27f8be513c14d3. * fix 500 * validate media type Co-authored-by: TLSM <duolsm@outlook.com>
2022-11-15 09:19:08 +00:00
def _archiveorg(url):
try:
2023-10-24 15:15:49 +00:00
requests.post('https://ghostarchive.org/archive2', data={"archive": url}, headers=HEADERS, timeout=10)
except: pass
try:
2023-10-24 15:15:49 +00:00
requests.get(f'https://web.archive.org/save/{url}', headers=HEADERS, timeout=10)
2022-09-03 14:24:16 +00:00
except: pass
2022-10-30 22:39:37 +00:00
2022-09-03 03:10:14 +00:00
2023-01-01 11:36:20 +00:00
def archive_url(url):
gevent.spawn(_archiveorg, url)
2022-09-03 03:10:14 +00:00
if url.startswith('https://instagram.com/'):
url = url.replace('https://instagram.com/', 'https://imginn.com/')
gevent.spawn(_archiveorg, url)
2022-09-03 03:10:14 +00:00
def snappy_report(post, reason):
2023-06-23 16:49:23 +00:00
report = Report(post_id=post.id, user_id=SNAPPY_ID, reason=reason)
g.db.add(report)
2024-02-20 00:00:21 +00:00
message = f'@Snappy reported {post.textlink})\n\n> {reason}'
send_repeatable_notification(post.author_id, message)
2023-07-30 00:42:06 +00:00
def execute_snappy(post, v):
2023-10-07 17:55:50 +00:00
if post.hole and g.db.query(Exile.user_id).filter_by(user_id=SNAPPY_ID, hole=post.hole).one_or_none():
return
ghost = post.ghost
snappy = get_account(SNAPPY_ID)
2023-08-18 02:21:56 +00:00
ping_cost = 0
2023-07-17 17:24:22 +00:00
post_ping_group_count = len(list(group_mention_regex.finditer(post.body)))
2023-07-29 18:31:40 +00:00
2024-03-05 00:17:52 +00:00
if SITE_NAME == 'rDrama' and (v.post_count <= 3 or v.new_user):
2024-02-29 14:41:31 +00:00
body = "Hey, I saw that you just joined rdrama and a group of people who hate me are trying to smear my name by calling me a date male feminist. I just wanted to let you know that it's not true. If you want all the receipts proving it they're right here.\nThe TL;DR is that I hooked up with one of the hot girls on rdrama, and since I was twice her age, a lot of the guys here who wanted to bang her got jealous and assumed that the only way I could have managed that was by raping her, even though she herself said both before and afterwards that it was all completely consensual. So now that you're the new hot girl on rdrama, I guess they think that I'm going to somehow seduce you into flying all the way across the country (or some crazy shit like that) to hook up with me and they're trying to talk shit about me to make sure that doesnt happen. I don't understand it either, but I just wanted to let you know that I'm a nice guy and I hope you'll look at the evidence and make up your own mind instead of listening to all the jealous haters.\nAnyway, with that little intro out of the way, welcome to rdrama! The culture's a little rough here and you're probably going to get tons of requests to •show boobsU but if you talk to some of the women here first before engaging with all the creepy dudes, they'll give you some good advice to avoid stalkers and predators. Or (If you haven't been scared off by the rumor mill) you're welcome to ask me and I'm happy to help.\nJust out of curiosity, how did you find this place?"
elif post.hole and post.hole_obj.snappy_quotes:
quotes = post.hole_obj.snappy_quotes.split("[para]")
body = random.choice(quotes).strip()
elif SITE_NAME == 'WPD' and ('killing myself' in post.title.lower() or (post.hole != 'suicide' and 'suicide' in post.title.lower())):
2023-10-15 15:13:22 +00:00
body = "https://i.watchpeopledie.tv/images/1697382435294321.webp"
elif post_ping_group_count > 3:
body = "Unnecessary and uncalled for ping :marseydownvotemad: two more strikes and you're getting blocked + megadownvoted buddy, don't test your luck"
2023-07-22 21:56:47 +00:00
vote = Vote(user_id=SNAPPY_ID,
vote_type=-1,
post_id=post.id,
real = True
)
g.db.add(vote)
post.downvotes += 1
elif v.id == CARP_ID:
2023-07-25 14:21:59 +00:00
if random.random() < 0.08:
2024-01-15 02:21:58 +00:00
body = random.choice(("i love you carp", "https://i.rdrama.net/images/16614707883108485.webp", "https://i.rdrama.net/images/1636916964YyM.webp", "https://youtube.com/watch?v=zRbQHTdsjuY", "https://i.rdrama.net/images/1696250281381682.webp", "https://i.rdrama.net/images/16975678508317988.webp", "https://i.rdrama.net/images/170526627808132.webp", "https://i.rdrama.net/images/17052853054732056.webp"))
2023-05-01 18:41:55 +00:00
elif IS_DKD():
body = ":#donkeykongfuckoffcarp:"
2023-09-28 23:58:09 +00:00
elif IS_HOMOWEEN():
body = "F̵̽̉U̷̓̕C̵̟̍K̴̾̍ ̵́̒O̶͐̇F̷͗̐F̴͛̄ ̸̆͠CARP"
2023-10-17 18:45:45 +00:00
elif IS_FISTMAS():
body = "Merry Christmas Carp :marseychristmasgift2:"
2023-05-01 18:41:55 +00:00
else:
2024-01-17 04:27:30 +00:00
body = ":#carpwavelove:"
elif v.id == AEVANN_ID:
2023-10-01 14:46:34 +00:00
body = "https://i.rdrama.net/images/16909380805064178.webp"
2023-12-15 01:55:56 +00:00
elif SITE == 'rdrama.net' and v.id == 253:
2023-10-01 14:46:34 +00:00
body = "https://i.rdrama.net/images/16961715452780113.webp"
2023-12-15 01:55:56 +00:00
elif SITE == 'rdrama.net' and v.id == 8094:
body = "https://i.rdrama.net/images/17025988883967621.webp"
2024-01-12 05:50:31 +00:00
elif SITE == 'rdrama.net' and v.id == 5214:
body = random.choice(("https://rdrama.net/audio/1704983217764354.mp3", "Dear Chiobu:\n\nWe are not accepting non-US residents because of difficulty of payment and difficulty of enforcing our Confidentiality Agreement internationally. Additionally, you seem to have opinions incompatible with ours, namely your opinions **Towards the Chinese** and **Towards Transgender Individuals**. We thank you for your interest."))
2024-02-07 23:22:02 +00:00
elif SITE == 'rdrama.net' and v.id == 9493:
body = "https://i.rdrama.net/images/16973719400351799.webp"
else:
2023-04-25 17:02:56 +00:00
if IS_DKD():
2023-05-02 13:49:28 +00:00
SNAPPY_CHOICES = SNAPPY_KONGS
2023-09-28 23:58:09 +00:00
elif IS_FISTMAS():
SNAPPY_CHOICES = SNAPPY_QUOTES_FISTMAS
elif IS_HOMOWEEN():
SNAPPY_CHOICES = SNAPPY_QUOTES_HOMOWEEN
2023-05-02 13:49:28 +00:00
elif SNAPPY_MARSEYS and SNAPPY_QUOTES:
2023-09-28 23:58:09 +00:00
if random.random() > 0.5:
SNAPPY_CHOICES = SNAPPY_QUOTES
2023-01-01 11:36:20 +00:00
else:
2023-05-02 13:49:28 +00:00
SNAPPY_CHOICES = SNAPPY_MARSEYS
elif SNAPPY_MARSEYS:
SNAPPY_CHOICES = SNAPPY_MARSEYS
elif SNAPPY_QUOTES:
SNAPPY_CHOICES = SNAPPY_QUOTES
else:
SNAPPY_CHOICES = [""]
body = random.choice(SNAPPY_CHOICES).strip()
2023-10-26 16:40:36 +00:00
body = body.replace('%OP%', f'@{post.author_name}')
if body.startswith('') or body.startswith(':#marseydownvote'):
if body.startswith(''): body = body[1:]
vote = Vote(user_id=SNAPPY_ID,
vote_type=-1,
2023-06-07 23:26:32 +00:00
post_id=post.id,
real = True
)
2023-03-16 06:27:58 +00:00
g.db.add(vote)
post.downvotes += 1
if body.startswith('OP is a Trump supporter'):
snappy_report(post, 'Trump supporter')
elif body.startswith('You had your chance. Downvoted and reported'):
snappy_report(post, 'Retard')
elif body.startswith('') or body.startswith(':#marseyupvote'):
if body.startswith(''): body = body[1:]
vote = Vote(user_id=SNAPPY_ID,
vote_type=1,
2023-06-07 23:26:32 +00:00
post_id=post.id,
real = True
)
2023-03-16 06:27:58 +00:00
g.db.add(vote)
post.upvotes += 1
elif ':#marseyghost' in body:
ghost = True
elif body == '!slots':
body = f'!slots{snappy.coins}'
elif body == '!pinggroup':
group = g.db.query(Group).filter(Group.name != 'focusgroup').order_by(func.random()).first()
cost = len(group.member_ids) * 5
snappy.charge_account('coins', cost)
body = f'!{group.name}'
2023-08-01 07:38:58 +00:00
2023-07-17 17:24:22 +00:00
ping_cost = cost
elif body.startswith(':#marseyglow'):
award_object = AwardRelationship(
user_id=snappy.id,
kind="glowie",
2023-06-07 23:26:32 +00:00
post_id=post.id,
2024-02-03 03:18:47 +00:00
awarded_utc=time.time(),
)
g.db.add(award_object)
2024-02-12 16:35:39 +00:00
awarded_coins = int(AWARDS["glowie"]['price'] * COSMETIC_AWARD_COIN_AWARD_PCT)
2024-03-02 17:24:07 +00:00
post.author.pay_account('coins', awarded_coins, f"Glowie award on {post.textlink}")
2024-02-12 16:35:39 +00:00
2024-02-20 00:00:21 +00:00
msg = f"@Snappy has given {post.textlink} the Glowie Award and you have received {awarded_coins} coins as a result!"
send_repeatable_notification(post.author.id, msg)
elif body.startswith("You're a chud, CHUD I tell you"):
award_object = AwardRelationship(
user_id=snappy.id,
kind="chud",
post_id=post.id,
awarded_utc=time.time(),
note="Trans lives matter",
)
g.db.add(award_object)
2024-02-20 00:00:21 +00:00
msg = f"@Snappy has given {post.textlink} the Chud Award\n\n**You now have to say this phrase in all posts and comments you make for 24 hours:**\n\n> Trans lives matter"
send_repeatable_notification(post.author.id, msg)
if v.chud != 1:
if v.chud and time.time() < v.chud: v.chud += 86400
else: v.chud = int(time.time()) + 86400
v.chud_phrase = 'trans lives matter'
badge_grant(user=v, badge_id=58)
post.chudded = True
complies_with_chud(post)
body += "\n\n"
captured = []
if post.url:
captured.append((post.url, post.url))
for i in list(snappy_url_regex.finditer(post.body_html.replace(' data-src="', ' src="'))):
2022-07-11 17:45:07 +00:00
href = i.group(1)
if href in [x[0] for x in captured]: continue
title = i.group(2)
2022-07-11 17:45:07 +00:00
captured.append((href, title))
captured2 = []
for href, title in captured:
if not (href.startswith('/') or href.startswith(f'{SITE_FULL}/') or href.startswith(f'{SITE_FULL_IMAGES}/') or href.startswith('https://videos.watchpeopledie.tv/')):
captured2.append((href, title))
if captured2:
body += "**Snapshots:**\n\n"
2022-07-11 17:45:07 +00:00
for href, title in captured2:
if f'**[{title}]({href})**:\n\n' not in body:
addition = f'**[{title}]({href})**:\n\n'
if href.startswith('https://old.reddit.com/r/'):
rev = href.replace('https://old.reddit.com/', '')
addition += f'* [undelete.pullpush.io](https://undelete.pullpush.io/{rev})\n\n'
elif href.startswith('https://old.reddit.com/user/'):
rev = href.replace('https://old.reddit.com/user/', '')
addition += f"* [search-new.pullpush.io](https://search-new.pullpush.io/?author={rev}&type=submission)\n\n"
elif href.startswith('https://boards.4chan.org/'):
rev = href.replace('https://boards.4chan.org/', '')
addition += f'* [archived.moe](https://archived.moe/{rev})\n\n'
elif href.startswith('https://scored.co/') and href != 'https://scored.co/':
rev = href.replace('https://scored.co/', '')
addition += f'* [unscored.arete.network](https://unscored.arete.network/{rev})\n\n'
addition += f'* [ghostarchive.org](https://ghostarchive.org/search?term={quote(href)})\n\n'
addition += f'* [archive.org](https://web.archive.org/{href})\n\n'
addition += f'* [archive.ph](https://archive.ph/?url={quote(href)}&run=1) (click to archive)\n\n'
if len(f'{body}{addition}') > COMMENT_BODY_LENGTH_LIMIT: break
body += addition
2022-09-03 03:10:14 +00:00
archive_url(href)
2022-08-15 17:45:43 +00:00
2023-07-30 06:20:02 +00:00
body = body[:COMMENT_BODY_LENGTH_LIMIT].strip()
body_html = sanitize(body, snappy=True, showmore=True)
if len(body_html) == 0:
return
if len(body_html) < COMMENT_BODY_HTML_LENGTH_LIMIT:
c = Comment(author_id=SNAPPY_ID,
distinguished=True,
parent_post=post.id,
level=1,
2023-10-05 10:19:50 +00:00
nsfw=False,
is_bot=True,
app_id=None,
body=body,
body_html=body_html,
2023-08-18 02:21:56 +00:00
ghost=ghost,
ping_cost=ping_cost,
)
2023-03-16 06:27:58 +00:00
g.db.add(c)
check_slots_command(c, v, snappy)
2022-11-07 00:08:50 +00:00
snappy.comment_count += 1
snappy.pay_account('coins', 1)
2023-03-16 06:27:58 +00:00
g.db.add(snappy)
if FEATURES['PINS'] and (body.startswith(':#marseypin:') or body.startswith(':#marseypin2:')):
2024-02-18 15:29:53 +00:00
post.pinned = "Snappy"
post.pinned_utc = int(time.time()) + 3600
elif SITE_NAME == 'rDrama' and body.startswith(':#marseyban:'):
days = 0.01
reason = f'<a href="/post/{post.id}">/post/{post.id}</a>'
v.ban(admin=snappy, reason=reason, days=days)
text = f"@Snappy has banned you for **{days}** days for the following reason:\n\n> {reason}"
send_repeatable_notification(v.id, text)
duration = f"for {days} days"
2023-08-23 21:57:39 +00:00
ma = ModAction(
kind="ban_user",
user_id=snappy.id,
target_user_id=v.id,
_note=f'duration: {duration}, reason: "{reason}"'
)
2023-03-16 06:27:58 +00:00
g.db.add(ma)
post.bannedfor = f'{duration} by @Snappy'
2023-03-16 06:27:58 +00:00
g.db.flush()
2023-08-18 02:21:56 +00:00
if c.ping_cost:
for x in group.member_ids:
n = Notification(comment_id=c.id, user_id=x)
g.db.add(n)
push_notif({x}, f'New mention of you by @Snappy', c.body, c)
c.top_comment_id = c.id
post.comment_count += 1
post.replies = [c]
2023-10-06 13:16:07 +00:00
def execute_zozbot(c, level, post, v):
2024-02-21 20:29:54 +00:00
if not ZOZBOT_ID: return
2023-10-06 17:09:40 +00:00
if random.random() >= 0.001: return
2023-10-06 13:16:07 +00:00
posting_to_post = isinstance(post, Post)
2023-10-06 17:09:40 +00:00
2023-10-07 17:55:50 +00:00
if posting_to_post and post.hole and g.db.query(Exile.user_id).filter_by(user_id=ZOZBOT_ID, hole=post.hole).one_or_none():
2023-10-06 17:09:40 +00:00
return
c2 = Comment(author_id=ZOZBOT_ID,
2023-10-06 13:16:07 +00:00
parent_post=post.id if posting_to_post else None,
wall_user_id=post.id if not posting_to_post else None,
2022-10-09 13:29:58 +00:00
parent_comment_id=c.id,
level=level+1,
is_bot=True,
body="zoz",
2024-02-18 23:46:12 +00:00
body_html='<p>zoz</p>',
2022-10-09 13:29:58 +00:00
top_comment_id=c.top_comment_id,
ghost=c.ghost,
distinguished=True
2022-10-09 13:29:58 +00:00
)
2023-03-16 06:27:58 +00:00
g.db.add(c2)
g.db.flush()
n = Notification(comment_id=c2.id, user_id=v.id)
2023-03-16 06:27:58 +00:00
g.db.add(n)
c3 = Comment(author_id=ZOZBOT_ID,
2023-10-06 13:16:07 +00:00
parent_post=post.id if posting_to_post else None,
wall_user_id=post.id if not posting_to_post else None,
parent_comment_id=c2.id,
level=level+2,
is_bot=True,
body="zle",
2024-02-18 23:46:12 +00:00
body_html='<p>zle</p>',
top_comment_id=c.top_comment_id,
ghost=c.ghost,
distinguished=True
)
2023-03-16 06:27:58 +00:00
g.db.add(c3)
g.db.flush()
c4 = Comment(author_id=ZOZBOT_ID,
2023-10-06 13:16:07 +00:00
parent_post=post.id if posting_to_post else None,
wall_user_id=post.id if not posting_to_post else None,
parent_comment_id=c3.id,
level=level+3,
is_bot=True,
body="zozzle",
2024-02-18 23:46:12 +00:00
body_html='<p>zozzle</p>',
top_comment_id=c.top_comment_id,
ghost=c.ghost,
distinguished=True
)
2023-03-16 06:27:58 +00:00
g.db.add(c4)
zozbot = get_account(ZOZBOT_ID)
zozbot.comment_count += 3
zozbot.pay_account('coins', 1)
2023-03-16 06:27:58 +00:00
g.db.add(zozbot)
if posting_to_post:
2023-10-06 13:16:07 +00:00
post.comment_count += 3
g.db.add(post)
2023-02-27 13:35:53 +00:00
push_notif({v.id}, f'New reply by @{c2.author_name}', "zoz", c2)
2023-10-06 13:16:07 +00:00
def execute_longpostbot(c, level, body, body_html, post, v):
2024-02-21 20:30:09 +00:00
if not LONGPOSTBOT_ID: return
2022-10-09 16:40:20 +00:00
if not len(c.body.split()) >= 200: return
2023-10-06 17:09:40 +00:00
if "</blockquote>" in body_html: return
2023-10-06 17:09:40 +00:00
posting_to_post = isinstance(post, Post)
2023-10-07 17:55:50 +00:00
if posting_to_post and post.hole and g.db.query(Exile.user_id).filter_by(user_id=LONGPOSTBOT_ID, hole=post.hole).one_or_none():
2023-10-06 17:09:40 +00:00
return
2023-08-10 12:04:20 +00:00
body = random.choice(LONGPOSTBOT_REPLIES)
if body.startswith(''):
body = body[1:]
vote = CommentVote(user_id=LONGPOSTBOT_ID,
vote_type=-1,
comment_id=c.id,
real = True
)
2023-03-16 06:27:58 +00:00
g.db.add(vote)
c.downvotes = 1
body_html = sanitize(body)
c2 = Comment(author_id=LONGPOSTBOT_ID,
2023-10-06 13:16:07 +00:00
parent_post=post.id if posting_to_post else None,
wall_user_id=post.id if not posting_to_post else None,
parent_comment_id=c.id,
level=level+1,
is_bot=True,
body=body,
body_html=body_html,
top_comment_id=c.top_comment_id,
ghost=c.ghost
)
2023-03-16 06:27:58 +00:00
g.db.add(c2)
longpostbot = get_account(LONGPOSTBOT_ID)
longpostbot.comment_count += 1
longpostbot.pay_account('coins', 1)
2023-03-16 06:27:58 +00:00
g.db.add(longpostbot)
g.db.flush()
n = Notification(comment_id=c2.id, user_id=v.id)
2023-03-16 06:27:58 +00:00
g.db.add(n)
2022-10-09 13:49:08 +00:00
if posting_to_post:
2023-10-06 13:16:07 +00:00
post.comment_count += 1
g.db.add(post)
2023-02-27 13:35:53 +00:00
push_notif({v.id}, f'New reply by @{c2.author_name}', c2.body, c2)
def tempban_for_spam(v):
text = "Your account has been banned for **1 day** for the following reason:\n\n> Too much spam!"
send_repeatable_notification(v.id, text)
v.ban(reason="Spam", days=1)
2023-08-23 21:57:39 +00:00
ma = ModAction(
kind="ban_user",
user_id=AUTOJANNY_ID,
target_user_id=v.id,
_note=f'duration: for 1 day, reason: "Spam"'
)
g.db.add(ma)
def execute_antispam_post_check(title, v, url):
2023-08-31 10:38:01 +00:00
if v.admin_level >= PERMS['BYPASS_ANTISPAM_CHECKS']:
2023-08-31 10:31:04 +00:00
return True
2023-08-08 12:04:15 +00:00
2022-10-12 05:11:20 +00:00
now = int(time.time())
cutoff = now - 60 * 60 * 24
2023-06-07 23:26:32 +00:00
similar_posts = g.db.query(Post).filter(
Post.author_id == v.id,
Post.title.op('<->')(title) < SPAM_SIMILARITY_THRESHOLD,
Post.created_utc > cutoff
2022-10-12 05:11:20 +00:00
).all()
if url:
2023-06-07 23:26:32 +00:00
similar_urls = g.db.query(Post).filter(
Post.author_id == v.id,
Post.url.op('<->')(url) < SPAM_URL_SIMILARITY_THRESHOLD,
Post.created_utc > cutoff
2022-10-12 05:11:20 +00:00
).all()
else: similar_urls = []
threshold = SPAM_SIMILAR_COUNT_THRESHOLD
if v.age >= (60 * 60 * 24 * 7): threshold *= 3
elif v.age >= (60 * 60 * 24): threshold *= 2
if max(len(similar_urls), len(similar_posts)) >= threshold:
tempban_for_spam(v)
2022-10-12 05:11:20 +00:00
for post in similar_posts + similar_urls:
post.is_banned = True
2024-02-18 15:29:53 +00:00
post.profile_pinned = False
2022-10-12 05:11:20 +00:00
post.ban_reason = "AutoJanny"
2023-03-16 06:27:58 +00:00
g.db.add(post)
2024-01-31 21:56:32 +00:00
ma = ModAction(
2022-10-12 05:11:20 +00:00
user_id=AUTOJANNY_ID,
2023-06-07 23:26:32 +00:00
target_post_id=post.id,
2022-10-12 05:11:20 +00:00
kind="ban_post",
_note="Spam"
2022-10-12 05:11:20 +00:00
)
2023-03-16 06:27:58 +00:00
g.db.add(ma)
2022-10-12 05:11:20 +00:00
return False
return True
2023-07-30 00:42:06 +00:00
def execute_antispam_duplicate_comment_check(v, body_html):
2023-08-31 10:38:01 +00:00
if v.admin_level >= PERMS['BYPASS_ANTISPAM_CHECKS']:
2023-08-31 10:31:04 +00:00
return
if v.id in ANTISPAM_BYPASS_IDS:
return
if v.age >= NOTIFICATION_SPAM_AGE_THRESHOLD:
return
if len(body_html) < 16:
return
2022-11-23 20:45:09 +00:00
ANTISPAM_DUPLICATE_THRESHOLD = 3
2022-11-14 03:48:52 +00:00
compare_time = int(time.time()) - 60 * 60 * 24
2023-03-16 06:27:58 +00:00
count = g.db.query(Comment.id).filter(Comment.body_html == body_html,
2022-11-23 20:45:09 +00:00
Comment.created_utc >= compare_time).count()
if count <= ANTISPAM_DUPLICATE_THRESHOLD: return
tempban_for_spam(v)
2023-03-16 06:27:58 +00:00
g.db.commit()
2022-11-14 03:48:52 +00:00
abort(403, "Too much spam!")
2023-07-30 00:42:06 +00:00
def execute_antispam_comment_check(body, v):
2023-08-31 10:38:01 +00:00
if v.admin_level >= PERMS['BYPASS_ANTISPAM_CHECKS']:
2023-08-31 10:31:04 +00:00
return
2022-10-24 17:27:25 +00:00
if v.id in ANTISPAM_BYPASS_IDS: return
2022-10-12 05:11:20 +00:00
if len(body) <= COMMENT_SPAM_LENGTH_THRESHOLD: return
now = int(time.time())
cutoff = now - 60 * 60 * 24
2023-03-16 06:27:58 +00:00
similar_comments = g.db.query(Comment).filter(
2022-10-12 05:11:20 +00:00
Comment.author_id == v.id,
Comment.body.op('<->')(body) < COMMENT_SPAM_SIMILAR_THRESHOLD,
Comment.created_utc > cutoff
).all()
threshold = COMMENT_SPAM_COUNT_THRESHOLD
if v.age >= (60 * 60 * 24 * 7):
threshold *= 3
elif v.age >= (60 * 60 * 24):
threshold *= 2
2022-10-12 05:11:20 +00:00
if len(similar_comments) <= threshold: return
tempban_for_spam(v)
2022-10-12 05:11:20 +00:00
for comment in similar_comments:
comment.is_banned = True
comment.ban_reason = "AutoJanny"
2023-03-16 06:27:58 +00:00
g.db.add(comment)
2024-01-31 21:56:32 +00:00
ma = ModAction(
2022-10-12 05:11:20 +00:00
user_id=AUTOJANNY_ID,
target_comment_id=comment.id,
kind="ban_comment",
_note="Spam"
2022-10-12 05:11:20 +00:00
)
2023-03-16 06:27:58 +00:00
g.db.add(ma)
g.db.commit()
2022-10-21 00:28:05 +00:00
abort(403, "Too much spam!")
2023-07-30 00:42:06 +00:00
def execute_under_siege(v, target, body, kind):
if v.shadowbanned: return
2023-06-30 20:17:56 +00:00
2023-08-31 10:38:01 +00:00
if v.admin_level >= PERMS['BYPASS_UNDER_SIEGE_MODE']: return
2023-02-27 12:49:19 +00:00
2024-01-31 23:28:39 +00:00
thresholds = cache.get("under_siege_thresholds")
if not thresholds:
thresholds = DEFAULT_UNDER_SIEGE_THRESHOLDS
cache.set("under_siege_thresholds", thresholds)
2023-02-27 12:49:19 +00:00
2024-01-31 23:28:39 +00:00
if v.age > thresholds[kind] * 60:
return
2022-12-18 14:23:59 +00:00
2023-08-11 13:15:34 +00:00
unshadowbannedcels = [x[0] for x in g.db.query(ModAction.target_user_id).filter_by(kind='unshadowban')]
if v.id in unshadowbannedcels: return
2023-07-25 16:42:16 +00:00
check_for_alts(v)
if v.shadowbanned: return
v.shadowbanned = AUTOJANNY_ID
v.shadowban_reason = "Under Siege"
g.db.add(v)
if kind == "report":
2023-06-07 23:26:32 +00:00
if isinstance(target, Post):
reason = f'report on <a href="{target.permalink}">post</a>'
else:
reason = f'report on <a href="{target.permalink}">comment</a>'
2024-02-11 16:45:00 +00:00
elif hasattr(target, 'permalink'):
reason = f'<a href="{target.permalink}">{kind}</a>'
else:
reason = kind
2024-02-01 17:30:04 +00:00
minutes = math.ceil(v.age / 60)
time_taken = f'{minutes} minute'
if minutes > 1:
time_taken += 's'
ma = ModAction(
kind="shadowban",
user_id=AUTOJANNY_ID,
target_user_id=v.id,
_note=f'reason: "Under Siege ({reason}, {time_taken})"'
)
g.db.add(ma)
def process_options(v, target):
patterns = [(poll_regex, 0), (choice_regex, 1)]
2023-03-12 17:36:35 +00:00
if v.admin_level >= PERMS['POST_BETS']:
patterns.append((bet_regex, 2))
option_count = 0
2023-03-23 15:52:31 +00:00
option_objects = []
for pattern, exclusive in patterns:
2023-07-14 14:46:35 +00:00
body_html = target.body_html.replace('&amp;', '&')
for i in pattern.finditer(body_html):
option_count += 1
if option_count > POLL_MAX_OPTIONS:
abort(400, f"Max number of poll options is {POLL_MAX_OPTIONS}")
2023-03-12 18:40:18 +00:00
body = i.group(2)
if len(body) > 500:
2024-02-14 09:34:49 +00:00
abort(400, f"Poll option body is too long (Max 500 characters)")
2023-06-07 23:26:32 +00:00
if isinstance(target, Post):
cls = PostOption
else:
cls = CommentOption
2023-03-16 06:27:58 +00:00
existing = g.db.query(cls).filter_by(
parent_id=target.id,
2023-07-14 14:46:35 +00:00
body_html=body,
exclusive=exclusive,
2023-02-28 23:46:11 +00:00
).first()
2023-05-05 21:45:25 +00:00
if not existing:
option = cls(
parent_id=target.id,
2023-07-14 14:46:35 +00:00
body_html=body,
exclusive=exclusive,
)
2023-03-23 15:53:01 +00:00
option_objects.append(option) #shitty hack to bypass autoflush
2023-03-23 15:52:31 +00:00
g.db.add_all(option_objects)