CustomModules 3.0.0__tar.gz → 3.1.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.
- {custommodules-3.0.0 → custommodules-3.1.1}/CustomModules/__init__.py +1 -1
- {custommodules-3.0.0 → custommodules-3.1.1}/CustomModules/log_handler.py +72 -2
- {custommodules-3.0.0 → custommodules-3.1.1}/CustomModules.egg-info/PKG-INFO +3 -1
- {custommodules-3.0.0 → custommodules-3.1.1}/CustomModules.egg-info/requires.txt +2 -0
- {custommodules-3.0.0 → custommodules-3.1.1}/PKG-INFO +3 -1
- {custommodules-3.0.0 → custommodules-3.1.1}/pyproject.toml +1 -1
- {custommodules-3.0.0 → custommodules-3.1.1}/setup.py +2 -1
- {custommodules-3.0.0 → custommodules-3.1.1}/CustomModules/app_translation.py +0 -0
- {custommodules-3.0.0 → custommodules-3.1.1}/CustomModules/bitmap_handler.py +0 -0
- {custommodules-3.0.0 → custommodules-3.1.1}/CustomModules/bot_directory.py +0 -0
- {custommodules-3.0.0 → custommodules-3.1.1}/CustomModules/database_handler.py +0 -0
- {custommodules-3.0.0 → custommodules-3.1.1}/CustomModules/googletrans.py +0 -0
- {custommodules-3.0.0 → custommodules-3.1.1}/CustomModules/invite_tracker.py +0 -0
- {custommodules-3.0.0 → custommodules-3.1.1}/CustomModules/killswitch.py +0 -0
- {custommodules-3.0.0 → custommodules-3.1.1}/CustomModules/libretrans.py +0 -0
- {custommodules-3.0.0 → custommodules-3.1.1}/CustomModules/patchnotes.py +0 -0
- {custommodules-3.0.0 → custommodules-3.1.1}/CustomModules/private_voice.py +0 -0
- {custommodules-3.0.0 → custommodules-3.1.1}/CustomModules/py.typed +0 -0
- {custommodules-3.0.0 → custommodules-3.1.1}/CustomModules/random_usernames.py +0 -0
- {custommodules-3.0.0 → custommodules-3.1.1}/CustomModules/stat_dock.py +0 -0
- {custommodules-3.0.0 → custommodules-3.1.1}/CustomModules/steam.py +0 -0
- {custommodules-3.0.0 → custommodules-3.1.1}/CustomModules/steam_charts.py +0 -0
- {custommodules-3.0.0 → custommodules-3.1.1}/CustomModules/twitch.py +0 -0
- {custommodules-3.0.0 → custommodules-3.1.1}/CustomModules.egg-info/SOURCES.txt +0 -0
- {custommodules-3.0.0 → custommodules-3.1.1}/CustomModules.egg-info/dependency_links.txt +0 -0
- {custommodules-3.0.0 → custommodules-3.1.1}/CustomModules.egg-info/not-zip-safe +0 -0
- {custommodules-3.0.0 → custommodules-3.1.1}/CustomModules.egg-info/top_level.txt +0 -0
- {custommodules-3.0.0 → custommodules-3.1.1}/LICENSE.txt +0 -0
- {custommodules-3.0.0 → custommodules-3.1.1}/MANIFEST.in +0 -0
- {custommodules-3.0.0 → custommodules-3.1.1}/README.md +0 -0
- {custommodules-3.0.0 → custommodules-3.1.1}/setup.cfg +0 -0
|
@@ -2,11 +2,73 @@ import logging
|
|
|
2
2
|
import logging.handlers
|
|
3
3
|
import os
|
|
4
4
|
import threading
|
|
5
|
+
from collections import deque
|
|
5
6
|
from typing import Optional
|
|
6
7
|
|
|
7
8
|
from colorama import Fore, Style, init
|
|
8
9
|
|
|
9
10
|
|
|
11
|
+
class _BufferedTimedRotatingFileHandler(logging.handlers.TimedRotatingFileHandler):
|
|
12
|
+
"""
|
|
13
|
+
A TimedRotatingFileHandler that buffers log records in RAM during rotation.
|
|
14
|
+
|
|
15
|
+
This prevents issues with concurrent writes during file rotation by temporarily
|
|
16
|
+
storing incoming log records in a deque buffer while the rotation is in progress.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
def __init__(self, *args, log_manager=None, **kwargs):
|
|
20
|
+
"""
|
|
21
|
+
Initialize the buffered handler.
|
|
22
|
+
|
|
23
|
+
Args:
|
|
24
|
+
*args: Positional arguments passed to TimedRotatingFileHandler.
|
|
25
|
+
log_manager (LogManager): Reference to the LogManager for accessing buffer state.
|
|
26
|
+
**kwargs: Keyword arguments passed to TimedRotatingFileHandler.
|
|
27
|
+
"""
|
|
28
|
+
super().__init__(*args, **kwargs)
|
|
29
|
+
self.log_manager = log_manager
|
|
30
|
+
|
|
31
|
+
def emit(self, record):
|
|
32
|
+
"""
|
|
33
|
+
Emit a record, buffering it if rotation is in progress.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
record (logging.LogRecord): The log record to emit.
|
|
37
|
+
"""
|
|
38
|
+
if self.log_manager and self.log_manager.buffer_logs_during_rotation:
|
|
39
|
+
# Check if rotation is in progress
|
|
40
|
+
if self.log_manager._rotation_in_progress:
|
|
41
|
+
# Buffer the record instead of writing it
|
|
42
|
+
self.log_manager._log_buffer.append(record)
|
|
43
|
+
return
|
|
44
|
+
|
|
45
|
+
# Normal emit
|
|
46
|
+
super().emit(record)
|
|
47
|
+
|
|
48
|
+
def doRollover(self):
|
|
49
|
+
"""
|
|
50
|
+
Perform a rollover, buffering incoming logs during the process.
|
|
51
|
+
"""
|
|
52
|
+
if self.log_manager and self.log_manager.buffer_logs_during_rotation:
|
|
53
|
+
# Signal that rotation is starting
|
|
54
|
+
self.log_manager._rotation_in_progress = True
|
|
55
|
+
|
|
56
|
+
try:
|
|
57
|
+
# Perform the actual rotation
|
|
58
|
+
super().doRollover()
|
|
59
|
+
finally:
|
|
60
|
+
# Signal that rotation is complete
|
|
61
|
+
self.log_manager._rotation_in_progress = False
|
|
62
|
+
|
|
63
|
+
# Flush buffered logs
|
|
64
|
+
while self.log_manager._log_buffer:
|
|
65
|
+
buffered_record = self.log_manager._log_buffer.popleft()
|
|
66
|
+
super().emit(buffered_record)
|
|
67
|
+
else:
|
|
68
|
+
# No buffering, perform normal rotation
|
|
69
|
+
super().doRollover()
|
|
70
|
+
|
|
71
|
+
|
|
10
72
|
class LogManager:
|
|
11
73
|
"""
|
|
12
74
|
Manages the creation of loggers with both file and console handlers.
|
|
@@ -16,6 +78,7 @@ class LogManager:
|
|
|
16
78
|
app_folder_name (str): The name of the application, used for naming the log file.
|
|
17
79
|
log_level (int): The logging level (e.g., logging.INFO).
|
|
18
80
|
logger (logging.Logger): Optional logger for meta-logging LogManager operations.
|
|
81
|
+
buffer_logs_during_rotation (bool): If True, logs are buffered in RAM during rotation.
|
|
19
82
|
"""
|
|
20
83
|
|
|
21
84
|
def __init__(
|
|
@@ -24,6 +87,7 @@ class LogManager:
|
|
|
24
87
|
app_folder_name,
|
|
25
88
|
log_level="INFO",
|
|
26
89
|
logger: Optional[logging.Logger] = None,
|
|
90
|
+
buffer_logs_during_rotation: bool = True,
|
|
27
91
|
):
|
|
28
92
|
"""
|
|
29
93
|
Initializes the LogManager with the specified log folder, application folder name, and log level.
|
|
@@ -34,6 +98,8 @@ class LogManager:
|
|
|
34
98
|
log_level (str): The log level as a string (e.g., 'INFO', 'DEBUG').
|
|
35
99
|
logger (Optional[logging.Logger]): Parent logger for meta-logging LogManager operations.
|
|
36
100
|
If provided, creates a child logger under CustomModules.LogHandler. Defaults to None.
|
|
101
|
+
buffer_logs_during_rotation (bool): If True, incoming logs are buffered in RAM during
|
|
102
|
+
file rotation to prevent issues. Defaults to True.
|
|
37
103
|
"""
|
|
38
104
|
init() # Initialize colorama for colored console output.
|
|
39
105
|
|
|
@@ -51,6 +117,9 @@ class LogManager:
|
|
|
51
117
|
self.app_folder_name = app_folder_name
|
|
52
118
|
self.log_level = self._get_log_level(log_level)
|
|
53
119
|
self._lock = threading.Lock() # Thread-safety lock for handler operations
|
|
120
|
+
self.buffer_logs_during_rotation = buffer_logs_during_rotation
|
|
121
|
+
self._rotation_in_progress = False
|
|
122
|
+
self._log_buffer = deque() # Buffer for logs during rotation
|
|
54
123
|
|
|
55
124
|
self.logger.info(f"LogManager initialized with log level {log_level}")
|
|
56
125
|
|
|
@@ -96,13 +165,14 @@ class LogManager:
|
|
|
96
165
|
)
|
|
97
166
|
return logger
|
|
98
167
|
|
|
99
|
-
# Create a file handler that rotates logs at midnight
|
|
100
|
-
file_handler =
|
|
168
|
+
# Create a file handler that rotates logs at midnight with buffering support
|
|
169
|
+
file_handler = _BufferedTimedRotatingFileHandler(
|
|
101
170
|
filename=os.path.join(self.log_folder, f"{self.app_folder_name}.log"),
|
|
102
171
|
when="midnight",
|
|
103
172
|
encoding="utf-8",
|
|
104
173
|
backupCount=27,
|
|
105
174
|
delay=True,
|
|
175
|
+
log_manager=self,
|
|
106
176
|
)
|
|
107
177
|
|
|
108
178
|
# Customize rotation naming: NAME.DATUM.log instead of NAME.log.DATUM
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: CustomModules
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.1.1
|
|
4
4
|
Summary: A collection of custom Python modules for Discord bots and utilities
|
|
5
5
|
Home-page: https://github.com/Serpensin/CustomModules-Python
|
|
6
6
|
Author: Serpensin
|
|
@@ -43,6 +43,7 @@ Requires-Dist: html2text>=2024.2.26; extra == "killswitch"
|
|
|
43
43
|
Requires-Dist: beautifulsoup4>=4.12.3; extra == "killswitch"
|
|
44
44
|
Provides-Extra: libretrans
|
|
45
45
|
Requires-Dist: aiohttp>=3.9.3; extra == "libretrans"
|
|
46
|
+
Requires-Dist: aiofiles>=25.1.0; extra == "libretrans"
|
|
46
47
|
Provides-Extra: loghandler
|
|
47
48
|
Requires-Dist: colorama>=0.4.6; extra == "loghandler"
|
|
48
49
|
Provides-Extra: patchnotes
|
|
@@ -65,6 +66,7 @@ Provides-Extra: twitch
|
|
|
65
66
|
Requires-Dist: aiohttp>=3.9.3; extra == "twitch"
|
|
66
67
|
Requires-Dist: requests>=2.31.0; extra == "twitch"
|
|
67
68
|
Provides-Extra: all
|
|
69
|
+
Requires-Dist: aiofiles>=25.1.0; extra == "all"
|
|
68
70
|
Requires-Dist: aiohttp>=3.9.3; extra == "all"
|
|
69
71
|
Requires-Dist: aiomysql>=0.2.0; extra == "all"
|
|
70
72
|
Requires-Dist: aiosqlite>=0.19.0; extra == "all"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: CustomModules
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.1.1
|
|
4
4
|
Summary: A collection of custom Python modules for Discord bots and utilities
|
|
5
5
|
Home-page: https://github.com/Serpensin/CustomModules-Python
|
|
6
6
|
Author: Serpensin
|
|
@@ -43,6 +43,7 @@ Requires-Dist: html2text>=2024.2.26; extra == "killswitch"
|
|
|
43
43
|
Requires-Dist: beautifulsoup4>=4.12.3; extra == "killswitch"
|
|
44
44
|
Provides-Extra: libretrans
|
|
45
45
|
Requires-Dist: aiohttp>=3.9.3; extra == "libretrans"
|
|
46
|
+
Requires-Dist: aiofiles>=25.1.0; extra == "libretrans"
|
|
46
47
|
Provides-Extra: loghandler
|
|
47
48
|
Requires-Dist: colorama>=0.4.6; extra == "loghandler"
|
|
48
49
|
Provides-Extra: patchnotes
|
|
@@ -65,6 +66,7 @@ Provides-Extra: twitch
|
|
|
65
66
|
Requires-Dist: aiohttp>=3.9.3; extra == "twitch"
|
|
66
67
|
Requires-Dist: requests>=2.31.0; extra == "twitch"
|
|
67
68
|
Provides-Extra: all
|
|
69
|
+
Requires-Dist: aiofiles>=25.1.0; extra == "all"
|
|
68
70
|
Requires-Dist: aiohttp>=3.9.3; extra == "all"
|
|
69
71
|
Requires-Dist: aiomysql>=0.2.0; extra == "all"
|
|
70
72
|
Requires-Dist: aiosqlite>=0.19.0; extra == "all"
|
|
@@ -49,6 +49,7 @@ extras_require = {
|
|
|
49
49
|
],
|
|
50
50
|
"libretrans": [
|
|
51
51
|
DEP_AIOHTTP,
|
|
52
|
+
"aiofiles>=25.1.0",
|
|
52
53
|
],
|
|
53
54
|
"loghandler": [
|
|
54
55
|
"colorama>=0.4.6",
|
|
@@ -89,7 +90,7 @@ extras_require["all"] = sorted(all_deps)
|
|
|
89
90
|
|
|
90
91
|
setup(
|
|
91
92
|
name="CustomModules",
|
|
92
|
-
version="3.
|
|
93
|
+
version="3.1.1",
|
|
93
94
|
author="Serpensin",
|
|
94
95
|
description="A collection of custom Python modules for Discord bots and utilities",
|
|
95
96
|
long_description=read_file("README.md"),
|
|
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
|