Skip to content

Commit

Permalink
Added support for CLI and CSV import (WIP)
Browse files Browse the repository at this point in the history
  • Loading branch information
davewalker5 committed Oct 6, 2023
1 parent 2b20d49 commit 131350c
Show file tree
Hide file tree
Showing 25 changed files with 785 additions and 64 deletions.
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>net7.0</TargetFramework>
<ReleaseVersion>1.1.0.0</ReleaseVersion>
<FileVersion>1.1.0.0</FileVersion>
<ProductVersion>1.1.0</ProductVersion>
<ReleaseVersion>1.2.0.0</ReleaseVersion>
<FileVersion>1.2.0.0</FileVersion>
<ProductVersion>1.2.0</ProductVersion>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
Expand Down
4 changes: 2 additions & 2 deletions src/MusicCatalogue.Data/MusicCatalogue.Data.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PackageId>MusicCatalogue.Data</PackageId>
<PackageVersion>1.1.0.0</PackageVersion>
<PackageVersion>1.2.0.0</PackageVersion>
<Authors>Dave Walker</Authors>
<Copyright>Copyright (c) Dave Walker 2023</Copyright>
<Owners>Dave Walker</Owners>
Expand All @@ -17,7 +17,7 @@
<PackageProjectUrl>https://github.com/davewalker5/MusicCatalogue</PackageProjectUrl>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
<ReleaseVersion>1.1.0.0</ReleaseVersion>
<ReleaseVersion>1.2.0.0</ReleaseVersion>
</PropertyGroup>

<ItemGroup>
Expand Down
15 changes: 15 additions & 0 deletions src/MusicCatalogue.Entities/CommandLine/CommandLineOption.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System.Diagnostics.CodeAnalysis;

namespace MusicCatalogue.Entities.CommandLine
{
[ExcludeFromCodeCoverage]
public class CommandLineOption
{
public CommandLineOptionType OptionType { get; set; }
public string Name { get; set; } = "";
public string ShortName { get; set; } = "";
public string Description { get; set; } = "";
public int MinimumNumberOfValues { get; set; } = 0;
public int MaximumNumberOfValues { get; set; } = 0;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace MusicCatalogue.Entities.CommandLine
{
public enum CommandLineOptionType
{
Unknown,
Lookup,
}
}
11 changes: 11 additions & 0 deletions src/MusicCatalogue.Entities/CommandLine/CommandLineOptionValue.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System.Diagnostics.CodeAnalysis;

namespace MusicCatalogue.Entities.CommandLine
{
[ExcludeFromCodeCoverage]
public class CommandLineOptionValue
{
public CommandLineOption? Option { get; set; }
public List<string> Values { get; private set; } = new List<string>();
}
}
70 changes: 70 additions & 0 deletions src/MusicCatalogue.Entities/DataExchange/FlattenedTrack.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
using MusicCatalogue.Entities.Database;
using System.Diagnostics.CodeAnalysis;

namespace MusicCatalogue.Entities.DataExchange
{
[ExcludeFromCodeCoverage]
public class FlattenedTrack : TrackBase
{
public const int ArtistField = 0;
public const int AlbumField = 1;
private const int GenreField = 2;
private const int ReleasedField = 3;
private const int CoverField = 4;
private const int TrackNumberField = 5;
private const int TitleField = 6;
private const int DurationField = 7;

public const string CsvRecordPattern = @"^(""[a-zA-Z0-9-() \/']+"",){3}""[0-9]+"",("".*"",)""[0-9]+"",(""[a-zA-Z0-9-() \/']+"",)""[0-9]+\:[0-9]{2}""$";

public string ArtistName{ get; set; } = "";
public string AlbumTitle { get; set; } = "";
public string Genre { get; set; } = "";
public int? Released { get; set; }
public string? CoverUrl { get; set; } = "";
public int TrackNumber { get; set; }
public string Title { get; set; } = "";

/// <summary>
/// Create a representation of the flattened track in CSV format
/// </summary>
/// <returns></returns>
public string ToCsv()
{
var representation = $"\"{ArtistName}\",\"{AlbumTitle}\",\"{Genre}\",\"{Released}\",\"{CoverUrl}\",\"{Title}\",\"{FormattedDuration()}\"";
return representation;
}

/// <summary>
/// Create a flattened track record from a CSV string
/// </summary>
/// <param name="record"></param>
/// <returns></returns>
public static FlattenedTrack FromCsv(string record)
{
// Split the record into words
var words = record.Split(new string[] { "\",\"" }, StringSplitOptions.None);

// Get the release date and cover URL, both of which may be NULL
int? releaseYear = !string.IsNullOrEmpty(words[ReleasedField]) ? int.Parse(words[ReleasedField]) : null;
string? coverUrl = !string.IsNullOrEmpty(words[CoverField]) ? words[CoverField] : null;

// Split the duration on the ":" separator and convert to milliseconds
var durationWords = words[DurationField][..^1].Split(new string[] { ":" }, StringSplitOptions.None);
var durationMs = 1000 * (60 * int.Parse(durationWords[0]) + 1000 * int.Parse(durationWords[1]));

// Create a new "flattened" record containing artist, album and track details
return new FlattenedTrack
{
ArtistName = words[ArtistField][1..],
AlbumTitle = words[AlbumField],
Genre = words[GenreField],
Released = releaseYear,
CoverUrl = coverUrl,
TrackNumber = int.Parse(words[TrackNumberField]),
Title = words[TitleField],
Duration = durationMs
};
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System.Diagnostics.CodeAnalysis;

namespace MusicCatalogue.Entities.DataExchange
{
[ExcludeFromCodeCoverage]
public class TrackDataExchangeEventArgs : EventArgs
{
public long RecordCount { get; set; }
public FlattenedTrack? Track { get; set; }
}
}
23 changes: 1 addition & 22 deletions src/MusicCatalogue.Entities/Database/Track.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace MusicCatalogue.Entities.Database
{
[ExcludeFromCodeCoverage]
public class Track
public class Track : TrackBase
{
[Key]
public int Id { get; set; }
Expand All @@ -18,26 +18,5 @@ public class Track

[Required]
public string Title { get; set; } = "";

public int? Duration { get; set; }

/// <summary>
/// Format the duration in MM:SS format
/// </summary>
/// <returns></returns>
public string? FormattedDuration()
{
string? formatted = null;

if (Duration != null)
{
int seconds = (Duration ?? 0) / 1000;
int minutes = seconds / 60;
seconds -= 60 * minutes;
formatted = $"{minutes:00}:{seconds:00}";
}

return formatted;
}
}
}
32 changes: 32 additions & 0 deletions src/MusicCatalogue.Entities/Database/TrackBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MusicCatalogue.Entities.Database
{
public abstract class TrackBase
{
public int? Duration { get; set; }

/// <summary>
/// Format the duration in MM:SS format
/// </summary>
/// <returns></returns>
public string? FormattedDuration()
{
string? formatted = null;

if (Duration != null)
{
int seconds = (Duration ?? 0) / 1000;
int minutes = seconds / 60;
seconds -= 60 * minutes;
formatted = $"{minutes:00}:{seconds:00}";
}

return formatted;
}
}
}
32 changes: 32 additions & 0 deletions src/MusicCatalogue.Entities/Exceptions/DuplicateOptionException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System.Diagnostics.CodeAnalysis;
using System.Runtime.Serialization;

namespace MusicCatalogue.Entities.Exceptions
{

[Serializable]
[ExcludeFromCodeCoverage]
public class DuplicateOptionException : Exception
{
public DuplicateOptionException()
{
}

public DuplicateOptionException(string message) : base(message)
{
}

public DuplicateOptionException(string message, Exception inner) : base(message, inner)
{
}

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

public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
base.GetObjectData(info, context);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System.Diagnostics.CodeAnalysis;
using System.Runtime.Serialization;

namespace MusicCatalogue.Entities.Exceptions
{
[Serializable]
[ExcludeFromCodeCoverage]
public class InvalidRecordFormatException : Exception
{
public InvalidRecordFormatException()
{
}

public InvalidRecordFormatException(string message) : base(message)
{
}

public InvalidRecordFormatException(string message, Exception inner) : base(message, inner)
{
}

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

public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
base.GetObjectData(info, context);
}
}
}

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

namespace MusicCatalogue.Entities.Exceptions
{
[Serializable]
[ExcludeFromCodeCoverage]
public class MalformedCommandLineException : Exception
{
public MalformedCommandLineException()
{
}

public MalformedCommandLineException(string message) : base(message)
{
}

public MalformedCommandLineException(string message, Exception inner) : base(message, inner)
{
}

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

public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
base.GetObjectData(info, context);
}
}
}
31 changes: 31 additions & 0 deletions src/MusicCatalogue.Entities/Exceptions/TooFewValuesException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System.Diagnostics.CodeAnalysis;
using System.Runtime.Serialization;

namespace MusicCatalogue.Entities.Exceptions
{
[Serializable]
[ExcludeFromCodeCoverage]
public class TooFewValuesException : Exception
{
public TooFewValuesException()
{
}

public TooFewValuesException(string message) : base(message)
{
}

public TooFewValuesException(string message, Exception inner) : base(message, inner)
{
}

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

public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
base.GetObjectData(info, context);
}
}
}
36 changes: 36 additions & 0 deletions src/MusicCatalogue.Entities/Exceptions/TooManyValuesException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;

namespace MusicCatalogue.Entities.Exceptions
{
[Serializable]
[ExcludeFromCodeCoverage]
public class TooManyValuesException : Exception
{
public TooManyValuesException()
{
}

public TooManyValuesException(string message) : base(message)
{
}

public TooManyValuesException(string message, Exception inner) : base(message, inner)
{
}

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

public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
base.GetObjectData(info, context);
}
}
}
Loading

0 comments on commit 131350c

Please sign in to comment.