This commit is contained in:
2020-04-09 21:11:01 -04:00
parent 74f3a621ca
commit 49275681fd
10 changed files with 112 additions and 25 deletions

View File

@@ -39,7 +39,7 @@ namespace Habitica.Todoist.Integration.Function.Sync
var items = await todoistService.ReadItemChanges(); var items = await todoistService.ReadItemChanges();
// perform actions // perform actions
await habiticaService.AddTasks(items.WhereAdded()); await habiticaService.Add(items.WhereAdded());
await habiticaService.UpdateTasks(items.WhereUpdated()); await habiticaService.UpdateTasks(items.WhereUpdated());
await habiticaService.CompleteTasks(items.WhereCompleted()); await habiticaService.CompleteTasks(items.WhereCompleted());
await habiticaService.DeleteTasks(items.WhereDeleted()); await habiticaService.DeleteTasks(items.WhereDeleted());

View File

@@ -21,7 +21,7 @@ namespace Habitica.Todoist.Integration.Function.Sync
[Singleton("SyncLock", SingletonScope.Host)] [Singleton("SyncLock", SingletonScope.Host)]
[FunctionName("ScheduledSyncFunction")] [FunctionName("ScheduledSyncFunction")]
public static async Task Run([TimerTrigger("0 0 * * * *")]TimerInfo myTimer, ILogger log) public static async Task Run([TimerTrigger("* * * * * *")]TimerInfo myTimer, ILogger log)
{ {
// initialize integration services // initialize integration services
var todoistService = new TodoistIntegrationService(ScheduledConfiguration.TodoistApiKey, var todoistService = new TodoistIntegrationService(ScheduledConfiguration.TodoistApiKey,
@@ -33,10 +33,11 @@ namespace Habitica.Todoist.Integration.Function.Sync
ScheduledConfiguration.GiosUserId); ScheduledConfiguration.GiosUserId);
// get all changed items from todoist // get all changed items from todoist
var items = await todoistService.ReadItemChanges(); var items = await todoistService.ReadItemChanges();
// perform actions // perform actions
await habiticaService.AddTasks(items.WhereAdded()); await habiticaService.Add(items.WhereAdded());
await habiticaService.UpdateTasks(items.WhereUpdated()); await habiticaService.UpdateTasks(items.WhereUpdated());
await habiticaService.CompleteTasks(items.WhereCompleted()); await habiticaService.CompleteTasks(items.WhereCompleted());
await habiticaService.DeleteTasks(items.WhereDeleted()); await habiticaService.DeleteTasks(items.WhereDeleted());

View File

@@ -0,0 +1,15 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;
namespace Habitica.Todoist.Integration.Model.Habitica
{
public class ChecklistItem
{
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("text")]
public string Text { get; set; }
}
}

View File

@@ -15,6 +15,8 @@ namespace Habitica.Todoist.Integration.Model.Habitica
public string Date { get; set; } public string Date { get; set; }
[JsonProperty("priority")] [JsonProperty("priority")]
public string Priority { get; set; } public string Priority { get; set; }
[JsonProperty("checklist", NullValueHandling = NullValueHandling.Ignore)]
public List<ChecklistItem> Checklist { get; set; }
[JsonProperty("id")] [JsonProperty("id")]
public string Id { get; set; } public string Id { get; set; }
} }

View File

@@ -1,5 +1,6 @@
using Newtonsoft.Json; using Newtonsoft.Json;
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
namespace Habitica.Todoist.Integration.Model.Todoist namespace Habitica.Todoist.Integration.Model.Todoist
@@ -14,9 +15,16 @@ namespace Habitica.Todoist.Integration.Model.Todoist
public Due Due { get; set; } public Due Due { get; set; }
[JsonProperty("priority")] [JsonProperty("priority")]
public int Priority { get; set; } public int Priority { get; set; }
[JsonProperty("parent_id")]
public string Parent_Id { get; set; }
[JsonProperty("is_deleted")] [JsonProperty("is_deleted")]
public int Is_deleted { get; set; } public int Is_deleted { get; set; }
[JsonProperty("project_id")]
public string Project_id { get; set; }
[JsonProperty("date_completed")] [JsonProperty("date_completed")]
public string Date_completed { get; set; } public string Date_completed { get; set; }
[JsonIgnore]
public bool IsChild => !string.IsNullOrEmpty(Parent_Id);
} }
} }

View File

@@ -9,8 +9,25 @@ namespace Habitica.Todoist.Integration.Services.Extensions
{ {
public static class Extensions public static class Extensions
{ {
public static ChecklistItem ToHabiticaChecklistItem(this Item item, string habiticaId = null)
{
if (string.IsNullOrEmpty(item.Parent_Id))
return null;
var checklistItem = new ChecklistItem
{
Id = habiticaId,
Text = item.Content
};
return checklistItem;
}
public static Task ToHabiticaTask(this Item item, string habiticaId = null) public static Task ToHabiticaTask(this Item item, string habiticaId = null)
{ {
if (!string.IsNullOrEmpty(item.Parent_Id))
return null;
var taskTypeStr = Enum.GetName(typeof(TaskType), TaskType.Todo).ToLower(); var taskTypeStr = Enum.GetName(typeof(TaskType), TaskType.Todo).ToLower();
var task = new Task var task = new Task
{ {

View File

@@ -1,10 +1,12 @@
using Habitica.Todoist.Integration.Data; using Habitica.Todoist.Integration.Data;
using ChecklistItem = Habitica.Todoist.Integration.Model.Habitica.ChecklistItem;
using Habitica.Todoist.Integration.Model.Habitica.Enums; using Habitica.Todoist.Integration.Model.Habitica.Enums;
using Habitica.Todoist.Integration.Model.Storage; using Habitica.Todoist.Integration.Model.Storage;
using Habitica.Todoist.Integration.Model.Todoist; using Habitica.Todoist.Integration.Model.Todoist;
using Habitica.Todoist.Integration.Services.Extensions; using Habitica.Todoist.Integration.Services.Extensions;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -27,14 +29,22 @@ namespace Habitica.Todoist.Integration.Services
this.userId = userId; this.userId = userId;
} }
public async Task AddTasks(IEnumerable<Item> items) public async Task Add(IEnumerable<Item> items)
{ {
foreach (var item in items) foreach (var item in items.OrderBy(x => x.Parent_Id))
await AddTask(item); {
if (!item.IsChild)
await AddTask(item);
else
await AddChecklistItem(item);
}
} }
public async Task AddTask(Item item) public async Task AddTask(Item item)
{ {
if (item.IsChild)
throw new ArgumentException("Item passed as arguement has a valid Parent_Id");
var task = (await habiticaClient.CreateTask(item.ToHabiticaTask())).Data; var task = (await habiticaClient.CreateTask(item.ToHabiticaTask())).Data;
var link = new TodoHabitLink(userId, item.Id, task.Id); var link = new TodoHabitLink(userId, item.Id, task.Id);
@@ -42,6 +52,20 @@ namespace Habitica.Todoist.Integration.Services
await storageClient.InsertOrUpdate(link.Reverse()); await storageClient.InsertOrUpdate(link.Reverse());
} }
public async Task AddChecklistItem(Item item)
{
if (!item.IsChild)
throw new ArgumentException("Item passed as arguement does not have a valid Parent_Id");
var habiticaTaskId = (await storageClient.RetrieveRecord<TodoHabitLink>(userId, item.Parent_Id)).HabiticaId;
var checklistItem = (await habiticaClient.CreateChecklistItem(item.ToHabiticaChecklistItem(), habiticaTaskId)).Data.Checklist
.First(x => x.Text == item.Content);
var link = new TodoHabitLink(userId, item.Id, checklistItem.Id);
await storageClient.InsertOrUpdate(link);
await storageClient.InsertOrUpdate(link.Reverse());
}
public async Task UpdateTasks(IEnumerable<Item> items) public async Task UpdateTasks(IEnumerable<Item> items)
{ {
foreach (var item in items) foreach (var item in items)

View File

@@ -1,4 +1,5 @@
using HabiticaTask = Habitica.Todoist.Integration.Model.Habitica.Task; using HabiticaTask = Habitica.Todoist.Integration.Model.Habitica.Task;
using ChecklistItem = Habitica.Todoist.Integration.Model.Habitica.ChecklistItem;
using System.Net; using System.Net;
using System.Threading.Tasks; using System.Threading.Tasks;
using Newtonsoft.Json; using Newtonsoft.Json;
@@ -22,6 +23,17 @@ namespace Habitica.Todoist.Integration.Services
this.apiKey = apiKey; this.apiKey = apiKey;
} }
public async Task<HabiticaReponse<HabiticaTask>> CreateChecklistItem(ChecklistItem checklistItem, string taskId)
{
using (var client = CreateWebClient())
{
var request = JsonConvert.SerializeObject(checklistItem);
var json = await client.UploadStringTaskAsync($"{baseUrl}/tasks/{taskId}/checklist", "POST", request);
return JsonConvert.DeserializeObject<HabiticaReponse<HabiticaTask>>(json);
}
}
public async Task<HabiticaReponse<HabiticaTask>> CreateTask(HabiticaTask task) public async Task<HabiticaReponse<HabiticaTask>> CreateTask(HabiticaTask task)
{ {
using (var client = CreateWebClient()) using (var client = CreateWebClient())

View File

@@ -29,10 +29,10 @@ namespace Habitica.Todoist.Integration.Services
public async Task<Items> ReadItemChanges() public async Task<Items> ReadItemChanges()
{ {
var response = await todoistClient.GetItemChanges(ReadLatestSyncToken()); var itemChangesResponse = await todoistClient.GetItemChanges(ReadLatestSyncToken());
latestSyncToken = response.Sync_token; latestSyncToken = itemChangesResponse.Sync_token;
return new Items(response.Items, storageClient, userId); return new Items(itemChangesResponse.Items, storageClient, userId);
} }
public async Task CommitRead() public async Task CommitRead()
@@ -57,48 +57,52 @@ namespace Habitica.Todoist.Integration.Services
public class Items : IEnumerable<Item> public class Items : IEnumerable<Item>
{ {
private List<Item> items { get; set; } private List<Item> changedItems;
private readonly TableStorageClient storageClient; private readonly TableStorageClient storageClient;
private readonly string userId; private readonly string userId;
internal Items(List<Item> items, TableStorageClient storageClient, string userId) internal Items(List<Item> changedItems, TableStorageClient storageClient, string userId)
{ {
this.items = items; this.changedItems = changedItems;
this.storageClient = storageClient; this.storageClient = storageClient;
this.userId = userId; this.userId = userId;
} }
public IEnumerable<Item> WhereAdded() public IEnumerable<Item> WhereAdded()
{ {
return items return changedItems
.Where(x => !storageClient .Where(x => !storageClient
.Exists<TodoHabitLink>(userId, x.Id) && x.Is_deleted == 0); .Exists<TodoHabitLink>(userId, x.Id) && x.Is_deleted == 0)
.OrderBy(x => x.Parent_Id);
} }
public IEnumerable<Item> WhereUpdated() public IEnumerable<Item> WhereUpdated()
{ {
return items return changedItems
.Where(x => storageClient .Where(x => storageClient
.Exists<TodoHabitLink>(userId, x.Id) && x.Is_deleted == 0); .Exists<TodoHabitLink>(userId, x.Id) && x.Is_deleted == 0)
.OrderBy(x => x.Parent_Id);
} }
public IEnumerable<Item> WhereCompleted() public IEnumerable<Item> WhereCompleted()
{ {
return items return changedItems
.Where(x => storageClient .Where(x => storageClient
.Exists<TodoHabitLink>(userId, x.Id) && x.Is_deleted == 0 && x.Date_completed != null); .Exists<TodoHabitLink>(userId, x.Id) && x.Is_deleted == 0 && x.Date_completed != null)
.OrderBy(x => x.Parent_Id);
} }
public IEnumerable<Item> WhereDeleted() public IEnumerable<Item> WhereDeleted()
{ {
return items return changedItems
.Where(x => storageClient .Where(x => storageClient
.Exists<TodoHabitLink>(userId, x.Id) && x.Is_deleted == 1); .Exists<TodoHabitLink>(userId, x.Id) && x.Is_deleted == 1)
.OrderBy(x => x.Parent_Id);
} }
public IEnumerator<Item> GetEnumerator() public IEnumerator<Item> GetEnumerator()
{ {
return items.GetEnumerator(); return changedItems.OrderBy(x => x.Parent_Id).GetEnumerator();
} }
IEnumerator IEnumerable.GetEnumerator() IEnumerator IEnumerable.GetEnumerator()

View File

@@ -19,11 +19,14 @@ namespace Habitica.Todoist.Integration.Services
this.apiKey = apiKey; this.apiKey = apiKey;
} }
public async Task<SyncResponse> GetItemChanges(string syncToken = null) public async Task<SyncResponse> GetItems()
{ {
if (string.IsNullOrEmpty(syncToken)) var response = await GetItemChanges("*");
syncToken = "*"; return response;
}
public async Task<SyncResponse> GetItemChanges(string syncToken)
{
using (var client = CreateWebClient()) using (var client = CreateWebClient())
{ {
var body = InitializeRequestBody(); var body = InitializeRequestBody();
@@ -31,7 +34,8 @@ namespace Habitica.Todoist.Integration.Services
body["resource_types"] = "[\"items\"]"; body["resource_types"] = "[\"items\"]";
var json = await client.UploadStringTaskAsync($"{baseUrl}sync", RequestBodyToString(body)); var json = await client.UploadStringTaskAsync($"{baseUrl}sync", RequestBodyToString(body));
return JsonConvert.DeserializeObject<SyncResponse>(json); var response = JsonConvert.DeserializeObject<SyncResponse>(json);
return response;
} }
} }