Compare commits

..

7 Commits

Author SHA1 Message Date
Robert McRackan
e67eac92fd Bug fix for issue #152 : individual episodes were ignored when targeted directly (as opposed to targeting the parent series) 2021-11-09 21:27:44 -05:00
Robert McRackan
6e84fd97f1 Accounts dialog: more user-friendly validation 2021-11-08 08:55:07 -05:00
Robert McRackan
9a458bf3dc Protect against blank settings.json 2021-11-05 15:25:31 -04:00
Robert McRackan
283a46e1e2 Add debugging for issue #149 2021-11-05 13:42:47 -04:00
Robert McRackan
6ff2859c39 Update dependencies 2021-11-04 16:13:43 -04:00
Robert McRackan
e8df4952fc update dependencies 2021-11-03 16:51:40 -04:00
rmcrackan
b19e1e8a30 Update README for Custom File Naming 2021-11-02 22:20:51 -04:00
9 changed files with 76 additions and 14 deletions

View File

@@ -6,7 +6,6 @@
<ItemGroup>
<PackageReference Include="AAXClean" Version="0.1.10" />
<PackageReference Include="Dinah.Core" Version="2.0.2.1" />
</ItemGroup>
<ItemGroup>

View File

@@ -3,7 +3,7 @@
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<Version>6.4.1.1</Version>
<Version>6.4.3.1</Version>
</PropertyGroup>
<ItemGroup>

View File

@@ -166,8 +166,7 @@ namespace AudibleUtilities
Serilog.Log.Logger.Information($"{parents.Count} series of shows/podcasts found");
// remove episode parents. even if the following stuff fails, these will still be removed from the collection.
// also must happen before processing children because children abuses this flag
// remove episode parents. even if the following stuff fails, these will still be removed from the collection
items.RemoveAll(i => i.IsEpisodes);
if (importEpisodes)
@@ -192,6 +191,14 @@ namespace AudibleUtilities
{
var children = await getEpisodeChildrenAsync(parent);
// actual individual episode, not the parent of a series.
// for now I'm keeping it inside this method since it fits the work flow, incl. importEpisodes logic
if (!children.Any())
{
results.Add(parent);
continue;
}
foreach (var child in children)
{
// use parent's 'DateAdded'. DateAdded is just a convenience prop for: PurchaseDate.UtcDateTime

View File

@@ -5,7 +5,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AudibleApi" Version="2.3.2.1" />
<PackageReference Include="AudibleApi" Version="2.3.4.1" />
</ItemGroup>
<ItemGroup>

View File

@@ -5,7 +5,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Dinah.Core" Version="2.0.2.1" />
<PackageReference Include="Dinah.Core" Version="3.0.1.1" />
<PackageReference Include="Polly" Version="7.2.2" />
</ItemGroup>

View File

@@ -30,8 +30,7 @@ namespace FileManager
if (IsReadOnly)
return;
File.WriteAllText(Filepath, "{}");
System.Threading.Thread.Sleep(100);
createNewFile();
}
public string GetString(string propertyName)
@@ -205,9 +204,39 @@ namespace FileManager
private JObject readFile()
{
if (!File.Exists(Filepath))
{
var msg = "Unrecoverable error. Settings file cannot be found";
var ex = new FileNotFoundException(msg, Filepath);
Serilog.Log.Logger.Error(msg, ex);
throw ex;
}
var settingsJsonContents = File.ReadAllText(Filepath);
if (string.IsNullOrWhiteSpace(settingsJsonContents))
{
createNewFile();
settingsJsonContents = File.ReadAllText(Filepath);
}
var jObject = JsonConvert.DeserializeObject<JObject>(settingsJsonContents);
if (jObject is null)
{
var msg = "Unrecoverable error. Unable to read settings from Settings file";
var ex = new NullReferenceException(msg);
Serilog.Log.Logger.Error(msg, ex);
throw ex;
}
return jObject;
}
private void createNewFile()
{
File.WriteAllText(Filepath, "{}");
System.Threading.Thread.Sleep(100);
}
}
}

View File

@@ -112,6 +112,9 @@ namespace LibationWinForms.Dialogs
{
try
{
if (!inputIsValid())
return;
// without transaction, accounts persister will write ANY EDIT immediately to file
using var persister = AudibleApiStorage.GetAccountsSettingsPersister();
@@ -129,6 +132,28 @@ namespace LibationWinForms.Dialogs
}
}
private bool inputIsValid()
{
var dtos = getRowDtos();
foreach (var dto in dtos)
{
if (string.IsNullOrWhiteSpace(dto.AccountId))
{
MessageBox.Show("Account id cannot be blank. Please enter an account id for all accounts.", "Blank account", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
if (string.IsNullOrWhiteSpace(dto.LocaleName))
{
MessageBox.Show("Please select a locale (i.e.: country or region) for all accounts.", "Blank region", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
}
return true;
}
private void persist(AccountsSettings accountsSettings)
{
var existingAccounts = accountsSettings.Accounts;
@@ -152,11 +177,6 @@ namespace LibationWinForms.Dialogs
// upsert each. validation occurs through Account and AccountsSettings
foreach (var dto in dtos)
{
if (string.IsNullOrWhiteSpace(dto.AccountId))
throw new Exception("Please enter an account id for all accounts");
if (string.IsNullOrWhiteSpace(dto.LocaleName))
throw new Exception("Please select a locale (i.e.: country or region) for all accounts");
var acct = accountsSettings.Upsert(dto.AccountId, dto.LocaleName);
acct.LibraryScan = dto.LibraryScan;
acct.AccountName

View File

@@ -29,7 +29,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Dinah.Core.WindowsDesktop" Version="2.0.2.2" />
<PackageReference Include="Dinah.Core.WindowsDesktop" Version="2.1.1.1" />
</ItemGroup>
<ItemGroup>

View File

@@ -27,6 +27,7 @@
- [Files and folders](#files-and-folders)
- [Linux and Mac (unofficial)](#linux-and-mac)
- [Settings](#settings)
- [Custom File Naming](#custom-file-naming)
- [Command Line Interface](#command-line-interface)
## Audible audiobook manager
@@ -243,6 +244,12 @@ Although Libation only currently officially supports Windows, [some users](https
* Allow Libation to fix up audiobook metadata. After decrypting a title, Libation attempts to fix details like chapters and cover art. Some power users and/or control freaks prefer to manage this themselves. By unchecking this setting, Libation will only decrypt the book and will leave metadata as-is, warts and all.
### Custom File Naming
In Settings, on the Download/Decrypt tab, you can specify the format in which you want your files to be named. As you edit these templates, a live example will be shown. Parameters are listed for folders, files, and files split by chapter including an explanation of what each naming option means. For instance: you can use template `<title short> - <ch# 0> of <ch count> - <ch title>` to create the file `A Study in Scarlet - 04 of 10 - A Flight for Life.m4b`.
These templates apply to GUI and CLI.
### Command Line Interface
Libationcli.exe allows limited access to Libation's functionalities as a CLI.