Search in sources :

Example 26 with Model

use of com.ichi2.libanki.Model in project AnkiChinaAndroid by ankichinateam.

the class Finder method ordForMid.

/**
 * Find duplicates
 * ***********************************************************
 */
public static Integer ordForMid(Collection col, Map<Long, Integer> fields, long mid, String fieldName) {
    if (!fields.containsKey(mid)) {
        JSONObject model = col.getModels().get(mid);
        JSONArray flds = model.getJSONArray("flds");
        for (int c = 0; c < flds.length(); c++) {
            JSONObject f = flds.getJSONObject(c);
            if (f.getString("name").equalsIgnoreCase(fieldName)) {
                fields.put(mid, c);
                break;
            }
        }
    }
    return fields.get(mid);
}
Also used : JSONObject(com.ichi2.utils.JSONObject) JSONArray(com.ichi2.utils.JSONArray)

Example 27 with Model

use of com.ichi2.libanki.Model in project AnkiChinaAndroid by ankichinateam.

the class Media method filesInStr.

/**
 * Extract media filenames from an HTML string.
 *
 * @param string        The string to scan for media filenames ([sound:...] or <img...>).
 * @param includeRemote If true will also include external http/https/ftp urls.
 * @return A list containing all the sound and image filenames found in the input string.
 */
public static List<String> filesInStr(Collection mCol, Long mid, String string, boolean includeRemote) {
    List<String> l = new ArrayList<>();
    JSONObject model = mCol.getModels().get(mid);
    List<String> strings = new ArrayList<>();
    if (model.getInt("type") == Consts.MODEL_CLOZE && string.contains("{{c")) {
        // if the field has clozes in it, we'll need to expand the
        // possibilities so we can render latex
        strings = _expandClozes(string);
    } else {
        strings.add(string);
    }
    for (String s : strings) {
        // handle latex
        s = LaTeX.mungeQA(s, mCol, model);
        // extract filenames
        Matcher m;
        for (Pattern p : mRegexps) {
            // NOTE: python uses the named group 'fname'. Java doesn't have named groups, so we have to determine
            // the index based on which pattern we are using
            int fnameIdx = p.equals(fSoundRegexps) ? 2 : p.equals(fImgRegExpU) ? 2 : 3;
            m = p.matcher(s);
            while (m.find()) {
                String fname = m.group(fnameIdx);
                boolean isLocal = !fRemotePattern.matcher(fname.toLowerCase(Locale.US)).find();
                if (isLocal || includeRemote) {
                    l.add(fname);
                }
            }
        }
    }
    return l;
}
Also used : Pattern(java.util.regex.Pattern) JSONObject(com.ichi2.utils.JSONObject) Matcher(java.util.regex.Matcher) ArrayList(java.util.ArrayList)

Example 28 with Model

use of com.ichi2.libanki.Model in project AnkiChinaAndroid by ankichinateam.

the class Collection method basicCheck.

/**
 * DB maintenance *********************************************************** ************************************
 */
/*
     * Basic integrity check for syncing. True if ok.
     */
public boolean basicCheck() {
    // cards without notes
    if (mDb.queryScalar("select 1 from cards where nid not in (select id from notes) limit 1") > 0) {
        return false;
    }
    boolean badNotes = mDb.queryScalar("select 1 from notes where id not in (select distinct nid from cards) " + "or mid not in " + Utils.ids2str(getModels().ids()) + " limit 1") > 0;
    // notes without cards or models
    if (badNotes) {
        return false;
    }
    // invalid ords
    for (JSONObject m : getModels().all()) {
        // ignore clozes
        if (m.getInt("type") != Consts.MODEL_STD) {
            continue;
        }
        // Make a list of valid ords for this model
        JSONArray tmpls = m.getJSONArray("tmpls");
        boolean badOrd = mDb.queryScalar("select 1 from cards where (ord < 0 or ord >= ?) and nid in ( " + "select id from notes where mid = ?) limit 1", tmpls.length(), m.getLong("id")) > 0;
        if (badOrd) {
            return false;
        }
    }
    return true;
}
Also used : JSONObject(com.ichi2.utils.JSONObject) JSONArray(com.ichi2.utils.JSONArray)

Example 29 with Model

use of com.ichi2.libanki.Model in project AnkiChinaAndroid by ankichinateam.

the class Collection method genCards.

public ArrayList<Long> genCards(long[] nids) {
    // build map of (nid,ord) so we don't create dupes
    String snids = Utils.ids2str(nids);
    HashMap<Long, HashMap<Integer, Long>> have = new HashMap<>();
    HashMap<Long, Long> dids = new HashMap<>();
    HashMap<Long, Long> dues = new HashMap<>();
    Cursor cur = null;
    try {
        cur = mDb.getDatabase().query("select id, nid, ord, did, due, odue, odid, type from cards where nid in " + snids, null);
        while (cur.moveToNext()) {
            long id = cur.getLong(0);
            long nid = cur.getLong(1);
            int ord = cur.getInt(2);
            long did = cur.getLong(3);
            long due = cur.getLong(4);
            long odue = cur.getLong(5);
            long odid = cur.getLong(6);
            @Consts.CARD_TYPE int type = cur.getInt(7);
            // existing cards
            if (!have.containsKey(nid)) {
                have.put(nid, new HashMap<Integer, Long>());
            }
            have.get(nid).put(ord, id);
            // if in a filtered deck, add new cards to original deck
            if (odid != 0) {
                did = odid;
            }
            // and their dids
            if (dids.containsKey(nid)) {
                if (dids.get(nid) != 0 && dids.get(nid) != did) {
                    // cards are in two or more different decks; revert to model default
                    dids.put(nid, 0L);
                }
            } else {
                // first card or multiple cards in same deck
                dids.put(nid, did);
            }
            // save due
            if (odid != 0) {
                due = odue;
            }
            if (!dues.containsKey(nid) && type == Consts.CARD_TYPE_NEW) {
                dues.put(nid, due);
            }
        }
    } finally {
        if (cur != null && !cur.isClosed()) {
            cur.close();
        }
    }
    // build cards for each note
    ArrayList<Object[]> data = new ArrayList<>();
    long ts = getTime().maxID(mDb);
    long now = getTime().intTime();
    ArrayList<Long> rem = new ArrayList<>();
    int usn = usn();
    cur = null;
    try {
        cur = mDb.getDatabase().query("SELECT id, mid, flds FROM notes WHERE id IN " + snids, null);
        while (cur.moveToNext()) {
            long nid = cur.getLong(0);
            long mid = cur.getLong(1);
            String flds = cur.getString(2);
            Model model = getModels().get(mid);
            ArrayList<Integer> avail = getModels().availOrds(model, Utils.splitFields(flds));
            Long did = dids.get(nid);
            // use sibling due if there is one, else use a new id
            long due;
            if (dues.containsKey(nid)) {
                due = dues.get(nid);
            } else {
                due = nextID("pos");
            }
            if (did == null || did == 0L) {
                did = model.getLong("did");
            }
            // add any missing cards
            for (JSONObject t : _tmplsFromOrds(model, avail)) {
                int tord = t.getInt("ord");
                boolean doHave = have.containsKey(nid) && have.get(nid).containsKey(tord);
                if (!doHave) {
                    // check deck is not a cram deck
                    long ndid;
                    try {
                        ndid = t.getLong("did");
                        if (ndid != 0) {
                            did = ndid;
                        }
                    } catch (JSONException e) {
                    // do nothing
                    }
                    if (getDecks().isDyn(did)) {
                        did = 1L;
                    }
                    // if the deck doesn't exist, use default instead
                    did = mDecks.get(did).getLong("id");
                    // give it a new id instead
                    data.add(new Object[] { ts, nid, did, tord, now, usn, due });
                    ts += 1;
                }
            }
            // note any cards that need removing
            if (have.containsKey(nid)) {
                for (Map.Entry<Integer, Long> n : have.get(nid).entrySet()) {
                    if (!avail.contains(n.getKey())) {
                        rem.add(n.getValue());
                    }
                }
            }
        }
    } finally {
        if (cur != null && !cur.isClosed()) {
            cur.close();
        }
    }
    // bulk update
    mDb.executeMany("INSERT INTO cards VALUES (?,?,?,?,?,?,0,0,?,0,0,0,0,0,0,0,0,\"\")", data);
    return rem;
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) JSONException(com.ichi2.utils.JSONException) Cursor(android.database.Cursor) SuppressLint(android.annotation.SuppressLint) JSONObject(com.ichi2.utils.JSONObject) Map(java.util.Map) HashMap(java.util.HashMap)

Example 30 with Model

use of com.ichi2.libanki.Model in project AnkiChinaAndroid by ankichinateam.

the class Models method scmhash.

/**
 * Schema hash ***********************************************************************************************
 */
/**
 * Return a hash of the schema, to see if models are compatible.
 */
public String scmhash(Model m) {
    String s = "";
    JSONArray flds = m.getJSONArray("flds");
    for (int i = 0; i < flds.length(); ++i) {
        s += flds.getJSONObject(i).getString("name");
    }
    JSONArray tmpls = m.getJSONArray("tmpls");
    for (int i = 0; i < tmpls.length(); ++i) {
        JSONObject t = tmpls.getJSONObject(i);
        s += t.getString("name");
    }
    return Utils.checksum(s);
}
Also used : JSONObject(com.ichi2.utils.JSONObject) JSONArray(com.ichi2.utils.JSONArray)

Aggregations

JSONObject (com.ichi2.utils.JSONObject)124 Model (com.ichi2.libanki.Model)95 Test (org.junit.Test)82 JSONArray (com.ichi2.utils.JSONArray)79 Collection (com.ichi2.libanki.Collection)53 ArrayList (java.util.ArrayList)48 Note (com.ichi2.libanki.Note)40 RobolectricTest (com.ichi2.anki.RobolectricTest)38 JSONException (com.ichi2.utils.JSONException)32 Intent (android.content.Intent)30 Card (com.ichi2.libanki.Card)27 ConfirmModSchemaException (com.ichi2.anki.exception.ConfirmModSchemaException)26 HashMap (java.util.HashMap)22 Bundle (android.os.Bundle)20 NonNull (androidx.annotation.NonNull)20 SuppressLint (android.annotation.SuppressLint)16 View (android.view.View)16 ConfirmationDialog (com.ichi2.anki.dialogs.ConfirmationDialog)15 IOException (java.io.IOException)15 Nullable (androidx.annotation.Nullable)14