ryry-cli 4.2__tar.gz → 4.3__tar.gz

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.
Files changed (32) hide show
  1. {ryry_cli-4.2/ryry_cli.egg-info → ryry_cli-4.3}/PKG-INFO +1 -1
  2. {ryry_cli-4.2 → ryry_cli-4.3}/ryry/constant.py +2 -2
  3. ryry_cli-4.3/ryry/daemon_base.py +224 -0
  4. {ryry_cli-4.2 → ryry_cli-4.3}/ryry/server_func.py +8 -8
  5. {ryry_cli-4.2 → ryry_cli-4.3}/ryry/upload.py +8 -7
  6. {ryry_cli-4.2 → ryry_cli-4.3/ryry_cli.egg-info}/PKG-INFO +1 -1
  7. {ryry_cli-4.2 → ryry_cli-4.3}/setup.py +1 -1
  8. ryry_cli-4.2/ryry/daemon_base.py +0 -131
  9. {ryry_cli-4.2 → ryry_cli-4.3}/LICENSE +0 -0
  10. {ryry_cli-4.2 → ryry_cli-4.3}/README.md +0 -0
  11. {ryry_cli-4.2 → ryry_cli-4.3}/ryry/__init__.py +0 -0
  12. {ryry_cli-4.2 → ryry_cli-4.3}/ryry/daemon_manager.py +0 -0
  13. {ryry_cli-4.2 → ryry_cli-4.3}/ryry/main.py +0 -0
  14. {ryry_cli-4.2 → ryry_cli-4.3}/ryry/ryry_server_socket.py +0 -0
  15. {ryry_cli-4.2 → ryry_cli-4.3}/ryry/ryry_service.py +0 -0
  16. {ryry_cli-4.2 → ryry_cli-4.3}/ryry/ryry_webapi.py +0 -0
  17. {ryry_cli-4.2 → ryry_cli-4.3}/ryry/ryry_widget.py +0 -0
  18. {ryry_cli-4.2 → ryry_cli-4.3}/ryry/script_template/__init__.py +0 -0
  19. {ryry_cli-4.2 → ryry_cli-4.3}/ryry/script_template/daemon.py +0 -0
  20. {ryry_cli-4.2 → ryry_cli-4.3}/ryry/script_template/main.py +0 -0
  21. {ryry_cli-4.2 → ryry_cli-4.3}/ryry/script_template/run.py +0 -0
  22. {ryry_cli-4.2 → ryry_cli-4.3}/ryry/shared_memory.py +0 -0
  23. {ryry_cli-4.2 → ryry_cli-4.3}/ryry/store.py +0 -0
  24. {ryry_cli-4.2 → ryry_cli-4.3}/ryry/task.py +0 -0
  25. {ryry_cli-4.2 → ryry_cli-4.3}/ryry/taskUtils.py +0 -0
  26. {ryry_cli-4.2 → ryry_cli-4.3}/ryry/utils.py +0 -0
  27. {ryry_cli-4.2 → ryry_cli-4.3}/ryry_cli.egg-info/SOURCES.txt +0 -0
  28. {ryry_cli-4.2 → ryry_cli-4.3}/ryry_cli.egg-info/dependency_links.txt +0 -0
  29. {ryry_cli-4.2 → ryry_cli-4.3}/ryry_cli.egg-info/entry_points.txt +0 -0
  30. {ryry_cli-4.2 → ryry_cli-4.3}/ryry_cli.egg-info/requires.txt +0 -0
  31. {ryry_cli-4.2 → ryry_cli-4.3}/ryry_cli.egg-info/top_level.txt +0 -0
  32. {ryry_cli-4.2 → ryry_cli-4.3}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ryry-cli
3
- Version: 4.2
3
+ Version: 4.3
4
4
  Summary: ryry tools
5
5
  Home-page: https://github.com/dalipenMedia
6
6
  Author: dalipen
@@ -1,6 +1,6 @@
1
1
  #!!!!! do not change this file !!!!!
2
- app_version="4.2"
3
- app_bulld_anchor="Noh_2025-07-15 16:56:04.603552"
2
+ app_version="4.3"
3
+ app_bulld_anchor="Noh_2025-07-17 12:12:40.198080"
4
4
  app_name="ryry-cli"
5
5
  import sys, os
6
6
  if getattr(sys, 'frozen', False):
@@ -0,0 +1,224 @@
1
+ import sys
2
+ import os
3
+ import json
4
+ import time
5
+ import signal
6
+ from typing import Optional, Dict, Any
7
+
8
+ class SimpleDaemonBase:
9
+ """
10
+ 简化的Daemon基类
11
+
12
+ 用户需要实现的方法:
13
+ - initialize(): 初始化资源
14
+ - loop_function(): 循环执行的任务(可选)
15
+ - on_stop(): 清理资源(可选)
16
+ """
17
+
18
+ def __init__(self, widget_id: str):
19
+ # 基础配置
20
+ self.widget_id = widget_id
21
+ self.widget_name = "???"
22
+ self.running = False
23
+
24
+ # 配置加载
25
+ self._load_config()
26
+
27
+ # 信号处理
28
+ self._setup_signal_handlers()
29
+
30
+ print(f"【{self.widget_name}】Daemon实例创建完成", file=sys.stderr)
31
+
32
+ def _load_config(self):
33
+ """加载配置文件"""
34
+ try:
35
+ self._script_path = os.path.abspath(sys.modules[self.__class__.__module__].__file__)
36
+ self.base_path = sys.argv[2] if len(sys.argv) > 2 else os.path.expanduser("~/.ryry")
37
+ config_path = os.path.join(os.path.dirname(self._script_path), "config.json")
38
+
39
+ if os.path.exists(config_path):
40
+ with open(config_path, 'r', encoding='utf-8') as f:
41
+ config = json.load(f)
42
+ self.timeout = config.get("timeout", 600)
43
+ self.widget_name = config.get("name", self.widget_name)
44
+ else:
45
+ self.timeout = 600
46
+ except Exception as e:
47
+ print(f"配置加载失败: {e}", file=sys.stderr)
48
+ self.timeout = 600
49
+
50
+ def _setup_signal_handlers(self):
51
+ """设置信号处理器"""
52
+ def signal_handler(signum, frame):
53
+ print(f"【{self.widget_name}】收到信号 {signum},开始停止", file=sys.stderr)
54
+ self.running = False
55
+
56
+ # 注册信号处理器
57
+ signal.signal(signal.SIGINT, signal_handler) # Ctrl+C
58
+ signal.signal(signal.SIGTERM, signal_handler) # 终止信号
59
+
60
+ if hasattr(signal, 'SIGBREAK'):
61
+ signal.signal(signal.SIGBREAK, signal_handler)
62
+
63
+ # ==================== 生命周期方法 ====================
64
+
65
+ def initialize(self):
66
+ """
67
+ 初始化方法 - 子类可选实现
68
+ 在这里进行资源初始化,如数据库连接、模型加载等
69
+ """
70
+ pass
71
+
72
+ def loop_function(self):
73
+ """
74
+ 循环执行的方法 - 子类可选实现
75
+ 每秒调用一次,用于定时任务、心跳等
76
+ """
77
+ pass
78
+
79
+ def on_stop(self):
80
+ """
81
+ 停止时的清理方法 - 子类可选实现
82
+ 在这里进行资源清理,如关闭连接、保存状态等
83
+ """
84
+ pass
85
+
86
+ # ==================== 通信方法 ====================
87
+
88
+ def send_ready_signal(self):
89
+ """发送就绪信号"""
90
+ try:
91
+ ready_file = os.path.join(self.base_path, f"daemon_ready_{self.widget_id}.json")
92
+ with open(ready_file, 'w', encoding='utf-8') as f:
93
+ json.dump({"accept_tasks": False}, f)
94
+ except Exception as e:
95
+ print(f"发送就绪信号失败: {e}", file=sys.stderr)
96
+
97
+ def process_command(self):
98
+ """处理命令文件"""
99
+ cmd_file = os.path.join(self.base_path, f"daemon_cmd_{self.widget_id}.json")
100
+ if not os.path.exists(cmd_file):
101
+ return
102
+
103
+ try:
104
+ with open(cmd_file, 'r', encoding='utf-8') as f:
105
+ command = json.load(f)
106
+ os.remove(cmd_file)
107
+
108
+ cmd_type = command.get("type")
109
+ if cmd_type == "task":
110
+ self._handle_task_command(command)
111
+ elif cmd_type == "health":
112
+ self._handle_health_command(command)
113
+ elif cmd_type == "stop":
114
+ self._handle_stop_command(command)
115
+
116
+ except Exception as e:
117
+ print(f"处理命令失败: {e}", file=sys.stderr)
118
+
119
+ def _handle_task_command(self, command: Dict[str, Any]):
120
+ """处理任务命令"""
121
+ task_data = command.get("data", {})
122
+ timeout = command.get("timeout", self.timeout)
123
+
124
+ try:
125
+ result = self.process_task(task_data, timeout)
126
+ self._send_response({
127
+ "type": "task_result",
128
+ "task_id": command.get("task_id"),
129
+ "success": True,
130
+ "data": result
131
+ })
132
+ except Exception as e:
133
+ self._send_response({
134
+ "type": "task_result",
135
+ "task_id": command.get("task_id"),
136
+ "success": False,
137
+ "error": str(e),
138
+ "data": {"result": [], "status": 1, "message": str(e)}
139
+ })
140
+
141
+ def _handle_health_command(self, command: Dict[str, Any]):
142
+ """处理健康检查命令"""
143
+ health = self.health_check()
144
+ self._send_response({
145
+ "type": "health_result",
146
+ "data": health
147
+ })
148
+
149
+ def _handle_stop_command(self, command: Dict[str, Any]):
150
+ """处理停止命令"""
151
+ self.running = False
152
+ self._send_response({
153
+ "type": "stop_result",
154
+ "success": True
155
+ })
156
+
157
+ def _send_response(self, response: Dict[str, Any]):
158
+ """发送响应"""
159
+ try:
160
+ result_file = os.path.join(self.base_path, f"daemon_result_{self.widget_id}.json")
161
+ with open(result_file, 'w', encoding='utf-8') as f:
162
+ json.dump(response, f)
163
+ except Exception as e:
164
+ print(f"发送响应失败: {e}", file=sys.stderr)
165
+
166
+ # ==================== 子类可选重写的方法 ====================
167
+
168
+ def process_task(self, task_data: Dict[str, Any], timeout: Optional[int] = None) -> Dict[str, Any]:
169
+ """
170
+ 处理短链任务 - 子类可选实现
171
+ 默认返回空结果
172
+ """
173
+ return {
174
+ "result": [{"type": "text", "content": [f"Processed: {task_data}"]}],
175
+ "status": 0,
176
+ "message": "Success"
177
+ }
178
+
179
+ def health_check(self) -> Dict[str, Any]:
180
+ """
181
+ 健康检查 - 子类可选重写
182
+ """
183
+ return {
184
+ "healthy": True,
185
+ "state": "running",
186
+ "accept_tasks": False,
187
+ "timestamp": time.time()
188
+ }
189
+
190
+ # ==================== 控制方法 ====================
191
+
192
+ def run(self):
193
+ """
194
+ 运行daemon的主入口方法
195
+ """
196
+ try:
197
+ # 初始化
198
+ self.initialize()
199
+
200
+ # 发送就绪信号
201
+ self.send_ready_signal()
202
+
203
+ # 主循环
204
+ self.running = True
205
+ while self.running:
206
+ try:
207
+ # 处理命令
208
+ self.process_command()
209
+ # 执行循环函数
210
+ self.loop_function()
211
+ time.sleep(1)
212
+ except KeyboardInterrupt:
213
+ print(f"【{self.widget_name}】收到KeyboardInterrupt", file=sys.stderr)
214
+ break
215
+ except Exception as e:
216
+ print(f"主循环异常: {e}", file=sys.stderr)
217
+ time.sleep(5) # 异常后等待5秒再继续
218
+ # 清理
219
+ self.on_stop()
220
+
221
+ except Exception as e:
222
+ print(f"运行异常: {e}", file=sys.stderr)
223
+ finally:
224
+ print(f"【{self.widget_name}】进程终止", file=sys.stderr)
@@ -79,10 +79,11 @@ class Task:
79
79
  if realTaskUUID == None or len(realTaskUUID) <= 0:
80
80
  realTaskUUID = taskUtils.taskInfoWithFirstTask()
81
81
 
82
- support_subdomain = upload.getFirstSupportSubdomain()
83
82
  mayby_domain = ""
84
- if support_subdomain:
85
- mayby_domain = support_subdomain["readpath"]
83
+ if "domain" not in multi_params[0]:
84
+ support_subdomain = upload.getFirstSupportSubdomain()
85
+ if support_subdomain:
86
+ mayby_domain = support_subdomain["domain"]
86
87
 
87
88
  def _callback(idx, data):
88
89
  self.thread_data[str(idx)]["result"] = data
@@ -118,12 +119,11 @@ class AsyncTask:
118
119
  if realTaskUUID == None or len(realTaskUUID) <= 0:
119
120
  realTaskUUID = taskUtils.taskInfoWithFirstTask()
120
121
 
121
- support_subdomain = upload.getFirstSupportSubdomain()
122
- domain = ""
123
- if support_subdomain:
124
- domain = support_subdomain["readpath"]
125
122
  self.params["fromUUID"] = realTaskUUID
126
- self.params["domain"] = domain
123
+ if "domain" not in self.params:
124
+ support_subdomain = upload.getFirstSupportSubdomain()
125
+ if support_subdomain:
126
+ self.params["domain"] = support_subdomain["domain"]
127
127
 
128
128
  def call(self):
129
129
  cmd = task.cmdWithWidgetName(self.func)
@@ -240,13 +240,13 @@ oss_template_config = {
240
240
  }
241
241
 
242
242
  DOMAIN_CONFIG = {
243
+ "192.168.50.12": {"type": "ftp", "config": ftp_192_168_50_12},
244
+ "183.6.90.205": {"type": "ftp", "config": ftp_183_6_90_205},
245
+ "ftp://192.168.50.12/mnt/NAS/mcn/cache": {"type": "ftp", "config": ftp_192_168_50_12},
246
+ "ftp://183.6.90.205/mnt/NAS/mcn/cache": {"type": "ftp", "config": ftp_183_6_90_205},
243
247
  "res.zjtemplate.com": {"type": "oss", "config": oss_res_config},
244
248
  "upload.zjtemplate.com": {"type": "oss", "config": oss_upload_config},
245
249
  "oss.zjtemplate.com": {"type": "oss", "config": oss_template_config},
246
- "ftp://192.168.50.12/mnt/NAS/mcn/cache": {"type": "ftp", "config": ftp_192_168_50_12},
247
- "ftp://183.6.90.205/mnt/NAS/mcn/cache": {"type": "ftp", "config": ftp_183_6_90_205},
248
- "192.168.50.12": {"type": "ftp", "config": ftp_192_168_50_12},
249
- "183.6.90.205": {"type": "ftp", "config": ftp_183_6_90_205},
250
250
  }
251
251
 
252
252
  SUBDOMAIN = {
@@ -299,11 +299,11 @@ def getFirstSupportSubdomain():
299
299
  def _getFirstSupportSubdomain():
300
300
  for domain, config in DOMAIN_CONFIG.items():
301
301
  if config["type"] == "oss":
302
- return {"type": "oss", "config": config["config"], "domain": domain}
302
+ return {"type": "oss", "config": config["config"], "domain": config["config"]["domain"]}
303
303
  elif config["type"] == "ftp":
304
304
  ftp_config = config["config"]
305
305
  if _can_connect_ftp(ftp_config["host"], ftp_config["port"], ftp_config["username"], ftp_config["password"], ftp_config["writepath"]):
306
- return {"type": "ftp", "config": ftp_config, "domain": domain}
306
+ return {"type": "ftp", "config": ftp_config, "domain": ftp_config["readpath"]}
307
307
 
308
308
  for ip in SUBDOMAIN.keys():
309
309
  for host_item in SUBDOMAIN[ip]:
@@ -322,7 +322,8 @@ def getFirstSupportSubdomain():
322
322
  sp.write(read_data)
323
323
  else:
324
324
  last_network_hash = firstSupportDomainConfig.get("hash", "")
325
- if last_network_hash != network_hash:
325
+ #网络变化,或者旧版本数据的时候,重新更新
326
+ if last_network_hash != network_hash or "domain" not in firstSupportDomainConfig:
326
327
  firstSupportDomainConfig = _getFirstSupportSubdomain()
327
328
  if firstSupportDomainConfig:
328
329
  firstSupportDomainConfig["hash"] = network_hash
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ryry-cli
3
- Version: 4.2
3
+ Version: 4.3
4
4
  Summary: ryry tools
5
5
  Home-page: https://github.com/dalipenMedia
6
6
  Author: dalipen
@@ -3,7 +3,7 @@ import os
3
3
  import subprocess
4
4
  import datetime
5
5
 
6
- ryry_version = "4.2"
6
+ ryry_version = "4.3"
7
7
  cur_dir = os.path.dirname(os.path.abspath(__file__))
8
8
  constanspy = os.path.join(cur_dir, "ryry", "constant.py")
9
9
  try:
@@ -1,131 +0,0 @@
1
- import sys
2
- import os
3
- import json
4
- import time
5
- from threading import Event
6
-
7
- DEFAULT_ACCEPT_TASKS = False # 默认是否接受短链任务
8
-
9
- class DaemonBase:
10
- def __init__(self, widget_id: str):
11
- self.widget_id = widget_id
12
- self.running = True
13
- self.stop_event = Event()
14
- self.accept_tasks = self.default_accept_tasks()
15
- self.widget_name = "???"
16
- # 获取子类文件(即实际widget的daemon.py)所在目录
17
- self._script_path = os.path.abspath(sys.modules[self.__class__.__module__].__file__)
18
- self.base_path = sys.argv[2] if len(sys.argv) > 2 else os.path.expanduser("~/.ryry")
19
- config_path = os.path.join(os.path.dirname(self._script_path), "config.json")
20
- if os.path.exists(config_path):
21
- try:
22
- with open(config_path, 'r', encoding='utf-8') as f:
23
- config = json.load(f)
24
- self.timeout = config.get("timeout", 600)
25
- self.widget_name = config.get("name", self.widget_name)
26
- except:
27
- self.timeout = 600
28
- else:
29
- self.timeout = 600
30
-
31
- def default_accept_tasks(self):
32
- return DEFAULT_ACCEPT_TASKS
33
-
34
- def initialize(self):
35
- pass
36
-
37
- def process_task(self, task_data, timeout=None):
38
- raise NotImplementedError("process_task必须由子类实现")
39
-
40
- def on_stop(self):
41
- pass
42
-
43
- def health_check(self):
44
- return {
45
- "healthy": True,
46
- "accept_tasks": self.accept_tasks,
47
- "timestamp": time.time()
48
- }
49
-
50
- def loop_function(self):
51
- pass
52
-
53
- def _send_ready_signal(self):
54
- try:
55
- ready_file = os.path.join(self.base_path, f"daemon_ready_{self.widget_id}.json")
56
- with open(ready_file, 'w', encoding='utf-8') as f:
57
- json.dump({"accept_tasks": self.accept_tasks}, f)
58
- except Exception as e:
59
- print(f"Failed to send ready signal: {e}", file=sys.stderr)
60
-
61
- def _send_response(self, response):
62
- try:
63
- result_file = os.path.join(self.base_path, f"daemon_result_{self.widget_id}.json")
64
- with open(result_file, 'w', encoding='utf-8') as f:
65
- json.dump(response, f)
66
- except Exception as e:
67
- print(f"Failed to send response: {e}", file=sys.stderr)
68
-
69
- def _process_command(self, command):
70
- cmd_type = command.get("type")
71
- if cmd_type == "task":
72
- task_data = command.get("data", {})
73
- timeout = command.get("timeout", self.timeout)
74
- try:
75
- result = self.process_task(task_data, timeout)
76
- self._send_response({
77
- "type": "task_result",
78
- "task_id": command.get("task_id"),
79
- "success": True,
80
- "data": result
81
- })
82
- except Exception as e:
83
- self._send_response({
84
- "type": "task_result",
85
- "task_id": command.get("task_id"),
86
- "success": False,
87
- "error": str(e),
88
- "data": {"result": [], "status": 1, "message": str(e)}
89
- })
90
- elif cmd_type == "health":
91
- health = self.health_check()
92
- self._send_response({
93
- "type": "health_result",
94
- "data": health
95
- })
96
- elif cmd_type == "stop":
97
- print(f"【{self.widget_name}后台进程】Received stop command", file=sys.stderr)
98
- self.running = False
99
- self.stop_event.set()
100
- self._send_response({
101
- "type": "stop_result",
102
- "success": True
103
- })
104
-
105
- def run(self):
106
- try:
107
- self.initialize()
108
- self._send_ready_signal()
109
- cmd_file = os.path.join(self.base_path, f"daemon_cmd_{self.widget_id}.json")
110
- while self.running:
111
- try:
112
- if os.path.exists(cmd_file):
113
- try:
114
- with open(cmd_file, 'r', encoding='utf-8') as f:
115
- command = json.load(f)
116
- os.remove(cmd_file)
117
- self._process_command(command)
118
- except Exception as e:
119
- print(f"Error processing command: {e}", file=sys.stderr)
120
- if self.stop_event.is_set():
121
- break
122
- self.loop_function()
123
- time.sleep(1)
124
- except KeyboardInterrupt:
125
- break
126
- except Exception as e:
127
- print(f"Error in main loop: {e}", file=sys.stderr)
128
- time.sleep(1)
129
- finally:
130
- self.on_stop()
131
- print(f"【{self.widget_name}】已终止", file=sys.stderr)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes