feat: supported link convert

This commit is contained in:
Hehesheng 2024-06-04 00:01:59 +08:00
parent 247c213599
commit 44803cf4a1
4 changed files with 40 additions and 5 deletions

View File

@ -167,7 +167,7 @@ class MediaChunkHolderManager(object):
def __init__(self) -> None: def __init__(self) -> None:
self.chunk_lru = collections.OrderedDict() self.chunk_lru = collections.OrderedDict()
self.disk_chunk_cache = diskcache.Cache( self.disk_chunk_cache = diskcache.Cache(
f"{os.path.dirname(__file__)}/cache_media", size_limit=MediaChunkHolderManager.MAX_CACHE_SIZE f"{os.path.dirname(__file__)}/cache_media", size_limit=MediaChunkHolderManager.MAX_CACHE_SIZE * 2
) )
self._restore_cache() self._restore_cache()

View File

@ -37,6 +37,7 @@ class TgFileSystemClient(object):
qr_login: QRLogin | None = None qr_login: QRLogin | None = None
login_task: asyncio.Task | None = None login_task: asyncio.Task | None = None
# rsa key # rsa key
sign: str
public_key: rsa.PublicKey public_key: rsa.PublicKey
private_key: rsa.PrivateKey private_key: rsa.PrivateKey
# task should: (task_id, callabledFunc) # task should: (task_id, callabledFunc)
@ -69,6 +70,7 @@ class TgFileSystemClient(object):
(client_param for client_param in param.clients if client_param.token == session_name), (client_param for client_param in param.clients if client_param.token == session_name),
configParse.TgToFileSystemParameter.ClientConfigPatameter(), configParse.TgToFileSystemParameter.ClientConfigPatameter(),
) )
self.sign = self.client_param.token
self.task_queue = asyncio.Queue() self.task_queue = asyncio.Queue()
self.client = TelegramClient( self.client = TelegramClient(
f"{os.path.dirname(__file__)}/db/{self.session_name}.session", f"{os.path.dirname(__file__)}/db/{self.session_name}.session",
@ -210,7 +212,7 @@ class TgFileSystemClient(object):
logger.info(f"{chat_id} quit cache task.") logger.info(f"{chat_id} quit cache task.")
@_acheck_before_call @_acheck_before_call
async def get_message(self, chat_id: int, msg_id: int) -> types.Message: async def get_message(self, chat_id: int | str, msg_id: int) -> types.Message:
msg = await self.client.get_messages(chat_id, ids=msg_id) msg = await self.client.get_messages(chat_id, ids=msg_id)
return msg return msg
@ -245,6 +247,10 @@ class TgFileSystemClient(object):
offset = first_id + offset offset = first_id + offset
return offset return offset
@_acheck_before_call
async def get_entity(self, chat_id_or_name) -> hints.Entity:
return await self.client.get_entity(chat_id_or_name)
@_acheck_before_call @_acheck_before_call
async def get_messages(self, chat_id: int, limit: int = 10, offset: int = 0) -> hints.TotalList: async def get_messages(self, chat_id: int, limit: int = 10, offset: int = 0) -> hints.TotalList:
offset = await self._get_offset_msg_id(chat_id, offset) offset = await self._get_offset_msg_id(chat_id, offset)

View File

@ -86,6 +86,11 @@ class TgFileSystemClientManager(object):
client = self.clients.get(client_id) client = self.clients.get(client_id)
return client return client
def get_first_client(self) -> TgFileSystemClient:
for client in self.clients.values():
return client
return None
async def get_client_force(self, client_id: str) -> TgFileSystemClient: async def get_client_force(self, client_id: str) -> TgFileSystemClient:
client = self.get_client(client_id) client = self.get_client(client_id)
if client is None: if client is None:

View File

@ -9,7 +9,7 @@ from fastapi import FastAPI, status, Request
from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import Response, StreamingResponse from fastapi.responses import Response, StreamingResponse
from contextlib import asynccontextmanager from contextlib import asynccontextmanager
from telethon import types, hints from telethon import types, hints, utils
from pydantic import BaseModel from pydantic import BaseModel
import configParse import configParse
@ -199,8 +199,32 @@ async def get_tg_file_client_status(request: Request):
@app.get("/tg/api/v1/client/link_convert") @app.get("/tg/api/v1/client/link_convert")
@apiutils.atimeit @apiutils.atimeit
async def convert_tg_msg_link_media_stream(link: str, sign: str): async def convert_tg_msg_link_media_stream(link: str):
raise NotImplementedError try:
link_slice = link.split("/")
if len(link_slice) < 5:
raise RuntimeError("link format invalid")
chat_id_or_name, msg_id = link_slice[-2:]
is_msg_id = msg_id.isascii() and msg_id.isdecimal()
if not is_msg_id:
raise RuntimeError("message id invalid")
msg_id = int(msg_id)
is_chat_name = chat_id_or_name.isascii() and not chat_id_or_name.isdecimal()
is_chat_id = chat_id_or_name.isascii() and chat_id_or_name.isdecimal()
if not is_chat_name and not is_chat_id:
raise RuntimeError("chat id invalid")
client = clients_mgr.get_first_client()
if client is None:
raise RuntimeError("client not ready, login first pls.")
if is_chat_id:
chat_id_or_name = int(chat_id_or_name)
msg = await client.get_message(chat_id_or_name, msg_id)
file_name = apiutils.get_message_media_name(msg)
url = f"{param.base.exposed_url}/tg/api/v1/file/get/{utils.get_peer_id(msg.peer_id)}/{msg.id}/{file_name}?sign={client.sign}"
return Response(json.dumps({"url": url}), status_code=status.HTTP_200_OK)
except Exception as err:
logger.error(f"{err=}")
return Response(json.dumps({"detail": "link invalid", "err": f"{err}"}), status_code=status.HTTP_404_NOT_FOUND)
@app.get("/tg/api/v1/client/profile_photo") @app.get("/tg/api/v1/client/profile_photo")