From 79d57d02f15aa406e38997d65ec8ed99374691b7 Mon Sep 17 00:00:00 2001
From: space-nuko <24979496+space-nuko@users.noreply.github.com>
Date: Wed, 29 Mar 2023 01:52:34 -0500
Subject: [PATCH 1/3] Improve custom code extension

- Uses `gr.Code` component
- Includes example
- Can return out of body
---
 scripts/custom_code.py | 63 +++++++++++++++++++++++++++++++++++++-----
 1 file changed, 56 insertions(+), 7 deletions(-)

diff --git a/scripts/custom_code.py b/scripts/custom_code.py
index d29113e67..4071d86d8 100644
--- a/scripts/custom_code.py
+++ b/scripts/custom_code.py
@@ -1,9 +1,40 @@
 import modules.scripts as scripts
 import gradio as gr
+import ast
+import copy
 
 from modules.processing import Processed
 from modules.shared import opts, cmd_opts, state
 
+
+def convertExpr2Expression(expr):
+    expr.lineno = 0
+    expr.col_offset = 0
+    result = ast.Expression(expr.value, lineno=0, col_offset = 0)
+
+    return result
+
+
+def exec_with_return(code, module):
+    """
+    like exec() but can return values
+    https://stackoverflow.com/a/52361938/5862977
+    """
+    code_ast = ast.parse(code)
+
+    init_ast = copy.deepcopy(code_ast)
+    init_ast.body = code_ast.body[:-1]
+
+    last_ast = copy.deepcopy(code_ast)
+    last_ast.body = code_ast.body[-1:]
+
+    exec(compile(init_ast, "<ast>", "exec"), module.__dict__)
+    if type(last_ast.body[0]) == ast.Expr:
+        return eval(compile(convertExpr2Expression(last_ast.body[0]), "<ast>", "eval"), module.__dict__)
+    else:
+        exec(compile(last_ast, "<ast>", "exec"), module.__dict__)
+
+
 class Script(scripts.Script):
 
     def title(self):
@@ -13,12 +44,23 @@ class Script(scripts.Script):
         return cmd_opts.allow_code
 
     def ui(self, is_img2img):
-        code = gr.Textbox(label="Python code", lines=1, elem_id=self.elem_id("code"))
+        example = """from modules.processing import process_images
 
-        return [code]
+p.width = 768
+p.height = 768
+p.batch_size = 2
+p.steps = 10
+
+return process_images(p)
+"""
 
 
-    def run(self, p, code):
+        code = gr.Code(value=example, language="python", label="Python code", elem_id=self.elem_id("code"))
+        indent_level = gr.Number(label='Indent level', value=2, precision=0, elem_id=self.elem_id("indent_level"))
+
+        return [code, indent_level]
+
+    def run(self, p, code, indent_level):
         assert cmd_opts.allow_code, '--allow-code option must be enabled'
 
         display_result_data = [[], -1, ""]
@@ -29,13 +71,20 @@ class Script(scripts.Script):
             display_result_data[2] = i
 
         from types import ModuleType
-        compiled = compile(code, '', 'exec')
         module = ModuleType("testmodule")
         module.__dict__.update(globals())
         module.p = p
         module.display = display
-        exec(compiled, module.__dict__)
+
+        indent = " " * indent_level
+        indented = code.replace('\n', '\n' + indent)
+        body = f"""def __webuitemp__():
+{indent}{indented}
+__webuitemp__()"""
+
+        result = exec_with_return(body, module)
+
+        if isinstance(result, Processed):
+            return result
 
         return Processed(p, *display_result_data)
-    
-    
\ No newline at end of file

From 101a18fc8466577501b57eac6a4b5d07351c9ec6 Mon Sep 17 00:00:00 2001
From: AUTOMATIC <16777216c@gmail.com>
Date: Sat, 29 Apr 2023 09:17:35 +0300
Subject: [PATCH 2/3] bump gradio to 3.27

---
 modules/api/api.py        | 12 +++---------
 modules/postprocessing.py |  9 +++++++--
 modules/ui.py             |  2 +-
 modules/ui_common.py      |  2 +-
 requirements.txt          |  2 +-
 requirements_versions.txt |  2 +-
 6 files changed, 14 insertions(+), 15 deletions(-)

diff --git a/modules/api/api.py b/modules/api/api.py
index 518b2a61f..5ed670e90 100644
--- a/modules/api/api.py
+++ b/modules/api/api.py
@@ -6,7 +6,6 @@ import uvicorn
 import gradio as gr
 from threading import Lock
 from io import BytesIO
-from gradio.processing_utils import decode_base64_to_file
 from fastapi import APIRouter, Depends, FastAPI, Request, Response
 from fastapi.security import HTTPBasic, HTTPBasicCredentials
 from fastapi.exceptions import HTTPException
@@ -395,16 +394,11 @@ class Api:
     def extras_batch_images_api(self, req: ExtrasBatchImagesRequest):
         reqDict = setUpscalers(req)
 
-        def prepareFiles(file):
-            file = decode_base64_to_file(file.data, file_path=file.name)
-            file.orig_name = file.name
-            return file
-
-        reqDict['image_folder'] = list(map(prepareFiles, reqDict['imageList']))
-        reqDict.pop('imageList')
+        image_list = reqDict.pop('imageList', [])
+        image_folder = [decode_base64_to_image(x.data) for x in image_list]
 
         with self.queue_lock:
-            result = postprocessing.run_extras(extras_mode=1, image="", input_dir="", output_dir="", save_output=False, **reqDict)
+            result = postprocessing.run_extras(extras_mode=1, image_folder=image_folder, image="", input_dir="", output_dir="", save_output=False, **reqDict)
 
         return ExtrasBatchImagesResponse(images=list(map(encode_pil_to_base64, result[0])), html_info=result[1])
 
diff --git a/modules/postprocessing.py b/modules/postprocessing.py
index 09d8e6056..ba5745b96 100644
--- a/modules/postprocessing.py
+++ b/modules/postprocessing.py
@@ -18,9 +18,14 @@ def run_postprocessing(extras_mode, image, image_folder, input_dir, output_dir,
 
     if extras_mode == 1:
         for img in image_folder:
-            image = Image.open(img)
+            if isinstance(img, Image.Image):
+                fn = ''
+            else:
+                image = Image.open(img)
+                fn = os.path.splitext(img.orig_name)[0]
+
             image_data.append(image)
-            image_names.append(os.path.splitext(img.orig_name)[0])
+            image_names.append(fn)
     elif extras_mode == 2:
         assert not shared.cmd_opts.hide_ui_dir_config, '--hide-ui-dir-config option must be disabled'
         assert input_dir, 'input directory not selected'
diff --git a/modules/ui.py b/modules/ui.py
index 627fbe0b5..dd28bdbb6 100644
--- a/modules/ui.py
+++ b/modules/ui.py
@@ -1204,7 +1204,7 @@ def create_ui():
 
             with gr.Column(elem_id='ti_gallery_container'):
                 ti_output = gr.Text(elem_id="ti_output", value="", show_label=False)
-                ti_gallery = gr.Gallery(label='Output', show_label=False, elem_id='ti_gallery').style(grid=4)
+                ti_gallery = gr.Gallery(label='Output', show_label=False, elem_id='ti_gallery').style(columns=4)
                 ti_progress = gr.HTML(elem_id="ti_progress", value="")
                 ti_outcome = gr.HTML(elem_id="ti_error", value="")
 
diff --git a/modules/ui_common.py b/modules/ui_common.py
index 3b11dcc85..27ab3ebb6 100644
--- a/modules/ui_common.py
+++ b/modules/ui_common.py
@@ -125,7 +125,7 @@ Requested path was: {f}
 
     with gr.Column(variant='panel', elem_id=f"{tabname}_results"):
         with gr.Group(elem_id=f"{tabname}_gallery_container"):
-            result_gallery = gr.Gallery(label='Output', show_label=False, elem_id=f"{tabname}_gallery").style(grid=4)
+            result_gallery = gr.Gallery(label='Output', show_label=False, elem_id=f"{tabname}_gallery").style(columns=4)
 
         generation_info = None
         with gr.Column():
diff --git a/requirements.txt b/requirements.txt
index c72b2927e..77954b8d7 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -4,7 +4,7 @@ basicsr
 fonts
 font-roboto
 gfpgan
-gradio==3.23
+gradio==3.27
 invisible-watermark
 numpy
 omegaconf
diff --git a/requirements_versions.txt b/requirements_versions.txt
index df65431a3..0a62c6de7 100644
--- a/requirements_versions.txt
+++ b/requirements_versions.txt
@@ -3,7 +3,7 @@ transformers==4.25.1
 accelerate==0.12.0
 basicsr==1.4.2
 gfpgan==1.3.8
-gradio==3.23
+gradio==3.27
 numpy==1.23.3
 Pillow==9.4.0
 realesrgan==0.3.0

From 5a666f3904c39bb3d7d86818b2b6579325a8fa8a Mon Sep 17 00:00:00 2001
From: AUTOMATIC <16777216c@gmail.com>
Date: Sat, 29 Apr 2023 09:17:35 +0300
Subject: [PATCH 3/3] bump gradio to 3.27

---
 modules/postprocessing.py | 1 +
 1 file changed, 1 insertion(+)

diff --git a/modules/postprocessing.py b/modules/postprocessing.py
index ba5745b96..ff055aae9 100644
--- a/modules/postprocessing.py
+++ b/modules/postprocessing.py
@@ -19,6 +19,7 @@ def run_postprocessing(extras_mode, image, image_folder, input_dir, output_dir,
     if extras_mode == 1:
         for img in image_folder:
             if isinstance(img, Image.Image):
+                image = img
                 fn = ''
             else:
                 image = Image.open(img)