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

Commit

Permalink
Merge pull request #14 from Typiqally/feat/multiple_exporters
Browse files Browse the repository at this point in the history
Add support for multiple exporters
  • Loading branch information
NealGeilen authored Jun 3, 2022
2 parents 3a5bec8 + 5ebb16a commit dc5628c
Show file tree
Hide file tree
Showing 15 changed files with 196 additions and 123 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Epsilon.Abstractions.Export;

public interface ICanvasModuleFileExporter : IFileExporter<IEnumerable<Module>>
public interface ICanvasModuleExporter : IExporter<IEnumerable<Module>>
{

}
8 changes: 8 additions & 0 deletions Epsilon.Abstractions/Export/IExporter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Epsilon.Abstractions.Export;

public interface IExporter<in T>
{
public IEnumerable<string> Formats { get; }

void Export(T data, string format);
}
8 changes: 0 additions & 8 deletions Epsilon.Abstractions/Export/IFileExporter.cs

This file was deleted.

6 changes: 6 additions & 0 deletions Epsilon.Abstractions/Export/IModuleExporterCollection.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Epsilon.Abstractions.Export;

public interface IModuleExporterCollection
{
public IDictionary<string, ICanvasModuleExporter> DetermineExporters(IEnumerable<string> formats);
}
71 changes: 46 additions & 25 deletions Epsilon.Cli/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Epsilon.Canvas;
using Epsilon.Canvas.Abstractions;
using Epsilon.Export;
using Epsilon.Export.Exceptions;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
Expand All @@ -12,44 +13,29 @@ public class Startup : IHostedService
{
private readonly ILogger<Startup> _logger;
private readonly IHostApplicationLifetime _lifetime;
private readonly ExportSettings _exportSettings;
private readonly ExportOptions _exportOptions;
private readonly CanvasSettings _canvasSettings;
private readonly ICanvasModuleCollectionFetcher _collectionFetcher;
private readonly ICanvasModuleCollectionExporter _collectionExporter;
private readonly IModuleExporterCollection _exporterCollection;

public Startup(
ILogger<Startup> logger,
IHostApplicationLifetime lifetime,
IOptions<CanvasSettings> canvasSettings,
IOptions<ExportSettings> exportSettings,
IOptions<ExportOptions> exportSettings,
ICanvasModuleCollectionFetcher collectionFetcher,
ICanvasModuleCollectionExporter collectionExporter)
IModuleExporterCollection exporterCollection)
{
_logger = logger;
_canvasSettings = canvasSettings.Value;
_exportSettings = exportSettings.Value;
_exportOptions = exportSettings.Value;
_lifetime = lifetime;
_collectionFetcher = collectionFetcher;
_collectionExporter = collectionExporter;
_exporterCollection = exporterCollection;
}

public Task StartAsync(CancellationToken cancellationToken)
{
if (_canvasSettings.CourseId <= 0)
{
_logger.LogError("No course id has been given");
return Task.FromException(new Exception("No course id has been given"));
}

if (_canvasSettings.AccessToken.Length <= 0)
{
_logger.LogError("No Access token has been given");
return Task.FromException(new Exception("No Access token has been given"));
}

_logger.LogInformation("Starting Epsilon, targeting course: {CourseId}", _canvasSettings.CourseId);
_logger.LogInformation("Using export format: {Format}", _exportSettings.Format);

_lifetime.ApplicationStarted.Register(() => Task.Run(ExecuteAsync, cancellationToken));

return Task.CompletedTask;
Expand All @@ -62,11 +48,46 @@ public Task StopAsync(CancellationToken cancellationToken)

private async Task ExecuteAsync()
{
var modules = await _collectionFetcher.Fetch(_canvasSettings.CourseId);
try
{
ValidateOptions();

_logger.LogInformation("Targeting Canvas course: {CourseId}, at {Url}", _canvasSettings.CourseId, _canvasSettings.ApiUrl);
_logger.LogInformation("Using export formats: {Formats}", string.Join(",", _exportOptions.Formats));

var format = _exportSettings.Format.ToLower();
_collectionExporter.Export(modules, format);
var exporters = _exporterCollection.DetermineExporters(_exportOptions.Formats).ToArray();
var modules = (await _collectionFetcher.Fetch(_canvasSettings.CourseId)).ToArray();

_lifetime.StopApplication();
foreach (var (format, exporter) in exporters)
{
_logger.LogInformation("Exporting to {Format} using {Exporter}...", format, exporter.GetType().Name);
exporter.Export(modules, format);
}
}
catch (ArgumentNullException e)
{
_logger.LogCritical("Argument is required: {ParamName}", e.ParamName);
}
catch (NoExportersFoundException e)
{
_logger.LogCritical("An error occured: {Message}", e.Message);
}
finally
{
_lifetime.StopApplication();
}
}

private void ValidateOptions()
{
if (_canvasSettings.CourseId <= 0)
{
throw new ArgumentNullException(nameof(_canvasSettings.CourseId));
}

if (string.IsNullOrEmpty(_canvasSettings.AccessToken))
{
throw new ArgumentNullException(nameof(_canvasSettings.AccessToken));
}
}
}
28 changes: 0 additions & 28 deletions Epsilon/Export/CanvasModuleCollectionExporter.cs

This file was deleted.

35 changes: 0 additions & 35 deletions Epsilon/Export/ConsoleCanvasModuleFileExporter.cs

This file was deleted.

13 changes: 13 additions & 0 deletions Epsilon/Export/Exceptions/NoExportersFoundException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace Epsilon.Export.Exceptions;

[Serializable]
public class NoExportersFoundException : Exception
{
public NoExportersFoundException()
{
}

public NoExportersFoundException(IEnumerable<string> formats) : base($"No exporters could be found with the given formats {string.Join(",", formats)}")
{
}
}
11 changes: 11 additions & 0 deletions Epsilon/Export/ExportOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace Epsilon.Export;

public class ExportOptions
{
public string OutputName { get; set; } = "Epsilon-Export-{DateTime}";

public List<string> Formats { get; } = new();

public string FormattedOutputName => OutputName
.Replace("{DateTime}", DateTime.Now.ToString("ddMMyyyyHHmmss"));
}
6 changes: 0 additions & 6 deletions Epsilon/Export/ExportSettings.cs

This file was deleted.

50 changes: 50 additions & 0 deletions Epsilon/Export/Exporters/ConsoleModuleExporter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using Epsilon.Abstractions.Export;
using Epsilon.Canvas.Abstractions.Data;
using Microsoft.Extensions.Logging;

namespace Epsilon.Export.Exporters;

public class ConsoleModuleExporter : ICanvasModuleExporter
{
private readonly ILogger<ConsoleModuleExporter> _logger;

public ConsoleModuleExporter(ILogger<ConsoleModuleExporter> logger)
{
_logger = logger;
}

public IEnumerable<string> Formats { get; } = new[] { "console", "logs" };

public void Export(IEnumerable<Module> data, string format)
{
LogModule(data);
}

private void LogModule(IEnumerable<Module> modules)
{
foreach (var module in modules)
{
_logger.LogInformation("================ {ModuleName} ================", module.Name);

LogAssignments(module.Assignments);
}
}

private void LogAssignments(IEnumerable<Assignment> assignments)
{
foreach (var assignment in assignments)
{
_logger.LogInformation("{AssignmentName}", assignment.Name);

LogOutcomeResults(assignment.OutcomeResults);
}
}

private void LogOutcomeResults(IEnumerable<OutcomeResult> results)
{
foreach (var outcomeResult in results)
{
_logger.LogInformation("\t- {OutcomeTitle}", outcomeResult.Outcome?.Title);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,26 @@
using System.Data;
using Epsilon.Abstractions.Export;
using Epsilon.Canvas.Abstractions.Data;
using Microsoft.Extensions.Options;

namespace Epsilon.Export;
namespace Epsilon.Export.Exporters;

public class CsvCanvasModuleFileExporter : ICanvasModuleFileExporter
public class CsvModuleExporter : ICanvasModuleExporter
{
public bool CanExport(string format) => format == "csv";
private readonly ExportOptions _options;

public void Export(IEnumerable<Module> data, string path)
public CsvModuleExporter(IOptions<ExportOptions> options)
{
_options = options.Value;
}

public IEnumerable<string> Formats { get; } = new[] { "csv" };

public void Export(IEnumerable<Module> data, string format)
{
var dt = CreateDataTable(data);

var stream = new StreamWriter(path + ".csv", false);
var stream = new StreamWriter($"{_options.FormattedOutputName}.{format}", false);
WriteHeader(stream, dt);
WriteRows(stream, dt);

Expand Down Expand Up @@ -50,7 +58,7 @@ private static void WriteHeader(TextWriter writer, DataTable dt)
writer.Write(dt.Columns[i]);
if (i < dt.Columns.Count - 1)
{
writer.Write(",");
writer.Write(";");
}
}

Expand All @@ -69,7 +77,7 @@ private static void WriteRows(TextWriter writer, DataTable dt)
var value = dr[i].ToString();
if (value != null)
{
if (value.Contains(','))
if (value.Contains(';'))
{
value = $"\"{value}\"";
writer.Write(value);
Expand All @@ -83,7 +91,7 @@ private static void WriteRows(TextWriter writer, DataTable dt)

if (i < dt.Columns.Count - 1)
{
writer.Write(",");
writer.Write(";");
}
}

Expand Down
Loading

0 comments on commit dc5628c

Please sign in to comment.