From f7431a72f1e603560af0e2326a13b492e21d0805 Mon Sep 17 00:00:00 2001 From: localhost_frssoft Date: Mon, 21 Nov 2022 23:33:00 +0300 Subject: [PATCH] states refactor --- src/fmn_poll.py | 17 ++++++++----- src/fmn_states_db.py | 54 +++++++++++++++-------------------------- src/listener_context.py | 19 ++++++++------- src/listener_mention.py | 13 ++++++---- 4 files changed, 48 insertions(+), 55 deletions(-) diff --git a/src/fmn_poll.py b/src/fmn_poll.py index 1419f92..21fbc32 100644 --- a/src/fmn_poll.py +++ b/src/fmn_poll.py @@ -1,5 +1,5 @@ from src.fedi_api import get_status, post_status, upload_attachment -from src.fmn_states_db import add_state, get_state, clear_all_states +from src.fmn_states_db import read_states, write_states from src.fmn_database import get_movies_for_poll, write_votes, read_votes, mark_as_watched_movie, get_already_watched, rewrite_db, reset_poll, get_count_all_watched_movies, force_commit from collections import Counter from loguru import logger @@ -36,13 +36,16 @@ def create_poll_movies(text=text_create_poll(), poll_expires=345600): poll_status_id = post_status(text, None, formated_poll_options, poll_expires=poll_expires, attachments=[upload_attachment('src/FMN.png')]) logger.success('Голосовалка создана') - add_state('poll_expires_at', int(time.time()) + poll_expires) - add_state('poll_status_id', poll_status_id['id']) + states = read_states() + states['poll_expires_at'] = int(time.time()) + poll_expires + states['poll_status_id'] = poll_status_id['id'] + write_states(states) return poll_status_id def get_winner_movie(poll_status_id=str): '''Отмечаем победивший фильм на голосовании как просмотренный или постим tie breaker''' + states = read_states() votes_counters = [] status_with_poll = get_status(poll_status_id) poll = status_with_poll['poll'] @@ -62,7 +65,7 @@ def get_winner_movie(poll_status_id=str): if len(winned_movies) > 1: logger.warning('Будет создан tie breaker') rewrite_db(winned_movies) - if get_state('tie_breaker'): + if states.get('tie_breaker'): create_tie_breaker(2) else: create_tie_breaker() @@ -81,14 +84,16 @@ def get_winner_movie(poll_status_id=str): logger.success("Победил " + str(movie)) post_status(text_winned, attachments=[upload_attachment('src/FMN.png')]) - clear_all_states() + write_states() reset_poll() def create_tie_breaker(count_tie=1): '''Создание tie breaker''' if count_tie == 1: - add_state('tie_breaker', 1) + states = read_states() + states['tie_breaker'] = 1 + write_states(states) poll_expires = 8*60*60 else: poll_expires = 4*60*60 diff --git a/src/fmn_states_db.py b/src/fmn_states_db.py index 5f0ff72..8f5d580 100644 --- a/src/fmn_states_db.py +++ b/src/fmn_states_db.py @@ -1,41 +1,25 @@ -import sqlite3 +import json from loguru import logger +states_file = 'fmn_states.json' -conn = sqlite3.connect("fmn_states.sqlite", check_same_thread=False) -c = conn.cursor() - -c.execute( - '''CREATE TABLE IF NOT EXISTS states(key VARCHAR (500) UNIQUE DEFAULT NULL, value VARCHAR (500) UNIQUE DEFAULT NULL)''') - -conn.commit() +@logger.catch +def read_states(): + try: + with open(states_file, 'rt') as f: + current_states = json.loads(f.read()) + except: + logger.warning('Стейты не найдены, создание плейсхолдера') + write_states() + current_states = {} + return current_states -def add_state(key, value): - '''Создание стейта, если существует - будет заменен''' - logger.debug(f'Adding {key}: {value}') - c.execute("INSERT OR REPLACE INTO states(key, value) VALUES (?, ?)", (key, value)) - conn.commit() - logger.warning(f'Добавлен стейт {key}: {value}') - - -def get_state(key): - '''Получение стейта по ключу''' - logger.trace(f'Запрошен стейт {key}') - value = c.execute("SELECT value FROM states WHERE key = (?)", (key,)).fetchone() - if value: - return value[0] - - -def remove_state(key): - '''Удалить стейт по ключу''' - c.execute("DELETE FROM states WHERE key = (?)", (key,)) - conn.commit() - logger.warning(f'Удален стейт {key}') - - -def clear_all_states(): - c.execute("DELETE FROM states") - conn.commit() - logger.warning(f'Все стейты удалены') +@logger.catch +def write_states(states={}): + with open(states_file, 'wt') as f: + f.write(json.dumps(states, indent=4)) + if states == {}: + logger.info('states empty wrote') + return states diff --git a/src/listener_context.py b/src/listener_context.py index df67003..28d3389 100644 --- a/src/listener_context.py +++ b/src/listener_context.py @@ -3,7 +3,7 @@ from src.fedi_api import get_status_context, get_status, post_status, mute_user from src.kinopoisk_api import get_kinopoisk_movie_to_imdb 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_states_db import read_states, write_states from src.fmn_poll import create_poll_movies, get_winner_movie import re import time @@ -33,15 +33,16 @@ 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') + states = read_states() + status_id = states.get('last_thread_id') + poll_created = states.get('poll_status_id') + stop_thread_scan = states.get('stop_thread_scan') time_now = int(time.time()) reserve_time = False 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') + status_id = states.get('last_thread_id') + stop_thread_scan = states.get('stop_thread_scan') time.sleep(1) if time_now >= int(stop_thread_scan): @@ -49,9 +50,9 @@ def scan_context_thread(): logger.debug('Сбор завершён, сканирование треда на опоздавших') if poll_created is None: create_poll_movies() - poll_created = get_state('poll_status_id') + poll_created = states.get('poll_status_id') else: - if time_now >= int(get_state('poll_expires_at')): + if time_now >= int(states.get('poll_expires_at')): get_winner_movie(poll_created) else: endings = int(stop_thread_scan) - time_now @@ -82,7 +83,7 @@ def scan_context_thread(): 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) + mute_user(acct_id, acct, int(states.get('max_mute_time')) - time_now) logger.warning(f'{acct} игнорируется - превышение fail limit') break # Нужно обновить тред, чтобы muted на заглушенном стал True diff --git a/src/listener_mention.py b/src/listener_mention.py index ac41f8d..708da00 100644 --- a/src/listener_mention.py +++ b/src/listener_mention.py @@ -1,5 +1,5 @@ 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 src.fmn_states_db import write_states, read_states from config import admins_bot, limit_movies_per_user, limit_all_movies_poll, hour_poll_posting, fmn_next_watching_hour import threading, time @@ -11,6 +11,7 @@ from loguru import logger def get_control_mention(): while True: + states = read_states() time.sleep(30) time_now = datetime.now() now_week = time_now.weekday() @@ -19,7 +20,7 @@ def get_control_mention(): continue if now_week == 6 and now_hour < fmn_next_watching_hour: # Предотвращение работы в холстую до начала сеанса continue - post_exists = get_state('last_thread_id') + post_exists = states.get('last_thread_id') if post_exists: continue logger.debug('Wait for from admin mention...') @@ -53,9 +54,11 @@ def get_control_mention(): 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) + + states['max_mute_time'] = int(max_mute_time) + states['stop_thread_scan'] = int(stop_thread_scan) + states['last_thread_id'] = st_id + write_states(states) break time.sleep(30)