Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
Update app.py
Browse files
app.py
CHANGED
@@ -1,11 +1,9 @@
|
|
1 |
import os
|
2 |
import gradio as gr
|
3 |
import shutil
|
4 |
-
import tempfile
|
5 |
import uuid
|
6 |
from pathlib import Path
|
7 |
import json
|
8 |
-
import base64
|
9 |
from PIL import Image
|
10 |
import fitz # PyMuPDF for PDF handling
|
11 |
|
@@ -14,7 +12,7 @@ TEMP_DIR = "temp"
|
|
14 |
UPLOAD_DIR = os.path.join(TEMP_DIR, "uploads")
|
15 |
OUTPUT_DIR = os.path.join(TEMP_DIR, "output")
|
16 |
THUMBS_DIR = os.path.join(OUTPUT_DIR, "thumbs")
|
17 |
-
HTML_DIR = os.path.join(
|
18 |
|
19 |
# Ensure directories exist
|
20 |
for dir_path in [TEMP_DIR, UPLOAD_DIR, OUTPUT_DIR, THUMBS_DIR, HTML_DIR]:
|
@@ -66,18 +64,14 @@ def process_pdf(pdf_path, session_id):
|
|
66 |
</div>
|
67 |
"""
|
68 |
|
69 |
-
#
|
70 |
-
rel_image_path = os.path.relpath(image_path, HTML_DIR).replace("\\", "/")
|
71 |
-
rel_thumb_path = os.path.relpath(thumb_path, HTML_DIR).replace("\\", "/")
|
72 |
-
|
73 |
-
# Add page info with interactive content
|
74 |
pages_info.append({
|
75 |
-
"src":
|
76 |
-
"thumb":
|
77 |
"title": f"ํ์ด์ง {page_num + 1}",
|
78 |
"htmlContent": html_content if html_content else None
|
79 |
})
|
80 |
-
print(f"Processed PDF page {page_num+1}: {
|
81 |
|
82 |
return pages_info
|
83 |
except Exception as e:
|
@@ -121,20 +115,14 @@ def process_images(image_paths, session_id):
|
|
121 |
</div>
|
122 |
"""
|
123 |
|
124 |
-
#
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
# Create a simpler page structure to avoid potential compatibility issues
|
129 |
-
page_info = {
|
130 |
-
"src": rel_image_path,
|
131 |
-
"thumb": rel_thumb_path,
|
132 |
"title": f"์ด๋ฏธ์ง {i + 1}",
|
133 |
"htmlContent": html_content if html_content else None
|
134 |
-
}
|
135 |
-
|
136 |
-
pages_info.append(page_info)
|
137 |
-
print(f"Processed image {i+1}: {rel_image_path}")
|
138 |
|
139 |
except Exception as e:
|
140 |
print(f"Error processing image {img_path}: {e}")
|
@@ -153,20 +141,28 @@ def create_flipbook_from_pdf(pdf_file, view_mode="2d", skin="light"):
|
|
153 |
pdf_path = pdf_file.name # Get the file path
|
154 |
debug_info += f"PDF path: {pdf_path}\n"
|
155 |
|
156 |
-
#
|
157 |
-
|
158 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
159 |
else:
|
160 |
return """<div style="color: red; padding: 20px;">PDF ํ์ผ์ ์
๋ก๋ํด์ฃผ์ธ์.</div>""", "No file uploaded"
|
161 |
-
|
162 |
-
if not pages_info:
|
163 |
-
return """<div style="color: red; padding: 20px;">PDF ํ์ผ ์ฒ๋ฆฌ ์ค ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค. ๋ค์ ์๋ํด์ฃผ์ธ์.</div>""", "No pages processed"
|
164 |
-
|
165 |
-
# Generate HTML file and return iframe HTML
|
166 |
-
iframe_html = generate_flipbook_html(pages_info, session_id, view_mode, skin)
|
167 |
-
debug_info += f"HTML file generated with view mode: {view_mode}, skin: {skin}\n"
|
168 |
-
|
169 |
-
return iframe_html, debug_info
|
170 |
|
171 |
except Exception as e:
|
172 |
error_msg = f"Error creating flipbook from PDF: {e}"
|
@@ -205,7 +201,7 @@ def create_flipbook_from_images(images, view_mode="2d", skin="light"):
|
|
205 |
return f"""<div style="color: red; padding: 20px;">์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค: {str(e)}</div>""", error_msg
|
206 |
|
207 |
def generate_flipbook_html(pages_info, session_id, view_mode, skin):
|
208 |
-
"""Generate a standalone HTML file for the flipbook and return
|
209 |
# Clean up pages_info to remove None values for JSON serialization
|
210 |
for page in pages_info:
|
211 |
if "htmlContent" in page and page["htmlContent"] is None:
|
@@ -228,7 +224,7 @@ def generate_flipbook_html(pages_info, session_id, view_mode, skin):
|
|
228 |
<meta charset="UTF-8">
|
229 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
230 |
<title>3D ํ๋ฆฝ๋ถ</title>
|
231 |
-
<link rel="stylesheet" type="text/css" href="
|
232 |
<style>
|
233 |
body, html {{
|
234 |
margin: 0;
|
@@ -265,11 +261,11 @@ def generate_flipbook_html(pages_info, session_id, view_mode, skin):
|
|
265 |
100% {{ transform: rotate(360deg); }}
|
266 |
}}
|
267 |
</style>
|
268 |
-
<script src="
|
269 |
-
<script src="
|
270 |
-
<script src="
|
271 |
-
<script src="
|
272 |
-
<script src="
|
273 |
</head>
|
274 |
<body>
|
275 |
<div id="flipbook-container"></div>
|
@@ -333,13 +329,16 @@ def generate_flipbook_html(pages_info, session_id, view_mode, skin):
|
|
333 |
with open(html_path, 'w', encoding='utf-8') as f:
|
334 |
f.write(html_content)
|
335 |
|
336 |
-
# Return
|
337 |
-
|
338 |
-
|
339 |
-
<div style="
|
340 |
-
<
|
|
|
|
|
341 |
</div>
|
342 |
-
|
|
|
343 |
<h3 style="margin-top:0; color:#333;">์ฌ์ฉ ํ:</h3>
|
344 |
<ul style="margin:10px 0; padding-left:20px;">
|
345 |
<li>ํ์ด์ง ๋ชจ์๋ฆฌ๋ฅผ ๋๋๊ทธํ์ฌ ๋๊ธธ ์ ์์ต๋๋ค.</li>
|
@@ -347,12 +346,25 @@ def generate_flipbook_html(pages_info, session_id, view_mode, skin):
|
|
347 |
<li>์ ์ฒดํ๋ฉด ๋ฒํผ์ ํด๋ฆญํ์ฌ ๋ ํฐ ํ๋ฉด์ผ๋ก ๋ณผ ์ ์์ต๋๋ค.</li>
|
348 |
</ul>
|
349 |
<div style="margin-top:10px; padding:10px; background-color:#e8f4fd; border-left:4px solid #2196F3; border-radius:2px;">
|
350 |
-
<strong>์ฐธ๊ณ :</strong>
|
351 |
</div>
|
352 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
353 |
"""
|
354 |
|
355 |
-
return
|
356 |
|
357 |
# Define the Gradio interface
|
358 |
with gr.Blocks(title="3D Flipbook Viewer") as demo:
|
@@ -445,4 +457,4 @@ with gr.Blocks(title="3D Flipbook Viewer") as demo:
|
|
445 |
|
446 |
# Launch the app
|
447 |
if __name__ == "__main__":
|
448 |
-
demo.launch(
|
|
|
1 |
import os
|
2 |
import gradio as gr
|
3 |
import shutil
|
|
|
4 |
import uuid
|
5 |
from pathlib import Path
|
6 |
import json
|
|
|
7 |
from PIL import Image
|
8 |
import fitz # PyMuPDF for PDF handling
|
9 |
|
|
|
12 |
UPLOAD_DIR = os.path.join(TEMP_DIR, "uploads")
|
13 |
OUTPUT_DIR = os.path.join(TEMP_DIR, "output")
|
14 |
THUMBS_DIR = os.path.join(OUTPUT_DIR, "thumbs")
|
15 |
+
HTML_DIR = os.path.join("public", "flipbooks") # Directory accessible via web
|
16 |
|
17 |
# Ensure directories exist
|
18 |
for dir_path in [TEMP_DIR, UPLOAD_DIR, OUTPUT_DIR, THUMBS_DIR, HTML_DIR]:
|
|
|
64 |
</div>
|
65 |
"""
|
66 |
|
67 |
+
# Add page info with web-accessible paths
|
|
|
|
|
|
|
|
|
68 |
pages_info.append({
|
69 |
+
"src": f"./temp/output/{session_id}/page_{page_num + 1}.png",
|
70 |
+
"thumb": f"./temp/output/thumbs/{session_id}/thumb_{page_num + 1}.png",
|
71 |
"title": f"ํ์ด์ง {page_num + 1}",
|
72 |
"htmlContent": html_content if html_content else None
|
73 |
})
|
74 |
+
print(f"Processed PDF page {page_num+1}: {image_path}")
|
75 |
|
76 |
return pages_info
|
77 |
except Exception as e:
|
|
|
115 |
</div>
|
116 |
"""
|
117 |
|
118 |
+
# Add page info with web-accessible paths
|
119 |
+
pages_info.append({
|
120 |
+
"src": f"./temp/output/{session_id}/image_{i + 1}.png",
|
121 |
+
"thumb": f"./temp/output/thumbs/{session_id}/thumb_{i + 1}.png",
|
|
|
|
|
|
|
|
|
122 |
"title": f"์ด๋ฏธ์ง {i + 1}",
|
123 |
"htmlContent": html_content if html_content else None
|
124 |
+
})
|
125 |
+
print(f"Processed image {i+1}: {dest_path}")
|
|
|
|
|
126 |
|
127 |
except Exception as e:
|
128 |
print(f"Error processing image {img_path}: {e}")
|
|
|
141 |
pdf_path = pdf_file.name # Get the file path
|
142 |
debug_info += f"PDF path: {pdf_path}\n"
|
143 |
|
144 |
+
# Copy the PDF file to a location accessible by the public URL
|
145 |
+
pdf_public_path = os.path.join(HTML_DIR, f"pdf_{session_id}.pdf")
|
146 |
+
shutil.copy(pdf_path, pdf_public_path)
|
147 |
+
|
148 |
+
# Create a simple HTML page with direct PDF loading
|
149 |
+
html_filename = f"flipbook_{session_id}.html"
|
150 |
+
html_path = os.path.join(HTML_DIR, html_filename)
|
151 |
+
|
152 |
+
# Create HTML content that uses CDN resources
|
153 |
+
html_content = create_flipbook_html_page(f"pdf_{session_id}.pdf", session_id, view_mode, skin)
|
154 |
+
|
155 |
+
# Write the HTML file
|
156 |
+
with open(html_path, 'w', encoding='utf-8') as f:
|
157 |
+
f.write(html_content)
|
158 |
+
|
159 |
+
# Generate link to the HTML file
|
160 |
+
public_url = f"/public/flipbooks/{html_filename}"
|
161 |
+
flipbook_link = generate_flipbook_link(public_url, session_id, view_mode, skin)
|
162 |
+
|
163 |
+
return flipbook_link, debug_info
|
164 |
else:
|
165 |
return """<div style="color: red; padding: 20px;">PDF ํ์ผ์ ์
๋ก๋ํด์ฃผ์ธ์.</div>""", "No file uploaded"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
166 |
|
167 |
except Exception as e:
|
168 |
error_msg = f"Error creating flipbook from PDF: {e}"
|
|
|
201 |
return f"""<div style="color: red; padding: 20px;">์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค: {str(e)}</div>""", error_msg
|
202 |
|
203 |
def generate_flipbook_html(pages_info, session_id, view_mode, skin):
|
204 |
+
"""Generate a standalone HTML file for the flipbook and return link HTML."""
|
205 |
# Clean up pages_info to remove None values for JSON serialization
|
206 |
for page in pages_info:
|
207 |
if "htmlContent" in page and page["htmlContent"] is None:
|
|
|
224 |
<meta charset="UTF-8">
|
225 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
226 |
<title>3D ํ๋ฆฝ๋ถ</title>
|
227 |
+
<link rel="stylesheet" type="text/css" href="../flipbook.css">
|
228 |
<style>
|
229 |
body, html {{
|
230 |
margin: 0;
|
|
|
261 |
100% {{ transform: rotate(360deg); }}
|
262 |
}}
|
263 |
</style>
|
264 |
+
<script src="../flipbook.js"></script>
|
265 |
+
<script src="../flipbook.webgl.js"></script>
|
266 |
+
<script src="../flipbook.swipe.js"></script>
|
267 |
+
<script src="../flipbook.scroll.js"></script>
|
268 |
+
<script src="../flipbook.book3.js"></script>
|
269 |
</head>
|
270 |
<body>
|
271 |
<div id="flipbook-container"></div>
|
|
|
329 |
with open(html_path, 'w', encoding='utf-8') as f:
|
330 |
f.write(html_content)
|
331 |
|
332 |
+
# Return HTML with a direct link to open the flipbook in a new tab
|
333 |
+
public_url = f"/public/flipbooks/{html_filename}"
|
334 |
+
link_html = f"""
|
335 |
+
<div style="text-align:center; padding:20px; background-color:#f9f9f9; border-radius:5px; margin-bottom:20px;">
|
336 |
+
<h2 style="margin-top:0; color:#333;">ํ๋ฆฝ๋ถ์ด ์ค๋น๋์์ต๋๋ค!</h2>
|
337 |
+
<p style="margin-bottom:20px;">์๋ ๋ฒํผ์ ํด๋ฆญํ์ฌ ํ๋ฆฝ๋ถ์ ์ ์ฐฝ์์ ์ด์ด๋ณด์ธ์.</p>
|
338 |
+
<a href="{public_url}" target="_blank" style="display:inline-block; background-color:#4CAF50; color:white; padding:12px 24px; text-decoration:none; border-radius:4px; font-weight:bold; font-size:16px;">ํ๋ฆฝ๋ถ ์ด๊ธฐ</a>
|
339 |
</div>
|
340 |
+
|
341 |
+
<div style="margin-top:20px; padding:15px; background-color:#f5f5f5; border-radius:5px; line-height:1.5;">
|
342 |
<h3 style="margin-top:0; color:#333;">์ฌ์ฉ ํ:</h3>
|
343 |
<ul style="margin:10px 0; padding-left:20px;">
|
344 |
<li>ํ์ด์ง ๋ชจ์๋ฆฌ๋ฅผ ๋๋๊ทธํ์ฌ ๋๊ธธ ์ ์์ต๋๋ค.</li>
|
|
|
346 |
<li>์ ์ฒดํ๋ฉด ๋ฒํผ์ ํด๋ฆญํ์ฌ ๋ ํฐ ํ๋ฉด์ผ๋ก ๋ณผ ์ ์์ต๋๋ค.</li>
|
347 |
</ul>
|
348 |
<div style="margin-top:10px; padding:10px; background-color:#e8f4fd; border-left:4px solid #2196F3; border-radius:2px;">
|
349 |
+
<strong>์ฐธ๊ณ :</strong> ํ๋ฆฝ๋ถ์ 2D ๋ชจ๋์์ ๊ฐ์ฅ ์์ ์ ์ผ๋ก ์๋ํฉ๋๋ค.
|
350 |
</div>
|
351 |
</div>
|
352 |
+
|
353 |
+
<div style="margin-top:15px; background-color:#f5f5f5; border-radius:5px; padding:10px;">
|
354 |
+
<details>
|
355 |
+
<summary style="cursor:pointer; color:#2196F3; font-weight:bold;">๊ธฐ์ ์ ์ธ๋ถ์ฌํญ (๊ฐ๋ฐ์์ฉ)</summary>
|
356 |
+
<div style="margin-top:10px;">
|
357 |
+
<p>์ธ์
ID: {session_id}</p>
|
358 |
+
<p>HTML ํ์ผ ๊ฒฝ๋ก: {html_path}</p>
|
359 |
+
<p>ํ์ด์ง ์: {len(pages_info)}</p>
|
360 |
+
<p>๋ทฐ ๋ชจ๋: {view_mode}</p>
|
361 |
+
<p>์คํจ: {skin}</p>
|
362 |
+
</div>
|
363 |
+
</details>
|
364 |
+
</div>
|
365 |
"""
|
366 |
|
367 |
+
return link_html
|
368 |
|
369 |
# Define the Gradio interface
|
370 |
with gr.Blocks(title="3D Flipbook Viewer") as demo:
|
|
|
457 |
|
458 |
# Launch the app
|
459 |
if __name__ == "__main__":
|
460 |
+
demo.launch() # Remove share=True as it's not supported in Spaces
|