psiutils 0.2.3__tar.gz → 0.2.4__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.
- {psiutils-0.2.3 → psiutils-0.2.4}/PKG-INFO +1 -1
- {psiutils-0.2.3 → psiutils-0.2.4}/pyproject.toml +1 -1
- psiutils-0.2.4/src/psiutils/_logger.py +95 -0
- psiutils-0.2.4/src/psiutils/_version.py +1 -0
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/known_paths.py +28 -15
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/utilities.py +1 -2
- psiutils-0.2.3/src/psiutils/_logger.py +0 -54
- psiutils-0.2.3/src/psiutils/_version.py +0 -1
- {psiutils-0.2.3 → psiutils-0.2.4}/README.md +0 -0
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/__init__.py +0 -0
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/_about_frame.py +0 -0
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/buttons.py +0 -0
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/constants.py +0 -0
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/drag_manager.py +0 -0
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/errors.py +0 -0
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/icecream_init.py +0 -0
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/icons/build.png +0 -0
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/icons/cancel.png +0 -0
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/icons/check.png +0 -0
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/icons/clear.png +0 -0
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/icons/code.png +0 -0
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/icons/compare.png +0 -0
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/icons/copy_clipboard.png +0 -0
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/icons/copy_docs.png +0 -0
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/icons/delete.png +0 -0
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/icons/diff.png +0 -0
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/icons/done.png +0 -0
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/icons/edit.png +0 -0
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/icons/gear.png +0 -0
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/icons/new.png +0 -0
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/icons/next.png +0 -0
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/icons/open.png +0 -0
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/icons/pause.png +0 -0
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/icons/preferences.png +0 -0
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/icons/previous.png +0 -0
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/icons/process.png +0 -0
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/icons/redo.png +0 -0
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/icons/refresh.png +0 -0
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/icons/rename.png +0 -0
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/icons/report.png +0 -0
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/icons/reset.png +0 -0
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/icons/revert.png +0 -0
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/icons/save.png +0 -0
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/icons/script.png +0 -0
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/icons/search.png +0 -0
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/icons/send.png +0 -0
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/icons/start.png +0 -0
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/icons/update.png +0 -0
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/icons/upgrade.png +0 -0
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/icons/windows.png +0 -0
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/images/icon-error.png +0 -0
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/images/icon-info.png +0 -0
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/images/icon-query.png +0 -0
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/menus.py +0 -0
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/messagebox.py +0 -0
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/text.py +0 -0
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/treeview.py +0 -0
- {psiutils-0.2.3 → psiutils-0.2.4}/src/psiutils/widgets.py +0 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# logging_setup.py
|
|
2
|
+
import logging
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from logging.handlers import RotatingFileHandler
|
|
5
|
+
import appdirs
|
|
6
|
+
import structlog
|
|
7
|
+
|
|
8
|
+
LOG_FILE_NAME = 'app.log'
|
|
9
|
+
MAX_BYTES = 5_000_000
|
|
10
|
+
BACKUP_COUNT = 5
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def psi_logger(app_name: str, level=logging.INFO):
|
|
14
|
+
"""
|
|
15
|
+
Creates and configures a logger for the specified application.
|
|
16
|
+
|
|
17
|
+
Args:
|
|
18
|
+
app_name (str): The name of the application.
|
|
19
|
+
level (int): The logging level (default is logging.INFO).
|
|
20
|
+
|
|
21
|
+
Returns:
|
|
22
|
+
Logger: A configured logger for the application.
|
|
23
|
+
|
|
24
|
+
Examples:
|
|
25
|
+
logger = psi_logger("my_app", logging.DEBUG)
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
log_file = _log_file(app_name)
|
|
29
|
+
console_handler = _console_handler(level)
|
|
30
|
+
file_handler = _file_handler(log_file, level)
|
|
31
|
+
|
|
32
|
+
root_logger = logging.getLogger()
|
|
33
|
+
root_logger.setLevel(level)
|
|
34
|
+
root_logger.addHandler(console_handler)
|
|
35
|
+
root_logger.addHandler(file_handler)
|
|
36
|
+
|
|
37
|
+
structlog.configure(
|
|
38
|
+
processors=_processors(),
|
|
39
|
+
wrapper_class=structlog.make_filtering_bound_logger(level),
|
|
40
|
+
context_class=dict,
|
|
41
|
+
logger_factory=structlog.stdlib.LoggerFactory(),
|
|
42
|
+
cache_logger_on_first_use=True,
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
return structlog.get_logger()
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _log_file(app_name: str) -> Path:
|
|
49
|
+
"""Return the path to the application log file."""
|
|
50
|
+
log_dir = Path(appdirs.user_data_dir(app_name))
|
|
51
|
+
log_dir.mkdir(parents=True, exist_ok=True)
|
|
52
|
+
return Path(log_dir, LOG_FILE_NAME)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def _console_handler(level=logging.INFO) -> logging.StreamHandler:
|
|
56
|
+
"""Return the console handler for the logger."""
|
|
57
|
+
console_handler = logging.StreamHandler()
|
|
58
|
+
console_handler.setLevel(level)
|
|
59
|
+
console_handler.setFormatter(
|
|
60
|
+
structlog.stdlib.ProcessorFormatter(
|
|
61
|
+
processor=structlog.dev.ConsoleRenderer(),
|
|
62
|
+
foreign_pre_chain=[structlog.processors.TimeStamper(fmt='iso')],
|
|
63
|
+
)
|
|
64
|
+
)
|
|
65
|
+
return console_handler
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def _file_handler(log_file: Path, level=logging.INFO) -> RotatingFileHandler:
|
|
69
|
+
"""Return the console handler for the logger."""
|
|
70
|
+
file_handler = RotatingFileHandler(
|
|
71
|
+
str(log_file),
|
|
72
|
+
maxBytes=MAX_BYTES,
|
|
73
|
+
backupCount=BACKUP_COUNT,
|
|
74
|
+
encoding='utf-8'
|
|
75
|
+
)
|
|
76
|
+
file_handler.setLevel(level)
|
|
77
|
+
file_handler.setFormatter(
|
|
78
|
+
structlog.stdlib.ProcessorFormatter(
|
|
79
|
+
processor=structlog.processors.JSONRenderer(),
|
|
80
|
+
foreign_pre_chain=[structlog.processors.TimeStamper(fmt='iso')],
|
|
81
|
+
)
|
|
82
|
+
)
|
|
83
|
+
return file_handler
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def _processors() -> list:
|
|
87
|
+
return [
|
|
88
|
+
structlog.processors.TimeStamper(fmt='iso'),
|
|
89
|
+
structlog.stdlib.add_log_level,
|
|
90
|
+
structlog.stdlib.add_logger_name,
|
|
91
|
+
structlog.stdlib.PositionalArgumentsFormatter(),
|
|
92
|
+
structlog.processors.StackInfoRenderer(),
|
|
93
|
+
structlog.processors.format_exc_info,
|
|
94
|
+
structlog.stdlib.ProcessorFormatter.wrap_for_formatter,
|
|
95
|
+
]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = '0.2.4'
|
|
@@ -24,23 +24,25 @@ from pathlib import Path
|
|
|
24
24
|
import platform
|
|
25
25
|
from typing import Any
|
|
26
26
|
|
|
27
|
-
MS_FOLDERS =
|
|
27
|
+
#MS_FOLDERS =
|
|
28
|
+
# r'SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders'
|
|
28
29
|
|
|
29
30
|
|
|
30
31
|
class GUID(ctypes.Structure):
|
|
31
32
|
_fields_ = [
|
|
32
|
-
("Data1",
|
|
33
|
-
("Data2",
|
|
34
|
-
("Data3",
|
|
35
|
-
("Data4",
|
|
33
|
+
("Data1", ctypes.c_ulong),
|
|
34
|
+
("Data2", ctypes.c_ushort),
|
|
35
|
+
("Data3", ctypes.c_ushort),
|
|
36
|
+
("Data4", ctypes.c_ubyte * 8),
|
|
36
37
|
]
|
|
37
38
|
|
|
38
|
-
def __init__(self,
|
|
39
|
+
def __init__(self, guid_string):
|
|
40
|
+
str_uuid = UUID(guid_string)
|
|
39
41
|
ctypes.Structure.__init__(self)
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
self.Data1 = str_uuid.time_low
|
|
43
|
+
self.Data2 = str_uuid.time_mid
|
|
44
|
+
self.Data3 = str_uuid.time_hi_version
|
|
45
|
+
self.Data4[:] = str_uuid.bytes[8:]
|
|
44
46
|
|
|
45
47
|
|
|
46
48
|
class folder_id:
|
|
@@ -163,11 +165,22 @@ class PathNotFoundException(Exception):
|
|
|
163
165
|
|
|
164
166
|
|
|
165
167
|
def get_path(folder: str) -> str | None:
|
|
166
|
-
|
|
167
|
-
fid = f'{{{getattr(folder_id, folder)}}}'
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
168
|
+
# FOLDERID_Documents GUID
|
|
169
|
+
fid = GUID(f'{{{getattr(folder_id, folder)}}}')
|
|
170
|
+
|
|
171
|
+
SHGetKnownFolderPath = ctypes.windll.shell32.SHGetKnownFolderPath
|
|
172
|
+
SHGetKnownFolderPath.argtypes = [
|
|
173
|
+
ctypes.POINTER(GUID),
|
|
174
|
+
wintypes.DWORD, wintypes.HANDLE,
|
|
175
|
+
ctypes.POINTER(ctypes.c_wchar_p)]
|
|
176
|
+
SHGetKnownFolderPath.restype = ctypes.HRESULT
|
|
177
|
+
|
|
178
|
+
path_ptr = ctypes.c_wchar_p()
|
|
179
|
+
result = SHGetKnownFolderPath(
|
|
180
|
+
ctypes.byref(fid), 0, None, ctypes.byref(path_ptr))
|
|
181
|
+
if result != 0:
|
|
182
|
+
raise OSError("SHGetKnownFolderPath failed")
|
|
183
|
+
return Path(path_ptr.value)
|
|
171
184
|
|
|
172
185
|
|
|
173
186
|
def get_downloads_dir() -> Path | str:
|
|
@@ -1,54 +0,0 @@
|
|
|
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()
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = '0.2.3'
|
|
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
|
|
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
|