use of com.ichi2.libanki.Model in project Anki-Android by ankidroid.
the class Models method load.
/**
* {@inheritDoc}
*/
@Override
public void load(@NonNull String json) {
mChanged = false;
mModels = new HashMap<>();
JSONObject modelarray = new JSONObject(json);
JSONArray ids = modelarray.names();
if (ids != null) {
for (String id : ids.stringIterable()) {
Model o = new Model(modelarray.getJSONObject(id));
mModels.put(o.getLong("id"), o);
}
}
}
use of com.ichi2.libanki.Model in project Anki-Android by ankidroid.
the class Models method scmhash.
/*
Schema hash ***********************************************************************************************
*/
@NonNull
@Override
public String scmhash(Model m) {
StringBuilder s = new StringBuilder();
JSONArray flds = m.getJSONArray("flds");
for (JSONObject fld : flds.jsonObjectIterable()) {
s.append(fld.getString("name"));
}
JSONArray tmpls = m.getJSONArray("tmpls");
for (JSONObject t : tmpls.jsonObjectIterable()) {
s.append(t.getString("name"));
}
return Utils.checksum(s.toString());
}
use of com.ichi2.libanki.Model in project Anki-Android by ankidroid.
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" }) {
// noinspection RegExpRedundantEscape // In Android, } should be escaped
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 (JSONObject ta : tmpls.jsonObjectIterable()) {
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);
Models._updateTemplOrds(m);
col.getModels().save(m);
}
use of com.ichi2.libanki.Model in project Anki-Android by ankidroid.
the class Syncer method sanityCheck.
public JSONObject sanityCheck() {
JSONObject result = new JSONObject();
try {
if (mCol.getDb().queryScalar("SELECT count() FROM cards WHERE nid NOT IN (SELECT id FROM notes)") != 0) {
Timber.e("Sync - SanityCheck: there are cards without mother notes");
result.put("client", "missing notes");
return result;
}
if (mCol.getDb().queryScalar("SELECT count() FROM notes WHERE id NOT IN (SELECT DISTINCT nid FROM cards)") != 0) {
Timber.e("Sync - SanityCheck: there are notes without cards");
result.put("client", "missing cards");
return result;
}
if (mCol.getDb().queryScalar("SELECT count() FROM cards WHERE usn = -1") != 0) {
Timber.e("Sync - SanityCheck: there are unsynced cards");
result.put("client", "cards had usn = -1");
return result;
}
if (mCol.getDb().queryScalar("SELECT count() FROM notes WHERE usn = -1") != 0) {
Timber.e("Sync - SanityCheck: there are unsynced notes");
result.put("client", "notes had usn = -1");
return result;
}
if (mCol.getDb().queryScalar("SELECT count() FROM revlog WHERE usn = -1") != 0) {
Timber.e("Sync - SanityCheck: there are unsynced revlogs");
result.put("client", "revlog had usn = -1");
return result;
}
if (mCol.getDb().queryScalar("SELECT count() FROM graves WHERE usn = -1") != 0) {
Timber.e("Sync - SanityCheck: there are unsynced graves");
result.put("client", "graves had usn = -1");
return result;
}
for (Deck g : mCol.getDecks().all()) {
if (g.getInt("usn") == -1) {
Timber.e("Sync - SanityCheck: unsynced deck: %s", g.getString("name"));
result.put("client", "deck had usn = -1");
return result;
}
}
if (mCol.getTags().minusOneValue()) {
Timber.e("Sync - SanityCheck: there are unsynced tags");
result.put("client", "tag had usn = -1");
return result;
}
boolean found = false;
for (JSONObject m : mCol.getModels().all()) {
if (mCol.getServer()) {
// the web upgrade was mistakenly setting usn
if (m.getInt("usn") < 0) {
m.put("usn", 0);
found = true;
}
} else {
if (m.getInt("usn") == -1) {
Timber.e("Sync - SanityCheck: unsynced model: %s", m.getString("name"));
result.put("client", "model had usn = -1");
return result;
}
}
}
if (found) {
mCol.getModels().save();
}
// check for missing parent decks
mCol.getSched().deckDueList();
// return summary of deck
JSONArray check = new JSONArray();
JSONArray counts = new JSONArray();
// #5666 - not in libAnki
// We modified mReportLimit inside the scheduler, and this causes issues syncing dynamic decks.
AbstractSched syncScheduler = mCol.createScheduler(SYNC_SCHEDULER_REPORT_LIMIT);
syncScheduler.resetCounts();
Counts counts_ = syncScheduler.counts();
counts.put(counts_.getNew());
counts.put(counts_.getLrn());
counts.put(counts_.getRev());
check.put(counts);
check.put(mCol.getDb().queryScalar("SELECT count() FROM cards"));
check.put(mCol.getDb().queryScalar("SELECT count() FROM notes"));
check.put(mCol.getDb().queryScalar("SELECT count() FROM revlog"));
check.put(mCol.getDb().queryScalar("SELECT count() FROM graves"));
check.put(mCol.getModels().all().size());
check.put(mCol.getDecks().all().size());
check.put(mCol.getDecks().allConf().size());
result.put("client", check);
return result;
} catch (JSONException e) {
Timber.e(e, "Syncer.sanityCheck()");
throw new RuntimeException(e);
}
}
use of com.ichi2.libanki.Model in project Anki-Android by ankidroid.
the class CollectionTest method test_furigana.
@Test
@Ignore("Pending port of media search from Rust code")
public void test_furigana() {
Collection col = getCol();
ModelManager mm = col.getModels();
Model m = mm.current();
// filter should work
m.getJSONArray("tmpls").getJSONObject(0).put("qfmt", "{{kana:Front}}");
mm.save(m);
Note n = col.newNote();
n.setItem("Front", "foo[abc]");
col.addNote(n);
Card c = n.cards().get(0);
assertTrue(c.q().endsWith("abc"));
// and should avoid sound
n.setItem("Front", "foo[sound:abc.mp3]");
n.flush();
String question = c.q(true);
assertThat("Question «" + question + "» does not contains «anki:play».", question, containsString("anki:play"));
// it shouldn't throw an error while people are editing
m.getJSONArray("tmpls").getJSONObject(0).put("qfmt", "{{kana:}}");
mm.save(m);
c.q(true);
}
Aggregations