use of com.ichi2.libanki.utils.Time in project AnkiChinaAndroid by ankichinateam.
the class Utils method markAsUploaded.
/**
* Set usn to 0 in every object.
*
* This method is called during full sync, before uploading, so
* during an instant, the value will be zero while the object is
* not actually online. This is not a problem because if the sync
* fails, a full sync will occur again next time.
*
* @return whether there was a non-zero usn; in this case the list
* should be saved before the upload.
*/
public static boolean markAsUploaded(ArrayList<? extends JSONObject> ar) {
boolean changed = false;
for (JSONObject obj : ar) {
if (obj.optInt("usn", 1) != 0) {
obj.put("usn", 0);
changed = true;
}
}
return changed;
}
use of com.ichi2.libanki.utils.Time in project AnkiChinaAndroid by ankichinateam.
the class Storage method Collection.
public static Collection Collection(Context context, String path, boolean server, boolean log, @NonNull Time time) {
assert path.endsWith(".anki2");
File dbFile = new File(path);
boolean create = !dbFile.exists();
// // connect
DB db = new DB(path);
try {
// initialize
int ver;
Timber.i("new collection:%s", create);
if (create) {
AnkiDroidApp.getSharedPrefs(context).edit().remove(Consts.KEY_SYNC_CHINA_SESSION).apply();
ver = _createDB(db, time);
} else {
ver = _upgradeSchema(db, time);
}
db.execute("PRAGMA temp_store = memory");
// add db to col and do any remaining upgrades
Collection col = new Collection(context, db, path, server, log, time);
if (ver < Consts.SCHEMA_VERSION) {
AnkiDroidApp.getSharedPrefs(context).edit().remove(Consts.KEY_SYNC_CHINA_SESSION).apply();
_upgrade(col, ver);
} else if (ver > Consts.SCHEMA_VERSION) {
if (ver == 12 && _isVer11(db)) {
// 判断数据库版本是否有问题
db.execute("UPDATE col SET ver = 11");
} else {
throw new RuntimeException("This file requires a newer version of Anki.");
}
} else if (create) {
// add in reverse order so basic is default
for (int i = StdModels.stdModels.length - 1; i >= 0; i--) {
StdModels.stdModels[i].add(col);
}
col.save();
}
return col;
} catch (Exception e) {
Timber.e(e, "Error opening collection; closing database");
db.close();
throw e;
}
}
use of com.ichi2.libanki.utils.Time in project AnkiChinaAndroid by ankichinateam.
the class Storage method _setColVars.
private static void _setColVars(DB db, @NonNull Time time) {
JSONObject g = new JSONObject(Decks.defaultDeck);
g.put("id", 1);
g.put("name", "Default");
g.put("conf", 1);
g.put("mod", time.intTime());
JSONObject gc = new JSONObject(Decks.defaultConf);
gc.put("id", 1);
JSONObject ag = new JSONObject();
ag.put("1", g);
JSONObject agc = new JSONObject();
agc.put("1", gc);
ContentValues values = new ContentValues();
values.put("conf", Collection.defaultConf);
values.put("decks", Utils.jsonToString(ag));
values.put("dconf", Utils.jsonToString(agc));
db.update("col", values);
}
use of com.ichi2.libanki.utils.Time in project AnkiChinaAndroid by ankichinateam.
the class Decks method update.
/**
* Add or update an existing deck. Used for syncing and merging.
*/
public void update(Deck g) {
long id = g.getLong("id");
JSONObject oldDeck = get(id, false);
if (oldDeck != null) {
// In case where another update got the name
// `oldName`, it would be a mistake to remove it from nameMap
mNameMap.remove(oldDeck.getString("name"), oldDeck);
}
mNameMap.add(g);
mDecks.put(g.getLong("id"), g);
maybeAddToActive();
// mark registry changed, but don't bump mod time
save();
}
use of com.ichi2.libanki.utils.Time in project AnkiChinaAndroid by ankichinateam.
the class AdvancedStatistics method calculateDueAsMetaInfo.
/**
* Determine forecast statistics based on a computation or simulation of future reviews.
* Returns all information required by stats.java to plot the 'forecast' chart based on these statistics.
* The chart will display:
* - The forecasted number of reviews per review type (relearn, mature, young, learn) as bars
* - The forecasted number of cards in each state (new, young, mature) as lines
* @param metaInfo Object which will be filled with all information required by stats.java to plot the 'forecast' chart and returned by this method.
* @param type Type of 'forecast' chart for which to determine forecast statistics. Accepted values:
* Stats.TYPE_MONTH: Determine forecast statistics for next 30 days with 1-day chunks
* Stats.TYPE_YEAR: Determine forecast statistics for next year with 7-day chunks
* Stats.TYPE_LIFE: Determine forecast statistics for next 2 years with 30-day chunks
* @param context Contains The collection which contains the decks to be simulated.
* Also used for access to the database and access to the creation time of the collection.
* The creation time of the collection is needed since due times of cards are relative to the creation time of the collection.
* So we could pass mCol here.
* @param dids Deck id's
* @return @see #metaInfo
*/
public StatsMetaInfo calculateDueAsMetaInfo(StatsMetaInfo metaInfo, Stats.AxisType type, Context context, String dids) {
if (!AnkiDroidApp.getSharedPrefs(context).getBoolean("advanced_statistics_enabled", false)) {
return metaInfo;
}
// To indicate that we calculated the statistics so that Stats.java knows that it shouldn't display the standard Forecast chart.
Settings = new Settings(context);
metaInfo.setStatsCalculated(true);
Collection mCol = CollectionHelper.getInstance().getCol(context);
double[][] mSeriesList;
int[] mValueLabels;
int[] mColors;
int[] mAxisTitles;
int mMaxCards = 0;
int mMaxElements;
double mFirstElement;
double mLastElement = 0;
int mZeroIndex = 0;
double[][] mCumulative;
double mMcount;
mValueLabels = new int[] { R.string.statistics_relearn, R.string.statistics_mature, R.string.statistics_young, R.string.statistics_learn };
mColors = new int[] { R.attr.stats_relearn, R.attr.stats_mature, R.attr.stats_young, R.attr.stats_learn };
mAxisTitles = new int[] { type.ordinal(), R.string.stats_cards, R.string.stats_cumulative_cards };
PlottableSimulationResult simuationResult = calculateDueAsPlottableSimulationResult(type, mCol, dids);
ArrayList<int[]> dues = simuationResult.getNReviews();
mSeriesList = new double[REVIEW_TYPE_COUNT_PLUS_1][dues.size()];
for (int t = 0; t < dues.size(); t++) {
int[] data = dues.get(t);
int nReviews = data[REVIEW_TYPE_LEARN_PLUS_1] + data[REVIEW_TYPE_YOUNG_PLUS_1] + data[REVIEW_TYPE_MATURE_PLUS_1] + data[REVIEW_TYPE_RELEARN_PLUS_1];
if (nReviews > mMaxCards)
// Y-Axis: Max. value
mMaxCards = nReviews;
// In the bar-chart, the bars will be stacked on top of each other.
// For the i^{th} bar counting from the bottom we therefore have to
// provide the sum of the heights of the i^{th} bar and all bars below it.
// X-Axis: Day / Week / Month
mSeriesList[TIME][t] = data[TIME];
mSeriesList[REVIEW_TYPE_LEARN_PLUS_1][t] = data[REVIEW_TYPE_LEARN_PLUS_1] + data[REVIEW_TYPE_YOUNG_PLUS_1] + data[REVIEW_TYPE_MATURE_PLUS_1] + // Y-Axis: # Cards
data[REVIEW_TYPE_RELEARN_PLUS_1];
mSeriesList[REVIEW_TYPE_YOUNG_PLUS_1][t] = data[REVIEW_TYPE_LEARN_PLUS_1] + data[REVIEW_TYPE_YOUNG_PLUS_1] + // Y-Axis: # Mature cards
data[REVIEW_TYPE_MATURE_PLUS_1];
mSeriesList[REVIEW_TYPE_MATURE_PLUS_1][t] = data[REVIEW_TYPE_LEARN_PLUS_1] + // Y-Axis: # Young
data[REVIEW_TYPE_YOUNG_PLUS_1];
// Y-Axis: # Learn
mSeriesList[REVIEW_TYPE_RELEARN_PLUS_1][t] = data[REVIEW_TYPE_LEARN_PLUS_1];
if (data[TIME] > mLastElement)
// X-Axis: Max. value (only for TYPE_LIFE)
mLastElement = data[TIME];
if (data[TIME] == 0) {
// Because we retrieve dues in the past and we should not cumulate them
mZeroIndex = t;
}
}
// # X values
mMaxElements = dues.size() - 1;
switch(type) {
case TYPE_MONTH:
// X-Axis: Max. value
mLastElement = 31;
break;
case TYPE_YEAR:
// X-Axis: Max. value
mLastElement = 52;
break;
default:
}
// X-Axis: Min. value
mFirstElement = 0;
// Day starting at mZeroIndex, Cumulative # cards
mCumulative = simuationResult.getNInState();
mMcount = // Y-Axis: Max. cumulative value
mCumulative[CARD_TYPE_NEW_PLUS_1][mCumulative[CARD_TYPE_NEW_PLUS_1].length - 1] + mCumulative[CARD_TYPE_YOUNG_PLUS_1][mCumulative[CARD_TYPE_YOUNG_PLUS_1].length - 1] + mCumulative[CARD_TYPE_MATURE_PLUS_1][mCumulative[CARD_TYPE_MATURE_PLUS_1].length - 1];
// some adjustments to not crash the chartbuilding with empty data
if (mMaxElements == 0) {
mMaxElements = 10;
}
if (mMcount == 0) {
mMcount = 10;
}
if (mFirstElement == mLastElement) {
mFirstElement = 0;
mLastElement = 6;
}
if (mMaxCards == 0)
mMaxCards = 10;
metaInfo.setmDynamicAxis(true);
metaInfo.setmHasColoredCumulative(true);
metaInfo.setmType(type);
metaInfo.setmTitle(R.string.stats_forecast);
metaInfo.setmBackwards(true);
metaInfo.setmValueLabels(mValueLabels);
metaInfo.setmColors(mColors);
metaInfo.setmAxisTitles(mAxisTitles);
metaInfo.setmMaxCards(mMaxCards);
metaInfo.setmMaxElements(mMaxElements);
metaInfo.setmFirstElement(mFirstElement);
metaInfo.setmLastElement(mLastElement);
metaInfo.setmZeroIndex(mZeroIndex);
metaInfo.setmCumulative(mCumulative);
metaInfo.setmMcount(mMcount);
metaInfo.setmSeriesList(mSeriesList);
metaInfo.setDataAvailable(dues.size() > 0);
return metaInfo;
}
Aggregations