discuss00/webdav-ssh6
0
1import os2from flask import Flask3from webdav3.client import Client4import paramiko5import logging6from requests.auth import HTTPBasicAuth7 8# 配置日志9logging.basicConfig(level=logging.INFO)10 11# 从环境变量获取配置信息12WEBDAV_URL = os.getenv('WEBDAV_URL')13WEBDAV_USERNAME = os.getenv('WEBDAV_USERNAME')14WEBDAV_PASSWORD = os.getenv('WEBDAV_PASSWORD')15WEBDAV_PATH = os.getenv('WEBDAV_PATH')16 17SSH_HOST = os.getenv('SSH_HOST')18SSH_PORT = 2219SSH_USERNAME = os.getenv('SSH_USERNAME')20SSH_PASSWORD = os.getenv('SSH_PASSWORD')21SSH_PATH = os.getenv('SSH_PATH')22 23app = Flask(__name__)24 25def safe_download(webdav_client, remote_path, local_path):26 try:27 webdav_client.download(remote_path, local_path)28 except KeyError as e:29 if str(e) == "'content-length'":30 logging.warning(f"'content-length' missing for {remote_path}. Using alternative download method.")31 32 # 使用基本认证进行请求33 auth = HTTPBasicAuth(WEBDAV_USERNAME, WEBDAV_PASSWORD)34 response = webdav_client.session.get(webdav_client.get_url(remote_path), stream=True, auth=auth)35 36 if response.status_code != 200:37 logging.error(f"Failed to download {remote_path}. Status code: {response.status_code}")38 return39 40 with open(local_path, 'wb') as f:41 for chunk in response.iter_content(chunk_size=8192):42 if chunk:43 f.write(chunk)44 45 logging.info(f"Downloaded file size: {os.path.getsize(local_path)} bytes")46 else:47 raise48 49@app.route('/')50def transfer_images():51 options = {52 'webdav_hostname': WEBDAV_URL,53 'webdav_login': WEBDAV_USERNAME,54 'webdav_password': WEBDAV_PASSWORD55 }56 webdav_client = Client(options)57 58 # 创建SSH客户端59 ssh = paramiko.SSHClient()60 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())61 ssh.connect(SSH_HOST, port=SSH_PORT, username=SSH_USERNAME, password=SSH_PASSWORD)62 sftp = ssh.open_sftp()63 64 # 获取WebDAV中的文件列表65 files = webdav_client.list(WEBDAV_PATH)66 67 # 转移文件68 for file in files:69 if file.endswith('.jpg'):70 file_name = os.path.basename(file)71 remote_path = os.path.join(SSH_PATH, file_name)72 73 logging.info(f"Checking if file {file_name} exists on remote server...")74 75 try:76 sftp.stat(remote_path)77 logging.info(f"File {file_name} already exists. Skipping...")78 except FileNotFoundError:79 local_tmp_file = '/tmp/' + file_name80 safe_download(webdav_client, f"{WEBDAV_PATH}/{file_name}", local_tmp_file)81 if os.path.exists(local_tmp_file) and os.path.getsize(local_tmp_file) > 0:82 sftp.put(local_tmp_file, remote_path)83 logging.info(f"File {file_name} transferred with size: {os.path.getsize(local_tmp_file)} bytes")84 85 sftp.close()86 ssh.close()87 88 return "Transfer complete!"89 90if __name__ == "__main__":91 app.run(host='0.0.0.0', port=8080)