rkihacker commited on
Commit
4f9dc53
·
verified ·
1 Parent(s): d15eefe

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +22 -21
main.py CHANGED
@@ -6,7 +6,6 @@ from fastapi import FastAPI, UploadFile, File, HTTPException
6
  from fastapi.responses import FileResponse
7
  import uvicorn
8
  import tempfile
9
- from typing import Dict
10
 
11
  # --- Configuration from environment variables ---
12
  SESSION_STRING = os.environ.get('SESSION_STRING')
@@ -21,10 +20,7 @@ UPLOAD_DIR = tempfile.gettempdir()
21
 
22
  app = FastAPI()
23
 
24
- # --- In-Memory Database for Filename to Message ID mapping ---
25
- # NOTE: This dictionary is not persistent. It will be cleared if the server restarts.
26
- # For production, replace this with a real database (e.g., Redis, SQLite).
27
- file_map: Dict[str, int] = {}
28
 
29
  async def upload_to_telegram(file_path: str):
30
  """Uploads a file and returns the full Telegram message object."""
@@ -32,6 +28,7 @@ async def upload_to_telegram(file_path: str):
32
  raise ValueError("Server is not configured with Telegram credentials.")
33
  async with TelegramClient(StringSession(SESSION_STRING), API_ID, API_HASH) as client:
34
  try:
 
35
  message = await client.send_file(TARGET_CHANNEL, file_path, force_document=True)
36
  if not message or not message.media:
37
  raise HTTPException(status_code=500, detail="Upload failed to return a valid message.")
@@ -42,7 +39,7 @@ async def upload_to_telegram(file_path: str):
42
  @app.post("/v1/upload")
43
  async def upload_file(file: UploadFile = File(...)):
44
  """
45
- Uploads a file to Telegram, stores its mapping, and returns full API details.
46
  """
47
  file_location = os.path.join(UPLOAD_DIR, file.filename)
48
  try:
@@ -52,15 +49,10 @@ async def upload_file(file: UploadFile = File(...)):
52
  message = await upload_to_telegram(file_location)
53
  doc = message.document
54
 
55
- # Extract the original filename from the document attributes
56
  original_filename = next((attr.file_name for attr in doc.attributes if hasattr(attr, 'file_name')), file.filename)
57
 
58
- # Store the mapping in our in-memory "database"
59
- file_map[original_filename] = message.id
60
-
61
- # Return a rich, detailed JSON response from the Telegram API
62
  return {
63
- "message": "File uploaded successfully.",
64
  "channel": TARGET_CHANNEL,
65
  "telegram_details": {
66
  "message_id": message.id,
@@ -76,28 +68,37 @@ async def upload_file(file: UploadFile = File(...)):
76
  if os.path.exists(file_location):
77
  os.remove(file_location)
78
 
79
- @app.get("/v1/download/{filename}")
80
- async def download_file(filename: str):
81
  """
82
- Downloads a file from Telegram by its filename using the stored mapping.
 
83
  """
84
- # Look up the message_id from our in-memory map
85
- message_id = file_map.get(filename)
86
- if not message_id:
87
- raise HTTPException(status_code=404, detail=f"File '{filename}' not found. The server may have restarted or the file was never uploaded.")
88
 
89
  download_path = None
90
  try:
91
  async with TelegramClient(StringSession(SESSION_STRING), API_ID, API_HASH) as client:
 
92
  message = await client.get_messages(TARGET_CHANNEL, ids=message_id)
 
93
  if not message or not message.media:
94
- raise HTTPException(status_code=404, detail="File found in map, but message is missing or has no media in Telegram.")
95
 
 
 
 
 
96
  download_path = await client.download_media(message, file=UPLOAD_DIR)
97
- return FileResponse(download_path, media_type='application/octet-stream', filename=filename)
 
 
 
98
  except Exception as e:
99
  raise HTTPException(status_code=500, detail=f"Failed to download from Telegram: {e}")
100
  finally:
 
101
  if download_path and os.path.exists(download_path):
102
  os.remove(download_path)
103
 
 
6
  from fastapi.responses import FileResponse
7
  import uvicorn
8
  import tempfile
 
9
 
10
  # --- Configuration from environment variables ---
11
  SESSION_STRING = os.environ.get('SESSION_STRING')
 
20
 
21
  app = FastAPI()
22
 
23
+ # NOTE: The in-memory file_map has been REMOVED for a stateless design.
 
 
 
24
 
25
  async def upload_to_telegram(file_path: str):
26
  """Uploads a file and returns the full Telegram message object."""
 
28
  raise ValueError("Server is not configured with Telegram credentials.")
29
  async with TelegramClient(StringSession(SESSION_STRING), API_ID, API_HASH) as client:
30
  try:
31
+ # force_document=True ensures it's treated as a file with a consistent filename
32
  message = await client.send_file(TARGET_CHANNEL, file_path, force_document=True)
33
  if not message or not message.media:
34
  raise HTTPException(status_code=500, detail="Upload failed to return a valid message.")
 
39
  @app.post("/v1/upload")
40
  async def upload_file(file: UploadFile = File(...)):
41
  """
42
+ Uploads a file to Telegram and returns its persistent message_id and other details.
43
  """
44
  file_location = os.path.join(UPLOAD_DIR, file.filename)
45
  try:
 
49
  message = await upload_to_telegram(file_location)
50
  doc = message.document
51
 
 
52
  original_filename = next((attr.file_name for attr in doc.attributes if hasattr(attr, 'file_name')), file.filename)
53
 
 
 
 
 
54
  return {
55
+ "message": "File uploaded successfully. Use the 'message_id' to download.",
56
  "channel": TARGET_CHANNEL,
57
  "telegram_details": {
58
  "message_id": message.id,
 
68
  if os.path.exists(file_location):
69
  os.remove(file_location)
70
 
71
+ @app.get("/v1/download/{message_id}")
72
+ async def download_file(message_id: int):
73
  """
74
+ Downloads a file from Telegram using its unique message_id from the channel.
75
+ This method is stateless and resilient to server restarts.
76
  """
77
+ if not all([SESSION_STRING, API_ID, API_HASH]):
78
+ raise HTTPException(status_code=500, detail="Server is not configured for downloads.")
 
 
79
 
80
  download_path = None
81
  try:
82
  async with TelegramClient(StringSession(SESSION_STRING), API_ID, API_HASH) as client:
83
+ # Fetch the message directly using its ID
84
  message = await client.get_messages(TARGET_CHANNEL, ids=message_id)
85
+
86
  if not message or not message.media:
87
+ raise HTTPException(status_code=404, detail=f"A message with ID '{message_id}' was not found or contains no media.")
88
 
89
+ # Determine the original filename for the response
90
+ original_filename = message.file.name if message.file and message.file.name else f"download_{message_id}"
91
+
92
+ # Download the file to a temporary location on the server
93
  download_path = await client.download_media(message, file=UPLOAD_DIR)
94
+
95
+ # Stream the file back to the client
96
+ return FileResponse(download_path, media_type='application/octet-stream', filename=original_filename)
97
+
98
  except Exception as e:
99
  raise HTTPException(status_code=500, detail=f"Failed to download from Telegram: {e}")
100
  finally:
101
+ # Crucially, clean up the temporary file from the server after sending it
102
  if download_path and os.path.exists(download_path):
103
  os.remove(download_path)
104