diff --git a/Management.Web/Pages/Index.razor b/Management.Web/Pages/Index.razor index 69a572a..5cd9450 100644 --- a/Management.Web/Pages/Index.razor +++ b/Management.Web/Pages/Index.razor @@ -84,6 +84,11 @@ > Sync With Canvas + + @if(planner.LoadingCanvasData) + { + + } } diff --git a/Management.Web/Program.cs b/Management.Web/Program.cs index 47f19cc..054e707 100644 --- a/Management.Web/Program.cs +++ b/Management.Web/Program.cs @@ -1,6 +1,7 @@ global using System.Text.Json.Serialization; global using System.Text.Json; global using System.ComponentModel.DataAnnotations; +global using Management.Services.Canvas; global using CanvasModel.EnrollmentTerms; global using CanvasModel.Courses; global using CanvasModel; @@ -19,8 +20,12 @@ var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddRazorPages(); builder.Services.AddServerSideBlazor(); + builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); builder.Services.AddScoped(); + builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); diff --git a/Management.Web/Shared/Course/CourseDetails.razor b/Management.Web/Shared/Course/CourseDetails.razor index fe7f1ca..bd5108f 100644 --- a/Management.Web/Shared/Course/CourseDetails.razor +++ b/Management.Web/Shared/Course/CourseDetails.razor @@ -14,19 +14,24 @@ } protected override async Task OnInitializedAsync() { - if( - planner.CanvasAssignments == null - && planner.LocalCourse != null - && planner.LocalCourse.CanvasId != null - ) - { - var canvasId = planner.LocalCourse.CanvasId ?? throw new Exception("no canvas id found for selected course"); - planner.CanvasAssignments = await canvas.GetAssignments(canvasId); - planner.CanvasModules = await canvas.GetModules(canvasId); - System.Console.WriteLine(JsonSerializer.Serialize(planner.CanvasAssignments)); - } - await base.OnInitializedAsync(); } + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if(firstRender) + { + if( + planner.CanvasAssignments == null + && planner.LocalCourse != null + && planner.LocalCourse.CanvasId != null + ) + { + await planner.LoadCanvasData(); + } + + } + } + + private void reload() { diff --git a/Management.Web/Shared/Module/Assignment/AssignmentDetails.razor b/Management.Web/Shared/Module/Assignment/AssignmentDetails.razor index bdda72c..01eb365 100644 --- a/Management.Web/Shared/Module/Assignment/AssignmentDetails.razor +++ b/Management.Web/Shared/Module/Assignment/AssignmentDetails.razor @@ -140,7 +140,19 @@ @if(isSyncedWithCanvas) { -
Synced With Canvas
+ @if(planner.LocalCourse != null + && planner.LocalCourse.CanvasId != null + && planner.CanvasAssignments != null + && planner.CanvasModules != null + && planner.AssignmentNeedsUpdates(Assignment) + ) + { +
need to update canvas
+ } + else + { +
Canvas is up to date
+ } } else { diff --git a/Management/Features/Configuration/CoursePlanner.cs b/Management/Features/Configuration/CoursePlanner.cs index 3d17cc6..483fd59 100644 --- a/Management/Features/Configuration/CoursePlanner.cs +++ b/Management/Features/Configuration/CoursePlanner.cs @@ -4,11 +4,14 @@ using CanvasModel; using LocalModels; using CanvasModel.Assignments; using CanvasModel.Modules; +using Management.Services.Canvas; +using System.Text.RegularExpressions; public class CoursePlanner { private readonly YamlManager yamlManager; private readonly CanvasService canvas; + public bool LoadingCanvasData { get; internal set; } = false; public CoursePlanner(YamlManager yamlManager, CanvasService canvas) { @@ -29,7 +32,7 @@ public class CoursePlanner return; } - var verifiedCourse = verifyCourse(value); + var verifiedCourse = cleanupCourse(value); // ignore initial load of course if (_localCourse != null) { @@ -41,7 +44,7 @@ public class CoursePlanner } public event Action? StateHasChanged; - private LocalCourse verifyCourse(LocalCourse incomingCourse) + private LocalCourse cleanupCourse(LocalCourse incomingCourse) { var modulesWithUniqueAssignments = incomingCourse.Modules.Select( module => module with { Assignments = module.Assignments.DistinctBy(a => a.id) } @@ -53,8 +56,42 @@ public class CoursePlanner }; } - public IEnumerable? CanvasAssignments { get; set; } = null; - public IEnumerable? CanvasModules { get; set; } = null; + private IEnumerable? canvasAssignments = null; + + public IEnumerable? CanvasAssignments + { + get => canvasAssignments; + set + { + canvasAssignments = value; + StateHasChanged?.Invoke(); + } + } + private IEnumerable? canvasModules = null; + public IEnumerable? CanvasModules + { + get => canvasModules; + set + { + canvasModules = value; + StateHasChanged?.Invoke(); + } + } + + public async Task LoadCanvasData() + { + LoadingCanvasData = true; + StateHasChanged?.Invoke(); + + Thread.Sleep(1000); + var canvasId = + LocalCourse?.CanvasId ?? throw new Exception("no canvas id found for selected course"); + CanvasAssignments = await canvas.Assignments.GetAll(canvasId); + CanvasModules = await canvas.GetModules(canvasId); + + LoadingCanvasData = false; + StateHasChanged?.Invoke(); + } public async Task SyncWithCanvas() { @@ -66,12 +103,18 @@ public class CoursePlanner ) return; + LoadingCanvasData = true; + StateHasChanged?.Invoke(); + var canvasId = LocalCourse.CanvasId ?? throw new Exception("no course canvas id to sync with canvas"); await ensureAllModulesCreated(canvasId); await reloadModules_UpdateLocalModulesWithNewId(canvasId); await ensureAllAssignmentsCreated_updateIds(canvasId); + + LoadingCanvasData = false; + StateHasChanged?.Invoke(); } private async Task reloadModules_UpdateLocalModulesWithNewId(ulong canvasId) @@ -139,21 +182,121 @@ public class CoursePlanner throw new Exception( "cannot create canvas assignment if local course is null or other values not set" ); + ulong canvasId = LocalCourse.CanvasId ?? throw new Exception("no canvas id to create course"); - var canvasAssignment = await canvas.CreateAssignment( - courseId: canvasId, - name: localAssignment.name, - submissionTypes: localAssignment.submission_types, - description: localAssignment.description, - dueAt: localAssignment.due_at, - lockAt: localAssignment.lock_at, - pointsPossible: localAssignment.points_possible + var canvasAssignment = CanvasAssignments.FirstOrDefault( + ca => ca.Id == localAssignment.canvasId + ); + string localHtmlDescription = getAssignmentDescriptionHtml(localAssignment); + + if (canvasAssignment != null) + { + var assignmentNeedsUpdates = AssignmentNeedsUpdates(localAssignment); + if (assignmentNeedsUpdates) + { + await canvas.Assignments.Update(courseId: canvasId, localAssignment, localHtmlDescription); + } + return localAssignment; + } + else + { + var createdAssignment = await canvas.Assignments.Create( + courseId: canvasId, + name: localAssignment.name, + submissionTypes: localAssignment.submission_types, + description: localHtmlDescription, + dueAt: localAssignment.due_at, + lockAt: localAssignment.lock_at, + pointsPossible: localAssignment.points_possible + ); + + return localAssignment with + { + canvasId = createdAssignment.Id + }; + } + } + + private string getAssignmentDescriptionHtml(LocalAssignment localAssignment) + { + if (LocalCourse == null) + throw new Exception( + "cannot get assignment description if local course is null or other values not set" + ); + return localAssignment.use_template + ? AssignmentTemplate.GetHtml( + LocalCourse.AssignmentTemplates.First(t => t.Id == localAssignment.template_id), + localAssignment + ) + : Markdig.Markdown.ToHtml(localAssignment.description); + } + + public bool AssignmentNeedsUpdates(LocalAssignment localAssignment) + { + if ( + LocalCourse == null + || LocalCourse.CanvasId == null + || CanvasAssignments == null + || CanvasModules == null + ) + throw new Exception( + "cannot check if assignment needs updates if local course is null or other values not set" + ); + + var canvasAssignment = CanvasAssignments.First(ca => ca.Id == localAssignment.canvasId); + + var localHtmlDescription = getAssignmentDescriptionHtml(localAssignment); + + var canvasHtmlDescription = canvasAssignment.Description; + canvasHtmlDescription = Regex.Replace(canvasHtmlDescription, "", ""); + canvasHtmlDescription = Regex.Replace(canvasHtmlDescription, "", ""); + + var dueDatesSame = canvasAssignment.DueAt == localAssignment.due_at; + var descriptionSame = canvasHtmlDescription == localHtmlDescription; + var nameSame = canvasAssignment.Name == localAssignment.name; + var lockDateSame = canvasAssignment.LockAt == localAssignment.lock_at; + var pointsSame = canvasAssignment.PointsPossible == localAssignment.points_possible; + var submissionTypesSame = canvasAssignment.SubmissionTypes.SequenceEqual( + localAssignment.submission_types.Select(t => t.ToString()) ); - return localAssignment with + if (!dueDatesSame) + Console.WriteLine( + $"Due dates different for {localAssignment.name}, local: {localAssignment.due_at}, in canvas {canvasAssignment.DueAt}" + ); + + if (!descriptionSame) { - canvasId = canvasAssignment.Id - }; + Console.WriteLine($"descriptions different for {localAssignment.name}"); + Console.WriteLine("Local Description:"); + Console.WriteLine(localHtmlDescription); + Console.WriteLine("Canvas Description: "); + Console.WriteLine(canvasHtmlDescription); + } + + if (!nameSame) + Console.WriteLine( + $"names different for {localAssignment.name}, local: {localAssignment.name}, in canvas {canvasAssignment.Name}" + ); + if (!lockDateSame) + Console.WriteLine( + $"Lock Dates different for {localAssignment.name}, local: {localAssignment.lock_at}, in canvas {canvasAssignment.LockAt}" + ); + if (!pointsSame) + Console.WriteLine( + $"Points different for {localAssignment.name}, local: {localAssignment.points_possible}, in canvas {canvasAssignment.PointsPossible}" + ); + if (!submissionTypesSame) + Console.WriteLine( + $"Submission Types different for {localAssignment.name}, local: {JsonSerializer.Serialize(localAssignment.submission_types.Select(t => t.ToString()))}, in canvas {JsonSerializer.Serialize(canvasAssignment.SubmissionTypes)}" + ); + + return !nameSame + || !dueDatesSame + || !lockDateSame + || !descriptionSame + || !pointsSame + || !submissionTypesSame; } public void Clear() diff --git a/Management/Models/Local/LocalAssignment.cs b/Management/Models/Local/LocalAssignment.cs index 6393974..cd86d00 100644 --- a/Management/Models/Local/LocalAssignment.cs +++ b/Management/Models/Local/LocalAssignment.cs @@ -1,3 +1,5 @@ +using LocalModels; + public record RubricItem { public static readonly string extraCredit = "(Extra Credit) "; diff --git a/Management/Services/Canvas/CanvasAssignmentService.cs b/Management/Services/Canvas/CanvasAssignmentService.cs new file mode 100644 index 0000000..eaa914e --- /dev/null +++ b/Management/Services/Canvas/CanvasAssignmentService.cs @@ -0,0 +1,89 @@ +using CanvasModel.Assignments; +using RestSharp; + +namespace Management.Services.Canvas; + +public class CanvasAssignmentService +{ + private IWebRequestor webRequestor; + private readonly CanvasServiceUtils utils; + + public CanvasAssignmentService(IWebRequestor webRequestor, CanvasServiceUtils utils) + { + this.webRequestor = webRequestor; + this.utils = utils; + } + + public async Task> GetAll(ulong courseId) + { + var url = $"courses/{courseId}/assignments"; + var request = new RestRequest(url); + var assignmentResponse = await utils.PaginatedRequest>(request); + return assignmentResponse.SelectMany( + assignments => + assignments.Select( + a => + a with + { + DueAt = a.DueAt?.ToLocalTime(), + LockAt = a.LockAt?.ToLocalTime() + } + ) + ); + } + + public async Task Create( + ulong courseId, + string name, + IEnumerable submissionTypes, + string? description, + DateTime? dueAt, + DateTime? lockAt, + int? pointsPossible + ) + { + System.Console.WriteLine($"creating assignment: {name}"); + var url = $"courses/{courseId}/assignments"; + var request = new RestRequest(url); + var body = new CanvasAssignmentCreationRequest() + { + name = name, + submission_types = submissionTypes.Select(t => t.ToString()), + description = description ?? "", + due_at = dueAt, + lock_at = lockAt, + points_possible = pointsPossible ?? 0 + }; + request.AddHeader("Content-Type", "application/json"); + var bodyObj = new { assignment = body }; + request.AddBody(bodyObj); + var (canvasAssignment, response) = await webRequestor.PostAsync(request); + if (canvasAssignment == null) + throw new Exception("created canvas assignment was null"); + return canvasAssignment with + { + DueAt = canvasAssignment.DueAt?.ToLocalTime(), + LockAt = canvasAssignment.LockAt?.ToLocalTime() + }; + } + + public async Task Update(ulong courseId, LocalAssignment localAssignment, string htmlDescription) + { + System.Console.WriteLine($"updating assignment: {localAssignment.name}"); + var url = $"courses/{courseId}/assignments/{localAssignment.canvasId}"; + var request = new RestRequest(url); + var body = new CanvasAssignmentCreationRequest() + { + name = localAssignment.name, + submission_types = localAssignment.submission_types.Select(t => t.ToString()), + description = htmlDescription, + due_at = localAssignment.due_at, + lock_at = localAssignment.lock_at, + points_possible = localAssignment.points_possible + }; + request.AddHeader("Content-Type", "application/json"); + var bodyObj = new { assignment = body }; + request.AddBody(bodyObj); + await webRequestor.PutAsync(request); + } +} diff --git a/Management/Services/CanvasRequests/CanvasAssignmentCreationRequest.cs b/Management/Services/Canvas/CanvasRequests/CanvasAssignmentCreationRequest.cs similarity index 89% rename from Management/Services/CanvasRequests/CanvasAssignmentCreationRequest.cs rename to Management/Services/Canvas/CanvasRequests/CanvasAssignmentCreationRequest.cs index 1f37595..66743a9 100644 --- a/Management/Services/CanvasRequests/CanvasAssignmentCreationRequest.cs +++ b/Management/Services/Canvas/CanvasRequests/CanvasAssignmentCreationRequest.cs @@ -1,3 +1,6 @@ + +namespace Management.Services.Canvas; + public record CanvasAssignmentCreationRequest { public string? name { get; set; } diff --git a/Management/Services/Canvas/CanvasService.cs b/Management/Services/Canvas/CanvasService.cs new file mode 100644 index 0000000..28f85eb --- /dev/null +++ b/Management/Services/Canvas/CanvasService.cs @@ -0,0 +1,93 @@ +using CanvasModel; +using CanvasModel.Assignments; +using CanvasModel.Courses; +using CanvasModel.EnrollmentTerms; +using CanvasModel.Modules; +using RestSharp; +namespace Management.Services.Canvas; + +public class CanvasService +{ + private readonly IWebRequestor webRequestor; + private readonly CanvasServiceUtils utils; + + public CanvasAssignmentService Assignments { get; } + + public CanvasService( + IWebRequestor webRequestor, + CanvasServiceUtils utils, + CanvasAssignmentService Assignments + ) + { + this.webRequestor = webRequestor; + this.utils = utils; + this.Assignments = Assignments; + } + + public async Task> GetTerms() + { + var url = $"accounts/10/terms"; + + var request = new RestRequest(url); + var termResponses = await utils.PaginatedRequest(request); + var terms = termResponses.Select(r => r.EnrollmentTerms).SelectMany(s => s).ToArray(); + return terms; + } + + public async Task> GetCourses(ulong termId) + { + var url = $"courses"; + var request = new RestRequest(url); + var coursesResponse = await utils.PaginatedRequest>(request); + return coursesResponse.SelectMany(c => c).Where(c => c.EnrollmentTermId == termId).ToArray(); + } + + public async Task GetCourse(ulong courseId) + { + var url = $"courses/{courseId}"; + var request = new RestRequest(url); + var (data, response) = await webRequestor.GetAsync(request); + + if (data == null) + { + System.Console.WriteLine(response.Content); + System.Console.WriteLine(response.ResponseUri); + throw new Exception("error getting course from canvas"); + } + return data; + } + + public async Task> GetModules(ulong courseId) + { + var url = $"courses/{courseId}/modules"; + var request = new RestRequest(url); + var modules = await utils.PaginatedRequest>(request); + return modules.SelectMany(c => c).ToArray(); + } + + public async Task CreateModule(ulong courseId, string name) + { + Console.WriteLine($"Creating Module: {name}"); + var url = $"courses/{courseId}/modules"; + var request = new RestRequest(url); + request.AddParameter("module[name]", name); + + await webRequestor.PostAsync(request); + } + + public async Task> GetCurrentTermsFor( + DateTime? _queryDate = null + ) + { + DateTime queryDate = _queryDate ?? DateTime.Now; + + var terms = await GetTerms(); + + var currentTerms = terms + .Where(t => t.EndAt != null && t.EndAt > queryDate && t.EndAt < queryDate.AddYears(1)) + .Take(3) + .OrderBy(t => t.StartAt); + + return currentTerms; + } +} diff --git a/Management/Services/Canvas/CanvasServiceUtils.cs b/Management/Services/Canvas/CanvasServiceUtils.cs new file mode 100644 index 0000000..1a40e20 --- /dev/null +++ b/Management/Services/Canvas/CanvasServiceUtils.cs @@ -0,0 +1,58 @@ +using RestSharp; + +namespace Management.Services.Canvas; +public class CanvasServiceUtils +{ + private const string BaseUrl = "https://snow.instructure.com/api/v1/"; + private readonly IWebRequestor webRequestor; + public CanvasServiceUtils(IWebRequestor webRequestor) + { + this.webRequestor = webRequestor; + } + + internal async Task> PaginatedRequest(RestRequest request) + { + var requestCount = 1; + request.AddQueryParameter("per_page", "100"); + var (data, response) = await webRequestor.GetAsync(request); + + if (response.ErrorMessage?.Length > 0) + { + System.Console.WriteLine("error in response"); + System.Console.WriteLine(response.ErrorMessage); + throw new Exception("error in response"); + } + + var returnData = data != null ? new T[] { data } : new T[] { }; + var nextUrl = getNextUrl(response.Headers); + + while (nextUrl is not null) + { + requestCount += 1; + RestRequest nextRequest = new RestRequest(nextUrl); + var (nextData, nextResponse) = await webRequestor.GetAsync(nextRequest); + if (nextData is not null) + returnData = returnData.Append(nextData).ToArray(); + nextUrl = getNextUrl(nextResponse.Headers); + } + + System.Console.WriteLine($"Requesting {typeof(T)} took {requestCount} requests"); + + return returnData; + } + + protected static string? getNextUrl(IEnumerable? headers) => + headers + ?.ToList() + .Find(h => h.Name == "Link") + ?.Value?.ToString() + ?.Split(",") + .Where(url => url.Contains("rel=\"next\"")) + .FirstOrDefault() + ?.Split(";") + .FirstOrDefault() + ?.TrimEnd('>') + .TrimStart('<') + .Replace(" ", "") + .Replace(BaseUrl, ""); +} \ No newline at end of file diff --git a/Management/Services/CanvasService.cs b/Management/Services/CanvasService.cs deleted file mode 100644 index 2ef08c8..0000000 --- a/Management/Services/CanvasService.cs +++ /dev/null @@ -1,175 +0,0 @@ -using CanvasModel; -using CanvasModel.Assignments; -using CanvasModel.Courses; -using CanvasModel.EnrollmentTerms; -using CanvasModel.Modules; -using RestSharp; - -public interface ICanvasService -{ - Task> GetCurrentTermsFor(DateTime? _queryDate = null); - Task> GetTerms(); -} - -public class CanvasService : ICanvasService -{ - private const string BaseUrl = "https://snow.instructure.com/api/v1/"; - private readonly IWebRequestor webRequestor; - - public CanvasService(IWebRequestor webRequestor) - { - this.webRequestor = webRequestor; - } - - public async Task> GetTerms() - { - var url = $"accounts/10/terms"; - - var request = new RestRequest(url); - var termResponses = await PaginatedRequest(request); - var terms = termResponses.Select(r => r.EnrollmentTerms).SelectMany(s => s).ToArray(); - return terms; - } - - public async Task> GetCourses(ulong termId) - { - var url = $"courses"; - var request = new RestRequest(url); - var coursesResponse = await PaginatedRequest>(request); - return coursesResponse.SelectMany(c => c).Where(c => c.EnrollmentTermId == termId).ToArray(); - } - - public async Task GetCourse(ulong courseId) - { - var url = $"courses/{courseId}"; - var request = new RestRequest(url); - var (data, response) = await webRequestor.GetAsync(request); - - if (data == null) - { - System.Console.WriteLine(response.Content); - System.Console.WriteLine(response.ResponseUri); - throw new Exception("error getting course from canvas"); - } - return data; - } - - public async Task> GetAssignments(ulong courseId) - { - var url = $"courses/{courseId}/assignments"; - var request = new RestRequest(url); - var assignmentResponse = await PaginatedRequest>(request); - return assignmentResponse.SelectMany(c => c); - } - - public async Task CreateAssignment( - ulong courseId, - string name, - IEnumerable submissionTypes, - string? description, - DateTime? dueAt, - DateTime? lockAt, - int? pointsPossible - ) - { - System.Console.WriteLine($"creating assignment: {name}"); - var url = $"courses/{courseId}/assignments"; - var request = new RestRequest(url); - var body = new CanvasAssignmentCreationRequest() - { - name = name, - submission_types = submissionTypes.Select(t => t.ToString()), - description = description, - due_at = dueAt, - lock_at = lockAt, - points_possible = pointsPossible - }; - request.AddHeader("Content-Type", "application/json"); - var bodyObj = new { assignment = body }; - request.AddBody(bodyObj); - var (canvasAssignment, response) = await webRequestor.PostAsync(request); - if (canvasAssignment == null) - throw new Exception("created canvas assignment was null"); - return canvasAssignment; - } - - public async Task> GetModules(ulong courseId) - { - var url = $"courses/{courseId}/modules"; - var request = new RestRequest(url); - var modules = await PaginatedRequest>(request); - return modules.SelectMany(c => c).ToArray(); - } - - public async Task CreateModule(ulong courseId, string name) - { - Console.WriteLine($"Creating Module: {name}"); - var url = $"courses/{courseId}/modules"; - var request = new RestRequest(url); - request.AddParameter("module[name]", name); - - await webRequestor.PostAsync(request); - } - - private async Task> PaginatedRequest(RestRequest request) - { - var requestCount = 1; - request.AddQueryParameter("per_page", "100"); - var (data, response) = await webRequestor.GetAsync(request); - - if (response.ErrorMessage?.Length > 0) - { - System.Console.WriteLine("error in response"); - System.Console.WriteLine(response.ErrorMessage); - throw new Exception("error in response"); - } - - var returnData = data != null ? new T[] { data } : new T[] { }; - var nextUrl = getNextUrl(response.Headers); - - while (nextUrl is not null) - { - requestCount += 1; - RestRequest nextRequest = new RestRequest(nextUrl); - var (nextData, nextResponse) = await webRequestor.GetAsync(nextRequest); - if (nextData is not null) - returnData = returnData.Append(nextData).ToArray(); - nextUrl = getNextUrl(nextResponse.Headers); - } - - System.Console.WriteLine($"Requesting {typeof(T)} took {requestCount} requests"); - - return returnData; - } - - private static string? getNextUrl(IEnumerable? headers) => - headers - ?.ToList() - .Find(h => h.Name == "Link") - ?.Value?.ToString() - ?.Split(",") - .Where(url => url.Contains("rel=\"next\"")) - .FirstOrDefault() - ?.Split(";") - .FirstOrDefault() - ?.TrimEnd('>') - .TrimStart('<') - .Replace(" ", "") - .Replace(BaseUrl, ""); - - public async Task> GetCurrentTermsFor( - DateTime? _queryDate = null - ) - { - DateTime queryDate = _queryDate ?? DateTime.Now; - - var terms = await GetTerms(); - - var currentTerms = terms - .Where(t => t.EndAt != null && t.EndAt > queryDate && t.EndAt < queryDate.AddYears(1)) - .Take(3) - .OrderBy(t => t.StartAt); - - return currentTerms; - } -} diff --git a/Management/Services/IWebRequestor.cs b/Management/Services/IWebRequestor.cs index 7523348..9a36444 100644 --- a/Management/Services/IWebRequestor.cs +++ b/Management/Services/IWebRequestor.cs @@ -6,4 +6,6 @@ public interface IWebRequestor Task<(T?, RestResponse)> GetAsync(RestRequest request); Task PostAsync(RestRequest request); Task<(T?, RestResponse)> PostAsync(RestRequest request); + Task PutAsync(RestRequest request); + Task<(T?, RestResponse)> PutAsync(RestRequest request); } diff --git a/Management/Services/WebRequestor.cs b/Management/Services/WebRequestor.cs index 3eb3c8d..85c22a0 100644 --- a/Management/Services/WebRequestor.cs +++ b/Management/Services/WebRequestor.cs @@ -46,7 +46,26 @@ public class WebRequestor : IWebRequestor return (Deserialize(response), response); } - public T? Deserialize(RestResponse response) + public async Task PutAsync(RestRequest request) + { + var response = await client.ExecutePutAsync(request); + if (!response.IsSuccessful) + { + System.Console.WriteLine(response.Content); + System.Console.WriteLine(response.ResponseUri); + System.Console.WriteLine("error with response"); + throw new Exception("error with response"); + } + return response; + } + + public async Task<(T?, RestResponse)> PutAsync(RestRequest request) + { + var response = await client.ExecutePutAsync(request); + return (Deserialize(response), response); + } + + private T? Deserialize(RestResponse response) { if (!response.IsSuccessful) {