· 5 years ago · Jun 30, 2020, 09:56 PM
1from anki.hooks import wrap
2from aqt.addcards import AddCards
3from anki.stats import CollectionStats
4from aqt.utils import showInfo
5from anki.notes import Note
6import aqt
7import anki
8
9import json
10import time
11import sqlite3
12from sqlite3 import Error
13import os
14import pathlib
15import sys
16
17
18def create_connection(db_file):
19 conn = None
20 try:
21 conn = sqlite3.connect(db_file)
22 except Error as e:
23 print(e)
24
25 return conn
26
27
28def myInit(self, mw):
29 self.start = time.time()
30
31
32def convert_time(seconds): # converts time to minutes / hours if needed
33 seconds = float(seconds)
34 if seconds >= 3600:
35 return str(round(seconds / 3600, 2)) + " " + "hours"
36 elif seconds >= 60:
37 return str(round(seconds / 60, 2)) + " " + "minutes"
38 else:
39 return str(round(seconds, 2)) + " " + "seconds"
40
41
42def addCardToDB(self, note):
43 t = round(time.time() - self.start, 2)
44 if t > maxCreationTime:
45 t = maxCreationTime
46
47 cursor.execute('''INSERT INTO times(note, time, deck) VALUES (?, ?, ?)''', [
48 note.id, t, self.deckChooser.selectedId()])
49 db.commit()
50 self.start = time.time()
51 return note
52
53
54def myTodayStats(self, _old):
55 lims = "WHERE note > %d" % ((self.col.sched.dayCutoff - 86400) * 1000)
56 if not self.wholeCollection:
57 deckId = self._limit()
58 lims += " AND " + ("deck = " + str(deckId))
59
60 todays_time_adding = cursor.execute(
61 '''SELECT time FROM times %s''' % lims).fetchall()
62 tot = sum([i[0] for i in todays_time_adding])
63
64 b = "<br>" + "Spent {} creating cards today".format(
65 str(convert_time(tot)))
66 return _old(self) + b
67
68
69def addGraph(self, _old):
70
71 colLearn = "#00F" # colour of bars
72 start, days, chunk = self.get_start_end_chunk()
73 lims = []
74 if days is not None:
75 lims.append("note > " +
76 str((aqt.mw.col.sched.dayCutoff - (days * chunk * 86400)) * 1000))
77 # adds an extra condition depending on the scope of the data
78 if not self.wholeCollection:
79 deckId = self._limit()
80 lims.append("deck = " + str(deckId))
81 if len(lims) == 2:
82 lim = "WHERE " + " AND ".join(lims)
83 elif len(lims) == 1:
84 lim = "WHERE " + lims[0]
85 else:
86 lim = ""
87 # lim is actually the last argument, it is just passed differently (%s)
88 # rounds time in minutes to 1 d.p, might change this later on
89 cursor.execute("""
90select
91(cast((note/1000.0 - ?) / 86400.0 as int))/? as day,
92round(sum(time/60), 1)
93from times %s
94group by day order by day"""
95 % lim, [self.col.sched.dayCutoff, chunk]
96 )
97 data = cursor.fetchall()
98
99 if not data:
100 return ""
101 conf = dict(
102 xaxis=dict(tickDecimals=0, max=0.5),
103 yaxes=[dict(min=0), dict(position="right", min=0)],
104 )
105 if days is not None:
106 conf["xaxis"]["min"] = -days + 0.5
107
108 def plot(id, data, ylabel, ylabel2):
109 return self._graph(
110 id, data=data, conf=conf, xunit=chunk, ylabel=ylabel, ylabel2=ylabel2
111 )
112 repdata, repsum = self._splitRepData(data, ((1, colLearn, ""),))
113 # sys.stderr.write(str(repdata) + "\n")
114 txt = self._title(_("Time Creating Cards"), _(
115 "The amount of time you have spent creating cards."))
116 txt += plot("added", repdata, ylabel=_("Minutes"),
117 ylabel2=_("Cumulative minutes"))
118 tot = sum([i[1] for i in data]) * 60 # convert minutes -> seconds
119
120 i = []
121 self._line(i, _("Total Time"), convert_time(tot))
122 txt += self._lineTbl(i)
123
124 return _old(self) + self._section("<center>%s</center>" % txt)
125
126
127 # finds path to test.db and opens it
128__here__ = pathlib.Path(__file__).resolve().parent
129db_file = str(__here__ / 'user_files' / "test.db")
130db = create_connection(db_file)
131
132# creates the table if it doesn't exist and commits
133cursor = db.cursor()
134cursor.execute(
135 '''CREATE TABLE IF NOT EXISTS times(note INTEGER, time INTEGER, deck INTEGER)''')
136db.commit()
137
138# finds the maxCreationTime variable from the json file
139config = aqt.mw.addonManager.getConfig(__name__)
140maxCreationTime = config['maxCreationTime']
141
142AddCards.__init__ = wrap(AddCards.__init__, myInit)
143AddCards.addNote = wrap(AddCards.addNote, addCardToDB)
144CollectionStats.todayStats = wrap(
145 CollectionStats.todayStats, myTodayStats, "around")
146
147# to get the graph in the correct position, i add the graph to the section
148# where the 'cards added' graph is returned
149CollectionStats.introductionGraph = wrap(
150 CollectionStats.introductionGraph, addGraph, "around")