Convert GtasksInvoker to Kotlin

pull/1051/head
Alex Baker 4 years ago
parent 90571eca35
commit b7b8d1667b

@ -1,198 +0,0 @@
package com.todoroo.astrid.gtasks.api;
import android.content.Context;
import androidx.annotation.Nullable;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpResponseException;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.GenericJson;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.tasks.Tasks;
import com.google.api.services.tasks.TasksRequest;
import com.google.api.services.tasks.TasksScopes;
import com.google.api.services.tasks.model.Task;
import com.google.api.services.tasks.model.TaskList;
import com.google.api.services.tasks.model.TaskLists;
import dagger.hilt.android.qualifiers.ApplicationContext;
import java.io.IOException;
import javax.inject.Inject;
import org.tasks.BuildConfig;
import org.tasks.DebugNetworkInterceptor;
import org.tasks.gtasks.GoogleAccountManager;
import org.tasks.preferences.Preferences;
import timber.log.Timber;
/**
* Wrapper around the official Google Tasks API to simplify common operations. In the case of an
* exception, each request is tried twice in case of a timeout.
*
* @author Sam Bosley
*/
public class GtasksInvoker {
private final Context context;
private final GoogleAccountManager googleAccountManager;
private final Preferences preferences;
private final DebugNetworkInterceptor interceptor;
private final String account;
private final Tasks service;
private final HttpCredentialsAdapter credentialsAdapter;
@Inject
public GtasksInvoker(
@ApplicationContext Context context,
GoogleAccountManager googleAccountManager,
Preferences preferences,
DebugNetworkInterceptor interceptor) {
this.context = context;
this.googleAccountManager = googleAccountManager;
this.preferences = preferences;
this.interceptor = interceptor;
account = null;
service = null;
credentialsAdapter = null;
}
private GtasksInvoker(
Context context,
GoogleAccountManager googleAccountManager,
Preferences preferences,
DebugNetworkInterceptor interceptor,
String account) {
this.context = context;
this.googleAccountManager = googleAccountManager;
this.preferences = preferences;
this.interceptor = interceptor;
this.account = account;
credentialsAdapter = new HttpCredentialsAdapter(googleAccountManager);
service =
new Tasks.Builder(new NetHttpTransport(), new JacksonFactory(), credentialsAdapter)
.setApplicationName(String.format("Tasks/%s", BuildConfig.VERSION_NAME))
.build();
}
public GtasksInvoker forAccount(String account) {
return new GtasksInvoker(context, googleAccountManager, preferences, interceptor, account);
}
public @Nullable TaskLists allGtaskLists(@Nullable String pageToken) throws IOException {
return execute(service.tasklists().list().setMaxResults(100L).setPageToken(pageToken));
}
public @Nullable com.google.api.services.tasks.model.Tasks getAllGtasksFromListId(
String listId, long lastSyncDate, @Nullable String pageToken) throws IOException {
return execute(
service
.tasks()
.list(listId)
.setMaxResults(100L)
.setShowDeleted(true)
.setShowHidden(true)
.setPageToken(pageToken)
.setUpdatedMin(
GtasksApiUtilities.unixTimeToGtasksCompletionTime(lastSyncDate).toStringRfc3339()));
}
public com.google.api.services.tasks.model.Tasks getAllPositions(
String listId, @Nullable String pageToken) throws IOException {
return execute(
service
.tasks()
.list(listId)
.setMaxResults(100L)
.setShowDeleted(false)
.setShowHidden(false)
.setPageToken(pageToken)
.setFields("items(id,parent,position),nextPageToken"));
}
public @Nullable Task createGtask(
String listId, Task task, @Nullable String parent, @Nullable String previous)
throws IOException {
return execute(service.tasks().insert(listId, task).setParent(parent).setPrevious(previous));
}
public void updateGtask(String listId, Task task) throws IOException {
execute(service.tasks().update(listId, task.getId(), task));
}
@Nullable
public Task moveGtask(String listId, String taskId, String parentId, String previousId)
throws IOException {
return execute(
service.tasks().move(listId, taskId).setParent(parentId).setPrevious(previousId));
}
public void deleteGtaskList(String listId) throws IOException {
try {
execute(service.tasklists().delete(listId));
} catch (HttpNotFoundException ignored) {
}
}
public @Nullable TaskList renameGtaskList(String listId, String title) throws IOException {
return execute(service.tasklists().patch(listId, new TaskList().setTitle(title)));
}
public @Nullable TaskList createGtaskList(String title) throws IOException {
return execute(service.tasklists().insert(new TaskList().setTitle(title)));
}
public void deleteGtask(String listId, String taskId) throws IOException {
try {
execute(service.tasks().delete(listId, taskId));
} catch (HttpNotFoundException ignored) {
}
}
private synchronized @Nullable <T> T execute(TasksRequest<T> request) throws IOException {
return execute(request, false);
}
private synchronized @Nullable <T> T execute(TasksRequest<T> request, boolean retry)
throws IOException {
credentialsAdapter.checkToken(account, TasksScopes.TASKS);
T response;
try {
HttpRequest httpRequest = request.buildHttpRequest();
Timber.d("%s", httpRequest.getUrl());
if (preferences.isFlipperEnabled()) {
response = interceptor.execute(httpRequest, request.getResponseClass());
} else {
response = httpRequest.execute().parseAs(request.getResponseClass());
}
} catch (HttpResponseException e) {
if (e.getStatusCode() == 401 && !retry) {
credentialsAdapter.invalidateToken();
return execute(request, true);
} else if (e.getStatusCode() == 404) {
throw new HttpNotFoundException(e);
} else {
throw e;
}
}
Timber.d("%s response: %s", getCaller(retry), prettyPrint(response));
return response;
}
private <T> Object prettyPrint(T object) throws IOException {
if (BuildConfig.DEBUG) {
if (object instanceof GenericJson) {
return ((GenericJson) object).toPrettyString();
}
}
return object;
}
private String getCaller(boolean retry) {
if (BuildConfig.DEBUG) {
try {
return Thread.currentThread().getStackTrace()[retry ? 6 : 5].getMethodName();
} catch (Exception e) {
Timber.e(e);
}
}
return "";
}
}

@ -0,0 +1,204 @@
package com.todoroo.astrid.gtasks.api
import android.content.Context
import com.google.api.client.http.HttpResponseException
import com.google.api.client.http.javanet.NetHttpTransport
import com.google.api.client.json.GenericJson
import com.google.api.client.json.jackson2.JacksonFactory
import com.google.api.services.tasks.Tasks
import com.google.api.services.tasks.TasksRequest
import com.google.api.services.tasks.TasksScopes
import com.google.api.services.tasks.model.Task
import com.google.api.services.tasks.model.TaskList
import com.google.api.services.tasks.model.TaskLists
import dagger.hilt.android.qualifiers.ApplicationContext
import org.tasks.BuildConfig
import org.tasks.DebugNetworkInterceptor
import org.tasks.gtasks.GoogleAccountManager
import org.tasks.preferences.Preferences
import timber.log.Timber
import java.io.IOException
import javax.inject.Inject
/**
* Wrapper around the official Google Tasks API to simplify common operations. In the case of an
* exception, each request is tried twice in case of a timeout.
*
* @author Sam Bosley
*/
class GtasksInvoker {
private val context: Context
private val googleAccountManager: GoogleAccountManager
private val preferences: Preferences
private val interceptor: DebugNetworkInterceptor
private val account: String?
private val service: Tasks?
private val credentialsAdapter: HttpCredentialsAdapter?
@Inject
constructor(
@ApplicationContext context: Context,
googleAccountManager: GoogleAccountManager,
preferences: Preferences,
interceptor: DebugNetworkInterceptor) {
this.context = context
this.googleAccountManager = googleAccountManager
this.preferences = preferences
this.interceptor = interceptor
account = null
service = null
credentialsAdapter = null
}
private constructor(
context: Context,
googleAccountManager: GoogleAccountManager,
preferences: Preferences,
interceptor: DebugNetworkInterceptor,
account: String) {
this.context = context
this.googleAccountManager = googleAccountManager
this.preferences = preferences
this.interceptor = interceptor
this.account = account
credentialsAdapter = HttpCredentialsAdapter(googleAccountManager)
service = Tasks.Builder(NetHttpTransport(), JacksonFactory(), credentialsAdapter)
.setApplicationName(String.format("Tasks/%s", BuildConfig.VERSION_NAME))
.build()
}
fun forAccount(account: String): GtasksInvoker {
return GtasksInvoker(context, googleAccountManager, preferences, interceptor, account)
}
@Throws(IOException::class)
fun allGtaskLists(pageToken: String?): TaskLists? {
return execute(service!!.tasklists().list().setMaxResults(100L).setPageToken(pageToken))
}
@Throws(IOException::class)
fun getAllGtasksFromListId(
listId: String?, lastSyncDate: Long, pageToken: String?): com.google.api.services.tasks.model.Tasks? {
return execute(
service!!
.tasks()
.list(listId)
.setMaxResults(100L)
.setShowDeleted(true)
.setShowHidden(true)
.setPageToken(pageToken)
.setUpdatedMin(
GtasksApiUtilities.unixTimeToGtasksCompletionTime(lastSyncDate).toStringRfc3339()))
}
@Throws(IOException::class)
fun getAllPositions(
listId: String?, pageToken: String?): com.google.api.services.tasks.model.Tasks {
return execute(
service!!
.tasks()
.list(listId)
.setMaxResults(100L)
.setShowDeleted(false)
.setShowHidden(false)
.setPageToken(pageToken)
.setFields("items(id,parent,position),nextPageToken"))!!
}
@Throws(IOException::class)
fun createGtask(
listId: String?, task: Task?, parent: String?, previous: String?): Task? {
return execute(service!!.tasks().insert(listId, task).setParent(parent).setPrevious(previous))
}
@Throws(IOException::class)
fun updateGtask(listId: String?, task: Task) {
execute(service!!.tasks().update(listId, task.id, task))
}
@Throws(IOException::class)
fun moveGtask(listId: String?, taskId: String?, parentId: String?, previousId: String?): Task? {
return execute(
service!!.tasks().move(listId, taskId).setParent(parentId).setPrevious(previousId))
}
@Throws(IOException::class)
fun deleteGtaskList(listId: String?) {
try {
execute(service!!.tasklists().delete(listId))
} catch (ignored: HttpNotFoundException) {
}
}
@Throws(IOException::class)
fun renameGtaskList(listId: String?, title: String?): TaskList? {
return execute(service!!.tasklists().patch(listId, TaskList().setTitle(title)))
}
@Throws(IOException::class)
fun createGtaskList(title: String?): TaskList? {
return execute(service!!.tasklists().insert(TaskList().setTitle(title)))
}
@Throws(IOException::class)
fun deleteGtask(listId: String?, taskId: String?) {
try {
execute(service!!.tasks().delete(listId, taskId))
} catch (ignored: HttpNotFoundException) {
}
}
@Synchronized
@Throws(IOException::class)
private fun <T> execute(request: TasksRequest<T>): T? {
return execute(request, false)
}
@Synchronized
@Throws(IOException::class)
private fun <T> execute(request: TasksRequest<T>, retry: Boolean): T? {
credentialsAdapter!!.checkToken(account, TasksScopes.TASKS)
val response: T?
response = try {
val httpRequest = request.buildHttpRequest()
Timber.d("%s", httpRequest.url)
if (preferences.isFlipperEnabled) {
interceptor.execute(httpRequest, request.responseClass)
} else {
httpRequest.execute().parseAs(request.responseClass)
}
} catch (e: HttpResponseException) {
return if (e.statusCode == 401 && !retry) {
credentialsAdapter.invalidateToken()
execute(request, true)
} else if (e.statusCode == 404) {
throw HttpNotFoundException(e)
} else {
throw e
}
}
Timber.d("%s response: %s", getCaller(retry), prettyPrint(response))
return response
}
@Throws(IOException::class)
private fun <T> prettyPrint(`object`: T?): Any? {
if (BuildConfig.DEBUG) {
if (`object` is GenericJson) {
return (`object` as GenericJson).toPrettyString()
}
}
return `object`
}
private fun getCaller(retry: Boolean): String {
if (BuildConfig.DEBUG) {
try {
return Thread.currentThread().stackTrace[if (retry) 6 else 5].methodName
} catch (e: Exception) {
Timber.e(e)
}
}
return ""
}
}
Loading…
Cancel
Save