Fix autopurchase server selection and RemnaWave stats handling

This commit is contained in:
Egor
2025-11-09 04:50:32 +03:00
parent b2d3eebe39
commit a0fa7f986b
3 changed files with 73 additions and 50 deletions

View File

@@ -520,7 +520,7 @@ class RemnaWaveService:
nodes_weekly_data = []
if nodes_stats.get('lastSevenDays'):
nodes_by_name = {}
nodes_by_name: Dict[str, Dict[str, Any]] = {}
for day_data in nodes_stats['lastSevenDays']:
node_name = day_data['nodeName']
if node_name not in nodes_by_name:
@@ -529,16 +529,16 @@ class RemnaWaveService:
'total_bytes': 0,
'days_data': []
}
daily_bytes = int(day_data['totalBytes'])
nodes_by_name[node_name]['total_bytes'] += daily_bytes
nodes_by_name[node_name]['days_data'].append({
'date': day_data['date'],
'bytes': daily_bytes
})
nodes_weekly_data = list(nodes_by_name.values())
nodes_weekly_data.sort(key=lambda x: x['total_bytes'], reverse=True)
nodes_weekly_data = list(nodes_by_name.values())
nodes_weekly_data.sort(key=lambda x: x['total_bytes'], reverse=True)
result = {
"system": {
@@ -706,46 +706,46 @@ class RemnaWaveService:
def _parse_bandwidth_string(self, bandwidth_str: str) -> int:
try:
if not bandwidth_str or bandwidth_str == '0 B' or bandwidth_str == '0':
return 0
bandwidth_str = bandwidth_str.replace(' ', '').upper()
units = {
'B': 1,
'KB': 1024,
'MB': 1024 ** 2,
'GB': 1024 ** 3,
'TB': 1024 ** 4,
'KIB': 1024,
'MIB': 1024 ** 2,
'GIB': 1024 ** 3,
'TIB': 1024 ** 4,
'KBPS': 1024,
'MBPS': 1024 ** 2,
'GBPS': 1024 ** 3
}
match = re.match(r'([0-9.,]+)([A-Z]+)', bandwidth_str)
if match:
value_str = match.group(1).replace(',', '.')
value = float(value_str)
unit = match.group(2)
if unit in units:
result = int(value * units[unit])
logger.debug(f"Парсинг '{bandwidth_str}': {value} {unit} = {result} байт")
return result
else:
logger.warning(f"Неизвестная единица измерения: {unit}")
logger.warning(f"Не удалось распарсить строку трафика: '{bandwidth_str}'")
return 0
except Exception as e:
logger.error(f"Ошибка парсинга строки трафика '{bandwidth_str}': {e}")
try:
if not bandwidth_str or bandwidth_str == '0 B' or bandwidth_str == '0':
return 0
bandwidth_str = bandwidth_str.replace(' ', '').upper()
units = {
'B': 1,
'KB': 1024,
'MB': 1024 ** 2,
'GB': 1024 ** 3,
'TB': 1024 ** 4,
'KIB': 1024,
'MIB': 1024 ** 2,
'GIB': 1024 ** 3,
'TIB': 1024 ** 4,
'KBPS': 1024,
'MBPS': 1024 ** 2,
'GBPS': 1024 ** 3
}
match = re.match(r'([0-9.,]+)([A-Z]+)', bandwidth_str)
if match:
value_str = match.group(1).replace(',', '.')
value = float(value_str)
unit = match.group(2)
if unit in units:
result = int(value * units[unit])
logger.debug(f"Парсинг '{bandwidth_str}': {value} {unit} = {result} байт")
return result
else:
logger.warning(f"Неизвестная единица измерения: {unit}")
logger.warning(f"Не удалось распарсить строку трафика: '{bandwidth_str}'")
return 0
except Exception as e:
logger.error(f"Ошибка парсинга строки трафика '{bandwidth_str}': {e}")
return 0
async def get_all_nodes(self) -> List[Dict[str, Any]]:

View File

@@ -96,14 +96,37 @@ async def _prepare_auto_purchase(
traffic_value = int(traffic_value)
devices = int(cart_data.get("devices") or period_config.devices.current or 1)
servers = list(cart_data.get("countries") or [])
if not servers:
servers = list(period_config.servers.default_selection)
raw_servers = list(cart_data.get("countries") or [])
if not raw_servers:
raw_servers = list(period_config.servers.default_selection)
resolved_servers: list[str] = []
seen_servers: set[str] = set()
selection_map = getattr(context, "server_selection_map", {}) or {}
for key in raw_servers:
if not key:
continue
str_key = str(key).strip()
if not str_key:
continue
uuid = selection_map.get(str_key, str_key)
if not uuid or uuid in seen_servers:
continue
seen_servers.add(uuid)
resolved_servers.append(uuid)
if not resolved_servers:
for key in period_config.servers.default_selection:
uuid = selection_map.get(key, key)
if uuid and uuid not in seen_servers:
seen_servers.add(uuid)
resolved_servers.append(uuid)
selection = PurchaseSelection(
period=period_config,
traffic_value=traffic_value,
servers=servers,
servers=resolved_servers,
devices=devices,
)

View File

@@ -265,8 +265,8 @@ class PurchaseOptionsContext:
default_period: PurchasePeriodConfig
period_map: Dict[str, PurchasePeriodConfig]
server_uuid_to_id: Dict[str, int]
server_selection_map: Dict[str, str]
payload: Dict[str, Any]
server_selection_map: Dict[str, str] = field(default_factory=dict)
payload: Dict[str, Any] = field(default_factory=dict)
class PurchaseValidationError(Exception):