soulsync 1.0.10 → 1.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/main.py +162 -140
package/package.json
CHANGED
package/src/main.py
CHANGED
|
@@ -106,151 +106,166 @@ class SoulSyncPlugin:
|
|
|
106
106
|
print("[SoulSync] Auth info saved to config.json")
|
|
107
107
|
|
|
108
108
|
def run_setup(self):
|
|
109
|
-
"""
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
109
|
+
"""交互式设置:注册或登录(带循环)"""
|
|
110
|
+
while True:
|
|
111
|
+
print("\n[SoulSync] ========================================")
|
|
112
|
+
print("[SoulSync] Welcome to SoulSync! / 欢迎使用 SoulSync!")
|
|
113
|
+
print("[SoulSync] ========================================")
|
|
114
|
+
print("[SoulSync] 1. Register / 注册")
|
|
115
|
+
print("[SoulSync] 2. Login / 登录")
|
|
116
|
+
print("[SoulSync] 0. Exit / 退出")
|
|
117
|
+
print("[SoulSync] ========================================")
|
|
118
|
+
|
|
119
|
+
try:
|
|
120
|
+
choice = input("[SoulSync] Choose / 选择 (0/1/2): ").strip()
|
|
121
|
+
except KeyboardInterrupt:
|
|
122
|
+
print("\n[SoulSync] Cancelled by user. Goodbye! / 已取消,再见!")
|
|
123
|
+
sys.exit(0)
|
|
124
|
+
|
|
125
|
+
if choice == '1':
|
|
126
|
+
result = self._interactive_register()
|
|
127
|
+
if result:
|
|
128
|
+
return result
|
|
129
|
+
elif choice == '2':
|
|
130
|
+
result = self._interactive_login()
|
|
131
|
+
if result:
|
|
132
|
+
return result
|
|
133
|
+
elif choice == '0':
|
|
134
|
+
print("[SoulSync] Goodbye! / 再见!")
|
|
135
|
+
sys.exit(0)
|
|
136
|
+
else:
|
|
137
|
+
print("[SoulSync] Invalid choice / 无效选择")
|
|
126
138
|
|
|
127
139
|
def _interactive_login(self):
|
|
128
|
-
"""
|
|
140
|
+
"""交互式登录(失败返回 None,由主循环处理)"""
|
|
129
141
|
from client import OpenClawClient
|
|
130
142
|
|
|
131
|
-
|
|
132
|
-
retry_count = 0
|
|
143
|
+
print("\n--- Login / 登录 ---")
|
|
133
144
|
|
|
134
|
-
|
|
135
|
-
print("\n--- Login / 登录 ---")
|
|
145
|
+
try:
|
|
136
146
|
email = input("[SoulSync] Email / 邮箱: ").strip()
|
|
137
147
|
if not email:
|
|
138
148
|
print("[SoulSync] Email cannot be empty / 邮箱不能为空")
|
|
139
|
-
|
|
140
|
-
|
|
149
|
+
return None
|
|
150
|
+
except KeyboardInterrupt:
|
|
151
|
+
print("\n[SoulSync] Cancelled. Returning to menu... / 已取消,返回菜单...")
|
|
152
|
+
return None
|
|
153
|
+
|
|
154
|
+
try:
|
|
141
155
|
password = getpass.getpass("[SoulSync] Password / 密码: ")
|
|
142
156
|
if not password:
|
|
143
157
|
print("[SoulSync] Password cannot be empty / 密码不能为空")
|
|
144
|
-
|
|
158
|
+
return None
|
|
159
|
+
except KeyboardInterrupt:
|
|
160
|
+
print("\n[SoulSync] Cancelled. Returning to menu... / 已取消,返回菜单...")
|
|
161
|
+
return None
|
|
162
|
+
|
|
163
|
+
try:
|
|
164
|
+
temp_client = OpenClawClient(self.config)
|
|
165
|
+
result = temp_client.authenticate(email, password)
|
|
166
|
+
if result:
|
|
167
|
+
print("\n[SoulSync] ✓ Login successful! / 登录成功!")
|
|
168
|
+
self._save_auth_to_config(result)
|
|
169
|
+
return True
|
|
170
|
+
except Exception as e:
|
|
171
|
+
error_msg = str(e)
|
|
145
172
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
remaining = max_retries - retry_count
|
|
156
|
-
error_msg = str(e)
|
|
157
|
-
|
|
158
|
-
if "429" in error_msg or "too many" in error_msg.lower():
|
|
159
|
-
print(f"\n[SoulSync] ❌ {e}")
|
|
160
|
-
print("\n[SoulSync] Too many failed attempts / 登录失败次数过多")
|
|
161
|
-
print("[SoulSync] Exiting... / 退出...")
|
|
162
|
-
sys.exit(0)
|
|
163
|
-
|
|
164
|
-
if remaining > 0:
|
|
165
|
-
print(f"\n[SoulSync] ❌ Login failed: {e} / 登录失败: {e}")
|
|
166
|
-
print(f"[SoulSync] Remaining attempts / 剩余尝试次数: {remaining}")
|
|
167
|
-
else:
|
|
168
|
-
print(f"\n[SoulSync] ❌ Login failed: {e} / 登录失败: {e}")
|
|
173
|
+
if "429" in error_msg or "too many" in error_msg.lower():
|
|
174
|
+
print(f"\n[SoulSync] ❌ {e}")
|
|
175
|
+
print("\n[SoulSync] Too many failed attempts. Please try again later / 登录失败次数过多,请稍后再试")
|
|
176
|
+
print("[SoulSync] Exiting... / 退出...")
|
|
177
|
+
sys.exit(0)
|
|
178
|
+
|
|
179
|
+
print(f"\n[SoulSync] ❌ Login failed: {e} / 登录失败: {e}")
|
|
180
|
+
print("[SoulSync] Returning to menu... / 返回菜单...")
|
|
181
|
+
return None
|
|
169
182
|
|
|
170
|
-
print("
|
|
171
|
-
print("[SoulSync]
|
|
172
|
-
|
|
183
|
+
print("[SoulSync] ❌ Login failed / 登录失败")
|
|
184
|
+
print("[SoulSync] Returning to menu... / 返回菜单...")
|
|
185
|
+
return None
|
|
173
186
|
|
|
174
187
|
def _interactive_register(self):
|
|
175
|
-
"""
|
|
188
|
+
"""交互式注册(失败返回 None)"""
|
|
176
189
|
from client import OpenClawClient
|
|
177
190
|
|
|
178
|
-
|
|
179
|
-
retry_count = 0
|
|
191
|
+
print("\n--- Register / 注册 ---")
|
|
180
192
|
|
|
181
|
-
|
|
182
|
-
print("\n--- Register / 注册 ---")
|
|
193
|
+
try:
|
|
183
194
|
email = input("[SoulSync] Email / 邮箱: ").strip()
|
|
184
195
|
if not email or '@' not in email:
|
|
185
196
|
print("[SoulSync] Invalid email / 无效邮箱")
|
|
186
|
-
|
|
197
|
+
return None
|
|
198
|
+
except KeyboardInterrupt:
|
|
199
|
+
print("\n[SoulSync] Cancelled. Returning to menu... / 已取消,返回菜单...")
|
|
200
|
+
return None
|
|
201
|
+
|
|
202
|
+
password = None
|
|
203
|
+
while password is None:
|
|
204
|
+
try:
|
|
205
|
+
password = getpass.getpass("[SoulSync] Password / 密码: ")
|
|
206
|
+
if len(password) < 6:
|
|
207
|
+
print("[SoulSync] Password must be at least 6 characters / 密码至少6位")
|
|
208
|
+
password = None
|
|
209
|
+
continue
|
|
210
|
+
except KeyboardInterrupt:
|
|
211
|
+
print("\n[SoulSync] Cancelled. Returning to menu... / 已取消,返回菜单...")
|
|
212
|
+
return None
|
|
187
213
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
214
|
+
try:
|
|
215
|
+
password2 = getpass.getpass("[SoulSync] Confirm password / 确认密码: ")
|
|
216
|
+
except KeyboardInterrupt:
|
|
217
|
+
print("\n[SoulSync] Cancelled. Returning to menu... / 已取消,返回菜单...")
|
|
218
|
+
return None
|
|
192
219
|
|
|
193
|
-
password2 = getpass.getpass("[SoulSync] Confirm password / 确认密码: ")
|
|
194
220
|
if password != password2:
|
|
195
221
|
print("[SoulSync] Passwords do not match / 两次密码不一致")
|
|
222
|
+
password = None
|
|
223
|
+
|
|
224
|
+
print(f"\n[SoulSync] Sending verification code to {email}...")
|
|
225
|
+
try:
|
|
226
|
+
temp_client = OpenClawClient(self.config)
|
|
227
|
+
temp_client.send_verification_code(email)
|
|
228
|
+
print("[SoulSync] ✓ Verification code sent! / 验证码已发送!")
|
|
229
|
+
except Exception as e:
|
|
230
|
+
print(f"[SoulSync] ❌ Failed to send code: {e}")
|
|
231
|
+
print("[SoulSync] Returning to menu... / 返回菜单...")
|
|
232
|
+
return None
|
|
233
|
+
|
|
234
|
+
code_success = False
|
|
235
|
+
code_retry = 0
|
|
236
|
+
max_code_retries = 3
|
|
237
|
+
|
|
238
|
+
while code_retry < max_code_retries and not code_success:
|
|
239
|
+
try:
|
|
240
|
+
code = input(f"[SoulSync] Enter code / 输入验证码 ({max_code_retries - code_retry} left): ").strip()
|
|
241
|
+
except KeyboardInterrupt:
|
|
242
|
+
print("\n[SoulSync] Cancelled. Returning to menu... / 已取消,返回菜单...")
|
|
243
|
+
return None
|
|
244
|
+
|
|
245
|
+
if len(code) != 6 or not code.isdigit():
|
|
246
|
+
code_retry += 1
|
|
247
|
+
print("[SoulSync] Invalid code format / 验证码格式错误")
|
|
196
248
|
continue
|
|
197
249
|
|
|
198
|
-
print(f"\n[SoulSync] Sending verification code to {email}...")
|
|
199
250
|
try:
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
251
|
+
result = temp_client.register(email, password, code)
|
|
252
|
+
print("\n[SoulSync] ✓ Registration successful! / 注册成功!")
|
|
253
|
+
self._save_auth_to_config(result)
|
|
254
|
+
return True
|
|
203
255
|
except Exception as e:
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
code = input(f"[SoulSync] Enter code / 输入验证码 ({max_retries - code_retry} attempts left): ").strip()
|
|
210
|
-
if len(code) != 6 or not code.isdigit():
|
|
211
|
-
code_retry += 1
|
|
212
|
-
print("[SoulSync] Invalid code format / 验证码格式错误")
|
|
213
|
-
continue
|
|
214
|
-
|
|
215
|
-
try:
|
|
216
|
-
result = temp_client.register(email, password, code)
|
|
217
|
-
print("\n[SoulSync] ✓ Registration successful! / 注册成功!")
|
|
218
|
-
self._save_auth_to_config(result)
|
|
219
|
-
return True
|
|
220
|
-
except Exception as e:
|
|
221
|
-
code_retry += 1
|
|
222
|
-
remaining_code = max_retries - code_retry
|
|
223
|
-
if "invalid" in str(e).lower() or "expired" in str(e).lower():
|
|
224
|
-
if remaining_code > 0:
|
|
225
|
-
print(f"[SoulSync] ❌ Invalid or expired code: {e}")
|
|
226
|
-
print(f"[SoulSync] Remaining attempts / 剩余尝试: {remaining_code}")
|
|
227
|
-
else:
|
|
228
|
-
print("[SoulSync] ❌ Too many code attempts / 验证码错误次数过多")
|
|
229
|
-
break
|
|
256
|
+
code_retry += 1
|
|
257
|
+
if "invalid" in str(e).lower() or "expired" in str(e).lower():
|
|
258
|
+
if code_retry < max_code_retries:
|
|
259
|
+
print(f"[SoulSync] ❌ Invalid or expired code: {e}")
|
|
260
|
+
print(f"[SoulSync] Remaining attempts / 剩余尝试: {max_code_retries - code_retry}")
|
|
230
261
|
else:
|
|
231
|
-
print(
|
|
232
|
-
break
|
|
233
|
-
|
|
234
|
-
if code_retry >= max_retries:
|
|
235
|
-
print("\n[SoulSync] Too many code verification failures.")
|
|
236
|
-
print("[SoulSync] 1. Resend code / 重新发送验证码")
|
|
237
|
-
print("[SoulSync] 2. Start over / 重新开始")
|
|
238
|
-
print("[SoulSync] 3. Exit / 退出")
|
|
239
|
-
|
|
240
|
-
sub_choice = input("[SoulSync] Choose / 选择 (1/2/3): ").strip()
|
|
241
|
-
if sub_choice == '1':
|
|
242
|
-
retry_count = 0
|
|
243
|
-
continue
|
|
244
|
-
elif sub_choice == '2':
|
|
245
|
-
retry_count = 0
|
|
246
|
-
break
|
|
262
|
+
print("[SoulSync] ❌ Too many code attempts / 验证码错误次数过多")
|
|
247
263
|
else:
|
|
248
|
-
print("[SoulSync]
|
|
249
|
-
sys.exit(0)
|
|
264
|
+
print(f"[SoulSync] ❌ Registration failed: {e}")
|
|
250
265
|
|
|
251
|
-
print("\n[SoulSync]
|
|
252
|
-
print("[SoulSync]
|
|
253
|
-
|
|
266
|
+
print("\n[SoulSync] Too many code verification failures.")
|
|
267
|
+
print("[SoulSync] Returning to menu... / 返回菜单...")
|
|
268
|
+
return None
|
|
254
269
|
|
|
255
270
|
def initialize(self):
|
|
256
271
|
"""初始化组件"""
|
|
@@ -436,34 +451,41 @@ class SoulSyncPlugin:
|
|
|
436
451
|
print("Plugin shutdown complete")
|
|
437
452
|
def main():
|
|
438
453
|
"""主函数"""
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
454
|
+
try:
|
|
455
|
+
parser = argparse.ArgumentParser(description='SoulSync Plugin')
|
|
456
|
+
parser.add_argument('--setup', action='store_true', help='Run interactive setup (register/login)')
|
|
457
|
+
parser.add_argument('--start', action='store_true', help='Start sync service (auto-login from config)')
|
|
458
|
+
|
|
459
|
+
args = parser.parse_args()
|
|
460
|
+
|
|
461
|
+
plugin = SoulSyncPlugin()
|
|
462
|
+
|
|
463
|
+
if args.setup:
|
|
464
|
+
try:
|
|
465
|
+
plugin.load_config()
|
|
466
|
+
plugin.run_setup()
|
|
467
|
+
print("\n[SoulSync] ✓ Setup complete! Run 'openclaw soulsync:start' to begin syncing.")
|
|
468
|
+
print("[SoulSync] 设置完成!运行 'openclaw soulsync:start' 开始同步。")
|
|
469
|
+
except KeyboardInterrupt:
|
|
470
|
+
print("\n[SoulSync] Cancelled by user. Goodbye! / 已取消,再见!")
|
|
471
|
+
sys.exit(0)
|
|
472
|
+
|
|
448
473
|
plugin.load_config()
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
print("[SoulSync]
|
|
474
|
+
|
|
475
|
+
email = plugin.config.get('email', '').strip()
|
|
476
|
+
password = plugin.config.get('password', '').strip()
|
|
477
|
+
|
|
478
|
+
if not email or not password:
|
|
479
|
+
print("\n[SoulSync] ========================================")
|
|
480
|
+
print("[SoulSync] Not configured. Run 'openclaw soulsync:setup' first.")
|
|
481
|
+
print("[SoulSync] 尚未配置,请先运行 'openclaw soulsync:setup'")
|
|
482
|
+
print("[SoulSync] ========================================\n")
|
|
483
|
+
sys.exit(0)
|
|
484
|
+
|
|
485
|
+
plugin.initialize()
|
|
486
|
+
plugin.run()
|
|
487
|
+
except KeyboardInterrupt:
|
|
488
|
+
print("\n[SoulSync] Cancelled by user. Goodbye! / 已取消,再见!")
|
|
464
489
|
sys.exit(0)
|
|
465
|
-
|
|
466
|
-
plugin.initialize()
|
|
467
|
-
plugin.run()
|
|
468
490
|
if __name__ == '__main__':
|
|
469
491
|
main()
|