From 872c09c2207d88ae93476410ff29738206550dcf Mon Sep 17 00:00:00 2001 From: JeLuF Date: Wed, 22 Mar 2023 23:06:03 +0100 Subject: [PATCH] Avoid name clashes for autosave files The old code had a 1.6% chance of name collisions (AAb/345 and AAB3/45 would generate the same filename) on Linux and 39% on Windows (base64 is case sensitive, Windows isn't). This code uses base36 (0-9, A-Z) to avoid case issues. To avoid collisions on fast computers or multi GPU computers, the time resolution of the timestamp is changed from seconds to 0.1ms, and the image number isn't added to the timestamp but appended as an extra character. Due to the limitation of the timestamps to 7 characters, the timecode will repeat every 90 days. This shouldn't be an issue since most sessions will not last this long. --- ui/easydiffusion/utils/save_utils.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ui/easydiffusion/utils/save_utils.py b/ui/easydiffusion/utils/save_utils.py index b4a85538..6012bc44 100644 --- a/ui/easydiffusion/utils/save_utils.py +++ b/ui/easydiffusion/utils/save_utils.py @@ -1,11 +1,11 @@ import os import time -import base64 import re from easydiffusion.types import TaskData, GenerateImageRequest from sdkit.utils import save_images, save_dicts +from numpy import base_repr filename_regex = re.compile("[^a-zA-Z0-9._-]") @@ -121,8 +121,7 @@ def make_filename_callback(req: GenerateImageRequest, suffix=None, now=None): now = time.time() def make_filename(i): - img_id = base64.b64encode(int(now + i).to_bytes(8, "big")).decode() # Generate unique ID based on time. - img_id = img_id.translate({43: None, 47: None, 61: None})[-8:] # Remove + / = and keep last 8 chars. + img_id = base_repr(int(now * 10000), 36)[-7:] + base_repr(int(i),36) # Base 36 conversion, 0-9, A-Z prompt_flattened = filename_regex.sub("_", req.prompt)[:50] name = f"{prompt_flattened}_{img_id}"