mirror of
https://github.com/alexmickelson/canvasManagement.git
synced 2026-03-25 23:28:33 -06:00
consolodated canvas data structure
This commit is contained in:
@@ -137,7 +137,7 @@
|
||||
}
|
||||
|
||||
private CanvasAssignment? assignmentInCanvas =>
|
||||
planner.CanvasAssignments?.FirstOrDefault(a => a.Name == assignmentContext.Assignment?.Name);
|
||||
planner.CanvasData?.Assignments.FirstOrDefault(a => a.Name == assignmentContext.Assignment?.Name);
|
||||
|
||||
private string canvasAssignmentUrl =>
|
||||
$"https://snow.instructure.com/courses/{planner.LocalCourse?.Settings.CanvasId}/assignments/{assignmentInCanvas?.Id}";
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
if(firstRender)
|
||||
{
|
||||
if(
|
||||
planner.CanvasAssignments == null
|
||||
planner.CanvasData == null
|
||||
&& planner.LocalCourse != null
|
||||
&& planner.LocalCourse.Settings.CanvasId != null
|
||||
)
|
||||
|
||||
@@ -87,7 +87,8 @@
|
||||
}
|
||||
|
||||
private bool isSyncedWithCanvas => planner
|
||||
.CanvasModules?
|
||||
.CanvasData?
|
||||
.Modules
|
||||
.FirstOrDefault(
|
||||
cm => cm.Name == Module.Name
|
||||
) != null;
|
||||
|
||||
@@ -38,7 +38,8 @@
|
||||
}
|
||||
|
||||
private CanvasAssignment? assignmentInCanvas => planner
|
||||
.CanvasAssignments?
|
||||
.CanvasData?
|
||||
.Assignments
|
||||
.FirstOrDefault(
|
||||
a => a.Name == Assignment.Name
|
||||
);
|
||||
@@ -53,8 +54,7 @@
|
||||
|
||||
private bool NeedsToBeUpdatedInCanvas => planner.LocalCourse != null
|
||||
&& planner.LocalCourse.Settings.CanvasId != null
|
||||
&& planner.CanvasAssignments != null
|
||||
&& planner.CanvasModules != null
|
||||
&& planner.CanvasData != null
|
||||
&& assignmentInCanvas != null
|
||||
&& Assignment.NeedsUpdates(
|
||||
(CanvasAssignment)assignmentInCanvas,
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
dragContainer.DropCallback = null;
|
||||
}
|
||||
private bool existsInCanvas =>
|
||||
planner.CanvasQuizzes != null
|
||||
? Quiz.QuizIsCreated(planner.CanvasQuizzes)
|
||||
planner.CanvasData != null
|
||||
? Quiz.QuizIsCreated(planner.CanvasData.Quizzes)
|
||||
: false;
|
||||
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
|
||||
private CanvasPage? pageInCanvas =>
|
||||
planner.CanvasPages?.FirstOrDefault(a => a.Title == pageContext.Page?.Name);
|
||||
planner.CanvasData?.Pages.FirstOrDefault(a => a.Title == pageContext.Page?.Name);
|
||||
|
||||
|
||||
private string canvasPageUrl =>
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
}
|
||||
StateHasChanged();
|
||||
|
||||
if (planner.CanvasQuizzes == null)
|
||||
if (planner.CanvasData == null)
|
||||
{
|
||||
await planner.LoadCanvasData();
|
||||
}
|
||||
@@ -91,7 +91,7 @@
|
||||
Navigation.NavigateTo("/course/" + planner.LocalCourse?.Settings.Name);
|
||||
}
|
||||
|
||||
private CanvasQuiz? quizInCanvas => planner.CanvasQuizzes?.FirstOrDefault(q => q.Title == quizContext.Quiz?.Name);
|
||||
private CanvasQuiz? quizInCanvas => planner.CanvasData?.Quizzes.FirstOrDefault(q => q.Title == quizContext.Quiz?.Name);
|
||||
|
||||
private string canvasQuizUrl =>
|
||||
$"https://snow.instructure.com/courses/{planner.LocalCourse?.Settings.CanvasId}/quizzes/{quizInCanvas?.Id}";
|
||||
|
||||
@@ -98,11 +98,11 @@ builder.Services.AddHostedService(sp => sp.GetRequiredService<AkkaService>());
|
||||
|
||||
|
||||
// TODO: need to handle scoped requirements
|
||||
builder.Services.AddSingleton(sp =>
|
||||
{
|
||||
var akka = sp.GetRequiredService<AkkaService>();
|
||||
return new CanvasQueue(akka.CanvasQueueActor ?? throw new Exception("Canvas queue actor not properly created"));
|
||||
});
|
||||
// builder.Services.AddSingleton(sp =>
|
||||
// {
|
||||
// var akka = sp.GetRequiredService<AkkaService>();
|
||||
// return new CanvasQueueActorWrapper(akka.CoursePlannerActor ?? throw new Exception("Canvas queue actor not properly created"));
|
||||
// });
|
||||
builder.Services.AddSingleton<IFileStorageManager>(sp =>
|
||||
{
|
||||
var akka = sp.GetRequiredService<AkkaService>();
|
||||
|
||||
@@ -72,7 +72,7 @@ public class AssignmentEditorContext
|
||||
|
||||
|
||||
await planner.LoadCanvasData();
|
||||
if (planner.CanvasAssignments == null)
|
||||
if (planner.CanvasData == null)
|
||||
{
|
||||
logger.Log("cannot update assignment in canvas, failed to retrieve current assignments");
|
||||
return;
|
||||
@@ -87,7 +87,7 @@ public class AssignmentEditorContext
|
||||
logger.Log("Cannot update assignment with null local course canvas id");
|
||||
return;
|
||||
}
|
||||
var assignmentInCanvas = planner.CanvasAssignments?.FirstOrDefault(a => a.Id == canvasAssignmentId);
|
||||
var assignmentInCanvas = planner.CanvasData.Assignments?.FirstOrDefault(a => a.Id == canvasAssignmentId);
|
||||
if (assignmentInCanvas == null)
|
||||
{
|
||||
logger.Log("cannot update assignment in canvas, could not find canvas assignment with id: " + canvasAssignmentId);
|
||||
@@ -121,7 +121,7 @@ public class AssignmentEditorContext
|
||||
return;
|
||||
}
|
||||
await planner.LoadCanvasData();
|
||||
if (planner.CanvasAssignments == null)
|
||||
if (planner.CanvasData == null)
|
||||
{
|
||||
logger.Log("cannot add assignment to canvas, failed to retrieve current assignments");
|
||||
return;
|
||||
@@ -144,7 +144,7 @@ public class AssignmentEditorContext
|
||||
var createdAssignmentCanvasId = await planner.LocalCourse.SyncAssignmentToCanvas(
|
||||
canvasCourseId: (ulong)courseCanvasId,
|
||||
localAssignment: Assignment,
|
||||
canvasAssignments: planner.CanvasAssignments,
|
||||
canvasAssignments: planner.CanvasData.Assignments,
|
||||
canvas: canvas
|
||||
);
|
||||
|
||||
@@ -179,7 +179,7 @@ public class AssignmentEditorContext
|
||||
private CanvasModule getCurrentCanvasModule(LocalAssignment assignment, LocalCourse course)
|
||||
{
|
||||
var localModule = getCurrentLocalModule(assignment, course);
|
||||
var canvasModule = planner.CanvasModules?.FirstOrDefault(m => m.Name == localModule.Name)
|
||||
var canvasModule = planner.CanvasData?.Modules.FirstOrDefault(m => m.Name == localModule.Name)
|
||||
?? throw new Exception($"error in assignment context, canvas module with name {localModule.Name} not found in planner");
|
||||
return canvasModule;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
using CanvasModel;
|
||||
using CanvasModel.Assignments;
|
||||
using CanvasModel.Courses;
|
||||
@@ -6,12 +7,25 @@ using CanvasModel.EnrollmentTerms;
|
||||
using CanvasModel.Modules;
|
||||
using CanvasModel.Pages;
|
||||
using CanvasModel.Quizzes;
|
||||
|
||||
using LocalModels;
|
||||
|
||||
using Management.Services;
|
||||
using Management.Services.Canvas;
|
||||
|
||||
namespace Management.Planner;
|
||||
|
||||
|
||||
public record CanvasCourseData
|
||||
{
|
||||
public required IEnumerable<CanvasAssignment> Assignments { get; init; }
|
||||
public required IEnumerable<CanvasAssignmentGroup> AssignmentGroups { get; init; }
|
||||
public required IEnumerable<CanvasQuiz> Quizzes { get; init; }
|
||||
public required IEnumerable<CanvasModule> Modules { get; init; }
|
||||
public required IEnumerable<CanvasPage> Pages { get; init; }
|
||||
public required Dictionary<CanvasModule, IEnumerable<CanvasModuleItem>> ModulesItems { get; init; }
|
||||
}
|
||||
|
||||
public class CoursePlanner
|
||||
{
|
||||
private readonly MyLogger<CoursePlanner> logger;
|
||||
@@ -72,11 +86,6 @@ public class CoursePlanner
|
||||
}
|
||||
}
|
||||
|
||||
public async Task LoadCourseByName(string courseName)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void saveCourseToFile(LocalCourse courseAsOfDebounce)
|
||||
{
|
||||
_debounceTimer?.Dispose();
|
||||
@@ -117,23 +126,10 @@ public class CoursePlanner
|
||||
|
||||
public event Action? StateHasChanged;
|
||||
|
||||
public IEnumerable<CanvasAssignment>? CanvasAssignments { get; internal set; }
|
||||
public IEnumerable<CanvasAssignmentGroup>? CanvasAssignmentGroups { get; internal set; }
|
||||
public IEnumerable<CanvasQuiz>? CanvasQuizzes { get; internal set; }
|
||||
public IEnumerable<CanvasModule>? CanvasModules { get; internal set; }
|
||||
public IEnumerable<CanvasPage>? CanvasPages { get; internal set; }
|
||||
public Dictionary<CanvasModule, IEnumerable<CanvasModuleItem>>? CanvasModulesItems { get; internal set; }
|
||||
public CanvasCourseData? CanvasData { get; internal set; }
|
||||
|
||||
public async Task<(
|
||||
IEnumerable<CanvasAssignment> CanvasAssignments,
|
||||
IEnumerable<CanvasModule> CanvasModules,
|
||||
Dictionary<CanvasModule, IEnumerable<CanvasModuleItem>> CanvasModulesItems,
|
||||
IEnumerable<CanvasQuiz> canvasQuizzes,
|
||||
IEnumerable<CanvasAssignmentGroup> canvasAssignmentGroups,
|
||||
IEnumerable<CanvasPage> canvasPages
|
||||
)> LoadCanvasData()
|
||||
public async Task LoadCanvasData()
|
||||
{
|
||||
|
||||
using var activity = DiagnosticsConfig.Source.StartActivity("Loading Canvas Data to Course Planner");
|
||||
LoadingCanvasData = true;
|
||||
StateHasChanged?.Invoke();
|
||||
@@ -147,17 +143,26 @@ public class CoursePlanner
|
||||
var assignmentGroupsTask = canvas.AssignmentGroups.GetAll(canvasId);
|
||||
var coursePagesTask = canvas.Pages.GetAll(canvasId);
|
||||
|
||||
CanvasAssignments = await assignmentsTask;
|
||||
CanvasQuizzes = await quizzesTask;
|
||||
CanvasModules = await modulesTask;
|
||||
CanvasAssignmentGroups = await assignmentGroupsTask;
|
||||
CanvasPages = await coursePagesTask;
|
||||
|
||||
CanvasModulesItems = await canvas.Modules.GetAllModulesItems(canvasId, CanvasModules);
|
||||
var canvasAssignments = (await assignmentsTask) ?? throw new Exception("Error loading canvas assignments");
|
||||
var canvasQuizzes = (await quizzesTask) ?? throw new Exception("Error loading canvas quizzes");
|
||||
var canvasAssignmentGroups = (await assignmentGroupsTask) ?? throw new Exception("Error loading canvas assignment groups");
|
||||
var canvasPages = (await coursePagesTask) ?? throw new Exception("Error loading canvas pages");
|
||||
var canvasModules = (await modulesTask) ?? throw new Exception("Error loading canvas modules");
|
||||
var canvasModulesItems = (await canvas.Modules.GetAllModulesItems(canvasId, canvasModules)) ?? throw new Exception("Error loading canvas module items");
|
||||
|
||||
CanvasData = new CanvasCourseData
|
||||
{
|
||||
Assignments = canvasAssignments,
|
||||
Quizzes = canvasQuizzes,
|
||||
AssignmentGroups = canvasAssignmentGroups,
|
||||
Pages = canvasPages,
|
||||
Modules = canvasModules,
|
||||
ModulesItems = canvasModulesItems,
|
||||
};
|
||||
|
||||
LoadingCanvasData = false;
|
||||
StateHasChanged?.Invoke();
|
||||
return (CanvasAssignments, CanvasModules, CanvasModulesItems, CanvasQuizzes, CanvasAssignmentGroups, CanvasPages);
|
||||
}
|
||||
|
||||
public async Task CreateModule(LocalModule newModule)
|
||||
@@ -167,14 +172,20 @@ public class CoursePlanner
|
||||
var canvasCourseId =
|
||||
LocalCourse.Settings.CanvasId ?? throw new Exception("no course canvas id to use to create module");
|
||||
await canvas.Modules.CreateModule(canvasCourseId, newModule.Name);
|
||||
CanvasModules = await canvas.Modules.GetModules(canvasCourseId);
|
||||
var canvasModules = await canvas.Modules.GetModules(canvasCourseId);
|
||||
if (CanvasData != null)
|
||||
{
|
||||
CanvasData = CanvasData with
|
||||
{
|
||||
Modules = canvasModules
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
CanvasData = null;
|
||||
LocalCourse = null;
|
||||
CanvasAssignments = null;
|
||||
CanvasModules = null;
|
||||
}
|
||||
|
||||
public async Task SyncAssignmentGroups()
|
||||
@@ -185,12 +196,11 @@ public class CoursePlanner
|
||||
var canvasCourseId =
|
||||
LocalCourse.Settings.CanvasId ?? throw new Exception("no course canvas id to use to create module");
|
||||
|
||||
var canvasAssignmentGroups = await canvas.AssignmentGroups.GetAll(canvasCourseId);
|
||||
|
||||
CanvasAssignmentGroups = await canvas.AssignmentGroups.GetAll(canvasCourseId);
|
||||
await LocalCourse.EnsureAllAssignmentGroupsExistInCanvas(canvasCourseId, canvasAssignmentGroups, canvas);
|
||||
|
||||
await LocalCourse.EnsureAllAssignmentGroupsExistInCanvas(canvasCourseId, CanvasAssignmentGroups, canvas);
|
||||
|
||||
CanvasAssignmentGroups = await canvas.AssignmentGroups.GetAll(canvasCourseId);
|
||||
canvasAssignmentGroups = await canvas.AssignmentGroups.GetAll(canvasCourseId);
|
||||
|
||||
LocalCourse = LocalCourse with
|
||||
{
|
||||
@@ -198,12 +208,16 @@ public class CoursePlanner
|
||||
{
|
||||
AssignmentGroups = LocalCourse.Settings.AssignmentGroups.Select(g =>
|
||||
{
|
||||
var canvasGroup = CanvasAssignmentGroups.FirstOrDefault(c => c.Name == g.Name);
|
||||
var canvasGroup = canvasAssignmentGroups.FirstOrDefault(c => c.Name == g.Name);
|
||||
return canvasGroup == null
|
||||
? g
|
||||
: g with { CanvasId = canvasGroup.Id };
|
||||
})
|
||||
}
|
||||
};
|
||||
CanvasData = CanvasData with
|
||||
{
|
||||
AssignmentGroups = canvasAssignmentGroups
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ public class PageEditorContext(
|
||||
return;
|
||||
}
|
||||
await planner.LoadCanvasData();
|
||||
if (planner.CanvasPages == null)
|
||||
if (planner.CanvasData == null)
|
||||
{
|
||||
logger.Log("cannot add page to canvas, failed to retrieve current pages");
|
||||
return;
|
||||
@@ -143,7 +143,7 @@ public class PageEditorContext(
|
||||
|
||||
|
||||
await planner.LoadCanvasData();
|
||||
if (planner.CanvasPages == null)
|
||||
if (planner.CanvasData == null)
|
||||
{
|
||||
logger.Log("cannot update page in canvas, failed to retrieve current pages");
|
||||
return;
|
||||
@@ -158,7 +158,7 @@ public class PageEditorContext(
|
||||
logger.Log("Cannot update page with null local course canvas id");
|
||||
return;
|
||||
}
|
||||
var assignmentInCanvas = planner.CanvasPages?.FirstOrDefault(p => p.PageId == canvasPageId);
|
||||
var assignmentInCanvas = planner.CanvasData?.Pages.FirstOrDefault(p => p.PageId == canvasPageId);
|
||||
if (assignmentInCanvas == null)
|
||||
{
|
||||
logger.Log("cannot update page in canvas, could not find canvas page with id: " + canvasPageId);
|
||||
@@ -184,7 +184,7 @@ public class PageEditorContext(
|
||||
private CanvasModule getCurrentCanvasModule(LocalCoursePage quiz, LocalCourse course)
|
||||
{
|
||||
var localModule = getCurrentLocalModule(quiz, course);
|
||||
var canvasModule = planner.CanvasModules?.FirstOrDefault(m => m.Name == localModule.Name)
|
||||
var canvasModule = planner.CanvasData?.Modules.FirstOrDefault(m => m.Name == localModule.Name)
|
||||
?? throw new Exception($"error in page context, canvas module with name {localModule.Name} not found in planner");
|
||||
return canvasModule;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
using System.Reflection.Metadata.Ecma335;
|
||||
|
||||
using CanvasModel.Modules;
|
||||
|
||||
using LocalModels;
|
||||
|
||||
using Management.Planner;
|
||||
using Management.Services;
|
||||
using Management.Services.Canvas;
|
||||
@@ -91,7 +94,7 @@ public class QuizEditorContext(
|
||||
return;
|
||||
}
|
||||
await planner.LoadCanvasData();
|
||||
if (planner.CanvasQuizzes == null)
|
||||
if (planner.CanvasData == null)
|
||||
{
|
||||
logger.Log("cannot add quiz to canvas, failed to retrieve current quizzes");
|
||||
return;
|
||||
@@ -142,7 +145,7 @@ public class QuizEditorContext(
|
||||
private CanvasModule getCurrentCanvasModule(LocalQuiz quiz, LocalCourse course)
|
||||
{
|
||||
var localModule = getCurrentLocalModule(quiz, course);
|
||||
var canvasModule = planner.CanvasModules?.FirstOrDefault(m => m.Name == localModule.Name)
|
||||
var canvasModule = planner.CanvasData?.Modules.FirstOrDefault(m => m.Name == localModule.Name)
|
||||
?? throw new Exception($"error in quiz context, canvas module with name {localModule.Name} not found in planner");
|
||||
return canvasModule;
|
||||
}
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
using Akka.Actor;
|
||||
|
||||
using Management.Services.Canvas;
|
||||
|
||||
public class CanvasQueue(IActorRef canvasQueueActor)
|
||||
{
|
||||
private readonly IActorRef canvasQueueActor = canvasQueueActor;
|
||||
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
using Akka.Actor;
|
||||
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
public class CanvasQueueActor : ReceiveActor
|
||||
{
|
||||
private readonly IServiceProvider serviceProvider;
|
||||
private readonly IServiceScope scope;
|
||||
private readonly ILogger<CanvasQueueActor> logger;
|
||||
|
||||
public CanvasQueueActor(IServiceProvider serviceProviderArg)
|
||||
{
|
||||
serviceProvider = serviceProviderArg;
|
||||
scope = serviceProvider.CreateScope();
|
||||
logger = scope.ServiceProvider.GetRequiredService<ILogger<CanvasQueueActor>>();
|
||||
}
|
||||
}
|
||||
18
Management/Services/Actors/CoursePlannerActor.cs
Normal file
18
Management/Services/Actors/CoursePlannerActor.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using Akka.Actor;
|
||||
|
||||
using Management.Services;
|
||||
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
public class CoursePlannerActor: ReceiveActor
|
||||
{
|
||||
private readonly IServiceProvider serviceProvider;
|
||||
private readonly IServiceScope scope;
|
||||
private readonly MyLogger<CoursePlannerActor> logger;
|
||||
public CoursePlannerActor(IServiceProvider serviceProviderArg)
|
||||
{
|
||||
serviceProvider = serviceProviderArg;
|
||||
scope = serviceProvider.CreateScope();
|
||||
logger = scope.ServiceProvider.GetRequiredService<MyLogger<CoursePlannerActor>>();
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,16 @@
|
||||
using Akka.Actor;
|
||||
|
||||
using LocalModels;
|
||||
|
||||
using Management.Services;
|
||||
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
public class IStorageActor : ReceiveActor {}
|
||||
|
||||
public class LocalStorageActor : IStorageActor
|
||||
public class LocalStorageActor : ReceiveActor
|
||||
{
|
||||
private readonly IServiceProvider serviceProvider;
|
||||
private readonly IServiceScope scope;
|
||||
private readonly MyLogger<CanvasQueueActor> logger;
|
||||
private readonly MyLogger<LocalStorageActor> logger;
|
||||
private readonly FileStorageService storage;
|
||||
|
||||
private DateTime? cacheTime { get; set; } = null;
|
||||
@@ -20,7 +21,7 @@ public class LocalStorageActor : IStorageActor
|
||||
{
|
||||
serviceProvider = serviceProviderArg;
|
||||
scope = serviceProvider.CreateScope();
|
||||
logger = scope.ServiceProvider.GetRequiredService<MyLogger<CanvasQueueActor>>();
|
||||
logger = scope.ServiceProvider.GetRequiredService<MyLogger<LocalStorageActor>>();
|
||||
storage = scope.ServiceProvider.GetRequiredService<FileStorageService>();
|
||||
|
||||
Receive<EmptyDirectoryAsk>(m =>
|
||||
|
||||
@@ -18,7 +18,7 @@ public class AkkaService(
|
||||
private readonly IConfiguration configuration = configuration;
|
||||
private readonly IServiceProvider serviceProvider = serviceProvider;
|
||||
private readonly IHostApplicationLifetime applicationLifetime = appLifetime;
|
||||
public IActorRef? CanvasQueueActor { get; private set; }
|
||||
public IActorRef? CoursePlannerActor { get; private set; }
|
||||
public IActorRef? StorageActor { get; private set; }
|
||||
|
||||
public Task StartAsync(CancellationToken cancellationToken)
|
||||
@@ -30,8 +30,8 @@ public class AkkaService(
|
||||
|
||||
actorSystem = ActorSystem.Create("canavas-management-actor-system", mergedSystemSetup);
|
||||
|
||||
var canvasQueueProps = DependencyResolver.For(actorSystem).Props<CanvasQueueActor>();
|
||||
CanvasQueueActor = actorSystem.ActorOf(canvasQueueProps, "canvasQueue");
|
||||
var canvasQueueProps = DependencyResolver.For(actorSystem).Props<CoursePlannerActor>();
|
||||
CoursePlannerActor = actorSystem.ActorOf(canvasQueueProps, "canvasQueue");
|
||||
var localStorageProps = DependencyResolver.For(actorSystem).Props<LocalStorageActor>();
|
||||
StorageActor = actorSystem.ActorOf(localStorageProps, "localStorage");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user