* Имплементация fail limit
* Добавлен api endpoit mute
* Изменения в конфигурации и уточнения
This commit is contained in:
localhost_frssoft 2022-09-02 15:39:46 +03:00
parent aee5d2a9c9
commit cc2993e59c
4 changed files with 55 additions and 16 deletions

View File

@ -2,9 +2,16 @@ admins_bot = ('drq@mastodon.ml',) # Адреса админов бота, кот
# Example: ('admin_user', 'another_admin_user2@example.example') or ('admin_user',)
bot_acct = 'fmn' # Ник бота на инстансе
instance = 'expired.mentality.rip' # Инстанс, где будет запущен бот
# Лимиты
limit_movies_per_user = 2 # Ограничение количества фильмов на одного пользователя
limit_all_movies_poll = 20 # Сколько можно добавить всего фильмов
hour_poll_posting=16 # Час в который будет создан пост с голосовалкой
max_fail_limit = 4 # Игнорировать предложения пользователя при достижении указанного числа проваленных поток предложить фильм
logger_default_level=10 # Уровень логгирования 10 - DEBUG, 20 - INFO, 30 - WARN
# Часы
# Note: Если на ОС часовой пояс отличается от Мск+3, то рекомендуется сместить эти часы здесь или поменять часовой пояс в ОС
hour_poll_posting = 16 # Час в который будет создан пост с голосовалкой (и завершение сбора)
fmn_next_watching_hour = 21 # Час начала киносеанса
logger_default_level = 10 # Уровень логгирования 10 - DEBUG, 20 - INFO, 30 - WARN

View File

@ -1,6 +1,9 @@
from config import instance
import json
import requests
from config import instance
import logging
logger = logging.getLogger('fedi_api')
instance_point = f"https://{instance}/api/v1"
@ -67,4 +70,14 @@ def upload_attachment(file_path):
r = requests.post(instance_point + "/media", params, files=file, headers=headers)
return r.json()['id']
def mute_user(acct_id=str, acct=str, duration=None):
params = {
"duration": duration
}
r = requests.post(instance_point + '/accounts' + f"/{acct_id}/mute", params, headers=headers)
if r.status_code == 200:
logger.info(f'Пользователь {acct} был заглушен на {duration} secs')
else:
logger.error(f'Ошибка глушения {r.status_code} - {acct}')

View File

@ -1,20 +1,22 @@
import time
from datetime import datetime
from dateutil.parser import parse as dateutilparse
from dateutil.relativedelta import relativedelta, TU
import re
import logging
from config import hour_poll_posting, bot_acct, instance, limit_all_movies_poll
from src.fedi_api import get_status_context, get_status, post_status
from config import hour_poll_posting, bot_acct, instance, limit_all_movies_poll, max_fail_limit
from src.fedi_api import get_status_context, get_status, post_status, mute_user
from src.kinopoisk_api import get_kinopoisk_movie
from src.imdb_datasets_worker import get_title_by_id
from src.fmn_database import add_movie_to_poll, get_already_watched, get_suggested_movies_count
from src.fmn_states_db import get_state, add_state
from src.fmn_poll import create_poll_movies, get_winner_movie
import time
from datetime import datetime
from dateutil.parser import parse as dateutilparse
from dateutil.relativedelta import relativedelta, TU
from collections import Counter
import re
import logging
logger = logging.getLogger('thread_listener')
def parse_links(text=str):
regex = r"kinopoisk\.ru/"
if re.search(regex, text.lower(), flags=re.MULTILINE):
@ -34,13 +36,14 @@ def parse_links_imdb(text=str):
def scan_context_thread():
fail_limit = Counter()
while True:
status_id = get_state('last_thread_id')
poll_created = get_state('poll_status_id')
stop_thread_scan = get_state('stop_thread_scan')
flag_scan = 0
time_now = int(time.time())
while status_id is None or stop_thread_scan is None:
fail_limit = Counter()
status_id = get_state('last_thread_id')
stop_thread_scan = get_state('stop_thread_scan')
time.sleep(1)
@ -66,11 +69,20 @@ def scan_context_thread():
id_st = status['id']
in_reply_acct = status['in_reply_to_account_id']
in_reply_id = status['in_reply_to_id']
muted = status['muted']
acct = status['account']['acct']
acct_id = status['account']['id']
content = status['pleroma']['content']['text/plain']
if id_st in replyed: # Игнорировать уже отвеченное
continue
if muted is True:
continue
if fail_limit[acct] >= max_fail_limit: # Игнорировать пользователя если он превысил fail limit
mute_user(acct_id, acct, int(get_state('max_mute_time')) - time_now)
logger.warning(f'{acct} игнорируется - превышение fail limit')
break # Нужно обновить тред, чтобы muted на заглушенном стал True
parsed_result = parse_links(content)
parsed_result_imdb = parse_links_imdb(content)
@ -80,6 +92,7 @@ def scan_context_thread():
if poll_created:
post_status(f' Приём заявок уже окончен.\n\nГолосовалка здесь: https://{instance}/notice/{poll_created}', id_st)
logger.info(f'{acct} был уведомлен о завершенной голосовалке')
fail_limit[acct] += 1
continue
if parsed_result is not None:
@ -100,10 +113,12 @@ def scan_context_thread():
logger.debug(str(movie))
if movie[index_type] == "404":
message_writer.append("Не найдено.")
fail_limit[acct] += 1
elif movie[index_type] not in ("movie", "FILM", "video"):
type_of_title = movie[index_type]
message_writer.append(f"Не принято:\n- Нам не подходят: сериалы, короткометражные и документальные фильмы")
logger.info(f'Предложение {acct} отклонено: не подходящий тип фильма: {type_of_title}')
fail_limit[acct] += 1
else:
name = movie[index_name]
@ -119,6 +134,7 @@ def scan_context_thread():
if get_suggested_movies_count() >= limit_all_movies_poll:
post_status('🎬 Мы не можем обработать ваше предложение: количество уже предложенных не помещается в лимит голосовалки.', id_st)
logger.warning(f'Предложение {acct} было отклонено: количество уже предложенных фильмов превышает\равно {limit_all_movies_poll}')
fail_limit[acct] += 1
break
if get_already_watched(name, name_ru, year) == True:
@ -132,6 +148,7 @@ def scan_context_thread():
else:
post_status("❌ Вы не можете добавить больше 2х фильмов", id_st)
logger.info(f'Предложение от {acct} было отлонено - лимит на пользователя')
fail_limit[acct] += 1
if message_writer != []:
post_status('\n'.join(message_writer) + "\nБлагодарим за ваше предложение!", id_st)

View File

@ -1,6 +1,6 @@
from src.fedi_api import get_notifications, mark_as_read_notification, post_status, upload_attachment
from src.fmn_states_db import add_state, get_state
from config import admins_bot, limit_movies_per_user, limit_all_movies_poll, hour_poll_posting
from config import admins_bot, limit_movies_per_user, limit_all_movies_poll, hour_poll_posting, fmn_next_watching_hour
import threading, time
from datetime import datetime
@ -28,9 +28,10 @@ def get_control_mention():
st_date = i['status']['created_at']
thread_created_at = dateutilparse(st_date)
delta = relativedelta(hour=hour_poll_posting, minute=0, second=0, weekday=TU(1))
next_movie_watching_delta = relativedelta(hour=21, minute=0, second=0, weekday=SU(1))
next_movie_watching_delta = relativedelta(hour=fmn_next_watching_hour, minute=0, second=0, weekday=SU(1))
stop_thread_scan = thread_created_at + delta
next_movie_watching = thread_created_at + next_movie_watching_delta
max_mute_time = time.mktime(time.struct_time(next_movie_watching.timetuple()))
next_movie_watching = next_movie_watching.strftime('%d.%m.%Y')
movies_accept_time = stop_thread_scan.strftime('%H:%M %d.%m.%Y MSK')
stop_thread_scan = time.mktime(time.struct_time(stop_thread_scan.timetuple()))
@ -38,6 +39,7 @@ def get_control_mention():
post_status(start_collect_movies_text(movies_accept_time, next_movie_watching), st_id, attachments=[upload_attachment('src/FMN.png')])
time.sleep(0.2)
mark_as_read_notification(i['id'])
add_state('max_mute_time', int(max_mute_time))
add_state('stop_thread_scan', int(stop_thread_scan))
add_state('last_thread_id', st_id)
break