diff --git a/Source/DataLayer/EfClasses/Book.cs b/Source/DataLayer/EfClasses/Book.cs index 8de17cb8..d11fb75b 100644 --- a/Source/DataLayer/EfClasses/Book.cs +++ b/Source/DataLayer/EfClasses/Book.cs @@ -42,6 +42,7 @@ namespace DataLayer public int LengthInMinutes { get; private set; } public ContentType ContentType { get; private set; } public string Locale { get; private set; } + public DateTime? IncludedUntil { get; private set; } // mutable public string PictureId { get; set; } @@ -73,7 +74,9 @@ namespace DataLayer ContentType contentType, IEnumerable authors, IEnumerable narrators, - string localeName) + string localeName, + DateTime? includedUntil + ) { // validate ArgumentValidator.EnsureNotNull(audibleProductId, nameof(audibleProductId)); @@ -97,6 +100,7 @@ namespace DataLayer UpdateTitle(title, subtitle); Description = description?.Trim() ?? ""; LengthInMinutes = lengthInMinutes; + IncludedUntil = includedUntil; ContentType = contentType; // assigns with biz logic @@ -113,6 +117,9 @@ namespace DataLayer public void UpdateLengthInMinutes(int lengthInMinutes) => LengthInMinutes = lengthInMinutes; + + public void UpdateIncludedUntil(DateTime? includedUntil) + => IncludedUntil = includedUntil; #region contributors, authors, narrators internal HashSet ContributorsLink { get; private set; } diff --git a/Source/DtoImporterService/BookImporter.cs b/Source/DtoImporterService/BookImporter.cs index e6596d09..b310b8aa 100644 --- a/Source/DtoImporterService/BookImporter.cs +++ b/Source/DtoImporterService/BookImporter.cs @@ -98,6 +98,20 @@ namespace DtoImporterService .DistinctBy(a => a.Name) .Select(n => contributorImporter.Cache[n.Name]) .ToList(); + + //Used to determine when your audible plus or free book will expire from your library + //plan.IsAyce from underlying AudibleApi project determines the plans to look at, first plan found is used. + DateTime? includedUntil = null; + if (item.Plans is not null) + { + foreach (var plan in item.Plans) + { + if (plan.IsAyce && plan.EndDate.Value.Year != 2099 && plan.EndDate.HasValue) + { + includedUntil = plan.EndDate.Value.LocalDateTime; + } + } + } Book book; try @@ -111,7 +125,9 @@ namespace DtoImporterService contentType, authors, narrators, - importItem.LocaleName) + importItem.LocaleName, + includedUntil + ) ).Entity; Cache.Add(book.AudibleProductId, book); } @@ -125,7 +141,8 @@ namespace DtoImporterService contentType, QtyAuthors = authors?.Count, QtyNarrators = narrators?.Count, - importItem.LocaleName + importItem.LocaleName, + includedUntil }); throw; } diff --git a/Source/LibationAvalonia/Controls/ThemePreviewControl.axaml.cs b/Source/LibationAvalonia/Controls/ThemePreviewControl.axaml.cs index ee35a855..bd28249b 100644 --- a/Source/LibationAvalonia/Controls/ThemePreviewControl.axaml.cs +++ b/Source/LibationAvalonia/Controls/ThemePreviewControl.axaml.cs @@ -4,6 +4,7 @@ using Dinah.Core.ErrorHandling; using LibationAvalonia.ViewModels; using LibationFileManager; using LibationUiBase.ProcessQueue; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -58,12 +59,12 @@ public partial class ThemePreviewControl : UserControl var author = new Contributor("Some Author", "asin_contributor"); var narrator = new Contributor("Some Narrator", "asin_narrator"); - var book1 = new Book(new AudibleProductId("asin_book1"), "Some Book 1", "The Theming", "Demo Book Entry", 525600, ContentType.Product, [author], [narrator], "us"); - var book2 = new Book(new AudibleProductId("asin_book2"), "Some Book 2", "The Theming", "Demo Book Entry", 525600, ContentType.Product, [author], [narrator], "us"); - var book3 = new Book(new AudibleProductId("asin_book3"), "Some Book 3", "The Theming", "Demo Book Entry", 525600, ContentType.Product, [author], [narrator], "us"); - var book4 = new Book(new AudibleProductId("asin_book4"), "Some Book 4", "The Theming", "Demo Book Entry", 525600, ContentType.Product, [author], [narrator], "us"); - var seriesParent = new Book(new AudibleProductId("asin_series"), "Some Series", "", "Demo Series Entry", 0, ContentType.Parent, [author], [narrator], "us"); - var episode = new Book(new AudibleProductId("asin_episode"), "Some Episode", "Episode 1", "Demo Episode Entry", 56, ContentType.Episode, [author], [narrator], "us"); + var book1 = new Book(new AudibleProductId("asin_book1"), "Some Book 1", "The Theming", "Demo Book Entry", 525600, ContentType.Product, [author], [narrator], "us", null); + var book2 = new Book(new AudibleProductId("asin_book2"), "Some Book 2", "The Theming", "Demo Book Entry", 525600, ContentType.Product, [author], [narrator], "us", null); + var book3 = new Book(new AudibleProductId("asin_book3"), "Some Book 3", "The Theming", "Demo Book Entry", 525600, ContentType.Product, [author], [narrator], "us", null); + var book4 = new Book(new AudibleProductId("asin_book4"), "Some Book 4", "The Theming", "Demo Book Entry", 525600, ContentType.Product, [author], [narrator], "us", null); + var seriesParent = new Book(new AudibleProductId("asin_series"), "Some Series", "", "Demo Series Entry", 0, ContentType.Parent, [author], [narrator], "us",null); + var episode = new Book(new AudibleProductId("asin_episode"), "Some Episode", "Episode 1", "Demo Episode Entry", 56, ContentType.Episode, [author], [narrator], "us",null); var series = new Series(new AudibleSeriesId(seriesParent.AudibleProductId), seriesParent.Title); diff --git a/Source/LibationAvalonia/ViewModels/ProductsDisplayViewModel.cs b/Source/LibationAvalonia/ViewModels/ProductsDisplayViewModel.cs index f51a3044..473a8592 100644 --- a/Source/LibationAvalonia/ViewModels/ProductsDisplayViewModel.cs +++ b/Source/LibationAvalonia/ViewModels/ProductsDisplayViewModel.cs @@ -477,6 +477,7 @@ namespace LibationAvalonia.ViewModels public DataGridLength PurchaseDateWidth { get => getColumnWidth("PurchaseDate", 75); set => setColumnWidth("PurchaseDate", value); } public DataGridLength MyRatingWidth { get => getColumnWidth("MyRating", 95); set => setColumnWidth("MyRating", value); } public DataGridLength MiscWidth { get => getColumnWidth("Misc", 140); set => setColumnWidth("Misc", value); } + public DataGridLength IncludedUntilWidth { get => getColumnWidth("IncludedUntil", 140); set => setColumnWidth("IncludedUntil", value); } public DataGridLength LastDownloadWidth { get => getColumnWidth("LastDownload", 100); set => setColumnWidth("LastDownload", value); } public DataGridLength BookTagsWidth { get => getColumnWidth("BookTags", 100); set => setColumnWidth("BookTags", value); } public DataGridLength IsSpatialWidth { get => getColumnWidth("IsSpatial", 100); set => setColumnWidth("IsSpatial", value); } diff --git a/Source/LibationAvalonia/Views/ProductsDisplay.axaml b/Source/LibationAvalonia/Views/ProductsDisplay.axaml index 8f2ec9c2..17cc6516 100644 --- a/Source/LibationAvalonia/Views/ProductsDisplay.axaml +++ b/Source/LibationAvalonia/Views/ProductsDisplay.axaml @@ -213,6 +213,16 @@ + + + + + + + + + + diff --git a/Source/LibationUiBase/GridView/GridEntry.cs b/Source/LibationUiBase/GridView/GridEntry.cs index 665859f1..3adf66f2 100644 --- a/Source/LibationUiBase/GridView/GridEntry.cs +++ b/Source/LibationUiBase/GridView/GridEntry.cs @@ -49,6 +49,7 @@ namespace LibationUiBase.GridView private string _bookTags; private Rating _myRating; private bool _isSpatial; + private string _includedUntil; public abstract bool? Remove { get; set; } public EntryStatus Liberate { get => _liberate; private set => RaiseAndSetIfChanged(ref _liberate, value); } public string PurchaseDate { get => _purchasedate; protected set => RaiseAndSetIfChanged(ref _purchasedate, value); } @@ -66,6 +67,7 @@ namespace LibationUiBase.GridView public Rating ProductRating { get => _productrating; private set => RaiseAndSetIfChanged(ref _productrating, value); } public string BookTags { get => _bookTags; private set => RaiseAndSetIfChanged(ref _bookTags, value); } public bool IsSpatial { get => _isSpatial; protected set => RaiseAndSetIfChanged(ref _isSpatial, value); } + public string IncludedUntil { get => _includedUntil; protected set => RaiseAndSetIfChanged(ref _includedUntil, value); } public Rating MyRating { @@ -120,6 +122,8 @@ namespace LibationUiBase.GridView SeriesIndex = Book.SeriesLink.FirstOrDefault()?.Index ?? 0; BookTags = GetBookTags(); IsSpatial = Book.IsSpatial; + IncludedUntil = GetIncludedUntilString(); + UserDefinedItem.ItemChanged += UserDefinedItem_ItemChanged; } @@ -128,6 +132,7 @@ namespace LibationUiBase.GridView protected virtual DateTime GetPurchaseDate() => LibraryBook.DateAdded; protected virtual int GetLengthInMinutes() => Book.LengthInMinutes; protected string GetPurchaseDateString() => GetPurchaseDate().ToString("d"); + protected string GetIncludedUntilString() => Book.IncludedUntil?.ToString("d") ?? string.Empty; protected string GetBookLengthString() { int bookLenMins = GetLengthInMinutes(); @@ -208,6 +213,7 @@ namespace LibationUiBase.GridView nameof(Liberate) => Liberate, nameof(DateAdded) => DateAdded, nameof(IsSpatial) => IsSpatial, + nameof(IncludedUntil) => IncludedUntil, _ => null }; diff --git a/Source/LibationWinForms/GridView/ProductsGrid.Designer.cs b/Source/LibationWinForms/GridView/ProductsGrid.Designer.cs index 3f004673..21874afa 100644 --- a/Source/LibationWinForms/GridView/ProductsGrid.Designer.cs +++ b/Source/LibationWinForms/GridView/ProductsGrid.Designer.cs @@ -54,6 +54,7 @@ namespace LibationWinForms.GridView lastDownloadedGVColumn = new LastDownloadedGridViewColumn(); isSpatialGVColumn = new System.Windows.Forms.DataGridViewCheckBoxColumn(); tagAndDetailsGVColumn = new EditTagsDataGridViewImageButtonColumn(); + includedUntilGVColumn = new System.Windows.Forms.DataGridViewTextBoxColumn(); ((System.ComponentModel.ISupportInitialize)gridEntryDataGridView).BeginInit(); ((System.ComponentModel.ISupportInitialize)syncBindingSource).BeginInit(); SuspendLayout(); @@ -66,7 +67,7 @@ namespace LibationWinForms.GridView gridEntryDataGridView.AllowUserToResizeRows = false; gridEntryDataGridView.AutoGenerateColumns = false; gridEntryDataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; - gridEntryDataGridView.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { removeGVColumn, liberateGVColumn, coverGVColumn, titleGVColumn, authorsGVColumn, narratorsGVColumn, lengthGVColumn, seriesGVColumn, seriesOrderGVColumn, descriptionGVColumn, categoryGVColumn, productRatingGVColumn, purchaseDateGVColumn, myRatingGVColumn, miscGVColumn, lastDownloadedGVColumn, isSpatialGVColumn, tagAndDetailsGVColumn }); + gridEntryDataGridView.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { removeGVColumn, liberateGVColumn, coverGVColumn, titleGVColumn, authorsGVColumn, narratorsGVColumn, lengthGVColumn, seriesGVColumn, seriesOrderGVColumn, descriptionGVColumn, categoryGVColumn, productRatingGVColumn, purchaseDateGVColumn, myRatingGVColumn, miscGVColumn, lastDownloadedGVColumn, isSpatialGVColumn, tagAndDetailsGVColumn, includedUntilGVColumn }); gridEntryDataGridView.ContextMenuStrip = showHideColumnsContextMenuStrip; gridEntryDataGridView.DataSource = syncBindingSource; dataGridViewCellStyle2.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; @@ -276,6 +277,16 @@ namespace LibationWinForms.GridView tagAndDetailsGVColumn.ScaleFactor = 0F; tagAndDetailsGVColumn.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic; // + // includedUntilGVColumn + // + includedUntilGVColumn.DataPropertyName = "IncludedUntil"; + includedUntilGVColumn.HeaderText = "Included Until"; + includedUntilGVColumn.MinimumWidth = 10; + includedUntilGVColumn.Name = "includedUntilGVColumn"; + includedUntilGVColumn.ReadOnly = true; + includedUntilGVColumn.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic; + includedUntilGVColumn.Width = 108; + // // ProductsGrid // AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); @@ -314,5 +325,6 @@ namespace LibationWinForms.GridView private LastDownloadedGridViewColumn lastDownloadedGVColumn; private System.Windows.Forms.DataGridViewCheckBoxColumn isSpatialGVColumn; private EditTagsDataGridViewImageButtonColumn tagAndDetailsGVColumn; + private System.Windows.Forms.DataGridViewTextBoxColumn includedUntilGVColumn; } }