From d994d92d3462495ceb9c66d09315b186e71c3751 Mon Sep 17 00:00:00 2001 From: Giovani Date: Sun, 22 Mar 2020 15:18:43 -0400 Subject: [PATCH] wip for todoist -> habitica syncing process --- ...abitica.Todoist.Integration.Console.csproj | 4 ++ .../Program.cs | 5 +- .../Habitica.Todoist.Integration.Data.csproj | 11 ++++ .../TableStorageClient.cs | 5 +- ...a.Todoist.Integration.Function.Sync.csproj | 1 + ...ncFunction.cs => ScheduledSyncFunction.cs} | 9 +-- ...bitica.Todoist.Integration.Services.csproj | 2 +- .../TodoistExtensions.cs | 41 ++++++++++++++ .../TodoistIntegrationService.cs | 55 +++++++++++++++++++ .../TodoistServiceClient.cs | 2 +- Habitica.Todoist.Integration.sln | 8 ++- 11 files changed, 131 insertions(+), 12 deletions(-) create mode 100644 Habitica.Todoist.Integration.Data/Habitica.Todoist.Integration.Data.csproj rename {Habitica.Todoist.Integration.Services => Habitica.Todoist.Integration.Data}/TableStorageClient.cs (94%) rename Habitica.Todoist.Integration.Function.Sync/{SyncFunction.cs => ScheduledSyncFunction.cs} (94%) create mode 100644 Habitica.Todoist.Integration.Services/TodoistExtensions.cs create mode 100644 Habitica.Todoist.Integration.Services/TodoistIntegrationService.cs diff --git a/Habitica.Todoist.Integration.Console/Habitica.Todoist.Integration.Console.csproj b/Habitica.Todoist.Integration.Console/Habitica.Todoist.Integration.Console.csproj index 8c6bf24..9790656 100644 --- a/Habitica.Todoist.Integration.Console/Habitica.Todoist.Integration.Console.csproj +++ b/Habitica.Todoist.Integration.Console/Habitica.Todoist.Integration.Console.csproj @@ -313,6 +313,10 @@ + + {08055C1C-7581-4E74-97BB-C5D56E0CA3D8} + Habitica.Todoist.Integration.Data + {1EDCF34E-E1B1-4F82-AEC7-90C35A267967} Habitica.Todoist.Integration.Model diff --git a/Habitica.Todoist.Integration.Console/Program.cs b/Habitica.Todoist.Integration.Console/Program.cs index 0ae9661..0c0dcf7 100644 --- a/Habitica.Todoist.Integration.Console/Program.cs +++ b/Habitica.Todoist.Integration.Console/Program.cs @@ -1,4 +1,5 @@ -using Habitica.Todoist.Integration.Model.Habitica; +using Habitica.Todoist.Integration.Data; +using Habitica.Todoist.Integration.Model.Habitica; using Habitica.Todoist.Integration.Model.Habitica.Enums; using Habitica.Todoist.Integration.Model.Storage; using Habitica.Todoist.Integration.Model.Todoist; @@ -40,7 +41,7 @@ namespace Habitica.Todoist.Integration.Console .OrderByDescending(x => x.Timestamp).First().RowKey; } catch { } // get all changed items from todoist - var response = todoistClient.GetChangedItems(syncToken).ConfigureAwait(false).GetAwaiter().GetResult(); + var response = todoistClient.GetItemChanges(syncToken).ConfigureAwait(false).GetAwaiter().GetResult(); var changedItems = response.Items; /* TESTING */ diff --git a/Habitica.Todoist.Integration.Data/Habitica.Todoist.Integration.Data.csproj b/Habitica.Todoist.Integration.Data/Habitica.Todoist.Integration.Data.csproj new file mode 100644 index 0000000..6a513ba --- /dev/null +++ b/Habitica.Todoist.Integration.Data/Habitica.Todoist.Integration.Data.csproj @@ -0,0 +1,11 @@ + + + + netstandard2.0 + + + + + + + diff --git a/Habitica.Todoist.Integration.Services/TableStorageClient.cs b/Habitica.Todoist.Integration.Data/TableStorageClient.cs similarity index 94% rename from Habitica.Todoist.Integration.Services/TableStorageClient.cs rename to Habitica.Todoist.Integration.Data/TableStorageClient.cs index d1de43c..3fbb069 100644 --- a/Habitica.Todoist.Integration.Services/TableStorageClient.cs +++ b/Habitica.Todoist.Integration.Data/TableStorageClient.cs @@ -1,12 +1,11 @@ -using Habitica.Todoist.Integration.Model.Storage; -using Microsoft.Azure.Cosmos.Table; +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 +namespace Habitica.Todoist.Integration.Data { public class TableStorageClient { diff --git a/Habitica.Todoist.Integration.Function.Sync/Habitica.Todoist.Integration.Function.Sync.csproj b/Habitica.Todoist.Integration.Function.Sync/Habitica.Todoist.Integration.Function.Sync.csproj index 688f7f7..d86f0b3 100644 --- a/Habitica.Todoist.Integration.Function.Sync/Habitica.Todoist.Integration.Function.Sync.csproj +++ b/Habitica.Todoist.Integration.Function.Sync/Habitica.Todoist.Integration.Function.Sync.csproj @@ -7,6 +7,7 @@ + diff --git a/Habitica.Todoist.Integration.Function.Sync/SyncFunction.cs b/Habitica.Todoist.Integration.Function.Sync/ScheduledSyncFunction.cs similarity index 94% rename from Habitica.Todoist.Integration.Function.Sync/SyncFunction.cs rename to Habitica.Todoist.Integration.Function.Sync/ScheduledSyncFunction.cs index 4467db8..f2fe240 100644 --- a/Habitica.Todoist.Integration.Function.Sync/SyncFunction.cs +++ b/Habitica.Todoist.Integration.Function.Sync/ScheduledSyncFunction.cs @@ -2,6 +2,7 @@ using System; using System.IO; using System.Linq; using System.Threading.Tasks; +using Habitica.Todoist.Integration.Data; using Habitica.Todoist.Integration.Model.Habitica.Enums; using Habitica.Todoist.Integration.Model.Storage; using Habitica.Todoist.Integration.Model.Todoist; @@ -14,7 +15,7 @@ using HabiticaTask = Habitica.Todoist.Integration.Model.Habitica.Task; namespace Habitica.Todoist.Integration.Function.Sync { - public static class SyncFunction + public static class ScheduledSyncFunction { private static IConfiguration configuration { get; set; } private static string habiticaUserId => configuration["habiticaUserId"]; @@ -24,8 +25,8 @@ namespace Habitica.Todoist.Integration.Function.Sync private static string giosUserId => "0b6ec4eb-8878-4b9e-8585-7673764a6541"; [Singleton] - [FunctionName("SyncFunction")] - public static async Task Run([TimerTrigger("0 */2 * * * *")]TimerInfo myTimer, ILogger log) + [FunctionName("ScheduledSyncFunction")] + public static async Task Run([TimerTrigger("0 */30 * * * *")]TimerInfo myTimer, ILogger log) { BuildConfig(); @@ -47,7 +48,7 @@ namespace Habitica.Todoist.Integration.Function.Sync catch { } // get all changed items from todoist - var response = await todoistClient.GetChangedItems(syncToken); + var response = await todoistClient.GetItemChanges(syncToken); var changedItems = response.Items; // filter out items by actions diff --git a/Habitica.Todoist.Integration.Services/Habitica.Todoist.Integration.Services.csproj b/Habitica.Todoist.Integration.Services/Habitica.Todoist.Integration.Services.csproj index 2ac2fc5..7e9feba 100644 --- a/Habitica.Todoist.Integration.Services/Habitica.Todoist.Integration.Services.csproj +++ b/Habitica.Todoist.Integration.Services/Habitica.Todoist.Integration.Services.csproj @@ -5,11 +5,11 @@ - + diff --git a/Habitica.Todoist.Integration.Services/TodoistExtensions.cs b/Habitica.Todoist.Integration.Services/TodoistExtensions.cs new file mode 100644 index 0000000..526fdcd --- /dev/null +++ b/Habitica.Todoist.Integration.Services/TodoistExtensions.cs @@ -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 WhereAdded(this List items, TableStorageClient storageClient, string userId) + { + return items + .Where(x => !storageClient + .Exists(userId, x.Id) && x.Is_deleted == 0); + } + + public static IEnumerable WhereUpdated(this List items, TableStorageClient storageClient, string userId) + { + return items + .Where(x => storageClient + .Exists(userId, x.Id) && x.Is_deleted == 0 && x.Date_completed == null); + } + + public static IEnumerable WhereCompleted(this List items, TableStorageClient storageClient, string userId) + { + return items + .Where(x => storageClient + .Exists(userId, x.Id) && x.Is_deleted == 0 && x.Date_completed != null); + } + + public static IEnumerable WhereDeleted(this List items, TableStorageClient storageClient, string userId) + { + return items + .Where(x => storageClient + .Exists(userId, x.Id) && x.Is_deleted == 1); + } + } +} diff --git a/Habitica.Todoist.Integration.Services/TodoistIntegrationService.cs b/Habitica.Todoist.Integration.Services/TodoistIntegrationService.cs new file mode 100644 index 0000000..7db444a --- /dev/null +++ b/Habitica.Todoist.Integration.Services/TodoistIntegrationService.cs @@ -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> 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() + .Where(x => x.PartitionKey == userId) + .ToList() + .OrderByDescending(x => x.Timestamp) + .First().RowKey; + } + catch { } + + return latestSyncToken; + } + } +} diff --git a/Habitica.Todoist.Integration.Services/TodoistServiceClient.cs b/Habitica.Todoist.Integration.Services/TodoistServiceClient.cs index 96da07b..f82847f 100644 --- a/Habitica.Todoist.Integration.Services/TodoistServiceClient.cs +++ b/Habitica.Todoist.Integration.Services/TodoistServiceClient.cs @@ -19,7 +19,7 @@ namespace Habitica.Todoist.Integration.Services this.apiKey = apiKey; } - public async Task GetChangedItems(string syncToken = null) + public async Task GetItemChanges(string syncToken = null) { if (string.IsNullOrEmpty(syncToken)) syncToken = "*"; diff --git a/Habitica.Todoist.Integration.sln b/Habitica.Todoist.Integration.sln index 81218a7..04f2851 100644 --- a/Habitica.Todoist.Integration.sln +++ b/Habitica.Todoist.Integration.sln @@ -18,7 +18,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Habitica.Todoist.Integratio EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Functions", "Functions", "{2DEF5574-4626-414C-9CF2-1FD6F3815B16}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Habitica.Todoist.Integration.Function.Sync", "Habitica.Todoist.Integration.Function.Sync\Habitica.Todoist.Integration.Function.Sync.csproj", "{9C825688-20BC-4580-8126-1E7320A8CC4D}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Habitica.Todoist.Integration.Function.Sync", "Habitica.Todoist.Integration.Function.Sync\Habitica.Todoist.Integration.Function.Sync.csproj", "{9C825688-20BC-4580-8126-1E7320A8CC4D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Habitica.Todoist.Integration.Data", "Habitica.Todoist.Integration.Data\Habitica.Todoist.Integration.Data.csproj", "{08055C1C-7581-4E74-97BB-C5D56E0CA3D8}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -42,6 +44,10 @@ Global {9C825688-20BC-4580-8126-1E7320A8CC4D}.Debug|Any CPU.Build.0 = Debug|Any CPU {9C825688-20BC-4580-8126-1E7320A8CC4D}.Release|Any CPU.ActiveCfg = Release|Any CPU {9C825688-20BC-4580-8126-1E7320A8CC4D}.Release|Any CPU.Build.0 = Release|Any CPU + {08055C1C-7581-4E74-97BB-C5D56E0CA3D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {08055C1C-7581-4E74-97BB-C5D56E0CA3D8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {08055C1C-7581-4E74-97BB-C5D56E0CA3D8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {08055C1C-7581-4E74-97BB-C5D56E0CA3D8}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE