aboutsummaryrefslogtreecommitdiffstats
path: root/cloud_mdir_sync/util.py
diff options
context:
space:
mode:
Diffstat (limited to 'cloud_mdir_sync/util.py')
-rw-r--r--cloud_mdir_sync/util.py70
1 files changed, 70 insertions, 0 deletions
diff --git a/cloud_mdir_sync/util.py b/cloud_mdir_sync/util.py
new file mode 100644
index 0000000..7799356
--- /dev/null
+++ b/cloud_mdir_sync/util.py
@@ -0,0 +1,70 @@
+# SPDX-License-Identifier: GPL-2.0+
+import contextlib
+import functools
+import inspect
+import json
+import logging
+import time
+
+from . import config
+
+
+@contextlib.contextmanager
+def log_progress_ctx(level, start_msg, end_msg, *args):
+ if inspect.isfunction(start_msg):
+ start_msg = start_msg(*args)
+ if end_msg is None:
+ end_msg = " "
+
+ config.logger.log(level, f"Starting {start_msg}")
+ st = time.perf_counter()
+ try:
+ yield
+ et = time.perf_counter()
+ except Exception as e:
+ if inspect.isfunction(end_msg):
+ end_msg = end_msg(*args)
+ config.logger.warning(f"FAILED({e!r}): {start_msg}")
+ raise
+
+ if inspect.isfunction(end_msg):
+ end_msg = end_msg(*args)
+ if end_msg.startswith("-"):
+ start_msg = ""
+ config.logger.info(
+ f"Completed {start_msg}{end_msg} (took {et-st:.4f} secs)")
+
+
+def log_progress(start_msg, end_msg=None, level=logging.INFO):
+ """Decorator to log the start/end and duration of a method"""
+ def inner(func):
+ @functools.wraps(func)
+ def wrapper(self, *args, **kwargs):
+ with log_progress_ctx(level, start_msg, end_msg, self):
+ res = func(self, *args, **kwargs)
+ return res
+
+ @functools.wraps(func)
+ async def async_wrapper(self, *args, **kwargs):
+ with log_progress_ctx(level, start_msg, end_msg, self):
+ res = await func(self, *args, **kwargs)
+ return res
+
+ if inspect.iscoroutinefunction(func):
+ return async_wrapper
+ return wrapper
+
+ return inner
+
+
+# https://stackoverflow.com/questions/1094841/reusable-library-to-get-human-readable-version-of-file-size
+def sizeof_fmt(num, suffix='B'):
+ for unit in ['', 'Ki', 'Mi', 'Gi', 'Ti', 'Pi', 'Ei', 'Zi']:
+ if abs(num) < 1024.0:
+ return "%3.1f%s%s" % (num, unit, suffix)
+ num /= 1024.0
+ return "%.1f%s%s" % (num, 'Yi', suffix)
+
+
+def pj(json_dict):
+ print(json.dumps(json_dict, indent=4, sort_keys=True))