Search in sources :

Example 51 with Time

use of com.ichi2.libanki.utils.Time in project AnkiChinaAndroid by ankichinateam.

the class ReminderService method getDeckOptionDue.

// getDeckOptionDue information, will recur one time to workaround collection close if recur is true
@Nullable
private List<DeckDueTreeNode> getDeckOptionDue(Collection col, long dConfId, boolean recur) {
    // are working
    if (col.getDb() == null || col.getDecks().getConf(dConfId) == null) {
        Timber.d("Deck option %s became unavailable while ReminderService was working. Ignoring", dConfId);
        return null;
    }
    List<DeckDueTreeNode> decks = new ArrayList<>();
    try {
        // This loop over top level deck only. No notification will ever occur for subdecks.
        for (DeckDueTreeNode node : col.getSched().deckDueTree()) {
            JSONObject deck = col.getDecks().get(node.getDid(), false);
            // Dynamic deck has no "conf", so are not added here.
            if (deck != null && deck.optLong("conf") == dConfId) {
                decks.add(node);
            }
        }
        return decks;
    } catch (Exception e) {
        if (recur) {
            Timber.i(e, "getDeckOptionDue exception - likely database re-initialization from auto-sync. Will re-try after sleep.");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ex) {
                Timber.i(ex, "Thread interrupted while waiting to retry. Likely unimportant.");
                Thread.currentThread().interrupt();
            }
            return getDeckOptionDue(col, dConfId, false);
        } else {
            Timber.w(e, "Database unavailable while working. No re-tries left.");
        }
    }
    return null;
}
Also used : DeckDueTreeNode(com.ichi2.libanki.sched.DeckDueTreeNode) JSONObject(com.ichi2.utils.JSONObject) ArrayList(java.util.ArrayList) Nullable(androidx.annotation.Nullable)

Example 52 with Time

use of com.ichi2.libanki.utils.Time in project AnkiChinaAndroid by ankichinateam.

the class ReviewerCustomFonts method getCustomFontsMap.

/**
 * Returns a map from custom fonts names to the corresponding {@link AnkiFont} object.
 * <p>
 * The list of constructed lazily the first time is needed.
 */
private static Map<String, AnkiFont> getCustomFontsMap(Context context) {
    List<AnkiFont> fonts = Utils.getCustomFonts(context);
    Map<String, AnkiFont> customFontsMap = new HashMap<>();
    for (AnkiFont f : fonts) {
        customFontsMap.put(f.getName(), f);
    }
    return customFontsMap;
}
Also used : AnkiFont(com.ichi2.anki.AnkiFont) HashMap(java.util.HashMap)

Example 53 with Time

use of com.ichi2.libanki.utils.Time in project AnkiChinaAndroid by ankichinateam.

the class ReviewerTest method testMultipleCards.

@Test
public synchronized void testMultipleCards() throws ConfirmModSchemaException, InterruptedException {
    addNoteWithThreeCards();
    Collection col = getCol();
    JSONObject nw = col.getDecks().confForDid(1).getJSONObject("new");
    MockTime time = getCollectionTime();
    nw.put("delays", new JSONArray(new int[] { 1, 10, 60, 120 }));
    waitForAsyncTasksToComplete();
    Reviewer reviewer = startReviewer();
    waitForAsyncTasksToComplete();
    assertCounts(reviewer, 3, 0, 0);
    // card 1 is shown
    answerCardOrdinalAsGood(reviewer, 1);
    // card get scheduler in [10, 12.5] minutes
    time.addM(3);
    // We wait 3 minutes to ensure card 2 is scheduled after card 1
    // card 2 is shown
    answerCardOrdinalAsGood(reviewer, 2);
    // Same as above
    time.addM(3);
    // card 3 is shown
    answerCardOrdinalAsGood(reviewer, 3);
    undo(reviewer);
    assertCurrentOrdIs(reviewer, 3);
    // card 3 is shown
    answerCardOrdinalAsGood(reviewer, 3);
    // Anki Desktop shows "1"
    assertCurrentOrdIsNot(reviewer, 3);
}
Also used : JSONObject(com.ichi2.utils.JSONObject) JSONArray(com.ichi2.utils.JSONArray) Collection(com.ichi2.libanki.Collection) MockTime(com.ichi2.testutils.MockTime) Test(org.junit.Test)

Example 54 with Time

use of com.ichi2.libanki.utils.Time in project AnkiChinaAndroid by ankichinateam.

the class ACRATest method testCrashReportLimit.

@Test
public void testCrashReportLimit() throws Exception {
    // To test ACRA switch on  reporting, plant a production tree, and trigger a report
    Timber.plant(new AnkiDroidApp.ProductionCrashReportingTree());
    // set up as if the user had prefs saved to full auto
    setReportConfig(FEEDBACK_REPORT_ALWAYS);
    // If the user is set to always, then it's production, with interaction mode toast
    // will be useful with ACRA 5.2.0
    setAcraConfig("Production");
    // The same class/method combo is only sent once, so we face a new method each time (should test that system later)
    Exception crash = new Exception("testCrashReportSend at " + System.currentTimeMillis());
    StackTraceElement[] trace = new StackTraceElement[] { new StackTraceElement("Class", "Method" + (int) System.currentTimeMillis(), "File", (int) System.currentTimeMillis()) };
    crash.setStackTrace(trace);
    // one send should work
    CrashReportData crashData = new CrashReportDataFactory(InstrumentationRegistry.getInstrumentation().getTargetContext(), AnkiDroidApp.getInstance().getAcraCoreConfigBuilder().build()).createCrashData(new ReportBuilder().exception(crash));
    assertTrue(new LimitingReportAdministrator().shouldSendReport(InstrumentationRegistry.getInstrumentation().getTargetContext(), AnkiDroidApp.getInstance().getAcraCoreConfigBuilder().build(), crashData));
    // A second send should not work
    assertFalse(new LimitingReportAdministrator().shouldSendReport(InstrumentationRegistry.getInstrumentation().getTargetContext(), AnkiDroidApp.getInstance().getAcraCoreConfigBuilder().build(), crashData));
    // Now let's clear data
    AnkiDroidApp.deleteACRALimiterData(InstrumentationRegistry.getInstrumentation().getTargetContext());
    // A third send should work again
    assertTrue(new LimitingReportAdministrator().shouldSendReport(InstrumentationRegistry.getInstrumentation().getTargetContext(), AnkiDroidApp.getInstance().getAcraCoreConfigBuilder().build(), crashData));
}
Also used : CrashReportData(org.acra.data.CrashReportData) ReportBuilder(org.acra.builder.ReportBuilder) LimitingReportAdministrator(org.acra.config.LimitingReportAdministrator) AnkiDroidApp(com.ichi2.anki.AnkiDroidApp) CrashReportDataFactory(org.acra.data.CrashReportDataFactory) ACRAConfigurationException(org.acra.config.ACRAConfigurationException) Test(org.junit.Test) UiThreadTest(androidx.test.annotation.UiThreadTest)

Example 55 with Time

use of com.ichi2.libanki.utils.Time in project AnkiChinaAndroid by ankichinateam.

the class Sched method _fillLrn.

// sub-day learning
@Override
protected boolean _fillLrn() {
    if (mLrnCount == 0) {
        return false;
    }
    if (!mLrnQueue.isEmpty()) {
        return true;
    }
    Cursor cur = null;
    mLrnQueue.clear();
    SupportSQLiteDatabase db = mCol.getDb().getDatabase();
    try {
        /* Difference with upstream:
             * Current card can't come in the queue.
             *
             * In standard usage, a card is not requested before the previous card is marked as reviewed. However, if we
             * decide to query a second card sooner, we don't want to get the same card a second time. This simulate
             * _getLrnCard which did remove the card from the queue. _sortIntoLrn will add the card back to the queue if
             * required when the card is reviewed.
             */
        cur = db.query("SELECT due, id FROM cards WHERE did IN " + _deckLimit() + " AND queue = " + Consts.QUEUE_TYPE_LRN + " AND due < ? AND id != ? LIMIT ?", new Object[] { mDayCutoff, currentCardId(), mReportLimit });
        while (cur.moveToNext()) {
            mLrnQueue.add(cur.getLong(0), cur.getLong(1));
        }
        // as it arrives sorted by did first, we need to sort it
        mLrnQueue.sort();
        return !mLrnQueue.isEmpty();
    } finally {
        if (cur != null && !cur.isClosed()) {
            cur.close();
        }
    }
}
Also used : SupportSQLiteDatabase(androidx.sqlite.db.SupportSQLiteDatabase) JSONObject(com.ichi2.utils.JSONObject) Cursor(android.database.Cursor)

Aggregations

Test (org.junit.Test)27 Collection (com.ichi2.libanki.Collection)26 JSONObject (com.ichi2.utils.JSONObject)26 RobolectricTest (com.ichi2.anki.RobolectricTest)19 Card (com.ichi2.libanki.Card)19 Note (com.ichi2.libanki.Note)15 JSONArray (com.ichi2.utils.JSONArray)15 Deck (com.ichi2.libanki.Deck)11 ArrayList (java.util.ArrayList)11 DeckConfig (com.ichi2.libanki.DeckConfig)10 IOException (java.io.IOException)10 ConfirmModSchemaException (com.ichi2.anki.exception.ConfirmModSchemaException)9 HashMap (java.util.HashMap)9 Cursor (android.database.Cursor)8 Nullable (androidx.annotation.Nullable)8 JSONException (com.ichi2.utils.JSONException)8 SharedPreferences (android.content.SharedPreferences)7 Resources (android.content.res.Resources)7 File (java.io.File)7 View (android.view.View)5