Skip to content
This repository has been archived by the owner on Sep 4, 2023. It is now read-only.

Code cleanup #40

Merged
merged 16 commits into from
Nov 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Epsilon.Abstractions/Export/ICanvasModuleExporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Epsilon.Abstractions.Export;

public interface ICanvasModuleExporter : IExporter<IEnumerable<Module>>
public interface ICanvasModuleExporter : IExporter<IAsyncEnumerable<ModuleOutcomeResultCollection>>
{

}
2 changes: 1 addition & 1 deletion Epsilon.Abstractions/Export/IExporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ public interface IExporter<in T>
{
public IEnumerable<string> Formats { get; }

void Export(T data, string format);
Task Export(T data, string format);
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace Epsilon.Http.Abstractions;
namespace Epsilon.Abstractions.Http;

public abstract class HttpService
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace Epsilon.Http.Abstractions.Json;
namespace Epsilon.Abstractions.Http.Json;

public static class HttpClientJsonExtensions
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System.Text.Json;

namespace Epsilon.Http.Abstractions.Json;
namespace Epsilon.Abstractions.Http.Json;

public static class HttpResponseMessageJsonExtensions
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ namespace Epsilon.Canvas.Abstractions;

public interface ICanvasModuleCollectionFetcher
{
public Task<IEnumerable<Module>> GetAll(int courseId);
public IAsyncEnumerable<ModuleOutcomeResultCollection> GetAll(int courseId);
}
7 changes: 1 addition & 6 deletions Epsilon.Canvas.Abstractions/Model/Module.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Text.Json.Serialization;
using Epsilon.Canvas.Abstractions.Response;

namespace Epsilon.Canvas.Abstractions.Model;

Expand All @@ -8,8 +7,4 @@ public record Module(
[property: JsonPropertyName("name")] string Name,
[property: JsonPropertyName("items_count")] int Count,
[property: JsonPropertyName("items")] IEnumerable<ModuleItem>? Items
)
{
[JsonIgnore]
public OutcomeResultCollection Collection { get; set; }
}
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
namespace Epsilon.Canvas.Abstractions.Model;

public record ModuleOutcomeResultCollection(Module Module, OutcomeResultCollection Collection);
19 changes: 8 additions & 11 deletions Epsilon.Canvas.Abstractions/Model/OutcomeResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,15 @@ public record OutcomeResult(
[property: JsonPropertyName("links")] OutcomeResultLink Link
)
{
public string Grade()
public string? Grade()
{
switch (Score)
return Score switch
{
default:
return "Unsatisfactory";
case 3:
return "Satisfactory";
case 4:
return "Good";
case 5:
return "Outstanding";
}
<= 2 => "Unsatisfactory",
3 => "Satisfactory",
4 => "Good",
5 => "Outstanding",
_ => null,
};
}
}
3 changes: 1 addition & 2 deletions Epsilon.Canvas.Abstractions/Model/OutcomeResultCollection.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System.Text.Json.Serialization;
using Epsilon.Canvas.Abstractions.Model;

namespace Epsilon.Canvas.Abstractions.Response;
namespace Epsilon.Canvas.Abstractions.Model;

public record OutcomeResultCollection(
[property: JsonPropertyName("outcome_results")] IEnumerable<OutcomeResult> OutcomeResults,
Expand Down
10 changes: 4 additions & 6 deletions Epsilon.Canvas.Abstractions/Model/OutcomeResultCollectionLink.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,13 @@
namespace Epsilon.Canvas.Abstractions.Model;

public record OutcomeResultCollectionLink(
[property: JsonPropertyName("outcomes")] IEnumerable<Outcome>? Outcomes,
[property: JsonPropertyName("alignments")] IEnumerable<Alignment>? Alignments
[property: JsonPropertyName("outcomes")] IEnumerable<Outcome> Outcomes,
[property: JsonPropertyName("alignments")] IEnumerable<Alignment> Alignments
)
{
public IDictionary<string, Outcome> OutcomesDictionary => Outcomes
.DistinctBy(static o => o.Id)
public IDictionary<string, Outcome> OutcomesDictionary => Outcomes.DistinctBy(static o => o.Id)
.ToDictionary(static o => o.Id.ToString(), static o => o);

public IDictionary<string, Alignment> AlignmentsDictionary => Alignments
.DistinctBy(static a => a.Id)
public IDictionary<string, Alignment> AlignmentsDictionary => Alignments.DistinctBy(static a => a.Id)
.ToDictionary(static a => a.Id, static a => a);
}
12 changes: 0 additions & 12 deletions Epsilon.Canvas.Abstractions/Model/User.cs

This file was deleted.

1 change: 0 additions & 1 deletion Epsilon.Canvas.Abstractions/Service/IOutcomeHttpService.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using Epsilon.Canvas.Abstractions.Model;
using Epsilon.Canvas.Abstractions.Response;

namespace Epsilon.Canvas.Abstractions.Service;

Expand Down
35 changes: 14 additions & 21 deletions Epsilon.Canvas/CanvasModuleCollectionFetcher.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
using Epsilon.Canvas.Abstractions;
using System.Diagnostics;
using Epsilon.Canvas.Abstractions;
using Epsilon.Canvas.Abstractions.Model;
using Epsilon.Canvas.Abstractions.Response;
using Epsilon.Canvas.Abstractions.Service;
using Microsoft.Extensions.Logging;

namespace Epsilon.Canvas;

public class CanvasModuleCollectionFetcher : ICanvasModuleCollectionFetcher
{
private readonly ILogger<CanvasModuleCollectionFetcher> _logger;
private readonly IModuleHttpService _moduleService;
private readonly IOutcomeHttpService _outcomeService;

Expand All @@ -18,36 +17,30 @@ public CanvasModuleCollectionFetcher(
IOutcomeHttpService outcomeService
)
{
_logger = logger;
_moduleService = moduleService;
_outcomeService = outcomeService;
}

public async Task<IEnumerable<Module>> GetAll(int courseId)
public async IAsyncEnumerable<ModuleOutcomeResultCollection> GetAll(int courseId)
{
_logger.LogInformation("Downloading results...");

var response = await _outcomeService.GetResults(courseId, new[] { "outcomes", "alignments" });

var alignments = response.Links.Alignments
.DistinctBy(static a => a.Id)
.ToDictionary(static a => a.Id, static a => a);

var outcomes = response.Links.Outcomes
.DistinctBy(static o => o.Id)
.ToDictionary(static o => o.Id.ToString(), static o => o);

var modules = await _moduleService.GetAll(courseId, new[] { "items" });
foreach (var module in modules)

Debug.Assert(response != null, nameof(response) + " != null");
Debug.Assert(modules != null, nameof(modules) + " != null");

foreach (var module in modules.ToArray())
{
Debug.Assert(module.Items != null, "module.Items != null");

var ids = module.Items.Select(static i => $"assignment_{i.ContentId}");

module.Collection = new OutcomeResultCollection(
Debug.Assert(response.Links?.Alignments != null, "response.Links?.Alignments != null");

yield return new ModuleOutcomeResultCollection(module, new OutcomeResultCollection(
response.OutcomeResults.Where(r => ids.Contains(r.Link.Alignment)),
response.Links with { Alignments = response.Links.Alignments.Where(a => ids.Contains(a.Id)) }
);
));
}

return modules;
}
}
1 change: 1 addition & 0 deletions Epsilon.Canvas/CanvasServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public static class CanvasServiceCollectionExtensions
{
private const string CanvasHttpClient = "CanvasHttpClient";

// ReSharper disable once UnusedMethodReturnValue.Global
public static IServiceCollection AddCanvas(this IServiceCollection services, IConfiguration config)
{
services.Configure<CanvasSettings>(config);
Expand Down
2 changes: 1 addition & 1 deletion Epsilon.Canvas/Converter/LinkHeaderConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public LinkHeader ConvertFrom(HttpResponseMessage response)
{
if (!response.Headers.Contains("Link"))
{
throw new ArgumentNullException(nameof(response.Headers), "Header does not contain link key");
throw new KeyNotFoundException("Header does not contain link key");
}

return ConvertFrom(response.Headers.GetValues("Link").First());
Expand Down
2 changes: 1 addition & 1 deletion Epsilon.Canvas/Epsilon.Canvas.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\Epsilon.Abstractions\Epsilon.Abstractions.csproj" />
<ProjectReference Include="..\Epsilon.Canvas.Abstractions\Epsilon.Canvas.Abstractions.csproj" />
<ProjectReference Include="..\Epsilon.Http.Abstractions\Epsilon.Http.Abstractions.csproj" />
</ItemGroup>

<ItemGroup>
Expand Down
6 changes: 3 additions & 3 deletions Epsilon.Canvas/Service/AssignmentHttpService.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using Epsilon.Canvas.Abstractions.Model;
using Epsilon.Abstractions.Http;
using Epsilon.Abstractions.Http.Json;
using Epsilon.Canvas.Abstractions.Model;
using Epsilon.Canvas.Abstractions.Service;
using Epsilon.Http.Abstractions;
using Epsilon.Http.Abstractions.Json;

namespace Epsilon.Canvas.Service;

Expand Down
4 changes: 2 additions & 2 deletions Epsilon.Canvas/Service/ModuleHttpService.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
using System.Text;
using Epsilon.Abstractions.Http;
using Epsilon.Abstractions.Http.Json;
using Epsilon.Canvas.Abstractions.Model;
using Epsilon.Canvas.Abstractions.Service;
using Epsilon.Http.Abstractions;
using Epsilon.Http.Abstractions.Json;

namespace Epsilon.Canvas.Service;

Expand Down
13 changes: 7 additions & 6 deletions Epsilon.Canvas/Service/OutcomeHttpService.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
using System.Text;
using Epsilon.Abstractions.Http;
using Epsilon.Abstractions.Http.Json;
using Epsilon.Canvas.Abstractions.Model;
using Epsilon.Canvas.Abstractions.Response;
using Epsilon.Canvas.Abstractions.Service;
using Epsilon.Http.Abstractions;
using Epsilon.Http.Abstractions.Json;

namespace Epsilon.Canvas.Service;

Expand All @@ -30,11 +29,13 @@ public OutcomeHttpService(HttpClient client, IPaginatorHttpService paginator) :
var query = $"?include[]={string.Join("&include[]=", include)}";

var responses = await _paginator.GetAllPages<OutcomeResultCollection>(HttpMethod.Get, url + query);
var responsesArray = responses.ToArray();

return new OutcomeResultCollection(
responses.SelectMany(static r => r.OutcomeResults),
responsesArray.SelectMany(static r => r.OutcomeResults),
new OutcomeResultCollectionLink(
responses.SelectMany(static r => r.Links.Outcomes),
responses.SelectMany(static r => r.Links.Alignments)
responsesArray.SelectMany(static r => r.Links?.Outcomes ?? Array.Empty<Outcome>()),
responsesArray.SelectMany(static r => r.Links?.Alignments ?? Array.Empty<Alignment>())
)
);
}
Expand Down
26 changes: 11 additions & 15 deletions Epsilon.Canvas/Service/PaginatorHttpService.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
using System.Web;
using Epsilon.Abstractions.Http;
using Epsilon.Abstractions.Http.Json;
using Epsilon.Canvas.Abstractions.Converter;
using Epsilon.Canvas.Abstractions.Service;
using Epsilon.Http.Abstractions;
using Epsilon.Http.Abstractions.Json;

namespace Epsilon.Canvas.Service;

public class PaginatorHttpService : HttpService, IPaginatorHttpService
{
private const int Limit = 100;
private readonly ILinkHeaderConverter _headerConverter;

public PaginatorHttpService(HttpClient client, ILinkHeaderConverter headerConverter) : base(client)
Expand All @@ -19,25 +20,20 @@ public async Task<IEnumerable<TResult>> GetAllPages<TResult>(HttpMethod method,
{
var pages = new List<TResult>();
var page = "1";
const int limit = 100;

if (!uri.Contains('?'))
{
uri += "?";
}
else
{
uri += "&";
}
uri += !uri.Contains('?') ? "?" : "&";

do
{
var offset = pages.Count * limit;
var request = new HttpRequestMessage(method, $"{uri}per_page={limit}&offset={offset}&page={page}");
var offset = pages.Count * Limit;
var request = new HttpRequestMessage(method, $"{uri}per_page={Limit}&offset={offset}&page={page}");
var (response, value) = await Client.SendAsync<TResult>(request);
var links = _headerConverter.ConvertFrom(response);

pages.Add(value);
if (value != null)
{
pages.Add(value);
}

if (links.NextLink == null)
{
Expand All @@ -46,7 +42,7 @@ public async Task<IEnumerable<TResult>> GetAllPages<TResult>(HttpMethod method,

var query = HttpUtility.ParseQueryString(new Uri(links.NextLink).Query);
page = query["page"];
} while (pages.Count * limit % limit == 0);
} while (pages.Count * Limit % Limit == 0);

return pages;
}
Expand Down
2 changes: 1 addition & 1 deletion Epsilon.Canvas/Service/SubmissionHttpService.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System.Text;
using Epsilon.Abstractions.Http;
using Epsilon.Canvas.Abstractions.Model;
using Epsilon.Canvas.Abstractions.Service;
using Epsilon.Http.Abstractions;

namespace Epsilon.Canvas.Service;

Expand Down
8 changes: 5 additions & 3 deletions Epsilon.Cli/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ private async Task ExecuteAsync()
}

_logger.LogInformation("Targeting Canvas course: {CourseId}, at {Url}", _canvasSettings.CourseId, _canvasSettings.ApiUrl);
var modules = await _collectionFetcher.GetAll(_canvasSettings.CourseId);
_logger.LogInformation("Downloading results, this may take a few seconds...");
var items = _collectionFetcher.GetAll(_canvasSettings.CourseId);

var formats = _exportOptions.Formats.Split(",");
var exporters = _exporterCollection.DetermineExporters(formats).ToArray();
Expand All @@ -73,7 +74,8 @@ private async Task ExecuteAsync()
foreach (var (format, exporter) in exporters)
{
_logger.LogInformation("Exporting to {Format} using {Exporter}...", format, exporter.GetType().Name);
exporter.Export(modules, format);
// ReSharper disable once PossibleMultipleEnumeration
await exporter.Export(items, format);
}
}
catch (Exception ex)
Expand All @@ -91,7 +93,7 @@ private static IEnumerable<ValidationResult> Validate(object model)
var results = new List<ValidationResult>();
var context = new ValidationContext(model);

var isValid = Validator.TryValidateObject(model, context, results, true);
Validator.TryValidateObject(model, context, results, true);

return results;
}
Expand Down
9 changes: 0 additions & 9 deletions Epsilon.Http.Abstractions/Epsilon.Http.Abstractions.csproj

This file was deleted.

Loading