chore: disable legacy audio proxy and hide audio controls
This commit is contained in:
1 parent
4e52cab88e
commit
dae0d525c7
4 files changed
+21
-90
No files matched your search
+4
-7
@@ -46,7 +46,7 @@ async def fetch_wiktionary_wikitext(word: str) -> Dict[str, Any]:
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
"ipa": ipa_cleaned,
|
"ipa": ipa_cleaned,
|
||||||
"audio": audio_matches,
|
"audio": [],
|
||||||
"ru_translations": ru_cleaned
|
"ru_translations": ru_cleaned
|
||||||
}
|
}
|
||||||
except Exception:
|
except Exception:
|
||||||
@@ -232,12 +232,9 @@ async def lookup_term(query: str) -> Dict[str, Any]:
|
|||||||
elif d_muse.get("ipa"):
|
elif d_muse.get("ipa"):
|
||||||
result["phonetic"] = d_muse["ipa"]
|
result["phonetic"] = d_muse["ipa"]
|
||||||
|
|
||||||
# 2. Audio URL / File
|
# 2. Audio URL / File (Disabled)
|
||||||
if free_dict.get("audio_url"):
|
result["audio_file"] = ""
|
||||||
result["audio_url"] = free_dict["audio_url"]
|
result["audio_url"] = ""
|
||||||
elif w_wiki.get("audio"):
|
|
||||||
result["audio_file"] = w_wiki["audio"][0]
|
|
||||||
result["audio_url"] = f"/api/audio?file={urllib.parse.quote(result['audio_file'])}"
|
|
||||||
|
|
||||||
# 3. Part of Speech
|
# 3. Part of Speech
|
||||||
if w_defs.get("parts_of_speech"):
|
if w_defs.get("parts_of_speech"):
|
||||||
|
|||||||
+3
-23
@@ -285,29 +285,9 @@ async def api_lookup(
|
|||||||
|
|
||||||
|
|
||||||
@app.api_route("/api/audio", methods=["GET", "HEAD"])
|
@app.api_route("/api/audio", methods=["GET", "HEAD"])
|
||||||
async def api_audio_proxy(url: str = Query(..., min_length=1), user: dict = Depends(require_user)):
|
async def api_audio_proxy():
|
||||||
try:
|
# Audio feature disabled
|
||||||
parsed = urllib.parse.urlparse(url)
|
return Response(status_code=204)
|
||||||
if parsed.scheme not in ("http", "https"):
|
|
||||||
raise HTTPException(status_code=400, detail="Invalid audio URL scheme")
|
|
||||||
if not parsed.netloc:
|
|
||||||
raise HTTPException(status_code=400, detail="Invalid audio host")
|
|
||||||
except Exception:
|
|
||||||
raise HTTPException(status_code=400, detail="Malformed audio URL")
|
|
||||||
|
|
||||||
try:
|
|
||||||
async with httpx.AsyncClient(timeout=10.0, follow_redirects=True) as client:
|
|
||||||
audio_resp = await client.get(url, headers={"User-Agent": USER_AGENT})
|
|
||||||
if audio_resp.status_code != 200:
|
|
||||||
raise HTTPException(status_code=audio_resp.status_code, detail="Audio upstream error")
|
|
||||||
media_type = audio_resp.headers.get("Content-Type", "audio/mpeg")
|
|
||||||
return Response(
|
|
||||||
content=audio_resp.content,
|
|
||||||
media_type=media_type,
|
|
||||||
headers={"Cache-Control": "public, max-age=604800"},
|
|
||||||
)
|
|
||||||
except Exception as e:
|
|
||||||
raise HTTPException(status_code=502, detail=f"Failed to fetch audio: {str(e)}")
|
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -125,7 +125,7 @@
|
|||||||
<div class="lookup-term-group">
|
<div class="lookup-term-group">
|
||||||
<h2 id="res-term" class="res-term">Word</h2>
|
<h2 id="res-term" class="res-term">Word</h2>
|
||||||
<span id="res-phonetic" class="res-phonetic">/wɜːd/</span>
|
<span id="res-phonetic" class="res-phonetic">/wɜːd/</span>
|
||||||
<button id="audio-play-btn" class="icon-btn audio-btn hidden" title="Прослушать произношение">🔊</button>
|
<button id="audio-play-btn" class="icon-btn audio-btn hidden" style="display: none;" title="Прослушать произношение">🔊</button>
|
||||||
</div>
|
</div>
|
||||||
<span id="res-pos" class="badge-pos">Noun</span>
|
<span id="res-pos" class="badge-pos">Noun</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -236,7 +236,7 @@
|
|||||||
<button class="srs-tab" data-mode="quiz">🎯 4 Варианта</button>
|
<button class="srs-tab" data-mode="quiz">🎯 4 Варианта</button>
|
||||||
<button class="srs-tab" data-mode="typing">✍️ Набор слова</button>
|
<button class="srs-tab" data-mode="typing">✍️ Набор слова</button>
|
||||||
<button class="srs-tab" data-mode="cloze">🧩 Пропуски</button>
|
<button class="srs-tab" data-mode="cloze">🧩 Пропуски</button>
|
||||||
<button class="srs-tab" data-mode="dictation">🎧 Диктант</button>
|
<button class="srs-tab" data-mode="dictation" style="display: none;">🎧 Диктант</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -290,7 +290,7 @@
|
|||||||
<h1 class="fc-main-term" id="fc-front-main">reluctant</h1>
|
<h1 class="fc-main-term" id="fc-front-main">reluctant</h1>
|
||||||
<div class="fc-phonetic-row" id="fc-front-phonetic-wrap">
|
<div class="fc-phonetic-row" id="fc-front-phonetic-wrap">
|
||||||
<span class="res-phonetic" id="fc-front-phonetic">/rɪˈlʌktənt/</span>
|
<span class="res-phonetic" id="fc-front-phonetic">/rɪˈlʌktənt/</span>
|
||||||
<button id="fc-front-audio-btn" class="icon-btn audio-round-btn" title="Озвучить (Ctrl+P / 🔊)">🔊</button>
|
<button id="fc-front-audio-btn" class="icon-btn audio-round-btn" style="display: none;" title="Озвучить (Ctrl+P / 🔊)">🔊</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="fc-hint-wrapper">
|
<div class="fc-hint-wrapper">
|
||||||
<button id="fc-hint-btn" class="btn btn-xs btn-ghost">💡 Показать контекст</button>
|
<button id="fc-hint-btn" class="btn btn-xs btn-ghost">💡 Показать контекст</button>
|
||||||
@@ -311,7 +311,7 @@
|
|||||||
<div class="fc-back-content">
|
<div class="fc-back-content">
|
||||||
<div class="fc-back-top">
|
<div class="fc-back-top">
|
||||||
<h2 class="fc-back-term" id="fc-back-term">reluctant</h2>
|
<h2 class="fc-back-term" id="fc-back-term">reluctant</h2>
|
||||||
<button id="fc-back-audio-btn" class="icon-btn audio-round-btn" title="Озвучить">🔊</button>
|
<button id="fc-back-audio-btn" class="icon-btn audio-round-btn" style="display: none;" title="Озвучить">🔊</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="fc-back-translation" id="fc-back-translation">неохотный, нежелающий</div>
|
<div class="fc-back-translation" id="fc-back-translation">неохотный, нежелающий</div>
|
||||||
<div class="fc-back-detail-box" id="fc-back-def-box">
|
<div class="fc-back-detail-box" id="fc-back-def-box">
|
||||||
@@ -372,7 +372,7 @@
|
|||||||
<div class="quiz-hero">
|
<div class="quiz-hero">
|
||||||
<div class="quiz-prompt-row">
|
<div class="quiz-prompt-row">
|
||||||
<h2 id="quiz-term-display" class="quiz-term-display">word</h2>
|
<h2 id="quiz-term-display" class="quiz-term-display">word</h2>
|
||||||
<button id="quiz-audio-btn" class="icon-btn audio-round-btn" title="Озвучить">🔊</button>
|
<button id="quiz-audio-btn" class="icon-btn audio-round-btn" style="display: none;" title="Озвучить">🔊</button>
|
||||||
</div>
|
</div>
|
||||||
<div id="quiz-phonetic-display" class="res-phonetic"></div>
|
<div id="quiz-phonetic-display" class="res-phonetic"></div>
|
||||||
<div id="quiz-context-hint" class="quiz-context-hint hidden"></div>
|
<div id="quiz-context-hint" class="quiz-context-hint hidden"></div>
|
||||||
@@ -588,7 +588,7 @@
|
|||||||
<div class="popup-term-wrap">
|
<div class="popup-term-wrap">
|
||||||
<strong id="popup-term" class="popup-term">word</strong>
|
<strong id="popup-term" class="popup-term">word</strong>
|
||||||
<span id="popup-phonetic" class="popup-phonetic">/wɜːd/</span>
|
<span id="popup-phonetic" class="popup-phonetic">/wɜːd/</span>
|
||||||
<button id="popup-audio-btn" class="icon-btn audio-btn" title="Слушать произношение">🔊</button>
|
<button id="popup-audio-btn" class="icon-btn audio-btn" style="display: none;" title="Слушать произношение">🔊</button>
|
||||||
</div>
|
</div>
|
||||||
<button id="popup-close-btn" class="popup-close-btn">✕</button>
|
<button id="popup-close-btn" class="popup-close-btn">✕</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+8
-54
@@ -330,16 +330,11 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
// Audio Player Helper
|
// Audio Player Helper (Disabled)
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
function playAudio(url) {
|
function playAudio(url) {
|
||||||
if (!url) return;
|
// Audio playback disabled
|
||||||
try {
|
return;
|
||||||
globalAudioPlayer.src = url;
|
|
||||||
globalAudioPlayer.play().catch(e => console.log('Audio playback error:', e));
|
|
||||||
} catch (e) {
|
|
||||||
console.log('Audio error:', e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
@@ -576,15 +571,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
resPhonetic.textContent = data.phonetic || '';
|
resPhonetic.textContent = data.phonetic || '';
|
||||||
resPhonetic.style.display = data.phonetic ? 'inline-block' : 'none';
|
resPhonetic.style.display = data.phonetic ? 'inline-block' : 'none';
|
||||||
resPos.textContent = data.part_of_speech || 'Phrase';
|
resPos.textContent = data.part_of_speech || 'Phrase';
|
||||||
|
audioPlayBtn.classList.add('hidden');
|
||||||
if (data.audio_url) {
|
|
||||||
audioPlayBtn.classList.remove('hidden');
|
|
||||||
audioPlayBtn.onclick = () => playAudio(data.audio_url);
|
|
||||||
// Auto play once
|
|
||||||
playAudio(data.audio_url);
|
|
||||||
} else {
|
|
||||||
audioPlayBtn.classList.add('hidden');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.definition_en) {
|
if (data.definition_en) {
|
||||||
resDefinition.textContent = data.definition_en;
|
resDefinition.textContent = data.definition_en;
|
||||||
@@ -761,7 +748,6 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
<span class="card-term">${escapeHtml(c.term)}</span>
|
<span class="card-term">${escapeHtml(c.term)}</span>
|
||||||
${c.phonetic ? `<span class="card-phonetic">${escapeHtml(c.phonetic)}</span>` : ''}
|
${c.phonetic ? `<span class="card-phonetic">${escapeHtml(c.phonetic)}</span>` : ''}
|
||||||
${c.part_of_speech ? `<span class="card-pos">${escapeHtml(c.part_of_speech)}</span>` : ''}
|
${c.part_of_speech ? `<span class="card-pos">${escapeHtml(c.part_of_speech)}</span>` : ''}
|
||||||
${c.audio_url ? `<button class="icon-btn audio-btn audio-inline-btn" data-audio="${encodeURIComponent(c.audio_url)}" title="Озвучить">🔊</button>` : ''}
|
|
||||||
</div>
|
</div>
|
||||||
<div class="card-actions">
|
<div class="card-actions">
|
||||||
<button class="icon-btn edit-card-btn" data-id="${c.id}" title="Редактировать">✏️</button>
|
<button class="icon-btn edit-card-btn" data-id="${c.id}" title="Редактировать">✏️</button>
|
||||||
@@ -779,15 +765,6 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
// Inline audio button
|
|
||||||
const audioBtn = cardEl.querySelector('.audio-inline-btn');
|
|
||||||
if (audioBtn) {
|
|
||||||
audioBtn.addEventListener('click', (e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
playAudio(decodeURIComponent(audioBtn.dataset.audio));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Edit button
|
// Edit button
|
||||||
cardEl.querySelector('.edit-card-btn').addEventListener('click', (e) => {
|
cardEl.querySelector('.edit-card-btn').addEventListener('click', (e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
@@ -1106,15 +1083,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
fcBackNotes.textContent = card.notes || '';
|
fcBackNotes.textContent = card.notes || '';
|
||||||
fcBackNotesBox.style.display = card.notes ? 'block' : 'none';
|
fcBackNotesBox.style.display = card.notes ? 'block' : 'none';
|
||||||
|
|
||||||
if (card.audio_url) {
|
fcFrontAudioBtn.style.display = 'none';
|
||||||
fcFrontAudioBtn.style.display = 'inline-flex';
|
fcBackAudioBtn.style.display = 'none';
|
||||||
fcBackAudioBtn.style.display = 'inline-flex';
|
|
||||||
fcFrontAudioBtn.onclick = (e) => { e.stopPropagation(); playAudio(card.audio_url); };
|
|
||||||
fcBackAudioBtn.onclick = (e) => { e.stopPropagation(); playAudio(card.audio_url); };
|
|
||||||
} else {
|
|
||||||
fcFrontAudioBtn.style.display = 'none';
|
|
||||||
fcBackAudioBtn.style.display = 'none';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function flipFlashcard() {
|
function flipFlashcard() {
|
||||||
@@ -1123,11 +1093,6 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
flashcardInner.classList.add('is-flipped');
|
flashcardInner.classList.add('is-flipped');
|
||||||
fcRatingBar.classList.remove('hidden');
|
fcRatingBar.classList.remove('hidden');
|
||||||
fcFlipBtnWrap.style.display = 'none';
|
fcFlipBtnWrap.style.display = 'none';
|
||||||
|
|
||||||
const card = srsQueue[srsCurrentIndex];
|
|
||||||
if (card && card.audio_url) {
|
|
||||||
playAudio(card.audio_url);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
flashcardFlipWrap.addEventListener('click', flipFlashcard);
|
flashcardFlipWrap.addEventListener('click', flipFlashcard);
|
||||||
@@ -1186,13 +1151,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
quizContextHint.classList.add('hidden');
|
quizContextHint.classList.add('hidden');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (card.audio_url) {
|
quizAudioBtn.classList.add('hidden');
|
||||||
quizAudioBtn.classList.remove('hidden');
|
|
||||||
quizAudioBtn.onclick = () => playAudio(card.audio_url);
|
|
||||||
playAudio(card.audio_url);
|
|
||||||
} else {
|
|
||||||
quizAudioBtn.classList.add('hidden');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate 4 options: target + 3 random from other cards or presets
|
// Generate 4 options: target + 3 random from other cards or presets
|
||||||
const correctText = card.translation;
|
const correctText = card.translation;
|
||||||
@@ -2000,12 +1959,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
popupLoading.classList.add('hidden');
|
popupLoading.classList.add('hidden');
|
||||||
popupContent.classList.remove('hidden');
|
popupContent.classList.remove('hidden');
|
||||||
|
|
||||||
if (data.audio_url) {
|
popupAudioBtn.classList.add('hidden');
|
||||||
popupAudioBtn.classList.remove('hidden');
|
|
||||||
popupAudioBtn.onclick = () => playAudio(data.audio_url);
|
|
||||||
} else {
|
|
||||||
popupAudioBtn.classList.add('hidden');
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
popupTranslation.textContent = 'Ошибка перевода';
|
popupTranslation.textContent = 'Ошибка перевода';
|
||||||
popupLoading.classList.add('hidden');
|
popupLoading.classList.add('hidden');
|
||||||
|
|||||||
Reference in new issue
Block a user