Search in sources :

Example 21 with LEFT

use of com.ichi2.anim.ActivityTransitionAnimation.LEFT in project AnkiChinaAndroid by ankichinateam.

the class AnkiChinaSyncer method getAddedRevLog.

private JSONObject getAddedRevLog() {
    Cursor cur = null;
    JSONObject result = new JSONObject();
    JSONArray changedData = new JSONArray();
    // String.format(Locale.ENGLISH, "select b.id,b.guid,b.mid,b.mod,b.usn,b.tags,b.flds,b.sfld,b.csum,b.flags,b.data,a.id as aid,a.mod as premod from synclog a left join %s b on a.id=b.id where a.type = %d and (b.mod ISNULL or a.mod !=b.mod)" +
    // " union " +
    // "select b.id,b.guid,b.mid,b.mod,b.usn,b.tags,b.flds,b.sfld,b.csum,b.flags,b.data,a.id as aid,a.mod as premod from %s b left join synclog a on a.id=b.id  and a.type =%d  where a.mod ISNULL or a.mod !=b.mod limit 1000 offset %d", tableName, type, tableName, type, page * 1000);
    String sql = "select b.id,b.cid,b.usn,b.ease,b.ivl,b.lastIvl,b.factor,b.time,b.type,a.id as aid,a.mod as premod from synclog a left join revlog b on a.id=b.id where a.type = 5 and (b.id ISNULL or a.mod !=b.id)" + " union " + "select b.id,b.cid,b.usn,b.ease,b.ivl,b.lastIvl,b.factor,b.time,b.type,a.id as aid,a.mod as premod from revlog b left join synclog a on a.id=b.id and a.type = 5 where a.mod ISNULL or a.mod !=b.id";
    try {
        cur = CollectionHelper.getInstance().getColSafe(AnkiDroidApp.getInstance()).getDb().getDatabase().query(sql, null);
        while (cur.moveToNext()) {
            String aid = cur.getString(cur.getColumnIndex("aid"));
            if (aid == null) {
                // 没有旧id,代表有新增
                List<Object> needReplace = new ArrayList<>();
                for (int i = 0; i < cur.getColumnCount() - 2; i++) {
                    // if(cur.getType(i) == Cursor.FIELD_TYPE_STRING)
                    needReplace.add(cur.getType(i) != Cursor.FIELD_TYPE_STRING ? cur.getLong(i) : cur.getString(i));
                }
                changedData.put(new JSONArray(needReplace));
            }
        }
    } finally {
        if (cur != null && !cur.isClosed()) {
            cur.close();
        }
    }
    result.put("replace", changedData);
    Timber.i("get added revlog:%s", result.toString());
    return result;
}
Also used : JSONObject(com.ichi2.utils.JSONObject) JSONArray(com.ichi2.utils.JSONArray) ArrayList(java.util.ArrayList) JSONObject(com.ichi2.utils.JSONObject) Cursor(android.database.Cursor) SuppressLint(android.annotation.SuppressLint)

Example 22 with LEFT

use of com.ichi2.anim.ActivityTransitionAnimation.LEFT in project AnkiChinaAndroid by ankichinateam.

the class AnkiChinaSyncer method handleServerData.

// 35%+25%
private void handleServerData(JSONObject item) {
    mCol = CollectionHelper.getInstance().getColSafe(AnkiDroidApp.getInstance());
    CollectionHelper.getInstance().lockCollection();
    updateDialogProgress(SYNCING_DATA, "更新全局配置中", mCurrentProgress + 1);
    DB db = mCol.getDb();
    try {
        JSONObject remoteCol = item.getJSONObject("col").getJSONObject("replace");
        // db.execute("update col set id ="+remoteCol.getInt("id")+","+"set crt =\"+remoteCol.getLong(\"crt\")");
        // db.execute("update col set crt ="+remoteCol.getLong("crt"));
        // db.execute("update col set mod ="+remoteCol.getLong("mod"));
        // db.execute("update col set scm ="+remoteCol.getLong("scm"));
        // db.execute("update col set ver ="+remoteCol.getInt("ver"));
        // db.execute("update col set dty ="+remoteCol.getInt("dty"));
        // db.execute("update col set usn ="+remoteCol.getInt("usn"));
        // db.execute("update col set ls ="+remoteCol.getLong("ls"));
        // db.execute("update col set conf ="+remoteCol.getString("conf"));
        // db.execute("update col set tags ="+remoteCol.getString("tags"));
        // db.execute("update col set tags ="+remoteCol.getString("tags"));
        // db.execute("update col set id = %d,");
        Timber.i("remote col config:%s", remoteCol.toString());
        @SuppressLint("DefaultLocale") String sql = String.format("update col set id = %d,crt = %d,mod=%d,scm=%d,ver=%d,dty=%d,usn=%d,ls=%d,conf='%s',tags='%s'", remoteCol.getInt("id"), remoteCol.getLong("crt"), remoteCol.getLong("mod"), remoteCol.getLong("scm"), remoteCol.getInt("ver"), remoteCol.getInt("dty"), remoteCol.getInt("usn"), remoteCol.getLong("ls"), remoteCol.getString("conf"), remoteCol.getString("tags") == null || !remoteCol.getString("tags").startsWith("{") ? "{}" : remoteCol.getString("tags"));
        db.execute(sql);
        mCol.load();
    } catch (Exception e) {
        e.printStackTrace();
    }
    Decks currentDecks = mCol.getDecks();
    // 删除多余的内容
    try {
        JSONArray deletedDecks = item.getJSONObject("decks").getJSONArray("delete");
        if (deletedDecks.length() > 0) {
            double percent = 2.0 / deletedDecks.length();
            for (int i = 0; i < deletedDecks.length(); i++) {
                String deckID = deletedDecks.getString(i);
                currentDecks.rem(Long.parseLong(deckID));
                updateDialogProgress(SYNCING_DATA, "删除多余牌组中", mCurrentProgress + percent);
            }
            mCol.save();
        }
    } catch (Exception e) {
    // e.printStackTrace();
    }
    try {
        JSONArray deletedDConf = item.getJSONObject("dconf").getJSONArray("delete");
        if (deletedDConf.length() > 0) {
            double percent = 2.0 / deletedDConf.length();
            for (int i = 0; i < deletedDConf.length(); i++) {
                String id = deletedDConf.getString(i);
                mCol.getDecks().remConf(Long.parseLong(id));
                updateDialogProgress(SYNCING_DATA, "删除多余牌组配置中", mCurrentProgress + percent);
            }
            mCol.save();
        }
    } catch (Exception e) {
    // e.printStackTrace();
    }
    try {
        JSONArray deletedModel = item.getJSONObject("models").getJSONArray("delete");
        if (deletedModel.length() > 0) {
            double percent = 2.0 / deletedModel.length();
            for (int i = 0; i < deletedModel.length(); i++) {
                String id = deletedModel.getString(i);
                mCol.getModels().rem(mCol.getModels().get(Long.parseLong(id)));
                updateDialogProgress(SYNCING_DATA, "删除多余模板中", mCurrentProgress + percent);
            }
            mCol.save();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    updateDialogProgress(SYNCING_DATA, "删除多余卡牌中", mCurrentProgress + 2);
    try {
        JSONArray deletedCards = item.getJSONObject("cards").getJSONArray("delete");
        List<Long> sids = ids2longList(deletedCards);
        Timber.e("need delete cards num:%s", sids.size());
        // db.execute("DELETE FROM cards WHERE id IN " + sids);
        mCol.remCards(sids);
        mCol.save();
    } catch (Exception e) {
        e.printStackTrace();
    }
    updateDialogProgress(SYNCING_DATA, "删除多余笔记中", mCurrentProgress + 2);
    try {
        JSONArray deletedNotes = item.getJSONObject("notes").getJSONArray("delete");
        long[] sids = ids2longArray(deletedNotes);
        // db.execute("DELETE FROM notes WHERE id IN " + sids);
        mCol.remNotes(sids);
        mCol.save();
    } catch (Exception e) {
        e.printStackTrace();
    }
    try {
        JSONObject replaceDecks = item.getJSONObject("decks").getJSONObject("replace");
        if (replaceDecks.length() > 0) {
            double percent = 2.0 / replaceDecks.length();
            Iterator<String> it = replaceDecks.keys();
            while (it.hasNext()) {
                String next = it.next();
                try {
                    // mCol.getDecks().getDecks().put(Long.parseLong(next), new Deck(replaceDecks.getJSONObject(next)));
                    mCol.getDecks().update(new Deck(replaceDecks.getJSONObject(next)));
                    updateDialogProgress(SYNCING_DATA, "同步牌组数据中", mCurrentProgress + percent);
                } catch (Exception e) {
                // 只遍历model id
                }
            }
            mCol.save();
        }
    } catch (Exception e) {
    // e.printStackTrace();
    }
    db.getDatabase().beginTransaction();
    try {
        JSONArray replace = item.getJSONObject("revlog").getJSONArray("replace");
        if (replace.length() > 0) {
            for (int i = 0; i < replace.length(); i++) {
                log(replace.getJSONArray(i).get(0), replace.getJSONArray(i).get(1), replace.getJSONArray(i).get(2), replace.getJSONArray(i).get(3), replace.getJSONArray(i).get(4), replace.getJSONArray(i).get(5), replace.getJSONArray(i).get(6), replace.getJSONArray(i).get(7), replace.getJSONArray(i).get(8));
            }
            db.getDatabase().setTransactionSuccessful();
            mCol.save();
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        db.getDatabase().endTransaction();
    }
    // Timber.e("看看是null还是null:%s,%s", (item.getJSONObject("dconf").get("replace")==JSONObject.NULL), (item.getJSONObject("dconf").getString("replace").equals("null")));
    try {
        JSONObject replaceDConf = item.getJSONObject("dconf").getJSONObject("replace");
        if (replaceDConf.length() > 0) {
            double percent = 2.0 / replaceDConf.length();
            Iterator<String> it = replaceDConf.keys();
            while (it.hasNext()) {
                String next = it.next();
                try {
                    Long.parseLong(next);
                    mCol.getDecks().updateConf(new DeckConfig(replaceDConf.getJSONObject(next)));
                    updateDialogProgress(SYNCING_DATA, "同步牌组配置数据中", mCurrentProgress + percent);
                } catch (Exception e) {
                // 只遍历model id
                }
            }
            mCol.save();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    try {
        JSONObject replaceModels = item.getJSONObject("models").getJSONObject("replace");
        if (replaceModels.length() > 0) {
            double percent = 5.0 / replaceModels.length();
            Iterator<String> it = replaceModels.keys();
            while (it.hasNext()) {
                String next = it.next();
                try {
                    Long.parseLong(next);
                    mCol.getModels().update(new Model(replaceModels.getJSONObject(next)));
                    updateDialogProgress(SYNCING_DATA, "同步模板数据中", mCurrentProgress + percent);
                } catch (Exception e) {
                // 只遍历model id
                }
            }
            mCol.save();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    db.getDatabase().beginTransaction();
    try {
        JSONArray replace = item.getJSONObject("notes").getJSONArray("replace");
        if (replace.length() > 0) {
            double percent = mPullNotesPerPercent / replace.length();
            for (int i = 0; i < replace.length(); i++) {
                // String values = replace.getJSONArray(i).toString().replace("[", "").replace("]", "").replaceAll("\"","'").replaceAll("\u001f","\u001f");
                // String sql = "replace into notes(id,guid,mid,mod,usn,tags,flds,sfld,csum,flags,data) values ( " + values + ")";
                // 
                db.execute("insert or replace into notes values (?,?,?,?,?,?,?,?,?,?,?)", replace.getJSONArray(i).get(0), replace.getJSONArray(i).get(1), replace.getJSONArray(i).get(2), replace.getJSONArray(i).get(3), replace.getJSONArray(i).get(4), replace.getJSONArray(i).get(5), replace.getJSONArray(i).get(6), replace.getJSONArray(i).get(7), replace.getJSONArray(i).get(8), replace.getJSONArray(i).get(9), replace.getJSONArray(i).get(10));
                updateDialogProgress(SYNCING_DATA, "同步笔记数据中", mCurrentProgress + percent);
            }
            db.getDatabase().setTransactionSuccessful();
            mCol.save();
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        db.getDatabase().endTransaction();
    }
    db.getDatabase().beginTransaction();
    try {
        JSONArray replace = item.getJSONObject("cards").getJSONArray("replace");
        if (replace.length() > 0) {
            double percent = 5.0 / replace.length();
            for (int i = 0; i < replace.length(); i++) {
                // String values = replace.getJSONArray(i).toString().replace("[", "").replace("]", "").replaceAll("\"","'").replaceAll("\u001f","\u001f");
                // String sql = "replace into cards(id,nid,did,ord,mod,usn,type,queue,due,ivl,factor,reps,lapses,left,odue,odid,flags,data) values ( " + values + ")";
                // Timber.i("update dialog progress:%d", percent);
                db.execute("insert or replace into cards values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", replace.getJSONArray(i).get(0), replace.getJSONArray(i).get(1), replace.getJSONArray(i).get(2), replace.getJSONArray(i).get(3), replace.getJSONArray(i).get(4), replace.getJSONArray(i).get(5), replace.getJSONArray(i).get(6), replace.getJSONArray(i).get(7), replace.getJSONArray(i).get(8), replace.getJSONArray(i).get(9), replace.getJSONArray(i).get(10), replace.getJSONArray(i).get(11), replace.getJSONArray(i).get(12), replace.getJSONArray(i).get(13), replace.getJSONArray(i).get(14), replace.getJSONArray(i).get(15), replace.getJSONArray(i).get(16), replace.getJSONArray(i).get(17));
                updateDialogProgress(SYNCING_DATA, "同步卡牌数据中", mCurrentProgress + percent);
            }
            db.getDatabase().setTransactionSuccessful();
            mCol.save();
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        db.getDatabase().endTransaction();
    }
    CollectionHelper.getInstance().unlockCollection();
}
Also used : Decks(com.ichi2.libanki.Decks) JSONArray(com.ichi2.utils.JSONArray) Deck(com.ichi2.libanki.Deck) FileNotFoundException(java.io.FileNotFoundException) SQLiteConstraintException(android.database.sqlite.SQLiteConstraintException) IOException(java.io.IOException) SuppressLint(android.annotation.SuppressLint) JSONObject(com.ichi2.utils.JSONObject) Model(com.ichi2.libanki.Model) SuppressLint(android.annotation.SuppressLint) DB(com.ichi2.libanki.DB) DeckConfig(com.ichi2.libanki.DeckConfig)

Example 23 with LEFT

use of com.ichi2.anim.ActivityTransitionAnimation.LEFT in project AnkiChinaAndroid by ankichinateam.

the class Sched method _answerLrnCard.

/**
 * @param ease 1=no, 2=yes, 3=remove
 */
@Override
protected void _answerLrnCard(@NonNull Card card, @Consts.BUTTON_TYPE int ease) {
    JSONObject conf = _lrnConf(card);
    @Consts.CARD_TYPE int type;
    if (card.getODid() != 0 && !card.getWasNew()) {
        type = Consts.CARD_TYPE_RELEARNING;
    } else if (card.getType() == Consts.CARD_TYPE_REV) {
        type = Consts.CARD_TYPE_REV;
    } else {
        type = Consts.CARD_TYPE_NEW;
    }
    boolean leaving = false;
    // lrnCount was decremented once when card was fetched
    int lastLeft = card.getLeft();
    // immediate graduate?
    if (ease == Consts.BUTTON_THREE) {
        _rescheduleAsRev(card, conf, true);
        leaving = true;
    // graduation time?
    } else if (ease == Consts.BUTTON_TWO && (card.getLeft() % 1000) - 1 <= 0) {
        _rescheduleAsRev(card, conf, false);
        leaving = true;
    } else {
        // one step towards graduation
        if (ease == Consts.BUTTON_TWO) {
            // decrement real left count and recalculate left today
            int left = (card.getLeft() % 1000) - 1;
            card.setLeft(_leftToday(conf.getJSONArray("delays"), left) * 1000 + left);
        // failed
        } else {
            card.setLeft(_startingLeft(card));
            boolean resched = _resched(card);
            if (conf.has("mult") && resched) {
                // review that's lapsed
                card.setIvl(Math.max(Math.max(1, (int) (card.getIvl() * conf.getDouble("mult"))), conf.getInt("minInt")));
            } else {
            // new card; no ivl adjustment
            // pass
            }
            if (resched && card.getODid() != 0) {
                card.setODue(mToday + 1);
            }
        }
        int delay = _delayForGrade(conf, card.getLeft());
        if (card.getDue() < getTime().intTime()) {
            // not collapsed; add some randomness
            delay *= Utils.randomFloatInRange(1f, 1.25f);
        }
        card.setDue(getTime().intTime() + delay);
        // due today?
        if (card.getDue() < mDayCutoff) {
            mLrnCount += card.getLeft() / 1000;
            // if the queue is not empty and there's nothing else to do, make
            // sure we don't put it at the head of the queue and end up showing
            // it twice in a row
            card.setQueue(Consts.QUEUE_TYPE_LRN);
            if (!mLrnQueue.isEmpty() && revCount() == 0 && newCount() == 0) {
                long smallestDue = mLrnQueue.getFirstDue();
                card.setDue(Math.max(card.getDue(), smallestDue + 1));
            }
            _sortIntoLrn(card.getDue(), card.getId());
        } else {
            // the card is due in one or more days, so we need to use the day learn queue
            long ahead = ((card.getDue() - mDayCutoff) / SECONDS_PER_DAY) + 1;
            card.setDue(mToday + ahead);
            card.setQueue(Consts.QUEUE_TYPE_DAY_LEARN_RELEARN);
        }
    }
    _logLrn(card, ease, conf, leaving, type, lastLeft);
}
Also used : JSONObject(com.ichi2.utils.JSONObject)

Example 24 with LEFT

use of com.ichi2.anim.ActivityTransitionAnimation.LEFT in project AnkiChinaAndroid by ankichinateam.

the class Sched method _getCard.

/**
 * Getting the next card ****************************************************
 * *******************************************
 */
/**
 * Return the next due card, or null.
 */
@Override
@Nullable
protected Card _getCard() {
    // learning card due?
    @Nullable Card c = _getLrnCard();
    if (c != null) {
        return c;
    }
    // new first, or time for one?
    if (_timeForNewCard()) {
        c = _getNewCard();
        if (c != null) {
            return c;
        }
    }
    // Card due for review?
    c = _getRevCard();
    if (c != null) {
        return c;
    }
    // day learning card due?
    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 25 with LEFT

use of com.ichi2.anim.ActivityTransitionAnimation.LEFT in project AnkiChinaAndroid by ankichinateam.

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();
    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.getConf().optBoolean("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)

Aggregations

JSONArray (com.ichi2.utils.JSONArray)16 Card (com.ichi2.libanki.Card)14 Collection (com.ichi2.libanki.Collection)12 JSONObject (com.ichi2.utils.JSONObject)12 DeckConfig (com.ichi2.libanki.DeckConfig)11 Note (com.ichi2.libanki.Note)11 Test (org.junit.Test)11 RobolectricTest (com.ichi2.anki.RobolectricTest)10 Cursor (android.database.Cursor)8 ArrayList (java.util.ArrayList)8 Nullable (androidx.annotation.Nullable)7 JSONException (com.ichi2.utils.JSONException)7 ConfirmModSchemaException (com.ichi2.anki.exception.ConfirmModSchemaException)5 Model (com.ichi2.libanki.Model)4 IOException (java.io.IOException)4 SuppressLint (android.annotation.SuppressLint)3 Intent (android.content.Intent)3 SharedPreferences (android.content.SharedPreferences)3 Menu (android.view.Menu)3 View (android.view.View)3