Add YAPF style + ignore, and format tracked Python files

This commit is contained in:
2025-12-29 18:42:02 -08:00
parent c019c00aed
commit 507946a3e4
108 changed files with 11664 additions and 6494 deletions

View File

@@ -12,7 +12,6 @@ from urllib.parse import urlparse
from ProviderCore.base import Provider, SearchResult
_TELEGRAM_DEFAULT_TIMESTAMP_STEM_RE = re.compile(
r"^(?P<prefix>photo|video|document|audio|voice|animation)_(?P<date>\d{4}-\d{2}-\d{2})_(?P<time>\d{2}-\d{2}-\d{2})(?: \(\d+\))?$",
flags=re.IGNORECASE,
@@ -39,7 +38,10 @@ def _unique_path(path: Path) -> Path:
return parent / f"{stem} (copy){suffix}"
def _maybe_strip_telegram_timestamped_default_filename(*, downloaded_path: Path) -> Path:
def _maybe_strip_telegram_timestamped_default_filename(
*,
downloaded_path: Path
) -> Path:
"""Normalize Telethon's default timestamped names.
Examples:
@@ -87,7 +89,8 @@ def _looks_like_telegram_message_url(url: str) -> bool:
except Exception:
return False
host = (parsed.hostname or "").lower().strip()
if host in {"t.me", "telegram.me"}:
if host in {"t.me",
"telegram.me"}:
return True
if host.endswith(".t.me"):
return True
@@ -147,9 +150,10 @@ class Telegram(Provider):
def __init__(self, config: Optional[Dict[str, Any]] = None):
super().__init__(config)
telegram_conf = (
self.config.get("provider", {}).get("telegram", {})
if isinstance(self.config, dict)
else {}
self.config.get("provider",
{}).get("telegram",
{}) if isinstance(self.config,
dict) else {}
)
self._app_id = telegram_conf.get("app_id")
self._api_hash = telegram_conf.get("api_hash")
@@ -178,8 +182,10 @@ class Telegram(Provider):
If an event loop is already running in this thread (common in REPL/TUI),
runs the coroutine in a worker thread with its own loop.
"""
result: Dict[str, Any] = {}
err: Dict[str, Any] = {}
result: Dict[str,
Any] = {}
err: Dict[str,
Any] = {}
def _runner() -> None:
loop = asyncio.new_event_loop()
@@ -201,7 +207,10 @@ class Telegram(Provider):
except Exception:
pass
if pending:
loop.run_until_complete(asyncio.gather(*pending, return_exceptions=True))
loop.run_until_complete(
asyncio.gather(*pending,
return_exceptions=True)
)
try:
loop.run_until_complete(loop.shutdown_asyncgens())
except Exception:
@@ -261,7 +270,10 @@ class Telegram(Provider):
if not legacy_session.is_file():
return
for suffix in (".session", ".session-journal", ".session-wal", ".session-shm"):
for suffix in (".session",
".session-journal",
".session-wal",
".session-shm"):
src = Path(str(legacy_base) + suffix)
dst = Path(str(new_base) + suffix)
try:
@@ -355,7 +367,10 @@ class Telegram(Provider):
except EOFError:
choice = ""
use_bot = choice in {"2", "b", "bot", "token"}
use_bot = choice in {"2",
"b",
"bot",
"token"}
bot_token = ""
if use_bot:
sys.stderr.write("[telegram] Bot token: ")
@@ -544,7 +559,9 @@ class Telegram(Provider):
app_id = int(self._app_id) if self._app_id not in (None, "") else None
except Exception:
app_id = None
api_hash = str(self._api_hash).strip() if self._api_hash not in (None, "") else ""
api_hash = str(self._api_hash
).strip() if self._api_hash not in (None,
"") else ""
if not bool(app_id and api_hash):
return False
@@ -565,10 +582,13 @@ class Telegram(Provider):
bot_token = str(self._bot_token or "").strip()
if bot_token:
return bool(
self._ensure_session_with_bot_token(bot_token) and self._session_is_authorized()
self._ensure_session_with_bot_token(bot_token)
and self._session_is_authorized()
)
if prompt:
return bool(self._ensure_session_interactive() and self._session_is_authorized())
return bool(
self._ensure_session_interactive() and self._session_is_authorized()
)
return False
def list_chats(self, *, limit: int = 200) -> list[Dict[str, Any]]:
@@ -652,12 +672,20 @@ class Telegram(Provider):
kind = "user"
else:
kind = (
type(entity).__name__.lower() if entity is not None else "unknown"
type(entity).__name__.lower()
if entity is not None else "unknown"
)
except Exception:
kind = "unknown"
rows.append({"id": chat_id, "title": title, "username": username, "type": kind})
rows.append(
{
"id": chat_id,
"title": title,
"username": username,
"type": kind
}
)
return rows
finally:
try:
@@ -672,7 +700,9 @@ class Telegram(Provider):
# Sort for stable display.
try:
rows.sort(key=lambda r: (str(r.get("type") or ""), str(r.get("title") or "")))
rows.sort(
key=lambda r: (str(r.get("type") or ""), str(r.get("title") or ""))
)
except Exception:
pass
return rows
@@ -682,7 +712,8 @@ class Telegram(Provider):
*,
chat_ids: Sequence[int],
usernames: Sequence[str],
files: Optional[Sequence[Dict[str, Any]]] = None,
files: Optional[Sequence[Dict[str,
Any]]] = None,
file_paths: Optional[Sequence[str]] = None,
) -> None:
"""Send local file(s) to one or more chats.
@@ -713,7 +744,10 @@ class Telegram(Provider):
# Back-compat: allow callers to pass `file_paths=`.
if files is None:
files = [{"path": str(p), "title": ""} for p in (file_paths or [])]
files = [{
"path": str(p),
"title": ""
} for p in (file_paths or [])]
def _sanitize_filename(text: str) -> str:
# Windows-safe plus generally safe for Telegram.
@@ -754,7 +788,10 @@ class Telegram(Provider):
title_text = str((f or {}).get("title") or "").strip()
except Exception:
title_text = ""
jobs.append({"path": str(path_obj), "title": title_text})
jobs.append({
"path": str(path_obj),
"title": title_text
})
if not jobs:
raise Exception("No files to send")
@@ -781,7 +818,9 @@ class Telegram(Provider):
try:
await client.connect()
if not bool(await client.is_user_authorized()):
raise Exception("Telegram session is not authorized. Run: .telegram -login")
raise Exception(
"Telegram session is not authorized. Run: .telegram -login"
)
# Resolve entities: prefer IDs. Only fall back to usernames when IDs are absent.
entities: list[Any] = []
@@ -826,8 +865,7 @@ class Telegram(Provider):
fallback = path_obj.stem
base = (
_sanitize_filename(title_raw)
if title_raw
else _sanitize_filename(fallback)
if title_raw else _sanitize_filename(fallback)
)
ext = path_obj.suffix
send_name = f"{base}{ext}" if ext else base
@@ -838,7 +876,11 @@ class Telegram(Provider):
if print_progress is None:
return
try:
print_progress(send_name, int(sent or 0), int(total or 0))
print_progress(
send_name,
int(sent or 0),
int(total or 0)
)
except Exception:
return
@@ -860,7 +902,11 @@ class Telegram(Provider):
finally:
if print_final_progress is not None:
try:
print_final_progress(send_name, int(file_size or 0), 0.0)
print_final_progress(
send_name,
int(file_size or 0),
0.0
)
except Exception:
pass
except Exception as exc:
@@ -900,9 +946,12 @@ class Telegram(Provider):
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
def _download_message_media_sync(
self, *, url: str, output_dir: Path
) -> Tuple[Path, Dict[str, Any]]:
def _download_message_media_sync(self,
*,
url: str,
output_dir: Path) -> Tuple[Path,
Dict[str,
Any]]:
# Ensure we have an authorized session before attempting API calls.
# Never prompt during downloads.
if not self.ensure_session(prompt=False):
@@ -928,14 +977,17 @@ class Telegram(Provider):
try:
await client.connect()
if not bool(await client.is_user_authorized()):
raise Exception("Telegram session is not authorized. Run: .telegram -login")
raise Exception(
"Telegram session is not authorized. Run: .telegram -login"
)
if chat.startswith("c:"):
channel_id = int(chat.split(":", 1)[1])
entity = PeerChannel(channel_id)
else:
entity = chat
if isinstance(entity, str) and entity and not entity.startswith("@"):
if isinstance(entity,
str) and entity and not entity.startswith("@"):
entity = "@" + entity
messages = await client.get_messages(entity, ids=[message_id])
@@ -1009,7 +1061,9 @@ class Telegram(Provider):
from models import ProgressBar
progress_bar = ProgressBar()
last_print = {"t": 0.0}
last_print = {
"t": 0.0
}
def _progress(current: int, total: int) -> None:
now = time.monotonic()
@@ -1017,7 +1071,10 @@ class Telegram(Provider):
return
last_print["t"] = now
progress_bar.update(
downloaded=int(current), total=int(total), label="telegram", file=sys.stderr
downloaded=int(current),
total=int(total),
label="telegram",
file=sys.stderr
)
part_kb = self._resolve_part_size_kb(file_size)
@@ -1030,7 +1087,9 @@ class Telegram(Provider):
)
except TypeError:
downloaded = await client.download_media(
message, file=str(output_dir), progress_callback=_progress
message,
file=str(output_dir),
progress_callback=_progress
)
progress_bar.finish()
if not downloaded:
@@ -1051,27 +1110,28 @@ class Telegram(Provider):
except Exception:
date_iso = None
info: Dict[str, Any] = {
"provider": "telegram",
"source_url": url,
"chat": {
"key": chat,
"title": chat_title,
"username": chat_username,
"id": chat_id,
},
"message": {
"id": msg_id,
"date": date_iso,
"caption": caption,
},
"file": {
"name": file_name,
"mime_type": file_mime,
"size": file_size,
"downloaded_path": str(downloaded_path),
},
}
info: Dict[str,
Any] = {
"provider": "telegram",
"source_url": url,
"chat": {
"key": chat,
"title": chat_title,
"username": chat_username,
"id": chat_id,
},
"message": {
"id": msg_id,
"date": date_iso,
"caption": caption,
},
"file": {
"name": file_name,
"mime_type": file_mime,
"size": file_size,
"downloaded_path": str(downloaded_path),
},
}
return downloaded_path, info
except errors.RPCError as exc:
raise Exception(f"Telegram RPC error: {exc}")