mirror of https://github.com/tasks/tasks
Remove ActFmInvoker, ActFmSyncService
parent
1fccbfda7b
commit
2eff822eca
@ -1,96 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2012 Todoroo Inc
|
||||
*
|
||||
* See the file "LICENSE" for the full license governing this code.
|
||||
*/
|
||||
package com.todoroo.astrid.actfm.sync;
|
||||
|
||||
import com.todoroo.andlib.service.Autowired;
|
||||
import com.todoroo.andlib.service.DependencyInjectionService;
|
||||
import com.todoroo.andlib.service.RestClient;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.TimeZone;
|
||||
|
||||
|
||||
public class ActFmInvoker {
|
||||
|
||||
/**
|
||||
* NOTE: these values are development values & will not work on production
|
||||
*/
|
||||
private static final String URL = "//10.0.2.2:3000/api/";
|
||||
private static final String APP_ID = "a4732a32859dbcd3e684331acd36432c";
|
||||
private static final String APP_SECRET = "e389bfc82a0d932332f9a8bd8203735f";
|
||||
|
||||
public static final String PROVIDER_PASSWORD = "password";
|
||||
|
||||
private static final int API_VERSION = 7;
|
||||
|
||||
@Autowired
|
||||
private RestClient restClient;
|
||||
|
||||
private String token = null;
|
||||
|
||||
// --- initialization, getters, setters
|
||||
|
||||
/**
|
||||
* Create new api invoker service without a token
|
||||
*/
|
||||
public ActFmInvoker() {
|
||||
//
|
||||
DependencyInjectionService.getInstance().inject(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new api invoker service with a token
|
||||
*
|
||||
* @token access token
|
||||
*/
|
||||
public ActFmInvoker(String token) {
|
||||
this.token = token;
|
||||
DependencyInjectionService.getInstance().inject(this);
|
||||
}
|
||||
|
||||
public String getToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
// --- special method invocations
|
||||
|
||||
/**
|
||||
* Authentication user with Act.fm server, returning a token
|
||||
*/
|
||||
public JSONObject authenticate(String email, String firstName, String lastName, String provider,
|
||||
String secret) throws IOException {
|
||||
JSONObject result = invoke(
|
||||
"user_signin",
|
||||
"email", email,
|
||||
"first_name", firstName,
|
||||
"last_name", lastName,
|
||||
"provider", provider,
|
||||
"secret", secret,
|
||||
"timezone", TimeZone.getDefault().getID());
|
||||
try {
|
||||
token = result.getString("token");
|
||||
} catch (JSONException e) {
|
||||
throw new IOException(e.toString());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// --- invocation
|
||||
|
||||
/**
|
||||
* Invokes API method using HTTP GET
|
||||
*
|
||||
* @param method API method to invoke
|
||||
* @param getParameters Name/Value pairs. Values will be URL encoded.
|
||||
* @return response object
|
||||
*/
|
||||
public JSONObject invoke(String method, Object... getParameters) throws IOException {
|
||||
return new JSONObject();
|
||||
}
|
||||
}
|
||||
@ -1,86 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2012 Todoroo Inc
|
||||
*
|
||||
* See the file "LICENSE" for the full license governing this code.
|
||||
*/
|
||||
package com.todoroo.astrid.actfm.sync;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.todoroo.andlib.service.Autowired;
|
||||
import com.todoroo.andlib.service.DependencyInjectionService;
|
||||
import com.todoroo.astrid.data.RemoteModel;
|
||||
import com.todoroo.astrid.data.User;
|
||||
import com.todoroo.astrid.service.TagDataService;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Service for synchronizing data on Astrid.com server with local.
|
||||
*
|
||||
* @author Tim Su <tim@todoroo.com>
|
||||
*/
|
||||
|
||||
public final class ActFmSyncService {
|
||||
|
||||
// --- instance variables
|
||||
|
||||
@Autowired
|
||||
private TagDataService tagDataService;
|
||||
@Autowired
|
||||
private ActFmPreferenceService actFmPreferenceService;
|
||||
@Autowired
|
||||
private ActFmInvoker actFmInvoker;
|
||||
|
||||
private String token;
|
||||
|
||||
public ActFmSyncService() {
|
||||
DependencyInjectionService.getInstance().inject(this);
|
||||
}
|
||||
|
||||
// --- generic invokation
|
||||
|
||||
/**
|
||||
* invoke authenticated method against the server
|
||||
*/
|
||||
public JSONObject invoke(String method, Object... getParameters) throws IOException {
|
||||
if (!checkForToken()) {
|
||||
throw new ActFmServiceException("not logged in", null);
|
||||
}
|
||||
Object[] parameters = new Object[getParameters.length + 2];
|
||||
parameters[0] = "token";
|
||||
parameters[1] = token;
|
||||
for (int i = 0; i < getParameters.length; i++) {
|
||||
parameters[i + 2] = getParameters[i];
|
||||
}
|
||||
return actFmInvoker.invoke(method, parameters);
|
||||
}
|
||||
|
||||
protected void handleException(String message, Exception exception) {
|
||||
Log.w("actfm-sync", message, exception);
|
||||
}
|
||||
|
||||
private boolean checkForToken() {
|
||||
return false;
|
||||
}
|
||||
|
||||
// --- json reader helper
|
||||
|
||||
/**
|
||||
* Read data models from JSON
|
||||
*/
|
||||
public static class JsonHelper {
|
||||
|
||||
public static void jsonFromUser(JSONObject json, User model) throws JSONException {
|
||||
json.put("id", model.getValue(User.UUID));
|
||||
json.put("name", model.getDisplayName());
|
||||
json.put("email", model.getValue(User.EMAIL));
|
||||
json.put("picture", model.getPictureUrl(User.PICTURE, RemoteModel.PICTURE_THUMB));
|
||||
json.put("first_name", model.getValue(User.FIRST_NAME));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,203 +1,19 @@
|
||||
package com.todoroo.astrid.actfm.sync.messages;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import com.todoroo.andlib.data.Property.IntegerProperty;
|
||||
import com.todoroo.andlib.data.Property.LongProperty;
|
||||
import com.todoroo.andlib.service.Autowired;
|
||||
import com.todoroo.andlib.service.DependencyInjectionService;
|
||||
import com.todoroo.astrid.actfm.sync.ActFmInvoker;
|
||||
import com.todoroo.astrid.actfm.sync.ActFmPreferenceService;
|
||||
import com.todoroo.astrid.actfm.sync.ActFmSyncThread.SyncMessageCallback;
|
||||
import com.todoroo.astrid.dao.HistoryDao;
|
||||
import com.todoroo.astrid.dao.RemoteModelDao;
|
||||
import com.todoroo.astrid.dao.UserDao;
|
||||
import com.todoroo.astrid.data.History;
|
||||
import com.todoroo.astrid.data.RemoteModel;
|
||||
import com.todoroo.astrid.data.Task;
|
||||
import com.todoroo.astrid.data.User;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
|
||||
public class FetchHistory<TYPE extends RemoteModel> {
|
||||
|
||||
private static final String ERROR_TAG = "actfm-fetch-history"; //$NON-NLS-1$
|
||||
|
||||
private final RemoteModelDao<TYPE> dao;
|
||||
private final LongProperty historyTimeProperty;
|
||||
private final IntegerProperty historyHasMoreProperty;
|
||||
private final String table;
|
||||
private final String uuid;
|
||||
private final String taskTitle;
|
||||
private final long modifiedAfter;
|
||||
private final int offset;
|
||||
private final SyncMessageCallback done;
|
||||
|
||||
@Autowired
|
||||
private ActFmInvoker actFmInvoker;
|
||||
|
||||
@Autowired
|
||||
private HistoryDao historyDao;
|
||||
|
||||
@Autowired
|
||||
private UserDao userDao;
|
||||
|
||||
@Autowired
|
||||
private ActFmPreferenceService actFmPreferenceService;
|
||||
|
||||
public FetchHistory(RemoteModelDao<TYPE> dao, LongProperty historyTimeProperty, IntegerProperty historyHasMoreProperty,
|
||||
String table, String uuid, String taskTitle, long modifiedAfter, int offset, SyncMessageCallback done) {
|
||||
DependencyInjectionService.getInstance().inject(this);
|
||||
this.dao = dao;
|
||||
this.historyTimeProperty = historyTimeProperty;
|
||||
this.historyHasMoreProperty = historyHasMoreProperty;
|
||||
this.table = table;
|
||||
this.uuid = uuid;
|
||||
this.taskTitle = taskTitle;
|
||||
this.modifiedAfter = modifiedAfter;
|
||||
this.offset = offset;
|
||||
this.done = done;
|
||||
}
|
||||
|
||||
|
||||
public void execute() {
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
String token = actFmPreferenceService.getToken();
|
||||
if (TextUtils.isEmpty(token) || TextUtils.isEmpty(uuid)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ArrayList<Object> params = new ArrayList<Object>();
|
||||
if (NameMaps.TABLE_ID_TASKS.equals(table)) {
|
||||
params.add("task_id");
|
||||
} else if (NameMaps.TABLE_ID_TAGS.equals(table)) {
|
||||
params.add("tag_id");
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
params.add(uuid);
|
||||
|
||||
if (modifiedAfter > 0) {
|
||||
params.add("modified_after");
|
||||
params.add(modifiedAfter / 1000L);
|
||||
}
|
||||
|
||||
if (offset > 0) {
|
||||
params.add("offset");
|
||||
params.add(offset);
|
||||
}
|
||||
|
||||
params.add("token");
|
||||
params.add(token);
|
||||
try {
|
||||
JSONObject result = actFmInvoker.invoke("model_history_list", params.toArray(new Object[params.size()]));
|
||||
JSONArray list = result.optJSONArray("list");
|
||||
boolean hasMore = result.optInt("has_more") > 0;
|
||||
long time = result.optLong("time") * 1000;
|
||||
if (hasMore && offset == 0) {
|
||||
historyDao.deleteWhere(History.TARGET_ID.eq(uuid));
|
||||
}
|
||||
if (list != null) {
|
||||
for (int i = 0; i < list.length(); i++) {
|
||||
JSONObject historyJson = list.optJSONObject(i);
|
||||
if (historyJson != null) {
|
||||
History history = new History();
|
||||
history.setValue(History.TABLE_ID, table);
|
||||
history.setValue(History.TARGET_ID, uuid);
|
||||
history.setValue(History.UUID, historyJson.optString("id") + ":" + uuid);
|
||||
|
||||
String userId = historyJson.optString("user_id");
|
||||
if (userId.equals(ActFmPreferenceService.userId())) {
|
||||
userId = Task.USER_ID_SELF;
|
||||
}
|
||||
history.setValue(History.USER_UUID, historyJson.optString("user_id"));
|
||||
history.setValue(History.COLUMN, historyJson.optString("column"));
|
||||
history.setValue(History.OLD_VALUE, historyJson.optString("prev"));
|
||||
history.setValue(History.NEW_VALUE, historyJson.optString("value"));
|
||||
history.setValue(History.CREATED_AT, historyJson.optLong("created_at") * 1000);
|
||||
|
||||
JSONArray taskObj = historyJson.optJSONArray("task");
|
||||
if (taskObj != null) {
|
||||
history.setValue(History.TABLE_ID, NameMaps.TABLE_ID_TASKS);
|
||||
history.setValue(History.TARGET_ID, taskObj.optString(0));
|
||||
history.setValue(History.TASK, taskObj.toString());
|
||||
} else if (NameMaps.TABLE_ID_TASKS.equals(table) && !TextUtils.isEmpty(taskTitle)) {
|
||||
taskObj = new JSONArray();
|
||||
taskObj.put(uuid);
|
||||
taskObj.put(taskTitle);
|
||||
history.setValue(History.TASK, taskObj.toString());
|
||||
}
|
||||
|
||||
if (NameMaps.TABLE_ID_TAGS.equals(table)) {
|
||||
history.setValue(History.TAG_ID, uuid);
|
||||
}
|
||||
|
||||
if (historyDao.update(History.UUID.eq(history.getValue(History.UUID)), history) <= 0) {
|
||||
historyDao.createNew(history);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (time > 0) {
|
||||
TYPE template;
|
||||
try {
|
||||
template = dao.getModelClass().newInstance();
|
||||
template.setValue(historyTimeProperty, time);
|
||||
if (modifiedAfter == 0 || hasMore) {
|
||||
template.setValue(historyHasMoreProperty, hasMore ? 1 : 0);
|
||||
}
|
||||
dao.update(RemoteModel.UUID_PROPERTY.eq(uuid), template);
|
||||
} catch (InstantiationException e) {
|
||||
Log.e(ERROR_TAG, "Error instantiating model for recording time", e);
|
||||
} catch (IllegalAccessException e) {
|
||||
Log.e(ERROR_TAG, "Error instantiating model for recording time", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JSONObject users = result.optJSONObject("users");
|
||||
if (users != null) {
|
||||
Iterator<String> keys = users.keys();
|
||||
while (keys.hasNext()) {
|
||||
String key = keys.next();
|
||||
JSONObject userObj = users.optJSONObject(key);
|
||||
if (userObj != null) {
|
||||
String userUuid = userObj.optString("id");
|
||||
if (RemoteModel.isUuidEmpty(uuid)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
User user = new User();
|
||||
user.setValue(User.FIRST_NAME, userObj.optString("first_name"));
|
||||
user.setValue(User.LAST_NAME, userObj.optString("last_name"));
|
||||
user.setValue(User.NAME, userObj.optString("name"));
|
||||
user.setValue(User.PICTURE, userObj.optString("picture"));
|
||||
user.setValue(User.UUID, userUuid);
|
||||
|
||||
if (userDao.update(User.UUID.eq(userUuid), user) <= 0) {
|
||||
userDao.createNew(user);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
Log.e(ERROR_TAG, "Error getting model history", e);
|
||||
}
|
||||
|
||||
if (done != null) {
|
||||
done.runOnSuccess();
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,167 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2012 Todoroo Inc
|
||||
*
|
||||
* See the file "LICENSE" for the full license governing this code.
|
||||
*/
|
||||
package com.todoroo.astrid.sync.repeats;
|
||||
|
||||
import com.google.ical.values.Frequency;
|
||||
import com.google.ical.values.RRule;
|
||||
import org.astrid.R;
|
||||
import com.todoroo.andlib.data.TodorooCursor;
|
||||
import com.todoroo.andlib.service.Autowired;
|
||||
import com.todoroo.andlib.sql.Query;
|
||||
import com.todoroo.andlib.utility.AndroidUtilities;
|
||||
import com.todoroo.andlib.utility.DateUtilities;
|
||||
import com.todoroo.andlib.utility.Preferences;
|
||||
import com.todoroo.astrid.actfm.sync.ActFmInvoker;
|
||||
import com.todoroo.astrid.actfm.sync.ActFmPreferenceService;
|
||||
import com.todoroo.astrid.actfm.sync.ActFmSyncService;
|
||||
import com.todoroo.astrid.actfm.sync.ActFmSyncV2Provider;
|
||||
import com.todoroo.astrid.dao.TaskDao.TaskCriteria;
|
||||
import com.todoroo.astrid.data.Task;
|
||||
import com.todoroo.astrid.service.MetadataService;
|
||||
import com.todoroo.astrid.sync.SyncResultCallbackAdapter;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.Semaphore;
|
||||
|
||||
public class RepeatTestsActFmSync extends AbstractSyncRepeatTests<Task> {
|
||||
|
||||
@Autowired
|
||||
MetadataService metadataService;
|
||||
@Autowired
|
||||
ActFmSyncService actFmSyncService;
|
||||
@Autowired
|
||||
ActFmPreferenceService actFmPreferenceService;
|
||||
protected static ActFmInvoker invoker = null;
|
||||
|
||||
private static final String TEST_ACCOUNT = "sync_tester2@astrid.com";
|
||||
private static final String TEST_PASSWORD = "wonkwonkjj";
|
||||
private static boolean initialized = false;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
Preferences.setStringFromInteger(R.string.p_default_urgency_key, 0);
|
||||
|
||||
if (!initialized) {
|
||||
initializeTestService();
|
||||
}
|
||||
|
||||
clearTasks();
|
||||
}
|
||||
|
||||
private void initializeTestService() throws Exception {
|
||||
invoker = new ActFmInvoker();
|
||||
authenticate(TEST_ACCOUNT, null, null, ActFmInvoker.PROVIDER_PASSWORD, TEST_PASSWORD);
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
private void clearTasks() throws Exception {
|
||||
}
|
||||
|
||||
private void authenticate(String email, String firstName, String lastName, String provider, String secret) {
|
||||
try {
|
||||
JSONObject result = invoker.authenticate(email, firstName, lastName, provider, secret);
|
||||
String token = invoker.getToken();
|
||||
postAuthenticate(result, token);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
fail("Error authenticating");
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("nls")
|
||||
private void postAuthenticate(JSONObject result, String token) {
|
||||
actFmPreferenceService.setToken(token);
|
||||
|
||||
Preferences.setString(ActFmPreferenceService.PREF_USER_ID,
|
||||
Long.toString(result.optLong("id")));
|
||||
Preferences.setString(ActFmPreferenceService.PREF_NAME, result.optString("name"));
|
||||
Preferences.setString(ActFmPreferenceService.PREF_EMAIL, result.optString("email"));
|
||||
Preferences.setString(ActFmPreferenceService.PREF_PICTURE, result.optString("picture"));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void waitAndSync() {
|
||||
AndroidUtilities.sleepDeep(3000L);
|
||||
final Semaphore sema = new Semaphore(0);
|
||||
new ActFmSyncV2Provider().synchronizeActiveTasks(true, new SyncResultCallbackAdapter() {
|
||||
@Override
|
||||
public void finished() {
|
||||
sema.release();
|
||||
}
|
||||
});
|
||||
try {
|
||||
sema.acquire();
|
||||
} catch (InterruptedException e) {
|
||||
fail("Interrupted while waiting for sync to finish");
|
||||
}
|
||||
AndroidUtilities.sleepDeep(3000L);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param t
|
||||
* @param expectedDueDate
|
||||
*/
|
||||
@Override
|
||||
protected Task assertTaskExistsRemotely(Task t, long expectedDueDate) {
|
||||
return null; //remote;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void testRepeating(boolean completeBefore, boolean fromCompletion, RRule rrule, Frequency frequency, String title) {
|
||||
Task t = new Task();
|
||||
t.setValue(Task.TITLE, title);
|
||||
long dueDate = DateUtilities.now() + ((completeBefore ? -1 : 1) * DateUtilities.ONE_DAY * 3);
|
||||
dueDate = Task.createDueDate(Task.URGENCY_SPECIFIC_DAY_TIME, (dueDate / 1000L) * 1000L); // Strip milliseconds
|
||||
|
||||
t.setValue(Task.DUE_DATE, dueDate);
|
||||
|
||||
if (rrule == null) {
|
||||
rrule = new RRule();
|
||||
rrule.setFreq(frequency);
|
||||
int interval = 5;
|
||||
rrule.setInterval(interval);
|
||||
}
|
||||
|
||||
String result = rrule.toIcal();
|
||||
if (fromCompletion)
|
||||
result = result + ";FROM=COMPLETION";
|
||||
|
||||
t.setValue(Task.RECURRENCE, rrule.toIcal());
|
||||
taskDao.save(t);
|
||||
|
||||
waitAndSync();
|
||||
t = taskDao.fetch(t.getId(), Task.PROPERTIES); // Refetch
|
||||
Task remoteModel = assertTaskExistsRemotely(t, dueDate);
|
||||
|
||||
long completionDate = setCompletionDate(completeBefore, t, remoteModel, dueDate);
|
||||
|
||||
waitAndSync();
|
||||
|
||||
TodorooCursor<Task> cursor = taskDao.query(Query.select(Task.PROPERTIES).where(TaskCriteria.notDeleted()));
|
||||
try {
|
||||
assertEquals(1, cursor.getCount());
|
||||
cursor.moveToFirst();
|
||||
t.readFromCursor(cursor);
|
||||
|
||||
long fromDate = (fromCompletion ? completionDate : dueDate);
|
||||
long expectedTime = computeNextDueDateFromDate(fromDate, rrule, fromCompletion);
|
||||
long newDueDate = t.getValue(Task.DUE_DATE);
|
||||
|
||||
assertTaskExistsRemotely(t, expectedTime);
|
||||
assertTrue(t.hasDueTime());
|
||||
assertEquals(title, t.getValue(Task.TITLE));
|
||||
assertTimesMatch(expectedTime, newDueDate);
|
||||
assertFalse(t.isCompleted());
|
||||
|
||||
} finally {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,34 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2012 Todoroo Inc
|
||||
*
|
||||
* See the file "LICENSE" for the full license governing this code.
|
||||
*/
|
||||
package com.todoroo.astrid.sync.repeats;
|
||||
|
||||
import com.todoroo.andlib.utility.DateUtilities;
|
||||
import com.todoroo.astrid.data.Task;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class RepeatTestsActFmSyncRemote extends RepeatTestsActFmSync {
|
||||
@Override
|
||||
protected long setCompletionDate(boolean completeBefore, Task t,
|
||||
Task remoteModel, long dueDate) {
|
||||
long completionDate = DateUtilities.now();
|
||||
|
||||
ArrayList<Object> params = new ArrayList<Object>();
|
||||
params.add("completed");
|
||||
params.add(completionDate / 1000L);
|
||||
|
||||
params.add("id");
|
||||
params.add(remoteModel.getValue(Task.UUID));
|
||||
try {
|
||||
invoker.invoke("task_save", params.toArray(new Object[params.size()]));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
fail("Error in actfm invoker");
|
||||
}
|
||||
return completionDate;
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue