Skip to content

Commit 08a822f

Browse files
committed
fixed cards with known morphs not being skipped (#207)
1 parent eea19e1 commit 08a822f

File tree

4 files changed

+76
-83
lines changed

4 files changed

+76
-83
lines changed

ankimorphs/reviewing_utils.py

Lines changed: 74 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
from __future__ import annotations
2+
13
from functools import partial
2-
from typing import Any, Callable, Optional, Union
4+
from typing import Any, Callable
35

46
from anki.cards import Card
57
from anki.collection import Collection, UndoStatus
@@ -16,7 +18,6 @@
1618
from .ankimorphs_db import AnkiMorphsDB
1719
from .browser_utils import browse_same_morphs
1820
from .exceptions import CancelledOperationException, CardQueueEmptyException
19-
from .skipped_cards import SkippedCards
2021

2122
SET_KNOWN_AND_SKIP_UNDO = "Set known and skip"
2223
ANKIMORPHS_UNDO = "AnkiMorphs custom undo"
@@ -28,7 +29,7 @@
2829
"Set Due Date",
2930
"Delete Note",
3031
}
31-
set_known_and_skip_undo: Optional[UndoStatus] = None
32+
set_known_and_skip_undo: UndoStatus | None = None
3233

3334

3435
def am_next_card() -> None:
@@ -119,15 +120,8 @@ def _get_next_card_background(
119120
if am_config_filter is None:
120121
break # card did not match any (note type and tags) set in the settings GUI
121122

122-
card_unknown_morphs: Optional[set[tuple[str, str]]] = am_db.get_morphs_of_card(
123-
reviewer.card.id, search_unknowns=True
124-
)
125-
126-
if card_unknown_morphs is None:
127-
break
128-
129123
skipped_cards.process_skip_conditions_of_card(
130-
am_config, am_db, note, card_unknown_morphs
124+
am_config, am_db, note=note, card_id=reviewer.card.id
131125
)
132126

133127
if not skipped_cards.did_skip_card:
@@ -294,9 +288,9 @@ def am_reviewer_shortcut_keys(
294288
self: Reviewer,
295289
_old: Callable[
296290
[Reviewer],
297-
list[Union[tuple[str, Callable[[], None]], tuple[Qt.Key, Callable[[], None]]]],
291+
list[tuple[str, Callable[[], None]] | tuple[Qt.Key, Callable[[], None]]],
298292
],
299-
) -> list[Union[tuple[str, Callable[[], None]], tuple[Qt.Key, Callable[[], None]]]]:
293+
) -> list[tuple[str, Callable[[], None]] | tuple[Qt.Key, Callable[[], None]]]:
300294
am_config = AnkiMorphsConfig()
301295

302296
key_browse_ready: QKeySequence = am_config.shortcut_browse_ready_same_unknown
@@ -353,7 +347,7 @@ def _show_scheduler_version_error() -> None:
353347

354348

355349
def _on_failure(
356-
error: Union[Exception, CardQueueEmptyException, CancelledOperationException]
350+
error: Exception | CardQueueEmptyException | CancelledOperationException,
357351
) -> None:
358352
# This function runs on the main thread.
359353
assert mw is not None
@@ -367,3 +361,69 @@ def _on_failure(
367361
mw.moveToState("overview")
368362
else:
369363
raise error
364+
365+
366+
class SkippedCards:
367+
__slots__ = (
368+
"skipped_known_cards",
369+
"skipped_already_seen_morphs_cards",
370+
"total_skipped_cards",
371+
"did_skip_card",
372+
)
373+
374+
def __init__(self) -> None:
375+
self.skipped_known_cards = 0
376+
self.skipped_already_seen_morphs_cards = 0
377+
self.total_skipped_cards = 0
378+
self.did_skip_card = False
379+
380+
def process_skip_conditions_of_card(
381+
self,
382+
am_config: AnkiMorphsConfig,
383+
am_db: AnkiMorphsDB,
384+
note: Note,
385+
card_id: int,
386+
) -> None:
387+
self.did_skip_card = False
388+
389+
learn_now_tag: bool = note.has_tag(am_config.tag_learn_card_now)
390+
known_automatically: bool = note.has_tag(am_config.tag_known_automatically)
391+
known_manually: bool = note.has_tag(am_config.tag_known_manually)
392+
known_tag: bool = known_automatically or known_manually
393+
394+
if learn_now_tag:
395+
self.did_skip_card = False
396+
elif known_tag:
397+
if am_config.skip_only_known_morphs_cards:
398+
self.skipped_known_cards += 1
399+
self.did_skip_card = True
400+
elif am_config.skip_unknown_morph_seen_today_cards:
401+
morphs_already_seen_morphs_today: set[str] = (
402+
am_db.get_all_morphs_seen_today()
403+
)
404+
card_unknown_morphs_raw: set[tuple[str, str]] | None = (
405+
am_db.get_morphs_of_card(card_id, search_unknowns=True)
406+
)
407+
if card_unknown_morphs_raw is not None:
408+
card_unknown_morphs: set[str] = {
409+
morph_raw[0] + morph_raw[1] for morph_raw in card_unknown_morphs_raw
410+
}
411+
if card_unknown_morphs.issubset(morphs_already_seen_morphs_today):
412+
self.skipped_already_seen_morphs_cards += 1
413+
self.did_skip_card = True
414+
415+
self.total_skipped_cards = (
416+
self.skipped_known_cards + self.skipped_already_seen_morphs_cards
417+
)
418+
419+
def show_tooltip_of_skipped_cards(self) -> None:
420+
skipped_string = ""
421+
422+
if self.skipped_known_cards > 0:
423+
skipped_string += f"Skipped <b>{self.skipped_known_cards}</b> cards with only known morphs"
424+
if self.skipped_already_seen_morphs_cards > 0:
425+
if skipped_string != "":
426+
skipped_string += "<br>"
427+
skipped_string += f"Skipped <b>{self.skipped_already_seen_morphs_cards}</b> cards with morphs already seen today"
428+
429+
tooltip(skipped_string, parent=mw)

ankimorphs/settings_dialog.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ def __init__(self) -> None:
105105
)
106106

107107
# Semantic Versioning https://semver.org/
108-
self.ui.ankimorphs_version_label.setText("AnkiMorphs version: 2.2.0")
108+
self.ui.ankimorphs_version_label.setText("AnkiMorphs version: 2.2.1")
109109

110110
self.show()
111111

ankimorphs/skipped_cards.py

Lines changed: 0 additions & 67 deletions
This file was deleted.

tests/review_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
ankimorphs_db,
2020
reviewing_utils,
2121
)
22-
from ankimorphs.skipped_cards import SkippedCards
22+
from ankimorphs.reviewing_utils import SkippedCards
2323

2424

2525
class MockDB(AnkiMorphsDB):

0 commit comments

Comments
 (0)