add heleket

This commit is contained in:
Yuriy Yuriev
2026-05-15 00:12:14 +07:00
parent ae5f7967f2
commit 7d28ba794b
4 changed files with 508 additions and 89 deletions
+70 -6
View File
@@ -7,7 +7,7 @@ import json
import logging
from pathlib import Path
from datetime import datetime
from typing import Dict
from typing import Dict, Optional
from managers.task_manager import TaskParams
@@ -173,10 +173,10 @@ class ChatStorage:
await asyncio.to_thread(self._save_sync, data)
class BalanceStorage:
"""Баланс переходов пользователей."""
class _IntBalanceStorage:
"""Базовое хранилище числового баланса пользователей."""
def __init__(self, file_path: str = "data/balances.json"):
def __init__(self, file_path: str):
self.file_path = Path(file_path)
self.file_path.parent.mkdir(parents=True, exist_ok=True)
self._lock = asyncio.Lock()
@@ -188,7 +188,7 @@ class BalanceStorage:
with open(self.file_path, "r", encoding="utf-8") as f:
return json.load(f)
except (json.JSONDecodeError, IOError) as e:
logger.warning(f"Failed to load balances: {e}")
logger.warning(f"Failed to load {self.file_path}: {e}")
return {}
def _save_sync(self, data: dict) -> None:
@@ -207,7 +207,7 @@ class BalanceStorage:
await asyncio.to_thread(self._save_sync, data)
return data[str(user_id)]
async def deduct(self, user_id: int, amount: int = 1) -> int:
async def deduct(self, user_id: int, amount: int) -> int:
async with self._lock:
data = await asyncio.to_thread(self._load_sync)
new_bal = max(0, data.get(str(user_id), 0) - amount)
@@ -218,3 +218,67 @@ class BalanceStorage:
async def get_all(self) -> dict:
async with self._lock:
return await asyncio.to_thread(self._load_sync)
class BalanceStorage(_IntBalanceStorage):
"""Баланс переходов пользователей."""
def __init__(self, file_path: str = "data/balances.json"):
super().__init__(file_path)
class RubleBalanceStorage(_IntBalanceStorage):
"""Рублёвый баланс пользователей."""
def __init__(self, file_path: str = "data/rub_balances.json"):
super().__init__(file_path)
class PaymentStorage:
"""Хранилище ожидающих платежей."""
def __init__(self, file_path: str = "data/payments.json"):
self.file_path = Path(file_path)
self.file_path.parent.mkdir(parents=True, exist_ok=True)
self._lock = asyncio.Lock()
def _load_sync(self) -> dict:
if not self.file_path.exists():
return {}
try:
with open(self.file_path, "r", encoding="utf-8") as f:
return json.load(f)
except (json.JSONDecodeError, IOError):
return {}
def _save_sync(self, data: dict) -> None:
with open(self.file_path, "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
async def save(self, payment_id: str, data: dict) -> None:
async with self._lock:
payments = await asyncio.to_thread(self._load_sync)
payments[payment_id] = data
await asyncio.to_thread(self._save_sync, payments)
async def get(self, payment_id: str) -> Optional[dict]:
async with self._lock:
payments = await asyncio.to_thread(self._load_sync)
return payments.get(payment_id)
async def delete(self, payment_id: str) -> None:
async with self._lock:
payments = await asyncio.to_thread(self._load_sync)
payments.pop(payment_id, None)
await asyncio.to_thread(self._save_sync, payments)
async def get_by_user(self, user_id: int) -> Optional[dict]:
async with self._lock:
payments = await asyncio.to_thread(self._load_sync)
for pid, data in payments.items():
if data.get("user_id") == user_id:
return {**data, "payment_id": pid}
return None