def lookAheadAndLog(self, cur, deckName, currDate, cardCount): """Look ahead number of days user has entered for deck and log any future dates where no cards are due as studied. currDate should be a datetime.datetime object.""" # Extract number of days from the collection dictionary numDays = int(mw.col.conf['num_days_show_anki_actbil']) # Find the due forecast for this deck, returned as array of integers future = Scheduler.dueForecast(self, numDays) # Since we're marking future days as studied where apropriate, studyPercent # should be 100 studyPercent = 100 deckName = formatDeckNameForDatabase(deckName) # Iterate through this list, excluding today (first entry) # daysAhead starts at 1 since we construct the loop in such a way as to # skip over the current date anyway daysAhead = 1 for x in future[1:]: if (x == 0): # Log the study for this future date futureDate = currDate + timedelta(days=daysAhead) # Check if we have already made a log of this day's session # and whether it was 100% checkStudyCurrDate(cur, deckName, futureDate) row = cur.fetchone() # We found a blank study day! if (row is None): logStudyToDatabase(cur, None, deckName, futureDate, studyPercent, cardCount) daysAhead += 1
def myFinishedMsg(self): """ New finished message method that will log a complete study session for us Store this in prefs.db within the user's ~/Documents/Anki/User 1/collection.media directory Store date in YYYY-MM-DD format so SQL commands can help us eliminate old dates """ # Get the due forecast for the next 7 days (0th day is today) future = Scheduler.dueForecast(self, 7) studyPercent = 100 # Grab the current date, split out the parts we want currDate = dt.datetime.now() # Get the deck ID - this will let us look up other information deckId = mw.col.decks.selected() # Get the parents array parents = mw.col.decks.parents(deckId) # Check the database version, update if necessary checkDBVersion() con = sqlite.connect(DATABASE_NAME) cur = con.cursor() # Running this guarantees that we have a valid database to query and # prevents crashes createStudyTable(cur) # If len(parents) is 0, we have the parent deck. Get children as # (name, deckId) and record studying complete for parent and child decks if (len(parents) == 0): deckName = mw.col.decks.name(deckId) parentDeckName = formatDeckNameForDatabase(deckName) # Set the studyPercent variable up for use in the routine studyPercent = 100 children = mw.col.decks.children(deckId) # As we iterate through child decks, increment parentCardCount so # we can store total card count for the parent deck parentCardCount = 0 for child, childDeckId in children: fullChildName = mw.col.decks.name(childDeckId) # Split the text by :: since that's how Anki separates # parent::child, then only display the child name # (childName[1]) childName = fullChildName.split("::") deckName = childName[1] deckName = formatDeckNameForDatabase(deckName) cardCount = mw.col.db.scalar("select count() from cards where did \ is %s" % childDeckId) parentCardCount = parentCardCount + cardCount # Store the current date into the database and 100% complete studyPercent = 100 # Check if this deck has been seen before. If not, log it so that # 'No Data' displays in the stats image checkIfNewDeck(cur, deckName, cardCount) # Check if we have already made a log of today's session # and whether it was 100% checkStudyCurrDate(cur, deckName, currDate) row = cur.fetchone() # We found a blank study day! if (row is None): logStudyToDatabase(cur, None, deckName, currDate, studyPercent, cardCount) # lookAheadAndLog(self, cur, deckName, currDate, cardCount) else: # Not a blank study day--check if study_complete is 100% if (row[3] != 100): rowId = row[0] logStudyToDatabase(cur, rowId, deckName, currDate, studyPercent, cardCount) # lookAheadAndLog(self, cur, deckName, currDate, cardCount) con.commit() # Log the parent study along with the acculumated card count # after checking whether we should be doing an insert or update. # An update could be needed if a student studied for the day but # later remembered to add a required deck for the day. checkStudyCurrDate(cur, parentDeckName, currDate) row = cur.fetchone() # This is needed to ensure we have correct card count. If a deck has no # children we must get its card count from the database. if (parentCardCount == 0): parentCardCount = mw.col.db.scalar("select count() from cards where\ did is %s" % deckId) # Check if this deck has been seen before. If not, log it so that # 'No Data' displays in the stats image checkIfNewDeck(cur, parentDeckName, parentCardCount) # If there's no row, pass None for rowId to do an INSERT # Otherwise, pass the rowId so that an UPDATE is performed if (row is None): logStudyToDatabase(cur, None, parentDeckName, currDate, studyPercent, parentCardCount) # lookAheadAndLog(self, cur, deckName, currDate, parentCardCount) else: logStudyToDatabase(cur, row[0], parentDeckName, currDate, studyPercent, parentCardCount) # lookAheadAndLog(self, cur, deckName, currDate, parentCardCount) con.commit() # If len(parents) is NOT 0, then we have a child deck. Check the status of # the parent deck. If studying is NOT complete for the parent, do nothing. # If studying IS complete for the parent, log the studying of this child # deck as complete as well. if (len(parents) != 0): parents = mw.col.decks.parents(deckId) deckName = mw.col.decks.name(deckId) deckName = formatDeckNameForDatabase(deckName) cardCount = mw.col.db.scalar("select count() from cards where did \ is %s" % deckId) # Check if this deck has been seen before. If not, log it so that # 'No Data' displays in the stats image checkIfNewDeck(cur, deckName, cardCount) # We use a for loop here so that the logic holds for decks that have # a parent and a grandparent for parent in parents: parentDeckName = formatDeckNameForDatabase(parent['name']) checkStudyCurrDate(cur, parentDeckName, currDate) row = cur.fetchone() # Check if parent deck studying is complete, if so, log child study if (row is not None and row[3] == 100): checkStudyCurrDate(cur, deckName, currDate) row = cur.fetchone() # We found a blank study day! if (row is None): logStudyToDatabase(cur, None, deckName, currDate, studyPercent, cardCount) # lookAheadAndLog(self, cur, deckName, currDate, cardCount) else: # Not a blank study day--check if study_complete is 100% if (row[3] != 100): rowId = row[0] logStudyToDatabase(cur, rowId, deckName, currDate, studyPercent, cardCount) # lookAheadAndLog(self, cur, deckName, currDate, # cardCount) else: # Display a message letting the user know to study the parent # deck or remove the deck and study separately # customPrettyMessage studyMsg = "Anki Accountability Message: Because this is a " +\ "nested deck, your study has not been logged as " +\ "complete. To have your study logged as " +\ "complete, either study the main deck to " +\ "completion, or remove this deck from the main deck " +\ "and click 'study now' again." showInfo(studyMsg) con.commit() # Close the DB connection con.close()