AI Update: تست اف تی پی نتیجه رو درست نمیگه

This commit is contained in:
Antigravity Bot
2026-08-30 21:23:34 +03:30
parent ab4764f521
commit 5ab0a40b03
4 changed files with 91 additions and 26 deletions
+7
View File
@@ -360,6 +360,13 @@ class SessionManager:
"created_at": p_obj.created_at,
"description": p_obj.description,
"conversation_titles": p_obj.conversation_titles,
"active_branch": p_obj.active_branch,
"ftp_host": p_obj.ftp_host,
"ftp_port": p_obj.ftp_port,
"ftp_user": p_obj.ftp_user,
"ftp_password": p_obj.ftp_password,
"ftp_path": p_obj.ftp_path,
"ftp_tls": p_obj.ftp_tls,
}
curr = self.get_current_project(sess.chat_id)
data[str(k)] = {
+17 -2
View File
@@ -4832,9 +4832,24 @@ async def callback_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
path=curr_proj.ftp_path or "/",
tls=curr_proj.ftp_tls,
)
icon = "" if test_ok else ""
res_card = (
f"{icon} <b>نتیجه تست اتصال FTP:</b>\n\n"
f"• 🌐 <b>هاست:</b> <code>{escape_html(curr_proj.ftp_host)}:{curr_proj.ftp_port}</code>\n"
f"• 👤 <b>نام کاربری:</b> <code>{escape_html(curr_proj.ftp_user or '(بدون نام کاربری)')}</code>\n"
f"• 📂 <b>مسیر:</b> <code>{escape_html(curr_proj.ftp_path or '/')}</code>\n"
f"• 🔒 <b>پروتکل:</b> {'FTPS/TLS امن 🔒' if curr_proj.ftp_tls else 'FTP معمولی'}\n\n"
f"📋 <b>گزارش ارتباط:</b>\n{test_msg}"
) if is_fa else (
f"{icon} <b>FTP Connection Test Result:</b>\n\n"
f"• 🌐 <b>Host:</b> <code>{escape_html(curr_proj.ftp_host)}:{curr_proj.ftp_port}</code>\n"
f"• 👤 <b>User:</b> <code>{escape_html(curr_proj.ftp_user or '(none)')}</code>\n"
f"• 📂 <b>Path:</b> <code>{escape_html(curr_proj.ftp_path or '/')}</code>\n"
f"• 🔒 <b>Protocol:</b> {'Secure FTPS/TLS 🔒' if curr_proj.ftp_tls else 'Standard FTP'}\n\n"
f"📋 <b>Status:</b>\n{test_msg}"
)
try:
alert_text = ("✅ اتصال FTP برقرار است" if test_ok else "❌ خطا در اتصال FTP") + f"\n{test_msg}"
await query.answer(alert_text[:200], show_alert=True)
await query.message.reply_html(res_card, disable_web_page_preview=True)
except Exception:
pass
else:
+55 -12
View File
@@ -116,17 +116,27 @@ class FTPManager:
timeout: int = 15,
) -> ftplib.FTP:
"""Helper to create and authenticate an FTP or FTPS client."""
clean_host = host.strip()
clean_user = user.strip() if user else ""
clean_pass = password.strip() if password else ""
if tls:
ftp = ftplib.FTP_TLS(timeout=timeout)
else:
ftp = ftplib.FTP(timeout=timeout)
ftp.connect(host=host, port=port, timeout=timeout)
ftp.login(user=user or "anonymous", passwd=password or "")
ftp.encoding = "utf-8"
ftp.connect(host=clean_host, port=int(port), timeout=timeout)
if tls and isinstance(ftp, ftplib.FTP_TLS):
ftp.auth()
ftp.login(user=clean_user or "anonymous", passwd=clean_pass)
ftp.prot_p() # Secure data connection
else:
ftp.login(user=clean_user or "anonymous", passwd=clean_pass)
# Force passive mode (standard for firewalls / NAT)
ftp.set_pasv(True)
return ftp
async def test_connection(
@@ -137,39 +147,72 @@ class FTPManager:
password: str = "",
path: str = "/",
tls: bool = False,
timeout: int = 10,
timeout: int = 12,
) -> Tuple[bool, str]:
"""Tests FTP credentials and verifies access to the target remote directory."""
if not host or not host.strip():
return False, "آدرس هاست (Host) FTP مشخص نشده است."
def _test():
ftp = None
try:
ftp = self._create_ftp_client(host.strip(), int(port), user.strip(), password, tls, timeout)
# Check root PWD
init_pwd = ftp.pwd()
# Test CWD to target path if specified
target_path = path.strip() if path else "/"
if target_path and target_path != "/":
try:
ftp.cwd(target_path)
except Exception as e:
pwd = ftp.pwd()
curr_pwd = ftp.pwd() if ftp else "/"
try:
ftp.quit()
return False, f"اتصال به FTP برقرار شد، اما مسیر ریموت «{target_path}» یافت نشد (مسیر فعلی: {pwd}): {e}"
except Exception:
pass
return False, f"اتصال به سرور برقرار شد، اما مسیر ریموت «{target_path}» یافت نشد (مسیر فعلی: {curr_pwd}): {e}"
pwd = ftp.pwd()
final_pwd = ftp.pwd()
# Test directory listing
item_count = 0
try:
listing = ftp.nlst()
count = len(listing)
item_count = len(listing)
except Exception:
count = 0
try:
lines = []
ftp.dir(lines.append)
item_count = len(lines)
except Exception:
item_count = 0
try:
ftp.quit()
return True, f"اتصال با موفقیت برقرار شد. مسیر فعلی: <code>{pwd}</code> (تعداد آیتم‌ها: {count})"
except (socket.gaierror, socket.timeout) as e:
return False, f"خطای شبکه / نامعتبر بودن آدرس سرور ({host}:{port}): {e}"
except Exception:
pass
tls_label = " (FTPS/TLS امن)" if tls else " (FTP معمولی)"
return True, f"اتصال با موفقیت برقرار شد{tls_label} | مسیر: <code>{final_pwd}</code> | تعداد فایل‌ها و پوشه‌ها: {item_count}"
except socket.gaierror as e:
return False, f"نام دامنه/هاست سرور یافت نشد ({host}): {e}"
except (socket.timeout, TimeoutError) as e:
return False, f"مهلت زمانی اتصال به سرور به پایان رسید (Timeout روی پورت {port}): {e}"
except ConnectionRefusedError as e:
return False, f"اتصال توسط سرور رد شد (پورت {port} بسته است یا FTP روی آن فعال نیست): {e}"
except ftplib.error_perm as e:
return False, f"خطای احراز هویت / دسترسی FTP: {e}"
return False, f"خطای نام کاربری یا رمز عبور (دسترسی نامعتبر): {e}"
except Exception as e:
return False, f"خطا در برقراری ارتباط با FTP: {e}"
finally:
if ftp:
try:
ftp.close()
except Exception:
pass
return await asyncio.to_thread(_test)
File diff suppressed because one or more lines are too long