Add YAPF style + ignore, and format tracked Python files
This commit is contained in:
@@ -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}")
|
||||
|
||||
Reference in New Issue
Block a user