Search in sources :

Example 71 with JSONArray

use of com.ichi2.utils.JSONArray in project Anki-Android by ankidroid.

the class Decks method select.

/**
 * {@inheritDoc}
 */
@Override
public void select(long did) {
    String name = mDecks.get(did).getString("name");
    // current deck
    mCol.set_config(CURRENT_DECK, did);
    // and active decks (current + all children)
    // Note: TreeMap is already sorted
    TreeMap<String, Long> actv = children(did);
    actv.put(name, did);
    JSONArray activeDecks = new JSONArray();
    for (Long n : actv.values()) {
        activeDecks.put(n);
    }
    mCol.set_config(ACTIVE_DECKS, activeDecks);
}
Also used : JSONArray(com.ichi2.utils.JSONArray)

Example 72 with JSONArray

use of com.ichi2.utils.JSONArray in project Anki-Android by ankidroid.

the class Finder method ordForMid.

/**
 * Find duplicates
 * ***********************************************************
 * @param col  The collection
 * @param fields A map from some note type id to the ord of the field fieldName
 * @param mid a note type id
 * @param fieldName A name, assumed to be the name of a field of some note type
 * @return The ord of the field fieldName in the note type whose id is mid. null if there is no such field. Save the information in fields
 */
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);
                return c;
            }
        }
        fields.put(mid, null);
    }
    return fields.get(mid);
}
Also used : JSONObject(com.ichi2.utils.JSONObject) JSONArray(com.ichi2.utils.JSONArray)

Example 73 with JSONArray

use of com.ichi2.utils.JSONArray in project Anki-Android by ankidroid.

the class Finder method _findField.

private String _findField(String field, String val) {
    /*
         * We need two expressions to query the cards: One that will use JAVA REGEX syntax and another
         * that should use SQLITE LIKE clause syntax.
         */
    String sqlVal = val.replace("%", // For SQLITE, we escape all % signs
    "\\%").replace("*", // And then convert the * into non-escaped % signs
    "%");
    /*
         * The following three lines make sure that only _ and * are valid wildcards.
         * Any other characters are enclosed inside the \Q \E markers, which force
         * all meta-characters in between them to lose their special meaning
         */
    String javaVal = val.replace("_", "\\E.\\Q").replace("*", "\\E.*\\Q");
    /*
         * For the pattern, we use the javaVal expression that uses JAVA REGEX syntax
         */
    Pattern pattern = Pattern.compile("\\Q" + javaVal + "\\E", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
    // find models that have that field
    Map<Long, Object[]> mods = HashUtil.HashMapInit(mCol.getModels().count());
    for (JSONObject m : mCol.getModels().all()) {
        JSONArray flds = m.getJSONArray("flds");
        for (JSONObject f : flds.jsonObjectIterable()) {
            String fieldName = f.getString("name");
            fieldName = Normalizer.normalize(fieldName, Normalizer.Form.NFC);
            if (fieldName.equalsIgnoreCase(field)) {
                mods.put(m.getLong("id"), new Object[] { m, f.getInt("ord") });
            }
        }
    }
    if (mods.isEmpty()) {
        // nothing has that field
        return null;
    }
    LinkedList<Long> nids = new LinkedList<>();
    try (Cursor cur = mCol.getDb().query("select id, mid, flds from notes where mid in " + Utils.ids2str(new LinkedList<>(mods.keySet())) + " and flds like ? escape '\\'", "%" + sqlVal + "%")) {
        while (cur.moveToNext()) {
            String[] flds = Utils.splitFields(cur.getString(2));
            int ord = (Integer) mods.get(cur.getLong(1))[1];
            String strg = flds[ord];
            if (pattern.matcher(strg).matches()) {
                nids.add(cur.getLong(0));
            }
        }
    }
    if (nids.isEmpty()) {
        return "0";
    }
    return "n.id in " + Utils.ids2str(nids);
}
Also used : Pattern(java.util.regex.Pattern) JSONObject(com.ichi2.utils.JSONObject) JSONArray(com.ichi2.utils.JSONArray) Cursor(android.database.Cursor) LinkedList(java.util.LinkedList)

Example 74 with JSONArray

use of com.ichi2.utils.JSONArray in project Anki-Android by ankidroid.

the class Media method mediaChangesZip.

/*
     * Media syncing: zips
     * ***********************************************************
     */
/**
 * Unlike python, our temp zip file will be on disk instead of in memory. This avoids storing
 * potentially large files in memory which is not feasible with Android's limited heap space.
 * <p>
 * Notes:
 * <p>
 * - The maximum size of the changes zip is decided by the constant SYNC_ZIP_SIZE. If a media file exceeds this
 * limit, only that file (in full) will be zipped to be sent to the server.
 * <p>
 * - This method will be repeatedly called from MediaSyncer until there are no more files (marked "dirty" in the DB)
 * to send.
 * <p>
 * - Since AnkiDroid avoids scanning the media directory on every sync, it is possible for a file to be marked as a
 * new addition but actually have been deleted (e.g., with a file manager). In this case we skip over the file
 * and mark it as removed in the database. (This behaviour differs from the desktop client).
 * <p>
 */
public Pair<File, List<String>> mediaChangesZip() {
    File f = new File(mCol.getPath().replaceFirst("collection\\.anki2$", "tmpSyncToServer.zip"));
    List<String> fnames = new ArrayList<>();
    try (ZipOutputStream z = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(f)));
        Cursor cur = mDb.query("select fname, csum from media where dirty=1 limit " + Consts.SYNC_MAX_FILES)) {
        z.setMethod(ZipOutputStream.DEFLATED);
        // meta is a list of (fname, zipname), where zipname of null is a deleted file
        // NOTE: In python, meta is a list of tuples that then gets serialized into json and added
        // to the zip as a string. In our version, we use JSON objects from the start to avoid the
        // serialization step. Instead of a list of tuples, we use JSONArrays of JSONArrays.
        JSONArray meta = new JSONArray();
        int sz = 0;
        byte[] buffer = new byte[2048];
        for (int c = 0; cur.moveToNext(); c++) {
            String fname = cur.getString(0);
            String csum = cur.getString(1);
            fnames.add(fname);
            String normname = Utils.nfcNormalized(fname);
            if (!TextUtils.isEmpty(csum)) {
                try {
                    mCol.log("+media zip " + fname);
                    File file = new File(dir(), fname);
                    BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file), 2048);
                    z.putNextEntry(new ZipEntry(Integer.toString(c)));
                    int count = 0;
                    while ((count = bis.read(buffer, 0, 2048)) != -1) {
                        z.write(buffer, 0, count);
                    }
                    z.closeEntry();
                    bis.close();
                    meta.put(new JSONArray().put(normname).put(Integer.toString(c)));
                    sz += file.length();
                } catch (FileNotFoundException e) {
                    Timber.w(e);
                    // A file has been marked as added but no longer exists in the media directory.
                    // Skip over it and mark it as removed in the db.
                    removeFile(fname);
                }
            } else {
                mCol.log("-media zip " + fname);
                meta.put(new JSONArray().put(normname).put(""));
            }
            if (sz >= Consts.SYNC_MAX_BYTES) {
                break;
            }
        }
        z.putNextEntry(new ZipEntry("_meta"));
        z.write(Utils.jsonToString(meta).getBytes());
        z.closeEntry();
        // Don't leave lingering temp files if the VM terminates.
        f.deleteOnExit();
        return new Pair<>(f, fnames);
    } catch (IOException e) {
        Timber.e(e, "Failed to create media changes zip: ");
        throw new RuntimeException(e);
    }
}
Also used : ZipEntry(java.util.zip.ZipEntry) ArrayList(java.util.ArrayList) JSONArray(com.ichi2.utils.JSONArray) FileNotFoundException(java.io.FileNotFoundException) IOException(java.io.IOException) Cursor(android.database.Cursor) FileInputStream(java.io.FileInputStream) BufferedInputStream(java.io.BufferedInputStream) ZipOutputStream(java.util.zip.ZipOutputStream) FileOutputStream(java.io.FileOutputStream) ZipFile(java.util.zip.ZipFile) File(java.io.File) BufferedOutputStream(java.io.BufferedOutputStream) Pair(android.util.Pair)

Example 75 with JSONArray

use of com.ichi2.utils.JSONArray in project Anki-Android by ankidroid.

the class Model method parsedNodes.

/**
 * @return A list of parsed nodes for each template's question. null in case of exception
 */
public List<ParsedNode> parsedNodes() {
    JSONArray tmpls = getJSONArray("tmpls");
    List<ParsedNode> nodes = new ArrayList<>(tmpls.length());
    for (JSONObject tmpl : tmpls.jsonObjectIterable()) {
        String format_question = tmpl.getString("qfmt");
        ParsedNode node = null;
        try {
            node = ParsedNode.parse_inner(format_question);
        } catch (TemplateError er) {
            Timber.w(er);
        }
        nodes.add(node);
    }
    return nodes;
}
Also used : ParsedNode(com.ichi2.libanki.template.ParsedNode) JSONObject(com.ichi2.utils.JSONObject) JSONArray(com.ichi2.utils.JSONArray) ArrayList(java.util.ArrayList) TemplateError(com.ichi2.libanki.template.TemplateError)

Aggregations

JSONArray (com.ichi2.utils.JSONArray)188 JSONObject (com.ichi2.utils.JSONObject)97 Collection (com.ichi2.libanki.Collection)54 Test (org.junit.Test)44 ArrayList (java.util.ArrayList)42 Note (com.ichi2.libanki.Note)40 Card (com.ichi2.libanki.Card)39 DeckConfig (com.ichi2.libanki.DeckConfig)37 RobolectricTest (com.ichi2.anki.RobolectricTest)36 Deck (com.ichi2.libanki.Deck)19 Model (com.ichi2.libanki.Model)19 JSONException (com.ichi2.utils.JSONException)19 Cursor (android.database.Cursor)17 HashMap (java.util.HashMap)16 SuppressLint (android.annotation.SuppressLint)15 IOException (java.io.IOException)14 NonNull (androidx.annotation.NonNull)13 File (java.io.File)10 Response (okhttp3.Response)10 JSONArray (org.json.JSONArray)8