MarseyWorld/files/helpers/actions.py

629 lines
19 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)
2024-02-08 00:36:54 +00:00
if url.startswith('https://twitter.com/'):
url = url.replace('https://twitter.com/', 'https://nitter.unixfox.eu/')
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
if 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)
post.author.pay_account('coins', awarded_coins)
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"
if post.url and not post.url.startswith('/') and not post.url.startswith(f'{SITE_FULL}/') and not post.url.startswith(SITE_FULL_IMAGES):
2023-10-26 21:53:16 +00:00
if post.url.startswith('https://old.reddit.com/r/') and '/comments/' in post.url:
2023-09-09 15:44:47 +00:00
rev = post.url.replace('https://old.reddit.com/', '')
rev = f"* [undelete.pullpush.io](https://undelete.pullpush.io/{rev})\n\n"
elif post.url.startswith("https://old.reddit.com/user/"):
rev = post.url.replace('https://old.reddit.com/user/', '')
rev = f"* [search-new.pullpush.io](https://search-new.pullpush.io/?author={rev}&type=submission)\n\n"
2023-09-09 15:44:47 +00:00
else: rev = ''
body += f"Snapshots:\n\n{rev}* [ghostarchive.org](https://ghostarchive.org/search?term={quote(post.url)})\n\n* [archive.org](https://web.archive.org/{post.url})\n\n* [archive.ph](https://archive.ph/?url={quote(post.url)}&run=1) (click to archive)\n\n"
2022-09-22 20:45:26 +00:00
archive_url(post.url)
2022-08-15 17:45:43 +00:00
captured = []
body_for_snappy = post.body_html.replace(' data-src="', ' src="')
2022-07-11 17:45:07 +00:00
for i in list(snappy_url_regex.finditer(body_for_snappy)):
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))
for href, title in captured:
2023-10-26 21:35:08 +00:00
if href == post.url: continue
if href.startswith(f'{SITE_FULL}/') or href.startswith(SITE_FULL_IMAGES): continue
if "Snapshots:\n\n" not in body: body += "Snapshots:\n\n"
if f'**[{title}]({href})**:\n\n' not in body:
addition = f'**[{title}]({href})**:\n\n'
2023-10-26 21:53:16 +00:00
if href.startswith('https://old.reddit.com/r/') and '/comments/' in href:
2023-09-09 15:44:47 +00:00
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"
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,
2022-12-30 15:47:40 +00:00
_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):
if SITE_NAME != 'rDrama': 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):
if SITE_NAME != 'rDrama': 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",
2023-02-19 13:24:42 +00:00
_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",
2023-02-19 13:24:42 +00:00
_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,
2024-02-01 17:30:04 +00:00
_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)