This commit is contained in:
2024-02-07 16:21:04 -07:00
parent 292c06ecc9
commit 0881acd1f8
77 changed files with 239 additions and 204 deletions

View File

@@ -122,7 +122,8 @@ public class AssignmentMarkdownTests
LockAt = new DateTime(), LockAt = new DateTime(),
SubmissionTypes = [], SubmissionTypes = [],
LocalAssignmentGroupName = "Final Project", LocalAssignmentGroupName = "Final Project",
Rubric = new List<RubricItem>() { Rubric = new List<RubricItem>()
{
} }
}; };

View File

@@ -72,8 +72,10 @@ public class FileStorageTests
[Test] [Test]
public async Task CourseSettings_CanBeSavedAndLoaded() public async Task CourseSettings_CanBeSavedAndLoaded()
{ {
LocalCourse testCourse = new() { LocalCourse testCourse = new()
Settings = new() { {
Settings = new()
{
AssignmentGroups = [], AssignmentGroups = [],
Name = "Test Course with settings", Name = "Test Course with settings",
DaysOfWeek = [DayOfWeek.Monday, DayOfWeek.Wednesday], DaysOfWeek = [DayOfWeek.Monday, DayOfWeek.Wednesday],
@@ -96,10 +98,12 @@ public class FileStorageTests
[Test] [Test]
public async Task EmptyCourseModules_CanBeSavedAndLoaded() public async Task EmptyCourseModules_CanBeSavedAndLoaded()
{ {
LocalCourse testCourse = new() { LocalCourse testCourse = new()
{
Settings = new() { Name = "Test Course with modules" }, Settings = new() { Name = "Test Course with modules" },
Modules = [ Modules = [
new() { new()
{
Name = "test module 1", Name = "test module 1",
Assignments = [], Assignments = [],
Quizzes = [] Quizzes = []
@@ -118,13 +122,16 @@ public class FileStorageTests
[Test] [Test]
public async Task CourseModules_WithAssignments_CanBeSavedAndLoaded() public async Task CourseModules_WithAssignments_CanBeSavedAndLoaded()
{ {
LocalCourse testCourse = new() { LocalCourse testCourse = new()
{
Settings = new() { Name = "Test Course with modules and assignments" }, Settings = new() { Name = "Test Course with modules and assignments" },
Modules = [ Modules = [
new() { new()
{
Name = "test module 1 with assignments", Name = "test module 1 with assignments",
Assignments = [ Assignments = [
new () { new()
{
Name = "test assignment", Name = "test assignment",
Description = "here is the description", Description = "here is the description",
DueAt = new DateTime(), DueAt = new DateTime(),
@@ -156,14 +163,17 @@ public class FileStorageTests
[Test] [Test]
public async Task CourseModules_WithQuizzes_CanBeSavedAndLoaded() public async Task CourseModules_WithQuizzes_CanBeSavedAndLoaded()
{ {
LocalCourse testCourse = new() { LocalCourse testCourse = new()
{
Settings = new() { Name = "Test Course with modules and quiz" }, Settings = new() { Name = "Test Course with modules and quiz" },
Modules = [ Modules = [
new() { new()
{
Name = "test module 1 with quiz", Name = "test module 1 with quiz",
Assignments = [], Assignments = [],
Quizzes = [ Quizzes = [
new() { new()
{
Name = "Test Quiz", Name = "Test Quiz",
Description = "quiz description", Description = "quiz description",
LockAt = new DateTime(2022, 10, 3, 12, 5, 0), LockAt = new DateTime(2022, 10, 3, 12, 5, 0),
@@ -172,7 +182,8 @@ public class FileStorageTests
OneQuestionAtATime = true, OneQuestionAtATime = true,
LocalAssignmentGroupName = "Assignments", LocalAssignmentGroupName = "Assignments",
Questions = [ Questions = [
new () { new()
{
Text = "test essay", Text = "test essay",
QuestionType = QuestionType.ESSAY, QuestionType = QuestionType.ESSAY,
Points = 1 Points = 1
@@ -196,8 +207,10 @@ public class FileStorageTests
[Test] [Test]
public async Task MarkdownStorage_FullyPopulated_DoesNotLoseData() public async Task MarkdownStorage_FullyPopulated_DoesNotLoseData()
{ {
LocalCourse testCourse = new() { LocalCourse testCourse = new()
Settings = new () { {
Settings = new()
{
AssignmentGroups = [], AssignmentGroups = [],
Name = "Test Course with lots of data", Name = "Test Course with lots of data",
DaysOfWeek = [DayOfWeek.Monday, DayOfWeek.Wednesday], DaysOfWeek = [DayOfWeek.Monday, DayOfWeek.Wednesday],
@@ -206,10 +219,12 @@ public class FileStorageTests
DefaultDueTime = new() { Hour = 1, Minute = 59 }, DefaultDueTime = new() { Hour = 1, Minute = 59 },
}, },
Modules = [ Modules = [
new() { new()
{
Name = "new test module", Name = "new test module",
Assignments = [ Assignments = [
new() { new()
{
Name = "test assignment", Name = "test assignment",
Description = "here is the description", Description = "here is the description",
DueAt = new DateTime(), DueAt = new DateTime(),
@@ -223,7 +238,8 @@ public class FileStorageTests
} }
], ],
Quizzes = [ Quizzes = [
new() { new()
{
Name = "Test Quiz", Name = "Test Quiz",
Description = "quiz description", Description = "quiz description",
LockAt = new DateTime(), LockAt = new DateTime(),
@@ -233,7 +249,8 @@ public class FileStorageTests
LocalAssignmentGroupName = "someId", LocalAssignmentGroupName = "someId",
AllowedAttempts = -1, AllowedAttempts = -1,
Questions = [ Questions = [
new() { new()
{
Text = "test short answer", Text = "test short answer",
QuestionType = QuestionType.SHORT_ANSWER, QuestionType = QuestionType.SHORT_ANSWER,
Points = 1 Points = 1
@@ -257,8 +274,10 @@ public class FileStorageTests
[Test] [Test]
public async Task MarkdownStorage_CanPersistPages() public async Task MarkdownStorage_CanPersistPages()
{ {
LocalCourse testCourse = new() { LocalCourse testCourse = new()
Settings = new () { {
Settings = new()
{
AssignmentGroups = [], AssignmentGroups = [],
Name = "Test Course with page", Name = "Test Course with page",
DaysOfWeek = [DayOfWeek.Monday, DayOfWeek.Wednesday], DaysOfWeek = [DayOfWeek.Monday, DayOfWeek.Wednesday],
@@ -267,10 +286,12 @@ public class FileStorageTests
DefaultDueTime = new() { Hour = 1, Minute = 59 }, DefaultDueTime = new() { Hour = 1, Minute = 59 },
}, },
Modules = [ Modules = [
new(){ new()
{
Name = "page test module", Name = "page test module",
Pages = [ Pages = [
new () { new()
{
Name = "test page persistence", Name = "test page persistence",
DueAt = new DateTime(), DueAt = new DateTime(),
Text = "this is some\n## markdown\n" Text = "this is some\n## markdown\n"

View File

@@ -1,3 +1,3 @@
global using NUnit.Framework;
global using FluentAssertions;
global using System.Text.Json; global using System.Text.Json;
global using FluentAssertions;
global using NUnit.Framework;

View File

@@ -45,7 +45,8 @@ public class DroppableQuiz : ComponentBase
.Select(q => .Select(q =>
q.Name + q.Description != Quiz.Name + Quiz.Description q.Name + q.Description != Quiz.Name + Quiz.Description
? q : ? q :
q with { q with
{
DueAt = defaultDueTimeDate, DueAt = defaultDueTimeDate,
LockAt = q.LockAt > defaultDueTimeDate ? q.LockAt : defaultDueTimeDate LockAt = q.LockAt > defaultDueTimeDate ? q.LockAt : defaultDueTimeDate
} }

View File

@@ -1,24 +1,23 @@
global using System.Text.Json.Serialization;
global using System.Text.Json;
global using System.ComponentModel.DataAnnotations; global using System.ComponentModel.DataAnnotations;
global using Management.Services.Canvas; global using System.Text.Json;
global using Management.Services; global using System.Text.Json.Serialization;
global using CanvasModel.EnrollmentTerms;
global using CanvasModel.Courses;
global using CanvasModel; global using CanvasModel;
global using CanvasModel.Courses;
global using CanvasModel.EnrollmentTerms;
global using LocalModels; global using LocalModels;
global using Management.Planner; global using Management.Planner;
global using Management.Web.Shared.Components; global using Management.Services;
global using Management.Services.Canvas;
global using Management.Web.Shared; global using Management.Web.Shared;
global using Management.Web.Shared.Components;
using dotenv.net; using dotenv.net;
using Microsoft.AspNetCore.Hosting.Server; using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.AspNetCore.Hosting.Server.Features; using Microsoft.AspNetCore.Hosting.Server.Features;
using OpenTelemetry;
using OpenTelemetry.Logs; using OpenTelemetry.Logs;
using OpenTelemetry.Metrics; using OpenTelemetry.Metrics;
using OpenTelemetry.Resources; using OpenTelemetry.Resources;
using OpenTelemetry.Trace; using OpenTelemetry.Trace;
using OpenTelemetry;
DotEnv.Load(); DotEnv.Load();

View File

@@ -1,14 +1,14 @@
using CanvasModel.EnrollmentTerms;
using CanvasModel.Courses;
using CanvasModel;
using LocalModels;
using CanvasModel.Assignments;
using CanvasModel.Modules;
using Management.Services.Canvas;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using CanvasModel.Quizzes; using CanvasModel;
using Management.Services; using CanvasModel.Assignments;
using CanvasModel.Courses;
using CanvasModel.EnrollmentTerms;
using CanvasModel.Modules;
using CanvasModel.Pages; using CanvasModel.Pages;
using CanvasModel.Quizzes;
using LocalModels;
using Management.Services;
using Management.Services.Canvas;
namespace Management.Planner; namespace Management.Planner;
@@ -181,8 +181,12 @@ public class CoursePlanner
CanvasAssignmentGroups = await canvas.AssignmentGroups.GetAll(canvasCourseId); CanvasAssignmentGroups = await canvas.AssignmentGroups.GetAll(canvasCourseId);
LocalCourse = LocalCourse with {Settings = LocalCourse.Settings with { LocalCourse = LocalCourse with
AssignmentGroups = LocalCourse.Settings.AssignmentGroups.Select(g => { {
Settings = LocalCourse.Settings with
{
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 return canvasGroup == null
? g ? g

View File

@@ -39,7 +39,8 @@ public static partial class ModuleSyncronizationExtensions
{ {
var canvasModuleItems = await canvas.Modules.GetModuleItems(canvasId, moduleCanvasId); var canvasModuleItems = await canvas.Modules.GetModuleItems(canvasId, moduleCanvasId);
var moduleItemsInCorrectOrder = canvasModuleItems var moduleItemsInCorrectOrder = canvasModuleItems
.OrderBy(canvasItem => { .OrderBy(canvasItem =>
{
if (canvasItem.Type == "Page") if (canvasItem.Type == "Page")
{ {

View File

@@ -1,3 +1,3 @@
global using System.Text.Json.Serialization;
global using System.Text.Json; global using System.Text.Json;
global using System.Text.Json.Serialization;
global using Microsoft.Extensions.Logging; global using Microsoft.Extensions.Logging;

View File

@@ -63,10 +63,12 @@ public class CanvasModuleService
if (items == null) if (items == null)
throw new Exception($"Error getting canvas module items for {url}"); throw new Exception($"Error getting canvas module items for {url}");
return items.Select(i => return items.Select(i =>
i with { i with
{
ContentDetails = i.ContentDetails == null ContentDetails = i.ContentDetails == null
? null ? null
: i.ContentDetails with { : i.ContentDetails with
{
DueAt = i.ContentDetails.DueAt?.ToLocalTime(), DueAt = i.ContentDetails.DueAt?.ToLocalTime(),
LockAt = i.ContentDetails.LockAt?.ToLocalTime(), LockAt = i.ContentDetails.LockAt?.ToLocalTime(),
} }

View File

@@ -123,8 +123,10 @@ public class CanvasQuizService(
activity?.SetCustomProperty("canvasQuizId", canvasQuizId); activity?.SetCustomProperty("canvasQuizId", canvasQuizId);
activity?.SetTag("canvas syncronization", true); activity?.SetTag("canvas syncronization", true);
var order = questionAndPositions.OrderBy(t => t.position).Select(tuple => { var order = questionAndPositions.OrderBy(t => t.position).Select(tuple =>
return new { {
return new
{
type = "question", type = "question",
id = tuple.question.Id.ToString(), id = tuple.question.Id.ToString(),
}; };
@@ -184,7 +186,8 @@ public class CanvasQuizService(
{ {
if (q.QuestionType == QuestionType.MATCHING) if (q.QuestionType == QuestionType.MATCHING)
return q.Answers return q.Answers
.Select(a => new { .Select(a => new
{
answer_match_left = a.Text, answer_match_left = a.Text,
answer_match_right = a.MatchedText answer_match_right = a.MatchedText
}) })

View File

@@ -1,11 +1,11 @@
using Microsoft.Extensions.Logging;
using CanvasModel; using CanvasModel;
using CanvasModel.Assignments; using CanvasModel.Assignments;
using CanvasModel.Courses; using CanvasModel.Courses;
using CanvasModel.EnrollmentTerms; using CanvasModel.EnrollmentTerms;
using CanvasModel.Modules; using CanvasModel.Modules;
using RestSharp;
using CanvasModel.Pages; using CanvasModel.Pages;
using Microsoft.Extensions.Logging;
using RestSharp;
namespace Management.Services.Canvas; namespace Management.Services.Canvas;

View File

@@ -45,12 +45,15 @@ public class WebRequestor : IWebRequestor
var response = await client.ExecutePostAsync(request); var response = await client.ExecutePostAsync(request);
if (isRateLimited(response)) { if (isRateLimited(response))
if(retryCount < rateLimitRetryCount){ {
if (retryCount < rateLimitRetryCount)
{
logger.LogInformation($"hit rate limit on post, retry count is {retryCount} / {rateLimitRetryCount}, retrying"); logger.LogInformation($"hit rate limit on post, retry count is {retryCount} / {rateLimitRetryCount}, retrying");
Console.WriteLine($"hit rate limit on post, retry count is {retryCount} / {rateLimitRetryCount}, retrying"); Console.WriteLine($"hit rate limit on post, retry count is {retryCount} / {rateLimitRetryCount}, retrying");
Thread.Sleep(rateLimitSleepInterval); Thread.Sleep(rateLimitSleepInterval);
return await rateLimitAwarePostAsync(request, retryCount + 1);} return await rateLimitAwarePostAsync(request, retryCount + 1);
}
} }
if (!response.IsSuccessful) if (!response.IsSuccessful)