dangthr commited on
Commit
4ea9e2d
·
verified ·
1 Parent(s): d09529f

Update remote_uploader.py

Browse files
Files changed (1) hide show
  1. remote_uploader.py +44 -20
remote_uploader.py CHANGED
@@ -7,7 +7,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')
@@ -21,22 +20,25 @@ class WebSocketFileUploader:
21
 
22
  async def connect_and_upload(self, upload_dir):
23
  """连接到 WebSocket 服务器并上传文件"""
24
-
25
- # --- 修复点: 统一将 URL 转换为小写,以处理类似 "HTTPS" 这样的异常情况 ---
26
- normalized_server_url = self.server_url.lower()
27
-
28
- # 使用转换后的 URL 进行协议替换
29
- ws_url = normalized_server_url.replace('https://', 'wss://').replace('http://', 'ws://').rstrip('/')
30
  ws_url += f'/ws/upload/{self.space_id}?token={self.api_key}'
31
-
32
  logger.info(f"正在连接到 WebSocket: {ws_url}")
33
 
34
  try:
35
- # 增加连接超时以更快地失败
36
- async with websockets.connect(ws_url, open_timeout=10, ping_interval=20, ping_timeout=60) as websocket:
37
  logger.info("WebSocket 连接成功")
38
 
39
- # 等待服务器的认证成功响应
 
 
 
 
 
 
 
 
40
  response = await websocket.recv()
41
  auth_response = json.loads(response)
42
 
@@ -45,19 +47,21 @@ class WebSocketFileUploader:
45
  return await self._upload_files(websocket, upload_dir)
46
  else:
47
  logger.error(f"认证失败: {auth_response.get('message', '未知错误')}")
48
- logger.info("回退到 HTTP API 上传...")
49
- return self._fallback_http_upload(upload_dir)
50
 
51
  except Exception as e:
52
  logger.error(f"WebSocket 连接失败: {e}")
 
53
  logger.info("回退到 HTTP API 上传...")
54
  return self._fallback_http_upload(upload_dir)
55
 
56
  async def _upload_files(self, websocket, upload_dir):
 
57
  if not os.path.exists(upload_dir):
58
  logger.error(f"目录不存在: {upload_dir}")
59
  return False
60
 
 
61
  all_files = []
62
  for root, dirs, files in os.walk(upload_dir):
63
  for file in files:
@@ -83,6 +87,7 @@ class WebSocketFileUploader:
83
  failed_count += 1
84
  logger.error(f"❌ 文件 '{os.path.basename(file_path)}' 上传失败")
85
 
 
86
  await asyncio.sleep(0.5)
87
 
88
  except Exception as e:
@@ -93,14 +98,17 @@ class WebSocketFileUploader:
93
  return success_count > 0
94
 
95
  async def _upload_single_file(self, websocket, file_path):
 
96
  try:
97
  filename = os.path.basename(file_path)
98
  logger.info(f"正在上传文件: {filename}")
99
 
 
100
  with open(file_path, 'rb') as f:
101
  file_content = f.read()
102
  file_b64 = base64.b64encode(file_content).decode('utf-8')
103
 
 
104
  upload_msg = {
105
  "type": "file_upload",
106
  "filename": filename,
@@ -108,8 +116,10 @@ class WebSocketFileUploader:
108
  "space_id": self.space_id
109
  }
110
 
 
111
  await websocket.send(json.dumps(upload_msg))
112
 
 
113
  response = await websocket.recv()
114
  result = json.loads(response)
115
 
@@ -124,17 +134,25 @@ class WebSocketFileUploader:
124
  return False
125
 
126
  def _fallback_http_upload(self, upload_dir):
 
127
  logger.info("使用 HTTP API 回退方案上传文件...")
128
 
129
  if not os.path.exists(upload_dir):
130
  logger.error(f"目录不存在: {upload_dir}")
131
  return False
132
 
 
133
  upload_url = f"{self.server_url.rstrip('/')}/api/remote_upload"
134
 
135
- headers = {'X-API-Key': self.api_key}
136
- data = {'space_id': self.space_id}
 
 
 
 
 
137
 
 
138
  all_files = []
139
  for root, dirs, files in os.walk(upload_dir):
140
  for file in files:
@@ -157,14 +175,18 @@ class WebSocketFileUploader:
157
  logger.info(f"正在上传文件: {filename}")
158
 
159
  with open(file_path, 'rb') as f:
160
- files = {'file': (filename, f)}
161
- response = requests.post(upload_url, headers=headers, data=data, files=files, timeout=60)
 
 
 
 
162
 
163
  if response.status_code == 200:
164
  logger.info(f"✅ 文件 '{filename}' 上传成功!")
165
  success_count += 1
166
  else:
167
- logger.error(f"❌ 上传失败: HTTP {response.status_code} - {response.text}")
168
  failed_count += 1
169
 
170
  time.sleep(0.5)
@@ -177,6 +199,7 @@ class WebSocketFileUploader:
177
  return success_count > 0
178
 
179
  async def upload_directory_websocket(upload_dir, server_url, api_key, space_id):
 
180
  logger.info(f"🔍 开始扫描目录: {upload_dir}")
181
  logger.info(f"📡 服务器地址: {server_url}")
182
  logger.info(f"🔑 Space ID: {space_id}")
@@ -196,9 +219,10 @@ if __name__ == "__main__":
196
  parser = argparse.ArgumentParser(description="WebSocket 文件上传器 - 扫描并上传指定文件夹中的所有文件")
197
  parser.add_argument("api_key", help="您的 API 密钥")
198
  parser.add_argument("space_id", help="Space ID")
199
- parser.add_argument("--server", default="http://127.0.0.1:5001", help="服务器的 URL 地址 (例如: http://127.0.0.1:5001)")
200
  parser.add_argument("--upload-dir", default="output", help="要上传的目录 (默认: output)")
201
 
202
  args = parser.parse_args()
203
 
204
- asyncio.run(upload_directory_websocket(args.upload_dir, args.server, args.api_key, args.space_id))
 
 
7
  import base64
8
  import logging
9
  import sys
 
10
 
11
  # 配置日志
12
  logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
 
20
 
21
  async def connect_and_upload(self, upload_dir):
22
  """连接到 WebSocket 服务器并上传文件"""
23
+ # 将 HTTP URL 转换为 WebSocket URL
24
+ ws_url = self.server_url.replace('http://', 'ws://').replace('https://', 'wss://').rstrip('/')
 
 
 
 
25
  ws_url += f'/ws/upload/{self.space_id}?token={self.api_key}'
26
+
27
  logger.info(f"正在连接到 WebSocket: {ws_url}")
28
 
29
  try:
30
+ async with websockets.connect(ws_url, ping_interval=20, ping_timeout=60) as websocket:
 
31
  logger.info("WebSocket 连接成功")
32
 
33
+ # 发送认证信息
34
+ auth_msg = {
35
+ "type": "auth",
36
+ "api_key": self.api_key,
37
+ "space_id": self.space_id
38
+ }
39
+ await websocket.send(json.dumps(auth_msg))
40
+
41
+ # 等待认证响应
42
  response = await websocket.recv()
43
  auth_response = json.loads(response)
44
 
 
47
  return await self._upload_files(websocket, upload_dir)
48
  else:
49
  logger.error(f"认证失败: {auth_response.get('message', '未知错误')}")
50
+ return False
 
51
 
52
  except Exception as e:
53
  logger.error(f"WebSocket 连接失败: {e}")
54
+ # 如果 WebSocket 失败,回退到 HTTP API
55
  logger.info("回退到 HTTP API 上传...")
56
  return self._fallback_http_upload(upload_dir)
57
 
58
  async def _upload_files(self, websocket, upload_dir):
59
+ """通过 WebSocket 上传目录中的所有文件"""
60
  if not os.path.exists(upload_dir):
61
  logger.error(f"目录不存在: {upload_dir}")
62
  return False
63
 
64
+ # 获取所有文件
65
  all_files = []
66
  for root, dirs, files in os.walk(upload_dir):
67
  for file in files:
 
87
  failed_count += 1
88
  logger.error(f"❌ 文件 '{os.path.basename(file_path)}' 上传失败")
89
 
90
+ # 稍微延迟一下
91
  await asyncio.sleep(0.5)
92
 
93
  except Exception as e:
 
98
  return success_count > 0
99
 
100
  async def _upload_single_file(self, websocket, file_path):
101
+ """上传单个文件通过 WebSocket"""
102
  try:
103
  filename = os.path.basename(file_path)
104
  logger.info(f"正在上传文件: {filename}")
105
 
106
+ # 读取文件内容并编码为 base64
107
  with open(file_path, 'rb') as f:
108
  file_content = f.read()
109
  file_b64 = base64.b64encode(file_content).decode('utf-8')
110
 
111
+ # 构建上传消息
112
  upload_msg = {
113
  "type": "file_upload",
114
  "filename": filename,
 
116
  "space_id": self.space_id
117
  }
118
 
119
+ # 发送文件
120
  await websocket.send(json.dumps(upload_msg))
121
 
122
+ # 等待响应
123
  response = await websocket.recv()
124
  result = json.loads(response)
125
 
 
134
  return False
135
 
136
  def _fallback_http_upload(self, upload_dir):
137
+ """HTTP API 回退方案"""
138
  logger.info("使用 HTTP API 回退方案上传文件...")
139
 
140
  if not os.path.exists(upload_dir):
141
  logger.error(f"目录不存在: {upload_dir}")
142
  return False
143
 
144
+ # 构建完整的 API 端点 URL
145
  upload_url = f"{self.server_url.rstrip('/')}/api/remote_upload"
146
 
147
+ # 准备请求头
148
+ headers = {
149
+ 'X-API-Key': self.api_key
150
+ }
151
+ data = {
152
+ 'space_id': self.space_id
153
+ }
154
 
155
+ # 获取所有文件
156
  all_files = []
157
  for root, dirs, files in os.walk(upload_dir):
158
  for file in files:
 
175
  logger.info(f"正在上传文件: {filename}")
176
 
177
  with open(file_path, 'rb') as f:
178
+ files = {
179
+ 'file': (filename, f)
180
+ }
181
+
182
+ # 发送 POST 请求
183
+ response = requests.post(upload_url, headers=headers, data=data, files=files, timeout=30)
184
 
185
  if response.status_code == 200:
186
  logger.info(f"✅ 文件 '{filename}' 上传成功!")
187
  success_count += 1
188
  else:
189
+ logger.error(f"❌ 上传失败: HTTP {response.status_code}")
190
  failed_count += 1
191
 
192
  time.sleep(0.5)
 
199
  return success_count > 0
200
 
201
  async def upload_directory_websocket(upload_dir, server_url, api_key, space_id):
202
+ """使用 WebSocket 方式上传目录中的所有文件"""
203
  logger.info(f"🔍 开始扫描目录: {upload_dir}")
204
  logger.info(f"📡 服务器地址: {server_url}")
205
  logger.info(f"🔑 Space ID: {space_id}")
 
219
  parser = argparse.ArgumentParser(description="WebSocket 文件上传器 - 扫描并上传指定文件夹中的所有文件")
220
  parser.add_argument("api_key", help="您的 API 密钥")
221
  parser.add_argument("space_id", help="Space ID")
222
+ parser.add_argument("--server", default="https://gkbtyo-rqvays-5001.preview.cloudstudio.work", help="服务器的 URL 地址")
223
  parser.add_argument("--upload-dir", default="output", help="要上传的目录 (默认: output)")
224
 
225
  args = parser.parse_args()
226
 
227
+ # 运行异步上传
228
+ asyncio.run(upload_directory_websocket(args.upload_dir, args.server, args.api_key, args.space_id))