mirror of https://github.com/tasks/tasks
Convert GtasksInvoker to Kotlin
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…
Reference in New Issue