Skip to content

Instantly share code, notes, and snippets.

@Ziaeemehr
Created October 28, 2025 08:08
Show Gist options
  • Select an option

  • Save Ziaeemehr/d677dcedc4f1daec90dd497b1de3cd81 to your computer and use it in GitHub Desktop.

Select an option

Save Ziaeemehr/d677dcedc4f1daec90dd497b1de3cd81 to your computer and use it in GitHub Desktop.
anki_add_tts
import base64
import os
import re
import time
from gtts import gTTS
import requests
from tqdm import tqdm
# -----------------------------
DECK_NAME = "Edito_A2_2022"
FRONT_FIELD = "Front" # فیلدی که متن فرانسوی در آن است
FIELD_NAME = "Front" # فیلدی که صدا به آن افزوده می‌شود
LANG = "fr"
TTS_SLOW = False
SLEEP_TIME = 0.5
CACHE_DIR = "tts_cache"
# -----------------------------
os.makedirs(CACHE_DIR, exist_ok=True)
def invoke(action, **params):
r = requests.post("http://localhost:8765", json={
"action": action,
"version": 6,
"params": params
}).json()
if r.get("error"):
raise Exception(r["error"])
return r["result"]
def strip_html(text):
return re.sub(r"<.*?>", "", text).strip()
# 1️⃣ یافتن کارت‌ها
cards = invoke("findCards", query=f'deck:"{DECK_NAME}"')
print(f"✅ {len(cards)} کارت در دک '{DECK_NAME}' یافت شد.\n")
# 2️⃣ استخراج note ID ها از کارت‌ها
notes = invoke("cardsToNotes", cards=cards)
notes_info = invoke("notesInfo", notes=notes)
for note in tqdm(notes_info, desc="🔊 در حال تولید تلفظ‌ها"):
note_id = note["noteId"]
fields = note["fields"]
front_text = fields.get(FRONT_FIELD, {}).get("value", "")
if not front_text.strip():
continue
# اگر صدا از قبل در فیلد هست → رد کن
if "[sound:" in fields.get(FIELD_NAME, {}).get("value", ""):
continue
clean_text = strip_html(front_text)
if not clean_text:
continue
# 🧠 فایل cache
filename = f"{clean_text}.mp3".replace(" ", "_").replace("/", "_")
audio_path = os.path.join(CACHE_DIR, filename)
# اگر فایل قبلاً ساخته شده، دوباره نساز
if not os.path.exists(audio_path):
try:
tts = gTTS(clean_text, lang=LANG, slow=TTS_SLOW)
tts.save(audio_path)
time.sleep(SLEEP_TIME)
except Exception as e:
print(f"\n⚠️ خطا در ساخت صدا برای '{clean_text}': {e}")
continue
# 📤 بارگذاری به Anki
with open(audio_path, "rb") as f:
audio_b64 = base64.b64encode(f.read()).decode()
invoke("storeMediaFile", filename=filename, data=audio_b64)
# ✏️ افزودن تگ صدا به فیلد
sound_tag = f"[sound:{filename}]"
new_value = fields[FIELD_NAME]["value"] + "<br>" + sound_tag
invoke("updateNoteFields", note={"id": note_id, "fields": {FIELD_NAME: new_value}})
print("\n✅ تمام تلفظ‌ها اضافه شدند (با پشتیبانی Cache).")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment