use of com.ichi2.anki.CardBrowser.Column.CARD in project AnkiChinaAndroid by ankichinateam.
the class SchedV2 method _walkingCount.
protected int _walkingCount(@NonNull LimitMethod limFn, @NonNull CountMethod cntFn) {
int tot = 0;
HashMap<Long, Integer> pcounts = new HashMap<>();
// for each of the active decks
for (long did : mCol.getDecks().active()) {
// get the individual deck's limit
int lim = limFn.operation(mCol.getDecks().get(did));
if (lim == 0) {
continue;
}
// check the parents
List<Deck> parents = mCol.getDecks().parents(did);
for (Deck p : parents) {
// add if missing
long id = p.getLong("id");
if (!pcounts.containsKey(id)) {
pcounts.put(id, limFn.operation(p));
}
// take minimum of child and parent
lim = Math.min(pcounts.get(id), lim);
}
// see how many cards we actually have
int cnt = cntFn.operation(did, lim);
// if non-zero, decrement from parents counts
for (Deck p : parents) {
long id = p.getLong("id");
pcounts.put(id, pcounts.get(id) - cnt);
}
// we may also be a parent
pcounts.put(did, lim - cnt);
// and add to running total
tot += cnt;
}
Timber.e("walking deck count:" + pcounts.size() + ",today new card count:" + tot);
return tot;
}
use of com.ichi2.anki.CardBrowser.Column.CARD in project AnkiChinaAndroid by ankichinateam.
the class SchedV2 method _answerLrnCard.
// Overriden
protected void _answerLrnCard(@NonNull Card card, @Consts.BUTTON_TYPE int ease) {
JSONObject conf = _lrnConf(card);
@Consts.CARD_TYPE int type;
if (card.getType() == Consts.CARD_TYPE_REV || card.getType() == Consts.CARD_TYPE_RELEARNING) {
type = Consts.CARD_TYPE_REV;
} else {
type = Consts.CARD_TYPE_NEW;
}
// lrnCount was decremented once when card was fetched
int lastLeft = card.getLeft();
boolean leaving = false;
// immediate graduate?
if (ease == Consts.BUTTON_FOUR) {
_rescheduleAsRev(card, conf, true);
leaving = true;
// next step?
} else if (ease == Consts.BUTTON_THREE) {
// graduation time?
if ((card.getLeft() % 1000) - 1 <= 0) {
_rescheduleAsRev(card, conf, false);
leaving = true;
} else {
_moveToNextStep(card, conf);
}
} else if (ease == Consts.BUTTON_TWO) {
_repeatStep(card, conf);
} else {
// move back to first step
_moveToFirstStep(card, conf);
}
_logLrn(card, ease, conf, leaving, type, lastLeft);
}
use of com.ichi2.anki.CardBrowser.Column.CARD in project AnkiChinaAndroid by ankichinateam.
the class SchedV2 method _newConf.
// Overridden: different delays for filtered cards.
@NonNull
protected JSONObject _newConf(@NonNull Card card) {
DeckConfig conf = _cardConf(card);
// normal deck
if (card.getODid() == 0) {
return conf.getJSONObject("new");
}
// dynamic deck; override some attributes, use original deck for others
DeckConfig oconf = mCol.getDecks().confForDid(card.getODid());
JSONObject dict = new JSONObject();
// original deck
dict.put("ints", oconf.getJSONObject("new").getJSONArray("ints"));
dict.put("initialFactor", oconf.getJSONObject("new").getInt("initialFactor"));
dict.put("bury", oconf.getJSONObject("new").optBoolean("bury", true));
dict.put("delays", oconf.getJSONObject("new").getJSONArray("delays"));
// overrides
dict.put("separate", conf.getBoolean("separate"));
dict.put("order", Consts.NEW_CARDS_DUE);
dict.put("perDay", mReportLimit);
return dict;
}
use of com.ichi2.anki.CardBrowser.Column.CARD in project AnkiChinaAndroid by ankichinateam.
the class SchedV2 method _earlyReviewIvl.
/**
* next interval for card when answered early+correctly
*/
private int _earlyReviewIvl(@NonNull Card card, @Consts.BUTTON_TYPE int ease) {
if (card.getODid() == 0 || card.getType() != Consts.CARD_TYPE_REV || card.getFactor() == 0) {
throw new RuntimeException("Unexpected card parameters");
}
if (ease <= 1) {
throw new RuntimeException("Ease must be greater than 1");
}
long elapsed = card.getIvl() - (card.getODue() - mToday);
@NonNull JSONObject conf = _revConf(card);
double easyBonus = 1;
// early 3/4 reviews shouldn't decrease previous interval
double minNewIvl = 1;
double factor;
if (ease == Consts.BUTTON_TWO) {
factor = conf.optDouble("hardFactor", 1.2);
// hard cards shouldn't have their interval decreased by more than 50%
// of the normal factor
minNewIvl = factor / 2;
} else if (ease == 3) {
factor = card.getFactor() / 1000.0;
} else {
// ease == 4
factor = card.getFactor() / 1000.0;
double ease4 = conf.getDouble("ease4");
// 1.3 -> 1.15
easyBonus = ease4 - (ease4 - 1) / 2;
}
double ivl = Math.max(elapsed * factor, 1);
// cap interval decreases
ivl = Math.max(card.getIvl() * minNewIvl, ivl) * easyBonus;
return _constrainedIvl(ivl, conf, 0, false);
}
use of com.ichi2.anki.CardBrowser.Column.CARD in project AnkiChinaAndroid by ankichinateam.
the class AnkiChinaSyncer method saveLatestData.
/**
* 同步结束后将数据写入synclog
*/
@SuppressLint("DefaultLocale")
private void saveLatestData() {
mCol = CollectionHelper.getInstance().getColSafe(AnkiDroidApp.getInstance());
CollectionHelper.getInstance().lockCollection();
mCol.getDb().getDatabase().beginTransaction();
try {
mCol.getDb().execute("delete from synclog");
} catch (Exception e) {
// mCol=CollectionHelper.getInstance().getColSafe(AnkiDroidApp.getInstance());
// mCol.getDb().execute("drop table synclog");
// mCol.getDb().execute("create table if not exists synclog (" + " id integer not null,"
// + " type integer not null," + " mod integer not null" + ")");
e.printStackTrace();
}
List<Deck> newDecks = mCol.getDecks().all();
StringBuilder values = new StringBuilder();
for (Deck item : newDecks) {
if (values.length() != 0) {
values.append(",");
}
values.append("(").append(item.getLong("id")).append(",").append(SYNC_LOG_TYPE_DECKS).append(",").append(item.getLong("mod")).append(")");
}
// db.execute(String.format("insert into synclog values %s",sbDeck.toString()));
List<Model> newModels = mCol.getModels().all();
// StringBuilder sbModel=new StringBuilder();
for (Model item : newModels) {
if (values.length() != 0) {
values.append(",");
}
values.append("(").append(item.getLong("id")).append(",").append(SYNC_LOG_TYPE_MODELS).append(",").append(item.getLong("mod")).append(")");
}
// db.execute(String.format("insert into synclog values %s",sbModel.toString()));
List<DeckConfig> newDConf = mCol.getDecks().allConf();
// StringBuilder sbDConf=new StringBuilder();
for (DeckConfig item : newDConf) {
if (values.length() != 0) {
values.append(",");
}
values.append("(").append(item.getLong("id")).append(",").append(SYNC_LOG_TYPE_DCONF).append(",").append(item.getLong("mod")).append(")");
}
String sql = String.format("insert into synclog values %s", values.toString());
Timber.i("sync to local synclog:%s", sql);
mCol.getDb().execute(sql);
// List<Card> newDConf = mCol.getDecks().allConf();
// for(DeckConfig item:newDConf){
// if(values.length()!=0)values.append(",");
// values.append("(").append(item.getLong("id")).append(",").append(SYNC_LOG_TYPE_DCONF).append(",").append(item.getLong("mod")).append(")");
// }
mCol.getDb().execute(String.format("insert into synclog select cards.id,%d,cards.mod from cards", SYNC_LOG_TYPE_CARD));
mCol.getDb().execute(String.format("insert into synclog select notes.id,%d,notes.mod from notes", SYNC_LOG_TYPE_NOTE));
mCol.getDb().execute(String.format("insert into synclog select revlog.id,%d,revlog.id from revlog", SYNC_LOG_TYPE_REVLOG));
mCol.getDb().getDatabase().setTransactionSuccessful();
mCol.getDb().getDatabase().endTransaction();
// mCol.fixIntegrity(new CollectionTask.ProgressCallback(null, AnkiDroidApp.getAppResources()));
CollectionHelper.getInstance().unlockCollection();
// db.execute(String.format("insert into synclog select revlog.id,%d,revlog.mod from revlog", SYNC_LOG_TYPE_REVLOG));
}
Aggregations