Update app.py
Browse files
app.py
CHANGED
|
@@ -9,7 +9,7 @@ import base64
|
|
| 9 |
import html
|
| 10 |
|
| 11 |
# Konfiguration
|
| 12 |
-
DATA_URL = "https://huggingface.co"
|
| 13 |
LOGO_NAME = "logo.jpg"
|
| 14 |
|
| 15 |
def load_data():
|
|
@@ -45,78 +45,117 @@ def markiere_rot(text, suchwort):
|
|
| 45 |
pattern = re.compile(re.escape(str(suchwort)), re.IGNORECASE)
|
| 46 |
return pattern.sub(lambda m: f"<span style='color:#e53935; font-weight:bold;'>{m.group(0)}</span>", text_str)
|
| 47 |
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 57 |
|
| 58 |
-
if
|
| 59 |
-
return "<p style='text-align:center; color:red; font-weight:bold;'>❌ Çi nêbi / Bulunamadı.</p>"
|
| 60 |
|
| 61 |
-
html_output = "
|
| 62 |
-
for _, row in
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 66 |
html_output += f"""
|
| 67 |
-
<div style='border: 1px solid #
|
| 68 |
-
<
|
| 69 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 70 |
</div>
|
| 71 |
"""
|
| 72 |
-
return html_output
|
| 73 |
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
|
| 88 |
-
|
| 89 |
-
with gr.Blocks(css="footer {visibility: hidden}", title="Kırmancki Qesebend") as demo:
|
| 90 |
with gr.Column():
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
gr.HTML(f"<div style='text-align:center;'><img src='{logo_base64}' width='150' style='margin:auto;'></div>")
|
| 95 |
-
|
| 96 |
-
gr.HTML("<h1 style='text-align:center; color: #e53935;'>Kırmancki - Qesebend</h1>")
|
| 97 |
-
|
| 98 |
-
# Wort des Tages (FIX: latex_delimiters=[] verhindert KaTeX Fehler)
|
| 99 |
-
word_of_the_day_display = gr.HTML(latex_delimiters=[])
|
| 100 |
-
|
| 101 |
-
# Suchbereich
|
| 102 |
-
search_input = gr.Textbox(
|
| 103 |
-
label="Bıgêyre / Kelime gir...",
|
| 104 |
-
placeholder="Mesela: 'mı'...",
|
| 105 |
-
lines=1
|
| 106 |
-
)
|
| 107 |
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 114 |
</div>
|
| 115 |
-
|
| 116 |
-
|
| 117 |
-
|
| 118 |
-
|
| 119 |
-
|
|
|
|
|
|
|
| 120 |
|
| 121 |
-
|
| 122 |
-
demo.launch()
|
|
|
|
| 9 |
import html
|
| 10 |
|
| 11 |
# Konfiguration
|
| 12 |
+
DATA_URL = "https://huggingface.co/datasets/Manidar/DEZD-Dictionary-Kirmancki/resolve/main/kirmancki%20qesebend%20dictionary.csv"
|
| 13 |
LOGO_NAME = "logo.jpg"
|
| 14 |
|
| 15 |
def load_data():
|
|
|
|
| 45 |
pattern = re.compile(re.escape(str(suchwort)), re.IGNORECASE)
|
| 46 |
return pattern.sub(lambda m: f"<span style='color:#e53935; font-weight:bold;'>{m.group(0)}</span>", text_str)
|
| 47 |
|
| 48 |
+
# Diese Funktion wird nun bei jedem Laden der Seite aufgerufen
|
| 49 |
+
def get_header_data_dynamic():
|
| 50 |
+
if DF_GLOBAL is None or DF_GLOBAL.empty:
|
| 51 |
+
return "⚠️ Veriler yüklenemedi.", ""
|
| 52 |
+
total = len(DF_GLOBAL)
|
| 53 |
+
seed = int(datetime.now().strftime("%Y%m%d"))
|
| 54 |
+
wotd_row = DF_GLOBAL.sample(n=1, random_state=seed).iloc[0].to_dict()
|
| 55 |
+
|
| 56 |
+
stats = f"📊 **{total}** Qesey u Ornagi (Kelimeler ve Örnekler)"
|
| 57 |
+
|
| 58 |
+
langs = []
|
| 59 |
+
if str(wotd_row.get('Tr', '')).strip(): langs.append(f"🇹🇷 {wotd_row['Tr']}")
|
| 60 |
+
if str(wotd_row.get('De', '')).strip(): langs.append(f"🇩🇪 {wotd_row['De']}")
|
| 61 |
+
if 'En' in wotd_row and str(wotd_row.get('En', '')).strip(): langs.append(f"🇬🇧 {wotd_row['En']}")
|
| 62 |
+
lang_html = "<br>".join(langs)
|
| 63 |
+
|
| 64 |
+
wotd_html = f"""
|
| 65 |
+
<div style='background-color: #f1f4ff; color: #1a237e; padding: 20px; border-radius: 12px; border-left: 8px solid #3f51b5; margin: 15px 0; border: 1px solid #d1d9ff;'>
|
| 66 |
+
<small style='color: #3f51b5; text-transform: uppercase; font-weight: bold;'>ROCA QESEY (Günün Kelimesi):</small><br>
|
| 67 |
+
<div style='margin-top: 10px;'>
|
| 68 |
+
<b style='font-size: 2em;'>{wotd_row['Kirm']}</b><br>
|
| 69 |
+
<div style='font-size: 1.1em; margin-top: 5px; color: #303f9f;'>{lang_html}</div>
|
| 70 |
+
</div>
|
| 71 |
+
</div>
|
| 72 |
+
"""
|
| 73 |
+
return f"<div style='text-align:center; margin-bottom: 10px; color: #555;'>{stats}</div>", wotd_html
|
| 74 |
+
|
| 75 |
+
js_speak = """
|
| 76 |
+
function speak(text) {
|
| 77 |
+
window.speechSynthesis.cancel();
|
| 78 |
+
const msg = new SpeechSynthesisUtterance(text);
|
| 79 |
+
msg.lang = 'tr-TR';
|
| 80 |
+
msg.rate = 0.5;
|
| 81 |
+
window.speechSynthesis.speak(msg);
|
| 82 |
+
}
|
| 83 |
+
"""
|
| 84 |
+
|
| 85 |
+
def suche(wort):
|
| 86 |
+
wort = str(wort).strip()
|
| 87 |
+
if len(wort) < 2: return "<p style='text-align:center; color:#777;'>✍️ Bınusnê...</p>"
|
| 88 |
+
if DF_GLOBAL is None: return "Hata."
|
| 89 |
+
|
| 90 |
+
mask = DF_GLOBAL.astype(str).apply(lambda x: x.str.contains(wort, case=False, na=False)).any(axis=1)
|
| 91 |
+
ergebnis = DF_GLOBAL[mask].head(50)
|
| 92 |
|
| 93 |
+
if ergebnis.empty: return "<h3 style='text-align:center;'>❌ Çino.</h3>"
|
|
|
|
| 94 |
|
| 95 |
+
html_output = ""
|
| 96 |
+
for _, row in ergebnis.iterrows():
|
| 97 |
+
clean_text = str(row['Kirm']).replace("'", "\\'")
|
| 98 |
+
kirm = markiere_rot(row['Kirm'], wort)
|
| 99 |
+
|
| 100 |
+
trans_lines = []
|
| 101 |
+
if str(row.get('Tr', '')).strip():
|
| 102 |
+
trans_lines.append(f"<div style='margin-bottom:2px;'><b>TR:</b> {markiere_rot(row['Tr'], wort)}</div>")
|
| 103 |
+
if str(row.get('De', '')).strip():
|
| 104 |
+
trans_lines.append(f"<div style='margin-bottom:2px;'><b>DE:</b> {markiere_rot(row['De'], wort)}</div>")
|
| 105 |
+
if str(row.get('En', '')).strip():
|
| 106 |
+
trans_lines.append(f"<div><b>EN:</b> {markiere_rot(row['En'], wort)}</div>")
|
| 107 |
+
|
| 108 |
html_output += f"""
|
| 109 |
+
<div style='margin-bottom: 25px; border-bottom: 1px solid #eee; padding-bottom: 15px;'>
|
| 110 |
+
<div style='display: flex; align-items: center; margin-bottom: 8px;'>
|
| 111 |
+
<h2 style='color:#1a237e; margin: 0 12px 0 0;'>☀️ {kirm}</h2>
|
| 112 |
+
<button onclick="speak('{clean_text}')" title="Gose de" style='cursor:pointer; background:transparent; border:none; font-size:1.3em; color:#1a237e;'>🎧</button>
|
| 113 |
+
</div>
|
| 114 |
+
<div style='color:#444; line-height: 1.6;'>
|
| 115 |
+
{"".join(trans_lines)}
|
| 116 |
+
</div>
|
| 117 |
</div>
|
| 118 |
"""
|
| 119 |
+
return html_output
|
| 120 |
|
| 121 |
+
logo_data = get_base64_image(LOGO_NAME)
|
| 122 |
+
|
| 123 |
+
custom_css = """
|
| 124 |
+
#search_input input {
|
| 125 |
+
border: 1px solid black !important;
|
| 126 |
+
box-shadow: none !important;
|
| 127 |
+
outline: 2px solid transparent !important;
|
| 128 |
+
}
|
| 129 |
+
#search_input input:focus {
|
| 130 |
+
border: 1.5px solid black !important;
|
| 131 |
+
}
|
| 132 |
+
footer { display: none !important; }
|
| 133 |
+
"""
|
| 134 |
|
| 135 |
+
with gr.Blocks(theme=gr.themes.Soft(primary_hue="indigo"), head=f"<script>{js_speak}</script>", css=custom_css) as demo:
|
|
|
|
| 136 |
with gr.Column():
|
| 137 |
+
if logo_data:
|
| 138 |
+
gr.HTML(f'<div style="text-align:center;"><img src="{logo_data}" width="420" style="margin: 0 auto; display: block;"></div>')
|
| 139 |
+
gr.HTML('<h1 style="text-align:center; margin-top: 10px;">DEZD Kırmancki Qesebend</h1>')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 140 |
|
| 141 |
+
# Diese Platzhalter werden beim Laden gefüllt
|
| 142 |
+
stats_display = gr.HTML()
|
| 143 |
+
wotd_display = gr.HTML()
|
| 144 |
+
|
| 145 |
+
suche_input = gr.Textbox(label="Cıgêyre / Ara", placeholder="Kelime gir...", autofocus=True, elem_id="search_input")
|
| 146 |
+
result_output = gr.HTML()
|
| 147 |
+
|
| 148 |
+
gr.HTML("""
|
| 149 |
+
<div style='text-align:center; margin-top: 50px; padding: 20px; border-top: 1px solid #eee; color: #555;'>
|
| 150 |
+
<p>📩 <a href="mailto:info@manidar.org">Xate vace</a> | 💬 <a href="mailto:info@manidar.org">Feedback</a></p>
|
| 151 |
+
<p style='margin-top: 15px; font-size: 1.1em;'><b>Raresnayoğe: Gülten Karaca</b></p>
|
| 152 |
</div>
|
| 153 |
+
""")
|
| 154 |
+
|
| 155 |
+
# Events
|
| 156 |
+
suche_input.change(fn=suche, inputs=suche_input, outputs=result_output)
|
| 157 |
+
|
| 158 |
+
# DAS IST NEU: Lädt Statistiken und Wort des Tages dynamisch beim Seitenaufruf
|
| 159 |
+
demo.load(fn=get_header_data_dynamic, outputs=[stats_display, wotd_display])
|
| 160 |
|
| 161 |
+
demo.launch()
|
|
|