Skip to content

Commit

Permalink
Implement albums by genre report
Browse files Browse the repository at this point in the history
  • Loading branch information
davewalker5 committed Aug 20, 2024
1 parent 72c010f commit dbc51aa
Show file tree
Hide file tree
Showing 30 changed files with 349 additions and 88 deletions.
4 changes: 2 additions & 2 deletions docker/api/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM mcr.microsoft.com/dotnet/core/aspnet:latest
COPY musiccatalogue.api-1.25.0.0 /opt/musiccatalogue.api-1.25.0.0
WORKDIR /opt/musiccatalogue.api-1.25.0.0/bin
COPY musiccatalogue.api-1.30.0.0 /opt/musiccatalogue.api-1.30.0.0
WORKDIR /opt/musiccatalogue.api-1.30.0.0/bin
ENTRYPOINT [ "./MusicCatalogue.Api" ]
4 changes: 2 additions & 2 deletions docker/ui/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
FROM node:20-alpine
COPY musiccatalogue.ui-1.29.0.0 /opt/musiccatalogue.ui-1.29.0.0
WORKDIR /opt/musiccatalogue.ui-1.29.0.0
COPY musiccatalogue.ui-1.30.0.0 /opt/musiccatalogue.ui-1.30.0.0
WORKDIR /opt/musiccatalogue.ui-1.30.0.0
RUN npm install
RUN npm run build
ENTRYPOINT [ "npm", "start" ]
17 changes: 16 additions & 1 deletion src/MusicCatalogue.Api/Controllers/ExportController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,24 @@ public class ExportController : Controller
private readonly IBackgroundQueue<GenreStatisticsExportWorkItem> _genreStatisticsQueue;
private readonly IBackgroundQueue<MonthlySpendExportWorkItem> _monthlySpendQueue;
private readonly IBackgroundQueue<RetailerStatisticsExportWorkItem> _retailerStatisticsQueue;
private readonly IBackgroundQueue<GenreAlbumsExportWorkItem> _genreAlbumsQueue;

public ExportController(
IBackgroundQueue<CatalogueExportWorkItem> catalogueQueue,
IBackgroundQueue<EquipmentExportWorkItem> equipmentQueue,
IBackgroundQueue<ArtistStatisticsExportWorkItem> artistStatisticsQueue,
IBackgroundQueue<GenreStatisticsExportWorkItem> genreStatisticsQueue,
IBackgroundQueue<MonthlySpendExportWorkItem> monthlySpendQueue,
IBackgroundQueue<RetailerStatisticsExportWorkItem> retailerStatisticsQueue)
IBackgroundQueue<RetailerStatisticsExportWorkItem> retailerStatisticsQueue,
IBackgroundQueue<GenreAlbumsExportWorkItem> genreAlbumsQueue)
{
_catalogueQueue = catalogueQueue;
_equipmentQueue = equipmentQueue;
_artistStatisticsQueue = artistStatisticsQueue;
_genreStatisticsQueue = genreStatisticsQueue;
_monthlySpendQueue = monthlySpendQueue;
_retailerStatisticsQueue = retailerStatisticsQueue;
_genreAlbumsQueue = genreAlbumsQueue;
}

[HttpPost]
Expand Down Expand Up @@ -105,5 +108,17 @@ public IActionResult ExportRetailerStatisticsReport([FromBody] RetailerStatistic
_retailerStatisticsQueue.Enqueue(item);
return Accepted();
}

[HttpPost]
[Route("genrealbums")]
public IActionResult ExportGenreAlbumsReport([FromBody] GenreAlbumsExportWorkItem item)
{
// Set the job name used in the job status record
item.JobName = "Albums by Genre Export";

// Queue the work item
_genreAlbumsQueue.Enqueue(item);
return Accepted();
}
}
}
8 changes: 8 additions & 0 deletions src/MusicCatalogue.Api/Entities/GenreAlbumsExportWorkItem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace MusicCatalogue.Api.Entities
{
public class GenreAlbumsExportWorkItem : BackgroundWorkItem
{
public string FileName { get; set; } = "";
public int GenreId { get; set; }
}
}
6 changes: 3 additions & 3 deletions src/MusicCatalogue.Api/MusicCatalogue.Api.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ReleaseVersion>1.26.0.0</ReleaseVersion>
<FileVersion>1.26.0.0</FileVersion>
<ProductVersion>1.26.0</ProductVersion>
<ReleaseVersion>1.30.0.0</ReleaseVersion>
<FileVersion>1.30.0.0</FileVersion>
<ProductVersion>1.30.0</ProductVersion>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
Expand Down
4 changes: 4 additions & 0 deletions src/MusicCatalogue.Api/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,10 @@ public static void Main(string[] args)
builder.Services.AddSingleton<IBackgroundQueue<RetailerStatisticsExportWorkItem>, BackgroundQueue<RetailerStatisticsExportWorkItem>>();
builder.Services.AddHostedService<RetailerStatisticsExportService>();

// Add the albums by genre exporter hosted service
builder.Services.AddSingleton<IBackgroundQueue<GenreAlbumsExportWorkItem>, BackgroundQueue<GenreAlbumsExportWorkItem>>();
builder.Services.AddHostedService<GenreAlbumsExportService>();

// Configure JWT
byte[] key = Encoding.ASCII.GetBytes(settings!.Secret);
builder.Services.AddAuthentication(x =>
Expand Down
45 changes: 45 additions & 0 deletions src/MusicCatalogue.Api/Services/GenreAlbumsExportService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using Microsoft.Extensions.Options;
using MusicCatalogue.Api.Entities;
using MusicCatalogue.Api.Interfaces;
using MusicCatalogue.Entities.Config;
using MusicCatalogue.Entities.Interfaces;
using MusicCatalogue.Entities.Reporting;
using MusicCatalogue.Logic.DataExchange.Generic;

namespace MusicCatalogue.Api.Services
{
public class GenreAlbumsExportService : BackgroundQueueProcessor<GenreAlbumsExportWorkItem>
{
private readonly MusicApplicationSettings _settings;
public GenreAlbumsExportService(
ILogger<BackgroundQueueProcessor<GenreAlbumsExportWorkItem>> logger,
IBackgroundQueue<GenreAlbumsExportWorkItem> queue,
IServiceScopeFactory serviceScopeFactory,
IOptions<MusicApplicationSettings> settings)
: base(logger, queue, serviceScopeFactory)
{
_settings = settings.Value;
}

/// <summary>
/// Export the albums by genre report
/// </summary>
/// <param name="item"></param>
/// <param name="factory"></param>
/// <returns></returns>
protected override async Task ProcessWorkItem(GenreAlbumsExportWorkItem item, IMusicCatalogueFactory factory)
{
// Get the report data
MessageLogger.LogInformation("Retrieving the albums by genre report for export");
var records = await factory.GenreAlbums.GenerateReportAsync(item.GenreId, 1, int.MaxValue);

// Construct the full path to the export file
var filePath = Path.Combine(_settings.ReportsExportPath, item.FileName);

// Export the report
var exporter = new CsvExporter<GenreAlbum>();
exporter.Export(records, filePath, ',');
MessageLogger.LogInformation("Albums by genre report export completed");
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Diagnostics.CodeAnalysis;
using System.Runtime.Serialization;

namespace MusicCatalogue.Entities.Exceptions
{
Expand All @@ -18,9 +17,5 @@ public ArtistInUseException(string message) : base(message)
public ArtistInUseException(string message, Exception inner) : base(message, inner)
{
}

protected ArtistInUseException(SerializationInfo serializationInfo, StreamingContext streamingContext) : base(serializationInfo, streamingContext)
{
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Diagnostics.CodeAnalysis;
using System.Runtime.Serialization;

namespace MusicCatalogue.Entities.Exceptions
{
Expand All @@ -19,9 +18,5 @@ public DuplicateOptionException(string message) : base(message)
public DuplicateOptionException(string message, Exception inner) : base(message, inner)
{
}

protected DuplicateOptionException(SerializationInfo serializationInfo, StreamingContext streamingContext) : base(serializationInfo, streamingContext)
{
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Diagnostics.CodeAnalysis;
using System.Runtime.Serialization;

namespace MusicCatalogue.Entities.Exceptions
{
Expand All @@ -18,9 +17,5 @@ public EquipmentTypeInUseException(string message) : base(message)
public EquipmentTypeInUseException(string message, Exception inner) : base(message, inner)
{
}

protected EquipmentTypeInUseException(SerializationInfo serializationInfo, StreamingContext streamingContext) : base(serializationInfo, streamingContext)
{
}
}
}
5 changes: 0 additions & 5 deletions src/MusicCatalogue.Entities/Exceptions/GenreInUseException.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Diagnostics.CodeAnalysis;
using System.Runtime.Serialization;

namespace MusicCatalogue.Entities.Exceptions
{
Expand All @@ -18,9 +17,5 @@ public GenreInUseException(string message) : base(message)
public GenreInUseException(string message, Exception inner) : base(message, inner)
{
}

protected GenreInUseException(SerializationInfo serializationInfo, StreamingContext streamingContext) : base(serializationInfo, streamingContext)
{
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Diagnostics.CodeAnalysis;
using System.Runtime.Serialization;

namespace MusicCatalogue.Entities.Exceptions
{
Expand All @@ -18,10 +17,6 @@ public InvalidRecordFormatException(string message) : base(message)
public InvalidRecordFormatException(string message, Exception inner) : base(message, inner)
{
}

protected InvalidRecordFormatException(SerializationInfo serializationInfo, StreamingContext streamingContext) : base(serializationInfo, streamingContext)
{
}
}
}

Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Diagnostics.CodeAnalysis;
using System.Runtime.Serialization;

namespace MusicCatalogue.Entities.Exceptions
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Diagnostics.CodeAnalysis;
using System.Runtime.Serialization;

namespace MusicCatalogue.Entities.Exceptions
{
Expand All @@ -19,9 +18,5 @@ public ManufacturerInUseException(string message) : base(message)
public ManufacturerInUseException(string message, Exception inner) : base(message, inner)
{
}

protected ManufacturerInUseException(SerializationInfo serializationInfo, StreamingContext streamingContext) : base(serializationInfo, streamingContext)
{
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Diagnostics.CodeAnalysis;
using System.Runtime.Serialization;

namespace MusicCatalogue.Entities.Exceptions
{
Expand All @@ -18,10 +17,6 @@ public MultipleOperationsException(string message) : base(message)
public MultipleOperationsException(string message, Exception inner) : base(message, inner)
{
}

protected MultipleOperationsException(SerializationInfo serializationInfo, StreamingContext streamingContext) : base(serializationInfo, streamingContext)
{
}
}
}

Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Diagnostics.CodeAnalysis;
using System.Runtime.Serialization;

namespace MusicCatalogue.Entities.Exceptions
{
Expand All @@ -19,9 +18,5 @@ public RetailerInUseException(string message) : base(message)
public RetailerInUseException(string message, Exception inner) : base(message, inner)
{
}

protected RetailerInUseException(SerializationInfo serializationInfo, StreamingContext streamingContext) : base(serializationInfo, streamingContext)
{
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Diagnostics.CodeAnalysis;
using System.Runtime.Serialization;

namespace MusicCatalogue.Entities.Exceptions
{
Expand All @@ -18,9 +17,5 @@ public TooFewValuesException(string message) : base(message)
public TooFewValuesException(string message, Exception inner) : base(message, inner)
{
}

protected TooFewValuesException(SerializationInfo serializationInfo, StreamingContext streamingContext) : base(serializationInfo, streamingContext)
{
}
}
}
12 changes: 1 addition & 11 deletions src/MusicCatalogue.Entities/Exceptions/TooManyValuesException.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics.CodeAnalysis;

namespace MusicCatalogue.Entities.Exceptions
{
Expand All @@ -23,9 +17,5 @@ public TooManyValuesException(string message) : base(message)
public TooManyValuesException(string message, Exception inner) : base(message, inner)
{
}

protected TooManyValuesException(SerializationInfo serializationInfo, StreamingContext streamingContext) : base(serializationInfo, streamingContext)
{
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Diagnostics.CodeAnalysis;
using System.Runtime.Serialization;

namespace MusicCatalogue.Entities.Exceptions
{
Expand All @@ -18,9 +17,5 @@ public UnrecognisedCommandLineOptionException(string message) : base(message)
public UnrecognisedCommandLineOptionException(string message, Exception inner) : base(message, inner)
{
}

protected UnrecognisedCommandLineOptionException(SerializationInfo serializationInfo, StreamingContext streamingContext) : base(serializationInfo, streamingContext)
{
}
}
}
9 changes: 6 additions & 3 deletions src/MusicCatalogue.Entities/Reporting/GenreAlbum.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,16 @@ public class GenreAlbum : ReportEntityBase
[Export("Genre", 3)]
public string Genre { get; set; } = "";

[Export("Purchased", 4)]
[Export("Released", 4)]
public int Released { get; set; }

[Export("Purchased", 5)]
public DateTime Purchased { get; set; }

[Export("Price", 5)]
[Export("Price", 6)]
public Decimal Price { get; set; }

[Export("Retailer", 6)]
[Export("Retailer", 7)]
public string Retailer { get; set; } = "";
}
}
30 changes: 16 additions & 14 deletions src/MusicCatalogue.Logic/Sql/GenreAlbum.sql
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
SELECT RANK() OVER ( ORDER BY ar.Name, al.Title ) AS 'Id',
ar.Name AS 'Artist',
al.Title, g.Name AS 'Genre',
IFNULL( DATE(al.Purchased), DATE('1900-01-01')) AS 'Purchased',
IFNULL( al.Price, 0 ) AS 'Price',
r.Name AS 'Retailer'
FROM ALBUMS al
INNER JOIN GENRES g ON g.Id = al.GenreId
INNER JOIN ARTISTS ar ON ar.Id = al.ArtistId
INNER JOIN RETAILERS r ON r.Id = al.RetailerId
WHERE g.Id = $genreId
AND IFNULL( al.IsWishListItem, 0 ) = 0
ORDER BY ar.Name ASC,
al.Title ASC
SELECT RANK() OVER ( ORDER BY ar.Name, al.Title ) AS 'Id',
ar.Name AS 'Artist',
al.Title,
g.Name AS 'Genre',
IFNULL( al.Released, 0 ) AS 'Released',
IFNULL( DATE(al.Purchased), DATE('1900-01-01')) AS 'Purchased',
IFNULL( al.Price, 0.0 ) AS 'Price',
IFNULL( r.Name, '') AS 'Retailer'
FROM ALBUMS al
INNER JOIN GENRES g ON g.Id = al.GenreId
INNER JOIN ARTISTS ar ON ar.Id = al.ArtistId
LEFT OUTER JOIN RETAILERS r ON r.Id = al.RetailerId
WHERE g.Id = $genreId
AND IFNULL( al.IsWishListItem, 0 ) = 0
ORDER BY ar.Name ASC,
al.Title ASC
Loading

0 comments on commit dbc51aa

Please sign in to comment.