bcmd 0.6.8__py3-none-any.whl → 0.6.9__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.

Potentially problematic release.


This version of bcmd might be problematic. Click here for more details.

bcmd/tasks/image.py CHANGED
@@ -1,9 +1,6 @@
1
- from __future__ import annotations
2
-
3
1
  import asyncio
4
2
  import os
5
3
  import random
6
- import tkinter as tk
7
4
  from enum import StrEnum
8
5
  from pathlib import Path
9
6
  from typing import Final, List, Tuple
@@ -16,9 +13,6 @@ from beni.bfunc import syncCall
16
13
  from beni.btype import Null, XPath
17
14
  from PIL import Image, ImageDraw, ImageFont
18
15
 
19
- from bcmd.utils.tkUtil import TkForm, setWidgetEnabled
20
- from tkinter import messagebox
21
-
22
16
  app: Final = btask.newSubApp('图片工具集')
23
17
 
24
18
 
@@ -310,67 +304,66 @@ async def merge(
310
304
  bcolor.printGreen('OK')
311
305
 
312
306
 
313
- @app.command()
314
- @syncCall
315
- async def xone():
316
- def showGui():
317
- app = TkForm()
318
- app.title('图片操作')
319
- entry = app.addEntry('保存文件', tk.StringVar(value=r'C:\project\docs\source\docs\public\icon.webp'), width=60)
320
- app.addEntry('输入密码', tk.StringVar(), password=True, width=60, command=lambda: messagebox.showerror('错误', '密码错误'))
321
-
322
- scrolltextVar = tk.StringVar(value='xxiioo')
323
- app.addScrolledText('测试信箱', scrolltextVar)
324
-
325
-
326
- radioVarScale = app.addRadioBtnList(
327
- '缩放操作',
328
- [
329
- '保持',
330
- '缩放比',
331
- '指定宽度',
332
- '指定高度',
333
- ],
334
- selectedIndex=0,
335
- onChanged=lambda x: onScaleValueChanged(x),
336
- )
337
-
338
- scaleValueEntry = app.addEntry('缩放参数', tk.StringVar(), width=10, justify=tk.CENTER)
339
-
340
- app.addChoisePath('选择文件', tk.StringVar(), isDir=True, focus=True)
341
-
342
- radioVarFormat = app.addRadioBtnList(
343
- '格式转换',
344
- [
345
- '保持',
346
- 'PNG',
347
- 'JPEG',
348
- 'WEBP',
349
- ],
350
- selectedIndex=0,
351
- )
352
- app.addCheckBox('去除透明', '去除透明', False)
353
- app.addCheckBox('TinyPng', 'TinyPng', True)
354
- app.addCheckBoxList('其他选项', [
355
- ('去除透明', False),
356
- ('TinyPng', True),
357
- ])
358
-
359
- def onScaleValueChanged(value: str):
360
- match value:
361
- case '保持':
362
- setWidgetEnabled(scaleValueEntry, False)
363
- case _:
364
- setWidgetEnabled(scaleValueEntry, True)
365
-
366
- app.addBtn('确定', lambda: onBtn())
367
-
368
- def onBtn():
369
- nonlocal result
370
- app.destroy()
371
-
372
- result: str = ''
373
- app.run()
374
- return result
375
-
376
- showGui()
307
+ # @app.command()
308
+ # @syncCall
309
+ # async def xone():
310
+ # def showGui():
311
+ # app = TkForm()
312
+ # app.title('图片操作')
313
+ # entry = app.addEntry('保存文件', tk.StringVar(value=r'C:\project\docs\source\docs\public\icon.webp'), width=60)
314
+ # app.addEntry('输入密码', tk.StringVar(), password=True, width=60, command=lambda: messagebox.showerror('错误', '密码错误'))
315
+
316
+ # scrolltextVar = tk.StringVar(value='xxiioo')
317
+ # app.addScrolledText('测试信箱', scrolltextVar)
318
+
319
+ # radioVarScale = app.addRadioBtnList(
320
+ # '缩放操作',
321
+ # [
322
+ # '保持',
323
+ # '缩放比',
324
+ # '指定宽度',
325
+ # '指定高度',
326
+ # ],
327
+ # onChanged=lambda x: onScaleValueChanged(x),
328
+ # var=tk.StringVar(value='保持'),
329
+ # )
330
+
331
+ # scaleValueEntry = app.addEntry('缩放参数', tk.StringVar(), width=10, justify=tk.CENTER)
332
+
333
+ # app.addChoisePath('选择文件', tk.StringVar(), isDir=True)
334
+
335
+ # radioVarFormat = app.addRadioBtnList(
336
+ # '格式转换',
337
+ # [
338
+ # '保持',
339
+ # 'PNG',
340
+ # 'JPEG',
341
+ # 'WEBP',
342
+ # ],
343
+ # var=tk.StringVar(value='保持'),
344
+ # )
345
+ # app.addCheckBox('去除透明', '去除透明', tk.BooleanVar(value=True))
346
+ # app.addCheckBox('TinyPng', 'TinyPng', tk.BooleanVar())
347
+ # app.addCheckBoxList('其他选项', [
348
+ # ('去除透明', tk.BooleanVar()),
349
+ # ('TinyPng', tk.BooleanVar(value=True)),
350
+ # ])
351
+
352
+ # def onScaleValueChanged(value: str):
353
+ # match value:
354
+ # case '保持':
355
+ # setWidgetEnabled(scaleValueEntry, False)
356
+ # case _:
357
+ # setWidgetEnabled(scaleValueEntry, True)
358
+
359
+ # app.addBtn('确定', lambda: onBtn())
360
+
361
+ # def onBtn():
362
+ # nonlocal result
363
+ # app.destroy()
364
+
365
+ # result: str = ''
366
+ # app.run()
367
+ # return result
368
+
369
+ # showGui()
bcmd/tasks/lib.py CHANGED
@@ -1,13 +1,13 @@
1
1
  import os
2
+ import tkinter as tk
2
3
  from pathlib import Path
3
4
  from typing import Final
4
5
 
5
6
  import typer
6
7
  from beni import bcolor, bfile, bpath, brun, btask
8
+ from beni.bform import BForm
7
9
  from beni.bfunc import syncCall
8
10
 
9
- from bcmd.utils.tkUtil import TkForm
10
-
11
11
  from ..common import secret
12
12
 
13
13
  app: Final = btask.newSubApp('lib 工具')
@@ -23,7 +23,7 @@ async def update_version(
23
23
  file = path / 'pyproject.toml'
24
24
  btask.assertTrue(file.is_file(), '文件不存在', file)
25
25
  data = await bfile.readToml(file)
26
- latestVersion = data['project']['version']
26
+ latestVersion: str = data['project']['version']
27
27
  vAry = [int(x) for x in latestVersion.split('.')]
28
28
  versionList = [
29
29
  f'{vAry[0] + 1}.0.0',
@@ -31,27 +31,24 @@ async def update_version(
31
31
  f'{vAry[0]}.{vAry[1]}.{vAry[2] + 1}',
32
32
  ]
33
33
 
34
- def showGui():
35
- app = TkForm()
36
- app.title('bcmd 版本更新')
37
- app.addLabel('当前版本号', latestVersion)
38
- version_var = app.addRadioBtnList(
39
- '请选择新版本',
40
- versionList,
41
- selectedIndex=-1,
42
- )
43
- result: str = ''
34
+ class UpdateVersionForm(BForm):
44
35
 
45
- def onBtn():
46
- nonlocal result
47
- result = version_var.get()
48
- app.destroy()
36
+ def __init__(self):
37
+ super().__init__()
38
+ self.versionVar = tk.StringVar(value=versionList[-1])
39
+ self.title('bcmd 版本更新')
40
+ self.addLabel('当前版本号', latestVersion)
41
+ self.addRadioBtnList(
42
+ '请选择新版本',
43
+ versionList,
44
+ var=self.versionVar,
45
+ )
46
+ self.addBtn('确定', self.destroy, focus=True)
49
47
 
50
- app.addBtn('确定', onBtn, focus=True)
51
- app.run()
52
- return result
48
+ def getResult(self) -> str:
49
+ return self.versionVar.get()
53
50
 
54
- newVersion = showGui()
51
+ newVersion: str = UpdateVersionForm().run()
55
52
  if not newVersion:
56
53
  btask.abort('用户取消操作')
57
54
  content = await bfile.readText(file)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bcmd
3
- Version: 0.6.8
3
+ Version: 0.6.9
4
4
  Summary: Commands for Beni
5
5
  Author-email: Beni Mang <benimang@126.com>
6
6
  Maintainer-email: Beni Mang <benimang@126.com>
@@ -8,7 +8,7 @@ Keywords: benimang,beni,bcmd
8
8
  Requires-Python: >=3.10
9
9
  Requires-Dist: aioconsole==0.8.1
10
10
  Requires-Dist: async-lru==2.0.5
11
- Requires-Dist: benimang==0.8.1
11
+ Requires-Dist: benimang==0.8.6
12
12
  Requires-Dist: cryptography==45.0.4
13
13
  Requires-Dist: nest-asyncio==1.6.0
14
14
  Requires-Dist: pillow==11.2.1
@@ -9,9 +9,9 @@ bcmd/tasks/code.py,sha256=IUs_ClZuSsBk2gavlitC8mkRrQQX9rvNDgR8cFxduBA,3992
9
9
  bcmd/tasks/crypto.py,sha256=LKvgsMPLvsi1wlt66TinYiN-oV2IPAfaN9y7hWaVpHs,2951
10
10
  bcmd/tasks/debian.py,sha256=B9aMIIct3vNqMJr5hTr1GegXVf20H49C27FMvRRGIzI,3004
11
11
  bcmd/tasks/download.py,sha256=XdZYKi8zQTNYWEgUxeTNDqPgP7IGYJkMmlDDC9u93Vk,2315
12
- bcmd/tasks/image.py,sha256=OQxrtTkPnJ_FZ6uenxdNlynhxwrAVy1P_68QAnSBYB0,14238
12
+ bcmd/tasks/image.py,sha256=_ck-WVfUlyQ2fZTpVPcpcurWSud7AkANKUuFjMW7MwA,14283
13
13
  bcmd/tasks/json.py,sha256=WWOyvcZPYaqQgp-Tkm-uIJschNMBKPKtZN3yXz_SC5s,635
14
- bcmd/tasks/lib.py,sha256=ODF21sTjQ687X5AXGOvJjjw6dGNSnflwSz4wDlIbYVM,2861
14
+ bcmd/tasks/lib.py,sha256=CmIRUHzNSa6s0Ft2oYZcfEr-5YwvxrVCNM55qq9sBXg,2948
15
15
  bcmd/tasks/math.py,sha256=xbl5UdaDMyAjiLodDPleP4Cutrk2S3NOAgurzAgOEAE,2862
16
16
  bcmd/tasks/mirror.py,sha256=nAe8NYftMKzht16MFBj7RqXwvVhR6Jh2uuAyJLh87og,1098
17
17
  bcmd/tasks/pdf.py,sha256=fkHRgxqzrRxdb4_-9pL9wp2roqAHJPS_dVqAGJvRUsM,1504
@@ -20,14 +20,13 @@ bcmd/tasks/time.py,sha256=ZiqA1jdgl-TBtFSOxxP51nwv4g9iZItmkFKpf9MKelk,2453
20
20
  bcmd/tasks/upgrade.py,sha256=z9Ein8U_Co7fsijPxyDFM8tXBFCp4bWATImwwwvC5ho,536
21
21
  bcmd/tasks/wasabi.py,sha256=xWFAxprSIlBqDDMGaNXZFb-SahnW1d_R9XxSKRYIhnM,3110
22
22
  bcmd/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
23
- bcmd/utils/tkUtil.py,sha256=zhOFQB0SN-ZPSXgJ0-pyHeVldf_u8VNnODz7pQRbLkw,7709
24
23
  test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
24
  test/conftest.py,sha256=grlPunlsvrkt_8QPckmF4POiKUPVxIxm2TPAh_ZB-zs,405
26
25
  test/test_pdf.py,sha256=7yYlfydyhy2dmVYdTA5Vir2AI8TUdzEi55fL-AqJmio,1533
27
26
  test/test_proxy.py,sha256=UMF2hFFGUEbJR1jT2mO_wdo-7Rfp0NDqIdTRnOmwtjY,164
28
27
  test/test_wasabi.py,sha256=qqXG1Kb9hKH6t624R173j6LagkgmejN0CFYt7kL0nNs,1066
29
- bcmd-0.6.8.dist-info/METADATA,sha256=cN10mQH_WWDQ2McdparDnOZkc6KS5a0JOULMxkd8sXs,812
30
- bcmd-0.6.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
31
- bcmd-0.6.8.dist-info/entry_points.txt,sha256=mriCeYh3wksKcqq3-LtzyFkSCIdN1uZc1IJwom-SW1s,34
32
- bcmd-0.6.8.dist-info/top_level.txt,sha256=fYY6tRrJ_G7tn24RXAG0M5ZKbcuaQznodfX1toFPSKs,10
33
- bcmd-0.6.8.dist-info/RECORD,,
28
+ bcmd-0.6.9.dist-info/METADATA,sha256=dUP3hFm6hT4tvf13ubEiaPvjyA5tloVlls7RlQQiNTE,812
29
+ bcmd-0.6.9.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
30
+ bcmd-0.6.9.dist-info/entry_points.txt,sha256=mriCeYh3wksKcqq3-LtzyFkSCIdN1uZc1IJwom-SW1s,34
31
+ bcmd-0.6.9.dist-info/top_level.txt,sha256=fYY6tRrJ_G7tn24RXAG0M5ZKbcuaQznodfX1toFPSKs,10
32
+ bcmd-0.6.9.dist-info/RECORD,,
bcmd/utils/tkUtil.py DELETED
@@ -1,243 +0,0 @@
1
- import tkinter as tk
2
- from tkinter import filedialog
3
- from tkinter.scrolledtext import ScrolledText
4
- from typing import Any, Callable, Literal, TypeVar, Union
5
- from uuid import uuid4
6
-
7
- RADIO_NOTHING = uuid4().hex
8
- TkVar = TypeVar('TkVar', bound=Union[tk.StringVar, tk.IntVar, tk.DoubleVar, tk.BooleanVar])
9
-
10
-
11
- class TkForm(tk.Tk):
12
-
13
- _rowIndex = -1
14
- _initList: list[Callable[..., None]] = []
15
- _varList: list[tk.Variable] = [] # 用来存储 var 变量,避免传出去,外面没有接收导致界面异常
16
-
17
- def __init__(self):
18
- super().__init__()
19
- self.resizable(False, False)
20
- self.bind("<Map>", self._onInit)
21
-
22
- def _onInit(self, evt: tk.Event):
23
- if evt.widget == self:
24
- for callback in self._initList:
25
- callback()
26
- self._initList.clear()
27
-
28
- def addInitHandler(self, handler: Callable[..., None]):
29
- self._initList.append(handler)
30
-
31
- def _initVar(self, var: TkVar) -> TkVar:
32
- self._varList.append(var)
33
- return var
34
-
35
- def run(self):
36
- self.center()
37
- self.mainloop()
38
-
39
- def center(self):
40
- self.withdraw() # 先隐藏窗口,避免闪动
41
- self.update_idletasks() # 确保获取正确的窗口尺寸
42
- width = self.winfo_width() # 获取窗口宽度
43
- height = self.winfo_height() # 获取窗口高度
44
- screen_width = self.winfo_screenwidth() # 屏幕宽度
45
- screen_height = self.winfo_screenheight() # 屏幕高度
46
- x = (screen_width - width) // 2 # 水平居中
47
- y = (screen_height - height) // 2 # 垂直居中
48
- self.geometry(f"+{x}+{y}") # 设置窗口位置
49
- self.deiconify() # 恢复显示窗口
50
-
51
- def addRow(self, desc: str, widget: tk.Widget):
52
- self._rowIndex += 1
53
- tk.Label(text=desc).grid(row=self._rowIndex, column=0, padx=10, pady=5, sticky='e')
54
- widget.grid(row=self._rowIndex, column=1, padx=10, pady=5, sticky='w')
55
-
56
- def addRowFrame(self):
57
- self._rowIndex += 1
58
- frame = tk.Frame(self)
59
- frame.grid(row=self._rowIndex, column=0, columnspan=2, padx=10, pady=5)
60
- return frame
61
-
62
- def addRowFrameWithDesc(self, desc: str):
63
- self._rowIndex += 1
64
- tk.Label(text=desc).grid(row=self._rowIndex, column=0, padx=10, pady=5, sticky='e')
65
- frame = tk.Frame(self)
66
- frame.grid(row=self._rowIndex, column=1, padx=10, pady=5, sticky='w')
67
- return frame
68
-
69
- def addLabel(
70
- self,
71
- desc: str,
72
- text: str
73
- ):
74
- self.addRow(desc, tk.Label(text=text))
75
-
76
- def addBtn(
77
- self,
78
- label: str,
79
- command: Callable[..., None],
80
- *,
81
- width: int = 20,
82
- focus: bool = False
83
- ):
84
- frame = self.addRowFrame()
85
- btn = tk.Button(frame, text=label, width=width, command=command)
86
- btn.pack(side="left", expand=True, padx=15)
87
- if focus:
88
- self._initFocus(btn)
89
-
90
- def addRadioBtnList(
91
- self,
92
- desc: str,
93
- selectionList: list[str],
94
- *,
95
- selectedIndex: int | None = None,
96
- focusIndex: int | None = None,
97
- onChanged: Callable[[str], None] | None = None,
98
- ):
99
- frame = tk.Frame()
100
- self.addRow(desc, frame)
101
- var = tk.StringVar(value=selectionList[selectedIndex] if selectedIndex is not None else RADIO_NOTHING)
102
- radioBtnList: list[tk.Radiobutton] = []
103
- for version in selectionList:
104
- radioBtn = tk.Radiobutton(frame, text=version, variable=var, value=version)
105
- radioBtn.pack(side="left", padx=(0, 15))
106
- setWidgetClickFocus(radioBtn)
107
- radioBtnList.append(radioBtn)
108
- if focusIndex is not None:
109
- self._initFocus(radioBtnList[focusIndex])
110
- if onChanged:
111
- var.trace_add('write', lambda *args: onChanged(var.get())) # type: ignore
112
- self.addInitHandler(
113
- lambda: onChanged(var.get())
114
- )
115
- return var
116
-
117
- def addEntry(
118
- self,
119
- desc: str,
120
- var: tk.StringVar,
121
- *,
122
- width: int = 60,
123
- focus: bool = False,
124
- justify: Literal['left', 'right', 'center'] = tk.LEFT,
125
- password: bool = False,
126
- command: Callable[..., Any] | None = None,
127
- ):
128
- self._initVar(var)
129
- entry = tk.Entry(self, width=width, justify=justify, textvariable=var)
130
- entry.icursor(tk.END)
131
- self.addRow(desc, entry)
132
- if password:
133
- entry.config(show='*')
134
- if focus:
135
- self._initFocus(entry)
136
- if command:
137
- entry.bind('<Return>', lambda event: command())
138
- return entry
139
-
140
- def addChoisePath(
141
- self,
142
- desc: str,
143
- var: tk.StringVar,
144
- *,
145
- width: int = 47,
146
- focus: bool = False,
147
- isDir: bool = False,
148
- ):
149
- self._initVar(var)
150
- frame = self.addRowFrameWithDesc(desc)
151
- entry = tk.Entry(frame, width=width, textvariable=var)
152
- entry.icursor(tk.END)
153
- entry.pack(side="left")
154
- btn = tk.Button(frame, text=f'选择{'目录' if isDir else '文件'} ...', width=10, command=lambda: onBtn())
155
- btn.pack(side="left", padx=(10, 0))
156
- if focus:
157
- self._initFocus(btn)
158
-
159
- def onBtn():
160
- if isDir:
161
- var.set(filedialog.askdirectory())
162
- else:
163
- var.set(filedialog.askopenfilename())
164
-
165
- def addScrolledText(
166
- self,
167
- desc: str,
168
- var: tk.StringVar,
169
- *,
170
- width: int = 60,
171
- height: int = 3,
172
- focus: bool = False,
173
- ):
174
- self._initVar(var)
175
- scrolledText = ScrolledText(self, width=width, height=height)
176
- scrolledText.insert(tk.END, var.get())
177
- self.addRow(desc, scrolledText)
178
-
179
- def on_text_change(*args: Any):
180
- new_value = scrolledText.get("1.0", tk.END)
181
- if new_value != var.get():
182
- var.set(new_value)
183
-
184
- scrolledText.bind("<KeyRelease>", on_text_change)
185
-
186
- def on_tab(event: tk.Event):
187
- widget = event.widget.tk_focusNext()
188
- assert widget
189
- widget.focus_set()
190
- return "break"
191
-
192
- scrolledText.bind("<Tab>", on_tab)
193
-
194
- if focus:
195
- self._initFocus(scrolledText)
196
- return scrolledText
197
-
198
- def addCheckBox(
199
- self,
200
- desc: str,
201
- text: str,
202
- value: bool = False,
203
- ):
204
- var = tk.BooleanVar(value=value)
205
- self._initVar(var)
206
- check_btn = tk.Checkbutton(text=text, variable=var)
207
- self.addRow(desc, check_btn)
208
- self.addInitHandler(
209
- lambda: var.set(var.get())
210
- )
211
- setWidgetClickFocus(check_btn)
212
- return var
213
-
214
- def addCheckBoxList(
215
- self,
216
- desc: str,
217
- dataList: list[tuple[str, bool]],
218
- ):
219
- varDict: dict[str, tk.BooleanVar] = {}
220
- frame = tk.Frame(self)
221
- self.addRow(desc, frame)
222
- for label, value in dataList:
223
- varDict[label] = tk.BooleanVar(value=value)
224
- checkbox = tk.Checkbutton(frame, text=label, variable=varDict[label])
225
- checkbox.pack(side="left", expand=True, padx=(0, 15))
226
- setWidgetClickFocus(checkbox)
227
- self.addInitHandler(
228
- lambda: varDict[label].set(varDict[label].get())
229
- )
230
- return varDict
231
-
232
- def _initFocus(self, widget: tk.Widget):
233
- self.addInitHandler(
234
- lambda: widget.focus_set()
235
- )
236
-
237
-
238
- def setWidgetEnabled(widget: tk.Widget, value: bool):
239
- widget['state'] = tk.NORMAL if value else tk.DISABLED
240
-
241
-
242
- def setWidgetClickFocus(widget: tk.Widget):
243
- widget.bind("<Button-1>", lambda args: args.widget.focus_set())
File without changes