Spaces:
Sleeping
Sleeping
Manish Gupta commited on
Commit ·
cecd5f5
1
Parent(s): 896b52b
Improved UI with better functionalities and UX.
Browse files
app.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
| 1 |
import os
|
|
|
|
| 2 |
import io
|
| 3 |
from PIL import Image
|
| 4 |
import gradio as gr
|
|
@@ -11,6 +12,15 @@ os.environ["AWS_SECRET_ACCESS_KEY"] = os.getenv("AWS_SECRET_ACCESS_KEY")
|
|
| 11 |
os.environ["S3_BUCKET_NAME"] = os.getenv("AWS_BUCKET")
|
| 12 |
|
| 13 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
def list_current_dir(bucket_name: str, folder_path: str = "") -> list:
|
| 15 |
response = aws_utils.S3_CLIENT.list_objects_v2(
|
| 16 |
Bucket=bucket_name, Prefix=folder_path, Delimiter="/"
|
|
@@ -24,85 +34,100 @@ def list_current_dir(bucket_name: str, folder_path: str = "") -> list:
|
|
| 24 |
return folders
|
| 25 |
|
| 26 |
|
| 27 |
-
def
|
| 28 |
-
episodes: list, current_episode: int, current_scene: int, current_frame: int
|
| 29 |
-
):
|
| 30 |
-
curr_frame = episodes[current_episode]["scenes"][current_scene]["frames"][
|
| 31 |
-
current_frame
|
| 32 |
-
]
|
| 33 |
-
return (
|
| 34 |
-
episodes,
|
| 35 |
-
current_episode,
|
| 36 |
-
current_scene,
|
| 37 |
-
current_frame,
|
| 38 |
-
str(current_episode + 1),
|
| 39 |
-
str(current_scene + 1),
|
| 40 |
-
str(current_frame + 1),
|
| 41 |
-
curr_frame["description"],
|
| 42 |
-
curr_frame["narration"],
|
| 43 |
-
curr_frame["audio_cue_character"],
|
| 44 |
-
curr_frame["audio_cue_text"],
|
| 45 |
-
)
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
def load_data(
|
| 49 |
-
episodes: list, current_episode: int, current_scene: int, current_frame: int
|
| 50 |
-
):
|
| 51 |
-
if current_frame + 1 < len(
|
| 52 |
-
episodes[current_episode]["scenes"][current_scene]["frames"]
|
| 53 |
-
):
|
| 54 |
-
current_frame += 1
|
| 55 |
-
else:
|
| 56 |
-
if current_scene + 1 < len(episodes[current_episode]["scenes"]):
|
| 57 |
-
current_scene += 1
|
| 58 |
-
current_frame = 0
|
| 59 |
-
else:
|
| 60 |
-
if current_episode + 1 < len(episodes):
|
| 61 |
-
current_episode += 1
|
| 62 |
-
current_scene = 0
|
| 63 |
-
current_frame = 0
|
| 64 |
-
else:
|
| 65 |
-
return [], current_episode, current_scene, current_frame
|
| 66 |
-
|
| 67 |
images = []
|
|
|
|
| 68 |
# Loading the 0th frame of 0th scene in 0th episode.
|
| 69 |
-
for comps in
|
| 70 |
-
|
| 71 |
-
]["compositions"]:
|
| 72 |
-
data = aws_utils.fetch_from_s3(comps["image"])
|
| 73 |
images.append(Image.open(io.BytesIO(data)))
|
| 74 |
|
| 75 |
-
return
|
| 76 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 77 |
)
|
| 78 |
|
| 79 |
|
| 80 |
-
def
|
| 81 |
-
comic_id: str, current_episode: int, current_scene: int, current_frame: int
|
| 82 |
-
):
|
| 83 |
# Logic to load and return images based on comic_id and episode
|
| 84 |
# You can replace this with actual image paths or generation logic
|
| 85 |
print(f"Getting episodes for comic id: {comic_id}")
|
| 86 |
-
|
| 87 |
-
|
| 88 |
for folder in list_current_dir(AWS_BUCKET, f"{comic_id}/"):
|
| 89 |
if "episode" in folder:
|
| 90 |
json_path = f"s3://{AWS_BUCKET}/{folder}episode.json"
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
)
|
| 94 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 95 |
|
| 96 |
-
images = []
|
| 97 |
-
# Loading the 0th frame of 0th scene in 0th episode.
|
| 98 |
-
for comps in episodes[current_episode]["scenes"][current_scene]["frames"][
|
| 99 |
-
current_frame
|
| 100 |
-
]["compositions"]:
|
| 101 |
-
data = aws_utils.fetch_from_s3(comps["image"])
|
| 102 |
-
images.append(Image.open(io.BytesIO(data)))
|
| 103 |
|
| 104 |
-
|
| 105 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 106 |
)
|
| 107 |
|
| 108 |
|
|
@@ -110,11 +135,10 @@ def save_image(
|
|
| 110 |
selected_image,
|
| 111 |
comic_id: str,
|
| 112 |
current_episode: int,
|
| 113 |
-
current_scene: int,
|
| 114 |
current_frame: int,
|
| 115 |
):
|
| 116 |
# Implement your AWS S3 save logic here
|
| 117 |
-
print(f"Saving image: {selected_image}")
|
| 118 |
with Image.open(selected_image[0]) as img:
|
| 119 |
# Convert and save as JPG
|
| 120 |
img_bytes = io.BytesIO()
|
|
@@ -123,58 +147,68 @@ def save_image(
|
|
| 123 |
|
| 124 |
aws_utils.save_to_s3(
|
| 125 |
AWS_BUCKET,
|
| 126 |
-
f"{comic_id}/episode-{current_episode}/images
|
| 127 |
img_bytes,
|
| 128 |
f"{current_frame}.jpg",
|
| 129 |
)
|
| 130 |
-
print("Image saved successfully!")
|
| 131 |
gr.Info("Saved Image successfully!")
|
| 132 |
|
| 133 |
|
| 134 |
with gr.Blocks() as demo:
|
| 135 |
selected_image = gr.State(None)
|
| 136 |
-
current_episode = gr.State(
|
| 137 |
-
|
| 138 |
-
current_frame = gr.State(0)
|
| 139 |
episodes_data = gr.State({})
|
| 140 |
|
| 141 |
with gr.Row():
|
| 142 |
comic_id = gr.Textbox(label="Enter Comic ID:", placeholder="Enter Comic ID")
|
| 143 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 144 |
|
| 145 |
images = gr.Gallery(
|
| 146 |
label="Select an Image", elem_id="image_select", columns=4, height=300
|
| 147 |
)
|
| 148 |
|
| 149 |
-
# Display information about current Image
|
| 150 |
with gr.Row():
|
| 151 |
-
|
| 152 |
-
|
| 153 |
-
frame = gr.Textbox(label="Current Frame", interactive=False)
|
| 154 |
|
| 155 |
-
image_description = gr.Textbox(label="Description", interactive=False)
|
| 156 |
-
narration = gr.Textbox(label="narration", interactive=False)
|
| 157 |
with gr.Row():
|
| 158 |
character = gr.Textbox(label="Character", interactive=False)
|
| 159 |
dialouge = gr.Textbox(label="dialouge", interactive=False)
|
| 160 |
|
| 161 |
# buttons to interact with the data
|
| 162 |
with gr.Row():
|
|
|
|
| 163 |
save_button = gr.Button("Save Image")
|
| 164 |
next_button = gr.Button("Next Image")
|
| 165 |
|
| 166 |
-
|
| 167 |
-
|
| 168 |
-
inputs=[comic_id
|
| 169 |
outputs=[
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 170 |
images,
|
| 171 |
episodes_data,
|
| 172 |
current_episode,
|
| 173 |
-
current_scene,
|
| 174 |
current_frame,
|
| 175 |
-
episode,
|
| 176 |
-
scene,
|
| 177 |
-
frame,
|
| 178 |
image_description,
|
| 179 |
narration,
|
| 180 |
character,
|
|
@@ -188,30 +222,35 @@ with gr.Blocks() as demo:
|
|
| 188 |
|
| 189 |
images.select(get_select_index, images, selected_image)
|
| 190 |
|
| 191 |
-
|
| 192 |
-
|
| 193 |
-
inputs=[
|
| 194 |
-
|
| 195 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 196 |
current_episode,
|
| 197 |
-
current_scene,
|
| 198 |
current_frame,
|
|
|
|
|
|
|
|
|
|
|
|
|
| 199 |
],
|
| 200 |
-
outputs=[],
|
| 201 |
)
|
| 202 |
|
| 203 |
-
|
| 204 |
-
|
| 205 |
-
inputs=[episodes_data, current_episode,
|
| 206 |
outputs=[
|
|
|
|
|
|
|
|
|
|
| 207 |
images,
|
| 208 |
episodes_data,
|
| 209 |
current_episode,
|
| 210 |
-
current_scene,
|
| 211 |
current_frame,
|
| 212 |
-
episode,
|
| 213 |
-
scene,
|
| 214 |
-
frame,
|
| 215 |
image_description,
|
| 216 |
narration,
|
| 217 |
character,
|
|
@@ -219,4 +258,15 @@ with gr.Blocks() as demo:
|
|
| 219 |
],
|
| 220 |
)
|
| 221 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 222 |
demo.launch(auth=("admin", "Qrt@12*34#immersfy"), share=True, ssr_mode=False)
|
|
|
|
| 1 |
import os
|
| 2 |
+
import dataclasses
|
| 3 |
import io
|
| 4 |
from PIL import Image
|
| 5 |
import gradio as gr
|
|
|
|
| 12 |
os.environ["S3_BUCKET_NAME"] = os.getenv("AWS_BUCKET")
|
| 13 |
|
| 14 |
|
| 15 |
+
@dataclasses.dataclass
|
| 16 |
+
class ComicFrame:
|
| 17 |
+
description: str
|
| 18 |
+
narration: str
|
| 19 |
+
character_dilouge: str
|
| 20 |
+
character: str
|
| 21 |
+
compositions: list
|
| 22 |
+
|
| 23 |
+
|
| 24 |
def list_current_dir(bucket_name: str, folder_path: str = "") -> list:
|
| 25 |
response = aws_utils.S3_CLIENT.list_objects_v2(
|
| 26 |
Bucket=bucket_name, Prefix=folder_path, Delimiter="/"
|
|
|
|
| 34 |
return folders
|
| 35 |
|
| 36 |
|
| 37 |
+
def load_data_inner(episodes_data: list, current_episode: int, current_frame: int):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 38 |
images = []
|
| 39 |
+
curr_frame = episodes_data[current_episode][current_frame]
|
| 40 |
# Loading the 0th frame of 0th scene in 0th episode.
|
| 41 |
+
for comps in curr_frame.compositions:
|
| 42 |
+
data = aws_utils.fetch_from_s3(comps)
|
|
|
|
|
|
|
| 43 |
images.append(Image.open(io.BytesIO(data)))
|
| 44 |
|
| 45 |
+
return (
|
| 46 |
+
images,
|
| 47 |
+
episodes_data,
|
| 48 |
+
current_episode,
|
| 49 |
+
current_frame,
|
| 50 |
+
curr_frame.description,
|
| 51 |
+
curr_frame.narration,
|
| 52 |
+
curr_frame.character,
|
| 53 |
+
curr_frame.character_dilouge,
|
| 54 |
)
|
| 55 |
|
| 56 |
|
| 57 |
+
def load_metadata_fn(comic_id: str):
|
|
|
|
|
|
|
| 58 |
# Logic to load and return images based on comic_id and episode
|
| 59 |
# You can replace this with actual image paths or generation logic
|
| 60 |
print(f"Getting episodes for comic id: {comic_id}")
|
| 61 |
+
episodes_data = {}
|
| 62 |
+
episode_idx = []
|
| 63 |
for folder in list_current_dir(AWS_BUCKET, f"{comic_id}/"):
|
| 64 |
if "episode" in folder:
|
| 65 |
json_path = f"s3://{AWS_BUCKET}/{folder}episode.json"
|
| 66 |
+
idx = int(folder.split("/")[1].split("-")[-1])
|
| 67 |
+
episode_idx.append(idx)
|
| 68 |
+
data = eval(aws_utils.fetch_from_s3(source=json_path).decode("utf-8"))
|
| 69 |
+
comic_frames = []
|
| 70 |
+
for scene in data["scenes"]:
|
| 71 |
+
for frame in scene["frames"]:
|
| 72 |
+
comic_frames.append(
|
| 73 |
+
ComicFrame(
|
| 74 |
+
description=frame["description"],
|
| 75 |
+
narration=frame["narration"],
|
| 76 |
+
character=frame["audio_cue_character"],
|
| 77 |
+
character_dilouge=frame["audio_cue_text"],
|
| 78 |
+
compositions=[
|
| 79 |
+
comp["image"] for comp in frame["compositions"]
|
| 80 |
+
],
|
| 81 |
+
)
|
| 82 |
+
)
|
| 83 |
+
episodes_data[idx] = comic_frames
|
| 84 |
+
current_episode, current_frame = min(episode_idx), 0
|
| 85 |
+
return (
|
| 86 |
+
gr.update(choices=episode_idx, value=episode_idx[0]),
|
| 87 |
+
gr.update(
|
| 88 |
+
choices=range(len(episodes_data[current_episode])), value=current_frame
|
| 89 |
+
),
|
| 90 |
+
episodes_data
|
| 91 |
+
)
|
| 92 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 93 |
|
| 94 |
+
def load_data_next(episodes_data: list, current_episode: int, current_frame: int):
|
| 95 |
+
if current_frame + 1 < len(episodes_data[current_episode]):
|
| 96 |
+
current_frame += 1
|
| 97 |
+
elif current_episode + 1 < len(episodes_data):
|
| 98 |
+
current_episode += 1
|
| 99 |
+
current_frame = 0
|
| 100 |
+
else:
|
| 101 |
+
return [], current_episode, current_frame
|
| 102 |
+
return (
|
| 103 |
+
gr.update(value=current_episode),
|
| 104 |
+
gr.update(value=current_frame),
|
| 105 |
+
*load_data_inner(episodes_data, current_episode, current_frame),
|
| 106 |
+
)
|
| 107 |
+
|
| 108 |
+
|
| 109 |
+
def load_data_prev(episodes_data: list, current_episode: int, current_frame: int):
|
| 110 |
+
if current_frame - 1 >= 0:
|
| 111 |
+
current_frame -= 1
|
| 112 |
+
elif current_episode - 1 > min(list(episodes_data.keys())):
|
| 113 |
+
current_episode -= 1
|
| 114 |
+
current_frame = 0
|
| 115 |
+
else:
|
| 116 |
+
return [], current_episode, current_frame
|
| 117 |
+
return (
|
| 118 |
+
gr.update(value=current_episode),
|
| 119 |
+
gr.update(value=current_frame),
|
| 120 |
+
*load_data_inner(episodes_data, current_episode, current_frame),
|
| 121 |
+
)
|
| 122 |
+
|
| 123 |
+
|
| 124 |
+
def load_from_dropdown(
|
| 125 |
+
episodes_data: dict, selected_episode, selected_frame,
|
| 126 |
+
):
|
| 127 |
+
return (
|
| 128 |
+
gr.update(value=selected_episode),
|
| 129 |
+
gr.update(value=selected_frame),
|
| 130 |
+
*load_data_inner(episodes_data, selected_episode, selected_frame),
|
| 131 |
)
|
| 132 |
|
| 133 |
|
|
|
|
| 135 |
selected_image,
|
| 136 |
comic_id: str,
|
| 137 |
current_episode: int,
|
|
|
|
| 138 |
current_frame: int,
|
| 139 |
):
|
| 140 |
# Implement your AWS S3 save logic here
|
| 141 |
+
# print(f"Saving image: {selected_image}")
|
| 142 |
with Image.open(selected_image[0]) as img:
|
| 143 |
# Convert and save as JPG
|
| 144 |
img_bytes = io.BytesIO()
|
|
|
|
| 147 |
|
| 148 |
aws_utils.save_to_s3(
|
| 149 |
AWS_BUCKET,
|
| 150 |
+
f"{comic_id}/episode-{current_episode}/images",
|
| 151 |
img_bytes,
|
| 152 |
f"{current_frame}.jpg",
|
| 153 |
)
|
|
|
|
| 154 |
gr.Info("Saved Image successfully!")
|
| 155 |
|
| 156 |
|
| 157 |
with gr.Blocks() as demo:
|
| 158 |
selected_image = gr.State(None)
|
| 159 |
+
current_episode = gr.State(-1)
|
| 160 |
+
current_frame = gr.State(-1)
|
|
|
|
| 161 |
episodes_data = gr.State({})
|
| 162 |
|
| 163 |
with gr.Row():
|
| 164 |
comic_id = gr.Textbox(label="Enter Comic ID:", placeholder="Enter Comic ID")
|
| 165 |
+
load_metadata = gr.Button("Load Metadata")
|
| 166 |
+
|
| 167 |
+
# Display information about current Image
|
| 168 |
+
with gr.Row():
|
| 169 |
+
episode_dropdown = gr.Dropdown(choices=[], label="Current Episode", interactive=True)
|
| 170 |
+
frame_dropdown = gr.Dropdown(choices=[], label="Current Frame", interactive=True)
|
| 171 |
+
load_images = gr.Button("Load Images")
|
| 172 |
|
| 173 |
images = gr.Gallery(
|
| 174 |
label="Select an Image", elem_id="image_select", columns=4, height=300
|
| 175 |
)
|
| 176 |
|
|
|
|
| 177 |
with gr.Row():
|
| 178 |
+
image_description = gr.Textbox(label="Description", interactive=False)
|
| 179 |
+
narration = gr.Textbox(label="narration", interactive=False)
|
|
|
|
| 180 |
|
|
|
|
|
|
|
| 181 |
with gr.Row():
|
| 182 |
character = gr.Textbox(label="Character", interactive=False)
|
| 183 |
dialouge = gr.Textbox(label="dialouge", interactive=False)
|
| 184 |
|
| 185 |
# buttons to interact with the data
|
| 186 |
with gr.Row():
|
| 187 |
+
prev_button = gr.Button("Prev Image")
|
| 188 |
save_button = gr.Button("Save Image")
|
| 189 |
next_button = gr.Button("Next Image")
|
| 190 |
|
| 191 |
+
load_metadata.click(
|
| 192 |
+
load_metadata_fn,
|
| 193 |
+
inputs=[comic_id],
|
| 194 |
outputs=[
|
| 195 |
+
episode_dropdown,
|
| 196 |
+
frame_dropdown,
|
| 197 |
+
episodes_data
|
| 198 |
+
],
|
| 199 |
+
)
|
| 200 |
+
|
| 201 |
+
load_images.click(
|
| 202 |
+
load_from_dropdown,
|
| 203 |
+
inputs=[episodes_data, episode_dropdown, frame_dropdown],
|
| 204 |
+
outputs=[
|
| 205 |
+
episode_dropdown,
|
| 206 |
+
frame_dropdown,
|
| 207 |
+
# Textual data returned from load_text_data()
|
| 208 |
images,
|
| 209 |
episodes_data,
|
| 210 |
current_episode,
|
|
|
|
| 211 |
current_frame,
|
|
|
|
|
|
|
|
|
|
| 212 |
image_description,
|
| 213 |
narration,
|
| 214 |
character,
|
|
|
|
| 222 |
|
| 223 |
images.select(get_select_index, images, selected_image)
|
| 224 |
|
| 225 |
+
next_button.click(
|
| 226 |
+
load_data_next,
|
| 227 |
+
inputs=[episodes_data, current_episode, current_frame],
|
| 228 |
+
outputs=[
|
| 229 |
+
episode_dropdown,
|
| 230 |
+
frame_dropdown,
|
| 231 |
+
# Textual data returned from load_text_data()
|
| 232 |
+
images,
|
| 233 |
+
episodes_data,
|
| 234 |
current_episode,
|
|
|
|
| 235 |
current_frame,
|
| 236 |
+
image_description,
|
| 237 |
+
narration,
|
| 238 |
+
character,
|
| 239 |
+
dialouge
|
| 240 |
],
|
|
|
|
| 241 |
)
|
| 242 |
|
| 243 |
+
prev_button.click(
|
| 244 |
+
load_data_prev,
|
| 245 |
+
inputs=[episodes_data, current_episode, current_frame],
|
| 246 |
outputs=[
|
| 247 |
+
episode_dropdown,
|
| 248 |
+
frame_dropdown,
|
| 249 |
+
# Textual data returned from load_text_data()
|
| 250 |
images,
|
| 251 |
episodes_data,
|
| 252 |
current_episode,
|
|
|
|
| 253 |
current_frame,
|
|
|
|
|
|
|
|
|
|
| 254 |
image_description,
|
| 255 |
narration,
|
| 256 |
character,
|
|
|
|
| 258 |
],
|
| 259 |
)
|
| 260 |
|
| 261 |
+
save_button.click(
|
| 262 |
+
save_image,
|
| 263 |
+
inputs=[
|
| 264 |
+
selected_image,
|
| 265 |
+
comic_id,
|
| 266 |
+
current_episode,
|
| 267 |
+
current_frame,
|
| 268 |
+
],
|
| 269 |
+
outputs=[],
|
| 270 |
+
)
|
| 271 |
+
|
| 272 |
demo.launch(auth=("admin", "Qrt@12*34#immersfy"), share=True, ssr_mode=False)
|