AI Update: تست اف تی پی نتیجه رو درست نمیگه
This commit is contained in:
@@ -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
@@ -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:
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user