import argparse import datetime import dateutil import sqlite3 import sys from voussoirkit import betterhelp def ankipit(sql, to_date): # My Anki is configured for 4:00 AM start of day timestamp_startofday = (to_date + datetime.timedelta(hours=4)).timestamp() * 1000 timestamp_endofday = (to_date + datetime.timedelta(days=1, hours=4)).timestamp() * 1000 card_ids = [x['id'] for x in sql.execute('SELECT id FROM cards WHERE id < ?', [timestamp_endofday]).fetchall()] cards_added_today = sql.execute('SELECT count(id) FROM cards WHERE id >= ? AND id < ?', [timestamp_startofday, timestamp_endofday]).fetchone()[0] revlog = sql.execute('SELECT id,cid,ivl,lastIvl,type from revlog WHERE id < ? ORDER BY id ASC', [timestamp_endofday]).fetchall() reviews_today = sql.execute('SELECT count(id) FROM revlog WHERE id >= ? AND id < ?', [timestamp_startofday, timestamp_endofday]).fetchone()[0] new_studied_today = sql.execute('SELECT count(id) FROM revlog WHERE id >= ? AND id < ? AND lastIvl=0', [timestamp_startofday, timestamp_endofday]).fetchone()[0] mature_pass_today = sql.execute('SELECT count(id) FROM revlog WHERE id >= ? AND id < ? AND ivl >= 21 AND lastIvl>=21', [timestamp_startofday, timestamp_endofday]).fetchone()[0] mature_fail_today = sql.execute('SELECT count(id) FROM revlog WHERE id >= ? AND id < ? AND ivl < 21 AND lastIvl>=21', [timestamp_startofday, timestamp_endofday]).fetchone()[0] mature_retention_today = 'n/a' if (mature_pass_today + mature_fail_today) == 0 else f'{(mature_pass_today*100)/((mature_pass_today+mature_fail_today)):0.1f}%' card_revs = {card_id: [] for card_id in card_ids} for rev in revlog: if rev['cid'] not in card_revs: continue card_revs[rev['cid']].append(rev) new = 0 learning = 0 relearning = 0 young = 0 mature = 0 mature_pass = 0 mature_fail = 0 total = len(card_ids) for (card_id, revs) in card_revs.items(): if len(revs) == 0: new += 1 continue last_rev = revs[-1] if last_rev['ivl'] != 0 and last_rev['lastIvl'] >= 21: if last_rev['ivl'] >= 21: mature_pass += 1 else: mature_fail += 1 if last_rev['ivl'] == 0: new += 1 elif last_rev['ivl'] < 0 and last_rev['type'] == 0: learning += 1 elif last_rev['ivl'] < 0: relearning += 1 elif last_rev['ivl'] >= 21: mature += 1 else: young += 1 dow = ['월', '화', '수', '목', '금', '토', '일'][to_date.weekday()] strfdate = to_date.strftime('%Y-%m-%d') print(f'{strfdate} ({dow})|{total}|{new}|{learning}|{relearning}|{young}|{mature}|{reviews_today}|{mature_pass_today}/{mature_pass_today+mature_fail_today} ({mature_retention_today})|{new_studied_today}') def ankipit_argparse(args): sql = sqlite3.connect(args.database) sql.row_factory = sqlite3.Row from_date = dateutil.parser.parse(args.from_date).replace(hour=0, minute=0, second=0, microsecond=0) to_date = dateutil.parser.parse(args.to_date).replace(hour=0, minute=0, second=0, microsecond=0) print('date|total cards|new|learning|relearning|young|mature|studied today|mature retention|new studied') print(' -:| -:| -:| -:| -:| -:| -:| -:| -:| -:') target_date = from_date while target_date <= to_date: ankipit(sql, target_date) target_date = target_date + datetime.timedelta(days=1) return 0 def main(argv): parser = argparse.ArgumentParser( description=''' ''', ) parser.add_argument( 'database', help=''' ''', ) parser.add_argument( '--from', dest='from_date', required=True, help=''' ''', ) parser.add_argument( '--to', dest='to_date', required=True, help=''' ''', ) parser.set_defaults(func=ankipit_argparse) return betterhelp.go(parser, argv) if __name__ == '__main__': raise SystemExit(main(sys.argv[1:]))