Added beta-specific logging

This commit is contained in:
Robert McRackan 2019-11-24 21:45:35 -05:00
parent 1375da2065
commit 6c9074169a
9 changed files with 145 additions and 87 deletions

View File

@ -50,6 +50,18 @@ namespace DtoImporterService
{ {
var book = context.Books.Local.SingleOrDefault(p => p.AudibleProductId == item.ProductId); var book = context.Books.Local.SingleOrDefault(p => p.AudibleProductId == item.ProductId);
if (book is null) if (book is null)
{
book = createNewBook(item, context);
qtyNew++;
}
updateBook(item, book, context);
}
return qtyNew;
}
private static Book createNewBook(Item item, LibationContext context)
{ {
// nested logic is required so order of names is retained. else, contributors may appear in the order they were inserted into the db // nested logic is required so order of names is retained. else, contributors may appear in the order they were inserted into the db
var authors = item var authors = item
@ -66,7 +78,7 @@ namespace DtoImporterService
.Select(n => context.Contributors.Local.Single(c => n.Name == c.Name)) .Select(n => context.Contributors.Local.Single(c => n.Name == c.Name))
.ToList(); .ToList();
book = context.Books.Add(new Book( var book = context.Books.Add(new Book(
new AudibleProductId(item.ProductId), new AudibleProductId(item.ProductId),
item.Title, item.Title,
item.Description, item.Description,
@ -82,27 +94,29 @@ namespace DtoImporterService
book.ReplacePublisher(publisher); book.ReplacePublisher(publisher);
} }
qtyNew++; // categories are laid out for a breadcrumb. category is 1st, subcategory is 2nd
var category = context.Categories.Local.SingleOrDefault(c => c.AudibleCategoryId == item.Categories.LastOrDefault().CategoryId);
if (category != null)
book.UpdateCategory(category, context);
book.UpdateBookDetails(item.IsAbridged, item.DatePublished);
if (!string.IsNullOrWhiteSpace(item.SupplementUrl))
book.AddSupplementDownloadUrl(item.SupplementUrl);
return book;
} }
private static void updateBook(Item item, Book book, LibationContext context)
{
// set/update book-specific info which may have changed // set/update book-specific info which may have changed
book.PictureId = item.PictureId; book.PictureId = item.PictureId;
book.UpdateProductRating(item.Product_OverallStars, item.Product_PerformanceStars, item.Product_StoryStars); book.UpdateProductRating(item.Product_OverallStars, item.Product_PerformanceStars, item.Product_StoryStars);
if (!string.IsNullOrWhiteSpace(item.SupplementUrl))
book.AddSupplementDownloadUrl(item.SupplementUrl);
// important to update user-specific info. this will have changed if user has rated/reviewed the book since last library import // important to update user-specific info. this will have changed if user has rated/reviewed the book since last library import
book.UserDefinedItem.UpdateRating(item.MyUserRating_Overall, item.MyUserRating_Performance, item.MyUserRating_Story); book.UserDefinedItem.UpdateRating(item.MyUserRating_Overall, item.MyUserRating_Performance, item.MyUserRating_Story);
// // update series even for existing books. these are occasionally updated
// this was round 1 when it was a 2 step process
//
//// update series even for existing books. these are occasionally updated
//var seriesIds = item.Series.Select(kvp => kvp.SeriesId).ToList();
//var allSeries = context.Series.Local.Where(c => seriesIds.Contains(c.AudibleSeriesId)).ToList();
//foreach (var series in allSeries)
// book.UpsertSeries(series);
// these will upsert over library-scraped series, but will not leave orphans // these will upsert over library-scraped series, but will not leave orphans
if (item.Series != null) if (item.Series != null)
{ {
@ -112,16 +126,6 @@ namespace DtoImporterService
book.UpsertSeries(series, seriesEntry.Index); book.UpsertSeries(series, seriesEntry.Index);
} }
} }
// categories are laid out for a breadcrumb. category is 1st, subcategory is 2nd
var category = context.Categories.Local.SingleOrDefault(c => c.AudibleCategoryId == item.Categories.LastOrDefault().CategoryId);
if (category != null)
book.UpdateCategory(category, context);
book.UpdateBookDetails(item.IsAbridged, item.DatePublished);
}
return qtyNew;
} }
} }
} }

View File

@ -19,10 +19,10 @@ namespace DtoImporterService
var publishers = items.GetPublishersDistinct().ToList(); var publishers = items.GetPublishersDistinct().ToList();
// load db existing => .Local // load db existing => .Local
var allNames = authors var allNames = publishers
.Select(a => a.Name) .Union(authors.Select(n => n.Name))
.Union(narrators.Select(n => n.Name)) .Union(narrators.Select(n => n.Name))
.Union(publishers) .Where(name => !string.IsNullOrWhiteSpace(name))
.ToList(); .ToList();
loadLocal_contributors(allNames, context); loadLocal_contributors(allNames, context);
@ -36,9 +36,6 @@ namespace DtoImporterService
private void loadLocal_contributors(List<string> contributorNames, LibationContext context) private void loadLocal_contributors(List<string> contributorNames, LibationContext context)
{ {
contributorNames.Remove(null);
contributorNames.Remove("");
//// BAD: very inefficient //// BAD: very inefficient
// var x = context.Contributors.Local.Where(c => !contribNames.Contains(c.Name)); // var x = context.Contributors.Local.Where(c => !contribNames.Contains(c.Name));

View File

@ -20,13 +20,29 @@ namespace DtoImporterService
} }
} }
try
{
var exceptions = Validate(param); var exceptions = Validate(param);
if (exceptions != null && exceptions.Any()) if (exceptions != null && exceptions.Any())
throw new AggregateException($"Device Jobs Service configuration validation failed", exceptions); throw new AggregateException($"Importer validation failed", exceptions);
}
catch (Exception ex)
{
Serilog.Log.Logger.Error(ex, "Import error: validation");
throw;
}
try
{
var result = func(param, context); var result = func(param, context);
return result; return result;
} }
catch (Exception ex)
{
Serilog.Log.Logger.Error(ex, "Import error: post-validation importing");
throw;
}
}
IEnumerable<Exception> Validate(T param); IEnumerable<Exception> Validate(T param);
} }

View File

@ -17,17 +17,17 @@ namespace DtoImporterService
var series = items.GetSeriesDistinct().ToList(); var series = items.GetSeriesDistinct().ToList();
// load db existing => .Local // load db existing => .Local
var seriesIds = series.Select(s => s.SeriesId).ToList(); loadLocal_series(series, context);
loadLocal_series(seriesIds, context);
// upsert // upsert
var qtyNew = upsertSeries(series, context); var qtyNew = upsertSeries(series, context);
return qtyNew; return qtyNew;
} }
private void loadLocal_series(List<string> seriesIds, LibationContext context) private void loadLocal_series(List<AudibleApiDTOs.Series> series, LibationContext context)
{ {
var localIds = context.Series.Local.Select(s => s.AudibleSeriesId); var seriesIds = series.Select(s => s.SeriesId).ToList();
var localIds = context.Series.Local.Select(s => s.AudibleSeriesId).ToList();
var remainingSeriesIds = seriesIds var remainingSeriesIds = seriesIds
.Distinct() .Distinct()
.Except(localIds) .Except(localIds)

View File

@ -28,7 +28,7 @@ namespace InternalUtilities
private async Task<List<Item>> getItemsAsync(ILoginCallback callback) private async Task<List<Item>> getItemsAsync(ILoginCallback callback)
{ {
var api = await EzApiCreator.GetApiAsync(AudibleApiStorage.IdentityTokensFile, callback, Configuration.Instance.LocaleCountryCode); var api = await getApiAsync(callback);
var items = await AudibleApiExtensions.GetAllLibraryItemsAsync(api); var items = await AudibleApiExtensions.GetAllLibraryItemsAsync(api);
// remove episode parents // remove episode parents
@ -62,6 +62,20 @@ namespace InternalUtilities
return items; return items;
} }
private async Task<Api> getApiAsync(ILoginCallback callback)
{
try
{
return await EzApiCreator.GetApiAsync(AudibleApiStorage.IdentityTokensFile, callback, Configuration.Instance.LocaleCountryCode);
}
catch (Exception ex)
{
Serilog.Log.Logger.Error(ex, "Error getting Audible API");
throw;
}
}
private static List<IValidator> getValidators() private static List<IValidator> getValidators()
{ {
var type = typeof(IValidator); var type = typeof(IValidator);

View File

@ -27,8 +27,19 @@ namespace InternalUtilities
ResponseGroups = LibraryOptions.ResponseGroupOptions.ALL_OPTIONS ResponseGroups = LibraryOptions.ResponseGroupOptions.ALL_OPTIONS
}); });
string pageStr = null;
LibraryDtoV10 libResult;
try
{
pageStr = page.ToString();
// important! use this convert method // important! use this convert method
var libResult = LibraryDtoV10.FromJson(page.ToString()); libResult = LibraryDtoV10.FromJson(pageStr);
}
catch (Exception ex)
{
Serilog.Log.Logger.Error(ex, "Error converting library for importing use. Full library:\r\n" + pageStr);
throw;
}
if (!libResult.Items.Any()) if (!libResult.Items.Any())
break; break;

View File

@ -1,4 +1,5 @@
using System.Windows.Forms; using System;
using System.Windows.Forms;
using ApplicationServices; using ApplicationServices;
namespace LibationWinForm namespace LibationWinForm
@ -20,9 +21,11 @@ namespace LibationWinForm
{ {
(TotalBooksProcessed, NewBooksAdded) = await LibraryCommands.IndexLibraryAsync(new Login.WinformResponder()); (TotalBooksProcessed, NewBooksAdded) = await LibraryCommands.IndexLibraryAsync(new Login.WinformResponder());
} }
catch catch (Exception ex)
{ {
MessageBox.Show("Error importing library. Please try again. If this happens after 2 or 3 tries, contact administrator", "Error importing library", MessageBoxButtons.OK, MessageBoxIcon.Error); var msg = "Error importing library. Please try again. If this happens after 2 or 3 tries, contact administrator";
Serilog.Log.Logger.Error(ex, msg);
MessageBox.Show(msg, "Error importing library", MessageBoxButtons.OK, MessageBoxIcon.Error);
} }
this.Close(); this.Close();

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Windows.Forms; using System.Windows.Forms;
using Serilog;
namespace LibationWinForm namespace LibationWinForm
{ {
@ -14,6 +15,8 @@ namespace LibationWinForm
if (!createSettings()) if (!createSettings())
return; return;
init();
Application.Run(new Form1()); Application.Run(new Form1());
} }
@ -29,7 +32,7 @@ Please fill in a few settings on the following page. You can also change these s
After you make your selections, get started by importing your library. After you make your selections, get started by importing your library.
Go to Import > Scan Library Go to Import > Scan Library
".Trim(); ".Trim();
MessageBox.Show(welcomeText, "Welcom to Libation", MessageBoxButtons.OK); MessageBox.Show(welcomeText, "Welcome to Libation", MessageBoxButtons.OK);
var dialogResult = new SettingsDialog().ShowDialog(); var dialogResult = new SettingsDialog().ShowDialog();
if (dialogResult != DialogResult.OK) if (dialogResult != DialogResult.OK)
{ {
@ -39,5 +42,14 @@ Go to Import > Scan Library
return true; return true;
} }
private static void init()
{
var logPath = System.IO.Path.Combine(FileManager.Configuration.Instance.LibationFiles, "Log.log");
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.File(logPath, rollingInterval: RollingInterval.Month)
.CreateLogger();
}
} }
} }

View File

@ -1,6 +1,7 @@
-- begin VERSIONING --------------------------------------------------------------------------------------------------------------------- -- begin VERSIONING ---------------------------------------------------------------------------------------------------------------------
https://github.com/rmcrackan/Libation/releases https://github.com/rmcrackan/Libation/releases
v3.1-beta.3 : fixed known performance issue: Full-screen grid is slow to respond loading when books aren't liberated
v3.1-beta.2 : fixed known performance issue: Tag add/edit v3.1-beta.2 : fixed known performance issue: Tag add/edit
v3.1-beta.1 : RELEASE TO BETA v3.1-beta.1 : RELEASE TO BETA
v3.0.3 : Switch to SQLite. No longer relies on LocalDB, which must be installed separately v3.0.3 : Switch to SQLite. No longer relies on LocalDB, which must be installed separately