mirror of
https://github.com/rmcrackan/Libation.git
synced 2026-01-01 18:38:01 -05:00
Compare commits
50 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d1834659d9 | ||
|
|
7842b521d7 | ||
|
|
0822f0229d | ||
|
|
26aee4d29d | ||
|
|
17a80a23a8 | ||
|
|
e26fc9ca62 | ||
|
|
a03ccf1143 | ||
|
|
bb8dd615db | ||
|
|
9022a2889f | ||
|
|
ef049a3b02 | ||
|
|
77409750aa | ||
|
|
1702130b01 | ||
|
|
b6d1a7e3ba | ||
|
|
2907ba5c13 | ||
|
|
6df6c79ac8 | ||
|
|
3a9ca5d827 | ||
|
|
e1e663e327 | ||
|
|
4b00d5fd84 | ||
|
|
02dbf8aad0 | ||
|
|
8326389f5c | ||
|
|
34535b3ce1 | ||
|
|
7e5366ab95 | ||
|
|
690de9bc5c | ||
|
|
c976aa2bb2 | ||
|
|
27f659285d | ||
|
|
423a5e7720 | ||
|
|
9152e12fe1 | ||
|
|
f471c53139 | ||
|
|
66d055bb90 | ||
|
|
2bbb35363a | ||
|
|
1d3687cf9e | ||
|
|
daf925157f | ||
|
|
40eec9e674 | ||
|
|
6f0782053e | ||
|
|
04ad033ba0 | ||
|
|
f12f8ba3ee | ||
|
|
cc6feb21ff | ||
|
|
c4f2ec428d | ||
|
|
59689cb647 | ||
|
|
d7f3758ebc | ||
|
|
49775b019c | ||
|
|
e55e969349 | ||
|
|
42a93bfac1 | ||
|
|
f86c77a546 | ||
|
|
88c35e2a56 | ||
|
|
b405e8b6b2 | ||
|
|
92d283187d | ||
|
|
51b8cfe71f | ||
|
|
c80da5357b | ||
|
|
736d7c4a5f |
8
.github/workflows/build-linux.yml
vendored
8
.github/workflows/build-linux.yml
vendored
@@ -33,7 +33,7 @@ on:
|
||||
|
||||
env:
|
||||
DOTNET_CONFIGURATION: 'Release'
|
||||
DOTNET_VERSION: '7.0.x'
|
||||
DOTNET_VERSION: '8.0.x'
|
||||
RELEASE_NAME: 'chardonnay'
|
||||
|
||||
jobs:
|
||||
@@ -41,9 +41,9 @@ jobs:
|
||||
name: '${{ inputs.OS }}-${{ inputs.architecture }}'
|
||||
runs-on: ${{ inputs.runs_on }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v3
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: ${{ env.DOTNET_VERSION }}
|
||||
env:
|
||||
@@ -124,7 +124,7 @@ jobs:
|
||||
echo "artifact=${artifact}" >> "${GITHUB_OUTPUT}"
|
||||
|
||||
- name: Publish bundle
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ steps.bundle.outputs.artifact }}
|
||||
path: ./Source/bin/Publish/bundle/${{ steps.bundle.outputs.artifact }}
|
||||
|
||||
8
.github/workflows/build-windows.yml
vendored
8
.github/workflows/build-windows.yml
vendored
@@ -18,7 +18,7 @@ on:
|
||||
|
||||
env:
|
||||
DOTNET_CONFIGURATION: 'Release'
|
||||
DOTNET_VERSION: '7.0.x'
|
||||
DOTNET_VERSION: '8.0.x'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
@@ -35,9 +35,9 @@ jobs:
|
||||
release_name: classic
|
||||
prefix: Classic-
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v3
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: ${{ env.DOTNET_VERSION }}
|
||||
env:
|
||||
@@ -107,7 +107,7 @@ jobs:
|
||||
Compress-Archive -Path "${bin_dir}*" -DestinationPath "$artifact.zip"
|
||||
|
||||
- name: Publish artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ steps.zip.outputs.artifact }}.zip
|
||||
path: ./Source/bin/Publish/${{ steps.zip.outputs.artifact }}.zip
|
||||
|
||||
10
.github/workflows/docker.yml
vendored
10
.github/workflows/docker.yml
vendored
@@ -24,22 +24,22 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.docker_username }}
|
||||
password: ${{ secrets.docker_token }}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v4
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
push: true
|
||||
build-args: 'FOLDER_NAME=Linux-chardonnay'
|
||||
|
||||
4
.github/workflows/release.yml
vendored
4
.github/workflows/release.yml
vendored
@@ -39,7 +39,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Download artifacts
|
||||
uses: actions/download-artifact@v3
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
path: artifacts
|
||||
|
||||
@@ -53,7 +53,7 @@ jobs:
|
||||
prerelease: false
|
||||
|
||||
- name: Upload release assets
|
||||
uses: dwenegar/upload-release-assets@v1
|
||||
uses: dwenegar/upload-release-assets@v2
|
||||
env:
|
||||
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
|
||||
with:
|
||||
|
||||
16
Documentation/FrequentlyAskedQuestions.md
Normal file
16
Documentation/FrequentlyAskedQuestions.md
Normal file
@@ -0,0 +1,16 @@
|
||||
## [Download Libation](https://github.com/rmcrackan/Libation/releases/latest)
|
||||
|
||||
### If you found this useful, tell a friend. If you found this REALLY useful, you can click here to [PayPal.me](https://paypal.me/MBucari?locale.x=en_us)
|
||||
...or just tell more friends. As long as I'm maintaining this software, it will remain **free** and **open source**.
|
||||
|
||||
|
||||
### Frequently Asked Questions
|
||||
|
||||
**Q: Now that I've downloaded my books, how can I listen to them?**
|
||||
|
||||
**A:** You can use any app which plays m4b files (or mp3 files if you used that setting). Here are just a few ideas. Disclaimer: I have no affiliation with any of these companies:
|
||||
|
||||
* iOS: [BookPlayer](https://apps.apple.com/us/app/bookplayer/id1138219998)
|
||||
* iOS: [Bound](https://apps.apple.com/us/app/bound-audiobook-player/id1041727137)
|
||||
* Android: [Smart AudioBook Player](https://play.google.com/store/apps/details?id=ak.alizandro.smartaudiobookplayer&hl=en_US&gl=US)
|
||||
* Desktop: [VLC](https://www.videolan.org/)
|
||||
@@ -23,6 +23,17 @@ This walkthrough should get you up and running with Libation on your Mac.
|
||||
```
|
||||
- Close the terminal and use Libation!
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
If Libation fails to start after completing the above steps, try the following:
|
||||
|
||||
1. Right-click the Libation app in your applications folder and select _Show Package Contents_
|
||||
2. Open the `Contents` folder and then the `MacOS` folder.
|
||||
3. Find the file named `Libation`, right-click it, and then select _Open_.
|
||||
|
||||
Libation _should_ launch, and you should now be able to open Libation by just double-clicking the app bundle in your applications folder.
|
||||
|
||||
|
||||
## Running Hangover
|
||||
|
||||
Libation comes with a recovery app called Hangover. You can start it by running this command:
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
- [Custom File Naming](Documentation/NamingTemplates.md)
|
||||
- [Command Line Interface](Documentation/Advanced.md#command-line-interface)
|
||||
- [Docker](Documentation/Docker.md)
|
||||
- [Frequently Asked Questions](Documentation/FrequentlyAskedQuestions.md)
|
||||
|
||||
## Getting started
|
||||
|
||||
|
||||
@@ -109,9 +109,6 @@ ln -s /usr/lib/libation/LibationCli /usr/bin/libationcli
|
||||
if ! grep -q 'fs.inotify.max_user_instances=524288' /etc/sysctl.conf; then
|
||||
echo fs.inotify.max_user_instances=524288 | tee -a /etc/sysctl.conf && sysctl -p
|
||||
fi
|
||||
# workaround until this file is moved to the user's home directory
|
||||
touch /usr/lib/libation/appsettings.json
|
||||
chmod 666 /usr/lib/libation/appsettings.json
|
||||
" >> $FOLDER_DEBIAN/postinst
|
||||
|
||||
echo "Creating control file..."
|
||||
|
||||
@@ -94,8 +94,6 @@ install * %{buildroot}%{_libdir}/%{name}/
|
||||
|
||||
if [ \$1 -eq 1 ] ; then
|
||||
# Initial installation
|
||||
touch %{_libdir}/%{name}/appsettings.json
|
||||
chmod 666 %{_libdir}/%{name}/appsettings.json
|
||||
|
||||
ln -s %{_libdir}/%{name}/Libation %{_bindir}/libation
|
||||
ln -s %{_libdir}/%{name}/Hangover %{_bindir}/hangover
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
@@ -13,7 +13,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AAXClean.Codecs" Version="1.1.0" />
|
||||
<PackageReference Include="AAXClean.Codecs" Version="1.1.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<Version>11.0.0.1</Version>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Version>11.3.2.1</Version>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Octokit" Version="7.1.0" />
|
||||
<PackageReference Include="Serilog.Sinks.ZipFile" Version="1.0.1" />
|
||||
<PackageReference Include="Octokit" Version="9.1.0" />
|
||||
<PackageReference Include="Serilog.Sinks.ZipFile" Version="3.1.1" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ApplicationServices\ApplicationServices.csproj" />
|
||||
@@ -19,4 +19,4 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<DebugType>embedded</DebugType>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CsvHelper" Version="30.0.1" />
|
||||
<PackageReference Include="NPOI" Version="2.6.1" />
|
||||
<PackageReference Include="NPOI" Version="2.6.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -119,9 +119,15 @@ namespace ApplicationServices
|
||||
|
||||
logTime($"pre {nameof(scanAccountsAsync)} all");
|
||||
var libraryOptions = new LibraryOptions
|
||||
{
|
||||
ResponseGroups = LibraryOptions.ResponseGroupOptions.ALL_OPTIONS,
|
||||
ImageSizes = LibraryOptions.ImageSizeOptions._500 | LibraryOptions.ImageSizeOptions._1215
|
||||
{
|
||||
ResponseGroups
|
||||
= LibraryOptions.ResponseGroupOptions.Rating | LibraryOptions.ResponseGroupOptions.Media
|
||||
| LibraryOptions.ResponseGroupOptions.Relationships | LibraryOptions.ResponseGroupOptions.ProductDesc
|
||||
| LibraryOptions.ResponseGroupOptions.Contributors | LibraryOptions.ResponseGroupOptions.ProvidedReview
|
||||
| LibraryOptions.ResponseGroupOptions.ProductPlans | LibraryOptions.ResponseGroupOptions.Series
|
||||
| LibraryOptions.ResponseGroupOptions.CategoryLadders | LibraryOptions.ResponseGroupOptions.ProductExtendedAttrs
|
||||
| LibraryOptions.ResponseGroupOptions.PdfUrl | LibraryOptions.ResponseGroupOptions.OriginAsin,
|
||||
ImageSizes = LibraryOptions.ImageSizeOptions._500 | LibraryOptions.ImageSizeOptions._1215
|
||||
};
|
||||
var importItems = await scanAccountsAsync(apiExtendedfunc, accounts, libraryOptions);
|
||||
logTime($"post {nameof(scanAccountsAsync)} all");
|
||||
|
||||
@@ -207,7 +207,11 @@ namespace AudibleUtilities
|
||||
try
|
||||
{
|
||||
var sw = Stopwatch.StartNew();
|
||||
var items = await Api.GetCatalogProductsAsync(asins, CatalogOptions.ResponseGroupOptions.ALL_OPTIONS);
|
||||
var items = await Api.GetCatalogProductsAsync(asins, CatalogOptions.ResponseGroupOptions.Rating | CatalogOptions.ResponseGroupOptions.Media
|
||||
| CatalogOptions.ResponseGroupOptions.Relationships | CatalogOptions.ResponseGroupOptions.ProductDesc
|
||||
| CatalogOptions.ResponseGroupOptions.Contributors | CatalogOptions.ResponseGroupOptions.ProvidedReview
|
||||
| CatalogOptions.ResponseGroupOptions.ProductPlans | CatalogOptions.ResponseGroupOptions.Series
|
||||
| CatalogOptions.ResponseGroupOptions.CategoryLadders | CatalogOptions.ResponseGroupOptions.ProductExtendedAttrs);
|
||||
sw.Stop();
|
||||
|
||||
Serilog.Log.Logger.Debug($"Batch {batchNum} End: Retrieved {items.Count} items in {sw.ElapsedMilliseconds} ms");
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AudibleApi" Version="8.4.3.1" />
|
||||
<PackageReference Include="AudibleApi" Version="9.0.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
@@ -10,14 +10,14 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Dinah.Core" Version="7.3.0.1" />
|
||||
<PackageReference Include="Dinah.EntityFrameworkCore" Version="7.3.0.1" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.10">
|
||||
<PackageReference Include="Dinah.Core" Version="8.0.0.1" />
|
||||
<PackageReference Include="Dinah.EntityFrameworkCore" Version="8.0.0.1" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.1">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.10" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.10">
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.1" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.1">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
||||
@@ -23,9 +23,11 @@ namespace DtoImporterService
|
||||
loadLocal_categories();
|
||||
|
||||
// upsert
|
||||
//Import item may not have no (null) categories
|
||||
var categoryLadders = importItems
|
||||
.Where(i => i.DtoItem.CategoryLadders is not null)
|
||||
.SelectMany(i => i.DtoItem.CategoryLadders)
|
||||
.Select(cl => cl.Ladder)
|
||||
.Select(cl => cl?.Ladder)
|
||||
.Where(l => l?.Length > 0)
|
||||
.ToList();
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
|
||||
@@ -60,6 +60,11 @@ namespace FileLiberator
|
||||
config.LameMatchSourceBR,
|
||||
chapters);
|
||||
|
||||
if (m4bBook.AppleTags.Tracks is (int trackNum, int trackCount))
|
||||
{
|
||||
lameConfig.ID3.Track = trackCount > 0 ? $"{trackNum}/{trackCount}" : trackNum.ToString();
|
||||
}
|
||||
|
||||
using var mp3File = File.Open(Path.GetTempFileName(), FileMode.OpenOrCreate, FileAccess.ReadWrite);
|
||||
try
|
||||
{
|
||||
|
||||
@@ -375,8 +375,15 @@ namespace FileLiberator
|
||||
{
|
||||
if (Configuration.Instance.AllowLibationFixup)
|
||||
{
|
||||
e = OnRequestCoverArt();
|
||||
abDownloader.SetCoverArt(e);
|
||||
try
|
||||
{
|
||||
e = OnRequestCoverArt();
|
||||
abDownloader.SetCoverArt(e);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Serilog.Log.Logger.Error(ex, "Failed to retrieve cover art from server.");
|
||||
}
|
||||
}
|
||||
|
||||
if (e is not null)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Dinah.Core" Version="7.3.0.1" />
|
||||
<PackageReference Include="Polly" Version="7.2.4" />
|
||||
<PackageReference Include="Dinah.Core" Version="8.0.0.1" />
|
||||
<PackageReference Include="Polly" Version="8.2.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<!--Avalonia doesen't support TrimMode=link currently,but we are working on that https://github.com/AvaloniaUI/Avalonia/issues/6892 -->
|
||||
<TrimMode>copyused</TrimMode>
|
||||
@@ -67,13 +67,13 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
<PackageReference Include="Avalonia" Version="11.0.3" />
|
||||
<PackageReference Include="Avalonia.Desktop" Version="11.0.3" />
|
||||
<PackageReference Include="Avalonia" Version="11.0.5" />
|
||||
<PackageReference Include="Avalonia.Desktop" Version="11.0.5" />
|
||||
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
|
||||
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.0.3" />
|
||||
<PackageReference Include="Avalonia.ReactiveUI" Version="11.0.3" />
|
||||
<PackageReference Include="Avalonia.Controls.ItemsRepeater" Version="11.0.3" />
|
||||
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.0.3" />
|
||||
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.0.5" />
|
||||
<PackageReference Include="Avalonia.ReactiveUI" Version="11.0.5" />
|
||||
<PackageReference Include="Avalonia.Controls.ItemsRepeater" Version="11.0.5" />
|
||||
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.0.5" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\HangoverBase\HangoverBase.csproj" />
|
||||
|
||||
@@ -8,7 +8,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
<Platform>Any CPU</Platform>
|
||||
<PublishDir>..\bin\Publish\Linux-chardonnay</PublishDir>
|
||||
<PublishProtocol>FileSystem</PublishProtocol>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<RuntimeIdentifier>linux-x64</RuntimeIdentifier>
|
||||
<SelfContained>true</SelfContained>
|
||||
<PublishSingleFile>false</PublishSingleFile>
|
||||
|
||||
@@ -8,7 +8,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
<Platform>Any CPU</Platform>
|
||||
<PublishDir>..\bin\Publish\MacOS-chardonnay</PublishDir>
|
||||
<PublishProtocol>FileSystem</PublishProtocol>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<RuntimeIdentifier>osx-x64</RuntimeIdentifier>
|
||||
<SelfContained>true</SelfContained>
|
||||
<PublishSingleFile>false</PublishSingleFile>
|
||||
|
||||
@@ -8,7 +8,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
<Platform>Any CPU</Platform>
|
||||
<PublishDir>..\bin\Publish\Windows-chardonnay</PublishDir>
|
||||
<PublishProtocol>FileSystem</PublishProtocol>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<SelfContained>true</SelfContained>
|
||||
<PublishSingleFile>false</PublishSingleFile>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net7.0-windows</TargetFramework>
|
||||
<TargetFramework>net8.0-windows7.0</TargetFramework>
|
||||
<EnableWindowsTargeting>true</EnableWindowsTargeting>
|
||||
<AssemblyName>Hangover</AssemblyName>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
|
||||
@@ -8,7 +8,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
<Platform>Any CPU</Platform>
|
||||
<PublishDir>..\bin\Publish\classic</PublishDir>
|
||||
<PublishProtocol>FileSystem</PublishProtocol>
|
||||
<TargetFramework>net7.0-windows</TargetFramework>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<SelfContained>true</SelfContained>
|
||||
<PublishSingleFile>false</PublishSingleFile>
|
||||
|
||||
@@ -6,6 +6,7 @@ MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "_Solution Items", "_Solution Items", "{03C8835F-936C-4AF7-87AE-FF92BDBE8B9B}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
REFERENCE.txt = REFERENCE.txt
|
||||
Upgrading dotnet version.txt = Upgrading dotnet version.txt
|
||||
_ARCHITECTURE NOTES.txt = _ARCHITECTURE NOTES.txt
|
||||
_AvaloniaUI Primer.txt = _AvaloniaUI Primer.txt
|
||||
_DB_NOTES.txt = _DB_NOTES.txt
|
||||
|
||||
@@ -27,6 +27,6 @@
|
||||
Margin="5"
|
||||
Padding="30,3,30,3"
|
||||
Content="Save"
|
||||
Command="{Binding SaveButtonAsync}" />
|
||||
Click="Save_Click" />
|
||||
</Grid>
|
||||
</Window>
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
using Avalonia.Controls;
|
||||
using LibationFileManager;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace LibationAvalonia.Dialogs
|
||||
{
|
||||
public partial class LibationFilesDialog : Window
|
||||
public partial class LibationFilesDialog : DialogWindow
|
||||
{
|
||||
private class DirSelectOptions
|
||||
{
|
||||
@@ -18,28 +16,26 @@ namespace LibationAvalonia.Dialogs
|
||||
|
||||
public string Directory { get; set; } = Configuration.GetKnownDirectoryPath(Configuration.KnownDirectories.UserProfile);
|
||||
}
|
||||
private DirSelectOptions dirSelectOptions;
|
||||
|
||||
private readonly DirSelectOptions dirSelectOptions;
|
||||
public string SelectedDirectory => dirSelectOptions.Directory;
|
||||
public DialogResult DialogResult { get; private set; }
|
||||
public LibationFilesDialog()
|
||||
|
||||
public LibationFilesDialog() : base(saveAndRestorePosition: false)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
DataContext = dirSelectOptions = new();
|
||||
}
|
||||
|
||||
public async Task SaveButtonAsync()
|
||||
public async void Save_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e)
|
||||
{
|
||||
var libationDir = dirSelectOptions.Directory;
|
||||
|
||||
if (!System.IO.Directory.Exists(libationDir))
|
||||
if (!System.IO.Directory.Exists(SelectedDirectory))
|
||||
{
|
||||
await MessageBox.Show("Not saving change to Libation Files location. This folder does not exist:\r\n" + libationDir, "Folder does not exist", MessageBoxButtons.OK, MessageBoxIcon.Error, saveAndRestorePosition: false);
|
||||
await MessageBox.Show("Not saving change to Libation Files location. This folder does not exist:\r\n" + SelectedDirectory, "Folder does not exist", MessageBoxButtons.OK, MessageBoxIcon.Error, saveAndRestorePosition: false);
|
||||
return;
|
||||
}
|
||||
|
||||
DialogResult = DialogResult.OK;
|
||||
Close(DialogResult);
|
||||
await SaveAndCloseAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d" d:DesignWidth="900" d:DesignHeight="750"
|
||||
MinWidth="900" MinHeight="750"
|
||||
mc:Ignorable="d" d:DesignWidth="900" d:DesignHeight="200"
|
||||
MinWidth="900" MinHeight="200"
|
||||
Width="900" Height="750"
|
||||
x:Class="LibationAvalonia.Dialogs.SettingsDialog"
|
||||
xmlns:controls="clr-namespace:LibationAvalonia.Controls"
|
||||
@@ -46,39 +46,41 @@
|
||||
</TabControl.Styles>
|
||||
|
||||
<TabItem>
|
||||
|
||||
<TabItem.Header>
|
||||
<TextBlock Text="Important Settings"/>
|
||||
</TabItem.Header>
|
||||
|
||||
<settings:Important DataContext="{CompiledBinding ImportantSettings}" />
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto">
|
||||
<settings:Important DataContext="{CompiledBinding ImportantSettings}" />
|
||||
</ScrollViewer>
|
||||
</TabItem>
|
||||
|
||||
<TabItem>
|
||||
|
||||
<TabItem.Header>
|
||||
<TextBlock Text="Import Library"/>
|
||||
</TabItem.Header>
|
||||
|
||||
<settings:Import DataContext="{CompiledBinding ImportSettings}" />
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto">
|
||||
<settings:Import DataContext="{CompiledBinding ImportSettings}" />
|
||||
</ScrollViewer>
|
||||
</TabItem>
|
||||
|
||||
<TabItem>
|
||||
|
||||
<TabItem.Header>
|
||||
<TextBlock Text="Download/Decrypt"/>
|
||||
</TabItem.Header>
|
||||
|
||||
<settings:DownloadDecrypt DataContext="{CompiledBinding DownloadDecryptSettings}" />
|
||||
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto">
|
||||
<settings:DownloadDecrypt DataContext="{CompiledBinding DownloadDecryptSettings}" />
|
||||
</ScrollViewer>
|
||||
</TabItem>
|
||||
|
||||
|
||||
<TabItem>
|
||||
|
||||
<TabItem.Header>
|
||||
<TextBlock Text="Audio File Settings"/>
|
||||
</TabItem.Header>
|
||||
|
||||
<settings:Audio DataContext="{CompiledBinding AudioSettings}" />
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto">
|
||||
<settings:Audio DataContext="{CompiledBinding AudioSettings}" />
|
||||
</ScrollViewer>
|
||||
</TabItem>
|
||||
</TabControl>
|
||||
</Grid>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net7.0-windows</TargetFramework>
|
||||
<TargetFramework>net8.0-windows7.0</TargetFramework>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
|
||||
<ApplicationIcon>Assets/libation.ico</ApplicationIcon>
|
||||
@@ -69,14 +69,14 @@
|
||||
<UpToDateCheckInput Remove="Controls\GroupBox.axaml" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Avalonia.Diagnostics" Version="11.0.3" Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'" />
|
||||
<PackageReference Include="Avalonia" Version="11.0.3" />
|
||||
<PackageReference Include="Avalonia.Controls.DataGrid" Version="11.0.3" />
|
||||
<PackageReference Include="Avalonia.Controls.ItemsRepeater" Version="11.0.3" />
|
||||
<PackageReference Include="Avalonia.Desktop" Version="11.0.3" />
|
||||
<PackageReference Include="Avalonia.ReactiveUI" Version="11.0.3" />
|
||||
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.0.3" />
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Avalonia.Diagnostics" Version="11.0.5" Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'" />
|
||||
<PackageReference Include="Avalonia" Version="11.0.5" />
|
||||
<PackageReference Include="Avalonia.Controls.DataGrid" Version="11.0.5" />
|
||||
<PackageReference Include="Avalonia.Controls.ItemsRepeater" Version="11.0.5" />
|
||||
<PackageReference Include="Avalonia.Desktop" Version="11.0.5" />
|
||||
<PackageReference Include="Avalonia.ReactiveUI" Version="11.0.5" />
|
||||
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.0.5" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -8,7 +8,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
<Platform>Any CPU</Platform>
|
||||
<PublishDir>..\bin\Publish\Linux-chardonnay</PublishDir>
|
||||
<PublishProtocol>FileSystem</PublishProtocol>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<RuntimeIdentifier>linux-x64</RuntimeIdentifier>
|
||||
<SelfContained>true</SelfContained>
|
||||
<PublishSingleFile>false</PublishSingleFile>
|
||||
|
||||
@@ -8,7 +8,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
<Platform>Any CPU</Platform>
|
||||
<PublishDir>..\bin\Publish\MacOS-chardonnay</PublishDir>
|
||||
<PublishProtocol>FileSystem</PublishProtocol>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<RuntimeIdentifier>osx-x64</RuntimeIdentifier>
|
||||
<SelfContained>true</SelfContained>
|
||||
<PublishSingleFile>false</PublishSingleFile>
|
||||
|
||||
@@ -8,7 +8,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
<Platform>Any CPU</Platform>
|
||||
<PublishDir>..\bin\Publish\Windows-chardonnay</PublishDir>
|
||||
<PublishProtocol>FileSystem</PublishProtocol>
|
||||
<TargetFramework>net7.0-windows</TargetFramework>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<SelfContained>true</SelfContained>
|
||||
<PublishSingleFile>false</PublishSingleFile>
|
||||
|
||||
@@ -265,7 +265,7 @@ namespace LibationAvalonia.ViewModels
|
||||
private byte[] AudioDecodable_RequestCoverArt(object sender, EventArgs e)
|
||||
{
|
||||
var quality
|
||||
= Configuration.Instance.FileDownloadQuality == Configuration.DownloadQuality.High
|
||||
= Configuration.Instance.FileDownloadQuality == Configuration.DownloadQuality.High && LibraryBook.Book.PictureLarge is not null
|
||||
? new PictureDefinition(LibraryBook.Book.PictureLarge, PictureSize.Native)
|
||||
: new PictureDefinition(LibraryBook.Book.PictureId, PictureSize._500x500);
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net7.0-windows</TargetFramework>
|
||||
<TargetFramework>net8.0-windows7.0</TargetFramework>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<PublishReadyToRun>true</PublishReadyToRun>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
|
||||
@@ -8,7 +8,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
<Platform>Any CPU</Platform>
|
||||
<PublishDir>..\bin\Publish\Linux-chardonnay</PublishDir>
|
||||
<PublishProtocol>FileSystem</PublishProtocol>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<RuntimeIdentifier>linux-x64</RuntimeIdentifier>
|
||||
<SelfContained>true</SelfContained>
|
||||
<PublishSingleFile>false</PublishSingleFile>
|
||||
|
||||
@@ -8,7 +8,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
<Platform>Any CPU</Platform>
|
||||
<PublishDir>..\bin\Publish\MacOS-chardonnay</PublishDir>
|
||||
<PublishProtocol>FileSystem</PublishProtocol>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<RuntimeIdentifier>osx-x64</RuntimeIdentifier>
|
||||
<SelfContained>true</SelfContained>
|
||||
<PublishSingleFile>false</PublishSingleFile>
|
||||
|
||||
@@ -8,7 +8,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
<Platform>Any CPU</Platform>
|
||||
<PublishDir>..\bin\Publish\Windows-chardonnay</PublishDir>
|
||||
<PublishProtocol>FileSystem</PublishProtocol>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<SelfContained>true</SelfContained>
|
||||
<PublishSingleFile>false</PublishSingleFile>
|
||||
|
||||
@@ -8,20 +8,21 @@ using Dinah.Core;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading;
|
||||
using FileManager;
|
||||
using AaxDecrypter;
|
||||
|
||||
#nullable enable
|
||||
namespace LibationFileManager
|
||||
{
|
||||
public abstract class AudibleFileStorage
|
||||
{
|
||||
protected abstract LongPath? GetFilePathCustom(string productId);
|
||||
protected abstract List<LongPath> GetFilePathsCustom(string productId);
|
||||
public abstract class AudibleFileStorage
|
||||
{
|
||||
protected abstract LongPath? GetFilePathCustom(string productId);
|
||||
protected abstract List<LongPath> GetFilePathsCustom(string productId);
|
||||
|
||||
#region static
|
||||
public static LongPath DownloadsInProgressDirectory => Directory.CreateDirectory(Path.Combine(Configuration.Instance.InProgress, "DownloadsInProgress")).FullName;
|
||||
public static LongPath DecryptInProgressDirectory => Directory.CreateDirectory(Path.Combine(Configuration.Instance.InProgress, "DecryptInProgress")).FullName;
|
||||
#region static
|
||||
public static LongPath DownloadsInProgressDirectory => Directory.CreateDirectory(Path.Combine(Configuration.Instance.InProgress, "DownloadsInProgress")).FullName;
|
||||
public static LongPath DecryptInProgressDirectory => Directory.CreateDirectory(Path.Combine(Configuration.Instance.InProgress, "DecryptInProgress")).FullName;
|
||||
|
||||
static AudibleFileStorage()
|
||||
static AudibleFileStorage()
|
||||
{
|
||||
//Clean up any partially-decrypted files from previous Libation instances.
|
||||
//Do no clean DownloadsInProgressDirectory because those files are resumable
|
||||
@@ -31,103 +32,103 @@ namespace LibationFileManager
|
||||
|
||||
|
||||
private static AaxcFileStorage AAXC { get; } = new AaxcFileStorage();
|
||||
public static bool AaxcExists(string productId) => AAXC.Exists(productId);
|
||||
public static bool AaxcExists(string productId) => AAXC.Exists(productId);
|
||||
|
||||
public static AudioFileStorage Audio { get; } = new AudioFileStorage();
|
||||
public static AudioFileStorage Audio { get; } = new AudioFileStorage();
|
||||
|
||||
public static LongPath BooksDirectory
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(Configuration.Instance.Books))
|
||||
Configuration.Instance.Books = Path.Combine(Configuration.UserProfile, "Books");
|
||||
return Directory.CreateDirectory(Configuration.Instance.Books).FullName;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
public static LongPath BooksDirectory
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(Configuration.Instance.Books))
|
||||
Configuration.Instance.Books = Path.Combine(Configuration.UserProfile, "Books");
|
||||
return Directory.CreateDirectory(Configuration.Instance.Books).FullName;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region instance
|
||||
private FileType FileType { get; }
|
||||
private string regexTemplate { get; }
|
||||
#region instance
|
||||
private FileType FileType { get; }
|
||||
private string regexTemplate { get; }
|
||||
|
||||
protected AudibleFileStorage(FileType fileType)
|
||||
{
|
||||
FileType = fileType;
|
||||
protected AudibleFileStorage(FileType fileType)
|
||||
{
|
||||
FileType = fileType;
|
||||
|
||||
var extAggr = FileTypes.GetExtensions(FileType).Aggregate((a, b) => $"{a}|{b}");
|
||||
regexTemplate = $@"{{0}}.*?\.({extAggr})$";
|
||||
}
|
||||
var extAggr = FileTypes.GetExtensions(FileType).Aggregate((a, b) => $"{a}|{b}");
|
||||
regexTemplate = $@"{{0}}.*?\.({extAggr})$";
|
||||
}
|
||||
|
||||
protected LongPath? GetFilePath(string productId)
|
||||
{
|
||||
// primary lookup
|
||||
var cachedFile = FilePathCache.GetFirstPath(productId, FileType);
|
||||
if (cachedFile is not null && File.Exists(cachedFile))
|
||||
return cachedFile;
|
||||
protected LongPath? GetFilePath(string productId)
|
||||
{
|
||||
// primary lookup
|
||||
var cachedFile = FilePathCache.GetFirstPath(productId, FileType);
|
||||
if (cachedFile is not null && File.Exists(cachedFile))
|
||||
return cachedFile;
|
||||
|
||||
// secondary lookup attempt
|
||||
var firstOrNull = GetFilePathCustom(productId);
|
||||
if (firstOrNull is not null)
|
||||
FilePathCache.Insert(productId, firstOrNull);
|
||||
// secondary lookup attempt
|
||||
var firstOrNull = GetFilePathCustom(productId);
|
||||
if (firstOrNull is not null)
|
||||
FilePathCache.Insert(productId, firstOrNull);
|
||||
|
||||
return firstOrNull;
|
||||
}
|
||||
return firstOrNull;
|
||||
}
|
||||
|
||||
public List<LongPath> GetPaths(string productId)
|
||||
=> GetFilePathsCustom(productId);
|
||||
public List<LongPath> GetPaths(string productId)
|
||||
=> GetFilePathsCustom(productId);
|
||||
|
||||
protected Regex GetBookSearchRegex(string productId)
|
||||
{
|
||||
var pattern = string.Format(regexTemplate, productId);
|
||||
return new Regex(pattern, RegexOptions.IgnoreCase);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
protected Regex GetBookSearchRegex(string productId)
|
||||
{
|
||||
var pattern = string.Format(regexTemplate, productId);
|
||||
return new Regex(pattern, RegexOptions.IgnoreCase);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
internal class AaxcFileStorage : AudibleFileStorage
|
||||
{
|
||||
internal AaxcFileStorage() : base(FileType.AAXC) { }
|
||||
internal class AaxcFileStorage : AudibleFileStorage
|
||||
{
|
||||
internal AaxcFileStorage() : base(FileType.AAXC) { }
|
||||
|
||||
protected override LongPath? GetFilePathCustom(string productId)
|
||||
=> GetFilePathsCustom(productId).FirstOrDefault();
|
||||
protected override LongPath? GetFilePathCustom(string productId)
|
||||
=> GetFilePathsCustom(productId).FirstOrDefault();
|
||||
|
||||
protected override List<LongPath> GetFilePathsCustom(string productId)
|
||||
{
|
||||
var regex = GetBookSearchRegex(productId);
|
||||
return FileUtility
|
||||
.SaferEnumerateFiles(DownloadsInProgressDirectory, "*.*", SearchOption.AllDirectories)
|
||||
.Where(s => regex.IsMatch(s)).ToList();
|
||||
}
|
||||
protected override List<LongPath> GetFilePathsCustom(string productId)
|
||||
{
|
||||
var regex = GetBookSearchRegex(productId);
|
||||
return FileUtility
|
||||
.SaferEnumerateFiles(DownloadsInProgressDirectory, "*.*", SearchOption.AllDirectories)
|
||||
.Where(s => regex.IsMatch(s)).ToList();
|
||||
}
|
||||
|
||||
public bool Exists(string productId) => GetFilePath(productId) is not null;
|
||||
}
|
||||
public bool Exists(string productId) => GetFilePath(productId) is not null;
|
||||
}
|
||||
|
||||
public class AudioFileStorage : AudibleFileStorage
|
||||
{
|
||||
internal AudioFileStorage() : base(FileType.Audio)
|
||||
=> BookDirectoryFiles ??= newBookDirectoryFiles();
|
||||
public class AudioFileStorage : AudibleFileStorage
|
||||
{
|
||||
internal AudioFileStorage() : base(FileType.Audio)
|
||||
=> BookDirectoryFiles ??= newBookDirectoryFiles();
|
||||
|
||||
private static BackgroundFileSystem? BookDirectoryFiles { get; set; }
|
||||
private static object bookDirectoryFilesLocker { get; } = new();
|
||||
private static BackgroundFileSystem? BookDirectoryFiles { get; set; }
|
||||
private static object bookDirectoryFilesLocker { get; } = new();
|
||||
private static EnumerationOptions enumerationOptions { get; } = new()
|
||||
{
|
||||
RecurseSubdirectories = true,
|
||||
IgnoreInaccessible = true,
|
||||
MatchCasing = MatchCasing.CaseInsensitive
|
||||
AttributesToSkip = FileAttributes.Hidden,
|
||||
};
|
||||
|
||||
protected override LongPath? GetFilePathCustom(string productId)
|
||||
=> GetFilePathsCustom(productId).FirstOrDefault();
|
||||
=> GetFilePathsCustom(productId).FirstOrDefault();
|
||||
|
||||
private static BackgroundFileSystem newBookDirectoryFiles()
|
||||
=> new BackgroundFileSystem(BooksDirectory, "*.*", SearchOption.AllDirectories);
|
||||
private static BackgroundFileSystem newBookDirectoryFiles()
|
||||
=> new BackgroundFileSystem(BooksDirectory, "*.*", SearchOption.AllDirectories);
|
||||
|
||||
protected override List<LongPath> GetFilePathsCustom(string productId)
|
||||
{
|
||||
// If user changed the BooksDirectory: reinitialize
|
||||
lock (bookDirectoryFilesLocker)
|
||||
if (BooksDirectory != BookDirectoryFiles?.RootDirectory)
|
||||
BookDirectoryFiles = newBookDirectoryFiles();
|
||||
{
|
||||
// If user changed the BooksDirectory: reinitialize
|
||||
lock (bookDirectoryFilesLocker)
|
||||
if (BooksDirectory != BookDirectoryFiles?.RootDirectory)
|
||||
BookDirectoryFiles = newBookDirectoryFiles();
|
||||
|
||||
var regex = GetBookSearchRegex(productId);
|
||||
|
||||
@@ -135,44 +136,60 @@ namespace LibationFileManager
|
||||
//using both the file system and the file path cache
|
||||
return
|
||||
FilePathCache
|
||||
.GetFiles(productId)
|
||||
.Where(c => c.fileType == FileType.Audio && File.Exists(c.path))
|
||||
.Select(c => c.path)
|
||||
.Union(BookDirectoryFiles.FindFiles(regex))
|
||||
.ToList();
|
||||
}
|
||||
.GetFiles(productId)
|
||||
.Where(c => c.fileType == FileType.Audio && File.Exists(c.path))
|
||||
.Select(c => c.path)
|
||||
.Union(BookDirectoryFiles.FindFiles(regex))
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public void Refresh()
|
||||
{
|
||||
if (BookDirectoryFiles is null)
|
||||
lock (bookDirectoryFilesLocker)
|
||||
BookDirectoryFiles = newBookDirectoryFiles();
|
||||
else
|
||||
BookDirectoryFiles?.RefreshFiles();
|
||||
}
|
||||
public void Refresh()
|
||||
{
|
||||
if (BookDirectoryFiles is null)
|
||||
lock (bookDirectoryFilesLocker)
|
||||
BookDirectoryFiles = newBookDirectoryFiles();
|
||||
else
|
||||
BookDirectoryFiles?.RefreshFiles();
|
||||
}
|
||||
|
||||
public LongPath? GetPath(string productId) => GetFilePath(productId);
|
||||
public LongPath? GetPath(string productId) => GetFilePath(productId);
|
||||
|
||||
public static async IAsyncEnumerable<FilePathCache.CacheEntry> FindAudiobooksAsync(LongPath searchDirectory, [EnumeratorCancellation] CancellationToken cancellationToken)
|
||||
{
|
||||
ArgumentValidator.EnsureNotNull(searchDirectory, nameof(searchDirectory));
|
||||
|
||||
foreach (LongPath path in Directory.EnumerateFiles(searchDirectory, "*.M4B", enumerationOptions))
|
||||
foreach (LongPath path in Directory.EnumerateFiles(searchDirectory, "*.*", enumerationOptions))
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
yield break;
|
||||
|
||||
if (getFormatByExtension(path) is not OutputFormat format)
|
||||
continue;
|
||||
|
||||
FilePathCache.CacheEntry? audioFile = default;
|
||||
|
||||
try
|
||||
{
|
||||
using var fileStream = File.OpenRead(path);
|
||||
if (format is OutputFormat.M4b)
|
||||
{
|
||||
var tags = await Task.Run(() => AAXClean.AppleTags.FromFile(path));
|
||||
|
||||
var mp4File = await Task.Run(() => new AAXClean.Mp4File(fileStream), cancellationToken);
|
||||
if (tags?.Asin is not null)
|
||||
audioFile = new FilePathCache.CacheEntry(tags.Asin, FileType.Audio, path);
|
||||
}
|
||||
else
|
||||
{
|
||||
using var fileStream = File.OpenRead(path);
|
||||
var id3 = await Task.Run(() => NAudio.Lame.ID3.Id3Tag.Create(fileStream));
|
||||
|
||||
if (mp4File?.AppleTags?.Asin is not null)
|
||||
audioFile = new FilePathCache.CacheEntry(mp4File.AppleTags.Asin, FileType.Audio, path);
|
||||
var asin = id3?.Children
|
||||
.OfType<NAudio.Lame.ID3.TXXXFrame>()
|
||||
.FirstOrDefault(f => f.FieldName == "AUDIBLE_ASIN")
|
||||
?.FieldValue;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(asin))
|
||||
audioFile = new FilePathCache.CacheEntry(asin, FileType.Audio, path);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -186,6 +203,15 @@ namespace LibationFileManager
|
||||
if (audioFile is not null)
|
||||
yield return audioFile;
|
||||
}
|
||||
|
||||
static OutputFormat? getFormatByExtension(string path)
|
||||
{
|
||||
var ext = Path.GetExtension(path).ToLower();
|
||||
|
||||
return ext == ".mp3" ? OutputFormat.Mp3
|
||||
: ext == ".m4b" ? OutputFormat.M4b
|
||||
: null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using Serilog;
|
||||
using Dinah.Core.Logging;
|
||||
using System.Diagnostics;
|
||||
|
||||
#nullable enable
|
||||
namespace LibationFileManager
|
||||
@@ -75,17 +76,19 @@ namespace LibationFileManager
|
||||
const string appsettings_filename = "appsettings.json";
|
||||
|
||||
//Possible appsettings.json locations, in order of preference.
|
||||
string[] possibleAppsettingsFiles = new[]
|
||||
string[] possibleAppsettingsDirectories = new[]
|
||||
{
|
||||
Path.Combine(ProcessDirectory, appsettings_filename),
|
||||
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Libation", appsettings_filename),
|
||||
Path.Combine(UserProfile, appsettings_filename),
|
||||
Path.Combine(Path.GetTempPath(), "Libation", appsettings_filename)
|
||||
ProcessDirectory,
|
||||
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Libation"),
|
||||
UserProfile,
|
||||
Path.Combine(Path.GetTempPath(), "Libation")
|
||||
};
|
||||
|
||||
//Try to find and validate appsettings.json in each folder
|
||||
foreach (var appsettingsFile in possibleAppsettingsFiles)
|
||||
foreach (var dir in possibleAppsettingsDirectories)
|
||||
{
|
||||
var appsettingsFile = Path.Combine(dir, appsettings_filename);
|
||||
|
||||
if (File.Exists(appsettingsFile))
|
||||
{
|
||||
try
|
||||
@@ -104,10 +107,13 @@ namespace LibationFileManager
|
||||
|
||||
//Valid appsettings.json not found. Try to create it in each folder.
|
||||
var endingContents = new JObject { { LIBATION_FILES_KEY, UserProfile } }.ToString(Formatting.Indented);
|
||||
foreach (var appsettingsFile in possibleAppsettingsFiles)
|
||||
foreach (var dir in possibleAppsettingsDirectories)
|
||||
{
|
||||
var appsettingsFile = Path.Combine(dir, appsettings_filename);
|
||||
|
||||
try
|
||||
{
|
||||
Directory.CreateDirectory(dir);
|
||||
File.WriteAllText(appsettingsFile, endingContents);
|
||||
return appsettingsFile;
|
||||
}
|
||||
@@ -121,16 +127,56 @@ namespace LibationFileManager
|
||||
}
|
||||
|
||||
private static string getLibationFilesSettingFromJson()
|
||||
{
|
||||
// do not check whether directory exists. special/meta directory (eg: AppDir) is valid
|
||||
// verify from live file. no try/catch. want failures to be visible
|
||||
var jObjFinal = JObject.Parse(File.ReadAllText(AppsettingsJsonFile));
|
||||
{
|
||||
// do not check whether directory exists. special/meta directory (eg: AppDir) is valid
|
||||
// verify from live file. no try/catch. want failures to be visible
|
||||
var jObjFinal = JObject.Parse(File.ReadAllText(AppsettingsJsonFile));
|
||||
|
||||
if (jObjFinal[LIBATION_FILES_KEY]?.Value<string>() is not string valueFinal)
|
||||
throw new InvalidDataException($"{LIBATION_FILES_KEY} not found in {AppsettingsJsonFile}");
|
||||
|
||||
return valueFinal;
|
||||
}
|
||||
if (IsWindows)
|
||||
{
|
||||
valueFinal = Environment.ExpandEnvironmentVariables(valueFinal);
|
||||
}
|
||||
else
|
||||
{
|
||||
//If the shell command fails and returns null, proceed with the verbatim
|
||||
//LIBATION_FILES_KEY path and hope for the best. If Libation can't find
|
||||
//anything at this path it will set LIBATION_FILES_KEY to UserProfile
|
||||
valueFinal = runShellCommand("echo " + valueFinal) ?? valueFinal;
|
||||
}
|
||||
|
||||
return valueFinal;
|
||||
|
||||
static string? runShellCommand(string command)
|
||||
{
|
||||
var psi = new ProcessStartInfo
|
||||
{
|
||||
FileName = "/bin/sh",
|
||||
RedirectStandardOutput = true,
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = true,
|
||||
ArgumentList =
|
||||
{
|
||||
"-c",
|
||||
command
|
||||
}
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
var proc = Process.Start(psi);
|
||||
proc?.WaitForExit();
|
||||
return proc?.StandardOutput?.ReadToEnd()?.Trim();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Serilog.Log.Error(e, "Failed to run shell command. {Arguments}", psi.ArgumentList);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetLibationFiles(string directory)
|
||||
{
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
|
||||
<PackageReference Include="NameParserSharp" Version="1.5.0" />
|
||||
<PackageReference Include="Serilog.Exceptions" Version="8.4.0" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -9,7 +9,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="LuceneNet303r2" Version="3.0.3.5" />
|
||||
<PackageReference Include="LuceneNet303r2" Version="3.0.3.8" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -95,20 +95,4 @@ public class GridContextMenu
|
||||
|
||||
return TemplateEditor<T>.CreateFilenameEditor(Configuration.Instance.Books, existingTemplate, folderDto, fileDto);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
class Command : ICommand
|
||||
{
|
||||
public event EventHandler CanExecuteChanged;
|
||||
|
||||
public bool CanExecute(object parameter)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Execute(object parameter)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<IsPublishable>true</IsPublishable>
|
||||
<PublishReadyToRun>true</PublishReadyToRun>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
@@ -9,7 +9,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="SixLabors.ImageSharp" Version="3.0.1" />
|
||||
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -229,7 +229,7 @@
|
||||
badBookGb.Controls.Add(badBookAskRb);
|
||||
badBookGb.Location = new System.Drawing.Point(7, 6);
|
||||
badBookGb.Name = "badBookGb";
|
||||
badBookGb.Size = new System.Drawing.Size(836, 76);
|
||||
badBookGb.Size = new System.Drawing.Size(841, 76);
|
||||
badBookGb.TabIndex = 13;
|
||||
badBookGb.TabStop = false;
|
||||
badBookGb.Text = "[bad book desc]";
|
||||
@@ -397,6 +397,7 @@
|
||||
//
|
||||
// tab1ImportantSettings
|
||||
//
|
||||
tab1ImportantSettings.AutoScroll = true;
|
||||
tab1ImportantSettings.Controls.Add(groupBox1);
|
||||
tab1ImportantSettings.Controls.Add(booksGb);
|
||||
tab1ImportantSettings.Controls.Add(logsBtn);
|
||||
@@ -412,6 +413,7 @@
|
||||
//
|
||||
// groupBox1
|
||||
//
|
||||
groupBox1.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
||||
groupBox1.Controls.Add(applyDisplaySettingsBtn);
|
||||
groupBox1.Controls.Add(gridScaleFactorLbl);
|
||||
groupBox1.Controls.Add(gridScaleFactorTbar);
|
||||
@@ -426,6 +428,7 @@
|
||||
//
|
||||
// applyDisplaySettingsBtn
|
||||
//
|
||||
applyDisplaySettingsBtn.Anchor = System.Windows.Forms.AnchorStyles.Right;
|
||||
applyDisplaySettingsBtn.Location = new System.Drawing.Point(689, 26);
|
||||
applyDisplaySettingsBtn.Name = "applyDisplaySettingsBtn";
|
||||
applyDisplaySettingsBtn.Size = new System.Drawing.Size(148, 34);
|
||||
@@ -554,6 +557,7 @@
|
||||
//
|
||||
// tab2ImportLibrary
|
||||
//
|
||||
tab2ImportLibrary.AutoScroll = true;
|
||||
tab2ImportLibrary.Controls.Add(autoDownloadEpisodesCb);
|
||||
tab2ImportLibrary.Controls.Add(autoScanCb);
|
||||
tab2ImportLibrary.Controls.Add(showImportedStatsCb);
|
||||
@@ -599,6 +603,7 @@
|
||||
//
|
||||
// tab3DownloadDecrypt
|
||||
//
|
||||
tab3DownloadDecrypt.AutoScroll = true;
|
||||
tab3DownloadDecrypt.Controls.Add(saveMetadataToFileCbox);
|
||||
tab3DownloadDecrypt.Controls.Add(useCoverAsFolderIconCb);
|
||||
tab3DownloadDecrypt.Controls.Add(inProgressFilesGb);
|
||||
@@ -764,6 +769,7 @@
|
||||
//
|
||||
// tab4AudioFileOptions
|
||||
//
|
||||
tab4AudioFileOptions.AutoScroll = true;
|
||||
tab4AudioFileOptions.Controls.Add(fileDownloadQualityCb);
|
||||
tab4AudioFileOptions.Controls.Add(fileDownloadQualityLbl);
|
||||
tab4AudioFileOptions.Controls.Add(combineNestedChapterTitlesCbox);
|
||||
@@ -845,7 +851,7 @@
|
||||
audiobookFixupsGb.Controls.Add(stripAudibleBrandingCbox);
|
||||
audiobookFixupsGb.Location = new System.Drawing.Point(6, 200);
|
||||
audiobookFixupsGb.Name = "audiobookFixupsGb";
|
||||
audiobookFixupsGb.Size = new System.Drawing.Size(403, 182);
|
||||
audiobookFixupsGb.Size = new System.Drawing.Size(385, 182);
|
||||
audiobookFixupsGb.TabIndex = 19;
|
||||
audiobookFixupsGb.TabStop = false;
|
||||
audiobookFixupsGb.Text = "Audiobook Fix-ups";
|
||||
@@ -872,6 +878,7 @@
|
||||
//
|
||||
// chapterTitleTemplateGb
|
||||
//
|
||||
chapterTitleTemplateGb.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
||||
chapterTitleTemplateGb.Controls.Add(chapterTitleTemplateBtn);
|
||||
chapterTitleTemplateGb.Controls.Add(chapterTitleTemplateTb);
|
||||
chapterTitleTemplateGb.Location = new System.Drawing.Point(3, 388);
|
||||
@@ -903,6 +910,7 @@
|
||||
//
|
||||
// lameOptionsGb
|
||||
//
|
||||
lameOptionsGb.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
||||
lameOptionsGb.Controls.Add(label20);
|
||||
lameOptionsGb.Controls.Add(label21);
|
||||
lameOptionsGb.Controls.Add(encoderQualityCb);
|
||||
@@ -912,9 +920,9 @@
|
||||
lameOptionsGb.Controls.Add(label1);
|
||||
lameOptionsGb.Controls.Add(lameQualityGb);
|
||||
lameOptionsGb.Controls.Add(groupBox2);
|
||||
lameOptionsGb.Location = new System.Drawing.Point(415, 6);
|
||||
lameOptionsGb.Location = new System.Drawing.Point(397, 6);
|
||||
lameOptionsGb.Name = "lameOptionsGb";
|
||||
lameOptionsGb.Size = new System.Drawing.Size(433, 376);
|
||||
lameOptionsGb.Size = new System.Drawing.Size(450, 376);
|
||||
lameOptionsGb.TabIndex = 14;
|
||||
lameOptionsGb.TabStop = false;
|
||||
lameOptionsGb.Text = "Mp3 Encoding Options";
|
||||
@@ -930,6 +938,7 @@
|
||||
//
|
||||
// label21
|
||||
//
|
||||
label21.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
||||
label21.AutoSize = true;
|
||||
label21.Location = new System.Drawing.Point(239, 89);
|
||||
label21.Name = "label21";
|
||||
@@ -939,33 +948,37 @@
|
||||
//
|
||||
// encoderQualityCb
|
||||
//
|
||||
encoderQualityCb.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
||||
encoderQualityCb.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
encoderQualityCb.FormattingEnabled = true;
|
||||
encoderQualityCb.Location = new System.Drawing.Point(337, 86);
|
||||
encoderQualityCb.Name = "encoderQualityCb";
|
||||
encoderQualityCb.Size = new System.Drawing.Size(90, 23);
|
||||
encoderQualityCb.Size = new System.Drawing.Size(107, 23);
|
||||
encoderQualityCb.TabIndex = 2;
|
||||
//
|
||||
// maxSampleRateCb
|
||||
//
|
||||
maxSampleRateCb.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
||||
maxSampleRateCb.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
maxSampleRateCb.FormattingEnabled = true;
|
||||
maxSampleRateCb.Location = new System.Drawing.Point(119, 86);
|
||||
maxSampleRateCb.Name = "maxSampleRateCb";
|
||||
maxSampleRateCb.Size = new System.Drawing.Size(101, 23);
|
||||
maxSampleRateCb.Size = new System.Drawing.Size(76, 23);
|
||||
maxSampleRateCb.TabIndex = 2;
|
||||
//
|
||||
// lameDownsampleMonoCbox
|
||||
//
|
||||
lameDownsampleMonoCbox.Location = new System.Drawing.Point(237, 30);
|
||||
lameDownsampleMonoCbox.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right;
|
||||
lameDownsampleMonoCbox.Location = new System.Drawing.Point(247, 29);
|
||||
lameDownsampleMonoCbox.Name = "lameDownsampleMonoCbox";
|
||||
lameDownsampleMonoCbox.Size = new System.Drawing.Size(184, 34);
|
||||
lameDownsampleMonoCbox.Size = new System.Drawing.Size(197, 34);
|
||||
lameDownsampleMonoCbox.TabIndex = 1;
|
||||
lameDownsampleMonoCbox.Text = "Downsample stereo to mono?\r\n(Recommended)\r\n";
|
||||
lameDownsampleMonoCbox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// lameBitrateGb
|
||||
//
|
||||
lameBitrateGb.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
||||
lameBitrateGb.Controls.Add(LameMatchSourceBRCbox);
|
||||
lameBitrateGb.Controls.Add(lameConstantBitrateCbox);
|
||||
lameBitrateGb.Controls.Add(label7);
|
||||
@@ -977,15 +990,16 @@
|
||||
lameBitrateGb.Controls.Add(lameBitrateTb);
|
||||
lameBitrateGb.Location = new System.Drawing.Point(6, 116);
|
||||
lameBitrateGb.Name = "lameBitrateGb";
|
||||
lameBitrateGb.Size = new System.Drawing.Size(421, 113);
|
||||
lameBitrateGb.Size = new System.Drawing.Size(438, 113);
|
||||
lameBitrateGb.TabIndex = 0;
|
||||
lameBitrateGb.TabStop = false;
|
||||
lameBitrateGb.Text = "Bitrate";
|
||||
//
|
||||
// LameMatchSourceBRCbox
|
||||
//
|
||||
LameMatchSourceBRCbox.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right;
|
||||
LameMatchSourceBRCbox.AutoSize = true;
|
||||
LameMatchSourceBRCbox.Location = new System.Drawing.Point(275, 76);
|
||||
LameMatchSourceBRCbox.Location = new System.Drawing.Point(254, 76);
|
||||
LameMatchSourceBRCbox.Name = "LameMatchSourceBRCbox";
|
||||
LameMatchSourceBRCbox.Size = new System.Drawing.Size(140, 19);
|
||||
LameMatchSourceBRCbox.TabIndex = 3;
|
||||
@@ -1005,6 +1019,7 @@
|
||||
//
|
||||
// label7
|
||||
//
|
||||
label7.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
||||
label7.AutoSize = true;
|
||||
label7.BackColor = System.Drawing.SystemColors.ControlLightLight;
|
||||
label7.Location = new System.Drawing.Point(390, 52);
|
||||
@@ -1015,6 +1030,7 @@
|
||||
//
|
||||
// label6
|
||||
//
|
||||
label6.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
||||
label6.AutoSize = true;
|
||||
label6.BackColor = System.Drawing.SystemColors.ControlLightLight;
|
||||
label6.Location = new System.Drawing.Point(309, 52);
|
||||
@@ -1025,6 +1041,7 @@
|
||||
//
|
||||
// label5
|
||||
//
|
||||
label5.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
||||
label5.AutoSize = true;
|
||||
label5.BackColor = System.Drawing.SystemColors.ControlLightLight;
|
||||
label5.Location = new System.Drawing.Point(228, 52);
|
||||
@@ -1035,6 +1052,7 @@
|
||||
//
|
||||
// label4
|
||||
//
|
||||
label4.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
||||
label4.AutoSize = true;
|
||||
label4.BackColor = System.Drawing.SystemColors.ControlLightLight;
|
||||
label4.Location = new System.Drawing.Point(147, 52);
|
||||
@@ -1045,6 +1063,7 @@
|
||||
//
|
||||
// label11
|
||||
//
|
||||
label11.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
||||
label11.AutoSize = true;
|
||||
label11.BackColor = System.Drawing.SystemColors.ControlLightLight;
|
||||
label11.Location = new System.Drawing.Point(10, 52);
|
||||
@@ -1055,6 +1074,7 @@
|
||||
//
|
||||
// label3
|
||||
//
|
||||
label3.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
||||
label3.AutoSize = true;
|
||||
label3.BackColor = System.Drawing.SystemColors.ControlLightLight;
|
||||
label3.Location = new System.Drawing.Point(71, 52);
|
||||
@@ -1071,7 +1091,7 @@
|
||||
lameBitrateTb.Maximum = 320;
|
||||
lameBitrateTb.Minimum = 16;
|
||||
lameBitrateTb.Name = "lameBitrateTb";
|
||||
lameBitrateTb.Size = new System.Drawing.Size(409, 45);
|
||||
lameBitrateTb.Size = new System.Drawing.Size(408, 45);
|
||||
lameBitrateTb.SmallChange = 8;
|
||||
lameBitrateTb.TabIndex = 0;
|
||||
lameBitrateTb.TickFrequency = 16;
|
||||
@@ -1090,6 +1110,7 @@
|
||||
//
|
||||
// lameQualityGb
|
||||
//
|
||||
lameQualityGb.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
||||
lameQualityGb.Controls.Add(label19);
|
||||
lameQualityGb.Controls.Add(label18);
|
||||
lameQualityGb.Controls.Add(label17);
|
||||
@@ -1105,13 +1126,14 @@
|
||||
lameQualityGb.Controls.Add(lameVBRQualityTb);
|
||||
lameQualityGb.Location = new System.Drawing.Point(6, 235);
|
||||
lameQualityGb.Name = "lameQualityGb";
|
||||
lameQualityGb.Size = new System.Drawing.Size(421, 109);
|
||||
lameQualityGb.Size = new System.Drawing.Size(438, 109);
|
||||
lameQualityGb.TabIndex = 0;
|
||||
lameQualityGb.TabStop = false;
|
||||
lameQualityGb.Text = "Quality";
|
||||
//
|
||||
// label19
|
||||
//
|
||||
label19.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
||||
label19.AutoSize = true;
|
||||
label19.Location = new System.Drawing.Point(349, 52);
|
||||
label19.Name = "label19";
|
||||
@@ -1121,6 +1143,7 @@
|
||||
//
|
||||
// label18
|
||||
//
|
||||
label18.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
||||
label18.AutoSize = true;
|
||||
label18.Location = new System.Drawing.Point(307, 52);
|
||||
label18.Name = "label18";
|
||||
@@ -1130,6 +1153,7 @@
|
||||
//
|
||||
// label17
|
||||
//
|
||||
label17.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
||||
label17.AutoSize = true;
|
||||
label17.Location = new System.Drawing.Point(265, 52);
|
||||
label17.Name = "label17";
|
||||
@@ -1139,6 +1163,7 @@
|
||||
//
|
||||
// label16
|
||||
//
|
||||
label16.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
||||
label16.AutoSize = true;
|
||||
label16.Location = new System.Drawing.Point(223, 52);
|
||||
label16.Name = "label16";
|
||||
@@ -1148,6 +1173,7 @@
|
||||
//
|
||||
// label12
|
||||
//
|
||||
label12.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
||||
label12.AutoSize = true;
|
||||
label12.Location = new System.Drawing.Point(182, 52);
|
||||
label12.Name = "label12";
|
||||
@@ -1157,6 +1183,7 @@
|
||||
//
|
||||
// label15
|
||||
//
|
||||
label15.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
||||
label15.AutoSize = true;
|
||||
label15.Location = new System.Drawing.Point(140, 52);
|
||||
label15.Name = "label15";
|
||||
@@ -1166,6 +1193,7 @@
|
||||
//
|
||||
// label9
|
||||
//
|
||||
label9.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
||||
label9.AutoSize = true;
|
||||
label9.Location = new System.Drawing.Point(97, 52);
|
||||
label9.Name = "label9";
|
||||
@@ -1175,6 +1203,7 @@
|
||||
//
|
||||
// label8
|
||||
//
|
||||
label8.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
||||
label8.AutoSize = true;
|
||||
label8.Location = new System.Drawing.Point(391, 52);
|
||||
label8.Name = "label8";
|
||||
@@ -1202,6 +1231,7 @@
|
||||
//
|
||||
// label14
|
||||
//
|
||||
label14.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
||||
label14.AutoSize = true;
|
||||
label14.Location = new System.Drawing.Point(56, 52);
|
||||
label14.Name = "label14";
|
||||
@@ -1211,6 +1241,7 @@
|
||||
//
|
||||
// label2
|
||||
//
|
||||
label2.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
||||
label2.AutoSize = true;
|
||||
label2.Location = new System.Drawing.Point(14, 52);
|
||||
label2.Name = "label2";
|
||||
@@ -1225,25 +1256,27 @@
|
||||
lameVBRQualityTb.Location = new System.Drawing.Point(10, 22);
|
||||
lameVBRQualityTb.Maximum = 9;
|
||||
lameVBRQualityTb.Name = "lameVBRQualityTb";
|
||||
lameVBRQualityTb.Size = new System.Drawing.Size(405, 45);
|
||||
lameVBRQualityTb.Size = new System.Drawing.Size(404, 45);
|
||||
lameVBRQualityTb.TabIndex = 0;
|
||||
lameVBRQualityTb.Value = 9;
|
||||
//
|
||||
// groupBox2
|
||||
//
|
||||
groupBox2.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
||||
groupBox2.Controls.Add(lameTargetQualityRb);
|
||||
groupBox2.Controls.Add(lameTargetBitrateRb);
|
||||
groupBox2.Location = new System.Drawing.Point(6, 22);
|
||||
groupBox2.Name = "groupBox2";
|
||||
groupBox2.Size = new System.Drawing.Size(214, 58);
|
||||
groupBox2.Size = new System.Drawing.Size(189, 58);
|
||||
groupBox2.TabIndex = 0;
|
||||
groupBox2.TabStop = false;
|
||||
groupBox2.Text = "Target";
|
||||
//
|
||||
// lameTargetQualityRb
|
||||
//
|
||||
lameTargetQualityRb.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right;
|
||||
lameTargetQualityRb.AutoSize = true;
|
||||
lameTargetQualityRb.Location = new System.Drawing.Point(139, 22);
|
||||
lameTargetQualityRb.Location = new System.Drawing.Point(118, 22);
|
||||
lameTargetQualityRb.Name = "lameTargetQualityRb";
|
||||
lameTargetQualityRb.Size = new System.Drawing.Size(63, 19);
|
||||
lameTargetQualityRb.TabIndex = 0;
|
||||
@@ -1321,7 +1354,6 @@
|
||||
Controls.Add(tabControl);
|
||||
Controls.Add(cancelBtn);
|
||||
Controls.Add(saveBtn);
|
||||
FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
|
||||
Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
MaximizeBox = false;
|
||||
MinimizeBox = false;
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing"">Blue</data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net7.0-windows</TargetFramework>
|
||||
<TargetFramework>net8.0-windows7.0</TargetFramework>
|
||||
<EnableWindowsTargeting>true</EnableWindowsTargeting>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<ApplicationIcon>libation.ico</ApplicationIcon>
|
||||
@@ -37,7 +37,7 @@
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Dinah.Core.WindowsDesktop" Version="7.3.0.1" />
|
||||
<PackageReference Include="Dinah.Core.WindowsDesktop" Version="8.0.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -250,7 +250,7 @@ namespace LibationWinForms.ProcessQueue
|
||||
private byte[] AudioDecodable_RequestCoverArt(object sender, EventArgs e)
|
||||
{
|
||||
var quality
|
||||
= Configuration.Instance.FileDownloadQuality == Configuration.DownloadQuality.High
|
||||
= Configuration.Instance.FileDownloadQuality == Configuration.DownloadQuality.High && LibraryBook.Book.PictureLarge is not null
|
||||
? new PictureDefinition(LibraryBook.Book.PictureLarge, PictureSize.Native)
|
||||
: new PictureDefinition(LibraryBook.Book.PictureId, PictureSize._500x500);
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
<Platform>Any CPU</Platform>
|
||||
<PublishDir>..\bin\Publish\classic</PublishDir>
|
||||
<PublishProtocol>FileSystem</PublishProtocol>
|
||||
<TargetFramework>net7.0-windows</TargetFramework>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<SelfContained>true</SelfContained>
|
||||
<PublishSingleFile>false</PublishSingleFile>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<PublishReadyToRun>true</PublishReadyToRun>
|
||||
<RuntimeIdentifier>linux-x64</RuntimeIdentifier>
|
||||
|
||||
@@ -8,7 +8,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
<Platform>Any CPU</Platform>
|
||||
<PublishDir>..\..\bin\Publish\Linux-chardonnay</PublishDir>
|
||||
<PublishProtocol>FileSystem</PublishProtocol>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<RuntimeIdentifier>linux-x64</RuntimeIdentifier>
|
||||
<SelfContained>true</SelfContained>
|
||||
<PublishSingleFile>false</PublishSingleFile>
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<!--<TargetFramework>net7.0-macos</TargetFramework>-->
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<!--<TargetFramework>net8.0-macos</TargetFramework>-->
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<PublishReadyToRun>true</PublishReadyToRun>
|
||||
<RuntimeIdentifier>osx-x64</RuntimeIdentifier>
|
||||
|
||||
@@ -8,7 +8,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
<Platform>Any CPU</Platform>
|
||||
<PublishDir>..\..\bin\Publish\MacOS-chardonnay</PublishDir>
|
||||
<PublishProtocol>FileSystem</PublishProtocol>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<RuntimeIdentifier>osx-x64</RuntimeIdentifier>
|
||||
<SelfContained>true</SelfContained>
|
||||
<PublishSingleFile>false</PublishSingleFile>
|
||||
|
||||
@@ -8,7 +8,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
<Platform>Any CPU</Platform>
|
||||
<PublishDir>..\..\bin\Publish\classic</PublishDir>
|
||||
<PublishProtocol>FileSystem</PublishProtocol>
|
||||
<TargetFramework>net7.0-windows</TargetFramework>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
<SelfContained>true</SelfContained>
|
||||
<PublishSingleFile>false</PublishSingleFile>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net7.0-windows</TargetFramework>
|
||||
<TargetFramework>net8.0-windows7.0</TargetFramework>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<EnableWindowsTargeting>true</EnableWindowsTargeting>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
@@ -26,7 +26,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.1901.177" />
|
||||
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.2210.55" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
9
Source/Upgrading dotnet version.txt
Normal file
9
Source/Upgrading dotnet version.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
For reasons I cannot figure out, upgrading the major .net version breaks Libation until these were done. Update these to the same version of .net as the app and release their nugets:
|
||||
|
||||
* https://github.com/rmcrackan/Dinah.Core
|
||||
* https://github.com/rmcrackan/AudibleApi
|
||||
* https://github.com/rmcrackan/LuceneNet303r2
|
||||
|
||||
* https://github.com/Mbucari/AAXClean.Codecs
|
||||
* https://github.com/Mbucari/AAXClean
|
||||
* https://github.com/Mbucari/serilog-sinks-zipfile
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
@@ -19,7 +19,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Dinah.Core" Version="7.3.0.1" />
|
||||
<PackageReference Include="Dinah.Core" Version="8.0.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net7.0-windows</TargetFramework>
|
||||
<TargetFramework>net8.0-windows7.0</TargetFramework>
|
||||
<EnableWindowsTargeting>true</EnableWindowsTargeting>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FluentAssertions" Version="6.11.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.0" />
|
||||
<PackageReference Include="FluentAssertions" Version="6.12.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
|
||||
<PackageReference Include="MSTest.TestAdapter" Version="3.1.1" />
|
||||
<PackageReference Include="MSTest.TestFramework" Version="3.1.1" />
|
||||
<PackageReference Include="coverlet.collector" Version="6.0.0">
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FluentAssertions" Version="6.11.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.0" />
|
||||
<PackageReference Include="FluentAssertions" Version="6.12.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
|
||||
<PackageReference Include="MSTest.TestAdapter" Version="3.1.1" />
|
||||
<PackageReference Include="MSTest.TestFramework" Version="3.1.1" />
|
||||
<PackageReference Include="coverlet.collector" Version="6.0.0">
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FluentAssertions" Version="6.11.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.0" />
|
||||
<PackageReference Include="FluentAssertions" Version="6.12.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
|
||||
<PackageReference Include="MSTest.TestAdapter" Version="3.1.1" />
|
||||
<PackageReference Include="MSTest.TestFramework" Version="3.1.1" />
|
||||
<PackageReference Include="coverlet.collector" Version="6.0.0">
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FluentAssertions" Version="6.11.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.0" />
|
||||
<PackageReference Include="FluentAssertions" Version="6.12.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
|
||||
<PackageReference Include="MSTest.TestAdapter" Version="3.1.1" />
|
||||
<PackageReference Include="MSTest.TestFramework" Version="3.1.1" />
|
||||
<PackageReference Include="coverlet.collector" Version="6.0.0">
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FluentAssertions" Version="6.11.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.0" />
|
||||
<PackageReference Include="FluentAssertions" Version="6.12.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
|
||||
<PackageReference Include="MSTest.TestAdapter" Version="3.1.1" />
|
||||
<PackageReference Include="MSTest.TestFramework" Version="3.1.1" />
|
||||
<PackageReference Include="coverlet.collector" Version="6.0.0">
|
||||
|
||||
Reference in New Issue
Block a user