diff --git a/astrid/plugin-src/com/todoroo/astrid/common/SyncProvider.java b/astrid/plugin-src/com/todoroo/astrid/common/SyncProvider.java index c48895bdf..a0785ec7e 100644 --- a/astrid/plugin-src/com/todoroo/astrid/common/SyncProvider.java +++ b/astrid/plugin-src/com/todoroo/astrid/common/SyncProvider.java @@ -15,8 +15,8 @@ import android.content.Context; import android.widget.Toast; import com.timsu.astrid.R; -import com.todoroo.andlib.data.TodorooCursor; import com.todoroo.andlib.data.Property.LongProperty; +import com.todoroo.andlib.data.TodorooCursor; import com.todoroo.andlib.service.Autowired; import com.todoroo.andlib.service.DependencyInjectionService; import com.todoroo.andlib.service.ExceptionService; @@ -260,6 +260,7 @@ public abstract class SyncProvider { } else { push(local, null); } + write(local); } catch (Exception e) { handleException("sync-local-updated", e, false); //$NON-NLS-1$ } diff --git a/astrid/plugin-src/com/todoroo/astrid/producteev/api/ProducteevInvoker.java b/astrid/plugin-src/com/todoroo/astrid/producteev/api/ProducteevInvoker.java index 78940c783..09dec1884 100644 --- a/astrid/plugin-src/com/todoroo/astrid/producteev/api/ProducteevInvoker.java +++ b/astrid/plugin-src/com/todoroo/astrid/producteev/api/ProducteevInvoker.java @@ -88,11 +88,11 @@ public class ProducteevInvoker { * @param status (optional) (1 = UNDONE, 2 = DONE) * @param star (optional) (0 to 5 stars) * - * @return array tasks/view + * @return task */ - public JSONArray tasksCreate(String title, Long idResponsible, Long idDashboard, + public JSONObject tasksCreate(String title, Long idResponsible, Long idDashboard, String deadline, Integer reminder, Integer status, Integer star) throws ApiServiceException, IOException { - return getResponse(invokeGet("tasks/create.json", + return invokeGet("tasks/create.json", "token", token, "title", title, "id_responsible", idResponsible, @@ -100,7 +100,7 @@ public class ProducteevInvoker { "deadline", deadline, "reminder", reminder, "status", status, - "star", star), "tasks"); + "star", star); } /** @@ -125,10 +125,10 @@ public class ProducteevInvoker { * * @return array tasks/view */ - public JSONArray tasksView(Long idTask) throws ApiServiceException, IOException { - return getResponse(invokeGet("tasks/view.json", + public JSONObject tasksView(Long idTask) throws ApiServiceException, IOException { + return invokeGet("tasks/view.json", "token", token, - "id_task", idTask), "tasks"); + "id_task", idTask); } /** @@ -139,11 +139,11 @@ public class ProducteevInvoker { * * @return array tasks/view */ - public JSONArray tasksSetTitle(long idTask, String title) throws ApiServiceException, IOException { - return getResponse(invokeGet("tasks/set_title.json", + public JSONObject tasksSetTitle(long idTask, String title) throws ApiServiceException, IOException { + return invokeGet("tasks/set_title.json", "token", token, "id_task", idTask, - "title", title), "tasks"); + "title", title); } /** @@ -154,11 +154,11 @@ public class ProducteevInvoker { * * @return array tasks/view */ - public JSONArray tasksSetStatus(long idTask, int status) throws ApiServiceException, IOException { - return getResponse(invokeGet("tasks/set_star.json", + public JSONObject tasksSetStatus(long idTask, int status) throws ApiServiceException, IOException { + return invokeGet("tasks/set_star.json", "token", token, "id_task", idTask, - "status", status), "tasks"); + "status", status); } /** @@ -169,11 +169,11 @@ public class ProducteevInvoker { * * @return array tasks/view */ - public JSONArray tasksSetStar(long idTask, int star) throws ApiServiceException, IOException { - return getResponse(invokeGet("tasks/set_star.json", + public JSONObject tasksSetStar(long idTask, int star) throws ApiServiceException, IOException { + return invokeGet("tasks/set_star.json", "token", token, "id_task", idTask, - "star", star), "tasks"); + "star", star); } /** @@ -184,11 +184,11 @@ public class ProducteevInvoker { * * @return array tasks/view */ - public JSONArray tasksSetDeadline(long idTask, String deadline) throws ApiServiceException, IOException { - return getResponse(invokeGet("tasks/set_deadline.json", + public JSONObject tasksSetDeadline(long idTask, String deadline) throws ApiServiceException, IOException { + return invokeGet("tasks/set_deadline.json", "token", token, "id_task", idTask, - "deadline", deadline), "tasks"); + "deadline", deadline); } /** @@ -225,7 +225,7 @@ public class ProducteevInvoker { * * @return array: tasks/view */ - public JSONArray tasksSetLabels(long idTask, long... idLabels) throws ApiServiceException, IOException { + public JSONObject tasksSetLabels(long idTask, long... idLabels) throws ApiServiceException, IOException { Object[] params = new Object[idLabels.length * 2 + 2]; params[0] = "token"; params[1] = token; @@ -234,7 +234,7 @@ public class ProducteevInvoker { params[i*2 + 3] = idLabels[i]; } - return getResponse(invokeGet("tasks/set_label.json", params), "tasks"); + return invokeGet("tasks/set_label.json", params); } /** @@ -245,7 +245,7 @@ public class ProducteevInvoker { * * @return array: tasks/view */ - public JSONArray tasksUnsetLabels(long idTask, long... idLabels) throws ApiServiceException, IOException { + public JSONObject tasksUnsetLabels(long idTask, long... idLabels) throws ApiServiceException, IOException { Object[] params = new Object[idLabels.length * 2 + 2]; params[0] = "token"; params[1] = token; @@ -254,7 +254,7 @@ public class ProducteevInvoker { params[i*2 + 3] = idLabels[i]; } - return getResponse(invokeGet("tasks/unset_label.json", params), "tasks"); + return invokeGet("tasks/unset_label.json", params); } /** @@ -337,6 +337,8 @@ public class ProducteevInvoker { try { String request = createFetchUrl(method, getParameters); String response = restClient.get(request); + if(response.startsWith("DEBUG MESSAGE")) + throw new ApiServiceException(response); return new JSONObject(response); } catch (JSONException e) { throw new ApiResponseParseException(e); @@ -374,6 +376,7 @@ public class ProducteevInvoker { } sigBuilder.append(apiSecret); + System.err.println("sigbuilder " + sigBuilder); byte[] digest = MessageDigest.getInstance("MD5").digest(sigBuilder.toString().getBytes("UTF-8")); String signature = new BigInteger(1, digest).toString(16); requestBuilder.append("api_sig").append('=').append(signature); diff --git a/astrid/plugin-src/com/todoroo/astrid/producteev/api/ProducteevRestClient.java b/astrid/plugin-src/com/todoroo/astrid/producteev/api/ProducteevRestClient.java index b6345f337..d359f2b83 100644 --- a/astrid/plugin-src/com/todoroo/astrid/producteev/api/ProducteevRestClient.java +++ b/astrid/plugin-src/com/todoroo/astrid/producteev/api/ProducteevRestClient.java @@ -88,14 +88,16 @@ public class ProducteevRestClient implements RestClient { int statusCode = response.getStatusLine().getStatusCode(); if(statusCode != HTTP_OK) { + ApiServiceException error; try { - JSONObject error = new JSONObject(body); - String errorMessage = error.getJSONObject("error").getString("message"); //$NON-NLS-1$ //$NON-NLS-2$ - throw new ApiServiceException(errorMessage); + JSONObject errorObject = new JSONObject(body).getJSONObject("error"); //$NON-NLS-1$ + String errorMessage = errorObject.getString("message"); //$NON-NLS-1$ + error= new ApiServiceException(errorMessage); } catch (Exception e) { - throw new ApiServiceException(response.getStatusLine() + + error = new ApiServiceException(response.getStatusLine() + "\n" + body); //$NON-NLS-1$ } + throw error; } diff --git a/astrid/plugin-src/com/todoroo/astrid/producteev/sync/ProducteevDataService.java b/astrid/plugin-src/com/todoroo/astrid/producteev/sync/ProducteevDataService.java index ce6df3ad3..61a1a3dfc 100644 --- a/astrid/plugin-src/com/todoroo/astrid/producteev/sync/ProducteevDataService.java +++ b/astrid/plugin-src/com/todoroo/astrid/producteev/sync/ProducteevDataService.java @@ -80,7 +80,7 @@ public final class ProducteevDataService { taskDao.query(Query.select(properties).join(ProducteevDataService.METADATA_JOIN).where(Criterion.and( Criterion.not(Task.ID.in(Query.select(Metadata.TASK).from(Metadata.TABLE). where(Criterion.and(MetadataCriteria.withKey(ProducteevTask.METADATA_KEY), ProducteevTask.ID.gt(0))))), - TaskCriteria.isActive()))); + TaskCriteria.isActive())).groupBy(Task.ID)); } /** @@ -95,7 +95,7 @@ public final class ProducteevDataService { return taskDao.query(Query.select(properties).join(ProducteevDataService.METADATA_JOIN). where(Criterion.and(MetadataCriteria.withKey(ProducteevTask.METADATA_KEY), - Task.MODIFICATION_DATE.gt(lastSyncDate)))); + Task.MODIFICATION_DATE.gt(lastSyncDate))).groupBy(Task.ID)); } /** @@ -123,7 +123,6 @@ public final class ProducteevDataService { * @param task */ public void saveTaskAndMetadata(ProducteevTaskContainer task) { - findLocalMatch(task); taskDao.save(task.task, true); metadataDao.deleteWhere(Criterion.and(MetadataCriteria.byTask(task.task.getId()), @@ -131,6 +130,7 @@ public final class ProducteevDataService { MetadataCriteria.withKey(ProducteevNote.METADATA_KEY), MetadataCriteria.withKey(TagService.KEY)))); task.metadata.add(task.pdvTask); + task.pdvTask.setValue(Metadata.KEY, ProducteevTask.METADATA_KEY); for(Metadata metadata : task.metadata) { metadata.setValue(Metadata.TASK, task.task.getId()); metadataDao.createNew(metadata); diff --git a/astrid/plugin-src/com/todoroo/astrid/producteev/sync/ProducteevSyncProvider.java b/astrid/plugin-src/com/todoroo/astrid/producteev/sync/ProducteevSyncProvider.java index 5e3547c6d..4cbff384b 100644 --- a/astrid/plugin-src/com/todoroo/astrid/producteev/sync/ProducteevSyncProvider.java +++ b/astrid/plugin-src/com/todoroo/astrid/producteev/sync/ProducteevSyncProvider.java @@ -80,6 +80,7 @@ public class ProducteevSyncProvider extends SyncProvider syncData = populateSyncData(tasks); try { @@ -238,8 +241,11 @@ public class ProducteevSyncProvider extends SyncProvider remoteTasks = new ArrayList(tasks.length()); - for(int i = 0; i < tasks.length(); i++) - remoteTasks.add(parseRemoteTask(tasks.getJSONObject(i))); + for(int i = 0; i < tasks.length(); i++) { + ProducteevTaskContainer remote = parseRemoteTask(tasks.getJSONObject(i)); + dataService.findLocalMatch(remote); + remoteTasks.add(remote); + } return new SyncData(remoteTasks, localCreated, localUpdated); } @@ -251,17 +257,15 @@ public class ProducteevSyncProvider extends SyncProvider metadata = new ArrayList(); + if(remoteTask.has("task")) + remoteTask = remoteTask.getJSONObject("task"); + task.setValue(Task.TITLE, remoteTask.getString("title")); task.setValue(Task.CREATION_DATE, ApiUtilities.producteevToUnixTime(remoteTask.getString("time_created"), 0)); task.setValue(Task.COMPLETION_DATE, remoteTask.getInt("status") == 2 ? DateUtilities.now() : 0); @@ -312,11 +319,9 @@ public class ProducteevSyncProvider extends SyncProvider metadata, Metadata remote) { + public ProducteevTaskContainer(Task task, ArrayList metadata, Metadata pdvTask) { this.task = task; this.metadata = metadata; - this.pdvTask = remote; - if(this.pdvTask == null) + this.pdvTask = pdvTask; + if(this.pdvTask == null) { this.pdvTask = new Metadata(); + this.pdvTask.setValue(Metadata.KEY, ProducteevTask.METADATA_KEY); + } } @SuppressWarnings("nls") public ProducteevTaskContainer(Task task, ArrayList metadata, JSONObject remoteTask) { this(task, metadata, new Metadata()); + pdvTask.setValue(Metadata.KEY, ProducteevTask.METADATA_KEY); pdvTask.setValue(ProducteevTask.ID, remoteTask.optLong("id_task")); pdvTask.setValue(ProducteevTask.DASHBOARD_ID, remoteTask.optLong("id_dashboard")); } @@ -46,8 +49,10 @@ public class ProducteevTaskContainer extends TaskContainer { break; } } - if(this.pdvTask == null) + if(this.pdvTask == null) { this.pdvTask = new Metadata(); + this.pdvTask.setValue(Metadata.KEY, ProducteevTask.METADATA_KEY); + } } diff --git a/astrid/plugin-src/com/todoroo/astrid/rmilk/data/MilkDataService.java b/astrid/plugin-src/com/todoroo/astrid/rmilk/data/MilkDataService.java index c130b3bfe..06887c257 100644 --- a/astrid/plugin-src/com/todoroo/astrid/rmilk/data/MilkDataService.java +++ b/astrid/plugin-src/com/todoroo/astrid/rmilk/data/MilkDataService.java @@ -13,8 +13,8 @@ import android.content.Context; import com.todoroo.andlib.data.GenericDao; import com.todoroo.andlib.data.Property; -import com.todoroo.andlib.data.TodorooCursor; import com.todoroo.andlib.data.Property.CountProperty; +import com.todoroo.andlib.data.TodorooCursor; import com.todoroo.andlib.service.Autowired; import com.todoroo.andlib.service.ContextManager; import com.todoroo.andlib.service.DependencyInjectionService; @@ -24,8 +24,8 @@ import com.todoroo.andlib.sql.Order; import com.todoroo.andlib.sql.Query; import com.todoroo.andlib.utility.SoftHashMap; import com.todoroo.astrid.dao.MetadataDao; -import com.todoroo.astrid.dao.TaskDao; import com.todoroo.astrid.dao.MetadataDao.MetadataCriteria; +import com.todoroo.astrid.dao.TaskDao; import com.todoroo.astrid.dao.TaskDao.TaskCriteria; import com.todoroo.astrid.model.Metadata; import com.todoroo.astrid.model.Task; @@ -95,7 +95,7 @@ public final class MilkDataService { taskDao.query(Query.select(properties).join(MilkDataService.METADATA_JOIN).where(Criterion.and( Criterion.not(Task.ID.in(Query.select(Metadata.TASK).from(Metadata.TABLE). where(Criterion.and(MetadataCriteria.withKey(MilkTask.METADATA_KEY), MilkTask.TASK_SERIES_ID.gt(0))))), - TaskCriteria.isActive()))); + TaskCriteria.isActive())).groupBy(Task.ID)); } /** @@ -110,7 +110,7 @@ public final class MilkDataService { return taskDao.query(Query.select(properties).join(MilkDataService.METADATA_JOIN). where(Criterion.and(MetadataCriteria.withKey(MilkTask.METADATA_KEY), - Task.MODIFICATION_DATE.gt(lastSyncDate)))); + Task.MODIFICATION_DATE.gt(lastSyncDate))).groupBy(Task.ID)); } /** diff --git a/astrid/res/drawable/ic_menu_producteev.png b/astrid/res/drawable/ic_menu_producteev.png index 00da794bc..4e9c45357 100644 Binary files a/astrid/res/drawable/ic_menu_producteev.png and b/astrid/res/drawable/ic_menu_producteev.png differ diff --git a/astrid/res/values/colors.xml b/astrid/res/values/colors.xml index bb2ccbbe2..6ad31074c 100644 --- a/astrid/res/values/colors.xml +++ b/astrid/res/values/colors.xml @@ -22,5 +22,7 @@ #fffea400 #ff33a5e8 #ff808080 + #ff505050 + #ff202020 diff --git a/astrid/src/com/todoroo/astrid/model/Task.java b/astrid/src/com/todoroo/astrid/model/Task.java index e728c639b..b0130614d 100644 --- a/astrid/src/com/todoroo/astrid/model/Task.java +++ b/astrid/src/com/todoroo/astrid/model/Task.java @@ -146,6 +146,10 @@ public final class Task extends AbstractModel { r.getColor(R.color.importance_2), r.getColor(R.color.importance_3), r.getColor(R.color.importance_4), + + // for external services with importances > 4 + r.getColor(R.color.importance_5), + r.getColor(R.color.importance_6), }; } diff --git a/astrid/src/com/todoroo/astrid/service/StartupService.java b/astrid/src/com/todoroo/astrid/service/StartupService.java index a9f19c83a..efe397b2f 100644 --- a/astrid/src/com/todoroo/astrid/service/StartupService.java +++ b/astrid/src/com/todoroo/astrid/service/StartupService.java @@ -8,8 +8,8 @@ import android.app.AlertDialog; import android.app.PendingIntent; import android.content.Context; import android.content.DialogInterface; -import android.content.Intent; import android.content.DialogInterface.OnClickListener; +import android.content.Intent; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.util.Log; @@ -21,6 +21,7 @@ import com.todoroo.andlib.service.DependencyInjectionService; import com.todoroo.andlib.service.ExceptionService; import com.todoroo.andlib.service.ExceptionService.TodorooUncaughtExceptionHandler; import com.todoroo.astrid.dao.Database; +import com.todoroo.astrid.producteev.ProducteevUtilities; import com.todoroo.astrid.rmilk.MilkUtilities; import com.todoroo.astrid.utility.Constants; import com.todoroo.astrid.utility.Preferences; @@ -114,6 +115,7 @@ public class StartupService { // if sync ongoing flag was set, clear it MilkUtilities.stopOngoing(); + new ProducteevUtilities().stopOngoing(); // check for task killers if(!Constants.OEM)