-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutils.py
More file actions
90 lines (73 loc) · 3.17 KB
/
Copy pathutils.py
File metadata and controls
90 lines (73 loc) · 3.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import logging
import os
import re
from datetime import datetime, timezone
from typing import Tuple, Optional, Pattern
ADMIN_INFO_PATTERN: Pattern = re.compile(
r":outbox_tray:\s*(?:\*\*)?(?:[\d:]{5,8}|[\d:]{2,5})?\s*(?:\*\*)?\s*(.+?):\s*(.+)", re.UNICODE)
PLAYER_INFO_PATTERN: Pattern = re.compile(
r":inbox_tray:\s*(?:\*\*)?(?:[\d:]{2,8})?\s*(?:\*\*)?\s*(.+?):", re.UNICODE)
SERVER_NAME_PATTERN: Pattern = re.compile(r"ahelp-(.+?)\s*\[")
def configure_logging(level: int = logging.INFO, log_file: Optional[str] = "ahelp_analyzer.log") -> None:
handlers = [logging.StreamHandler()]
if log_file:
handlers.append(logging.FileHandler(log_file, encoding="utf-8"))
logging.basicConfig(
level=level, format="%(asctime)s - %(levelname)s - %(message)s", handlers=handlers)
logging.getLogger("matplotlib.font_manager").setLevel(logging.ERROR)
logging.getLogger("PIL").setLevel(logging.WARNING)
logging.getLogger("discord").setLevel(logging.WARNING)
def clean_sheet_name(sheet_name: str) -> str:
sheet_name = re.sub(r"[\\/*?:\[\]]", "_", sheet_name)
sheet_name = re.sub(r"\W+", "_", sheet_name)
return sheet_name[:31]
def normalize_admin_string(s: str) -> str:
s = re.sub(r"\(Admin Only\)", "", s, flags=re.IGNORECASE)
s = re.sub(r"\(S\)\s*", "", s)
s = s.replace("**", "")
s = re.sub(r"#\d{2,}$", "", s)
return s.strip()
def extract_admin_info(line: str) -> Tuple[Optional[str], Optional[str], bool]:
match = ADMIN_INFO_PATTERN.search(line)
if not match:
return None, None, False
admin_info_part = match.group(1)
is_admin_only = "(Admin Only)" in admin_info_part
if "|" in admin_info_part:
parts = [p.strip() for p in admin_info_part.split("|")]
admin_name = parts[-1]
admin_role = " | ".join(parts[:-1]) if parts[:-1] else "Unknown"
else:
admin_name = admin_info_part
admin_role = "Unknown"
return normalize_admin_string(admin_name), normalize_admin_string(admin_role), is_admin_only
def extract_player_name(line: str) -> Optional[str]:
match = PLAYER_INFO_PATTERN.search(line)
if not match:
return None
return normalize_admin_string(match.group(1))
def parse_message_time(message_timestamp: str) -> Optional[datetime]:
if not message_timestamp:
return None
try:
dt = datetime.fromisoformat(message_timestamp.replace("Z", "+00:00"))
if dt.tzinfo is None:
dt = dt.replace(tzinfo=timezone.utc)
else:
dt = dt.astimezone(timezone.utc)
return dt
except Exception as e:
logging.error(f"Ошибка парсинга времени сообщения '{message_timestamp}': {e}")
return None
def extract_server_name(file_path: str) -> str:
base = os.path.basename(file_path)
m = SERVER_NAME_PATTERN.search(base)
return m.group(1) if m else os.path.splitext(base)[0]
def format_date_range(start_date: Optional[str], end_date: Optional[str]) -> str:
if start_date and end_date:
return f"{start_date} до {end_date}"
if start_date:
return f"С {start_date}"
if end_date:
return f"До {end_date}"
return "Все даты"