forked from open-spaced-repetition/fsrs4anki-helper
-
Notifications
You must be signed in to change notification settings - Fork 0
/
sync_hook.py
101 lines (83 loc) · 2.83 KB
/
sync_hook.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
from aqt.gui_hooks import sync_will_start, sync_did_finish
from .schedule.reschedule import reschedule
from .schedule.disperse_siblings import disperse_siblings
from .configuration import Config
from .utils import *
from anki.utils import ids2str
def create_comparelog(local_rids: List[int]) -> None:
local_rids.clear()
local_rids.extend([id for id in mw.col.db.list("SELECT id FROM revlog")])
def review_cid_remote(local_rids: List[int]):
config = Config()
config.load()
local_rid_string = ids2str(local_rids)
# get cids of revlog entries that were not present in the collection before sync
# exclude manual entries and reviews done in filtered decks with rescheduling disabled
remote_reviewed_cids = [
cid
for cid in mw.col.db.list(
f"""SELECT DISTINCT cid
FROM revlog
WHERE id NOT IN {local_rid_string}
AND ease > 0
AND (type < 3 OR factor != 0)
"""
) # type: 0=learn, 1=review, 2=relearn, 3=filtered, 4=manual
]
return remote_reviewed_cids
def auto_reschedule(local_rids: List[int], texts: List[str]):
if len(local_rids) == 0:
return
texts.clear()
config = Config()
config.load()
if not config.auto_reschedule_after_sync:
texts.append("reschedule skipped")
return
remote_reviewed_cids = review_cid_remote(local_rids)
fut = reschedule(
did=None,
recent=False,
filter_flag=True,
filtered_cids=set(remote_reviewed_cids),
)
if fut:
# wait for reschedule to finish
texts.append(fut.result())
def auto_disperse(local_rids: List[int], texts: List[str]):
if len(local_rids) == 0:
return
config = Config()
config.load()
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 = [
nid
for nid in mw.col.db.list(
f"""SELECT DISTINCT nid
FROM cards
WHERE id IN {remote_reviewed_cid_string}
"""
)
]
remote_reviewed_nid_string = ids2str(remote_reviewed_nids)
fut = disperse_siblings(
None,
filter_flag=True,
filtered_nid_string=remote_reviewed_nid_string,
text_from_reschedule="<br>".join(texts),
)
texts.clear()
if fut:
# wait for disperse to finish
return fut.result()
def init_sync_hook():
local_rids = []
texts = []
sync_will_start.append(lambda: create_comparelog(local_rids))
sync_did_finish.append(lambda: auto_reschedule(local_rids, texts))
sync_did_finish.append(lambda: auto_disperse(local_rids, texts))