def _style(self): from anki import version anki_version = int(version.replace('.', '')) if anki_version > 2119: from aqt.theme import theme_manager config = mw.addonManager.getConfig(__name__) sidebar_theme = config['Card Info sidebar_ theme'] sidebar_font = config['Card Info sidebar_ Font'] from . import styles dark_styles = styles.dark light_styles = styles.light if anki_version > 2119: if sidebar_theme == 2: mystyle = dark_styles elif sidebar_theme == 1: mystyle = light_styles else: if theme_manager.night_mode: mystyle = dark_styles else: mystyle = light_styles else: if sidebar_theme == 2: mystyle = dark_styles else: mystyle = light_styles from anki import version if version.startswith("2.0."): return "" return mystyle + "td { font-size: 75%; font-family:" + "{}".format( sidebar_font) + ";}"
#// auth_ Mohamad Janati #// Copyright (c) 2019-2020 Mohamad Janati (freaking stupid, right? :|) import json from anki.stats import CollectionStats from anki import version from typing import Any, Dict, List, Optional, Sequence, Tuple, Union anki_version = int(version.replace('.', '')) if anki_version > 2119: from aqt.theme import theme_manager def _graph_mod( self, id: str, data: Any, conf: Optional[Any] = None, type: str = "bars", xunit: int = 1, ylabel: str = _("Cards"), ylabel2: str = "", ) -> str: if conf is None: conf = {} # display settings if type == "pie": conf["legend"] = {"container": "#%sLegend" % id, "noColumns": 2} else: conf["legend"] = {"container": "#%sLegend" % id, "noColumns": 10} conf["series"] = dict(stack=True)
def _table(self): """Returns html table with more statistics than before.""" sched = self.mw.col.sched deck = self.mw.col.decks.current() dconf = self.mw.col.decks.confForDid(deck.get('id')) but = self.mw.button # Get default counts # 0 = new, 1 = learn, 2 = review counts = list(sched.counts()) finished = not sum(counts) counts = _limit(counts) totals = [ #new sched.col.db.scalar(""" select count() from (select id from cards where did = %s and queue = 0)""" % deck.get('id')), # learn sched.col.db.scalar(""" select count() from (select id from cards where did = %s and queue in (1,3))""" % deck.get('id')), # review sched.col.db.scalar(""" select count() from (select id from cards where did = %s and queue = 2)""" % deck.get('id')), # suspended sched.col.db.scalar(""" select count() from (select id from cards where did = %s and queue = -1)""" % deck.get('id')), # buried sched.col.db.scalar(""" select count() from (select id from cards where did = %s and queue = -2)""" % deck.get('id')), ] if (dconf.get('new')): dueTomorrow = _limit([ # new min(dconf.get('new').get('perDay'), totals[0]), # review sched.col.db.scalar( """ select count() from cards where did = %s and queue = 3 and due = ?""" % deck.get('id'), sched.today + 1), sched.col.db.scalar( """ select count() from cards where did = %s and queue = 2 and due = ?""" % deck.get('id'), sched.today + 1) ]) html = '' # Style if less than 2.1.20 if (int(version.replace('.', '')) < 2120): html += ''' <style> .new-count {color: #00a} .learn-count {color: #C35617} .review-count {color: #0a0} </style>''' # No need to show due if we have finished collection today if finished: mssg = sched.finishedMsg() html += ''' <div style="white-space: pre-wrap;">%s</div> <table cellspacing=5>''' % mssg else: html += '''%s <table cellpadding=5> <tr><td align=center valign=top nowrap="nowrap"> <table cellspacing=5> <tr><td nowrap="nowrap">%s:</td><td align=right> <span title="new" class="new-count">%s</span> <span title="learn" class="learn-count">%s</span> <span title="review" class="review-count">%s</span> </td></tr>''' % (bottomHTML_style, _("Due today"), counts[0], counts[1], counts[2]) if (dconf.get('new')): html += ''' <tr><td nowrap="nowrap">%s:</td><td align=right> <span title="new" class="new-count">%s</span> <span title="learn" class="learn-count">%s</span> <span title="review" class="review-count">%s</span> </td></tr>''' % (_("Due tomorrow"), dueTomorrow[0], dueTomorrow[1], dueTomorrow[2]) html += ''' <tr> <td nowrap="nowrap">%s:</td> <td align=right nowrap="nowrap"> <span title="new" class="new-count">%s</span> <span title="learn" class="learn-count">%s</span> <span title="review" class="review-count">%s</span> <span title="buried" style="color:#ffa500">%s</span> <span title="suspended" style="color:#adb300">%s</span> </td> </tr> </table>''' % (_("Total Cards"), totals[0], totals[1], totals[2], totals[4], totals[3]) if not finished: if style_mainScreenButtons: #// style='height: px' -> to prevent changing main screen buttons heights # based on height defined in #main {} mainScreen_style = """id=main style='height: px' """ else: mainScreen_style = "" if style_mainScreenButtons: studyButton_id = "main" else: studyButton_id = "study" html += '''</td> <td align=center nowrap="nowrap">%s</td> </tr></table>''' % (but("study", _("Study Now"), id="{}".format(studyButton_id), extra="autofocus")) return html
def report_mod(self): from anki import version anki_version = int(version.replace('.', '')) if anki_version > 2119: from aqt.theme import theme_manager config = mw.addonManager.getConfig(__name__) infobar_created = config['Card Info sidebar_ Created'] infobar_edited = config['Card Info sidebar_ Edited'] infobar_firstReview = config['Card Info sidebar_ First Review'] infobar_latestReview = config['Card Info sidebar_ Latest Review'] infobar_due = config['Card Info sidebar_ Due'] infobar_interval = config['Card Info sidebar_ Interval'] infobar_ease = config['Card Info sidebar_ Ease'] infobar_reviews = config['Card Info sidebar_ Reviews'] infobar_lapses = config['Card Info sidebar_ Lapses'] infobar_correctPercent = config['Card Info Sidebar_ COrrect Percent'] infobar_fastestReview = config['Card Info Sidebar_ Fastest Review'] infobar_slowestReview = config['Card Info Sidebar_ Slowest Review'] infobar_avgTime = config['Card Info sidebar_ Average Time'] infobar_totalTime = config['Card Info sidebar_ Total Time'] infobar_cardType = config['Card Info sidebar_ Card Type'] infobar_noteType = config['Card Info sidebar_ Note Type'] infobar_deck = config['Card Info sidebar_ Deck'] infobar_tags = config['Card Info sidebar_ Tags'] infobar_noteID = config['Card Info Sidebar_ Note ID'] infobar_cardID = config['Card Info Sidebar_ Card ID'] infobar_sortField = config['Card Info sidebar_ Sort Field'] c = self.card fmt = lambda x, **kwargs: fmtTimeSpan(x, short=True, **kwargs) self.txt = "<table width=100%>" if infobar_created: self.addLine( "Created", time.strftime("%Y-%m-%d | %H:%M", time.localtime(c.id / 1000))) if infobar_edited: if c.note().mod != False and time.localtime( c.id / 1000) != time.localtime(c.note().mod): self.addLine( "Edited", time.strftime("%Y-%m-%d | %H:%M", time.localtime(c.note().mod))) first = self.col.db.scalar("select min(id) from revlog where cid = ?", c.id) last = self.col.db.scalar("select max(id) from revlog where cid = ?", c.id) if first: if infobar_firstReview: self.addLine( "First Review", time.strftime("%Y-%m-%d | %H:%M", time.localtime(first / 1000))) if infobar_latestReview: self.addLine( "Latest Review", time.strftime("%Y-%m-%d | %H:%M", time.localtime(last / 1000))) if c.type != 0: if c.odid or c.queue < 0: next = None else: if c.queue in (2, 3): next = time.time() + ( (c.due - self.col.sched.today) * 86400) else: next = c.due next = self.date(next) if next: if infobar_due: self.addLine("Due", next) if c.queue == 2: if infobar_interval: self.addLine("Interval", fmt(c.ivl * 86400)) if infobar_ease: self.addLine("Ease", "%d%%" % (c.factor / 10.0)) if infobar_lapses: self.addLine("Lapses", "%d" % c.lapses) if self.col.schedVer() == 1: pressed_again = mw.col.db.scalar( "select sum(case when ease = 1 then 1 else 0 end) from revlog where cid = ?", c.id) pressed_good = mw.col.db.scalar( "select sum(case when ease = 2 then 1 else 0 end) from revlog where cid = ?", c.id) pressed_easy = mw.col.db.scalar( "select sum(case when ease = 3 then 1 else 0 end) from revlog where cid = ?", c.id) pressed_all = pressed_again + pressed_good + pressed_easy self.addLine( "Again", "{} | {:.0f}%".format( str(pressed_again).rjust(4), float(pressed_again / pressed_all) * 100)) self.addLine( "Good", "{} | {:.0f}%".format( str(pressed_good).rjust(4), float(pressed_good / pressed_all) * 100)) self.addLine( "Easy", "{} | {:.0f}%".format( str(pressed_easy).rjust(4), float(pressed_easy / pressed_all) * 100)) elif self.col.schedVer() == 2: pressed_again = mw.col.db.scalar( "select sum(case when ease = 1 then 1 else 0 end) from revlog where cid = ?", c.id) pressed_hard = mw.col.db.scalar( "select sum(case when ease = 2 then 1 else 0 end) from revlog where cid = ?", c.id) pressed_good = mw.col.db.scalar( "select sum(case when ease = 3 then 1 else 0 end) from revlog where cid = ?", c.id) pressed_easy = mw.col.db.scalar( "select sum(case when ease = 4 then 1 else 0 end) from revlog where cid = ?", c.id) pressed_all = pressed_again + pressed_hard + pressed_good + pressed_easy self.addLine( "Again", "{} | {:.0f}%".format( str(pressed_again).rjust(4), float(pressed_again / pressed_all) * 100)) self.addLine( "Hard", "{} | {:.0f}%".format( str(pressed_hard).rjust(4), float(pressed_hard / pressed_all) * 100)) self.addLine( "Good", "{} | {:.0f}%".format( str(pressed_good).rjust(4), float(pressed_good / pressed_all) * 100)) self.addLine( "Easy", "{} | {:.0f}%".format( str(pressed_easy).rjust(4), float(pressed_easy / pressed_all) * 100)) if infobar_reviews: self.addLine("Reviews", "%d" % c.reps) (cnt, total) = self.col.db.first( "select count(), sum(time)/1000 from revlog where cid = ?", c.id) if infobar_correctPercent and c.reps > 0: self.addLine( "Correct Percentage", "{:.0f}%".format( float((c.reps - c.lapses) / c.reps) * 100)) if infobar_fastestReview: fastes_rev = mw.col.db.scalar( "select time/1000.0 from revlog where cid = ? order by time asc limit 1", c.id) self.addLine("Fastest Review", self.time(fastes_rev)) if infobar_slowestReview: slowest_rev = mw.col.db.scalar( "select time/1000.0 from revlog where cid = ? order by time desc limit 1", c.id) self.addLine("Slowest Review", self.time(slowest_rev)) if cnt: if infobar_avgTime: self.addLine("Average Time", self.time(total / float(cnt))) if infobar_totalTime: self.addLine("Total Time", self.time(total)) elif c.queue == 0: if infobar_due: self.addLine("Position", c.due) if infobar_cardType: self.addLine("Card Type", c.template()['name']) if infobar_noteType: self.addLine("Note Type", c.model()['name']) if infobar_noteID: self.addLine("Note ID", c.nid) if infobar_cardID: self.addLine("Card ID", c.id) if infobar_deck: self.addLine("Deck", self.col.decks.name(c.did)) if c.note().tags: if infobar_tags: self.addLine("Tags", " | ".join(c.note().tags)) f = c.note() sort_field = htmlToTextLine(f.fields[self.col.models.sortIdx( f.model())]) if infobar_sortField: if len(sort_field) > 40: self.addLine( "Sort Field", "[{}<br>{}<br>{}...]".format(sort_field[:20], sort_field[20:41], sort_field[41:58])) else: self.addLine( "Sort Field", htmlToTextLine(f.fields[self.col.models.sortIdx( f.model())])) self.txt += "</table>" return self.txt