mirror of
https://gitea.phreedom.club/localhost_frssoft/FMN_bot
synced 2024-11-25 09:09:20 +02:00
Changes:
* Имплементация fail limit * Добавлен api endpoit mute * Изменения в конфигурации и уточнения
This commit is contained in:
parent
aee5d2a9c9
commit
cc2993e59c
11
config.py
11
config.py
|
@ -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
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
@ -68,3 +71,13 @@ def upload_attachment(file_path):
|
|||
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}')
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue