1
0
Fork 0
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:
torzdf 2022-07-28 23:53:31 +01:00
parent dcb436c9df
commit 03f6cb4e7e
12 changed files with 732 additions and 403 deletions

View file

@ -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 () {

View file

@ -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

View file

@ -8,3 +8,5 @@ faceswap
plugins/plugins
scripts
tools/tools
setup
update_deps

8
docs/full/setup.rst Normal file
View file

@ -0,0 +1,8 @@
************
setup module
************
.. automodule:: setup
:members:
:undoc-members:
:show-inheritance:

View file

@ -0,0 +1,8 @@
******************
update_deps module
******************
.. automodule:: update_deps
:members:
:undoc-members:
:show-inheritance:

View file

@ -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()

View file

@ -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,9 +263,9 @@ 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)
stdout, _ = cmd.communicate()
retcode = cmd.poll()
with Popen(gitcmd, shell=True, stdout=PIPE, stderr=STDOUT, cwd=_WORKING_DIR) as cmd:
stdout, _ = cmd.communicate()
retcode = cmd.poll()
if retcode != 0:
logger.debug("Unable to list git branches. return code: %s, message: %s",
retcode, stdout.decode().strip().replace("\n", " - "))
@ -315,10 +315,10 @@ 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)
stdout, _ = cmd.communicate()
retcode = cmd.poll()
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:
logger.error("Unable to switch branch. return code: %s, message: %s",
retcode, stdout.decode().strip().replace("\n", " - "))
@ -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,9 +395,9 @@ 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)
stdout, _ = cmd.communicate()
retcode = cmd.poll()
with Popen(gitcmd, shell=True, stdout=PIPE, stderr=STDOUT, cwd=_WORKING_DIR) as cmd:
stdout, _ = cmd.communicate()
retcode = cmd.poll()
if retcode != 0:
msg = ("Git is not installed or you are not running a cloned repo. "
"Unable to check for updates")
@ -427,15 +427,20 @@ 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)
while True:
output = cmd.stdout.readline().decode(encoding)
if output == "" and cmd.poll() is not None:
break
if output:
logger.debug("'%s' output: '%s'", gitcmd, output.strip())
print(output.strip())
retcode = cmd.poll()
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:
break
if output:
logger.debug("'%s' output: '%s'", gitcmd, output.strip())
print(output.strip())
retcode = cmd.poll()
logger.debug("'%s' returncode: %s", gitcmd, retcode)
if retcode != 0:
logger.info("An error occurred during update. return code: %s", retcode)
@ -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(

View file

@ -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)
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)
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")
s_handler = _stream_handler(numeric_loglevel, is_gui)
f_handler = _file_handler(numeric_loglevel, log_file, log_format, command)
rootlogger.addHandler(f_handler)
rootlogger.addHandler(s_handler)
rootlogger.addHandler(c_handler)
logging.info("Log level set to: %s", loglevel.upper())
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

View file

@ -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"

View file

@ -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.*]

787
setup.py

File diff suppressed because it is too large Load diff

View file

@ -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()