Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into 323-refactor-remove-t…
Browse files Browse the repository at this point in the history
…mp_dirs-from-PushPrompts-and-`PromptDiffDeterminer`
  • Loading branch information
MartinBernstorff committed Dec 13, 2023
2 parents 9fc4e3e + 5f38dfe commit caa1a43
Show file tree
Hide file tree
Showing 18 changed files with 131 additions and 138 deletions.
16 changes: 2 additions & 14 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,8 @@
"python.analysis.diagnosticMode": "workspace",
"githubIssues.queries": [
{
"label": "🔥",
"query": "repo:${owner}/${repository} is:open is:issue milestone:acute-🔥 sort:updated-asc"
},
{
"label": "🌿",
"query": "repo:${owner}/${repository} is:open is:issue milestone:important-🌿 sort:updated-asc"
},
{
"label": "No milestone",
"query": "repo:${owner}/${repository} is:open is:issue no:milestone sort:updated-asc"
},
{
"label": "🌲",
"query": "repo:${owner}/${repository} is:open is:issue milestone:investment-🌲 sort:updated-asc"
"label": "Assigned to me",
"query": "repo:${owner}/${repository} project:martinbernstorff/2 assignee:MartinBernstorff is:open"
},
],
}
38 changes: 14 additions & 24 deletions personal_mnemonic_medium/v2/data_access/ankiconnect_gateway.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,17 @@ class AnkiConnectCommand(Enum):


class AnkiConnectGateway:
def __init__(self, ankiconnect_url: str, deck_name: str) -> None:
def __init__(
self,
ankiconnect_url: str,
deck_name: str,
tmp_read_dir: Path,
tmp_write_dir: Path,
) -> None:
self.ankiconnect_url = ankiconnect_url
self.deck_name = deck_name
self.tmp_read_dir = tmp_read_dir
self.tmp_write_dir = tmp_write_dir

def update_model(self, model: genanki.Model) -> None:
self._invoke(
Expand All @@ -57,17 +65,12 @@ def update_model(self, model: genanki.Model) -> None:
model={"name": model.name, "css": model.css}, # type: ignore
)

def import_package(
self,
package: genanki.Package,
tmp_write_dir: Path,
tmp_read_dir: Path,
) -> None:
def import_package(self, package: genanki.Package) -> None:
apkg_name = f"{datetime.datetime.now().strftime('%Y-%m-%d-%H-%M-%S')}.apkg"
write_path = tmp_write_dir / apkg_name
write_path = self.tmp_write_dir / apkg_name
package.write_to_file(write_path) # type: ignore

read_path = tmp_read_dir / apkg_name
read_path = self.tmp_read_dir / apkg_name
try:
self._invoke(
AnkiConnectCommand.IMPORT_PACKAGE, path=str(read_path)
Expand Down Expand Up @@ -140,8 +143,6 @@ class FakeAnkiCommand:
@dataclass(frozen=True)
class ImportPackage(FakeAnkiCommand):
package: genanki.Package
tmp_write_dir: Path
tmp_read_dir: Path


@dataclass(frozen=True)
Expand All @@ -161,16 +162,5 @@ def get_all_note_infos(self) -> Sequence[NoteInfo]:
def update_model(self, model: genanki.Model) -> None:
self.executed_commands.append(UpdateModel(model=model))

def import_package(
self,
package: genanki.Package,
tmp_write_dir: Path,
tmp_read_dir: Path,
) -> None:
self.executed_commands.append(
ImportPackage(
package=package,
tmp_write_dir=tmp_write_dir,
tmp_read_dir=tmp_read_dir,
)
)
def import_package(self, package: genanki.Package) -> None:
self.executed_commands.append(ImportPackage(package=package))
35 changes: 17 additions & 18 deletions personal_mnemonic_medium/v2/data_access/test_ankiconnect.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,17 @@ class MockNoteInfo(NoteInfo):
reason="Tests require a running AnkiConnect server",
)
class TestAnkiConnectGateway:
output_path = Path("/output")
gateway = AnkiConnectGateway(
ankiconnect_url=ANKICONNECT_URL, deck_name="Test deck"
ankiconnect_url=ANKICONNECT_URL,
deck_name="Test deck",
tmp_read_dir=Path("/Users/Leisure/ankidecks"),
tmp_write_dir=output_path,
)

def test_import_package(self):
output_path = Path("/output")

# Delete all .apkg in the output directory
for f in output_path.glob("*.apkg"):
for f in self.output_path.glob("*.apkg"):
f.unlink()

deck = genanki.Deck(deck_id=1, name="Test deck")
Expand All @@ -66,20 +68,17 @@ def test_import_package(self):
)

package = genanki.Package(deck_or_decks=deck)
self.gateway.import_package(
package=package,
tmp_write_dir=Path("/output"),
tmp_read_dir=Path("/Users/Leisure/ankidecks"),
)
assert len(list(Path("/output").glob("*.apkg"))) == 0

def test_delete_notes(self):
self.gateway.delete_notes(note_ids=[1, 2, 3])
# Phase 1: Importing
self.gateway.import_package(package=package)
assert len(list(Path("/output").glob("*.apkg"))) == 0

def test_get_note_infos(self):
note_infos = self.gateway.get_all_note_infos()
# Phase 2: Getting
all_notes = self.gateway.get_all_note_infos()
assert len(all_notes) == 1

assert [
isinstance(note_info, NoteInfo)
for note_info in note_infos
]
# Phase 3: Deleting
self.gateway.delete_notes(
note_ids=[n.noteId for n in all_notes]
)
assert len(self.gateway.get_all_note_infos()) == 0
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
DeletePrompts,
PushPrompts,
)
from ..prompts.base_prompt import BasePrompt
from ..prompts.base_prompt import BasePrompt, DestinationPrompt

K = TypeVar("K")
T = TypeVar("T")
Expand All @@ -20,7 +20,7 @@ class BaseDiffDeterminer(Protocol):
def sync(
self,
source_prompts: Sequence[BasePrompt],
destination_prompts: Sequence[BasePrompt],
destination_prompts: Sequence[DestinationPrompt],
) -> Sequence[PromptDestinationCommand]:
...

Expand Down Expand Up @@ -51,12 +51,13 @@ class PromptDiffDeterminer(BaseDiffDeterminer):
def sync(
self,
source_prompts: Sequence[BasePrompt],
destination_prompts: Sequence[BasePrompt],
destination_prompts: Sequence[DestinationPrompt],
) -> Sequence[PromptDestinationCommand]:
syncer = GeneralSyncer(
source={prompt.uid: prompt for prompt in source_prompts},
destination={
prompt.uid: prompt for prompt in destination_prompts
dest_prompt.prompt.uid: dest_prompt
for dest_prompt in destination_prompts
},
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
DeletePrompts,
PushPrompts,
)
from ..prompts.base_prompt import DestinationPrompt
from ..prompts.qa_prompt import QAPrompt
from .base_diff_determiner import GeneralSyncer, PromptDiffDeterminer

Expand All @@ -27,16 +28,27 @@ def test_prompt_diff_determiner(tmp_path: Path):
QAPrompt(question="b", answer="b"),
]
destination_prompts = [
QAPrompt(question="b", answer="b"),
QAPrompt(question="c", answer="c"),
DestinationPrompt(
QAPrompt(question="b", answer="b"), destination_id="2"
),
DestinationPrompt(
QAPrompt(question="c", answer="c"), destination_id="3"
),
]

diff = syncer.sync(
source_prompts=source_prompts,
destination_prompts=destination_prompts,
)
assert diff == [
DeletePrompts([QAPrompt(question="c", answer="c")]),
DeletePrompts(
[
DestinationPrompt(
QAPrompt(question="c", answer="c"),
destination_id="3",
)
]
),
PushPrompts(
[QAPrompt(question="a", answer="a")],
tmp_write_dir=tmp_path,
Expand Down
17 changes: 0 additions & 17 deletions personal_mnemonic_medium/v2/domain/main.py

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
AnkiConnectGateway,
NoteInfo,
)
from ...prompts.base_prompt import BasePrompt
from ...prompts.cloze_prompt import RemoteClozePrompt
from ...prompts.qa_prompt import RemoteQAPrompt
from ...prompts.base_prompt import DestinationPrompt
from ...prompts.cloze_prompt import ClozeWithoutDoc
from ...prompts.qa_prompt import QAWithoutDoc
from ..base_prompt_destination import PromptDestination
from .prompt_converter.anki_prompt_converter import (
AnkiPromptConverter,
Expand All @@ -32,38 +32,48 @@ def __init__(
self.gateway = gateway
self.prompt_converter = prompt_converter

def _note_info_to_prompt(self, note_info: NoteInfo) -> BasePrompt:
def _note_info_to_prompt(
self, note_info: NoteInfo
) -> DestinationPrompt:
if (
"Question" in note_info.fields
and "Answer" in note_info.fields
):
return RemoteQAPrompt(
question=note_info.fields["Question"].value,
answer=note_info.fields["Answer"].value,
add_tags=note_info.tags,
remote_id=str(note_info.noteId),
return DestinationPrompt(
QAWithoutDoc(
question=note_info.fields["Question"].value,
answer=note_info.fields["Answer"].value,
add_tags=note_info.tags,
),
destination_id=str(note_info.noteId),
)

if "Text" in note_info.fields:
return RemoteClozePrompt(
text=note_info.fields["Text"].value,
add_tags=note_info.tags,
remote_id=str(note_info.noteId),
return DestinationPrompt(
ClozeWithoutDoc(
text=note_info.fields["Text"].value,
add_tags=note_info.tags,
),
destination_id=str(note_info.noteId),
)

raise ValueError(
f"NoteInfo {note_info} has neither Question nor Text field"
)

def get_all_prompts(self) -> Sequence[BasePrompt]:
def get_all_prompts(self) -> Sequence[DestinationPrompt]:
return (
Seq(self.gateway.get_all_note_infos())
.map(self._note_info_to_prompt)
.to_list()
)

def _delete_prompts(self, prompts: Sequence[BasePrompt]) -> None:
prompt_ids = {int(prompt.uid) for prompt in prompts}
def _delete_prompts(
self, prompts: Sequence[DestinationPrompt]
) -> None:
prompt_ids = {
int(remote_prompt.prompt.uid) for remote_prompt in prompts
}
self.gateway.delete_notes(list(prompt_ids))

def _grouped_cards_to_deck(
Expand Down Expand Up @@ -102,11 +112,7 @@ def _push_prompts(self, command: PushPrompts) -> None:

package = self._create_package(cards)

self.gateway.import_package(
package,
tmp_write_dir=command.tmp_write_dir,
tmp_read_dir=command.tmp_read_dir,
)
self.gateway.import_package(package)

def update(
self, commands: Sequence[PromptDestinationCommand]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
)

from ....prompts.base_prompt import BasePrompt
from ....prompts.cloze_prompt import RemoteClozePrompt
from ....prompts.cloze_prompt import ClozeWithoutDoc
from ....prompts.qa_prompt import QAPrompt


Expand Down Expand Up @@ -45,7 +45,7 @@ def _prompt_to_card(self, prompt: BasePrompt) -> AnkiCard:
tags=prompt.tags,
css=self.card_css,
)
case RemoteClozePrompt():
case ClozeWithoutDoc():
card = AnkiCloze(
text=prompt.text,
deck=deck,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import pytest

from ....prompts.base_prompt import BasePrompt
from ....prompts.cloze_prompt import RemoteClozePrompt
from ....prompts.qa_prompt import RemoteQAPrompt
from ....prompts.cloze_prompt import ClozeWithoutDoc
from ....prompts.qa_prompt import QAWithoutDoc
from .anki_prompt_converter import AnkiPromptConverter
from .prompts.anki_cloze import AnkiCloze
from .prompts.anki_qa import AnkiQA
Expand All @@ -25,18 +25,15 @@
("input_prompt", "expected_card"),
[
(
RemoteQAPrompt(
QAWithoutDoc(
question="FakeQuestion",
answer="FakeAnswer",
add_tags=["FakeTag"],
remote_id="1",
),
fake_anki_qa,
),
(
RemoteClozePrompt(
text="FakeText", add_tags=["FakeTag"], remote_id="1"
),
ClozeWithoutDoc(text="FakeText", add_tags=["FakeTag"]),
fake_anki_cloze,
),
],
Expand Down
Loading

0 comments on commit caa1a43

Please sign in to comment.