initial
This commit is contained in:
commit
ca59f2882a
|
@ -0,0 +1,13 @@
|
||||||
|
.idea
|
||||||
|
.venv
|
||||||
|
lib64
|
||||||
|
lib
|
||||||
|
includes
|
||||||
|
.env
|
||||||
|
pyvenv.cfg
|
||||||
|
__pycache__
|
||||||
|
bin
|
||||||
|
logs
|
||||||
|
venv
|
||||||
|
.env
|
||||||
|
.env.dev
|
|
@ -0,0 +1,18 @@
|
||||||
|
import logging
|
||||||
|
import var
|
||||||
|
|
||||||
|
logger = logging.getLogger('logger')
|
||||||
|
logger.setLevel(logging.INFO)
|
||||||
|
|
||||||
|
file_log = logging.FileHandler(f'logs/log{var.log_startup_time}.txt')
|
||||||
|
file_log.setLevel(logging.INFO)
|
||||||
|
|
||||||
|
console_log = logging.StreamHandler()
|
||||||
|
console_log.setLevel(logging.INFO)
|
||||||
|
|
||||||
|
formatter = logging.Formatter('%(asctime)s - %(name)s - %(module)s - %(levelname)s - %(message)s')
|
||||||
|
file_log.setFormatter(formatter)
|
||||||
|
console_log.setFormatter(formatter)
|
||||||
|
|
||||||
|
logger.addHandler(file_log)
|
||||||
|
logger.addHandler(console_log)
|
|
@ -0,0 +1,39 @@
|
||||||
|
#!/home/opc/automod3/mv/bin/python3.11
|
||||||
|
import asyncio
|
||||||
|
from datetime import datetime
|
||||||
|
import functions.get_newest_count
|
||||||
|
from functions.send_message import send_message
|
||||||
|
from functions.scan_posts import scan_posts
|
||||||
|
from functions.check_chat import check_chat
|
||||||
|
import var
|
||||||
|
from beloved_logger import logger
|
||||||
|
from functions.update_display_name import update_display_name
|
||||||
|
|
||||||
|
|
||||||
|
async def main_loop():
|
||||||
|
await check_chat()
|
||||||
|
|
||||||
|
if var.text_scanning_is_running or var.image_scanning_is_running:
|
||||||
|
await scan_posts()
|
||||||
|
|
||||||
|
|
||||||
|
async def startup():
|
||||||
|
var.current_posts_at_start_time = await functions.get_newest_count.get_newest_count()
|
||||||
|
var.bot_started_at = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
||||||
|
|
||||||
|
logger.info(f"Started bot with values:\n "
|
||||||
|
f"bot start time: {var.bot_started_at}\n"
|
||||||
|
f"logging start time: {var.log_startup_time}\n"
|
||||||
|
f"site used: {var.site}\n"
|
||||||
|
f"imagescanning runs: {var.image_scanning_is_running}\n"
|
||||||
|
f"image scan only scans new users: {var.scan_new_users_only}\n"
|
||||||
|
f"textscanning runs: {var.text_scanning_is_running}\n"
|
||||||
|
f"chat number: {var.chat_number}\n"
|
||||||
|
f"filters list: {var.filters_list}\n")
|
||||||
|
await update_display_name()
|
||||||
|
while True:
|
||||||
|
await main_loop()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
asyncio.run(startup())
|
|
@ -0,0 +1,158 @@
|
||||||
|
import requests
|
||||||
|
import datetime
|
||||||
|
import boto3
|
||||||
|
import var
|
||||||
|
import classes.rating
|
||||||
|
from functions.delete_post import delete_post
|
||||||
|
from beloved_logger import logger
|
||||||
|
|
||||||
|
|
||||||
|
class Post:
|
||||||
|
post_id = None
|
||||||
|
post_description = None
|
||||||
|
post_name = None
|
||||||
|
image = None
|
||||||
|
user_id = None
|
||||||
|
poster_username = None
|
||||||
|
poster_sign_up_time = None
|
||||||
|
response = None
|
||||||
|
date = None
|
||||||
|
infringing_words = []
|
||||||
|
ratings = None
|
||||||
|
post_will_be_deleted = None
|
||||||
|
deletion_status = None
|
||||||
|
|
||||||
|
def __init__(self, post_id):
|
||||||
|
logger.info(f"Post was made with ID {post_id}")
|
||||||
|
self.post_id = post_id
|
||||||
|
self.infringing_words = []
|
||||||
|
|
||||||
|
async def get_values(self):
|
||||||
|
response = requests.get(f"https://{var.site}/posts/{self.post_id}",
|
||||||
|
headers={'User-Agent': 'automod',
|
||||||
|
"Accept": "application/json,text/plain, */*"})
|
||||||
|
|
||||||
|
if response.status_code == 200:
|
||||||
|
self.response = response.json()
|
||||||
|
if response.json()['post']['resource_url']:
|
||||||
|
self.image = requests.get(self.response['post']['resource_url']).content
|
||||||
|
|
||||||
|
self.post_name = self.response['post']["title"]
|
||||||
|
self.user_id = self.response['post']['profile_id']
|
||||||
|
self.poster_username = self.response['post']['profile']['username']
|
||||||
|
self.poster_sign_up_time = self.response['post']['profile']['created_at']
|
||||||
|
self.date = self.response['post']['created_at']
|
||||||
|
self.post_description = self.response['post']["description"]
|
||||||
|
|
||||||
|
logger.debug(f"Got post {self.post_id} with details {self.response}")
|
||||||
|
else:
|
||||||
|
logger.info(f"An error occurred getting post with ID {self.post_id} for reason {response.status_code}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
async def analyse_text(self):
|
||||||
|
logger.info(f"Getting text analysis of post with post ID {self.post_id}")
|
||||||
|
|
||||||
|
if self.post_name:
|
||||||
|
for word in var.filters_list:
|
||||||
|
if word.lower() in self.post_name.lower() and word not in self.infringing_words:
|
||||||
|
logger.info(f"Post {self.post_id}'s name contained infringing word {word}")
|
||||||
|
self.infringing_words.append(word)
|
||||||
|
|
||||||
|
if self.post_description:
|
||||||
|
for word in var.filters_list:
|
||||||
|
if word.lower() in self.post_description.lower() and word not in self.infringing_words:
|
||||||
|
logger.info(f"Post {self.post_id}'s description contained infringing word {word}")
|
||||||
|
self.infringing_words.append(word)
|
||||||
|
|
||||||
|
async def analyse_image(self):
|
||||||
|
logger.info(f"Getting image analysis of post with post ID {self.post_id}")
|
||||||
|
if self.image:
|
||||||
|
logger.info(f"Post {self.post_id} had an image")
|
||||||
|
await self.detect_image()
|
||||||
|
if self.ratings:
|
||||||
|
logger.info(f"Post {self.post_id} has ratings: {await self.get_ratings_string()}")
|
||||||
|
await self.check_ratings()
|
||||||
|
if self.post_will_be_deleted:
|
||||||
|
logger.info(f"Post {self.post_id} will be deleted")
|
||||||
|
await self.remove_post()
|
||||||
|
logger.info(f"Post {self.post_id} was deleted")
|
||||||
|
else:
|
||||||
|
logger.info(f"Post {self.post_id} will not be deleted")
|
||||||
|
else:
|
||||||
|
logger.info(f"Post {self.post_id} did not have any ratings")
|
||||||
|
else:
|
||||||
|
logger.info(f"Post {self.post_id} was either a text post or deleted before analysis")
|
||||||
|
|
||||||
|
async def detect_image(self):
|
||||||
|
logger.info(f"Sending data to AWS for post {self.post_id}")
|
||||||
|
client = boto3.client('rekognition', region_name=var.aws_region)
|
||||||
|
self.ratings = classes.rating.create_ratings(client.detect_moderation_labels(Image={'Bytes': self.image}))
|
||||||
|
|
||||||
|
async def check_ratings(self):
|
||||||
|
logger.info(f"Checking ratings for post {self.post_id}")
|
||||||
|
one_rating_was_false = False
|
||||||
|
|
||||||
|
for post_rating in self.ratings:
|
||||||
|
if post_rating.confidence > 90 and post_rating.enabled:
|
||||||
|
logger.info(f"Post {self.post_id} contained enabled rating more than 90 for {post_rating.name} which "
|
||||||
|
f"was type of {post_rating.type}")
|
||||||
|
self.post_will_be_deleted = True
|
||||||
|
elif not post_rating.enabled:
|
||||||
|
logger.info(f"Post {self.post_id} had a rating of {post_rating.name} in the "
|
||||||
|
f"{post_rating.type} category at confidence {post_rating.confidence}"
|
||||||
|
f"but it was not enabled. Post will not be deleted.")
|
||||||
|
one_rating_was_false = True
|
||||||
|
|
||||||
|
if one_rating_was_false:
|
||||||
|
self.post_will_be_deleted = False
|
||||||
|
self.ratings = None
|
||||||
|
|
||||||
|
async def remove_post(self):
|
||||||
|
var.most_recently_deleted_post_id = self.post_id
|
||||||
|
self.deletion_status = False
|
||||||
|
if self.post_will_be_deleted:
|
||||||
|
logger.info(f"Attempting to delete a post {self.post_id} for {await self.get_ratings_string()}")
|
||||||
|
|
||||||
|
self.deletion_status = await delete_post(self.post_id)
|
||||||
|
if self.deletion_status == 200:
|
||||||
|
logger.info(f"Post {self.post_id} was deleted")
|
||||||
|
self.deletion_status = True
|
||||||
|
else:
|
||||||
|
logger.info(f"An issue occurred deleting {self.post_id} for reason {self.deletion_status}")
|
||||||
|
self.deletion_status = f"Problem occurred with deletion: {self.deletion_status}"
|
||||||
|
|
||||||
|
async def get_readable_date(self):
|
||||||
|
return datetime.datetime.utcfromtimestamp(self.date).strftime('%Y-%m-%d %H:%M:%S')
|
||||||
|
|
||||||
|
async def get_censorship_string(self):
|
||||||
|
return '", "'.join(self.infringing_words)
|
||||||
|
|
||||||
|
async def get_ratings_string(self):
|
||||||
|
ratings_string = ""
|
||||||
|
for post_rating in self.ratings:
|
||||||
|
ratings_string += str(post_rating)
|
||||||
|
return ratings_string
|
||||||
|
|
||||||
|
async def get_as_text_detection_text(self):
|
||||||
|
string = (f'‼️ *DETECTED:* "{await self.get_censorship_string()}"\n' +
|
||||||
|
f'🗒️ *TITLE:* "{self.post_name}"\n' +
|
||||||
|
f"🔗 *URL:* https://{var.site}/admin/posts/{self.post_id}\n" +
|
||||||
|
f"👤 *POSTER:* https://{var.site}/users/{self.user_id} / @{self.poster_username}\n"
|
||||||
|
f"The user was also suspended for a day, you will have to reverse this suspension if the moderation action was not warranted..")
|
||||||
|
return string
|
||||||
|
|
||||||
|
async def get_as_image_deletion_text(self):
|
||||||
|
ratings_string = ""
|
||||||
|
for post_rating in self.ratings:
|
||||||
|
ratings_string += str(post_rating)
|
||||||
|
|
||||||
|
if self.deletion_status is None:
|
||||||
|
self.deletion_status = False
|
||||||
|
|
||||||
|
string = (f"{ratings_string} \n " +
|
||||||
|
f'🗒️ *TITLE:* "{self.post_name}"\n' +
|
||||||
|
f"🔗 *URL:* https://{var.site}/admin/posts/{self.post_id}\n" +
|
||||||
|
f"👤 *POSTER:* https://{var.site}/users/{self.user_id} / @{self.poster_username}\n" +
|
||||||
|
f"❌ *DELETED:* {str(self.deletion_status)}"
|
||||||
|
f"The user was also suspended for a day, if the suspension was not warranted you must undo the suspension")
|
||||||
|
return string
|
|
@ -0,0 +1,54 @@
|
||||||
|
import var
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
|
class Rating:
|
||||||
|
name = ""
|
||||||
|
confidence = 0
|
||||||
|
enabled = False
|
||||||
|
type = ""
|
||||||
|
|
||||||
|
def __init__(self, name, confidence):
|
||||||
|
self.name = name
|
||||||
|
self.confidence = confidence
|
||||||
|
self.enabled = self.get_status()
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"‼️ *{self.name}:* {round(self.confidence, 2)}%\n"
|
||||||
|
|
||||||
|
def get_status(self):
|
||||||
|
with open(var.labels_file, 'r') as file:
|
||||||
|
data = json.load(file)
|
||||||
|
|
||||||
|
top_level_true = []
|
||||||
|
top_level_false = []
|
||||||
|
lower_level_true = []
|
||||||
|
lower_level_false = []
|
||||||
|
|
||||||
|
for top_level_object, top_level_data in data.items():
|
||||||
|
if top_level_data.get("status") is True:
|
||||||
|
top_level_true.append(top_level_object)
|
||||||
|
elif top_level_data.get("status") is False:
|
||||||
|
top_level_false.append(top_level_object)
|
||||||
|
|
||||||
|
for lower_level_object, lower_level_status in top_level_data.items():
|
||||||
|
if lower_level_status is True and lower_level_object != "status":
|
||||||
|
lower_level_true.append(f"{lower_level_object}")
|
||||||
|
elif lower_level_status is False and lower_level_object != "status":
|
||||||
|
lower_level_false.append(f"{lower_level_object}")
|
||||||
|
|
||||||
|
if self.name in lower_level_true:
|
||||||
|
self.type = "secondary"
|
||||||
|
return True
|
||||||
|
if self.name in top_level_true:
|
||||||
|
self.type = "primary"
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def create_ratings(response):
|
||||||
|
ratings = []
|
||||||
|
for label in response['ModerationLabels']:
|
||||||
|
rating = Rating(label['Name'], label['Confidence'])
|
||||||
|
ratings.append(rating)
|
||||||
|
return ratings
|
|
@ -0,0 +1,9 @@
|
||||||
|
ted
|
||||||
|
green
|
||||||
|
bert
|
||||||
|
filter
|
||||||
|
HELLO
|
||||||
|
DIGLES
|
||||||
|
wiglett
|
||||||
|
STUPID
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
boto3~=1.28.39\nselenium~=4.12.0\npy-cord\nrequests~=2.31.0\npython-dotenv
|
|
@ -0,0 +1,71 @@
|
||||||
|
{
|
||||||
|
"Explicit Nudity": {
|
||||||
|
"status": true,
|
||||||
|
"Nudity": true,
|
||||||
|
"Graphic Male Nudity": true,
|
||||||
|
"Graphic Female Nudity": true,
|
||||||
|
"Sexual Activity": true,
|
||||||
|
"Illustrated Explicit Nudity": true,
|
||||||
|
"Adult Toys": true
|
||||||
|
},
|
||||||
|
"Suggestive": {
|
||||||
|
"status": true,
|
||||||
|
"Female Swimwear Or Underwear": true,
|
||||||
|
"Male Swimwear Or Underwear": true,
|
||||||
|
"Partial Nudity": false,
|
||||||
|
"Barechested Male": false,
|
||||||
|
"Revealing Clothes": false,
|
||||||
|
"Sexual Situations": true
|
||||||
|
},
|
||||||
|
"Violence": {
|
||||||
|
"status": true,
|
||||||
|
"Graphic Violence Or Gore": true,
|
||||||
|
"Physical Violence": true,
|
||||||
|
"Weapon Violence": true,
|
||||||
|
"Weapons": false,
|
||||||
|
"Self Injury": true
|
||||||
|
},
|
||||||
|
"Visually Disturbing":
|
||||||
|
{
|
||||||
|
"status": true,
|
||||||
|
"Emaciated Bodies": true,
|
||||||
|
"Corpses": true,
|
||||||
|
"Hanging": true,
|
||||||
|
"Air Crash": false,
|
||||||
|
"Explosions And Blasts": false
|
||||||
|
},
|
||||||
|
"Rude Gestures":
|
||||||
|
{
|
||||||
|
"status": false,
|
||||||
|
"Middle Finger": false
|
||||||
|
},
|
||||||
|
"Drugs": {
|
||||||
|
"status": false,
|
||||||
|
"Drug Products": false,
|
||||||
|
"Drug Use": false,
|
||||||
|
"Pills": false,
|
||||||
|
"Drug Paraphernalia": false
|
||||||
|
},
|
||||||
|
"Tobacco": {
|
||||||
|
"status": false,
|
||||||
|
"Tobacco Products": false,
|
||||||
|
"Smoking": false
|
||||||
|
},
|
||||||
|
"Alcohol": {
|
||||||
|
"status": false,
|
||||||
|
"Drinking": false,
|
||||||
|
"Alcoholic Beverages": false
|
||||||
|
},
|
||||||
|
"Gambling": {
|
||||||
|
"status": false,
|
||||||
|
"Gambling": false
|
||||||
|
},
|
||||||
|
"Hate Symbols": {
|
||||||
|
"status": true,
|
||||||
|
"Nazi Party": true,
|
||||||
|
"White Supremacy": true,
|
||||||
|
"Extremist": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
{
|
||||||
|
"Explicit Nudity": {
|
||||||
|
"status": true,
|
||||||
|
"Nudity": true,
|
||||||
|
"Graphic Male Nudity": true,
|
||||||
|
"Graphic Female Nudity": true,
|
||||||
|
"Sexual Activity": true,
|
||||||
|
"Illustrated Explicit Nudity": true,
|
||||||
|
"Adult Toys": true
|
||||||
|
},
|
||||||
|
"Suggestive": {
|
||||||
|
"status": true,
|
||||||
|
"Female Swimwear Or Underwear": false,
|
||||||
|
"Male Swimwear Or Underwear": false,
|
||||||
|
"Partial Nudity": false,
|
||||||
|
"Barechested Male": false,
|
||||||
|
"Revealing Clothes": false,
|
||||||
|
"Sexual Situations": true
|
||||||
|
},
|
||||||
|
"Violence": {
|
||||||
|
"status": true,
|
||||||
|
"Graphic Violence Or Gore": true,
|
||||||
|
"Physical Violence": true,
|
||||||
|
"Weapon Violence": true,
|
||||||
|
"Weapons": false,
|
||||||
|
"Self Injury": true
|
||||||
|
},
|
||||||
|
"Visually Disturbing":
|
||||||
|
{
|
||||||
|
"status": true,
|
||||||
|
"Emaciated Bodies": true,
|
||||||
|
"Corpses": true,
|
||||||
|
"Hanging": true,
|
||||||
|
"Air Crash": false,
|
||||||
|
"Explosions And Blasts": false
|
||||||
|
},
|
||||||
|
"Rude Gestures":
|
||||||
|
{
|
||||||
|
"status": false,
|
||||||
|
"Middle Finger": false
|
||||||
|
},
|
||||||
|
"Drugs": {
|
||||||
|
"status": false,
|
||||||
|
"Drug Products": false,
|
||||||
|
"Drug Use": false,
|
||||||
|
"Pills": false,
|
||||||
|
"Drug Paraphernalia": false
|
||||||
|
},
|
||||||
|
"Tobacco": {
|
||||||
|
"status": false,
|
||||||
|
"Tobacco Products": false,
|
||||||
|
"Smoking": false
|
||||||
|
},
|
||||||
|
"Alcohol": {
|
||||||
|
"status": false,
|
||||||
|
"Drinking": false,
|
||||||
|
"Alcoholic Beverages": false
|
||||||
|
},
|
||||||
|
"Gambling": {
|
||||||
|
"status": false,
|
||||||
|
"Gambling": false
|
||||||
|
},
|
||||||
|
"Hate Symbols": {
|
||||||
|
"status": true,
|
||||||
|
"Nazi Party": true,
|
||||||
|
"White Supremacy": true,
|
||||||
|
"Extremist": true
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 7.3 KiB |
Binary file not shown.
After Width: | Height: | Size: 9.3 KiB |
|
@ -0,0 +1,274 @@
|
||||||
|
import logging
|
||||||
|
import requests
|
||||||
|
import json
|
||||||
|
import functions.get_filters_from_text
|
||||||
|
import functions.get_newest_count
|
||||||
|
import var
|
||||||
|
from functions.send_message import send_message
|
||||||
|
from functions.roll_token import roll_token
|
||||||
|
from beloved_logger import logger
|
||||||
|
from functions.update_display_name import update_display_name
|
||||||
|
|
||||||
|
|
||||||
|
async def get_chat_messages():
|
||||||
|
await roll_token()
|
||||||
|
cookies = {
|
||||||
|
var.cookie_name: var.cookie_value,
|
||||||
|
'sketchers_united_session': var.session,
|
||||||
|
'XSRF-TOKEN': var.xsrf_token
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.debug(f"Getting chat messages with cookies {cookies}")
|
||||||
|
|
||||||
|
headers = {
|
||||||
|
'User-Agent': 'automod',
|
||||||
|
'Accept': 'application/json, */*',
|
||||||
|
'X-CSRF-TOKEN': var.csrf_token,
|
||||||
|
'X-XSRF-TOKEN': var.xsrf_token,
|
||||||
|
}
|
||||||
|
|
||||||
|
params = {
|
||||||
|
'n': '30',
|
||||||
|
}
|
||||||
|
|
||||||
|
get_page_correctly = False
|
||||||
|
response = ""
|
||||||
|
|
||||||
|
while not get_page_correctly:
|
||||||
|
logging.info(f"Getting messages for {var.chat_number}")
|
||||||
|
response = requests.get(f'https://{var.site}/chats/{var.chat_number}/messages', params=params,
|
||||||
|
cookies=cookies,
|
||||||
|
headers=headers)
|
||||||
|
|
||||||
|
if response.status_code == 200:
|
||||||
|
get_page_correctly = True
|
||||||
|
else:
|
||||||
|
logging.error(f"An issue occurred getting the messages "
|
||||||
|
f"for {var.chat_number} with error {response.status_code}")
|
||||||
|
|
||||||
|
return response.json()
|
||||||
|
|
||||||
|
|
||||||
|
async def check_chat():
|
||||||
|
new_chat = await get_chat_messages()
|
||||||
|
if len(var.old_chat) == 0:
|
||||||
|
logging.info("No chat messages were loaded before, so setting the old chat value to the new one")
|
||||||
|
var.old_chat = new_chat
|
||||||
|
|
||||||
|
old_ids = [message["id"] for message in var.old_chat]
|
||||||
|
|
||||||
|
newest_messages = [message for message in new_chat if message["id"] not in old_ids]
|
||||||
|
newest_messages.sort(key=lambda message: message["id"])
|
||||||
|
newest = newest_messages[:15]
|
||||||
|
|
||||||
|
for x in newest:
|
||||||
|
if "@automod" in x['text'][:8]:
|
||||||
|
logging.info(f"Somebody mentioned me with {x['text']}")
|
||||||
|
if "@automod status" in x['text']:
|
||||||
|
if var.image_scanning_is_running:
|
||||||
|
if var.scan_new_users_only:
|
||||||
|
image_scan_status = "Yes, but only for users who have signed up in the past 2 weeks"
|
||||||
|
else:
|
||||||
|
image_scan_status = "Yes"
|
||||||
|
else:
|
||||||
|
image_scan_status = "No"
|
||||||
|
|
||||||
|
if var.text_scanning_is_running:
|
||||||
|
text_scan_status = "Yes"
|
||||||
|
else:
|
||||||
|
text_scan_status = "No"
|
||||||
|
|
||||||
|
await send_message("*🕰 Status*\n"
|
||||||
|
f"🖼️️ *Is image scanning on?:* {image_scan_status}\n"
|
||||||
|
f"💬 *Is text scanning on?:* {text_scan_status}\n"
|
||||||
|
f"🏃♀️ *Running since:* {var.bot_started_at}\n"
|
||||||
|
f"❓ Try typing '@automod help'")
|
||||||
|
|
||||||
|
elif "@automod i love you" in x['text']:
|
||||||
|
await send_message(f"💌 I love you too @{x['profile']['username']}...")
|
||||||
|
|
||||||
|
elif "@automod ping" in x['text']:
|
||||||
|
await send_message("☹️ I've been pinged")
|
||||||
|
|
||||||
|
elif "@automod help" in x['text']:
|
||||||
|
|
||||||
|
await send_message("""⌨️ Prefix commands with @automod e.g. @automod ping
|
||||||
|
ℹ️ *Informational*
|
||||||
|
status
|
||||||
|
i love you
|
||||||
|
ping
|
||||||
|
|
||||||
|
🖼️ *Image scanning*
|
||||||
|
imagescanning on
|
||||||
|
imagescanning off
|
||||||
|
imagescanning list
|
||||||
|
🛑 imagescanning enable _label_
|
||||||
|
🛑 imagescanning disable _label_
|
||||||
|
|
||||||
|
💬️ *Text scanning*
|
||||||
|
textscanning on
|
||||||
|
textscanning off
|
||||||
|
textscanning list
|
||||||
|
textscanning add _word_
|
||||||
|
textscanning remove _word_
|
||||||
|
|
||||||
|
❗ *If I didn't reply to your message, I am likely subject to a rate limit.*
|
||||||
|
🙂 I still did something though, I just didn't tell you about it.""")
|
||||||
|
|
||||||
|
#
|
||||||
|
# TEXT SCANNING
|
||||||
|
#
|
||||||
|
|
||||||
|
elif "@automod textscanning on" in x['text']:
|
||||||
|
if var.text_scanning_is_running:
|
||||||
|
logging.info("Text scanning attempted to be turned on but was already running.")
|
||||||
|
await send_message("💬️ Text scanning is already running!")
|
||||||
|
else:
|
||||||
|
var.current_posts_at_start_time = await functions.get_newest_count.get_newest_count()
|
||||||
|
var.text_scanning_is_running = True
|
||||||
|
logging.info("Turned on textscanning")
|
||||||
|
await send_message(f"💬 Text scanning has been enabled by @{x['profile']['username']}")
|
||||||
|
await update_display_name()
|
||||||
|
|
||||||
|
elif "@automod textscanning off" in x['text']:
|
||||||
|
if var.image_scanning_is_running is False:
|
||||||
|
logging.info("Text scanning attempted to be turning off but was already off")
|
||||||
|
await send_message("🖼️ Text scanning is already off!")
|
||||||
|
else:
|
||||||
|
var.text_scanning_is_running = False
|
||||||
|
logging.info("Turning off textscanning")
|
||||||
|
await send_message(f"💬 Text scanning has been disabled by @{x['profile']['username']}")
|
||||||
|
await update_display_name()
|
||||||
|
|
||||||
|
elif "@automod textscanning list" in x['text']:
|
||||||
|
logging.info("Retrieving textscanning list")
|
||||||
|
with open(var.filter_file, 'r') as file:
|
||||||
|
lines = [line.strip() for line in file if line.strip()]
|
||||||
|
|
||||||
|
lines_joined = ', '.join(lines)
|
||||||
|
logging.debug(f"Currently filtered words retrieved as {lines_joined}")
|
||||||
|
|
||||||
|
await send_message(f"*Current filtered words*\n"
|
||||||
|
f"{lines_joined}")
|
||||||
|
|
||||||
|
elif "@automod textscanning add" in x['text']:
|
||||||
|
parts = x['text'].split()
|
||||||
|
if len(parts) == 4:
|
||||||
|
text_to_add = parts[3]
|
||||||
|
logging.info(f"Adding new word {text_to_add} to list {var.filters_list}")
|
||||||
|
|
||||||
|
if text_to_add.strip() in var.filters_list:
|
||||||
|
logging.info(f"Word {text_to_add} was already in the list {var.filters_list}")
|
||||||
|
await send_message(f"‼️ '{text_to_add}' is already in the filtered words list!")
|
||||||
|
else:
|
||||||
|
with open(var.filter_file, 'a') as file:
|
||||||
|
logging.info(f"Writing {text_to_add} to {var.filter_file}")
|
||||||
|
file.write(text_to_add + '\n')
|
||||||
|
|
||||||
|
await send_message(f"🎉 Added {text_to_add} to the filtered words list.")
|
||||||
|
var.filters_list = await functions.get_filters_from_text.get_filters_from_text(var.filter_file)
|
||||||
|
else:
|
||||||
|
logging.info("Adding of a textscanning word was called without any word provided.")
|
||||||
|
await send_message(f"‼️ You have to provide a word to add to the filtered words list!"
|
||||||
|
f"\ne.g. '@automod filters add _sketch_' will add "
|
||||||
|
f"the word 'sketch' to the filtered words list.")
|
||||||
|
|
||||||
|
elif "@automod textscanning remove" in x['text']:
|
||||||
|
parts = x['text'].split()
|
||||||
|
if len(parts) == 4:
|
||||||
|
text_to_remove = parts[3]
|
||||||
|
logging.info(f"Removing word {text_to_remove} from list {var.filters_list}")
|
||||||
|
|
||||||
|
if text_to_remove.strip() not in var.filters_list:
|
||||||
|
logging.info(f"{text_to_remove} was not a pre-existing filtered word in {var.filters_list}")
|
||||||
|
await send_message(f"⁉️ '{text_to_remove}' was not a pre-existing filtered word.")
|
||||||
|
else:
|
||||||
|
with open(var.filter_file, 'r') as file:
|
||||||
|
lines = file.readlines()
|
||||||
|
|
||||||
|
logging.info(f"Taking away {text_to_remove} from {var.filter_file}")
|
||||||
|
modified_lines = [line.replace(text_to_remove, '') for line in lines]
|
||||||
|
|
||||||
|
with open(var.filter_file, 'w') as file:
|
||||||
|
logging.info(f"Writing the new file back to {var.filter_file}")
|
||||||
|
file.writelines(modified_lines)
|
||||||
|
|
||||||
|
var.filters_list = await functions.get_filters_from_text.get_filters_from_text(var.filter_file)
|
||||||
|
await send_message(f"🎉 Removed '{text_to_remove}' from the filtered words list.")
|
||||||
|
else:
|
||||||
|
logging.info("Removal of a textscanning word was called without any word provided.")
|
||||||
|
await send_message(f"‼️ You have to provide a word to add to the filtered words list!"
|
||||||
|
f"\ne.g. '@automod filters remove _sketch_' will remove "
|
||||||
|
f"the word 'sketch' from the filtered words list.")
|
||||||
|
|
||||||
|
#
|
||||||
|
# IMAGE SCANNING
|
||||||
|
#
|
||||||
|
|
||||||
|
elif "@automod imagescanning on" in x['text']:
|
||||||
|
if var.image_scanning_is_running:
|
||||||
|
logging.info("Image scanning attempted to be turned on but was already running.")
|
||||||
|
await send_message("🖼️ Image scanning is already running!")
|
||||||
|
else:
|
||||||
|
var.current_posts_at_start_time = await functions.get_newest_count.get_newest_count()
|
||||||
|
var.image_scanning_is_running = True
|
||||||
|
logging.info("Image scanning was turned on")
|
||||||
|
await send_message(f"🖼️ Image scanning has been enabled by @{x['profile']['username']}")
|
||||||
|
await update_display_name()
|
||||||
|
|
||||||
|
elif "@automod imagescanning off" in x['text']:
|
||||||
|
if var.image_scanning_is_running is False:
|
||||||
|
logging.info("Image scanning attempted to be turning off but was already off")
|
||||||
|
await send_message("🖼️ Image scanning is already off!")
|
||||||
|
else:
|
||||||
|
var.image_scanning_is_running = False
|
||||||
|
logging.info("Image scanning was turned off")
|
||||||
|
await send_message(f"🖼️ Image scanning has been disabled by @{x['profile']['username']}")
|
||||||
|
await update_display_name()
|
||||||
|
|
||||||
|
elif "@automod imagescanning list" in x['text']:
|
||||||
|
with open(var.labels_file, 'r') as file:
|
||||||
|
logging.info(f"Showing list of imagescanning labels from {var.labels_file}")
|
||||||
|
data = json.load(file)
|
||||||
|
|
||||||
|
top_level_true = []
|
||||||
|
top_level_false = []
|
||||||
|
lower_level_true = []
|
||||||
|
lower_level_false = []
|
||||||
|
|
||||||
|
for top_level_object, top_level_data in data.items():
|
||||||
|
if top_level_data.get("status") is True:
|
||||||
|
top_level_true.append(top_level_object)
|
||||||
|
elif top_level_data.get("status") is False:
|
||||||
|
top_level_false.append(top_level_object)
|
||||||
|
|
||||||
|
for lower_level_object, lower_level_status in top_level_data.items():
|
||||||
|
if lower_level_status is True and lower_level_object != "status":
|
||||||
|
lower_level_true.append(f"{lower_level_object}")
|
||||||
|
elif lower_level_status is False and lower_level_object != "status":
|
||||||
|
lower_level_false.append(f"{lower_level_object}")
|
||||||
|
|
||||||
|
logging.debug(f"*❌ Disabled:* \n"
|
||||||
|
f" _Top level:_ {', '.join(top_level_false)}, \n"
|
||||||
|
f" _Lower level:_ {', '.join(lower_level_false)}\n"
|
||||||
|
f"*✅ Enabled:* \n"
|
||||||
|
f" _Top level:_ {', '.join(top_level_true)}, \n"
|
||||||
|
f" _Lower level:_ {', '.join(lower_level_true)}")
|
||||||
|
|
||||||
|
await send_message(f"*❌ Disabled:* \n"
|
||||||
|
f" _Top level:_ {', '.join(top_level_false)}, \n"
|
||||||
|
f" _Lower level:_ {', '.join(lower_level_false)}\n"
|
||||||
|
f"*✅ Enabled:* \n"
|
||||||
|
f" _Top level:_ {', '.join(top_level_true)}, \n"
|
||||||
|
f" _Lower level:_ {', '.join(lower_level_true)}")
|
||||||
|
|
||||||
|
elif "@automod imagescanning enablefilter" in x['text']:
|
||||||
|
await send_message("Not yet implemented")
|
||||||
|
|
||||||
|
elif "@automod imagescanning disablefilter" in x['text']:
|
||||||
|
await send_message("Not yet implemented")
|
||||||
|
|
||||||
|
else:
|
||||||
|
await send_message("Invalid command given")
|
||||||
|
|
||||||
|
var.old_chat = new_chat
|
|
@ -0,0 +1,28 @@
|
||||||
|
import var
|
||||||
|
import requests
|
||||||
|
from functions.roll_token import roll_token
|
||||||
|
from beloved_logger import logger
|
||||||
|
|
||||||
|
|
||||||
|
async def delete_post(post_id):
|
||||||
|
await roll_token()
|
||||||
|
|
||||||
|
cookies = {
|
||||||
|
var.cookie_name: var.cookie_value,
|
||||||
|
'sketchers_united_session': var.session,
|
||||||
|
'XSRF-TOKEN': var.xsrf_token
|
||||||
|
}
|
||||||
|
logger.debug(f"Deleting post {post_id} with cookies {cookies}")
|
||||||
|
|
||||||
|
headers = {
|
||||||
|
'User-Agent': 'automod',
|
||||||
|
'Accept': 'application/json, */*',
|
||||||
|
'X-CSRF-TOKEN': var.csrf_token,
|
||||||
|
'X-XSRF-TOKEN': var.xsrf_token
|
||||||
|
}
|
||||||
|
|
||||||
|
response = requests.delete(f'https://{var.site}/admin/posts/{post_id}', cookies=cookies,
|
||||||
|
headers=headers)
|
||||||
|
logger.info(f"Deleting post {post_id} concluded with response {response.status_code}")
|
||||||
|
|
||||||
|
return response.status_code
|
|
@ -0,0 +1,8 @@
|
||||||
|
async def get_filters_from_text(filter_file):
|
||||||
|
lines_list = []
|
||||||
|
with open(filter_file, 'r') as file:
|
||||||
|
for line in file:
|
||||||
|
stripped_line = line.strip()
|
||||||
|
if stripped_line:
|
||||||
|
lines_list.append(stripped_line)
|
||||||
|
return lines_list
|
|
@ -0,0 +1,26 @@
|
||||||
|
import requests
|
||||||
|
|
||||||
|
import var
|
||||||
|
from beloved_logger import logger
|
||||||
|
|
||||||
|
|
||||||
|
async def get_newest_count():
|
||||||
|
# logger.info("Getting newest post count")
|
||||||
|
while True:
|
||||||
|
headers = {
|
||||||
|
"Accept": "application/json, */*"
|
||||||
|
}
|
||||||
|
|
||||||
|
response = requests.get(f"https://{var.site}/json/posts", headers=headers)
|
||||||
|
|
||||||
|
if response.status_code == 200:
|
||||||
|
if response.json():
|
||||||
|
if response.json()['data']['posts'][0]['id']:
|
||||||
|
# logger.info(f"Newest post count of {response.json()['data']['posts'][0]['id']}")
|
||||||
|
return response.json()['data']['posts'][0]['id']
|
||||||
|
else:
|
||||||
|
while response.status_code != 200:
|
||||||
|
logger.info(f"Error getting newest post count with reason {response.status_code}, retrying")
|
||||||
|
response = requests.get(f"https://{var.site}/json/posts", headers=headers)
|
||||||
|
# logger.info(f"Newest post count of {response.json()['data']['posts'][0]['id']}")
|
||||||
|
return response.json()['data']['posts'][0]['id']
|
|
@ -0,0 +1,45 @@
|
||||||
|
import var
|
||||||
|
from bs4 import BeautifulSoup
|
||||||
|
import requests
|
||||||
|
from beloved_logger import logger
|
||||||
|
|
||||||
|
|
||||||
|
async def roll_token():
|
||||||
|
logger.debug("Rolled a new token set")
|
||||||
|
|
||||||
|
cookies = {
|
||||||
|
var.cookie_name: var.cookie_value,
|
||||||
|
'sketchers_united_session': var.session
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.debug(f"Using cookies {cookies}")
|
||||||
|
|
||||||
|
headers = {
|
||||||
|
'User-Agent': 'automod',
|
||||||
|
}
|
||||||
|
|
||||||
|
get_page_correctly = False
|
||||||
|
response = None
|
||||||
|
|
||||||
|
|
||||||
|
while not get_page_correctly:
|
||||||
|
try:
|
||||||
|
response = requests.get(f'https://{var.site}', cookies=cookies, headers=headers)
|
||||||
|
|
||||||
|
if response.status_code == 200:
|
||||||
|
var.session = response.cookies["sketchers_united_session"]
|
||||||
|
logger.debug(f"Got session of {var.session}")
|
||||||
|
|
||||||
|
var.xsrf_token = response.cookies["XSRF-TOKEN"]
|
||||||
|
logger.debug(f"Got xsrf of {var.xsrf_token}")
|
||||||
|
|
||||||
|
get_page_correctly = True
|
||||||
|
else:
|
||||||
|
logger.info("An error occurred trying to get the page when rolling tokens, retrying")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.info(f"Exception in rolling token {e}")
|
||||||
|
|
||||||
|
soup = BeautifulSoup(response.text, 'html.parser')
|
||||||
|
var.csrf_token = soup.find('meta', {'name': 'csrf-token'}).get('content')
|
||||||
|
logger.debug(f"Got csrf of {var.csrf_token}")
|
|
@ -0,0 +1,67 @@
|
||||||
|
import functions.get_newest_count
|
||||||
|
import var
|
||||||
|
from classes import post
|
||||||
|
from datetime import datetime, timedelta
|
||||||
|
from functions.send_message import send_message
|
||||||
|
from functions.suspend_user import suspend_user_for_post
|
||||||
|
from beloved_logger import logger
|
||||||
|
|
||||||
|
|
||||||
|
async def scan_posts():
|
||||||
|
logger.debug("Start post scan")
|
||||||
|
if var.most_recently_deleted_post_id > var.current_posts_at_start_time:
|
||||||
|
var.current_posts_at_start_time = var.most_recently_deleted_post_id
|
||||||
|
|
||||||
|
current_posts_now = var.current_posts_at_start_time
|
||||||
|
new_posts = await functions.get_newest_count.get_newest_count()
|
||||||
|
if new_posts != 0:
|
||||||
|
current_posts_now = new_posts
|
||||||
|
|
||||||
|
logger.debug(f"posts now: {current_posts_now}")
|
||||||
|
logger.debug(f"posts previous: {var.current_posts_at_start_time}")
|
||||||
|
|
||||||
|
if current_posts_now != var.current_posts_at_start_time:
|
||||||
|
for i in range(int(var.current_posts_at_start_time) + 1, int(current_posts_now) + 1):
|
||||||
|
post_to_analyse = post.Post(i)
|
||||||
|
await post_to_analyse.get_values()
|
||||||
|
|
||||||
|
if post_to_analyse.response:
|
||||||
|
if var.text_scanning_is_running:
|
||||||
|
await post_to_analyse.analyse_text()
|
||||||
|
if len(post_to_analyse.infringing_words) > 0:
|
||||||
|
await send_message(await post_to_analyse.get_as_text_detection_text())
|
||||||
|
|
||||||
|
if var.image_scanning_is_running:
|
||||||
|
if var.scan_new_users_only:
|
||||||
|
cut_off_date = datetime.now() - timedelta(weeks=2)
|
||||||
|
current_date = datetime.strptime(post_to_analyse.poster_sign_up_time, "%Y-%m-%d %H:%M:%S")
|
||||||
|
|
||||||
|
logger.debug(f"User signed up at {current_date}, we are checking for "
|
||||||
|
f"users that signed up after {cut_off_date}")
|
||||||
|
|
||||||
|
if current_date < cut_off_date:
|
||||||
|
logger.info(f"User was signed up before {cut_off_date}, so checks won't occur")
|
||||||
|
var.most_recently_deleted_post_id = i
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
logger.info(f"User was signed up after {cut_off_date}, so checks will occur")
|
||||||
|
|
||||||
|
logger.info(f"Analysing {i} for image")
|
||||||
|
await post_to_analyse.analyse_image()
|
||||||
|
if post_to_analyse.ratings:
|
||||||
|
if post_to_analyse.deletion_status:
|
||||||
|
message_string = f"""👋 Hello, I am an automatic moderation bot for Sketchers United.
|
||||||
|
|
||||||
|
Your most recent post titled '{post_to_analyse.post_name}' was removed automatically as it was detected to have inappropriate content.
|
||||||
|
As a result, your account was suspended for one day.
|
||||||
|
|
||||||
|
*If this was a mistake don't worry, all deletions and suspensions are subject to human review and corrections to automatic moderation actions (removal of suspensions and restoration of deleted posts) will be made as soon as possible if they are not warranted.*
|
||||||
|
|
||||||
|
❓ If there any questions, problems, or concerns please contact @username
|
||||||
|
"""
|
||||||
|
|
||||||
|
await suspend_user_for_post(post_to_analyse)
|
||||||
|
await send_message(await post_to_analyse.get_as_image_deletion_text())
|
||||||
|
await send_message(message_string, post_to_analyse.poster_username)
|
||||||
|
|
||||||
|
var.current_posts_at_start_time = current_posts_now
|
|
@ -0,0 +1,65 @@
|
||||||
|
import requests
|
||||||
|
from functions.roll_token import roll_token
|
||||||
|
import var
|
||||||
|
from beloved_logger import logger
|
||||||
|
|
||||||
|
|
||||||
|
async def send_message(text, chat_id=None):
|
||||||
|
if chat_id is None:
|
||||||
|
logger.debug(f"No chat id was given, using {var.chat_number}")
|
||||||
|
chat_id = int(var.chat_number)
|
||||||
|
|
||||||
|
logger.info(f"Sending message to {chat_id}")
|
||||||
|
logger.debug(f"Message contents: {text}")
|
||||||
|
|
||||||
|
await roll_token()
|
||||||
|
|
||||||
|
if type(chat_id) != int:
|
||||||
|
cookies = {
|
||||||
|
var.cookie_name: var.cookie_value,
|
||||||
|
'sketchers_united_session': var.session
|
||||||
|
}
|
||||||
|
|
||||||
|
headers = {
|
||||||
|
'User-Agent': 'automod',
|
||||||
|
'Accept': 'application/json, text/plain, */*',
|
||||||
|
}
|
||||||
|
|
||||||
|
response = requests.get(f'https://{var.site}/chats/@{chat_id}',
|
||||||
|
cookies=cookies,
|
||||||
|
headers=headers)
|
||||||
|
|
||||||
|
if response.status_code != 200 and response.status_code != 201:
|
||||||
|
logger.error(f"There was an issue with getting an id from the {chat_id} "
|
||||||
|
f"with error {response.status_code}")
|
||||||
|
return False
|
||||||
|
chat_id = response.json()['id']
|
||||||
|
|
||||||
|
cookies = {
|
||||||
|
var.cookie_name: var.cookie_value,
|
||||||
|
'sketchers_united_session': var.session,
|
||||||
|
'XSRF-TOKEN': var.xsrf_token
|
||||||
|
}
|
||||||
|
|
||||||
|
headers = {
|
||||||
|
'User-Agent': 'automod',
|
||||||
|
'Accept': 'application/json, */*',
|
||||||
|
'X-CSRF-TOKEN': var.csrf_token,
|
||||||
|
'X-XSRF-TOKEN': var.xsrf_token,
|
||||||
|
'Content-Type': 'multipart/form-data; boundary=---------------------------9051447283201882072943098316'
|
||||||
|
}
|
||||||
|
|
||||||
|
data = (f'-----------------------------9051447283201882072943098316'
|
||||||
|
f'\r\nContent-Disposition: form-data; '
|
||||||
|
f'name="text"\r\n\r\n{text}'
|
||||||
|
f'\r\n-----------------------------9051447283201882072943098316--\r\n').encode()
|
||||||
|
|
||||||
|
response = requests.post(f'https://{var.site}/chats/{chat_id}/messages', cookies=cookies,
|
||||||
|
headers=headers,
|
||||||
|
data=data)
|
||||||
|
logger.info(f"Sending message concluded with response {response.status_code}")
|
||||||
|
|
||||||
|
if response.status_code != 200 and response.status_code != 201:
|
||||||
|
logger.error(f"There was an issue with sending a message to the {chat_id} "
|
||||||
|
f"with error {response.status_code}")
|
||||||
|
return False
|
|
@ -0,0 +1,46 @@
|
||||||
|
import logging
|
||||||
|
|
||||||
|
import var
|
||||||
|
import requests
|
||||||
|
from functions.roll_token import roll_token
|
||||||
|
from beloved_logger import logger
|
||||||
|
|
||||||
|
|
||||||
|
async def suspend_user_for_post(post):
|
||||||
|
await roll_token()
|
||||||
|
|
||||||
|
cookies = {
|
||||||
|
var.cookie_name: var.cookie_value,
|
||||||
|
'sketchers_united_session': var.session,
|
||||||
|
'XSRF-TOKEN': var.xsrf_token
|
||||||
|
}
|
||||||
|
|
||||||
|
logging.debug(f"Suspending user with cookies {cookies}")
|
||||||
|
|
||||||
|
headers = {
|
||||||
|
'User-Agent': 'automod',
|
||||||
|
'Content-Type': 'multipart/form-data; boundary=---------------------------33943441651739618973055574259',
|
||||||
|
}
|
||||||
|
|
||||||
|
data = ('-----------------------------33943441651739618973055574259\r\n'
|
||||||
|
'Content-Disposition: form-data; name="_method"\r\n'
|
||||||
|
'\r\nPOST\r\n'
|
||||||
|
'-----------------------------33943441651739618973055574259\r\n'
|
||||||
|
'Content-Disposition: form-data; name="_token"\r\n'
|
||||||
|
f'\r\n{var.csrf_token}\r\n'
|
||||||
|
'-----------------------------33943441651739618973055574259'
|
||||||
|
'\r\nContent-Disposition: form-data; name="blocked_id"\r\n'
|
||||||
|
f'\r\n{post.user_id}\r\n'
|
||||||
|
f'-----------------------------33943441651739618973055574259\r\n'
|
||||||
|
'Content-Disposition: form-data; name="days"\r\n'
|
||||||
|
'\r\n1\r\n'
|
||||||
|
'-----------------------------33943441651739618973055574259\r\n'
|
||||||
|
'Content-Disposition: form-data; name="reason"\r\n'
|
||||||
|
'\r\nother\r\n'
|
||||||
|
'-----------------------------33943441651739618973055574259'
|
||||||
|
'\r\nContent-Disposition: form-data; name="note"\r\n'
|
||||||
|
f'\r\n{await post.get_ratings_string()}\r\n\r\n at https://{var.site}/admin/posts/{post.post_id}\r\n'
|
||||||
|
f'-----------------------------33943441651739618973055574259--\r\n').encode()
|
||||||
|
|
||||||
|
response = requests.post(f'https://{var.site}/admin/blocks', cookies=cookies, headers=headers, data=data)
|
||||||
|
logger.info(f"Suspending user {post.user_id} occurred with: {response.status_code}")
|
|
@ -0,0 +1,89 @@
|
||||||
|
import requests
|
||||||
|
import var
|
||||||
|
from functions.roll_token import roll_token
|
||||||
|
from beloved_logger import logger
|
||||||
|
|
||||||
|
|
||||||
|
async def update_display_name():
|
||||||
|
await roll_token()
|
||||||
|
|
||||||
|
cookies = {
|
||||||
|
var.cookie_name: var.cookie_value,
|
||||||
|
'sketchers_united_session': var.session,
|
||||||
|
'XSRF-TOKEN': var.xsrf_token
|
||||||
|
}
|
||||||
|
logger.debug(f"Updating display name with cookies {cookies}")
|
||||||
|
|
||||||
|
headers = {
|
||||||
|
'User-Agent': 'automod',
|
||||||
|
'Content-Type': 'multipart/form-data; boundary=---------------------------39838723211327797103443672495',
|
||||||
|
}
|
||||||
|
|
||||||
|
value = ""
|
||||||
|
|
||||||
|
if var.text_scanning_is_running:
|
||||||
|
value += "💬"
|
||||||
|
if var.image_scanning_is_running:
|
||||||
|
value += "🖼️"
|
||||||
|
|
||||||
|
new_name = "ms alice a. automod " + value
|
||||||
|
description = (f"automatic moderation bot run by @username, send me a message if there\'s a problem"
|
||||||
|
f"\r\nmessages sent to this account will not be read\r\n")
|
||||||
|
|
||||||
|
data = (f'-----------------------------39838723211327797103443672495'
|
||||||
|
f'\r\nContent-Disposition: form-data; '
|
||||||
|
f'name="_token"\r\n'
|
||||||
|
f'\r\n{var.csrf_token}'
|
||||||
|
f'\r\n-----------------------------39838723211327797103443672495\r'
|
||||||
|
f'\nContent-Disposition: form-data; name="profile_image"; filename=""'
|
||||||
|
f'\r\nContent-Type: '
|
||||||
|
f'application/octet-stream\r\n'
|
||||||
|
f'\r\n-----------------------------39838723211327797103443672495'
|
||||||
|
f'\r\nContent'
|
||||||
|
f'-Disposition: form-data; name="backdrop_image"; filename=""'
|
||||||
|
f'\r\nContent-Type: '
|
||||||
|
f'application/octet-stream\r\n'
|
||||||
|
f'\r\n-----------------------------39838723211327797103443672495'
|
||||||
|
f'\r\nContent'
|
||||||
|
f'-Disposition: form-data; name="name"\r\n'
|
||||||
|
f'\r\n{new_name}'
|
||||||
|
f'\r\n-----------------------------39838723211327797103443672495'
|
||||||
|
f'\r\nContent-Disposition: form-data; '
|
||||||
|
f'name="username"\r\n'
|
||||||
|
f'\r\nakemi'
|
||||||
|
f'\r\n-----------------------------39838723211327797103443672495'
|
||||||
|
f'\r\nContent'
|
||||||
|
f'-Disposition: form-data; name="description"\r\n'
|
||||||
|
f'\r\n{description}'
|
||||||
|
f'-----------------------------39838723211327797103443672495'
|
||||||
|
f'\r\nContent'
|
||||||
|
f'-Disposition: form-data; '
|
||||||
|
f'name="link_amino"\r\n'
|
||||||
|
f'\r\n\r\n-----------------------------39838723211327797103443672495'
|
||||||
|
f'\r\nContent'
|
||||||
|
f'-Disposition: form-data; '
|
||||||
|
f'name="link_deviantart"\r\n'
|
||||||
|
f'\r\n\r\n-----------------------------39838723211327797103443672495'
|
||||||
|
f'\r\nContent'
|
||||||
|
f'-Disposition: form-data; '
|
||||||
|
f'name="link_facebook"\r\n'
|
||||||
|
f'\r\n\r\n-----------------------------39838723211327797103443672495'
|
||||||
|
f'\r\nContent'
|
||||||
|
f'-Disposition: form-data; '
|
||||||
|
f'name="link_instagram"\r\n'
|
||||||
|
f'\r\n\r\n-----------------------------39838723211327797103443672495'
|
||||||
|
f'\r\nContent'
|
||||||
|
f'-Disposition: form-data; '
|
||||||
|
f'name="link_twitter"\r\n'
|
||||||
|
f'\r\n\r\n-----------------------------39838723211327797103443672495'
|
||||||
|
f'\r\nContent'
|
||||||
|
f'-Disposition: form-data; '
|
||||||
|
f'name="link_youtube"\r\n'
|
||||||
|
f'\r\n\r\n-----------------------------39838723211327797103443672495--'
|
||||||
|
f'\r\n').encode()
|
||||||
|
|
||||||
|
response = requests.post(f'https://{var.site}/users/{var.bot_user_number}/update',
|
||||||
|
cookies=cookies,
|
||||||
|
headers=headers,
|
||||||
|
data=data)
|
||||||
|
logger.info(f"Updating display name concluded with response {response.status_code}")
|
|
@ -0,0 +1,5 @@
|
||||||
|
boto3~=1.28.39
|
||||||
|
requests~=2.31.0
|
||||||
|
python-dotenv~=1.0.0
|
||||||
|
websockets~=11.0.3
|
||||||
|
beautifulsoup4~=4.12.2
|
|
@ -0,0 +1,35 @@
|
||||||
|
import asyncio
|
||||||
|
import os
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
from datetime import datetime
|
||||||
|
from functions.get_filters_from_text import get_filters_from_text
|
||||||
|
|
||||||
|
|
||||||
|
load_dotenv('data/.env')
|
||||||
|
|
||||||
|
site = os.getenv("SITE")
|
||||||
|
cookie_name = os.getenv("COOKIE_NAME")
|
||||||
|
cookie_value = os.getenv("COOKIE_VALUE")
|
||||||
|
chat_number = os.getenv("CHAT_NUMBER")
|
||||||
|
filter_file = os.getenv("FILTER_FILE")
|
||||||
|
websocket_url = os.getenv("WEBSOCKET_URL")
|
||||||
|
labels_file = os.getenv("LABELS_FILE")
|
||||||
|
session = os.getenv("STARTUP_SESSION_VALUE")
|
||||||
|
bot_user_number = os.getenv("USER_NUMBER")
|
||||||
|
aws_region = os.getenv("AWS_REGION")
|
||||||
|
|
||||||
|
old_chat = {}
|
||||||
|
scan_new_users_only = True
|
||||||
|
image_scanning_is_running = True
|
||||||
|
text_scanning_is_running = False
|
||||||
|
most_recently_deleted_post_id = 0
|
||||||
|
current_posts_at_start_time = None
|
||||||
|
bot_started_at = None
|
||||||
|
posts_removed = None
|
||||||
|
scanning_since = None
|
||||||
|
user_timeout = None
|
||||||
|
xsrf_token = None
|
||||||
|
csrf_token = None
|
||||||
|
|
||||||
|
filters_list = asyncio.run(get_filters_from_text(filter_file))
|
||||||
|
log_startup_time = datetime.now().strftime("%Y%m%d%H%M%S")
|
Loading…
Reference in New Issue