dfd
This commit is contained in:
@@ -144,7 +144,7 @@ class Matrix(Provider):
|
||||
out.append({"room_id": room_id, "name": name})
|
||||
return out
|
||||
|
||||
def upload_to_room(self, file_path: str, room_id: str) -> str:
|
||||
def upload_to_room(self, file_path: str, room_id: str, **kwargs: Any) -> str:
|
||||
"""Upload a file and send it to a specific room."""
|
||||
path = Path(file_path)
|
||||
if not path.exists():
|
||||
@@ -174,6 +174,22 @@ class Matrix(Provider):
|
||||
if not content_uri:
|
||||
raise Exception("No content_uri returned")
|
||||
|
||||
# Build a fragment-free URL suitable for storage backends.
|
||||
# `matrix.to` links use fragments (`#/...`) which some backends normalize away.
|
||||
download_url_for_store = ""
|
||||
try:
|
||||
curi = str(content_uri or "").strip()
|
||||
if curi.startswith("mxc://"):
|
||||
rest = curi[len("mxc://"):]
|
||||
if "/" in rest:
|
||||
server_name, media_id = rest.split("/", 1)
|
||||
server_name = str(server_name).strip()
|
||||
media_id = str(media_id).strip()
|
||||
if server_name and media_id:
|
||||
download_url_for_store = f"{base}/_matrix/media/v3/download/{quote(server_name, safe='')}/{quote(media_id, safe='')}"
|
||||
except Exception:
|
||||
download_url_for_store = ""
|
||||
|
||||
# Determine message type
|
||||
msgtype = "m.file"
|
||||
ext = path.suffix.lower()
|
||||
@@ -199,6 +215,44 @@ class Matrix(Provider):
|
||||
if send_resp.status_code != 200:
|
||||
raise Exception(f"Matrix send message failed: {send_resp.text}")
|
||||
|
||||
event_id = (send_resp.json() or {}).get("event_id")
|
||||
link = f"https://matrix.to/#/{room_id}/{event_id}" if event_id else f"https://matrix.to/#/{room_id}"
|
||||
|
||||
# Optional: if a PipeObject is provided and it already has store+hash,
|
||||
# attach the uploaded URL back to the stored file.
|
||||
try:
|
||||
pipe_obj = kwargs.get("pipe_obj")
|
||||
if pipe_obj is not None:
|
||||
from Store import Store
|
||||
|
||||
# Prefer the direct media download URL for storage backends.
|
||||
Store(self.config, suppress_debug=True).try_add_url_for_pipe_object(
|
||||
pipe_obj,
|
||||
download_url_for_store or link,
|
||||
)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return link
|
||||
|
||||
def send_text_to_room(self, text: str, room_id: str) -> str:
|
||||
"""Send a plain text message to a specific room."""
|
||||
message = str(text or "").strip()
|
||||
if not message:
|
||||
return ""
|
||||
if not room_id:
|
||||
raise Exception("Matrix room_id missing")
|
||||
|
||||
base, token = self._get_homeserver_and_token()
|
||||
encoded_room = quote(str(room_id), safe="")
|
||||
txn_id = f"mm_{int(time.time())}_{uuid.uuid4().hex[:8]}"
|
||||
send_url = f"{base}/_matrix/client/v3/rooms/{encoded_room}/send/m.room.message/{txn_id}"
|
||||
send_headers = {"Authorization": f"Bearer {token}"}
|
||||
payload = {"msgtype": "m.text", "body": message}
|
||||
send_resp = requests.put(send_url, headers=send_headers, json=payload)
|
||||
if send_resp.status_code != 200:
|
||||
raise Exception(f"Matrix send text failed: {send_resp.text}")
|
||||
|
||||
event_id = (send_resp.json() or {}).get("event_id")
|
||||
return f"https://matrix.to/#/{room_id}/{event_id}" if event_id else f"https://matrix.to/#/{room_id}"
|
||||
|
||||
@@ -247,9 +301,11 @@ class Matrix(Provider):
|
||||
try:
|
||||
file_path = ''
|
||||
delete_after = False
|
||||
pipe_obj = None
|
||||
if isinstance(payload, dict):
|
||||
file_path = str(payload.get('path') or '')
|
||||
delete_after = bool(payload.get('delete_after', False))
|
||||
pipe_obj = payload.get('pipe_obj')
|
||||
else:
|
||||
file_path = str(getattr(payload, 'path', '') or '')
|
||||
if not file_path:
|
||||
@@ -262,7 +318,7 @@ class Matrix(Provider):
|
||||
print(f"Matrix upload file missing: {file_path}")
|
||||
continue
|
||||
|
||||
link = self.upload_to_room(str(media_path), str(room_id))
|
||||
link = self.upload_to_room(str(media_path), str(room_id), pipe_obj=pipe_obj)
|
||||
if link:
|
||||
print(link)
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@ from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import re
|
||||
import sys
|
||||
import time
|
||||
from pathlib import Path
|
||||
from typing import Any, Dict, Optional, Tuple
|
||||
from urllib.parse import urlparse
|
||||
@@ -143,6 +145,21 @@ class Telegram(Provider):
|
||||
session_base = self._session_base_path()
|
||||
chat, message_id = _parse_telegram_message_url(url)
|
||||
|
||||
def _format_bytes(num: Optional[int]) -> str:
|
||||
try:
|
||||
if num is None:
|
||||
return "?B"
|
||||
n = float(num)
|
||||
suffixes = ["B", "KB", "MB", "GB", "TB"]
|
||||
for s in suffixes:
|
||||
if n < 1024 or s == suffixes[-1]:
|
||||
if s == "B":
|
||||
return f"{int(n)}{s}"
|
||||
return f"{n:.1f}{s}"
|
||||
n /= 1024
|
||||
except Exception:
|
||||
return "?B"
|
||||
|
||||
client = TelegramClient(str(session_base), app_id, api_hash)
|
||||
try:
|
||||
# This prompts on first run for phone/code and persists the session.
|
||||
@@ -226,7 +243,35 @@ class Telegram(Provider):
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
downloaded = _resolve(client.download_media(message, file=str(output_dir)))
|
||||
# Progress callback: prints to stderr so it doesn't interfere with pipeline stdout.
|
||||
last_print = {"t": 0.0}
|
||||
def _progress(current: int, total: int) -> None:
|
||||
try:
|
||||
now = time.monotonic()
|
||||
# Throttle to avoid spamming.
|
||||
if now - float(last_print.get("t", 0.0)) < 0.25 and current < total:
|
||||
return
|
||||
last_print["t"] = now
|
||||
|
||||
pct = ""
|
||||
try:
|
||||
if total and total > 0:
|
||||
pct = f" {min(100.0, (current / total) * 100.0):5.1f}%"
|
||||
except Exception:
|
||||
pct = ""
|
||||
|
||||
line = f"[telegram] Downloading{pct} ({_format_bytes(current)}/{_format_bytes(total)})"
|
||||
sys.stderr.write("\r" + line)
|
||||
sys.stderr.flush()
|
||||
except Exception:
|
||||
return
|
||||
|
||||
downloaded = _resolve(client.download_media(message, file=str(output_dir), progress_callback=_progress))
|
||||
try:
|
||||
sys.stderr.write("\n")
|
||||
sys.stderr.flush()
|
||||
except Exception:
|
||||
pass
|
||||
if not downloaded:
|
||||
raise Exception("Telegram download returned no file")
|
||||
downloaded_path = Path(str(downloaded))
|
||||
|
||||
@@ -24,7 +24,17 @@ class ZeroXZero(Provider):
|
||||
response = client.post("https://0x0.st", files={"file": handle})
|
||||
|
||||
if response.status_code == 200:
|
||||
return response.text.strip()
|
||||
uploaded_url = response.text.strip()
|
||||
try:
|
||||
pipe_obj = kwargs.get("pipe_obj")
|
||||
if pipe_obj is not None:
|
||||
from Store import Store
|
||||
|
||||
Store(self.config, suppress_debug=True).try_add_url_for_pipe_object(pipe_obj, uploaded_url)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return uploaded_url
|
||||
|
||||
raise Exception(f"Upload failed: {response.status_code} - {response.text}")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user