diff --git a/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksTaskListUpdater.java b/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksTaskListUpdater.java index cc44bad6c..c59ee0003 100644 --- a/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksTaskListUpdater.java +++ b/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksTaskListUpdater.java @@ -22,7 +22,6 @@ import com.todoroo.astrid.dao.MetadataDao; import com.todoroo.astrid.data.Metadata; import com.todoroo.astrid.data.StoreObject; import com.todoroo.astrid.data.Task; -import com.todoroo.astrid.gtasks.sync.GtasksTaskContainer; public class GtasksTaskListUpdater { @@ -284,15 +283,6 @@ public class GtasksTaskListUpdater { // --- used during synchronization - /** - * Update order, parent, and indentation fields for all tasks in all lists - */ - public void updateAllMetadata() { - for(StoreObject list : gtasksListService.getLists()) { - correctMetadataForList(list.getValue(GtasksList.REMOTE_ID)); - } - } - /** * Update order, parent, and indentation fields for all tasks in the given list * @param listId @@ -402,30 +392,5 @@ public class GtasksTaskListUpdater { }); } - /** - * Must be called after creating parent and sibling maps. Updates a - * task container's parent and sibling fields. - * - * @param container - */ - public void updateParentAndSibling(GtasksTaskContainer container) { - long taskId = container.task.getId(); - if(parents.containsKey(taskId)) { - long parentId = parents.get(taskId); - if(localToRemoteIdMap.containsKey(parentId)) - container.parentId = localToRemoteIdMap.get(parentId); - } - if(siblings.containsKey(taskId)) { - long siblingId = siblings.get(taskId); - if(localToRemoteIdMap.containsKey(siblingId)) - container.priorSiblingId = localToRemoteIdMap.get(siblingId); - } - } - - public void addRemoteTaskMapping(long id, String remoteId) { - localToRemoteIdMap.put(id, remoteId); - } - - } diff --git a/astrid/plugin-src/com/todoroo/astrid/gtasks/sync/GtasksSyncProvider.java b/astrid/plugin-src/com/todoroo/astrid/gtasks/sync/GtasksSyncProvider.java deleted file mode 100644 index a34e7883c..000000000 --- a/astrid/plugin-src/com/todoroo/astrid/gtasks/sync/GtasksSyncProvider.java +++ /dev/null @@ -1,686 +0,0 @@ -/** - * See the file "LICENSE" for the full license governing this code. - */ -package com.todoroo.astrid.gtasks.sync; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.concurrent.Semaphore; -import java.util.concurrent.atomic.AtomicInteger; - -import org.json.JSONException; - -import android.app.Activity; -import android.app.Notification; -import android.app.PendingIntent; -import android.content.Context; -import android.content.Intent; -import android.text.TextUtils; -import android.util.Log; - -import com.google.api.services.tasks.model.TaskList; -import com.google.api.services.tasks.model.TaskLists; -import com.timsu.astrid.R; -import com.todoroo.andlib.data.AbstractModel; -import com.todoroo.andlib.data.Property; -import com.todoroo.andlib.data.TodorooCursor; -import com.todoroo.andlib.service.Autowired; -import com.todoroo.andlib.service.ContextManager; -import com.todoroo.andlib.utility.AndroidUtilities; -import com.todoroo.andlib.utility.DateUtilities; -import com.todoroo.andlib.utility.Preferences; -import com.todoroo.astrid.api.AstridApiConstants; -import com.todoroo.astrid.core.PluginServices; -import com.todoroo.astrid.dao.TaskDao; -import com.todoroo.astrid.data.Metadata; -import com.todoroo.astrid.data.StoreObject; -import com.todoroo.astrid.data.Task; -import com.todoroo.astrid.gtasks.GtasksBackgroundService; -import com.todoroo.astrid.gtasks.GtasksList; -import com.todoroo.astrid.gtasks.GtasksListService; -import com.todoroo.astrid.gtasks.GtasksMetadata; -import com.todoroo.astrid.gtasks.GtasksMetadataService; -import com.todoroo.astrid.gtasks.GtasksPreferenceService; -import com.todoroo.astrid.gtasks.GtasksPreferences; -import com.todoroo.astrid.gtasks.GtasksTaskListUpdater; -import com.todoroo.astrid.gtasks.api.CreateRequest; -import com.todoroo.astrid.gtasks.api.GoogleTasksException; -import com.todoroo.astrid.gtasks.api.GtasksApiUtilities; -import com.todoroo.astrid.gtasks.api.GtasksInvoker; -import com.todoroo.astrid.gtasks.api.MoveListRequest; -import com.todoroo.astrid.gtasks.api.MoveRequest; -import com.todoroo.astrid.gtasks.api.PushRequest; -import com.todoroo.astrid.gtasks.api.UpdateRequest; -import com.todoroo.astrid.gtasks.auth.GtasksLoginActivity; -import com.todoroo.astrid.gtasks.auth.GtasksTokenValidator; -import com.todoroo.astrid.service.AstridDependencyInjector; -import com.todoroo.astrid.service.StatisticsConstants; -import com.todoroo.astrid.service.StatisticsService; -import com.todoroo.astrid.sync.SyncContainer; -import com.todoroo.astrid.sync.SyncProvider; -import com.todoroo.astrid.sync.SyncProviderUtilities; -import com.todoroo.astrid.utility.Constants; - -@SuppressWarnings("nls") -public class GtasksSyncProvider extends SyncProvider { - - @Autowired private GtasksListService gtasksListService; - @Autowired private GtasksMetadataService gtasksMetadataService; - @Autowired private GtasksPreferenceService gtasksPreferenceService; - @Autowired private GtasksTaskListUpdater gtasksTaskListUpdater; - - /** google task service fields */ - private GtasksInvoker taskService = null; - - public GtasksInvoker getGtasksService() { - return taskService; - } - - /** tasks to read id for */ - ArrayList createdWithoutId; - ArrayList createdWithoutOrder; - Semaphore pushedTaskSemaphore = new Semaphore(0); - AtomicInteger pushedTaskCount = new AtomicInteger(0); - - static { - AstridDependencyInjector.initialize(); - } - - // ---------------------------------------------------------------------- - // ------------------------------------------------------ utility methods - // ---------------------------------------------------------------------- - - @Override - protected SyncProviderUtilities getUtilities() { - return gtasksPreferenceService; - } - - /** - * Sign out of service, deleting all synchronization metadata - */ - public void signOut() { - gtasksPreferenceService.clearLastSyncDate(); - gtasksPreferenceService.setToken(null); - Preferences.setString(GtasksPreferenceService.PREF_USER_NAME, null); - gtasksMetadataService.clearMetadata(); - } - - // ---------------------------------------------------------------------- - // ------------------------------------------------------ initiating sync - // ---------------------------------------------------------------------- - - /** - * initiate sync in background - */ - @Override - protected void initiateBackground() { - try { - String authToken = gtasksPreferenceService.getToken(); - authToken = GtasksTokenValidator.validateAuthToken(ContextManager.getContext(), authToken); - gtasksPreferenceService.setToken(authToken); - - taskService = new GtasksInvoker(authToken); - performSync(); - } catch (IllegalStateException e) { - // occurs when application was closed - } catch (Exception e) { - handleException("gtasks-authenticate", e, true); - } finally { - gtasksPreferenceService.stopOngoing(); - } - } - - /** - * If user isn't already signed in, show sign in dialog. Else perform sync. - */ - @Override - protected void initiateManual(final Activity activity) { - String authToken = gtasksPreferenceService.getToken(); - gtasksPreferenceService.stopOngoing(); - - // check if we have a token & it works - if(authToken == null) { - Intent intent = new Intent(activity, GtasksLoginActivity.class); - activity.startActivityForResult(intent, 0); - } else { - activity.startService(new Intent(null, null, - activity, GtasksBackgroundService.class)); - activity.finish(); - } - } - - // ---------------------------------------------------------------------- - // ----------------------------------------------------- synchronization! - // ---------------------------------------------------------------------- - - protected void performSync() { - String syncSuccess = "failed"; - gtasksPreferenceService.recordSyncStart(); - if(Constants.DEBUG) - Log.e("gtasks-debug", "- -------- SYNC STARTED"); - createdWithoutId = new ArrayList(); - createdWithoutOrder = new ArrayList(); - try { - TaskLists allTaskLists = taskService.allGtaskLists(); - - new GtasksLegacyMigrator(taskService, gtasksListService, - allTaskLists).checkAndMigrateLegacy(); - - getActiveList(allTaskLists); - - gtasksListService.updateLists(allTaskLists); - - gtasksTaskListUpdater.createParentSiblingMaps(); - - // read non-deleted tasks for each list - SyncData syncData = populateSyncData(); - try { - synchronizeTasks(syncData); - AndroidUtilities.sleepDeep(3000L); // Wait for changes to be saved (i.e. for repeating tasks to be cloned) - checkForCreatedDuringSync(); - } finally { - syncData.localCreated.close(); - syncData.localUpdated.close(); - } - - gtasksTaskListUpdater.updateAllMetadata(); - - gtasksPreferenceService.recordSuccessfulSync(); - - Intent broadcastIntent = new Intent(AstridApiConstants.BROADCAST_EVENT_REFRESH); - ContextManager.getContext().sendBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ); - if(Constants.DEBUG) - Log.e("gtasks-debug", "- ------ SYNC FINISHED"); - - syncSuccess = getFinalSyncStatus(); - } catch (IllegalStateException e) { - // occurs when application was closed - } catch (IOException e) { - handleException("gtasks-sync", e, true); //$NON-NLS-1$ - } finally { - StatisticsService.reportEvent(StatisticsConstants.GTASKS_SYNC_FINISHED, - "success", syncSuccess); //$NON-NLS-1$ - } - } - - private void checkForCreatedDuringSync() { - TodorooCursor localCreated = gtasksMetadataService.getLocallyCreated(PROPERTIES); - try { - SyncData localCreatedData = new SyncData(null, localCreated, null); - sendLocallyCreated(localCreatedData, new HashMap()); - } catch (IOException e) { - handleException("gtasks-sync", e, true); - } finally { - localCreated.close(); - } - } - - private void getActiveList(TaskLists taskView) throws IOException { - String listId; - if(taskView.getItems().size() == 0) { - if(Constants.DEBUG) - Log.e("gtasks-debug", "ACTION: createList(4)"); - TaskList newList = taskService.createGtaskList(ContextManager.getString(R.string.app_name)); - listId = newList.getId(); - } else if (Preferences.getStringValue(GtasksPreferenceService.PREF_DEFAULT_LIST) != null) { - listId = Preferences.getStringValue(GtasksPreferenceService.PREF_DEFAULT_LIST); - } else { - listId = taskService.getGtaskList("@default").getId(); - } - - Preferences.setString(GtasksPreferenceService.PREF_DEFAULT_LIST, listId); - } - - @Override - protected void readRemotelyUpdated(SyncData data) - throws IOException { - - // wait for pushed threads - try { - pushedTaskSemaphore.acquire(pushedTaskCount.get()); - pushedTaskCount.set(0); - } catch (InterruptedException e) { - return; - } - - // match remote tasks to locally created tasks - HashMap locals = new HashMap(); - for(GtasksTaskContainer task : createdWithoutId) { - locals.put(task.gtaskMetadata.getValue(GtasksMetadata.ID), task); - } - - verifyCreatedOrder(); - - // first, pull all tasks. then we can write them - // include deleted tasks so we can delete them in astrid - data.remoteUpdated = readAllRemoteTasks(true, true); - - for(GtasksTaskContainer remote : data.remoteUpdated) { - if(remote.task.getId() < 1) { - GtasksTaskContainer local = locals.get(remote.gtaskMetadata.getValue(GtasksMetadata.ID)); - if(local != null) { - if(Constants.DEBUG) - Log.e("gtasks-debug", "FOUND LOCAL - " + remote.task.getId()); - remote.task.setId(local.task.getId()); - } - } - } - - super.readRemotelyUpdated(data); - } - - private void verifyCreatedOrder() throws IOException { - Collections.sort(createdWithoutOrder, new Comparator() { - @Override - public int compare(GtasksTaskContainer arg0, GtasksTaskContainer arg1) { - long order0 = arg0.gtaskMetadata.getValue(GtasksMetadata.ORDER); - long order1 = arg1.gtaskMetadata.getValue(GtasksMetadata.ORDER); - - if (order0 == order1) return 0; - if (order0 < order1) return -1; - else return 1; - } - - }); - for (GtasksTaskContainer t : createdWithoutOrder) { - String toMove = t.gtaskMetadata.getValue(GtasksMetadata.ID); - String listId = t.gtaskMetadata.getValue(GtasksMetadata.LIST_ID); - String remoteParent = gtasksMetadataService.getRemoteParentId(t.gtaskMetadata); - String remoteSibling = gtasksMetadataService.getRemoteSiblingId(listId, t.gtaskMetadata); - - MoveRequest move = new MoveRequest(taskService, toMove, listId, remoteParent, remoteSibling); - move.push(); - } - } - - - // ---------------------------------------------------------------------- - // ------------------------------------------------------------ sync data - // ---------------------------------------------------------------------- - - // all synchronized properties - private static final Property[] PROPERTIES = Task.PROPERTIES; - - /** - * Populate SyncData data structure - * @throws JSONException - */ - private SyncData populateSyncData() throws IOException { - - // fetch remote tasks - ArrayList remoteTasks = readAllRemoteTasks(false, false); - - // fetch locally created tasks - TodorooCursor localCreated = gtasksMetadataService.getLocallyCreated(PROPERTIES); - - // fetch locally updated tasks - TodorooCursor localUpdated = gtasksMetadataService.getLocallyUpdated(PROPERTIES); - - return new SyncData(remoteTasks, localCreated, localUpdated); - } - - // ---------------------------------------------------------------------- - // ------------------------------------------------- create / push / pull - // ---------------------------------------------------------------------- - - private ArrayList readAllRemoteTasks(final boolean includeDeleted, final boolean includeHidden) { - final ArrayList list = new ArrayList(); - final Semaphore listsFinished = new Semaphore(0); - - // launch threads - StoreObject[] lists = gtasksListService.getLists(); - for(final StoreObject dashboard : lists) { - new Thread(new Runnable() { - @Override - public void run() { - try { - String listId = dashboard.getValue(GtasksList.REMOTE_ID); - if(Constants.DEBUG) - Log.e("gtasks-debug", "ACTION: getTasks, " + listId); - List remoteTasks = taskService.getAllGtasksFromListId(listId, includeDeleted, includeHidden, 0).getItems(); - addRemoteTasksToList(remoteTasks, listId, list); - } catch (Exception e) { - handleException("read-remotes", e, false); - } finally { - listsFinished.release(); - } - } - }).start(); - } - - try { - listsFinished.acquire(lists.length); - } catch (InterruptedException e) { - handleException("wait-for-remotes", e, false); - } - return list; - } - - private void addRemoteTasksToList(List remoteTasks, String listId, ArrayList list) { - - if (remoteTasks != null) { - long order = 0; - HashMap idsToTasks = new HashMap(); - HashMap indentation = new HashMap(); - HashMap parentToPriorSiblingMap = new HashMap(); - - - //Build map of String ids to task objects - for (com.google.api.services.tasks.model.Task task : remoteTasks) { - String id = task.getId(); - idsToTasks.put(id, task); - } - - for(com.google.api.services.tasks.model.Task remoteTask : remoteTasks) { - if(TextUtils.isEmpty(remoteTask.getTitle())) - continue; - - GtasksTaskContainer container = parseRemoteTask(remoteTask, listId); - String id = remoteTask.getId(); - - // update parents, prior sibling - String parent = remoteTask.getParent(); // can be null, which means top level task - container.parentId = parent; - if(parentToPriorSiblingMap.containsKey(parent)) - container.priorSiblingId = parentToPriorSiblingMap.get(parent); - parentToPriorSiblingMap.put(parent, id); - - // update order, indent - container.gtaskMetadata.setValue(GtasksMetadata.ORDER, order++); - int indent = findIndentation(idsToTasks, indentation, remoteTask); - indentation.put(id, indent); - container.gtaskMetadata.setValue(GtasksMetadata.INDENT, indent); - - // update reminder flags for incoming remote tasks to prevent annoying - if(container.task.hasDueDate() && container.task.getValue(Task.DUE_DATE) < DateUtilities.now()) - container.task.setFlag(Task.REMINDER_FLAGS, Task.NOTIFY_AFTER_DEADLINE, false); - - gtasksMetadataService.findLocalMatch(container); - synchronized(list) { - list.add(container); - } - } - } - } - - private int findIndentation(HashMap idsToTasks, - HashMap indentation, com.google.api.services.tasks.model.Task task) { - if (task == null) return 0; //TODO: Not sure why this is happening... - if(indentation.containsKey(task.getId())) - return indentation.get(task.getId()); - - if(TextUtils.isEmpty(task.getParent())) - return 0; - - return findIndentation(idsToTasks, indentation, idsToTasks.get(task.getParent())) + 1; - } - - @Override - protected GtasksTaskContainer create(GtasksTaskContainer local) throws IOException { - String listId = Preferences.getStringValue(GtasksPreferenceService.PREF_DEFAULT_LIST); - if(local.gtaskMetadata.containsNonNullValue(GtasksMetadata.LIST_ID)) - listId = local.gtaskMetadata.getValue(GtasksMetadata.LIST_ID); - gtasksTaskListUpdater.updateParentAndSibling(local); - local.gtaskMetadata.setValue(GtasksMetadata.ID, null); - local.gtaskMetadata.setValue(GtasksMetadata.LIST_ID, listId); - - com.google.api.services.tasks.model.Task createdTask = new com.google.api.services.tasks.model.Task(); - - CreateRequest createRequest = new CreateRequest(taskService, listId, createdTask, local.parentId, local.priorSiblingId); - //updateTaskHelper(local, null, createRequest); - localPropertiesToModel(local, null, createRequest.getToPush()); - com.google.api.services.tasks.model.Task createResult = createRequest.push(); - createdWithoutId.add(local); - createdWithoutOrder.add(local); - String newIdTask = createResult.getId(); - local.gtaskMetadata.setValue(GtasksMetadata.ID, newIdTask); - - return local; - }//*/ - - private void localPropertiesToModel(GtasksTaskContainer local, GtasksTaskContainer remote, - com.google.api.services.tasks.model.Task model) { - if(shouldTransmit(local, Task.TITLE, remote)) - model.setTitle(local.task.getValue(Task.TITLE)); - if(shouldTransmit(local, Task.DUE_DATE, remote)) { - model.setDue(GtasksApiUtilities.unixTimeToGtasksDueDate(local.task.getValue(Task.DUE_DATE))); - } - if(shouldTransmit(local, Task.COMPLETION_DATE, remote)) { - model.setCompleted(GtasksApiUtilities.unixTimeToGtasksCompletionTime(local.task.getValue(Task.COMPLETION_DATE))); - model.setStatus((local.task.isCompleted() ? "completed" : "needsAction")); - } - if(shouldTransmit(local, Task.DELETION_DATE, remote)) - model.setDeleted(local.task.isDeleted()); - if(shouldTransmit(local, Task.NOTES, remote)) - model.setNotes(local.task.getValue(Task.NOTES)); - } - - private void updateTaskHelper(final GtasksTaskContainer local, - final GtasksTaskContainer remote, final PushRequest request) throws IOException { - - final String idTask = local.gtaskMetadata.getValue(GtasksMetadata.ID); - final String idList = local.gtaskMetadata.getValue(GtasksMetadata.LIST_ID); - - try { - // set properties - localPropertiesToModel(local, null, request.getToPush()); - - // write task (and perform move action if requested) - if(request instanceof UpdateRequest) { - if(Constants.DEBUG) - Log.e("gtasks-debug", "ACTION: task edit (6), " + idTask); - } else if(request instanceof CreateRequest) { - if(Constants.DEBUG) - Log.e("gtasks-debug", "ACTION: task create (7), " + local.task.getValue(Task.TITLE)); - } else - throw new GoogleTasksException("Unknown request type " + request.getClass()); - - pushedTaskCount.incrementAndGet(); - new Thread(new Runnable() { - @Override - public void run() { - String newIdTask = idTask; - try { - /*if (request instanceof CreateRequest) { //This is commented out until bugs with multithreaded task creation are resolved - com.google.api.services.tasks.v1.model.Task createResult = request.executePush(); - newIdTask = createResult.id; - System.err.println("Created " + createResult.title + " successfully, remote id: " + createResult.id); - local.gtaskMetadata.setValue(GtasksMetadata.ID, newIdTask); - }//*/ - if(!TextUtils.isEmpty(newIdTask) && remote != null && (local.parentId != remote.parentId || - local.priorSiblingId != remote.priorSiblingId)) { - if(Constants.DEBUG) - Log.e("gtasks-debug", "ACTION: move(1) - " + newIdTask + ", " + local.parentId + ", " + local.priorSiblingId); - //This case basically defaults to whatever local settings are. Future versions could try and merge better - MoveRequest moveRequest = new MoveRequest(taskService, newIdTask, idList, local.parentId, local.priorSiblingId); - moveRequest.push(); - - } - if (request instanceof UpdateRequest) { - request.push(); - } - - //Strategy--delete, migrate properties, recreate, update local AND remote ids; happens in MoveListRequest - if(remote != null && !idList.equals(remote.gtaskMetadata.getValue( - GtasksMetadata.LIST_ID))) { - if(Constants.DEBUG) - Log.e("gtasks-debug", "ACTION: moveTask(5), " + newIdTask + ", " + idList + " to " + - remote.gtaskMetadata.getValue(GtasksMetadata.LIST_ID)); - MoveListRequest moveList = new MoveListRequest(taskService, newIdTask, remote.gtaskMetadata.getValue(GtasksMetadata.LIST_ID), idList, null); - com.google.api.services.tasks.model.Task result = moveList.push(); - local.gtaskMetadata.setValue(GtasksMetadata.ID, result.getId()); - remote.gtaskMetadata.setValue(GtasksMetadata.ID, result.getId()); - } - } catch (IOException e) { - handleException("update-task", e, false); - } finally { - pushedTaskSemaphore.release(); - } - } - }).start(); - - } catch (Exception e) { - throw new GoogleTasksException(e); - } - }//*/ - - /** Create a task container for the given remote task - * @throws JSONException */ - private GtasksTaskContainer parseRemoteTask(com.google.api.services.tasks.model.Task remoteTask, String listId) { - Task task = new Task(); - - ArrayList metadata = new ArrayList(); - - task.setValue(Task.TITLE, remoteTask.getTitle()); - task.setValue(Task.CREATION_DATE, DateUtilities.now()); - task.setValue(Task.COMPLETION_DATE, GtasksApiUtilities.gtasksCompletedTimeToUnixTime(remoteTask.getCompleted(), 0)); - if (remoteTask.getDeleted() == null || !remoteTask.getDeleted().booleanValue()) - task.setValue(Task.DELETION_DATE, 0L); - else if (remoteTask.getDeleted().booleanValue()) - task.setValue(Task.DELETION_DATE, DateUtilities.now()); - if (remoteTask.getHidden() != null && remoteTask.getHidden().booleanValue()) - task.setValue(Task.DELETION_DATE, DateUtilities.now()); - - long dueDate = GtasksApiUtilities.gtasksDueTimeToUnixTime(remoteTask.getDue(), 0); - long createdDate = Task.createDueDate(Task.URGENCY_SPECIFIC_DAY, dueDate); - task.setValue(Task.DUE_DATE, createdDate); - task.setValue(Task.NOTES, remoteTask.getNotes()); - - Metadata gtasksMetadata = GtasksMetadata.createEmptyMetadata(AbstractModel.NO_ID); - gtasksMetadata.setValue(GtasksMetadata.ID, remoteTask.getId()); - gtasksMetadata.setValue(GtasksMetadata.LIST_ID, listId); - - GtasksTaskContainer container = new GtasksTaskContainer(task, metadata, - gtasksMetadata); - return container; - } - - @Override - protected GtasksTaskContainer pull(GtasksTaskContainer task) throws IOException { - // we pull all tasks at the end, so here we just - // return the task that was requested - return task; - } - - /** - * Send changes for the given Task across the wire. If a remoteTask is - * supplied, we attempt to intelligently only transmit the values that - * have changed. - */ - @Override - protected GtasksTaskContainer push(GtasksTaskContainer local, GtasksTaskContainer remote) throws IOException { - gtasksTaskListUpdater.updateParentAndSibling(local); - - String id = local.gtaskMetadata.getValue(GtasksMetadata.ID); - if(Constants.DEBUG) - Log.e("gtasks-debug", "ACTION: modifyTask(3) - " + id); - - com.google.api.services.tasks.model.Task toUpdate = taskService.getGtask(local.gtaskMetadata.getValue(GtasksMetadata.LIST_ID), id); - UpdateRequest modifyTask = new UpdateRequest(taskService, local.gtaskMetadata.getValue(GtasksMetadata.LIST_ID), toUpdate); - updateTaskHelper(local, remote, modifyTask); - - return pull(remote); - }//*/ - - // ---------------------------------------------------------------------- - // --------------------------------------------------------- read / write - // ---------------------------------------------------------------------- - - @Override - protected GtasksTaskContainer read(TodorooCursor cursor) throws IOException { - return gtasksMetadataService.readTaskAndMetadata(cursor); - } - - @Override - protected void write(GtasksTaskContainer task) throws IOException { - // merge astrid dates with google dates - if(task.task.isSaved()) { - Task local = PluginServices.getTaskService().fetchById(task.task.getId(), Task.DUE_DATE, Task.COMPLETION_DATE); - mergeDates(task.task, local); - if(task.task.isCompleted() && !local.isCompleted()) - StatisticsService.reportEvent(StatisticsConstants.GTASKS_TASK_COMPLETED); - } else { // Set default reminders for remotely created tasks - TaskDao.setDefaultReminders(task.task); - } - gtasksMetadataService.saveTaskAndMetadata(task); - } - - /** pick up due time from local task */ - private void mergeDates(Task remote, Task local) { - if(remote.hasDueDate() && local.hasDueTime()) { - Date newDate = new Date(remote.getValue(Task.DUE_DATE)); - Date oldDate = new Date(local.getValue(Task.DUE_DATE)); - newDate.setHours(oldDate.getHours()); - newDate.setMinutes(oldDate.getMinutes()); - newDate.setSeconds(oldDate.getSeconds()); - long setDate = Task.createDueDate(Task.URGENCY_SPECIFIC_DAY_TIME, - newDate.getTime()); - remote.setValue(Task.DUE_DATE, setDate); - } - } - - // ---------------------------------------------------------------------- - // --------------------------------------------------------- misc helpers - // ---------------------------------------------------------------------- - - @Override - protected int matchTask(ArrayList tasks, GtasksTaskContainer target) { - int length = tasks.size(); - for(int i = 0; i < length; i++) { - GtasksTaskContainer task = tasks.get(i); - if(AndroidUtilities.equals(task.gtaskMetadata.getValue(GtasksMetadata.ID), - target.gtaskMetadata.getValue(GtasksMetadata.ID))) - return i; - } - return -1; - } - - /** - * Determine whether this task's property should be transmitted - * @param task task to consider - * @param property property to consider - * @param remoteTask remote task proxy - * @return - */ - private boolean shouldTransmit(SyncContainer task, Property property, SyncContainer remoteTask) { - if(!task.task.containsValue(property)) - return false; - - if(remoteTask == null) - return true; - if(!remoteTask.task.containsValue(property)) - return true; - - // special cases - match if they're zero or nonzero - if(property == Task.COMPLETION_DATE || - property == Task.DELETION_DATE) - return !AndroidUtilities.equals((Long)task.task.getValue(property) == 0, - (Long)remoteTask.task.getValue(property) == 0); - - return !AndroidUtilities.equals(task.task.getValue(property), - remoteTask.task.getValue(property)); - } - - @Override - protected int updateNotification(Context context, Notification notification) { - String notificationTitle = context.getString(R.string.gtasks_notification_title); - Intent intent = new Intent(context, GtasksPreferences.class); - PendingIntent notificationIntent = PendingIntent.getActivity(context, 0, - intent, 0); - notification.setLatestEventInfo(context, - notificationTitle, context.getString(R.string.SyP_progress), - notificationIntent); - return Constants.NOTIFICATION_SYNC; - } - - @Override - protected void transferIdentifiers(GtasksTaskContainer source, - GtasksTaskContainer destination) { - destination.gtaskMetadata = source.gtaskMetadata; - } -}