wip for todoist -> habitica syncing process

This commit is contained in:
2020-03-22 15:18:43 -04:00
parent 20bf4fe93f
commit d994d92d34
11 changed files with 131 additions and 12 deletions

View File

@@ -5,11 +5,11 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Azure.Cosmos.Table" Version="1.0.6" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Habitica.Todoist.Integration.Data\Habitica.Todoist.Integration.Data.csproj" />
<ProjectReference Include="..\Habitica.Todoist.Integration.Model\Habitica.Todoist.Integration.Model.csproj" />
</ItemGroup>

View File

@@ -1,76 +0,0 @@
using Habitica.Todoist.Integration.Model.Storage;
using Microsoft.Azure.Cosmos.Table;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Habitica.Todoist.Integration.Services
{
public class TableStorageClient
{
private CloudStorageAccount storageAccount { get; set; }
private CloudTableClient tableClient { get; set; }
/* TODO: change this so it reads from classes available instead of hardcoding */
private static List<string> tableNames = new List<string>()
{
"habittodolink",
"todohabitlink",
"todochange",
"todoistsync"
};
private Dictionary<string, CloudTable> tables = new Dictionary<string, CloudTable>();
public TableStorageClient(string connectionString)
{
storageAccount = CloudStorageAccount.Parse(connectionString);
tableClient = storageAccount.CreateCloudTableClient(new TableClientConfiguration());
// initialize all tables to use
foreach (var tableName in tableNames)
{
var table = tableClient.GetTableReference(tableName);
table.CreateIfNotExists();
tables[tableName] = table;
}
}
public async Task<T> InsertOrUpdate<T>(T entity) where T : TableEntity, new()
{
var tableName = typeof(T).Name.ToLower();
var table = tables[tableName];
var operation = TableOperation.InsertOrReplace(entity); // TODO: InsertOrReplace vs InsertOrMerge
var result = await table.ExecuteAsync(operation);
return result.Result as T;
}
public async Task<bool> ExistsAsync<T>(string partitionKey, string rowKey) where T : TableEntity, new()
{
var tableName = typeof(T).Name.ToLower();
var table = tables[tableName];
var operation = TableOperation.Retrieve(partitionKey, rowKey);
var result = await table.ExecuteAsync(operation);
return result.Result != null;
}
public bool Exists<T>(string partitionKey, string rowKey) where T : TableEntity, new()
{
return Query<T>().Where(x => x.PartitionKey == partitionKey && x.RowKey == rowKey).ToList().Any();
}
public TableQuery<T> Query<T>() where T : TableEntity, new()
{
var tableName = typeof(T).Name.ToLower();
var table = tables[tableName];
return table.CreateQuery<T>();
}
}
}

View File

@@ -0,0 +1,41 @@
using Habitica.Todoist.Integration.Data;
using Habitica.Todoist.Integration.Model.Storage;
using Habitica.Todoist.Integration.Model.Todoist;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Habitica.Todoist.Integration.Services
{
public static class TodoistExtensions
{
public static IEnumerable<Item> WhereAdded(this List<Item> items, TableStorageClient storageClient, string userId)
{
return items
.Where(x => !storageClient
.Exists<TodoHabitLink>(userId, x.Id) && x.Is_deleted == 0);
}
public static IEnumerable<Item> WhereUpdated(this List<Item> items, TableStorageClient storageClient, string userId)
{
return items
.Where(x => storageClient
.Exists<TodoHabitLink>(userId, x.Id) && x.Is_deleted == 0 && x.Date_completed == null);
}
public static IEnumerable<Item> WhereCompleted(this List<Item> items, TableStorageClient storageClient, string userId)
{
return items
.Where(x => storageClient
.Exists<TodoHabitLink>(userId, x.Id) && x.Is_deleted == 0 && x.Date_completed != null);
}
public static IEnumerable<Item> WhereDeleted(this List<Item> items, TableStorageClient storageClient, string userId)
{
return items
.Where(x => storageClient
.Exists<TodoHabitLink>(userId, x.Id) && x.Is_deleted == 1);
}
}
}

View File

@@ -0,0 +1,55 @@
using Habitica.Todoist.Integration.Data;
using Habitica.Todoist.Integration.Model.Storage;
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using Habitica.Todoist.Integration.Model.Todoist;
using System.Threading.Tasks;
namespace Habitica.Todoist.Integration.Services
{
public class TodoistIntegrationService
{
private TodoistServiceClient todoistClient { get; set; }
private TableStorageClient storageClient { get; set; }
private string userId { get; set; }
private string latestSyncToken { get; set; } = string.Empty;
public TodoistIntegrationService(TodoistServiceClient todoistClient,
TableStorageClient storageClient,
string userId)
{
this.todoistClient = todoistClient;
this.storageClient = storageClient;
this.userId = userId;
}
public async Task<List<Item>> ReadItemChanges()
{
var response = await todoistClient.GetItemChanges(ReadLatestSyncToken());
return response.Items;
}
public async Task CommitRead()
{
await storageClient.InsertOrUpdate(new TodoistSync(userId, latestSyncToken));
}
private string ReadLatestSyncToken()
{
try
{
latestSyncToken = storageClient.Query<TodoistSync>()
.Where(x => x.PartitionKey == userId)
.ToList()
.OrderByDescending(x => x.Timestamp)
.First().RowKey;
}
catch { }
return latestSyncToken;
}
}
}

View File

@@ -19,7 +19,7 @@ namespace Habitica.Todoist.Integration.Services
this.apiKey = apiKey;
}
public async Task<SyncResponse> GetChangedItems(string syncToken = null)
public async Task<SyncResponse> GetItemChanges(string syncToken = null)
{
if (string.IsNullOrEmpty(syncToken))
syncToken = "*";