Search in sources :

Example 6 with DUE

use of com.ichi2.anki.CardBrowser.Column.DUE in project AnkiChinaAndroid by ankichinateam.

the class CollectionTask method doInBackgroundCheckDatabase.

private TaskData doInBackgroundCheckDatabase() {
    Timber.d("doInBackgroundCheckDatabase");
    Collection col = getCol();
    // Don't proceed if collection closed
    if (col == null) {
        Timber.e("doInBackgroundCheckDatabase :: supplied collection was null");
        return new TaskData(false);
    }
    Collection.CheckDatabaseResult result = col.fixIntegrity(new ProgressCallback(this, AnkiDroidApp.getAppResources()));
    if (result.getFailed()) {
        // we can fail due to a locked database, which requires knowledge of the failure.
        return new TaskData(false, new Object[] { result });
    } else {
        // Close the collection and we restart the app to reload
        CollectionHelper.getInstance().closeCollection(true, "Check Database Completed");
        return new TaskData(true, new Object[] { result });
    }
}
Also used : Collection(com.ichi2.libanki.Collection)

Example 7 with DUE

use of com.ichi2.anki.CardBrowser.Column.DUE in project AnkiChinaAndroid by ankichinateam.

the class CollectionTask method doInBackgroundLoadDeck.

private TaskData doInBackgroundLoadDeck() {
    Timber.d("doInBackgroundLoadDeckCounts");
    Collection col = CollectionHelper.getInstance().getCol(mContext);
    try {
        // Get due tree
        Object[] o = new Object[] { col.getSched().quickDeckDueTree() };
        return new TaskData(o);
    } catch (RuntimeException e) {
        Timber.w(e, "doInBackgroundLoadDeckCounts - error");
        return null;
    }
}
Also used : Collection(com.ichi2.libanki.Collection) JSONObject(com.ichi2.utils.JSONObject)

Example 8 with DUE

use of com.ichi2.anki.CardBrowser.Column.DUE in project AnkiChinaAndroid by ankichinateam.

the class BootService method scheduleNotification.

public static void scheduleNotification(Time time, Context context) {
    AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    SharedPreferences sp = AnkiDroidApp.getSharedPrefs(context);
    // Don't schedule a notification if the due reminders setting is not enabled
    if (Integer.parseInt(sp.getString("minimumCardsDueForNotification", Integer.toString(Preferences.PENDING_NOTIFICATIONS_ONLY))) >= Preferences.PENDING_NOTIFICATIONS_ONLY) {
        return;
    }
    final Calendar calendar = time.calendar();
    calendar.set(Calendar.HOUR_OF_DAY, sp.getInt("dayOffset", 0));
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    final PendingIntent notificationIntent = PendingIntent.getBroadcast(context, 0, new Intent(context, NotificationService.class), 0);
    alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, notificationIntent);
}
Also used : SharedPreferences(android.content.SharedPreferences) Calendar(java.util.Calendar) DeckOptions.reminderToCalendar(com.ichi2.anki.DeckOptions.reminderToCalendar) AlarmManager(android.app.AlarmManager) Intent(android.content.Intent) PendingIntent(android.app.PendingIntent) PendingIntent(android.app.PendingIntent)

Example 9 with DUE

use of com.ichi2.anki.CardBrowser.Column.DUE in project AnkiChinaAndroid by ankichinateam.

the class ReminderService method onReceive.

@Override
public void onReceive(Context context, Intent intent) {
    cancelDeckReminder(context, intent);
    // 0 is not a valid dconf id.
    final long dConfId = intent.getLongExtra(EXTRA_DECK_OPTION_ID, 0);
    if (dConfId == 0) {
        Timber.w("onReceive - dConfId 0, returning");
        return;
    }
    CollectionHelper colHelper;
    Collection col;
    try {
        colHelper = CollectionHelper.getInstance();
        col = colHelper.getCol(context);
    } catch (Throwable t) {
        Timber.w("onReceive - unexpectedly unable to get collection. Returning.");
        return;
    }
    if (null == col || !colHelper.colIsOpen()) {
        Timber.w("onReceive - null or closed collection, unable to process reminders");
        return;
    }
    if (col.getDecks().getConf(dConfId) == null) {
        final AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        final PendingIntent reminderIntent = PendingIntent.getBroadcast(context, (int) dConfId, new Intent(context, ReminderService.class).putExtra(EXTRA_DECK_OPTION_ID, dConfId), 0);
        alarmManager.cancel(reminderIntent);
    }
    final NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
    if (!notificationManager.areNotificationsEnabled()) {
        Timber.v("onReceive - notifications disabled, returning");
        return;
    }
    List<DeckDueTreeNode> decksDue = getDeckOptionDue(col, dConfId, true);
    if (null == decksDue) {
        Timber.v("onReceive - no decks due, returning");
        return;
    }
    for (DeckDueTreeNode deckDue : decksDue) {
        long deckId = deckDue.getDid();
        final int total = deckDue.getRevCount() + deckDue.getLrnCount() + deckDue.getNewCount();
        if (total <= 0) {
            Timber.v("onReceive - no cards due in deck %d", deckId);
            continue;
        }
        Timber.v("onReceive - deck '%s' due count %d", deckDue.getFullDeckName(), total);
        final Notification notification = new NotificationCompat.Builder(context, NotificationChannels.getId(NotificationChannels.Channel.DECK_REMINDERS)).setCategory(NotificationCompat.CATEGORY_REMINDER).setContentTitle(context.getString(R.string.reminder_title)).setContentText(context.getResources().getQuantityString(R.plurals.reminder_text, total, deckDue.getFullDeckName(), total)).setSmallIcon(R.drawable.ic_stat_notify).setColor(ContextCompat.getColor(context, R.color.material_light_blue_700)).setContentIntent(PendingIntent.getActivity(context, (int) deckId, getReviewDeckIntent(context, deckId), PendingIntent.FLAG_UPDATE_CURRENT)).setAutoCancel(true).build();
        notificationManager.notify((int) deckId, notification);
        Timber.v("onReceive - notification state: %s", notification);
    }
}
Also used : NotificationManagerCompat(androidx.core.app.NotificationManagerCompat) Intent(android.content.Intent) PendingIntent(android.app.PendingIntent) Notification(android.app.Notification) DeckDueTreeNode(com.ichi2.libanki.sched.DeckDueTreeNode) Collection(com.ichi2.libanki.Collection) AlarmManager(android.app.AlarmManager) CollectionHelper(com.ichi2.anki.CollectionHelper) PendingIntent(android.app.PendingIntent)

Example 10 with DUE

use of com.ichi2.anki.CardBrowser.Column.DUE in project AnkiChinaAndroid by ankichinateam.

the class Collection method genCards.

public ArrayList<Long> genCards(long[] nids) {
    // build map of (nid,ord) so we don't create dupes
    String snids = Utils.ids2str(nids);
    HashMap<Long, HashMap<Integer, Long>> have = new HashMap<>();
    HashMap<Long, Long> dids = new HashMap<>();
    HashMap<Long, Long> dues = new HashMap<>();
    Cursor cur = null;
    try {
        cur = mDb.getDatabase().query("select id, nid, ord, did, due, odue, odid, type from cards where nid in " + snids, null);
        while (cur.moveToNext()) {
            long id = cur.getLong(0);
            long nid = cur.getLong(1);
            int ord = cur.getInt(2);
            long did = cur.getLong(3);
            long due = cur.getLong(4);
            long odue = cur.getLong(5);
            long odid = cur.getLong(6);
            @Consts.CARD_TYPE int type = cur.getInt(7);
            // existing cards
            if (!have.containsKey(nid)) {
                have.put(nid, new HashMap<Integer, Long>());
            }
            have.get(nid).put(ord, id);
            // if in a filtered deck, add new cards to original deck
            if (odid != 0) {
                did = odid;
            }
            // and their dids
            if (dids.containsKey(nid)) {
                if (dids.get(nid) != 0 && dids.get(nid) != did) {
                    // cards are in two or more different decks; revert to model default
                    dids.put(nid, 0L);
                }
            } else {
                // first card or multiple cards in same deck
                dids.put(nid, did);
            }
            // save due
            if (odid != 0) {
                due = odue;
            }
            if (!dues.containsKey(nid) && type == Consts.CARD_TYPE_NEW) {
                dues.put(nid, due);
            }
        }
    } finally {
        if (cur != null && !cur.isClosed()) {
            cur.close();
        }
    }
    // build cards for each note
    ArrayList<Object[]> data = new ArrayList<>();
    long ts = getTime().maxID(mDb);
    long now = getTime().intTime();
    ArrayList<Long> rem = new ArrayList<>();
    int usn = usn();
    cur = null;
    try {
        cur = mDb.getDatabase().query("SELECT id, mid, flds FROM notes WHERE id IN " + snids, null);
        while (cur.moveToNext()) {
            long nid = cur.getLong(0);
            long mid = cur.getLong(1);
            String flds = cur.getString(2);
            Model model = getModels().get(mid);
            ArrayList<Integer> avail = getModels().availOrds(model, Utils.splitFields(flds));
            Long did = dids.get(nid);
            // use sibling due if there is one, else use a new id
            long due;
            if (dues.containsKey(nid)) {
                due = dues.get(nid);
            } else {
                due = nextID("pos");
            }
            if (did == null || did == 0L) {
                did = model.getLong("did");
            }
            // add any missing cards
            for (JSONObject t : _tmplsFromOrds(model, avail)) {
                int tord = t.getInt("ord");
                boolean doHave = have.containsKey(nid) && have.get(nid).containsKey(tord);
                if (!doHave) {
                    // check deck is not a cram deck
                    long ndid;
                    try {
                        ndid = t.getLong("did");
                        if (ndid != 0) {
                            did = ndid;
                        }
                    } catch (JSONException e) {
                    // do nothing
                    }
                    if (getDecks().isDyn(did)) {
                        did = 1L;
                    }
                    // if the deck doesn't exist, use default instead
                    did = mDecks.get(did).getLong("id");
                    // give it a new id instead
                    data.add(new Object[] { ts, nid, did, tord, now, usn, due });
                    ts += 1;
                }
            }
            // note any cards that need removing
            if (have.containsKey(nid)) {
                for (Map.Entry<Integer, Long> n : have.get(nid).entrySet()) {
                    if (!avail.contains(n.getKey())) {
                        rem.add(n.getValue());
                    }
                }
            }
        }
    } finally {
        if (cur != null && !cur.isClosed()) {
            cur.close();
        }
    }
    // bulk update
    mDb.executeMany("INSERT INTO cards VALUES (?,?,?,?,?,?,0,0,?,0,0,0,0,0,0,0,0,\"\")", data);
    return rem;
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) JSONException(com.ichi2.utils.JSONException) Cursor(android.database.Cursor) SuppressLint(android.annotation.SuppressLint) JSONObject(com.ichi2.utils.JSONObject) Map(java.util.Map) HashMap(java.util.HashMap)

Aggregations

Test (org.junit.Test)58 Collection (com.ichi2.libanki.Collection)57 Card (com.ichi2.libanki.Card)55 Note (com.ichi2.libanki.Note)52 RobolectricTest (com.ichi2.anki.RobolectricTest)51 JSONObject (com.ichi2.utils.JSONObject)25 DeckConfig (com.ichi2.libanki.DeckConfig)20 JSONArray (com.ichi2.utils.JSONArray)16 ArrayList (java.util.ArrayList)16 Cursor (android.database.Cursor)14 Deck (com.ichi2.libanki.Deck)10 ContentResolver (android.content.ContentResolver)6 ContentValues (android.content.ContentValues)6 Uri (android.net.Uri)6 IOException (java.io.IOException)6 HashMap (java.util.HashMap)6 SuppressLint (android.annotation.SuppressLint)5 FileNotFoundException (java.io.FileNotFoundException)5 Activity (android.app.Activity)4 WebView (android.webkit.WebView)4