use of com.ichi2.libanki.DeckConfig in project AnkiChinaAndroid by ankichinateam.
the class Sched method _deckRevLimitSingle.
/**
* Maximal number of rev card still to see today in deck d. It's computed as:
* the number of rev card to see by day according
* minus the number of rev cards seen today in deck d or a descendant
* plus the number of extra cards to see today in deck d, a parent or a descendant.
*
* Limits of its ancestors are not applied. Current card is treated the same way as other cards.
*/
@Override
protected int _deckRevLimitSingle(@NonNull Deck d) {
if (d.getInt("dyn") != 0) {
return mReportLimit;
}
long did = d.getLong("id");
DeckConfig c = mCol.getDecks().confForDid(did);
int lim = Math.max(0, c.getJSONObject("rev").getInt("perDay") - d.getJSONArray("revToday").getInt(1));
if (currentCardIsInQueueWithDeck(Consts.QUEUE_TYPE_REV, did)) {
lim--;
}
// So currentCard does not have to be taken into consideration in this method
return lim;
}
use of com.ichi2.libanki.DeckConfig 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.libanki.DeckConfig 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;
}
use of com.ichi2.libanki.DeckConfig in project AnkiChinaAndroid by ankichinateam.
the class NoteImporter method importNotes.
/**
* Convert each card into a note, apply attributes and add to col.
*/
public void importNotes(List<ForeignNote> notes) {
Assert.that(mappingOk());
// note whether tags are mapped
mTagsMapped = false;
for (String f : mMapping) {
if ("_tags".equals(f)) {
mTagsMapped = true;
break;
}
}
// gather checks for duplicate comparison
HashMap<Long, List<Long>> csums = new HashMap<>();
try (Cursor c = mCol.getDb().query("select csum, id from notes where mid = ?", mModel.getLong("id"))) {
while (c.moveToNext()) {
long csum = c.getLong(0);
long id = c.getLong(1);
if (csums.containsKey(csum)) {
csums.get(csum).add(id);
} else {
csums.put(csum, new ArrayList<>(Collections.singletonList(id)));
}
}
}
HashMap<String, Boolean> firsts = new HashMap<>();
int fld0index = mMapping.indexOf(mModel.getJSONArray("flds").getJSONObject(0).getString("name"));
mFMap = mCol.getModels().fieldMap(mModel);
mNextId = mCol.getTime().timestampID(mCol.getDb(), "notes");
// loop through the notes
List<Object[]> updates = new ArrayList<>();
List<String> updateLog = new ArrayList<>();
// PORT: Translations moved closer to their sources
List<Object[]> _new = new ArrayList<>();
_ids = new ArrayList<>();
_cards = new ArrayList<>();
mEmptyNotes = false;
int dupeCount = 0;
List<String> dupes = new ArrayList<>();
for (ForeignNote n : notes) {
for (int c = 0; c < n.mFields.size(); c++) {
if (!this.mAllowHTML) {
n.mFields.set(c, HtmlUtils.escape(n.mFields.get(c)));
}
n.mFields.set(c, n.mFields.get(c).trim());
if (!this.mAllowHTML) {
n.mFields.set(c, n.mFields.get(c).replace("\n", "<br>"));
}
}
String fld0 = n.mFields.get(fld0index);
long csum = fieldChecksum(fld0);
// first field must exist
if (fld0 == null || fld0.length() == 0) {
getLog().add(getString(R.string.note_importer_error_empty_first_field, TextUtils.join(" ", n.mFields)));
continue;
}
// earlier in import?
if (firsts.containsKey(fld0) && mImportMode != ADD_MODE) {
// duplicates in source file; log and ignore
getLog().add(getString(R.string.note_importer_error_appeared_twice, fld0));
continue;
}
firsts.put(fld0, true);
// already exists?
boolean found = false;
if (csums.containsKey(csum)) {
// csum is not a guarantee; have to check
for (Long id : csums.get(csum)) {
String flds = mCol.getDb().queryString("select flds from notes where id = ?", id);
String[] sflds = splitFields(flds);
if (fld0.equals(sflds[0])) {
// duplicate
found = true;
if (mImportMode == UPDATE_MODE) {
Object[] data = updateData(n, id, sflds);
if (data != null && data.length > 0) {
updates.add(data);
updateLog.add(getString(R.string.note_importer_error_first_field_matched, fld0));
dupeCount += 1;
found = true;
}
} else if (mImportMode == IGNORE_MODE) {
dupeCount += 1;
} else if (mImportMode == ADD_MODE) {
// allow duplicates in this case
if (!dupes.contains(fld0)) {
// only show message once, no matter how many
// duplicates are in the collection already
updateLog.add(getString(R.string.note_importer_error_added_duplicate_first_field, fld0));
dupes.add(fld0);
}
found = false;
}
}
}
}
// newly add
if (!found) {
Object[] data = newData(n);
if (data != null && data.length > 0) {
_new.add(data);
// note that we've seen this note once already
firsts.put(fld0, true);
}
}
}
addNew(_new);
addUpdates(updates);
// make sure to update sflds, etc
mCol.updateFieldCache(collection2Array(_ids));
// generate cards
if (!mCol.genCards(_ids).isEmpty()) {
this.getLog().add(0, getString(R.string.note_importer_empty_cards_found));
}
// apply scheduling updates
updateCards();
// we randomize or order here, to ensure that siblings
// have the same due#
long did = mCol.getDecks().selected();
DeckConfig conf = mCol.getDecks().confForDid(did);
// in order due?
if (conf.getJSONObject("new").getInt("order") == NEW_CARDS_RANDOM) {
mCol.getSched().randomizeCards(did);
}
String part1 = getQuantityString(R.plurals.note_importer_notes_added, _new.size());
String part2 = getQuantityString(R.plurals.note_importer_notes_updated, mUpdateCount);
int unchanged;
if (mImportMode == UPDATE_MODE) {
unchanged = dupeCount - mUpdateCount;
} else if (mImportMode == IGNORE_MODE) {
unchanged = dupeCount;
} else {
unchanged = 0;
}
String part3 = getQuantityString(R.plurals.note_importer_notes_unchanged, unchanged);
mLog.add(String.format("%s, %s, %s.", part1, part2, part3));
mLog.addAll(updateLog);
if (mEmptyNotes) {
mLog.add(getString(R.string.note_importer_error_empty_notes));
}
mTotal = _ids.size();
}
use of com.ichi2.libanki.DeckConfig in project AnkiChinaAndroid by ankichinateam.
the class Decks method load.
public void load(String decks, String dconf) {
mDecks = new HashMap<>();
mDconf = new HashMap<>();
JSONObject decksarray = new JSONObject(decks);
JSONArray ids = decksarray.names();
for (int i = 0; i < ids.length(); i++) {
String id = ids.getString(i);
try {
long longId = Long.parseLong(id);
Deck o = new Deck(decksarray.getJSONObject(id));
mDecks.put(longId, o);
} catch (NumberFormatException e) {
Timber.w("id is not valid");
}
}
mNameMap = NameMap.constructor(mDecks.values());
JSONObject confarray = new JSONObject(dconf);
ids = confarray.names();
for (int i = 0; ids != null && i < ids.length(); i++) {
String id = ids.getString(i);
try {
mDconf.put(Long.parseLong(id), new DeckConfig(confarray.getJSONObject(id)));
} catch (NumberFormatException e) {
Timber.w("id is not valid");
}
}
mChanged = false;
}
Aggregations