Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -1,105 +1,149 @@
|
|
1 |
import gradio as gr
|
|
|
|
|
|
|
|
|
2 |
import webbrowser
|
3 |
-
from datetime import datetime
|
4 |
|
5 |
-
#
|
6 |
-
|
7 |
|
8 |
-
#
|
9 |
-
|
10 |
-
|
11 |
-
return "๊ฒ์์ด๋ฅผ ์
๋ ฅํ์ธ์.", ""
|
12 |
-
|
13 |
-
# ์ผ๋ณธ์ด๋ก ๋ฒ์ญ๋ ํค์๋ ์์ฑ (์ด ๋ถ๋ถ์ ์ค์ ๋ฒ์ญ API ์ฌ์ฉ ๋๋ ๋์ฒด ๋ก์ง์ผ๋ก ์์ ๊ฐ๋ฅ)
|
14 |
-
japanese_keyword = keyword # ์ด ๋ถ๋ถ์ ๋จ์ํ๋ ์์์
๋๋ค.
|
15 |
-
url = f"https://www.irasutoya.com/search?q={japanese_keyword}"
|
16 |
-
|
17 |
-
# ๊ฒ์ ๊ธฐ๋ก ์ ์ฅ
|
18 |
-
save_search_history(keyword, japanese_keyword, url)
|
19 |
-
|
20 |
-
# ๊ฒฐ๊ณผ ๋ฐํ
|
21 |
-
return f"๊ฒ์์ด: {keyword}\n์ผ๋ณธ์ด: {japanese_keyword}\n\n[์ผ๋ฌ์คํธ ๋ณด๋ฌ๊ฐ๊ธฐ]({url})", url
|
22 |
-
|
23 |
-
# ๊ฒ์ ๊ธฐ๋ก ์ ์ฅ ํจ์
|
24 |
-
def save_search_history(keyword, japanese_keyword, url):
|
25 |
-
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
26 |
-
search_history.append((timestamp, keyword, japanese_keyword, url))
|
27 |
-
|
28 |
-
# ๊ฒ์ ๊ธฐ๋ก ์กฐํ ํจ์
|
29 |
-
def load_search_history():
|
30 |
-
return [f"{record[0]} - {record[1]}: {record[2]} (๋งํฌ: {record[3]})" for record in search_history]
|
31 |
-
|
32 |
-
# ๊ฒ์ ๊ธฐ๋ก ์ฌ๊ฒ์ ํจ์
|
33 |
-
def replay_history(selected_item):
|
34 |
-
if not selected_item:
|
35 |
-
return "๊ฒ์ ๊ธฐ๋ก์ ์ ํํ์ธ์.", ""
|
36 |
-
keyword = selected_item.split(" - ")[1].split(":")[0]
|
37 |
-
return search_and_update_history(keyword)
|
38 |
-
|
39 |
-
# ์๋ด ๋ฌธ๊ตฌ ์ถ๊ฐ
|
40 |
-
def get_info_text():
|
41 |
-
return """
|
42 |
-
**์ด๋ผ์คํ ์ผ(Irasutoya.com)**๋ ์ผ๋ณธ์ ์ผ๋ฌ์คํธ๋ ์ดํฐ์ธ ๋ฏธ์ฆํ๋ ํ์นด์(Takashi Mizutani)๊ฐ ์ด์ํ๋ ๋ฌด๋ฃ ์ผ๋ฌ์คํธ ์ฌ์ดํธ์
๋๋ค.
|
43 |
-
์ด ์ฌ์ดํธ๋ ๊ท์ฝ๊ณ ๋จ์ํ ์คํ์ผ์ ์ผ๋ฌ์คํธ๋ฅผ ์ ๊ณตํ๋ฉฐ, ์ฃผ๋ก ์น์ฌ์ดํธ, ํ๋ ์ ํ
์ด์
, ๋ธ๋ก๊ทธ ํฌ์คํธ, ์ธ์๋ฌผ ๋ฑ์์ ์ฌ์ฉ๋ ์ ์๋ ๋ค์ํ ์ฃผ์ ์ ์ด๋ฏธ์ง๋ฅผ ๋ค์ด๋ก๋ํ ์ ์์ต๋๋ค.
|
44 |
-
์ด๋ผ์คํ ์ผ์ ์ผ๋ฌ์คํธ๋ ํนํ ์ผ๋ณธ ๋ด์์ ๋๋ฆฌ ์ฌ์ฉ๋๊ณ ์์ผ๋ฉฐ, ๊ณต๊ณต๊ธฐ๊ด, ๊ธฐ์
, ๊ฐ์ธ ๋ธ๋ก๊ทธ ๋ฑ ๋ค์ํ ๊ณณ์์ ์ฝ๊ฒ ๋ณผ ์ ์์ต๋๋ค.
|
45 |
-
|
46 |
-
**์ฃผ์ ์ฌํญ:** ์ด ์ฌ์ดํธ๋ ๋จ์ํ ๊ฒ์์ด ํธํ๋๋ก ์ผ๋ณธ์ด๋ก ๋ฒ์ญํด์ ์ ๋ฌํ๋ ๊ธฐ๋ฅ ์ธ์๋ ๋ค๋ฅธ ๊ธฐ๋ฅ์ด ์์ต๋๋ค.
|
47 |
-
|
48 |
-
- **์ฌ์ฉ ๋ฐฉ๋ฒ**:
|
49 |
-
1. ๊ฒ์ ์ฐฝ์ ํ๊ธ๋ก ํค์๋๋ฅผ ์
๋ ฅํฉ๋๋ค.
|
50 |
-
2. ๊ฒ์ ๋ฒํผ์ ํด๋ฆญํฉ๋๋ค.
|
51 |
-
3. ์๋์ผ๋ก ์ผ๋ณธ์ด๋ก ๋ฒ์ญ๋ ๊ฒ์์ด๋ก ์ด๋ผ์คํ ์ผ ์ฌ์ดํธ๊ฐ ์ด๋ฆฌ๋ฉฐ, ์ํ๋ ์ ๋๋ฉ์ด์
์ด๋ฏธ์ง๋ฅผ ๋ค์ด๋ก๋ํ ์ ์์ต๋๋ค.
|
52 |
-
|
53 |
-
**์ ์๊ถ ์๋ด**:
|
54 |
-
๊ฐ์ธ, ๋ฒ์ธ, ์์
์ ์ฌ์ฉ ๋ชจ๋ ๋ฌด๋ฃ๋ก ์ ๊ณต๋ฉ๋๋ค. ๋จ, ์ ์๋ฌผ๋น 20๊ฐ๊น์ง ๊ฐ๋ฅํ๋ฉฐ, 21์ ๋ถํฐ๋ ์ ๋ฃ๋ก ์ฌ์ฉํด์ผ ํฉ๋๋ค.
|
55 |
-
์ ์๊ถ ํ๊ธฐ ์๋ฌด๋ ์์ผ๋ฉฐ, ์์ ๋กญ๊ฒ ํธ์ง ๊ฐ๊ณต์ด ๊ฐ๋ฅํฉ๋๋ค.
|
56 |
-
|
57 |
-
**์ผ๋ณธ์ด ํ์ต**:
|
58 |
-
์ผ๋ณธ์ด ๋ฐ์ ๋ฃ๊ธฐ ๊ธฐ๋ฅ์ ํตํด ๊ฐ๋จํ ์ผ๋ณธ์ด ๊ณต๋ถ๋ ๊ฐ๋ฅํฉ๋๋ค!
|
59 |
-
"""
|
60 |
|
61 |
-
#
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
103 |
|
104 |
# ์ฑ ์คํ
|
105 |
-
|
|
|
1 |
import gradio as gr
|
2 |
+
from deep_translator import GoogleTranslator
|
3 |
+
from gtts import gTTS
|
4 |
+
import pykakasi
|
5 |
+
import os
|
6 |
import webbrowser
|
|
|
7 |
|
8 |
+
# ํ์ฌ ๋ฒ์ ์ ๋ณด
|
9 |
+
__version__ = "1.6.1"
|
10 |
|
11 |
+
# Kakasi ์ค์ (๋ก๋ง์ ๋ณํ)
|
12 |
+
kakasi = pykakasi.kakasi()
|
13 |
+
conv = kakasi.convert
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
|
15 |
+
# ๋ก๋ง์ ๋ณํ ํจ์
|
16 |
+
def to_romaji(japanese_text):
|
17 |
+
result = conv(japanese_text)
|
18 |
+
romaji = ''.join([item['hepburn'] for item in result])
|
19 |
+
return romaji
|
20 |
|
21 |
+
# ๊ฒ์ ๋ฐ ๊ฒฐ๊ณผ ์ถ๋ ฅ ํจ์
|
22 |
+
def search_and_update_history(keyword):
|
23 |
+
result, japanese_keyword = search(keyword)
|
24 |
+
|
25 |
+
if japanese_keyword:
|
26 |
+
audio_path = generate_audio_file(japanese_keyword)
|
27 |
+
return result, gr.update(value=audio_path, visible=True)
|
28 |
+
else:
|
29 |
+
return result, gr.update(visible=False)
|
30 |
+
|
31 |
+
# ๊ฒ์ ํจ์
|
32 |
+
def search(keyword):
|
33 |
+
try:
|
34 |
+
translator = GoogleTranslator(source='ko', target='ja')
|
35 |
+
japanese_keyword = translator.translate(keyword)
|
36 |
+
|
37 |
+
url = f"https://www.irasutoya.com/search?q={japanese_keyword}"
|
38 |
+
romaji = to_romaji(japanese_keyword)
|
39 |
+
result_text = (
|
40 |
+
f"**๊ฒ์์ด:** {keyword}\n"
|
41 |
+
f"**์ผ๋ณธ์ด ๋ฒ์ญ:** {japanese_keyword} ({romaji})\n"
|
42 |
+
f"<a href='{url}' target='_blank'>๊ฒ์ ๊ฒฐ๊ณผ ๋ณด๊ธฐ (์ ํญ์์ ์ด๊ธฐ)</a>\n\n"
|
43 |
+
f"**์๋ด:** ๋ก๋ง์ ํ๊ธฐ์ ์์ฑ์ ์ค์ ๋ฐ์๊ณผ ๋ค๋ฅผ ์ ์์ต๋๋ค."
|
44 |
+
)
|
45 |
+
return result_text, japanese_keyword
|
46 |
+
except Exception as e:
|
47 |
+
return f"๋ฒ์ญ ์ค ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค: {e}", None
|
48 |
+
|
49 |
+
# ์ผ๋ณธ์ด ์์ฑ ์์ฑ ํจ์
|
50 |
+
def generate_audio_file(japanese_text):
|
51 |
+
try:
|
52 |
+
tts = gTTS(japanese_text, lang='ja')
|
53 |
+
file_path = "japanese_audio.mp3"
|
54 |
+
tts.save(file_path)
|
55 |
+
return file_path
|
56 |
+
except Exception as e:
|
57 |
+
return None
|
58 |
+
|
59 |
+
# Gradio ์ธํฐํ์ด์ค ์ค์
|
60 |
+
with gr.Blocks(css="""
|
61 |
+
.container {
|
62 |
+
max-width: 100%;
|
63 |
+
margin: auto;
|
64 |
+
padding: 10px;
|
65 |
+
}
|
66 |
+
.input-box {
|
67 |
+
padding: 10px;
|
68 |
+
border: 2px solid #ddd;
|
69 |
+
border-radius: 4px;
|
70 |
+
font-size: 16px;
|
71 |
+
width: 100%;
|
72 |
+
}
|
73 |
+
.result-output {
|
74 |
+
background-color: #fff;
|
75 |
+
padding: 10px;
|
76 |
+
border: 1px solid #ddd;
|
77 |
+
border-radius: 4px;
|
78 |
+
font-size: 16px;
|
79 |
+
width: 100%;
|
80 |
+
margin-top: 15px;
|
81 |
+
}
|
82 |
+
.title {
|
83 |
+
font-size: 24px;
|
84 |
+
font-weight: bold;
|
85 |
+
color: #2C3E50;
|
86 |
+
margin-bottom: 10px;
|
87 |
+
text-align: center;
|
88 |
+
}
|
89 |
+
.btn-large {
|
90 |
+
font-size: 16px;
|
91 |
+
padding: 8px;
|
92 |
+
border-radius: 4px;
|
93 |
+
width: 100%;
|
94 |
+
margin-top: 5px;
|
95 |
+
}
|
96 |
+
.btn-search {
|
97 |
+
background-color: #4CAF50;
|
98 |
+
color: white;
|
99 |
+
}
|
100 |
+
.btn-clear {
|
101 |
+
background-color: #f39c12;
|
102 |
+
color: white;
|
103 |
+
}
|
104 |
+
.creator-info {
|
105 |
+
font-size: 12px;
|
106 |
+
color: #7f8c8d;
|
107 |
+
text-align: center;
|
108 |
+
margin-top: 20px;
|
109 |
+
}
|
110 |
+
""") as demo:
|
111 |
+
|
112 |
+
with gr.Column(elem_classes="container"):
|
113 |
+
gr.Markdown(f"## Irasutoya ํ๊ธ ๊ฒ์๊ธฐ - ๋ฒ์ {__version__}", elem_classes="title")
|
114 |
+
|
115 |
+
keyword_input = gr.Textbox(label="ํ๊ธ ๊ฒ์์ด ์
๋ ฅ", placeholder="ํ๊ธ๋ก ๊ฒ์์ด๋ฅผ ์
๋ ฅํ์ธ์", elem_classes="input-box")
|
116 |
+
search_button = gr.Button("๊ฒ์", elem_classes="btn-large btn-search")
|
117 |
+
clear_button = gr.Button("์ง์ฐ๊ธฐ", elem_classes="btn-large btn-clear")
|
118 |
+
|
119 |
+
result_output = gr.Markdown(elem_classes="result-output")
|
120 |
+
play_audio = gr.Audio(visible=False) # ์์ฑ ํ์ผ์ ์ฌ์ํ๋ ์ปดํฌ๋ํธ
|
121 |
+
|
122 |
+
search_button.click(
|
123 |
+
fn=search_and_update_history,
|
124 |
+
inputs=[keyword_input],
|
125 |
+
outputs=[result_output, play_audio],
|
126 |
+
)
|
127 |
+
|
128 |
+
keyword_input.submit(
|
129 |
+
fn=search_and_update_history,
|
130 |
+
inputs=[keyword_input],
|
131 |
+
outputs=[result_output, play_audio],
|
132 |
+
)
|
133 |
+
|
134 |
+
clear_button.click(
|
135 |
+
fn=lambda: ("", "", gr.update(visible=False)),
|
136 |
+
outputs=[keyword_input, result_output, play_audio],
|
137 |
+
)
|
138 |
+
|
139 |
+
# ์ ์์ ์ ๋ณด ์น์
์ถ๊ฐ
|
140 |
+
gr.Markdown("""
|
141 |
+
<div style="text-align: center;">
|
142 |
+
<a href="https://litt.ly/goverse" target="_blank" style="color: #2980b9; text-decoration: underline;">๊ณ ๋ฒ์คTV</a>
|
143 |
+
</div>
|
144 |
+
""")
|
145 |
+
|
146 |
+
gr.Markdown("์ ์์: ๊ณ ๋ฒ์คTV", elem_classes="creator-info")
|
147 |
|
148 |
# ์ฑ ์คํ
|
149 |
+
demo.launch(share=False)
|