Search in sources :

Example 21 with R

use of com.ichi2.anki.R in project AnkiChinaAndroid by ankichinateam.

the class HttpSyncer method req.

/**
 * Note: Return value must be closed
 */
private Response req(String method, InputStream fobj, int comp, JSONObject registerData) throws UnknownHttpResponseException {
    File tmpFileBuffer = null;
    try {
        String bdry = "--" + BOUNDARY;
        StringWriter buf = new StringWriter();
        // post vars
        mPostVars.put("c", comp != 0 ? 1 : 0);
        for (String key : mPostVars.keySet()) {
            buf.write(bdry + "\r\n");
            buf.write(String.format(Locale.US, "Content-Disposition: form-data; name=\"%s\"\r\n\r\n%s\r\n", key, mPostVars.get(key)));
        }
        tmpFileBuffer = File.createTempFile("syncer", ".tmp", new File(AnkiDroidApp.getCacheStorageDirectory()));
        FileOutputStream fos = new FileOutputStream(tmpFileBuffer);
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        GZIPOutputStream tgt;
        // payload as raw data or json
        if (fobj != null) {
            // header
            buf.write(bdry + "\r\n");
            buf.write("Content-Disposition: form-data; name=\"data\"; filename=\"data\"\r\nContent-Type: application/octet-stream\r\n\r\n");
            buf.close();
            bos.write(buf.toString().getBytes("UTF-8"));
            // write file into buffer, optionally compressing
            int len;
            int totalLen = 0;
            BufferedInputStream bfobj = new BufferedInputStream(fobj);
            byte[] chunk = new byte[65536];
            if (comp != 0) {
                tgt = new GZIPOutputStream(bos);
                while ((len = bfobj.read(chunk)) >= 0) {
                    tgt.write(chunk, 0, len);
                    totalLen += len;
                }
                tgt.close();
                bos = new BufferedOutputStream(new FileOutputStream(tmpFileBuffer, true));
            } else {
                while ((len = bfobj.read(chunk)) >= 0) {
                    bos.write(chunk, 0, len);
                    totalLen += len;
                }
            }
            // ������Ⱦ�����ͨ���ݳ���
            Timber.d("Write common data length: %d", totalLen);
            // ������Ⱦ�����ͨ���ݳ���
            Timber.d("Write common data length2: %d", tmpFileBuffer.length());
            bos.write(("\r\n" + bdry + "--\r\n").getBytes("UTF-8"));
        } else {
            buf.close();
            bos.write(buf.toString().getBytes("UTF-8"));
            bos.write((bdry + "--\r\n").getBytes("UTF-8"));
        }
        bos.flush();
        bos.close();
        // connection headers
        String url = Uri.parse(syncURL()).buildUpon().appendPath(method).toString();
        Request.Builder requestBuilder = new Request.Builder();
        requestBuilder.url(parseUrl(url));
        Timber.d("request url: %s", url);
        requestBuilder.post(new CountingFileRequestBody(tmpFileBuffer, ANKI_POST_TYPE.toString(), num -> {
            bytesSent += num;
            publishProgress();
        }));
        Request httpPost = requestBuilder.build();
        try {
            OkHttpClient httpClient = getHttpClient();
            Response httpResponse = httpClient.newCall(httpPost).execute();
            // we assume badAuthRaises flag from Anki Desktop always False
            // so just throw new RuntimeException if response code not 200 or 403
            Timber.d("TLSVersion in use is: %s", (httpResponse.handshake() != null ? httpResponse.handshake().tlsVersion() : "unknown"));
            assertOk(httpResponse);
            return httpResponse;
        } catch (SSLException e) {
            Timber.e(e, "SSLException while building HttpClient");
            throw new RuntimeException("SSLException while building HttpClient", e);
        }
    } catch (UnsupportedEncodingException e) {
        throw new RuntimeException(e);
    } catch (IOException e) {
        Timber.e(e, "BasicHttpSyncer.sync: IOException");
        throw new RuntimeException(e);
    } finally {
        if (tmpFileBuffer != null && tmpFileBuffer.exists()) {
            tmpFileBuffer.delete();
        }
    }
}
Also used : BufferedInputStream(java.io.BufferedInputStream) Uri(android.net.Uri) HashMap(java.util.HashMap) Random(java.util.Random) BufferedOutputStream(java.io.BufferedOutputStream) RequestBody(okhttp3.RequestBody) ByteArrayInputStream(java.io.ByteArrayInputStream) Locale(java.util.Locale) Map(java.util.Map) API_VERSION(com.ichi2.libanki.Consts.API_VERSION) Connection(com.ichi2.async.Connection) Response(okhttp3.Response) NoEnoughServerSpaceException(com.ichi2.anki.exception.NoEnoughServerSpaceException) Utils(com.ichi2.libanki.Utils) MediaType(okhttp3.MediaType) OutputStream(java.io.OutputStream) Request(okhttp3.Request) AbstractHttpEntity(org.apache.http.entity.AbstractHttpEntity) StringWriter(java.io.StringWriter) FileOutputStream(java.io.FileOutputStream) CustomSyncServer(com.ichi2.anki.web.CustomSyncServer) IOException(java.io.IOException) UnknownHttpResponseException(com.ichi2.anki.exception.UnknownHttpResponseException) JSONObject(com.ichi2.utils.JSONObject) FileInputStream(java.io.FileInputStream) InputStreamReader(java.io.InputStreamReader) File(java.io.File) FileNotFoundException(java.io.FileNotFoundException) Timber(timber.log.Timber) TimeUnit(java.util.concurrent.TimeUnit) ANKI_CHINA_BASE(com.ichi2.libanki.Consts.ANKI_CHINA_BASE) SSLException(javax.net.ssl.SSLException) Nullable(androidx.annotation.Nullable) OkHttpClient(okhttp3.OkHttpClient) SharedPreferences(android.content.SharedPreferences) AnkiDroidApp(com.ichi2.anki.AnkiDroidApp) Consts(com.ichi2.libanki.Consts) GZIPOutputStream(java.util.zip.GZIPOutputStream) BufferedReader(java.io.BufferedReader) HttpUrl(okhttp3.HttpUrl) VersionUtils(com.ichi2.utils.VersionUtils) UnsupportedEncodingException(java.io.UnsupportedEncodingException) InputStream(java.io.InputStream) OkHttpClient(okhttp3.OkHttpClient) Request(okhttp3.Request) UnsupportedEncodingException(java.io.UnsupportedEncodingException) IOException(java.io.IOException) SSLException(javax.net.ssl.SSLException) Response(okhttp3.Response) StringWriter(java.io.StringWriter) GZIPOutputStream(java.util.zip.GZIPOutputStream) BufferedInputStream(java.io.BufferedInputStream) FileOutputStream(java.io.FileOutputStream) File(java.io.File) BufferedOutputStream(java.io.BufferedOutputStream)

Example 22 with R

use of com.ichi2.anki.R in project AnkiChinaAndroid by ankichinateam.

the class Models method _updateRequired.

/**
 * Required field/text cache
 * ***********************************************************************************************
 */
private void _updateRequired(Model m) {
    if (m.getInt("type") == Consts.MODEL_CLOZE) {
        // nothing to do
        return;
    }
    JSONArray req = new JSONArray();
    ArrayList<String> flds = new ArrayList<>();
    JSONArray fields;
    fields = m.getJSONArray("flds");
    for (int i = 0; i < fields.length(); i++) {
        flds.add(fields.getJSONObject(i).getString("name"));
    }
    JSONArray templates = m.getJSONArray("tmpls");
    for (int i = 0; i < templates.length(); i++) {
        JSONObject t = templates.getJSONObject(i);
        Object[] ret = _reqForTemplate(m, flds, t);
        JSONArray r = new JSONArray();
        r.put(t.getInt("ord"));
        r.put(ret[0]);
        r.put(ret[1]);
        req.put(r);
    }
    m.put("req", req);
}
Also used : JSONObject(com.ichi2.utils.JSONObject) JSONArray(com.ichi2.utils.JSONArray) ArrayList(java.util.ArrayList) JSONObject(com.ichi2.utils.JSONObject)

Example 23 with R

use of com.ichi2.anki.R in project AnkiChinaAndroid by ankichinateam.

the class Storage method _upgradeClozeModel.

private static void _upgradeClozeModel(Collection col, Model m) throws ConfirmModSchemaException {
    m.put("type", Consts.MODEL_CLOZE);
    // convert first template
    JSONObject t = m.getJSONArray("tmpls").getJSONObject(0);
    for (String type : new String[] { "qfmt", "afmt" }) {
        t.put(type, t.getString(type).replaceAll("\\{\\{cloze:1:(.+?)\\}\\}", "{{cloze:$1}}"));
    }
    t.put("name", "Cloze");
    // delete non-cloze cards for the model
    JSONArray tmpls = m.getJSONArray("tmpls");
    ArrayList<JSONObject> rem = new ArrayList<>();
    for (int i = 1; i < tmpls.length(); i++) {
        JSONObject ta = tmpls.getJSONObject(i);
        if (!ta.getString("afmt").contains("{{cloze:")) {
            rem.add(ta);
        }
    }
    for (JSONObject r : rem) {
        col.getModels().remTemplate(m, r);
    }
    JSONArray newTmpls = new JSONArray();
    newTmpls.put(tmpls.getJSONObject(0));
    m.put("tmpls", newTmpls);
    col.getModels()._updateTemplOrds(m);
    col.getModels().save(m);
}
Also used : JSONObject(com.ichi2.utils.JSONObject) JSONArray(com.ichi2.utils.JSONArray) ArrayList(java.util.ArrayList)

Example 24 with R

use of com.ichi2.anki.R in project AnkiChinaAndroid by ankichinateam.

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", 0);
                d.put("collapsed", false);
                col.getDecks().save(d);
            }
        }
        if (ver < 4) {
            col.modSchemaNoCheck();
            ArrayList<Model> clozes = new ArrayList<>();
            for (Model m : col.getModels().all()) {
                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.defaultModel).getString("css"));
                JSONArray ar = m.getJSONArray("tmpls");
                for (int i = 0; i < ar.length(); i++) {
                    JSONObject t = ar.getJSONObject(i);
                    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.getInt("dyn") != 0) {
                    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 (int ti = 0; ti < tmpls.length(); ++ti) {
                    JSONObject t = tmpls.getJSONObject(ti);
                    t.put("bqfmt", "");
                    t.put("bafmt", "");
                }
                col.getModels().save(m);
            }
            col.getDb().execute("update col set ver = 11");
        }
    // if (ver < 12) {
    // col.getDb().execute("create table if not exists synclog (" + "    id             integer not null,"
    // + "    type             integer not null,"+ "    mod             integer not null" + ")");
    // col.getDb().execute("update col set ver = 12");
    // _updateIndices(col.getDb());
    // }
    } 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 25 with R

use of com.ichi2.anki.R in project AnkiChinaAndroid by ankichinateam.

the class ModelTest method test_req.

@Test
public void test_req() {
    Collection col = getCol();
    Models mm = col.getModels();
    Model basic = mm.byName("Basic");
    assertTrue(basic.has("req"));
    reqSize(basic);
    JSONArray r = basic.getJSONArray("req").getJSONArray(0);
    assertEquals(0, r.getInt(0));
    assertTrue(Arrays.asList(new String[] { "any", "all" }).contains(r.getString(1)));
    assertEquals(1, r.getJSONArray(2).length());
    assertEquals(0, r.getJSONArray(2).getInt(0));
    Model opt = mm.byName("Basic (optional reversed card)");
    reqSize(opt);
    r = opt.getJSONArray("req").getJSONArray(0);
    assertTrue(Arrays.asList(new String[] { "any", "all" }).contains(r.getString(1)));
    assertEquals(1, r.getJSONArray(2).length());
    assertEquals(0, r.getJSONArray(2).getInt(0));
    assertEquals(new JSONArray("[1,\"all\",[1,2]]"), opt.getJSONArray("req").getJSONArray(1));
    // testing any
    opt.getJSONArray("tmpls").getJSONObject(1).put("qfmt", "{{Back}}{{Add Reverse}}");
    mm.save(opt, true);
    assertEquals(new JSONArray("[1, \"any\", [1, 2]]"), opt.getJSONArray("req").getJSONArray(1));
    // testing null
    opt.getJSONArray("tmpls").getJSONObject(1).put("qfmt", "{{^Add Reverse}}{{/Add Reverse}}");
    mm.save(opt, true);
    assertEquals(new JSONArray("[1, \"none\", []]"), opt.getJSONArray("req").getJSONArray(1));
    opt = mm.byName("Basic (type in the answer)");
    reqSize(opt);
    r = opt.getJSONArray("req").getJSONArray(0);
    assertTrue(Arrays.asList(new String[] { "any", "all" }).contains(r.getString(1)));
    // TODO: Port anki@4e33775ed4346ef136ece6ef5efec5ba46057c6b
    assertEquals(new JSONArray("[0]"), r.getJSONArray(2));
}
Also used : JSONArray(com.ichi2.utils.JSONArray) RobolectricTest(com.ichi2.anki.RobolectricTest) Test(org.junit.Test)

Aggregations

JSONObject (com.ichi2.utils.JSONObject)17 JSONArray (com.ichi2.utils.JSONArray)14 ArrayList (java.util.ArrayList)10 Test (org.junit.Test)7 ConfirmModSchemaException (com.ichi2.anki.exception.ConfirmModSchemaException)6 Model (com.ichi2.libanki.Model)6 EditText (android.widget.EditText)5 File (java.io.File)5 Random (java.util.Random)5 Nullable (androidx.annotation.Nullable)4 ConfirmationDialog (com.ichi2.anki.dialogs.ConfirmationDialog)4 Connection (com.ichi2.async.Connection)4 IOException (java.io.IOException)4 Intent (android.content.Intent)3 SharedPreferences (android.content.SharedPreferences)3 Cursor (android.database.Cursor)3 Bundle (android.os.Bundle)3 Timber (timber.log.Timber)3 Context (android.content.Context)2 LayoutInflater (android.view.LayoutInflater)2