psiutils 0.1.68__py3-none-any.whl → 0.1.70__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.
psiutils/_logger.py ADDED
@@ -0,0 +1,54 @@
1
+ import logging
2
+ from logging.handlers import RotatingFileHandler
3
+ import structlog
4
+
5
+ # === 1. Console handler with pretty dev output ===
6
+ console_handler = logging.StreamHandler()
7
+ console_handler.setLevel(logging.INFO)
8
+ console_handler.setFormatter(
9
+ structlog.stdlib.ProcessorFormatter(
10
+ processor=structlog.dev.ConsoleRenderer(),
11
+ foreign_pre_chain=[
12
+ structlog.processors.TimeStamper(fmt="iso"),
13
+ ],
14
+ )
15
+ )
16
+
17
+ # === 2. File handler with JSON output ===
18
+ file_handler = RotatingFileHandler(
19
+ "app.log", maxBytes=5_000_000, backupCount=5, encoding="utf-8"
20
+ )
21
+ file_handler.setLevel(logging.INFO)
22
+ file_handler.setFormatter(
23
+ structlog.stdlib.ProcessorFormatter(
24
+ processor=structlog.processors.JSONRenderer(), # Structured JSON
25
+ foreign_pre_chain=[
26
+ structlog.processors.TimeStamper(fmt="iso"),
27
+ ],
28
+ )
29
+ )
30
+
31
+ # === 3. Attach both handlers ===
32
+ root_logger = logging.getLogger()
33
+ root_logger.setLevel(logging.INFO)
34
+ root_logger.addHandler(console_handler)
35
+ root_logger.addHandler(file_handler)
36
+
37
+ # === 4. Configure structlog to use stdlib logging ===
38
+ structlog.configure(
39
+ processors=[
40
+ structlog.processors.TimeStamper(fmt="iso"),
41
+ structlog.stdlib.add_log_level,
42
+ structlog.stdlib.add_logger_name,
43
+ structlog.stdlib.PositionalArgumentsFormatter(),
44
+ structlog.processors.StackInfoRenderer(),
45
+ structlog.processors.format_exc_info,
46
+ structlog.stdlib.ProcessorFormatter.wrap_for_formatter,
47
+ ],
48
+ wrapper_class=structlog.make_filtering_bound_logger(logging.INFO),
49
+ context_class=dict,
50
+ logger_factory=structlog.stdlib.LoggerFactory(),
51
+ cache_logger_on_first_use=True,
52
+ )
53
+
54
+ logger = structlog.get_logger()
psiutils/_version.py CHANGED
@@ -1 +1 @@
1
- __version__ = '0.1.68'
1
+ __version__ = '0.1.70'
psiutils/buttons.py CHANGED
@@ -21,9 +21,9 @@ class IconButton(ttk.Frame):
21
21
  dimmable: bool = False,
22
22
  icon_path: str = '',
23
23
  **kwargs):
24
- super().__init__(master, borderwidth=1, relief="raised", **kwargs)
24
+ super().__init__(master, borderwidth=1, relief='raised', **kwargs)
25
25
  self.command = command
26
- self._state = 'normal'
26
+ self._state = tk.NORMAL
27
27
  self.text = button_text
28
28
  self.icon = icon
29
29
 
@@ -74,6 +74,8 @@ class IconButton(ttk.Frame):
74
74
  event.widget.winfo_toplevel().config(cursor=HAND)
75
75
 
76
76
  def _on_click(self, *args):
77
+ if self._state == tk.DISABLED:
78
+ return
77
79
  if self.command:
78
80
  self.command()
79
81
 
psiutils/menus.py CHANGED
@@ -12,8 +12,9 @@ class Menu(tk.Menu):
12
12
  super().__init__(root)
13
13
  self.menu_items = menu_items
14
14
  for menu_item in menu_items:
15
+ menu_item.menu = self
15
16
  self.add_command(label=menu_item.text, command=menu_item.command,
16
- underline= menu_item.underline,)
17
+ underline=menu_item.underline,)
17
18
 
18
19
  def enable(self, enable: bool = True) -> None:
19
20
  enable_menu_items(self, self.menu_items, enable)
@@ -32,8 +33,10 @@ class MenuItem():
32
33
  self.command: object = command
33
34
  self.dimmable = dimmable
34
35
  self.underline = None
36
+ self.menu = None
35
37
 
36
38
  if 'disabled' in kwargs and kwargs['disabled']:
39
+ self.state = tk.DISABLED
37
40
  self.disable()
38
41
  if 'underline' in kwargs:
39
42
  self.underline = kwargs['underline']
@@ -41,6 +44,12 @@ class MenuItem():
41
44
  def __repr__(self) -> str:
42
45
  return f'MenuItem: {self.text}'
43
46
 
47
+ def enable(self) -> None:
48
+ enable_menu_items(self.menu, [self], True)
49
+
50
+ def disable(self) -> None:
51
+ enable_menu_items(self.menu, [self], False)
52
+
44
53
 
45
54
  def enable_menu_items(menu: Menu, menu_items: list, enable: bool) -> None:
46
55
  state = tk.NORMAL if enable else tk.DISABLED
psiutils/utilities.py CHANGED
@@ -6,7 +6,8 @@ from typing import Any
6
6
  import platform
7
7
 
8
8
  from psiconfig import TomlConfig
9
- import psiutils.text as text
9
+ from psiutils._logger import logger
10
+ import psiutils.text as txt
10
11
 
11
12
  DEFAULT_GEOMETRY = '500x400'
12
13
 
@@ -19,7 +20,7 @@ def display_icon(root: tk.Tk, icon_file_path: str,
19
20
  icon = tk.PhotoImage(master=root, file=icon_file_path)
20
21
  root.wm_iconphoto(True, icon)
21
22
  except tk.TclError as err:
22
- if ignore_error and text.NO_SUCH_FILE in str(err):
23
+ if ignore_error and txt.NO_SUCH_FILE in str(err):
23
24
  return
24
25
  print(f'Cannot find icon file: {icon_file_path}')
25
26
 
@@ -30,7 +31,7 @@ class Enum():
30
31
 
31
32
 
32
33
  def confirm_delete(parent: Any) -> str:
33
- question = text.DELETE_THESE_ITEMS
34
+ question = txt.DELETE_THESE_ITEMS
34
35
  return tk.messagebox.askquestion(
35
36
  'Delete items', question, icon='warning', parent=parent)
36
37
 
@@ -1,14 +1,21 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: psiutils
3
- Version: 0.1.68
3
+ Version: 0.1.70
4
4
  Summary: Various TKinter utilities.
5
5
  Author: Jeff
6
6
  Author-email: Jeff <<jeffwatkins2000@gmail.com>>
7
- Requires-Dist: pillow>=11
8
- Requires-Dist: tkinterweb>=4
9
- Requires-Dist: markdown>=3.8
10
- Requires-Dist: psiconfig>=0.0.13
11
- Requires-Dist: psi-toml>=0.0.11
7
+ Requires-Dist: iniconfig>=2.1.0
8
+ Requires-Dist: markdown>=3.8.2
9
+ Requires-Dist: packaging>=25.0
10
+ Requires-Dist: pillow>=11.3.0
11
+ Requires-Dist: pluggy>=1.6.0
12
+ Requires-Dist: psi-toml>=0.0.12
13
+ Requires-Dist: psiconfig>=0.0.14
14
+ Requires-Dist: pygments>=2.19.2
15
+ Requires-Dist: tkinterweb>=4.4.4
16
+ Requires-Dist: tkinterweb-tkhtml>=1.1.1
17
+ Requires-Dist: tomli>=2.2.1
18
+ Requires-Dist: tomli-w>=1.2.0
12
19
  Requires-Python: ==3.13.*
13
20
  Description-Content-Type: text/markdown
14
21
 
@@ -1,7 +1,8 @@
1
1
  psiutils/__init__.py,sha256=07c98b1c26029c3d0b730b0602d4b71ccf6461dc159e17fa74d5cbea2d47e246,145
2
2
  psiutils/_about_frame.py,sha256=bf6b1b848b2fc1c890addf57fb738e8891b09873f3ebdcc772a975cca7fbfbb8,7634
3
- psiutils/_version.py,sha256=93d5d41661698e74e24ae08387055d142aa631f76924f8839d5ffee221be1bec,22
4
- psiutils/buttons.py,sha256=9be3cc8547615c447389078002511e6a52f5c5c20d09475ce48089162a41c138,8311
3
+ psiutils/_logger.py,sha256=e76067d9d01c0e6e781bb56c1f88c321944cd603171ee99508f7d5cce4bed57e,1725
4
+ psiutils/_version.py,sha256=c5e1ec534b61f398ecb8e9af137f0d3f5ec4bfff69d6c2196ea2ec8df37ae2c9,22
5
+ psiutils/buttons.py,sha256=4436d5543591e86fc5cfdedbb0eee75385893c6d4a32989592d1da3f7b8f804b,8370
5
6
  psiutils/constants.py,sha256=4fc023601926bb38805a35e038df928f400ceb63401a5ba3fd8ea096b3856c77,1107
6
7
  psiutils/drag_manager.py,sha256=2f4e06cca2229d65f31826b0bd39e7d7c175004b7c3d43d2d54f87a8256b878f,3470
7
8
  psiutils/errors.py,sha256=b40ca9164a73a5b78ea693bdcca4229a59d1572af7b0c3e88b0874c8add873cf,562
@@ -39,12 +40,12 @@ psiutils/images/icon-error.png,sha256=164d48323caa5c00946df7021931ccf90d466ffe77
39
40
  psiutils/images/icon-info.png,sha256=24509b1a461f3b5043ed545841799332339e3cf46bc23925f8a4851ed288044e,5979
40
41
  psiutils/images/icon-query.png,sha256=7b5f21aa47b0e1e3b1001bc408a9fb0463b65531d313e5cb3163d241f496f5d5,2808
41
42
  psiutils/known_paths.py,sha256=3f9011e3cdb2fbd6108cbff8554c787144cf6217df893ad62c4a901982f6e11e,9158
42
- psiutils/menus.py,sha256=dcf647898ee98e8b2d01f56b80927df370d37ac82ecf2e5cb0b09402390b6883,1485
43
+ psiutils/menus.py,sha256=e295076f77c46332e7b1fb7174a07f36394faf28ffa6eed6379232e50bb2f7e3,1746
43
44
  psiutils/messagebox.py,sha256=d785b82b3120f058b538288e5fdcd9be89a84aa89b018362a50a5af794dca393,4969
44
45
  psiutils/text.py,sha256=b67bc67d180df70c67b57306f587a25af91318a249d3cc9e142e9249f520f483,738
45
46
  psiutils/treeview.py,sha256=8ed4b32d6ae7148043595e58856351a19c205be2a3f3fed756a672bacafeae24,2826
46
- psiutils/utilities.py,sha256=0f06fcd059d9973ae6fae72365504b89243216b7080b7542957db4d4bfee81de,3074
47
+ psiutils/utilities.py,sha256=0ab732a14324d9df5665cbfbc9a84225d5a1a5a18ceeec777523f9904bd0a1e0,3107
47
48
  psiutils/widgets.py,sha256=a28180cb4214ddcb7d69eaa706a314af6015caa83fcca1c6f059bd1a6f969f96,11114
48
- psiutils-0.1.68.dist-info/WHEEL,sha256=b6dc288e80aa2d1b1518ddb3502fd5b53e8fd6cb507ed2a4f932e9e6088b264a,78
49
- psiutils-0.1.68.dist-info/METADATA,sha256=f56e12b1c145caf1f3dd1db5e8ed286cf9c18c3835ceea712354e102c85f94ae,1745
50
- psiutils-0.1.68.dist-info/RECORD,,
49
+ psiutils-0.1.70.dist-info/WHEEL,sha256=0f7d664a881437bddec71c703c3c2f01fd13581519f95130abcc96e296ef0426,79
50
+ psiutils-0.1.70.dist-info/METADATA,sha256=b41daf5cee058af68cf64a70d33e21f82c4de2744ddc9617e92357c73413b9df,1977
51
+ psiutils-0.1.70.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: uv 0.8.4
2
+ Generator: uv 0.8.11
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any