put a little more work into quizzes

This commit is contained in:
2023-08-16 22:59:08 -06:00
parent 4def2fd689
commit 4fb257e000
12 changed files with 258 additions and 77 deletions

View File

@@ -21,7 +21,7 @@ public class CoursePlanner
this.canvas = canvas;
}
private Timer _debounceTimer;
private Timer? _debounceTimer;
private int _debounceInterval = 1000;
private LocalCourse? _localCourse { get; set; }
public LocalCourse? LocalCourse
@@ -54,6 +54,7 @@ public class CoursePlanner
private void saveCourseToFile(LocalCourse courseAsOfDebounce)
{
_debounceTimer?.Dispose();
// ignore initial load of course
if (LocalCourse == null)
{
@@ -137,6 +138,8 @@ public class CoursePlanner
LocalCourse = await LocalCourse.SyncAssignmentsWithCanvas(canvasId, CanvasAssignments, canvas);
CanvasAssignments = await canvas.Assignments.GetAll(canvasId);
await syncModuleItemsWithCanvas(canvasId);
CanvasModulesItems = await canvas.GetAllModulesItems(canvasId, CanvasModules);

View File

@@ -1,75 +1,16 @@
using System.Text.RegularExpressions;
using CanvasModel.Assignments;
using CanvasModel.Modules;
using CanvasModel.Quizzes;
using LocalModels;
using Management.Services.Canvas;
namespace Management.Planner;
public static partial class CoursePlannerSyncronizationExtensions
public static partial class AssignmentSyncronizationExtensions
{
internal static async Task<IEnumerable<LocalModule>> EnsureAllModulesExistInCanvas(
this LocalCourse localCourse,
ulong canvasId,
IEnumerable<CanvasModule> canvasModules,
CanvasService canvas
)
{
var moduleTasks = localCourse.Modules.Select(async module =>
{
var canvasModule = canvasModules.FirstOrDefault(cm => cm.Id == module.CanvasId);
if (canvasModule == null)
{
var newModule = await canvas.CreateModule(canvasId, module.Name);
return module with { CanvasId = newModule.Id };
}
else
return module;
});
var newModules = await Task.WhenAll(moduleTasks);
return newModules ?? throw new Exception("Error ensuring all modules exist in canvas");
}
internal static async Task SortCanvasModules(
this LocalCourse localCourse,
ulong canvasId,
IEnumerable<CanvasModule> canvasModules,
CanvasService canvas
)
{
var currentCanvasPositions = canvasModules.ToDictionary(m => m.Id, m => m.Position);
foreach (var (localModule, i) in localCourse.Modules.Select((m, i) => (m, i)))
{
var correctPosition = i + 1;
var moduleCanvasId =
localModule.CanvasId ?? throw new Exception("cannot sort module if no module canvas id");
var currentCanvasPosition = currentCanvasPositions[moduleCanvasId];
if (currentCanvasPosition != correctPosition)
{
await canvas.UpdateModule(canvasId, moduleCanvasId, localModule.Name, correctPosition);
}
}
}
internal static async Task<LocalCourse> SyncModulesWithCanvasData(
this LocalCourse localCourse,
ulong canvasId,
IEnumerable<CanvasModule> canvasModules,
CanvasService canvas
)
{
canvasModules = await canvas.GetModules(canvasId);
return localCourse with
{
Modules = localCourse.Modules.Select(m =>
{
var canvasModule = canvasModules.FirstOrDefault(cm => cm.Name == m.Name);
return canvasModule == null ? m : m with { CanvasId = canvasModule.Id };
})
};
}
internal static async Task<LocalAssignment> SyncToCanvas(
internal static async Task<LocalAssignment> SyncAssignmentToCanvas(
this LocalCourse localCourse,
ulong canvasId,
LocalAssignment localAssignment,
@@ -114,38 +55,51 @@ public static partial class CoursePlannerSyncronizationExtensions
var localHtmlDescription = localAssignment
.GetDescriptionHtml(courseAssignmentTemplates)
.Replace("<hr />", "<hr>")
.Replace("&gt;", "")
.Replace("&lt;", "")
.Replace(">", "")
.Replace("<", "");
.Replace("<", "")
.Replace("&quot;", "")
.Replace("\"", "");
var canvasHtmlDescription = canvasAssignment.Description;
canvasHtmlDescription = CanvasScriptTagRegex().Replace(canvasHtmlDescription, "");
canvasHtmlDescription = CanvasLinkTagRegex().Replace(canvasHtmlDescription, "");
canvasHtmlDescription = canvasHtmlDescription
.Replace("<hr />", "<hr>")
.Replace("&gt;", "")
.Replace("&lt;", "")
.Replace(">", "")
.Replace("<", "");
.Replace("<", "")
.Replace("&quot;", "")
.Replace("\"", "");
var dueDatesSame =
var canvasComparisonDueDate =
canvasAssignment.DueAt != null
&& new DateTime(
year: canvasAssignment.DueAt.Value.Year,
month: canvasAssignment.DueAt.Value.Month,
day: canvasAssignment.DueAt.Value.Day,
hour: canvasAssignment.DueAt.Value.Hour,
minute: canvasAssignment.DueAt.Value.Minute,
second: canvasAssignment.DueAt.Value.Second
)
== new DateTime(
? new DateTime(
year: canvasAssignment.DueAt.Value.Year,
month: canvasAssignment.DueAt.Value.Month,
day: canvasAssignment.DueAt.Value.Day,
hour: canvasAssignment.DueAt.Value.Hour,
minute: canvasAssignment.DueAt.Value.Minute,
second: canvasAssignment.DueAt.Value.Second
)
: new DateTime();
var localComparisonDueDate =
canvasAssignment.DueAt != null
? new DateTime(
year: localAssignment.DueAt.Year,
month: localAssignment.DueAt.Month,
day: localAssignment.DueAt.Day,
hour: localAssignment.DueAt.Hour,
minute: localAssignment.DueAt.Minute,
second: localAssignment.DueAt.Second
);
)
: new DateTime();
var dueDatesSame =
canvasAssignment.DueAt != null && canvasComparisonDueDate == localComparisonDueDate;
var descriptionSame = canvasHtmlDescription == localHtmlDescription;
var nameSame = canvasAssignment.Name == localAssignment.Name;
@@ -159,6 +113,9 @@ public static partial class CoursePlannerSyncronizationExtensions
{
if (!dueDatesSame)
{
Console.WriteLine(JsonSerializer.Serialize(canvasAssignment));
Console.WriteLine(canvasComparisonDueDate);
Console.WriteLine(localComparisonDueDate);
Console.WriteLine(
$"Due dates different for {localAssignment.Name}, local: {localAssignment.DueAt}, in canvas {canvasAssignment.DueAt}"
);
@@ -219,7 +176,7 @@ public static partial class CoursePlannerSyncronizationExtensions
var moduleTasks = localCourse.Modules.Select(async m =>
{
var assignmentTasks = m.Assignments.Select(
(a) => localCourse.SyncToCanvas(canvasId, a, canvasAssignments, canvas)
(a) => localCourse.SyncAssignmentToCanvas(canvasId, a, canvasAssignments, canvas)
);
var assignments = await Task.WhenAll(assignmentTasks);
return m with { Assignments = assignments };

View File

@@ -0,0 +1,72 @@
using System.Text.RegularExpressions;
using CanvasModel.Assignments;
using CanvasModel.Modules;
using CanvasModel.Quizzes;
using LocalModels;
using Management.Services.Canvas;
namespace Management.Planner;
public static partial class ModuleSyncronizationExtensions
{
internal static async Task<IEnumerable<LocalModule>> EnsureAllModulesExistInCanvas(
this LocalCourse localCourse,
ulong canvasId,
IEnumerable<CanvasModule> canvasModules,
CanvasService canvas
)
{
var moduleTasks = localCourse.Modules.Select(async module =>
{
var canvasModule = canvasModules.FirstOrDefault(cm => cm.Id == module.CanvasId);
if (canvasModule == null)
{
var newModule = await canvas.CreateModule(canvasId, module.Name);
return module with { CanvasId = newModule.Id };
}
else
return module;
});
var newModules = await Task.WhenAll(moduleTasks);
return newModules ?? throw new Exception("Error ensuring all modules exist in canvas");
}
internal static async Task SortCanvasModules(
this LocalCourse localCourse,
ulong canvasId,
IEnumerable<CanvasModule> canvasModules,
CanvasService canvas
)
{
var currentCanvasPositions = canvasModules.ToDictionary(m => m.Id, m => m.Position);
foreach (var (localModule, i) in localCourse.Modules.Select((m, i) => (m, i)))
{
var correctPosition = i + 1;
var moduleCanvasId =
localModule.CanvasId ?? throw new Exception("cannot sort module if no module canvas id");
var currentCanvasPosition = currentCanvasPositions[moduleCanvasId];
if (currentCanvasPosition != correctPosition)
{
await canvas.UpdateModule(canvasId, moduleCanvasId, localModule.Name, correctPosition);
}
}
}
internal static async Task<LocalCourse> SyncModulesWithCanvasData(
this LocalCourse localCourse,
ulong canvasId,
IEnumerable<CanvasModule> canvasModules,
CanvasService canvas
)
{
canvasModules = await canvas.GetModules(canvasId);
return localCourse with
{
Modules = localCourse.Modules.Select(m =>
{
var canvasModule = canvasModules.FirstOrDefault(cm => cm.Name == m.Name);
return canvasModule == null ? m : m with { CanvasId = canvasModule.Id };
})
};
}
}

View File

@@ -0,0 +1,43 @@
using System.Text.RegularExpressions;
using CanvasModel.Assignments;
using CanvasModel.Modules;
using CanvasModel.Quizzes;
using LocalModels;
using Management.Services.Canvas;
namespace Management.Planner;
public static partial class QuizSyncronizationExtensions
{
internal static async Task<LocalQuiz> SyncQuizToCanvas(
this LocalCourse localCourse,
ulong canvasId,
LocalQuiz localQuiz,
IEnumerable<CanvasQuiz> canvasQuizzes,
CanvasService canvas
)
{
// TODO actually sync
return localQuiz;
}
internal static async Task<LocalCourse> SyncQuizzesWithCanvas(
this LocalCourse localCourse,
ulong canvasId,
IEnumerable<CanvasQuiz> canvasQuizzes,
CanvasService canvas
)
{
var moduleTasks = localCourse.Modules.Select(async m =>
{
var quizTasks = m.Quizzes.Select(
(q) => localCourse.SyncQuizToCanvas(canvasId, q, canvasQuizzes, canvas)
);
var quizzes = await Task.WhenAll(quizTasks);
return m with { Quizzes = quizzes };
});
var modules = await Task.WhenAll(moduleTasks);
return localCourse;
}
}