qwen_agent/webdav_server.py
2025-11-08 00:48:01 +08:00

182 lines
5.1 KiB
Python

#!/usr/bin/env python3
"""
WebDAV 服务器模块
提供基于 WsgiDAV 的文件管理服务
"""
import os
from pathlib import Path
from wsgidav.wsgidav_app import WsgiDAVApp
from wsgidav.fs_dav_provider import FilesystemProvider
from wsgidav.http_authenticator import HTTPAuthenticator
class SimpleDomainController:
"""简单域控制器,支持固定用户名密码认证"""
def __init__(self, wsgidav_app, config):
# 简单的用户名密码配置
self.users = {
"admin": "admin123", # 用户名: admin, 密码: admin123
"webdav": "webdav123", # 用户名: webdav, 密码: webdav123
}
def get_domain_realm(self, path_info, environ):
return "WebDAV"
def require_authentication(self, realm, environ):
return False # 暂时不强制认证,兼容性更好
def is_authenticated_user(self, realm, user_name, environ):
return True # 允许任何用户名通过
def auth_user(self, realm, user_name, password, environ):
# 如果用户名为空,允许通过(匿名访问)
if not user_name:
return True
# 检查用户名密码
return self.users.get(user_name) == password
def supports_http_digest_auth(self):
return True
def is_share_anonymous(self, share):
return True # 允许匿名访问
def create_webdav_app():
"""
创建 WebDAV 应用
Returns:
WsgiDAVApp: 配置好的 WebDAV 应用实例
"""
# 确保projects目录存在
projects_dir = Path("projects")
projects_dir.mkdir(exist_ok=True)
# 配置 WebDAV
config = {
"host": "0.0.0.0",
"port": 8001,
"provider_mapping": {
"/": FilesystemProvider(str(projects_dir))
},
"http_authenticator": {
"domain_controller": "webdav_server.SimpleDomainController",
"accept_basic": True,
"accept_digest": True,
"default_to_digest": False,
},
"verbose": 1, # 日志级别
"dir_browser": {
"enable": True,
"response_trailer": True,
"davmount_path": "/webdav",
"ms_mount_path": "/webdav",
}
}
# 创建 WsgiDAV 应用
app = WsgiDAVApp(config)
return app
class ProjectWebDAVProvider(FilesystemProvider):
"""
自定义的 WebDAV 提供器,专门用于管理 projects 目录
"""
def __init__(self, root_folder="projects"):
super().__init__(root_folder)
self.root_folder = Path(root_folder)
def get_file_info(self, path):
"""获取文件信息"""
full_path = self.root_folder / path.lstrip('/')
if not full_path.exists():
return None
stat = full_path.stat()
return {
"path": path,
"name": full_path.name,
"is_dir": full_path.is_dir(),
"size": stat.st_size if full_path.is_file() else 0,
"modified": stat.st_mtime,
"created": stat.st_ctime
}
def create_directory(self, path, **kwargs):
"""创建目录"""
full_path = self.root_folder / path.lstrip('/')
full_path.mkdir(parents=True, exist_ok=True)
return True
def delete_file(self, path):
"""删除文件"""
full_path = self.root_folder / path.lstrip('/')
if full_path.is_file():
full_path.unlink()
elif full_path.is_dir():
import shutil
shutil.rmtree(full_path)
return True
def move_file(self, src_path, dest_path):
"""移动文件"""
src_full = self.root_folder / src_path.lstrip('/')
dest_full = self.root_folder / dest_path.lstrip('/')
# 确保目标目录存在
dest_full.parent.mkdir(parents=True, exist_ok=True)
import shutil
shutil.move(str(src_full), str(dest_full))
return True
def copy_file(self, src_path, dest_path):
"""复制文件"""
src_full = self.root_folder / src_path.lstrip('/')
dest_full = self.root_folder / dest_path.lstrip('/')
# 确保目标目录存在
dest_full.parent.mkdir(parents=True, exist_ok=True)
import shutil
if src_full.is_file():
shutil.copy2(str(src_full), str(dest_full))
elif src_full.is_dir():
shutil.copytree(str(src_full), str(dest_full))
return True
def start_webdav_server(host="0.0.0.0", port=8090):
"""
启动独立的 WebDAV 服务器
Args:
host: 主机地址
port: 端口号
"""
app = create_webdav_app()
# 修改配置,使用不同端口避免冲突
app.config["host"] = host
app.config["port"] = port
print(f"Starting WebDAV server on http://{host}:{port}/webdav")
print(f"Projects directory: {Path.cwd()}/projects")
# 启动服务器
from wsgidav.server.run_server import run_server
run_server(app)
if __name__ == "__main__":
start_webdav_server()