dangthr commited on
Commit
d00e188
·
verified ·
1 Parent(s): 28cf1dd

Update remote_uploader.py

Browse files
Files changed (1) hide show
  1. remote_uploader.py +193 -87
remote_uploader.py CHANGED
@@ -1,27 +1,150 @@
1
  import requests
2
  import argparse
3
  import os
4
- import time
 
 
 
 
 
5
 
6
- class FileUploader:
7
- def __init__(self, api_key, space_id):
8
- self.server_url = "https://gkbtyo-rqvays-5001.preview.cloudstudio.work"
 
 
 
 
9
  self.api_key = api_key
10
  self.space_id = space_id
11
 
12
- def upload_file(self, file_path):
13
- """上传单个文件"""
14
- if not os.path.exists(file_path):
15
- print(f"文件不存在: {file_path}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  return False
17
 
18
- filename = os.path.basename(file_path)
19
- print(f"正在上传文件: {filename}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
 
21
  # 构建完整的 API 端点 URL
22
  upload_url = f"{self.server_url.rstrip('/')}/api/remote_upload"
23
 
24
- # 准备请求头和数据
25
  headers = {
26
  'X-API-Key': self.api_key
27
  }
@@ -29,94 +152,77 @@ class FileUploader:
29
  'space_id': self.space_id
30
  }
31
 
32
- # 读取文件内容并上传
33
- try:
34
- with open(file_path, 'rb') as f:
35
- files = {
36
- 'file': (filename, f)
37
- }
38
-
39
- # 发送 POST 请求
40
- response = requests.post(upload_url, headers=headers, data=data, files=files)
 
 
 
 
 
 
 
 
 
 
 
 
41
 
42
- # 打印服务器响应
43
- print(f"服务器响应 ({response.status_code}):")
44
- try:
45
- result = response.json()
46
- print(result)
 
 
 
47
  if response.status_code == 200:
48
- print(f"✅ 文件 '{filename}' 上传成功!")
49
- return True
50
  else:
51
- print(f"❌ 上传失败: {result.get('error', '未知错误')}")
52
- return False
53
- except requests.exceptions.JSONDecodeError:
54
- print(response.text)
55
- return False
56
-
57
- except IOError as e:
58
- print(f"读取文件时出错: {e}")
59
- return False
60
- except requests.exceptions.RequestException as e:
61
- print(f"请求时出错: {e}")
62
- return False
63
-
64
- def upload_directory_once(upload_dir, api_key, space_id):
65
- """一次性扫描并上传目录中的所有文件"""
66
- if not os.path.exists(upload_dir):
67
- print(f"目录不存在: {upload_dir}")
68
- return
69
-
70
- print(f"🔍 开始扫描目录: {upload_dir}")
71
- print(f"🔑 Space ID: {space_id}")
72
- print("-" * 50)
73
-
74
- uploader = FileUploader(api_key, space_id)
75
-
76
- # 获取所有文件
77
- all_files = []
78
- for root, dirs, files in os.walk(upload_dir):
79
- for file in files:
80
- file_path = os.path.join(root, file)
81
- if os.path.isfile(file_path):
82
- all_files.append(file_path)
83
-
84
- if not all_files:
85
- print("📁 目录中没有找到任何文件")
86
- return
87
-
88
- print(f"📁 找到 {len(all_files)} 个文件,开始上传...")
89
-
90
- success_count = 0
91
- failed_count = 0
92
-
93
- for file_path in all_files:
94
- try:
95
- if uploader.upload_file(file_path):
96
- success_count += 1
97
- else:
98
  failed_count += 1
99
- # 稍微延迟一下,避免服务器压力过大
100
- time.sleep(0.5)
101
- except Exception as e:
102
- print(f"上传文件 {file_path} 时发生异常: {e}")
103
- failed_count += 1
 
 
 
 
 
104
 
105
- print("-" * 50)
106
- print(f"📊 上传完成! 成功: {success_count}, 失败: {failed_count}")
107
 
108
- if success_count > 0:
109
- print("🎉 文件已成功上传到您的网盘!")
 
 
110
 
111
- return success_count, failed_count
112
 
113
  if __name__ == "__main__":
114
- parser = argparse.ArgumentParser(description="一次性文件上传器 - 扫描并上传指定文件夹中的所有文件")
115
  parser.add_argument("api_key", help="您的 API 密钥")
116
  parser.add_argument("space_id", help="Space ID")
 
117
  parser.add_argument("--upload-dir", default="output", help="要上传的目录 (默认: output)")
118
 
119
  args = parser.parse_args()
120
 
121
- # 开始一次性上传
122
- upload_directory_once(args.upload_dir, args.api_key, args.space_id)
 
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
 
11
+ # 配置日志
12
+ logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
13
+ logger = logging.getLogger(__name__)
14
+
15
+ class WebSocketFileUploader:
16
+ def __init__(self, server_url, api_key, space_id):
17
+ self.server_url = server_url
18
  self.api_key = api_key
19
  self.space_id = space_id
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
+
45
+ if auth_response.get("type") == "auth_success":
46
+ logger.info("认证成功,开始上传文件...")
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:
68
+ file_path = os.path.join(root, file)
69
+ if os.path.isfile(file_path):
70
+ all_files.append(file_path)
71
+
72
+ if not all_files:
73
+ logger.info("📁 目录中没有找到任何文件")
74
+ return True
75
+
76
+ logger.info(f"📁 找到 {len(all_files)} 个文件,开始上传...")
77
+
78
+ success_count = 0
79
+ failed_count = 0
80
+
81
+ for file_path in all_files:
82
+ try:
83
+ if await self._upload_single_file(websocket, file_path):
84
+ success_count += 1
85
+ logger.info(f"✅ 文件 '{os.path.basename(file_path)}' 上传成功!")
86
+ else:
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:
94
+ logger.error(f"上传文件 {file_path} 时发生异常: {e}")
95
+ failed_count += 1
96
+
97
+ logger.info(f"📊 上传完成! 成功: {success_count}, 失败: {failed_count}")
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,
115
+ "content": file_b64,
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
+
126
+ if result.get("type") == "upload_success":
127
+ return True
128
+ else:
129
+ logger.error(f"上传失败: {result.get('message', '未知错误')}")
130
+ return False
131
+
132
+ except Exception as e:
133
+ logger.error(f"上传文件 {file_path} 时出错: {e}")
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
  }
 
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:
159
+ file_path = os.path.join(root, file)
160
+ if os.path.isfile(file_path):
161
+ all_files.append(file_path)
162
+
163
+ if not all_files:
164
+ logger.info("📁 目录中没有找到任何文件")
165
+ return True
166
+
167
+ logger.info(f"📁 找到 {len(all_files)} 个文件,开始HTTP上传...")
168
+
169
+ success_count = 0
170
+ failed_count = 0
171
+
172
+ for file_path in all_files:
173
+ try:
174
+ filename = os.path.basename(file_path)
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)
193
+
194
+ except Exception as e:
195
+ logger.error(f"上传文件 {file_path} 时发生异常: {e}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
196
  failed_count += 1
197
+
198
+ logger.info(f"📊 上传完成! 成功: {success_count}, 失败: {failed_count}")
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}")
206
+ logger.info("-" * 50)
207
 
208
+ uploader = WebSocketFileUploader(server_url, api_key, space_id)
209
+ success = await uploader.connect_and_upload(upload_dir)
210
 
211
+ if success:
212
+ logger.info("🎉 文件已成功上传到您的网盘!")
213
+ else:
214
+ logger.error("❌ 文件上传失败")
215
 
216
+ return success
217
 
218
  if __name__ == "__main__":
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))