diff --git a/AppScaffolding/AppScaffolding.csproj b/AppScaffolding/AppScaffolding.csproj
index a30ef065..c6ee6f0c 100644
--- a/AppScaffolding/AppScaffolding.csproj
+++ b/AppScaffolding/AppScaffolding.csproj
@@ -3,7 +3,7 @@
net5.0
- 6.4.3.1
+ 6.4.4.1
diff --git a/ApplicationServices/LibraryCommands.cs b/ApplicationServices/LibraryCommands.cs
index 29f413f2..963e4ce2 100644
--- a/ApplicationServices/LibraryCommands.cs
+++ b/ApplicationServices/LibraryCommands.cs
@@ -167,8 +167,8 @@ namespace ApplicationServices
{
logTime("importIntoDbAsync -- pre db");
using var context = DbContexts.GetContext();
- var libraryImporter = new LibraryBookImporter(context);
- var newCount = await Task.Run(() => libraryImporter.Import(importItems));
+ var libraryBookImporter = new LibraryBookImporter(context);
+ var newCount = await Task.Run(() => libraryBookImporter.Import(importItems));
logTime("importIntoDbAsync -- post Import()");
var qtyChanges = context.SaveChanges();
logTime("importIntoDbAsync -- post SaveChanges");
diff --git a/AudibleUtilities/AudibleUtilities.csproj b/AudibleUtilities/AudibleUtilities.csproj
index 5d5f1c81..467a4404 100644
--- a/AudibleUtilities/AudibleUtilities.csproj
+++ b/AudibleUtilities/AudibleUtilities.csproj
@@ -5,7 +5,7 @@
-
+
diff --git a/FileManager/FileManager.csproj b/FileManager/FileManager.csproj
index 3a6458c4..4ac2e23d 100644
--- a/FileManager/FileManager.csproj
+++ b/FileManager/FileManager.csproj
@@ -5,7 +5,7 @@
-
+
diff --git a/LibationFileManager/TemplateTags.cs b/LibationFileManager/TemplateTags.cs
index c3476fe7..ac5005d2 100644
--- a/LibationFileManager/TemplateTags.cs
+++ b/LibationFileManager/TemplateTags.cs
@@ -21,8 +21,8 @@ namespace LibationFileManager
// putting these first is the incredibly lazy way to make them show up first in the EditTemplateDialog
public static TemplateTags ChCount { get; } = new TemplateTags("ch count", "Number of chapters", true);
public static TemplateTags ChTitle { get; } = new TemplateTags("ch title", "Chapter title", true);
- public static TemplateTags ChNumber { get; } = new TemplateTags("ch#", "Chapter number", true);
- public static TemplateTags ChNumber0 { get; } = new TemplateTags("ch# 0", "Chapter number with leading zeros", true);
+ public static TemplateTags ChNumber { get; } = new TemplateTags("ch#", "Chapter #", true);
+ public static TemplateTags ChNumber0 { get; } = new TemplateTags("ch# 0", "Chapter # with leading zeros", true);
public static TemplateTags Id { get; } = new TemplateTags("id", "Audible ID");
public static TemplateTags Title { get; } = new TemplateTags("title", "Full title");
@@ -36,5 +36,9 @@ namespace LibationFileManager
public static TemplateTags SeriesNumber { get; } = new TemplateTags("series#", "Number order in series");
public static TemplateTags Account { get; } = new TemplateTags("account", "Audible account of this book");
public static TemplateTags Locale { get; } = new TemplateTags("locale", "Region/country");
+
+ // Special case. Isn't mapped to a replacement in Templates.cs
+ // Included here for display by EditTemplateDialog
+ public static TemplateTags IfSeries { get; } = new TemplateTags("if series->...<-if series", "Only include if part of a series");
}
}
diff --git a/LibationFileManager/Templates.cs b/LibationFileManager/Templates.cs
index c75e4b81..4c427de5 100644
--- a/LibationFileManager/Templates.cs
+++ b/LibationFileManager/Templates.cs
@@ -1,9 +1,10 @@
-using Dinah.Core;
-using FileManager;
-using System;
+using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
+using System.Text.RegularExpressions;
+using Dinah.Core;
+using FileManager;
namespace LibationFileManager
{
@@ -106,12 +107,21 @@ namespace LibationFileManager
: getFileNamingTemplate(libraryBookDto, template, null, null)
.GetFilePath();
+ private static Regex ifSeriesRegex { get; } = new Regex("(.*?)<-if series>", RegexOptions.Compiled | RegexOptions.IgnoreCase);
+
internal static FileNamingTemplate getFileNamingTemplate(LibraryBookDto libraryBookDto, string template, string dirFullPath, string extension)
{
ArgumentValidator.EnsureNotNullOrWhiteSpace(template, nameof(template));
ArgumentValidator.EnsureNotNull(libraryBookDto, nameof(libraryBookDto));
dirFullPath = dirFullPath?.Trim() ?? "";
+
+ // for non-series, remove and <-if series> tags and everything in between
+ // for series, remove and <-if series> tags, what's in between will remain
+ template = ifSeriesRegex.Replace(
+ template,
+ string.IsNullOrWhiteSpace(libraryBookDto.SeriesName) ? "" : "$1");
+
var t = template + FileUtility.GetStandardizedExtension(extension);
var fullfilename = dirFullPath == "" ? t : Path.Combine(dirFullPath, t);
diff --git a/LibationWinForms/Dialogs/EditTemplateDialog.Designer.cs b/LibationWinForms/Dialogs/EditTemplateDialog.Designer.cs
index 5afd6a12..deea82d3 100644
--- a/LibationWinForms/Dialogs/EditTemplateDialog.Designer.cs
+++ b/LibationWinForms/Dialogs/EditTemplateDialog.Designer.cs
@@ -114,12 +114,12 @@
// columnHeader1
//
this.columnHeader1.Text = "Tag";
- this.columnHeader1.Width = 90;
+ this.columnHeader1.Width = 137;
//
// columnHeader2
//
this.columnHeader2.Text = "Description";
- this.columnHeader2.Width = 230;
+ this.columnHeader2.Width = 170;
//
// richTextBox1
//
@@ -137,14 +137,13 @@
// warningsLbl
//
this.warningsLbl.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
- this.warningsLbl.AutoSize = true;
this.warningsLbl.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point);
this.warningsLbl.ForeColor = System.Drawing.Color.Firebrick;
this.warningsLbl.Location = new System.Drawing.Point(346, 262);
this.warningsLbl.Name = "warningsLbl";
- this.warningsLbl.Size = new System.Drawing.Size(14, 15);
- this.warningsLbl.TabIndex = 100;
- this.warningsLbl.Text = "6";
+ this.warningsLbl.Size = new System.Drawing.Size(574, 77);
+ this.warningsLbl.TabIndex = 6;
+ this.warningsLbl.Text = "[warnings]";
//
// exampleLbl
//
diff --git a/LibationWinForms/GridEntry.cs b/LibationWinForms/GridEntry.cs
index ca183e11..822b4b2a 100644
--- a/LibationWinForms/GridEntry.cs
+++ b/LibationWinForms/GridEntry.cs
@@ -18,7 +18,7 @@ namespace LibationWinForms
///
internal class GridEntry : AsyncNotifyPropertyChanged, IMemberComparable
{
- #region implementation properties
+ #region implementation properties NOT exposed to the view
// hide from public fields from Data Source GUI with [Browsable(false)]
[Browsable(false)]
@@ -28,10 +28,52 @@ namespace LibationWinForms
#endregion
+ #region Model properties exposed to the view
+ private Image _cover;
+ public Image Cover
+ {
+ get => _cover;
+ private set
+ {
+ _cover = value;
+ NotifyPropertyChanged();
+ }
+ }
+
+ public string ProductRating { get; }
+ public string PurchaseDate { get; }
+ public string MyRating { get; }
+ public string Series { get; }
+ public string Title { get; }
+ public string Length { get; }
+ public string Authors { get; }
+ public string Narrators { get; }
+ public string Category { get; }
+ public string Misc { get; }
+ public string Description { get; }
+ public string DisplayTags
+ {
+ get => string.Join("\r\n", Book.UserDefinedItem.TagsEnumerated);
+ set => Book.UserDefinedItem.Tags = value;
+ }
+
+ // these 2 values being in 1 field is the trick behind getting the liberated+pdf 'stoplight' icon to draw. See: LiberateDataGridViewImageButtonCell.Paint
+ public (LiberatedStatus BookStatus, LiberatedStatus? PdfStatus) Liberate
+ {
+ get => (LibraryCommands.Liberated_Status(LibraryBook.Book), LibraryCommands.Pdf_Status(LibraryBook.Book));
+
+ set
+ {
+ LibraryBook.Book.UserDefinedItem.BookStatus = value.BookStatus;
+ LibraryBook.Book.UserDefinedItem.PdfStatus = value.PdfStatus;
+ }
+ }
+
+ #endregion
+
public event EventHandler Committed;
private Book Book => LibraryBook.Book;
- private Image _cover;
public GridEntry(LibraryBook libraryBook)
{
@@ -145,53 +187,13 @@ namespace LibationWinForms
Committed?.Invoke(this, null);
}
- #endregion
-
- #region Model properties exposed to the view
- public Image Cover
- {
- get
- {
- return _cover;
- }
- private set
- {
- _cover = value;
- NotifyPropertyChanged();
- }
- }
-
- public string ProductRating { get; }
- public string PurchaseDate { get; }
- public string MyRating { get; }
- public string Series { get; }
- public string Title { get; }
- public string Length { get; }
- public string Authors { get; }
- public string Narrators { get; }
- public string Category { get; }
- public string Misc { get; }
- public string Description { get; }
- public string DisplayTags
- {
- get => string.Join("\r\n", Book.UserDefinedItem.TagsEnumerated);
- set => Book.UserDefinedItem.Tags = value;
- }
- // these 2 values being in 1 field is the trick behind getting the liberated+pdf 'stoplight' icon to draw. See: LiberateDataGridViewImageButtonCell.Paint
- public (LiberatedStatus BookStatus, LiberatedStatus? PdfStatus) Liberate
- {
- get => (LibraryCommands.Liberated_Status(LibraryBook.Book), LibraryCommands.Pdf_Status(LibraryBook.Book));
-
- set
- {
- LibraryBook.Book.UserDefinedItem.BookStatus = value.BookStatus;
- LibraryBook.Book.UserDefinedItem.PdfStatus = value.PdfStatus;
- }
- }
-
#endregion
#region Data Sorting
+ // These methods are implementation of Dinah.Core.DataBinding.IMemberComparable
+ // Used by Dinah.Core.DataBinding.SortableBindingList for all sorting
+ public virtual object GetMemberValue(string memberName) => _memberValues[memberName]();
+ public virtual IComparer GetMemberComparer(Type memberType) => _memberTypeComparers[memberType];
private Dictionary> _memberValues { get; }
@@ -225,9 +227,6 @@ namespace LibationWinForms
{ typeof(LiberatedStatus), new ObjectComparer() },
};
- public virtual object GetMemberValue(string memberName) => _memberValues[memberName]();
- public virtual IComparer GetMemberComparer(Type memberType) => _memberTypeComparers[memberType];
-
private static readonly string[] _sortPrefixIgnores = { "the", "a", "an" };
private static string GetSortName(string unformattedName)
{
diff --git a/LibationWinForms/LibationWinForms.csproj b/LibationWinForms/LibationWinForms.csproj
index ca0f987d..ab57fec8 100644
--- a/LibationWinForms/LibationWinForms.csproj
+++ b/LibationWinForms/LibationWinForms.csproj
@@ -29,7 +29,7 @@
-
+
diff --git a/LibationWinForms/ProductsGrid.cs b/LibationWinForms/ProductsGrid.cs
index 1154db8f..0fc13de5 100644
--- a/LibationWinForms/ProductsGrid.cs
+++ b/LibationWinForms/ProductsGrid.cs
@@ -71,7 +71,7 @@ namespace LibationWinForms
}
}
- private async Task Liberate_Click(GridEntry liveGridEntry)
+ private static async Task Liberate_Click(GridEntry liveGridEntry)
{
var libraryBook = liveGridEntry.LibraryBook;
@@ -91,7 +91,7 @@ namespace LibationWinForms
await BookLiberation.ProcessorAutomationController.BackupSingleBookAsync(libraryBook);
}
- private void Details_Click(GridEntry liveGridEntry)
+ private static void Details_Click(GridEntry liveGridEntry)
{
var bookDetailsForm = new BookDetailsDialog(liveGridEntry.LibraryBook);
if (bookDetailsForm.ShowDialog() != DialogResult.OK)
diff --git a/_Tests/LibationFileManager.Tests/TemplatesTests.cs b/_Tests/LibationFileManager.Tests/TemplatesTests.cs
index 080cde1b..bd8d6db9 100644
--- a/_Tests/LibationFileManager.Tests/TemplatesTests.cs
+++ b/_Tests/LibationFileManager.Tests/TemplatesTests.cs
@@ -13,7 +13,7 @@ namespace TemplatesTests
{
public static class Shared
{
- public static LibraryBookDto GetLibraryBook(string asin)
+ public static LibraryBookDto GetLibraryBook(string asin, string seriesName = "Sherlock Holmes")
=> new()
{
Account = "my account",
@@ -22,7 +22,7 @@ namespace TemplatesTests
Locale = "us",
Authors = new List { "Arthur Conan Doyle", "Stephen Fry - introductions" },
Narrators = new List { "Stephen Fry" },
- SeriesName = "Sherlock Holmes",
+ SeriesName = seriesName ?? "",
SeriesNumber = "1"
};
}
@@ -75,6 +75,24 @@ namespace TemplatesTests
=> Templates.getFileNamingTemplate(GetLibraryBook(asin), template, dirFullPath, extension)
.GetFilePath()
.Should().Be(expected);
+
+ [TestMethod]
+ public void IfSeries_empty()
+ => Templates.getFileNamingTemplate(GetLibraryBook("asin", "Sherlock Holmes"), "foo<-if series>bar", @"C:\a\b", "ext")
+ .GetFilePath()
+ .Should().Be(@"C:\a\b\foobar.ext");
+
+ [TestMethod]
+ public void IfSeries_no_series()
+ => Templates.getFileNamingTemplate(GetLibraryBook("asin", ""), "foo---<-if series>bar", @"C:\a\b", "ext")
+ .GetFilePath()
+ .Should().Be(@"C:\a\b\foobar.ext");
+
+ [TestMethod]
+ public void IfSeries_with_series()
+ => Templates.getFileNamingTemplate(GetLibraryBook("asin", "Sherlock Holmes"), "foo---<-if series>bar", @"C:\a\b", "ext")
+ .GetFilePath()
+ .Should().Be(@"C:\a\b\foo-Sherlock Holmes-asin-bar.ext");
}
}