ginipick commited on
Commit
31c4a0e
Β·
verified Β·
1 Parent(s): cf741ec

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +25 -61
app.py CHANGED
@@ -1,113 +1,77 @@
1
  # app.py
2
- #
3
- # Hugging Face Spaces ➜ Build type: "FastAPI" (Python)
4
- # μ‹€ν–‰ μ‹œ http://<space-url>/ 둜 μ ‘μ†ν•˜λ©΄ FlipBook UIκ°€ ν‘œμ‹œλ©λ‹ˆλ‹€.
5
-
6
  from fastapi import FastAPI
7
  from fastapi.responses import HTMLResponse
8
  from fastapi.staticfiles import StaticFiles
9
- import pathlib
10
 
11
  BASE = pathlib.Path(__file__).parent
12
 
13
  app = FastAPI()
14
 
15
- # ── 1. 같은 ν΄λ”μ˜ 정적 파일(js / css / img / mp3 λ“±)을 /static 경둜둜 μ„œλΉ™
16
  app.mount("/static", StaticFiles(directory=BASE), name="static")
17
 
18
- # ── 2. index.html μ†ŒμŠ€ (script/link 경둜만 /static/ 둜 λ°”κΏˆ)
19
  INDEX_HTML = """
20
  <!DOCTYPE html>
21
  <html lang="ko">
22
  <head>
23
  <meta charset="UTF-8">
24
- <title>FlipBook – μ—…λ‘œλ“œ + λ‚΄μž₯ μ‚¬μš΄λ“œ</title>
25
-
26
  <link rel="stylesheet" href="/static/flipbook.css">
27
-
28
- <!-- ν•„μˆ˜ JS μˆœμ„œ -->
29
  <script src="/static/three.js"></script>
30
  <script src="/static/iscroll.js"></script>
31
  <script src="/static/mark.js"></script>
32
  <script src="/static/mod3d.js"></script>
33
-
34
  <script src="/static/flipbook.js"></script>
35
  <script src="/static/flipbook.book3.js"></script>
36
  <script src="/static/flipbook.scroll.js"></script>
37
  <script src="/static/flipbook.swipe.js"></script>
38
  <script src="/static/flipbook.webgl.js"></script>
39
-
40
  <style>
41
  body{margin:0;font-family:sans-serif;background:#f4f4f4}
42
- h1{text-align:center;margin:24px 0}
43
- #viewer{width:900px;height:600px;margin:0 auto 40px;background:#fff;border:1px solid #ccc}
44
  .upload-wrapper{display:flex;justify-content:center}
45
- #uploadBtn{
46
- all:unset;width:44px;height:44px;line-height:44px;text-align:center;
47
- font-size:26px;border-radius:50%;cursor:pointer;
48
- background:#ffb84d;color:#fff;box-shadow:0 2px 4px rgba(0,0,0,.2);transition:.2s;
49
- }
50
- #uploadBtn:hover{transform:translateY(-2px);box-shadow:0 4px 8px rgba(0,0,0,.25)}
51
  #fileInput{display:none}
52
  </style>
53
  </head>
54
  <body>
55
-
56
- <h1>Real3D FlipBook – 이미지 μ—…λ‘œλ“œ + μ‚¬μš΄λ“œ ✨</h1>
57
-
58
  <div id="viewer"></div>
59
-
60
  <div class="upload-wrapper">
61
  <button id="uploadBtn" title="이미지 μ—…λ‘œλ“œ">πŸ“·</button>
62
- <input id="fileInput" type="file" accept="image/*" multiple />
63
  </div>
64
-
65
  <script>
66
- let book=null;
67
- const holder=document.getElementById('viewer');
68
-
69
  document.getElementById('uploadBtn').onclick=()=>document.getElementById('fileInput').click();
70
-
71
  document.getElementById('fileInput').onchange=e=>{
72
  if(!e.target.files.length) return;
73
- const files=[...e.target.files];
74
- const pages=[];
75
- let done=0;
76
- files.forEach((f,i)=>{
77
- const rd=new FileReader();
78
- rd.onload=ev=>{
79
- pages[i]={src:ev.target.result,thumb:ev.target.result};
80
- if(++done===files.length) createBook(pages);
81
- };
82
- rd.readAsDataURL(f);
83
- });
84
  };
85
-
86
- function createBook(pages){
87
- if(book){ book.destroy(); holder.innerHTML=''; }
88
-
89
  book=new FlipBook(holder,{
90
- pages,
91
- viewMode:'webgl',
92
- autoSize:true,
93
- flipDuration:800,
94
- backgroundColor:'#ffffff',
95
-
96
- sound:true,
97
- assets:{
98
- flipMp3:'/static/turnPage2.mp3',
99
- hardFlipMp3:'/static/turnPage2.mp3'
100
- },
101
-
102
  controlsProps:{enableFullscreen:true,thumbnails:true}
103
  });
104
  }
105
  </script>
106
- </body>
107
- </html>
108
  """
109
 
110
- # ── 3. λΌμš°ν„°: GET / β†’ index.html λ°˜ν™˜
111
  @app.get("/", response_class=HTMLResponse)
112
  async def root():
113
  return INDEX_HTML
 
 
 
 
 
 
1
  # app.py
 
 
 
 
2
  from fastapi import FastAPI
3
  from fastapi.responses import HTMLResponse
4
  from fastapi.staticfiles import StaticFiles
5
+ import pathlib, os, uvicorn
6
 
7
  BASE = pathlib.Path(__file__).parent
8
 
9
  app = FastAPI()
10
 
11
+ # ── 정적 파일 (JS / CSS / 이미지 / MP3) μ„œλΉ™ ──
12
  app.mount("/static", StaticFiles(directory=BASE), name="static")
13
 
14
+ # ── index.html 원문 ──
15
  INDEX_HTML = """
16
  <!DOCTYPE html>
17
  <html lang="ko">
18
  <head>
19
  <meta charset="UTF-8">
20
+ <title>FlipBook – μ—…λ‘œλ“œ + μ‚¬μš΄λ“œ</title>
 
21
  <link rel="stylesheet" href="/static/flipbook.css">
 
 
22
  <script src="/static/three.js"></script>
23
  <script src="/static/iscroll.js"></script>
24
  <script src="/static/mark.js"></script>
25
  <script src="/static/mod3d.js"></script>
 
26
  <script src="/static/flipbook.js"></script>
27
  <script src="/static/flipbook.book3.js"></script>
28
  <script src="/static/flipbook.scroll.js"></script>
29
  <script src="/static/flipbook.swipe.js"></script>
30
  <script src="/static/flipbook.webgl.js"></script>
 
31
  <style>
32
  body{margin:0;font-family:sans-serif;background:#f4f4f4}
33
+ #viewer{width:900px;height:600px;margin:40px auto;background:#fff;border:1px solid #ccc}
 
34
  .upload-wrapper{display:flex;justify-content:center}
35
+ #uploadBtn{all:unset;width:44px;height:44px;line-height:44px;text-align:center;
36
+ font-size:26px;border-radius:50%;cursor:pointer;background:#ffb84d;color:#fff}
 
 
 
 
37
  #fileInput{display:none}
38
  </style>
39
  </head>
40
  <body>
41
+ <h2 style="text-align:center">Real3D FlipBook – μ—…λ‘œλ“œ βœ¨πŸ“–</h2>
 
 
42
  <div id="viewer"></div>
 
43
  <div class="upload-wrapper">
44
  <button id="uploadBtn" title="이미지 μ—…λ‘œλ“œ">πŸ“·</button>
45
+ <input id="fileInput" type="file" accept="image/*" multiple>
46
  </div>
 
47
  <script>
48
+ let book=null, holder=document.getElementById('viewer');
 
 
49
  document.getElementById('uploadBtn').onclick=()=>document.getElementById('fileInput').click();
 
50
  document.getElementById('fileInput').onchange=e=>{
51
  if(!e.target.files.length) return;
52
+ const files=[...e.target.files], pages=[], tot=files.length; let cnt=0;
53
+ files.forEach((f,i)=>{const r=new FileReader();r.onload=x=>{
54
+ pages[i]={src:x.target.result,thumb:x.target.result};
55
+ if(++cnt===tot) makeBook(pages);
56
+ };r.readAsDataURL(f);});
 
 
 
 
 
 
57
  };
58
+ function makeBook(p){
59
+ if(book){book.destroy();holder.innerHTML='';}
 
 
60
  book=new FlipBook(holder,{
61
+ pages:p,viewMode:'webgl',autoSize:true,flipDuration:800,backgroundColor:'#fff',
62
+ sound:true,assets:{flipMp3:'/static/turnPage2.mp3',hardFlipMp3:'/static/turnPage2.mp3'},
 
 
 
 
 
 
 
 
 
 
63
  controlsProps:{enableFullscreen:true,thumbnails:true}
64
  });
65
  }
66
  </script>
67
+ </body></html>
 
68
  """
69
 
 
70
  @app.get("/", response_class=HTMLResponse)
71
  async def root():
72
  return INDEX_HTML
73
+
74
+ # ── Hugging Faceκ°€ β€˜python app.py’ 둜 μ‹€ν–‰ν•  λ•Œ 직접 uvicorn을 띄움 ──
75
+ if __name__ == "__main__":
76
+ port = int(os.environ.get("PORT", 7860))
77
+ uvicorn.run("app:app", host="0.0.0.0", port=port, reload=False)