kerrickstaley / genanki

A Python 3 library for generating Anki decks
MIT License
1.97k stars 149 forks source link

Cards created with genanki dont sync correctly to the mobile version #117

Closed JamesKnochen closed 7 months ago

JamesKnochen commented 1 year ago

Description The cards i created using genanki dont sync correctly to the mobile version of anki. I tried different types of cards and none of them work.

To reproduce Create a deck of cards with genanki. Import the deck to anki over your computer and create a few cards maunally for comparrison. Sync the deck with your anki mobile app.

Expected behavior The cards should be displayed exactly like on the computer Question: "Yes" Answer: "si"

Actual behavior Cards created with genanki are not displayed correctly. Question: "Card 1" Answer: "Card 1si" Cards which were created manually are displayed correctly. All cards are displayed correctly on the computer

kerrickstaley commented 1 year ago

Can you upload some code that generates the deck that is causing the problem?

JamesKnochen commented 1 year ago

The program is supposed to scrape a website for vocabulary and create anki cards with it. One audio file with the pronunciation is created for every card.

from bs4 import BeautifulSoup
import requests
import genanki
from gtts import gTTS
import os
import random

# Wörter von der Tabelle einlesen und in eine Liste tun
def get_words():
    url = "https://www.sprachheld.de/grundwortschatz-spanisch-wichtigste-vokabeln/"
    website = requests.get(url).text
    html = BeautifulSoup(website, "html.parser")
    daten = html.find_all("td")

    result = []
    for i in range(0, len(daten), 2):
        zelle = daten[i:i + 2]
        zelle[0] = zelle[0].string
        zelle[1] = zelle[1].string
        result.append(zelle)
        print(zelle)
    return result

def create_flashcard_deck(data_list, deck_name):
    """
    Creates a deck of Anki flashcards with basic and reverse card types.
    'data_list' is a two-dimensional list of strings, where each inner list
    represents a card and its corresponding answer.
    'deck_name' is the name of the deck to be created.
    """
    # Define the model for the deck
    model_name = deck_name + " Model"
    model_id=random.randrange(1 << 30, 1 << 31)
    Model = genanki.Model(
        model_id,
        model_name,
        fields=[{"name": "Card"}, {"name": "Answer"}],
        templates=[
            {
                "name": "Card 1",
                "qfmt": "<div style='font-family: Arial; font-size: 30px; font-weight: bold;'>{{Card}}</div>",
                "afmt": "<div style='font-family: Arial; font-size: 30px; font-weight: bold;'>{{FrontSide}}<hr id='answer'><div style='font-size: 30px;'>{{Answer}}</div></div>",
            },
            {
                "name": "Card 2",
                "qfmt": "<div style='font-family: Arial; font-size: 30px; font-weight: bold;'>{{Answer}}</div>",
                "afmt": "<div style='font-family: Arial; font-size: 30px; font-weight: bold;'>{{FrontSide}}<hr id='answer'><div style='font-size: 30px;'>{{Card}}</div></div>",
            },
        ],
    )

    # Define the deck and add the cards
    deck_id = random.randrange(1 << 30, 1 << 31)
    Deck = genanki.Deck(
        1,
        deck_name,
    )

    # Create the package
    my_package = genanki.Package(Deck)
    my_package.media_files = []

    # Create card
    i = 1
    for data_pair in data_list:

        # Generate the audio file for the answer using gTTS
        tts = gTTS(text=data_pair[1], lang="es")
        audio_file = f"{deck_name}_audio{i}.mp3"  # Limit the filename to the first 10 characters of the answer
        tts.save(audio_file)
        my_package.media_files.append(audio_file)

        card = genanki.Note(
            model=Model,
            fields=[data_pair[0], f"{data_pair[1]} [sound:{audio_file}]"]
        )
        Deck.add_note(card)
        print(f"Karte erstellt {data_pair[0]} : {data_pair[1]} [sound:{audio_file}]")

        i += 1

    # export the deck to a .apkg file
    my_package.write_to_file(f"{deck_name}.apkg")
    print ("Deck erzeugt")

    # Delete the generated audio files
    for media_file in my_package.media_files:
        os.remove(media_file)

wort_liste = get_words()

deck_name = "Spanish Grundwortschatz mit Audio"
create_flashcard_deck(wort_liste, deck_name)
kerrickstaley commented 1 year ago

Can you provide a minimal, reproducible example? Something that doesn’t make network requests.

kerrickstaley commented 7 months ago

Closing for now; please re-open if you're able to give a smaller example that demonstrates the bug.