Update app.py
Browse files
app.py
CHANGED
|
@@ -1,30 +1,110 @@
|
|
|
|
|
| 1 |
import gradio as gr
|
| 2 |
import os
|
| 3 |
import tempfile
|
| 4 |
from datetime import datetime
|
| 5 |
from PIL import Image
|
|
|
|
| 6 |
|
| 7 |
-
#
|
| 8 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9 |
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 13 |
|
| 14 |
-
#
|
| 15 |
try:
|
| 16 |
-
|
| 17 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 18 |
except ImportError as e:
|
| 19 |
-
print(f"โ
|
| 20 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 21 |
|
| 22 |
-
# ์ปค์คํ
CSS ์คํ์ผ (
|
| 23 |
custom_css = """
|
| 24 |
/* ============================================
|
| 25 |
๋คํฌ๋ชจ๋ ์๋ ๋ณ๊ฒฝ ํ
ํ๋ฆฟ CSS
|
| 26 |
============================================ */
|
| 27 |
-
|
| 28 |
/* 1. CSS ๋ณ์ ์ ์ (๋ผ์ดํธ๋ชจ๋ - ๊ธฐ๋ณธ๊ฐ) */
|
| 29 |
:root {
|
| 30 |
/* ๋ฉ์ธ ์ปฌ๋ฌ */
|
|
@@ -56,7 +136,6 @@ custom_css = """
|
|
| 56 |
/* ๊ธฐํ */
|
| 57 |
--border-radius: 18px;
|
| 58 |
}
|
| 59 |
-
|
| 60 |
/* 2. ๋คํฌ๋ชจ๋ ์์ ๋ณ์ (์๋ ๊ฐ์ง) */
|
| 61 |
@media (prefers-color-scheme: dark) {
|
| 62 |
:root {
|
|
@@ -82,7 +161,6 @@ custom_css = """
|
|
| 82 |
--shadow-light: 0 2px 4px rgba(0, 0, 0, 0.2);
|
| 83 |
}
|
| 84 |
}
|
| 85 |
-
|
| 86 |
/* 3. ์๋ ๋คํฌ๋ชจ๋ ํด๋์ค (Gradio ํ ๊ธ์ฉ) */
|
| 87 |
[data-theme="dark"],
|
| 88 |
.dark,
|
|
@@ -108,7 +186,6 @@ custom_css = """
|
|
| 108 |
--shadow: 0 8px 30px rgba(0, 0, 0, 0.3);
|
| 109 |
--shadow-light: 0 2px 4px rgba(0, 0, 0, 0.2);
|
| 110 |
}
|
| 111 |
-
|
| 112 |
/* 4. ๊ธฐ๋ณธ ์์ ๋คํฌ๋ชจ๋ ์ ์ฉ */
|
| 113 |
body {
|
| 114 |
font-family: 'Pretendard', 'Noto Sans KR', -apple-system, BlinkMacSystemFont, sans-serif;
|
|
@@ -120,7 +197,6 @@ body {
|
|
| 120 |
font-size: 16px;
|
| 121 |
transition: background-color 0.3s ease, color 0.3s ease;
|
| 122 |
}
|
| 123 |
-
|
| 124 |
/* 5. Gradio ์ปจํ
์ด๋ ๊ฐ์ ์ ์ฉ */
|
| 125 |
.gradio-container,
|
| 126 |
.gradio-container *,
|
|
@@ -130,19 +206,16 @@ body {
|
|
| 130 |
background-color: var(--background-color) !important;
|
| 131 |
color: var(--text-color) !important;
|
| 132 |
}
|
| 133 |
-
|
| 134 |
/* ํธํฐ ์จ๊น ์ค์ ์ถ๊ฐ */
|
| 135 |
footer {
|
| 136 |
visibility: hidden;
|
| 137 |
}
|
| 138 |
-
|
| 139 |
.gradio-container {
|
| 140 |
width: 100%;
|
| 141 |
margin: 0 auto;
|
| 142 |
padding: 20px;
|
| 143 |
background-color: var(--background-color);
|
| 144 |
}
|
| 145 |
-
|
| 146 |
/* โโ ๊ทธ๋ฃน ๋ํผ ๋ฐฐ๊ฒฝ ์์ ์ ๊ฑฐ โโ */
|
| 147 |
.custom-section-group,
|
| 148 |
.gr-block.gr-group {
|
|
@@ -156,13 +229,11 @@ footer {
|
|
| 156 |
display: none !important;
|
| 157 |
content: none !important;
|
| 158 |
}
|
| 159 |
-
|
| 160 |
/* ๊ทธ๋ฃน ์ปจํ
์ด๋ ๋ฐฐ๊ฒฝ์ ์์ด๋ณด๋ฆฌ๋ก, ๊ทธ๋ฆผ์ ์ ๊ฑฐ */
|
| 161 |
.custom-section-group {
|
| 162 |
background-color: var(--background-color) !important;
|
| 163 |
box-shadow: none !important;
|
| 164 |
}
|
| 165 |
-
|
| 166 |
/* 6. ์นด๋ ๋ฐ ํจ๋ ์คํ์ผ */
|
| 167 |
.custom-frame,
|
| 168 |
.gr-form,
|
|
@@ -179,7 +250,6 @@ footer {
|
|
| 179 |
box-shadow: var(--shadow) !important;
|
| 180 |
color: var(--text-color) !important;
|
| 181 |
}
|
| 182 |
-
|
| 183 |
/* ์น์
๊ทธ๋ฃน ์คํ์ผ - ํ์ ๋ฐฐ๊ฒฝ ์์ ์ ๊ฑฐ */
|
| 184 |
.custom-section-group {
|
| 185 |
margin-top: 20px;
|
|
@@ -189,7 +259,6 @@ footer {
|
|
| 189 |
background-color: var(--background-color);
|
| 190 |
box-shadow: none !important;
|
| 191 |
}
|
| 192 |
-
|
| 193 |
/* ๋ฒํผ ์คํ์ผ - ๊ธ์ ํฌ๊ธฐ 18px */
|
| 194 |
.custom-button {
|
| 195 |
border-radius: 30px !important;
|
|
@@ -205,7 +274,6 @@ footer {
|
|
| 205 |
transform: translateY(-2px);
|
| 206 |
box-shadow: 0 6px 12px rgba(251, 127, 13, 0.3);
|
| 207 |
}
|
| 208 |
-
|
| 209 |
/* ์ ๋ชฉ ์คํ์ผ (๋ชจ๋ ํญ๋ชฉ๋ช
์ด ๋์ผํ๊ฒ custom-title ํด๋์ค๋ก) */
|
| 210 |
.custom-title {
|
| 211 |
font-size: 28px;
|
|
@@ -215,7 +283,6 @@ footer {
|
|
| 215 |
border-bottom: 2px solid var(--primary-color);
|
| 216 |
padding-bottom: 5px;
|
| 217 |
}
|
| 218 |
-
|
| 219 |
/* ์ด๋ฏธ์ง ์ปจํ
์ด๋ - ํฌ๊ธฐ ๊ณ ์ */
|
| 220 |
.image-container {
|
| 221 |
border-radius: var(--border-radius);
|
|
@@ -224,7 +291,6 @@ footer {
|
|
| 224 |
transition: all 0.3s ease;
|
| 225 |
background-color: var(--card-bg);
|
| 226 |
}
|
| 227 |
-
|
| 228 |
/* ์ด๋ฏธ์ง ์
๋ก๋ ์์ญ ๊ฐ์ */
|
| 229 |
.gradio-container .gr-image {
|
| 230 |
border: 2px dashed var(--border-color) !important;
|
|
@@ -232,12 +298,10 @@ footer {
|
|
| 232 |
background-color: var(--card-bg) !important;
|
| 233 |
transition: all 0.3s ease !important;
|
| 234 |
}
|
| 235 |
-
|
| 236 |
.gradio-container .gr-image:hover {
|
| 237 |
border-color: var(--primary-color) !important;
|
| 238 |
box-shadow: 0 4px 12px rgba(251, 127, 13, 0.15) !important;
|
| 239 |
}
|
| 240 |
-
|
| 241 |
/* ์
๋ก๋ ์์ญ ๋ด๋ถ ํ
์คํธ */
|
| 242 |
.gradio-container .gr-image .upload-container,
|
| 243 |
.gradio-container .gr-image [data-testid="upload-container"] {
|
|
@@ -245,14 +309,12 @@ footer {
|
|
| 245 |
color: var(--text-color) !important;
|
| 246 |
border: none !important;
|
| 247 |
}
|
| 248 |
-
|
| 249 |
/* ์
๋ก๋ ์์ญ ๋๋๊ทธ ์๋ด ํ
์คํธ */
|
| 250 |
.gradio-container .gr-image .upload-container p,
|
| 251 |
.gradio-container .gr-image [data-testid="upload-container"] p {
|
| 252 |
color: var(--text-color) !important;
|
| 253 |
font-size: 14px !important;
|
| 254 |
}
|
| 255 |
-
|
| 256 |
/* ์
๋ก๋ ๋ฒํผ ์คํ์ผ ๊ฐ์ */
|
| 257 |
.gradio-container .gr-image .upload-container button,
|
| 258 |
.gradio-container .gr-image [data-testid="upload-container"] button {
|
|
@@ -265,13 +327,11 @@ footer {
|
|
| 265 |
cursor: pointer !important;
|
| 266 |
transition: all 0.3s ease !important;
|
| 267 |
}
|
| 268 |
-
|
| 269 |
.gradio-container .gr-image .upload-container button:hover,
|
| 270 |
.gradio-container .gr-image [data-testid="upload-container"] button:hover {
|
| 271 |
background-color: var(--secondary-color) !important;
|
| 272 |
transform: translateY(-1px) !important;
|
| 273 |
}
|
| 274 |
-
|
| 275 |
/* ์
๋ก๋ ์์ญ ์์ด์ฝ */
|
| 276 |
.gradio-container .gr-image .upload-container svg,
|
| 277 |
.gradio-container .gr-image [data-testid="upload-container"] svg {
|
|
@@ -279,13 +339,11 @@ footer {
|
|
| 279 |
width: 32px !important;
|
| 280 |
height: 32px !important;
|
| 281 |
}
|
| 282 |
-
|
| 283 |
/* ์ด๋ฏธ์ง๊ฐ ์
๋ก๋๋ ํ ํ์ ์์ญ */
|
| 284 |
.gradio-container .gr-image img {
|
| 285 |
background-color: var(--card-bg) !important;
|
| 286 |
border-radius: var(--border-radius) !important;
|
| 287 |
}
|
| 288 |
-
|
| 289 |
/* ์ด๋ฏธ์ง ์ ๊ฑฐ ๋ฒํผ */
|
| 290 |
.gradio-container .gr-image .image-container button,
|
| 291 |
.gradio-container .gr-image [data-testid="image"] button {
|
|
@@ -301,13 +359,11 @@ footer {
|
|
| 301 |
cursor: pointer !important;
|
| 302 |
transition: all 0.3s ease !important;
|
| 303 |
}
|
| 304 |
-
|
| 305 |
.gradio-container .gr-image .image-container button:hover,
|
| 306 |
.gradio-container .gr-image [data-testid="image"] button:hover {
|
| 307 |
background-color: rgba(255, 255, 255, 1) !important;
|
| 308 |
transform: scale(1.1) !important;
|
| 309 |
}
|
| 310 |
-
|
| 311 |
/* ์
๋ก๋ ์ด๋ฏธ์ง ์ปจํ
์ด๋ (600x600) */
|
| 312 |
.upload-image-container {
|
| 313 |
width: 600px !important;
|
|
@@ -317,7 +373,6 @@ footer {
|
|
| 317 |
max-width: 600px !important;
|
| 318 |
max-height: 600px !important;
|
| 319 |
}
|
| 320 |
-
|
| 321 |
/* ์ถ๋ ฅ ์ด๋ฏธ์ง ์ปจํ
์ด๋ (700x600) */
|
| 322 |
.output-image-container {
|
| 323 |
width: 700px !important;
|
|
@@ -327,17 +382,14 @@ footer {
|
|
| 327 |
max-width: 700px !important;
|
| 328 |
max-height: 600px !important;
|
| 329 |
}
|
| 330 |
-
|
| 331 |
.image-container:hover {
|
| 332 |
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
|
| 333 |
}
|
| 334 |
-
|
| 335 |
.image-container img {
|
| 336 |
width: 100% !important;
|
| 337 |
height: 100% !important;
|
| 338 |
object-fit: contain !important;
|
| 339 |
}
|
| 340 |
-
|
| 341 |
/* Gradio ์
๋ก๋ ์ด๋ฏธ์ง ์ปดํฌ๋ํธ ํฌ๊ธฐ ๊ณ ์ (600x600) */
|
| 342 |
.gradio-container .gr-image.upload-image {
|
| 343 |
width: 600px !important;
|
|
@@ -347,7 +399,6 @@ footer {
|
|
| 347 |
max-width: 600px !important;
|
| 348 |
max-height: 600px !important;
|
| 349 |
}
|
| 350 |
-
|
| 351 |
/* Gradio ์ถ๋ ฅ ์ด๋ฏธ์ง ์ปดํฌ๋ํธ ํฌ๊ธฐ ๊ณ ์ (700x600) */
|
| 352 |
.gradio-container .gr-image.output-image {
|
| 353 |
width: 700px !important;
|
|
@@ -357,7 +408,6 @@ footer {
|
|
| 357 |
max-width: 700px !important;
|
| 358 |
max-height: 600px !important;
|
| 359 |
}
|
| 360 |
-
|
| 361 |
/* ์ด๋ฏธ์ง ์
๋ก๋ ์์ญ ํฌ๊ธฐ ๊ณ ์ */
|
| 362 |
.gradio-container .gr-image.upload-image > div {
|
| 363 |
width: 600px !important;
|
|
@@ -367,7 +417,6 @@ footer {
|
|
| 367 |
max-width: 600px !important;
|
| 368 |
max-height: 600px !important;
|
| 369 |
}
|
| 370 |
-
|
| 371 |
/* ์ด๋ฏธ์ง ์ถ๋ ฅ ์์ญ ํฌ๊ธฐ ๊ณ ์ */
|
| 372 |
.gradio-container .gr-image.output-image > div {
|
| 373 |
width: 700px !important;
|
|
@@ -377,7 +426,6 @@ footer {
|
|
| 377 |
max-width: 700px !important;
|
| 378 |
max-height: 600px !important;
|
| 379 |
}
|
| 380 |
-
|
| 381 |
/* ์ด๋ฏธ์ง ์
๋ก๋ ๋๋๊ทธ ์์ญ ํฌ๊ธฐ ๊ณ ์ */
|
| 382 |
.gradio-container .gr-image.upload-image .image-container,
|
| 383 |
.gradio-container .gr-image.upload-image [data-testid="image"],
|
|
@@ -389,7 +437,6 @@ footer {
|
|
| 389 |
max-width: 600px !important;
|
| 390 |
max-height: 600px !important;
|
| 391 |
}
|
| 392 |
-
|
| 393 |
/* ์ด๋ฏธ์ง ์ถ๋ ฅ ๋๋๊ทธ ์์ญ ํฌ๊ธฐ ๊ณ ์ */
|
| 394 |
.gradio-container .gr-image.output-image .image-container,
|
| 395 |
.gradio-container .gr-image.output-image [data-testid="image"],
|
|
@@ -401,7 +448,6 @@ footer {
|
|
| 401 |
max-width: 700px !important;
|
| 402 |
max-height: 600px !important;
|
| 403 |
}
|
| 404 |
-
|
| 405 |
/* 7. ์
๋ ฅ ํ๋ ์คํ์ผ */
|
| 406 |
.gr-input, .gr-text-input, .gr-sample-inputs,
|
| 407 |
input[type="text"],
|
|
@@ -421,7 +467,6 @@ select,
|
|
| 421 |
box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05) !important;
|
| 422 |
transition: all 0.3s ease !important;
|
| 423 |
}
|
| 424 |
-
|
| 425 |
.gr-input:focus, .gr-text-input:focus,
|
| 426 |
input[type="text"]:focus,
|
| 427 |
input[type="number"]:focus,
|
|
@@ -435,7 +480,6 @@ select:focus,
|
|
| 435 |
outline: none !important;
|
| 436 |
box-shadow: 0 0 0 2px rgba(251, 127, 13, 0.2) !important;
|
| 437 |
}
|
| 438 |
-
|
| 439 |
/* 8. ๋ผ๋ฒจ ๋ฐ ํ
์คํธ ์์ */
|
| 440 |
.gradio-container label,
|
| 441 |
label,
|
|
@@ -448,12 +492,10 @@ p, span, div {
|
|
| 448 |
font-weight: 600 !important;
|
| 449 |
margin-bottom: 8px !important;
|
| 450 |
}
|
| 451 |
-
|
| 452 |
/* ๋๋กญ๋ค์ด ๋ฐ ๋ผ๋์ค ๋ฒํผ ํฐํธ ํฌ๊ธฐ */
|
| 453 |
.gr-radio label, .gr-dropdown label, .gr-checkbox label {
|
| 454 |
font-size: 15px !important;
|
| 455 |
}
|
| 456 |
-
|
| 457 |
/* ๋ผ๋์ค ๋ฒํผ ์ ํ์ง ๋ณผ๋ ์ฒ๋ฆฌ ์ ๊ฑฐ */
|
| 458 |
.gr-radio .gr-radio-option label,
|
| 459 |
.gr-radio input[type="radio"] + label,
|
|
@@ -461,26 +503,22 @@ p, span, div {
|
|
| 461 |
font-weight: normal !important;
|
| 462 |
font-size: 15px !important;
|
| 463 |
}
|
| 464 |
-
|
| 465 |
/* ๋ผ๋์ค ๋ฒํผ ๊ทธ๋ฃน ๋ด ๋ชจ๋ ๋ผ๋ฒจ ์ผ๋ฐ ํฐํธ๋ก ์ค์ */
|
| 466 |
.gr-radio fieldset label {
|
| 467 |
font-weight: normal !important;
|
| 468 |
}
|
| 469 |
-
|
| 470 |
/* ๋งํฌ๋ค์ด ํ
์คํธ ํฌ๊ธฐ ์ฆ๊ฐ */
|
| 471 |
.gradio-container .gr-markdown {
|
| 472 |
font-size: 15px !important;
|
| 473 |
line-height: 1.6 !important;
|
| 474 |
color: var(--text-color) !important;
|
| 475 |
}
|
| 476 |
-
|
| 477 |
/* ํ
์คํธ๋ฐ์ค ๋ด์ฉ ํฐํธ ํฌ๊ธฐ */
|
| 478 |
.gr-textbox textarea, .gr-textbox input {
|
| 479 |
font-size: 15px !important;
|
| 480 |
background-color: var(--input-bg) !important;
|
| 481 |
color: var(--text-color) !important;
|
| 482 |
}
|
| 483 |
-
|
| 484 |
/* ์์ฝ๋์ธ ์ ๋ชฉ ํฐํธ ํฌ๊ธฐ */
|
| 485 |
.gr-accordion summary {
|
| 486 |
font-size: 17px !important;
|
|
@@ -488,44 +526,36 @@ p, span, div {
|
|
| 488 |
background-color: var(--card-bg) !important;
|
| 489 |
color: var(--text-color) !important;
|
| 490 |
}
|
| 491 |
-
|
| 492 |
/* ๋ฉ์ธ ์ปจํ
์ธ ์คํฌ๋กค๋ฐ */
|
| 493 |
::-webkit-scrollbar {
|
| 494 |
width: 8px;
|
| 495 |
height: 8px;
|
| 496 |
}
|
| 497 |
-
|
| 498 |
::-webkit-scrollbar-track {
|
| 499 |
background: var(--card-bg);
|
| 500 |
border-radius: 10px;
|
| 501 |
}
|
| 502 |
-
|
| 503 |
::-webkit-scrollbar-thumb {
|
| 504 |
background: var(--primary-color);
|
| 505 |
border-radius: 10px;
|
| 506 |
}
|
| 507 |
-
|
| 508 |
::-webkit-scrollbar-thumb:hover {
|
| 509 |
background: var(--secondary-color);
|
| 510 |
}
|
| 511 |
-
|
| 512 |
/* ์ ๋๋ฉ์ด์
์คํ์ผ */
|
| 513 |
@keyframes fadeIn {
|
| 514 |
from { opacity: 0; transform: translateY(10px); }
|
| 515 |
to { opacity: 1; transform: translateY(0); }
|
| 516 |
}
|
| 517 |
-
|
| 518 |
.fade-in {
|
| 519 |
animation: fadeIn 0.5s ease-out;
|
| 520 |
}
|
| 521 |
-
|
| 522 |
/* ๋ฐ์ํ */
|
| 523 |
@media (max-width: 768px) {
|
| 524 |
.button-grid {
|
| 525 |
grid-template-columns: repeat(2, 1fr);
|
| 526 |
}
|
| 527 |
}
|
| 528 |
-
|
| 529 |
/* ์น์
์ ๋ชฉ ์คํ์ผ */
|
| 530 |
.section-title {
|
| 531 |
display: flex;
|
|
@@ -538,7 +568,6 @@ p, span, div {
|
|
| 538 |
border-bottom: 2px solid var(--primary-color);
|
| 539 |
font-family: 'Pretendard', 'Noto Sans KR', -apple-system, BlinkMacSystemFont, sans-serif;
|
| 540 |
}
|
| 541 |
-
|
| 542 |
.section-title img {
|
| 543 |
margin-right: 12px;
|
| 544 |
width: 28px;
|
|
@@ -546,21 +575,18 @@ p, span, div {
|
|
| 546 |
/* ๋คํฌ๋ชจ๋์์ ์์ด์ฝ ํํฐ ์ ์ฉ */
|
| 547 |
filter: brightness(0) saturate(100%) invert(27%) sepia(51%) saturate(2878%) hue-rotate(346deg) brightness(104%) contrast(97%);
|
| 548 |
}
|
| 549 |
-
|
| 550 |
/* ๋ผ์ดํธ๋ชจ๋์์๋ ์๋ ์์ด๏ฟฝ๏ฟฝ๏ฟฝ ์์ ์ ์ง */
|
| 551 |
@media (prefers-color-scheme: light) {
|
| 552 |
.section-title img {
|
| 553 |
filter: none;
|
| 554 |
}
|
| 555 |
}
|
| 556 |
-
|
| 557 |
/* ์๋ ๋คํฌ๋ชจ๋ ํด๋์ค์์๋ ์์ด์ฝ ์์ ์ ์ฉ */
|
| 558 |
[data-theme="dark"] .section-title img,
|
| 559 |
.dark .section-title img,
|
| 560 |
.gr-theme-dark .section-title img {
|
| 561 |
filter: brightness(0) saturate(100%) invert(27%) sepia(51%) saturate(2878%) hue-rotate(346deg) brightness(104%) contrast(97%);
|
| 562 |
}
|
| 563 |
-
|
| 564 |
/* 10. ์์ฝ๋์ธ ๋ฐ ๋๋กญ๋ค์ด - ์๋์ค์ ์์ญ ํ์ ๋ฐฐ๊ฒฝ ์ ๊ฑฐ */
|
| 565 |
details,
|
| 566 |
.gr-accordion,
|
|
@@ -571,7 +597,6 @@ details,
|
|
| 571 |
border-radius: var(--border-radius) !important;
|
| 572 |
margin: 10px 0 !important;
|
| 573 |
}
|
| 574 |
-
|
| 575 |
details summary,
|
| 576 |
.gr-accordion summary,
|
| 577 |
.gr-accordion details summary {
|
|
@@ -584,20 +609,17 @@ details summary,
|
|
| 584 |
font-weight: 600 !important;
|
| 585 |
transition: all 0.3s ease !important;
|
| 586 |
}
|
| 587 |
-
|
| 588 |
details summary:hover,
|
| 589 |
.gr-accordion summary:hover,
|
| 590 |
.gr-accordion details summary:hover {
|
| 591 |
background-color: var(--table-hover-bg) !important;
|
| 592 |
}
|
| 593 |
-
|
| 594 |
/* ์์ฝ๋์ธ ๋ด๋ถ ์ฝํ
์ธ */
|
| 595 |
details[open],
|
| 596 |
.gr-accordion[open],
|
| 597 |
.gr-accordion details[open] {
|
| 598 |
background-color: var(--background-color) !important;
|
| 599 |
}
|
| 600 |
-
|
| 601 |
details[open] > *:not(summary),
|
| 602 |
.gr-accordion[open] > *:not(summary),
|
| 603 |
.gr-accordion details[open] > *:not(summary) {
|
|
@@ -606,7 +628,6 @@ details[open] > *:not(summary),
|
|
| 606 |
padding: 16px !important;
|
| 607 |
border-top: 1px solid var(--border-color) !important;
|
| 608 |
}
|
| 609 |
-
|
| 610 |
/* ๊ทธ๋ฃน ๋ด๋ถ ์คํ์ผ - ์๋์ค์ ๋ด๋ถ ๊ทธ๋ฃน๋ค */
|
| 611 |
.gr-group,
|
| 612 |
details .gr-group,
|
|
@@ -617,7 +638,6 @@ details .gr-group,
|
|
| 617 |
margin: 8px 0 !important;
|
| 618 |
border-radius: var(--border-radius) !important;
|
| 619 |
}
|
| 620 |
-
|
| 621 |
/* ๊ทธ๋ฃน ๋ด๋ถ ์ ๋ชฉ */
|
| 622 |
.gr-group .gr-markdown h3,
|
| 623 |
.gr-group h3 {
|
|
@@ -628,7 +648,6 @@ details .gr-group,
|
|
| 628 |
padding-bottom: 6px !important;
|
| 629 |
border-bottom: 1px solid var(--border-color) !important;
|
| 630 |
}
|
| 631 |
-
|
| 632 |
/* 11. ์ถ๊ฐ Gradio ์ปดํฌ๋ํธ๋ค */
|
| 633 |
.gr-block,
|
| 634 |
.gr-group,
|
|
@@ -637,23 +656,12 @@ details .gr-group,
|
|
| 637 |
background-color: var(--background-color) !important;
|
| 638 |
color: var(--text-color) !important;
|
| 639 |
}
|
| 640 |
-
|
| 641 |
/* 12. ๋ฒํผ์ ๊ธฐ์กด ์คํ์ผ ์ ์ง (primary-color ์ฌ์ฉ) */
|
| 642 |
button:not([class*="custom"]):not([class*="primary"]):not([class*="secondary"]) {
|
| 643 |
background-color: var(--card-bg) !important;
|
| 644 |
color: var(--text-color) !important;
|
| 645 |
border-color: var(--border-color) !important;
|
| 646 |
}
|
| 647 |
-
|
| 648 |
-
/* 13. ์ฝ๋ ๋ธ๋ก ๋ฐ pre ํ๊ทธ */
|
| 649 |
-
code,
|
| 650 |
-
pre,
|
| 651 |
-
.code-block {
|
| 652 |
-
background-color: var(--table-even-bg) !important;
|
| 653 |
-
color: var(--text-color) !important;
|
| 654 |
-
border-color: var(--border-color) !important;
|
| 655 |
-
}
|
| 656 |
-
|
| 657 |
/* 14. ์ ํ ์ ๋๋ฉ์ด์
*/
|
| 658 |
* {
|
| 659 |
transition: background-color 0.3s ease,
|
|
@@ -719,22 +727,13 @@ def prepare_download_file(image, keyword):
|
|
| 719 |
image_to_save.save(file_path, 'JPEG', quality=95)
|
| 720 |
|
| 721 |
print(f"โ
๋ค์ด๋ก๋ ํ์ผ ์ค๋น: {filename}")
|
|
|
|
| 722 |
return file_path
|
| 723 |
|
| 724 |
except Exception as e:
|
| 725 |
print(f"โ ๋ค์ด๋ก๋ ํ์ผ ์ค๋น ์คํจ: {e}")
|
| 726 |
return None
|
| 727 |
|
| 728 |
-
# ๐ฏ ํต์ฌ: ํด๋ผ์ด์ธํธ ์ฐ๊ฒฐ ํจ์ (๋ก๊ทธ ์ต์ํ)
|
| 729 |
-
def get_client():
|
| 730 |
-
"""ํ๊ฒฝ๋ณ์ ๊ธฐ๋ฐ ํด๋ผ์ด์ธํธ ์ฐ๊ฒฐ"""
|
| 731 |
-
try:
|
| 732 |
-
client = Client(API_ENDPOINT)
|
| 733 |
-
return client
|
| 734 |
-
except Exception as e:
|
| 735 |
-
print(f"โ ์ฐ๊ฒฐ ์คํจ: {str(e)[:50]}...")
|
| 736 |
-
return None
|
| 737 |
-
|
| 738 |
def main():
|
| 739 |
with gr.Blocks(
|
| 740 |
css=custom_css,
|
|
@@ -927,116 +926,194 @@ def main():
|
|
| 927 |
interactive=False
|
| 928 |
)
|
| 929 |
|
| 930 |
-
#
|
| 931 |
-
|
| 932 |
-
def update_copy_type_description(selected_type):
|
| 933 |
-
"""์๋ณธ๊ณผ ๋์ผํ ์นดํผ ํ์
์ ํ์ ์ค๋ช
์
๋ฐ์ดํธ"""
|
| 934 |
-
try:
|
| 935 |
-
client = get_client()
|
| 936 |
-
if not client:
|
| 937 |
-
return "โ ์๋ฒ ์ฐ๊ฒฐ ์คํจ"
|
| 938 |
-
|
| 939 |
-
result = client.predict(
|
| 940 |
-
selected_type=selected_type,
|
| 941 |
-
api_name="/update_copy_type_description"
|
| 942 |
-
)
|
| 943 |
-
return result
|
| 944 |
-
except Exception as e:
|
| 945 |
-
print(f"โ ์นดํผ ํ์
์ค๋ช
์
๋ฐ์ดํธ ์คํจ: {str(e)[:50]}...")
|
| 946 |
-
return f"โ ์ค๋ฅ: ์ค๋ช
์
๋ฐ์ดํธ ์คํจ"
|
| 947 |
|
| 948 |
def handle_copy_generation(keyword, selected_type):
|
| 949 |
-
"""
|
| 950 |
-
|
| 951 |
-
|
| 952 |
-
|
| 953 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 954 |
|
| 955 |
-
|
| 956 |
-
|
| 957 |
-
|
| 958 |
-
api_name="/handle_copy_generation"
|
| 959 |
-
)
|
| 960 |
|
| 961 |
-
#
|
| 962 |
-
|
| 963 |
-
|
| 964 |
-
|
| 965 |
-
|
| 966 |
-
|
| 967 |
-
|
|
|
|
| 968 |
|
| 969 |
-
|
| 970 |
-
|
| 971 |
-
|
| 972 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 973 |
|
| 974 |
-
def handle_copy_selection(
|
| 975 |
-
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 976 |
try:
|
| 977 |
-
|
| 978 |
-
|
| 979 |
-
|
| 980 |
-
|
| 981 |
-
|
| 982 |
-
|
| 983 |
-
|
| 984 |
-
|
| 985 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 986 |
|
| 987 |
-
|
| 988 |
-
return result
|
| 989 |
|
| 990 |
except Exception as e:
|
| 991 |
-
print(f"โ
|
| 992 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 993 |
|
| 994 |
def handle_image_generation(input_image, main_text, sub_text, color_mode,
|
| 995 |
main_font_choice, sub_font_choice, manual_bg_color, manual_main_text_color,
|
| 996 |
manual_sub_text_color, manual_main_font_size, manual_sub_font_size,
|
| 997 |
top_bottom_margin, text_gap, current_keyword):
|
| 998 |
-
"""
|
| 999 |
-
|
| 1000 |
-
|
| 1001 |
-
|
| 1002 |
-
|
| 1003 |
-
|
| 1004 |
-
|
| 1005 |
-
|
| 1006 |
-
|
| 1007 |
-
|
| 1008 |
-
|
| 1009 |
-
|
| 1010 |
-
|
| 1011 |
-
|
| 1012 |
-
|
| 1013 |
-
|
| 1014 |
-
|
| 1015 |
-
|
| 1016 |
-
|
| 1017 |
-
|
| 1018 |
-
|
| 1019 |
-
|
| 1020 |
-
|
| 1021 |
-
|
| 1022 |
-
|
| 1023 |
-
|
| 1024 |
-
|
| 1025 |
-
api_name="/handle_image_generation"
|
| 1026 |
-
)
|
| 1027 |
-
|
| 1028 |
-
# ์๋ณธ๊ณผ ๋์ผํ ํํ ๋ฐํ (9๊ฐ ์์)
|
| 1029 |
-
# [0] ์ด๋ฏธ์ง, [1] ์์๋ชจ๋, [2] ๋ฐฐ๊ฒฝ์, [3] ๋ฉ์ธํ
์คํธ์, [4] ์๋ธํ
์คํธ์,
|
| 1030 |
-
# [5] ๋ฉ์ธํฐํธํฌ๊ธฐ, [6] ์๋ธํฐํธํฌ๊ธฐ, [7] ๋ค์ด๋ก๋ํ์ผ, [8] ์ฌ๋ฐฑ์ ๋ณด
|
| 1031 |
-
return result
|
| 1032 |
-
|
| 1033 |
-
except Exception as e:
|
| 1034 |
-
print(f"โ ์ด๋ฏธ์ง ์์ฑ ์คํจ: {str(e)[:50]}...")
|
| 1035 |
-
return (None, color_mode, manual_bg_color, manual_main_text_color,
|
| 1036 |
-
manual_sub_text_color, manual_main_font_size, manual_sub_font_size,
|
| 1037 |
-
None, "โ ์ด๋ฏธ์ง ์์ฑ ์ค ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค")
|
| 1038 |
|
| 1039 |
-
#
|
| 1040 |
copy_type_selection.change(
|
| 1041 |
fn=update_copy_type_description,
|
| 1042 |
inputs=[copy_type_selection],
|
|
|
|
| 1 |
+
#app.py
|
| 2 |
import gradio as gr
|
| 3 |
import os
|
| 4 |
import tempfile
|
| 5 |
from datetime import datetime
|
| 6 |
from PIL import Image
|
| 7 |
+
import random
|
| 8 |
|
| 9 |
+
# ๐ ํ๊น
ํ์ด์ค Secrets์์ API ํค๋ค ๊ฐ์ ธ์์ ๋๋ค ์ ํ
|
| 10 |
+
def get_random_gemini_api_key():
|
| 11 |
+
"""ํ๊น
ํ์ด์ค Secrets์์ API ํค ๋ฆฌ์คํธ๋ฅผ ๊ฐ์ ธ์ ๋๋ค ์ ํ (๋๋ฒ๊น
๊ฐํ)"""
|
| 12 |
+
try:
|
| 13 |
+
print("๐ API ํค ๋ก๋ฉ ์์...")
|
| 14 |
+
|
| 15 |
+
# Secrets์์ API ํค ๋ฆฌ์คํธ ๊ฐ์ ธ์ค๊ธฐ (์ฝค๋ง๋ก ๊ตฌ๋ถ๋ ๋ฌธ์์ด)
|
| 16 |
+
api_keys_string = os.environ.get('GEMINI_API_KEYS')
|
| 17 |
+
print(f"๐ GEMINI_API_KEYS ์๋ณธ: {api_keys_string[:50] if api_keys_string else 'None'}...")
|
| 18 |
+
|
| 19 |
+
if api_keys_string:
|
| 20 |
+
# ์ฝค๋ง๋ก ๋ถ๋ฆฌํ๊ณ ๊ณต๋ฐฑ ์ ๊ฑฐ
|
| 21 |
+
api_keys = [key.strip() for key in api_keys_string.split(',') if key.strip()]
|
| 22 |
+
print(f"๐ ํ์ฑ๋ ํค ๊ฐ์: {len(api_keys)}")
|
| 23 |
+
|
| 24 |
+
for i, key in enumerate(api_keys):
|
| 25 |
+
print(f" ํค {i+1}: {key[:8]}***{key[-4:] if len(key) > 12 else '***'} (๊ธธ์ด: {len(key)})")
|
| 26 |
+
|
| 27 |
+
if api_keys:
|
| 28 |
+
# ๋๋คํ๊ฒ ํ๋ ์ ํ
|
| 29 |
+
selected_key = random.choice(api_keys)
|
| 30 |
+
print(f"๐ฒ ๋๋ค API ํค ์ ํ: {selected_key[:8]}***{selected_key[-4:]}")
|
| 31 |
+
return selected_key
|
| 32 |
+
else:
|
| 33 |
+
print("โ ํ์ฑ๋ ํค๊ฐ ์์")
|
| 34 |
+
else:
|
| 35 |
+
print("โ GEMINI_API_KEYS ํ๊ฒฝ๋ณ์๊ฐ ์์")
|
| 36 |
+
|
| 37 |
+
# ํด๋ฐฑ: ๋จ์ผ ํค
|
| 38 |
+
fallback_key = os.environ.get('GEMINI_API_KEY')
|
| 39 |
+
if fallback_key:
|
| 40 |
+
print(f"๐ ํด๋ฐฑ API ํค ์ฌ์ฉ: {fallback_key[:8]}***{fallback_key[-4:]}")
|
| 41 |
+
return fallback_key
|
| 42 |
+
|
| 43 |
+
print("โ ๋ชจ๋ API ํค๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค")
|
| 44 |
+
return None
|
| 45 |
+
|
| 46 |
+
except Exception as e:
|
| 47 |
+
print(f"โ API ํค ์ ํ ์คํจ: {e}")
|
| 48 |
+
return os.environ.get('GEMINI_API_KEY')
|
| 49 |
|
| 50 |
+
# ํ๊น
ํ์ด์ค Secrets์์ ๋ชจ๋ ์ฝ๋ ๋ถ๋ฌ์์ ์คํ
|
| 51 |
+
def load_module_from_env(env_var_name):
|
| 52 |
+
"""ํ๊ฒฝ๋ณ์์์ ์ฝ๋๋ฅผ ๋ถ๋ฌ์์ ๋ชจ๋๋ก ์คํ"""
|
| 53 |
+
try:
|
| 54 |
+
code = os.environ.get(env_var_name)
|
| 55 |
+
if not code:
|
| 56 |
+
raise ImportError(f"Environment variable '{env_var_name}' not found")
|
| 57 |
+
|
| 58 |
+
# ๋ชจ๋ namespace ์์ฑํ๊ณ ์ฝ๋ ์คํ
|
| 59 |
+
module_globals = {}
|
| 60 |
+
exec(code, module_globals)
|
| 61 |
+
|
| 62 |
+
print(f"โ
{env_var_name} ๋ชจ๋ ๋ก๋ ์ฑ๊ณต")
|
| 63 |
+
return module_globals
|
| 64 |
+
|
| 65 |
+
except Exception as e:
|
| 66 |
+
print(f"โ {env_var_name} ๋ชจ๋ ๋ก๋ ์คํจ: {e}")
|
| 67 |
+
return None
|
| 68 |
|
| 69 |
+
# ์ด๋ฏธ์ง ์ฒ๋ฆฌ ๋ชจ๋ ์ํฌํธ
|
| 70 |
try:
|
| 71 |
+
image_processor_module = load_module_from_env('IMAGE_PROCESSOR_CODE')
|
| 72 |
+
if image_processor_module:
|
| 73 |
+
create_uhp_image = image_processor_module['create_uhp_image']
|
| 74 |
+
save_image_to_downloads = image_processor_module['save_image_to_downloads']
|
| 75 |
+
print("โ
image_processor ๋ชจ๋ ์ํฌํธ ์ฑ๊ณต")
|
| 76 |
+
else:
|
| 77 |
+
raise ImportError("IMAGE_PROCESSOR_CODE not found")
|
| 78 |
except ImportError as e:
|
| 79 |
+
print(f"โ image_processor ์ํฌํธ ์ค๋ฅ: {e}")
|
| 80 |
+
|
| 81 |
+
def create_uhp_image(*args, **kwargs):
|
| 82 |
+
return None, "์ถ์ฒ๋ฐฐ๊ฒฝ", "#FFFFFF", "#000000", "#000000", 100, 55, {}
|
| 83 |
+
|
| 84 |
+
def save_image_to_downloads(*args, **kwargs):
|
| 85 |
+
return None, "image_processor ๋ชจ๋์ ์ฐพ์ ์ ์์ต๋๋ค."
|
| 86 |
+
|
| 87 |
+
# ์นดํผ ์์ฑ ๋ชจ๋ ์ํฌํธ
|
| 88 |
+
try:
|
| 89 |
+
copy_generator_module = load_module_from_env('COPY_GENERATOR_CODE')
|
| 90 |
+
if copy_generator_module:
|
| 91 |
+
generate_copy_suggestions = copy_generator_module['generate_copy_suggestions']
|
| 92 |
+
print("โ
copy_generator ๋ชจ๋ ์ํฌํธ ์ฑ๊ณต")
|
| 93 |
+
else:
|
| 94 |
+
raise ImportError("COPY_GENERATOR_CODE not found")
|
| 95 |
+
except ImportError as e:
|
| 96 |
+
print(f"โ ๏ธ copy_generator ์ํฌํธ ์ค๋ฅ: {e}")
|
| 97 |
+
|
| 98 |
+
def generate_copy_suggestions(keyword, api_key, selected_type):
|
| 99 |
+
return {
|
| 100 |
+
"error": "copy_generator ๋ชจ๋์ ์ฐพ์ ์ ์์ต๋๋ค. ์นดํผ ์์ฑ ๊ธฐ๋ฅ์ด ๋นํ์ฑํ๋ฉ๋๋ค."
|
| 101 |
+
}, ""
|
| 102 |
|
| 103 |
+
# ์ปค์คํ
CSS ์คํ์ผ (๋คํฌ๋ชจ๋ ์ ์ฉ ๋ฒ์ )
|
| 104 |
custom_css = """
|
| 105 |
/* ============================================
|
| 106 |
๋คํฌ๋ชจ๋ ์๋ ๋ณ๊ฒฝ ํ
ํ๋ฆฟ CSS
|
| 107 |
============================================ */
|
|
|
|
| 108 |
/* 1. CSS ๋ณ์ ์ ์ (๋ผ์ดํธ๋ชจ๋ - ๊ธฐ๋ณธ๊ฐ) */
|
| 109 |
:root {
|
| 110 |
/* ๋ฉ์ธ ์ปฌ๋ฌ */
|
|
|
|
| 136 |
/* ๊ธฐํ */
|
| 137 |
--border-radius: 18px;
|
| 138 |
}
|
|
|
|
| 139 |
/* 2. ๋คํฌ๋ชจ๋ ์์ ๋ณ์ (์๋ ๊ฐ์ง) */
|
| 140 |
@media (prefers-color-scheme: dark) {
|
| 141 |
:root {
|
|
|
|
| 161 |
--shadow-light: 0 2px 4px rgba(0, 0, 0, 0.2);
|
| 162 |
}
|
| 163 |
}
|
|
|
|
| 164 |
/* 3. ์๋ ๋คํฌ๋ชจ๋ ํด๋์ค (Gradio ํ ๊ธ์ฉ) */
|
| 165 |
[data-theme="dark"],
|
| 166 |
.dark,
|
|
|
|
| 186 |
--shadow: 0 8px 30px rgba(0, 0, 0, 0.3);
|
| 187 |
--shadow-light: 0 2px 4px rgba(0, 0, 0, 0.2);
|
| 188 |
}
|
|
|
|
| 189 |
/* 4. ๊ธฐ๋ณธ ์์ ๋คํฌ๋ชจ๋ ์ ์ฉ */
|
| 190 |
body {
|
| 191 |
font-family: 'Pretendard', 'Noto Sans KR', -apple-system, BlinkMacSystemFont, sans-serif;
|
|
|
|
| 197 |
font-size: 16px;
|
| 198 |
transition: background-color 0.3s ease, color 0.3s ease;
|
| 199 |
}
|
|
|
|
| 200 |
/* 5. Gradio ์ปจํ
์ด๋ ๊ฐ์ ์ ์ฉ */
|
| 201 |
.gradio-container,
|
| 202 |
.gradio-container *,
|
|
|
|
| 206 |
background-color: var(--background-color) !important;
|
| 207 |
color: var(--text-color) !important;
|
| 208 |
}
|
|
|
|
| 209 |
/* ํธํฐ ์จ๊น ์ค์ ์ถ๊ฐ */
|
| 210 |
footer {
|
| 211 |
visibility: hidden;
|
| 212 |
}
|
|
|
|
| 213 |
.gradio-container {
|
| 214 |
width: 100%;
|
| 215 |
margin: 0 auto;
|
| 216 |
padding: 20px;
|
| 217 |
background-color: var(--background-color);
|
| 218 |
}
|
|
|
|
| 219 |
/* โโ ๊ทธ๋ฃน ๋ํผ ๋ฐฐ๊ฒฝ ์์ ์ ๊ฑฐ โโ */
|
| 220 |
.custom-section-group,
|
| 221 |
.gr-block.gr-group {
|
|
|
|
| 229 |
display: none !important;
|
| 230 |
content: none !important;
|
| 231 |
}
|
|
|
|
| 232 |
/* ๊ทธ๋ฃน ์ปจํ
์ด๋ ๋ฐฐ๊ฒฝ์ ์์ด๋ณด๋ฆฌ๋ก, ๊ทธ๋ฆผ์ ์ ๊ฑฐ */
|
| 233 |
.custom-section-group {
|
| 234 |
background-color: var(--background-color) !important;
|
| 235 |
box-shadow: none !important;
|
| 236 |
}
|
|
|
|
| 237 |
/* 6. ์นด๋ ๋ฐ ํจ๋ ์คํ์ผ */
|
| 238 |
.custom-frame,
|
| 239 |
.gr-form,
|
|
|
|
| 250 |
box-shadow: var(--shadow) !important;
|
| 251 |
color: var(--text-color) !important;
|
| 252 |
}
|
|
|
|
| 253 |
/* ์น์
๊ทธ๋ฃน ์คํ์ผ - ํ์ ๋ฐฐ๊ฒฝ ์์ ์ ๊ฑฐ */
|
| 254 |
.custom-section-group {
|
| 255 |
margin-top: 20px;
|
|
|
|
| 259 |
background-color: var(--background-color);
|
| 260 |
box-shadow: none !important;
|
| 261 |
}
|
|
|
|
| 262 |
/* ๋ฒํผ ์คํ์ผ - ๊ธ์ ํฌ๊ธฐ 18px */
|
| 263 |
.custom-button {
|
| 264 |
border-radius: 30px !important;
|
|
|
|
| 274 |
transform: translateY(-2px);
|
| 275 |
box-shadow: 0 6px 12px rgba(251, 127, 13, 0.3);
|
| 276 |
}
|
|
|
|
| 277 |
/* ์ ๋ชฉ ์คํ์ผ (๋ชจ๋ ํญ๋ชฉ๋ช
์ด ๋์ผํ๊ฒ custom-title ํด๋์ค๋ก) */
|
| 278 |
.custom-title {
|
| 279 |
font-size: 28px;
|
|
|
|
| 283 |
border-bottom: 2px solid var(--primary-color);
|
| 284 |
padding-bottom: 5px;
|
| 285 |
}
|
|
|
|
| 286 |
/* ์ด๋ฏธ์ง ์ปจํ
์ด๋ - ํฌ๊ธฐ ๊ณ ์ */
|
| 287 |
.image-container {
|
| 288 |
border-radius: var(--border-radius);
|
|
|
|
| 291 |
transition: all 0.3s ease;
|
| 292 |
background-color: var(--card-bg);
|
| 293 |
}
|
|
|
|
| 294 |
/* ์ด๋ฏธ์ง ์
๋ก๋ ์์ญ ๊ฐ์ */
|
| 295 |
.gradio-container .gr-image {
|
| 296 |
border: 2px dashed var(--border-color) !important;
|
|
|
|
| 298 |
background-color: var(--card-bg) !important;
|
| 299 |
transition: all 0.3s ease !important;
|
| 300 |
}
|
|
|
|
| 301 |
.gradio-container .gr-image:hover {
|
| 302 |
border-color: var(--primary-color) !important;
|
| 303 |
box-shadow: 0 4px 12px rgba(251, 127, 13, 0.15) !important;
|
| 304 |
}
|
|
|
|
| 305 |
/* ์
๋ก๋ ์์ญ ๋ด๋ถ ํ
์คํธ */
|
| 306 |
.gradio-container .gr-image .upload-container,
|
| 307 |
.gradio-container .gr-image [data-testid="upload-container"] {
|
|
|
|
| 309 |
color: var(--text-color) !important;
|
| 310 |
border: none !important;
|
| 311 |
}
|
|
|
|
| 312 |
/* ์
๋ก๋ ์์ญ ๋๋๊ทธ ์๋ด ํ
์คํธ */
|
| 313 |
.gradio-container .gr-image .upload-container p,
|
| 314 |
.gradio-container .gr-image [data-testid="upload-container"] p {
|
| 315 |
color: var(--text-color) !important;
|
| 316 |
font-size: 14px !important;
|
| 317 |
}
|
|
|
|
| 318 |
/* ์
๋ก๋ ๋ฒํผ ์คํ์ผ ๊ฐ์ */
|
| 319 |
.gradio-container .gr-image .upload-container button,
|
| 320 |
.gradio-container .gr-image [data-testid="upload-container"] button {
|
|
|
|
| 327 |
cursor: pointer !important;
|
| 328 |
transition: all 0.3s ease !important;
|
| 329 |
}
|
|
|
|
| 330 |
.gradio-container .gr-image .upload-container button:hover,
|
| 331 |
.gradio-container .gr-image [data-testid="upload-container"] button:hover {
|
| 332 |
background-color: var(--secondary-color) !important;
|
| 333 |
transform: translateY(-1px) !important;
|
| 334 |
}
|
|
|
|
| 335 |
/* ์
๋ก๋ ์์ญ ์์ด์ฝ */
|
| 336 |
.gradio-container .gr-image .upload-container svg,
|
| 337 |
.gradio-container .gr-image [data-testid="upload-container"] svg {
|
|
|
|
| 339 |
width: 32px !important;
|
| 340 |
height: 32px !important;
|
| 341 |
}
|
|
|
|
| 342 |
/* ์ด๋ฏธ์ง๊ฐ ์
๋ก๋๋ ํ ํ์ ์์ญ */
|
| 343 |
.gradio-container .gr-image img {
|
| 344 |
background-color: var(--card-bg) !important;
|
| 345 |
border-radius: var(--border-radius) !important;
|
| 346 |
}
|
|
|
|
| 347 |
/* ์ด๋ฏธ์ง ์ ๊ฑฐ ๋ฒํผ */
|
| 348 |
.gradio-container .gr-image .image-container button,
|
| 349 |
.gradio-container .gr-image [data-testid="image"] button {
|
|
|
|
| 359 |
cursor: pointer !important;
|
| 360 |
transition: all 0.3s ease !important;
|
| 361 |
}
|
|
|
|
| 362 |
.gradio-container .gr-image .image-container button:hover,
|
| 363 |
.gradio-container .gr-image [data-testid="image"] button:hover {
|
| 364 |
background-color: rgba(255, 255, 255, 1) !important;
|
| 365 |
transform: scale(1.1) !important;
|
| 366 |
}
|
|
|
|
| 367 |
/* ์
๋ก๋ ์ด๋ฏธ์ง ์ปจํ
์ด๋ (600x600) */
|
| 368 |
.upload-image-container {
|
| 369 |
width: 600px !important;
|
|
|
|
| 373 |
max-width: 600px !important;
|
| 374 |
max-height: 600px !important;
|
| 375 |
}
|
|
|
|
| 376 |
/* ์ถ๋ ฅ ์ด๋ฏธ์ง ์ปจํ
์ด๋ (700x600) */
|
| 377 |
.output-image-container {
|
| 378 |
width: 700px !important;
|
|
|
|
| 382 |
max-width: 700px !important;
|
| 383 |
max-height: 600px !important;
|
| 384 |
}
|
|
|
|
| 385 |
.image-container:hover {
|
| 386 |
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
|
| 387 |
}
|
|
|
|
| 388 |
.image-container img {
|
| 389 |
width: 100% !important;
|
| 390 |
height: 100% !important;
|
| 391 |
object-fit: contain !important;
|
| 392 |
}
|
|
|
|
| 393 |
/* Gradio ์
๋ก๋ ์ด๋ฏธ์ง ์ปดํฌ๋ํธ ํฌ๊ธฐ ๊ณ ์ (600x600) */
|
| 394 |
.gradio-container .gr-image.upload-image {
|
| 395 |
width: 600px !important;
|
|
|
|
| 399 |
max-width: 600px !important;
|
| 400 |
max-height: 600px !important;
|
| 401 |
}
|
|
|
|
| 402 |
/* Gradio ์ถ๋ ฅ ์ด๋ฏธ์ง ์ปดํฌ๋ํธ ํฌ๊ธฐ ๊ณ ์ (700x600) */
|
| 403 |
.gradio-container .gr-image.output-image {
|
| 404 |
width: 700px !important;
|
|
|
|
| 408 |
max-width: 700px !important;
|
| 409 |
max-height: 600px !important;
|
| 410 |
}
|
|
|
|
| 411 |
/* ์ด๋ฏธ์ง ์
๋ก๋ ์์ญ ํฌ๊ธฐ ๊ณ ์ */
|
| 412 |
.gradio-container .gr-image.upload-image > div {
|
| 413 |
width: 600px !important;
|
|
|
|
| 417 |
max-width: 600px !important;
|
| 418 |
max-height: 600px !important;
|
| 419 |
}
|
|
|
|
| 420 |
/* ์ด๋ฏธ์ง ์ถ๋ ฅ ์์ญ ํฌ๊ธฐ ๊ณ ์ */
|
| 421 |
.gradio-container .gr-image.output-image > div {
|
| 422 |
width: 700px !important;
|
|
|
|
| 426 |
max-width: 700px !important;
|
| 427 |
max-height: 600px !important;
|
| 428 |
}
|
|
|
|
| 429 |
/* ์ด๋ฏธ์ง ์
๋ก๋ ๋๋๊ทธ ์์ญ ํฌ๊ธฐ ๊ณ ์ */
|
| 430 |
.gradio-container .gr-image.upload-image .image-container,
|
| 431 |
.gradio-container .gr-image.upload-image [data-testid="image"],
|
|
|
|
| 437 |
max-width: 600px !important;
|
| 438 |
max-height: 600px !important;
|
| 439 |
}
|
|
|
|
| 440 |
/* ์ด๋ฏธ์ง ์ถ๋ ฅ ๋๋๊ทธ ์์ญ ํฌ๊ธฐ ๊ณ ์ */
|
| 441 |
.gradio-container .gr-image.output-image .image-container,
|
| 442 |
.gradio-container .gr-image.output-image [data-testid="image"],
|
|
|
|
| 448 |
max-width: 700px !important;
|
| 449 |
max-height: 600px !important;
|
| 450 |
}
|
|
|
|
| 451 |
/* 7. ์
๋ ฅ ํ๋ ์คํ์ผ */
|
| 452 |
.gr-input, .gr-text-input, .gr-sample-inputs,
|
| 453 |
input[type="text"],
|
|
|
|
| 467 |
box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05) !important;
|
| 468 |
transition: all 0.3s ease !important;
|
| 469 |
}
|
|
|
|
| 470 |
.gr-input:focus, .gr-text-input:focus,
|
| 471 |
input[type="text"]:focus,
|
| 472 |
input[type="number"]:focus,
|
|
|
|
| 480 |
outline: none !important;
|
| 481 |
box-shadow: 0 0 0 2px rgba(251, 127, 13, 0.2) !important;
|
| 482 |
}
|
|
|
|
| 483 |
/* 8. ๋ผ๋ฒจ ๋ฐ ํ
์คํธ ์์ */
|
| 484 |
.gradio-container label,
|
| 485 |
label,
|
|
|
|
| 492 |
font-weight: 600 !important;
|
| 493 |
margin-bottom: 8px !important;
|
| 494 |
}
|
|
|
|
| 495 |
/* ๋๋กญ๋ค์ด ๋ฐ ๋ผ๋์ค ๋ฒํผ ํฐํธ ํฌ๊ธฐ */
|
| 496 |
.gr-radio label, .gr-dropdown label, .gr-checkbox label {
|
| 497 |
font-size: 15px !important;
|
| 498 |
}
|
|
|
|
| 499 |
/* ๋ผ๋์ค ๋ฒํผ ์ ํ์ง ๋ณผ๋ ์ฒ๋ฆฌ ์ ๊ฑฐ */
|
| 500 |
.gr-radio .gr-radio-option label,
|
| 501 |
.gr-radio input[type="radio"] + label,
|
|
|
|
| 503 |
font-weight: normal !important;
|
| 504 |
font-size: 15px !important;
|
| 505 |
}
|
|
|
|
| 506 |
/* ๋ผ๋์ค ๋ฒํผ ๊ทธ๋ฃน ๋ด ๋ชจ๋ ๋ผ๋ฒจ ์ผ๋ฐ ํฐํธ๋ก ์ค์ */
|
| 507 |
.gr-radio fieldset label {
|
| 508 |
font-weight: normal !important;
|
| 509 |
}
|
|
|
|
| 510 |
/* ๋งํฌ๋ค์ด ํ
์คํธ ํฌ๊ธฐ ์ฆ๊ฐ */
|
| 511 |
.gradio-container .gr-markdown {
|
| 512 |
font-size: 15px !important;
|
| 513 |
line-height: 1.6 !important;
|
| 514 |
color: var(--text-color) !important;
|
| 515 |
}
|
|
|
|
| 516 |
/* ํ
์คํธ๋ฐ์ค ๋ด์ฉ ํฐํธ ํฌ๊ธฐ */
|
| 517 |
.gr-textbox textarea, .gr-textbox input {
|
| 518 |
font-size: 15px !important;
|
| 519 |
background-color: var(--input-bg) !important;
|
| 520 |
color: var(--text-color) !important;
|
| 521 |
}
|
|
|
|
| 522 |
/* ์์ฝ๋์ธ ์ ๋ชฉ ํฐํธ ํฌ๊ธฐ */
|
| 523 |
.gr-accordion summary {
|
| 524 |
font-size: 17px !important;
|
|
|
|
| 526 |
background-color: var(--card-bg) !important;
|
| 527 |
color: var(--text-color) !important;
|
| 528 |
}
|
|
|
|
| 529 |
/* ๋ฉ์ธ ์ปจํ
์ธ ์คํฌ๋กค๋ฐ */
|
| 530 |
::-webkit-scrollbar {
|
| 531 |
width: 8px;
|
| 532 |
height: 8px;
|
| 533 |
}
|
|
|
|
| 534 |
::-webkit-scrollbar-track {
|
| 535 |
background: var(--card-bg);
|
| 536 |
border-radius: 10px;
|
| 537 |
}
|
|
|
|
| 538 |
::-webkit-scrollbar-thumb {
|
| 539 |
background: var(--primary-color);
|
| 540 |
border-radius: 10px;
|
| 541 |
}
|
|
|
|
| 542 |
::-webkit-scrollbar-thumb:hover {
|
| 543 |
background: var(--secondary-color);
|
| 544 |
}
|
|
|
|
| 545 |
/* ์ ๋๋ฉ์ด์
์คํ์ผ */
|
| 546 |
@keyframes fadeIn {
|
| 547 |
from { opacity: 0; transform: translateY(10px); }
|
| 548 |
to { opacity: 1; transform: translateY(0); }
|
| 549 |
}
|
|
|
|
| 550 |
.fade-in {
|
| 551 |
animation: fadeIn 0.5s ease-out;
|
| 552 |
}
|
|
|
|
| 553 |
/* ๋ฐ์ํ */
|
| 554 |
@media (max-width: 768px) {
|
| 555 |
.button-grid {
|
| 556 |
grid-template-columns: repeat(2, 1fr);
|
| 557 |
}
|
| 558 |
}
|
|
|
|
| 559 |
/* ์น์
์ ๋ชฉ ์คํ์ผ */
|
| 560 |
.section-title {
|
| 561 |
display: flex;
|
|
|
|
| 568 |
border-bottom: 2px solid var(--primary-color);
|
| 569 |
font-family: 'Pretendard', 'Noto Sans KR', -apple-system, BlinkMacSystemFont, sans-serif;
|
| 570 |
}
|
|
|
|
| 571 |
.section-title img {
|
| 572 |
margin-right: 12px;
|
| 573 |
width: 28px;
|
|
|
|
| 575 |
/* ๋คํฌ๋ชจ๋์์ ์์ด์ฝ ํํฐ ์ ์ฉ */
|
| 576 |
filter: brightness(0) saturate(100%) invert(27%) sepia(51%) saturate(2878%) hue-rotate(346deg) brightness(104%) contrast(97%);
|
| 577 |
}
|
|
|
|
| 578 |
/* ๋ผ์ดํธ๋ชจ๋์์๋ ์๋ ์์ด๏ฟฝ๏ฟฝ๏ฟฝ ์์ ์ ์ง */
|
| 579 |
@media (prefers-color-scheme: light) {
|
| 580 |
.section-title img {
|
| 581 |
filter: none;
|
| 582 |
}
|
| 583 |
}
|
|
|
|
| 584 |
/* ์๋ ๋คํฌ๋ชจ๋ ํด๋์ค์์๋ ์์ด์ฝ ์์ ์ ์ฉ */
|
| 585 |
[data-theme="dark"] .section-title img,
|
| 586 |
.dark .section-title img,
|
| 587 |
.gr-theme-dark .section-title img {
|
| 588 |
filter: brightness(0) saturate(100%) invert(27%) sepia(51%) saturate(2878%) hue-rotate(346deg) brightness(104%) contrast(97%);
|
| 589 |
}
|
|
|
|
| 590 |
/* 10. ์์ฝ๋์ธ ๋ฐ ๋๋กญ๋ค์ด - ์๋์ค์ ์์ญ ํ์ ๋ฐฐ๊ฒฝ ์ ๊ฑฐ */
|
| 591 |
details,
|
| 592 |
.gr-accordion,
|
|
|
|
| 597 |
border-radius: var(--border-radius) !important;
|
| 598 |
margin: 10px 0 !important;
|
| 599 |
}
|
|
|
|
| 600 |
details summary,
|
| 601 |
.gr-accordion summary,
|
| 602 |
.gr-accordion details summary {
|
|
|
|
| 609 |
font-weight: 600 !important;
|
| 610 |
transition: all 0.3s ease !important;
|
| 611 |
}
|
|
|
|
| 612 |
details summary:hover,
|
| 613 |
.gr-accordion summary:hover,
|
| 614 |
.gr-accordion details summary:hover {
|
| 615 |
background-color: var(--table-hover-bg) !important;
|
| 616 |
}
|
|
|
|
| 617 |
/* ์์ฝ๋์ธ ๋ด๋ถ ์ฝํ
์ธ */
|
| 618 |
details[open],
|
| 619 |
.gr-accordion[open],
|
| 620 |
.gr-accordion details[open] {
|
| 621 |
background-color: var(--background-color) !important;
|
| 622 |
}
|
|
|
|
| 623 |
details[open] > *:not(summary),
|
| 624 |
.gr-accordion[open] > *:not(summary),
|
| 625 |
.gr-accordion details[open] > *:not(summary) {
|
|
|
|
| 628 |
padding: 16px !important;
|
| 629 |
border-top: 1px solid var(--border-color) !important;
|
| 630 |
}
|
|
|
|
| 631 |
/* ๊ทธ๋ฃน ๋ด๋ถ ์คํ์ผ - ์๋์ค์ ๋ด๋ถ ๊ทธ๋ฃน๋ค */
|
| 632 |
.gr-group,
|
| 633 |
details .gr-group,
|
|
|
|
| 638 |
margin: 8px 0 !important;
|
| 639 |
border-radius: var(--border-radius) !important;
|
| 640 |
}
|
|
|
|
| 641 |
/* ๊ทธ๋ฃน ๋ด๋ถ ์ ๋ชฉ */
|
| 642 |
.gr-group .gr-markdown h3,
|
| 643 |
.gr-group h3 {
|
|
|
|
| 648 |
padding-bottom: 6px !important;
|
| 649 |
border-bottom: 1px solid var(--border-color) !important;
|
| 650 |
}
|
|
|
|
| 651 |
/* 11. ์ถ๊ฐ Gradio ์ปดํฌ๋ํธ๋ค */
|
| 652 |
.gr-block,
|
| 653 |
.gr-group,
|
|
|
|
| 656 |
background-color: var(--background-color) !important;
|
| 657 |
color: var(--text-color) !important;
|
| 658 |
}
|
|
|
|
| 659 |
/* 12. ๋ฒํผ์ ๊ธฐ์กด ์คํ์ผ ์ ์ง (primary-color ์ฌ์ฉ) */
|
| 660 |
button:not([class*="custom"]):not([class*="primary"]):not([class*="secondary"]) {
|
| 661 |
background-color: var(--card-bg) !important;
|
| 662 |
color: var(--text-color) !important;
|
| 663 |
border-color: var(--border-color) !important;
|
| 664 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 665 |
/* 14. ์ ํ ์ ๋๋ฉ์ด์
*/
|
| 666 |
* {
|
| 667 |
transition: background-color 0.3s ease,
|
|
|
|
| 727 |
image_to_save.save(file_path, 'JPEG', quality=95)
|
| 728 |
|
| 729 |
print(f"โ
๋ค์ด๋ก๋ ํ์ผ ์ค๋น: {filename}")
|
| 730 |
+
print(f"๐ ํ์ผ ๊ฒฝ๋ก: {file_path}")
|
| 731 |
return file_path
|
| 732 |
|
| 733 |
except Exception as e:
|
| 734 |
print(f"โ ๋ค์ด๋ก๋ ํ์ผ ์ค๋น ์คํจ: {e}")
|
| 735 |
return None
|
| 736 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 737 |
def main():
|
| 738 |
with gr.Blocks(
|
| 739 |
css=custom_css,
|
|
|
|
| 926 |
interactive=False
|
| 927 |
)
|
| 928 |
|
| 929 |
+
# ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ค
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 930 |
|
| 931 |
def handle_copy_generation(keyword, selected_type):
|
| 932 |
+
"""์นดํผ ์์ฑ ์ฒ๋ฆฌ (๋๋ค API ํค ์ฌ์ฉ)"""
|
| 933 |
+
# ๐ฒ ๋๋ค API ํค ์ ํ
|
| 934 |
+
api_key = get_random_gemini_api_key()
|
| 935 |
+
print(f"๐ ์นดํผ ์์ฑ์ฉ API ํค: {api_key[:8] if api_key else 'None'}***")
|
| 936 |
+
|
| 937 |
+
if not keyword.strip():
|
| 938 |
+
return ("โ ๏ธ ์ํ ํค์๋๋ฅผ ์
๋ ฅํด์ฃผ์ธ๏ฟฝ๏ฟฝ๏ฟฝ.", {}, "", "", "", "", "", "", "", keyword.strip())
|
| 939 |
+
|
| 940 |
+
if not api_key:
|
| 941 |
+
return ("โ ๏ธ API ํค๊ฐ ์ค์ ๋์ง ์์์ต๋๋ค.", {}, "", "", "", "", "", "", "", keyword.strip())
|
| 942 |
+
|
| 943 |
+
if not selected_type:
|
| 944 |
+
return ("โ ๏ธ ์นดํผ ํ์
์ ๋จผ์ ์ ํํด์ฃผ์ธ์.", {}, "", "", "", "", "", "", "", keyword.strip())
|
| 945 |
+
|
| 946 |
+
print(f"๐ ์นดํผ ์์ฑ ํ๋ก์ธ์ค ์์: {keyword} - {selected_type}")
|
| 947 |
+
suggestions, analysis = generate_copy_suggestions(keyword, api_key, selected_type)
|
| 948 |
+
|
| 949 |
+
print(f"๐ AI ์๋ต ํ์
: {type(suggestions)}")
|
| 950 |
+
print(f"๐ AI ์๋ต ํค๋ค: {list(suggestions.keys()) if isinstance(suggestions, dict) else 'Not dict'}")
|
| 951 |
+
|
| 952 |
+
if "error" not in suggestions:
|
| 953 |
+
print("โ
์นดํผ ์์ฑ ์ฑ๊ณต!")
|
| 954 |
|
| 955 |
+
# ์ ํ๋ ํ์
์ ์นดํผ ๋ฆฌ์คํธ ๊ฐ์ ธ์ค๊ธฐ
|
| 956 |
+
copy_list = suggestions.get(selected_type, [])
|
| 957 |
+
print(f"๐ {selected_type} ์นดํผ ๊ฐ์: {len(copy_list)}")
|
|
|
|
|
|
|
| 958 |
|
| 959 |
+
# ๊ฐ ์นดํผ ์์ดํ
๊ฒ์ฆ
|
| 960 |
+
for i, item in enumerate(copy_list):
|
| 961 |
+
if isinstance(item, dict):
|
| 962 |
+
main = item.get("main", "")
|
| 963 |
+
sub = item.get("sub", "")
|
| 964 |
+
print(f" ์ถ์ฒ{i+1}: ๋ฉ์ธ='{main}', ์๋ธ='{sub}'")
|
| 965 |
+
else:
|
| 966 |
+
print(f" ์ถ์ฒ{i+1}: ์๋ชป๋ ํ์ {type(item)}")
|
| 967 |
|
| 968 |
+
# ํ์์ฉ ์นดํผ ๋ฌธ์์ด ์์ฑ (์ถ์ฒ1~5 ํ
์คํธ๋ฐ์ค์ฉ)
|
| 969 |
+
copy_values = []
|
| 970 |
+
for i in range(5):
|
| 971 |
+
if i < len(copy_list) and isinstance(copy_list[i], dict):
|
| 972 |
+
main = copy_list[i].get("main", "")
|
| 973 |
+
sub = copy_list[i].get("sub", "")
|
| 974 |
+
combined = f"{main} / {sub}"
|
| 975 |
+
copy_values.append(combined)
|
| 976 |
+
print(f"๐ ์ถ์ฒ{i+1} ํ์: {combined}")
|
| 977 |
+
else:
|
| 978 |
+
copy_values.append("")
|
| 979 |
+
print(f"๐ ์ถ์ฒ{i+1} ํ์: (๋น์ด์์)")
|
| 980 |
+
|
| 981 |
+
# ์ฒซ ๋ฒ์งธ ์นดํผ๋ฅผ ๋ฉ์ธ/์๋ธ ํ
์คํธ๋ฐ์ค์ ์๋ ์
๋ ฅ
|
| 982 |
+
first_main = ""
|
| 983 |
+
first_sub = ""
|
| 984 |
+
if copy_list and isinstance(copy_list[0], dict):
|
| 985 |
+
first_main = copy_list[0].get("main", "")
|
| 986 |
+
first_sub = copy_list[0].get("sub", "")
|
| 987 |
+
print(f"๐ฏ ์๋ ์ ํ: ๋ฉ์ธ='{first_main}', ์๋ธ='{first_sub}'")
|
| 988 |
+
|
| 989 |
+
return (f"โ
{selected_type} ์นดํผ ์์ฑ ์๋ฃ!", suggestions, *copy_values, first_main, first_sub, keyword.strip())
|
| 990 |
+
else:
|
| 991 |
+
print(f"โ ์นดํผ ์์ฑ ์คํจ: {suggestions['error']}")
|
| 992 |
+
error_msg = f"โ ์ค๋ฅ: {suggestions['error']}"
|
| 993 |
+
return (error_msg, {}, "", "", "", "", "", "", "", keyword.strip())
|
| 994 |
+
|
| 995 |
+
def update_copy_type_description(selected_type):
|
| 996 |
+
"""์นดํผ ํ์
์ ํ์ ์ค๋ช
์
๋ฐ์ดํธ"""
|
| 997 |
+
descriptions = {
|
| 998 |
+
"์ฅ์ ์์ฝํ": "**์ฅ์ ์์ฝํ**: ์ ํ์ ์ฅ์ ์ ํ๋์ ๊ฐ์กฐ - ํต์ฌ ๊ธฐ๋ฅ๊ณผ ํํ์ ๊ฐ๊ฒฐํ๊ฒ ์์ฝํ์ฌ ์ ์",
|
| 999 |
+
"๋ฌธ์ ์ ์ํ": "**๋ฌธ์ ์ ์ํ**: ๋ฌธ์ ๋ฅผ ์ ์ ํ ํด๊ฒฐ์ฑ
์ ์ - ๊ณ ๊ฐ์ ๋ถํธํจ์ ๋จผ์ ์ธ๊ธํ๊ณ ํด๊ฒฐ๋ฐฉ์ ์ ์",
|
| 1000 |
+
"์ฌํ์ ์ฆ๊ฑฐํ": "**์ฌํ์ ์ฆ๊ฑฐํ**: ์ ๋ขฐ์ ์ธ๊ธฐ๋ฅผ ๊ฐ์กฐ - ํ์ธ์ ์ฌ์ฉํ๊ธฐ์ ๊ฒ์ฆ๋ ์ค์ ์ผ๋ก ์ ๋ขฐ์ฑ ์ดํ",
|
| 1001 |
+
"๊ธด๊ธ์ฑ์ ๋ํ": "**๊ธด๊ธ์ฑ์ ๋ํ**: ์ฆ์ ๊ตฌ๋งค๋ฅผ ์ ๋ - ํ์ ์๋, ์๊ฐ์ ํ ๋ฑ์ผ๋ก ๊ธด๊ธ๊ฐ ์กฐ์ฑ",
|
| 1002 |
+
"๊ฐ๊ฒฉ๊ฒฝ์๋ ฅํ": "**๊ฐ๊ฒฉ๊ฒฝ์๋ ฅํ**: ํฉ๋ฆฌ์ ๊ฐ๊ฒฉ์ ๊ฐ์กฐํด ์ฑ์ทจ - ๊ฐ์ฑ๋น, ํ ์ธ๏ฟฝ๏ฟฝํ ๋ฑ ๊ฒฝ์ ์ ์ด๋ ๊ฐ์กฐ",
|
| 1003 |
+
"๋งค์ธ๋ณํํ": "**๋งค์ธ๋ณํํ**: ๊ฐํ ๋น๊ต๋ฅผ ์์ ์ง์ค - ์ฌ์ฉ ์ ํ ๋ณํ๋ ๊ทน์ ์ธ ๊ฐ์ ํจ๊ณผ ๋ถ๊ฐ",
|
| 1004 |
+
"์ถฉ๋๊ตฌ๋งค์ ๋ํ": "**์ถฉ๋๊ตฌ๋งค์ ๋ํ**: ํน์ ๊ตฌ๋งค์๊ตฌ๋ฅผ ์๊ทน - ํน๋ณํจ๊ณผ ํ๋ฆฌ๋ฏธ์ ๊ฐ์น๋ก ์์ ์ ์๊ทน",
|
| 1005 |
+
"๊ณตํฌ์๊ตฌํ": "**๊ณตํฌ์๊ตฌํ**: ๋ถ์ ์ํ์ ๊ฐ์กฐํด ๊ฐ์ ์ ๋ฐ - ๋์น๋ฉด ํํํ ๊ธฐํ๋ ์ํ์ฑ์ ๊ฒฝ๊ณ "
|
| 1006 |
+
}
|
| 1007 |
+
|
| 1008 |
+
if selected_type and selected_type in descriptions:
|
| 1009 |
+
return descriptions[selected_type]
|
| 1010 |
+
else:
|
| 1011 |
+
return "### ์นดํผ ํ์
์ ์ ํํ๋ฉด ์ค๋ช
์ด ํ์๋ฉ๋๋ค."
|
| 1012 |
|
| 1013 |
+
def handle_copy_selection(suggestions, selected_type, selected_copy):
|
| 1014 |
+
"""์นดํผ ์ ํ์ ๋ฉ์ธ/์๋ธ ํ
์คํธ๋ฐ์ค ์
๋ฐ์ดํธ (๊ฐ์ ๋ ๋ฒ์ )"""
|
| 1015 |
+
print(f"๐ ๋ผ๋์ค ์ ํ: {selected_copy}, ํ์
: {selected_type}")
|
| 1016 |
+
print(f"๐ suggestions ์ํ: {type(suggestions)}, ํค: {list(suggestions.keys()) if suggestions else 'None'}")
|
| 1017 |
+
|
| 1018 |
+
if not suggestions or "error" in suggestions:
|
| 1019 |
+
print("โ suggestions ๋ฐ์ดํฐ๊ฐ ์๊ฑฐ๋ ์๋ฌ ์ํ")
|
| 1020 |
+
return "", ""
|
| 1021 |
+
|
| 1022 |
+
if not selected_type or not selected_copy:
|
| 1023 |
+
print("โ ํ์
์ด๋ ์ ํ๋ ์นดํผ๊ฐ ์์")
|
| 1024 |
+
return "", ""
|
| 1025 |
+
|
| 1026 |
+
if selected_type not in suggestions:
|
| 1027 |
+
print(f"โ {selected_type} ํ์
์ suggestions์์ ์ฐพ์ ์ ์์")
|
| 1028 |
+
print(f"๐ ์ฌ์ฉ ๊ฐ๋ฅํ ํ์
๋ค: {list(suggestions.keys())}")
|
| 1029 |
+
return "", ""
|
| 1030 |
+
|
| 1031 |
+
copy_list = suggestions[selected_type]
|
| 1032 |
+
if not isinstance(copy_list, list):
|
| 1033 |
+
print(f"โ {selected_type} ๋ฐ์ดํฐ๊ฐ ๋ฆฌ์คํธ๊ฐ ์๋: {type(copy_list)}")
|
| 1034 |
+
return "", ""
|
| 1035 |
+
|
| 1036 |
+
print(f"๐ {selected_type} ์นดํผ ๋ฆฌ์คํธ: {len(copy_list)}๊ฐ")
|
| 1037 |
+
|
| 1038 |
+
# ๋ผ๋์ค ๋ฒํผ ์ ํ๊ฐ์์ ๋ฒํธ ์ถ์ถ (๋ ์์ ํ ๋ฐฉ๋ฒ)
|
| 1039 |
try:
|
| 1040 |
+
if "์ถ์ฒ 1" in selected_copy:
|
| 1041 |
+
option_number = 0
|
| 1042 |
+
elif "์ถ์ฒ 2" in selected_copy:
|
| 1043 |
+
option_number = 1
|
| 1044 |
+
elif "์ถ์ฒ 3" in selected_copy:
|
| 1045 |
+
option_number = 2
|
| 1046 |
+
elif "์ถ์ฒ 4" in selected_copy:
|
| 1047 |
+
option_number = 3
|
| 1048 |
+
elif "์ถ์ฒ 5" in selected_copy:
|
| 1049 |
+
option_number = 4
|
| 1050 |
+
else:
|
| 1051 |
+
# ๋ฐฑ์
๋ฐฉ๋ฒ: ์ซ์ ์ถ์ถ
|
| 1052 |
+
import re
|
| 1053 |
+
numbers = re.findall(r'\d+', selected_copy)
|
| 1054 |
+
option_number = int(numbers[0]) - 1 if numbers else 0
|
| 1055 |
|
| 1056 |
+
print(f"๐ข ์ถ์ถ๋ ์ต์
๋ฒํธ: {option_number}")
|
|
|
|
| 1057 |
|
| 1058 |
except Exception as e:
|
| 1059 |
+
print(f"โ ์ต์
๋ฒํธ ์ถ์ถ ์คํจ: {e}, ๊ธฐ๋ณธ๊ฐ 0 ์ฌ์ฉ")
|
| 1060 |
+
option_number = 0
|
| 1061 |
+
|
| 1062 |
+
# ๋ฒ์ ์ฒดํฌ
|
| 1063 |
+
if 0 <= option_number < len(copy_list):
|
| 1064 |
+
selected_copy_item = copy_list[option_number]
|
| 1065 |
+
|
| 1066 |
+
if not isinstance(selected_copy_item, dict):
|
| 1067 |
+
print(f"โ ์ ํ๋ ์นดํผ ์์ดํ
์ด ๋์
๋๋ฆฌ๊ฐ ์๋: {type(selected_copy_item)}")
|
| 1068 |
+
return "", ""
|
| 1069 |
+
|
| 1070 |
+
main_text = selected_copy_item.get("main", "")
|
| 1071 |
+
sub_text = selected_copy_item.get("sub", "")
|
| 1072 |
+
|
| 1073 |
+
print(f"โ
์ ํ๋ ์นดํผ - ๋ฉ์ธ: '{main_text}', ์๋ธ: '{sub_text}'")
|
| 1074 |
+
|
| 1075 |
+
# ๋น ๋ฌธ์์ด ์ฒดํฌ
|
| 1076 |
+
if not main_text and not sub_text:
|
| 1077 |
+
print("โ ๏ธ ๋ฉ์ธ์นดํผ์ ์๋ธ์นดํผ๊ฐ ๋ชจ๋ ๋น์ด์์")
|
| 1078 |
+
|
| 1079 |
+
return main_text, sub_text
|
| 1080 |
+
else:
|
| 1081 |
+
print(f"โ ์๋ชป๋ ์ต์
๋ฒํธ: {option_number} (๋ฒ์: 0~{len(copy_list)-1})")
|
| 1082 |
+
return "", ""
|
| 1083 |
|
| 1084 |
def handle_image_generation(input_image, main_text, sub_text, color_mode,
|
| 1085 |
main_font_choice, sub_font_choice, manual_bg_color, manual_main_text_color,
|
| 1086 |
manual_sub_text_color, manual_main_font_size, manual_sub_font_size,
|
| 1087 |
top_bottom_margin, text_gap, current_keyword):
|
| 1088 |
+
"""์ด๋ฏธ์ง ์์ฑ ์ฒ๋ฆฌ (์ฌ๋ฐฑ ์กฐ์ ๊ธฐ๋ฅ ํฌํจ)"""
|
| 1089 |
+
# ๐ฒ ๋๋ค API ํค ์ ํ
|
| 1090 |
+
api_key = get_random_gemini_api_key()
|
| 1091 |
+
print(f"๐ ์ด๋ฏธ์ง ์์ฑ์ฉ API ํค: {api_key[:8] if api_key else 'None'}***")
|
| 1092 |
+
|
| 1093 |
+
# ๐ฏ NEW: ์ฌ๋ฐฑ ์ค์ ์ create_uhp_image ํจ์์ ์ ๋ฌ
|
| 1094 |
+
image_result, color_mode_result, new_bg_color, new_main_text_color, new_sub_text_color, new_main_font_size, new_sub_font_size, applied_margin_info = create_uhp_image(
|
| 1095 |
+
input_image, main_text, sub_text, color_mode,
|
| 1096 |
+
main_font_choice, sub_font_choice, manual_bg_color, manual_main_text_color, manual_sub_text_color,
|
| 1097 |
+
manual_main_font_size, manual_sub_font_size, api_key,
|
| 1098 |
+
top_bottom_margin, text_gap # ์๋ก์ด ์ฌ๋ฐฑ ํ๋ผ๋ฏธํฐ ์ถ๊ฐ
|
| 1099 |
+
)
|
| 1100 |
+
|
| 1101 |
+
# ๐ฏ ํต์ฌ: ๋ค์ด๋ก๋ ํ์ผ ์ค๋น
|
| 1102 |
+
download_file_path = None
|
| 1103 |
+
if image_result is not None:
|
| 1104 |
+
download_file_path = prepare_download_file(image_result, current_keyword)
|
| 1105 |
+
|
| 1106 |
+
# ๐ฏ NEW: ์ ์ฉ๋ ์ฌ๋ฐฑ ์ ๋ณด ์์ฑ
|
| 1107 |
+
margin_info_text = f"""๐ **์ ์ฉ๋ ์ฌ๋ฐฑ ์ ๋ณด:**
|
| 1108 |
+
โข ์ํ ์ฌ๋ฐฑ: {applied_margin_info.get('top_bottom_margin', 0)}px
|
| 1109 |
+
โข ๋ฉ์ธโ์๋ธ ๊ฐ๊ฒฉ: {applied_margin_info.get('text_gap', 0)}px
|
| 1110 |
+
โข ์ด๋ฏธ์ง ํฌ๊ธฐ: {applied_margin_info.get('canvas_width', 0)} ร {applied_margin_info.get('canvas_height', 0)}px
|
| 1111 |
+
โข ์๋ณธ ํฌ๊ธฐ: {applied_margin_info.get('original_width', 0)} ร {applied_margin_info.get('original_height', 0)}px"""
|
| 1112 |
+
|
| 1113 |
+
return (image_result, color_mode_result, new_bg_color, new_main_text_color, new_sub_text_color,
|
| 1114 |
+
new_main_font_size, new_sub_font_size, download_file_path, margin_info_text)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1115 |
|
| 1116 |
+
# ์ด๋ฒคํธ ์ฐ๊ฒฐ
|
| 1117 |
copy_type_selection.change(
|
| 1118 |
fn=update_copy_type_description,
|
| 1119 |
inputs=[copy_type_selection],
|