Created
August 3, 2024 17:57
-
-
Save DDRBoxman/46f6dd6bac813e12966216123c312955 to your computer and use it in GitHub Desktop.
Anki add matched audio files
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from aqt import mw | |
from aqt.qt import * | |
from anki.hooks import addHook | |
import os | |
import unicodedata | |
def add_media_to_cards(deck_name, field_name, media_folder, target_field): | |
# Function to normalize Unicode strings | |
def normalize(s): | |
return unicodedata.normalize('NFC', s) | |
# Get the deck ID | |
deck_id = mw.col.decks.id(deck_name) | |
if not deck_id: | |
raise ValueError(f"Deck '{deck_name}' not found.") | |
# Get the cards in the deck | |
card_ids = mw.col.db.list("select id from cards where did = ?", deck_id) | |
if not card_ids: | |
raise ValueError("No cards found in the specified deck.") | |
# Preload media files dictionary with normalized names | |
media_files = {} | |
for filename in os.listdir(media_folder): | |
base_name, ext = os.path.splitext(filename) | |
if ext.lower() not in ['.mp3', '.wav', '.ogg']: | |
continue | |
normalized_name = normalize(base_name.split(" - ", 1)[-1]) | |
media_files[normalized_name] = filename | |
# Print loaded media files for debugging | |
print("Loaded media files:", media_files) | |
# Iterate over each card | |
for cid in card_ids: | |
card = mw.col.get_card(cid) | |
note = card.note() | |
# Get the content of the specified field | |
if field_name not in note: | |
continue # Skip cards without the field | |
field_value = normalize(note[field_name].strip()) | |
if not field_value: | |
continue # Skip cards with an empty field | |
# Debugging: Print the field value being searched | |
print(f"Searching for file containing '{field_value}'") | |
# Find the file match | |
matched_file = None | |
for normalized_name, filename in media_files.items(): | |
if field_value in normalized_name: | |
matched_file = os.path.join(media_folder, filename) | |
break | |
if matched_file: | |
# Debugging: Print the found file path | |
print(f"Found file '{matched_file}' for '{field_value}'") | |
# Add the file as media to the card | |
try: | |
stored_filename = mw.col.media.add_file(matched_file) | |
note[target_field] = f"[sound:{stored_filename}]" | |
except Exception as e: | |
print(f"Error adding media file '{matched_file}': {e}") | |
else: | |
print(f"File for '{field_value}' not found in '{media_folder}'.") | |
# Save changes to the note | |
try: | |
mw.col.update_note(note) | |
except Exception as e: | |
print(f"Error updating note for field value '{field_value}': {e}") | |
# Example usage: | |
def on_run_action(): | |
deck_name = "Pokemon Names" | |
field_name = "Japanese" | |
media_folder = "/Users/ddrboxman/Downloads/日本語/" | |
target_field = "Pronunciation" # Updated to the correct target field | |
try: | |
add_media_to_cards(deck_name, field_name, media_folder, target_field) | |
QMessageBox.information(mw, "Success", "Media added to cards successfully.") | |
except Exception as e: | |
QMessageBox.critical(mw, "Error", str(e)) | |
# This will add a menu item to run your script from the Tools menu | |
def add_menu_item(): | |
action = QAction("Add Media to Cards", mw) | |
action.triggered.connect(on_run_action) | |
mw.form.menuTools.addAction(action) | |
addHook("profileLoaded", add_menu_item) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment