Added playlist repository logic.

This commit is contained in:
2025-02-18 20:49:04 -05:00
parent 8cf4bb2804
commit 2bafd474a0
7 changed files with 182 additions and 6 deletions

View File

@@ -0,0 +1,94 @@
namespace Harmonia.Core.Data;
public abstract class FileRepository<TObject> : IRepository<TObject> where TObject : notnull
{
private readonly Dictionary<TObject, string> _fileNameMap = [];
protected abstract string DirectoryName { get; }
protected abstract string Extension { get; }
protected abstract string GetNewFileName();
protected abstract string Serialize(TObject playlist);
protected abstract TObject Deserialize(Stream stream);
public FileRepository()
{
if (string.IsNullOrWhiteSpace(DirectoryName) || Directory.Exists(DirectoryName) == false)
return;
if (string.IsNullOrWhiteSpace(Extension))
return;
List<string> fileNames = GetAllFileNames();
LoadFileNamesIntoMap(fileNames);
}
private List<string> GetAllFileNames()
{
var directoryInfo = new DirectoryInfo(DirectoryName);
var directories = directoryInfo.GetDirectories().Where(x => x.Attributes.HasFlag(FileAttributes.Hidden) == false);
var fileInfoList = directoryInfo.EnumerateFiles("*." + Extension, SearchOption.TopDirectoryOnly).Where(x => x.Attributes.HasFlag(FileAttributes.Hidden) == false);
return fileInfoList.Select(fileInfo => fileInfo.FullName).ToList();
}
private void LoadFileNamesIntoMap(List<string> fileNames)
{
foreach (var fileName in fileNames)
{
using StreamReader textReader = new(fileName);
try
{
TObject obj = Deserialize(textReader.BaseStream);
_fileNameMap.Add(obj, fileName);
}
catch (Exception)
{
}
}
}
public List<TObject> Get()
{
return [.. _fileNameMap.Keys];
}
public void Save(TObject obj)
{
string serializedObject = Serialize(obj);
string fileName = Path.Combine(DirectoryName, GetFileName(obj));
string? path = Path.GetDirectoryName(fileName);
if (string.IsNullOrWhiteSpace(path))
return;
if (Directory.Exists(path) == false)
Directory.CreateDirectory(path);
using TextWriter textWriter = new StreamWriter(fileName);
textWriter.Write(serializedObject);
}
private string GetFileName(TObject obj)
{
if (_fileNameMap.TryGetValue(obj, out string? value))
return value;
string fileName = GetNewFileName();
_fileNameMap.Add(obj, fileName);
return fileName;
}
public void Delete(TObject obj)
{
string fileName = Path.Combine(DirectoryName, GetFileName(obj));
if (File.Exists(fileName))
File.Delete(fileName);
}
}

View File

@@ -0,0 +1,8 @@
namespace Harmonia.Core.Data;
public interface IRepository<TObject>
{
List<TObject> Get();
void Save(TObject value);
void Delete(TObject value);
}

View File

@@ -0,0 +1,26 @@
using System.Text.Json.Serialization;
using System.Text.Json;
namespace Harmonia.Core.Data;
public abstract class JsonFileRepository<TObject> : FileRepository<TObject> where TObject : notnull, new()
{
private readonly JsonSerializerOptions _options = new()
{
WriteIndented = true,
IgnoreReadOnlyProperties = true,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
};
protected override string Extension => "json";
protected override TObject Deserialize(Stream stream)
{
return JsonSerializer.Deserialize<TObject>(stream) ?? new();
}
protected override string Serialize(TObject obj)
{
return JsonSerializer.Serialize(obj, _options);
}
}

View File

@@ -0,0 +1,22 @@
using Harmonia.Core.Models;
namespace Harmonia.Core.Data;
public class PlaylistRepository : JsonFileRepository<Playlist>
{
protected override string DirectoryName => string.Empty;
protected override string GetNewFileName()
{
for (int i = 0; i < 1000; i++)
{
string shortFileName = $"Playlist{i.ToString().PadLeft(3, '0')}.{Extension}";
string filePath = Path.Combine(DirectoryName, shortFileName);
if (File.Exists(filePath) == false)
return shortFileName;
}
throw new Exception("Unable to determine new fileName");
}
}

View File

@@ -0,0 +1,26 @@
using System.Xml.Serialization;
namespace Harmonia.Core.Data;
public abstract class XMLFileRepository<TObject> : FileRepository<TObject> where TObject : notnull, new()
{
private readonly XmlSerializer _serializer = new(typeof(TObject));
protected override string Extension => "xml";
protected override TObject Deserialize(Stream stream)
{
using TextReader textReader = new StreamReader(stream);
return (TObject?)_serializer.Deserialize(textReader) ?? new();
}
protected override string Serialize(TObject obj)
{
using TextWriter textWriter = new StringWriter();
_serializer.Serialize(textWriter, obj);
return textWriter.ToString() ?? string.Empty;
}
}

View File

@@ -3,12 +3,12 @@ using Harmonia.Core.Extensions;
namespace Harmonia.Core.Models;
public class Playlist(string name)
public class Playlist
{
private readonly List<PlaylistSong> _songs = [];
public string UID { get; init; } = Guid.NewGuid().ToString();
public string Name { get; set; } = name;
public string? Name { get; set; }
public IReadOnlyList<PlaylistSong> Songs => _songs;
public List<GroupOption> GroupOptions { get; set; } = [];
public List<SortOption> SortOptions { get; set; } = [];

View File

@@ -9,7 +9,7 @@ public class PlaylistTests
[Fact]
public void Add_Songs()
{
Playlist playlist = new("Test");
Playlist playlist = new();
Song[] songs =
[
@@ -38,7 +38,7 @@ public class PlaylistTests
[Fact]
public void Sort_Songs()
{
Playlist playlist = new("Test");
Playlist playlist = new();
Song[] songs =
[
@@ -75,7 +75,7 @@ public class PlaylistTests
[Fact]
public void Remove_Songs()
{
Playlist playlist = new("Test");
Playlist playlist = new();
Song[] songs =
[
@@ -101,7 +101,7 @@ public class PlaylistTests
[Fact]
public void Lock_Playlist()
{
Playlist playlist = new("Test");
Playlist playlist = new();
Song[] songs =
[