mirror of
https://github.com/rmcrackan/Libation.git
synced 2026-01-07 13:28:08 -05:00
Compare commits
3 Commits
v3.1-beta.
...
v3.1-beta.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5c81441f83 | ||
|
|
57bc74cd23 | ||
|
|
1cecd4ba2e |
@@ -72,8 +72,9 @@ namespace AaxDecrypter
|
||||
}
|
||||
private AaxToM4bConverter(string inputFile, string decryptKey)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(inputFile)) throw new ArgumentNullException(nameof(inputFile), "Input file may not be null or whitespace");
|
||||
if (!File.Exists(inputFile)) throw new ArgumentNullException(nameof(inputFile), "File does not exist");
|
||||
ArgumentValidator.EnsureNotNullOrWhiteSpace(inputFile, nameof(inputFile));
|
||||
if (!File.Exists(inputFile))
|
||||
throw new ArgumentNullException(nameof(inputFile), "File does not exist");
|
||||
|
||||
steps = new StepSequence
|
||||
{
|
||||
@@ -89,20 +90,20 @@ namespace AaxDecrypter
|
||||
["End: Create Nfo"] = End_CreateNfo
|
||||
};
|
||||
|
||||
this.inputFileName = inputFile;
|
||||
inputFileName = inputFile;
|
||||
this.decryptKey = decryptKey;
|
||||
}
|
||||
|
||||
private async Task prelimProcessing()
|
||||
{
|
||||
this.tags = new Tags(this.inputFileName);
|
||||
this.encodingInfo = new EncodingInfo(this.inputFileName);
|
||||
this.chapters = new Chapters(this.inputFileName, this.tags.duration.TotalSeconds);
|
||||
tags = new Tags(inputFileName);
|
||||
encodingInfo = new EncodingInfo(inputFileName);
|
||||
chapters = new Chapters(inputFileName, tags.duration.TotalSeconds);
|
||||
|
||||
var defaultFilename = Path.Combine(
|
||||
Path.GetDirectoryName(this.inputFileName),
|
||||
getASCIITag(this.tags.author),
|
||||
getASCIITag(this.tags.title) + ".m4b"
|
||||
Path.GetDirectoryName(inputFileName),
|
||||
getASCIITag(tags.author),
|
||||
getASCIITag(tags.title) + ".m4b"
|
||||
);
|
||||
SetOutputFilename(defaultFilename);
|
||||
|
||||
@@ -118,7 +119,7 @@ namespace AaxDecrypter
|
||||
private void saveCover(string aaxFile)
|
||||
{
|
||||
using var file = TagLib.File.Create(aaxFile, "audio/mp4", TagLib.ReadStyle.Average);
|
||||
this.coverBytes = file.Tag.Pictures[0].Data.Data;
|
||||
coverBytes = file.Tag.Pictures[0].Data.Data;
|
||||
}
|
||||
|
||||
private void printPrelim()
|
||||
@@ -156,21 +157,21 @@ namespace AaxDecrypter
|
||||
|
||||
public void SetOutputFilename(string outFileName)
|
||||
{
|
||||
this.outputFileName = outFileName;
|
||||
outputFileName = outFileName;
|
||||
|
||||
if (Path.GetExtension(this.outputFileName) != ".m4b")
|
||||
this.outputFileName = outputFileWithNewExt(".m4b");
|
||||
if (Path.GetExtension(outputFileName) != ".m4b")
|
||||
outputFileName = outputFileWithNewExt(".m4b");
|
||||
|
||||
this.outDir = Path.GetDirectoryName(this.outputFileName);
|
||||
outDir = Path.GetDirectoryName(outputFileName);
|
||||
}
|
||||
|
||||
private string outputFileWithNewExt(string extension)
|
||||
=> Path.Combine(this.outDir, Path.GetFileNameWithoutExtension(this.outputFileName) + '.' + extension.Trim('.'));
|
||||
=> Path.Combine(outDir, Path.GetFileNameWithoutExtension(outputFileName) + '.' + extension.Trim('.'));
|
||||
|
||||
public bool Step1_CreateDir()
|
||||
{
|
||||
ProcessRunner.WorkingDir = this.outDir;
|
||||
Directory.CreateDirectory(this.outDir);
|
||||
ProcessRunner.WorkingDir = outDir;
|
||||
Directory.CreateDirectory(outDir);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -178,7 +179,7 @@ namespace AaxDecrypter
|
||||
{
|
||||
DecryptProgressUpdate?.Invoke(this, 0);
|
||||
|
||||
var tempRipFile = Path.Combine(this.outDir, "funny.aac");
|
||||
var tempRipFile = Path.Combine(outDir, "funny.aac");
|
||||
|
||||
var fail = "WARNING-Decrypt failure. ";
|
||||
|
||||
@@ -193,7 +194,7 @@ namespace AaxDecrypter
|
||||
if (returnCode == -99)
|
||||
{
|
||||
Console.WriteLine($"{fail}Incorrect decrypt key: {decryptKey}");
|
||||
this.decryptKey = null;
|
||||
decryptKey = null;
|
||||
returnCode = getKey_decrypt(tempRipFile);
|
||||
}
|
||||
}
|
||||
@@ -232,7 +233,7 @@ namespace AaxDecrypter
|
||||
|
||||
Console.WriteLine("Cracking activation bytes");
|
||||
var activation_bytes = BytesCracker.GetActivationBytes(checksum);
|
||||
this.decryptKey = activation_bytes;
|
||||
decryptKey = activation_bytes;
|
||||
Console.WriteLine("Activation bytes cracked. Decrypt key: " + activation_bytes);
|
||||
}
|
||||
|
||||
@@ -243,10 +244,10 @@ namespace AaxDecrypter
|
||||
Console.WriteLine("Decrypting with key " + decryptKey);
|
||||
|
||||
var returnCode = 100;
|
||||
var thread = new Thread(() => returnCode = this.ngDecrypt());
|
||||
var thread = new Thread(() => returnCode = ngDecrypt());
|
||||
thread.Start();
|
||||
|
||||
double fileLen = new FileInfo(this.inputFileName).Length;
|
||||
double fileLen = new FileInfo(inputFileName).Length;
|
||||
while (thread.IsAlive && returnCode == 100)
|
||||
{
|
||||
Thread.Sleep(500);
|
||||
@@ -266,7 +267,7 @@ namespace AaxDecrypter
|
||||
var info = new ProcessStartInfo
|
||||
{
|
||||
FileName = DecryptSupportLibraries.mp4trackdumpPath,
|
||||
Arguments = "-c " + this.encodingInfo.channels + " -r " + this.encodingInfo.sampleRate + " \"" + this.inputFileName + "\""
|
||||
Arguments = "-c " + encodingInfo.channels + " -r " + encodingInfo.sampleRate + " \"" + inputFileName + "\""
|
||||
};
|
||||
info.EnvironmentVariables["VARIABLE"] = decryptKey;
|
||||
|
||||
@@ -280,20 +281,20 @@ namespace AaxDecrypter
|
||||
}
|
||||
|
||||
// temp file names for steps 3, 4, 5
|
||||
string tempChapsPath => Path.Combine(this.outDir, "tempChaps.mp4");
|
||||
string tempChapsPath => Path.Combine(outDir, "tempChaps.mp4");
|
||||
string mp4_file => outputFileWithNewExt(".mp4");
|
||||
string ff_txt_file => mp4_file + ".ff.txt";
|
||||
|
||||
public bool Step3_Chapterize()
|
||||
{
|
||||
string str1 = "";
|
||||
if (this.chapters.FirstChapterStart != 0.0)
|
||||
if (chapters.FirstChapterStart != 0.0)
|
||||
{
|
||||
str1 = " -ss " + this.chapters.FirstChapterStart.ToString("0.000", CultureInfo.InvariantCulture) + " -t " + (this.chapters.LastChapterStart - 1.0).ToString("0.000", CultureInfo.InvariantCulture) + " ";
|
||||
str1 = " -ss " + chapters.FirstChapterStart.ToString("0.000", CultureInfo.InvariantCulture) + " -t " + (chapters.LastChapterStart - 1.0).ToString("0.000", CultureInfo.InvariantCulture) + " ";
|
||||
}
|
||||
|
||||
string ffmpegTags = this.tags.GenerateFfmpegTags();
|
||||
string ffmpegChapters = this.chapters.GenerateFfmpegChapters();
|
||||
string ffmpegTags = tags.GenerateFfmpegTags();
|
||||
string ffmpegChapters = chapters.GenerateFfmpegChapters();
|
||||
File.WriteAllText(ff_txt_file, ffmpegTags + ffmpegChapters);
|
||||
|
||||
var tagAndChapterInfo = new ProcessStartInfo
|
||||
@@ -309,8 +310,8 @@ namespace AaxDecrypter
|
||||
public bool Step4_InsertCoverArt()
|
||||
{
|
||||
// save cover image as temp file
|
||||
var coverPath = Path.Combine(this.outDir, "cover-" + Guid.NewGuid() + ".jpg");
|
||||
FileExt.CreateFile(coverPath, this.coverBytes);
|
||||
var coverPath = Path.Combine(outDir, "cover-" + Guid.NewGuid() + ".jpg");
|
||||
FileExt.CreateFile(coverPath, coverBytes);
|
||||
|
||||
var insertCoverArtInfo = new ProcessStartInfo
|
||||
{
|
||||
@@ -329,26 +330,26 @@ namespace AaxDecrypter
|
||||
{
|
||||
FileExt.SafeDelete(mp4_file);
|
||||
FileExt.SafeDelete(ff_txt_file);
|
||||
FileExt.SafeMove(tempChapsPath, this.outputFileName);
|
||||
FileExt.SafeMove(tempChapsPath, outputFileName);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Step6_AddTags()
|
||||
{
|
||||
this.tags.AddAppleTags(this.outputFileName);
|
||||
tags.AddAppleTags(outputFileName);
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool End_CreateCue()
|
||||
{
|
||||
File.WriteAllText(outputFileWithNewExt(".cue"), this.chapters.GetCuefromChapters(Path.GetFileName(this.outputFileName)));
|
||||
File.WriteAllText(outputFileWithNewExt(".cue"), chapters.GetCuefromChapters(Path.GetFileName(outputFileName)));
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool End_CreateNfo()
|
||||
{
|
||||
File.WriteAllText(outputFileWithNewExt(".nfo"), NFO.CreateNfoContents(AppName, this.tags, this.encodingInfo, this.chapters));
|
||||
File.WriteAllText(outputFileWithNewExt(".nfo"), NFO.CreateNfoContents(AppName, tags, encodingInfo, chapters));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace AaxDecrypter
|
||||
using TagLib.File tagLibFile = TagLib.File.Create(file, "audio/mp4", ReadStyle.Average);
|
||||
this.title = tagLibFile.Tag.Title.Replace(" (Unabridged)", "");
|
||||
this.album = tagLibFile.Tag.Album.Replace(" (Unabridged)", "");
|
||||
this.author = tagLibFile.Tag.FirstPerformer;
|
||||
this.author = tagLibFile.Tag.FirstPerformer ?? "[unknown]";
|
||||
this.year = tagLibFile.Tag.Year.ToString();
|
||||
this.comments = tagLibFile.Tag.Comment;
|
||||
this.duration = tagLibFile.Properties.Duration;
|
||||
|
||||
@@ -9,30 +9,49 @@ namespace ApplicationServices
|
||||
{
|
||||
public static class LibraryCommands
|
||||
{
|
||||
public static async Task<(int totalCount, int newCount)> IndexLibraryAsync(ILoginCallback callback)
|
||||
public static async Task<(int totalCount, int newCount)> ImportLibraryAsync(ILoginCallback callback)
|
||||
{
|
||||
var audibleApiActions = new AudibleApiActions();
|
||||
var items = await audibleApiActions.GetAllLibraryItemsAsync(callback);
|
||||
var totalCount = items.Count;
|
||||
try
|
||||
{
|
||||
var audibleApiActions = new AudibleApiActions();
|
||||
var items = await audibleApiActions.GetAllLibraryItemsAsync(callback);
|
||||
var totalCount = items.Count;
|
||||
Serilog.Log.Logger.Debug($"GetAllLibraryItems: Total count {totalCount}");
|
||||
|
||||
var libImporter = new LibraryImporter();
|
||||
var newCount = await Task.Run(() => libImporter.Import(items));
|
||||
var libImporter = new LibraryImporter();
|
||||
var newCount = await Task.Run(() => libImporter.Import(items));
|
||||
Serilog.Log.Logger.Debug($"Import: New count {newCount}");
|
||||
|
||||
await Task.Run(() => SearchEngineCommands.FullReIndex());
|
||||
await Task.Run(() => SearchEngineCommands.FullReIndex());
|
||||
Serilog.Log.Logger.Debug("FullReIndex: success");
|
||||
|
||||
return (totalCount, newCount);
|
||||
return (totalCount, newCount);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Serilog.Log.Logger.Error(ex, "Error importing library");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public static int UpdateTags(this LibationContext context, Book book, string newTags)
|
||||
{
|
||||
book.UserDefinedItem.Tags = newTags;
|
||||
try
|
||||
{
|
||||
book.UserDefinedItem.Tags = newTags;
|
||||
|
||||
var qtyChanges = context.SaveChanges();
|
||||
var qtyChanges = context.SaveChanges();
|
||||
|
||||
if (qtyChanges > 0)
|
||||
SearchEngineCommands.UpdateBookTags(book);
|
||||
if (qtyChanges > 0)
|
||||
SearchEngineCommands.UpdateBookTags(book);
|
||||
|
||||
return qtyChanges;
|
||||
return qtyChanges;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Serilog.Log.Logger.Error(ex, "Error updating tags");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,13 +12,13 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.0.0">
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.0.1">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="3.0.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.0.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.0.0">
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="3.0.1" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.0.1" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.0.1">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
||||
@@ -83,9 +83,9 @@ namespace FileManager
|
||||
catch (IOException)
|
||||
{
|
||||
try { resave(); }
|
||||
catch (IOException)
|
||||
{
|
||||
Console.WriteLine("...that's not good");
|
||||
catch (IOException ex)
|
||||
{
|
||||
Serilog.Log.Logger.Error(ex, "Error saving FilePaths.json");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,12 +105,12 @@ namespace FileManager
|
||||
catch (IOException)
|
||||
{
|
||||
try { resave(); }
|
||||
catch (IOException)
|
||||
{
|
||||
Console.WriteLine("...that's not good");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
Serilog.Log.Logger.Error(ex, "Error saving QuickFilters.json");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace InternalUtilities
|
||||
|
||||
private async Task<List<Item>> getItemsAsync(ILoginCallback callback)
|
||||
{
|
||||
var api = await getApiAsync(callback);
|
||||
var api = await EzApiCreator.GetApiAsync(AudibleApiStorage.IdentityTokensFile, callback, Configuration.Instance.LocaleCountryCode);
|
||||
var items = await AudibleApiExtensions.GetAllLibraryItemsAsync(api);
|
||||
|
||||
// remove episode parents
|
||||
@@ -62,20 +62,6 @@ namespace InternalUtilities
|
||||
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()
|
||||
{
|
||||
var type = typeof(IValidator);
|
||||
|
||||
@@ -27,11 +27,11 @@ namespace InternalUtilities
|
||||
ResponseGroups = LibraryOptions.ResponseGroupOptions.ALL_OPTIONS
|
||||
});
|
||||
|
||||
string pageStr = null;
|
||||
var pageStr = page.ToString();
|
||||
|
||||
LibraryDtoV10 libResult;
|
||||
try
|
||||
{
|
||||
pageStr = page.ToString();
|
||||
// important! use this convert method
|
||||
libResult = LibraryDtoV10.FromJson(pageStr);
|
||||
}
|
||||
@@ -43,6 +43,8 @@ namespace InternalUtilities
|
||||
|
||||
if (!libResult.Items.Any())
|
||||
break;
|
||||
else
|
||||
Serilog.Log.Logger.Debug($"Page {i}: {libResult.Items.Length} results");
|
||||
|
||||
allItems.AddRange(libResult.Items);
|
||||
}
|
||||
|
||||
@@ -13,10 +13,20 @@ namespace LibationWinForm.BookLiberation
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public void AppendError(Exception ex) => AppendText("ERROR: " + ex.Message);
|
||||
public void AppendText(string text) => logTb.UIThread(() => logTb.AppendText($"{DateTime.Now} {text}{Environment.NewLine}"));
|
||||
public void AppendError(Exception ex)
|
||||
{
|
||||
Serilog.Log.Logger.Error(ex, "Automated backup: error");
|
||||
appendText("ERROR: " + ex.Message);
|
||||
}
|
||||
public void AppendText(string text)
|
||||
{
|
||||
Serilog.Log.Logger.Debug($"Automated backup: {text}");
|
||||
appendText(text);
|
||||
}
|
||||
private void appendText(string text)
|
||||
=> logTb.UIThread(() => logTb.AppendText($"{DateTime.Now} {text}{Environment.NewLine}"));
|
||||
|
||||
public void FinalizeUI()
|
||||
public void FinalizeUI()
|
||||
{
|
||||
keepGoingCb.Enabled = false;
|
||||
logTb.AppendText("");
|
||||
|
||||
@@ -8,18 +8,23 @@ namespace LibationWinForm.BookLiberation
|
||||
{
|
||||
public partial class DecryptForm : Form
|
||||
{
|
||||
public DecryptForm()
|
||||
class SerilogTextWriter : System.IO.TextWriter
|
||||
{
|
||||
public override System.Text.Encoding Encoding => System.Text.Encoding.ASCII;
|
||||
public override void WriteLine(string value) => Serilog.Log.Logger.Debug(value);
|
||||
}
|
||||
|
||||
public DecryptForm()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
System.IO.TextWriter origOut = Console.Out;
|
||||
System.IO.TextWriter origOut { get; } = Console.Out;
|
||||
private void DecryptForm_Load(object sender, EventArgs e)
|
||||
{
|
||||
// redirect Console.WriteLine to console, textbox
|
||||
System.IO.TextWriter origOut = Console.Out;
|
||||
var controlWriter = new RichTextBoxTextWriter(this.rtbLog);
|
||||
var multiLogger = new MultiTextWriter(origOut, controlWriter);
|
||||
var multiLogger = new MultiTextWriter(origOut, controlWriter, new SerilogTextWriter());
|
||||
Console.SetOut(multiLogger);
|
||||
}
|
||||
|
||||
@@ -58,13 +63,6 @@ namespace LibationWinForm.BookLiberation
|
||||
public void SetCoverImage(byte[] coverBytes)
|
||||
=> pictureBox1.UIThread(() => pictureBox1.Image = ImageReader.ToImage(coverBytes));
|
||||
|
||||
public static void AppendError(Exception ex) => AppendText("ERROR: " + ex.Message);
|
||||
public static void AppendText(string text) =>
|
||||
// redirected to log textbox
|
||||
Console.WriteLine($"{DateTime.Now} {text}")
|
||||
//logTb.UIThread(() => logTb.AppendText($"{DateTime.Now} {text}{Environment.NewLine}"))
|
||||
;
|
||||
|
||||
public void UpdateProgress(int percentage) => progressBar1.UIThread(() => progressBar1.Value = percentage);
|
||||
public void UpdateProgress(int percentage) => progressBar1.UIThread(() => progressBar1.Value = percentage);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,12 +19,11 @@ namespace LibationWinForm
|
||||
{
|
||||
try
|
||||
{
|
||||
(TotalBooksProcessed, NewBooksAdded) = await LibraryCommands.IndexLibraryAsync(new Login.WinformResponder());
|
||||
(TotalBooksProcessed, NewBooksAdded) = await LibraryCommands.ImportLibraryAsync(new Login.WinformResponder());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var msg = "Error importing library. Please try again. If this happens after 2 or 3 tries, contact administrator";
|
||||
Serilog.Log.Logger.Error(ex, msg);
|
||||
var msg = "Error importing library. Please try again. If this still happens after 2 or 3 tries, stop and contact administrator";
|
||||
MessageBox.Show(msg, "Error importing library", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
|
||||
|
||||
@@ -109,8 +109,20 @@ namespace LibationWinForm
|
||||
.Select(sp => sp.Book)
|
||||
.ToList();
|
||||
|
||||
setBookBackupCounts(books);
|
||||
setPdfBackupCounts(books);
|
||||
// will often fail once if book has been moved while libation is closed. just retry once for now
|
||||
// fix actual issue later
|
||||
// FilePathCache.GetPath() :: inMemoryCache.SingleOrDefault(i => i.Id == id && i.FileType == type)
|
||||
try
|
||||
{
|
||||
setBookBackupCounts(books);
|
||||
setPdfBackupCounts(books);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Threading.Thread.Sleep(100);
|
||||
setBookBackupCounts(books);
|
||||
setPdfBackupCounts(books);
|
||||
}
|
||||
}
|
||||
enum AudioFileState { full, aax, none }
|
||||
private void setBookBackupCounts(IEnumerable<Book> books)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
using Dinah.Core.Logging;
|
||||
using Serilog;
|
||||
|
||||
namespace LibationWinForm
|
||||
@@ -45,11 +46,29 @@ Go to Import > Scan Library
|
||||
|
||||
private static void init()
|
||||
{
|
||||
// default. for reference. output example:
|
||||
// 2019-11-26 08:48:40.224 -05:00 [DBG] Begin Libation
|
||||
var default_outputTemplate = "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception}";
|
||||
// with class and method info. output example:
|
||||
// 2019-11-26 08:48:40.224 -05:00 [DBG] (at LibationWinForm.Program.init()) Begin Libation
|
||||
var code_outputTemplate = "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] (at {Caller}) {Message:lj}{NewLine}{Exception}";
|
||||
|
||||
|
||||
var logPath = System.IO.Path.Combine(FileManager.Configuration.Instance.LibationFiles, "Log.log");
|
||||
|
||||
Log.Logger = new LoggerConfiguration()
|
||||
.Enrich.WithCaller()
|
||||
.MinimumLevel.Debug()
|
||||
.WriteTo.File(logPath, rollingInterval: RollingInterval.Month)
|
||||
.WriteTo.File(logPath,
|
||||
rollingInterval: RollingInterval.Month,
|
||||
outputTemplate: code_outputTemplate)
|
||||
.CreateLogger();
|
||||
|
||||
Log.Logger.Debug("Begin Libation");
|
||||
|
||||
// .Here() captures debug info via System.Runtime.CompilerServices attributes. Warning: expensive
|
||||
//var withLineNumbers_outputTemplate = "[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message}{NewLine}in method {MemberName} at {FilePath}:{LineNumber}{NewLine}{Exception}{NewLine}";
|
||||
//Log.Logger.Here().Debug("Begin Libation. Debug with line numbers");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
-- begin VERSIONING ---------------------------------------------------------------------------------------------------------------------
|
||||
https://github.com/rmcrackan/Libation/releases
|
||||
|
||||
v3.1-beta.7 : Bugfix: decrypt book with no author
|
||||
v3.1-beta.6 : Improved logging
|
||||
v3.1-beta.5 : Improved importing
|
||||
v3.1-beta.4 : Added beta-specific logging
|
||||
v3.1-beta.3 : fixed known performance issue: Full-screen grid is slow to respond loading when books aren't liberated
|
||||
|
||||
Reference in New Issue
Block a user