import time from datetime import date, timedelta from aqt import mw from copy import deepcopy from aqt.utils import shortcut, showInfo, tr from anki import version anki_version = int(version.replace('.', '')) if anki_version > 2119: from aqt.deckbrowser import DeckBrowserBottomBar from aqt.overview import OverviewBottomBar from aqt.deckbrowser import DeckBrowser from aqt.overview import Overview from . import styles config = mw.addonManager.getConfig(__name__) studyNow_label = config['Button Label_ Study Now'] more_overviewStats = config[' More Overview Stats'] bottombarButtons_style = config[' Review_ Bottombar Buttons Style'] style_mainScreenButtons = config[' Style Main Screen Buttons'] bottombar_neon1 = styles.bottombar_neon1 bottombar_neon2 = styles.bottombar_neon2 bottombar_fill1 = styles.bottombar_fill1 bottombar_fill2 = styles.bottombar_fill2 #// Chosing stylinhg for review other buttons in reviewer bottombar based on chosen style if bottombarButtons_style == 0: bottomHTML_style = "" elif bottombarButtons_style == 1: bottomHTML_style = bottombar_neon1 elif bottombarButtons_style == 2: bottomHTML_style = bottombar_neon2 elif bottombarButtons_style == 3: bottomHTML_style = bottombar_fill1 elif bottombarButtons_style == 4: bottomHTML_style = bottombar_fill2 #// Main Screen Bottombar Buttons def _drawButtons(self): buf = "{}".format(bottomHTML_style) 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 = "" drawLinks = deepcopy(self.drawLinks) for b in drawLinks: b.insert(0, "{}".format(mainScreen_style)) if b[0]: b[0] = ("Shortcut key: %s") % shortcut(b[0]) buf += """ """ % (tuple(b)) if anki_version > 2121: self.bottom.draw( buf=buf, link_handler=self._linkHandler, web_context=DeckBrowserBottomBar(self), ) else: self.bottom.draw(buf) self.bottom.web.onBridgeCmd = self._linkHandler #// Deck Overview Bottombar Buttons def _renderBottom(self): links = [ ["O", "opts", tr.actions_options()], ] if self.mw.col.decks.current()["dyn"]: links.append(["R", "refresh", tr.actions_rebuild()]) links.append(["E", "empty", tr.studying_empty()]) else: links.append(["C", "studymore", tr.actions_custom_study()]) # links.append(["F", "cram", ("Filter/Cram")]) if self.mw.col.sched.haveBuried(): links.append(["U", "unbury", tr.studying_unbury()]) links.append(["", "description", tr.scheduling_description()]) buf = "{}".format(bottomHTML_style) 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 = "" for b in links: b.insert(0, "{}".format(mainScreen_style)) if b[0]: b[0] = ("Shortcut key: %s") % shortcut(b[0]) buf += """ """ % tuple(b) if anki_version > 2121: self.bottom.draw( buf=buf, link_handler=self._linkHandler, web_context=OverviewBottomBar(self) ) else: self.bottom.draw(buf) self.bottom.web.onBridgeCmd = self._linkHandler #// Deck Overview Study Now Button | code from more overview stats to add more overview stats, OBVIOUSLY if more_overviewStats == 1: 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 += ''' ''' # No need to show due if we have finished collection today if finished: mssg = sched.finishedMsg() html += '''
%s
''' % mssg else: html +='''%s
''' % (bottomHTML_style, tr.browsing_sidebar_due_today(), counts[0], counts[1], counts[2]) if (dconf.get('new')): html += ''' ''' % (tr.statistics_due_tomorrow(), dueTomorrow[0], dueTomorrow[1], dueTomorrow[2]) html += '''
%s: %s %s %s
%s: %s %s %s
%s: %s %s %s %s %s
''' % (tr.statistics_counts_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 += '''
%s
''' % (but("study", ("{}".format(studyNow_label)), id="{}".format(studyButton_id), extra="autofocus")) return html elif more_overviewStats == 2: def _table(self): stat_colors = { "New" : "#00a", "Learning" : "#a00", "Review" : "#080", "Percent" : "#888", "Mature" : "#0051ff", "Young" : "#0051ff", "Learned" : "#080", "Unseen" : "#a00", "Suspended" : "#e7a100", "Done on Date" : "#ddd", "Days until done" : "#ddd", "Total" : "#ddd", } date_format = "%d.%m.%Y" correction_for_notes = 1 last_match_length = 0 current_deck_name = self.mw.col.decks.current()['name'] date_format = "%m/%d/%Y" try: learn_per_day = self.mw.col.decks.confForDid(self.mw.col.decks.current()['id'])['new']['perDay'] except: learn_per_day = 0 total, mature, young, unseen, suspended, due = self.mw.col.db.first( u''' select -- total count(id), -- mature sum(case when queue = 2 and ivl >= 21 then 1 else 0 end), -- young / learning sum(case when queue in (1, 3) or (queue = 2 and ivl < 21) then 1 else 0 end), -- unseen sum(case when queue = 0 then 1 else 0 end), -- suspended sum(case when queue < 0 then 1 else 0 end), -- due sum(case when queue = 1 and due <= ? then 1 else 0 end) from cards where did in {:s} '''.format(self.mw.col.sched._deckLimit()), round(time.time()) ) if not total: return u'

No Cards Found.

' scheduled_counts = list(self.mw.col.sched.counts()) deck_is_finished = not sum(scheduled_counts) cards = {} cards['mature'] = mature // int(correction_for_notes) cards['young'] = young // int(correction_for_notes) cards['unseen'] = unseen // int(correction_for_notes) cards['suspended'] = suspended // int(correction_for_notes) cards['total'] = total // int(correction_for_notes) cards['learned'] = cards['mature'] + cards['young'] cards['unlearned'] = cards['total'] - cards['learned'] cards['new'] = scheduled_counts[0] cards['learning'] = scheduled_counts[1] cards['review'] = scheduled_counts[2] # cards['due'] = due + cards['review'] cards['total_without_suspended'] = cards['total'] - cards['suspended'] try: daysUntilDone = math.ceil(cards['unseen'] / learn_per_day) except: daysUntilDone = 0 try: cards['doneDate'] = (date.today()+timedelta(days=daysUntilDone)).strftime(date_format) except: showInfo("Unsupported date format. Defaulting to Day.Month.Year instead. Use one of the shorthands: \"us\", \"asia\" or \"eu\", or specify the date like \"\%d.\%m.\%Y\", \"\%m/\%d/\%Y\" etc.\n For more information check the table at: https://docs.python.org/2/library/datetime.html#strftime-and-strptime-behavior", type="warning", title="More Overview Stats 2.1 Warning") print(date_format) cards['doneDate'] = (date.today()+timedelta(days=daysUntilDone)).strftime("%d.%m.%Y") cards['daysLeft'] = daysUntilDone if(daysUntilDone == 1): cards['daysLeft'] = '{} day'.format(daysUntilDone) else: cards['daysLeft'] = '{} days'.format(daysUntilDone) cards_percent = {} cards_percent['mature'] = cards['mature'] * 1.0 / cards['total'] cards_percent['young'] = cards['young'] * 1.0 / cards['total'] cards_percent['unseen'] = cards['unseen'] * 1.0 / cards['total'] cards_percent['suspended'] = cards['suspended'] * 1.0 / cards['total'] cards_percent['total'] = 1.0 cards_percent['learned'] = cards['learned'] * 1.0 / cards['total'] cards_percent['unlearned'] = cards['unlearned'] * 1.0 / cards['total'] cards_percent['new'] = cards['new'] * 1.0 / cards['total'] cards_percent['learning'] = cards['learning'] * 1.0 / cards['total'] cards_percent['review'] = cards['review'] * 1.0 / cards['total'] # cards_percent['due'] = cards['due'] * 1.0 / cards['total'] cards_percent_without_suspended = {} if(cards['total_without_suspended'] != 0): cards_percent_without_suspended['mature'] = cards['mature'] * 1.0 / cards['total_without_suspended'] cards_percent_without_suspended['young'] = cards['young'] * 1.0 / cards['total_without_suspended'] cards_percent_without_suspended['unseen'] = cards['unseen'] * 1.0 / cards['total_without_suspended'] cards_percent_without_suspended['suspended'] = cards['suspended'] * 1.0 / cards['total_without_suspended'] cards_percent_without_suspended['total'] = 1.0 cards_percent_without_suspended['learned'] = cards['learned'] * 1.0 / cards['total_without_suspended'] cards_percent_without_suspended['unlearned'] = cards['unlearned'] * 1.0 / cards['total_without_suspended'] cards_percent_without_suspended['new'] = cards['new'] * 1.0 / cards['total_without_suspended'] cards_percent_without_suspended['learning'] = cards['learning'] * 1.0 / cards['total_without_suspended'] cards_percent_without_suspended['review'] = cards['review'] * 1.0 / cards['total_without_suspended'] else: cards_percent_without_suspended['mature'] = 0 cards_percent_without_suspended['young'] = 0 cards_percent_without_suspended['unseen'] = 0 cards_percent_without_suspended['suspended'] = 0 cards_percent_without_suspended['total'] = 1.0 cards_percent_without_suspended['learned'] = 0 cards_percent_without_suspended['unlearned'] = 0 cards_percent_without_suspended['new'] = 0 cards_percent_without_suspended['learning'] = 0 cards_percent_without_suspended['review'] = 0 labels = {} labels['mature'] = tr.statistics_counts_mature_cards() labels['young'] = tr.statistics_counts_young_cards() labels['unseen'] = ('Unseen') labels['suspended'] = tr.statistics_counts_suspended_cards() labels['total'] = tr.statistics_counts_total_cards() labels['learned'] = ('Learned') labels['unlearned'] = ('Unlearned') labels['new'] = tr.statistics_counts_new_cards() labels['learning'] = tr.statistics_counts_learning_cards() labels['review'] = ('Review') # labels['due'] = ('Due') labels['doneDate'] = ('Done in') for key in labels: labels[key] = u'{:s}:'.format(labels[key]) button = self.mw.button output_table = u''' ''' if not deck_is_finished: output_table += u''' '''.format(label=labels, cards=cards, percent=cards_percent, percent2=cards_percent_without_suspended) output_table += u''' '''.format(label=labels, cards=cards, percent=cards_percent, percent2=cards_percent_without_suspended) output = '' if deck_is_finished: if (config == None or not 'options' in config) or (config['options'].get('Show table for finished decks', True)): output += output_table output += u'''
{label[new]:s} {cards[new]:d} {percent[new]:.0%} {percent2[new]:.0%}
{label[learning]:s} {cards[learning]:d} {percent[learning]:.0%} {percent2[learning]:.0%}
{label[review]:s} {cards[review]:d} {percent[review]:.0%} {percent2[review]:.0%}

{label[mature]:s} {cards[mature]:d} {percent[mature]:.0%} {percent2[mature]:.0%}
{label[young]:s} {cards[young]:d} {percent[young]:.0%} {percent2[young]:.0%}

{label[learned]:s} {cards[learned]:d} {percent[learned]:.0%} {percent2[learned]:.0%}
{label[unseen]:s} {cards[unseen]:d} {percent[unseen]:.0%} {percent2[unseen]:.0%}
{label[suspended]:s} {cards[suspended]:d} {percent[suspended]:.0%} ignored

{label[total]:s} {cards[total]:d} {percent[total]:.0%} {percent2[total]:.0%}

{label[doneDate]:s} {cards[daysLeft]:s} on: {cards[doneDate]:s}

''' output += u'''
{:s}
'''.format(self.mw.col.sched.finishedMsg()) else: 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" output += output_table output += bottomHTML_style output += u''' {button:s} '''.format(button=button('study', tr.studying_study_now(), id='{}'.format(studyButton_id), extra="autofocus")) return output else: def _table(self): counts = list(self.mw.col.sched.counts()) finished = not sum(counts) if self.mw.col.sched_ver() == 1: for n in range(len(counts)): if counts[n] >= 1000: counts[n] = "1000+" but = self.mw.button if finished: return '
%s
' % ( self.mw.col.sched.finishedMsg() ) else: 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" return """%s
%s:%s
%s:%s
%s:%s
%s
""" % ( bottomHTML_style, tr.actions_new(), counts[0], tr.scheduling_learning(), counts[1], tr.studying_to_review(), counts[2], but("study", tr.studying_study_now(), id="{}".format(studyButton_id), extra="autofocus"), ) def _limit(counts): for i, count in enumerate(counts): if count >= 1000: counts[i] = "1000+" return counts Overview._renderBottom = _renderBottom DeckBrowser._drawButtons = _drawButtons Overview._table = _table