Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/disperse siblings after reschedule #393

Merged
merged 5 commits into from
Apr 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions __init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,14 +89,24 @@ def set_auto_disperse_after_sync(checked, _):


def set_auto_disperse_when_review(checked, _):
config.auto_disperse = checked
config.auto_disperse_when_review = checked


menu_auto_disperse = checkable(
title="Auto disperse siblings when review", on_click=set_auto_disperse_when_review
)


def set_auto_disperse_after_reschedule(checked, _):
config.auto_disperse_after_reschedule = checked


menu_auto_disperse_after_reschedule = checkable(
title="Disperse siblings after rescheduling (breaks Load Balance)",
on_click=set_auto_disperse_after_reschedule,
)


def set_display_memory_state(checked, _):
config.display_memory_state = checked

Expand Down Expand Up @@ -145,6 +155,7 @@ def reschedule_recent(did):
menu_for_helper.addAction(menu_auto_disperse)
menu_for_helper.addAction(menu_display_memory_state)
menu_for_helper.addAction(menu_load_balance)
menu_for_helper.addAction(menu_auto_disperse_after_reschedule)
menu_for_easy_days = menu_for_helper.addMenu(
"Less Anki on Easy Days (requires Load Balancing)"
)
Expand Down Expand Up @@ -228,9 +239,12 @@ def adjust_menu():
)
menu_auto_reschedule_after_sync.setChecked(config.auto_reschedule_after_sync)
menu_auto_disperse_after_sync.setChecked(config.auto_disperse_after_sync)
menu_auto_disperse.setChecked(config.auto_disperse)
menu_auto_disperse.setChecked(config.auto_disperse_when_review)
menu_display_memory_state.setChecked(config.display_memory_state)
menu_load_balance.setChecked(config.load_balance)
menu_auto_disperse_after_reschedule.setChecked(
config.auto_disperse_after_reschedule
)
menu_for_auto_easy_days.setChecked(config.auto_easy_days)
menu_for_easy_0.setChecked(0 in config.easy_days)
menu_for_easy_1.setChecked(1 in config.easy_days)
Expand Down
3 changes: 2 additions & 1 deletion config.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
"days_to_reschedule": 7,
"auto_reschedule_after_sync": false,
"auto_disperse_after_sync": false,
"auto_disperse": false,
"auto_disperse_when_review": false,
"auto_disperse_after_reschedule": false,
"mature_ivl": 21,
"debug_notify": false,
"fsrs_stats": true,
Expand Down
22 changes: 16 additions & 6 deletions configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
DAYS_TO_RESCHEDULE = "days_to_reschedule"
AUTO_RESCHEDULE_AFTER_SYNC = "auto_reschedule_after_sync"
AUTO_DISPERSE_AFTER_SYNC = "auto_disperse_after_sync"
AUTO_DISPERSE = "auto_disperse"
AUTO_DISPERSE_WHEN_REVIEW = "auto_disperse_when_review"
AUTO_DISPERSE_AFTER_RESCHEDULE = "auto_disperse_after_reschedule"
MATURE_IVL = "mature_ivl"
DEBUG_NOTIFY = "debug_notify"
FSRS_STATS = "fsrs_stats"
Expand Down Expand Up @@ -95,12 +96,21 @@ def auto_disperse_after_sync(self, value):
self.save()

@property
def auto_disperse(self):
return self.data[AUTO_DISPERSE]
def auto_disperse_when_review(self):
return self.data[AUTO_DISPERSE_WHEN_REVIEW]

@auto_disperse.setter
def auto_disperse(self, value):
self.data[AUTO_DISPERSE] = value
@auto_disperse_when_review.setter
def auto_disperse_when_review(self, value):
self.data[AUTO_DISPERSE_WHEN_REVIEW] = value
self.save()

@property
def auto_disperse_after_reschedule(self):
return self.data[AUTO_DISPERSE_AFTER_RESCHEDULE]

@auto_disperse_after_reschedule.setter
def auto_disperse_after_reschedule(self, value):
self.data[AUTO_DISPERSE_AFTER_RESCHEDULE] = value
self.save()

@property
Expand Down
2 changes: 1 addition & 1 deletion schedule/disperse_siblings.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ def disperse_siblings_when_review(reviewer, card: Card, ease):

config = Config()
config.load()
if not config.auto_disperse:
if not config.auto_disperse_when_review:
return

siblings = get_siblings_when_review(card)
Expand Down
42 changes: 30 additions & 12 deletions schedule/reschedule.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
from aqt import QAction, browser

from .disperse_siblings import disperse_siblings
from ..utils import *
from ..configuration import Config
from anki.cards import Card, FSRSMemoryState
Expand Down Expand Up @@ -140,9 +142,18 @@ def reschedule(
start_time = time.time()

def on_done(future):
mw.progress.finish()
tooltip(f"{future.result()} in {time.time() - start_time:.2f} seconds")
mw.reset()
config = Config()
config.load()
if config.auto_disperse_after_reschedule:
finish_text, filtered_nid_string = future.result()
mw.progress.finish()
mw.reset()
disperse_siblings(did, True, filtered_nid_string, finish_text)
else:
finish_text = future.result()
mw.progress.finish()
tooltip(f"{finish_text} in {time.time() - start_time:.2f} seconds")
mw.reset()

fut = mw.taskman.run_in_background(
lambda: reschedule_background(
Expand Down Expand Up @@ -189,14 +200,15 @@ def reschedule_background(
if filter_flag:
filter_query = f"AND id IN {ids2str(filtered_cids)}"

cards = mw.col.db.all(
cid_did_nid = mw.col.db.all(
f"""
SELECT
id,
CASE WHEN odid==0
THEN did
ELSE odid
END
END,
nid
FROM cards
WHERE queue IN ({QUEUE_TYPE_LRN}, {QUEUE_TYPE_REV}, {QUEUE_TYPE_DAY_LEARN_RELEARN})
{did_query if did is not None else ""}
Expand All @@ -205,16 +217,16 @@ def reschedule_background(
ORDER BY ivl
"""
)
total_cnt = len(cards)
total_cnt = len(cid_did_nid)
undo_entry = mw.col.add_custom_undo_entry("Reschedule")
mw.taskman.run_on_main(
lambda: mw.progress.start(label="Rescheduling", max=total_cnt, immediate=False)
)
# x[0]: cid
# x[1]: did
# x[2]: desired retention
# x[3]: max interval
# x[4]: weights
# x[2]: nid
# x[3]: desired retention
# x[4]: max interval
cards = map(
lambda x: (
x
Expand All @@ -223,11 +235,11 @@ def reschedule_background(
DM.config_dict_for_deck_id(x[1])["rev"]["maxIvl"],
]
),
cards,
cid_did_nid,
)
cnt = 0
cancelled = False
for cid, _, desired_retention, maximum_interval in cards:
for cid, _, _, desired_retention, maximum_interval in cards:
if cancelled:
break
fsrs.desired_retention = desired_retention
Expand All @@ -249,7 +261,13 @@ def reschedule_background(
if mw.progress.want_cancel():
cancelled = True

return f"{cnt} cards rescheduled"
finish_text = f"{cnt} cards rescheduled"

if config.auto_disperse_after_reschedule:
filtered_nid_string = ids2str(set(map(lambda x: x[2], cid_did_nid)))
return (finish_text, filtered_nid_string)

return finish_text


def reschedule_card(cid, fsrs: FSRS, recompute=False):
Expand Down
3 changes: 3 additions & 0 deletions sync_hook.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ def auto_disperse(local_rids: List[int], texts: List[str]):
if not config.auto_disperse_after_sync:
return

if config.auto_reschedule_after_sync and config.auto_disperse_after_reschedule:
return

remote_reviewed_cids = review_cid_remote(local_rids)
remote_reviewed_cid_string = ids2str(remote_reviewed_cids)
remote_reviewed_nids = [
Expand Down
Loading