From 696c8cd4c7cb464921665a97bda256dd1acf1169 Mon Sep 17 00:00:00 2001 From: Tim Su Date: Wed, 29 Sep 2010 15:59:24 -0700 Subject: [PATCH] Now able to synchronize a google task list successfully. Some kinks to work out. --- astrid/AndroidManifest.xml | 1 + astrid/astrid.launch | 4 +- astrid/libs/todoroo-g.jar | Bin 30584 -> 30950 bytes .../gtasks/GtasksBackgroundService.java | 37 +++++ .../astrid/gtasks/GtasksListService.java | 1 - .../astrid/gtasks/GtasksPreferences.java | 5 +- .../gtasks/GtasksSyncActionExposer.java | 8 +- .../gtasks/sync/GtasksSyncProvider.java | 149 ++++++++++++------ .../org/weloveastrid/rmilk/MilkUtilities.java | 10 +- 9 files changed, 157 insertions(+), 58 deletions(-) create mode 100644 astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksBackgroundService.java diff --git a/astrid/AndroidManifest.xml b/astrid/AndroidManifest.xml index 498c34a9b..bf6a56298 100644 --- a/astrid/AndroidManifest.xml +++ b/astrid/AndroidManifest.xml @@ -235,6 +235,7 @@ + diff --git a/astrid/astrid.launch b/astrid/astrid.launch index 18a0852f5..63d8c0eae 100644 --- a/astrid/astrid.launch +++ b/astrid/astrid.launch @@ -5,8 +5,8 @@ - - + + diff --git a/astrid/libs/todoroo-g.jar b/astrid/libs/todoroo-g.jar index fb9d883e7f3fce744c8882ef1494c89fdef1ee65..a415f05d41417c18584d488d042c2aeac805ceef 100644 GIT binary patch delta 7362 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 tH$1-;p^r%n8Y#^k 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 getSyncProvider() { + return new GtasksSyncProvider(); + } + + @Override + protected SyncProviderUtilities getSyncUtilities() { + return gtasksPreferenceService; + } + + @Override + public void onCreate() { + super.onCreate(); + FlurryAgent.onStartSession(this, Constants.FLURRY_KEY); + } + + @Override + public void onDestroy() { + FlurryAgent.onEndSession(this); + super.onDestroy(); + } + +} diff --git a/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksListService.java b/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksListService.java index 6e90695fb..5396ea374 100644 --- a/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksListService.java +++ b/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksListService.java @@ -58,7 +58,6 @@ public class GtasksListService { return LIST_NOT_FOUND; } - @SuppressWarnings("nls") public void updateLists(GoogleTaskListInfo[] remoteLists) { readLists(); for(int i = 0; i < remoteLists.length; i++) { diff --git a/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksPreferences.java b/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksPreferences.java index bb17a7e9d..889968ca3 100644 --- a/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksPreferences.java +++ b/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksPreferences.java @@ -3,6 +3,7 @@ package com.todoroo.astrid.gtasks; import com.timsu.astrid.R; import com.todoroo.andlib.service.Autowired; import com.todoroo.andlib.service.DependencyInjectionService; +import com.todoroo.astrid.gtasks.sync.GtasksSyncProvider; import com.todoroo.astrid.sync.SyncProviderPreferences; import com.todoroo.astrid.sync.SyncProviderUtilities; @@ -29,12 +30,12 @@ public class GtasksPreferences extends SyncProviderPreferences { @Override public void startSync() { - // + new GtasksSyncProvider().synchronize(this); } @Override public void logOut() { - // + new GtasksSyncProvider().signOut(); } @Override diff --git a/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksSyncActionExposer.java b/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksSyncActionExposer.java index 645c2fd85..717bc0235 100644 --- a/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksSyncActionExposer.java +++ b/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksSyncActionExposer.java @@ -14,6 +14,7 @@ import com.todoroo.andlib.service.ContextManager; import com.todoroo.andlib.service.DependencyInjectionService; import com.todoroo.astrid.api.AstridApiConstants; import com.todoroo.astrid.api.SyncAction; +import com.todoroo.astrid.sync.SyncBackgroundService; /** * Exposes sync action @@ -32,10 +33,9 @@ public class GtasksSyncActionExposer extends BroadcastReceiver { if(!gtasksPreferenceService.isLoggedIn()) return; - // TODO - Intent syncIntent = new Intent(intent.getAction(), null, - context, GtasksSyncActionExposer.class); - PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, syncIntent, 0); + Intent syncIntent = new Intent(SyncBackgroundService.SYNC_ACTION, null, + context, GtasksBackgroundService.class); + PendingIntent pendingIntent = PendingIntent.getService(context, 0, syncIntent, PendingIntent.FLAG_UPDATE_CURRENT); SyncAction syncAction = new SyncAction(context.getString(R.string.gtasks_GPr_header), pendingIntent); diff --git a/astrid/plugin-src/com/todoroo/astrid/gtasks/sync/GtasksSyncProvider.java b/astrid/plugin-src/com/todoroo/astrid/gtasks/sync/GtasksSyncProvider.java index 25ac58dd1..d454ac789 100644 --- a/astrid/plugin-src/com/todoroo/astrid/gtasks/sync/GtasksSyncProvider.java +++ b/astrid/plugin-src/com/todoroo/astrid/gtasks/sync/GtasksSyncProvider.java @@ -29,9 +29,11 @@ import com.todoroo.andlib.service.ExceptionService; import com.todoroo.andlib.utility.AndroidUtilities; import com.todoroo.andlib.utility.DateUtilities; import com.todoroo.andlib.utility.DialogUtilities; +import com.todoroo.andlib.utility.Preferences; 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; @@ -39,15 +41,14 @@ 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.producteev.ProducteevBackgroundService; -import com.todoroo.astrid.producteev.ProducteevLoginActivity; -import com.todoroo.astrid.producteev.ProducteevUtilities; import com.todoroo.astrid.producteev.api.ApiServiceException; import com.todoroo.astrid.service.AstridDependencyInjector; +import com.todoroo.astrid.sync.SyncBackgroundService; import com.todoroo.astrid.sync.SyncContainer; import com.todoroo.astrid.sync.SyncProvider; import com.todoroo.astrid.utility.Constants; -import com.todoroo.andlib.utility.Preferences; +import com.todoroo.gtasks.GoogleConnectionManager; +import com.todoroo.gtasks.GoogleLoginException; import com.todoroo.gtasks.GoogleTaskService; import com.todoroo.gtasks.GoogleTaskService.ConvenientTaskCreator; import com.todoroo.gtasks.GoogleTaskTask; @@ -79,7 +80,6 @@ public class GtasksSyncProvider extends SyncProvider { private final HashMap> listActions = new HashMap>(); - static { AstridDependencyInjector.initialize(); } @@ -90,6 +90,8 @@ public class GtasksSyncProvider extends SyncProvider { public GtasksSyncProvider() { super(); DependencyInjectionService.getInstance().inject(this); + // TODO? + gtasksPreferenceService.stopOngoing(); } // ---------------------------------------------------------------------- @@ -155,24 +157,15 @@ public class GtasksSyncProvider extends SyncProvider { try { String authToken = gtasksPreferenceService.getToken(); - String email = "tasktest@todoroo.com"; // TODO - String password = "tasktest0000"; - - taskService = new GoogleTaskService(email, password); - - // check if we have a token & it works - if(authToken != null) { - - taskService.getTaskView(); - performSync(); + final GoogleConnectionManager connectionManager; + if(authToken == null) { + connectionManager = logInHelper(); } else { - if (email == null && password == null) { - // we can't do anything, user is not logged in - } else { - //authToken = null; // TODO set up auth token - performSync(); - } + connectionManager = new GoogleConnectionManager(authToken); } + + taskService = new GoogleTaskService(connectionManager); + performSync(); } catch (IllegalStateException e) { // occurs when application was closed } catch (Exception e) { @@ -182,25 +175,39 @@ public class GtasksSyncProvider extends SyncProvider { } } + private GoogleConnectionManager logInHelper() throws GoogleLoginException, + IOException { + // TODO get email and password or something? + String email = "tasktest@todoroo.com"; + String password = "tasktest0000"; + GoogleConnectionManager connectionManager = new GoogleConnectionManager(email, password); + connectionManager.authenticate(true); + gtasksPreferenceService.setToken(connectionManager.getToken()); + return connectionManager; + } + /** * If user isn't already signed in, show sign in dialog. Else perform sync. */ @Override protected void initiateManual(Activity activity) { String authToken = gtasksPreferenceService.getToken(); - ProducteevUtilities.INSTANCE.stopOngoing(); + gtasksPreferenceService.stopOngoing(); // check if we have a token & it works if(authToken == null) { - // display login-activity - Intent intent = new Intent(activity, ProducteevLoginActivity.class); - activity.startActivityForResult(intent, 0); - } else { - activity.startService(new Intent(ProducteevBackgroundService.SYNC_ACTION, null, - activity, ProducteevBackgroundService.class)); + try { + logInHelper(); + } catch (Exception e) { + handleException("auth", e, true); + } } + + activity.startService(new Intent(SyncBackgroundService.SYNC_ACTION, null, + activity, GtasksBackgroundService.class)); } + // ---------------------------------------------------------------------- // ----------------------------------------------------- synchronization! // ---------------------------------------------------------------------- @@ -227,15 +234,8 @@ public class GtasksSyncProvider extends SyncProvider { } taskService.executeActions(getTasksActions.toArray(new GetTasksAction[getTasksActions.size()])); for(GetTasksAction action : getTasksActions) { - List remoteTasksInList = action.getGoogleTasks(); - for(GoogleTaskTask remoteTask : remoteTasksInList) { - GtasksTaskContainer remote = parseRemoteTask(remoteTask); - // update reminder flags for incoming remote tasks to prevent annoying - if(remote.task.hasDueDate() && remote.task.getValue(Task.DUE_DATE) < DateUtilities.now()) - remote.task.setFlag(Task.REMINDER_FLAGS, Task.NOTIFY_AFTER_DEADLINE, false); - gtasksMetadataService.findLocalMatch(remote); - remoteTasks.add(remote); - } + List list = action.getGoogleTasks(); + readTasksIntoRemoteTasks(list, remoteTasks); } SyncData syncData = populateSyncData(remoteTasks); @@ -255,6 +255,51 @@ public class GtasksSyncProvider extends SyncProvider { } } + private void readTasksIntoRemoteTasks(List list, + ArrayList remoteTasks) { + + int order = 0; + HashMap parents = new HashMap(); + HashMap indentation = new HashMap(); + HashMap parentToPriorSiblingMap = new HashMap(); + + for(GoogleTaskTask remoteTask : list) { + GtasksTaskContainer container = parseRemoteTask(remoteTask); + String id = remoteTask.getId(); + + // update parents, prior sibling + for(String child : remoteTask.getChild_ids()) + parents.put(child, id); + String parent = parents.get(id); // can be null, which means top level task + 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(parents, indentation, id); + 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); + remoteTasks.add(container); + } + } + + private int findIndentation(HashMap parents, + HashMap indentation, String task) { + if(indentation.containsKey(task)) + return indentation.get(task); + + if(!parents.containsKey(task)) + return 0; + + return findIndentation(parents, indentation, parents.get(task)) + 1; + } + // ---------------------------------------------------------------------- // ------------------------------------------------------------ sync data // ---------------------------------------------------------------------- @@ -299,6 +344,7 @@ public class GtasksSyncProvider extends SyncProvider { ConvenientTaskCreator createdTask; try { createdTask = taskService.createTask(list, local.task.getValue(Task.TITLE)); + createdTask.parentId(local.parentId); } catch (JSONException e) { throw new RuntimeException(e); } @@ -329,12 +375,10 @@ public class GtasksSyncProvider extends SyncProvider { // moving between lists if(remote != null && !idList.equals(remote.gtaskMetadata.getValue(GtasksMetadata.LIST_ID))) { - a.moveTask(idTask, idList, remote.gtaskMetadata.getValue(GtasksMetadata.LIST_ID), null); + batch(a.moveTask(idTask, idList, remote.gtaskMetadata.getValue(GtasksMetadata.LIST_ID), null)); } // other properties - if(shouldTransmit(local, Task.TITLE, remote)) - ((TaskModifier)builder).name(local.task.getValue(Task.TITLE)); if(shouldTransmit(local, Task.DUE_DATE, remote)) builder.taskDate(local.task.getValue(Task.DUE_DATE)); if(shouldTransmit(local, Task.COMPLETION_DATE, remote)) @@ -344,11 +388,15 @@ public class GtasksSyncProvider extends SyncProvider { if(shouldTransmit(local, Task.NOTES, remote)) builder.notes(local.task.getValue(Task.NOTES)); + // moving within a list + if(remote == null || local.parentId != remote.parentId || local.priorSiblingId != remote.priorSiblingId) { + batch(local.gtaskMetadata.getValue(GtasksMetadata.LIST_ID), + l.move(idTask, local.parentId, local.priorSiblingId)); + } + } catch (JSONException e) { throw new GoogleTasksException(e); } - - // TODO indentation } /** Create a task container for the given RtmTaskSeries @@ -363,16 +411,15 @@ public class GtasksSyncProvider extends SyncProvider { task.setValue(Task.DELETION_DATE, remoteTask.isDeleted() ? DateUtilities.now() : 0); long dueDate = remoteTask.getTask_date(); - task.setValue(Task.DUE_DATE, task.createDueDate(Task.URGENCY_SPECIFIC_DAY_TIME, dueDate)); + task.setValue(Task.DUE_DATE, task.createDueDate(Task.URGENCY_SPECIFIC_DAY, dueDate)); task.setValue(Task.NOTES, remoteTask.getNotes()); Metadata gtasksMetadata = GtasksMetadata.createEmptyMetadata(AbstractModel.NO_ID); gtasksMetadata.setValue(GtasksMetadata.LIST_ID, remoteTask.getList_id()); - // TODO gtasksMetadata.setValue(GtasksMetadata.INDENT, remoteTask.???); GtasksTaskContainer container = new GtasksTaskContainer(task, metadata, gtasksMetadata); - + // TODO indent return container; } @@ -406,10 +453,15 @@ public class GtasksSyncProvider extends SyncProvider { @Override protected void push(GtasksTaskContainer local, GtasksTaskContainer remote) throws IOException { try { - TaskModifier modifyTask = l.modifyTask(remote.gtaskMetadata.getValue(GtasksMetadata.ID)); + String id = local.gtaskMetadata.getValue(GtasksMetadata.ID); + TaskModifier modifyTask = l.modifyTask(id); updateTaskHelper(local, remote, modifyTask); + + if(shouldTransmit(local, Task.TITLE, remote)) + modifyTask.name(local.task.getValue(Task.TITLE)); ListAction action = modifyTask.done(); batch(local.gtaskMetadata.getValue(GtasksMetadata.LIST_ID), action); + } catch (JSONException e) { throw new GoogleTasksException(e); } @@ -422,6 +474,11 @@ public class GtasksSyncProvider extends SyncProvider { listActions.get(list).add(action); } + /** add action to batch */ + private void batch(Action action) { + actions.add(action); + } + // ---------------------------------------------------------------------- // --------------------------------------------------------- read / write // ---------------------------------------------------------------------- diff --git a/astrid/rmilk-src/org/weloveastrid/rmilk/MilkUtilities.java b/astrid/rmilk-src/org/weloveastrid/rmilk/MilkUtilities.java index a1018a939..dbdbd6d96 100644 --- a/astrid/rmilk-src/org/weloveastrid/rmilk/MilkUtilities.java +++ b/astrid/rmilk-src/org/weloveastrid/rmilk/MilkUtilities.java @@ -9,6 +9,7 @@ import android.content.SharedPreferences.Editor; import com.timsu.astrid.R; import com.todoroo.andlib.service.ContextManager; +import com.todoroo.andlib.utility.Preferences; import com.todoroo.astrid.sync.SyncProviderUtilities; /** @@ -27,23 +28,26 @@ public class MilkUtilities extends SyncProviderUtilities { public static final MilkUtilities INSTANCE = new MilkUtilities(); + private static final String EXPORTED_PREFS_CHECKED = IDENTIFIER + "-prefscheck"; + // --- utilities boilerplate private MilkUtilities() { // if no token is set, see if astrid has exported one - if(getToken() == null) { + if(getToken() == null && !Preferences.getBoolean(EXPORTED_PREFS_CHECKED, false)) { try { Context astridContext = ContextManager.getContext().createPackageContext("com.timsu.astrid", 0); SharedPreferences sharedPreferences = astridContext.getSharedPreferences("rtm", 0); + Editor editor = getPrefs().edit(); if(sharedPreferences != null) { String token = sharedPreferences.getString("rmilk_token", null); long lastSyncDate = sharedPreferences.getLong("rmilk_last_sync", 0); - Editor editor = getPrefs().edit(); editor.putString(getIdentifier() + PREF_TOKEN, token); editor.putLong(getIdentifier() + PREF_LAST_SYNC, lastSyncDate); - editor.commit(); } + editor.putBoolean(EXPORTED_PREFS_CHECKED, true); + editor.commit(); } catch (Exception e) { // too bad }