use of com.ichi2.utils.JSONObject 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;
}
use of com.ichi2.utils.JSONObject in project AnkiChinaAndroid by ankichinateam.
the class Sched method _checkLeech.
/**
* Leeches ****************************************************************** *****************************
*/
/**
* Leech handler. True if card was a leech.
*/
@Override
protected boolean _checkLeech(@NonNull Card card, @NonNull JSONObject conf) {
int lf;
lf = conf.getInt("leechFails");
if (lf == 0) {
return false;
}
// if over threshold or every half threshold reps after that
if (card.getLapses() >= lf && (card.getLapses() - lf) % Math.max(lf / 2, 1) == 0) {
// add a leech tag
Note n = card.note();
n.addTag("leech");
n.flush();
// handle
if (conf.getInt("leechAction") == Consts.LEECH_SUSPEND) {
// if it has an old due, remove it from cram/relearning
if (card.getODue() != 0) {
card.setDue(card.getODue());
}
if (card.getODid() != 0) {
card.setDid(card.getODid());
}
card.setODue(0);
card.setODid(0);
card.setQueue(Consts.QUEUE_TYPE_SUSPENDED);
}
// notify UI
if (mContextReference != null) {
Activity context = mContextReference.get();
leech(card, context);
}
return true;
}
return false;
}
use of com.ichi2.utils.JSONObject in project AnkiChinaAndroid by ankichinateam.
the class Sched method _updateRevIvl.
@Override
protected void _updateRevIvl(@NonNull Card card, @Consts.BUTTON_TYPE int ease) {
try {
int idealIvl = _nextRevIvl(card, ease);
JSONObject conf = _revConf(card);
card.setIvl(Math.min(Math.max(_adjRevIvl(card, idealIvl), card.getIvl() + 1), conf.getInt("maxIvl")));
} catch (JSONException e) {
throw new RuntimeException(e);
}
}
use of com.ichi2.utils.JSONObject in project AnkiChinaAndroid by ankichinateam.
the class Sched method _lapseConf.
@Override
@NonNull
protected JSONObject _lapseConf(@NonNull Card card) {
DeckConfig conf = _cardConf(card);
// normal deck
if (card.getODid() == 0) {
return conf.getJSONObject("lapse");
}
// dynamic deck; override some attributes, use original deck for others
DeckConfig oconf = mCol.getDecks().confForDid(card.getODid());
JSONArray delays = conf.optJSONArray("delays");
if (delays == null) {
delays = oconf.getJSONObject("lapse").getJSONArray("delays");
}
JSONObject dict = new JSONObject();
// original deck
dict.put("minInt", oconf.getJSONObject("lapse").getInt("minInt"));
dict.put("leechFails", oconf.getJSONObject("lapse").getInt("leechFails"));
dict.put("leechAction", oconf.getJSONObject("lapse").getInt("leechAction"));
dict.put("mult", oconf.getJSONObject("lapse").getDouble("mult"));
// overrides
dict.put("delays", delays);
dict.put("resched", conf.getBoolean("resched"));
return dict;
}
use of com.ichi2.utils.JSONObject in project AnkiChinaAndroid by ankichinateam.
the class Sched method _newConf.
/**
* Tools ******************************************************************** ***************************
*/
@Override
@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());
JSONArray delays = conf.optJSONArray("delays");
if (delays == null) {
delays = oconf.getJSONObject("new").getJSONArray("delays");
}
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));
// overrides
dict.put("delays", delays);
dict.put("separate", conf.getBoolean("separate"));
dict.put("order", Consts.NEW_CARDS_DUE);
dict.put("perDay", mReportLimit);
return dict;
}
Aggregations