dangthr commited on
Commit
8000595
·
verified ·
1 Parent(s): fd75740

Update remote_uploader.py

Browse files
Files changed (1) hide show
  1. remote_uploader.py +46 -215
remote_uploader.py CHANGED
@@ -1,233 +1,64 @@
1
  import requests
2
  import argparse
3
  import os
4
- import asyncio
5
- import websockets
6
- import json
7
- import base64
8
- import logging
9
- import sys
10
- import time
11
 
12
- # 配置日志
13
- logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
14
- logger = logging.getLogger(__name__)
15
 
16
- class WebSocketFileUploader:
17
- def __init__(self, server_url, api_key, space_id):
18
- self.server_url = server_url
19
- self.api_key = api_key
20
- self.space_id = space_id
21
-
22
- async def connect_and_upload(self, upload_dir):
23
- """连接到 WebSocket 服务器并上传文件"""
24
- # 将 HTTP URL 转换为 WebSocket URL
25
- # 清理URL,移除可能的换行符、空格和反引号
26
- clean_server_url = self.server_url.strip().replace('`', '') # 移除反引号
27
- ws_url = clean_server_url.replace('http://', 'ws://').replace('https://', 'wss://').rstrip('/')
28
- ws_url += f'/ws/upload/{self.space_id}?token={self.api_key}'
29
-
30
- logger.info(f"正在连接到 WebSocket: {ws_url}")
31
-
32
- try:
33
- async with websockets.connect(ws_url, ping_interval=20, ping_timeout=60) as websocket:
34
- logger.info("WebSocket 连接成功")
35
-
36
- # 发送认证信息
37
- auth_msg = {
38
- "type": "auth",
39
- "api_key": self.api_key,
40
- "space_id": self.space_id
41
- }
42
- await websocket.send(json.dumps(auth_msg))
43
-
44
- # 等待认证响应
45
- response = await websocket.recv()
46
- auth_response = json.loads(response)
47
-
48
- if auth_response.get("type") == "auth_success":
49
- logger.info("认证成功,开始上传文件...")
50
- return await self._upload_files(websocket, upload_dir)
51
- else:
52
- logger.error(f"认证失败: {auth_response.get('message', '未知错误')}")
53
- return False
54
-
55
- except Exception as e:
56
- logger.error(f"WebSocket 连接失败: {e}")
57
- # 如果 WebSocket 失败,回退到 HTTP API
58
- logger.info("回退到 HTTP API 上传...")
59
- return self._fallback_http_upload(upload_dir)
60
 
61
- async def _upload_files(self, websocket, upload_dir):
62
- """通过 WebSocket 上传目录中的所有文件"""
63
- if not os.path.exists(upload_dir):
64
- logger.error(f"目录不存在: {upload_dir}")
65
- return False
66
-
67
- # 获取所有文件
68
- all_files = []
69
- for root, dirs, files in os.walk(upload_dir):
70
- for file in files:
71
- file_path = os.path.join(root, file)
72
- if os.path.isfile(file_path):
73
- all_files.append(file_path)
74
-
75
- if not all_files:
76
- logger.info("📁 目录中没有找到任何文件")
77
- return True
78
-
79
- logger.info(f"📁 找到 {len(all_files)} 个文件,开始上传...")
80
-
81
- success_count = 0
82
- failed_count = 0
83
-
84
- for file_path in all_files:
85
- try:
86
- if await self._upload_single_file(websocket, file_path):
87
- success_count += 1
88
- logger.info(f"✅ 文件 '{os.path.basename(file_path)}' 上传成功!")
89
- else:
90
- failed_count += 1
91
- logger.error(f"❌ 文件 '{os.path.basename(file_path)}' 上传失败")
92
-
93
- # 稍微延迟一下
94
- await asyncio.sleep(0.5)
95
-
96
- except Exception as e:
97
- logger.error(f"上传文件 {file_path} 时发生异常: {e}")
98
- failed_count += 1
99
-
100
- logger.info(f"📊 上传完成! 成功: {success_count}, 失败: {failed_count}")
101
- return success_count > 0
102
 
103
- async def _upload_single_file(self, websocket, file_path):
104
- """上传单个文件通过 WebSocket"""
105
- try:
106
- filename = os.path.basename(file_path)
107
- logger.info(f"正在上传文件: {filename}")
108
-
109
- # 读取文件内容并编码为 base64
110
- with open(file_path, 'rb') as f:
111
- file_content = f.read()
112
- file_b64 = base64.b64encode(file_content).decode('utf-8')
113
-
114
- # 构建上传消息
115
- upload_msg = {
116
- "type": "file_upload",
117
- "filename": filename,
118
- "content": file_b64,
119
- "space_id": self.space_id
120
  }
121
 
122
- # 发送文件
123
- await websocket.send(json.dumps(upload_msg))
124
 
125
- # 等待响应
126
- response = await websocket.recv()
127
- result = json.loads(response)
128
 
129
- if result.get("type") == "upload_success":
130
- return True
131
- else:
132
- logger.error(f"上传失败: {result.get('message', '未知错误')}")
133
- return False
134
-
135
- except Exception as e:
136
- logger.error(f"上传文件 {file_path} 时出错: {e}")
137
- return False
138
-
139
- def _fallback_http_upload(self, upload_dir):
140
- """HTTP API 回退方案"""
141
- logger.info("使用 HTTP API 回退方案上传文件...")
142
-
143
- if not os.path.exists(upload_dir):
144
- logger.error(f"目录不存在: {upload_dir}")
145
- return False
146
-
147
- # 构建完整的 API 端点 URL
148
- # 清理URL,移除可能的换行符、空格和反引号
149
- clean_server_url = self.server_url.strip().replace('`', '') # 移除反引号
150
- upload_url = f"{clean_server_url.rstrip('/')}/api/remote_upload"
151
-
152
- # 准备请求头
153
- headers = {
154
- 'X-API-Key': self.api_key
155
- }
156
- data = {
157
- 'space_id': self.space_id
158
- }
159
-
160
- # 获取所有文件
161
- all_files = []
162
- for root, dirs, files in os.walk(upload_dir):
163
- for file in files:
164
- file_path = os.path.join(root, file)
165
- if os.path.isfile(file_path):
166
- all_files.append(file_path)
167
-
168
- if not all_files:
169
- logger.info("📁 目录中没有找到任何文件")
170
- return True
171
-
172
- logger.info(f"📁 找到 {len(all_files)} 个文件,开始HTTP上传...")
173
-
174
- success_count = 0
175
- failed_count = 0
176
-
177
- for file_path in all_files:
178
  try:
179
- filename = os.path.basename(file_path)
180
- logger.info(f"正在上传文件: {filename}")
181
-
182
- with open(file_path, 'rb') as f:
183
- files = {
184
- 'file': (filename, f)
185
- }
186
-
187
- # 发送 POST 请求
188
- response = requests.post(upload_url, headers=headers, data=data, files=files, timeout=30)
189
-
190
- if response.status_code == 200:
191
- logger.info(f"✅ 文件 '{filename}' 上传成功!")
192
- success_count += 1
193
- else:
194
- logger.error(f"❌ 上传失败: HTTP {response.status_code}")
195
- failed_count += 1
196
-
197
- time.sleep(0.5)
198
-
199
- except Exception as e:
200
- logger.error(f"上传文件 {file_path} 时发生异常: {e}")
201
- failed_count += 1
202
-
203
- logger.info(f"📊 上传完成! 成功: {success_count}, 失败: {failed_count}")
204
- return success_count > 0
205
 
206
- async def upload_directory_websocket(upload_dir, server_url, api_key, space_id):
207
- """使用 WebSocket 方式上传目录中的所有文件"""
208
- logger.info(f"🔍 开始扫描目录: {upload_dir}")
209
- logger.info(f"📡 服务器地址: {server_url}")
210
- logger.info(f"🔑 Space ID: {space_id}")
211
- logger.info("-" * 50)
212
-
213
- uploader = WebSocketFileUploader(server_url, api_key, space_id)
214
- success = await uploader.connect_and_upload(upload_dir)
215
-
216
- if success:
217
- logger.info("🎉 文件已成功上传到您的网盘!")
218
- else:
219
- logger.error("❌ 文件上传失败")
220
-
221
- return success
222
 
223
  if __name__ == "__main__":
224
- parser = argparse.ArgumentParser(description="WebSocket 文件上传器 - 扫描并上传指定文件夹中的所有文件")
225
- parser.add_argument("api_key", help="您的 API 密钥")
226
- parser.add_argument("space_id", help="Space ID")
227
- parser.add_argument("--server", default="https://gkbtyo-rqvays-5001.preview.cloudstudio.work", help="服务器的 URL 地址")
228
- parser.add_argument("--upload-dir", default="output", help="要上传的目录 (默认: output)")
229
 
230
  args = parser.parse_args()
231
 
232
- # 运行异步上传
233
- asyncio.run(upload_directory_websocket(args.upload_dir, args.server, args.api_key, args.space_id))
 
1
  import requests
2
  import argparse
3
  import os
 
 
 
 
 
 
 
4
 
5
+ def upload_file(server_url, api_key, space_id, file_path):
6
+ """
7
+ 通过 API 将文件上传到服务器。
8
 
9
+ :param server_url: Flask 服务器的 URL (例如 http://127.0.0.1:5001)
10
+ :param api_key: 您的用户 API 密钥
11
+ :param space_id: 与此次上传关联的 Space ID
12
+ :param file_path: 要上传的文件的本地路径
13
+ """
14
+ if not os.path.exists(file_path):
15
+ print(f"错误: 文件未找到 -> {file_path}")
16
+ return
17
+
18
+ # 构建完整的 API 端点 URL
19
+ upload_url = f"{server_url.rstrip('/')}/api/remote_upload"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
 
21
+ # 准备请求头和数据
22
+ headers = {
23
+ 'X-API-Key': api_key
24
+ }
25
+ data = {
26
+ 'space_id': space_id
27
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
 
29
+ # 读取文件内容
30
+ try:
31
+ with open(file_path, 'rb') as f:
32
+ files = {
33
+ 'file': (os.path.basename(file_path), f)
 
 
 
 
 
 
 
 
 
 
 
 
34
  }
35
 
36
+ print(f"正在上传 '{os.path.basename(file_path)}' 到 {upload_url}...")
 
37
 
38
+ # 发送 POST 请求
39
+ response = requests.post(upload_url, headers=headers, data=data, files=files)
 
40
 
41
+ # 打印服务器响应
42
+ print(f"\n服务器响应 ({response.status_code}):")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  try:
44
+ print(response.json())
45
+ except requests.exceptions.JSONDecodeError:
46
+ print(response.text)
47
+
48
+ except IOError as e:
49
+ print(f"读取文件时出错: {e}")
50
+ except requests.exceptions.RequestException as e:
51
+ print(f"请求时出错: {e}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
 
54
  if __name__ == "__main__":
55
+ parser = argparse.ArgumentParser(description="远程上传文件到您的个人网盘。")
56
+ parser.add_argument("file_path", help="要上传的文件的路径。")
57
+ parser.add_argument("--key", required=True, help="您的 API 密钥。")
58
+ parser.add_argument("--space", required=True, help="与此次上传关联的 Space ID。")
59
+ parser.add_argument("--server", default="http://127.0.0.1:5001", help="服务器的 URL 地址。 (默认: http://127.0.0.1:5001)")
60
 
61
  args = parser.parse_args()
62
 
63
+ upload_file(args.server, args.key, args.space, args.file_path)
64
+