#!/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()