/** * Show a new notification about the given task. Returns false if there was some sort of error or * the alarm should be disabled. */ public boolean showTaskNotification(long id, int type, String reminder) { Task task; try { task = taskDao.fetch( id, Task.ID, Task.TITLE, Task.HIDE_UNTIL, Task.COMPLETION_DATE, Task.DUE_DATE, Task.DELETION_DATE, Task.REMINDER_FLAGS); if (task == null) throw new IllegalArgumentException("cound not find item with id"); // $NON-NLS-1$ } catch (Exception e) { exceptionService.reportError("show-notif", e); // $NON-NLS-1$ return false; } // you're done - don't sound, do delete if (task.isCompleted() || task.isDeleted()) return false; // it's hidden - don't sound, don't delete if (task.isHidden() && type == ReminderService.TYPE_RANDOM) return true; // task due date was changed, but alarm wasn't rescheduled if ((type == ReminderService.TYPE_DUE || type == ReminderService.TYPE_OVERDUE) && (!task.hasDueDate() || task.getValue(Task.DUE_DATE) > DateUtilities.now())) return true; // read properties String taskTitle = task.getValue(Task.TITLE); boolean nonstopMode = task.getFlag(Task.REMINDER_FLAGS, Task.NOTIFY_MODE_NONSTOP); boolean ringFiveMode = task.getFlag(Task.REMINDER_FLAGS, Task.NOTIFY_MODE_FIVE); int ringTimes = nonstopMode ? -1 : (ringFiveMode ? 5 : 1); // update last reminder time task.setValue(Task.REMINDER_LAST, DateUtilities.now()); taskDao.saveExisting(task); Context context = ContextManager.getContext(); String title = context.getString(R.string.app_name); String text = reminder + " " + taskTitle; // $NON-NLS-1$ Intent notifyIntent = new Intent(context, NotificationActivity.class); notifyIntent.setAction("NOTIFY" + id); // $NON-NLS-1$ notifyIntent.putExtra(NotificationActivity.TOKEN_ID, id); notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK); showNotification((int) id, notifyIntent, type, title, text, ringTimes); return true; }
/** Clean up tasks. Typically called on startup */ public void deleteTasksWithEmptyTitles() { TodorooCursor<Task> cursor = taskDao.query(Query.select(Task.ID).where(TaskDao.TaskCriteria.hasNoTitle())); try { if (cursor.getCount() == 0) { return; } for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) { long id = cursor.getLong(0); taskDao.delete(id); } } finally { cursor.close(); } }
public static ActFmSyncThread initializeSyncComponents( TaskDao taskDao, TagDataDao tagDataDao, UserActivityDao userActivityDao, TaskAttachmentDao taskAttachmentDao, TaskListMetadataDao taskListMetadataDao) { if (instance == null) { synchronized (ActFmSyncThread.class) { if (instance == null) { List<ClientToServerMessage<?>> syncQueue = Collections.synchronizedList(new LinkedList<ClientToServerMessage<?>>()); ActFmSyncMonitor monitor = ActFmSyncMonitor.getInstance(); ActFmSyncWaitingPool waitingPool = ActFmSyncWaitingPool.getInstance(); instance = new ActFmSyncThread(syncQueue, monitor); taskDao.addListener(new SyncDatabaseListener<Task>(instance, ModelType.TYPE_TASK)); tagDataDao.addListener(new SyncDatabaseListener<TagData>(instance, ModelType.TYPE_TAG)); userActivityDao.addListener( new SyncDatabaseListener<UserActivity>(instance, ModelType.TYPE_ACTIVITY)); taskAttachmentDao.addListener( new SyncDatabaseListener<TaskAttachment>(instance, ModelType.TYPE_ATTACHMENT)); taskListMetadataDao.addListener( new TaskListMetadataSyncDatabaseListener( instance, waitingPool, ModelType.TYPE_TASK_LIST_METADATA)); instance.startSyncThread(); } } } return instance; }
private void write(GtasksTaskContainer task) throws IOException { // merge astrid dates with google dates if (!task.task.isSaved() && actFmPreferenceService.isLoggedIn()) titleMatchWithActFm(task.task); if (task.task.isSaved()) { Task local = PluginServices.getTaskService() .fetchById(task.task.getId(), Task.DUE_DATE, Task.COMPLETION_DATE); if (local == null) { task.task.clearValue(Task.ID); } else { mergeDates(task.task, local); if (task.task.isCompleted() && !local.isCompleted()) StatisticsService.reportEvent(StatisticsConstants.GTASKS_TASK_COMPLETED); } } else { // Set default importance and reminders for remotely created tasks task.task.setValue( Task.IMPORTANCE, Preferences.getIntegerFromString( R.string.p_default_importance_key, Task.IMPORTANCE_SHOULD_DO)); TaskDao.setDefaultReminders(task.task); } if (!TextUtils.isEmpty(task.task.getValue(Task.TITLE))) { task.task.putTransitory(SyncFlags.GTASKS_SUPPRESS_SYNC, true); gtasksMetadataService.saveTaskAndMetadata(task); } }
/** * Schedules alarms for a single task * * @param shouldPerformPropertyCheck whether to check if task has requisite properties */ private void scheduleAlarm(Task task, boolean shouldPerformPropertyCheck) { if (task == null || !task.isSaved()) return; // read data if necessary if (shouldPerformPropertyCheck) { for (Property<?> property : NOTIFICATION_PROPERTIES) { if (!task.containsValue(property)) { task = taskDao.fetch(task.getId(), NOTIFICATION_PROPERTIES); if (task == null) return; break; } } } // Make sure no alarms are scheduled other than the next one. When that one is shown, it // will schedule the next one after it, and so on and so forth. clearAllAlarms(task); if (task.isCompleted() || task.isDeleted() || !Task.USER_ID_SELF.equals(task.getValue(Task.USER_ID))) { return; } // snooze reminder long whenSnooze = calculateNextSnoozeReminder(task); // random reminders long whenRandom = calculateNextRandomReminder(task); // notifications at due date long whenDueDate = calculateNextDueDateReminder(task); // notifications after due date long whenOverdue = calculateNextOverdueReminder(task); // For alarms around/before now, increment the now value so the next one will be later if (whenDueDate <= now || whenOverdue <= now) { whenDueDate = now; whenOverdue = now; now += 30 * DateUtilities.ONE_MINUTE; // Prevents overdue tasks from being scheduled all at once } // if random reminders are too close to due date, favor due date if (whenRandom != NO_ALARM && whenDueDate - whenRandom < DateUtilities.ONE_DAY) whenRandom = NO_ALARM; // snooze trumps all if (whenSnooze != NO_ALARM) { scheduler.createAlarm(task, whenSnooze, TYPE_SNOOZE); } else if (whenRandom < whenDueDate && whenRandom < whenOverdue) { scheduler.createAlarm(task, whenRandom, TYPE_RANDOM); } else if (whenDueDate < whenOverdue) { scheduler.createAlarm(task, whenDueDate, TYPE_DUE); } else if (whenOverdue != NO_ALARM) { scheduler.createAlarm(task, whenOverdue, TYPE_OVERDUE); } else { scheduler.createAlarm(task, 0, 0); } }
protected Task createTask(String title) { Task task = new Task(); task.setTitle(title); task.setImportance(SYNC_TASK_IMPORTANCE); taskDao.createNew(task); return task; }
/** * Gets a listing of all tasks that are active & * * @param properties * @return todoroo cursor. PLEASE CLOSE THIS CURSOR! */ private TodorooCursor<Task> getTasksWithReminders(Property<?>... properties) { return taskDao.query( Query.select(properties) .where( Criterion.and( TaskCriteria.isActive(), TaskCriteria.ownedByMe(), Criterion.or(Task.REMINDER_FLAGS.gt(0), Task.REMINDER_PERIOD.gt(0))))); }
private int countTasks(Filter filter) { String queryTemplate = PermaSql.replacePlaceholders(filter.getSqlQuery()); TodorooCursor<Task> cursor = taskDao.query(Query.select(Task.ID).withQueryTemplate(queryTemplate)); try { return cursor.getCount(); } finally { cursor.close(); } }
@SuppressWarnings("nls") public void initialize() { new Thread( new Runnable() { public void run() { while (true) { SyncOnSaveOperation op; try { op = operationQueue.take(); } catch (InterruptedException e) { continue; } try { if (!gtasksPreferenceService.isOngoing()) { GtasksInvoker invoker = new GtasksInvoker(gtasksPreferenceService.getToken()); if (op instanceof TaskPushOp) { TaskPushOp taskPush = (TaskPushOp) op; if (DateUtilities.now() - taskPush.creationDate < 1000) AndroidUtilities.sleepDeep( 1000 - (DateUtilities.now() - taskPush.creationDate)); pushTaskOnSave( taskPush.model, taskPush.model.getMergedValues(), invoker, false); } else if (op instanceof MoveOp) { MoveOp move = (MoveOp) op; pushMetadataOnSave(move.metadata, invoker); } } } catch (IOException e) { Crittercism.logHandledException(e); Log.w("gtasks-sync-error", "Sync on save failed", e); } } } }) .start(); taskDao.addListener( new ModelUpdateListener<Task>() { public void onModelUpdated(final Task model) { if (model.checkAndClearTransitory(SyncFlags.GTASKS_SUPPRESS_SYNC)) return; if (gtasksPreferenceService .isOngoing()) // Don't try and sync changes that occur during a normal sync return; final ContentValues setValues = model.getSetValues(); if (setValues == null || !checkForToken()) return; if (!checkValuesForProperties( setValues, TASK_PROPERTIES)) // None of the properties we sync were updated return; Task toPush = taskDao.fetch(model.getId(), TASK_PROPERTIES); operationQueue.offer(new TaskPushOp(toPush)); } }); }
public void delete(Task item) { if (!item.isSaved()) { return; } if (item.containsValue(Task.TITLE) && item.getTitle().length() == 0) { taskDao.delete(item.getId()); item.setId(Task.NO_ID); } else { long id = item.getId(); item.clear(); item.setId(id); gcalHelper.deleteTaskEvent(item); item.setDeletionDate(DateUtilities.now()); taskService.save(item); } }
/** Synchronize with server when data changes */ public void pushTaskOnSave(Task task, ContentValues values, GtasksInvoker invoker, boolean sleep) throws IOException { if (sleep) AndroidUtilities.sleepDeep(1000L); // Wait for metadata to be saved Metadata gtasksMetadata = gtasksMetadataService.getTaskMetadata(task.getId()); com.google.api.services.tasks.model.Task remoteModel = null; boolean newlyCreated = false; String remoteId = null; String listId = Preferences.getStringValue(GtasksPreferenceService.PREF_DEFAULT_LIST); if (listId == null) { com.google.api.services.tasks.model.TaskList defaultList = invoker.getGtaskList(DEFAULT_LIST); if (defaultList != null) { listId = defaultList.getId(); Preferences.setString(GtasksPreferenceService.PREF_DEFAULT_LIST, listId); } else { listId = DEFAULT_LIST; } } if (gtasksMetadata == null || !gtasksMetadata.containsNonNullValue(GtasksMetadata.ID) || TextUtils.isEmpty(gtasksMetadata.getValue(GtasksMetadata.ID))) { // Create case if (gtasksMetadata == null) { gtasksMetadata = GtasksMetadata.createEmptyMetadata(task.getId()); } if (gtasksMetadata.containsNonNullValue(GtasksMetadata.LIST_ID)) { listId = gtasksMetadata.getValue(GtasksMetadata.LIST_ID); } remoteModel = new com.google.api.services.tasks.model.Task(); newlyCreated = true; } else { // update case remoteId = gtasksMetadata.getValue(GtasksMetadata.ID); listId = gtasksMetadata.getValue(GtasksMetadata.LIST_ID); remoteModel = new com.google.api.services.tasks.model.Task(); remoteModel.setId(remoteId); } // If task was newly created but without a title, don't sync--we're in the middle of // creating a task which may end up being cancelled if (newlyCreated && (!values.containsKey(Task.TITLE.name) || TextUtils.isEmpty(task.getValue(Task.TITLE)))) { return; } // Update the remote model's changed properties if (values.containsKey(Task.DELETION_DATE.name) && task.isDeleted()) { remoteModel.setDeleted(true); } if (values.containsKey(Task.TITLE.name)) { remoteModel.setTitle(task.getValue(Task.TITLE)); } if (values.containsKey(Task.NOTES.name)) { remoteModel.setNotes(task.getValue(Task.NOTES)); } if (values.containsKey(Task.DUE_DATE.name) && task.hasDueDate()) { remoteModel.setDue(GtasksApiUtilities.unixTimeToGtasksDueDate(task.getValue(Task.DUE_DATE))); } if (values.containsKey(Task.COMPLETION_DATE.name)) { if (task.isCompleted()) { remoteModel.setCompleted( GtasksApiUtilities.unixTimeToGtasksCompletionTime(task.getValue(Task.COMPLETION_DATE))); remoteModel.setStatus("completed"); // $NON-NLS-1$ } else { remoteModel.setCompleted(null); remoteModel.setStatus("needsAction"); // $NON-NLS-1$ } } if (!newlyCreated) { invoker.updateGtask(listId, remoteModel); } else { String parent = gtasksMetadataService.getRemoteParentId(gtasksMetadata); String priorSibling = gtasksMetadataService.getRemoteSiblingId(listId, gtasksMetadata); CreateRequest create = new CreateRequest(invoker, listId, remoteModel, parent, priorSibling); com.google.api.services.tasks.model.Task created = create.executePush(); if (created != null) { // Update the metadata for the newly created task gtasksMetadata.setValue(GtasksMetadata.ID, created.getId()); gtasksMetadata.setValue(GtasksMetadata.LIST_ID, listId); } else return; } task.setValue(Task.MODIFICATION_DATE, DateUtilities.now()); gtasksMetadata.setValue(GtasksMetadata.LAST_SYNC, DateUtilities.now() + 1000L); metadataService.save(gtasksMetadata); task.putTransitory(SyncFlags.GTASKS_SUPPRESS_SYNC, true); taskDao.saveExistingWithSqlConstraintCheck(task); }
/** Permanently delete the given task. */ public void purge(long taskId) { taskDao.delete(taskId); }
public int purgeDeletedTasks() { return taskDao.deleteWhere(Task.DELETION_DATE.gt(0)); }
public void initialize() { taskDao.addListener( new ModelUpdateListener<Task>() { @Override public void onModelUpdated(final Task model) { if (Flags.checkAndClear(Flags.SUPPRESS_SYNC)) return; final ContentValues setValues = model.getSetValues(); if (setValues == null || !checkForToken() || setValues.containsKey(RemoteModel.REMOTE_ID_PROPERTY_NAME)) return; new Thread( new Runnable() { @Override public void run() { // sleep so metadata associated with task is saved AndroidUtilities.sleepDeep(1000L); pushTaskOnSave(model, setValues); } }) .start(); } }); updateDao.addListener( new ModelUpdateListener<Update>() { @Override public void onModelUpdated(final Update model) { if (Flags.checkAndClear(Flags.SUPPRESS_SYNC)) return; final ContentValues setValues = model.getSetValues(); if (setValues == null || !checkForToken() || model.getValue(Update.REMOTE_ID) > 0) return; new Thread( new Runnable() { @Override public void run() { pushUpdateOnSave(model, setValues); } }) .start(); } }); tagDataDao.addListener( new ModelUpdateListener<TagData>() { @Override public void onModelUpdated(final TagData model) { if (Flags.checkAndClear(Flags.SUPPRESS_SYNC)) return; final ContentValues setValues = model.getSetValues(); if (setValues == null || !checkForToken() || setValues.containsKey(RemoteModel.REMOTE_ID_PROPERTY_NAME)) return; new Thread( new Runnable() { @Override public void run() { pushTagDataOnSave(model, setValues); } }) .start(); } }); }
/** Synchronize with server when data changes */ public void pushTaskOnSave(Task task, ContentValues values) { long remoteId; if (task.containsValue(Task.REMOTE_ID)) remoteId = task.getValue(Task.REMOTE_ID); else { Task taskForRemote = taskService.fetchById(task.getId(), Task.REMOTE_ID); if (taskForRemote == null) return; remoteId = taskForRemote.getValue(Task.REMOTE_ID); } boolean newlyCreated = remoteId == 0; ArrayList<Object> params = new ArrayList<Object>(); if (values.containsKey(Task.TITLE.name)) { params.add("title"); params.add(task.getValue(Task.TITLE)); } if (values.containsKey(Task.DUE_DATE.name)) { params.add("due"); params.add(task.getValue(Task.DUE_DATE) / 1000L); params.add("has_due_time"); params.add(task.hasDueTime() ? 1 : 0); } if (values.containsKey(Task.NOTES.name)) { params.add("notes"); params.add(task.getValue(Task.NOTES)); } if (values.containsKey(Task.DELETION_DATE.name)) { params.add("deleted_at"); params.add(task.getValue(Task.DELETION_DATE) / 1000L); } if (values.containsKey(Task.COMPLETION_DATE.name)) { params.add("completed"); params.add(task.getValue(Task.COMPLETION_DATE) / 1000L); } if (values.containsKey(Task.IMPORTANCE.name)) { params.add("importance"); params.add(task.getValue(Task.IMPORTANCE)); } if (values.containsKey(Task.RECURRENCE.name)) { params.add("repeat"); params.add(task.getValue(Task.RECURRENCE)); } if (values.containsKey(Task.USER_ID.name) && task.getValue(Task.USER_ID) >= 0) { params.add("user_id"); if (task.getValue(Task.USER_ID) == 0) params.add(ActFmPreferenceService.userId()); else params.add(task.getValue(Task.USER_ID)); } if (Flags.checkAndClear(Flags.TAGS_CHANGED) || newlyCreated) { TodorooCursor<Metadata> cursor = TagService.getInstance().getTags(task.getId()); try { if (cursor.getCount() == 0) { params.add("tags"); params.add(""); } else { Metadata metadata = new Metadata(); for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) { metadata.readFromCursor(cursor); if (metadata.containsNonNullValue(TagService.REMOTE_ID) && metadata.getValue(TagService.REMOTE_ID) > 0) { params.add("tag_ids[]"); params.add(metadata.getValue(TagService.REMOTE_ID)); } else { params.add("tags[]"); params.add(metadata.getValue(TagService.TAG)); } } } } finally { cursor.close(); } } if (params.size() == 0 || !checkForToken()) return; System.err.println("PUSHN ON SAVE: " + task.getMergedValues()); System.err.println("SETVALUES: " + values); if (!newlyCreated) { params.add("id"); params.add(remoteId); } else if (!params.contains(Task.TITLE.name)) return; try { params.add("token"); params.add(token); JSONObject result = actFmInvoker.invoke("task_save", params.toArray(new Object[params.size()])); ArrayList<Metadata> metadata = new ArrayList<Metadata>(); JsonHelper.taskFromJson(result, task, metadata); task.setValue(Task.MODIFICATION_DATE, DateUtilities.now()); task.setValue(Task.LAST_SYNC, DateUtilities.now()); Flags.set(Flags.SUPPRESS_SYNC); taskDao.saveExisting(task); } catch (JSONException e) { handleException("task-save-json", e); } catch (IOException e) { handleException("task-save-io", e); } }