Merge pull request #3763 from vladmandic/dev

refresh master
This commit is contained in:
Vladimir Mandic
2025-02-20 12:56:48 -05:00
committed by GitHub
6 changed files with 37 additions and 16 deletions
+11 -1
View File
@@ -2,7 +2,17 @@
## Update for 2025-02-20
### Highlight for 2025-02-20
Quick release refresh:
- remove ui splash screen on auth fail
- add `--extensions-dir` cli arg and `SD_EXTENSIONSDIR` env variable to specify extensions directory
- log full path when reading/saving `config.json`
- log full path to `sdnext.log`
- log system hostname in `sdnext.log`
- log extensions path in `sdnext.log`
## Update for 2025-02-18
### Highlight for 2025-02-18
We're back with another update with nearly 100 commits!
- Starting with massive UI update with full [localization](https://vladmandic.github.io/sdnext-docs/Locale/) for 8 languages
+5 -4
View File
@@ -5,6 +5,7 @@ import json
import time
import shutil
import locale
import socket
import logging
import platform
import subprocess
@@ -26,6 +27,7 @@ console = None
debug = log.debug if os.environ.get('SD_INSTALL_DEBUG', None) is not None else lambda *args, **kwargs: None
pip_log = '--log pip.log ' if os.environ.get('SD_PIP_DEBUG', None) is not None else ''
log_file = os.path.join(os.path.dirname(__file__), 'sdnext.log')
hostname = socket.gethostname()
log_rolled = False
first_call = True
quick_allowed = True
@@ -176,7 +178,7 @@ def setup_logging():
fh.doRollover()
log_rolled = True
fh.formatter = logging.Formatter('%(asctime)s | %(name)s | %(levelname)s | %(module)s | %(message)s')
fh.formatter = logging.Formatter(f'%(asctime)s | {hostname} | %(name)s | %(levelname)s | %(module)s | %(message)s')
fh.setLevel(logging.DEBUG)
log.addHandler(fh)
@@ -203,7 +205,7 @@ def setup_logging():
def get_logfile():
log_size = os.path.getsize(log_file) if os.path.exists(log_file) else 0
log.info(f'Logger: file="{log_file}" level={logging.getLevelName(logging.DEBUG if args.debug else logging.INFO)} size={log_size} mode={"append" if not log_rolled else "create"}')
log.info(f'Logger: file="{os.path.abspath(log_file)}" level={logging.getLevelName(logging.DEBUG if args.debug else logging.INFO)} host="{hostname}" size={log_size} mode={"append" if not log_rolled else "create"}')
return log_file
@@ -979,14 +981,13 @@ def run_extension_installer(folder):
# get list of all enabled extensions
def list_extensions_folder(folder, quiet=False):
name = os.path.basename(folder)
disabled_extensions_all = opts.get('disable_all_extensions', 'none')
if disabled_extensions_all != 'none':
return []
disabled_extensions = opts.get('disabled_extensions', [])
enabled_extensions = [x for x in os.listdir(folder) if os.path.isdir(os.path.join(folder, x)) and x not in disabled_extensions and not x.startswith('.')]
if not quiet:
log.info(f'Extensions: enabled={enabled_extensions} {name}')
log.info(f'Extensions: path="{folder}" enabled={enabled_extensions}')
return enabled_extensions
+16 -10
View File
@@ -19,11 +19,22 @@ async function preloadImages() {
}
try {
await Promise.all(imagePromises);
return true;
} catch (error) {
error(`preloadImages: ${error}`);
return false;
}
}
async function removeSplash() {
const splash = document.getElementById('splash');
if (splash) splash.remove();
log('removeSplash');
const t = Math.round(performance.now() - appStartTime) / 1000;
log('startupTime', t);
xhrPost(`${window.api}/log`, { message: `ready time=${t}` });
}
async function createSplash() {
const dark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
log('createSplash', { theme: dark ? 'dark' : 'light' });
@@ -34,7 +45,11 @@ async function createSplash() {
<div id="motd" class="motd""></div>
</div>`;
document.body.insertAdjacentHTML('beforeend', splash);
await preloadImages();
const ok = await preloadImages();
if (!ok) {
removeSplash();
return;
}
const imgEl = `<div id="spash-img" class="splash-img" alt="logo" style="background-image: url(file=html/logo-bg-${dark ? 'dark' : 'light'}.jpg), url(file=html/logo-bg-${num}.jpg); background-blend-mode: ${dark ? 'multiply' : 'lighten'}"></div>`;
document.getElementById('splash').insertAdjacentHTML('afterbegin', imgEl);
fetch(`${window.api}/motd`)
@@ -46,13 +61,4 @@ async function createSplash() {
.catch((err) => error(`getMOTD: ${err}`));
}
async function removeSplash() {
const splash = document.getElementById('splash');
if (splash) splash.remove();
log('removeSplash');
const t = Math.round(performance.now() - appStartTime) / 1000;
log('startupTime', t);
xhrPost(`${window.api}/log`, { message: `ready time=${t}` });
}
window.onload = createSplash;
+1
View File
@@ -31,6 +31,7 @@ def main_args():
group_paths.add_argument("--ckpt", type=str, default=os.environ.get("SD_MODEL", None), help="Path to model checkpoint to load immediately, default: %(default)s")
group_paths.add_argument("--data-dir", type=str, default=os.environ.get("SD_DATADIR", ''), help="Base path where all user data is stored, default: %(default)s")
group_paths.add_argument("--models-dir", type=str, default=os.environ.get("SD_MODELSDIR", 'models'), help="Base path where all models are stored, default: %(default)s",)
group_paths.add_argument("--extensions-dir", type=str, default=os.environ.get("SD_EXTENSIONSDIR", None), help="Base path where all extensions are stored, default: %(default)s",)
group_diag = parser.add_argument_group('Diagnostics')
group_diag.add_argument("--no-hashing", default=os.environ.get("SD_NOHASHING", False), action='store_true', help="Disable hashing of checkpoints, default: %(default)s")
+2 -1
View File
@@ -13,6 +13,7 @@ parser = argparse.ArgumentParser(add_help=False)
parser.add_argument("--ckpt", type=str, default=os.environ.get("SD_MODEL", None), help="Path to model checkpoint to load immediately, default: %(default)s")
parser.add_argument("--data-dir", type=str, default=os.environ.get("SD_DATADIR", ''), help="Base path where all user data is stored, default: %(default)s")
parser.add_argument("--models-dir", type=str, default=os.environ.get("SD_MODELSDIR", None), help="Base path where all models are stored, default: %(default)s",)
parser.add_argument("--extensions-dir", type=str, default=os.environ.get("SD_EXTENSIONSDIR", None), help="Base path where all extensions are stored, default: %(default)s",)
cli = parser.parse_known_args(argv)[0]
parser.add_argument("--config", type=str, default=os.environ.get("SD_CONFIG", os.path.join(cli.data_dir, 'config.json')), help="Use specific server configuration file, default: %(default)s") # twice because we want data_dir
cli = parser.parse_known_args(argv)[0]
@@ -28,7 +29,7 @@ script_path = os.path.dirname(modules_path)
data_path = cli.data_dir
models_config = cli.models_dir or config.get('models_dir') or 'models'
models_path = models_config if os.path.isabs(models_config) else os.path.join(data_path, models_config)
extensions_dir = os.path.join(data_path, "extensions")
extensions_dir = cli.extensions_dir or os.path.join(data_path, "extensions")
extensions_builtin_dir = "extensions-builtin"
sd_configs_path = os.path.join(script_path, "configs")
sd_default_config = os.path.join(sd_configs_path, "v1-inference.yaml")
+2
View File
@@ -1129,6 +1129,7 @@ class Options:
self.filename = config_filename
if filename is None:
filename = self.filename
filename = os.path.abspath(filename)
if cmd_opts.freeze:
log.warning(f'Setting: fn="{filename}" save disabled')
return
@@ -1173,6 +1174,7 @@ class Options:
def load(self, filename=None):
if filename is None:
filename = self.filename
filename = os.path.abspath(filename)
if not os.path.isfile(filename):
log.debug(f'Settings: fn="{filename}" created')
self.save(filename)