Update app.py
Browse files
app.py
CHANGED
@@ -1,4 +1,7 @@
|
|
1 |
#!/usr/bin/env python3
|
|
|
|
|
|
|
2 |
import os
|
3 |
import glob
|
4 |
import time
|
@@ -17,252 +20,277 @@ from dataclasses import dataclass
|
|
17 |
from typing import Optional
|
18 |
import gradio as gr
|
19 |
|
|
|
20 |
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
|
21 |
logger = logging.getLogger(__name__)
|
22 |
-
log_records = []
|
23 |
|
|
|
24 |
class LogCaptureHandler(logging.Handler):
|
|
|
25 |
def emit(self, record):
|
26 |
log_records.append(record)
|
27 |
|
28 |
-
logger.addHandler(LogCaptureHandler())
|
29 |
|
|
|
30 |
@dataclass
|
31 |
class ModelConfig:
|
32 |
-
name: str
|
33 |
-
base_model: str
|
34 |
-
size: str
|
35 |
-
domain: Optional[str] = None
|
36 |
-
model_type: str = "causal_lm"
|
|
|
37 |
@property
|
38 |
def model_path(self):
|
39 |
return f"models/{self.name}"
|
40 |
|
|
|
41 |
@dataclass
|
42 |
class DiffusionConfig:
|
43 |
-
name: str
|
44 |
-
base_model: str
|
45 |
-
size: str
|
46 |
-
domain: Optional[str] = None
|
|
|
47 |
@property
|
48 |
def model_path(self):
|
49 |
return f"diffusion_models/{self.name}"
|
50 |
|
|
|
51 |
class ModelBuilder:
|
|
|
52 |
def __init__(self):
|
53 |
-
self.config = None
|
54 |
-
self.model = None
|
55 |
-
self.tokenizer = None
|
|
|
56 |
def load_model(self, model_path: str, config: Optional[ModelConfig] = None):
|
57 |
-
self.model = AutoModelForCausalLM.from_pretrained(model_path)
|
58 |
-
self.tokenizer = AutoTokenizer.from_pretrained(model_path)
|
59 |
if self.tokenizer.pad_token is None:
|
60 |
-
self.tokenizer.pad_token = self.tokenizer.eos_token
|
61 |
if config:
|
62 |
-
self.config = config
|
63 |
-
self.model.to("cuda" if torch.cuda.is_available() else "cpu")
|
64 |
return self
|
|
|
65 |
def save_model(self, path: str):
|
66 |
-
os.makedirs(os.path.dirname(path), exist_ok=True)
|
67 |
-
self.model.save_pretrained(path)
|
68 |
-
self.tokenizer.save_pretrained(path)
|
69 |
|
|
|
70 |
class DiffusionBuilder:
|
|
|
71 |
def __init__(self):
|
72 |
-
self.config = None
|
73 |
-
self.pipeline = None
|
|
|
74 |
def load_model(self, model_path: str, config: Optional[DiffusionConfig] = None):
|
75 |
-
self.pipeline = StableDiffusionPipeline.from_pretrained(model_path, torch_dtype=torch.float32).to("cpu")
|
76 |
if config:
|
77 |
-
self.config = config
|
78 |
return self
|
|
|
79 |
def save_model(self, path: str):
|
80 |
-
os.makedirs(os.path.dirname(path), exist_ok=True)
|
81 |
-
self.pipeline.save_pretrained(path)
|
|
|
82 |
def generate(self, prompt: str):
|
83 |
-
return self.pipeline(prompt, num_inference_steps=20).images[0]
|
84 |
|
|
|
85 |
def generate_filename(sequence, ext):
|
86 |
-
timestamp = time.strftime("%d%m%Y%H%M%S")
|
87 |
return f"{sequence}_{timestamp}.{ext}"
|
88 |
|
|
|
89 |
def get_gallery_files(file_types):
|
90 |
-
return sorted(list(set([f for ext in file_types for f in glob.glob(f"*.{ext}")]))) #
|
91 |
|
|
|
92 |
async def process_image_gen(prompt, output_file, builder):
|
93 |
if builder and isinstance(builder, DiffusionBuilder) and builder.pipeline:
|
94 |
-
pipeline = builder.pipeline
|
95 |
else:
|
96 |
-
pipeline = StableDiffusionPipeline.from_pretrained("OFA-Sys/small-stable-diffusion-v0", torch_dtype=torch.float32).to("cpu")
|
97 |
-
gen_image = pipeline(prompt, num_inference_steps=20).images[0]
|
98 |
-
gen_image.save(output_file)
|
99 |
return gen_image
|
100 |
|
101 |
-
#
|
102 |
def upload_images(files, history, selected_files):
|
103 |
if not files:
|
104 |
-
return "No files uploaded", history, selected_files
|
105 |
uploaded = []
|
106 |
for file in files:
|
107 |
-
ext = file.name.split('.')[-1].lower()
|
108 |
if ext in ["jpg", "png"]:
|
109 |
-
output_path = f"img_{int(time.time())}_{os.path.basename(file.name)}"
|
110 |
with open(output_path, "wb") as f:
|
111 |
-
f.write(file.read())
|
112 |
uploaded.append(output_path)
|
113 |
-
history.append(f"Uploaded Image: {output_path}")
|
114 |
-
selected_files[output_path] = False
|
115 |
return f"Uploaded {len(uploaded)} images", history, selected_files
|
116 |
|
|
|
117 |
def upload_videos(files, history, selected_files):
|
118 |
if not files:
|
119 |
-
return "No files uploaded", history, selected_files
|
120 |
uploaded = []
|
121 |
for file in files:
|
122 |
-
ext = file.name.split('.')[-1].lower()
|
123 |
if ext == "mp4":
|
124 |
-
output_path = f"vid_{int(time.time())}_{os.path.basename(file.name)}"
|
125 |
with open(output_path, "wb") as f:
|
126 |
-
f.write(file.read())
|
127 |
uploaded.append(output_path)
|
128 |
-
history.append(f"Uploaded Video: {output_path}")
|
129 |
-
selected_files[output_path] = False
|
130 |
return f"Uploaded {len(uploaded)} videos", history, selected_files
|
131 |
|
|
|
132 |
def upload_documents(files, history, selected_files):
|
133 |
if not files:
|
134 |
-
return "No files uploaded", history, selected_files
|
135 |
uploaded = []
|
136 |
for file in files:
|
137 |
-
ext = file.name.split('.')[-1].lower()
|
138 |
if ext in ["md", "pdf", "docx"]:
|
139 |
-
output_path = f"doc_{int(time.time())}_{os.path.basename(file.name)}"
|
140 |
with open(output_path, "wb") as f:
|
141 |
-
f.write(file.read())
|
142 |
uploaded.append(output_path)
|
143 |
-
history.append(f"Uploaded Document: {output_path}")
|
144 |
-
selected_files[output_path] = False
|
145 |
return f"Uploaded {len(uploaded)} documents", history, selected_files
|
146 |
|
|
|
147 |
def upload_datasets(files, history, selected_files):
|
148 |
if not files:
|
149 |
-
return "No files uploaded", history, selected_files
|
150 |
uploaded = []
|
151 |
for file in files:
|
152 |
-
ext = file.name.split('.')[-1].lower()
|
153 |
if ext in ["csv", "xlsx"]:
|
154 |
-
output_path = f"data_{int(time.time())}_{os.path.basename(file.name)}"
|
155 |
with open(output_path, "wb") as f:
|
156 |
-
f.write(file.read())
|
157 |
uploaded.append(output_path)
|
158 |
-
history.append(f"Uploaded Dataset: {output_path}")
|
159 |
-
selected_files[output_path] = False
|
160 |
return f"Uploaded {len(uploaded)} datasets", history, selected_files
|
161 |
|
|
|
162 |
def upload_links(links_title, links_url, history, selected_files):
|
163 |
if not links_title or not links_url:
|
164 |
-
return "No links provided", history, selected_files
|
165 |
-
links = list(zip(links_title.split('\n'), links_url.split('\n')))
|
166 |
uploaded = []
|
167 |
for title, url in links:
|
168 |
if title and url:
|
169 |
-
link_entry = f"[{title}]({url})"
|
170 |
uploaded.append(link_entry)
|
171 |
-
history.append(f"Added Link: {link_entry}")
|
172 |
-
selected_files[link_entry] = False
|
173 |
return f"Added {len(uploaded)} links", history, selected_files
|
174 |
|
175 |
-
# Gallery
|
176 |
def update_galleries(history, selected_files):
|
177 |
galleries = {
|
178 |
-
"images": get_gallery_files(["jpg", "png"]),
|
179 |
-
"videos": get_gallery_files(["mp4"]),
|
180 |
-
"documents": get_gallery_files(["md", "pdf", "docx"]),
|
181 |
-
"datasets": get_gallery_files(["csv", "xlsx"]),
|
182 |
-
"links": [f for f in selected_files.keys() if f.startswith('[') and '](' in f and f.endswith(')')]
|
183 |
}
|
184 |
gallery_outputs = {
|
185 |
-
"images": [(Image.open(f), os.path.basename(f)) for f in galleries["images"]],
|
186 |
-
"videos": [(f, os.path.basename(f)) for f in galleries["videos"]], #
|
187 |
-
"documents": [(Image.frombytes("RGB", fitz.open(f)[0].get_pixmap(matrix=fitz.Matrix(0.5, 0.5)).size, fitz.open(f)[0].get_pixmap(matrix=fitz.Matrix(0.5, 0.5)).samples) if f.endswith('.pdf') else f, os.path.basename(f)) for f in galleries["documents"]],
|
188 |
-
"datasets": [(f, os.path.basename(f)) for f in galleries["datasets"]],
|
189 |
-
"links": [(f, f.split(']')[0][1:]) for f in galleries["links"]]
|
190 |
}
|
191 |
-
history.append(f"Updated galleries: {sum(len(g) for g in galleries.values())} files")
|
192 |
return gallery_outputs, history, selected_files
|
193 |
|
194 |
-
# Sidebar
|
195 |
def update_sidebar(history, selected_files):
|
196 |
-
all_files = get_gallery_files(["jpg", "png", "mp4", "md", "pdf", "docx", "csv", "xlsx"]) + [f for f in selected_files.keys() if f.startswith('[') and '](' in f and f.endswith(')')]
|
197 |
-
file_list = [gr.File(label=os.path.basename(f) if not f.startswith('[') else f.split(']')[0][1:], value=f) for f in all_files]
|
198 |
return file_list, history
|
199 |
|
200 |
-
#
|
201 |
def toggle_selection(file_list, selected_files):
|
202 |
for file in file_list:
|
203 |
-
selected_files[file] = not selected_files.get(file, False)
|
204 |
return selected_files
|
205 |
|
|
|
206 |
def image_gen(prompt, builder, history, selected_files):
|
207 |
-
selected = [f for f, sel in selected_files.items() if sel and f.endswith(('.jpg', '.png'))]
|
208 |
if not selected:
|
209 |
-
return "No images selected", None, history, selected_files
|
210 |
-
output_file = generate_filename("gen_output", "png")
|
211 |
-
gen_image = asyncio.run(process_image_gen(prompt, output_file, builder))
|
212 |
-
history.append(f"Image Gen: {prompt} -> {output_file}")
|
213 |
-
selected_files[output_file] = True
|
214 |
return f"Image saved to {output_file}", gen_image, history, selected_files
|
215 |
|
216 |
-
# Gradio UI
|
217 |
with gr.Blocks(title="AI Vision & SFT Titans π") as demo:
|
218 |
-
gr.Markdown("# AI Vision & SFT Titans π")
|
219 |
-
history = gr.State(value=[])
|
220 |
-
builder = gr.State(value=None)
|
221 |
-
selected_files = gr.State(value={})
|
222 |
|
223 |
with gr.Row():
|
224 |
with gr.Column(scale=1):
|
225 |
-
gr.Markdown("## π Files")
|
226 |
-
sidebar_files = gr.Files(label="Downloads", height=300)
|
227 |
|
228 |
with gr.Column(scale=3):
|
229 |
with gr.Row():
|
230 |
-
gr.Markdown("## π οΈ Toolbar")
|
231 |
-
select_btn = gr.Button("β
Select")
|
232 |
-
gen_btn = gr.Button("π¨ Generate")
|
233 |
|
234 |
with gr.Tabs():
|
235 |
-
with gr.TabItem("π€ Upload"):
|
236 |
with gr.Row():
|
237 |
-
img_upload = gr.File(label="πΌοΈ Images (jpg/png)", file_count="multiple", accept=["image/jpeg", "image/png"])
|
238 |
-
vid_upload = gr.File(label="π₯ Videos (mp4)", file_count="multiple", accept=["video/mp4"])
|
239 |
with gr.Row():
|
240 |
-
doc_upload = gr.File(label="π Docs (md/pdf/docx)", file_count="multiple", accept=["text/markdown", "application/pdf", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"])
|
241 |
-
data_upload = gr.File(label="π Data (csv/xlsx)", file_count="multiple", accept=["text/csv", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"])
|
242 |
with gr.Row():
|
243 |
-
links_title = gr.Textbox(label="π Link Titles", lines=3)
|
244 |
-
links_url = gr.Textbox(label="π Link URLs", lines=3)
|
245 |
-
upload_status = gr.Textbox(label="Status")
|
246 |
gr.Button("π€ Upload Images").click(upload_images, inputs=[img_upload, history, selected_files], outputs=[upload_status, history, selected_files]).then(update_galleries, inputs=[history, selected_files], outputs=[gr.Gallery(), gr.Gallery(), gr.Gallery(), gr.Gallery(), gr.Gallery(), history, selected_files]).then(update_sidebar, inputs=[history, selected_files], outputs=[sidebar_files, history])
|
247 |
gr.Button("π€ Upload Videos").click(upload_videos, inputs=[vid_upload, history, selected_files], outputs=[upload_status, history, selected_files]).then(update_galleries, inputs=[history, selected_files], outputs=[gr.Gallery(), gr.Gallery(), gr.Gallery(), gr.Gallery(), gr.Gallery(), history, selected_files]).then(update_sidebar, inputs=[history, selected_files], outputs=[sidebar_files, history])
|
248 |
gr.Button("π€ Upload Docs").click(upload_documents, inputs=[doc_upload, history, selected_files], outputs=[upload_status, history, selected_files]).then(update_galleries, inputs=[history, selected_files], outputs=[gr.Gallery(), gr.Gallery(), gr.Gallery(), gr.Gallery(), gr.Gallery(), history, selected_files]).then(update_sidebar, inputs=[history, selected_files], outputs=[sidebar_files, history])
|
249 |
gr.Button("π€ Upload Data").click(upload_datasets, inputs=[data_upload, history, selected_files], outputs=[upload_status, history, selected_files]).then(update_galleries, inputs=[history, selected_files], outputs=[gr.Gallery(), gr.Gallery(), gr.Gallery(), gr.Gallery(), gr.Gallery(), history, selected_files]).then(update_sidebar, inputs=[history, selected_files], outputs=[sidebar_files, history])
|
250 |
gr.Button("π€ Upload Links").click(upload_links, inputs=[links_title, links_url, history, selected_files], outputs=[upload_status, history, selected_files]).then(update_galleries, inputs=[history, selected_files], outputs=[gr.Gallery(), gr.Gallery(), gr.Gallery(), gr.Gallery(), gr.Gallery(), history, selected_files]).then(update_sidebar, inputs=[history, selected_files], outputs=[sidebar_files, history])
|
251 |
|
252 |
-
with gr.TabItem("πΌοΈ Gallery"):
|
253 |
-
img_gallery = gr.Gallery(label="πΌοΈ Images (jpg/png)", columns=4, height="auto")
|
254 |
-
vid_gallery = gr.Gallery(label="π₯ Videos (mp4)", columns=4, height="auto")
|
255 |
-
doc_gallery = gr.Gallery(label="π Docs (md/pdf/docx)", columns=4, height="auto")
|
256 |
-
data_gallery = gr.Gallery(label="π Data (csv/xlsx)", columns=4, height="auto")
|
257 |
-
link_gallery = gr.Gallery(label="π Links", columns=4, height="auto")
|
258 |
gr.Button("π Refresh").click(update_galleries, inputs=[history, selected_files], outputs=[img_gallery, vid_gallery, doc_gallery, data_gallery, link_gallery, history, selected_files]).then(update_sidebar, inputs=[history, selected_files], outputs=[sidebar_files, history])
|
259 |
|
260 |
-
with gr.TabItem("π Operations"):
|
261 |
-
prompt = gr.Textbox(label="Image Gen Prompt", value="Generate a neon version")
|
262 |
-
op_status = gr.Textbox(label="Status")
|
263 |
-
op_output = gr.Image(label="Output")
|
264 |
-
select_files = gr.Dropdown(choices=list(selected_files.value.keys()), multiselect=True, label="Select Files")
|
265 |
select_btn.click(toggle_selection, inputs=[select_files, selected_files], outputs=[selected_files]).then(update_sidebar, inputs=[history, selected_files], outputs=[sidebar_files, history])
|
266 |
gen_btn.click(image_gen, inputs=[prompt, builder, history, selected_files], outputs=[op_status, op_output, history, selected_files]).then(update_galleries, inputs=[history, selected_files], outputs=[img_gallery, vid_gallery, doc_gallery, data_gallery, link_gallery, history, selected_files]).then(update_sidebar, inputs=[history, selected_files], outputs=[sidebar_files, history])
|
267 |
|
|
|
268 |
demo.launch()
|
|
|
1 |
#!/usr/bin/env python3
|
2 |
+
# π Shebanginβ it like itβs 1999βPython 3, letβs roll!
|
3 |
+
|
4 |
+
# 𧳠Importing the whole circusβget ready for a wild ride!
|
5 |
import os
|
6 |
import glob
|
7 |
import time
|
|
|
20 |
from typing import Optional
|
21 |
import gradio as gr
|
22 |
|
23 |
+
# π Logging setupβbecause even AIs need a diary!
|
24 |
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
|
25 |
logger = logging.getLogger(__name__)
|
26 |
+
log_records = [] # ποΈ Dear diary, today I logged a thing...
|
27 |
|
28 |
+
# π€ LogCaptureHandler classβcatching logs like a pro fisherman!
|
29 |
class LogCaptureHandler(logging.Handler):
|
30 |
+
# π£ Hooking those logs right outta the stream!
|
31 |
def emit(self, record):
|
32 |
log_records.append(record)
|
33 |
|
34 |
+
logger.addHandler(LogCaptureHandler()) # π Adding the hook to the loggerβcatch βem all!
|
35 |
|
36 |
+
# π° ModelConfig dataclassβbuilding castles for our AI kings!
|
37 |
@dataclass
|
38 |
class ModelConfig:
|
39 |
+
name: str # π·οΈ Naming our royal model
|
40 |
+
base_model: str # ποΈ The foundation it stands on
|
41 |
+
size: str # π How bigβs this beast?
|
42 |
+
domain: Optional[str] = None # π Where does it rule? Optional kingdom!
|
43 |
+
model_type: str = "causal_lm" # βοΈ What kind of magic does it wield?
|
44 |
+
# πΊοΈ Property to map the pathβwhere the king resides!
|
45 |
@property
|
46 |
def model_path(self):
|
47 |
return f"models/{self.name}"
|
48 |
|
49 |
+
# π¨ DiffusionConfig dataclassβart school for diffusion models!
|
50 |
@dataclass
|
51 |
class DiffusionConfig:
|
52 |
+
name: str # ποΈ Whatβs this masterpiece called?
|
53 |
+
base_model: str # πΌοΈ The canvas it starts with
|
54 |
+
size: str # π Size of the artwork, big or small?
|
55 |
+
domain: Optional[str] = None # π¨ Optional styleβabstract or realism?
|
56 |
+
# πΊοΈ Property to find the galleryβwhere the art hangs!
|
57 |
@property
|
58 |
def model_path(self):
|
59 |
return f"diffusion_models/{self.name}"
|
60 |
|
61 |
+
# π€ ModelBuilder classβassembling AI like Lego bricks!
|
62 |
class ModelBuilder:
|
63 |
+
# π οΈ Initβsetting up the workshop!
|
64 |
def __init__(self):
|
65 |
+
self.config = None # πΊοΈ Blueprint? Not yet!
|
66 |
+
self.model = None # π€ The robotβs still in pieces
|
67 |
+
self.tokenizer = None # π No word-chopper yet
|
68 |
+
# π Load_modelβblast off with a pre-trained brain!
|
69 |
def load_model(self, model_path: str, config: Optional[ModelConfig] = None):
|
70 |
+
self.model = AutoModelForCausalLM.from_pretrained(model_path) # π§ Brain downloaded!
|
71 |
+
self.tokenizer = AutoTokenizer.from_pretrained(model_path) # βοΈ Word-slicer ready!
|
72 |
if self.tokenizer.pad_token is None:
|
73 |
+
self.tokenizer.pad_token = self.tokenizer.eos_token # π©Ή Patching up the tokenizer
|
74 |
if config:
|
75 |
+
self.config = config # π Got the blueprint now!
|
76 |
+
self.model.to("cuda" if torch.cuda.is_available() else "cpu") # β‘ GPU or bust!
|
77 |
return self
|
78 |
+
# πΎ Save_modelβstashing the AI for later glory!
|
79 |
def save_model(self, path: str):
|
80 |
+
os.makedirs(os.path.dirname(path), exist_ok=True) # π Making room for the save
|
81 |
+
self.model.save_pretrained(path) # π§ Brain archived!
|
82 |
+
self.tokenizer.save_pretrained(path) # βοΈ Slicer stored!
|
83 |
|
84 |
+
# π¨ DiffusionBuilder classβcrafting diffusion dreams one pixel at a time!
|
85 |
class DiffusionBuilder:
|
86 |
+
# ποΈ Initβprepping the easel for some art!
|
87 |
def __init__(self):
|
88 |
+
self.config = None # πΊοΈ No art plan yet
|
89 |
+
self.pipeline = None # π¨ No paintbrush in hand
|
90 |
+
# πΌοΈ Load_modelβgrabbing a pre-painted masterpiece!
|
91 |
def load_model(self, model_path: str, config: Optional[DiffusionConfig] = None):
|
92 |
+
self.pipeline = StableDiffusionPipeline.from_pretrained(model_path, torch_dtype=torch.float32).to("cpu") # ποΈ Brush loaded, CPU style!
|
93 |
if config:
|
94 |
+
self.config = config # π Art plan acquired!
|
95 |
return self
|
96 |
+
# πΎ Save_modelβframing the artwork for the gallery!
|
97 |
def save_model(self, path: str):
|
98 |
+
os.makedirs(os.path.dirname(path), exist_ok=True) # π Prepping the gallery wall
|
99 |
+
self.pipeline.save_pretrained(path) # πΌοΈ Hung up for all to see!
|
100 |
+
# π Generateβspinning pixels into gold, Picasso-style!
|
101 |
def generate(self, prompt: str):
|
102 |
+
return self.pipeline(prompt, num_inference_steps=20).images[0] # π¨ Art in 20 steps or less!
|
103 |
|
104 |
+
# π Time to stamp files like a bossβunique names incoming!
|
105 |
def generate_filename(sequence, ext):
|
106 |
+
timestamp = time.strftime("%d%m%Y%H%M%S") # β° Clock says βname me now!β
|
107 |
return f"{sequence}_{timestamp}.{ext}"
|
108 |
|
109 |
+
# π΅οΈββοΈ Sherlocking the filesystem for your precious files!
|
110 |
def get_gallery_files(file_types):
|
111 |
+
return sorted(list(set([f for ext in file_types for f in glob.glob(f"*.{ext}")]))) # ποΈ Deduped treasure hunt!
|
112 |
|
113 |
+
# π¨ Paint the town neonβasync image gen magic ahead!
|
114 |
async def process_image_gen(prompt, output_file, builder):
|
115 |
if builder and isinstance(builder, DiffusionBuilder) and builder.pipeline:
|
116 |
+
pipeline = builder.pipeline # ποΈ Using the proβs brush!
|
117 |
else:
|
118 |
+
pipeline = StableDiffusionPipeline.from_pretrained("OFA-Sys/small-stable-diffusion-v0", torch_dtype=torch.float32).to("cpu") # π¨ Default brush, CPU vibes!
|
119 |
+
gen_image = pipeline(prompt, num_inference_steps=20).images[0] # π 20 steps to brilliance!
|
120 |
+
gen_image.save(output_file) # πΌοΈ Saving the neon dream!
|
121 |
return gen_image
|
122 |
|
123 |
+
# πΌοΈ Snap those pics like a paparazziβupload images with flair!
|
124 |
def upload_images(files, history, selected_files):
|
125 |
if not files:
|
126 |
+
return "No files uploaded", history, selected_files # π’ No pics, no party!
|
127 |
uploaded = []
|
128 |
for file in files:
|
129 |
+
ext = file.name.split('.')[-1].lower() # π΅οΈ Sniffing out the file type!
|
130 |
if ext in ["jpg", "png"]:
|
131 |
+
output_path = f"img_{int(time.time())}_{os.path.basename(file.name)}" # π·οΈ Tagging it fresh!
|
132 |
with open(output_path, "wb") as f:
|
133 |
+
f.write(file.read()) # πΈ Snap saved!
|
134 |
uploaded.append(output_path)
|
135 |
+
history.append(f"Uploaded Image: {output_path}") # π Logging the fame!
|
136 |
+
selected_files[output_path] = False # β
Unchecked for now!
|
137 |
return f"Uploaded {len(uploaded)} images", history, selected_files
|
138 |
|
139 |
+
# π₯ Roll cameraβvideo uploads thatβll make Spielberg jealous!
|
140 |
def upload_videos(files, history, selected_files):
|
141 |
if not files:
|
142 |
+
return "No files uploaded", history, selected_files # π¬ No footage, no Oscar!
|
143 |
uploaded = []
|
144 |
for file in files:
|
145 |
+
ext = file.name.split('.')[-1].lower() # π΅οΈ Checking the reel type!
|
146 |
if ext == "mp4":
|
147 |
+
output_path = f"vid_{int(time.time())}_{os.path.basename(file.name)}" # ποΈ Reel name ready!
|
148 |
with open(output_path, "wb") as f:
|
149 |
+
f.write(file.read()) # π₯ Action, saved!
|
150 |
uploaded.append(output_path)
|
151 |
+
history.append(f"Uploaded Video: {output_path}") # π Cue the credits!
|
152 |
+
selected_files[output_path] = False # β
Not selected yet!
|
153 |
return f"Uploaded {len(uploaded)} videos", history, selected_files
|
154 |
|
155 |
+
# π Scribble some docsβPDFs and more, oh what a bore!
|
156 |
def upload_documents(files, history, selected_files):
|
157 |
if not files:
|
158 |
+
return "No files uploaded", history, selected_files # π No docs, no drama!
|
159 |
uploaded = []
|
160 |
for file in files:
|
161 |
+
ext = file.name.split('.')[-1].lower() # π΅οΈ Peeking at the paper type!
|
162 |
if ext in ["md", "pdf", "docx"]:
|
163 |
+
output_path = f"doc_{int(time.time())}_{os.path.basename(file.name)}" # π·οΈ Stamping the scroll!
|
164 |
with open(output_path, "wb") as f:
|
165 |
+
f.write(file.read()) # π Scroll secured!
|
166 |
uploaded.append(output_path)
|
167 |
+
history.append(f"Uploaded Document: {output_path}") # π Noted in history!
|
168 |
+
selected_files[output_path] = False # β
Still on the bench!
|
169 |
return f"Uploaded {len(uploaded)} documents", history, selected_files
|
170 |
|
171 |
+
# π Data nerd alertβCSV and Excel uploads for the win!
|
172 |
def upload_datasets(files, history, selected_files):
|
173 |
if not files:
|
174 |
+
return "No files uploaded", history, selected_files # π No data, no geek-out!
|
175 |
uploaded = []
|
176 |
for file in files:
|
177 |
+
ext = file.name.split('.')[-1].lower() # π΅οΈ Cracking the data code!
|
178 |
if ext in ["csv", "xlsx"]:
|
179 |
+
output_path = f"data_{int(time.time())}_{os.path.basename(file.name)}" # π·οΈ Labeling the stats!
|
180 |
with open(output_path, "wb") as f:
|
181 |
+
f.write(file.read()) # π Stats stashed!
|
182 |
uploaded.append(output_path)
|
183 |
+
history.append(f"Uploaded Dataset: {output_path}") # π Dataβs in the books!
|
184 |
+
selected_files[output_path] = False # β
Not picked yet!
|
185 |
return f"Uploaded {len(uploaded)} datasets", history, selected_files
|
186 |
|
187 |
+
# π Link it upβURLs and titles, the webβs wild child!
|
188 |
def upload_links(links_title, links_url, history, selected_files):
|
189 |
if not links_title or not links_url:
|
190 |
+
return "No links provided", history, selected_files # π No links, no surf!
|
191 |
+
links = list(zip(links_title.split('\n'), links_url.split('\n'))) # 𧩠Pairing titles and URLs!
|
192 |
uploaded = []
|
193 |
for title, url in links:
|
194 |
if title and url:
|
195 |
+
link_entry = f"[{title}]({url})" # π Crafting the web gem!
|
196 |
uploaded.append(link_entry)
|
197 |
+
history.append(f"Added Link: {link_entry}") # π Linking history!
|
198 |
+
selected_files[link_entry] = False # β
Surfβs not up yet!
|
199 |
return f"Added {len(uploaded)} links", history, selected_files
|
200 |
|
201 |
+
# πΌοΈ Gallery glow-upβshow off all your files in style!
|
202 |
def update_galleries(history, selected_files):
|
203 |
galleries = {
|
204 |
+
"images": get_gallery_files(["jpg", "png"]), # πΌοΈ Picture parade!
|
205 |
+
"videos": get_gallery_files(["mp4"]), # π₯ Video vault!
|
206 |
+
"documents": get_gallery_files(["md", "pdf", "docx"]), # π Doc depot!
|
207 |
+
"datasets": get_gallery_files(["csv", "xlsx"]), # π Data den!
|
208 |
+
"links": [f for f in selected_files.keys() if f.startswith('[') and '](' in f and f.endswith(')')] # π Link lounge!
|
209 |
}
|
210 |
gallery_outputs = {
|
211 |
+
"images": [(Image.open(f), os.path.basename(f)) for f in galleries["images"]], # πΌοΈ Picture perfect!
|
212 |
+
"videos": [(f, os.path.basename(f)) for f in galleries["videos"]], # π₯ Reel deal!
|
213 |
+
"documents": [(Image.frombytes("RGB", fitz.open(f)[0].get_pixmap(matrix=fitz.Matrix(0.5, 0.5)).size, fitz.open(f)[0].get_pixmap(matrix=fitz.Matrix(0.5, 0.5)).samples) if f.endswith('.pdf') else f, os.path.basename(f)) for f in galleries["documents"]], # π Doc dazzle!
|
214 |
+
"datasets": [(f, os.path.basename(f)) for f in galleries["datasets"]], # π Data delight!
|
215 |
+
"links": [(f, f.split(']')[0][1:]) for f in galleries["links"]] # π Link love!
|
216 |
}
|
217 |
+
history.append(f"Updated galleries: {sum(len(g) for g in galleries.values())} files") # π Gallery grand total!
|
218 |
return gallery_outputs, history, selected_files
|
219 |
|
220 |
+
# π Sidebar swaggerβdownload links that scream βtake me home!β
|
221 |
def update_sidebar(history, selected_files):
|
222 |
+
all_files = get_gallery_files(["jpg", "png", "mp4", "md", "pdf", "docx", "csv", "xlsx"]) + [f for f in selected_files.keys() if f.startswith('[') and '](' in f and f.endswith(')')] # ποΈ All the loot!
|
223 |
+
file_list = [gr.File(label=os.path.basename(f) if not f.startswith('[') else f.split(']')[0][1:], value=f) for f in all_files] # π₯ Download goodies!
|
224 |
return file_list, history
|
225 |
|
226 |
+
# β
Check it or wreck itβtoggle those selections like a pro!
|
227 |
def toggle_selection(file_list, selected_files):
|
228 |
for file in file_list:
|
229 |
+
selected_files[file] = not selected_files.get(file, False) # β
Flip the switch, baby!
|
230 |
return selected_files
|
231 |
|
232 |
+
# π¨ Neon dreams unleashedβgenerate images that pop!
|
233 |
def image_gen(prompt, builder, history, selected_files):
|
234 |
+
selected = [f for f, sel in selected_files.items() if sel and f.endswith(('.jpg', '.png'))] # πΌοΈ Picking the canvas!
|
235 |
if not selected:
|
236 |
+
return "No images selected", None, history, selected_files # π’ No art, no party!
|
237 |
+
output_file = generate_filename("gen_output", "png") # π·οΈ New masterpiece name!
|
238 |
+
gen_image = asyncio.run(process_image_gen(prompt, output_file, builder)) # π Paint it neon!
|
239 |
+
history.append(f"Image Gen: {prompt} -> {output_file}") # π Art history in the making!
|
240 |
+
selected_files[output_file] = True # β
Auto-select the new star!
|
241 |
return f"Image saved to {output_file}", gen_image, history, selected_files
|
242 |
|
243 |
+
# πͺ Gradio UIβstep right up to the AI circus!
|
244 |
with gr.Blocks(title="AI Vision & SFT Titans π") as demo:
|
245 |
+
gr.Markdown("# AI Vision & SFT Titans π") # π Welcome to the big top!
|
246 |
+
history = gr.State(value=[]) # π The ringmasterβs logbook!
|
247 |
+
builder = gr.State(value=None) # π€ The AI acrobat, waiting in the wings!
|
248 |
+
selected_files = gr.State(value={}) # β
The chosen ones, ready to perform!
|
249 |
|
250 |
with gr.Row():
|
251 |
with gr.Column(scale=1):
|
252 |
+
gr.Markdown("## π Files") # ποΈ The file circus tent!
|
253 |
+
sidebar_files = gr.Files(label="Downloads", height=300) # π₯ Grab your souvenirs here!
|
254 |
|
255 |
with gr.Column(scale=3):
|
256 |
with gr.Row():
|
257 |
+
gr.Markdown("## π οΈ Toolbar") # π§ The circus control panel!
|
258 |
+
select_btn = gr.Button("β
Select") # β
Pick your performers!
|
259 |
+
gen_btn = gr.Button("π¨ Generate") # π¨ Unleash the art clowns!
|
260 |
|
261 |
with gr.Tabs():
|
262 |
+
with gr.TabItem("π€ Upload"): # π€ The upload trapeze!
|
263 |
with gr.Row():
|
264 |
+
img_upload = gr.File(label="πΌοΈ Images (jpg/png)", file_count="multiple", accept=["image/jpeg", "image/png"]) # πΌοΈ Picture trapeze!
|
265 |
+
vid_upload = gr.File(label="π₯ Videos (mp4)", file_count="multiple", accept=["video/mp4"]) # π₯ Video vault!
|
266 |
with gr.Row():
|
267 |
+
doc_upload = gr.File(label="π Docs (md/pdf/docx)", file_count="multiple", accept=["text/markdown", "application/pdf", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"]) # π Doc drop!
|
268 |
+
data_upload = gr.File(label="π Data (csv/xlsx)", file_count="multiple", accept=["text/csv", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"]) # π Data dive!
|
269 |
with gr.Row():
|
270 |
+
links_title = gr.Textbox(label="π Link Titles", lines=3) # π Title tightrope!
|
271 |
+
links_url = gr.Textbox(label="π Link URLs", lines=3) # π URL unicycle!
|
272 |
+
upload_status = gr.Textbox(label="Status") # π’ Ringmasterβs update!
|
273 |
gr.Button("π€ Upload Images").click(upload_images, inputs=[img_upload, history, selected_files], outputs=[upload_status, history, selected_files]).then(update_galleries, inputs=[history, selected_files], outputs=[gr.Gallery(), gr.Gallery(), gr.Gallery(), gr.Gallery(), gr.Gallery(), history, selected_files]).then(update_sidebar, inputs=[history, selected_files], outputs=[sidebar_files, history])
|
274 |
gr.Button("π€ Upload Videos").click(upload_videos, inputs=[vid_upload, history, selected_files], outputs=[upload_status, history, selected_files]).then(update_galleries, inputs=[history, selected_files], outputs=[gr.Gallery(), gr.Gallery(), gr.Gallery(), gr.Gallery(), gr.Gallery(), history, selected_files]).then(update_sidebar, inputs=[history, selected_files], outputs=[sidebar_files, history])
|
275 |
gr.Button("π€ Upload Docs").click(upload_documents, inputs=[doc_upload, history, selected_files], outputs=[upload_status, history, selected_files]).then(update_galleries, inputs=[history, selected_files], outputs=[gr.Gallery(), gr.Gallery(), gr.Gallery(), gr.Gallery(), gr.Gallery(), history, selected_files]).then(update_sidebar, inputs=[history, selected_files], outputs=[sidebar_files, history])
|
276 |
gr.Button("π€ Upload Data").click(upload_datasets, inputs=[data_upload, history, selected_files], outputs=[upload_status, history, selected_files]).then(update_galleries, inputs=[history, selected_files], outputs=[gr.Gallery(), gr.Gallery(), gr.Gallery(), gr.Gallery(), gr.Gallery(), history, selected_files]).then(update_sidebar, inputs=[history, selected_files], outputs=[sidebar_files, history])
|
277 |
gr.Button("π€ Upload Links").click(upload_links, inputs=[links_title, links_url, history, selected_files], outputs=[upload_status, history, selected_files]).then(update_galleries, inputs=[history, selected_files], outputs=[gr.Gallery(), gr.Gallery(), gr.Gallery(), gr.Gallery(), gr.Gallery(), history, selected_files]).then(update_sidebar, inputs=[history, selected_files], outputs=[sidebar_files, history])
|
278 |
|
279 |
+
with gr.TabItem("πΌοΈ Gallery"): # πΌοΈ The big top showcase!
|
280 |
+
img_gallery = gr.Gallery(label="πΌοΈ Images (jpg/png)", columns=4, height="auto") # πΌοΈ Picture parade!
|
281 |
+
vid_gallery = gr.Gallery(label="π₯ Videos (mp4)", columns=4, height="auto") # π₯ Video vault!
|
282 |
+
doc_gallery = gr.Gallery(label="π Docs (md/pdf/docx)", columns=4, height="auto") # π Doc depot!
|
283 |
+
data_gallery = gr.Gallery(label="π Data (csv/xlsx)", columns=4, height="auto") # π Data den!
|
284 |
+
link_gallery = gr.Gallery(label="π Links", columns=4, height="auto") # π Link lounge!
|
285 |
gr.Button("π Refresh").click(update_galleries, inputs=[history, selected_files], outputs=[img_gallery, vid_gallery, doc_gallery, data_gallery, link_gallery, history, selected_files]).then(update_sidebar, inputs=[history, selected_files], outputs=[sidebar_files, history])
|
286 |
|
287 |
+
with gr.TabItem("π Operations"): # π The magic trick tent!
|
288 |
+
prompt = gr.Textbox(label="Image Gen Prompt", value="Generate a neon version") # π¨ Art spellbook!
|
289 |
+
op_status = gr.Textbox(label="Status") # π’ Trick status!
|
290 |
+
op_output = gr.Image(label="Output") # π¨ The big reveal!
|
291 |
+
select_files = gr.Dropdown(choices=list(selected_files.value.keys()), multiselect=True, label="Select Files") # β
Pick your props!
|
292 |
select_btn.click(toggle_selection, inputs=[select_files, selected_files], outputs=[selected_files]).then(update_sidebar, inputs=[history, selected_files], outputs=[sidebar_files, history])
|
293 |
gen_btn.click(image_gen, inputs=[prompt, builder, history, selected_files], outputs=[op_status, op_output, history, selected_files]).then(update_galleries, inputs=[history, selected_files], outputs=[img_gallery, vid_gallery, doc_gallery, data_gallery, link_gallery, history, selected_files]).then(update_sidebar, inputs=[history, selected_files], outputs=[sidebar_files, history])
|
294 |
|
295 |
+
# π Launch the circusβstep right up, folks!
|
296 |
demo.launch()
|