diff --git a/src/anki_hsk_creator/__about__.py b/src/anki_hsk_creator/__about__.py index fa228b1..0fffff4 100644 --- a/src/anki_hsk_creator/__about__.py +++ b/src/anki_hsk_creator/__about__.py @@ -3,4 +3,4 @@ # SPDX-FileCopyrightText: 2026-present Wolfang Torres # # SPDX-License-Identifier: GPL-3.0-or-later -__version__ = "0.2.0" +__version__ = "0.2.1" diff --git a/src/anki_hsk_creator/anki_generation.py b/src/anki_hsk_creator/anki_generation.py index 3791e6b..7c460ca 100644 --- a/src/anki_hsk_creator/anki_generation.py +++ b/src/anki_hsk_creator/anki_generation.py @@ -13,6 +13,7 @@ from pinyin_tone_converter.pinyin_tone_converter import PinyinToneConverter # Local from .utility import DictionaryResult, ProcessFile, ProcessFolder, TranslationResult +from .constants import DICT_TYPE, DICTATION_TYPE, PHRASES_TYPE # Constants @@ -241,31 +242,60 @@ def output_anki_phrase( def output_anki_package( process_folder: ProcessFolder, results: dict[ProcessFile, list[TranslationResult]] ): - final_file = process_file.output_name.with_suffix(".apkg") + final_file = process_folder.output_name.with_suffix(".apkg") decks = [] audios = [] for process_file, results in results.items(): deck_name = "::".join( - ProcessFolder.input_folder.parts[:-1] + (ProcessFolder.output_name.stem,) + process_file.input_file.parts[:-1] + (process_file.output_name.stem,) ) deck = Deck( random.randrange(1 << 30, 1 << 31), deck_name, - f"Deck for {final_file.name}, " + f"Deck for {process_file.input_file}, " "created in https://www.wolfang.info.ve/hskankicreator/", ) - for result in results: - note = Note( - model=DICTATION_MODEL, - fields=[ - result.translated, - result.line, - f"[sound:{result.audio_path}]", - ], - ) - deck.add_note(note) - audios.append(result.audio_path) + if process_file.file_type is DICTATION_TYPE: + for result in results: + note = Note( + model=DICTATION_MODEL, + fields=[ + result.translated, + result.line, + f"[sound:{result.audio_path}]", + ], + ) + deck.add_note(note) + audios.append(result.audio_path) + elif process_file.file_type is DICT_TYPE: + for result in results: + note = Note( + model=HSK_MODEL, + fields=[ + # "\n ".join(f"{n+1}. {m}" for n, m in enumerate(result.meanings)), + result.meaning, + PinyinToneConverter().convert_text(result.pinyin), + result.simplified, + result.traditional, + f"[sound:{result.audio_path}]", + ], + ) + deck.add_note(note) + audios.append(result.audio_path) + elif process_file.file_type is PHRASES_TYPE: + for result in results: + note = Note( + model=PHRASE_MODEL, + fields=[ + result.translated, + result.line, + f"[sound:{result.audio_path}]", + ], + ) + deck.add_note(note) + audios.append(result.audio_path) decks.append(deck) - package = Package(decks) - package.media_files = audios - package.write_to_file(final_file) + package = Package(decks) + package.media_files = audios + package.write_to_file(final_file) + return final_file diff --git a/src/anki_hsk_creator/api.py b/src/anki_hsk_creator/api.py index 8345fdc..7ec203d 100644 --- a/src/anki_hsk_creator/api.py +++ b/src/anki_hsk_creator/api.py @@ -12,6 +12,7 @@ from .anki_generation import ( output_anki_dictation, output_anki_dictionary, output_anki_phrase, + output_anki_package, ) from .constants import ( DICTATION_TYPE, @@ -84,7 +85,7 @@ def select_file(file_path: Path) -> ProcessFile: def select_folder(file_path: Path) -> ProcessFile: """Given a relative path from `list_input_files`, return a ProcessFile""" if (INPUT / file_path).is_dir(): - return ProcessFile(file_path) + return ProcessFolder(file_path) else: raise ValueError(f"{file_path} is not a folder") @@ -254,25 +255,27 @@ def folder_proccess(process_folder: ProcessFolder, language_id: str): TRANS.create_translator(LANGUAGES.CN, language_id) CCCEDICT.create_cedict(language_id) results = {} - for file in process_folder.input_files: - if file.file_type is DICT_TYPE: - with file.absolute_input_file.open( + for process_file in process_folder.input_files: + print(f"Proccessing {process_file}") + if process_file.file_type is DICT_TYPE: + with process_file.absolute_input_file.open( "r", encoding="utf8", newline="\n" ) as file: words_list = [word.strip() for word in file.readlines() if word] - dictionary_bulk_process(words_list, file) - results[file] = dictionary_process(file) - elif file.file_type is DICTATION_TYPE: - with file.absolute_input_file.open( + dictionary_bulk_process(words_list, process_file) + results[process_file] = dictionary_process(process_file) + elif process_file.file_type is DICTATION_TYPE: + with process_file.absolute_input_file.open( "r", encoding="utf8", newline="\n" ) as file: text_lines = [ line.strip() for line in file.read().split("。") if line.strip() ] - results[file] = dictation_process(text_lines, file) - elif file.file_type is PHRASES_TYPE: - with file.absolute_input_file.open( + results[process_file] = dictation_process(text_lines, process_file) + elif process_file.file_type is PHRASES_TYPE: + with process_file.absolute_input_file.open( "r", encoding="utf8", newline="\n" ) as file: text_lines = [line.strip() for line in file.readlines() if line.strip()] - results[file] = translator_process(text_lines, file) + results[process_file] = translator_process(text_lines, process_file) + return output_anki_package(process_folder, results) diff --git a/src/anki_hsk_creator/proccessor.py b/src/anki_hsk_creator/proccessor.py index 4ffc727..55767f3 100644 --- a/src/anki_hsk_creator/proccessor.py +++ b/src/anki_hsk_creator/proccessor.py @@ -14,7 +14,7 @@ from .utility import CCCEDICT, TTS, DictionaryResult, ProcessFile, TranslationRe # Constants -FIELDNAMES = ["n" "simplified", "traditional", "pinyin", "meaning"] +FIELDNAMES = ["n", "simplified", "traditional", "pinyin", "meaning"] DIALECT = "excel-tab" # Results Classes @@ -80,38 +80,36 @@ def dictionary_bulk_process(words_list: list[str], process_file: ProcessFile): [ entry for entry in entries - for meaning in entry.meaning + for meaning in entry.meanings if hint in meaning ] if hint else [] ) pos_entries = pos_meanings or entries - meanings = "\n".join( - f"{i} - {entry.meaning}" for i, entry in enumerate(pos_entries) - ) + meanings = [] + for entry in pos_entries: + for meaning in entry.meanings: + if hint and hint in meaning: + meanings.append(meaning) + if not meanings: + meanings = [ + meaning for entry in pos_entries for meaning in entry.meanings + ] + meanings_text = meanings[0] tsv_writer.writerow( { - "n": n, + "n": number, "simplified": entry.simplified, "traditional": entry.traditional, "pinyin": entry.pinyin, - "meaning": meanings, + "meaning": meanings_text, } ) else: print("============================================") print(f"===================>ERROR: {word} not found") print("============================================") - tsv_writer.writerow( - { - "n": number, - "simplified": word, - "traditional": None, - "pinyin": None, - "meaning": None, - } - ) number += 1 @@ -163,7 +161,7 @@ def dictionary_pre_process(words_list: list[str], process_file: ProcessFile): print("============================================") tsv_writer.writerow( { - "n": n, + "n": number, "simplified": word, "traditional": None, "pinyin": None, diff --git a/src/anki_hsk_creator/utility.py b/src/anki_hsk_creator/utility.py index 83ca6e0..55b2d61 100644 --- a/src/anki_hsk_creator/utility.py +++ b/src/anki_hsk_creator/utility.py @@ -161,7 +161,6 @@ class TTS: DEVICE = None DEFAULTS = { "language": "Chinese", - "speaker": "Uncle_Fu", "instruct": "语速缓慢而审慎,每个音节的语调都拿捏得恰到好处,宛如教授在指导新生。", "instruct": "Speak in a slow pace and enuntiate every word, as a teacher to a learning student", } @@ -189,11 +188,13 @@ class TTS: @staticmethod def generate(text: str): """Generates a Waw using the defaulst values""" + print(f"starting to generate {text}") speaker = random.choice(TTS.VOICES) - return TTS.MODEL.generate_custom_voice( + audio = TTS.MODEL.generate_custom_voice( text=text, **TTS.DEFAULTS, speaker=speaker ) - + print(f"finish to generate {text}") + return audio # Clases @@ -207,6 +208,7 @@ class ProcessFolder: def __init__(self, input_folder: Path, language_id: str = None): self.input_folder = input_folder self._language_id = language_id + self.absolute_input_folder = INPUT / self.input_folder # process file type self.out_folder = OUTPUT / input_folder self.out_folder.mkdir(parents=True, exist_ok=True) @@ -214,24 +216,23 @@ class ProcessFolder: self.resources.mkdir(parents=True, exist_ok=True) @property - def output_name(): + def output_name(self): """Posible name for the output file, still missing the filetype""" if self.language_id is None: raise ValueError("Not a valid language selected") - return self.out_folder / f"{self.input_file.stem}.{self.language_id}.temp" - - @property - def absolute_input_file(self): - """Absolute input file""" - return INPUT / self.input_file + return self.out_folder / f"{self.input_folder.stem}.{self.language_id}.temp" @property def input_files(self): input_files = [] - for file in self.absolute_input_file.glob(f"*.txt"): + for file in self.absolute_input_folder.glob(f"*.txt"): for file_type in (DICT_TYPE, PHRASES_TYPE, DICTATION_TYPE): if file_type in file.suffixes: - input_files.append(ProcessFile(file, language_id=self.language_id)) + input_files.append( + ProcessFile( + file.relative_to(INPUT), language_id=self.language_id + ) + ) return input_files @property @@ -339,6 +340,7 @@ class DictionaryResult: def __init__( self, + n: str, language_id: str, simplified: str, traditional: str, @@ -346,6 +348,7 @@ class DictionaryResult: meaning: str, audio_path: Path, ): + self.n = n self.language_id = language_id self.simplified = simplified self.traditional = traditional