Merge pull request #3571 from pypeclub/feature/lib_cleanup

General: Lib cleanup
This commit is contained in:
Jakub Trllo 2022-07-27 10:50:33 +02:00 committed by GitHub
commit 830e79ca17
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 166 additions and 206 deletions

View file

@ -9,6 +9,7 @@ from .settings import (
)
from .lib import (
PypeLogger,
Logger,
Anatomy,
config,
execute,
@ -58,8 +59,6 @@ from .action import (
RepairContextAction
)
# for backward compatibility with Pype 2
Logger = PypeLogger
__all__ = [
"get_system_settings",

View file

@ -63,7 +63,10 @@ from .execute import (
path_to_subprocess_arg,
CREATE_NO_WINDOW
)
from .log import PypeLogger, timeit
from .log import (
Logger,
PypeLogger,
)
from .path_templates import (
merge_dict,
@ -83,8 +86,9 @@ from .anatomy import (
Anatomy
)
from .config import (
from .dateutils import (
get_datetime_data,
get_timestamp,
get_formatted_current_time
)
@ -370,13 +374,13 @@ __all__ = [
"get_datetime_data",
"get_formatted_current_time",
"Logger",
"PypeLogger",
"get_default_components",
"validate_mongo_connection",
"OpenPypeMongoConnection",
"timeit",
"is_overlapping_otio_ranges",
"otio_range_with_handles",
"convert_to_padded_path",

View file

@ -1,82 +1,41 @@
# -*- coding: utf-8 -*-
"""Get configuration data."""
import datetime
import warnings
import functools
def get_datetime_data(datetime_obj=None):
"""Returns current datetime data as dictionary.
class ConfigDeprecatedWarning(DeprecationWarning):
pass
Args:
datetime_obj (datetime): Specific datetime object
Returns:
dict: prepared date & time data
def deprecated(func):
"""Mark functions as deprecated.
Available keys:
"d" - <Day of month number> in shortest possible way.
"dd" - <Day of month number> with 2 digits.
"ddd" - <Week day name> shortened week day. e.g.: `Mon`, ...
"dddd" - <Week day name> full name of week day. e.g.: `Monday`, ...
"m" - <Month number> in shortest possible way. e.g.: `1` if January
"mm" - <Month number> with 2 digits.
"mmm" - <Month name> shortened month name. e.g.: `Jan`, ...
"mmmm" - <Month name> full month name. e.g.: `January`, ...
"yy" - <Year number> shortened year. e.g.: `19`, `20`, ...
"yyyy" - <Year number> full year. e.g.: `2019`, `2020`, ...
"H" - <Hours number 24-hour> shortened hours.
"HH" - <Hours number 24-hour> with 2 digits.
"h" - <Hours number 12-hour> shortened hours.
"hh" - <Hours number 12-hour> with 2 digits.
"ht" - <Midday type> AM or PM.
"M" - <Minutes number> shortened minutes.
"MM" - <Minutes number> with 2 digits.
"S" - <Seconds number> shortened seconds.
"SS" - <Seconds number> with 2 digits.
It will result in a warning being emitted when the function is used.
"""
if not datetime_obj:
datetime_obj = datetime.datetime.now()
year = datetime_obj.strftime("%Y")
month = datetime_obj.strftime("%m")
month_name_full = datetime_obj.strftime("%B")
month_name_short = datetime_obj.strftime("%b")
day = datetime_obj.strftime("%d")
weekday_full = datetime_obj.strftime("%A")
weekday_short = datetime_obj.strftime("%a")
hours = datetime_obj.strftime("%H")
hours_midday = datetime_obj.strftime("%I")
hour_midday_type = datetime_obj.strftime("%p")
minutes = datetime_obj.strftime("%M")
seconds = datetime_obj.strftime("%S")
return {
"d": str(int(day)),
"dd": str(day),
"ddd": weekday_short,
"dddd": weekday_full,
"m": str(int(month)),
"mm": str(month),
"mmm": month_name_short,
"mmmm": month_name_full,
"yy": str(year[2:]),
"yyyy": str(year),
"H": str(int(hours)),
"HH": str(hours),
"h": str(int(hours_midday)),
"hh": str(hours_midday),
"ht": hour_midday_type,
"M": str(int(minutes)),
"MM": str(minutes),
"S": str(int(seconds)),
"SS": str(seconds),
}
@functools.wraps(func)
def new_func(*args, **kwargs):
warnings.simplefilter("always", ConfigDeprecatedWarning)
warnings.warn(
(
"Deprecated import of function '{}'."
" Class was moved to 'openpype.lib.dateutils.{}'."
" Please change your imports."
).format(func.__name__),
category=ConfigDeprecatedWarning
)
return func(*args, **kwargs)
return new_func
@deprecated
def get_datetime_data(datetime_obj=None):
from .dateutils import get_datetime_data
return get_datetime_data(datetime_obj)
@deprecated
def get_formatted_current_time():
return datetime.datetime.now().strftime(
"%Y%m%dT%H%M%SZ"
)
from .dateutils import get_formatted_current_time
return get_formatted_current_time()

95
openpype/lib/dateutils.py Normal file
View file

@ -0,0 +1,95 @@
# -*- coding: utf-8 -*-
"""Get configuration data."""
import datetime
def get_datetime_data(datetime_obj=None):
"""Returns current datetime data as dictionary.
Args:
datetime_obj (datetime): Specific datetime object
Returns:
dict: prepared date & time data
Available keys:
"d" - <Day of month number> in shortest possible way.
"dd" - <Day of month number> with 2 digits.
"ddd" - <Week day name> shortened week day. e.g.: `Mon`, ...
"dddd" - <Week day name> full name of week day. e.g.: `Monday`, ...
"m" - <Month number> in shortest possible way. e.g.: `1` if January
"mm" - <Month number> with 2 digits.
"mmm" - <Month name> shortened month name. e.g.: `Jan`, ...
"mmmm" - <Month name> full month name. e.g.: `January`, ...
"yy" - <Year number> shortened year. e.g.: `19`, `20`, ...
"yyyy" - <Year number> full year. e.g.: `2019`, `2020`, ...
"H" - <Hours number 24-hour> shortened hours.
"HH" - <Hours number 24-hour> with 2 digits.
"h" - <Hours number 12-hour> shortened hours.
"hh" - <Hours number 12-hour> with 2 digits.
"ht" - <Midday type> AM or PM.
"M" - <Minutes number> shortened minutes.
"MM" - <Minutes number> with 2 digits.
"S" - <Seconds number> shortened seconds.
"SS" - <Seconds number> with 2 digits.
"""
if not datetime_obj:
datetime_obj = datetime.datetime.now()
year = datetime_obj.strftime("%Y")
month = datetime_obj.strftime("%m")
month_name_full = datetime_obj.strftime("%B")
month_name_short = datetime_obj.strftime("%b")
day = datetime_obj.strftime("%d")
weekday_full = datetime_obj.strftime("%A")
weekday_short = datetime_obj.strftime("%a")
hours = datetime_obj.strftime("%H")
hours_midday = datetime_obj.strftime("%I")
hour_midday_type = datetime_obj.strftime("%p")
minutes = datetime_obj.strftime("%M")
seconds = datetime_obj.strftime("%S")
return {
"d": str(int(day)),
"dd": str(day),
"ddd": weekday_short,
"dddd": weekday_full,
"m": str(int(month)),
"mm": str(month),
"mmm": month_name_short,
"mmmm": month_name_full,
"yy": str(year[2:]),
"yyyy": str(year),
"H": str(int(hours)),
"HH": str(hours),
"h": str(int(hours_midday)),
"hh": str(hours_midday),
"ht": hour_midday_type,
"M": str(int(minutes)),
"MM": str(minutes),
"S": str(int(seconds)),
"SS": str(seconds),
}
def get_timestamp(datetime_obj=None):
"""Get standardized timestamp from datetime object.
Args:
datetime_obj (datetime.datetime): Object of datetime. Current time
is used if not passed.
"""
if datetime_obj is None:
datetime_obj = datetime.datetime.now()
return datetime_obj.strftime(
"%Y%m%dT%H%M%SZ"
)
def get_formatted_current_time():
return get_timestamp()

View file

@ -1,86 +0,0 @@
import git
from tqdm import tqdm
class _GitProgress(git.remote.RemoteProgress):
""" Class handling displaying progress during git operations.
This is using **tqdm** for showing progress bars. As **GitPython**
is parsing progress directly from git command, it is somehow unreliable
as in some operations it is difficult to get total count of iterations
to display meaningful progress bar.
"""
_t = None
_code = 0
_current_status = ''
_current_max = ''
_description = {
256: "Checking out files",
4: "Counting objects",
128: "Finding sources",
32: "Receiving objects",
64: "Resolving deltas",
16: "Writing objects"
}
def __init__(self):
super().__init__()
def __del__(self):
if self._t is not None:
self._t.close()
def _detroy_tqdm(self):
""" Used to close tqdm when operation ended.
"""
if self._t is not None:
self._t.close()
self._t = None
def _check_mask(self, opcode: int) -> bool:
"""" Add meaningful description to **GitPython** opcodes.
:param opcode: OP_MASK opcode
:type opcode: int
:return: String description of opcode
:rtype: str
.. seealso:: For opcodes look at :class:`git.RemoteProgress`
"""
if opcode & self.COUNTING:
return self._description.get(self.COUNTING)
elif opcode & self.CHECKING_OUT:
return self._description.get(self.CHECKING_OUT)
elif opcode & self.WRITING:
return self._description.get(self.WRITING)
elif opcode & self.RECEIVING:
return self._description.get(self.RECEIVING)
elif opcode & self.RESOLVING:
return self._description.get(self.RESOLVING)
elif opcode & self.FINDING_SOURCES:
return self._description.get(self.FINDING_SOURCES)
else:
return "Processing"
def update(self, op_code, cur_count, max_count=None, message=''):
""" Called when git operation update progress.
.. seealso:: For more details see
:func:`git.objects.submodule.base.Submodule.update`
`Documentation <https://gitpython.readthedocs.io/en/\
stable/reference.html#git.objects.submodule.base.Submodule.update>`_
"""
code = self._check_mask(op_code)
if self._current_status != code or self._current_max != max_count:
self._current_max = max_count
self._current_status = code
self._detroy_tqdm()
self._t = tqdm(total=max_count)
self._t.set_description(" . {}".format(code))
self._t.update(cur_count)

View file

@ -42,13 +42,13 @@ except ImportError:
USE_UNICODE = hasattr(__builtins__, "unicode")
class PypeStreamHandler(logging.StreamHandler):
class LogStreamHandler(logging.StreamHandler):
""" StreamHandler class designed to handle utf errors in python 2.x hosts.
"""
def __init__(self, stream=None):
super(PypeStreamHandler, self).__init__(stream)
super(LogStreamHandler, self).__init__(stream)
self.enabled = True
def enable(self):
@ -57,7 +57,6 @@ class PypeStreamHandler(logging.StreamHandler):
Used to silence output
"""
self.enabled = True
pass
def disable(self):
""" Disable StreamHandler
@ -108,13 +107,13 @@ class PypeStreamHandler(logging.StreamHandler):
self.handleError(record)
class PypeFormatter(logging.Formatter):
class LogFormatter(logging.Formatter):
DFT = '%(levelname)s >>> { %(name)s }: [ %(message)s ]'
default_formatter = logging.Formatter(DFT)
def __init__(self, formats):
super(PypeFormatter, self).__init__()
super(LogFormatter, self).__init__()
self.formatters = {}
for loglevel in formats:
self.formatters[loglevel] = logging.Formatter(formats[loglevel])
@ -142,7 +141,7 @@ class PypeFormatter(logging.Formatter):
return out
class PypeMongoFormatter(logging.Formatter):
class MongoFormatter(logging.Formatter):
DEFAULT_PROPERTIES = logging.LogRecord(
'', '', '', '', '', '', '', '').__dict__.keys()
@ -162,7 +161,7 @@ class PypeMongoFormatter(logging.Formatter):
'method': record.funcName,
'lineNumber': record.lineno
}
document.update(PypeLogger.get_process_data())
document.update(Logger.get_process_data())
# Standard document decorated with exception info
if record.exc_info is not None:
@ -182,7 +181,7 @@ class PypeMongoFormatter(logging.Formatter):
return document
class PypeLogger:
class Logger:
DFT = '%(levelname)s >>> { %(name)s }: [ %(message)s ] '
DBG = " - { %(name)s }: [ %(message)s ] "
INF = ">>> [ %(message)s ] "
@ -240,7 +239,7 @@ class PypeLogger:
for handler in logger.handlers:
if isinstance(handler, MongoHandler):
add_mongo_handler = False
elif isinstance(handler, PypeStreamHandler):
elif isinstance(handler, LogStreamHandler):
add_console_handler = False
if add_console_handler:
@ -293,7 +292,7 @@ class PypeLogger:
"username": components["username"],
"password": components["password"],
"capped": True,
"formatter": PypeMongoFormatter()
"formatter": MongoFormatter()
}
if components["port"] is not None:
kwargs["port"] = int(components["port"])
@ -304,10 +303,10 @@ class PypeLogger:
@classmethod
def _get_console_handler(cls):
formatter = PypeFormatter(cls.FORMAT_FILE)
console_handler = PypeStreamHandler()
formatter = LogFormatter(cls.FORMAT_FILE)
console_handler = LogStreamHandler()
console_handler.set_name("PypeStreamHandler")
console_handler.set_name("LogStreamHandler")
console_handler.setFormatter(formatter)
return console_handler
@ -418,9 +417,9 @@ class PypeLogger:
def get_process_name(cls):
"""Process name that is like "label" of a process.
Pype's logging can be used from pype itseld of from hosts. Even in Pype
it's good to know if logs are from Pype tray or from pype's event
server. This should help to identify that information.
OpenPype's logging can be used from OpenPyppe itself of from hosts.
Even in OpenPype process it's good to know if logs are from tray or
from other cli commands. This should help to identify that information.
"""
if cls._process_name is not None:
return cls._process_name
@ -486,23 +485,13 @@ class PypeLogger:
return OpenPypeMongoConnection.get_mongo_client()
def timeit(method):
"""Print time in function.
For debugging.
"""
log = logging.getLogger()
def timed(*args, **kw):
ts = time.time()
result = method(*args, **kw)
te = time.time()
if 'log_time' in kw:
name = kw.get('log_name', method.__name__.upper())
kw['log_time'][name] = int((te - ts) * 1000)
else:
log.debug('%r %2.2f ms' % (method.__name__, (te - ts) * 1000))
print('%r %2.2f ms' % (method.__name__, (te - ts) * 1000))
return result
return timed
class PypeLogger(Logger):
@classmethod
def get_logger(cls, *args, **kwargs):
logger = Logger.get_logger(*args, **kwargs)
# TODO uncomment when replaced most of places
# logger.warning((
# "'openpype.lib.PypeLogger' is deprecated class."
# " Please use 'openpype.lib.Logger' instead."
# ))
return logger

View file

@ -16,7 +16,7 @@ from openpype_modules.ftrack.lib.avalon_sync import CUST_ATTR_ID_KEY
from openpype_modules.ftrack.lib.custom_attributes import (
query_custom_attributes
)
from openpype.lib import config
from openpype.lib.dateutils import get_datetime_data
from openpype.lib.delivery import (
path_from_representation,
get_format_dict,
@ -555,7 +555,7 @@ class Delivery(BaseAction):
format_dict = get_format_dict(anatomy, location_path)
datetime_data = config.get_datetime_data()
datetime_data = get_datetime_data()
for repre in repres_to_deliver:
source_path = repre.get("data", {}).get("path")
debug_msg = "Processing representation {}".format(repre["_id"])

View file

@ -4,10 +4,10 @@ from collections import defaultdict
from Qt import QtWidgets, QtCore, QtGui
from openpype.client import get_representations
from openpype.lib import config
from openpype.pipeline import load, Anatomy
from openpype import resources, style
from openpype.lib.dateutils import get_datetime_data
from openpype.lib.delivery import (
sizeof_fmt,
path_from_representation,
@ -160,7 +160,7 @@ class DeliveryOptionsDialog(QtWidgets.QDialog):
selected_repres = self._get_selected_repres()
datetime_data = config.get_datetime_data()
datetime_data = get_datetime_data()
template_name = self.dropdown.currentText()
format_dict = get_format_dict(self.anatomy, self.root_line_edit.text())
for repre in self._representations:

View file

@ -5,7 +5,7 @@ Provides:
"""
import pyblish.api
from openpype.api import config
from openpype.lib.dateutils import get_datetime_data
class CollectDateTimeData(pyblish.api.ContextPlugin):
@ -15,4 +15,4 @@ class CollectDateTimeData(pyblish.api.ContextPlugin):
def process(self, context):
key = "datetimeData"
if key not in context.data:
context.data[key] = config.get_datetime_data()
context.data[key] = get_datetime_data()