|
14 | 14 | import argparse |
15 | 15 | import logging |
16 | 16 | import typing as ty |
| 17 | +from contextlib import contextmanager |
17 | 18 | from logging.handlers import RotatingFileHandler |
18 | 19 | from pathlib import Path |
19 | 20 |
|
| 21 | +import tqdm |
20 | 22 | from platformdirs import user_log_path |
21 | 23 | from scenedetect import FrameTimecode |
22 | 24 |
|
| 25 | +# TODO: This is a hack and will break eventually, but this is the only way to handle this |
| 26 | +# right now unfortunately. logging_redirect_tqdm from the tqdm contrib module doesn't respect |
| 27 | +# verbosity unfortunately. This is being tracked by https://github.com/tqdm/tqdm/issues/1272. |
| 28 | +from tqdm.contrib.logging import ( |
| 29 | + _get_first_found_console_logging_handler, |
| 30 | + _is_console_logging_handler, |
| 31 | + _TqdmLoggingHandler, |
| 32 | +) |
| 33 | + |
23 | 34 | from dvr_scan.overlays import BoundingBoxOverlay, TextOverlay |
24 | 35 | from dvr_scan.platform import LOG_FORMAT_ROLLING_LOGS, attach_log_handler |
25 | 36 | from dvr_scan.platform import init_logger as _init_logger |
@@ -186,3 +197,57 @@ def init_scanner( |
186 | 197 | ) |
187 | 198 |
|
188 | 199 | return scanner |
| 200 | + |
| 201 | + |
| 202 | +@contextmanager |
| 203 | +def logging_redirect_tqdm( |
| 204 | + loggers: ty.Optional[ty.List[logging.Logger]], instance: ty.Type = tqdm.tqdm |
| 205 | +): |
| 206 | + """ |
| 207 | + Context manager redirecting console logging to `tqdm.write()`, leaving |
| 208 | + other logging handlers (e.g. log files) unaffected. |
| 209 | +
|
| 210 | + Parameters |
| 211 | + ---------- |
| 212 | + loggers : list, optional |
| 213 | + Which handlers to redirect (default: [logging.root]). |
| 214 | + tqdm_class : optional |
| 215 | +
|
| 216 | + Example |
| 217 | + ------- |
| 218 | + ```python |
| 219 | + import logging |
| 220 | + from tqdm import trange |
| 221 | + from tqdm.contrib.logging import logging_redirect_tqdm |
| 222 | +
|
| 223 | + LOG = logging.getLogger(__name__) |
| 224 | +
|
| 225 | + if __name__ == "__main__": |
| 226 | + logging.basicConfig(level=logging.INFO) |
| 227 | + with logging_redirect_tqdm(): |
| 228 | + for i in trange(9): |
| 229 | + if i == 4: |
| 230 | + LOG.info("console logging redirected to `tqdm.write()`") |
| 231 | + # logging restored |
| 232 | + ``` |
| 233 | + """ |
| 234 | + if loggers is None: |
| 235 | + loggers = [logging.root] |
| 236 | + original_handlers_list = [logger.handlers for logger in loggers] |
| 237 | + try: |
| 238 | + for logger in loggers: |
| 239 | + tqdm_handler = _TqdmLoggingHandler(instance) |
| 240 | + orig_handler = _get_first_found_console_logging_handler(logger.handlers) |
| 241 | + if orig_handler is not None: |
| 242 | + tqdm_handler.setFormatter(orig_handler.formatter) |
| 243 | + tqdm_handler.stream = orig_handler.stream |
| 244 | + # The following is missing from the original logging_redirect_tqdm. |
| 245 | + # This is being tracked by https://github.com/tqdm/tqdm/issues/1272. |
| 246 | + tqdm_handler.setLevel(orig_handler.level) |
| 247 | + logger.handlers = [ |
| 248 | + handler for handler in logger.handlers if not _is_console_logging_handler(handler) |
| 249 | + ] + [tqdm_handler] |
| 250 | + yield |
| 251 | + finally: |
| 252 | + for logger, original_handlers in zip(loggers, original_handlers_list): |
| 253 | + logger.handlers = original_handlers |
0 commit comments