using CanvasModel.Modules; using LocalModels; using RestSharp; namespace Management.Services.Canvas; public interface ICanvasModuleService { Task> GetModules(ulong courseId); Task CreateModule(ulong courseId, string name); Task UpdateModule(ulong courseId, ulong moduleId, string name, uint position); Task> GetModuleItems(ulong courseId, ulong moduleId); Task>> GetAllModulesItems(ulong courseId, IEnumerable modules); } public class CanvasModuleService: ICanvasModuleService { private readonly IWebRequestor webRequestor; private readonly CanvasServiceUtils utils; public CanvasModuleService(IWebRequestor webRequestor, CanvasServiceUtils utils) { this.webRequestor = webRequestor; this.utils = utils; } 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); var body = new { module = new { name } }; request.AddBody(body); var (newModule, _) = await webRequestor.PostAsync(request); return newModule ?? throw new Exception($"failed to create new canvas module {name}"); } public async Task UpdateModule(ulong courseId, ulong moduleId, string name, uint position) { Console.WriteLine($"Updating Module: {name}"); var url = $"courses/{courseId}/modules/{moduleId}"; var body = new { module = new { name = name, position = position } }; var request = new RestRequest(url); request.AddBody(body); await webRequestor.PutAsync(request); } public async Task> GetModuleItems(ulong courseId, ulong moduleId) { var url = $"courses/{courseId}/modules/{moduleId}/items?include[]=content_details"; var request = new RestRequest(url); var (items, response) = await webRequestor.GetAsync>(request); if (items == null) throw new Exception($"Error getting canvas module items for {url}"); return items.Select(i => i with { ContentDetails = i.ContentDetails == null ? null : i.ContentDetails with { DueAt = i.ContentDetails.DueAt?.ToLocalTime(), LockAt = i.ContentDetails.LockAt?.ToLocalTime(), } } ); } public async Task>> GetAllModulesItems( ulong courseId, IEnumerable modules ) { var itemsTasks = modules.Select( async (m) => { var items = await GetModuleItems(courseId, m.Id); return (m, items); } ); var output = new Dictionary>(); var itemTasksResult = await Task.WhenAll(itemsTasks); foreach (var (module, items) in itemTasksResult) { if (module == null || items == null) throw new Exception( "i'm not sure how we got here, but module and items are null after looking up module items" ); output[module] = items; } return output; } }