import os import random import genanki from datetime import datetime from typing import List, Tuple, Optional from .models import GermanWord, UnsplashImage from .clients.llm import AnthropicClient from .clients.unsplash import UnsplashClient class GermanDeckPackage(genanki.Package): """Custom Package class to include media files""" def __init__(self, deck, media_files): super().__init__(deck) self.media_files = media_files class CardGenerator: def __init__(self, llm_client: AnthropicClient, unsplash_client: UnsplashClient): self.llm_client = llm_client self.unsplash_client = unsplash_client self.model = self._create_model() def _create_model(self): """Create the Anki note model""" return genanki.Model( random.randrange(1 << 30, 1 << 31), 'German Vocabulary Model', fields=[ {'name': 'German_Word'}, {'name': 'Part_of_Speech'}, {'name': 'Source'}, {'name': 'English_Meaning'}, {'name': 'Article'}, {'name': 'Plural_Form'}, {'name': 'Example_Sentence'}, {'name': 'Sentence_Translation'}, {'name': 'Usage_Notes'}, {'name': 'Related_Words'}, {'name': 'Image'}, {'name': 'Image_Credit'}, {'name': 'Tags'} ], templates=[ { 'name': 'German Vocabulary Card', 'qfmt': '''
{{German_Word}}
Part of speech: {{Part_of_Speech}}
Source: {{Source}}
{{#Image}}
{{/Image}} ''', 'afmt': ''' {{FrontSide}}
English meaning: {{English_Meaning}}
Article: {{Article}}
Plural Form: {{Plural_Form}}
Example: {{Example_Sentence}}
Translation: {{Sentence_Translation}}
Usage notes: {{Usage_Notes}}
Related words: {{Related_Words}}
{{#Image_Credit}}
Photo: {{Image_Credit}}
{{/Image_Credit}}
Tags: {{Tags}}
''' } ], css=''' .card { font-family: arial; font-size: 16px; text-align: center; color: black; background-color: white; } img { margin: 20px auto; border-radius: 5px; box-shadow: 0 2px 5px rgba(0,0,0,0.2); } ''' ) def create_deck(self, word_list: List[Tuple[str, str]], deck_name: str = "German Vocabulary") -> Tuple[genanki.Deck, List[str]]: """Create an Anki deck from a list of words""" deck_id = random.randrange(1 << 30, 1 << 31) deck = genanki.Deck(deck_id, deck_name) media_files = [] for word, source in word_list: try: card_info_dict = self.llm_client.get_card_info(word, source) card_info = GermanWord(**card_info_dict) # Get image image_filename = f"media/{word.lower().replace(' ', '_')}.jpg" image = self.unsplash_client.get_image( card_info.image_search_term, image_filename ) if image and image.local_path: media_files.append(image.local_path) image_filename = os.path.basename(image.local_path) else: image_filename = "" # Create note note = genanki.Note( model=self.model, fields=[ card_info.german_word, card_info.part_of_speech, source, card_info.english_meaning, card_info.article or "", card_info.plural_form, card_info.example_sentence, card_info.sentence_translation, card_info.usage_notes, card_info.related_words, image_filename, image.photographer if image else "", ' '.join(card_info.tags) ] ) deck.add_note(note) print(f"Added card for: {word}") except Exception as e: print(f"Error creating card for {word}: {str(e)}") return deck, media_files