pymecli 0.5.0__tar.gz → 0.5.1__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 (44) hide show
  1. {pymecli-0.5.0 → pymecli-0.5.1}/PKG-INFO +1 -1
  2. {pymecli-0.5.0 → pymecli-0.5.1}/cli/dst.py +111 -41
  3. {pymecli-0.5.0 → pymecli-0.5.1}/pyproject.toml +2 -2
  4. pymecli-0.5.0/cli/baidu.py +0 -93
  5. {pymecli-0.5.0 → pymecli-0.5.1}/.gitignore +0 -0
  6. {pymecli-0.5.0 → pymecli-0.5.1}/README.md +0 -0
  7. {pymecli-0.5.0 → pymecli-0.5.1}/api/__init__.py +0 -0
  8. {pymecli-0.5.0 → pymecli-0.5.1}/api/v1/__init__.py +0 -0
  9. {pymecli-0.5.0 → pymecli-0.5.1}/api/v1/clash.py +0 -0
  10. {pymecli-0.5.0 → pymecli-0.5.1}/api/v1/redis.py +0 -0
  11. {pymecli-0.5.0 → pymecli-0.5.1}/cli/__init__.py +0 -0
  12. {pymecli-0.5.0 → pymecli-0.5.1}/cli/bitget.py +0 -0
  13. {pymecli-0.5.0 → pymecli-0.5.1}/cli/example.py +0 -0
  14. {pymecli-0.5.0 → pymecli-0.5.1}/cli/fast.py +0 -0
  15. {pymecli-0.5.0 → pymecli-0.5.1}/cli/gate.py +0 -0
  16. {pymecli-0.5.0 → pymecli-0.5.1}/cli/redis_csv.py +0 -0
  17. {pymecli-0.5.0 → pymecli-0.5.1}/cli/util.py +0 -0
  18. {pymecli-0.5.0 → pymecli-0.5.1}/core/__init__.py +0 -0
  19. {pymecli-0.5.0 → pymecli-0.5.1}/core/clash.py +0 -0
  20. {pymecli-0.5.0 → pymecli-0.5.1}/core/config.py +0 -0
  21. {pymecli-0.5.0 → pymecli-0.5.1}/core/redis_client.py +0 -0
  22. {pymecli-0.5.0 → pymecli-0.5.1}/crypto/__init__.py +0 -0
  23. {pymecli-0.5.0 → pymecli-0.5.1}/crypto/bitget.py +0 -0
  24. {pymecli-0.5.0 → pymecli-0.5.1}/crypto/gate.py +0 -0
  25. {pymecli-0.5.0 → pymecli-0.5.1}/data/__init__.py +0 -0
  26. {pymecli-0.5.0 → pymecli-0.5.1}/data/dou_dict.py +0 -0
  27. {pymecli-0.5.0 → pymecli-0.5.1}/data/dou_list.py +0 -0
  28. {pymecli-0.5.0 → pymecli-0.5.1}/data/main.py +0 -0
  29. {pymecli-0.5.0 → pymecli-0.5.1}/data/template.yaml +0 -0
  30. {pymecli-0.5.0 → pymecli-0.5.1}/models/__init__.py +0 -0
  31. {pymecli-0.5.0 → pymecli-0.5.1}/models/douzero_model.py +0 -0
  32. {pymecli-0.5.0 → pymecli-0.5.1}/models/ocr_model.py +0 -0
  33. {pymecli-0.5.0 → pymecli-0.5.1}/models/response.py +0 -0
  34. {pymecli-0.5.0 → pymecli-0.5.1}/utils/__init__.py +0 -0
  35. {pymecli-0.5.0 → pymecli-0.5.1}/utils/elapsed.py +0 -0
  36. {pymecli-0.5.0 → pymecli-0.5.1}/utils/helper.py +0 -0
  37. {pymecli-0.5.0 → pymecli-0.5.1}/utils/logger.py +0 -0
  38. {pymecli-0.5.0 → pymecli-0.5.1}/utils/mysql.py +0 -0
  39. {pymecli-0.5.0 → pymecli-0.5.1}/utils/path.py +0 -0
  40. {pymecli-0.5.0 → pymecli-0.5.1}/utils/pd.py +0 -0
  41. {pymecli-0.5.0 → pymecli-0.5.1}/utils/pyredis.py +0 -0
  42. {pymecli-0.5.0 → pymecli-0.5.1}/utils/sleep.py +0 -0
  43. {pymecli-0.5.0 → pymecli-0.5.1}/utils/text.py +0 -0
  44. {pymecli-0.5.0 → pymecli-0.5.1}/utils/toml.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pymecli
3
- Version: 0.5.0
3
+ Version: 0.5.1
4
4
  Summary: My CLI
5
5
  Project-URL: Homepage, https://pypi.org/project/pymecli
6
6
  Project-URL: Repository, https://github.com/meme2046/pymecli
@@ -25,7 +25,7 @@ def get_mod_versions(workshop_ids: List[str]) -> Dict[str, Dict[str, Optional[st
25
25
  response.raise_for_status()
26
26
  result = response.json()
27
27
  except Exception as e:
28
- typer.secho(f"❌ Steam API 请求失败: {e}", fg=typer.colors.RED)
28
+ typer.secho(f"✗ Steam API 请求失败: {e}", fg=typer.colors.RED)
29
29
  return {}
30
30
 
31
31
  versions: Dict[str, Dict[str, Optional[str]]] = {}
@@ -65,48 +65,46 @@ def write_lua_file(file_path: str, data: dict):
65
65
  f.write("return " + lua.encode(data) + "\n")
66
66
 
67
67
 
68
- def get_client_mods_list(file_path: str, mod_id: str) -> Optional[tuple[dict, dict]]:
68
+ def get_client_mods(file_path: str, mod_id: str) -> Optional[tuple[dict, dict]]:
69
69
  """
70
- 解析 lua 文件,返回 (data, client_mods_list)。
71
- 失败返回 None(错误信息已由函数自行打印)。
70
+ 解析 lua 文件,返回 (data, client_mods)。
71
+ 失败返回 None(错误信息已由函数自行打印)。
72
72
  """
73
73
  try:
74
74
  data = parse_lua_file(file_path)
75
75
  except FileNotFoundError:
76
- typer.secho(f"❌ 文件不存在: {file_path}", fg=typer.colors.RED)
76
+ typer.secho(f"✗ 文件不存在: {file_path}", fg=typer.colors.RED)
77
77
  return None
78
78
  except Exception as e:
79
- typer.secho(f"❌ 解析 Lua 文件失败: {e}", fg=typer.colors.RED)
79
+ typer.secho(f"✗ 解析 Lua 文件失败: {e}", fg=typer.colors.RED)
80
80
  return None
81
81
 
82
82
  main_mod_key = f"workshop-{mod_id}"
83
83
  main_mod = data.get(main_mod_key)
84
84
  if not main_mod:
85
- typer.secho(f"❌ 未找到 {main_mod_key}", fg=typer.colors.RED)
86
- return None
85
+ typer.secho(f"✗ 未找到 {main_mod_key}", fg=typer.colors.RED)
86
+ return data, {}
87
87
 
88
- client_mods_list = main_mod.get("configuration_options", {}).get(
89
- "client_mods_list", {}
90
- )
91
- if not client_mods_list:
92
- typer.secho("❌ 未找到 client_mods_list", fg=typer.colors.RED)
93
- return None
88
+ client_mods = main_mod.get("configuration_options", {}).get("client_mods_list", {})
89
+ if not client_mods:
90
+ typer.secho("✗ 未找到 client_mods", fg=typer.colors.RED)
91
+ return data, {}
94
92
 
95
- return data, client_mods_list
93
+ return data, client_mods
96
94
 
97
95
 
98
96
  # update_client_mods
99
97
  @app.command()
100
- def cmu(
98
+ def convert_update(
101
99
  file_path: str = typer.Argument(
102
- "d:/.backups/dontstarvetogether/modoverrides.lua",
100
+ "d:/github/meme2046/docker/dst/modoverrides.lua",
103
101
  help="modoverrides.lua 文件路径",
104
102
  ),
105
103
  mod_id: str = typer.Option(
106
104
  "3486375086",
107
105
  "--mod-id",
108
106
  "-m",
109
- help="主 mod 的 workshop ID",
107
+ help="模组: 客户端Mod转为服务器Mod<3486375086>的ID, 固定值",
110
108
  ),
111
109
  output: List[str] = typer.Option(
112
110
  None,
@@ -115,34 +113,37 @@ def cmu(
115
113
  help="额外的输出路径,可多次指定",
116
114
  ),
117
115
  ):
118
- result = get_client_mods_list(file_path, mod_id)
116
+ """
117
+ 更新modoverrides.lua中<3486375086>的mods的版本信息
118
+ """
119
+ result = get_client_mods(file_path, mod_id)
119
120
  if result is None:
120
121
  raise typer.Exit(code=1)
121
- data, client_mods_list = result
122
+ data, client_mods = result
122
123
 
123
124
  workshop_ids = []
124
- for key in client_mods_list.keys():
125
+ for key in client_mods.keys():
125
126
  wid = extract_workshop_id(key)
126
127
  if wid:
127
128
  workshop_ids.append(wid)
128
129
 
129
130
  if not workshop_ids:
130
- typer.secho("❌ 未找到任何 client_mods", fg=typer.colors.RED)
131
+ typer.secho("✗ 未找到任何 client_mods", fg=typer.colors.RED)
131
132
  raise typer.Exit(code=1)
132
133
 
133
134
  typer.secho(
134
- f"🔍 发现 {len(workshop_ids)} 个 client mods,正在查询 Steam API...",
135
+ f"🔍 发现 {len(workshop_ids)} 个 client mods, 正在查询 Steam API...",
135
136
  fg=typer.colors.BLUE,
136
137
  )
137
138
  versions = get_mod_versions(workshop_ids)
138
139
 
139
140
  if not versions:
140
- typer.secho("❌ 未能获取版本信息", fg=typer.colors.RED)
141
+ typer.secho("✗ 未能获取steam版本信息", fg=typer.colors.RED)
141
142
  raise typer.Exit(code=1)
142
143
 
143
144
  typer.secho("📝 正在更新版本号...", fg=typer.colors.BLUE)
144
145
  updated_count = 0
145
- for mod_key, mod_info in client_mods_list.items():
146
+ for mod_key, mod_info in client_mods.items():
146
147
  wid = extract_workshop_id(mod_key)
147
148
  if not wid:
148
149
  continue
@@ -167,7 +168,7 @@ def cmu(
167
168
  )
168
169
  else:
169
170
  typer.secho(
170
- f"ℹ️ {mod_key} ({title}): 已是最新版本 {old_version}",
171
+ f"{mod_key} ({title}): 已是最新版本 {old_version}",
171
172
  fg=typer.colors.WHITE,
172
173
  )
173
174
 
@@ -180,43 +181,112 @@ def cmu(
180
181
  write_lua_file(p, data)
181
182
  typer.secho(f"💾 已保存到: {p}", fg=typer.colors.CYAN)
182
183
  except Exception as e:
183
- typer.secho(f"❌ 写入文件失败: {e}", fg=typer.colors.RED)
184
+ typer.secho(f"✗ 写入文件失败: {e}", fg=typer.colors.RED)
184
185
  raise typer.Exit(code=1)
185
186
 
186
187
  if updated_count > 0:
187
188
  typer.secho(f"\n🎉 成功更新 {updated_count} 个 mod 版本", fg=typer.colors.GREEN)
188
189
  else:
189
- typer.secho("\nℹ️ 所有 mod 已是最新版本", fg=typer.colors.YELLOW)
190
+ typer.secho("\n✅ 所有 mod 已是最新版本", fg=typer.colors.YELLOW)
190
191
 
191
192
 
192
- # list_client_mods
193
193
  @app.command()
194
- def cml(
194
+ def mod_setup(
195
195
  file_path: str = typer.Argument(
196
- "d:/.backups/dontstarvetogether/modoverrides.lua",
196
+ "d:/github/meme2046/docker/dst/modoverrides.lua",
197
197
  help="modoverrides.lua 文件路径",
198
198
  ),
199
199
  mod_id: str = typer.Option(
200
200
  "3486375086",
201
201
  "--mod-id",
202
202
  "-m",
203
- help="主 mod 的 workshop ID",
203
+ help="模组: 客户端Mod转为服务器Mod<3486375086>的ID, 固定值",
204
+ ),
205
+ output: List[str] = typer.Option(
206
+ ["dedicated_server_mods_setup.lua"],
207
+ "--output",
208
+ "-o",
209
+ help="mods_setup输出路径,可多次指定",
204
210
  ),
205
211
  ):
206
212
  """
207
- 列出 client_mods_list 中所有 mod 的当前版本
213
+ 列出所有 mod, 并以<dedicated_server_mods_setup>格式保存到指定文件
208
214
  """
209
- result = get_client_mods_list(file_path, mod_id)
215
+ result = get_client_mods(file_path, mod_id)
210
216
  if result is None:
211
217
  raise typer.Exit(code=1)
212
- _, client_mods_list = result
218
+ data, client_mods = result
219
+
220
+ client_ids = []
221
+ for key in client_mods.keys():
222
+ wid = extract_workshop_id(key)
223
+ if wid:
224
+ client_ids.append(wid)
225
+
226
+ server_ids = []
227
+ for key in data.keys():
228
+ wid = extract_workshop_id(key)
229
+ if wid:
230
+ server_ids.append(wid)
231
+
232
+ versions = get_mod_versions(server_ids + client_ids)
233
+
234
+ if not versions:
235
+ typer.secho("✗ 未能获取steam版本信息", fg=typer.colors.RED)
236
+ raise typer.Exit(code=1)
237
+
238
+ setup_list = []
239
+
240
+ typer.secho(
241
+ f"📢 server_mods({len(server_ids)}):",
242
+ fg=typer.colors.GREEN,
243
+ )
244
+
245
+ for item in server_ids:
246
+ mod_data = versions.get(item)
247
+
248
+ if mod_data is None:
249
+ typer.secho(f"✗ {item}: 未获取到版本信息", fg=typer.colors.YELLOW)
250
+ raise typer.Exit(code=1)
251
+
252
+ setup_list.append(f'ServerModSetup("{item}")')
253
+
254
+ new_version = mod_data.get("version")
255
+ title = mod_data.get("title", "")
256
+
257
+ typer.secho(
258
+ f"✅ {item} ({title}): {new_version}",
259
+ fg=typer.colors.WHITE,
260
+ )
261
+
262
+ typer.secho(
263
+ f"\n📋 client_mods({len(client_ids)}):",
264
+ fg=typer.colors.GREEN,
265
+ )
266
+
267
+ for item in client_ids:
268
+ mod_data = versions.get(item)
269
+
270
+ if mod_data is None:
271
+ typer.secho(f"✗ {item}: 未获取到版本信息", fg=typer.colors.YELLOW)
272
+ raise typer.Exit(code=1)
273
+
274
+ setup_list.append(f'ServerModSetup("{item}")')
275
+
276
+ new_version = mod_data.get("version")
277
+ title = mod_data.get("title", "")
278
+
279
+ typer.secho(
280
+ f"✅ {item} ({title}): {new_version}",
281
+ fg=typer.colors.WHITE,
282
+ )
213
283
 
214
- typer.secho("\n📋 client_mods_list 中的 mod 列表:", fg=typer.colors.BLUE)
215
- for i, (mod_key, mod_info) in enumerate(client_mods_list.items(), 1):
216
- version = mod_info.get("version", "unknown")
217
- typer.secho(f"{i}. {mod_key}: {version}", fg=typer.colors.WHITE)
284
+ for p in output:
285
+ with open(p, "w", encoding="utf-8") as f:
286
+ f.write("\n".join(setup_list))
287
+ typer.secho(f"\n💾 <setup_list>已保存到: {p}", fg=typer.colors.CYAN)
218
288
 
219
289
 
220
290
  if __name__ == "__main__":
221
- # cmu("d:/.backups/dontstarvetogether/modoverrides.lua", "3486375086")
222
- cml("d:/.backups/dontstarvetogether/modoverrides.lua", "3486375086")
291
+ # cmu("d:/github/meme2046/docker/dst/modoverrides.lua", "3486375086")
292
+ convert_update("d:/github/meme2046/docker/dst/modoverrides.lua", "3486375086")
@@ -35,14 +35,14 @@
35
35
  name = "pymecli"
36
36
  readme = "README.md"
37
37
  requires-python = ">=3.10"
38
- version = "0.5.0"
38
+ version = "0.5.1"
39
39
 
40
40
  [project.urls]
41
41
  Homepage = "https://pypi.org/project/pymecli"
42
42
  Repository = "https://github.com/meme2046/pymecli"
43
43
 
44
44
  [project.scripts]
45
- baidu = "cli.baidu:app"
45
+ # baidu = "cli.baidu:app"
46
46
  bitget = "cli.bitget:app"
47
47
  dst = "cli.dst:app"
48
48
  example = "cli.example:app"
@@ -1,93 +0,0 @@
1
- import json
2
-
3
- import typer
4
- from selenium import webdriver
5
- from selenium.webdriver.chrome.options import Options
6
- from selenium.webdriver.chrome.service import Service
7
- from webdriver_manager.chrome import ChromeDriverManager
8
-
9
- from utils.pyredis import get_redis_client_sync
10
-
11
- app = typer.Typer()
12
-
13
- r = get_redis_client_sync()
14
-
15
-
16
- @app.command()
17
- def acsToken(
18
- url: str = typer.Argument(
19
- "https://finance.baidu.com/index/ab-000001?name=%25E4%25B8%258A%25E8%25AF%2581%25E6%258C%2587%25E6%2595%25B0",
20
- help="request url",
21
- ),
22
- timeout: int = typer.Option(
23
- 10,
24
- "--timeout",
25
- "-t",
26
- help="timeout内如果没有请求完整,会强制中断,然后从已有的请求中获取数据",
27
- ),
28
- ):
29
- """通过selenium获取百度股事通Acs-Token
30
-
31
- Args:
32
- url (str, optional): 请求的『URL』地址. Defaults to typer.Argument( "https://finance.baidu.com/", help="request url", ).
33
- timeout (int, optional): _description_. Defaults to typer.Option( 3, "--timeout", "-t", help="timeout内如果没有请求完整,会强制中断,然后从已有的请求中获取数据", ).
34
-
35
- Returns:
36
- str: 『Acs-Token』字符串
37
- """
38
- # 配置 Chrome 浏览器以启用 Performance API
39
- chrome_options = Options()
40
- chrome_options.add_argument("--enable-logging")
41
- chrome_options.add_argument("--v=1")
42
- chrome_options.add_argument("--headless") # 启用无头模式
43
- chrome_options.add_argument("--disable-gpu") # 禁用 GPU 加速
44
- chrome_options.add_argument("--window-size=1920,1080") # 设置窗口大小
45
- chrome_options.add_argument("--no-sandbox") # 禁用沙盒模式
46
- chrome_options.add_argument("--disable-dev-shm-usage") # 禁用 /dev/shm 使用
47
- chrome_options.set_capability("goog:loggingPrefs", {"performance": "ALL"})
48
-
49
- driver = webdriver.Chrome(
50
- service=Service(ChromeDriverManager().install()), options=chrome_options
51
- )
52
- driver.set_page_load_timeout(timeout)
53
-
54
- try:
55
- driver.get(url)
56
- except Exception:
57
- driver.execute_script("window.stop();")
58
-
59
- # 从网络请求中提取 Acs-Token
60
- acs_token = get_acs_token_from_requests(driver)
61
-
62
- driver.quit()
63
-
64
- if acs_token:
65
- print(f"Acs-Token:『{acs_token}』")
66
- r.set("baidu.Acs-Token", acs_token)
67
-
68
- return acs_token
69
-
70
-
71
- def get_acs_token_from_requests(driver):
72
- """从网络请求中提取 Acs-Token"""
73
- # 获取性能日志
74
-
75
- logs = driver.get_log("performance")
76
-
77
- for entry in logs:
78
- log = json.loads(entry["message"])["message"]
79
-
80
- # 检查是否是网络请求
81
- if log["method"] == "Network.requestWillBeSent":
82
- request = log["params"].get("request", {})
83
- headers = request.get("headers", {})
84
-
85
- # 检查请求头中是否包含 Acs-Token
86
- if "Acs-Token" in headers:
87
- return headers["Acs-Token"]
88
-
89
- return ""
90
-
91
-
92
- if __name__ == "__main__":
93
- app()
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
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
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