finished creating second level todos in todoist as checklists in habitica
This commit is contained in:
@@ -40,9 +40,9 @@ namespace Habitica.Todoist.Integration.Function.Sync
|
|||||||
|
|
||||||
// perform actions
|
// perform actions
|
||||||
await habiticaService.Add(items.WhereAdded());
|
await habiticaService.Add(items.WhereAdded());
|
||||||
await habiticaService.UpdateTasks(items.WhereUpdated());
|
await habiticaService.Update(items.WhereUpdated());
|
||||||
await habiticaService.CompleteTasks(items.WhereCompleted());
|
await habiticaService.Complete(items.WhereCompleted());
|
||||||
await habiticaService.DeleteTasks(items.WhereDeleted());
|
await habiticaService.Delete(items.WhereDeleted());
|
||||||
|
|
||||||
// commit read changes
|
// commit read changes
|
||||||
await todoistService.CommitRead();
|
await todoistService.CommitRead();
|
||||||
|
|||||||
@@ -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("* * * * * *")]TimerInfo myTimer, ILogger log)
|
public static async Task Run([TimerTrigger("0 */30 * * * *")]TimerInfo myTimer, ILogger log)
|
||||||
{
|
{
|
||||||
// initialize integration services
|
// initialize integration services
|
||||||
var todoistService = new TodoistIntegrationService(ScheduledConfiguration.TodoistApiKey,
|
var todoistService = new TodoistIntegrationService(ScheduledConfiguration.TodoistApiKey,
|
||||||
@@ -33,14 +33,13 @@ 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.Add(items.WhereAdded());
|
await habiticaService.Add(items.WhereAdded());
|
||||||
await habiticaService.UpdateTasks(items.WhereUpdated());
|
await habiticaService.Update(items.WhereUpdated());
|
||||||
await habiticaService.CompleteTasks(items.WhereCompleted());
|
await habiticaService.Complete(items.WhereCompleted());
|
||||||
await habiticaService.DeleteTasks(items.WhereDeleted());
|
await habiticaService.Delete(items.WhereDeleted());
|
||||||
|
|
||||||
// commit read changes
|
// commit read changes
|
||||||
await todoistService.CommitRead();
|
await todoistService.CommitRead();
|
||||||
|
|||||||
@@ -9,13 +9,15 @@ namespace Habitica.Todoist.Integration.Model.Storage
|
|||||||
{
|
{
|
||||||
public HabitTodoLink() { }
|
public HabitTodoLink() { }
|
||||||
|
|
||||||
public HabitTodoLink(string userId, string habiticaId, string todoistId)
|
public HabitTodoLink(string userId, string habiticaId, string todoistId, string habiticaParentId = null)
|
||||||
{
|
{
|
||||||
PartitionKey = userId;
|
PartitionKey = userId;
|
||||||
RowKey = habiticaId;
|
RowKey = habiticaId;
|
||||||
|
HabiticaParentId = habiticaParentId;
|
||||||
TodoistId = todoistId;
|
TodoistId = todoistId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string HabiticaParentId { get; set; }
|
||||||
public string TodoistId { get; set; }
|
public string TodoistId { get; set; }
|
||||||
|
|
||||||
public TodoHabitLink Reverse()
|
public TodoHabitLink Reverse()
|
||||||
|
|||||||
@@ -9,18 +9,20 @@ namespace Habitica.Todoist.Integration.Model.Storage
|
|||||||
{
|
{
|
||||||
public TodoHabitLink() { }
|
public TodoHabitLink() { }
|
||||||
|
|
||||||
public TodoHabitLink(string userId, string todoistId, string habiticaId)
|
public TodoHabitLink(string userId, string todoistId, string habiticaId, string todoistParentId = null)
|
||||||
{
|
{
|
||||||
PartitionKey = userId;
|
PartitionKey = userId;
|
||||||
RowKey = todoistId;
|
RowKey = todoistId;
|
||||||
|
TodoistParentId = todoistParentId;
|
||||||
HabiticaId = habiticaId;
|
HabiticaId = habiticaId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string TodoistParentId { get; set; }
|
||||||
public string HabiticaId { get; set; }
|
public string HabiticaId { get; set; }
|
||||||
|
|
||||||
public HabitTodoLink Reverse()
|
public HabitTodoLink Reverse(string habiticaParentId = null)
|
||||||
{
|
{
|
||||||
return new HabitTodoLink(PartitionKey, HabiticaId, RowKey);
|
return new HabitTodoLink(PartitionKey, HabiticaId, RowKey, habiticaParentId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,9 @@ namespace Habitica.Todoist.Integration.Model.Todoist
|
|||||||
[JsonProperty("date_completed")]
|
[JsonProperty("date_completed")]
|
||||||
public string Date_completed { get; set; }
|
public string Date_completed { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This field will always be false when an item is marked as deleted
|
||||||
|
/// </summary>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public bool IsChild => !string.IsNullOrEmpty(Parent_Id);
|
public bool IsChild => !string.IsNullOrEmpty(Parent_Id);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ namespace Habitica.Todoist.Integration.Services.Extensions
|
|||||||
{
|
{
|
||||||
public static ChecklistItem ToHabiticaChecklistItem(this Item item, string habiticaId = null)
|
public static ChecklistItem ToHabiticaChecklistItem(this Item item, string habiticaId = null)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(item.Parent_Id))
|
if (!item.IsChild)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var checklistItem = new ChecklistItem
|
var checklistItem = new ChecklistItem
|
||||||
@@ -25,7 +25,7 @@ namespace Habitica.Todoist.Integration.Services.Extensions
|
|||||||
|
|
||||||
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))
|
if (item.IsChild)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var taskTypeStr = Enum.GetName(typeof(TaskType), TaskType.Todo).ToLower();
|
var taskTypeStr = Enum.GetName(typeof(TaskType), TaskType.Todo).ToLower();
|
||||||
|
|||||||
@@ -61,32 +61,50 @@ namespace Habitica.Todoist.Integration.Services
|
|||||||
var checklistItem = (await habiticaClient.CreateChecklistItem(item.ToHabiticaChecklistItem(), habiticaTaskId)).Data.Checklist
|
var checklistItem = (await habiticaClient.CreateChecklistItem(item.ToHabiticaChecklistItem(), habiticaTaskId)).Data.Checklist
|
||||||
.First(x => x.Text == item.Content);
|
.First(x => x.Text == item.Content);
|
||||||
|
|
||||||
var link = new TodoHabitLink(userId, item.Id, checklistItem.Id);
|
var link = new TodoHabitLink(userId, item.Id, checklistItem.Id, item.Parent_Id);
|
||||||
await storageClient.InsertOrUpdate(link);
|
await storageClient.InsertOrUpdate(link);
|
||||||
await storageClient.InsertOrUpdate(link.Reverse());
|
await storageClient.InsertOrUpdate(link.Reverse(habiticaTaskId));
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task UpdateTasks(IEnumerable<Item> items)
|
public async Task Update(IEnumerable<Item> items)
|
||||||
{
|
{
|
||||||
foreach (var item in items)
|
foreach (var item in items.OrderBy(x => x.Parent_Id))
|
||||||
await UpdateTask(item);
|
{
|
||||||
|
if (!item.IsChild)
|
||||||
|
await UpdateTask(item);
|
||||||
|
else
|
||||||
|
await UpdateChecklistItem(item);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task UpdateTask(Item item)
|
public async Task UpdateTask(Item item)
|
||||||
{
|
{
|
||||||
|
if (item.IsChild)
|
||||||
|
throw new ArgumentException("Item passed as arguement has a valid Parent_Id");
|
||||||
|
|
||||||
var habiticaId = (await storageClient.RetrieveRecord<TodoHabitLink>(userId, item.Id)).HabiticaId;
|
var habiticaId = (await storageClient.RetrieveRecord<TodoHabitLink>(userId, item.Id)).HabiticaId;
|
||||||
await habiticaClient.UpdateTask(item.ToHabiticaTask(habiticaId));
|
await habiticaClient.UpdateTask(item.ToHabiticaTask(habiticaId));
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task CompleteTasks(IEnumerable<Item> items)
|
public async Task UpdateChecklistItem(Item item)
|
||||||
{
|
{
|
||||||
foreach (var item in items)
|
if (!item.IsChild)
|
||||||
await CompleteTask(item);
|
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 habiticaChecklistId = (await storageClient.RetrieveRecord<TodoHabitLink>(userId, item.Id)).HabiticaId;
|
||||||
|
await habiticaClient.UpdateChecklistItem(item.ToHabiticaChecklistItem(habiticaChecklistId), habiticaTaskId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task CompleteTask(Item item)
|
public async Task Complete(IEnumerable<Item> items)
|
||||||
{
|
{
|
||||||
await CompleteTask(item.Id);
|
foreach (var item in items.OrderByDescending(x => x.Parent_Id))
|
||||||
|
{
|
||||||
|
if (!item.IsChild)
|
||||||
|
await CompleteTask(item.Id);
|
||||||
|
else
|
||||||
|
await CompleteChecklistItem(item.Id, item.Parent_Id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task CompleteTask(string todoistId)
|
public async Task CompleteTask(string todoistId)
|
||||||
@@ -95,15 +113,28 @@ namespace Habitica.Todoist.Integration.Services
|
|||||||
await habiticaClient.ScoreTask(habiticaId, ScoreAction.Up);
|
await habiticaClient.ScoreTask(habiticaId, ScoreAction.Up);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task DeleteTasks(IEnumerable<Item> items)
|
public async Task CompleteChecklistItem(string todoistId, string todoistParentId)
|
||||||
{
|
{
|
||||||
foreach (var item in items)
|
var habiticaTaskId = (await storageClient.RetrieveRecord<TodoHabitLink>(userId, todoistParentId)).HabiticaId;
|
||||||
await DeleteTask(item);
|
var habiticaChecklistId = (await storageClient.RetrieveRecord<TodoHabitLink>(userId, todoistId)).HabiticaId;
|
||||||
|
await habiticaClient.ScoreChecklistItem(habiticaTaskId, habiticaChecklistId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task DeleteTask(Item item)
|
public async Task Delete(IEnumerable<Item> items)
|
||||||
{
|
{
|
||||||
await DeleteTask(item.Id);
|
List<(Item Item, TodoHabitLink Link)> itemsAndLinks = new List<(Item, TodoHabitLink)>();
|
||||||
|
foreach (var item in items)
|
||||||
|
itemsAndLinks.Add((item, await storageClient.RetrieveRecord<TodoHabitLink>(userId, item.Id)));
|
||||||
|
|
||||||
|
foreach (var itemAndLink in itemsAndLinks.OrderByDescending(x => x.Link.TodoistParentId))
|
||||||
|
{
|
||||||
|
var item = itemAndLink.Item;
|
||||||
|
var link = itemAndLink.Link;
|
||||||
|
if (string.IsNullOrEmpty(link.TodoistParentId))
|
||||||
|
await DeleteTask(item.Id);
|
||||||
|
else
|
||||||
|
await DeleteChecklistItem(item.Id, link.TodoistParentId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task DeleteTask(string todoistId)
|
public async Task DeleteTask(string todoistId)
|
||||||
@@ -111,5 +142,12 @@ namespace Habitica.Todoist.Integration.Services
|
|||||||
var habiticaId = (await storageClient.RetrieveRecord<TodoHabitLink>(userId, todoistId)).HabiticaId;
|
var habiticaId = (await storageClient.RetrieveRecord<TodoHabitLink>(userId, todoistId)).HabiticaId;
|
||||||
await habiticaClient.DeleteTask(habiticaId);
|
await habiticaClient.DeleteTask(habiticaId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task DeleteChecklistItem(string todoistId, string todoistParentId)
|
||||||
|
{
|
||||||
|
var habiticaTaskId = (await storageClient.RetrieveRecord<TodoHabitLink>(userId, todoistParentId)).HabiticaId;
|
||||||
|
var habiticaChecklistId = (await storageClient.RetrieveRecord<TodoHabitLink>(userId, todoistId)).HabiticaId;
|
||||||
|
await habiticaClient.DeleteChecklistItem(habiticaTaskId, habiticaChecklistId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,17 +23,6 @@ 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())
|
||||||
@@ -45,19 +34,6 @@ namespace Habitica.Todoist.Integration.Services
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<HabiticaReponse<List<HabiticaTask>>> ReadTasks(TaskType taskType = TaskType.Todo)
|
|
||||||
{
|
|
||||||
var taskTypeStr = Enum.GetName(taskType.GetType(), taskType).ToLower();
|
|
||||||
using (var client = CreateWebClient())
|
|
||||||
{
|
|
||||||
var json = await client.DownloadStringTaskAsync($"{baseUrl}/tasks/user");
|
|
||||||
var response = JsonConvert.DeserializeObject<HabiticaReponse<List<HabiticaTask>>>(json);
|
|
||||||
response.Data.RemoveAll(x => x.Type != taskTypeStr);
|
|
||||||
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<HabiticaTask> UpdateTask(HabiticaTask task)
|
public async Task<HabiticaTask> UpdateTask(HabiticaTask task)
|
||||||
{
|
{
|
||||||
using (var client = CreateWebClient())
|
using (var client = CreateWebClient())
|
||||||
@@ -82,6 +58,53 @@ namespace Habitica.Todoist.Integration.Services
|
|||||||
await client.UploadStringTaskAsync($"{baseUrl}/tasks/{taskId}/score/{actionStr}", "POST", "");
|
await client.UploadStringTaskAsync($"{baseUrl}/tasks/{taskId}/score/{actionStr}", "POST", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//public async Task<HabiticaReponse<List<HabiticaTask>>> ReadTasks(TaskType taskType = TaskType.Todo)
|
||||||
|
//{
|
||||||
|
// var taskTypeStr = Enum.GetName(taskType.GetType(), taskType).ToLower();
|
||||||
|
// using (var client = CreateWebClient())
|
||||||
|
// {
|
||||||
|
// var json = await client.DownloadStringTaskAsync($"{baseUrl}/tasks/user");
|
||||||
|
// var response = JsonConvert.DeserializeObject<HabiticaReponse<List<HabiticaTask>>>(json);
|
||||||
|
// response.Data.RemoveAll(x => x.Type != taskTypeStr);
|
||||||
|
|
||||||
|
// return response;
|
||||||
|
// }
|
||||||
|
//} //public async Task<HabiticaReponse<List<HabiticaTask>>> ReadTasks(TaskType taskType = TaskType.Todo)
|
||||||
|
|
||||||
|
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>> UpdateChecklistItem(ChecklistItem checklistItem, string taskId)
|
||||||
|
{
|
||||||
|
using (var client = CreateWebClient())
|
||||||
|
{
|
||||||
|
var request = JsonConvert.SerializeObject(checklistItem);
|
||||||
|
var json = await client.UploadStringTaskAsync($"{baseUrl}/tasks/{taskId}/checklist/{checklistItem.Id}", "PUT", request);
|
||||||
|
|
||||||
|
return JsonConvert.DeserializeObject<HabiticaReponse<HabiticaTask>>(json);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task DeleteChecklistItem(string taskId, string checklistItemId)
|
||||||
|
{
|
||||||
|
using (var client = CreateWebClient())
|
||||||
|
await client.UploadStringTaskAsync($"{baseUrl}/tasks/{taskId}/checklist/{checklistItemId}", "DELETE", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task ScoreChecklistItem(string taskId, string checklistItemId)
|
||||||
|
{
|
||||||
|
using (var client = CreateWebClient())
|
||||||
|
await client.UploadStringTaskAsync($"{baseUrl}/tasks/{taskId}/checklist/{checklistItemId}/score", "POST", "");
|
||||||
|
}
|
||||||
|
|
||||||
private WebClient CreateWebClient()
|
private WebClient CreateWebClient()
|
||||||
{
|
{
|
||||||
var client = new WebClient();
|
var client = new WebClient();
|
||||||
|
|||||||
@@ -89,20 +89,19 @@ namespace Habitica.Todoist.Integration.Services
|
|||||||
return changedItems
|
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);
|
.OrderByDescending(x => x.Parent_Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<Item> WhereDeleted()
|
public IEnumerable<Item> WhereDeleted()
|
||||||
{
|
{
|
||||||
return changedItems
|
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 changedItems.OrderBy(x => x.Parent_Id).GetEnumerator();
|
return changedItems.GetEnumerator();
|
||||||
}
|
}
|
||||||
|
|
||||||
IEnumerator IEnumerable.GetEnumerator()
|
IEnumerator IEnumerable.GetEnumerator()
|
||||||
|
|||||||
Reference in New Issue
Block a user