Spaces:
Running
Running
feat: working image template in Safari on IOS and Chrome in Android" [fragrantica ad71397] feat: working image template in Safari on IOS and Chrome in Android (#7)
Browse files- feat: working image template in Safari on IOS and Chrome in Android" [fragrantica ad71397] feat: working image template in Safari on IOS and Chrome in Android (228c16d9e9ff09e8703581026e46ec515906efa8)
app.py
CHANGED
|
@@ -144,33 +144,54 @@ def clean_env_vars():
|
|
| 144 |
os.environ.pop("OPENAI_MODEL_NAME", None)
|
| 145 |
|
| 146 |
js_share_logic = """
|
| 147 |
-
async (
|
| 148 |
-
if (!
|
| 149 |
-
console.error("Share button clicked, but no image
|
| 150 |
alert("No image to share. Please generate an image first.");
|
| 151 |
return;
|
| 152 |
}
|
| 153 |
|
| 154 |
-
const dataUrl = image_data_url;
|
| 155 |
-
|
| 156 |
try {
|
| 157 |
-
const response = await fetch(
|
| 158 |
const blob = await response.blob();
|
| 159 |
-
|
| 160 |
-
|
| 161 |
-
|
| 162 |
-
|
| 163 |
-
|
| 164 |
-
|
| 165 |
-
|
| 166 |
-
|
| 167 |
-
|
| 168 |
-
|
| 169 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 170 |
} catch (error) {
|
| 171 |
if (error.name === 'AbortError') {
|
| 172 |
console.log("Share dialog cancelled by user.");
|
| 173 |
-
// Do nothing, as this is a user-initiated cancellation
|
| 174 |
} else {
|
| 175 |
console.error("Error sharing:", error);
|
| 176 |
alert("An error occurred while trying to share.");
|
|
@@ -235,12 +256,8 @@ with gr.Blocks() as demo:
|
|
| 235 |
image_coupon_code_input = gr.Textbox(label="Coupon Code", placeholder="Enter coupon code...")
|
| 236 |
gen_image_btn = gr.Button("Generate Image")
|
| 237 |
with gr.Column():
|
| 238 |
-
image_output = gr.Image(label="Generated Image", height=500, type="
|
| 239 |
-
|
| 240 |
-
label="Image Data URL (for debugging)",
|
| 241 |
-
visible=True,
|
| 242 |
-
elem_id="image_data_url_storage"
|
| 243 |
-
)
|
| 244 |
share_button = gr.Button("🚀 Share Image", interactive=False)
|
| 245 |
|
| 246 |
with gr.Tab("Settings"):
|
|
@@ -271,24 +288,14 @@ with gr.Blocks() as demo:
|
|
| 271 |
return
|
| 272 |
yield report.raw
|
| 273 |
|
| 274 |
-
|
| 275 |
-
print(f"image_to_base64 called. pil_image type: {type(pil_image)}")
|
| 276 |
-
if pil_image is None:
|
| 277 |
-
print("pil_image is None. Returning empty string and interactive=False.")
|
| 278 |
-
return "", gr.update(interactive=False)
|
| 279 |
-
buffered = BytesIO()
|
| 280 |
-
pil_image.save(buffered, format="PNG")
|
| 281 |
-
img_str = base64.b64encode(buffered.getvalue()).decode("utf-8")
|
| 282 |
-
data_url = f"data:image/png;base64,{img_str}"
|
| 283 |
-
print("Returning data_url and interactive=True.")
|
| 284 |
-
return data_url, gr.update(interactive=True)
|
| 285 |
|
| 286 |
def generate_image(product_image_url, product_name, original_price, final_price, coupon_code):
|
| 287 |
tool = GenerateImageTool()
|
| 288 |
original_price_str = f"{original_price:.2f}".replace('.', ',')
|
| 289 |
final_price_str = f"{final_price:.2f}".replace('.', ',')
|
| 290 |
|
| 291 |
-
yield gr.update(interactive=False, value="Generating..."), None
|
| 292 |
|
| 293 |
image_path = tool._run(
|
| 294 |
product_image_url=product_image_url,
|
|
@@ -298,17 +305,28 @@ with gr.Blocks() as demo:
|
|
| 298 |
coupon_code=coupon_code
|
| 299 |
)
|
| 300 |
|
| 301 |
-
|
| 302 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 303 |
|
| 304 |
generate_ad_button.click(generate_ad, inputs=[url_input, store_name_input, main_cupom_input, main_cupom_discount_percentage_input, cupom_1_input, original_price_input, discounted_price_input, openai_key_input, natura_token_input, openai_base_url_input, openai_model_name_input], outputs=[generate_ad_button, ad_output])
|
| 305 |
clear_button.click(clear_fields, inputs=[], outputs=[url_input, original_price_input, discounted_price_input])
|
| 306 |
analyze_fragrantica_button.click(analyze_fragrantica_url, inputs=[fragrantica_url_input, openai_key_input, natura_token_input, openai_base_url_input, openai_model_name_input], outputs=fragrantica_output)
|
| 307 |
-
gen_image_btn.click(generate_image,
|
| 308 |
-
|
| 309 |
-
|
| 310 |
-
|
| 311 |
-
|
| 312 |
|
| 313 |
if __name__ == "__main__":
|
| 314 |
demo.launch(server_name="0.0.0.0", server_port=7860)
|
|
|
|
| 144 |
os.environ.pop("OPENAI_MODEL_NAME", None)
|
| 145 |
|
| 146 |
js_share_logic = """
|
| 147 |
+
async (image_url) => {
|
| 148 |
+
if (!image_url) {
|
| 149 |
+
console.error("Share button clicked, but no image URL found.");
|
| 150 |
alert("No image to share. Please generate an image first.");
|
| 151 |
return;
|
| 152 |
}
|
| 153 |
|
|
|
|
|
|
|
| 154 |
try {
|
| 155 |
+
const response = await fetch(image_url);
|
| 156 |
const blob = await response.blob();
|
| 157 |
+
|
| 158 |
+
const reader = new FileReader();
|
| 159 |
+
reader.readAsDataURL(blob);
|
| 160 |
+
reader.onloadend = async function() {
|
| 161 |
+
const base64data = reader.result;
|
| 162 |
+
|
| 163 |
+
const parts = base64data.split(';base64,');
|
| 164 |
+
const contentType = parts[0].split(':')[1];
|
| 165 |
+
const raw = window.atob(parts[1]);
|
| 166 |
+
const rawLength = raw.length;
|
| 167 |
+
const uInt8Array = new Uint8Array(rawLength);
|
| 168 |
+
|
| 169 |
+
for (let i = 0; i < rawLength; ++i) {
|
| 170 |
+
uInt8Array[i] = raw.charCodeAt(i);
|
| 171 |
+
}
|
| 172 |
+
|
| 173 |
+
const newBlob = new Blob([uInt8Array], { type: contentType });
|
| 174 |
+
const fileName = `shared_image_${new Date().getTime()}.png`;
|
| 175 |
+
const file = new File([newBlob], fileName, { type: contentType });
|
| 176 |
+
|
| 177 |
+
if (navigator.share && navigator.canShare({ files: [file] })) {
|
| 178 |
+
await navigator.share({
|
| 179 |
+
files: [file],
|
| 180 |
+
title: "Image",
|
| 181 |
+
text: "Shared from app.",
|
| 182 |
+
});
|
| 183 |
+
} else {
|
| 184 |
+
alert("Sharing not supported on this browser.");
|
| 185 |
+
}
|
| 186 |
+
};
|
| 187 |
+
reader.onerror = function(error) {
|
| 188 |
+
console.error("Error converting blob to data URL:", error);
|
| 189 |
+
alert("An error occurred while preparing image for sharing.");
|
| 190 |
+
};
|
| 191 |
+
|
| 192 |
} catch (error) {
|
| 193 |
if (error.name === 'AbortError') {
|
| 194 |
console.log("Share dialog cancelled by user.");
|
|
|
|
| 195 |
} else {
|
| 196 |
console.error("Error sharing:", error);
|
| 197 |
alert("An error occurred while trying to share.");
|
|
|
|
| 256 |
image_coupon_code_input = gr.Textbox(label="Coupon Code", placeholder="Enter coupon code...")
|
| 257 |
gen_image_btn = gr.Button("Generate Image")
|
| 258 |
with gr.Column():
|
| 259 |
+
image_output = gr.Image(label="Generated Image", height=500, type="filepath", interactive=False)
|
| 260 |
+
base64_debug_output = gr.Textbox(label="Base64 Debug Output", visible=True, interactive=False)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 261 |
share_button = gr.Button("🚀 Share Image", interactive=False)
|
| 262 |
|
| 263 |
with gr.Tab("Settings"):
|
|
|
|
| 288 |
return
|
| 289 |
yield report.raw
|
| 290 |
|
| 291 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 292 |
|
| 293 |
def generate_image(product_image_url, product_name, original_price, final_price, coupon_code):
|
| 294 |
tool = GenerateImageTool()
|
| 295 |
original_price_str = f"{original_price:.2f}".replace('.', ',')
|
| 296 |
final_price_str = f"{final_price:.2f}".replace('.', ',')
|
| 297 |
|
| 298 |
+
yield gr.update(interactive=False, value="Generating..."), None, gr.update(interactive=False)
|
| 299 |
|
| 300 |
image_path = tool._run(
|
| 301 |
product_image_url=product_image_url,
|
|
|
|
| 305 |
coupon_code=coupon_code
|
| 306 |
)
|
| 307 |
|
| 308 |
+
yield gr.update(interactive=True, value="Generate Image"), image_path, gr.update(interactive=True)
|
| 309 |
+
|
| 310 |
+
def process_image_for_sharing(image_path):
|
| 311 |
+
if image_path is None:
|
| 312 |
+
return ""
|
| 313 |
+
try:
|
| 314 |
+
with open(image_path, "rb") as image_file:
|
| 315 |
+
encoded_string = base64.b64encode(image_file.read()).decode("utf-8")
|
| 316 |
+
data_url = f"data:image/png;base64,{encoded_string}"
|
| 317 |
+
return data_url
|
| 318 |
+
except Exception as e:
|
| 319 |
+
print(f"Error processing image for sharing: {e}")
|
| 320 |
+
return ""
|
| 321 |
|
| 322 |
generate_ad_button.click(generate_ad, inputs=[url_input, store_name_input, main_cupom_input, main_cupom_discount_percentage_input, cupom_1_input, original_price_input, discounted_price_input, openai_key_input, natura_token_input, openai_base_url_input, openai_model_name_input], outputs=[generate_ad_button, ad_output])
|
| 323 |
clear_button.click(clear_fields, inputs=[], outputs=[url_input, original_price_input, discounted_price_input])
|
| 324 |
analyze_fragrantica_button.click(analyze_fragrantica_url, inputs=[fragrantica_url_input, openai_key_input, natura_token_input, openai_base_url_input, openai_model_name_input], outputs=fragrantica_output)
|
| 325 |
+
gen_image_btn.click(generate_image,
|
| 326 |
+
inputs=[image_product_url_input, image_product_name_input, image_original_price_input, image_final_price_input, image_coupon_code_input],
|
| 327 |
+
outputs=[gen_image_btn, image_output, share_button])
|
| 328 |
+
share_button.click(fn=process_image_for_sharing, inputs=[image_output], outputs=[base64_debug_output])
|
| 329 |
+
base64_debug_output.change(fn=None, inputs=[base64_debug_output], js=js_share_logic)
|
| 330 |
|
| 331 |
if __name__ == "__main__":
|
| 332 |
demo.launch(server_name="0.0.0.0", server_port=7860)
|