Spaces:
Runtime error
Runtime error
Update remote_uploader.py
Browse files- remote_uploader.py +53 -191
remote_uploader.py
CHANGED
@@ -10,6 +10,7 @@ import os
|
|
10 |
import threading
|
11 |
import requests
|
12 |
from urllib.parse import urlparse
|
|
|
13 |
|
14 |
# Configure logging
|
15 |
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
|
@@ -18,216 +19,77 @@ logger = logging.getLogger(__name__)
|
|
18 |
# 全局变量,用于在用户输入时访问 WebSocket
|
19 |
global_websocket = None
|
20 |
|
21 |
-
async def connect(
|
22 |
global global_websocket
|
23 |
-
|
|
|
24 |
encoded_secret = urllib.parse.quote(machine_secret)
|
25 |
-
|
26 |
-
uri = f"wss://remote-terminal-worker.nianxi4563.workers.dev/terminal/{space_id}?secret={encoded_secret}&token={encoded_token}"
|
27 |
logger.info(f"Attempting to connect to {uri}")
|
|
|
28 |
try:
|
29 |
async with websockets.connect(uri, ping_interval=20, ping_timeout=60) as websocket:
|
30 |
global_websocket = websocket
|
31 |
logger.info("Connected to WebSocket")
|
32 |
-
|
|
|
33 |
await websocket.send(json.dumps(machine_info))
|
34 |
logger.debug(f"Sent machine registration: {machine_info}")
|
35 |
|
36 |
-
#
|
37 |
-
if
|
38 |
-
|
39 |
-
|
40 |
-
with open(upload_file, 'rb') as f:
|
41 |
-
file_content = f.read()
|
42 |
-
file_b64 = base64.b64encode(file_content).decode('utf-8')
|
43 |
-
file_msg = {
|
44 |
-
"type": "file_upload",
|
45 |
-
"filename": os.path.basename(upload_file),
|
46 |
-
"content": file_b64,
|
47 |
-
"token": token
|
48 |
-
}
|
49 |
-
await websocket.send(json.dumps(file_msg))
|
50 |
-
logger.info(f"Uploaded file: {upload_file}")
|
51 |
-
except Exception as e:
|
52 |
-
logger.error(f"Error uploading file {upload_file}: {e}")
|
53 |
-
else:
|
54 |
-
logger.error(f"File not found: {upload_file}")
|
55 |
-
|
56 |
-
# 如果指定了上传目录,扫描并上传所有文件
|
57 |
-
if upload_dir:
|
58 |
-
if os.path.exists(upload_dir):
|
59 |
-
all_files = []
|
60 |
-
for root, dirs, files in os.walk(upload_dir):
|
61 |
-
for file in files:
|
62 |
-
file_path = os.path.join(root, file)
|
63 |
-
if os.path.isfile(file_path):
|
64 |
-
all_files.append(file_path)
|
65 |
-
if all_files:
|
66 |
-
logger.info(f"Found {len(all_files)} files in {upload_dir}, starting upload...")
|
67 |
-
for file_path in all_files:
|
68 |
-
try:
|
69 |
-
with open(file_path, 'rb') as f:
|
70 |
-
file_content = f.read()
|
71 |
-
file_b64 = base64.b64encode(file_content).decode('utf-8')
|
72 |
-
file_msg = {
|
73 |
-
"type": "file_upload",
|
74 |
-
"filename": os.path.basename(file_path),
|
75 |
-
"content": file_b64,
|
76 |
-
"token": token
|
77 |
-
}
|
78 |
-
await websocket.send(json.dumps(file_msg))
|
79 |
-
logger.info(f"Uploaded file from dir: {file_path}")
|
80 |
-
except Exception as e:
|
81 |
-
logger.error(f"Error uploading file {file_path}: {e}")
|
82 |
-
else:
|
83 |
-
logger.info(f"No files found in {upload_dir}")
|
84 |
-
else:
|
85 |
-
logger.error(f"Directory not found: {upload_dir}")
|
86 |
-
|
87 |
-
# 创建下载目录
|
88 |
-
os.makedirs("./downloads", exist_ok=True)
|
89 |
-
|
90 |
-
# 启动用户输入监听(非阻塞)
|
91 |
-
asyncio.create_task(listen_user_input())
|
92 |
-
|
93 |
-
while True:
|
94 |
-
try:
|
95 |
-
message = await websocket.recv()
|
96 |
-
logger.debug(f"Received message: {message}")
|
97 |
-
data = json.loads(message)
|
98 |
-
if data["type"] == "command":
|
99 |
-
command = data["command"]
|
100 |
-
logger.info(f"Executing command: {command}")
|
101 |
-
try:
|
102 |
-
process = subprocess.run(command, shell=True, capture_output=True, text=True)
|
103 |
-
output = process.stdout + process.stderr
|
104 |
-
logger.debug(f"Command output: {output}")
|
105 |
-
if process.returncode == 0:
|
106 |
-
await websocket.send(json.dumps({"type": "output", "data": output}))
|
107 |
-
else:
|
108 |
-
await websocket.send(json.dumps({"type": "error", "data": output}))
|
109 |
-
except Exception as e:
|
110 |
-
error_message = f"Error executing command: {e}"
|
111 |
-
logger.error(error_message)
|
112 |
-
await websocket.send(json.dumps({"type": "error", "data": error_message}))
|
113 |
-
elif data["type"] == "file_download_url":
|
114 |
-
# 处理从服务器发来的文件下载URL
|
115 |
-
url = data["url"]
|
116 |
-
filename = data["filename"]
|
117 |
-
logger.info(f"Received file download URL: {url}")
|
118 |
-
try:
|
119 |
-
download_dir = "./downloads"
|
120 |
-
os.makedirs(download_dir, exist_ok=True)
|
121 |
-
response = requests.get(url)
|
122 |
-
if response.status_code == 200:
|
123 |
-
file_path = os.path.join(download_dir, filename)
|
124 |
-
with open(file_path, 'wb') as f:
|
125 |
-
f.write(response.content)
|
126 |
-
success_msg = f"File downloaded successfully: {file_path}"
|
127 |
-
logger.info(success_msg)
|
128 |
-
await websocket.send(json.dumps({
|
129 |
-
"type": "output",
|
130 |
-
"data": success_msg
|
131 |
-
}))
|
132 |
-
else:
|
133 |
-
error_msg = f"Failed to download file. Status code: {response.status_code}"
|
134 |
-
logger.error(error_msg)
|
135 |
-
await websocket.send(json.dumps({
|
136 |
-
"type": "error",
|
137 |
-
"data": error_msg
|
138 |
-
}))
|
139 |
-
except Exception as e:
|
140 |
-
error_msg = f"Error downloading file from URL: {e}"
|
141 |
-
logger.error(error_msg)
|
142 |
-
await websocket.send(json.dumps({
|
143 |
-
"type": "error",
|
144 |
-
"data": error_msg
|
145 |
-
}))
|
146 |
-
elif data["type"] == "ping":
|
147 |
-
logger.debug("Received ping, sending pong")
|
148 |
-
await websocket.send(json.dumps({"type": "pong"}))
|
149 |
-
except websockets.exceptions.ConnectionClosed:
|
150 |
-
logger.error("WebSocket connection closed")
|
151 |
-
break
|
152 |
-
except Exception as e:
|
153 |
-
logger.error(f"Error processing message: {e}")
|
154 |
-
await websocket.send(json.dumps({"type": "error", "data": str(e)}))
|
155 |
-
except Exception as e:
|
156 |
-
logger.error(f"Failed to connect or maintain connection: {e}")
|
157 |
-
|
158 |
-
async def listen_user_input():
|
159 |
-
global global_websocket
|
160 |
-
logger.info("Started listening for user input. Use ' --upload' to upload files to server.")
|
161 |
-
while True:
|
162 |
-
try:
|
163 |
-
user_input = await asyncio.to_thread(input, "Enter command or file path to upload: ")
|
164 |
-
if user_input.strip():
|
165 |
-
parts = user_input.strip().split()
|
166 |
-
if len(parts) >= 2 and parts[-1] == "--upload":
|
167 |
-
filename = " ".join(parts[:-1])
|
168 |
-
if os.path.exists(filename):
|
169 |
try:
|
170 |
-
with open(
|
171 |
file_content = f.read()
|
172 |
file_b64 = base64.b64encode(file_content).decode('utf-8')
|
173 |
file_msg = {
|
174 |
"type": "file_upload",
|
175 |
-
"filename": os.path.basename(
|
176 |
"content": file_b64
|
|
|
177 |
}
|
178 |
-
|
179 |
-
|
180 |
-
logger.info(f"Uploaded file via input: {filename}")
|
181 |
-
else:
|
182 |
-
logger.error("WebSocket not connected")
|
183 |
except Exception as e:
|
184 |
-
logger.error(f"Error uploading file {
|
185 |
-
else:
|
186 |
-
logger.error(f"File not found: {filename}")
|
187 |
-
elif len(parts) >= 2 and parts[-1] == "--download":
|
188 |
-
url = " ".join(parts[:-1])
|
189 |
-
try:
|
190 |
-
parsed_url = urlparse(url)
|
191 |
-
filename = os.path.basename(parsed_url.path)
|
192 |
-
download_dir = "./downloads"
|
193 |
-
os.makedirs(download_dir, exist_ok=True)
|
194 |
-
logger.info(f"Downloading file from URL: {url}")
|
195 |
-
response = requests.get(url)
|
196 |
-
if response.status_code == 200:
|
197 |
-
file_path = os.path.join(download_dir, filename)
|
198 |
-
with open(file_path, 'wb') as f:
|
199 |
-
f.write(response.content)
|
200 |
-
logger.info(f"File downloaded successfully: {file_path}")
|
201 |
-
else:
|
202 |
-
logger.error(f"Failed to download file. Status code: {response.status_code}")
|
203 |
-
except Exception as e:
|
204 |
-
logger.error(f"Error downloading from URL {url}: {e}")
|
205 |
-
else:
|
206 |
-
if global_websocket:
|
207 |
-
await global_websocket.send(json.dumps({
|
208 |
-
"type": "command",
|
209 |
-
"command": user_input
|
210 |
-
}))
|
211 |
-
logger.info(f"Sent command: {user_input}")
|
212 |
else:
|
213 |
-
logger.error("
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
|
|
|
|
|
|
|
|
|
|
218 |
|
219 |
if __name__ == "__main__":
|
220 |
-
|
221 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
222 |
sys.exit(1)
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
|
|
|
|
|
|
|
|
|
10 |
import threading
|
11 |
import requests
|
12 |
from urllib.parse import urlparse
|
13 |
+
import argparse
|
14 |
|
15 |
# Configure logging
|
16 |
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
|
|
|
19 |
# 全局变量,用于在用户输入时访问 WebSocket
|
20 |
global_websocket = None
|
21 |
|
22 |
+
async def connect(card_id, machine_secret, upload_files=None, server="wss://remote-terminal-worker.nianxi4563.workers.dev/terminal/"):
|
23 |
global global_websocket
|
24 |
+
|
25 |
+
# 使用查询参数传递 machine_secret
|
26 |
encoded_secret = urllib.parse.quote(machine_secret)
|
27 |
+
uri = f"{server}{card_id}?secret={encoded_secret}"
|
|
|
28 |
logger.info(f"Attempting to connect to {uri}")
|
29 |
+
|
30 |
try:
|
31 |
async with websockets.connect(uri, ping_interval=20, ping_timeout=60) as websocket:
|
32 |
global_websocket = websocket
|
33 |
logger.info("Connected to WebSocket")
|
34 |
+
|
35 |
+
machine_info = {"type": "machine", "card_id": card_id, "token": machine_secret} # 添加用户token
|
36 |
await websocket.send(json.dumps(machine_info))
|
37 |
logger.debug(f"Sent machine registration: {machine_info}")
|
38 |
|
39 |
+
# 如果指定了上传文件列表,发送文件内容
|
40 |
+
if upload_files:
|
41 |
+
for upload_file in upload_files:
|
42 |
+
if os.path.exists(upload_file):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
try:
|
44 |
+
with open(upload_file, 'rb') as f:
|
45 |
file_content = f.read()
|
46 |
file_b64 = base64.b64encode(file_content).decode('utf-8')
|
47 |
file_msg = {
|
48 |
"type": "file_upload",
|
49 |
+
"filename": os.path.basename(upload_file),
|
50 |
"content": file_b64
|
51 |
+
# 去除 machine_id
|
52 |
}
|
53 |
+
await websocket.send(json.dumps(file_msg))
|
54 |
+
logger.info(f"Uploaded file: {upload_file}")
|
|
|
|
|
|
|
55 |
except Exception as e:
|
56 |
+
logger.error(f"Error uploading file {upload_file}: {e}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
57 |
else:
|
58 |
+
logger.error(f"File not found: {upload_file}")
|
59 |
+
|
60 |
+
# 等待一段时间以接收任何响应,然后关闭
|
61 |
+
try:
|
62 |
+
await asyncio.sleep(5) # 等待服务器响应
|
63 |
+
except:
|
64 |
+
pass
|
65 |
+
|
66 |
+
except Exception as e:
|
67 |
+
logger.error(f"Failed to connect or maintain connection: {e}")
|
68 |
|
69 |
if __name__ == "__main__":
|
70 |
+
parser = argparse.ArgumentParser(description="WebSocket-based File Uploader for remote control file transfer")
|
71 |
+
parser.add_argument("api_key", help="API Key (used as machine_secret and token)")
|
72 |
+
parser.add_argument("space_id", help="Space ID (used as card_id)")
|
73 |
+
parser.add_argument("--server", default="wss://remote-terminal-worker.nianxi4563.workers.dev/terminal/", help="WebSocket server base URL (default: wss://remote-terminal-worker.nianxi4563.workers.dev/terminal/)")
|
74 |
+
parser.add_argument("--upload-dir", default="output", help="Directory to upload files from (default: output)")
|
75 |
+
|
76 |
+
args = parser.parse_args()
|
77 |
+
|
78 |
+
if not os.path.exists(args.upload_dir):
|
79 |
+
print(f"目录不存在: {args.upload_dir}")
|
80 |
sys.exit(1)
|
81 |
+
|
82 |
+
all_files = []
|
83 |
+
for root, dirs, files in os.walk(args.upload_dir):
|
84 |
+
for file in files:
|
85 |
+
file_path = os.path.join(root, file)
|
86 |
+
if os.path.isfile(file_path):
|
87 |
+
all_files.append(file_path)
|
88 |
+
|
89 |
+
if not all_files:
|
90 |
+
print("目录中没有找到任何文件")
|
91 |
+
sys.exit(0)
|
92 |
+
|
93 |
+
print(f"找到 {len(all_files)} 个文件,开始上传...")
|
94 |
+
asyncio.run(connect(args.space_id, args.api_key, upload_files=all_files, server=args.server))
|
95 |
+
print("上传完成!")
|