danicor commited on
Commit
d459a7d
·
verified ·
1 Parent(s): ea62202

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +186 -65
app.py CHANGED
@@ -5,24 +5,53 @@ from datetime import datetime
5
  from pathlib import Path
6
  from telethon import TelegramClient, events
7
  from telethon.sessions import StringSession
8
- from typing import Optional
 
 
 
9
 
10
  # تنظیمات لاگ
11
- logging.basicConfig(level=logging.INFO)
 
 
 
12
  logger = logging.getLogger(__name__)
13
 
14
- # تنظیمات از متغیرهای محیطی (در Spaces از Secrets استفاده می‌شود)
15
- API_ID = os.environ.get("API_ID", "your_api_id_here")
16
- API_HASH = os.environ.get("API_HASH", "your_api_hash_here")
17
- BOT_TOKEN = os.environ.get("BOT_TOKEN", "your_bot_token_here")
18
 
19
  # مسیر ذخیره‌سازی در فضای HuggingFace
20
  BASE_DIR = Path("/tmp/telegram_bot_files")
21
- BASE_DIR.makedirs(parents=True, exist_ok=True)
22
 
23
  # دیکشنری برای ذخیره اطلاعات کاربران
24
  user_data = {}
25
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  class TelegramFileBot:
27
  def __init__(self):
28
  self.client = None
@@ -31,6 +60,8 @@ class TelegramFileBot:
31
  async def start(self):
32
  """شروع ربات"""
33
  try:
 
 
34
  self.client = TelegramClient(
35
  StringSession(),
36
  int(API_ID),
@@ -39,17 +70,59 @@ class TelegramFileBot:
39
 
40
  await self.client.start(bot_token=BOT_TOKEN)
41
  self.running = True
42
- logger.info("🤖 ربات تلگرام با موفقیت شروع به کار کرد!")
 
 
 
 
 
 
 
 
 
43
 
44
  # ثبت هندلرها
45
  await self._setup_handlers()
46
 
 
 
 
47
  # اجرای ربات
48
  await self.client.run_until_disconnected()
49
 
50
  except Exception as e:
51
- logger.error(f"خطا در شروع ربات: {e}")
52
  self.running = False
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
 
54
  async def _setup_handlers(self):
55
  """تنظیم هندلرهای ربات"""
@@ -57,6 +130,9 @@ class TelegramFileBot:
57
  @self.client.on(events.NewMessage(pattern='/start'))
58
  async def start_handler(event):
59
  """هندلر دستور /start"""
 
 
 
60
  welcome_msg = """
61
  🌟 **به ربات آپلود فایل خوش آمدید!**
62
 
@@ -76,6 +152,7 @@ class TelegramFileBot:
76
  /list - نمایش فایل‌های شما
77
  /clean - پاکسازی فایل‌های قدیمی
78
  /stats - آمار ربات
 
79
 
80
  **⚠️ توجه:**
81
  • فایل‌ها به صورت موقت ذخیره می‌شوند
@@ -92,22 +169,24 @@ class TelegramFileBot:
92
  **🔹 نحوه کار:**
93
  1. هر فایلی (عکس، ویدیو، سند، ...) را برای ربات بفرستید
94
  2. ربات فایل را دریافت و ذخیره می‌کند
95
- 3. لینک دانلود فایل برای شما ارسال می‌شود
 
96
 
97
  **🔹 دستورات موجود:**
98
- • `/list` - نمایش تمام فایل‌های آپلود شده شما
99
- • `/clean` - پاک کردن فایل‌های قدیمی شما
 
100
  • `/stats` - مشاهده آمار ربات
101
 
102
- **🔹 محدودیت‌ها:**
103
- • حداکثر حجم فایل: 2GB
104
- فضای ذخیره‌سازی: موقتی
105
- • فرمت‌ها: تمامی فرمت‌ها پشتیبانی می‌شوند
106
 
107
  **🔹 نکات مهم:**
108
- فایل‌ها فقط تا زمان فعالیت Space ذخیره می‌شوند
109
- برای نگهداری طولانی‌مدت، فایل‌ها را دانلود کنید
110
- از ارسال فایل‌های حساس خودداری کنید
111
  """
112
  await event.reply(help_text)
113
 
@@ -125,12 +204,17 @@ class TelegramFileBot:
125
 
126
  response = "📁 **فایل‌های شما:**\n\n"
127
  for idx, file_info in enumerate(files[-10:], 1): # آخرین 10 فایل
128
- response += f"{idx}. **{file_info['name']}**\n"
129
  response += f" 📏 حجم: {file_info['size_mb']:.2f} MB\n"
130
  response += f" 🕐 زمان: {file_info['time']}\n"
131
  response += f" 🔗 کد: `{file_info['code']}`\n\n"
132
 
133
- response += "📥 برای دانلود از دستور /download کد_فایل استفاده کنید."
 
 
 
 
 
134
  await event.reply(response)
135
  else:
136
  await event.reply("📭 **هیچ فایلی از شما آپلود نشده است.**")
@@ -140,18 +224,23 @@ class TelegramFileBot:
140
  """پاکسازی فایل‌های کاربر"""
141
  user_id = event.sender_id
142
 
143
- if user_id in user_data:
 
 
144
  # پاک کردن فایل‌های فیزیکی
145
- if "files" in user_data[user_id]:
146
- for file_info in user_data[user_id]["files"]:
147
- file_path = BASE_DIR / file_info["code"]
148
- if file_path.exists():
149
  file_path.unlink()
 
 
 
150
 
151
  # پاک کردن داده‌های کاربر
152
  user_data[user_id]["files"] = []
153
 
154
- await event.reply("🗑️ **تمام فایل‌های شما با موفقیت پاک شدند.**")
155
  else:
156
  await event.reply("📭 **هیچ فایلی برای پاک کردن وجود ندارد.**")
157
 
@@ -168,19 +257,32 @@ class TelegramFileBot:
168
  for file_info in data["files"]:
169
  total_size += file_info.get("size_bytes", 0)
170
 
 
 
 
 
 
 
 
 
 
171
  stats_msg = f"""
172
  📊 **آمار ربات:**
173
 
174
  👥 کاربران فعال: {total_users}
175
  📁 فایل‌های آپلود شده: {total_files}
176
  💾 فضای استفاده شده: {total_size / 1024 / 1024:.2f} MB
177
- 🗂️ مسیر ذخیره‌سازی: `{BASE_DIR}`
178
 
179
- ️ **توجه:** فایل‌ها موقتی هستند و بعد از ری‌استارت پاک می‌شوند.
 
 
 
 
 
180
  """
181
  await event.reply(stats_msg)
182
 
183
- @self.client.on(events.NewMessage(pattern='/download'))
184
  async def download_handler(event):
185
  """دانلود فایل با کد"""
186
  try:
@@ -207,29 +309,32 @@ class TelegramFileBot:
207
 
208
  if file_info:
209
  # ارسال فایل به کاربر
210
- caption = f"📄 **{file_info['name']}**\n📏 حجم: {file_info['size_mb']:.2f} MB"
211
  await event.reply("📤 **در حال ارسال فایل...**")
212
- await event.respond(file=file_path, caption=caption)
 
 
 
 
 
 
 
 
213
  else:
214
  await event.reply("⚠️ **اطلاعات فایل یافت نشد.**")
215
 
216
  except Exception as e:
217
- logger.error(f"خطا در دانلود: {e}")
218
  await event.reply(f"❌ **خطا در پردازش:** {str(e)}")
219
 
220
  @self.client.on(events.NewMessage)
221
  async def message_handler(event):
222
  """هندلر پیام‌های معمولی و فایل‌ها"""
223
- # اگر پیام دستور باشد، نادیده بگیر (دستورات بالا مدیریت می‌شوند)
224
  if event.message.text and event.message.text.startswith('/'):
225
  return
226
 
227
  user_id = event.sender_id
228
- chat_id = event.chat_id
229
-
230
- # ایجاد پوشه کاربر اگر وجود نداشته باشد
231
- if user_id not in user_data:
232
- user_data[user_id] = {"files": [], "chat_id": chat_id}
233
 
234
  # اگر پیام حاوی فایل باشد
235
  if event.file:
@@ -244,10 +349,16 @@ class TelegramFileBot:
244
  # اطلاعات فایل
245
  file_name = event.file.name or f"file_{datetime.now().strftime('%Y%m%d_%H%M%S')}"
246
  file_size = event.file.size
247
- file_ext = os.path.splitext(file_name)[1] or ".bin"
 
 
 
 
 
248
 
249
  # ایجاد کد یکتا برای فایل
250
- file_code = f"{user_id}_{int(datetime.now().timestamp())}_{os.urandom(4).hex()}"
 
251
  save_path = BASE_DIR / file_code
252
 
253
  # اطلاع‌رسانی شروع دریافت
@@ -259,7 +370,7 @@ class TelegramFileBot:
259
  )
260
 
261
  # دانلود فایل
262
- download_path = await event.download_media(file=save_path)
263
 
264
  # ذخیره اطلاعات فایل
265
  file_info = {
@@ -269,10 +380,13 @@ class TelegramFileBot:
269
  "size_bytes": file_size,
270
  "size_mb": file_size / 1024 / 1024,
271
  "time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
272
- "extension": file_ext,
273
  "message_id": event.id
274
  }
275
 
 
 
 
 
276
  user_data[user_id]["files"].append(file_info)
277
 
278
  # فقط آخرین 20 فایل را نگه دار
@@ -282,6 +396,7 @@ class TelegramFileBot:
282
  old_path = BASE_DIR / old_file["code"]
283
  if old_path.exists():
284
  old_path.unlink()
 
285
 
286
  # پاسخ موفقیت‌آمیز
287
  success_msg = (
@@ -290,8 +405,9 @@ class TelegramFileBot:
290
  f"📏 حجم فایل: {file_size / 1024 / 1024:.2f} MB\n"
291
  f"🔢 کد فایل: `{file_code}`\n\n"
292
  f"📥 **برای دانلود:**\n"
293
- f"1. از دستور `/download {file_code}` استفاده کنید\n"
294
- f"2. یا از منوی /list فایل خود را انتخاب کنید\n\n"
 
295
  f"📋 **تعداد فایل‌های شما:** {len(user_data[user_id]['files'])}"
296
  )
297
 
@@ -300,38 +416,43 @@ class TelegramFileBot:
300
  logger.info(f"فایل دریافت شد: {file_name} ({file_code}) توسط کاربر {user_id}")
301
 
302
  except Exception as e:
303
- logger.error(f"خطا در دریافت فایل: {e}")
304
  await event.reply(f"❌ **خطا در دریافت فایل:**\n{str(e)}")
305
 
306
- # تابع اصلی
307
  async def main():
308
  """تابع اصلی اجرای ربات"""
309
- bot = TelegramFileBot()
310
-
311
- # چک کردن تنظیمات
312
- if API_ID == "your_api_id_here" or API_HASH == "your_api_hash_here" or BOT_TOKEN == "your_bot_token_here":
313
- logger.error("❌ لطفا API_ID, API_HASH و BOT_TOKEN را تنظیم کنید!")
314
- logger.info("📝 در HuggingFace Spaces از Secrets استفاده کنید.")
315
  return
316
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
317
  try:
318
  await bot.start()
319
  except KeyboardInterrupt:
320
  logger.info("🛑 ربات متوقف شد.")
321
  except Exception as e:
322
- logger.error(f"خطای غیرمنتظره: {e}")
323
 
324
  # اجرای ربات
325
  if __name__ == "__main__":
326
- # ایجاد مسیرهای لازم
327
- BASE_DIR.makedirs(parents=True, exist_ok=True)
328
-
329
- # چاپ اطلاعات
330
- logger.info("=" * 50)
331
- logger.info("🤖 ربات آپلود فایل تلگرام")
332
- logger.info(f"📁 مسیر ذخیره‌سازی: {BASE_DIR}")
333
- logger.info(f"💾 فضای موجود: {sum(f.stat().st_size for f in BASE_DIR.glob('**/*') if f.is_file()) / 1024 / 1024:.2f} MB")
334
- logger.info("=" * 50)
335
-
336
- # اجرای ربات
337
  asyncio.run(main())
 
5
  from pathlib import Path
6
  from telethon import TelegramClient, events
7
  from telethon.sessions import StringSession
8
+ import nest_asyncio
9
+
10
+ # فعال کردن nest_asyncio برای محیط‌هایی مثل Colab/Jupyter
11
+ nest_asyncio.apply()
12
 
13
  # تنظیمات لاگ
14
+ logging.basicConfig(
15
+ level=logging.INFO,
16
+ format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
17
+ )
18
  logger = logging.getLogger(__name__)
19
 
20
+ # تنظیمات از متغیرهای محیطی
21
+ API_ID = os.environ.get("API_ID")
22
+ API_HASH = os.environ.get("API_HASH")
23
+ BOT_TOKEN = os.environ.get("BOT_TOKEN")
24
 
25
  # مسیر ذخیره‌سازی در فضای HuggingFace
26
  BASE_DIR = Path("/tmp/telegram_bot_files")
27
+ BASE_DIR.mkdir(parents=True, exist_ok=True)
28
 
29
  # دیکشنری برای ذخیره اطلاعات کاربران
30
  user_data = {}
31
 
32
+ def check_config():
33
+ """بررسی تنظیمات لازم"""
34
+ missing_configs = []
35
+
36
+ if not API_ID:
37
+ missing_configs.append("API_ID")
38
+ if not API_HASH:
39
+ missing_configs.append("API_HASH")
40
+ if not BOT_TOKEN:
41
+ missing_configs.append("BOT_TOKEN")
42
+
43
+ if missing_configs:
44
+ logger.error(f"❌ تنظیمات زیر تنظیم نشده‌اند: {', '.join(missing_configs)}")
45
+ logger.info("📝 لطفاً در HuggingFace Spaces از Secrets استفاده کنید:")
46
+ logger.info("1. به Settings > Secrets بروید")
47
+ logger.info("2. متغیرهای زیر را اضافه کنید:")
48
+ logger.info(" - API_ID: API ID از my.telegram.org")
49
+ logger.info(" - API_HASH: API Hash از my.telegram.org")
50
+ logger.info(" - BOT_TOKEN: توکن ربات از @BotFather")
51
+ return False
52
+
53
+ return True
54
+
55
  class TelegramFileBot:
56
  def __init__(self):
57
  self.client = None
 
60
  async def start(self):
61
  """شروع ربات"""
62
  try:
63
+ logger.info("🚀 در حال راه‌اندازی ربات...")
64
+
65
  self.client = TelegramClient(
66
  StringSession(),
67
  int(API_ID),
 
70
 
71
  await self.client.start(bot_token=BOT_TOKEN)
72
  self.running = True
73
+
74
+ me = await self.client.get_me()
75
+ logger.info(f"🤖 ربات با موفقیت شروع به کار کرد: @{me.username}")
76
+ logger.info(f"📁 مسیر ذخیره‌سازی: {BASE_DIR}")
77
+
78
+ # ایجاد پوشه ذخیره‌سازی
79
+ BASE_DIR.mkdir(parents=True, exist_ok=True)
80
+
81
+ # نمایش اطلاعات فضای ذخیره‌سازی
82
+ await self.show_storage_info()
83
 
84
  # ثبت هندلرها
85
  await self._setup_handlers()
86
 
87
+ # اطلاع‌رسانی شروع
88
+ await self.notify_admin("✅ ربات با موفقیت راه‌اندازی شد!")
89
+
90
  # اجرای ربات
91
  await self.client.run_until_disconnected()
92
 
93
  except Exception as e:
94
+ logger.error(f"خطا در شروع ربات: {e}", exc_info=True)
95
  self.running = False
96
+
97
+ async def show_storage_info(self):
98
+ """نمایش اطلاعات فضای ذخیره‌سازی"""
99
+ try:
100
+ total_size = 0
101
+ file_count = 0
102
+
103
+ for file_path in BASE_DIR.glob("*"):
104
+ if file_path.is_file():
105
+ total_size += file_path.stat().st_size
106
+ file_count += 1
107
+
108
+ logger.info(f"💾 فضای ذخیره‌سازی:")
109
+ logger.info(f" 📁 تعداد فایل‌ها: {file_count}")
110
+ logger.info(f" 📊 حجم استفاده شده: {total_size / 1024 / 1024:.2f} MB")
111
+ logger.info(f" 📍 مسیر: {BASE_DIR}")
112
+
113
+ except Exception as e:
114
+ logger.error(f"خطا در دریافت اطلاعات فضای ذخیره‌سازی: {e}")
115
+
116
+ async def notify_admin(self, message):
117
+ """ارسال اطلاع به ادمین"""
118
+ try:
119
+ # در اینجا می‌توانید چت آیدی ادمین را اضافه کنید
120
+ # به عنوان مثال: ADMIN_CHAT_ID = "123456789"
121
+ # if ADMIN_CHAT_ID:
122
+ # await self.client.send_message(int(ADMIN_CHAT_ID), message)
123
+ pass
124
+ except Exception as e:
125
+ logger.error(f"خطا در ارسال اطلاع به ادمین: {e}")
126
 
127
  async def _setup_handlers(self):
128
  """تنظیم هندلرهای ربات"""
 
130
  @self.client.on(events.NewMessage(pattern='/start'))
131
  async def start_handler(event):
132
  """هندلر دستور /start"""
133
+ user = await event.get_sender()
134
+ logger.info(f"کاربر {user.id} ({user.username}) دستور /start را فرستاد")
135
+
136
  welcome_msg = """
137
  🌟 **به ربات آپلود فایل خوش آمدید!**
138
 
 
152
  /list - نمایش فایل‌های شما
153
  /clean - پاکسازی فایل‌های قدیمی
154
  /stats - آمار ربات
155
+ /download [کد] - دانلود فایل
156
 
157
  **⚠️ توجه:**
158
  • فایل‌ها به صورت موقت ذخیره می‌شوند
 
169
  **🔹 نحوه کار:**
170
  1. هر فایلی (عکس، ویدیو، سند، ...) را برای ربات بفرستید
171
  2. ربات فایل را دریافت و ذخیره می‌کند
172
+ 3. یک کد یکتا برای فایل ایجاد می‌شود
173
+ 4. با دستور /download می‌توانید فایل را دانلود کنید
174
 
175
  **🔹 دستورات موجود:**
176
+ • `/list` - نمایش 10 فایل آخر شما
177
+ • `/download کد` - دانلود فایل با کد
178
+ • `/clean` - پاک کردن تمام فایل‌های شما
179
  • `/stats` - مشاهده آمار ربات
180
 
181
+ **🔹 مثال:**
182
+ ```
183
+ /download 123456_abc
184
+ ```
185
 
186
  **🔹 نکات مهم:**
187
+ حداکثر حجم فایل: 2GB
188
+ فایل‌ها موقتی ذخیره می‌شوند
189
+ کد فایل را در مکانی امن ذخیره کنید
190
  """
191
  await event.reply(help_text)
192
 
 
204
 
205
  response = "📁 **فایل‌های شما:**\n\n"
206
  for idx, file_info in enumerate(files[-10:], 1): # آخرین 10 فایل
207
+ response += f"**{idx}. {file_info['name']}**\n"
208
  response += f" 📏 حجم: {file_info['size_mb']:.2f} MB\n"
209
  response += f" 🕐 زمان: {file_info['time']}\n"
210
  response += f" 🔗 کد: `{file_info['code']}`\n\n"
211
 
212
+ response += "📥 برای دانلود:\n"
213
+ response += "```\n"
214
+ response += "/download کد_فایل\n"
215
+ response += "```\n\n"
216
+ response += "مثال: `/download abc123`"
217
+
218
  await event.reply(response)
219
  else:
220
  await event.reply("📭 **هیچ فایلی از شما آپلود نشده است.**")
 
224
  """پاکسازی فایل‌های کاربر"""
225
  user_id = event.sender_id
226
 
227
+ if user_id in user_data and "files" in user_data[user_id]:
228
+ file_count = len(user_data[user_id]["files"])
229
+
230
  # پاک کردن فایل‌های فیزیکی
231
+ for file_info in user_data[user_id]["files"]:
232
+ file_path = BASE_DIR / file_info["code"]
233
+ if file_path.exists():
234
+ try:
235
  file_path.unlink()
236
+ logger.info(f"فایل پاک شد: {file_info['code']}")
237
+ except Exception as e:
238
+ logger.error(f"خطا در پاک کردن فایل {file_info['code']}: {e}")
239
 
240
  # پاک کردن داده‌های کاربر
241
  user_data[user_id]["files"] = []
242
 
243
+ await event.reply(f"🗑️ **{file_count} فایل با موفقیت پاک شدند.**")
244
  else:
245
  await event.reply("📭 **هیچ فایلی برای پاک کردن وجود ندارد.**")
246
 
 
257
  for file_info in data["files"]:
258
  total_size += file_info.get("size_bytes", 0)
259
 
260
+ # محاسبه فضای باقی‌مانده
261
+ try:
262
+ statvfs = os.statvfs('/tmp')
263
+ free_space = (statvfs.f_bavail * statvfs.f_frsize) / 1024 / 1024 / 1024 # GB
264
+ total_space = (statvfs.f_blocks * statvfs.f_frsize) / 1024 / 1024 / 1024 # GB
265
+ used_space = total_space - free_space
266
+ except:
267
+ free_space = used_space = total_space = 0
268
+
269
  stats_msg = f"""
270
  📊 **آمار ربات:**
271
 
272
  👥 کاربران فعال: {total_users}
273
  📁 فایل‌های آپلود شده: {total_files}
274
  💾 فضای استفاده شده: {total_size / 1024 / 1024:.2f} MB
 
275
 
276
+ 🗂️ **فضای ذخیرهسازی:**
277
+ 📊 استفاده شده: {used_space:.2f} GB
278
+ 📈 کل فضای /tmp: {total_space:.2f} GB
279
+ 📉 فضای آزاد: {free_space:.2f} GB
280
+
281
+ ⚠️ **توجه:** فایل‌ها در `/tmp` ذخیره می‌شوند و موقتی هستند.
282
  """
283
  await event.reply(stats_msg)
284
 
285
+ @self.client.on(events.NewMessage(pattern=r'/download\s+\S+'))
286
  async def download_handler(event):
287
  """دانلود فایل با کد"""
288
  try:
 
309
 
310
  if file_info:
311
  # ارسال فایل به کاربر
312
+ caption = f"📄 **{file_info['name']}**\n📏 حجم: {file_info['size_mb']:.2f} MB\n🕐 زمان آپلود: {file_info['time']}"
313
  await event.reply("📤 **در حال ارسال فایل...**")
314
+
315
+ # ارسال فایل
316
+ await event.respond(
317
+ file=file_path,
318
+ caption=caption,
319
+ force_document=True
320
+ )
321
+
322
+ logger.info(f"فایل ارسال شد: {file_code} به کاربر {event.sender_id}")
323
  else:
324
  await event.reply("⚠️ **اطلاعات فایل یافت نشد.**")
325
 
326
  except Exception as e:
327
+ logger.error(f"خطا در دانلود: {e}", exc_info=True)
328
  await event.reply(f"❌ **خطا در پردازش:** {str(e)}")
329
 
330
  @self.client.on(events.NewMessage)
331
  async def message_handler(event):
332
  """هندلر پیام‌های معمولی و فایل‌ها"""
333
+ # اگر پیام دستور باشد، نادیده بگیر
334
  if event.message.text and event.message.text.startswith('/'):
335
  return
336
 
337
  user_id = event.sender_id
 
 
 
 
 
338
 
339
  # اگر پیام حاوی فایل باشد
340
  if event.file:
 
349
  # اطلاعات فایل
350
  file_name = event.file.name or f"file_{datetime.now().strftime('%Y%m%d_%H%M%S')}"
351
  file_size = event.file.size
352
+
353
+ # بررسی حجم فایل (حداکثر 2GB)
354
+ max_size = 2 * 1024 * 1024 * 1024 # 2GB
355
+ if file_size > max_size:
356
+ await event.reply(f"❌ **حجم فایل بسیار بزرگ است!**\nحداکثر حجم مجاز: 2GB\nحجم فایل شما: {file_size / 1024 / 1024 / 1024:.2f} GB")
357
+ return
358
 
359
  # ایجاد کد یکتا برای فایل
360
+ timestamp = int(datetime.now().timestamp())
361
+ file_code = f"{user_id}_{timestamp}_{os.urandom(4).hex()}"
362
  save_path = BASE_DIR / file_code
363
 
364
  # اطلاع‌رسانی شروع دریافت
 
370
  )
371
 
372
  # دانلود فایل
373
+ download_path = await event.download_media(file=str(save_path))
374
 
375
  # ذخیره اطلاعات فایل
376
  file_info = {
 
380
  "size_bytes": file_size,
381
  "size_mb": file_size / 1024 / 1024,
382
  "time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
 
383
  "message_id": event.id
384
  }
385
 
386
+ # ایجاد یا به‌روزرسانی داده کاربر
387
+ if user_id not in user_data:
388
+ user_data[user_id] = {"files": []}
389
+
390
  user_data[user_id]["files"].append(file_info)
391
 
392
  # فقط آخرین 20 فایل را نگه دار
 
396
  old_path = BASE_DIR / old_file["code"]
397
  if old_path.exists():
398
  old_path.unlink()
399
+ logger.info(f"فایل قدیمی پاک شد: {old_file['code']}")
400
 
401
  # پاسخ موفقیت‌آمیز
402
  success_msg = (
 
405
  f"📏 حجم فایل: {file_size / 1024 / 1024:.2f} MB\n"
406
  f"🔢 کد فایل: `{file_code}`\n\n"
407
  f"📥 **برای دانلود:**\n"
408
+ f"```\n"
409
+ f"/download {file_code}\n"
410
+ f"```\n\n"
411
  f"📋 **تعداد فایل‌های شما:** {len(user_data[user_id]['files'])}"
412
  )
413
 
 
416
  logger.info(f"فایل دریافت شد: {file_name} ({file_code}) توسط کاربر {user_id}")
417
 
418
  except Exception as e:
419
+ logger.error(f"خطا در دریافت فایل: {e}", exc_info=True)
420
  await event.reply(f"❌ **خطا در دریافت فایل:**\n{str(e)}")
421
 
 
422
  async def main():
423
  """تابع اصلی اجرای ربات"""
424
+ # بررسی تنظیمات
425
+ if not check_config():
 
 
 
 
426
  return
427
 
428
+ # ایجاد مسیر ذخیره‌سازی
429
+ BASE_DIR.mkdir(parents=True, exist_ok=True)
430
+
431
+ # نمایش اطلاعات راه‌اندازی
432
+ logger.info("=" * 50)
433
+ logger.info("🤖 ربات آپلود فایل تلگرام")
434
+ logger.info(f"📁 مسیر ذخیره‌سازی: {BASE_DIR}")
435
+
436
+ # محاسبه فضای موجود
437
+ try:
438
+ statvfs = os.statvfs('/tmp')
439
+ free_gb = (statvfs.f_bavail * statvfs.f_frsize) / 1024 / 1024 / 1024
440
+ logger.info(f"💾 فضای آزاد /tmp: {free_gb:.2f} GB")
441
+ except:
442
+ logger.info("💾 فضای /tmp: نامشخص")
443
+
444
+ logger.info("=" * 50)
445
+
446
+ # ایجاد و اجرای ربات
447
+ bot = TelegramFileBot()
448
+
449
  try:
450
  await bot.start()
451
  except KeyboardInterrupt:
452
  logger.info("🛑 ربات متوقف شد.")
453
  except Exception as e:
454
+ logger.error(f"خطای غیرمنتظره: {e}", exc_info=True)
455
 
456
  # اجرای ربات
457
  if __name__ == "__main__":
 
 
 
 
 
 
 
 
 
 
 
458
  asyncio.run(main())