use of com.ichi2.utils.JSONArray in project AnkiChinaAndroid by ankichinateam.
the class SchedV2 method _updateStats.
public void _updateStats(@NonNull Card card, @NonNull String type, long cnt) {
String key = type + "Today";
long did = card.getDid();
List<Deck> list = mCol.getDecks().parents(did);
list.add(mCol.getDecks().get(did));
for (Deck g : list) {
JSONArray a = g.getJSONArray(key);
// add
a.put(1, a.getLong(1) + cnt);
mCol.getDecks().save(g);
}
}
use of com.ichi2.utils.JSONArray in project AnkiChinaAndroid by ankichinateam.
the class SchedV2 method _fillDyn.
/**
* Whether the filtered deck is empty
* Overriden
*/
private int _fillDyn(Deck deck) {
int start = -100000;
int total = 0;
JSONArray terms;
List<Long> ids;
terms = deck.getJSONArray("terms");
for (int i = 0; i < terms.length(); i++) {
JSONArray term = terms.getJSONArray(i);
String search = term.getString(0);
int limit = term.getInt(1);
int order = term.getInt(2);
String orderlimit = _dynOrder(order, limit);
if (!TextUtils.isEmpty(search.trim())) {
search = String.format(Locale.US, "(%s)", search);
}
search = String.format(Locale.US, "%s -is:suspended -is:buried -deck:filtered", search);
ids = mCol.findCards(search, orderlimit);
if (ids.isEmpty()) {
return total;
}
// move the cards over
mCol.log(deck.getLong("id"), ids);
_moveToDyn(deck.getLong("id"), ids, start + total);
total += ids.size();
}
return total;
}
use of com.ichi2.utils.JSONArray in project AnkiChinaAndroid by ankichinateam.
the class SchedV2 method extendLimits.
public void extendLimits(int newc, int rev) {
Deck cur = mCol.getDecks().current();
ArrayList<Deck> decks = new ArrayList<>();
decks.add(cur);
decks.addAll(mCol.getDecks().parents(cur.getLong("id")));
for (long did : mCol.getDecks().children(cur.getLong("id")).values()) {
decks.add(mCol.getDecks().get(did));
}
for (Deck g : decks) {
// add
JSONArray today = g.getJSONArray("newToday");
today.put(1, today.getInt(1) - newc);
today = g.getJSONArray("revToday");
today.put(1, today.getInt(1) - rev);
mCol.getDecks().save(g);
}
}
use of com.ichi2.utils.JSONArray in project AnkiChinaAndroid by ankichinateam.
the class SchedV2 method _delayForGrade.
protected int _delayForGrade(JSONObject conf, int left) {
left = left % 1000;
try {
double delay;
JSONArray delays = conf.getJSONArray("delays");
int len = delays.length();
try {
delay = delays.getDouble(len - left);
} catch (JSONException e) {
if (conf.getJSONArray("delays").length() > 0) {
delay = conf.getJSONArray("delays").getDouble(0);
} else {
// user deleted final step; use dummy value
delay = 1.0;
}
}
return (int) (delay * 60.0);
} catch (JSONException e) {
throw new RuntimeException(e);
}
}
use of com.ichi2.utils.JSONArray in project AnkiChinaAndroid by ankichinateam.
the class MediaSyncer method sync.
public String sync(long restSpace) throws UnknownHttpResponseException, MediaSyncException, NoEnoughServerSpaceException {
// of this class about this difference to the original.
if (mCol.getMedia().needScan()) {
mCon.publishProgress(R.string.sync_media_find);
mCol.log("findChanges");
try {
mCol.getMedia().findChanges();
} catch (SQLException ignored) {
return "corruptMediaDB";
}
}
// begin session and check if in sync
int lastUsn = mCol.getMedia().lastUsn();
JSONObject ret = mServer.begin();
int srvUsn = ret.getInt("usn");
if ((lastUsn == srvUsn) && !(mCol.getMedia().haveDirty())) {
return "noChanges";
}
// loop through and process changes from server
mCol.log("last local usn is " + lastUsn);
mDownloadCount = 0;
while (true) {
// Allow cancellation (note: media sync has no finish command, so just throw)
if (Connection.getIsCancelled()) {
Timber.i("Sync was cancelled");
throw new RuntimeException("UserAbortedSync");
}
JSONArray data = mServer.mediaChanges(lastUsn);
mCol.log("mediaChanges resp count: ", data.length());
if (data.length() == 0) {
break;
}
List<String> need = new ArrayList<>();
lastUsn = data.getJSONArray(data.length() - 1).getInt(1);
for (int i = 0; i < data.length(); i++) {
// Allow cancellation (note: media sync has no finish command, so just throw)
if (Connection.getIsCancelled()) {
Timber.i("Sync was cancelled");
throw new RuntimeException("UserAbortedSync");
}
String fname = data.getJSONArray(i).getString(0);
int rusn = data.getJSONArray(i).getInt(1);
String rsum = null;
if (!data.getJSONArray(i).isNull(2)) {
// If `rsum` is a JSON `null` value, `.optString(2)` will
// return `"null"` as a string
rsum = data.getJSONArray(i).optString(2);
}
Pair<String, Integer> info = mCol.getMedia().syncInfo(fname);
String lsum = info.first;
int ldirty = info.second;
mCol.log(String.format(Locale.US, "check: lsum=%s rsum=%s ldirty=%d rusn=%d fname=%s", TextUtils.isEmpty(lsum) ? "" : lsum.subSequence(0, 4), TextUtils.isEmpty(rsum) ? "" : rsum.subSequence(0, 4), ldirty, rusn, fname));
if (!TextUtils.isEmpty(rsum)) {
// added/changed remotely
if (TextUtils.isEmpty(lsum) || !lsum.equals(rsum)) {
mCol.log("will fetch");
need.add(fname);
} else {
mCol.log("have same already");
}
mCol.getMedia().markClean(Collections.singletonList(fname));
} else if (!TextUtils.isEmpty(lsum)) {
// deleted remotely
if (ldirty == 0) {
mCol.log("delete local");
mCol.getMedia().syncDelete(fname);
} else {
// conflict: local add overrides remote delete
mCol.log("conflict; will send");
}
} else {
// deleted both sides
mCol.log("both sides deleted");
mCol.getMedia().markClean(Collections.singletonList(fname));
}
}
_downloadFiles(need);
mCol.log("update last usn to " + lastUsn);
// commits
mCol.getMedia().setLastUsn(lastUsn);
}
// at this point, we're all up to date with the server's changes,
// and we need to send our own
boolean updateConflict = false;
int toSend = mCol.getMedia().dirtyCount();
long needSize = mCol.getMedia().getMediaSizeNeededUpload();
if (needSize >= 0 && restSpace < needSize && Consts.loginAnkiChina()) {
Timber.d("No Enough Server Space Exception,rest is:" + restSpace + ",need size:" + needSize);
throw new NoEnoughServerSpaceException(restSpace, needSize);
}
while (true) {
Pair<File, List<String>> changesZip = mCol.getMedia().mediaChangesZip();
File zip = changesZip.first;
try {
List<String> fnames = changesZip.second;
if (fnames.size() == 0) {
break;
}
mCon.publishProgress(String.format(AnkiDroidApp.getAppResources().getString(R.string.sync_media_changes_count), toSend));
JSONArray changes = mServer.uploadChanges(zip);
int processedCnt = changes.getInt(0);
int serverLastUsn = changes.getInt(1);
mCol.getMedia().markClean(fnames.subList(0, processedCnt));
mCol.log(String.format(Locale.US, "processed %d, serverUsn %d, clientUsn %d", processedCnt, serverLastUsn, lastUsn));
if (serverLastUsn - processedCnt == lastUsn) {
mCol.log("lastUsn in sync, updating local");
lastUsn = serverLastUsn;
// commits
mCol.getMedia().setLastUsn(serverLastUsn);
} else {
mCol.log("concurrent update, skipping usn update");
// commit for markClean
mCol.getMedia().getDb().commit();
updateConflict = true;
}
toSend -= processedCnt;
} finally {
zip.delete();
}
}
if (updateConflict) {
mCol.log("restart sync due to concurrent update");
return sync(restSpace);
}
int lcnt = mCol.getMedia().mediacount();
String sRet = mServer.mediaSanity(lcnt);
if ("OK".equals(sRet)) {
return "OK";
} else {
mCol.getMedia().forceResync();
return sRet;
}
}
Aggregations