Edit on GitHub

src.scheduler.balance

Уведомления и списания баланса

  1"""Уведомления и списания баланса"""
  2
  3import logging
  4import os
  5import pickle
  6from datetime import datetime, timedelta, timezone
  7
  8from aiogram import Bot
  9
 10from core.config import decr_time, noticed_time
 11from core.err import log_cash_error
 12from db.models import UserActivity
 13from db.utils import get_valid_users, raise_money
 14from kb import static_balance_button
 15from text import get_end_sub
 16
 17logger = logging.getLogger("apscheduler")
 18logging.getLogger("apscheduler.executors.default").setLevel(logging.WARNING)
 19
 20
 21def check_time(timeFile: str) -> bool:
 22    """Проверяет, прошло ли больше суток с последнего обновления времени.
 23
 24    Args:
 25        timeFile (str): Путь к файлу, содержащему время последнего обновления.
 26
 27    Returns:
 28        bool: True, если прошло больше суток, иначе False.
 29    """
 30    last_updated = datetime.today()
 31    if os.path.isfile(timeFile) and os.path.getsize(timeFile) > 0:
 32        with open(timeFile, "rb") as file:
 33            prev_updated: datetime = pickle.load(file)
 34
 35        diff = last_updated - prev_updated
 36
 37    else:
 38        diff = last_updated - last_updated
 39
 40    if diff > timedelta(days=1):
 41        return True
 42    return False
 43
 44
 45def increment_time(timeFile: str):
 46    """Увеличивает время в файле на один день.
 47
 48    Args:
 49        timeFile (str): Путь к файлу, содержащему время последнего обновления.
 50    """
 51    with open(timeFile, "rb+") as file:
 52        prev_updated: datetime = pickle.load(file)
 53        file.seek(0)
 54        pickle.dump(prev_updated + timedelta(days=1), file)
 55
 56
 57async def balance_decrement():
 58    """Осуществляет ежедневное списание средств с баланса пользователей.
 59
 60    Проверяет, прошло ли больше суток с последнего списания, и если да,
 61    вызывает функцию для списания средств. Логирует информацию о проведенном списании.
 62    """
 63    try:
 64        if check_time(decr_time):
 65            await raise_money()
 66            logger.info("Произведено ежедневное списание")
 67
 68            increment_time(decr_time)
 69    except Exception as e:
 70        if log_cash_error(e):
 71            logger.exception(
 72                "Ошибка базы данных при осуществлении декремента баланса пользователей"
 73            )
 74
 75
 76async def users_notice(bot: Bot):
 77    """Отправляет уведомления пользователям о состоянии их аккаунтов.
 78
 79    Проверяет, прошло ли больше суток с последнего уведомления, и если да,
 80    отправляет сообщения пользователям о состоянии их аккаунтов, включая
 81    уведомления о блокировке и необходимости пополнения баланса.
 82
 83    Args:
 84        bot (Bot): Экземпляр бота для отправки сообщений пользователям.
 85    """
 86    try:
 87        if check_time(noticed_time):
 88            users = await get_valid_users(0)
 89
 90            for user in users:
 91                end = get_end_sub(user)
 92
 93                diff = datetime.now(timezone.utc) - user.updated
 94
 95                if user.active == UserActivity.inactive:
 96                    if (timedelta(days=1) < diff < timedelta(days=2)) or (
 97                        timedelta(days=3) < diff < timedelta(days=4)
 98                        or (timedelta(days=7) < diff < timedelta(days=8))
 99                    ):
100                        await bot.send_message(
101                            user.telegram_id,
102                            "Здравствуйте, ваш аккаунт заблокирован, однако если вы пополните баланс, то снова сможете пользоваться своими конфигурациями!",
103                            reply_markup=static_balance_button,
104                        )
105
106                        logger.info(
107                            "Отправлено уведомление о возврате в сервис",
108                            extra={"user_id": user.telegram_id, "trigger": diff},
109                        )
110
111                elif end == 0:  # TODO twice executed
112                    await bot.send_message(
113                        user.telegram_id,
114                        "Здравствуйте, пополните баланс, иначе в скором времени вы будете заблокированы.",
115                        reply_markup=static_balance_button,
116                    )
117
118                    logger.info(
119                        "Отправлено уведомление о блокировке",
120                        extra={"user_id": user.telegram_id, "end": end},
121                    )
122                elif end <= 2:
123                    await bot.send_message(
124                        user.telegram_id,
125                        "Здравствуйте, ваши средства на балансе в скором времени закончатся."
126                        "По окончании этого периода ваш аккаунт будет заблокирован системой (пока вы снова не пополните баланс 🙄)",
127                        reply_markup=static_balance_button,
128                    )
129
130                    logger.info(
131                        "Отправлено уведомление о скорой блокировке",
132                        extra={"user_id": user.telegram_id, "end": end},
133                    )
134
135            increment_time(noticed_time)
136
137    except Exception as e:
138        if log_cash_error(e):
139            logger.exception(
140                "Ошибка базы данных при отправке уведомлений пользователям"
141            )
logger = <Logger apscheduler (INFO)>
def check_time(timeFile: str) -> bool:
22def check_time(timeFile: str) -> bool:
23    """Проверяет, прошло ли больше суток с последнего обновления времени.
24
25    Args:
26        timeFile (str): Путь к файлу, содержащему время последнего обновления.
27
28    Returns:
29        bool: True, если прошло больше суток, иначе False.
30    """
31    last_updated = datetime.today()
32    if os.path.isfile(timeFile) and os.path.getsize(timeFile) > 0:
33        with open(timeFile, "rb") as file:
34            prev_updated: datetime = pickle.load(file)
35
36        diff = last_updated - prev_updated
37
38    else:
39        diff = last_updated - last_updated
40
41    if diff > timedelta(days=1):
42        return True
43    return False

Проверяет, прошло ли больше суток с последнего обновления времени.

Arguments:
  • timeFile (str): Путь к файлу, содержащему время последнего обновления.
Returns:

bool: True, если прошло больше суток, иначе False.

def increment_time(timeFile: str):
46def increment_time(timeFile: str):
47    """Увеличивает время в файле на один день.
48
49    Args:
50        timeFile (str): Путь к файлу, содержащему время последнего обновления.
51    """
52    with open(timeFile, "rb+") as file:
53        prev_updated: datetime = pickle.load(file)
54        file.seek(0)
55        pickle.dump(prev_updated + timedelta(days=1), file)

Увеличивает время в файле на один день.

Arguments:
  • timeFile (str): Путь к файлу, содержащему время последнего обновления.
async def balance_decrement():
58async def balance_decrement():
59    """Осуществляет ежедневное списание средств с баланса пользователей.
60
61    Проверяет, прошло ли больше суток с последнего списания, и если да,
62    вызывает функцию для списания средств. Логирует информацию о проведенном списании.
63    """
64    try:
65        if check_time(decr_time):
66            await raise_money()
67            logger.info("Произведено ежедневное списание")
68
69            increment_time(decr_time)
70    except Exception as e:
71        if log_cash_error(e):
72            logger.exception(
73                "Ошибка базы данных при осуществлении декремента баланса пользователей"
74            )

Осуществляет ежедневное списание средств с баланса пользователей.

Проверяет, прошло ли больше суток с последнего списания, и если да, вызывает функцию для списания средств. Логирует информацию о проведенном списании.

async def users_notice(bot: aiogram.client.bot.Bot):
 77async def users_notice(bot: Bot):
 78    """Отправляет уведомления пользователям о состоянии их аккаунтов.
 79
 80    Проверяет, прошло ли больше суток с последнего уведомления, и если да,
 81    отправляет сообщения пользователям о состоянии их аккаунтов, включая
 82    уведомления о блокировке и необходимости пополнения баланса.
 83
 84    Args:
 85        bot (Bot): Экземпляр бота для отправки сообщений пользователям.
 86    """
 87    try:
 88        if check_time(noticed_time):
 89            users = await get_valid_users(0)
 90
 91            for user in users:
 92                end = get_end_sub(user)
 93
 94                diff = datetime.now(timezone.utc) - user.updated
 95
 96                if user.active == UserActivity.inactive:
 97                    if (timedelta(days=1) < diff < timedelta(days=2)) or (
 98                        timedelta(days=3) < diff < timedelta(days=4)
 99                        or (timedelta(days=7) < diff < timedelta(days=8))
100                    ):
101                        await bot.send_message(
102                            user.telegram_id,
103                            "Здравствуйте, ваш аккаунт заблокирован, однако если вы пополните баланс, то снова сможете пользоваться своими конфигурациями!",
104                            reply_markup=static_balance_button,
105                        )
106
107                        logger.info(
108                            "Отправлено уведомление о возврате в сервис",
109                            extra={"user_id": user.telegram_id, "trigger": diff},
110                        )
111
112                elif end == 0:  # TODO twice executed
113                    await bot.send_message(
114                        user.telegram_id,
115                        "Здравствуйте, пополните баланс, иначе в скором времени вы будете заблокированы.",
116                        reply_markup=static_balance_button,
117                    )
118
119                    logger.info(
120                        "Отправлено уведомление о блокировке",
121                        extra={"user_id": user.telegram_id, "end": end},
122                    )
123                elif end <= 2:
124                    await bot.send_message(
125                        user.telegram_id,
126                        "Здравствуйте, ваши средства на балансе в скором времени закончатся."
127                        "По окончании этого периода ваш аккаунт будет заблокирован системой (пока вы снова не пополните баланс 🙄)",
128                        reply_markup=static_balance_button,
129                    )
130
131                    logger.info(
132                        "Отправлено уведомление о скорой блокировке",
133                        extra={"user_id": user.telegram_id, "end": end},
134                    )
135
136            increment_time(noticed_time)
137
138    except Exception as e:
139        if log_cash_error(e):
140            logger.exception(
141                "Ошибка базы данных при отправке уведомлений пользователям"
142            )

Отправляет уведомления пользователям о состоянии их аккаунтов.

Проверяет, прошло ли больше суток с последнего уведомления, и если да, отправляет сообщения пользователям о состоянии их аккаунтов, включая уведомления о блокировке и необходимости пополнения баланса.

Arguments:
  • bot (Bot): Экземпляр бота для отправки сообщений пользователям.