New feature #284 : Add bitrate, sample rate, and channels to template options and to exports

This commit is contained in:
Robert McRackan 2022-07-21 08:37:04 -04:00
parent 7f086aeaac
commit 77e61479cf
9 changed files with 89 additions and 55 deletions

View File

@ -100,6 +100,9 @@ namespace ApplicationServices
[Name("Content Type")] [Name("Content Type")]
public string ContentType { get; set; } public string ContentType { get; set; }
[Name("Audio Format")]
public string AudioFormat { get; set; }
} }
public static class LibToDtos public static class LibToDtos
{ {
@ -132,7 +135,8 @@ namespace ApplicationServices
MyLibationTags = a.Book.UserDefinedItem.Tags, MyLibationTags = a.Book.UserDefinedItem.Tags,
BookStatus = a.Book.UserDefinedItem.BookStatus.ToString(), BookStatus = a.Book.UserDefinedItem.BookStatus.ToString(),
PdfStatus = a.Book.UserDefinedItem.PdfStatus.ToString(), PdfStatus = a.Book.UserDefinedItem.PdfStatus.ToString(),
ContentType = a.Book.ContentType.ToString() ContentType = a.Book.ContentType.ToString(),
AudioFormat = a.Book.AudioFormat.ToString()
}).ToList(); }).ToList();
} }
public static class LibraryExporter public static class LibraryExporter
@ -176,33 +180,34 @@ namespace ApplicationServices
var row = sheet.CreateRow(rowIndex); var row = sheet.CreateRow(rowIndex);
var columns = new[] { var columns = new[] {
nameof (ExportDto.Account), nameof(ExportDto.Account),
nameof (ExportDto.DateAdded), nameof(ExportDto.DateAdded),
nameof (ExportDto.AudibleProductId), nameof(ExportDto.AudibleProductId),
nameof (ExportDto.Locale), nameof(ExportDto.Locale),
nameof (ExportDto.Title), nameof(ExportDto.Title),
nameof (ExportDto.AuthorNames), nameof(ExportDto.AuthorNames),
nameof (ExportDto.NarratorNames), nameof(ExportDto.NarratorNames),
nameof (ExportDto.LengthInMinutes), nameof(ExportDto.LengthInMinutes),
nameof (ExportDto.Description), nameof(ExportDto.Description),
nameof (ExportDto.Publisher), nameof(ExportDto.Publisher),
nameof (ExportDto.HasPdf), nameof(ExportDto.HasPdf),
nameof (ExportDto.SeriesNames), nameof(ExportDto.SeriesNames),
nameof (ExportDto.SeriesOrder), nameof(ExportDto.SeriesOrder),
nameof (ExportDto.CommunityRatingOverall), nameof(ExportDto.CommunityRatingOverall),
nameof (ExportDto.CommunityRatingPerformance), nameof(ExportDto.CommunityRatingPerformance),
nameof (ExportDto.CommunityRatingStory), nameof(ExportDto.CommunityRatingStory),
nameof (ExportDto.PictureId), nameof(ExportDto.PictureId),
nameof (ExportDto.IsAbridged), nameof(ExportDto.IsAbridged),
nameof (ExportDto.DatePublished), nameof(ExportDto.DatePublished),
nameof (ExportDto.CategoriesNames), nameof(ExportDto.CategoriesNames),
nameof (ExportDto.MyRatingOverall), nameof(ExportDto.MyRatingOverall),
nameof (ExportDto.MyRatingPerformance), nameof(ExportDto.MyRatingPerformance),
nameof (ExportDto.MyRatingStory), nameof(ExportDto.MyRatingStory),
nameof (ExportDto.MyLibationTags), nameof(ExportDto.MyLibationTags),
nameof (ExportDto.BookStatus), nameof(ExportDto.BookStatus),
nameof (ExportDto.PdfStatus), nameof(ExportDto.PdfStatus),
nameof (ExportDto.ContentType) nameof(ExportDto.ContentType),
nameof(ExportDto.AudioFormat)
}; };
var col = 0; var col = 0;
foreach (var c in columns) foreach (var c in columns)
@ -268,6 +273,7 @@ namespace ApplicationServices
row.CreateCell(col++).SetCellValue(dto.BookStatus); row.CreateCell(col++).SetCellValue(dto.BookStatus);
row.CreateCell(col++).SetCellValue(dto.PdfStatus); row.CreateCell(col++).SetCellValue(dto.PdfStatus);
row.CreateCell(col++).SetCellValue(dto.ContentType); row.CreateCell(col++).SetCellValue(dto.ContentType);
row.CreateCell(col++).SetCellValue(dto.AudioFormat);
rowIndex++; rowIndex++;
} }

View File

@ -17,7 +17,6 @@ namespace DataLayer
public class AudioFormat : IComparable<AudioFormat>, IComparable public class AudioFormat : IComparable<AudioFormat>, IComparable
{ {
internal int AudioFormatID { get; private set; } internal int AudioFormatID { get; private set; }
public int Bitrate { get; private init; } public int Bitrate { get; private init; }
public int SampleRate { get; private init; } public int SampleRate { get; private init; }

View File

@ -37,7 +37,11 @@ namespace FileLiberator
Narrators = libraryBook.Book.Narrators.Select(c => c.Name).ToList(), Narrators = libraryBook.Book.Narrators.Select(c => c.Name).ToList(),
SeriesName = libraryBook.Book.SeriesLink.FirstOrDefault()?.Series.Name, SeriesName = libraryBook.Book.SeriesLink.FirstOrDefault()?.Series.Name,
SeriesNumber = libraryBook.Book.SeriesLink.FirstOrDefault()?.Order SeriesNumber = libraryBook.Book.SeriesLink.FirstOrDefault()?.Order,
BitRate = libraryBook.Book.AudioFormat.Bitrate,
SampleRate = libraryBook.Book.AudioFormat.SampleRate,
Channels = libraryBook.Book.AudioFormat.Channels,
}; };
} }
} }

View File

@ -20,6 +20,10 @@ namespace LibationFileManager
public string SeriesName { get; set; } public string SeriesName { get; set; }
public string SeriesNumber { get; set; } public string SeriesNumber { get; set; }
public int BitRate { get; set; }
public int SampleRate { get; set; }
public int Channels { get; set; }
} }
public class LibraryBookDto : BookDto public class LibraryBookDto : BookDto

View File

@ -34,6 +34,9 @@ namespace LibationFileManager
public static TemplateTags Series { get; } = new TemplateTags("series", "Name of series"); public static TemplateTags Series { get; } = new TemplateTags("series", "Name of series");
// can't also have a leading zeros version. Too many weird edge cases. Eg: "1-4" // can't also have a leading zeros version. Too many weird edge cases. Eg: "1-4"
public static TemplateTags SeriesNumber { get; } = new TemplateTags("series#", "Number order in series"); public static TemplateTags SeriesNumber { get; } = new TemplateTags("series#", "Number order in series");
public static TemplateTags Bitrate { get; } = new TemplateTags("bitrate", "File's orig. bitrate");
public static TemplateTags SampleRate { get; } = new TemplateTags("samplerate", "File's orig. sample rate");
public static TemplateTags Channels { get; } = new TemplateTags("channels", "Number of audio channels");
public static TemplateTags Account { get; } = new TemplateTags("account", "Audible account of this book"); public static TemplateTags Account { get; } = new TemplateTags("account", "Audible account of this book");
public static TemplateTags Locale { get; } = new TemplateTags("locale", "Region/country"); public static TemplateTags Locale { get; } = new TemplateTags("locale", "Region/country");

View File

@ -137,6 +137,9 @@ namespace LibationFileManager
fileNamingTemplate.AddParameterReplacement(TemplateTags.FirstNarrator, libraryBookDto.FirstNarrator); fileNamingTemplate.AddParameterReplacement(TemplateTags.FirstNarrator, libraryBookDto.FirstNarrator);
fileNamingTemplate.AddParameterReplacement(TemplateTags.Series, libraryBookDto.SeriesName); fileNamingTemplate.AddParameterReplacement(TemplateTags.Series, libraryBookDto.SeriesName);
fileNamingTemplate.AddParameterReplacement(TemplateTags.SeriesNumber, libraryBookDto.SeriesNumber); fileNamingTemplate.AddParameterReplacement(TemplateTags.SeriesNumber, libraryBookDto.SeriesNumber);
fileNamingTemplate.AddParameterReplacement(TemplateTags.Bitrate, libraryBookDto.BitRate);
fileNamingTemplate.AddParameterReplacement(TemplateTags.SampleRate, libraryBookDto.SampleRate);
fileNamingTemplate.AddParameterReplacement(TemplateTags.Channels, libraryBookDto.Channels);
fileNamingTemplate.AddParameterReplacement(TemplateTags.Account, libraryBookDto.Account); fileNamingTemplate.AddParameterReplacement(TemplateTags.Account, libraryBookDto.Account);
fileNamingTemplate.AddParameterReplacement(TemplateTags.Locale, libraryBookDto.Locale); fileNamingTemplate.AddParameterReplacement(TemplateTags.Locale, libraryBookDto.Locale);

View File

@ -79,7 +79,10 @@ namespace LibationWinForms.Dialogs
Authors = new List<string> { "Arthur Conan Doyle", "Stephen Fry - introductions" }, Authors = new List<string> { "Arthur Conan Doyle", "Stephen Fry - introductions" },
Narrators = new List<string> { "Stephen Fry" }, Narrators = new List<string> { "Stephen Fry" },
SeriesName = "Sherlock Holmes", SeriesName = "Sherlock Holmes",
SeriesNumber = "1" SeriesNumber = "1",
BitRate = 128,
SampleRate = 44100,
Channels = 2
}; };
var chapterName = "A Flight for Life"; var chapterName = "A Flight for Life";
var chapterNumber = 4; var chapterNumber = 4;

View File

@ -21,7 +21,7 @@ namespace FileNamingTemplateTests
sb.Append('0', 300); sb.Append('0', 300);
var longText = sb.ToString(); var longText = sb.ToString();
var expectedNew = "C:\\foo\\bar\\my book 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 [ID123456].txt"; var expectedNew = @"C:\foo\bar\my book 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 [ID123456].txt";
var f2 = NEW_GetValidFilename_FileNamingTemplate(@"C:\foo\bar", "my: book " + longText, "txt", "ID123456"); var f2 = NEW_GetValidFilename_FileNamingTemplate(@"C:\foo\bar", "my: book " + longText, "txt", "ID123456");
f2.Should().Be(expectedNew); f2.Should().Be(expectedNew);

View File

@ -12,19 +12,30 @@ using static TemplatesTests.Shared;
namespace TemplatesTests namespace TemplatesTests
{ {
/////////////////////////////////////////////////
// //
// add general tag replacement tests to: //
// //
// getFileNamingTemplate.Tests //
// //
/////////////////////////////////////////////////
public static class Shared public static class Shared
{ {
public static LibraryBookDto GetLibraryBook(string asin, string seriesName = "Sherlock Holmes") public static LibraryBookDto GetLibraryBook(string seriesName = "Sherlock Holmes")
=> new() => new()
{ {
Account = "my account", Account = "my account",
AudibleProductId = asin, AudibleProductId = "asin",
Title = "A Study in Scarlet: A Sherlock Holmes Novel", Title = "A Study in Scarlet: A Sherlock Holmes Novel",
Locale = "us", Locale = "us",
Authors = new List<string> { "Arthur Conan Doyle", "Stephen Fry - introductions" }, Authors = new List<string> { "Arthur Conan Doyle", "Stephen Fry - introductions" },
Narrators = new List<string> { "Stephen Fry" }, Narrators = new List<string> { "Stephen Fry" },
SeriesName = seriesName ?? "", SeriesName = seriesName ?? "",
SeriesNumber = "1" SeriesNumber = "1",
BitRate = 128,
SampleRate = 44100,
Channels = 2
}; };
} }
@ -56,48 +67,49 @@ namespace TemplatesTests
[TestMethod] [TestMethod]
[DataRow(null, "asin", @"C:\", "ext")] [DataRow(null, @"C:\", "ext")]
[ExpectedException(typeof(ArgumentNullException))] [ExpectedException(typeof(ArgumentNullException))]
public void arg_null_exception(string template, string asin, string dirFullPath, string extension) public void arg_null_exception(string template, string dirFullPath, string extension)
=> Templates.getFileNamingTemplate(GetLibraryBook(asin), template, dirFullPath, extension); => Templates.getFileNamingTemplate(GetLibraryBook(), template, dirFullPath, extension);
[TestMethod] [TestMethod]
[DataRow("", "asin", @"C:\foo\bar", "ext")] [DataRow("", @"C:\foo\bar", "ext")]
[DataRow(" ", "asin", @"C:\foo\bar", "ext")] [DataRow(" ", @"C:\foo\bar", "ext")]
[ExpectedException(typeof(ArgumentException))] [ExpectedException(typeof(ArgumentException))]
public void arg_exception(string template, string asin, string dirFullPath, string extension) public void arg_exception(string template, string dirFullPath, string extension)
=> Templates.getFileNamingTemplate(GetLibraryBook(asin), template, dirFullPath, extension); => Templates.getFileNamingTemplate(GetLibraryBook(), template, dirFullPath, extension);
[TestMethod] [TestMethod]
public void null_extension() => Tests("f.txt", "asin", @"C:\foo\bar", null, @"C:\foo\bar\f.txt"); public void null_extension() => Tests("f.txt", @"C:\foo\bar", null, @"C:\foo\bar\f.txt");
[TestMethod] [TestMethod]
[DataRow("f.txt", "asin", @"C:\foo\bar", "ext", @"C:\foo\bar\f.txt.ext")] [DataRow("f.txt", @"C:\foo\bar", "ext", @"C:\foo\bar\f.txt.ext")]
[DataRow("f", "asin", @"C:\foo\bar", "ext", @"C:\foo\bar\f.ext")] [DataRow("f", @"C:\foo\bar", "ext", @"C:\foo\bar\f.ext")]
[DataRow("<id>", "asin", @"C:\foo\bar", "ext", @"C:\foo\bar\asin.ext")] [DataRow("<id>", @"C:\foo\bar", "ext", @"C:\foo\bar\asin.ext")]
public void Tests(string template, string asin, string dirFullPath, string extension, string expected) [DataRow("<bitrate> - <samplerate> - <channels>", @"C:\foo\bar", "ext", @"C:\foo\bar\128 - 44100 - 2.ext")]
=> Templates.getFileNamingTemplate(GetLibraryBook(asin), template, dirFullPath, extension) public void Tests(string template, string dirFullPath, string extension, string expected)
=> Templates.getFileNamingTemplate(GetLibraryBook(), template, dirFullPath, extension)
.GetFilePath(Replacements) .GetFilePath(Replacements)
.PathWithoutPrefix .PathWithoutPrefix
.Should().Be(expected); .Should().Be(expected);
[TestMethod] [TestMethod]
public void IfSeries_empty() public void IfSeries_empty()
=> Templates.getFileNamingTemplate(GetLibraryBook("asin", "Sherlock Holmes"), "foo<if series-><-if series>bar", @"C:\a\b", "ext") => Templates.getFileNamingTemplate(GetLibraryBook(), "foo<if series-><-if series>bar", @"C:\a\b", "ext")
.GetFilePath(Replacements) .GetFilePath(Replacements)
.PathWithoutPrefix .PathWithoutPrefix
.Should().Be(@"C:\a\b\foobar.ext"); .Should().Be(@"C:\a\b\foobar.ext");
[TestMethod] [TestMethod]
public void IfSeries_no_series() public void IfSeries_no_series()
=> Templates.getFileNamingTemplate(GetLibraryBook("asin", ""), "foo<if series->-<series>-<id>-<-if series>bar", @"C:\a\b", "ext") => Templates.getFileNamingTemplate(GetLibraryBook(null), "foo<if series->-<series>-<id>-<-if series>bar", @"C:\a\b", "ext")
.GetFilePath(Replacements) .GetFilePath(Replacements)
.PathWithoutPrefix .PathWithoutPrefix
.Should().Be(@"C:\a\b\foobar.ext"); .Should().Be(@"C:\a\b\foobar.ext");
[TestMethod] [TestMethod]
public void IfSeries_with_series() public void IfSeries_with_series()
=> Templates.getFileNamingTemplate(GetLibraryBook("asin", "Sherlock Holmes"), "foo<if series->-<series>-<id>-<-if series>bar", @"C:\a\b", "ext") => Templates.getFileNamingTemplate(GetLibraryBook(), "foo<if series->-<series>-<id>-<-if series>bar", @"C:\a\b", "ext")
.GetFilePath(Replacements) .GetFilePath(Replacements)
.PathWithoutPrefix .PathWithoutPrefix
.Should().Be(@"C:\a\b\foo-Sherlock Holmes-asin-bar.ext"); .Should().Be(@"C:\a\b\foo-Sherlock Holmes-asin-bar.ext");
@ -394,10 +406,10 @@ namespace Templates_ChapterFile_Tests
static readonly ReplacementCharacters Default = ReplacementCharacters.Default; static readonly ReplacementCharacters Default = ReplacementCharacters.Default;
[TestMethod] [TestMethod]
[DataRow("asin", "[<id>] <ch# 0> of <ch count> - <ch title>", @"C:\foo\", "txt", 6, 10, "chap", @"C:\foo\[asin] 06 of 10 - chap.txt")] [DataRow("[<id>] <ch# 0> of <ch count> - <ch title>", @"C:\foo\", "txt", 6, 10, "chap", @"C:\foo\[asin] 06 of 10 - chap.txt")]
[DataRow("asin", "<ch#>", @"C:\foo\", "txt", 6, 10, "chap", @"C:\foo\6.txt")] [DataRow("<ch#>", @"C:\foo\", "txt", 6, 10, "chap", @"C:\foo\6.txt")]
public void Tests(string asin, string template, string dir, string ext, int pos, int total, string chapter, string expected) public void Tests(string template, string dir, string ext, int pos, int total, string chapter, string expected)
=> Templates.ChapterFile.GetPortionFilename(GetLibraryBook(asin), template, new() { OutputFileName = $"xyz.{ext}", PartsPosition = pos, PartsTotal = total, Title = chapter }, dir, Default) => Templates.ChapterFile.GetPortionFilename(GetLibraryBook(), template, new() { OutputFileName = $"xyz.{ext}", PartsPosition = pos, PartsTotal = total, Title = chapter }, dir, Default)
.Should().Be(expected); .Should().Be(expected);
} }
} }