Search in sources :

Example 96 with DUE

use of com.ichi2.anki.CardBrowser.Column.DUE in project Anki-Android by ankidroid.

the class SchedV2 method _moveToDyn.

protected void _moveToDyn(long did, @NonNull List<Long> ids, int start) {
    Deck deck = mCol.getDecks().get(did);
    ArrayList<Object[]> data = new ArrayList<>(ids.size());
    int u = mCol.usn();
    int due = start;
    for (Long id : ids) {
        data.add(new Object[] { did, due, u, id });
        due += 1;
    }
    String queue = "";
    if (!deck.getBoolean("resched")) {
        queue = ", queue = " + Consts.QUEUE_TYPE_REV + "";
    }
    mCol.getDb().executeMany("UPDATE cards SET odid = did, " + "odue = due, did = ?, due = (case when due <= 0 then due else ? end), usn = ? " + queue + " WHERE id = ?", data);
}
Also used : ArrayList(java.util.ArrayList) Deck(com.ichi2.libanki.Deck)

Example 97 with DUE

use of com.ichi2.anki.CardBrowser.Column.DUE in project Anki-Android by ankidroid.

the class SchedV2 method _getCard.

/*
      Getting the next card ****************************************************
      *******************************************
     */
/**
 * Return the next due card, or null.
 * Overridden: V1 does not allow dayLearnFirst
 */
@Nullable
protected Card _getCard() {
    // learning card due?
    @Nullable Card c = _getLrnCard(false);
    if (c != null) {
        return c;
    }
    // new first, or time for one?
    if (_timeForNewCard()) {
        c = _getNewCard();
        if (c != null) {
            return c;
        }
    }
    // Day learning first and card due?
    boolean dayLearnFirst = mCol.get_config("dayLearnFirst", false);
    if (dayLearnFirst) {
        c = _getLrnDayCard();
        if (c != null) {
            return c;
        }
    }
    // Card due for review?
    c = _getRevCard();
    if (c != null) {
        return c;
    }
    // day learning card due?
    if (!dayLearnFirst) {
        c = _getLrnDayCard();
        if (c != null) {
            return c;
        }
    }
    // New cards left?
    c = _getNewCard();
    if (c != null) {
        return c;
    }
    // collapse or finish
    return _getLrnCard(true);
}
Also used : Nullable(androidx.annotation.Nullable) Card(com.ichi2.libanki.Card) Nullable(androidx.annotation.Nullable)

Example 98 with DUE

use of com.ichi2.anki.CardBrowser.Column.DUE in project Anki-Android by ankidroid.

the class Anki2Importer method _importCards.

/**
 * Cards
 * ***********************************************************
 */
private void _importCards() {
    if (mMustResetLearning) {
        try {
            mSrc.changeSchedulerVer(2);
        } catch (ConfirmModSchemaException e) {
            throw new RuntimeException("Changing the scheduler of an import should not cause schema modification", e);
        }
    }
    // build map of guid -> (ord -> cid) and used id cache
    /*
         * Since we can't use a tuple as a key in Java, we resort to indexing twice with nested maps.
         * Python: (guid, ord) -> cid
         * Java: guid -> ord -> cid
         */
    int nbCard = mDst.cardCount();
    Map<String, Map<Integer, Long>> cardsByGuid = HashUtil.HashMapInit(nbCard);
    Set<Long> existing = HashUtil.HashSetInit(nbCard);
    try (Cursor cur = mDst.getDb().query("select f.guid, c.ord, c.id from cards c, notes f " + "where c.nid = f.id")) {
        while (cur.moveToNext()) {
            String guid = cur.getString(0);
            int ord = cur.getInt(1);
            long cid = cur.getLong(2);
            existing.add(cid);
            if (cardsByGuid.containsKey(guid)) {
                cardsByGuid.get(guid).put(ord, cid);
            } else {
                // The size is at most the number of card type in the note type.
                Map<Integer, Long> map = new HashMap<>();
                map.put(ord, cid);
                cardsByGuid.put(guid, map);
            }
        }
    }
    // loop through src
    int nbCardsToImport = mSrc.cardCount();
    List<Object[]> cards = new ArrayList<>(nbCardsToImport);
    int totalCardCount = 0;
    final int thresExecCards = 1000;
    List<Object[]> revlog = new ArrayList<>(mSrc.getSched().logCount());
    int totalRevlogCount = 0;
    final int thresExecRevlog = 1000;
    int usn = mDst.usn();
    long aheadBy = mSrc.getSched().getToday() - mDst.getSched().getToday();
    mDst.getDb().getDatabase().beginTransaction();
    try (Cursor cur = mSrc.getDb().query("select f.guid, c.id, c.did, c.ord, c.type, c.queue, c.due, c.ivl, c.factor, c.reps, c.lapses, c.left, c.odue, c.odid, c.flags, c.data from cards c, notes f " + "where c.nid = f.id")) {
        // Counters for progress updates
        int total = cur.getCount();
        boolean largeCollection = total > 200;
        int onePercent = total / 100;
        int i = 0;
        while (cur.moveToNext()) {
            String guid = cur.getString(0);
            long cid = cur.getLong(1);
            // To keep track of card id in source
            long scid = cid;
            long did = cur.getLong(2);
            int ord = cur.getInt(3);
            @Consts.CARD_TYPE int type = cur.getInt(4);
            @Consts.CARD_QUEUE int queue = cur.getInt(5);
            long due = cur.getLong(6);
            long ivl = cur.getLong(7);
            long factor = cur.getLong(8);
            int reps = cur.getInt(9);
            int lapses = cur.getInt(10);
            int left = cur.getInt(11);
            long odue = cur.getLong(12);
            long odid = cur.getLong(13);
            int flags = cur.getInt(14);
            String data = cur.getString(15);
            if (mIgnoredGuids.contains(guid)) {
                continue;
            }
            // does the card's note exist in dst col?
            if (!mNotes.containsKey(guid)) {
                continue;
            }
            NoteTriple dnid = mNotes.get(guid);
            // does the card already exist in the dst col?
            if (cardsByGuid.containsKey(guid) && cardsByGuid.get(guid).containsKey(ord)) {
                // fixme: in future, could update if newer mod time
                continue;
            }
            // ensure the card id is unique
            while (existing.contains(cid)) {
                cid += 999;
            }
            existing.add(cid);
            // update cid, nid, etc
            long nid = mNotes.get(guid).mNid;
            did = _did(did);
            long mod = mCol.getTime().intTime();
            // review cards have a due date relative to collection
            if (queue == QUEUE_TYPE_REV || queue == QUEUE_TYPE_DAY_LEARN_RELEARN || type == CARD_TYPE_REV) {
                due -= aheadBy;
            }
            // odue needs updating too
            if (odue != 0) {
                odue -= aheadBy;
            }
            // if odid true, convert card from filtered to normal
            if (odid != 0) {
                // odid
                odid = 0;
                // odue
                due = odue;
                odue = 0;
                // queue
                if (type == CARD_TYPE_LRN) {
                    // type
                    queue = QUEUE_TYPE_NEW;
                } else {
                    queue = type;
                }
                // type
                if (type == CARD_TYPE_LRN) {
                    type = CARD_TYPE_NEW;
                }
            }
            cards.add(new Object[] { cid, nid, did, ord, mod, usn, type, queue, due, ivl, factor, reps, lapses, left, odue, odid, flags, data });
            // we need to import revlog, rewriting card ids and bumping usn
            try (Cursor cur2 = mSrc.getDb().query("select * from revlog where cid = " + scid)) {
                while (cur2.moveToNext()) {
                    Object[] rev = new Object[] { cur2.getLong(0), cur2.getLong(1), cur2.getInt(2), cur2.getInt(3), cur2.getLong(4), cur2.getLong(5), cur2.getLong(6), cur2.getLong(7), cur2.getInt(8) };
                    rev[1] = cid;
                    rev[2] = mDst.usn();
                    revlog.add(rev);
                }
            }
            i++;
            // apply card changes partially
            if (cards.size() >= thresExecCards) {
                totalCardCount += cards.size();
                insertCards(cards);
                cards.clear();
                Timber.d("add cards: %d", totalCardCount);
            }
            // apply revlog changes partially
            if (revlog.size() >= thresExecRevlog) {
                totalRevlogCount += revlog.size();
                insertRevlog(revlog);
                revlog.clear();
                Timber.d("add revlog: %d", totalRevlogCount);
            }
            if (total != 0 && (!largeCollection || i % onePercent == 0)) {
                publishProgress(100, i * 100 / total, 0);
            }
        }
        publishProgress(100, 100, 0);
        // count total values
        totalCardCount += cards.size();
        totalRevlogCount += revlog.size();
        Timber.d("add cards total:  %d", totalCardCount);
        Timber.d("add revlog total: %d", totalRevlogCount);
        // apply (for last chunk)
        insertCards(cards);
        cards.clear();
        insertRevlog(revlog);
        revlog.clear();
        mLog.add(getRes().getString(R.string.import_complete_count, totalCardCount));
        mDst.getDb().getDatabase().setTransactionSuccessful();
    } finally {
        DB.safeEndInTransaction(mDst.getDb());
    }
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Cursor(android.database.Cursor) ConfirmModSchemaException(com.ichi2.anki.exception.ConfirmModSchemaException) HashMap(java.util.HashMap) Map(java.util.Map)

Example 99 with DUE

use of com.ichi2.anki.CardBrowser.Column.DUE in project Anki-Android by ankidroid.

the class Storage method _upgrade.

private static void _upgrade(Collection col, int ver) {
    try {
        if (ver < 3) {
            // new deck properties
            for (Deck d : col.getDecks().all()) {
                d.put("dyn", DECK_STD);
                d.put("collapsed", false);
                col.getDecks().save(d);
            }
        }
        if (ver < 4) {
            col.modSchemaNoCheck();
            List<Model> models = col.getModels().all();
            ArrayList<Model> clozes = new ArrayList<>(models.size());
            for (Model m : models) {
                if (!m.getJSONArray("tmpls").getJSONObject(0).getString("qfmt").contains("{{cloze:")) {
                    m.put("type", Consts.MODEL_STD);
                } else {
                    clozes.add(m);
                }
            }
            for (Model m : clozes) {
                try {
                    _upgradeClozeModel(col, m);
                } catch (ConfirmModSchemaException e) {
                    // Will never be reached as we already set modSchemaNoCheck()
                    throw new RuntimeException(e);
                }
            }
            col.getDb().execute("UPDATE col SET ver = 4");
        }
        if (ver < 5) {
            col.getDb().execute("UPDATE cards SET odue = 0 WHERE queue = 2");
            col.getDb().execute("UPDATE col SET ver = 5");
        }
        if (ver < 6) {
            col.modSchemaNoCheck();
            for (Model m : col.getModels().all()) {
                m.put("css", new JSONObject(Models.DEFAULT_MODEL).getString("css"));
                JSONArray ar = m.getJSONArray("tmpls");
                for (JSONObject t : ar.jsonObjectIterable()) {
                    if (!t.has("css")) {
                        continue;
                    }
                    m.put("css", m.getString("css") + "\n" + t.getString("css").replace(".card ", ".card" + t.getInt("ord") + 1));
                    t.remove("css");
                }
                col.getModels().save(m);
            }
            col.getDb().execute("UPDATE col SET ver = 6");
        }
        if (ver < 7) {
            col.modSchemaNoCheck();
            col.getDb().execute("UPDATE cards SET odue = 0 WHERE (type = " + Consts.CARD_TYPE_LRN + " OR queue = 2) AND NOT odid");
            col.getDb().execute("UPDATE col SET ver = 7");
        }
        if (ver < 8) {
            col.modSchemaNoCheck();
            col.getDb().execute("UPDATE cards SET due = due / 1000 WHERE due > 4294967296");
            col.getDb().execute("UPDATE col SET ver = 8");
        }
        if (ver < 9) {
            col.getDb().execute("UPDATE col SET ver = 9");
        }
        if (ver < 10) {
            col.getDb().execute("UPDATE cards SET left = left + left * 1000 WHERE queue = " + Consts.QUEUE_TYPE_LRN);
            col.getDb().execute("UPDATE col SET ver = 10");
        }
        if (ver < 11) {
            col.modSchemaNoCheck();
            for (Deck d : col.getDecks().all()) {
                if (d.isDyn()) {
                    int order = d.getInt("order");
                    // failed order was removed
                    if (order >= 5) {
                        order -= 1;
                    }
                    JSONArray terms = new JSONArray(Arrays.asList(d.getString("search"), d.getInt("limit"), order));
                    d.put("terms", new JSONArray());
                    d.getJSONArray("terms").put(0, terms);
                    d.remove("search");
                    d.remove("limit");
                    d.remove("order");
                    d.put("resched", true);
                    d.put("return", true);
                } else {
                    if (!d.has("extendNew")) {
                        d.put("extendNew", 10);
                        d.put("extendRev", 50);
                    }
                }
                col.getDecks().save(d);
            }
            for (DeckConfig c : col.getDecks().allConf()) {
                JSONObject r = c.getJSONObject("rev");
                r.put("ivlFct", r.optDouble("ivlFct", 1));
                if (r.has("ivlfct")) {
                    r.remove("ivlfct");
                }
                r.put("maxIvl", 36500);
                col.getDecks().save(c);
            }
            for (Model m : col.getModels().all()) {
                JSONArray tmpls = m.getJSONArray("tmpls");
                for (JSONObject t : tmpls.jsonObjectIterable()) {
                    t.put("bqfmt", "");
                    t.put("bafmt", "");
                }
                col.getModels().save(m);
            }
            col.getDb().execute("update col set ver = 11");
        }
    } catch (JSONException e) {
        throw new RuntimeException(e);
    }
}
Also used : JSONObject(com.ichi2.utils.JSONObject) ArrayList(java.util.ArrayList) JSONArray(com.ichi2.utils.JSONArray) ConfirmModSchemaException(com.ichi2.anki.exception.ConfirmModSchemaException) JSONException(com.ichi2.utils.JSONException)

Example 100 with DUE

use of com.ichi2.anki.CardBrowser.Column.DUE in project Anki-Android by ankidroid.

the class Reviewer method initLayout.

@Override
protected void initLayout() {
    mTextBarNew = findViewById(R.id.new_number);
    mTextBarLearn = findViewById(R.id.learn_number);
    mTextBarReview = findViewById(R.id.review_number);
    super.initLayout();
    if (!mShowRemainingCardCount) {
        mTextBarNew.setVisibility(View.GONE);
        mTextBarLearn.setVisibility(View.GONE);
        mTextBarReview.setVisibility(View.GONE);
    }
    // can't move this into onCreate due to mTopBarLayout
    ImageView mark = mTopBarLayout.findViewById(R.id.mark_icon);
    ImageView flag = mTopBarLayout.findViewById(R.id.flag_icon);
    mCardMarker = new CardMarker(mark, flag);
}
Also used : CardMarker(com.ichi2.anki.reviewer.CardMarker) ImageView(android.widget.ImageView)

Aggregations

Test (org.junit.Test)58 Collection (com.ichi2.libanki.Collection)57 Card (com.ichi2.libanki.Card)55 Note (com.ichi2.libanki.Note)52 RobolectricTest (com.ichi2.anki.RobolectricTest)51 JSONObject (com.ichi2.utils.JSONObject)25 DeckConfig (com.ichi2.libanki.DeckConfig)20 JSONArray (com.ichi2.utils.JSONArray)16 ArrayList (java.util.ArrayList)16 Cursor (android.database.Cursor)14 Deck (com.ichi2.libanki.Deck)10 ContentResolver (android.content.ContentResolver)6 ContentValues (android.content.ContentValues)6 Uri (android.net.Uri)6 IOException (java.io.IOException)6 HashMap (java.util.HashMap)6 SuppressLint (android.annotation.SuppressLint)5 FileNotFoundException (java.io.FileNotFoundException)5 Activity (android.app.Activity)4 WebView (android.webkit.WebView)4