Search in sources :

Example 11 with Time

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;
}
Also used : JSONObject(com.ichi2.utils.JSONObject)

Example 12 with Time

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;
    }
}
Also used : File(java.io.File) ConfirmModSchemaException(com.ichi2.anki.exception.ConfirmModSchemaException) JSONException(com.ichi2.utils.JSONException)

Example 13 with Time

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);
}
Also used : ContentValues(android.content.ContentValues) JSONObject(com.ichi2.utils.JSONObject)

Example 14 with Time

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();
}
Also used : JSONObject(com.ichi2.utils.JSONObject)

Example 15 with Time

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;
}
Also used : Collection(com.ichi2.libanki.Collection)

Aggregations

Test (org.junit.Test)27 Collection (com.ichi2.libanki.Collection)26 JSONObject (com.ichi2.utils.JSONObject)26 RobolectricTest (com.ichi2.anki.RobolectricTest)19 Card (com.ichi2.libanki.Card)19 Note (com.ichi2.libanki.Note)15 JSONArray (com.ichi2.utils.JSONArray)15 Deck (com.ichi2.libanki.Deck)11 ArrayList (java.util.ArrayList)11 DeckConfig (com.ichi2.libanki.DeckConfig)10 IOException (java.io.IOException)10 ConfirmModSchemaException (com.ichi2.anki.exception.ConfirmModSchemaException)9 HashMap (java.util.HashMap)9 Cursor (android.database.Cursor)8 Nullable (androidx.annotation.Nullable)8 JSONException (com.ichi2.utils.JSONException)8 SharedPreferences (android.content.SharedPreferences)7 Resources (android.content.res.Resources)7 File (java.io.File)7 View (android.view.View)5