mirror of
https://github.com/deepfakes/faceswap
synced 2025-06-07 10:43:27 -04:00
setup.py: implement logging
This commit is contained in:
parent
dcb436c9df
commit
03f6cb4e7e
12 changed files with 732 additions and 403 deletions
|
@ -385,7 +385,7 @@ setup_faceswap() {
|
|||
# Run faceswap setup script
|
||||
info "Setting up Faceswap..."
|
||||
if [ $VERSION != "cpu" ] ; then args="--$VERSION" ; else args="" ; fi
|
||||
python "$DIR_FACESWAP/setup.py" --installer $args
|
||||
python -u "$DIR_FACESWAP/setup.py" --installer $args
|
||||
}
|
||||
|
||||
create_gui_launcher () {
|
||||
|
|
|
@ -448,7 +448,7 @@ Function SetupFaceSwap
|
|||
StrCpy $0 "$0 --$setupType"
|
||||
${EndIf}
|
||||
SetDetailsPrint listonly
|
||||
ExecDos::exec /NOUNLOAD /ASYNC /DETAILED "$\"$dirConda\scripts\activate.bat$\" && conda activate $\"$envName$\" && python $\"$INSTDIR\setup.py$\" $0 && conda deactivate"
|
||||
ExecDos::exec /NOUNLOAD /ASYNC /DETAILED "$\"$dirConda\scripts\activate.bat$\" && conda activate $\"$envName$\" && python -u $\"$INSTDIR\setup.py$\" $0 && conda deactivate"
|
||||
pop $0
|
||||
ExecDos::wait $0
|
||||
pop $0
|
||||
|
|
|
@ -8,3 +8,5 @@ faceswap
|
|||
plugins/plugins
|
||||
scripts
|
||||
tools/tools
|
||||
setup
|
||||
update_deps
|
||||
|
|
8
docs/full/setup.rst
Normal file
8
docs/full/setup.rst
Normal file
|
@ -0,0 +1,8 @@
|
|||
************
|
||||
setup module
|
||||
************
|
||||
|
||||
.. automodule:: setup
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
8
docs/full/update_deps.rst
Normal file
8
docs/full/update_deps.rst
Normal file
|
@ -0,0 +1,8 @@
|
|||
******************
|
||||
update_deps module
|
||||
******************
|
||||
|
||||
.. automodule:: update_deps
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
|
@ -238,6 +238,7 @@ class _SysOutRouter():
|
|||
self._console = console
|
||||
self._out_type = out_type
|
||||
self._recolor = re.compile(r".+?(\s\d+:\d+:\d+\s)(?P<lvl>[A-Z]+)\s")
|
||||
self._ansi_escape = re.compile(r"\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])")
|
||||
logger.debug("Initialized %s", self.__class__.__name__)
|
||||
|
||||
def _get_tag(self, string):
|
||||
|
@ -254,6 +255,7 @@ class _SysOutRouter():
|
|||
|
||||
def write(self, string):
|
||||
""" Capture stdout/stderr """
|
||||
string = self._ansi_escape.sub("", string)
|
||||
self._console.insert(tk.END, string, self._get_tag(string))
|
||||
self._console.see(tk.END)
|
||||
|
||||
|
@ -315,9 +317,8 @@ class _WidgetRedirector:
|
|||
tk_.createcommand(wgt, self.dispatch)
|
||||
|
||||
def __repr__(self):
|
||||
return "%s(%s<%s>)" % (self.__class__.__name__,
|
||||
self.widget.__class__.__name__,
|
||||
self.widget._w) # pylint:disable=protected-access
|
||||
return (f"{self.__class__.__name__}({self.widget.__class__.__name__}"
|
||||
f"<{self.widget._w}>)") # pylint:disable=protected-access
|
||||
|
||||
def close(self):
|
||||
"de-register operations and revert redirection created by .__init__."
|
||||
|
@ -409,8 +410,7 @@ class _OriginalCommand:
|
|||
self.orig_and_operation = (redirect.orig, operation)
|
||||
|
||||
def __repr__(self):
|
||||
return "%s(%r, %r)" % (self.__class__.__name__,
|
||||
self.redirect, self.operation)
|
||||
return f"{self.__class__.__name__}({self.redirect}, {self.operation})"
|
||||
|
||||
def __call__(self, *args):
|
||||
return self.tk_call(self.orig_and_operation + args)
|
||||
|
@ -619,12 +619,8 @@ class Tooltip: # pylint:disable=too-few-public-methods
|
|||
x_1, y_1 = mouse_x + tip_delta[0], mouse_y + tip_delta[1]
|
||||
x_2, y_2 = x_1 + width, y_1 + height
|
||||
|
||||
x_delta = x_2 - s_width
|
||||
if x_delta < 0:
|
||||
x_delta = 0
|
||||
y_delta = y_2 - s_height
|
||||
if y_delta < 0:
|
||||
y_delta = 0
|
||||
x_delta = max(x_2 - s_width, 0)
|
||||
y_delta = max(y_2 - s_height, 0)
|
||||
|
||||
offscreen = (x_delta, y_delta) != (0, 0)
|
||||
|
||||
|
@ -670,7 +666,7 @@ class Tooltip: # pylint:disable=too-few-public-methods
|
|||
|
||||
text = self._text
|
||||
if self._text_variable and self._text_variable.get():
|
||||
text += "\n\nCurrent value: '{}'".format(self._text_variable.get())
|
||||
text += f"\n\nCurrent value: '{self._text_variable.get()}'"
|
||||
label = tk.Label(win,
|
||||
text=text,
|
||||
justify=tk.LEFT,
|
||||
|
@ -687,7 +683,7 @@ class Tooltip: # pylint:disable=too-few-public-methods
|
|||
|
||||
xpos, ypos = tip_pos_calculator(widget, label)
|
||||
|
||||
self._topwidget.wm_geometry("+%d+%d" % (xpos, ypos))
|
||||
self._topwidget.wm_geometry(f"+{xpos}+{ypos}")
|
||||
|
||||
def _hide(self):
|
||||
""" Hide the tooltip """
|
||||
|
@ -819,7 +815,7 @@ class PopupProgress(tk.Toplevel):
|
|||
center = np.array((
|
||||
(self.master.winfo_width() // 2) - (self.winfo_width() // 2),
|
||||
(self.master.winfo_height() // 2) - (self.winfo_height() // 2))) + offset
|
||||
self.wm_geometry("+{}+{}".format(*center))
|
||||
self.wm_geometry(f"+{center[0]}+{center[1]}")
|
||||
get_config().set_cursor_busy()
|
||||
self.grab_set()
|
||||
|
||||
|
|
|
@ -166,10 +166,10 @@ class FileMenu(tk.Menu): # pylint:disable=too-many-ancestors
|
|||
kwargs = dict(filename=filename)
|
||||
else:
|
||||
load_func = self._config.tasks.load
|
||||
lbl = "{} Task".format(command)
|
||||
lbl = f"{command} Task"
|
||||
kwargs = dict(filename=filename, current_tab=False)
|
||||
self.recent_menu.add_command(
|
||||
label="{} ({})".format(filename, lbl.title()),
|
||||
label=f"{filename} ({lbl.title()})",
|
||||
command=lambda kw=kwargs, fn=load_func: fn(**kw))
|
||||
if removed_files:
|
||||
for recent_item in removed_files:
|
||||
|
@ -188,7 +188,7 @@ class FileMenu(tk.Menu): # pylint:disable=too-many-ancestors
|
|||
def clear_recent_files(serializer, menu_file):
|
||||
""" Creates or clears recent file list """
|
||||
logger.debug("clearing recent files list: '%s'", menu_file)
|
||||
serializer.save(menu_file, list())
|
||||
serializer.save(menu_file, [])
|
||||
|
||||
def refresh_recent_menu(self):
|
||||
""" Refresh recent menu on save/load of files """
|
||||
|
@ -263,7 +263,7 @@ class HelpMenu(tk.Menu): # pylint:disable=too-many-ancestors
|
|||
error then `None` is returned
|
||||
"""
|
||||
gitcmd = "git branch -a"
|
||||
cmd = Popen(gitcmd, shell=True, stdout=PIPE, stderr=STDOUT, cwd=_WORKING_DIR)
|
||||
with Popen(gitcmd, shell=True, stdout=PIPE, stderr=STDOUT, cwd=_WORKING_DIR) as cmd:
|
||||
stdout, _ = cmd.communicate()
|
||||
retcode = cmd.poll()
|
||||
if retcode != 0:
|
||||
|
@ -315,8 +315,8 @@ class HelpMenu(tk.Menu): # pylint:disable=too-many-ancestors
|
|||
The branch to switch to
|
||||
"""
|
||||
logger.info("Switching branch to '%s'...", branch)
|
||||
gitcmd = "git checkout {}".format(branch)
|
||||
cmd = Popen(gitcmd, shell=True, stdout=PIPE, stderr=STDOUT, cwd=_WORKING_DIR)
|
||||
gitcmd = f"git checkout {branch}"
|
||||
with Popen(gitcmd, shell=True, stdout=PIPE, stderr=STDOUT, cwd=_WORKING_DIR) as cmd:
|
||||
stdout, _ = cmd.communicate()
|
||||
retcode = cmd.poll()
|
||||
if retcode != 0:
|
||||
|
@ -358,7 +358,7 @@ class HelpMenu(tk.Menu): # pylint:disable=too-many-ancestors
|
|||
from lib.sysinfo import sysinfo # pylint:disable=import-outside-toplevel
|
||||
info = sysinfo
|
||||
except Exception as err: # pylint:disable=broad-except
|
||||
info = "Error obtaining system info: {}".format(str(err))
|
||||
info = f"Error obtaining system info: {str(err)}"
|
||||
self.clear_console()
|
||||
logger.debug("Obtained system information: %s", info)
|
||||
print(info)
|
||||
|
@ -382,7 +382,7 @@ class HelpMenu(tk.Menu): # pylint:disable=too-many-ancestors
|
|||
success = False
|
||||
if self.check_for_updates(encoding):
|
||||
success = self.do_update(encoding)
|
||||
update_deps.main(logger=logger)
|
||||
update_deps.main(is_gui=True)
|
||||
if success:
|
||||
logger.info("Please restart Faceswap to complete the update.")
|
||||
self.root.config(cursor="")
|
||||
|
@ -395,7 +395,7 @@ class HelpMenu(tk.Menu): # pylint:disable=too-many-ancestors
|
|||
update = False
|
||||
msg = ""
|
||||
gitcmd = "git remote update && git status -uno"
|
||||
cmd = Popen(gitcmd, shell=True, stdout=PIPE, stderr=STDOUT, cwd=_WORKING_DIR)
|
||||
with Popen(gitcmd, shell=True, stdout=PIPE, stderr=STDOUT, cwd=_WORKING_DIR) as cmd:
|
||||
stdout, _ = cmd.communicate()
|
||||
retcode = cmd.poll()
|
||||
if retcode != 0:
|
||||
|
@ -427,7 +427,12 @@ class HelpMenu(tk.Menu): # pylint:disable=too-many-ancestors
|
|||
""" Update Faceswap """
|
||||
logger.info("A new version is available. Updating...")
|
||||
gitcmd = "git pull"
|
||||
cmd = Popen(gitcmd, shell=True, stdout=PIPE, stderr=STDOUT, bufsize=1, cwd=_WORKING_DIR)
|
||||
with Popen(gitcmd,
|
||||
shell=True,
|
||||
stdout=PIPE,
|
||||
stderr=STDOUT,
|
||||
bufsize=1,
|
||||
cwd=_WORKING_DIR) as cmd:
|
||||
while True:
|
||||
output = cmd.stdout.readline().decode(encoding)
|
||||
if output == "" and cmd.poll() is not None:
|
||||
|
@ -482,7 +487,7 @@ class TaskBar(ttk.Frame): # pylint: disable=too-many-ancestors
|
|||
frame.pack(side=tk.LEFT, anchor=tk.W, expand=False, padx=2)
|
||||
|
||||
for loadtype in ("load", "save", "save_as", "clear", "reload"):
|
||||
btntype = "{}2".format(loadtype)
|
||||
btntype = f"{loadtype}2"
|
||||
logger.debug("Adding button: '%s'", btntype)
|
||||
|
||||
loader, kwargs = self._loader_and_kwargs(loadtype)
|
||||
|
@ -507,7 +512,7 @@ class TaskBar(ttk.Frame): # pylint: disable=too-many-ancestors
|
|||
kwargs = dict(save_as=True)
|
||||
else:
|
||||
loader = btntype
|
||||
kwargs = dict()
|
||||
kwargs = {}
|
||||
logger.debug("btntype: %s, loader: %s, kwargs: %s", btntype, loader, kwargs)
|
||||
return loader, kwargs
|
||||
|
||||
|
@ -516,7 +521,7 @@ class TaskBar(ttk.Frame): # pylint: disable=too-many-ancestors
|
|||
frame = ttk.Frame(self._btn_frame)
|
||||
frame.pack(side=tk.LEFT, anchor=tk.W, expand=False, padx=2)
|
||||
for name in ("extract", "train", "convert"):
|
||||
btntype = "settings_{}".format(name)
|
||||
btntype = f"settings_{name}"
|
||||
btntype = btntype if btntype in get_images().icons else "settings"
|
||||
logger.debug("Adding button: '%s'", btntype)
|
||||
btn = ttk.Button(
|
||||
|
|
189
lib/logger.py
189
lib/logger.py
|
@ -4,16 +4,19 @@ import collections
|
|||
import logging
|
||||
from logging.handlers import RotatingFileHandler
|
||||
import os
|
||||
import platform
|
||||
import re
|
||||
import sys
|
||||
import time
|
||||
import traceback
|
||||
|
||||
from datetime import datetime
|
||||
from tqdm import tqdm
|
||||
from typing import Union
|
||||
|
||||
|
||||
class FaceswapLogger(logging.Logger):
|
||||
""" A standard :class:`logging.logger` with additional "verbose" and "trace" levels added. """
|
||||
def __init__(self, name):
|
||||
def __init__(self, name: str) -> None:
|
||||
for new_level in (("VERBOSE", 15), ("TRACE", 5)):
|
||||
level_name, level_num = new_level
|
||||
if hasattr(logging, level_name):
|
||||
|
@ -22,7 +25,7 @@ class FaceswapLogger(logging.Logger):
|
|||
setattr(logging, level_name, level_num)
|
||||
super().__init__(name)
|
||||
|
||||
def verbose(self, msg, *args, **kwargs):
|
||||
def verbose(self, msg: str, *args, **kwargs) -> None:
|
||||
# pylint:disable=wrong-spelling-in-docstring
|
||||
""" Create a log message at severity level 15.
|
||||
|
||||
|
@ -38,7 +41,7 @@ class FaceswapLogger(logging.Logger):
|
|||
if self.isEnabledFor(15):
|
||||
self._log(15, msg, args, **kwargs)
|
||||
|
||||
def trace(self, msg, *args, **kwargs):
|
||||
def trace(self, msg: str, *args, **kwargs) -> None:
|
||||
# pylint:disable=wrong-spelling-in-docstring
|
||||
""" Create a log message at severity level 5.
|
||||
|
||||
|
@ -55,6 +58,102 @@ class FaceswapLogger(logging.Logger):
|
|||
self._log(5, msg, args, **kwargs)
|
||||
|
||||
|
||||
class ColoredFormatter(logging.Formatter):
|
||||
""" Overrides the stand :class:`logging.Formatter` to enable colored labels for message level
|
||||
labels on supported platforms
|
||||
|
||||
Parameters
|
||||
----------
|
||||
fmt: str
|
||||
The format string for the message as a whole
|
||||
pad_newlines: bool, Optional
|
||||
If ``True`` new lines will be padded to appear in line with the log message, if ``False``
|
||||
they will be left aligned
|
||||
|
||||
kwargs: dict
|
||||
Standard :class:`logging.Formatter` keyword arguments
|
||||
"""
|
||||
def __init__(self, fmt: str, pad_newlines: bool = False, **kwargs) -> None:
|
||||
super().__init__(fmt, **kwargs)
|
||||
self._use_color = platform.system().lower() in ("linux", "darwin")
|
||||
self._level_colors = dict(CRITICAL="\033[31m", # red
|
||||
ERROR="\033[31m", # red
|
||||
WARNING="\033[33m", # yellow
|
||||
INFO="\033[32m", # green
|
||||
VERBOSE="\033[34m") # blue
|
||||
self._default_color = "\033[0m"
|
||||
self._newline_padding = self._get_newline_padding(pad_newlines, fmt)
|
||||
|
||||
def _get_newline_padding(self, pad_newlines: bool, fmt: str) -> int:
|
||||
""" Parses the format string to obtain padding for newlines if requested
|
||||
|
||||
Parameters
|
||||
----------
|
||||
fmt: str
|
||||
The format string for the message as a whole
|
||||
pad_newlines: bool, Optional
|
||||
If ``True`` new lines will be padded to appear in line with the log message, if
|
||||
``False`` they will be left aligned
|
||||
|
||||
Returns
|
||||
-------
|
||||
int
|
||||
The amount of padding to apply to the front of newlines
|
||||
"""
|
||||
if not pad_newlines:
|
||||
return 0
|
||||
msg_idx = fmt.find("%(message)") + 1
|
||||
filtered = fmt[:msg_idx - 1]
|
||||
spaces = filtered.count(" ")
|
||||
pads = [int(pad.replace("s", "")) for pad in re.findall(r"\ds", filtered)]
|
||||
if "asctime" in filtered:
|
||||
pads.append(self._get_sample_time_string())
|
||||
return sum(pads) + spaces
|
||||
|
||||
def _get_sample_time_string(self) -> int:
|
||||
""" Obtain a sample time string and calculate correct padding.
|
||||
|
||||
This may be inaccurate wheb ticking over an integer from single to double digits, but that
|
||||
shouldn't be a huge issue.
|
||||
|
||||
Returns
|
||||
-------
|
||||
int
|
||||
The length of the formatted date-time string
|
||||
"""
|
||||
sample_time = time.time()
|
||||
date_format = self.datefmt if self.datefmt else self.default_time_format
|
||||
datestring = time.strftime(date_format, logging.Formatter.converter(sample_time))
|
||||
if not self.datefmt and self.default_msec_format:
|
||||
msecs = (sample_time - int(sample_time)) * 1000
|
||||
datestring = self.default_msec_format % (datestring, msecs)
|
||||
return len(datestring)
|
||||
|
||||
def format(self, record: logging.LogRecord) -> str:
|
||||
""" Color the log message level if supported otherwise return the standard log message.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
record: :class:`logging.LogRecord`
|
||||
The incoming log record to be formatted for entry into the logger.
|
||||
|
||||
Returns
|
||||
-------
|
||||
str
|
||||
The formatted log message
|
||||
"""
|
||||
formatted = super().format(record)
|
||||
levelname = record.levelname
|
||||
if self._use_color and levelname in self._level_colors:
|
||||
formatted = re.sub(levelname,
|
||||
f"{self._level_colors[levelname]}{levelname}{self._default_color}",
|
||||
formatted,
|
||||
1)
|
||||
if self._newline_padding:
|
||||
formatted = formatted.replace("\n", f"\n{' ' * self._newline_padding}")
|
||||
return formatted
|
||||
|
||||
|
||||
class FaceswapFormatter(logging.Formatter):
|
||||
""" Overrides the standard :class:`logging.Formatter`.
|
||||
|
||||
|
@ -63,7 +162,7 @@ class FaceswapFormatter(logging.Formatter):
|
|||
Rewrites some upstream warning messages to debug level to avoid spamming the console.
|
||||
"""
|
||||
|
||||
def format(self, record):
|
||||
def format(self, record: logging.LogRecord) -> str:
|
||||
""" Strip new lines from log records and rewrite certain warning messages to debug level.
|
||||
|
||||
Parameters
|
||||
|
@ -102,7 +201,7 @@ class FaceswapFormatter(logging.Formatter):
|
|||
return msg
|
||||
|
||||
@classmethod
|
||||
def _rewrite_warnings(cls, record):
|
||||
def _rewrite_warnings(cls, record: logging.LogRecord) -> logging.LogRecord:
|
||||
""" Change certain warning messages from WARNING to DEBUG to avoid passing non-important
|
||||
information to output.
|
||||
|
||||
|
@ -133,7 +232,7 @@ class FaceswapFormatter(logging.Formatter):
|
|||
return record
|
||||
|
||||
@classmethod
|
||||
def _lower_external(cls, record):
|
||||
def _lower_external(cls, record: logging.LogRecord) -> logging.LogRecord:
|
||||
""" Some external libs log at a higher level than we would really like, so lower their
|
||||
log level.
|
||||
|
||||
|
@ -162,7 +261,7 @@ class RollingBuffer(collections.deque):
|
|||
"""File-like that keeps a certain number of lines of text in memory for writing out to the
|
||||
crash log. """
|
||||
|
||||
def write(self, buffer):
|
||||
def write(self, buffer: str) -> None:
|
||||
""" Splits lines from the incoming buffer and writes them out to the rolling buffer.
|
||||
|
||||
Parameters
|
||||
|
@ -178,7 +277,7 @@ class TqdmHandler(logging.StreamHandler):
|
|||
""" Overrides :class:`logging.StreamHandler` to use :func:`tqdm.tqdm.write` rather than writing
|
||||
to :func:`sys.stderr` so that log messages do not mess up tqdm progress bars. """
|
||||
|
||||
def emit(self, record):
|
||||
def emit(self, record: logging.LogRecord) -> None:
|
||||
""" Format the incoming message and pass to :func:`tqdm.tqdm.write`.
|
||||
|
||||
Parameters
|
||||
|
@ -186,11 +285,13 @@ class TqdmHandler(logging.StreamHandler):
|
|||
record : :class:`logging.LogRecord`
|
||||
The incoming log record to be formatted for entry into the logger.
|
||||
"""
|
||||
# tqdm is imported here as it won't be installed when setup.py is running
|
||||
from tqdm import tqdm # pylint:disable=import-outside-toplevel
|
||||
msg = self.format(record)
|
||||
tqdm.write(msg)
|
||||
|
||||
|
||||
def _set_root_logger(loglevel=logging.INFO):
|
||||
def _set_root_logger(loglevel: int = logging.INFO) -> logging.Logger:
|
||||
""" Setup the root logger.
|
||||
|
||||
Parameters
|
||||
|
@ -208,7 +309,7 @@ def _set_root_logger(loglevel=logging.INFO):
|
|||
return rootlogger
|
||||
|
||||
|
||||
def log_setup(loglevel, log_file, command, is_gui=False):
|
||||
def log_setup(loglevel, log_file: str, command: str, is_gui: bool = False) -> None:
|
||||
""" Set up logging for Faceswap.
|
||||
|
||||
Sets up the root logger, the formatting for the crash logger and the file logger, and sets up
|
||||
|
@ -230,19 +331,32 @@ def log_setup(loglevel, log_file, command, is_gui=False):
|
|||
numeric_loglevel = get_loglevel(loglevel)
|
||||
root_loglevel = min(logging.DEBUG, numeric_loglevel)
|
||||
rootlogger = _set_root_logger(loglevel=root_loglevel)
|
||||
|
||||
if command == "setup":
|
||||
log_format = FaceswapFormatter("%(asctime)s %(module)-16s %(funcName)-30s %(levelname)-8s "
|
||||
"%(message)s", datefmt="%m/%d/%Y %H:%M:%S")
|
||||
s_handler = _stream_setup_handler(numeric_loglevel)
|
||||
f_handler = _file_handler(root_loglevel, log_file, log_format, command)
|
||||
else:
|
||||
log_format = FaceswapFormatter("%(asctime)s %(processName)-15s %(threadName)-30s "
|
||||
"%(module)-15s %(funcName)-30s %(levelname)-8s %(message)s",
|
||||
datefmt="%m/%d/%Y %H:%M:%S")
|
||||
f_handler = _file_handler(numeric_loglevel, log_file, log_format, command)
|
||||
s_handler = _stream_handler(numeric_loglevel, is_gui)
|
||||
c_handler = _crash_handler(log_format)
|
||||
f_handler = _file_handler(numeric_loglevel, log_file, log_format, command)
|
||||
|
||||
rootlogger.addHandler(f_handler)
|
||||
rootlogger.addHandler(s_handler)
|
||||
|
||||
if command != "setup":
|
||||
c_handler = _crash_handler(log_format)
|
||||
rootlogger.addHandler(c_handler)
|
||||
logging.info("Log level set to: %s", loglevel.upper())
|
||||
|
||||
|
||||
def _file_handler(loglevel, log_file, log_format, command):
|
||||
def _file_handler(loglevel,
|
||||
log_file: str,
|
||||
log_format: FaceswapFormatter,
|
||||
command: str) -> RotatingFileHandler:
|
||||
""" Add a rotating file handler for the current Faceswap session. 1 backup is always kept.
|
||||
|
||||
Parameters
|
||||
|
@ -270,21 +384,21 @@ def _file_handler(loglevel, log_file, log_format, command):
|
|||
filename += "_gui.log" if command == "gui" else ".log"
|
||||
|
||||
should_rotate = os.path.isfile(filename)
|
||||
log_file = RotatingFileHandler(filename, backupCount=1, encoding="utf-8")
|
||||
handler = RotatingFileHandler(filename, backupCount=1, encoding="utf-8")
|
||||
if should_rotate:
|
||||
log_file.doRollover()
|
||||
log_file.setFormatter(log_format)
|
||||
log_file.setLevel(loglevel)
|
||||
return log_file
|
||||
handler.doRollover()
|
||||
handler.setFormatter(log_format)
|
||||
handler.setLevel(loglevel)
|
||||
return handler
|
||||
|
||||
|
||||
def _stream_handler(loglevel, is_gui):
|
||||
def _stream_handler(loglevel: int, is_gui: bool) -> Union[logging.StreamHandler, TqdmHandler]:
|
||||
""" Add a stream handler for the current Faceswap session. The stream handler will only ever
|
||||
output at a maximum of VERBOSE level to avoid spamming the console.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
loglevel: str
|
||||
loglevel: int
|
||||
The requested log level that messages should be logged at.
|
||||
is_gui: bool, optional
|
||||
Whether Faceswap is running in the GUI or not. Dictates where the stream handler should
|
||||
|
@ -311,7 +425,30 @@ def _stream_handler(loglevel, is_gui):
|
|||
return log_console
|
||||
|
||||
|
||||
def _crash_handler(log_format):
|
||||
def _stream_setup_handler(loglevel: int) -> logging.StreamHandler:
|
||||
""" Add a stream handler for faceswap's setup.py script
|
||||
This stream handler outputs a limited set of easy to use information using colored labels
|
||||
if available. It will only ever output at a minimum of INFO level
|
||||
|
||||
Parameters
|
||||
----------
|
||||
loglevel: int
|
||||
The requested log level that messages should be logged at.
|
||||
|
||||
Returns
|
||||
-------
|
||||
:class:`logging.StreamHandler`
|
||||
The stream handler to use
|
||||
"""
|
||||
loglevel = max(loglevel, 15)
|
||||
log_format = ColoredFormatter("%(levelname)-8s %(message)s", pad_newlines=True)
|
||||
handler = logging.StreamHandler(sys.stdout)
|
||||
handler.setFormatter(log_format)
|
||||
handler.setLevel(loglevel)
|
||||
return handler
|
||||
|
||||
|
||||
def _crash_handler(log_format: FaceswapFormatter) -> logging.StreamHandler:
|
||||
""" Add a handler that stores the last 100 debug lines to :attr:'_DEBUG_BUFFER' for use in
|
||||
crash reports.
|
||||
|
||||
|
@ -331,7 +468,7 @@ def _crash_handler(log_format):
|
|||
return log_crash
|
||||
|
||||
|
||||
def get_loglevel(loglevel):
|
||||
def get_loglevel(loglevel: str) -> int:
|
||||
""" Check whether a valid log level has been supplied, and return the numeric log level that
|
||||
corresponds to the given string level.
|
||||
|
||||
|
@ -351,7 +488,7 @@ def get_loglevel(loglevel):
|
|||
return numeric_level
|
||||
|
||||
|
||||
def crash_log():
|
||||
def crash_log() -> str:
|
||||
""" On a crash, write out the contents of :func:`_DEBUG_BUFFER` containing the last 100 lines
|
||||
of debug messages to a crash report in the root Faceswap folder.
|
||||
|
||||
|
@ -379,11 +516,11 @@ def crash_log():
|
|||
_OLD_FACTORY = logging.getLogRecordFactory()
|
||||
|
||||
|
||||
def _faceswap_logrecord(*args, **kwargs):
|
||||
def _faceswap_logrecord(*args, **kwargs) -> logging.LogRecord:
|
||||
""" Add a flag to :class:`logging.LogRecord` to not strip formatting from particular
|
||||
records. """
|
||||
record = _OLD_FACTORY(*args, **kwargs)
|
||||
record.strip_spaces = True
|
||||
record.strip_spaces = True # type:ignore
|
||||
return record
|
||||
|
||||
|
||||
|
|
|
@ -13,6 +13,6 @@ ffmpy==0.2.3
|
|||
#nvidia-ml-py>=11.510,<300
|
||||
# Pin nvidida-ml-py to <11.515 until we know if bytes->str is an error or permanent change
|
||||
nvidia-ml-py<11.515
|
||||
tensorflow_probability<0.17
|
||||
tensorflow-probability<0.17
|
||||
typing-extensions>=4.0.0
|
||||
pywin32>=228 ; sys_platform == "win32"
|
||||
|
|
|
@ -16,6 +16,8 @@ ignore_missing_imports = True
|
|||
ignore_missing_imports = True
|
||||
[mypy-matplotlib.*]
|
||||
ignore_missing_imports = True
|
||||
[mypy-pexpect.*]
|
||||
ignore_missing_imports = True
|
||||
[mypy-PIL.*]
|
||||
ignore_missing_imports = True
|
||||
[mypy-plaidml.*]
|
||||
|
|
|
@ -3,30 +3,32 @@
|
|||
|
||||
Checks for installed Conda / Pip packages and updates accordingly
|
||||
"""
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
|
||||
from setup import Environment, Install, Output
|
||||
from lib.logger import log_setup
|
||||
from setup import Environment, Install
|
||||
|
||||
_LOGGER = None
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def output(msg):
|
||||
""" Output to print or logger """
|
||||
if _LOGGER is not None:
|
||||
_LOGGER.info(msg)
|
||||
else:
|
||||
Output().info(msg)
|
||||
def main(is_gui=False) -> None:
|
||||
""" Check for and update dependencies
|
||||
|
||||
|
||||
def main(logger=None):
|
||||
""" Check for and update dependencies """
|
||||
if logger is not None:
|
||||
global _LOGGER # pylint:disable=global-statement
|
||||
_LOGGER = logger
|
||||
output("Updating dependencies...")
|
||||
update = Environment(logger=logger, updater=True)
|
||||
Install(update)
|
||||
output("Dependencies updated")
|
||||
Parameters
|
||||
----------
|
||||
is_gui: bool, optional
|
||||
``True`` if being called by the GUI. Prevents the updater from outputting progress bars
|
||||
which get scrambled in the GUI
|
||||
"""
|
||||
logger.info("Updating dependencies...")
|
||||
update = Environment(updater=True)
|
||||
Install(update, is_gui=is_gui)
|
||||
logger.info("Dependencies updated")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
logfile = os.path.join(os.path.dirname(os.path.realpath(sys.argv[0])), "faceswap_update.log")
|
||||
log_setup("INFO", logfile, "setup")
|
||||
main()
|
||||
|
|
Loading…
Add table
Reference in a new issue