-
Notifications
You must be signed in to change notification settings - Fork 0
/
AnkiPoll.py
75 lines (64 loc) · 2.62 KB
/
AnkiPoll.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
import json
import urllib.request
from bs4 import BeautifulSoup
import re
import logging
def request(action, **params):
return {"action": action, "params": params, "version": 6}
def invoke(action, **params):
try:
requestJson = json.dumps(request(action, **params)).encode("utf-8")
response = json.load(
urllib.request.urlopen(
urllib.request.Request("http://localhost:8765", requestJson)
)
)
if len(response) != 2:
raise Exception("response has an unexpected number of fields")
if "error" not in response:
raise Exception("response is missing required error field")
if "result" not in response:
raise Exception("response is missing required result field")
if response["error"] is not None:
raise Exception(response["error"])
return response["result"]
except urllib.error.URLError as ex:
print(
"Could not reach Anki. Is Anki running and the AnkiConnect add-on installed?"
)
def parseCollectionStats(stats_html):
soup = BeautifulSoup(stats_html, features="html.parser")
section = soup.find("h1", text="Today").parent
m = re.search(
r"Studied \u2068(?P<numcards>\d*)\u2069 cards.*in \u2068(?P<duration>\d*(\.\d*)?)\u2069 (?P<timeunits>.*)\u2069 today",
str(section),
re.DOTALL,
)
if m:
return m.groupdict()
elif str(section).find("No cards have been studied today"):
return {"numcards": "0", "duration": "0", "timeunits": "seconds"}
else:
logging.error("Failure parsing the collection stats.", section)
return {"numcards": "0", "duration": "0", "timeunits": "seconds"}
if __name__ == "__main__":
for name in invoke("getProfiles"):
invoke("loadProfile", name=name)
# Anki may be set to auto sync when switching profiles. If not, invoke('sync')
due = invoke("findCards", query="is:due")
new = invoke("findCards", query="is:new")
studied = invoke("findCards", query="rated:1")
stats_html = invoke("getCollectionStatsHTML")
stats = parseCollectionStats(stats_html)
print(
"{name} has {due} due, {new} new, studied {numcards} cards ({distinctcards} distinct) for {duration} {timeunits} today".format(
name=name,
due=len(due),
new=len(new),
distinctcards=len(studied),
numcards=stats["numcards"],
duration=stats["duration"],
timeunits=stats["timeunits"],
)
)
# invoke('guiExitAnki')