From 01ec6484cce41b46b382fb0bd544a0e6f27b018e Mon Sep 17 00:00:00 2001 From: Martin Bernstorff Date: Fri, 27 Oct 2023 19:23:17 +0000 Subject: [PATCH] misc. --- application/main.py | 4 +--- pyproject.toml | 4 ++++ src/personal_mnemonic_medium/card_pipeline.py | 9 +++----- .../exporters/anki/card_types/base.py | 9 ++++---- .../exporters/anki/globals.py | 10 ++++----- .../exporters/anki/package_generator.py | 21 ++++++------------- .../exporters/anki/sync.py | 17 +++++---------- .../note_factories/note.py | 10 ++------- .../prompt_extractors/cloze_extractor.py | 5 ++--- .../prompt_extractors/qa_extractor.py | 10 ++++----- tests/exporters/anki/test_card_converter.py | 17 ++++----------- .../exporters/anki/test_package_generator.py | 4 +--- .../note_factories/test_markdown_extractor.py | 2 +- 13 files changed, 42 insertions(+), 80 deletions(-) diff --git a/application/main.py b/application/main.py index d457f88..22d55ec 100644 --- a/application/main.py +++ b/application/main.py @@ -67,9 +67,7 @@ def main( ClozePromptExtractor(), ], card_exporter=AnkiPackageGenerator(), # Step 3, get the cards from the prompts - ).run( - input_path=input_dir, - ) + ).run(input_path=input_dir) grouped_cards = ( Seq(cards).group_by(lambda card: card.deckname).to_iter() diff --git a/pyproject.toml b/pyproject.toml index fbd7e78..0664515 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -125,12 +125,16 @@ exclude = [ dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$" target-version = "py311" +[tool.ruff.format] +skip-magic-trailing-comma = true + [tool.ruff.flake8-annotations] mypy-init-return = true suppress-none-returning = true [tool.ruff.isort] known-third-party = ["wandb"] +split-on-trailing-comma = false [tool.ruff.mccabe] # Unlike Flake8, default to a complexity level of 10. diff --git a/src/personal_mnemonic_medium/card_pipeline.py b/src/personal_mnemonic_medium/card_pipeline.py index cfb14eb..c11beca 100644 --- a/src/personal_mnemonic_medium/card_pipeline.py +++ b/src/personal_mnemonic_medium/card_pipeline.py @@ -26,10 +26,7 @@ def __init__( self.prompt_extractors = prompt_extractors self.card_exporter = card_exporter - def run( - self, - input_path: Path, - ) -> list[AnkiCard]: + def run(self, input_path: Path) -> list[AnkiCard]: notes: list[Document] = [] if input_path.is_dir(): notes += list( @@ -40,7 +37,7 @@ def run( if not input_path.is_dir(): note_from_file = self.document_factory.get_note_from_file( - file_path=input_path, + file_path=input_path ) notes.append(note_from_file) @@ -51,6 +48,6 @@ def run( collected_prompts += extractor.extract_prompts(note) cards: list[AnkiCard] = self.card_exporter.prompts_to_cards( - prompts=collected_prompts, + prompts=collected_prompts ) return cards diff --git a/src/personal_mnemonic_medium/exporters/anki/card_types/base.py b/src/personal_mnemonic_medium/exporters/anki/card_types/base.py index a0ab01a..4b66a98 100644 --- a/src/personal_mnemonic_medium/exporters/anki/card_types/base.py +++ b/src/personal_mnemonic_medium/exporters/anki/card_types/base.py @@ -84,7 +84,7 @@ def deckname(self) -> str: + self.subdeck ) raise ValueError( - "Subdeck length is 0", + "Subdeck length is 0" ) # This is purposefully non-valid code except: # noqa return "0. Don't click me::1. Active::Personal Mnemonic Medium" @@ -100,8 +100,7 @@ def add_field(self, field: Any): def get_source_button(self) -> str: """Get the button to open the source document.""" url = self.url_generator( - self.source_doc.source_path, - self.source_prompt.line_nr, + self.source_doc.source_path, self.source_prompt.line_nr ) html = f'

Open

' return html @@ -110,7 +109,7 @@ def to_genanki_note(self) -> genanki.Note: """Produce a genanki. Note with the specified guid.""" if len(self.html_fields) > len(self.genanki_model.fields): # type: ignore raise ValueError( - f"Too many fields for model {self.genanki_model.name}: {self.html_fields}", # type: ignore + f"Too many fields for model {self.genanki_model.name}: {self.html_fields}" # type: ignore ) if len(self.html_fields) < len(self.genanki_model.fields): # type: ignore @@ -157,7 +156,7 @@ def determine_media_references( for i, field in enumerate(self.html_fields): current_stage = field for regex in [ - r'src="([^"]*?)"', + r'src="([^"]*?)"' ]: # TODO not sure how this should work:, r'\[sound:(.*?)\]']: results = [] diff --git a/src/personal_mnemonic_medium/exporters/anki/globals.py b/src/personal_mnemonic_medium/exporters/anki/globals.py index c633ea8..b0adbbd 100644 --- a/src/personal_mnemonic_medium/exporters/anki/globals.py +++ b/src/personal_mnemonic_medium/exporters/anki/globals.py @@ -13,7 +13,7 @@ CARD_MATHJAX_CONTENT = textwrap.dedent( """\ -""", +""" ) VERSION = "0.1" @@ -52,19 +52,19 @@ """, - }, + } ] CLOZE_MODEL_TEMPLATE = [ { "name": "Ankdown Cloze Card with UUID", "qfmt": r"{{{{cloze:Text}}}}\n
{{{{Extra}}}}
\n{}".format( - CARD_MATHJAX_CONTENT, + CARD_MATHJAX_CONTENT ), "afmt": r"{{{{cloze:Text}}}}\n
{{{{Extra}}}}
\n{}".format( - CARD_MATHJAX_CONTENT, + CARD_MATHJAX_CONTENT ), - }, + } ] CONFIG = { diff --git a/src/personal_mnemonic_medium/exporters/anki/package_generator.py b/src/personal_mnemonic_medium/exporters/anki/package_generator.py index ac29f79..ae8d2b9 100644 --- a/src/personal_mnemonic_medium/exporters/anki/package_generator.py +++ b/src/personal_mnemonic_medium/exporters/anki/package_generator.py @@ -68,14 +68,11 @@ def cards_to_deck_bundle(cards: list[AnkiCard]) -> DeckBundle: """ deck, media = AnkiPackageGenerator.cards_to_deck(cards=cards) - return DeckBundle( - deck=deck, - media=media, - ) + return DeckBundle(deck=deck, media=media) @staticmethod def cards_to_deck( - cards: Sequence[AnkiCard], + cards: Sequence[AnkiCard] ) -> tuple[genanki.Deck, set[str]]: media = set() @@ -87,8 +84,7 @@ def cards_to_deck( for abspath, newpath in card.determine_media_references(): try: copyfile( - abspath, - newpath, + abspath, newpath ) # This is inefficient but definitely works on all platforms. media.add(newpath) except FileNotFoundError as e: @@ -106,8 +102,7 @@ def cards_to_deck( return deck, media def prompts_to_cards( - self, - prompts: Sequence[Prompt], + self, prompts: Sequence[Prompt] ) -> list[AnkiCard]: """Takes an iterable of prompts and turns them into AnkiCards""" @@ -116,16 +111,12 @@ def prompts_to_cards( for prompt in prompts: if isinstance(prompt, QAPrompt): card = AnkiQA( - fields=[ - prompt.question, - prompt.answer, - ], + fields=[prompt.question, prompt.answer], source_prompt=prompt, ) elif isinstance(prompt, ClozePrompt): card = AnkiCloze( - fields=[prompt.content], - source_prompt=prompt, + fields=[prompt.content], source_prompt=prompt ) else: raise NotImplementedError( diff --git a/src/personal_mnemonic_medium/exporters/anki/sync.py b/src/personal_mnemonic_medium/exporters/anki/sync.py index a2bf6e3..4c2e8d3 100644 --- a/src/personal_mnemonic_medium/exporters/anki/sync.py +++ b/src/personal_mnemonic_medium/exporters/anki/sync.py @@ -39,7 +39,7 @@ def invoke(action: Any, **params: Any) -> Any: response = json.load( urllib.request.urlopen( urllib.request.Request(ANKICONNECT_URL, requestJson) - ), + ) ) if len(response) != 2: raise Exception("response has an unexpected number of fields") @@ -60,7 +60,7 @@ def anki_connect_is_live() -> bool: except Exception as err: msg.info(f"Attempted connection on {ANKICONNECT_URL}") msg.info( - "Unable to reach anki connect. Make sure anki is running and the Anki Connect addon is installed.", + "Unable to reach anki connect. Make sure anki is running and the Anki Connect addon is installed." ) msg.fail(f"Error was {err}") @@ -129,10 +129,7 @@ def sync_deck( for guid in guids_to_delete ] - invoke( - "deleteNotes", - notes=note_ids, - ) + invoke("deleteNotes", notes=note_ids) msg.good( f"Deleted {len(guids_to_delete)} notes" ) @@ -164,8 +161,7 @@ def get_anki_note_infos( deck_bundle: DeckBundle ) -> tuple[dict[str, Any], set[str]]: anki_card_ids: list[int] = invoke( - "findCards", - query=f'"deck:{deck_bundle.deck.name}"', + "findCards", query=f'"deck:{deck_bundle.deck.name}"' ) # get a list of anki notes in the deck @@ -228,10 +224,7 @@ def sync_model(model: Model): try: invoke( "updateModelStyling", - model={ - "name": model.name, - "css": model.css, - }, + model={"name": model.name, "css": model.css}, ) msg.good(f"\tUpdated model {model.name} css") except Exception as e: diff --git a/src/personal_mnemonic_medium/note_factories/note.py b/src/personal_mnemonic_medium/note_factories/note.py index e8bd73c..5718036 100644 --- a/src/personal_mnemonic_medium/note_factories/note.py +++ b/src/personal_mnemonic_medium/note_factories/note.py @@ -5,11 +5,7 @@ class Document: def __init__( - self, - title: str, - content: str, - uuid: str, - source_path: Path, + self, title: str, content: str, uuid: str, source_path: Path ): self.title = title self.uuid = uuid @@ -31,9 +27,7 @@ def replace_alias_wiki_links(text: str) -> str: rf"\[\[{tokens_in_link}+\|{tokens_in_link}+\]\]" ) pattern_matches = re.findall( - pattern=regex_pattern, - string=text, - flags=re.DOTALL, + pattern=regex_pattern, string=text, flags=re.DOTALL ) for match in pattern_matches: diff --git a/src/personal_mnemonic_medium/prompt_extractors/cloze_extractor.py b/src/personal_mnemonic_medium/prompt_extractors/cloze_extractor.py index ba12e99..46caab1 100644 --- a/src/personal_mnemonic_medium/prompt_extractors/cloze_extractor.py +++ b/src/personal_mnemonic_medium/prompt_extractors/cloze_extractor.py @@ -42,8 +42,7 @@ def _has_cloze(string: str) -> bool: @staticmethod def _replace_cloze_id_with_unique( - string: str, - selected_cloze: str | None = None, + string: str, selected_cloze: str | None = None ) -> str: """Each cloze deletion in a note is numbered sequentially. @@ -104,7 +103,7 @@ def extract_prompts( tags=note.tags, note_uuid=note.uuid, source_note=note, - ), + ) ) return prompts diff --git a/src/personal_mnemonic_medium/prompt_extractors/qa_extractor.py b/src/personal_mnemonic_medium/prompt_extractors/qa_extractor.py index 655538a..cc2bdd3 100644 --- a/src/personal_mnemonic_medium/prompt_extractors/qa_extractor.py +++ b/src/personal_mnemonic_medium/prompt_extractors/qa_extractor.py @@ -12,9 +12,7 @@ log = logging.getLogger(__name__) # Log to disk, not to console. logging.basicConfig( - filename="qa_extractor.log", - filemode="w", - level=logging.DEBUG, + filename="qa_extractor.log", filemode="w", level=logging.DEBUG ) @@ -72,7 +70,7 @@ def _has_qa(self, string: str) -> bool: + r"{0,1}\. ", string, flags=re.DOTALL, - ), + ) ) != 0 ): @@ -94,7 +92,7 @@ def extract_prompts(self, note: Document) -> Sequence[QAPrompt]: answer = self._get_first_answer(block_string) except IndexError: logging.warn( - f"Could not find answer in {note.title} for {question}", + f"Could not find answer in {note.title} for {question}" ) continue @@ -106,7 +104,7 @@ def extract_prompts(self, note: Document) -> Sequence[QAPrompt]: note_uuid=note.uuid, source_note=note, line_nr=block_starting_line_nr, - ), + ) ) block_lines = len( diff --git a/tests/exporters/anki/test_card_converter.py b/tests/exporters/anki/test_card_converter.py index 5766db7..fd2ab76 100644 --- a/tests/exporters/anki/test_card_converter.py +++ b/tests/exporters/anki/test_card_converter.py @@ -48,13 +48,8 @@ def __init__( card_exporter=card_exporter, ) - def test_card_pipeline( - self, - input_path: Path, - ) -> list[AnkiCard]: - return self.run( - input_path=input_path, - ) + def test_card_pipeline(self, input_path: Path) -> list[AnkiCard]: + return self.run(input_path=input_path) def test_custom_card_to_genanki_card(): @@ -106,9 +101,7 @@ def test_qa_uuid_generation(): ) cards = TestCardPipeline( prompt_extractors=[QAPromptExtractor()] - ).run( - input_path=file_path, - ) + ).run(input_path=file_path) notes = [c.to_genanki_note() for c in cards] field_guids = {note.guid for note in notes} @@ -126,9 +119,7 @@ def test_cloze_uuid_generation(): ) cloze_cards = TestCardPipeline( prompt_extractors=[ClozePromptExtractor()] - ).run( - input_path=file_path, - ) + ).run(input_path=file_path) cloze_generated_guids = {card.card_uuid for card in cloze_cards} cloze_reference_guids = {3001245253, 952903559} diff --git a/tests/exporters/anki/test_package_generator.py b/tests/exporters/anki/test_package_generator.py index 0676951..95e549c 100644 --- a/tests/exporters/anki/test_package_generator.py +++ b/tests/exporters/anki/test_package_generator.py @@ -66,6 +66,4 @@ def test_package_generators(): for _ in range(4) ] - AnkiPackageGenerator().cards_to_deck_bundle( - cards=genanki_notes, - ) + AnkiPackageGenerator().cards_to_deck_bundle(cards=genanki_notes) diff --git a/tests/note_factories/test_markdown_extractor.py b/tests/note_factories/test_markdown_extractor.py index cb09106..df8a045 100644 --- a/tests/note_factories/test_markdown_extractor.py +++ b/tests/note_factories/test_markdown_extractor.py @@ -9,7 +9,7 @@ def test_get_notes_from_dir(): notes = MarkdownNoteFactory().get_notes_from_dir( - PROJECT_ROOT / "tests" / "test_md_files", + PROJECT_ROOT / "tests" / "test_md_files" ) assert len(notes) == 4