diff --git a/CHANGELOG.md b/CHANGELOG.md index 773a59419..e1d9950d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,8 @@ # Change Log for SD.Next -## Update for 2023-10-09 +## Update for 2023-10-11 -- Final strech of the DEV branch before merge to master -- Requires pending `diffusers==0.22.0` +- Final strech of the DEV branch before merge to master: requires pending `diffusers==0.22.0` This is a major release, with many changes and new functionality... @@ -173,6 +172,10 @@ or even free speedups and quality improvements (regardless of which workflows yo new option *settings -> inference -> batch mode* when using img2img process batch, process multiple images in batch in parallel thanks @Symbiomatrix +- **NSFW** + - install extension: [NudeNet](https://github.com/vladmandic/sd-extension-nudenet) + body part detection, image metadata, advanced censoring, etc... + more in the extension notes - **General** - **Startup** - all main CLI parameters can now be set as environment variable as well diff --git a/TODO.md b/TODO.md index 223f6d0db..0229f99cd 100644 --- a/TODO.md +++ b/TODO.md @@ -23,6 +23,7 @@ Stuff to be added, in no particular order... - Rename repo: **automatic** -> **sdnext** - New Minor - Prompt padding for positive/negative + - PyTorch / XLA - New Major - Profile manager (for `config.json` and `ui-config.json`) - Multi-user support diff --git a/html/notification.mp3 b/html/notification.mp3 index dba530bf7..a54ba70a8 100644 Binary files a/html/notification.mp3 and b/html/notification.mp3 differ diff --git a/installer.py b/installer.py index 6fd051290..c7545f98c 100644 --- a/installer.py +++ b/installer.py @@ -959,10 +959,14 @@ def git_reset(): log.warning('Running GIT reset') global quick_allowed # pylint: disable=global-statement quick_allowed = False - git('merge --abort') + git('add .') + git('stash') + git('merge --abort', folder=None, ignore=True) git('fetch --all') git('reset --hard origin/master') git('checkout master') + git('submodule update --init --recursive') + git('submodule sync --recursive') log.info('GIT reset complete') diff --git a/javascript/style.css b/javascript/style.css index bc6188003..62bdde2e0 100644 --- a/javascript/style.css +++ b/javascript/style.css @@ -77,7 +77,7 @@ button.custom-button{ border-radius: var(--button-large-radius); padding: var(-- #txt2img_generate_line2 > button, #img2img_generate_line2 > button, #extras_generate_box > button, #txt2img_tools > button, #img2img_tools > button { height: 2em; line-height: 0; font-size: var(--input-text-size); min-width: unset; display: block !important; margin-left: 0.4em; margin-right: 0.4em; } #txt2img_prompt, #txt2img_neg_prompt, #img2img_prompt, #img2img_neg_prompt { display: contents; } -.interrogate-col{ min-width: 0 !important; max-width: fit-content; gap: 0.5em; } +.interrogate-col{ min-width: 0 !important; max-width: fit-content; margin-right: var(--spacing-xxl); } .interrogate-col > button{ flex: 1; } #sampler_selection_img2img { margin-top: 1em; } #txtimg_hr_finalres{ min-height: 0 !important; } diff --git a/modules/images.py b/modules/images.py index 1c930b212..16afeeae9 100644 --- a/modules/images.py +++ b/modules/images.py @@ -9,6 +9,7 @@ import string import hashlib import queue import threading +from pathlib import Path from collections import namedtuple import pytz import numpy as np @@ -266,58 +267,47 @@ def resize_image(resize_mode, im, width, height, upscaler_name=None, output_type return res -invalid_filename_chars = '<>:"/\\|?*\n' -invalid_filename_prefix = ' ' -invalid_filename_postfix = ' .' re_nonletters = re.compile(r'[\s' + string.punctuation + ']+') re_pattern = re.compile(r"(.*?)(?:\[([^\[\]]+)\]|$)") re_pattern_arg = re.compile(r"(.*)<([^>]*)>$") -max_filename_part_length = 128 +re_attention = re.compile(r'[\(*\[*](\w+)(:\d+(\.\d+))?[\)*\]*]|') +re_network = re.compile(r'\<\w+:(\w+)(:\d+(\.\d+))?\>|') +re_brackets = re.compile(r'[\([{})\]]') + NOTHING = object() -def sanitize_filename_part(text, replace_spaces=True): - if text is None: - return None - text = os.path.basename(text) - if replace_spaces: - text = text.replace(' ', '_') - text = text.replace('#', '_') - text = text.translate({ord(x): '_' for x in invalid_filename_chars}) - text = text.lstrip(invalid_filename_prefix)[:max_filename_part_length] - text = text.rstrip(invalid_filename_postfix) - return text - - class FilenameGenerator: replacements = { + 'width': lambda self: self.image.width, + 'height': lambda self: self.image.height, 'batch_number': lambda self: self.batch_number, 'iter_number': lambda self: self.iter_number, - 'cfg': lambda self: self.p and self.p.cfg_scale, - 'clip_skip': lambda self: self.p and self.p.clip_skip, + 'num': lambda self: NOTHING if self.p.n_iter == 1 and self.p.batch_size == 1 else self.p.iteration * self.p.batch_size + self.p.batch_index + 1, + 'generation_number': lambda self: NOTHING if self.p.n_iter == 1 and self.p.batch_size == 1 else self.p.iteration * self.p.batch_size + self.p.batch_index + 1, 'date': lambda self: datetime.datetime.now().strftime('%Y-%m-%d'), 'datetime': lambda self, *args: self.datetime(*args), # accepts formats: [datetime], [datetime], [datetime