Restructuring. Added services.

This commit is contained in:
watsonb8
2019-05-19 20:21:54 -04:00
parent 1fcaffb9b1
commit 4b7c146041
15 changed files with 175 additions and 28 deletions

View File

@ -0,0 +1,56 @@
using System;
namespace Aurora.Backend.Models
{
public abstract class BaseSong
{
public BaseSong()
{
Id = Guid.NewGuid().ToString();
}
#region Properties
public string Id { get; private set; }
/// <summary>
/// The title of the song.
/// </summary>
/// <value></value>
public string Title { get; set; }
/// <summary>
/// The artist of the song.
/// </summary>
/// <value></value>
public string Artist { get; set; }
/// <summary>
/// The album from which the song belongs.
/// </summary>
/// <value></value>
public string Album { get; set; }
/// <summary>
/// The duration of the song.
/// </summary>
/// <value></value>
public string Duration { get; set; }
/// <summary>
/// Extra data associated with a song.
/// </summary>
/// <value></value>
public object Metadata { get; set; }
#endregion Properties
#region Methods
/// <summary>
/// Play this instance.
/// </summary>
public abstract void Play();
#endregion
}
}

View File

@ -0,0 +1,26 @@
using System;
using System.IO;
namespace Aurora.Backend.Models
{
public class LocalSong : BaseSong
{
public LocalSong(FileInfo fileInfo)
{
File = fileInfo;
}
#region Properties
public FileInfo File { get; private set; }
#endregion Properties
#region Methods
public override void Play()
{
throw new NotImplementedException();
}
#endregion Methods
}
}

View File

@ -0,0 +1,22 @@
using System;
namespace Aurora.Backend.Services
{
public abstract class BaseService<T> where T : class
{
private static volatile Lazy<T> _instance = new Lazy<T>(() => CreateInstanceOfT());
public static T Instance
{
get { return _instance.Value; }
}
private static T CreateInstanceOfT()
{
return Activator.CreateInstance(typeof(T), true) as T;
}
}
}

View File

@ -0,0 +1,65 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using Aurora.Backend.Models;
using Aurora.Backend.Utils;
using NAudio.Wave;
namespace Aurora.Backend.Services
{
public class LibraryService : BaseService<LibraryService>
{
#region Fields
private string _pathName = "/Users/brandonwatson/Music/iTunes/iTunes Media/Music";
private string _extensions = ".wav,.mp3,.aiff,.flac,.m4a,.m4b,.wma";
private Dictionary<string, Song> _library;
#endregion Fields
public LibraryService()
{
_library = new Dictionary<string, Song>();
LoadLibrary();
}
/// <summary>
/// Gets the songs.
/// </summary>
/// <returns>The songs.</returns>
public ObservableCollection<Song> GetLibrary()
{
ObservableCollection<Song> collection = new ObservableCollection<Song>();
foreach (KeyValuePair<string, Song> pair in _library)
{
collection.Add(pair.Value);
}
return collection;
}
/// <summary>
/// Loads library from files.
/// </summary>
private void LoadLibrary()
{
//Get songs
List<FileInfo> musicFiles = FileSystemUtils.TraverseFoldersAsync(_pathName, _extensions);
foreach (FileInfo file in musicFiles)
{
TagLib.File tagFile = TagLib.File.Create(file.FullName);
Song song = new Song(file)
{
Title = tagFile.Tag.Title,
Album = tagFile.Tag.Album,
Artist = tagFile.Tag.FirstAlbumArtist
};
_library.Add(song.Id, song);
}
}
}
}

View File

@ -0,0 +1,82 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
namespace Aurora.Backend.Utils
{
public class FileSystemUtils
{
public FileSystemUtils()
{
}
/// <summary>
/// Asynchronousely recursively traverse a directory path.
/// </summary>
/// <param name="path">The path to the directory to traverse</param>
/// <param name="extensions">Comma separated list of file extensions to accept</param>
public static List<FileInfo> TraverseFoldersAsync(string path, string extensions)
{
string[] extensionList = extensions.Split(',');
ConcurrentBag<Task> tasks = new ConcurrentBag<Task>();
List<FileInfo> outFiles = new List<FileInfo>();
DirectoryInfo directoryInfo = new DirectoryInfo(path);
tasks.Add(Task.Run(() => Traverse(directoryInfo, tasks, outFiles, extensionList)));
Task waitingTask;
while (tasks.TryTake(out waitingTask))
{
waitingTask.Wait();
}
return outFiles;
}
/// <summary>
/// Recursive method to capture children of a directory.
/// </summary>
/// <param name="dir">The directory to traverse</param>
/// <param name="tasks">The list of currently running tasks</param>
private static void Traverse(DirectoryInfo dir, ConcurrentBag<Task> tasks, List<FileInfo> outFiles, string[] extensions)
{
try
{
DirectoryInfo[] directoryInfos = dir.GetDirectories();
//Enque children
foreach (DirectoryInfo childInfo in directoryInfos)
{
tasks.Add(Task.Run(() => Traverse(childInfo, tasks, outFiles, extensions)));
}
//Collect files
foreach (FileInfo fileInfo in dir.GetFiles())
{
if (extensions.Any(e => e == fileInfo.Extension))
{
//Don't know if this lock is necessary
lock (outFiles)
{
outFiles.Add(fileInfo);
}
}
}
}
catch (Exception ex)
{
Console.WriteLine($"{ex.GetType()} {ex.Message}\n{ex.StackTrace}");
ex = ex.InnerException;
}
}
}
}