Search in sources :

Example 91 with DeckConfig

use of com.ichi2.libanki.DeckConfig in project Anki-Android by ankidroid.

the class Decks method load.

@Override
public void load(@NonNull String decks, @NonNull String dconf) {
    JSONObject decksarray = new JSONObject(decks);
    JSONArray ids = decksarray.names();
    mDecks = HashUtil.HashMapInit(decksarray.length());
    if (ids != null) {
        for (String id : ids.stringIterable()) {
            Deck o = new Deck(decksarray.getJSONObject(id));
            long longId = Long.parseLong(id);
            mDecks.put(longId, o);
        }
    }
    mNameMap = NameMap.constructor(mDecks.values());
    JSONObject confarray = new JSONObject(dconf);
    ids = confarray.names();
    mDconf = HashUtil.HashMapInit(confarray.length());
    if (ids != null) {
        for (String id : ids.stringIterable()) {
            mDconf.put(Long.parseLong(id), new DeckConfig(confarray.getJSONObject(id), DeckConfig.Source.DECK_CONFIG));
        }
    }
    mChanged = false;
}
Also used : JSONObject(com.ichi2.utils.JSONObject) JSONArray(com.ichi2.utils.JSONArray)

Example 92 with DeckConfig

use of com.ichi2.libanki.DeckConfig 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 93 with DeckConfig

use of com.ichi2.libanki.DeckConfig in project Anki-Android by ankidroid.

the class ZipFile method exportInto.

/**
 * Export source database into new destination database Note: The following python syntax isn't supported in
 * Android: for row in mSrc.db.execute("select * from cards where id in "+ids2str(cids)): therefore we use a
 * different method for copying tables
 *
 * @param path String path to destination database
 * @throws JSONException
 * @throws IOException
 */
public void exportInto(@NonNull String path, Context context) throws JSONException, IOException, ImportExportException {
    // create a new collection at the target
    new File(path).delete();
    Collection dst = Storage.Collection(context, path);
    mSrc = mCol;
    // find cards
    Long[] cids = cardIds();
    // attach dst to src so we can copy data between them. This isn't done in original libanki as Python more
    // flexible
    dst.close();
    Timber.d("Attach DB");
    mSrc.getDb().getDatabase().execSQL("ATTACH '" + path + "' AS DST_DB");
    // copy cards, noting used nids (as unique set)
    Timber.d("Copy cards");
    mSrc.getDb().getDatabase().execSQL("INSERT INTO DST_DB.cards select * from cards where id in " + Utils.ids2str(cids));
    List<Long> uniqueNids = mSrc.getDb().queryLongList("select distinct nid from cards where id in " + Utils.ids2str(cids));
    // notes
    Timber.d("Copy notes");
    String strnids = Utils.ids2str(uniqueNids);
    mSrc.getDb().getDatabase().execSQL("INSERT INTO DST_DB.notes select * from notes where id in " + strnids);
    // remove system tags if not exporting scheduling info
    if (!mIncludeSched) {
        Timber.d("Stripping system tags from list");
        ArrayList<String> srcTags = mSrc.getDb().queryStringList("select tags from notes where id in " + strnids);
        ArrayList<Object[]> args = new ArrayList<>(srcTags.size());
        Object[] arg = new Object[2];
        for (int row = 0; row < srcTags.size(); row++) {
            arg[0] = removeSystemTags(srcTags.get(row));
            arg[1] = uniqueNids.get(row);
            args.add(row, arg);
        }
        mSrc.getDb().executeMany("UPDATE DST_DB.notes set tags=? where id=?", args);
    }
    // models used by the notes
    Timber.d("Finding models used by notes");
    ArrayList<Long> mids = mSrc.getDb().queryLongList("select distinct mid from DST_DB.notes where id in " + strnids);
    // card history and revlog
    if (mIncludeSched) {
        Timber.d("Copy history and revlog");
        mSrc.getDb().getDatabase().execSQL("insert into DST_DB.revlog select * from revlog where cid in " + Utils.ids2str(cids));
        // reopen collection to destination database (different from original python code)
        mSrc.getDb().getDatabase().execSQL("DETACH DST_DB");
        dst.reopen();
    } else {
        Timber.d("Detaching destination db and reopening");
        // first reopen collection to destination database (different from original python code)
        mSrc.getDb().getDatabase().execSQL("DETACH DST_DB");
        dst.reopen();
        // then need to reset card state
        Timber.d("Resetting cards");
        dst.getSched().resetCards(cids);
    }
    // models - start with zero
    Timber.d("Copy models");
    for (Model m : mSrc.getModels().all()) {
        if (mids.contains(m.getLong("id"))) {
            dst.getModels().update(m);
        }
    }
    // decks
    Timber.d("Copy decks");
    java.util.Collection<Long> dids = null;
    if (mDid != null) {
        dids = new HashSet<>(mSrc.getDecks().children(mDid).values());
        dids.add(mDid);
    }
    JSONObject dconfs = new JSONObject();
    for (Deck d : mSrc.getDecks().all()) {
        if ("1".equals(d.getString("id"))) {
            continue;
        }
        if (dids != null && !dids.contains(d.getLong("id"))) {
            continue;
        }
        if (d.isStd() && d.getLong("conf") != 1L) {
            if (mIncludeSched) {
                dconfs.put(Long.toString(d.getLong("conf")), true);
            }
        }
        Deck destinationDeck = d.deepClone();
        if (!mIncludeSched) {
            // scheduling not included, so reset deck settings to default
            destinationDeck.put("conf", 1);
        }
        dst.getDecks().update(destinationDeck);
    }
    // copy used deck confs
    Timber.d("Copy deck options");
    for (DeckConfig dc : mSrc.getDecks().allConf()) {
        if (dconfs.has(dc.getString("id"))) {
            dst.getDecks().updateConf(dc);
        }
    }
    // find used media
    Timber.d("Find used media");
    JSONObject media = new JSONObject();
    mMediaDir = mSrc.getMedia().dir();
    if (mIncludeMedia) {
        ArrayList<Long> mid = mSrc.getDb().queryLongList("select mid from notes where id in " + strnids);
        ArrayList<String> flds = mSrc.getDb().queryStringList("select flds from notes where id in " + strnids);
        for (int idx = 0; idx < mid.size(); idx++) {
            for (String file : mSrc.getMedia().filesInStr(mid.get(idx), flds.get(idx))) {
                // skip files in subdirs
                if (file.contains(File.separator)) {
                    continue;
                }
                media.put(file, true);
            }
        }
        if (mMediaDir != null) {
            for (File f : new File(mMediaDir).listFiles()) {
                if (f.isDirectory()) {
                    continue;
                }
                String fname = f.getName();
                if (fname.startsWith("_")) {
                    // Loop through every model that will be exported, and check if it contains a reference to f
                    for (JSONObject model : mSrc.getModels().all()) {
                        if (_modelHasMedia(model, fname)) {
                            media.put(fname, true);
                            break;
                        }
                    }
                }
            }
        }
    }
    JSONArray keys = media.names();
    if (keys != null) {
        mMediaFiles.ensureCapacity(keys.length());
        addAll(mMediaFiles, keys.stringIterable());
    }
    Timber.d("Cleanup");
    dst.setCrt(mSrc.getCrt());
    // todo: tags?
    mCount = dst.cardCount();
    dst.setMod();
    postExport();
    dst.close();
}
Also used : ArrayList(java.util.ArrayList) JSONArray(com.ichi2.utils.JSONArray) SuppressLint(android.annotation.SuppressLint) JSONObject(com.ichi2.utils.JSONObject) JSONObject(com.ichi2.utils.JSONObject) File(java.io.File)

Aggregations

DeckConfig (com.ichi2.libanki.DeckConfig)85 Collection (com.ichi2.libanki.Collection)57 Card (com.ichi2.libanki.Card)50 Test (org.junit.Test)49 RobolectricTest (com.ichi2.anki.RobolectricTest)48 Note (com.ichi2.libanki.Note)47 JSONArray (com.ichi2.utils.JSONArray)42 JSONObject (com.ichi2.utils.JSONObject)27 Deck (com.ichi2.libanki.Deck)14 NonNull (androidx.annotation.NonNull)12 Cursor (android.database.Cursor)5 JSONException (com.ichi2.utils.JSONException)5 ArrayList (java.util.ArrayList)5 Model (com.ichi2.libanki.Model)4 HashMap (java.util.HashMap)4 SuppressLint (android.annotation.SuppressLint)3 Map (java.util.Map)3 TreeMap (java.util.TreeMap)3 ContentValues (android.content.ContentValues)2 Intent (android.content.Intent)2