/// <summary> /// Full path to Artist folder /// </summary> /// <param name="artistSortName">Sort name of Artist to use for folder name</param> public static string ArtistPath(IRoadieSettings configuration, int artistId, string artistSortName, bool createIfNotFound = false) { SimpleContract.Requires <ArgumentException>(!string.IsNullOrEmpty(artistSortName), "Invalid Artist Sort Name"); SimpleContract.Requires <ArgumentException>(configuration.LibraryFolder.Length < MaximumLibraryFolderNameLength, $"Library Folder maximum length is [{ MaximumLibraryFolderNameLength }]"); var asn = new StringBuilder(artistSortName); foreach (var stringReplacement in FolderSpaceReplacements) { if (!asn.Equals(stringReplacement)) { asn.Replace(stringReplacement, " "); } } var artistFolder = asn.ToString().ToAlphanumericName(false, false).ToFolderNameFriendly().ToTitleCase(false); if (string.IsNullOrEmpty(artistFolder)) { throw new Exception($"ArtistFolder [{ artistFolder }] is invalid. ArtistId [{ artistId }], ArtistSortName [{ artistSortName }]."); } var afUpper = artistFolder.ToUpper(); var fnSubPart1 = afUpper.ToUpper().ToCharArray().Take(1).First(); if (!char.IsLetterOrDigit(fnSubPart1)) { fnSubPart1 = '#'; } else if (char.IsNumber(fnSubPart1)) { fnSubPart1 = '0'; } var fnSubPart2 = afUpper.Length > 2 ? afUpper.Substring(0, 2) : afUpper; if (fnSubPart2.EndsWith(" ")) { var pos = 1; while (fnSubPart2.EndsWith(" ")) { pos++; fnSubPart2 = fnSubPart2.Substring(0, 1) + afUpper.Substring(pos, 1); } } var fnSubPart = Path.Combine(fnSubPart1.ToString(), fnSubPart2); var fnIdPart = $" [{ artistId }]"; var maxFnLength = (MaximumArtistFolderNameLength - (fnSubPart.Length + fnIdPart.Length)) - 2; if (artistFolder.Length > maxFnLength) { artistFolder = artistFolder.Substring(0, maxFnLength); } artistFolder = Path.Combine(fnSubPart, $"{ artistFolder }{ fnIdPart }"); var directoryInfo = new DirectoryInfo(Path.Combine(configuration.LibraryFolder, artistFolder)); if (createIfNotFound && !directoryInfo.Exists) { directoryInfo.Create(); } return(directoryInfo.FullName); }
/// <summary> /// Full path to Release folder using given full Artist folder /// </summary> /// <param name="artistFolder">Full path to Artist folder</param> /// <param name="releaseTitle">Title of Release</param> /// <param name="releaseDate">Date of Release</param> public static string ReleasePath(string artistFolder, string releaseTitle, DateTime releaseDate) { SimpleContract.Requires <ArgumentException>(!string.IsNullOrEmpty(artistFolder), "Invalid Artist Folder"); SimpleContract.Requires <ArgumentException>(!string.IsNullOrEmpty(releaseTitle), "Invalid Release Title"); SimpleContract.Requires <ArgumentException>(releaseDate != DateTime.MinValue, "Invalid Release Date"); var directoryInfo = new DirectoryInfo(Path.Combine(artistFolder, string.Format("{1}{0}", releaseTitle.ToTitleCase(false).ToFolderNameFriendly(), string.Format("[{0}] ", releaseDate.ToString("yyyy"))))); return(directoryInfo.FullName); }
/// <summary> /// Full path to Artist folder using destinationFolder as folder Root /// </summary> /// <param name="artistSortName">Sort name of Artist to use for folder name</param> /// <param name="destinationFolder">Optional Root folder defaults to Library Folder from Settings</param> public static string ArtistPath(IRoadieSettings configuration, string artistSortName, string destinationFolder = null) { SimpleContract.Requires <ArgumentException>(!string.IsNullOrEmpty(artistSortName), "Invalid Artist Sort Name"); var artistFolder = artistSortName.ToTitleCase(false); destinationFolder = destinationFolder ?? configuration.LibraryFolder; var directoryInfo = new DirectoryInfo(Path.Combine(destinationFolder, artistFolder.ToFolderNameFriendly())); return(directoryInfo.FullName); }
public static string LabelPath(IRoadieSettings configuration, string labelSortName) { SimpleContract.Requires <ArgumentException>(!string.IsNullOrEmpty(labelSortName), "Invalid Label Sort Name"); SimpleContract.Requires <ArgumentException>(configuration.LabelImageFolder.Length < MaximumLabelFolderNameLength, $"Label Image Folder maximum length is [{ MaximumLibraryFolderNameLength }]"); var lsn = new StringBuilder(labelSortName); foreach (var stringReplacement in FolderSpaceReplacements) { if (!lsn.Equals(stringReplacement)) { lsn.Replace(stringReplacement, " "); } } var labelFolder = lsn.ToString().ToAlphanumericName(false, false).ToFolderNameFriendly().ToTitleCase(false); if (string.IsNullOrEmpty(labelFolder)) { throw new Exception($"LabelFolder [{ labelFolder }] is invalid. LabelSortName [{ labelSortName }]."); } var lfUpper = labelFolder.ToUpper(); var fnSubPart1 = lfUpper.ToUpper().ToCharArray().Take(1).First(); if (!char.IsLetterOrDigit(fnSubPart1)) { fnSubPart1 = '#'; } else if (char.IsNumber(fnSubPart1)) { fnSubPart1 = '0'; } var fnSubPart2 = lfUpper.Length > 2 ? lfUpper.Substring(0, 2) : lfUpper; if (fnSubPart2.EndsWith(" ")) { var pos = 1; while (fnSubPart2.EndsWith(" ")) { pos++; fnSubPart2 = fnSubPart2.Substring(0, 1) + lfUpper.Substring(pos, 1); } } var fnSubPart = Path.Combine(fnSubPart1.ToString(), fnSubPart2); var directoryInfo = new DirectoryInfo(Path.Combine(configuration.LabelImageFolder, fnSubPart)); return(directoryInfo.FullName); }
/// <summary> /// Full path to Release folder using given full Artist folder /// </summary> /// <param name="artistFolder">Full path to Artist folder</param> /// <param name="releaseTitle">Title of Release</param> /// <param name="releaseDate">Date of Release</param> public static string ReleasePath(string artistFolder, string releaseTitle, DateTime releaseDate, bool createIfNotFound = false) { SimpleContract.Requires <ArgumentException>(!string.IsNullOrEmpty(artistFolder), "Invalid Artist Folder"); SimpleContract.Requires <ArgumentException>(artistFolder.Length < MaximumArtistFolderNameLength, $"Artist Folder is longer than maximum allowed [{ MaximumArtistFolderNameLength }]"); SimpleContract.Requires <ArgumentException>(!string.IsNullOrEmpty(releaseTitle), "Invalid Release Title"); SimpleContract.Requires <ArgumentException>(releaseDate != DateTime.MinValue, "Invalid Release Date"); var rt = new StringBuilder(releaseTitle); foreach (var stringReplacement in FolderSpaceReplacements) { if (!rt.Equals(stringReplacement)) { rt.Replace(stringReplacement, " "); } } var releasePathTitle = rt.ToString().ToAlphanumericName(false, false).ToFolderNameFriendly().ToTitleCase(false); if (string.IsNullOrEmpty(releasePathTitle)) { throw new Exception($"ReleaseTitle [{ releaseTitle }] is invalid. ArtistFolder [{ artistFolder }]."); } var maxFnLength = MaximumReleaseFolderNameLength - 7; if (releasePathTitle.Length > maxFnLength) { releasePathTitle = releasePathTitle.Substring(0, maxFnLength); } var releasePath = $"[{ releaseDate.ToString("yyyy")}] {releasePathTitle}"; var directoryInfo = new DirectoryInfo(Path.Combine(artistFolder, releasePath)); if (createIfNotFound && !directoryInfo.Exists) { directoryInfo.Create(); } return(directoryInfo.FullName); }
/// <summary> /// Returns the FileName for given Track details, this is not the Full Path (FQDN) only the FileName /// </summary> /// <param name="trackTitle">Title of the Track</param> /// <param name="trackNumber">Track Number</param> /// <param name="discNumber">Optional disc number defaults to 0</param> /// <param name="totalTrackNumber">Optional Total Tracks defaults to TrackNumber</param> /// <param name="fileExtension">Optional File Extension defaults to mp3</param> public static string TrackFileName(IRoadieSettings configuration, string trackTitle, short trackNumber, int?discNumber = null, int?totalTrackNumber = null, string fileExtension = "mp3") { SimpleContract.Requires <ArgumentException>(!string.IsNullOrEmpty(trackTitle), "Invalid Track Title"); SimpleContract.Requires <ArgumentException>(trackNumber > 0, "Invalid Track Number"); SimpleContract.Requires <ArgumentException>(!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 = discNumber ?? 0; var disc = 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}", disc, track, fileNameFromTitle, fileExtension.ToLower())); }
/// <summary> /// For given artist delete any empty folders /// </summary> /// <param name="artist">Populated Artist database record</param> public static bool DeleteEmptyFoldersForArtist(IRoadieSettings configuration, Artist artist) { SimpleContract.Requires <ArgumentException>(artist != null, "Invalid Artist"); return(DeleteEmptyFolders(new DirectoryInfo(artist.ArtistFileFolder(configuration)))); }
/// <summary> /// For given artist delete any empty folders /// </summary> /// <param name="artist">Populated Artist database record</param> /// <param name="destinationFolder">Optional Root folder defaults to Library Folder from Settings</param> /// <returns></returns> public static bool DeleteEmptyFoldersForArtist(IRoadieSettings configuration, Data.Artist artist, string destinationFolder = null) { destinationFolder = destinationFolder ?? configuration.LibraryFolder; SimpleContract.Requires <ArgumentException>(artist != null, "Invalid Artist"); return(FolderPathHelper.DeleteEmptyFolders(new DirectoryInfo(artist.ArtistFileFolder(configuration, destinationFolder)))); }