2022-09-04 02:32:25 +03:00
|
|
|
|
from config import hour_poll_posting, bot_acct, instance, limit_all_movies_poll, limit_movies_per_user, max_fail_limit
|
2022-09-02 15:39:46 +03:00
|
|
|
|
from src.fedi_api import get_status_context, get_status, post_status, mute_user
|
2022-09-04 02:32:25 +03:00
|
|
|
|
from src.kinopoisk_api import get_kinopoisk_movie_to_imdb
|
2022-09-02 15:39:46 +03:00
|
|
|
|
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
|
2022-09-07 02:55:12 +03:00
|
|
|
|
import re
|
2022-08-31 13:20:49 +03:00
|
|
|
|
import time
|
|
|
|
|
from datetime import datetime
|
|
|
|
|
from dateutil.parser import parse as dateutilparse
|
|
|
|
|
from dateutil.relativedelta import relativedelta, TU
|
2022-09-02 15:39:46 +03:00
|
|
|
|
from collections import Counter
|
2022-09-07 02:55:12 +03:00
|
|
|
|
from loguru import logger
|
2022-08-31 13:20:49 +03:00
|
|
|
|
|
2022-09-02 15:39:46 +03:00
|
|
|
|
|
2022-08-31 13:20:49 +03:00
|
|
|
|
def parse_links(text=str):
|
|
|
|
|
regex = r"kinopoisk\.ru/"
|
|
|
|
|
if re.search(regex, text.lower(), flags=re.MULTILINE):
|
|
|
|
|
kinopoisk_ids = re.findall(r"film/(\d{1,})", text.lower())
|
2022-09-04 02:32:25 +03:00
|
|
|
|
if kinopoisk_ids != []:
|
|
|
|
|
return kinopoisk_ids[:limit_movies_per_user]
|
2022-08-31 13:20:49 +03:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def parse_links_imdb(text=str):
|
|
|
|
|
regex = r"imdb\.com/"
|
|
|
|
|
if re.search(regex, text.lower(), flags=re.MULTILINE):
|
|
|
|
|
imdb_ids = re.findall(r"tt(\d{1,})", text.lower())
|
2022-09-04 02:32:25 +03:00
|
|
|
|
if imdb_ids != []:
|
|
|
|
|
return imdb_ids[:limit_movies_per_user]
|
2022-08-31 13:20:49 +03:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def scan_context_thread():
|
2022-09-02 15:39:46 +03:00
|
|
|
|
fail_limit = Counter()
|
2022-08-31 13:20:49 +03:00
|
|
|
|
while True:
|
2022-08-31 18:24:30 +03:00
|
|
|
|
status_id = get_state('last_thread_id')
|
|
|
|
|
poll_created = get_state('poll_status_id')
|
2022-08-31 22:26:58 +03:00
|
|
|
|
stop_thread_scan = get_state('stop_thread_scan')
|
|
|
|
|
time_now = int(time.time())
|
|
|
|
|
while status_id is None or stop_thread_scan is None:
|
2022-09-02 15:39:46 +03:00
|
|
|
|
fail_limit = Counter()
|
2022-08-31 18:24:30 +03:00
|
|
|
|
status_id = get_state('last_thread_id')
|
2022-08-31 22:26:58 +03:00
|
|
|
|
stop_thread_scan = get_state('stop_thread_scan')
|
2022-08-31 13:20:49 +03:00
|
|
|
|
time.sleep(1)
|
2022-08-31 18:24:30 +03:00
|
|
|
|
|
2022-08-31 22:26:58 +03:00
|
|
|
|
if time_now >= int(stop_thread_scan):
|
2022-08-31 13:20:49 +03:00
|
|
|
|
logger.debug('Сбор завершён, сканирование треда на опоздавших')
|
2022-08-31 18:24:30 +03:00
|
|
|
|
if poll_created is None:
|
2022-08-31 13:20:49 +03:00
|
|
|
|
create_poll_movies()
|
2022-08-31 18:24:30 +03:00
|
|
|
|
poll_created = get_state('poll_status_id')
|
2022-08-31 22:26:58 +03:00
|
|
|
|
else:
|
|
|
|
|
if time_now >= int(get_state('poll_expires_at')):
|
|
|
|
|
get_winner_movie(poll_created)
|
2022-08-31 13:20:49 +03:00
|
|
|
|
else:
|
2022-08-31 22:26:58 +03:00
|
|
|
|
endings = int(stop_thread_scan) - time_now
|
2022-08-31 13:20:49 +03:00
|
|
|
|
logger.debug(f'Осталось до закрытия сбора: {endings}')
|
|
|
|
|
descendants = get_status_context(status_id)['descendants']
|
|
|
|
|
replyed = []
|
|
|
|
|
for status in descendants:
|
|
|
|
|
if status['account']['acct'] == bot_acct:
|
|
|
|
|
replyed.append(status['in_reply_to_id'])
|
|
|
|
|
|
|
|
|
|
for status in descendants:
|
|
|
|
|
id_st = status['id']
|
|
|
|
|
in_reply_acct = status['in_reply_to_account_id']
|
|
|
|
|
in_reply_id = status['in_reply_to_id']
|
2022-09-02 15:39:46 +03:00
|
|
|
|
muted = status['muted']
|
2022-08-31 13:20:49 +03:00
|
|
|
|
acct = status['account']['acct']
|
2022-09-02 15:39:46 +03:00
|
|
|
|
acct_id = status['account']['id']
|
2022-08-31 13:20:49 +03:00
|
|
|
|
content = status['pleroma']['content']['text/plain']
|
|
|
|
|
|
|
|
|
|
if id_st in replyed: # Игнорировать уже отвеченное
|
|
|
|
|
continue
|
2022-09-02 15:39:46 +03:00
|
|
|
|
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
|
|
|
|
|
|
2022-08-31 13:20:49 +03:00
|
|
|
|
parsed_result = parse_links(content)
|
|
|
|
|
parsed_result_imdb = parse_links_imdb(content)
|
|
|
|
|
|
|
|
|
|
if parsed_result is None and parsed_result_imdb is None:
|
|
|
|
|
continue
|
|
|
|
|
|
2022-08-31 18:24:30 +03:00
|
|
|
|
if poll_created:
|
|
|
|
|
post_status(f'ℹ️ Приём заявок уже окончен.\n\nГолосовалка здесь: https://{instance}/notice/{poll_created}', id_st)
|
2022-09-01 15:21:35 +03:00
|
|
|
|
logger.info(f'{acct} был уведомлен о завершенной голосовалке')
|
2022-09-02 15:39:46 +03:00
|
|
|
|
fail_limit[acct] += 1
|
2022-08-31 13:20:49 +03:00
|
|
|
|
continue
|
2022-09-04 02:32:25 +03:00
|
|
|
|
|
|
|
|
|
index_type = 1
|
|
|
|
|
index_name = 2
|
|
|
|
|
index_ru_name = 3
|
|
|
|
|
index_year = 4
|
2022-08-31 13:20:49 +03:00
|
|
|
|
if parsed_result is not None:
|
2022-09-04 02:32:25 +03:00
|
|
|
|
print(parsed_result)
|
|
|
|
|
suggested_movies = get_kinopoisk_movie_to_imdb(parsed_result)
|
|
|
|
|
if suggested_movies is None:
|
|
|
|
|
post_status('❌ Не удалось выполнить запрос: возможно некорректный тип фильма, попробуйте использовать imdb.com', id_st)
|
|
|
|
|
fail_limit[acct] += 1
|
|
|
|
|
continue
|
2022-08-31 13:20:49 +03:00
|
|
|
|
elif parsed_result_imdb is not None:
|
|
|
|
|
suggested_movies = get_title_by_id(parsed_result_imdb)
|
2022-09-04 02:32:25 +03:00
|
|
|
|
|
2022-08-31 13:20:49 +03:00
|
|
|
|
message_writer = []
|
2022-09-04 02:32:25 +03:00
|
|
|
|
success = False
|
2022-08-31 13:20:49 +03:00
|
|
|
|
for movie in suggested_movies:
|
2022-09-01 15:21:35 +03:00
|
|
|
|
logger.debug(str(movie))
|
2022-08-31 13:20:49 +03:00
|
|
|
|
if movie[index_type] == "404":
|
|
|
|
|
message_writer.append("❌ Не найдено.")
|
2022-09-02 15:39:46 +03:00
|
|
|
|
fail_limit[acct] += 1
|
2022-09-04 02:32:25 +03:00
|
|
|
|
elif movie[index_type] not in ("movie", "video"):
|
2022-09-01 15:21:35 +03:00
|
|
|
|
type_of_title = movie[index_type]
|
2022-09-02 11:28:24 +03:00
|
|
|
|
message_writer.append(f"❌ Не принято:\n- Нам не подходят: сериалы, короткометражные и документальные фильмы")
|
2022-09-01 15:21:35 +03:00
|
|
|
|
logger.info(f'Предложение {acct} отклонено: не подходящий тип фильма: {type_of_title}')
|
2022-09-02 15:39:46 +03:00
|
|
|
|
fail_limit[acct] += 1
|
2022-08-31 13:20:49 +03:00
|
|
|
|
else:
|
|
|
|
|
|
|
|
|
|
name = movie[index_name]
|
|
|
|
|
name_ru = movie[index_ru_name]
|
|
|
|
|
year = movie[index_year]
|
|
|
|
|
movie_string = f"{name_ru} / {name}, {year}"
|
|
|
|
|
|
|
|
|
|
if name is None:
|
|
|
|
|
movie_string = f"{name_ru}, {year}"
|
|
|
|
|
if name_ru is None:
|
|
|
|
|
movie_string = f"{name}, {year}"
|
2022-09-03 19:46:13 +03:00
|
|
|
|
if year is None:
|
|
|
|
|
post_status('🎬 Мы временно не можем обработать ваше предложение: Обработка фильма без наличия года невозможна.', id_st)
|
|
|
|
|
fail_limit[acct] += 1
|
|
|
|
|
break
|
2022-09-02 11:28:24 +03:00
|
|
|
|
if get_suggested_movies_count() >= limit_all_movies_poll:
|
|
|
|
|
post_status('🎬 Мы не можем обработать ваше предложение: количество уже предложенных не помещается в лимит голосовалки.', id_st)
|
|
|
|
|
logger.warning(f'Предложение {acct} было отклонено: количество уже предложенных фильмов превышает\равно {limit_all_movies_poll}')
|
2022-09-02 15:39:46 +03:00
|
|
|
|
fail_limit[acct] += 1
|
2022-09-02 11:28:24 +03:00
|
|
|
|
break
|
|
|
|
|
|
2022-08-31 13:20:49 +03:00
|
|
|
|
if get_already_watched(name, name_ru, year) == True:
|
2022-09-04 02:32:25 +03:00
|
|
|
|
message_writer.append(f"ℹ️ Этот фильм уже был на FMN: {movie_string}")
|
2022-09-02 11:28:24 +03:00
|
|
|
|
logger.info(f'Попытка предложить уже просмотренный фильм: {acct} {name} {name_ru} {year}')
|
2022-09-03 19:46:13 +03:00
|
|
|
|
fail_limit[acct] += 1
|
2022-08-31 13:20:49 +03:00
|
|
|
|
continue
|
|
|
|
|
|
2022-09-03 19:46:13 +03:00
|
|
|
|
add_result = add_movie_to_poll(acct, name, name_ru, year)
|
|
|
|
|
if add_result == 0:
|
2022-08-31 13:20:49 +03:00
|
|
|
|
message_writer.append(f"✅ Принято: {movie_string}")
|
2022-09-07 02:55:12 +03:00
|
|
|
|
logger.success(f'Предложение от {acct} принято: {name} {name_ru} {year}')
|
2022-09-04 02:32:25 +03:00
|
|
|
|
success = True
|
2022-09-03 19:46:13 +03:00
|
|
|
|
elif add_result == 1:
|
2022-09-04 02:32:25 +03:00
|
|
|
|
message_writer.append("❌ Этот фильм уже был предложен")
|
2022-09-03 19:46:13 +03:00
|
|
|
|
logger.info(f'Предложение от {acct} было отлонено - фильм в опросе существует')
|
|
|
|
|
fail_limit[acct] += 1
|
2022-08-31 13:20:49 +03:00
|
|
|
|
else:
|
2022-09-04 02:32:25 +03:00
|
|
|
|
message_writer.append("❌ Вы не можете добавить больше 2х фильмов")
|
2022-09-01 15:21:35 +03:00
|
|
|
|
logger.info(f'Предложение от {acct} было отлонено - лимит на пользователя')
|
2022-09-02 15:39:46 +03:00
|
|
|
|
fail_limit[acct] += 1
|
2022-08-31 13:20:49 +03:00
|
|
|
|
if message_writer != []:
|
2022-09-04 02:32:25 +03:00
|
|
|
|
message = ''
|
|
|
|
|
if success:
|
|
|
|
|
message = "\nБлагодарим за ваше предложение!"
|
|
|
|
|
post_status('\n'.join(message_writer) + message, id_st)
|
2022-08-31 13:20:49 +03:00
|
|
|
|
|
|
|
|
|
time.sleep(30)
|
|
|
|
|
|
2022-09-03 19:46:13 +03:00
|
|
|
|
|