diff --git a/anki/stats.py b/anki/stats.py index f127eca1a..68b9f10e5 100644 --- a/anki/stats.py +++ b/anki/stats.py @@ -117,6 +117,7 @@ class CollectionStats(object): txt += self.todayStats() txt += self.dueGraph() txt += self.repsGraph() + txt += self.introductionGraph() txt += self.ivlGraph() txt += self.hourGraph() txt += self.easeGraph() @@ -254,9 +255,49 @@ group by day order by day""" % (self._limit(), lim), today=self.col.sched.today, chunk=chunk) - # Reps and time spent + # Added, reps and time spent ###################################################################### + def introductionGraph(self): + if self.type == 0: + days = 30; chunk = 1 + elif self.type == 1: + days = 52; chunk = 7 + else: + days = None; chunk = 30 + return self._introductionGraph(self._added(days, chunk), + days, _("Added")) + + def _introductionGraph(self, data, days, title): + if not data: + return "" + d = data + conf = dict( + xaxis=dict(tickDecimals=0, max=0.5), + yaxes=[dict(min=0), dict(position="right",min=0)]) + if days is not None: + conf['xaxis']['min'] = -days+0.5 + def plot(id, data, ylabel, ylabel2): + return self._graph( + id, data=data, conf=conf, ylabel=ylabel, ylabel2=ylabel2) + # graph + (repdata, repsum) = self._splitRepData(d, ((1, colLearn, ""),)) + txt = self._title( + title, _("The number of new cards you have added.")) + txt += plot("intro", repdata, ylabel=_("Cards"), ylabel2=_("Cumulative Cards")) + # total and per day average + tot = sum([i[1] for i in d]) + period = self._periodDays() + if not period: + # base off date of earliest added card + period = self._deckAge('add') + i = [] + self._line(i, _("Total"), _("%i cards") % tot) + self._line(i, _("Average"), _("%.01f cards/day") % (float(tot) / period)) + txt += self._lineTbl(i) + + return txt + def repsGraph(self): if self.type == 0: days = 30; chunk = 1 @@ -322,15 +363,7 @@ group by day order by day""" % (self._limit(), lim), period = self._periodDays() if not period: # base off earliest repetition date - lim = self._revlogLimit() - if lim: - lim = " where " + lim - t = self.col.db.scalar("select id from revlog %s order by id limit 1" % lim) - if not t: - period = 1 - else: - period = max( - 1, int(1+((self.col.sched.dayCutoff - (t/1000)) / 86400))) + period = self._deckAge('review') i = [] self._line(i, _("Days studied"), _("%(pct)d%% (%(x)s of %(y)s)") % dict( @@ -394,6 +427,27 @@ group by day order by day""" % (self._limit(), lim), bars={'show': False}, lines=dict(show=True), stack=-n)) return (ret, alltot) + def _added(self, num=7, chunk=1): + lims = [] + if num is not None: + lims.append("id > %d" % ( + (self.col.sched.dayCutoff-(num*chunk*86400))*1000)) + lims.append("did in %s" % self._limit()) + if lims: + lim = "where " + " and ".join(lims) + else: + lim = "" + if self.type == 0: + tf = 60.0 # minutes + else: + tf = 3600.0 # hours + return self.col.db.all(""" +select +(cast((id/1000.0 - :cut) / 86400.0 as int))/:chunk as day, +count(id) +from cards %s +group by day order by day""" % lim, cut=self.col.sched.dayCutoff,tf=tf, chunk=chunk) + def _done(self, num=7, chunk=1): lims = [] if num is not None: @@ -839,6 +893,22 @@ $(function () { def _title(self, title, subtitle=""): return '

%s

%s' % (title, subtitle) + def _deckAge(self, by): + lim = self._revlogLimit() + if lim: + lim = " where " + lim + if by == 'review': + t = self.col.db.scalar("select id from revlog %s order by id limit 1" % lim) + elif by == 'add': + lim = "where did in %s" % ids2str(self.col.decks.active()) + t = self.col.db.scalar("select id from cards %s order by id limit 1" % lim) + if not t: + period = 1 + else: + period = max( + 1, int(1+((self.col.sched.dayCutoff - (t/1000)) / 86400))) + return period + def _periodDays(self): if self.type == 0: return 30 diff --git a/aqt/exporting.py b/aqt/exporting.py index cb5bdd1ae..bc373b077 100644 --- a/aqt/exporting.py +++ b/aqt/exporting.py @@ -41,6 +41,7 @@ class ExportDialog(QDialog): def exporterChanged(self, idx): self.exporter = exporters()[idx][1](self.col) self.isApkg = hasattr(self.exporter, "includeSched") + self.isTextNote = hasattr(self.exporter, "includeTags") self.hideTags = hasattr(self.exporter, "hideTags") self.frm.includeSched.setVisible(self.isApkg) self.frm.includeMedia.setVisible(self.isApkg) @@ -103,8 +104,12 @@ class ExportDialog(QDialog): period = 5000 else: period = 3000 - msg = ngettext("%d card exported.", "%d cards exported.", \ - self.exporter.count) % self.exporter.count + if self.isTextNote: + msg = ngettext("%d note exported.", "%d notes exported.", + self.exporter.count) % self.exporter.count + else: + msg = ngettext("%d card exported.", "%d cards exported.", + self.exporter.count) % self.exporter.count tooltip(msg, period=period) finally: self.mw.progress.finish()