using Roadie.Library.Configuration;
using Roadie.Library.Extensions;
using Roadie.Library.MetaData.Audio;
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
namespace Roadie.Library.Utility
{
///
/// Helper to determine paths for file storage
///
public static class FolderPathHelper
{
///
/// Full path to Artist folder using destinationFolder as folder Root
///
/// Sort name of Artist to use for folder name
/// Optional Root folder defaults to Library Folder from Settings
public static string ArtistPath(IRoadieSettings configuration, string artistSortName, string destinationFolder = null)
{
SimpleContract.Requires(!string.IsNullOrEmpty(artistSortName), "Invalid Artist Sort Name");
var artistFolder = artistSortName.ToTitleCase(false);
destinationFolder = destinationFolder ?? configuration.LibraryFolder;
return Path.Combine(destinationFolder, artistFolder.ToFolderNameFriendly());
}
///
/// Delete any empty folders in the given folder
///
///
///
public static bool DeleteEmptyFolders(DirectoryInfo processingFolder)
{
if (processingFolder == null || !processingFolder.Exists)
{
return true;
}
foreach (var folder in processingFolder.GetDirectories("*.*", SearchOption.AllDirectories))
{
if (folder.Exists)
{
if (!folder.GetFiles("*.*", SearchOption.AllDirectories).Any())
{
folder.Delete(true);
Trace.WriteLine(string.Format("Deleting Empty Folder [{0}]", folder.FullName), "Debug");
}
}
}
return true;
}
///
/// For given artist delete any empty folders
///
/// Populated Artist database record
/// Optional Root folder defaults to Library Folder from Settings
///
public static bool DeleteEmptyFoldersForArtist(IRoadieSettings configuration, Data.Artist artist, string destinationFolder = null)
{
destinationFolder = destinationFolder ?? configuration.LibraryFolder;
SimpleContract.Requires(artist != null, "Invalid Artist");
return FolderPathHelper.DeleteEmptyFolders(new DirectoryInfo(artist.ArtistFileFolder(configuration, destinationFolder)));
}
///
/// For a given Track database record determine the path using the given destination folder
///
/// Populate track database record
/// Optional Root folder defaults to Library Folder from Settings
public static string PathForTrack(IRoadieSettings configuration, Data.Track track, string destinationFolder = null)
{
destinationFolder = destinationFolder ?? configuration.LibraryFolder;
if (string.IsNullOrEmpty(track.FilePath) || string.IsNullOrEmpty(track.FileName))
{
return null;
}
return Path.Combine(destinationFolder, track.FilePath, track.FileName);
}
///
/// Full path to Release folder using given full Artist folder
///
/// Full path to Artist folder
/// Title of Release
/// Date of Release
public static string ReleasePath(string artistFolder, string releaseTitle, DateTime releaseDate)
{
SimpleContract.Requires(!string.IsNullOrEmpty(artistFolder), "Invalid Artist Folder");
SimpleContract.Requires(!string.IsNullOrEmpty(releaseTitle), "Invalid Release Title");
SimpleContract.Requires(releaseDate != DateTime.MinValue, "Invalid Release Date");
return Path.Combine(artistFolder, string.Format("{1}{0}", releaseTitle.ToTitleCase(false).ToFolderNameFriendly(), string.Format("[{0}] ", releaseDate.ToString("yyyy"))));
}
///
/// Returns the FileName for given Track details, this is not the Full Path (FQDN) only the FileName
///
/// Populated Track MetaData
public static string TrackFileName(IRoadieSettings configuration, AudioMetaData metaData)
{
var fileInfo = new FileInfo(metaData.Filename);
return FolderPathHelper.TrackFileName(configuration, metaData.Release, metaData.TrackNumber ?? 0, metaData.Disk, metaData.TotalTrackNumbers, fileInfo.Extension.ToLower());
}
///
/// Returns the FileName for given Track details, this is not the Full Path (FQDN) only the FileName
///
/// Title of the Track
/// Track Number
/// Optional disk number defaults to 0
/// Optional Total Tracks defaults to TrackNumber
/// Optional File Extension defaults to mp3
public static string TrackFileName(IRoadieSettings configuration, string trackTitle, short trackNumber, int? diskNumber = null, int? totalTrackNumber = null, string fileExtension = "mp3")
{
SimpleContract.Requires(!string.IsNullOrEmpty(trackTitle), "Invalid Track Title");
SimpleContract.Requires(trackNumber > 0, "Invalid Track Number");
SimpleContract.Requires(!string.IsNullOrEmpty(fileExtension), "Invalid File Extension");
// If the total number of tracks is more than 99 or the track number itself is more than 99 then 3 pad else 2 pad
var track = (totalTrackNumber ?? trackNumber) > 99 || trackNumber > 99 ? trackNumber.ToString("D3") : trackNumber.ToString("D2");
// Put an "m" for media on the TPOS greater than 1 so the directory sorts proper
var dn = diskNumber ?? 0;
var disk = dn > 1 ? string.Format("m{0} ", dn.ToString("D3")) : string.Empty;
// Get new name for file
var fileNameFromTitle = trackTitle.ToTitleCase(false).ToFileNameFriendly();
if (fileNameFromTitle.StartsWith(track))
{
fileNameFromTitle = fileNameFromTitle
.RemoveStartsWith(string.Format("{0} -", track))
.RemoveStartsWith(string.Format("{0} ", track))
.RemoveStartsWith(string.Format("{0}.", track))
.RemoveStartsWith(string.Format("{0}-", track))
.ToTitleCase(false);
}
var trackPathReplace = configuration.TrackPathReplace;
if (trackPathReplace != null)
{
foreach (var kp in trackPathReplace)
{
fileNameFromTitle = fileNameFromTitle.Replace(kp.Key, kp.Value);
}
}
return string.Format("{0}{1} {2}.{3}", disk, track, fileNameFromTitle, fileExtension.ToLower());
}
///
/// Returns the Full path (FQDN) for given Track details
///
/// Populated Track MetaData
/// Optional Root folder defaults to Library Folder from Settings
/// Optional ArtistFolder default is to get from MetaData artist
public static string TrackFullPath(IRoadieSettings configuration, AudioMetaData metaData, string destinationFolder = null, string artistFolder = null)
{
return FolderPathHelper.TrackFullPath(configuration, metaData.Artist, metaData.Release, SafeParser.ToDateTime(metaData.Year).Value, metaData.Title, metaData.TrackNumber ?? 0, destinationFolder, metaData.Disk ?? 0, metaData.TotalTrackNumbers ?? 0, artistFolder: artistFolder);
}
///
/// Returns the Full path (FQDN) for given Track details
///
/// Artist For release
/// Release
/// Track
/// Optional Root folder defaults to Library Folder from Settings
///
public static string TrackFullPath(IRoadieSettings configuration, Data.Artist artist, Data.Release release, Data.Track track, string destinationFolder = null)
{
return FolderPathHelper.TrackFullPath(configuration, artist.SortNameValue, release.Title, release.ReleaseDate.Value, track.Title, track.TrackNumber, destinationFolder);
}
///
/// Return the full path (FQDN) for given Track details
///
/// Sort name of Artist to use for folder name
/// Title of Release
/// Date of Release
/// Track Number
/// Optional Root folder defaults to Library Folder from Settings
/// Optional disk number defaults to 0
/// Optional Total Tracks defaults to TrackNumber
/// Optional File Extension defaults to mp3
public static string TrackFullPath(IRoadieSettings configuration, string artistSortName, string releaseTitle, DateTime releaseDate, string trackTitle, short trackNumber, string destinationFolder = null, int? diskNumber = null, int? totalTrackNumber = null, string fileExtension = "mp3", string artistFolder = null)
{
destinationFolder = destinationFolder ?? configuration.LibraryFolder;
artistFolder = artistFolder ?? FolderPathHelper.ArtistPath(configuration, artistSortName, destinationFolder);
var releaseFolder = FolderPathHelper.ReleasePath(artistFolder, releaseTitle, releaseDate);
var trackFileName = FolderPathHelper.TrackFileName(configuration, trackTitle, trackNumber, diskNumber, totalTrackNumber, fileExtension);
var result = Path.Combine(artistFolder, releaseFolder, trackFileName);
Trace.WriteLine(string.Format("TrackPath [{0}] For ArtistName [{1}], ReleaseTitle [{2}], ReleaseDate [{3}], TrackNumber [{4}]", result, artistSortName, releaseTitle, releaseDate, trackNumber));
return result;
}
///
/// Returns the Directory for a Track (just directory not Track FileName)
///
/// Populated Track MetaData
/// Optional Root folder defaults to Library Folder from Settings
/// Optional ArtistFolder default is to get from MetaData artist///
public static string TrackPath(IRoadieSettings configuration, AudioMetaData metaData, string destinationFolder = null, string artistFolder = null)
{
var fileInfo = new FileInfo(FolderPathHelper.TrackFullPath(configuration, metaData, destinationFolder, artistFolder));
return fileInfo.Directory.Name;
}
///
/// Returns the Directory for a Track (just directory not Track FileName)
///
/// Artist For release
/// Release
/// Track
/// Optional Root folder defaults to Library Folder from Settings
public static string TrackPath(IRoadieSettings configuration, Data.Artist artist, Data.Release release, Data.Track track, string destinationFolder = null)
{
var fileInfo = new FileInfo(FolderPathHelper.TrackFullPath(configuration, artist.SortNameValue, release.Title, release.ReleaseDate.Value, track.Title, track.TrackNumber, destinationFolder));
return fileInfo.Directory.Name;
}
///
/// Returns the Directory for a Track (just directory not Track FileName)
///
/// Sort name of Artist to use for folder name
/// Title of Release
/// Date of Release
/// Track Number
/// Optional Root folder defaults to Library Folder from Settings
/// Optional disk number defaults to 0
/// Optional Total Tracks defaults to TrackNumber
/// Optional File Extension defaults to mp3
public static string TrackPath(IRoadieSettings configuration, string artistSortName, string releaseTitle, DateTime releaseDate, string trackTitle, short trackNumber, string destinationFolder = null, int? diskNumber = null, int? totalTrackNumber = null, string fileExtension = "mp3")
{
var fileInfo = new FileInfo(FolderPathHelper.TrackFullPath(configuration, artistSortName, releaseTitle, releaseDate, trackTitle, trackNumber, destinationFolder, diskNumber, totalTrackNumber));
return fileInfo.Directory.Name;
}
}
}