ryry-cli 1.0__py3-none-any.whl
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.
- ryry/__init__.py +0 -0
- ryry/constant.py +5 -0
- ryry/main.py +300 -0
- ryry/ryry_server_socket.py +180 -0
- ryry/ryry_service.py +220 -0
- ryry/ryry_webapi.py +251 -0
- ryry/ryry_widget.py +398 -0
- ryry/script_template/__init__.py +0 -0
- ryry/script_template/main.py +25 -0
- ryry/script_template/run.py +22 -0
- ryry/server_func.py +74 -0
- ryry/store.py +161 -0
- ryry/task.py +203 -0
- ryry/taskUtils.py +283 -0
- ryry/upload.py +139 -0
- ryry/utils.py +358 -0
- ryry_cli-1.0.dist-info/LICENSE +7 -0
- ryry_cli-1.0.dist-info/METADATA +72 -0
- ryry_cli-1.0.dist-info/RECORD +22 -0
- ryry_cli-1.0.dist-info/WHEEL +5 -0
- ryry_cli-1.0.dist-info/entry_points.txt +2 -0
- ryry_cli-1.0.dist-info/top_level.txt +3 -0
ryry/utils.py
ADDED
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
import uuid
|
|
2
|
+
import platform
|
|
3
|
+
import subprocess
|
|
4
|
+
import os
|
|
5
|
+
import sys
|
|
6
|
+
import requests
|
|
7
|
+
from io import BytesIO
|
|
8
|
+
import psutil
|
|
9
|
+
import pynvml
|
|
10
|
+
from datetime import datetime, timedelta
|
|
11
|
+
import http
|
|
12
|
+
import json
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
import zipfile
|
|
15
|
+
import socket
|
|
16
|
+
from PIL import Image
|
|
17
|
+
|
|
18
|
+
def get_mac_from_nettools():
|
|
19
|
+
try:
|
|
20
|
+
cmd = "ifconfig"
|
|
21
|
+
output = subprocess.check_output(cmd, shell=True)
|
|
22
|
+
output_str = output.decode(encoding='UTF-8')
|
|
23
|
+
mac = output_str[output_str.index('ether') + 6:output_str.index('ether') + 23].replace(':', '')
|
|
24
|
+
return True, mac
|
|
25
|
+
except Exception as e:
|
|
26
|
+
return False, None
|
|
27
|
+
|
|
28
|
+
def get_mac_from_system():
|
|
29
|
+
try:
|
|
30
|
+
root_path = '/sys/class/net/'
|
|
31
|
+
dbtype_list = os.listdir(root_path)
|
|
32
|
+
for dbtype in dbtype_list:
|
|
33
|
+
if os.path.isfile(os.path.join(root_path, dbtype)):
|
|
34
|
+
dbtype_list.remove(dbtype)
|
|
35
|
+
|
|
36
|
+
if len(dbtype_list) == 0:
|
|
37
|
+
return False, None
|
|
38
|
+
mac = ''
|
|
39
|
+
for dbtype in dbtype_list:
|
|
40
|
+
cmd = f"cat {root_path}{dbtype}/address"
|
|
41
|
+
output = subprocess.check_output(cmd, shell=True)
|
|
42
|
+
mac += output.decode(encoding='UTF-8')
|
|
43
|
+
return True, mac
|
|
44
|
+
except Exception as e:
|
|
45
|
+
return False, None
|
|
46
|
+
|
|
47
|
+
mac_value = ""
|
|
48
|
+
def get_mac_address():
|
|
49
|
+
global mac_value
|
|
50
|
+
if mac_value and len(mac_value) > 0:
|
|
51
|
+
return mac_value
|
|
52
|
+
|
|
53
|
+
if platform.system() == 'Windows':
|
|
54
|
+
cmd = "ipconfig /all"
|
|
55
|
+
output = subprocess.check_output(cmd, shell=True)
|
|
56
|
+
output_str = output.decode('gbk')
|
|
57
|
+
pos = output_str.find('Physical Address')
|
|
58
|
+
if pos == -1:
|
|
59
|
+
pos = output_str.find('物理地址')
|
|
60
|
+
mac_value = (output_str[pos:pos+100].split(':')[1]).strip().replace('-', '')
|
|
61
|
+
elif platform.system() == 'Linux' or platform.system() == 'Darwin':
|
|
62
|
+
ok, mac_value = get_mac_from_nettools()
|
|
63
|
+
if ok:
|
|
64
|
+
return mac_value
|
|
65
|
+
ok, mac_value = get_mac_from_system()
|
|
66
|
+
if ok:
|
|
67
|
+
return mac_value
|
|
68
|
+
return None
|
|
69
|
+
else:
|
|
70
|
+
mac_value = None
|
|
71
|
+
return mac_value
|
|
72
|
+
|
|
73
|
+
cpu_serial = ""
|
|
74
|
+
def get_cpu_serial():
|
|
75
|
+
global cpu_serial
|
|
76
|
+
if cpu_serial and len(cpu_serial) > 0:
|
|
77
|
+
return cpu_serial
|
|
78
|
+
|
|
79
|
+
if platform.system() == 'Windows':
|
|
80
|
+
cmd = "wmic cpu get ProcessorId"
|
|
81
|
+
output = subprocess.check_output(cmd, shell=True)
|
|
82
|
+
output_str = output.decode('gbk')
|
|
83
|
+
pos = output_str.index("\n")
|
|
84
|
+
cpu_serial = output_str[pos:].strip()
|
|
85
|
+
elif platform.system() == 'Linux':
|
|
86
|
+
with open('/proc/cpuinfo') as f:
|
|
87
|
+
|
|
88
|
+
for line in f:
|
|
89
|
+
if line[0:6] == 'Serial':
|
|
90
|
+
return "1"
|
|
91
|
+
if line.strip().startswith('serial'):
|
|
92
|
+
cpu_serial = line.split(":")[1].strip()
|
|
93
|
+
break
|
|
94
|
+
if not cpu_serial:
|
|
95
|
+
cpu_serial = None
|
|
96
|
+
elif platform.system() == 'Darwin':
|
|
97
|
+
cmd = "/usr/sbin/system_profiler SPHardwareDataType"
|
|
98
|
+
output = subprocess.check_output(cmd, shell=True)
|
|
99
|
+
output_str = output.decode(encoding='UTF-8')
|
|
100
|
+
cpu_serial = output_str[output_str.index('Hardware UUID:') + 14:output_str.index('Hardware UUID:') + 51].replace('-', '')
|
|
101
|
+
else:
|
|
102
|
+
cpu_serial = None
|
|
103
|
+
return cpu_serial
|
|
104
|
+
|
|
105
|
+
def get_hostname():
|
|
106
|
+
return socket.gethostname()
|
|
107
|
+
|
|
108
|
+
def generate_unique_id():
|
|
109
|
+
mac = get_mac_address()
|
|
110
|
+
cpu_serial = get_cpu_serial()
|
|
111
|
+
hostname = get_hostname()
|
|
112
|
+
if mac and cpu_serial:
|
|
113
|
+
unique_id = uuid.uuid5(uuid.NAMESPACE_DNS, mac + cpu_serial + hostname)
|
|
114
|
+
return str(unique_id).replace('-', '')
|
|
115
|
+
if mac :
|
|
116
|
+
unique_id = uuid.uuid5(uuid.NAMESPACE_DNS, mac + hostname)
|
|
117
|
+
return str(unique_id).replace('-', '')
|
|
118
|
+
|
|
119
|
+
def getOssImageSize(p):
|
|
120
|
+
try:
|
|
121
|
+
s = requests.session()
|
|
122
|
+
s.keep_alive = False
|
|
123
|
+
res = s.get(p, timeout=60)
|
|
124
|
+
image = Image.open(BytesIO(res.content), "r")
|
|
125
|
+
s.close()
|
|
126
|
+
return image.size
|
|
127
|
+
except:
|
|
128
|
+
return 0, 0
|
|
129
|
+
|
|
130
|
+
def deviceInfo():
|
|
131
|
+
mac = get_mac_address()
|
|
132
|
+
mac = "" if mac == None else mac
|
|
133
|
+
cpu_serial = get_cpu_serial()
|
|
134
|
+
cpu_serial = "" if cpu_serial == None else cpu_serial
|
|
135
|
+
hostname = get_hostname()
|
|
136
|
+
M=1024*1024
|
|
137
|
+
data = {
|
|
138
|
+
"cpu": {
|
|
139
|
+
"logical_count" : psutil.cpu_count(),
|
|
140
|
+
"count" : psutil.cpu_count(logical=False),
|
|
141
|
+
"max_freq" : f"{psutil.cpu_freq().max / 1000} GHz",
|
|
142
|
+
},
|
|
143
|
+
"memory": {
|
|
144
|
+
"total" : f"{psutil.virtual_memory().total/M} M",
|
|
145
|
+
"free" : f"{psutil.virtual_memory().free/M} M"
|
|
146
|
+
},
|
|
147
|
+
"gpu": {
|
|
148
|
+
"count" : 0,
|
|
149
|
+
"list" : [],
|
|
150
|
+
"mem" : []
|
|
151
|
+
},
|
|
152
|
+
"device_id": generate_unique_id(),
|
|
153
|
+
"host_name": hostname
|
|
154
|
+
}
|
|
155
|
+
try:
|
|
156
|
+
pynvml.nvmlInit()
|
|
157
|
+
gpuCount = pynvml.nvmlDeviceGetCount()
|
|
158
|
+
data["gpu"]["count"] = gpuCount
|
|
159
|
+
for i in range(gpuCount):
|
|
160
|
+
handle = pynvml.nvmlDeviceGetHandleByIndex(i)
|
|
161
|
+
data["gpu"]["list"].append(f"GPU{i}: {pynvml.nvmlDeviceGetName(handle)}")
|
|
162
|
+
memInfo = pynvml.nvmlDeviceGetMemoryInfo(handle)
|
|
163
|
+
data["gpu"]["mem"].append(f"GPU{i}: total:{memInfo.total/M} M free:{memInfo.free/M} M")
|
|
164
|
+
|
|
165
|
+
pynvml.nvmlShutdown()
|
|
166
|
+
except Exception as e:
|
|
167
|
+
data["gpu"]["count"] = 1
|
|
168
|
+
data["gpu"]["list"].append(f"GPU0: Normal")
|
|
169
|
+
return data
|
|
170
|
+
|
|
171
|
+
def reportLog():
|
|
172
|
+
reason = ""
|
|
173
|
+
if len(sys.argv) >= 2:
|
|
174
|
+
reason = sys.argv[2].strip().replace("\n","").replace(",","").replace(" ","").replace(";","")
|
|
175
|
+
d = datetime.now().strftime('%Y_%m_%d_%H_%M_%S')
|
|
176
|
+
uid = generate_unique_id()
|
|
177
|
+
|
|
178
|
+
thisFileDir = os.path.dirname(os.path.abspath(__file__))
|
|
179
|
+
dist = os.path.join(thisFileDir, f"{uid}_{reason}_{d}.zip")
|
|
180
|
+
zip = zipfile.ZipFile(dist, "w", zipfile.ZIP_DEFLATED)
|
|
181
|
+
|
|
182
|
+
for root,dirs,files in os.walk(thisFileDir):
|
|
183
|
+
for file in files:
|
|
184
|
+
if str(file).startswith("~$"):
|
|
185
|
+
continue
|
|
186
|
+
ext = file[file.rindex("."):]
|
|
187
|
+
if ext == ".log" or ext == ".json" or ".log." in file:
|
|
188
|
+
filepath = os.path.join(root, file)
|
|
189
|
+
zip.write(filepath, file)
|
|
190
|
+
if root != files:
|
|
191
|
+
break
|
|
192
|
+
zip.close()
|
|
193
|
+
ossurl = uploadOSS(dist)
|
|
194
|
+
os.remove(dist)
|
|
195
|
+
return ossurl
|
|
196
|
+
|
|
197
|
+
def uploadOSS(file):
|
|
198
|
+
conn = http.client.HTTPSConnection("api.ryryai.com")
|
|
199
|
+
payload = json.dumps({
|
|
200
|
+
"sign": "f0463f490eb84133c0aab3a8576ed2fc"
|
|
201
|
+
})
|
|
202
|
+
headers = {
|
|
203
|
+
'Content-Type': 'application/json'
|
|
204
|
+
}
|
|
205
|
+
conn.request("POST", "/proxymsg/get_oss_config", payload, headers)
|
|
206
|
+
res = conn.getresponse()
|
|
207
|
+
data = json.loads(res.read().decode("utf-8"))
|
|
208
|
+
if data["code"] == 0:
|
|
209
|
+
AccessKeyId = data["data"]["AccessKeyId"]
|
|
210
|
+
AccessKeySecret = data["data"]["AccessKeySecret"]
|
|
211
|
+
SecurityToken = data["data"]["SecurityToken"]
|
|
212
|
+
BucketName = data["data"]["BucketName"]
|
|
213
|
+
Expiration = data["data"]["Expiration"]
|
|
214
|
+
Endpoint = data["data"]["Endpoint"]
|
|
215
|
+
CallbackUrl = data["data"]["CallbackUrl"]
|
|
216
|
+
cdn = data["data"]["cdn"]
|
|
217
|
+
|
|
218
|
+
if len(AccessKeyId) > 0:
|
|
219
|
+
import oss2
|
|
220
|
+
auth = oss2.StsAuth(AccessKeyId, AccessKeySecret, SecurityToken)
|
|
221
|
+
bucket = oss2.Bucket(auth, Endpoint, BucketName, connect_timeout=600)
|
|
222
|
+
with open(file, "rb") as f:
|
|
223
|
+
byte_data = f.read()
|
|
224
|
+
file_name = Path(file).name
|
|
225
|
+
publish_name = f"ryry/report/{file_name}"
|
|
226
|
+
bucket.put_object(publish_name, byte_data)
|
|
227
|
+
return f"{cdn}{publish_name}"
|
|
228
|
+
else:
|
|
229
|
+
print(f"get_oss_config fail: response={data}")
|
|
230
|
+
|
|
231
|
+
def process_is_alive(pid: int) -> bool:
|
|
232
|
+
try:
|
|
233
|
+
process = psutil.Process(pid)
|
|
234
|
+
pstatus = process.status()
|
|
235
|
+
if pstatus == psutil.STATUS_RUNNING or pstatus == psutil.STATUS_SLEEPING:
|
|
236
|
+
return True
|
|
237
|
+
else:
|
|
238
|
+
return False
|
|
239
|
+
except (FileNotFoundError, psutil.NoSuchProcess):
|
|
240
|
+
return False
|
|
241
|
+
except Exception as e:
|
|
242
|
+
return False
|
|
243
|
+
|
|
244
|
+
def process_is_zombie_but_cannot_kill(pid: int) -> bool:
|
|
245
|
+
try:
|
|
246
|
+
process = psutil.Process(pid)
|
|
247
|
+
pstatus = process.status()
|
|
248
|
+
if pstatus == psutil.STATUS_DISK_SLEEP:
|
|
249
|
+
return True
|
|
250
|
+
except Exception as e:
|
|
251
|
+
return False
|
|
252
|
+
return False
|
|
253
|
+
|
|
254
|
+
def firstExitWithDir(root, suffix):
|
|
255
|
+
for root,dirs,files in os.walk(root):
|
|
256
|
+
for file in files:
|
|
257
|
+
if file.find(".") <= 0:
|
|
258
|
+
continue
|
|
259
|
+
ext = file[file.rindex("."):]
|
|
260
|
+
if ext == f".{suffix}":
|
|
261
|
+
return os.path.join(root, file)
|
|
262
|
+
if root != files:
|
|
263
|
+
break
|
|
264
|
+
return None
|
|
265
|
+
|
|
266
|
+
def begin_restart(reason, update_cli=False, simple="https://pypi.python.org/simple/"):
|
|
267
|
+
thisFileDir = os.path.dirname(os.path.abspath(__file__))
|
|
268
|
+
restart_file = os.path.join(thisFileDir, "restart")
|
|
269
|
+
if os.path.exists(restart_file):
|
|
270
|
+
os.remove(restart_file)
|
|
271
|
+
stop_file = os.path.join(thisFileDir, "stop.now")
|
|
272
|
+
with open(stop_file, 'w') as f:
|
|
273
|
+
f.write("")
|
|
274
|
+
with open(restart_file, 'w') as f:
|
|
275
|
+
json.dump({
|
|
276
|
+
"reason": reason,
|
|
277
|
+
"update_cli": update_cli,
|
|
278
|
+
"simple": simple
|
|
279
|
+
},f)
|
|
280
|
+
|
|
281
|
+
def check_restart():
|
|
282
|
+
thisFileDir = os.path.dirname(os.path.abspath(__file__))
|
|
283
|
+
restart_file = os.path.join(thisFileDir, "restart")
|
|
284
|
+
if os.path.exists(restart_file) == False:
|
|
285
|
+
return
|
|
286
|
+
from ryry import taskUtils
|
|
287
|
+
from ryry import store
|
|
288
|
+
import time, calendar, platform, subprocess
|
|
289
|
+
reason = "unknow"
|
|
290
|
+
update_cli = False
|
|
291
|
+
simple = "https://pypi.python.org/simple/"
|
|
292
|
+
try:
|
|
293
|
+
with open(restart_file, 'r') as f:
|
|
294
|
+
config = json.load(f)
|
|
295
|
+
reason = config["reason"]
|
|
296
|
+
update_cli = config["update_cli"]
|
|
297
|
+
simple = config["simple"]
|
|
298
|
+
except:
|
|
299
|
+
pass
|
|
300
|
+
|
|
301
|
+
if platform.system() == 'Windows':
|
|
302
|
+
time_task_file = os.path.join(thisFileDir, "update_ryry.bat")
|
|
303
|
+
elif platform.system() == 'Linux' or platform.system() == 'Darwin':
|
|
304
|
+
time_task_file = os.path.join(thisFileDir, "update_ryry.sh")
|
|
305
|
+
else:
|
|
306
|
+
time_task_file = os.path.join(thisFileDir, "update_ryry.txt")
|
|
307
|
+
if os.path.exists(time_task_file):
|
|
308
|
+
os.remove(time_task_file)
|
|
309
|
+
|
|
310
|
+
def getCommandResult(cmd):
|
|
311
|
+
try:
|
|
312
|
+
result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
|
|
313
|
+
if result.returncode == 0:
|
|
314
|
+
return result.stdout.decode(encoding="utf8", errors="ignore").replace("\n","").strip()
|
|
315
|
+
except subprocess.CalledProcessError as e:
|
|
316
|
+
print(f"getCommandResult fail {e}")
|
|
317
|
+
return ""
|
|
318
|
+
print(" restart_ryry_cli begin...")
|
|
319
|
+
taskUtils.restartNotify(reason)
|
|
320
|
+
restart_command = "ryry service start"
|
|
321
|
+
threadNum = store.get_multithread()
|
|
322
|
+
if threadNum > 1:
|
|
323
|
+
restart_command = f"{restart_command} -thread {threadNum}"
|
|
324
|
+
restart_command = f"{restart_command}"
|
|
325
|
+
if platform.system() == 'Windows':
|
|
326
|
+
new_time = datetime.now() + timedelta(minutes=1)
|
|
327
|
+
win_time = new_time.strftime("%H:%M")
|
|
328
|
+
with open(time_task_file, 'w') as f:
|
|
329
|
+
if update_cli:
|
|
330
|
+
f.write(f'''pip uninstall ryry-cli -y
|
|
331
|
+
pip install -U ryry-cli -i {simple} --extra-index-url https://pypi.python.org/simple/
|
|
332
|
+
start /B {restart_command}''')
|
|
333
|
+
else:
|
|
334
|
+
f.write(f'''start /B {restart_command}''')
|
|
335
|
+
result = subprocess.Popen(['schtasks', '/create', '/sc', 'ONCE', '/st', f'{win_time}', '/tn', f'ryryUpdate-{calendar.timegm(time.gmtime())}', '/tr', f"\"{time_task_file}\""], shell=True)
|
|
336
|
+
print(f"{result.stdout}\n{result.stderr}")
|
|
337
|
+
elif platform.system() == 'Linux' or platform.system() == 'Darwin':
|
|
338
|
+
def run_subprocess(s):
|
|
339
|
+
r = subprocess.run(s, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
|
|
340
|
+
print(f"{r.stdout}\n{r.stderr}")
|
|
341
|
+
if len(getCommandResult("which at")) <= 0:
|
|
342
|
+
run_subprocess(f"apt-get update")
|
|
343
|
+
run_subprocess(f"apt-get install -y at libopencv-features2d-dev=4.5.4+dfsg-9ubuntu4 systemctl")
|
|
344
|
+
run_subprocess(f"systemctl start atd")
|
|
345
|
+
with open(time_task_file, 'w') as f:
|
|
346
|
+
if update_cli:
|
|
347
|
+
f.write(f'''#!/bin/bash
|
|
348
|
+
pip uninstall ryry-cli -y
|
|
349
|
+
pip install -U ryry-cli -i {simple} --extra-index-url https://pypi.python.org/simple/
|
|
350
|
+
nohup {restart_command} &''')
|
|
351
|
+
else:
|
|
352
|
+
f.write(f'''#!/bin/bash
|
|
353
|
+
nohup {restart_command} &''')
|
|
354
|
+
ot = os.path.join(thisFileDir, "update_ryry.out")
|
|
355
|
+
result = subprocess.run(f"at now + 1 minutes -f {time_task_file} > {ot}", stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
|
|
356
|
+
print(f"{result.stdout}\n{result.stderr}")
|
|
357
|
+
os.remove(restart_file)
|
|
358
|
+
print("one minute later must be start!")
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Copyright 2023 https://www.dalipen.com/
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
4
|
+
|
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: ryry-cli
|
|
3
|
+
Version: 1.0
|
|
4
|
+
Summary: ryry tools
|
|
5
|
+
Home-page: https://github.com/dalipenMedia
|
|
6
|
+
Author: dalipen
|
|
7
|
+
Author-email: dalipen01@gmail.com
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Requires-Python: >=3.4
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
Requires-Dist: requests
|
|
15
|
+
Requires-Dist: uuid
|
|
16
|
+
Requires-Dist: Image
|
|
17
|
+
Requires-Dist: pillow
|
|
18
|
+
Requires-Dist: protobuf
|
|
19
|
+
Requires-Dist: psutil
|
|
20
|
+
Requires-Dist: pynvml
|
|
21
|
+
Requires-Dist: requests-toolbelt
|
|
22
|
+
Requires-Dist: matplotlib
|
|
23
|
+
Requires-Dist: ping3
|
|
24
|
+
Requires-Dist: piexif
|
|
25
|
+
Requires-Dist: gputil
|
|
26
|
+
Requires-Dist: urlparser
|
|
27
|
+
Requires-Dist: setuptools
|
|
28
|
+
Requires-Dist: twine
|
|
29
|
+
Requires-Dist: python-crontab
|
|
30
|
+
|
|
31
|
+
ryry Python Tool
|
|
32
|
+
===============================================
|
|
33
|
+
The ryry Python Tool is a official tool, you can use it to **Register** device to ryry server, other person can use **ryry Application** assign tasks to you for implementation
|
|
34
|
+
|
|
35
|
+
Installation
|
|
36
|
+
------------
|
|
37
|
+
|
|
38
|
+
The ryry requires [Python](http://www.python.org/download) 3.10.6 or later.
|
|
39
|
+
|
|
40
|
+
##### Installing
|
|
41
|
+
pip install ryry-cli
|
|
42
|
+
|
|
43
|
+
##### Uninstalling
|
|
44
|
+
pip uninstall ryry-cli
|
|
45
|
+
|
|
46
|
+
Use
|
|
47
|
+
------------
|
|
48
|
+
##### 1. Running
|
|
49
|
+
$ ryry service start
|
|
50
|
+
start a process to wait for the server to issue tasks. **Please do not close it**
|
|
51
|
+
|
|
52
|
+
Module Developer
|
|
53
|
+
------------
|
|
54
|
+
$ ryry widget init
|
|
55
|
+
|
|
56
|
+
in empty folder, use above command craete a ryry module, structure is like
|
|
57
|
+
|
|
58
|
+
[widget folder]
|
|
59
|
+
|-- config.json //*required, do not change*
|
|
60
|
+
|-- main.py //*required, do not change*
|
|
61
|
+
|-- run.py
|
|
62
|
+
|
|
63
|
+
if other person share widget code to you , you can add widget path in your computer to ryry environment
|
|
64
|
+
|
|
65
|
+
$ ryry widget add [path_with_widget_code]
|
|
66
|
+
|
|
67
|
+
you can modify script and h5 file yourself, then publish to ryry sever
|
|
68
|
+
|
|
69
|
+
$ ryry widget publish
|
|
70
|
+
|
|
71
|
+
get ryry status
|
|
72
|
+
$ ryry services status
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
ryry/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
ryry/constant.py,sha256=l7BxTcRrq4VngqIsy1UZkIjM2TckIWUkvhhAlmZX2nk,150
|
|
3
|
+
ryry/main.py,sha256=wQXEkj3YZMYkYjtXsmT03sCbHfzJJ136fefx1Tguwck,10438
|
|
4
|
+
ryry/ryry_server_socket.py,sha256=bZsN1UwNkM6SAmTFmRK7o_cU_-4bL_ME5iqJ59l_5-Q,5895
|
|
5
|
+
ryry/ryry_service.py,sha256=gyB-d0o-ROL4Bo_k6ClMKH7akaPwIt0fDgYHyDxEanw,9198
|
|
6
|
+
ryry/ryry_webapi.py,sha256=NLuJ7N1n_dZftInWkkaG7ZVZdYrBOnwE0h33LGUPRRg,8105
|
|
7
|
+
ryry/ryry_widget.py,sha256=73-J7M10CU_G4KvtpzAPbP0vHBs16Bim2DidnTvhwx4,14641
|
|
8
|
+
ryry/server_func.py,sha256=1c1PW_Gr568XlAwfHwNFEGPXUqeqJJMBaVqhdSb4iOI,2447
|
|
9
|
+
ryry/store.py,sha256=_xeCH8Q68pEEPe7aYr9Vfc8UVuLO3juSMAGbDuuuj_4,4375
|
|
10
|
+
ryry/task.py,sha256=LGqhk_-RpyH9yFPudqif53WSj-vnlHq2tryvo_Zn86E,8723
|
|
11
|
+
ryry/taskUtils.py,sha256=asnr5opQDesMK1TkG79wQC6RZj99xuDcBdLe0J3xkDg,10277
|
|
12
|
+
ryry/upload.py,sha256=TUldEew7iwve4TRojNsIt706vA6izh9CaA6clLfCuZ4,5279
|
|
13
|
+
ryry/utils.py,sha256=7QR67JAOPYveCwhjntj3ctnSh1sDn1vHvFx0O18d-UE,13198
|
|
14
|
+
ryry/script_template/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
|
+
ryry/script_template/main.py,sha256=2ywgwhL0XA1fO-ufxR0AubT7q1KdDI6waSfEMVrBPK0,893
|
|
16
|
+
ryry/script_template/run.py,sha256=iLHbjGoHL0_A26R2EbRogsyXLWkWfWH3jrYqw9wkTrY,495
|
|
17
|
+
ryry_cli-1.0.dist-info/LICENSE,sha256=MeYPss-bnfrn3Fu_fVxdNBhLFiCAHywtGVLQzQWw2Oc,1077
|
|
18
|
+
ryry_cli-1.0.dist-info/METADATA,sha256=FlMpqWqAoiGf4kTsOMELy-_iLZ3WMjAkk9Z8KHMZAbs,2013
|
|
19
|
+
ryry_cli-1.0.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92
|
|
20
|
+
ryry_cli-1.0.dist-info/entry_points.txt,sha256=0Hf0kMFkZhv1zASQaBZkpDyVBxwPLPV6_P59O5AuFlQ,40
|
|
21
|
+
ryry_cli-1.0.dist-info/top_level.txt,sha256=blmPfw7PDn2CArFtSzCw8i_AaGsxh77Ta3Kvo46j4dI,26
|
|
22
|
+
ryry_cli-1.0.dist-info/RECORD,,
|