用AI开发软件:FTP管理工具(附完整代码)

在当今快速发展的技术世界中,人工智能(AI)正在改变我们开发软件的方式。无论是代码生成、问题调试,还是架构设计,AI工具都能为开发者提供强大的支持。今天,我们将探索如何利用AI开发一个简单的FTP(文件传输协议)工具,并附上完整的代码实现。技术栈
编程语言:Python
AI工具:DeepSeek(用于代码生成和问题排查)
核心库:
from pyftpdlib.authorizers import DummyAuthorizer
from pyftpdlib.handlers import FTPHandler
from pyftpdlib.servers import FTPServer当前功能

多IP地址自动检测
实时连接数统计
细粒度权限控制
操作日志记录
软件截图

完整代码(单文件)
代码完全根据个人习惯和喜好进行编写;大家可以根据代码中包含的各项注释进行阅读或修改。
import tkinter as tk
from tkinter import ttk, filedialog, messagebox, scrolledtext
from pyftpdlib.authorizers import DummyAuthorizer
from pyftpdlib.handlers import FTPHandler
from pyftpdlib.servers import FTPServer
import threading
import socket
import webbrowser
from typing import List

class FTPServerGUI:
def __init__(self, root):
self.root = root
self.server = None
self.connection_count = 0
self.setup_ui()
self.show_filtered_ips()
self.display_welcome_msg()

def setup_ui(self):
# 主窗口设置
self.root.title("FTP服务器 v1.0")
self.root.geometry("560x500")
self.root.minsize(560, 480)

# 配置网格布局权重
self.root.columnconfigure(0, weight=1)
self.root.columnconfigure(1, weight=1)
self.root.rowconfigure(4, weight=1) # 日志区域行

# 顶部信息栏
top_info = ttk.Frame(self.root)
top_info.grid(row=0, column=0, columnspan=2, padx=10, pady=5, sticky="ew")

# 当前连接数显示
self.conn_label = ttk.Label(top_info, text="当前连接: 0", foreground="green")
self.conn_label.pack(side="right", padx=10)

# IP地址显示
ttk.Label(top_info, text="服务器IP:").pack(side="left")
self.ip_label = ttk.Label(top_info, text="正在获取...", foreground="blue")
self.ip_label.pack(side="left", padx=5)

# 配置框架
config_frame = ttk.LabelFrame(self.root, text="服务器配置")
config_frame.grid(row=1, column=0, columnspan=2, padx=10, pady=5, sticky="ew")

# 输入字段布局
input_grid = ttk.Frame(config_frame)
input_grid.pack(fill="x", padx=5, pady=5)

# 端口配置
ttk.Label(input_grid, text="端口:").grid(row=0, column=0, padx=5, sticky="w")
self.port_entry = ttk.Entry(input_grid, width=8)
self.port_entry.grid(row=0, column=1, sticky="w")
self.port_entry.insert(0, "21")

# 用户配置
ttk.Label(input_grid, text="用户:").grid(row=0, column=2, padx=(15,5), sticky="w")
self.user_entry = ttk.Entry(input_grid, width=12)
self.user_entry.grid(row=0, column=3, sticky="w")
self.user_entry.insert(0, "user")

# 密码配置
ttk.Label(input_grid, text="密码:").grid(row=0, column=4, padx=(15,5), sticky="w")
self.pass_entry = ttk.Entry(input_grid, width=12, show="*")
self.pass_entry.grid(row=0, column=5, sticky="w")
self.pass_entry.insert(0, "123")

# 目录选择
dir_frame = ttk.Frame(config_frame)
dir_frame.pack(fill="x", padx=5, pady=5)
ttk.Button(dir_frame, text="选择FTP目录", command=self.select_directory).pack(side="left")
self.dir_label = ttk.Label(dir_frame, text="未选择目录", foreground="gray")
self.dir_label.pack(side="left", padx=10)

# 权限设置框架
perm_frame = ttk.LabelFrame(self.root, text="用户权限设置")
perm_frame.grid(row=2, column=0, columnspan=2, padx=10, pady=5, sticky="nsew")

# 三列布局
self.perm_vars = {
'e': tk.BooleanVar(value=True),
'l': tk.BooleanVar(value=True),
'r': tk.BooleanVar(value=True),
'a': tk.BooleanVar(),
'd': tk.BooleanVar(),
'f': tk.BooleanVar(),
'm': tk.BooleanVar(value=True),
'M': tk.BooleanVar(),
'w': tk.BooleanVar(value=True),
}

cols =
for i, col in enumerate(cols):
col.grid(row=0, column=i, sticky="nsew", padx=5)
perm_frame.columnconfigure(i, weight=1)

# 权限项分布
permissions = [
("上传文件 (w)", 'w', 0),
("下载文件 (r)", 'r', 0),
("删除文件 (d)", 'd', 0),
("查看列表 (l)", 'l', 1),
("切换目录 (e)", 'e', 1),
("创建目录 (m)", 'm', 1),
("修改权限 (M)", 'M', 2),
("重命名 (f)", 'f', 2),
("追加文件 (a)", 'a', 2)
]

for text, key, col_idx in permissions:
ttk.Checkbutton(cols, text=text, variable=self.perm_vars).pack(anchor="w", pady=2)

# 控制按钮
btn_frame = ttk.Frame(self.root)
btn_frame.grid(row=3, column=0, columnspan=2, pady=10)
self.start_btn = ttk.Button(btn_frame, text="启动服务器", command=self.toggle_server)
self.start_btn.pack(side="left", padx=5)

# 日志区域
log_frame = ttk.LabelFrame(self.root, text="服务器日志")
log_frame.grid(row=4, column=0, columnspan=2, padx=10, pady=5, sticky="nsew")
self.log_text = scrolledtext.ScrolledText(log_frame, wrap=tk.WORD, height=8)
self.log_text.pack(expand=True, fill="both")

# 博客链接
blog_link = ttk.Label(self.root, text="zneVue & AI", foreground="blue", cursor="hand2")
blog_link.grid(row=5, column=1, padx=10, pady=5, sticky="se")
blog_link.bind("<Button-1>", lambda e: webbrowser.open("https://www.52pojie.cn/home.php?mod=space&uid=2299786"))

# 布局权重配置
perm_frame.rowconfigure(0, weight=1)
log_frame.rowconfigure(0, weight=1)
log_frame.columnconfigure(0, weight=1)

def show_filtered_ips(self) -> List:
try:
ips = socket.gethostbyname_ex(socket.gethostname())
filtered_ips = [
ip for ip in ips
if ip != "127.0.0.1"
and not ip.startswith("169.254.")
]

self.ip_label.config(text=", ".join(filtered_ips) if filtered_ips else "未找到有效IP")
return filtered_ips
except Exception as e:
self.ip_label.config(text=f"获取IP失败: {str(e)}")
return

def is_valid_ip(self, ip: str) -> bool:
if ip.startswith("127.") or ip == "::1":
return False
if ip.startswith("169.254."): # APIPA地址
return False
if ip.startswith("172.17."): # Docker默认地址
return False
if ip.startswith("192.168.") or ip.startswith("10."): # 内网地址
return True # 保留显示内网地址
return True

def select_directory(self):
directory = filedialog.askdirectory()
if directory:
self.dir_label.config(text=directory, foreground="black")

def update_connection_count(self, delta: int):
"""线程安全更新连接数"""
self.connection_count += delta
self.root.after(0, self.conn_label.config,
{"text": f"当前连接: {self.connection_count}"})

def log_message(self, msg: str):
self.log_text.insert(tk.END, msg + "\n")
self.log_text.see(tk.END)

def thread_safe_log(self, msg: str):
self.root.after(0, self.log_message, msg)

def toggle_server(self):
if self.server is None:
self.start_server()
else:
self.stop_server()

def start_server(self):
port = int(self.port_entry.get())
user = self.user_entry.get()
password = self.pass_entry.get()
directory = self.dir_label.cget("text")

if not all() or directory == "未选择目录":
messagebox.showerror("错误", "请填写所有必填字段!")
return

perm = ''.join()
if not perm:
messagebox.showerror("错误", "请至少选择一个权限!")
return

class CustomHandler(FTPHandler):
gui = self # 引用GUI实例

def on_connect(self):
self.gui.update_connection_count(1)
self.gui.thread_safe_log(f" {self.remote_ip}:{self.remote_port} 已连接")

def on_disconnect(self):
self.gui.update_connection_count(-1)
self.gui.thread_safe_log(f" {self.remote_ip}:{self.remote_port} 断开连接")

def on_login(self, username):
self.gui.thread_safe_log(f" 用户 {username} 登录成功")

def on_login_failed(self, username, password):
self.gui.thread_safe_log(f" 登录失败 用户名: {username}")

try:
authorizer = DummyAuthorizer()
authorizer.add_user(user, password, directory, perm=perm)

handler = CustomHandler
handler.authorizer = authorizer

self.server = FTPServer(("0.0.0.0", port), handler)
self.thread_safe_log(f" 服务已启动于 0.0.0.0:{port}")
self.thread_safe_log(f" 可用地址: {self.ip_label.cget('text')}")
self.start_btn.config(text="停止服务器")

server_thread = threading.Thread(target=self.server.serve_forever)
server_thread.daemon = True
server_thread.start()
except Exception as e:
self.thread_safe_log(f" 启动失败: {str(e)}")

def stop_server(self):
if self.server:
self.server.close_all()
self.server = None
self.connection_count = 0
self.conn_label.config(text="当前连接: 0")
self.thread_safe_log(" 服务器已停止")
self.start_btn.config(text="启动服务器")

def display_welcome_msg(self):
"""显示欢迎信息"""
welcome_text = """=== FTP服务器 v1.0 ===
【使用指南】
1. 选择FTP目录 -> 设置用户权限 -> 启动服务
2. 客户端连接地址显示在顶部IP栏
3. 日志区域实时显示连接状态
【常用命令帮助】
USER - 登录认证
PASS - 输入密码
LIST - 列出文件列表
RETR - 下载文件
STOR - 上传文件
QUIT/EXIT - 断开连接
当前版本功能:
• 多IP地址自动检测
• 实时连接数统计
• 细粒度权限控制
• 操作日志记录
"""
self.log_text.configure(state='normal')
self.log_text.delete(1.0, tk.END)
self.log_text.insert(tk.END, welcome_text)

# 设置文本样式
self.log_text.tag_configure("title", foreground="#2E75B6", font=('微软雅黑', 10, 'bold'))
self.log_text.tag_add("title", "1.0", "1.19")

if __name__ == "__main__":
root = tk.Tk()
app = FTPServerGUI(root)
root.mainloop()
想使用但是本地没有python的朋友可以直接食用。(代码经过 pystaller 本地打包,没有任何病毒,请放心使用)

https://zheyue.lanzoue.com/iogdb2rsuppi

分类