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 fb9d883e7..a415f05d4 100644
Binary files a/astrid/libs/todoroo-g.jar and b/astrid/libs/todoroo-g.jar differ
diff --git a/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksBackgroundService.java b/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksBackgroundService.java
new file mode 100644
index 000000000..fec6661c3
--- /dev/null
+++ b/astrid/plugin-src/com/todoroo/astrid/gtasks/GtasksBackgroundService.java
@@ -0,0 +1,37 @@
+package com.todoroo.astrid.gtasks;
+
+import com.flurry.android.FlurryAgent;
+import com.todoroo.andlib.service.Autowired;
+import com.todoroo.astrid.gtasks.sync.GtasksSyncProvider;
+import com.todoroo.astrid.sync.SyncBackgroundService;
+import com.todoroo.astrid.sync.SyncProvider;
+import com.todoroo.astrid.sync.SyncProviderUtilities;
+import com.todoroo.astrid.utility.Constants;
+
+public class GtasksBackgroundService extends SyncBackgroundService {
+
+ @Autowired private GtasksPreferenceService gtasksPreferenceService;
+
+ @Override
+ protected SyncProvider> 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
}