diff --git a/bot/handlers/client/menus.py b/bot/handlers/client/menus.py
index 0b1f6ed..2a70cd0 100644
--- a/bot/handlers/client/menus.py
+++ b/bot/handlers/client/menus.py
@@ -10,9 +10,7 @@ from bot.texts import (
CALLBACK_FALLBACK,
FAQ_TEXT,
GENERAL_PROCESSING,
- GENERAL_SUCCESS,
NO_SUBSCRIPTION,
- NOTHING_PLACEHOLDER,
)
from db.models.users import User
from misc import utils
diff --git a/bot/main.py b/bot/main.py
index 3451ec4..ca194be 100644
--- a/bot/main.py
+++ b/bot/main.py
@@ -1,4 +1,5 @@
import asyncio
+import contextlib
import logging
from aiogram import Bot, Dispatcher
@@ -21,6 +22,7 @@ from services.renewal_service import RenewalService
from services.user_service import UserService
logging.basicConfig(level=logging.DEBUG)
+contextlib.suppress(asyncio.CancelledError)
async def main():
@@ -78,10 +80,7 @@ async def main():
await dp.start_polling(bot)
finally:
scheduler_task.cancel()
- try:
- await scheduler_task
- except asyncio.CancelledError:
- pass
+ await scheduler_task
if __name__ == "__main__":
diff --git a/bot/scheduler.py b/bot/scheduler.py
index 93d9d36..1fb7431 100644
--- a/bot/scheduler.py
+++ b/bot/scheduler.py
@@ -1,7 +1,7 @@
import asyncio
import logging
-from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker
+from sqlalchemy.ext.asyncio import async_sessionmaker
from services.renewal_service import RenewalService
diff --git a/bot/texts.py b/bot/texts.py
index c46bb31..eeb49e6 100644
--- a/bot/texts.py
+++ b/bot/texts.py
@@ -227,4 +227,4 @@ AUTORENEWAL_INSUFFICIENT_FUNDS = (
AUTORENEWAL_SUCCESS = (
"✅ Подписка продлена автоматически. Списано {price}₽."
"Новая дата окончания: {end_date}."
-)
\ No newline at end of file
+)
diff --git a/config.py b/config.py
index 2e73f46..695a8ee 100644
--- a/config.py
+++ b/config.py
@@ -1,5 +1,5 @@
from dotenv import load_dotenv
-from pydantic import Field, SecretStr
+from pydantic import Field
from pydantic_settings import BaseSettings
load_dotenv(override=True)
@@ -10,11 +10,11 @@ class Settings(BaseSettings):
"postgresql+asyncpg://malenia:skibidi@localhost:5432/malenia_db", alias="POSTGRES_URL"
)
- bot_token: SecretStr = Field(alias="BOT_TOKEN")
+ bot_token: str = Field(alias="BOT_TOKEN")
admins: list[int] = Field(alias="ADMINS")
- pally_shop_id: SecretStr = Field(alias="PALLY_SHOP_ID")
- pally_token: SecretStr = Field(alias="PALLY_TOKEN")
+ pally_shop_id: str = Field(alias="PALLY_SHOP_ID")
+ pally_token: str = Field(alias="PALLY_TOKEN")
referal_bonus: int = Field(10, alias="REFERAL_BONUS")
deposit_threshold: int = Field(50)
@@ -23,7 +23,7 @@ class Settings(BaseSettings):
remnawave_url: str = Field(alias="REMNAWAVE_URL")
subscription_url: str = Field(alias="SUBSCRIPTION_URL")
- remnawave_token: SecretStr = Field(alias="REMNAWAVE_TOKEN")
+ remnawave_token: str = Field(alias="REMNAWAVE_TOKEN")
min_devices: int = Field(3, alias="MIN_DEVICES")
max_devices: int = Field(12, alias="MAX_DEVICES")
diff --git a/repositories/subscriptions.py b/repositories/subscriptions.py
index 1e53b2e..ad43b14 100644
--- a/repositories/subscriptions.py
+++ b/repositories/subscriptions.py
@@ -1,4 +1,4 @@
-from datetime import datetime, timezone
+from datetime import UTC, datetime, timedelta
from sqlalchemy import select, update
from sqlalchemy.ext.asyncio import AsyncSession
@@ -10,13 +10,12 @@ class SubscriptionRepository:
async def get_subscriptions_for_autorenewal(
self, session: AsyncSession, *, days_before_expiry: int = 1
) -> list[Subscription]:
- from datetime import timedelta
- threshold = datetime.now(timezone.utc) + timedelta(days=days_before_expiry)
+ threshold = datetime.now(UTC) + timedelta(days=days_before_expiry)
stmt = (
select(Subscription)
.where(
- Subscription.autorenew == True,
+ Subscription.autorenew == True, # noqa: E712
Subscription.status == SubscriptionStatus.ACTIVE,
Subscription.end_date <= threshold,
)
diff --git a/schemas/di.py b/schemas/di.py
index 9c269f0..7e6ab25 100644
--- a/schemas/di.py
+++ b/schemas/di.py
@@ -1,6 +1,5 @@
from dataclasses import dataclass
-from aiogram import Bot
from remnawave import RemnawaveSDK
from misc.pally import PallyClient
diff --git a/schemas/users.py b/schemas/users.py
index 461b990..f148f70 100644
--- a/schemas/users.py
+++ b/schemas/users.py
@@ -1,6 +1,8 @@
from dataclasses import dataclass
+
from pydantic import BaseModel
+
class NewUserDTO(BaseModel):
id: int
referal: int | None = None
diff --git a/services/renewal_service.py b/services/renewal_service.py
index 68eda61..4be75e9 100644
--- a/services/renewal_service.py
+++ b/services/renewal_service.py
@@ -13,6 +13,7 @@ from misc import utils
from repositories.subscriptions import SubscriptionRepository
from repositories.users import UserRepository
from schemas.subscriptions import InternalSquads, SubscriptionPlan, SubscriptionStatus
+from services import rw as rw_service
logger = logging.getLogger(__name__)
@@ -48,22 +49,14 @@ class RenewalService:
return utils.calculate_price(plan)
async def _renew_subscription_in_rw(self, subscription: Subscription) -> None:
- from services import rw as rw_service
-
rw_user = await rw_service.get_user_by_telegram_id(self.rw_sdk, subscription.user_id)
if not rw_user:
raise RenewalServiceError(f"RW user not found for user_id={subscription.user_id}")
- duration = datetime.timedelta(days=subscription.duration_days)
squads = [InternalSquads.DEFAULT]
if subscription.whitelists:
squads.append(InternalSquads.WHITELISTS)
- if rw_user.expire_at > datetime.datetime.now(datetime.UTC):
- new_expire = rw_user.expire_at + duration
- else:
- new_expire = datetime.datetime.now(datetime.UTC) + duration
-
await rw_service.add_days(self.rw_sdk, rw_user.uuid, subscription.duration_days)
await rw_service.update_squads(self.rw_sdk, rw_user.uuid, squads)
await rw_service.set_hwid_limit(self.rw_sdk, rw_user.uuid, subscription.devices)
@@ -95,10 +88,7 @@ class RenewalService:
await self.subscription_repository.update_subscription_autorenew(
session, user_id, False
)
- await self._notify_user(
- user_id,
- AUTORENEWAL_INSUFFICIENT_FUNDS
- )
+ await self._notify_user(user_id, AUTORENEWAL_INSUFFICIENT_FUNDS)
return False
result = await self.user_repository.decrease_user_balance(
@@ -143,7 +133,7 @@ class RenewalService:
user_id,
AUTORENEWAL_SUCCESS.format(
price=price,
- end_date=new_end_date.strftime('%d.%m.%Y'),
+ end_date=new_end_date.strftime("%d.%m.%Y"),
),
)
@@ -171,9 +161,7 @@ class RenewalService:
else:
results["failed"] += 1
except Exception:
- logger.exception(
- "Error processing autorenewal for user %d", subscription.user_id
- )
+ logger.exception("Error processing autorenewal for user %d", subscription.user_id)
results["failed"] += 1
logger.info(