import random import re import copy def get_prompt_parameters(user_message, settings): params = {} if "defaults" in settings.keys(): params = settings["defaults"].copy() mutable_string = user_message mutable_string = re.sub(r"[^A-Za-z0-9 \-,\.>\(\)]", "", mutable_string) mutable_string = re.sub(r"\s{1,}", " ", mutable_string) # Get the options from the mutable string: options = "" options_re = r"^((.+)>)" match = re.search(options_re, mutable_string) if match is not None: options = match.group(2).strip() mutable_string = re.sub(options_re, "", mutable_string) # Get the repeat_n_times from the mutable string: repeat_re = r"( x([0-9]{1,2}))$" match = re.search(repeat_re, mutable_string) if match is not None: params["repeat_n_times"] = int(match.group(2).strip()) mutable_string = re.sub(repeat_re, "", mutable_string) # Get the negative prompt from the mutable string: negative_re = r"( -(.+))$" match = re.search(negative_re, mutable_string) if match is not None: params["negative"] = match.group(2).strip() mutable_string = re.sub(negative_re, "", mutable_string) params["positive"] = mutable_string.strip() # Allow the user to set the square size by SSSp: if params["width"] == params["height"]: match = re.search(r"([1-9][0-9]{2,3})p", options) if match is not None: s = int(match.group(1)) params["width"] = s params["height"] = s # Allow user to specify ratio: match = re.search(r"([0-9]{1,2})(x|\:)([0-9]{1,2})", options) if match is not None: # Use the smallest dimension for calculations: size = params["width"] if params["width"] <= params["height"] else params["height"] r_num = int(match.group(1)) r_den = int(match.group(3)) # Largest dimension not to exceed the size: if r_num > r_den: ratio = 1.0 * r_num / r_den params["width"] = size params["height"] = size * (1 / ratio) elif r_num < r_den: ratio = 1.0 * r_num / r_den params["width"] = size * ratio params["height"] = size # Allow user to explicitly set the size by WWWxHHHp: match = re.search(r"([0-9]{1,})(x)([0-9]{1,})p", options) if match is not None: output["width"] = int(match.group(1)) output["height"] = int(match.group(3)) # Allow all other explicit parameter overrides: overwrite_re = r"([A-Za-z_]{1,})=?([0-9\.]{1,})" for (k, v) in re.findall(overwrite_re, options): params[k] = float(v) # Process limitations, e.g. max_width and max_height: params_clone = copy.deepcopy(params) for key in params.keys(): limit_value = params[key] term = "min_" if re.search(rf"^{term}", key): target_key = re.sub(rf"^{term}", "", key) if target_key not in params.keys(): params_clone[target_key] = limit_value params_clone[target_key] = limit_value if params[target_key] < limit_value else params[target_key] term = "max_" if re.search(rf"^{term}", key): target_key = re.sub(rf"^{term}", "", key) if target_key in params.keys(): params_clone[target_key] = limit_value if params[target_key] > limit_value else params[target_key] term = "force_" if re.search(rf"^{term}", key): target_key = re.sub(rf"^{term}", "", key) params_clone[target_key] = limit_value params = params_clone return params