1
1
import copy
2
2
import math
3
3
import os
4
+ import random
4
5
import sys
5
6
import traceback
6
7
import shlex
@@ -81,32 +82,34 @@ def cmdargs(line):
81
82
return res
82
83
83
84
85
+ def load_prompt_file (file ):
86
+ if (file is None ):
87
+ lines = []
88
+ else :
89
+ lines = [x .strip () for x in file .decode ('utf8' , errors = 'ignore' ).split ("\n " )]
90
+
91
+ return None , "\n " .join (lines ), gr .update (lines = 7 )
92
+
84
93
class Script (scripts .Script ):
85
94
def title (self ):
86
95
return "Prompts from file or textbox"
87
96
88
97
def ui (self , is_img2img ):
89
- # This checkbox would look nicer as two tabs, but there are two problems:
90
- # 1) There is a bug in Gradio 3.3 that prevents visibility from working on Tabs
91
- # 2) Even with Gradio 3.3.1, returning a control (like Tabs) that can't be used as input
92
- # causes a AttributeError: 'Tabs' object has no attribute 'preprocess' assert,
93
- # due to the way Script assumes all controls returned can be used as inputs.
94
- # Therefore, there's no good way to use grouping components right now,
95
- # so we will use a checkbox! :)
96
- checkbox_txt = gr .Checkbox (label = "Show Textbox" , value = False )
97
- file = gr .File (label = "File with inputs" , type = 'bytes' )
98
- prompt_txt = gr .TextArea (label = "Prompts" )
99
- checkbox_txt .change (fn = lambda x : [gr .File .update (visible = not x ), gr .TextArea .update (visible = x )], inputs = [checkbox_txt ], outputs = [file , prompt_txt ])
100
- return [checkbox_txt , file , prompt_txt ]
101
-
102
- def on_show (self , checkbox_txt , file , prompt_txt ):
103
- return [ gr .Checkbox .update (visible = True ), gr .File .update (visible = not checkbox_txt ), gr .TextArea .update (visible = checkbox_txt ) ]
104
-
105
- def run (self , p , checkbox_txt , data : bytes , prompt_txt : str ):
106
- if checkbox_txt :
107
- lines = [x .strip () for x in prompt_txt .splitlines ()]
108
- else :
109
- lines = [x .strip () for x in data .decode ('utf8' , errors = 'ignore' ).split ("\n " )]
98
+ checkbox_iterate = gr .Checkbox (label = "Iterate seed every line" , value = False )
99
+
100
+ prompt_txt = gr .Textbox (label = "List of prompt inputs" , lines = 1 )
101
+ file = gr .File (label = "Upload prompt inputs" , type = 'bytes' )
102
+
103
+ file .change (fn = load_prompt_file , inputs = [file ], outputs = [file , prompt_txt , prompt_txt ])
104
+
105
+ # We start at one line. When the text changes, we jump to seven lines, or two lines if no \n.
106
+ # We don't shrink back to 1, because that causes the control to ignore [enter], and it may
107
+ # be unclear to the user that shift-enter is needed.
108
+ prompt_txt .change (lambda tb : gr .update (lines = 7 ) if ("\n " in tb ) else gr .update (lines = 2 ), inputs = [prompt_txt ], outputs = [prompt_txt ])
109
+ return [checkbox_iterate , file , prompt_txt ]
110
+
111
+ def run (self , p , checkbox_iterate , file , prompt_txt : str ):
112
+ lines = [x .strip () for x in prompt_txt .splitlines ()]
110
113
lines = [x for x in lines if len (x ) > 0 ]
111
114
112
115
p .do_not_save_grid = True
@@ -134,6 +137,9 @@ def run(self, p, checkbox_txt, data: bytes, prompt_txt: str):
134
137
jobs .append (args )
135
138
136
139
print (f"Will process { len (lines )} lines in { job_count } jobs." )
140
+ if (checkbox_iterate and p .seed == - 1 ):
141
+ p .seed = int (random .randrange (4294967294 ))
142
+
137
143
state .job_count = job_count
138
144
139
145
images = []
@@ -146,5 +152,9 @@ def run(self, p, checkbox_txt, data: bytes, prompt_txt: str):
146
152
147
153
proc = process_images (copy_p )
148
154
images += proc .images
155
+
156
+ if (checkbox_iterate ):
157
+ p .seed = p .seed + (p .batch_size * p .n_iter )
158
+
149
159
150
- return Processed (p , images , p .seed , "" )
160
+ return Processed (p , images , p .seed , "" )
0 commit comments