Compare commits

..
2578 Commits
Author SHA1 Message Date
rmcrackan a25fd35f29 Fix release upload path for merge-multiple artifact download 2026-06-08 13:19:10 -04:00
rmcrackan 20a99c6e20 Exclude Docker cache blobs from release artifact download 2026-06-08 11:59:03 -04:00
rmcrackan f39cfaccc7 Fix release artifact pattern for Libation-Classic assets 2026-06-08 11:21:20 -04:00
rmcrackan 6db78e4268 Merge pull request #1859 from rmcrackan/rmcrackan/windows-installer-fix
Fix arm64 Windows zip artifact name in CI matrix
2026-06-08 11:03:49 -04:00
rmcrackan 74e9cf24a8 Fix arm64 Windows zip artifact name in CI matrix 2026-06-08 11:01:42 -04:00
rmcrackan 6ce88072c5 Merge pull request #1858 from rmcrackan/rmcrackan/windows-installer-fix
yaml bug fix
2026-06-08 10:53:50 -04:00
rmcrackan 9058c7368c yaml bug fix 2026-06-08 10:53:05 -04:00
rmcrackan 37d5517756 Merge pull request #1857 from rmcrackan/rmcrackan/windows-installer
Add Windows installers to release build
2026-06-08 10:45:39 -04:00
rmcrackan 0a33863635 Merge branch 'master' into rmcrackan/windows-installer 2026-06-08 10:44:58 -04:00
rmcrackan d03955a2ca Add Windows installers to release build 2026-06-08 10:43:32 -04:00
Robert b2c5ae3c2e incr ver 2026-06-08 10:27:17 -04:00
rmcrackan fb7e0857c6 Merge pull request #1856 from rmcrackan/rmcrackan/releaseindex
update backwards compat releaseindex in prep for future changes
2026-06-08 10:15:26 -04:00
rmcrackan 60965902ca update backwards compat releaseindex in prep for future changes 2026-06-08 10:15:00 -04:00
rmcrackan ef62ee15e2 Merge branch 'master' of https://github.com/rmcrackan/Libation 2026-06-07 12:56:21 -04:00
rmcrackan c285522a0c Add contributor from PR #1854 2026-06-07 12:56:13 -04:00
rmcrackan 0fb3eb152f Merge pull request #1854 from matalvernaz/fix/1729-sqlite-migration-lock-deadlock
Skip EF migration lock when no migrations are pending (fixes SQLite scan-hang #1729)
2026-06-07 12:55:20 -04:00
Matthew Alvernaz 63325b9cad Skip EF migration lock when no migrations are pending (#1729)
DbContexts.GetContext() runs ApplyMigrations on every context creation,
calling Database.Migrate(). Migrate() acquires the EF migration lock
before checking whether anything is pending. For SQLite that lock is a
persisted row in __EFMigrationsLock with no timeout (SQLite has no
connection-scoped lock that frees on disconnect). A process killed after
acquiring the lock but before releasing it - even during an otherwise
no-op Migrate() - orphans the row, and every later Migrate() then spins
forever in SqliteHistoryRepository.AcquireDatabaseLock(). The row lives
in the db file, so restarts never clear it, matching the "scan hangs,
reboot doesn't help" reports in #1729.

Guard Migrate()/MigrateAsync() behind GetPendingMigrations(), which only
reads __EFMigrationsHistory and never acquires the lock. The steady-state
path (schema already current) no longer touches the lock at all; first
run and real migrations are unchanged.
2026-06-06 22:23:12 -07:00
rmcrackan 37a60ca654 Merge pull request #1853 from rmcrackan/rmcrackan-patch-1
increm ver
2026-06-05 10:42:50 -04:00
rmcrackan 6623300883 Update AppScaffolding.csproj 2026-06-05 10:42:21 -04:00
rmcrackan 329df0882a Merge pull request #1852 from rmcrackan/rmcrackan/1851-threading
#1851 - threading bug
2026-06-04 10:23:11 -04:00
rmcrackan da000694d7 upgrade dependency 2026-06-04 10:17:23 -04:00
rmcrackan f1a7a837f3 CI bug. try upgrading 2026-06-04 10:13:22 -04:00
rmcrackan 869917e0ce #1851 - threading bug 2026-06-04 09:59:12 -04:00
rmcrackan d532e40fe9 Merge pull request #1850 from rmcrackan/rmcrackan/doc-cleanup
Clean up docs
2026-06-03 11:05:49 -04:00
rmcrackan 9ef5e95801 Clean up docs 2026-06-03 11:04:59 -04:00
rmcrackan c1c3c33ea8 Merge pull request #1849 from rmcrackan/rmcrackan/docs-better-atmos
better atmos docs
2026-06-02 16:45:36 -04:00
rmcrackan b31e7cb819 better atmos docs 2026-06-02 16:44:54 -04:00
rmcrackan 314a46d59d Merge pull request #1848 from rmcrackan/rmcrackan/docs-spacial-audio
new page for spacial audio info
2026-06-02 16:39:21 -04:00
rmcrackan 721f09a62b new page for spacial audio info 2026-06-02 16:38:12 -04:00
rmcrackan 545b3057d4 Merge pull request #1847 from rmcrackan/rmcrackan/1845-better-non-json
#1845 - improve error message for common VPN blocking errors
2026-06-02 12:58:30 -04:00
rmcrackan 2c2ae2c8b0 #1845 - improve error message for common VPN blocking errors. improve troubleshooting docs 2026-06-02 12:53:20 -04:00
rmcrackan f456c68176 Merge pull request #1846 from rmcrackan/rmcrackan/1844-nre
#1844 - add lock to avoid race/NRE
2026-06-02 10:59:25 -04:00
rmcrackan e6c17053f7 #1844 - add lock to avoid race/NRE 2026-06-02 10:54:14 -04:00
rmcrackan 0c22b821bf incr ver 2026-05-25 11:16:38 -04:00
rmcrackan 8902ddc565 Merge pull request #1838 from rmcrackan/rmcrackan/1836-disk-space
#1836 - Fix misleading "Not enough disk space" warnings
2026-05-25 11:15:08 -04:00
rmcrackan 9ed98cbfff unit test fix: this is always going be a weird test. it's trying to balance machine speed vs long running process -- and test 'unreasonable' response time 2026-05-25 10:58:57 -04:00
rmcrackan 3cf5d0b3fa unit test bug fix: culture info 2026-05-25 10:46:34 -04:00
rmcrackan 6bd1ea7ca4 fix unit tests for windows-only logic 2026-05-25 10:41:20 -04:00
rmcrackan f8c5f0da68 #1836 - Fix misleading "Not enough disk space" warnings when Books and In progress are on different drives 2026-05-25 10:25:46 -04:00
rmcrackan a3f272a48e #1835 - add log file guidance to FAQ 2026-05-22 15:00:34 -04:00
Robert 9ee59738eb incr ver 2026-05-21 10:36:21 -04:00
rmcrackan f57839c104 Merge pull request #1834 from rmcrackan/rmcrackan/1833-pdf-bug-fix
Download works but queue goes red with Download PDF
2026-05-21 10:33:52 -04:00
rmcrackan d63fabd73d Download works but queue goes red with Download PDF 2026-05-21 10:33:13 -04:00
rmcrackan 54a97cc3c4 Merge pull request #1830 from rmcrackan/fix/docs-vite-security-override
Pin vite 6.4.2 for docs site (Dependabot GHSA-4w7w-66w2-5vf9)
2026-05-19 09:44:28 -04:00
rmcrackanandCursor 1e3daa40dc Pin vite 6.4.2 for docs site to resolve Dependabot alert.
VitePress 1.6.4 requires vite ^5.4.14, which has no backport for
GHSA-4w7w-66w2-5vf9. An npm override keeps VitePress 1.x while
using a patched vite. Deploy workflow now watches package files.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-19 09:40:44 -04:00
rmcrackan 8f3f069d54 Merge pull request #1829 from rmcrackan/rmcrakan/13-4-2
incr ver
2026-05-19 08:57:00 -04:00
rmcrackan 88e3bbab89 Merge pull request #1828 from rmcrackan/rmcrackan/1827-cli-liberate-single
#1827 - CLI option to liberate single book
2026-05-19 08:56:49 -04:00
rmcrackan ca52ed4b7a incr ver 2026-05-19 08:55:57 -04:00
rmcrackan bb4a5298ae #1827 - CLI option to liberate single book 2026-05-19 08:51:21 -04:00
rmcrackan 9512e62deb Merge pull request #1824 from rmcrackan/rmcrackan/1819-ntfs-note
#1819 - Better NTFS invalid character note
2026-05-18 16:47:25 -04:00
rmcrackan 91174ed8dd Merge pull request #1826 from rmcrackan/rmcrackan/1823-full-disk
#1823 - Address full disk better
2026-05-18 10:09:33 -04:00
rmcrackan b9490966bb * Multi-step backup: PDF and later steps now run in the same awaited chain, so disk full on PDF stops the queue instead of counting as success.
* Detection: Quota / NAS “out of space” messages are treated like disk full, not generic retries.
2026-05-18 10:00:32 -04:00
rmcrackan d1114b410e sync/async bug fixes 2026-05-18 09:53:05 -04:00
rmcrackan 49e9b0c9ce oops, wrong branch. revert 2026-05-18 09:42:08 -04:00
rmcrackan 0b0d1afc48 Fix build failures on non-windows 2026-05-18 09:39:57 -04:00
rmcrackan 77f518f8d3 #1823 - Address full disk better. Fail clearly and early when possible, fail safely when space cannot be queried, and do not take down the UI or spam the user when the disk is full. 2026-05-18 09:20:51 -04:00
rmcrackan 9f1d4a383b Merge pull request #1825 from rmcrackan/rmcrackan/1822-crash-after-upgrade
#1822 - Fix the startup crash after auto-upgrade
2026-05-18 09:02:42 -04:00
rmcrackan 74b18c170a #1822 - Fix the startup crash after auto-upgrade by loading the library only after InteropFactory assembly resolution is ready, checking that Microsoft.EntityFrameworkCore.Sqlite.dll is present in the install folder, and showing a clear reinstall message instead of a generic "Unexpected error" when that still fails. 2026-05-18 08:54:40 -04:00
rmcrackan c85c11b27a #1819 - Better NTFS invalid character note 2026-05-18 08:21:51 -04:00
rmcrackan c8ac585ab3 Merge pull request #1817 from rmcrackan/rmcrackan/1811-threading
#1811 - fix UI threading
2026-05-15 12:10:39 -04:00
rmcrackan 55b45ae45d #1811 - fix UI threading 2026-05-15 12:02:23 -04:00
rmcrackan 776cd5215f Merge pull request #1816 from rmcrackan/rmcrackan/docker-yaml-context
Avoid default git context refs/pull/*/merge (breaks after PR merge or…
2026-05-15 11:45:03 -04:00
rmcrackan 1b8840c3b0 Avoid default git context refs/pull/*/merge (breaks after PR merge or on some re-runs) 2026-05-15 11:13:04 -04:00
rmcrackan 97537df933 Merge pull request #1815 from rmcrackan/rmcrackan/update-contribs
Add @CryptoJones to contributor list
2026-05-15 09:41:54 -04:00
rmcrackan eb4ab59737 Add @CryptoJones to contributor list 2026-05-15 09:41:33 -04:00
rmcrackan 55c2bf3be7 Merge pull request #1814 from CryptoJones/fix/tag-culture-test-de-ch-locale
Fix Tag_culture_test platform dependency on de-CH NumberGroupSeparator
2026-05-15 09:39:06 -04:00
AK ClarkandClaude Opus 4.7 ebce0c073b Fix Tag_culture_test platform dependency on de-CH NumberGroupSeparator
The de-CH row hard-coded U+2019 as the expected thousands separator,
which only matches certain .NET/ICU/CLDR data versions. Linux .NET hosts
return U+0027 (ASCII apostrophe) for the same culture, so every Linux CI
run failed this test regardless of the actual change under test.

Resolve U+2019 in DataRow expectations to the runtime culture's
NumberGroupSeparator before comparison so the test stays stable across
hosts while still verifying the engine respects culture-specific
formatting.

- Added DataRows for de-DE (period) and ja-JP (comma)
- Added Samplerate_template_uses_culture_NumberGroupSeparator as an
  explicit regression guard that asserts the engine uses whatever the
  runtime CultureInfo reports

Fixes #1813.

Verified locally: 584 tests pass, 0 failed (565 succeeded, 19 skipped
Windows-only).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 01:10:57 -05:00
rmcrackan 0499bbae7e Merge pull request #1803 from Jo-Be-Co/1762_filter
1762 add filter() to list properties
2026-05-14 11:29:26 -04:00
Jo-Be-Co 4be0361e42 fixing typos and naming of test method 2026-05-14 16:51:51 +02:00
Jo-Be-Co c2c7b04acd minor fixes and comment corrections 2026-05-14 02:12:25 +02:00
Jo-Be-Co f194032139 #1762 add filter() to list properties 2026-05-14 02:10:38 +02:00
Jo-Be-Co a21bb8174d #1762 introduce CommonFormatters.TryGetLiteral 2026-05-14 02:04:26 +02:00
rmcrackan 3fc5ab0f8d Merge pull request #1807 from rmcrackan/rmcrackan/acct-export-disable
Account 'export' should be disabled when the account has no keys/tokens
2026-05-12 12:52:34 -04:00
rmcrackan 591a6d1594 Account 'export' should be disabled when the account has no keys/tokens 2026-05-12 12:05:11 -04:00
rmcrackan c4ac900045 Merge pull request #1806 from rmcrackan/rmcrackan/1804-win-folder-picker-custom-paths
#1804 - Fix Windows folder picker crash on custom paths
2026-05-12 09:04:18 -04:00
rmcrackan 50fde66a4c #1804 - Fix Windows folder picker crash on custom paths. Normalize stored paths before opening the OS folder dialog (\\?\ / UNC handling, existence check) in shared FolderPickerInitialPath, use it from WinForms and Avalonia folder pickers, and retry once if the dialog still throws. Adds small FileManager tests. 2026-05-12 08:55:12 -04:00
rmcrackan 597c8f7b3d Merge pull request #1795 from Jo-Be-Co/1762_unique_and_count
#1762 add unique() and count() to list properties
2026-05-09 23:21:29 -04:00
Jo-Be-Co 4ffcbeb1db Fix typos 2026-05-10 00:37:02 +02:00
Jo-Be-Co 6996fb1b81 When formatting ContributorDto, retain the IFormatProvider even if the format is empty 2026-05-10 00:36:49 +02:00
Jo-Be-Co 7ef10b1e7d #1762 add unique() and count() to list properties 2026-05-09 21:15:24 +02:00
Jo-Be-Co 0a644695d8 #1762 extract comparison to separate reusable class 2026-05-09 00:59:35 +02:00
rmcrackan 86b50b45ef Merge pull request #1796 from rmcrackan/rmcrackan/1711-linux-safety
#1711 : Linux/Docker: the default in-progress download/decrypt folder…
2026-05-08 09:10:23 -04:00
rmcrackan 727c869ba9 #1711 : Linux/Docker: the default in-progress download/decrypt folder is now per-user (/tmp/Libation-<username>) and is created with 0700 permissions, fixing failures caused by leftover /tmp/Libation directories from previous root installs and hardening against another local user reading partial download artifacts. Auto-upgrade downloads now land in a randomly-named per-run temp directory. 2026-05-08 09:04:39 -04:00
Robert f330d8bed6 incr ver 2026-05-05 13:45:27 -04:00
rmcrackan 9aecd26aea Merge pull request #1791 from rmcrackan/rmcrackan/1732-bug-fixes
#1732 bug fixes
2026-05-05 13:41:32 -04:00
rmcrackan 0cc2ef773d * Default Scan library to on for new accounts from Upsert / Mkb79 import (matches GUI)
* CLI liberate: print short license-denial reasons to stderr
* GUI: message when stoplight can’t queue (e.g. absent from last scan)
2026-05-05 13:32:28 -04:00
Robert 78371e3522 incr ver 2026-05-05 09:41:26 -04:00
rmcrackan 24a896e61b Merge pull request #1790 from Mbucari/master
Update Avalonia to v12
2026-05-05 09:39:52 -04:00
MBucari e4daa5b8e8 Fix macos bundle build failure 2026-05-04 21:20:42 -06:00
MBucari 505c614210 Code Cleanup
Remove unused parameters
Remove unnecessary casts
Make fields readonly
Order modifiers
Format document
Sort usings
Remove unnecessary nullable directive
Apply namespace preferences (file-level)
2026-05-04 21:10:28 -06:00
Michael Bucari-Tovo df531de255 Update Avalonia to v12
Avalonia 12 uses compiled bindings by default. Converted all remaining reflection bindings into compiled bindings,

Fixed binding errors
2026-05-04 21:08:26 -06:00
rmcrackan 7b1dd64936 incr ver 2026-05-04 13:43:05 -04:00
rmcrackan c226e8ca38 Merge pull request #1789 from rmcrackan/rmcrackan/1732-feedback
Rmcrackan/1732 feedback
2026-05-04 13:42:01 -04:00
rmcrackan 673ff153b0 #1732 - new CLI list accounts option 2026-05-04 13:28:36 -04:00
rmcrackan 5b898dcd48 #1732 - fix: --help, -h, /?, /h, /help 2026-05-04 13:20:58 -04:00
rmcrackan b1df70f66c Merge pull request #1788 from rmcrackan/rmcrackan/1786-win-10
#1786 : win 10+ only
2026-05-04 11:06:02 -04:00
rmcrackan 220c916258 #1786 : win 10+ only 2026-05-04 11:05:32 -04:00
rmcrackan c3e0247940 Merge pull request #1787 from rmcrackan/rmcrackan/1783-chardonnay-x-filter
Bug fix #1783 : X to clear filter in Chardonnay
2026-05-04 10:12:01 -04:00
rmcrackan 0891fcf256 Bug fix #1783 : X to clear filter in Chardonnay 2026-05-04 10:02:18 -04:00
rmcrackan b259fdc9a5 Merge pull request #1785 from rmcrackan/rmcrackan/634-too-small
troubleshooting: if UI too small then AVALONIA_GLOBAL_SCALE_FACTOR
2026-05-04 09:35:56 -04:00
rmcrackan ecee08aaf7 troubleshooting: if UI too small then AVALONIA_GLOBAL_SCALE_FACTOR 2026-05-04 09:35:22 -04:00
rmcrackan b53a092327 Merge pull request #1784 from rmcrackan/rmcrackan/1199-docs
Add to linux troubleshooting, per solution in #1199
2026-05-04 09:07:21 -04:00
rmcrackan 0c838a483e Add to linux troubleshooting, per solution in #1199 2026-05-04 09:06:50 -04:00
rmcrackan d934511c32 incr ver 2026-05-01 10:11:51 -04:00
rmcrackan 8c88739644 Merge pull request #1747 from rmcrackan/rmcrackan/1732-cli-auth
add CLI auth options
2026-05-01 10:05:41 -04:00
rmcrackan 05e1de78da Merge pull request #1779 from rmcrackan/rmcrackan/1776-snap-docs
Make Linux Snap SQLite startup failures easier to understand
2026-05-01 10:01:45 -04:00
rmcrackan dd059a0ce9 #1776 - Make Linux Snap SQLite startup failures easier to understand and fix (stale LibationFiles in appsettings.json after a revision change), improve crash and log detail (inner exceptions + paths), and document that in the docs and FAQ. Tests lock in exception formatting behavior. 2026-05-01 10:01:03 -04:00
rmcrackan 4f401fe6c7 Merge pull request #1778 from rmcrackan/rmcrackan/1744-imgs
trying again to fix the intermittent cover image issue
2026-05-01 09:46:35 -04:00
rmcrackan 849f5f508e trying again to fix the intermittent cover image issue 2026-05-01 09:38:29 -04:00
rmcrackan ac2b5ef3e2 Merge pull request #1777 from rmcrackan/rmcrackan/1776-improve-errors
#1776. better messages to users. improve all exception display
2026-04-30 11:11:26 -04:00
rmcrackan 13bdebbe9d #1776. better messages to users. improve all exception display 2026-04-30 11:04:50 -04:00
rmcrackan 6445a758a2 Merge pull request #1772 from rmcrackan/dependabot/npm_and_yarn/postcss-8.5.12
Bump postcss from 8.5.6 to 8.5.12
2026-04-27 19:08:01 -04:00
dependabot[bot] f6b0765dbc Bump postcss from 8.5.6 to 8.5.12
Bumps [postcss](https://github.com/postcss/postcss) from 8.5.6 to 8.5.12.
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/postcss/postcss/compare/8.5.6...8.5.12)

---
updated-dependencies:
- dependency-name: postcss
  dependency-version: 8.5.12
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-27 23:04:47 +00:00
rmcrackan 95dfee130e Merge pull request #1771 from Mbucari/master
Re-add Category Name Column to database
2026-04-27 19:03:47 -04:00
Michael Bucari-Tovo b8616a6da0 Re-add Category Name Column to database
Category names were accidently removed during the last DB migration in d67692355f.

Re-add the Names column and modify CategoryImporter to upsert the names on update.
2026-04-27 14:45:13 -06:00
rmcrackan 0b975a168e Merge pull request #1769 from rmcrackan/rmcrackan/1744-folder-icons
#1744 Make Explorer folder icons reliable
2026-04-27 10:31:05 -04:00
rmcrackan f610ccdf58 #1744 Make Explorer folder icons reliable by running them after other post-download work, retrying briefly when the 300×300 cover or ICO write fails, and logging clear, actionable messages when it still cannot succeed. 2026-04-27 10:30:27 -04:00
rmcrackan f0c61ec7db typo 2026-04-23 11:20:32 -04:00
rmcrackan 14bd9d9deb Merge pull request #1759 from rmcrackan/rmcrackan/1694-mac-docs
Improve mac troubleshooting docs per discoveries in #1694
2026-04-23 11:13:42 -04:00
rmcrackan 01487690d4 Improve mac troubleshooting docs per discoveries in #1694 2026-04-23 11:13:17 -04:00
rmcrackan acfde519f5 Merge pull request #1758 from rmcrackan/rmcrackan/fix-naming-template
fix naming template markdown
2026-04-22 13:50:14 -04:00
rmcrackan 7fb6ea4701 fix {{ literal 2026-04-22 13:47:29 -04:00
rmcrackan db1566a32d This font is too clever with rendering things like <- as arrows. Let's just make this page monospace 2026-04-22 13:47:01 -04:00
rmcrackan ca48767cc1 syntax fixes 2026-04-22 10:45:57 -04:00
rmcrackan 310abe951a Merge pull request #1757 from rmcrackan/dependabot/github_actions/apple-actions/import-codesign-certs-7
Bump apple-actions/import-codesign-certs from 6 to 7
2026-04-21 10:24:34 -04:00
dependabot[bot] aed2aec38e Bump apple-actions/import-codesign-certs from 6 to 7
Bumps [apple-actions/import-codesign-certs](https://github.com/apple-actions/import-codesign-certs) from 6 to 7.
- [Release notes](https://github.com/apple-actions/import-codesign-certs/releases)
- [Commits](https://github.com/apple-actions/import-codesign-certs/compare/v6...v7)

---
updated-dependencies:
- dependency-name: apple-actions/import-codesign-certs
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-21 14:14:34 +00:00
rmcrackan 531d98a0d5 Merge pull request #1756 from rmcrackan/rmcrackan/fix-docs
fix vitepress/vue syntax
2026-04-21 08:56:00 -04:00
rmcrackan dd8bba959d fix vitepress/vue syntax 2026-04-21 08:54:53 -04:00
Robert 9d6f0f7700 incr ver 2026-04-20 22:01:31 -04:00
rmcrackan 274cbf37ca Merge pull request #1755 from Jo-Be-Co/Conditional-output-on-format-templates
#1754 Conditional output on format templates
2026-04-20 21:59:02 -04:00
Jo-Be-Co 2b25ced65b documentation for format-templates 2026-04-21 00:18:14 +02:00
Jo-Be-Co 417e654799 #1754 Conditional output on format templates 2026-04-20 23:15:54 +02:00
rmcrackan e9550055c6 Merge pull request #1750 from Jo-Be-Co/refactor-format-escapes
fixed quoting errors in format-strings
2026-04-20 16:46:43 -04:00
Jo-Be-Co fa64be7ad0 fixed typoo ;-) 2026-04-20 22:41:34 +02:00
Jo-Be-Co e3508b2998 rebased and small fixes 2026-04-20 22:06:40 +02:00
Jo-Be-Co 30809fb38d fixed quoting errors in format-strings 2026-04-20 21:38:45 +02:00
rmcrackan 5b89f29a4f Merge pull request #1735 from Jo-Be-Co/bifunctions
1714 conditional tag cmp working on two properties
2026-04-20 14:36:24 -04:00
Jo-Be-Co ea33d8933a test added with colons in tag comparison 2026-04-20 19:24:21 +02:00
Jo-Be-Co c1e9911ade Small fixes on auto checks 2026-04-20 18:43:33 +02:00
Jo-Be-Co 962a5055b2 Fixed PR comments 2026-04-20 18:07:17 +02:00
rmcrackan 3108bfa469 Merge pull request #1753 from rmcrackan/rmcrackan/1748-upgrader
In-app upgrades now wait for the real installer and treat failures as failures
2026-04-20 10:21:13 -04:00
rmcrackan ccc74cef56 #1748: In-app upgrades now wait for the real installer and treat failures as failures. 2026-04-20 10:20:29 -04:00
rmcrackan 1de778adef Merge pull request #1752 from rmcrackan/rmcrackan/1751-resizeable
#1751 - text should always be readable
2026-04-20 09:48:38 -04:00
rmcrackan 4a30acf0eb #1751 - text should always be readable. Allow for user-resizing when it's not the case. 2026-04-20 09:48:13 -04:00
rmcrackan 6d326ebabc #1732 add CLI auth options. Add to the CLI these features which are already available in the GUI: importing from @mkb79 's audible-cli , and the external browser login (aka: alternative login). Caveat: 2nd feature doesn't work for Brazil (gui or cli) 2026-04-18 15:29:57 -04:00
rmcrackan f2ef616203 Merge pull request #1745 from Jo-Be-Co/refactor-LocaleDto
Some optimizations after last update to AudibleApi
2026-04-17 17:53:07 -04:00
Jo-Be-Co 87e8c6a32a fixed pr remarks 2026-04-17 23:48:22 +02:00
rmcrackan 62dfc20255 Merge pull request #1746 from rmcrackan/rmcrackan/1744-images
#1744 - attempt to harded code for cover image/folder image
2026-04-17 16:11:21 -04:00
rmcrackan 9f255a3bc1 #1744 - attempt to harded code for cover image/folder image 2026-04-17 16:07:00 -04:00
Jo-Be-Co 6d7af0a8ae Some optimizations after last update to AudibleApi 2026-04-17 21:43:42 +02:00
Jo-Be-Co 650b9c7f5b added docs for cmp tag 2026-04-17 21:22:30 +02:00
Jo-Be-Co dc353aa7e5 Merge branch 'master' into bifunctions 2026-04-17 08:50:53 +02:00
Jo-Be-Co d5258b7e64 fixed merge collision 2026-04-17 08:46:52 +02:00
Jo-Be-Co 475f20b3cb unit tests added for new list operations 2026-04-17 08:35:43 +02:00
rmcrackan 6efc64b927 incr ver 2026-04-16 12:27:11 -04:00
rmcrackan d2cc9ff26f Merge pull request #1743 from rmcrackan/rmcrackan/corrupt-search
Attempt to recover from corrupt search engine
2026-04-15 13:32:14 -04:00
rmcrackan cfe4770387 Attempt to recover from corrupt search engine 2026-04-15 13:24:26 -04:00
rmcrackan 33967adb15 Merge pull request #1742 from rmcrackan/rmcrackan/harden-webview
harden webview for linux
2026-04-15 10:22:39 -04:00
rmcrackan 9ef8dca4d5 Document Linux runtime dependency 2026-04-15 09:58:36 -04:00
rmcrackan af1029f4b5 Honor "don't use WebView" for this path 2026-04-15 09:50:18 -04:00
rmcrackan 63e7f0f44e Automatic fallback when WebKit is missing. If embedded WebView cannot load, route the same “add account” flow to non-WebView login, so Arch minimal installs work without WebKit. 2026-04-15 09:45:35 -04:00
rmcrackan 65623e8e81 Catch WebKit load failures on account login. Wrap the code path that opens NativeWebDialog / WebView for Audible login in a try/catch for DllNotFoundException (and related load failures). On failure, show a short dialog: install WebKit2GTK and do not crash the app. 2026-04-15 09:41:47 -04:00
rmcrackan a5912efa0c upgrade nuget 2026-04-15 08:10:09 -04:00
rmcrackan dba3e6ca8e Merge pull request #1725 from Jo-Be-Co/language_and_region
Extend <language> and <locale> tags
2026-04-15 08:00:49 -04:00
Jo-Be-Co a4bc39ee6b switched from RegionInfo to AudibleApi.Locale 2026-04-15 00:45:55 +02:00
rmcrackan 675fecec67 Merge pull request #1737 from rmcrackan/dependabot/github_actions/actions/upload-pages-artifact-5
Bump actions/upload-pages-artifact from 4 to 5
2026-04-14 10:22:55 -04:00
dependabot[bot] be1eac5692 Bump actions/upload-pages-artifact from 4 to 5
Bumps [actions/upload-pages-artifact](https://github.com/actions/upload-pages-artifact) from 4 to 5.
- [Release notes](https://github.com/actions/upload-pages-artifact/releases)
- [Commits](https://github.com/actions/upload-pages-artifact/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/upload-pages-artifact
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-14 14:14:02 +00:00
Jo-Be-Co 8bad7d90c3 List os and ui tag in documentation 2026-04-14 03:04:26 +02:00
Jo-Be-Co c72e5a3568 fixed matching of first property 2026-04-14 02:48:03 +02:00
rmcrackan e145e46579 Merge pull request #1731 from Jo-Be-Co/1729_docker_resilient-creation-of-db-link
1729 docker resilient creation of db link
2026-04-13 19:38:44 -04:00
Jo-Be-Co 5fd8ac481b review fixes 2026-04-14 01:14:45 +02:00
Jo-Be-Co b6c7612ec4 Merge remote-tracking branch 'upstream/master' into language_and_region 2026-04-14 00:55:42 +02:00
Jo-Be-Co 3456eb6c35 Merge remote-tracking branch 'upstream/master' into 1729_docker_resilient-creation-of-db-link
# Conflicts:
#	Docker/liberate.sh
2026-04-14 00:51:09 +02:00
Jo-Be-Co c1b8cc894a add mathematical symbols 2026-04-14 00:41:22 +02:00
Jo-Be-Co 56c15d3108 add checks on lists 2026-04-14 00:38:41 +02:00
Jo-Be-Co 810ea90770 introduce cmp tag as check with two operands 2026-04-14 00:30:34 +02:00
rmcrackan b90cc67b09 Merge pull request #1734 from rmcrackan/dependabot/github_actions/softprops/action-gh-release-3
Bump softprops/action-gh-release from 2 to 3
2026-04-13 11:34:55 -04:00
dependabot[bot] 550a99ac90 Bump softprops/action-gh-release from 2 to 3
Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 2 to 3.
- [Release notes](https://github.com/softprops/action-gh-release/releases)
- [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)
- [Commits](https://github.com/softprops/action-gh-release/compare/v2...v3)

---
updated-dependencies:
- dependency-name: softprops/action-gh-release
  dependency-version: '3'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-13 15:30:12 +00:00
rmcrackan 9ed89eca9e Merge pull request #1733 from rmcrackan/rmcrackan/1729-docker-tweak
#1729 minor docker tweak
2026-04-13 08:51:28 -04:00
rmcrackan 197d645e10 #1729 minor docker tweak 2026-04-13 08:51:07 -04:00
rmcrackan bdfc99f209 Merge pull request #1730 from rmcrackan/dependabot/github_actions/actions/github-script-9
Bump actions/github-script from 8 to 9
2026-04-13 08:37:44 -04:00
Jo-Be-Co a010da5251 #1714 Convert the evaluation of the 'is' tag into two-parameter logic 2026-04-13 01:39:16 +02:00
Jo-Be-Co 4c212e752f some refinements 2026-04-11 22:19:31 +02:00
Jo-Be-Co e8d2ac5c62 #1729 added resilience when creating the link to the database file 2026-04-11 21:22:54 +02:00
Jo-Be-Co 6c552623d9 Adding documentation for region and language tags 2026-04-11 01:59:49 +02:00
dependabot[bot] 5a0d62687c Bump actions/github-script from 8 to 9
Bumps [actions/github-script](https://github.com/actions/github-script) from 8 to 9.
- [Release notes](https://github.com/actions/github-script/releases)
- [Commits](https://github.com/actions/github-script/compare/v8...v9)

---
updated-dependencies:
- dependency-name: actions/github-script
  dependency-version: '9'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-10 14:13:05 +00:00
Jo-Be-Co f4e61d0445 hardend an commented unit tests for region output 2026-04-10 11:44:28 +02:00
Jo-Be-Co 54765fc181 Fixed cross-platform problems on region tests 2026-04-10 10:14:19 +02:00
Jo-Be-Co d292cb0472 Merge remote-tracking branch 'origin/language_and_region' into language_and_region
# Conflicts:
#	Source/_Tests/LibationFileManager.Tests/TemplatesTests.cs
2026-04-10 09:47:00 +02:00
Jo-Be-Co b4f48cb54c Extend <language> and <locale> tags to allow different outputs like ISO-codes or names in different languages 2026-04-10 09:43:11 +02:00
rmcrackan e7d08d30b0 Merge pull request #1727 from rmcrackan/rmcrackan/log-init-db
Log initial db state, esp to capture books in trash
2026-04-09 11:05:36 -04:00
rmcrackan 26946e8a87 Log initial db state, esp to capture books in trash 2026-04-09 10:57:41 -04:00
rmcrackan ecf1cf4404 Merge pull request #1726 from rmcrackan/rmcrackan/vulnerable-nuget
copilot fix to vulnerable nuget pkg
2026-04-09 10:03:54 -04:00
rmcrackan 8213521404 copilot fix to vulnerable nuget pkg 2026-04-09 09:57:41 -04:00
Jo-Be-Co 0ef73464b8 Extend <language> and <locale> tags to allow different outputs like ISO-codes or names in different languages 2026-04-09 02:33:05 +02:00
rmcrackan 3030b748d7 Merge pull request #1723 from rmcrackan/rmcrackan/sqlite-readonly
Better handling of sqlite readonly
2026-04-08 17:48:55 -04:00
rmcrackan ccef50d681 move new check into datalayer 2026-04-08 17:43:21 -04:00
rmcrackan 78e6d7c5c1 Better handling of sqlite readonly 2026-04-08 17:33:07 -04:00
rmcrackan 846b93c97c Merge pull request #1720 from rmcrackan/rmcrackan/1719-corrupt-search-engine
#1719 - add defensive code to recover from a corrupt search engine
2026-04-07 15:05:45 -04:00
rmcrackan b0e79faacf #1719 - add defensive code to recover from a corrupt search engine 2026-04-07 15:00:18 -04:00
rmcrackan 3fece6aa44 Merge pull request #1718 from rmcrackan/rmcrackan/1716
#1716 - fix NAS bug
2026-04-05 15:47:41 -04:00
rmcrackan a7c7bd9925 #1716 - fix NAS bug 2026-04-05 15:41:58 -04:00
rmcrackan 3373b0979a Merge pull request #1713 from Jo-Be-Co/first-tag
Add `<first tag[...]>`
2026-04-03 09:19:50 -04:00
Jo-Be-Co 3e3da2298e Add <first tag[...]> 2026-04-03 03:48:09 +02:00
rmcrackan a9cb560f95 Merge pull request #1709 from rmcrackan/rmcrackan/plus-warning
Give better feedback to user with 'plus' license denied
2026-03-31 17:42:51 -04:00
rmcrackan e4282f014e remove close issues search link 2026-03-31 17:38:32 -04:00
rmcrackan b694e319f7 Give better feedback to user when they're getting persistent 'license denied' errors which are likely caused by too many Plus downloads 2026-03-31 17:31:40 -04:00
rmcrackan 67e3e41b15 Merge pull request #1708 from rmcrackan/rmcrackan/1704-mkb79import
fix bug with importing mkb79 auth with website_cookies: null vs empty
2026-03-31 13:22:33 -04:00
rmcrackan ad2101ab8c fix bug with importing mkb79 auth with website_cookies: null vs empty 2026-03-30 15:10:55 -04:00
rmcrackan d7ea8eb8f1 Merge pull request #1707 from rmcrackan/rmcrackan/webview-err-msg
better error messages when webview is the problem
2026-03-30 14:22:51 -04:00
rmcrackan 5c1153e187 better error messages when webview is the problem. shouldn't appear like a scan error 2026-03-30 14:22:09 -04:00
rmcrackan e929ab3062 Merge pull request #1706 from rmcrackan/dependabot/github_actions/actions/configure-pages-6
Bump actions/configure-pages from 5 to 6
2026-03-30 11:43:22 -04:00
dependabot[bot] d64fd564ab Bump actions/configure-pages from 5 to 6
Bumps [actions/configure-pages](https://github.com/actions/configure-pages) from 5 to 6.
- [Release notes](https://github.com/actions/configure-pages/releases)
- [Commits](https://github.com/actions/configure-pages/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/configure-pages
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-30 15:38:21 +00:00
rmcrackan 340b0a0d29 Merge pull request #1705 from rmcrackan/rmcrackan/fix-template-esc
fix escaped html tags
2026-03-30 11:27:51 -04:00
rmcrackan 1f217b3966 fix escaped html tags 2026-03-30 11:26:53 -04:00
rmcrackan accb43456b Merge pull request #1700 from rmcrackan/rmcrackan/fix-templates-docs
fix tags in templates doc
2026-03-27 16:22:57 -04:00
rmcrackan b3a781de5e fix tags in templates doc 2026-03-27 16:21:32 -04:00
rmcrackan 34613f7e97 Merge pull request #1699 from rmcrackan/rmcrackan-patch-1
Update naming-templates.md
2026-03-27 16:02:38 -04:00
rmcrackan 1def16a157 Update naming-templates.md 2026-03-27 16:02:27 -04:00
rmcrackan 33a209df3c Merge pull request #1690 from Jo-Be-Co/improve-formatting-tags
Improve formatting tags
2026-03-27 15:56:51 -04:00
Jo-Be-Co 2daf2da30a Test fixes 2026-03-27 09:11:00 +01:00
Jo-Be-Co dd2bc7c461 Documentation for TimeSpan. 2026-03-27 01:14:42 +01:00
Jo-Be-Co 1d1936734b Test hardening.
Ensure tests check error and warning output to confirm assertions are correctly formulated.
2026-03-27 00:06:17 +01:00
rmcrackan e7f6e71d3b Merge pull request #1698 from rmcrackan/1692-mac-rt-clk-attempt2
#1692 : 2nd attempt to fix mac rt-clk issue
2026-03-26 16:23:51 -04:00
rmcrackan 0da8af3b8f incr ver 2026-03-26 16:17:51 -04:00
rmcrackan f159bcdbb9 2nd attempt 2026-03-26 15:26:06 -04:00
rmcrackan fc85aa457c Merge pull request #1695 from rmcrackan/dependabot/github_actions/actions/checkout-6
Bump actions/checkout from 4 to 6
2026-03-26 10:40:55 -04:00
rmcrackan 687a51b7bc Merge pull request #1696 from rmcrackan/dependabot/github_actions/actions/deploy-pages-5
Bump actions/deploy-pages from 4 to 5
2026-03-26 10:40:25 -04:00
dependabot[bot] 477d0088e2 Bump actions/deploy-pages from 4 to 5
Bumps [actions/deploy-pages](https://github.com/actions/deploy-pages) from 4 to 5.
- [Release notes](https://github.com/actions/deploy-pages/releases)
- [Commits](https://github.com/actions/deploy-pages/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/deploy-pages
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-26 14:12:37 +00:00
dependabot[bot] 38138d8272 Bump actions/checkout from 4 to 6
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-26 14:12:33 +00:00
Jo-Be-Co fc92c633e1 No made up format for minutes as .NET already knows how to format them.
User documentation needs to follow.
2026-03-26 03:12:24 +01:00
Jo-Be-Co 3c71cb10b2 some minor fixes 2026-03-26 03:10:43 +01:00
rmcrackan 65d8adc018 Merge pull request #1693 from rmcrackan/rmcrackan/close-stale
#1532 -- issue cleanup. Close stale tickets. Thanks @HenraL !
2026-03-25 11:13:30 -04:00
rmcrackan 9e739e48d7 #1532 -- issue cleanup. Close stale tickets. Thanks @HenraL ! 2026-03-25 10:59:12 -04:00
Jo-Be-Co 6b26280aa8 Get formats for properties in given form to the formatters by no unescaping them in advance. 2026-03-25 14:23:03 +01:00
Jo-Be-Co 14d8bb2205 As stated in the "Naming Templates" documentation, support custom formatters on numbers.
Only trim spaces on tags where they are disruptive.
2026-03-25 02:34:32 +01:00
rmcrackan 0960edeafb Add contributor: Jo-Be-Co 2026-03-24 15:16:17 -04:00
Jo-Be-Co 6d2b0b952d - Inspect exception on regexp timeout
- special tests for checks with whitespace
- Escaping allows whitespace at the edges
2026-03-24 00:18:40 +01:00
Jo-Be-Co fb277cff81 Faulty regex patterns will throw InvalidOperationException during evaluation. 2026-03-23 15:29:32 +01:00
Jo-Be-Co dbd5af8ab0 QS second part:
Made Evaluate() more resilient.
Added tests to CommonFormatters.
2026-03-22 22:22:02 +01:00
Jo-Be-Co 02b9b4fa1c QS updates:
- fixed documentation
- regexp-checks running with timeout and culture-invariant matching
- changed check-building in ConditionalTagCollection to use NonNull parameters. So no warnings occure.
- add tests for <!is ...> and escaped chars
2026-03-22 19:18:55 +01:00
Jo-Be-Co 7ecd571364 Corrections to documentation and comments. 2026-03-22 13:55:28 +01:00
Jo-Be-Co 32f3e6a886 Introduces the slice() format directive 2026-03-22 13:55:27 +01:00
Jo-Be-Co e477c29890 New tags <minutes>, <tag> and <if abridged->...<-if abridged> 2026-03-22 13:55:27 +01:00
Jo-Be-Co a8621699c1 Add numerical checks for conditional tag.
- numbers are compared with their value
- strings are compared by checking the length
- Collections are evaluated on cheking their size
2026-03-22 13:55:27 +01:00
Jo-Be-Co cd9a070784 Allow two step formatting to get checkable values and not only single stringa
Introduce <is-> Tag. Like <has-> but with additional check on content.

Retrieve objects instead of string for conditions

Pass undefined formats as null instead of empty strings
2026-03-22 13:55:26 +01:00
Jo-Be-Co d8ce7cc9b0 Formats are now escapable and the evaluation of HasValue has been transformed into a configuration parameter. 2026-03-22 13:55:26 +01:00
Jo-Be-Co 1d6d4ff9ac GetTagExpression uses Dictionary for capture names from Regexes 2026-03-22 13:55:26 +01:00
Jo-Be-Co db3a810f47 Regular Expressions with capture names on coments 2026-03-22 13:55:26 +01:00
Jo-Be-Co 508ea1032d Tests are using empty values for various fields 2026-03-22 13:55:25 +01:00
Jo-Be-Co 10fc5837cb Allow sorting in reverse order by specifying the sort key with lowercase 2026-03-22 13:55:25 +01:00
Jo-Be-Co 812e0c3b60 Format details on fields specified in format. Introduce by colon.
Use dictionaries for field access and sorting.

Added sorting to series lists.
2026-03-22 13:55:25 +01:00
Jo-Be-Co d161bdfaeb Introduce culture parameter for formatting. 2026-03-22 13:55:24 +01:00
Jo-Be-Co a6aa14c7f8 Collect formatters into CommonFormatters 2026-03-22 13:55:24 +01:00
Jo-Be-Co 7dd55a2545 Refactorings 2026-03-22 13:55:24 +01:00
rmcrackan 1081dfe8df Merge pull request #1689 from rmcrackan/rmcrackan/mac-yaml
mac yaml. print stdout, stderr
2026-03-18 14:53:27 -04:00
rmcrackan 3f716cd1ac - **Fix:** When xcrun notarytool submit failed (e.g. Apple TOS / "sign agreement" required), the job failed immediately and the real error never appeared in the workflow log.
- **Change:** Capture notarytool stdout+stderr with `|| true` so the script always runs `echo "$RESPONSE"`, then fail the step explicitly if no submission id is found. The job still fails on errors, but the full notarytool output (including stderr) is now visible in the Actions log.
- **Result:** Failures like "you must accept the agreement" show up in the run so you don’t have to reproduce them locally to see the message.
2026-03-18 14:49:02 -04:00
Robert 338715d52a incr ver 2026-03-17 23:07:30 -04:00
rmcrackan d275ad034b Merge pull request #1688 from rmcrackan/rmcrackan/macos-build
attempt to fix Bundle_MacOS
2026-03-17 23:04:23 -04:00
rmcrackan b5ecff7e27 attempt to fix Bundle_MacOS 2026-03-17 23:03:43 -04:00
Robert 3144506ad5 incr ver 2026-03-17 22:30:05 -04:00
rmcrackan 99629c3c25 Merge pull request #1678 from rmcrackan/rmcrackan/screenreader-msg
Add info in walkthrough for screen-reader users
2026-03-17 22:19:07 -04:00
rmcrackan 3fdb8ef15d Merge pull request #1679 from rmcrackan/rmcrackan/1677-linux-crash
Rmcrackan/1677 linux crash
2026-03-17 22:18:54 -04:00
rmcrackan a43a700e37 Merge pull request #1686 from rmcrackan/rmcrackan/empty-cookies
don't set cookies without values. Attempting to solve #1682
2026-03-17 22:18:45 -04:00
rmcrackan 80823bf15c don't set cookies without values. Attempting to solve #1682 2026-03-17 16:59:11 -04:00
rmcrackan 0a576069df clean up essential file validation 2026-03-12 15:27:04 -04:00
rmcrackan 0b0f5184d2 Validate essential files early 2026-03-12 14:55:14 -04:00
rmcrackan 24d825607d * Reads relative paths from appsettings and resolves them to absolute once.
* Writes only absolute paths for LibationFiles, so future reads and all callers see a single, consistent path.
2026-03-12 13:57:39 -04:00
rmcrackan 14e4ea4592 Resolve to an absolute path when reading 2026-03-12 13:53:27 -04:00
rmcrackan 56720124b8 Add info in walkthrough for screen-reader users 2026-03-12 11:43:06 -04:00
Robert 20c7d72181 incr ver 2026-03-12 09:30:22 -04:00
rmcrackan 0d00cf2b10 Merge pull request #1676 from rmcrackan/rmcrackan/1625-mac-key-bindings
Bug fix #1625 -- fix mac key bindings
2026-03-12 09:23:16 -04:00
rmcrackan a79da66b0e Bug fix #1625 -- fix mac key bindings 2026-03-12 09:16:41 -04:00
rmcrackan fdc56e9ad6 Merge pull request #1673 from rmcrackan/rmcrackan/fix-naming-template-links
Fix naming template links
2026-03-11 13:54:23 -04:00
rmcrackan ddef3b649b Fix naming template links 2026-03-11 13:45:59 -04:00
rmcrackan 01c2a3b1c3 Merge pull request #1672 from rmcrackan/rmcrackan/linux-snap-no-webview
WebView breaks catastrophically under Linux Snap
2026-03-11 13:27:34 -04:00
rmcrackan 4eec61a659 another build fix attempt 2026-03-11 13:23:21 -04:00
rmcrackan c983513f45 attempt to fix build failures 2026-03-11 13:20:44 -04:00
rmcrackan 0172c7b8eb add 'linux' to wording 2026-03-11 13:07:10 -04:00
rmcrackan 5cf710756f Bug fix #1664 - WebView breaks catastrophically under Linux Snap -- segfault with no logged errors 2026-03-11 13:00:19 -04:00
rmcrackan 760b0dcb6b Merge pull request #1670 from rmcrackan/rmcrackan/access1668-1
First first 2 items in #1668 -- accessibility bugs
2026-03-10 15:53:44 -04:00
rmcrackan 6c602286c0 First first 2 items in #1668 -- accessibility bugs 2026-03-10 15:51:25 -04:00
rmcrackan 8e69191bbf Merge branch 'master' of https://github.com/rmcrackan/Libation 2026-03-07 16:21:11 -05:00
rmcrackan 58095f291b When displaying upgrade notes, exclude <!-- NO-APP --> blocks 2026-03-07 16:21:04 -05:00
rmcrackan 50319defa9 Merge pull request #1666 from rmcrackan/rmcrackan-patch-2
Update command-line-interface.md
2026-03-07 15:29:26 -05:00
rmcrackan fd35b6dd85 Update command-line-interface.md 2026-03-07 15:29:10 -05:00
rmcrackan 2da2d1c29e Merge pull request #1665 from rmcrackan/rmcrackan-cli-details-block
Update command-line-interface.md
2026-03-07 15:27:26 -05:00
rmcrackan 64c5807daa Update command-line-interface.md 2026-03-07 15:27:09 -05:00
rmcrackan 1e8358eeeb Merge pull request #1663 from cvigano/add-replacement-char-documentation
Add documentation on how to customize replacement characters on CLI
2026-03-07 15:22:34 -05:00
Christoph Vigano 2868039772 Add documentation on how to customize replacement characters on CLI 2026-03-07 13:55:34 +01:00
rmcrackan 45af5aa913 Merge pull request #1662 from rmcrackan/dependabot/github_actions/docker/build-push-action-7
Bump docker/build-push-action from 6 to 7
2026-03-06 09:54:49 -05:00
rmcrackan 487fcb007c Merge pull request #1661 from rmcrackan/dependabot/github_actions/docker/metadata-action-6
Bump docker/metadata-action from 5 to 6
2026-03-06 09:54:19 -05:00
dependabot[bot] 76d4a44040 Bump docker/build-push-action from 6 to 7
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6 to 7.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v6...v7)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-06 14:13:14 +00:00
dependabot[bot] 07d9fff2b3 Bump docker/metadata-action from 5 to 6
Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 5 to 6.
- [Release notes](https://github.com/docker/metadata-action/releases)
- [Commits](https://github.com/docker/metadata-action/compare/v5...v6)

---
updated-dependencies:
- dependency-name: docker/metadata-action
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-06 14:13:10 +00:00
rmcrackan bf1e90c33c incr ver 2026-03-05 12:11:03 -05:00
rmcrackan c30a79d97b Fix release workflow YAML: quote body to avoid < parse error 2026-03-05 12:08:03 -05:00
Robert 737121963f incr ver 2026-03-05 11:54:07 -05:00
rmcrackan 6b319fe1a7 Merge pull request #1658 from rmcrackan/rmcrackan/bugfix-save-templates
Bug fix #1657 - error in saving templates
2026-03-05 11:47:23 -05:00
rmcrackan 70ef1c52a4 Bug fix #1657 - error in saving templates 2026-03-05 11:46:35 -05:00
rmcrackan bdf5f2faea Merge pull request #1656 from rmcrackan/rmcrackan/widget-edits
#1652 - widget eidts
2026-03-05 10:16:57 -05:00
rmcrackan 5ff3dc7581 #1652 - widget eidts 2026-03-05 10:16:25 -05:00
rmcrackan 41fcef207b Merge pull request #1655 from rmcrackan/rmcrackan/widget-styling
#1652 - edit widget styling
2026-03-05 10:08:02 -05:00
rmcrackan 4edc77aa00 #1652 - edit widget styling 2026-03-05 10:07:31 -05:00
rmcrackan 6d05391151 Merge pull request #1654 from rmcrackan/rmcrackan/vitepress-fix
#1652: Fix vitepress publish
2026-03-05 09:49:16 -05:00
rmcrackan f9e2af6916 Fix vitepress publish 2026-03-05 09:48:57 -05:00
rmcrackan 75e9a7db1f Merge pull request #1653 from rmcrackan/rmcrackan/dl-suggester
#1652: add a homepage widget: download version suggester
2026-03-05 09:41:02 -05:00
rmcrackan ee92988125 #1652: add a homepage widget: download version suggester 2026-03-05 09:35:53 -05:00
rmcrackan c005af2457 Merge pull request #1651 from rmcrackan/dependabot/github_actions/docker/setup-buildx-action-4
Bump docker/setup-buildx-action from 3 to 4
2026-03-05 09:25:24 -05:00
dependabot[bot] 89ae5709a9 Bump docker/setup-buildx-action from 3 to 4
Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 3 to 4.
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](https://github.com/docker/setup-buildx-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: docker/setup-buildx-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-05 14:13:42 +00:00
rmcrackan 9c9f1c67c8 Merge pull request #1650 from rmcrackan/rmcrackan/autoscan-default-false
AutoScan defaultValue: false
2026-03-04 15:12:55 -05:00
rmcrackan d637068f64 AutoScan defaultValue: false 2026-03-04 15:12:25 -05:00
rmcrackan 490d292c18 Merge pull request #1648 from rmcrackan/dependabot/github_actions/docker/setup-qemu-action-4
Bump docker/setup-qemu-action from 3 to 4
2026-03-04 09:39:09 -05:00
rmcrackan 8417b121a4 Merge pull request #1647 from rmcrackan/dependabot/github_actions/docker/login-action-4
Bump docker/login-action from 3 to 4
2026-03-04 09:38:45 -05:00
dependabot[bot] 72edd1c896 Bump docker/setup-qemu-action from 3 to 4
Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 3 to 4.
- [Release notes](https://github.com/docker/setup-qemu-action/releases)
- [Commits](https://github.com/docker/setup-qemu-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: docker/setup-qemu-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-04 14:14:26 +00:00
dependabot[bot] 4e8306470c Bump docker/login-action from 3 to 4
Bumps [docker/login-action](https://github.com/docker/login-action) from 3 to 4.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-04 14:14:23 +00:00
rmcrackan bdbeeb8935 Merge pull request #1646 from rmcrackan/rmcrackan/cli-doc-progressbar
document CLI progress bar option
2026-03-03 17:19:47 -05:00
rmcrackan 1b12dd04ff document CLI progress bar option 2026-03-03 17:18:38 -05:00
rmcrackan 589b806aff Merge pull request #1645 from rmcrackan/rmcrackan/cli-docs
Break out CLI into its own page
2026-03-03 16:45:28 -05:00
rmcrackan c248bc0a04 Break out CLI into its own page 2026-03-03 16:44:56 -05:00
Robert db4ef4b321 incr ver 2026-03-03 15:44:12 -05:00
rmcrackan ca7d3feaf9 Merge pull request #1642 from rmcrackan/rmcrackan/improved-upgrade-check
Upgrade checks to include: yes, no, don't know
2026-03-02 08:47:55 -05:00
rmcrackan 2b0b1ac798 comment 2026-03-02 08:47:28 -05:00
rmcrackan 41e0aa0dfb Upgrade checks to include: yes, no, don't know 2026-03-02 08:44:18 -05:00
rmcrackan f3eb4d9f87 Merge pull request #1641 from rmcrackan/rmcrackan-linux-deb-version
Update .releaseindex.json. Add Linux DEB
2026-03-02 08:41:14 -05:00
rmcrackan ae157a1506 Update .releaseindex.json 2026-03-02 08:40:55 -05:00
rmcrackan a7654745b6 Merge pull request #1640 from rmcrackan/rmcrackan/lucene-exp-backoff
Lucene search engine retries to use exponential backoff
2026-03-02 08:05:21 -05:00
rmcrackan 8dad104121 fix file encoding 2026-03-02 08:04:48 -05:00
rmcrackan 5bf1438e00 exp bak comments 2026-03-02 08:04:04 -05:00
rmcrackan da3d057372 Lucene search engine retries to use exponential backoff 2026-03-02 07:59:45 -05:00
Robert 9fec47e8ab incr ver 2026-03-01 10:07:44 -05:00
rmcrackan a218ed5e66 update AudibleApi 2026-02-28 17:03:51 -05:00
rmcrackan 4f28268785 Merge pull request #1638 from rmcrackan/rmcrackan/lucene-corrupt
Bug fix #1628 , #1636 : Address lucene search engine corruption
2026-02-28 16:29:06 -05:00
rmcrackan e3e55a30e1 Bug fix #1628 , #1636 : Address lucene search engine corruption 2026-02-28 16:28:33 -05:00
rmcrackan b157d760ec Merge pull request #1634 from rmcrackan/dependabot/npm_and_yarn/rollup-4.59.0
Bump rollup from 4.53.4 to 4.59.0
2026-02-27 09:55:55 -05:00
dependabot[bot] 60c532a3bc Bump rollup from 4.53.4 to 4.59.0
Bumps [rollup](https://github.com/rollup/rollup) from 4.53.4 to 4.59.0.
- [Release notes](https://github.com/rollup/rollup/releases)
- [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rollup/rollup/compare/v4.53.4...v4.59.0)

---
updated-dependencies:
- dependency-name: rollup
  dependency-version: 4.59.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-27 14:54:46 +00:00
rmcrackan 2a348df4ac Merge pull request #1633 from rmcrackan/dependabot/github_actions/actions/upload-artifact-7
Bump actions/upload-artifact from 6 to 7
2026-02-27 09:54:24 -05:00
rmcrackan bd881d4dc4 Merge pull request #1632 from rmcrackan/dependabot/github_actions/actions/download-artifact-8
Bump actions/download-artifact from 7 to 8
2026-02-27 09:53:47 -05:00
dependabot[bot] a6a9b33d01 Bump actions/upload-artifact from 6 to 7
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 6 to 7.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-27 14:13:38 +00:00
dependabot[bot] a77fe73153 Bump actions/download-artifact from 7 to 8
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 7 to 8.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v7...v8)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: '8'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-27 14:13:29 +00:00
rmcrackan 8d77787df7 Merge pull request #1622 from rmcrackan/rmcrackan-lucene-attrib
Update lucene.md
2026-02-22 09:03:30 -05:00
rmcrackan 44fe5b95f1 Update lucene.md 2026-02-22 09:03:03 -05:00
rmcrackan b8d7a956cd Merge pull request #1615 from rmcrackan/rmcrackan-lucene-4
Update searching-and-filtering.md
2026-02-18 09:06:27 -05:00
rmcrackan 002bdde444 Update searching-and-filtering.md
Attempting to force update for docs sidebar
2026-02-18 09:06:14 -05:00
rmcrackan 642eeecc0a Merge pull request #1614 from rmcrackan/rmcrackan-lucene-docs-3
Update config.js
2026-02-18 09:02:53 -05:00
rmcrackan 3343ef263c Update config.js 2026-02-18 09:02:33 -05:00
rmcrackan 6cf51c63c6 Merge pull request #1613 from rmcrackan/rmcrackan-patch-1
Update index.md
2026-02-18 08:58:09 -05:00
rmcrackan c34342ecb5 Update index.md 2026-02-18 08:57:56 -05:00
rmcrackan 53e5b635a3 Merge pull request #1612 from rmcrackan/rmcrackan-lucene-docs
Update searching-and-filtering.md
2026-02-18 08:54:41 -05:00
rmcrackan e6b12914a4 Update searching-and-filtering.md 2026-02-18 08:54:09 -05:00
rmcrackan 28327efd7b Create lucene.md 2026-02-18 08:52:38 -05:00
rmcrackan f17af04908 Merge pull request #1601 from Mbucari/master
Enable project-wide nullable reference types
2026-02-09 17:30:06 -05:00
Michael Bucari-Tovo 3ab1edc076 Code Cleanup
Make fields readonly
Remove unnecessary casts
Format document
Remove unnecessary usings
Sort usings
Use file-level namespaces
Order modifiers
2026-02-05 12:48:44 -07:00
Michael Bucari-Tovo d67692355f Enable project-wide nullable reference types
Added DB migration for nullable types.
2026-02-05 12:43:05 -07:00
rmcrackan f15e073204 Merge pull request #1589 from rmcrackan/rmcrackan-master-1
Update config.js
2026-02-03 10:07:39 -05:00
rmcrackan f00951d615 Update config.js
"Edit this page" went to 'main' instead of 'master'
2026-02-03 10:07:17 -05:00
Robert c7e844a54c incr ver 2026-02-03 09:38:30 -05:00
rmcrackan 178cc82d65 Merge pull request #1587 from Mbucari/master
Documentation and bug fixes
2026-02-03 09:05:06 -05:00
Michael Bucari-Tovo 054f7437d1 Fix importer NRE 2026-02-02 16:02:44 -07:00
Mbucari 99051b6975 Merge branch 'rmcrackan:master' into master 2026-01-31 23:52:05 -07:00
Robert eed7f1811b incr ver 2026-01-31 23:33:29 -05:00
rmcrackan 33cd6b8639 Merge pull request #1585 from thoughtbox/patch-2
Fix typos
2026-01-31 23:31:16 -05:00
rmcrackan 06014f467e Merge pull request #1581 from scagood/patch-1
Remove progress bar in non interactive mode (#1481)
2026-01-31 23:29:04 -05:00
Tor Houghton b2eef18217 Fix typos
buit-in -> built-in
broswer -> browser
2026-01-31 22:19:53 +01:00
Robert 443d1f64ca incr ver 2026-01-31 12:36:46 -05:00
Robert c43e88d269 verbose null checking to debug #1578 2026-01-31 12:36:29 -05:00
Michael Bucari-Tovo dc1919f411 Update AAXClean to 3.0.2 and fix deprecation warnings 2026-01-30 14:46:11 -07:00
Mbucari fdfae2f806 Merge branch 'rmcrackan:master' into master 2026-01-30 14:42:13 -07:00
Sebastian Good 5c56e1d39b Correct small spelling mistake 2026-01-30 16:12:48 +00:00
Sebastian Good b39e2c3e0b Remove progress bar in non interactive mode (#1481) 2026-01-30 16:12:44 +00:00
Robert 946d4779a9 incr ver 2026-01-28 07:47:10 -05:00
Robert e620d0be24 remove unneeded coalesce 2026-01-28 07:44:32 -05:00
Mbucari d58f5abe35 Add Troubleshooting link to Advanced topics
Added 'Troubleshooting' link to the Advanced section.
2026-01-27 14:58:37 -07:00
Mbucari d957d6d5d7 Update troubleshooting guide with Hangover app details
Added troubleshooting information for the Hangover app and SQLite Error 10.
2026-01-27 14:53:08 -07:00
Michael Bucari-Tovo cb159336a6 Enable NTRs on main form and fix resulting warnings. 2026-01-27 12:42:21 -07:00
Michael Bucari-Tovo 807bb56c49 Refactor Chardonnay startup to prevent loading library twice. 2026-01-27 12:31:17 -07:00
Mbucari 3d56554aa5 Merge branch 'rmcrackan:master' into master 2026-01-27 12:29:03 -07:00
rmcrackan f720127a68 Merge pull request #1579 from rmcrackan/rmcrackan/bug-1578
Bug #1578 Add null checks
2026-01-27 13:22:20 -05:00
Robert c6c3b39e9c Bug #1578 Adding null checks to the line that's logged with NRE. This bit of code has been untouched for years and is run hundreds of times per day. I'm documenting this suspiciously 2026-01-27 09:06:46 -05:00
rmcrackan e70cc5342c Merge pull request #1572 from shuvashish76/patch-1
Add AppImage installation instructions
2026-01-23 09:45:12 -05:00
shuvashish76 bf0d380dd2 Add AppImage installation instructions
Added installation instructions for AppImage using AppMan and AM.
2026-01-23 14:41:46 +05:30
Michael Bucari-Tovo 471fd1e757 Remove unwanted meta box from dash files 2026-01-22 16:33:12 -07:00
Robert a43f25db23 incr ver 2026-01-22 17:50:31 -05:00
rmcrackan e1f4168599 Merge pull request #1567 from Mbucari/master
Minor big fixes and performance improvements
2026-01-22 17:48:31 -05:00
Michael Bucari-Tovo 29501bddf3 Clean up queries
Use .NET 10 extensions
Refactor some extensions for clarity
2026-01-22 13:36:25 -07:00
Michael Bucari-Tovo e9016ace03 Make IncludedUntil and LastDownload nulls always sort to bottom 2026-01-21 13:41:47 -07:00
Michael Bucari-Tovo d498c094bf Update AAXClean
Some minor performance improvements, especially when opening a file/stream.
2026-01-21 13:40:59 -07:00
Michael Bucari-Tovo ce92e79cd8 Fix SaferEnumerateFiles creating too manu open file handles (#1565)
Using the EnumerationOptions overload of EnumerateFiles() serves the same function as the previous manual implementation.
2026-01-21 10:34:59 -07:00
Michael Bucari-Tovo f54a789ae8 Improve querying UnLiberated books
Add GetUnliberated_Flat_NoTracking() which queries only unliberated books/episodes and does not load the entire library.

Fix UnLiberated() query to only return products or episodes (not parents) (#1564)
2026-01-19 16:57:32 -07:00
Michael Bucari-Tovo 3ef0bce909 No reason to restrict CDM type to Android or Level to L3 2026-01-19 14:16:47 -07:00
Robert 413da72bf0 logging typo 2026-01-19 10:31:34 -05:00
Robert db9c810c2d incr ver 2026-01-13 20:05:28 -05:00
rmcrackan ae18ae1b8d Merge pull request #1558 from Mbucari/master
Fix export, remove spatial audio option, and add file move progress.
2026-01-13 19:56:24 -05:00
Michael Bucari-Tovo c1298e9ff6 Update dependencies 2026-01-13 12:02:36 -07:00
Michael Bucari-Tovo 647eb8b9d9 Use MemoryPool 2026-01-13 11:35:59 -07:00
Michael Bucari-Tovo fd64d394c2 Remove spatial audio options #1553 2026-01-13 09:43:51 -07:00
Michael Bucari-Tovo f026d415bd Fix library export #1552 2026-01-13 09:35:08 -07:00
Michael Bucari-Tovo 3948e25c99 Add file move progress 2026-01-12 14:34:52 -07:00
Robert 6df47d4d9c incr ver 2026-01-12 16:32:16 -05:00
rmcrackan 0103c879f2 Merge pull request #1551 from Mbucari/master
Update dependencies
2026-01-12 14:17:05 -05:00
Michael Bucari-Tovo 79e2bca8fc Update dependencies 2026-01-12 10:42:04 -07:00
rmcrackan 7bbc681767 Merge pull request #1548 from Mbucari/master
Improved trash bin, new book properties, and bug fixes
2026-01-11 17:54:53 -05:00
Mbucari c95dccd246 Add confirmation dialog when removing books from Audible 2026-01-11 15:45:56 -07:00
Mbucari 94cf665be7 Fix books not being marked absent on large imports 2026-01-11 15:40:11 -07:00
Mbucari 7d38874257 Merge branch 'rmcrackan:master' into master 2026-01-09 16:49:09 -07:00
Michael Bucari-Tovo 659f793eb8 Improve TrashBinDialog functionality
- Use the main display grid control to display deleted books
- Added search functionality for deleted books. This required creating a temporary search index in the `InProgress` folder. The products grid control now uses an instance of `ISearchEngine` to filter its grid entries.  The main grid uses a singleton instance of `MainSearchEngine`, which merely wraps `SearchEngineCommands.Search()`.  The TrashBinDialogs use `TempSearchEngine`.
- Users can now batch select `Everyting` as well as `Audible Plus Books`

Avalonia:
  - Refactor main grid context menus to no longer require reflection
2026-01-09 16:47:37 -07:00
MBucari 6f7cd4d5b5 Fix narrators with null ASINs not importing (#1545 ) 2026-01-08 19:57:47 -07:00
Michael Bucari-Tovo 068f37319f Add option to adjust minimum file duration
when splitting audiobooks into multiple files by chapter
2026-01-08 18:36:57 -07:00
Michael Bucari-Tovo dc58a101af Add cli export option to specify Asins 2026-01-08 16:54:43 -07:00
Michael Bucari-Tovo 7b68415b02 Add more properties to search engine and library export
- Add `IsAudiblePlus` to search engine
- Add `IsAudiblePlus` and `AbsentFromLastScan` properties to library export
- Refactor library export ToXlsx method
  - Make nullable
  - Improve readability and extensability
  - Use same column header names as CSV
  - Extend export methods to accept optional list of books (future use)
2026-01-08 15:14:20 -07:00
Michael Bucari-Tovo 1514de54da Add menu option to remove Plus books from Audible 2026-01-08 13:00:47 -07:00
Michael Bucari-Tovo 804bac5c4c Add LibraryBook.IsAudiblePlus property 2026-01-07 15:50:23 -07:00
Michael Bucari-Tovo 3fa805d51f Verify correct Serilog parameters used (#1536 ) 2026-01-07 15:10:54 -07:00
rmcrackan 1eff725125 Merge pull request #1541 from rmcrackan/dependabot/npm_and_yarn/preact-10.28.2
Bump preact from 10.28.0 to 10.28.2
2026-01-07 14:35:44 -05:00
dependabot[bot] af1b1a70ae Bump preact from 10.28.0 to 10.28.2
Bumps [preact](https://github.com/preactjs/preact) from 10.28.0 to 10.28.2.
- [Release notes](https://github.com/preactjs/preact/releases)
- [Commits](https://github.com/preactjs/preact/compare/10.28.0...10.28.2)

---
updated-dependencies:
- dependency-name: preact
  dependency-version: 10.28.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-07 19:29:23 +00:00
Robert 042f2e135a incr ver 2026-01-06 07:28:33 -05:00
Robert 930fc3da58 Merge branch 'master' of https://github.com/rmcrackan/Libation 2026-01-06 07:26:40 -05:00
Robert 90e8d03590 add github doc contributor 2026-01-06 07:26:35 -05:00
rmcrackan ee908a4f13 Merge pull request #1534 from Mbucari/master
Improve LocateAudiobooksDialog and fix Classic upgrade dialog
2026-01-06 07:26:08 -05:00
rmcrackan 70ec31303b Merge pull request #1535 from niontrix/patch-1
Document Pacstall for program installation on Linux
2026-01-06 07:16:14 -05:00
Tobias Heinlein 319d547aa0 Document Pacstall for program installation on Linux
Added information about Pacstall for easier program installation.
2026-01-06 10:33:20 +01:00
Mbucari a59e42e7c9 Merge branch 'rmcrackan:master' into master 2026-01-05 18:50:51 -07:00
Michael Bucari-Tovo af2e89dd1e Remove UpgradeNotificationDialog form positioning
Hopefully address #1531
2026-01-05 18:50:28 -07:00
rmcrackan b2c5884e11 Merge pull request #1533 from rmcrackan/rmcrackan/log-friendly2
Rmcrackan/log friendly2
2026-01-05 19:30:43 -05:00
Robert 11d9cdefe2 typo 2026-01-05 19:30:03 -05:00
Robert 54485ae150 LogFriendly 2026-01-05 19:28:50 -05:00
Michael Bucari-Tovo 4bd641ee50 Improve LocateAudiobooksDialog
- Move LocatedAudiobooksViewModel to LibationUiBase
- Refactor Avalonia and Classic displays to use same view model.
- Do scan on background task
2026-01-05 15:38:15 -07:00
Robert 6e56297434 LogFriendly 2026-01-05 14:00:43 -05:00
rmcrackan e1f59eadbd Merge pull request #1529 from rmcrackan/rmcrackan/doc-github-sources
Doc re-directs to include pointers to github sources
2026-01-04 09:49:57 -05:00
Robert cfda065219 Doc re-directs to include pointers to github sources 2026-01-04 09:48:14 -05:00
Robert e3ad4a2c32 incr ver 2026-01-02 16:20:46 -05:00
rmcrackan 2b1c772df7 Merge pull request #1527 from Mbucari/master
Add feature to scan library for higher quality books
2026-01-02 16:02:01 -05:00
Mbucari 9b3e4f8762 Merge branch 'rmcrackan:master' into master 2026-01-02 13:13:12 -07:00
MBucari 396d2c8a95 Address rmcrackan comments and refactor 2026-01-02 13:04:35 -07:00
rmcrackan 91090b74ab Merge pull request #1526 from rmcrackan/rmcrackan/fix-export-columns
Bug fix #1524 - Fix export columns
2026-01-02 09:52:33 -05:00
Robert 32979b5905 Bug fix #1524 - Fix export columns 2026-01-02 09:52:17 -05:00
Michael Bucari-Tovo f6b96fc210 Add feature to scan for better quality audiobooks
Add AccessibleDataGridViewColumn which can apply Accessability names and descriptions from the designer.

Create reusable SortBindingList<T> for basic sorting of data-bound items.
2025-12-31 16:31:52 -07:00
Michael Bucari-Tovo 09e610fe08 Sanitize contributor names (#1518) 2025-12-31 13:09:47 -07:00
Michael Bucari-Tovo e50d8c74de Add UseWindowsForms to csproj 2025-12-31 11:28:45 -07:00
Michael Bucari-Tovo 2b1ca13249 Prevent migrations from running more than once 2025-12-31 11:25:43 -07:00
Michael Bucari-Tovo 7d30a3036d Move viewmodel into UiBase 2025-12-30 15:56:47 -07:00
Michael Bucari-Tovo bb8b435810 Improve Find Better Quality Audiobooks scanner
Try to load best audio format from actual liberated audiobook files
Allow re-scanning after completing scanning.
2025-12-30 14:49:58 -07:00
MBucari e850465ec1 Add more null safety
Enable project-wide nullable on LibationUiBase and LibationAvalonia

Explicitly parallelize unit tests
2025-12-30 13:17:11 -07:00
MBucari 29a5c943cb Auto-scroll process queue 2025-12-29 21:52:36 -07:00
Mbucari 31087c0855 Add feature to scan library for higher quality books 2025-12-29 19:30:47 -07:00
rmcrackan c91d359017 Merge pull request #1517 from Mbucari/master
Fix mp3 conversion of liberated AC-4 files and add metadata tags
2025-12-27 22:21:10 -05:00
MBucari 7dfdc0688a Add some more useful tags
AUDIBLE_ACR, AUDIBLE_DRM_TYPE, and AUDIBLE_LOCALE
2025-12-27 15:40:57 -07:00
MBucari c6c36c74f1 Allow converting already downloaded AC-4 to mp3 2025-12-27 14:40:10 -07:00
rmcrackan d932b57853 Merge pull request #1512 from radiorambo/fix-1508
Fix 1508 | auto redirect old docs links to new docs, add new development section to docs
2025-12-27 09:47:04 -05:00
radiorambo a29da7318b remove routex packgage 2025-12-27 13:04:37 +05:30
radiorambo 678c3e6bcd add Documentation folder with old pages but with only link to new docs 2025-12-27 13:03:55 +05:30
rmcrackan a8466e38d4 Merge pull request #1515 from Mbucari/master
Add CFBundleShortVersionString to Info.plist
2025-12-26 16:41:03 -05:00
Mbucari 802ccf25e8 Add recent contributors 2025-12-26 14:08:59 -07:00
Mbucari c243b9c913 Add CFBundleShortVersionString to Info.plist 2025-12-26 13:41:38 -07:00
radiorambo 4d47ab3ebe update old docs links 2025-12-25 15:53:01 +05:30
Umesh 8dea6200ce Merge branch 'master' into fix-1508 2025-12-24 13:38:24 +05:30
radiorambo a578777352 fix broken links 2025-12-24 11:17:43 +05:30
radiorambo e58e5165cf update readme 2025-12-24 11:17:29 +05:30
radiorambo 87c2cb6e19 add separete section for development related 2025-12-24 11:11:48 +05:30
Robert 4f44c26b57 incr ver 2025-12-23 09:52:25 -05:00
rmcrackan 03534773ab Merge pull request #1510 from rmcrackan/dependabot/github_actions/actions/configure-pages-5
Bump actions/configure-pages from 4 to 5
2025-12-23 09:39:59 -05:00
rmcrackan 37f223fb77 Merge pull request #1509 from rmcrackan/dependabot/github_actions/actions/upload-pages-artifact-4
Bump actions/upload-pages-artifact from 3 to 4
2025-12-23 09:31:01 -05:00
radiorambo cf932bd66c redirect old doc links to new doc links 2025-12-23 19:58:14 +05:30
rmcrackan f0dc33a01e Merge pull request #1511 from rmcrackan/dependabot/github_actions/actions/checkout-6
Bump actions/checkout from 5 to 6
2025-12-23 09:11:11 -05:00
dependabot[bot] 315d76e061 Bump actions/checkout from 5 to 6
Bumps [actions/checkout](https://github.com/actions/checkout) from 5 to 6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-23 14:06:01 +00:00
dependabot[bot] 6e78145adc Bump actions/configure-pages from 4 to 5
Bumps [actions/configure-pages](https://github.com/actions/configure-pages) from 4 to 5.
- [Release notes](https://github.com/actions/configure-pages/releases)
- [Commits](https://github.com/actions/configure-pages/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/configure-pages
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-23 14:05:51 +00:00
dependabot[bot] 200a334f86 Bump actions/upload-pages-artifact from 3 to 4
Bumps [actions/upload-pages-artifact](https://github.com/actions/upload-pages-artifact) from 3 to 4.
- [Release notes](https://github.com/actions/upload-pages-artifact/releases)
- [Commits](https://github.com/actions/upload-pages-artifact/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/upload-pages-artifact
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-23 14:05:45 +00:00
rmcrackan 4dd4a1495a Update docker.md 2025-12-22 17:46:10 -05:00
rmcrackan b3ce0e0af0 Update docker.md
Add LIBATION_CONNECTION_STRING
2025-12-22 17:45:15 -05:00
Mbucari 1299d91d08 Restrict workflow runs to specific paths 2025-12-22 12:54:58 -07:00
rmcrackan ad3a767057 Merge pull request #1504 from Youssef1313/mtp
Migrate from VSTest to MTP
2025-12-22 14:45:19 -05:00
Michael Bucari-Tovo a59c73caf8 Add win-arm64 release identfier 2025-12-22 12:37:22 -07:00
rmcrackan 442a688b85 Update README.md 2025-12-22 10:28:21 -05:00
rmcrackan 0c85ea4d11 Merge pull request #1498 from radiorambo/new-documentation-website
add new documentation website
2025-12-22 09:50:45 -05:00
Youssef1313 03ed8e6b57 Migrate from VSTest to MTP 2025-12-21 15:03:52 +01:00
rmcrackan 3eca508a26 Merge pull request #1501 from Mbucari/master
Add support for decoding Windows Arm64 and AC-4 audio files
2025-12-19 08:21:26 -05:00
radiorambo 770adf33f3 add gitHub actions workflow for vitePress deployment to gitHub pages. 2025-12-19 14:09:21 +05:30
MBucari 1087ffb150 Add support for converting AC-4 files to mp3 2025-12-19 00:18:06 -07:00
radiorambo f620234e7d add docs overview in homepage and in nav bar links 2025-12-18 14:28:46 +05:30
radiorambo 2b6b5d082e fix nav link increase website width in tablet view 2025-12-18 14:27:17 +05:30
Michael Bucari-Tovo cbbc45c3c5 Add Windows arm64 build 2025-12-17 11:00:29 -07:00
rmcrackan 28de1a6cb6 Merge pull request #1500 from Mbucari/master
Update AAXClean
2025-12-17 06:45:13 -05:00
Michael Bucari-Tovo 1615c6ef77 Update AAXClean 2025-12-16 23:44:04 -07:00
radiorambo 6961bd72fa rename 'report issues' button to 'issues & requests' and simple installation routes 2025-12-16 13:22:56 +05:30
radiorambo 68846a90e5 fix dead links 2025-12-16 13:11:56 +05:30
radiorambo d60ec0702c update nav and homepage buttons 2025-12-16 13:07:55 +05:30
radiorambo 1c55c8533a improve docs 2025-12-16 13:06:44 +05:30
radiorambo 6fa69b603e rename files 2025-12-15 22:08:01 +05:30
radiorambo 3df8a97463 configure config for clean urls 2025-12-15 21:36:39 +05:30
rmcrackan 0bd7bd80b9 Merge pull request #1496 from rmcrackan/dependabot/github_actions/actions/download-artifact-7
Bump actions/download-artifact from 6 to 7
2025-12-15 09:17:03 -05:00
rmcrackan 13bb4238b4 Merge pull request #1497 from rmcrackan/dependabot/github_actions/actions/upload-artifact-6
Bump actions/upload-artifact from 5 to 6
2025-12-15 09:16:49 -05:00
dependabot[bot] d5021e4f74 Bump actions/upload-artifact from 5 to 6
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 5 to 6.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-15 14:06:46 +00:00
dependabot[bot] 5e1458cfb4 Bump actions/download-artifact from 6 to 7
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 6 to 7.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-15 14:06:41 +00:00
radiorambo e1d4533887 use github syntax for admonitions in homepage 2025-12-15 18:27:37 +05:30
radiorambo c1bd1d983b make documentation development section in readme concise 2025-12-15 17:50:39 +05:30
radiorambo b567c38a98 update syntax, adjust heading levels, reformat tables, and apply minor text and capitalization fixes across documentation. 2025-12-15 17:45:34 +05:30
radiorambo 348ec22465 update package-lock.json 2025-12-15 17:43:46 +05:30
radiorambo 90bb4d9176 fix favicon and logo not visible 2025-12-15 16:05:02 +05:30
radiorambo 7944154ea6 add icons 2025-12-15 15:37:19 +05:30
radiorambo 01fc7f3fb9 rename documentation files for simple routing paths and reorganise for better navigation 2025-12-15 15:37:07 +05:30
radiorambo b70f973994 update .gitignore for vitepress 2025-12-15 15:34:37 +05:30
radiorambo 98d3f85579 install vitepress and configure 2025-12-15 15:28:05 +05:30
Robert bdae155af6 incr ver 2025-12-11 16:41:36 -05:00
rmcrackan c8b44193ac Merge pull request #1490 from Mbucari/master
Two bugfixes
2025-12-09 13:39:14 -05:00
Mbucari 9545b3a874 Invoke MessageBox on UI thread 2025-12-06 18:55:38 -07:00
Mbucari e932c9fab9 Merge branch 'rmcrackan:master' into master 2025-12-06 18:02:38 -07:00
Robert c8f4c1e751 Merge branch 'master' of https://github.com/rmcrackan/Libation 2025-12-06 14:48:26 -05:00
Robert 0303db153f update audibleapi 2025-12-06 14:48:24 -05:00
Mbucari a7e9479eab Fix file utility modifying file extension using replacement character
The file extension should not be subject to renaming. #1483
2025-12-06 10:40:02 -07:00
Mbucari d339dbc906 Update macOS install instructions. 2025-12-05 21:06:02 -07:00
Robert 5fe6f931ad incr ver 2025-12-04 20:54:08 -05:00
rmcrackan ca9fe9fc32 Merge pull request #1479 from Mbucari/master
Two minor bug fixes
2025-12-04 20:52:19 -05:00
MBucari 986dbd678f Don't throw exceptions from failure to delete db-wal and db-shm files (#1478) 2025-12-03 22:09:35 -07:00
MBucari ea3716f48a Fix books dialog not saving or updating properly (#1477) 2025-12-03 22:03:14 -07:00
rmcrackan 426d5a87b4 Merge pull request #1476 from rmcrackan/dependabot/github_actions/apple-actions/import-codesign-certs-6
Bump apple-actions/import-codesign-certs from 5 to 6
2025-12-03 09:48:46 -05:00
dependabot[bot] c893bbe52e Bump apple-actions/import-codesign-certs from 5 to 6
Bumps [apple-actions/import-codesign-certs](https://github.com/apple-actions/import-codesign-certs) from 5 to 6.
- [Release notes](https://github.com/apple-actions/import-codesign-certs/releases)
- [Commits](https://github.com/apple-actions/import-codesign-certs/compare/v5...v6)

---
updated-dependencies:
- dependency-name: apple-actions/import-codesign-certs
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-03 14:06:28 +00:00
Robert ad5a9874af incr ver 2025-12-02 15:28:59 -05:00
rmcrackan 3b70c08439 Merge pull request #1471 from Mbucari/master
Classic dark mode, customizable downloads, bug fixes
2025-12-02 15:26:24 -05:00
Michael Bucari-Tovo a230605ed5 Improve GetCounts performance. 2025-12-02 12:43:12 -07:00
Michael Bucari-Tovo d48ce39773 Move LibraryCommands.GetCounts() to background thread. 2025-12-02 12:30:05 -07:00
Michael Bucari-Tovo 368e695214 Allow users to shoose whether Libation imports Audible Plus titles. 2025-12-02 12:28:16 -07:00
Michael Bucari-Tovo 9c3881c67d Fix LibationCli reusing content licenses (#1473) 2025-12-02 11:09:58 -07:00
MBucari 4c5fdf05f5 Add "Download split by chapters" context menu item (#1436)
All processables are now created with an instance of Configuration, and they use that instance's settings.

Added Configuration.CreateEphemeralCopy() to clone Configuration without persistence.
2025-12-01 23:23:47 -07:00
MBucari 4bd491f5b9 Make winforms book details and search syntax dialogs nonmodal
Match Chardonnay behavior
2025-12-01 21:24:30 -07:00
MBucari c34b1e752e Update dependencies 2025-12-01 20:40:34 -07:00
MBucari fa30c10435 Fix PDF validation error (#1470 ) 2025-12-01 20:39:52 -07:00
Michael Bucari-Tovo cdb91ae2ca Add dark mode to winforms
- Add dark theme icon variants
- Change all light theme icon fill colors to match Chardonnay

Also fixed #1460  by chaing the directory select control to DirectoryOrCustomSelectControl
2025-12-01 20:39:22 -07:00
Robert 7852067b81 incr ver 2025-11-29 23:22:42 -05:00
rmcrackan 3708515df9 Merge pull request #1467 from Mbucari/master
Fix MessageBox launch error on macOS
2025-11-29 23:21:14 -05:00
Mbucari 530aca4f4d Fix MessageBox launch error on macOS 2025-11-29 15:41:38 -07:00
Robert cf571148bc incr ver 2025-11-25 23:19:49 -05:00
rmcrackan 2c2a720ba9 Merge pull request #1458 from Mbucari/master
Bug fixes in the downloader
2025-11-25 22:47:48 -05:00
Michael Bucari-Tovo b577ef7187 Improve SetBeckupCounts
Change Avalonia's Task-based approach to WinForms' BackgroundWorker approach.
- Reduce number of calls to GetLibrary by adding the Library to the LibraryStats record.
2025-11-25 14:59:48 -07:00
Michael Bucari-Tovo ffbb3c3516 Make namespace name match assembly name 2025-11-25 13:34:12 -07:00
Michael Bucari-Tovo 2a6cf38677 Fix book details dialog not saving 2025-11-25 13:33:40 -07:00
Michael Bucari-Tovo d8104a4d7c Check is stream is disposed before reading position. 2025-11-25 12:34:20 -07:00
Michael Bucari-Tovo af85ea9219 Fix exception being throw in Dispose() 2025-11-25 12:24:07 -07:00
rmcrackan c30e149a36 Merge pull request #1456 from Mbucari/master
Fix database lock from -wal and -whm files
2025-11-24 22:57:12 -05:00
MBucari 050a4867b7 Fix database lock from -wal and -whm files
Delete LibationContext.db-shm and LibationContext.db-wal files as part of startup routine.
2025-11-24 20:45:55 -07:00
Robert 2bf6f7a4f2 incr ver 2025-11-24 15:46:01 -05:00
rmcrackan 788a768271 Merge pull request #1455 from Mbucari/master
Add liberate option `--license` to use license file.
2025-11-24 15:43:18 -05:00
Michael Bucari-Tovo 022a6e979d Add error handling for cookies 2025-11-24 12:01:10 -07:00
Michael Bucari-Tovo 9fc5a7d834 Add liberate option --license to use license file.
Added instructions for liberating using a license file.
2025-11-24 11:36:31 -07:00
Robert b72e5039b1 incr ver 2025-11-24 09:48:22 -05:00
rmcrackan e992b49da2 Merge pull request #1451 from Mbucari/master
Add more liberation logging
2025-11-24 09:14:23 -05:00
MBucari 74afbbf581 Add more liberation logging 2025-11-23 23:40:23 -07:00
rmcrackan d82ffe1467 Merge pull request #1444 from Mbucari/master
Use C# 14 `field` and extension members.
2025-11-23 22:44:57 -05:00
Mbucari 8a84a083d1 Fix removed field 2025-11-23 20:38:20 -07:00
Mbucari 04827f81da Tweak in-app web browser login
- Use private browsing mode
- Use the Android User-Agent
- Use initial signin cookies
2025-11-23 20:35:04 -07:00
Mbucari 805f42b1cc Add warnings for inaccessable InProgress directory (#1446) 2025-11-22 15:29:54 -07:00
Mbucari b9a1709284 Use release version of EntityFrameworkCore.PostgreSQL 2025-11-22 11:46:27 -07:00
Michael Bucari-Tovo b0a40e12b7 Create some extension members
Trying out .NET 10s extension members with some Book extension properties.
2025-11-21 12:31:50 -07:00
Michael Bucari-Tovo dfbc5ec9db Use the new field keyword where appropriate. 2025-11-21 11:50:07 -07:00
rmcrackan 649ef5f864 Merge pull request #1441 from rmcrackan/dependabot/github_actions/apple-actions/import-codesign-certs-5
Bump apple-actions/import-codesign-certs from 3 to 5
2025-11-21 11:19:27 -05:00
rmcrackan 4345bf2ee2 Merge pull request #1442 from rmcrackan/dependabot/github_actions/actions/checkout-6
Bump actions/checkout from 5 to 6
2025-11-21 11:19:09 -05:00
rmcrackan 441d430dea Merge pull request #1439 from Mbucari/master
Update to .NET 10
2025-11-21 09:15:00 -05:00
dependabot[bot] 85ee0bcddb Bump actions/checkout from 5 to 6
Bumps [actions/checkout](https://github.com/actions/checkout) from 5 to 6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-21 14:06:00 +00:00
dependabot[bot] 0f1fc0f11d Bump apple-actions/import-codesign-certs from 3 to 5
Bumps [apple-actions/import-codesign-certs](https://github.com/apple-actions/import-codesign-certs) from 3 to 5.
- [Release notes](https://github.com/apple-actions/import-codesign-certs/releases)
- [Commits](https://github.com/apple-actions/import-codesign-certs/compare/v3...v5)

---
updated-dependencies:
- dependency-name: apple-actions/import-codesign-certs
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-21 14:05:53 +00:00
MBucari 75aa17df11 Fix winforms STAThread on main 2025-11-20 22:35:13 -07:00
MBucari 913019cdfd Revert hack workaround for DataGridView error 2025-11-20 22:19:43 -07:00
MBucari a55da5f187 Refactor DbContext access and disposal
- Remove instance queue. This is a database, after all, and is designed to be accessed and written to concurrently
- Reduce the number of calls to DbContexts.Create()
- Ensure that no LibationContext remains open across an await boundary. Multithread context access is the most likely culprit for past issues.
- Make all Update UserDefinedItem methods asynchronous.
2025-11-20 22:15:54 -07:00
MBucari f9ac0253fb Improve import performance on large batches 2025-11-20 21:37:13 -07:00
MBucari fde78f4167 Update to .NET 10
- Update all project runtime targets
- Update all dependencies
  - NOTE: Using Npgsql.EntityFrameworkCore.PostgreSQL RTM build from MyGet
- Delete unused pubxml files (they were made redundant by recent workflow changes)
- Replace Libation.sln with Libation.slnx
2025-11-20 15:56:47 -07:00
rmcrackan 22159b79d8 Merge pull request #1429 from Mbucari/master
Minor Bugfixes, new Workflows, and signed macOS bundles, refactor LibationFiles, improve libationCLI
2025-11-20 13:45:25 -05:00
MBucari 7fe170acdf Fix CLI help tex being squashed to a single column 2025-11-20 10:42:14 -07:00
MBucari c0898a288b Additional LibationCli documentation
Move CLI examples to the bottom of the page.
2025-11-20 09:55:35 -07:00
MBucari ce2b81036f Add license and settings overrides to LibationCli
- Add `LIBATION_FILES_DIR` environment variable to specify LibationFiles directory instead of appsettings.json
- OptionsBase supports overriding setting
  - Added `EphemeralSettings` which are loaded from Settings.json once and can be modified with the `--override` command parameter
- Added `get-setting` command
  - Prints (editable) settings and their values. Prints specified settings, or all settings if none specified
  - `--listEnumValues` option will list all names for a speficied enum-type settings. If no setting names are specified, prints all enum values for all enum settings.
  - Prints in a text-based table or bare with `-b` switch
- Added `get-license` command which requests a content license and prints it as a json to stdout
- Improved `liberate` command
  - Added `-force` option to force liberation without validation.
  - Added support to download with a license file supplied to stdin
  - Improve startup performance when downloading explicit ASIN(s)
  - Fix long-standing bug where cover art was not being downloading
2025-11-19 23:47:41 -07:00
Michael Bucari-Tovo 65d24ce223 Fix NRE in FileSystemTest when Books dir is invalid (#1435) 2025-11-17 10:54:25 -07:00
MBucari e8c911e603 Improve management and validation of Libation settings
- Move all settings file logic into new LibationFiles class
  - Configuration.LibationFiles is a singleton instance of the LibationFiles class.
  - A LibationFiles instance is bound to a single appsettings.json path. All updates to LibationFiles location are updated in that appsettings.json file
- Unify initial setup and settings validation process
  - Add LibationSetup which handles all startup validation of settings files and prompts users for setup if needed
  - Added a new LibationUiBase.Tests test project with tests for various
2025-11-17 10:49:23 -07:00
Michael Bucari-Tovo 59f66ff480 Fix subdirectory create failing on root drive (#1432)
This appears to be a bug in .NET. Someone started to fix it in a PR, but it went stale and was auto-closed.

https://github.com/dotnet/runtime/pull/117519
2025-11-14 13:44:46 -07:00
Michael Bucari-Tovo e05dcd6f54 Don't overwrite LibationFiles setting in appsettings.json 2025-11-14 13:35:36 -07:00
Michael Bucari-Tovo d1ce9d5a83 Update Mac Workflow
- Add new repo variables
  - `SIGN_MAC_APP_ON_VALIDATE` will force sign/notarize on the validate workflow (normally only done for releases)
  - `WAIT_FOR_NOTARIZE` Causes the build-mac workflow to wait for apple to notarize the bundle so that it can be stapled. This is usually fast (1-2 mis), but can be very long and may cause workflow runners to time out.
2025-11-14 11:19:21 -07:00
Mbucari 2213f5c86a Change msaOS updater to get DMGs
This will break _Automatic_ updates for existing mac users (although I'm not sure it worked all that well to begin with. However, the update notification dialog has had a link to download the bundle manually for a long time now. Old users will still be notified of the new release and be given a direct link to download it.
2025-11-13 23:15:29 -07:00
Mbucari d6b232f342 Update Logging and Error Handling
- Add Configuration.LoggingEnabled property which gets set as soon as Serilog is configured
- Add error handling to InteropFactory
2025-11-13 23:12:57 -07:00
Mbucari f29c19beb8 Update .gitignore 2025-11-13 23:04:33 -07:00
Mbucari 9f6d08fc1f Update Workflows
- Simplify workflows build commands
- Don't build ReadyToRun on validate
- Move get-version into it's own job in build.yml
- Split  macOS into it's own reusable workflow
  - Add app bundle code signing
  - Add notarization
2025-11-13 22:59:26 -07:00
MBucari 717dfcd923 Fix trying to cancel disposed cancellation token source 2025-11-11 14:06:54 -07:00
MBucari a3d181b2ec Fix Primary Screen NRE (#1420) 2025-11-11 03:21:20 -07:00
Mbucari d16eeea56b Improve detection of NativeWebDialog crash 2025-11-10 22:58:05 -07:00
Mbucari 5d2513ec33 Improve button display size uniformity. 2025-11-10 22:21:51 -07:00
Mbucari e5043dcf40 Move button styling to App.xaml 2025-11-10 21:42:34 -07:00
Mbucari c61bfb4134 Fix EditQuickFilters not displaying with no filters 2025-11-10 21:42:06 -07:00
Robert d47a2595b9 incr ver 2025-11-10 22:19:24 -05:00
rmcrackan 55e74db4fb Merge pull request #1419 from Mbucari/master
Bug Fixes and UI Improvement
2025-11-10 22:17:12 -05:00
MBucari 0a171222bc Update Dependency 2025-11-10 19:29:30 -07:00
MBucari c2093157ca Add dolby atmos logo for spatial audiobooks 2025-11-10 19:28:18 -07:00
MBucari 8e073800cd Fix BookDetailsDialog crash when changing error status 2025-11-10 18:25:59 -07:00
MBucari 1daf07b882 Improve logging 2025-11-10 17:58:48 -07:00
MBucari 27a23a16d6 Update AAXClean 2025-11-10 17:34:17 -07:00
Michael Bucari-Tovo c878b9fec0 Detect webview crash and disable webview login 2025-11-10 13:14:23 -07:00
rmcrackan 7a01f075ac Merge pull request #1415 from Mbucari/master
Fix minor UI bugs
2025-11-08 18:04:13 -05:00
Michael Bucari-Tovo 23d391485d Update AboutDialog and add recent contributors 2025-11-07 10:35:33 -07:00
Michael Bucari-Tovo 46be532740 Improve SearchSyntaxDialog
- Double-clicking a tag will paste the tage into the search bar
- SearchSyntaxDialog now modeless
2025-11-06 23:53:57 -07:00
Michael Bucari-Tovo e2fd88d075 Improve ScanAccountsDialog usability 2025-11-06 23:24:17 -07:00
Michael Bucari-Tovo bb0dea3fa9 Improve EditReplacementChars dialog usability 2025-11-06 22:49:09 -07:00
Michael Bucari-Tovo def0b1f611 Prevent crash if watched RootDirectory is deleted 2025-11-06 14:57:54 -07:00
Michael Bucari-Tovo bfee579719 Fix DirectoryOrCustomSelectControl 2025-11-06 13:47:51 -07:00
Mbucari d4139861f3 Only allow mocking lobby bugging 2025-11-06 07:59:55 -07:00
Robert ba15eb1a95 incr ver 2025-11-06 09:43:11 -05:00
rmcrackan 6263fedf84 Merge pull request #1406 from Mbucari/master
Improved Login experience, error messages, and published size.
2025-11-06 08:44:44 -05:00
MBucari 0cbffc3f6c Only allow mocking settings while debugging 2025-11-05 23:52:44 -07:00
MBucari 5f093b06ec Improve Chardonnay setup reliability. 2025-11-05 23:40:20 -07:00
Michael Bucari-Tovo f815c5fd47 Define context menu in XAML, remove need for reflection 2025-11-05 16:20:47 -07:00
Michael Bucari-Tovo 69a8eaad4a Add mock LibraryBook and Configuration capabilities
- Added `MockLibraryBook` which contains factories for easily creating mock LibraryBooks and Books
- Added mock Configuration
  - New `IPersistentDictionary` interface
  - New `MockPersistentDictionary` class which uses a `JObject` as its data store
  - Added `public static Configuration CreateMockInstance()`
    - This method returns a mock Configuration instance **and also sets the `Configuration.Instance` property**
    - Throws an exception if not in debug
- Updated all chardonnay controls to use the mocks in design mode. Previously I was using my actual database and settings file, but that approach is fragile and is unfriendly towards anyone else trying to work on it.
2025-11-05 13:28:49 -07:00
Michael Bucari-Tovo 01b5c18b2b Improve Column Context Menu CheckBox display 2025-11-05 09:39:32 -07:00
Michael Bucari-Tovo 5634fee2aa Add Account column #1398 2025-11-05 08:48:29 -07:00
MBucari e98e4f10bc Ensure FileSystemWatcher is disposed 2025-11-04 22:08:36 -07:00
MBucari ec32ff77b2 Fix theme not being applied when changed by the system (#1368) 2025-11-04 22:07:29 -07:00
Michael Bucari-Tovo 683c984246 Modify script which populates username in webview 2025-11-04 15:06:03 -07:00
Michael Bucari-Tovo 0fa5c4eb1e Request metadata for the audiobook version being downloaded (#1261) 2025-11-04 14:58:27 -07:00
Michael Bucari-Tovo 7507044b82 Improve detection and logging of download capabilities
- Check if the Api supports widevine before trying to download
- Additional logging
2025-11-04 14:32:28 -07:00
Michael Bucari-Tovo 017902ab52 Click to open libation log file 2025-11-04 13:19:40 -07:00
Mbucari dcc5c1c640 Fix quotes in Libation.desktop Exec command 2025-11-03 18:32:05 -07:00
Michael Bucari-Tovo 19efa8c918 Improve error messages for Chardonnay
- A message box alert should be possible regardless of the error
- If crash pre-logging, attempt to write to last used Libation log file
2025-11-03 17:40:38 -07:00
Michael Bucari-Tovo a34efb5e61 Add multiple image sizes in windows folder icons 2025-11-03 14:04:30 -07:00
Michael Bucari-Tovo 9533f80e89 Replace NPOI excel workbook library with ClosedXML
- Reduce build bundles by 30-40 MB
2025-11-03 13:13:13 -07:00
Michael Bucari-Tovo fa238a0915 Use xplat webview control for Audible login
- Use Avalonia-based webview control for Audible login with Chardonnay
- Remove webview interfaces from IInteropFunctions
- Remove Microsoft.Web.WebView2 package from WindowsConfigApp
- Add Microsoft.Web.WebView2 to LibationWinForms
- Remove all other login forms except the external login dialog (fallback in case webview doesn't work). The AudibleApi login with username/password doesn't work anymore. Need to use external browser login method.
2025-11-03 11:29:57 -07:00
Michael Bucari-Tovo f98adef9e9 Update Dependencies
- Remove package references that are already included transitively
- Change Avalonia.ReactiveUI to ReactiveUI.Avalonia
2025-11-03 09:34:23 -07:00
rmcrackan d85e5a0f98 Update Advanced.md
CLI: copy the local sqlite database to postgres
2025-11-03 11:24:02 -05:00
Robert 365ac8167f incr ver 2025-11-03 11:04:55 -05:00
Robert 4720779373 Bug fix. DesignTimeDbContextFactoryBase used to call context.Database.Migrate() . Must now do so ourselves 2025-11-03 11:00:10 -05:00
Robert 0c512162ab Reverting migration notes from #1402 2025-11-03 10:21:13 -05:00
rmcrackan 09ca419faf Merge pull request #1402 from twsouthwick/postgres
Add support for postgres
2025-11-03 09:47:48 -05:00
Taylor Southwick a2b1f13601 remove migration calls 2025-11-02 18:32:20 -08:00
Robert f4e7cf3418 Bugfix #1403 : Trash bin actions result in app crashes 2025-11-01 13:32:19 -04:00
MBucari 8492a7ea3a Properly disposed of LibationContext (#1403) 2025-10-31 13:45:07 -06:00
Taylor Southwick 1b5db9b28f Add support for postgres
Supporting postgres simplifies deployments to environments such as kubernetes. Since sqlite doesn't work well on nfs shares it can be easier for databases to have a dedicated db set up that applications can connect to. Sqlite is easier for most deployments though, so this will default to that if the settings haven't been updated to support it.

This change does the following:

- Separate out SQLite from the DataLayer and adds a Postgres assembly for migrations as well
- Add a configuration setting for a postgres connection string that will be used if it is there, otherwise reverts to the original sqlite string
- Add a copydb command for the cli to bootstrap the postgres db
- A convenience script to update migrations for both dbs at the same time
2025-10-27 16:30:50 -07:00
rmcrackan 5589a6cbd5 Merge pull request #1401 from rmcrackan/dependabot/github_actions/actions/upload-artifact-5
Bump actions/upload-artifact from 4 to 5
2025-10-27 11:22:19 -04:00
dependabot[bot] bfbad988c0 Bump actions/upload-artifact from 4 to 5
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4 to 5.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-27 15:14:03 +00:00
rmcrackan 8db8615713 Merge pull request #1400 from rmcrackan/dependabot/github_actions/actions/download-artifact-6
Bump actions/download-artifact from 5 to 6
2025-10-27 11:07:00 -04:00
dependabot[bot] e8fa3f14b3 Bump actions/download-artifact from 5 to 6
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 5 to 6.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-27 14:59:43 +00:00
Robert 71552f2417 incr ver 2025-10-23 09:45:55 -04:00
rmcrackan 5b96f96a80 Merge pull request #1390 from Mbucari/master
Bug Fixes and attempts to solve random crashes
2025-10-23 09:43:23 -04:00
Michael Bucari-Tovo afffeb953c Enforce sequential access to DbContext. 2025-10-22 09:22:05 -06:00
Mbucari f4d8685058 Merge branch 'rmcrackan:master' into master 2025-10-22 09:16:49 -06:00
Robert b4cfd18976 incr ver 2025-10-20 21:12:43 -04:00
rmcrackan e12548dacd Merge pull request #1388 from delebash/master
Added IncludedUntil Date
2025-10-20 21:10:46 -04:00
delebash fd95ac7a9c changes per Mbucari 2025-10-20 16:31:06 -04:00
delebash f7cd2b106b fix migration files 2025-10-20 14:12:04 -04:00
delebash 07e51f2191 IncludedUntil migration 2025-10-20 13:09:41 -04:00
delebash fcd79c5561 InludedUntil fixes by Mbucari 2025-10-20 12:55:48 -04:00
delebash ba98820989 move code to LibraryBook 2025-10-18 02:05:56 -04:00
delebash b07e61e6a8 fix UntilDate 2025-10-17 13:49:37 -04:00
delebash 8c3fd19c70 Merge remote-tracking branch 'origin/master' 2025-10-17 13:36:21 -04:00
delebash fa8f761771 Added IncludedUntil Date 2025-10-17 13:36:01 -04:00
rmcrackan 2c882e883d #1378 : allow for invalid beginning-of-time 'purchase_date'. This is the case for an actual user 2025-09-30 16:28:48 -04:00
Mbucari 74c76a7414 Enhance bug report template formatting and instructions
Updated the bug report template to improve clarity and formatting, including default log file locations for various platforms.
2025-09-04 12:46:22 -06:00
Mbucari 17a0c21453 Document xHE-AAC conformance errors for Audible
Added notes on xHE-AAC conformance errors related to Audible files.
2025-09-04 12:24:46 -06:00
rmcrackan fc9c9dfe48 Merge pull request #1360 from rmcrackan/dependabot/github_actions/actions/setup-dotnet-5
Bump actions/setup-dotnet from 4 to 5
2025-09-03 21:43:10 -04:00
dependabot[bot] d5f0e39981 Bump actions/setup-dotnet from 4 to 5
Bumps [actions/setup-dotnet](https://github.com/actions/setup-dotnet) from 4 to 5.
- [Release notes](https://github.com/actions/setup-dotnet/releases)
- [Commits](https://github.com/actions/setup-dotnet/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/setup-dotnet
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-04 00:05:35 +00:00
rmcrackan 0f6493f4af Merge pull request #1353 from rmcrackan/rmcrackan-patch-2
Update NamingTemplates.md
2025-08-27 09:30:09 -04:00
rmcrackan 454b490a06 Update NamingTemplates.md 2025-08-27 09:28:45 -04:00
rmcrackan ffea2648aa Merge pull request #1352 from rmcrackan/rmcrackan-patch-1
Update NamingTemplates.md
2025-08-27 09:22:20 -04:00
rmcrackan 1ac967500c Update NamingTemplates.md
Better documentation for inverted tags
2025-08-27 08:57:20 -04:00
Michael Bucari-Tovo 39e9f675d2 Fix possible race error on startup with autoscan 2025-08-26 10:00:21 -06:00
rmcrackan ed5afe5d0f update dependencies 2025-08-20 12:07:53 -04:00
rmcrackan ab075d0bef Merge pull request #1343 from MajorTanya/patch-1
Place examples in their own line
2025-08-20 11:49:46 -04:00
MajorTanya 7fb1adb41b Place examples in their own line
Markdown collapses single line breaks, so this change makes it so the examples will have their own lines.
2025-08-20 17:26:48 +02:00
rmcrackan 9735a8391c incr ver 2025-08-20 08:39:10 -04:00
rmcrackan dbdfdbc536 Merge pull request #1342 from Mbucari/master
Added new <has PROPERTY-><-has> conditional tag
2025-08-20 08:37:11 -04:00
Michael Bucari-Tovo 3b86fc405f Add <has-> template tag 2025-08-19 18:41:31 -06:00
MBucari 4ea7f04921 Preserve space between series order numbers 2025-08-17 13:40:37 -06:00
MBucari 5b59b442ab Add last downloaded sample rate, bitrate and codec name to search engine. 2025-08-17 13:07:24 -06:00
rmcrackan b5d9c0a27a Incr ver 2025-08-17 10:06:12 -04:00
rmcrackan f5cbf89e13 Merge pull request #1337 from Mbucari/master
Fix linux crpto and series order parsing
2025-08-17 09:57:43 -04:00
rmcrackan 00dc9e020d Update bug_report.md 2025-08-17 09:55:26 -04:00
MBucari bfa0e4d338 Parse floats with invariant culture 2025-08-16 16:39:36 -06:00
Mbucari 5ceda408da Use managed RSASSA-PSS with SHA-1
OpenSSL (the underlying RSA implementation on Linux) has deprecated SHA-1 signing. Used a managed implementation so that it does not error.
2025-08-16 16:28:33 -06:00
Mbucari 716b1923a4 Update FrequentlyAskedQuestions.md 2025-08-15 12:25:03 -06:00
rmcrackan 1148d8125d incr ver 2025-08-15 13:10:05 -04:00
rmcrackan 690fd10e42 Merge pull request #1331 from Mbucari/master
Audio format docs, new audio format options, series order parsing.
2025-08-15 13:08:10 -04:00
Michael Bucari-Tovo 736fbbf82f Improve FilePathCache performance 2025-08-15 10:50:37 -06:00
Michael Bucari-Tovo eda100b7ac Remove FluentAssertions 2025-08-15 10:29:23 -06:00
Michael Bucari-Tovo ceb007500d Update assertions to use ThrowsExactly 2025-08-14 15:58:01 -06:00
Michael Bucari-Tovo 05fad01624 Update dependencies 2025-08-14 15:57:35 -06:00
Michael Bucari-Tovo e1d789ccdc Improve series order parsing and formatting 2025-08-14 15:37:53 -06:00
Michael Bucari-Tovo d0f00f3f1e Add xHE-AAC option 2025-08-14 13:20:01 -06:00
Michael Bucari-Tovo 6ab82dba7b Add audio format info to wiki 2025-08-14 13:16:27 -06:00
rmcrackan 0045202334 update dependencies 2025-08-13 07:52:13 -04:00
rmcrackan 4c80813651 Merge pull request #1330 from rmcrackan/dependabot/github_actions/actions/checkout-5
Bump actions/checkout from 4 to 5
2025-08-11 17:38:40 -04:00
dependabot[bot] 6b637b35ab Bump actions/checkout from 4 to 5
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-11 20:35:21 +00:00
rmcrackan 9b55ffa715 Merge pull request #1329 from rmcrackan/rmcrackan/dolby-atmos
Begin documentation for Dolby Atmos
2025-08-11 09:22:03 -04:00
rmcrackan 65da7890f1 Begin documentation for Dolby Atmos 2025-08-11 09:21:03 -04:00
rmcrackan 72f92ec6c0 update dependencies 2025-08-10 11:21:34 -04:00
rmcrackan 4efc084375 Merge pull request #1324 from rmcrackan/dependabot/github_actions/actions/download-artifact-5
Bump actions/download-artifact from 4 to 5
2025-08-06 10:24:33 -04:00
dependabot[bot] f955daa5ed Bump actions/download-artifact from 4 to 5
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 4 to 5.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-06 14:09:36 +00:00
rmcrackan 144ab2162a incr ver 2025-08-05 12:58:45 -04:00
rmcrackan 6d0c4a9b3c Merge pull request #1322 from Mbucari/master
Improve Libation's interaction with the file system & other minor fixes
2025-08-05 12:57:03 -04:00
Michael Bucari-Tovo 8a682533c1 Change repo link to rmcrackan 2025-08-05 10:39:03 -06:00
Michael Bucari-Tovo cecabc911e Add "Locate Audiobooks" help text 2025-08-05 10:29:48 -06:00
Michael Bucari-Tovo e35f5209dc Don't change user's replacement character settings
Instead, add the NTFS-only invalid characters to the set of invalid filename characters.
2025-08-05 09:49:22 -06:00
MBucari 4ffe70af0e Fix serilog not logging caller name 2025-08-04 23:24:55 -06:00
MBucari 233ba3184f Add link to naming template wiki 2025-08-04 21:23:50 -06:00
Michael Bucari-Tovo ac4c168725 Allow Libation to start with an invalid Books directory
- Configuration.LibationSettingsAreValid is true if Books property exists and is any non-null, non-empty string.
- If LibationSettingsAreValid is false, Libation will prompt user to set up Libation.
- When the main window is shown, Libation checks if the books directory exists, and if it doesn't, user is notified and prompted to change their setting
- When a user tries to liberate or convert a book, Books directory is validated and user notified if it does not exist.
2025-08-04 19:58:26 -06:00
Michael Bucari-Tovo db588629c0 Null safety and minor UI bugfix
Properly cancel the Locate Audiobooks when the dialog window closes before scanning is finished.
2025-08-04 17:15:37 -06:00
Michael Bucari-Tovo 29be091a4b Fix cross-thread error on AccoundSettings.Saved event 2025-08-04 14:18:04 -06:00
Michael Bucari-Tovo 82a48db57b Fix walkthrough errors on chardonnay. 2025-08-04 10:27:37 -06:00
Mbucari 9f0f32a462 Merge branch 'rmcrackan:master' into master 2025-08-04 10:02:02 -06:00
rmcrackan f64239b5ee Merge pull request #1316 from ajundi/master
Added nix flake and shell files for nixos developers
2025-08-04 09:55:42 -04:00
Ayman Jundi bc8a35aedd Added nix flake and shell files for nixos users who want to work on development. You can use flake method => 'nix develop' or non flake method =>`nix-shell'
The shell.nix file is used for both flake and non-flake invocations. The lock file is also set at a version where the project works.
Note the none-flake method will follow the version of the system and isn't guaranteed to work on older installations if they haven't been updated in a while.
Added Documentation for using Nix package manager for development ./Documentation/LinuxDevelopmentSetupUsingNix.md

Signed-off-by: Ayman Jundi <ajundi@gmail.com>
2025-08-03 16:36:03 -04:00
Ayman Jundi 2fca6b8b91 Added launch.json and task.json entries that allows building and debugging for linux-64 targets without having to modify the csproj files.
Signed-off-by: Ayman Jundi <ajundi@gmail.com>
2025-08-03 15:33:17 -04:00
Mbucari bc2eddd2dd Merge branch 'rmcrackan:master' into master 2025-07-31 10:36:26 -06:00
Michael Bucari-Tovo ae012548bd Smart handling of filename limitations cross platform
Automatically determine if filename lengths in the Books directory are limited to 255 UTF-16 characters (NTFS) or 255 UTF-8 bytes (pretty much every other file system) (#1260)

In non-Windows environments, determine if the Books directory supports filenames containing characters which are illegal in Windows environments (<>|:*?). If it doesn't, then ensure those characters are included in the user's ReplacementCharacters settings (#1258).
2025-07-30 16:04:48 -06:00
rmcrackan 76a59873ea undo dependabot overreach 2025-07-30 09:42:43 -04:00
rmcrackan 3129fdba7b Merge pull request #1319 from rmcrackan/dependabot/nuget/Source/ApplicationServices/multi-ab24e9613a
Bump SixLabors.ImageSharp to 2.1.11, 3.1.11
2025-07-30 09:37:18 -04:00
dependabot[bot] 1771813849 Bump SixLabors.ImageSharp to 2.1.11, 3.1.11
---
updated-dependencies:
- dependency-name: SixLabors.ImageSharp
  dependency-version: 2.1.11
  dependency-type: direct:production
- dependency-name: SixLabors.ImageSharp
  dependency-version: 3.1.11
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-30 13:30:26 +00:00
Michael Bucari-Tovo 7024bbf823 Provide NTFS default characters for non-windows users (#1258) 2025-07-29 15:20:52 -06:00
Michael Bucari-Tovo 663f70b8bf Use series Order string instead of parsed float in template tags (#1056) 2025-07-29 12:18:37 -06:00
rmcrackan 7741e3caff incr ver 2025-07-29 07:54:24 -04:00
rmcrackan c82eefa768 Merge pull request #1317 from Mbucari/master
Bug fixes and UI tweak
2025-07-29 07:52:01 -04:00
Michael Bucari-Tovo 0e4231906a Set IsSpatial field instead of only flipping to true (#1273) 2025-07-28 15:28:04 -06:00
Michael Bucari-Tovo 9bca84dca4 Sort columns with null values always at the bottom 2025-07-28 09:29:17 -06:00
MBucari ca30fd41c6 Use proper version string based on build version 2025-07-28 08:59:20 -06:00
MBucari be96f99461 Increment Version 2025-07-27 11:40:35 -06:00
MBucari f017fe419f Fix ID3 tag encoding error (#1315) 2025-07-27 11:38:01 -06:00
rmcrackan ed42916cb2 incr ver 2025-07-26 23:11:51 -04:00
rmcrackan 0bb5bba3c8 Merge pull request #1314 from Mbucari/master
New audio format features, bug fixes, and minor tweaks/improvements.
2025-07-26 23:10:05 -04:00
MBucari a887bf4619 Add "Is Spatial" grid column. 2025-07-26 18:19:19 -06:00
MBucari 53eebcd6ba Use single file downloader/namer if file has only 1 chapter 2025-07-25 16:02:28 -06:00
MBucari a09ae1316d Don't display null file versions 2025-07-25 16:01:48 -06:00
MBucari 7088bd4b8d Check for file existance 2025-07-25 15:49:41 -06:00
MBucari b27325cdcb Improve comvert to mp3 task
- Improve progress reporting and cancellation performance
- Clear current book from queue before queueing single convert to mp3 task
2025-07-25 15:35:03 -06:00
MBucari accedeb1b1 Improve EditQuickFilters dialog reordering behavior 2025-07-25 14:23:14 -06:00
MBucari c98c7c095a Fix quickfilter modification bug (#1313) 2025-07-25 14:22:29 -06:00
MBucari 9b217a4e18 Add audio format data
- Add Book.IsSpatial property and add it to search index
- Read audio format of actual output files and store it in UserDefinedItem. Now works with MP3s.
- Store last downloaded audio file version
- Add IsSpatial, file version, and Audio Format to library exports and to template tags. Updated docs.
- Add last downloaded audio file version and format info to the Last Downloaded tab
- Migrated the DB
- Update AAXClean with some bug fixes
  - Fixed error converting xHE-AAC audio files to mp3 when splitting by chapter (or trimming the audible branding from the beginning of the file)
  - Improve mp3 ID# tags support. Chapter titles are now preserved.
  - Add support for reading EC-3 and AC-4 audio format metadata
2025-07-25 12:18:50 -06:00
Michael Bucari-Tovo a62a9ffc5b Use HttpClient in synchronous mode 2025-07-23 17:00:54 -06:00
Michael Bucari-Tovo 08aebf8ecf Add thread safety 2025-07-23 17:00:36 -06:00
Michael Bucari-Tovo 2f082a9656 Refactor and optimize audiobook download and decrypt process
- Add more null safety
- Fix possible FilePathCache race condition
- Add MoveFilesToBooksDir progress reporting
- All metadata is now downloaded in parallel with other post-success tasks.
- Improve download resuming and file cleanup reliability
- The downloader creates temp files with a UUID filename and does not insert them into the FilePathCache. Created files only receive their final file names when they are moved into the Books folder. This is to prepare for a future plan re naming templates
2025-07-23 16:55:09 -06:00
Michael Bucari-Tovo 1f473039e1 Make search syntax dialog field names scrollable 2025-07-22 15:39:43 -06:00
Michael Bucari-Tovo 0f4197924e Use LibationUiBase.ReactiveObject where applicable
Also tweak the classic process queue control layout
2025-07-22 11:59:34 -06:00
rmcrackan 0f7ffacdf8 incr ver 2025-07-22 10:20:39 -04:00
rmcrackan 829b35c5a8 Merge pull request #1311 from Mbucari/master
Fix serilog dynamic assembly loading issue (#1310)
2025-07-22 10:18:33 -04:00
Michael Bucari-Tovo 614b05d5ff Fix serilog dynamic assembly loading issue (#1310) 2025-07-22 08:00:31 -06:00
rmcrackan 26ccc77b47 incr ver 2025-07-22 07:24:26 -04:00
rmcrackan 64fb2ccf7c Merge pull request #1308 from Mbucari/master
Refactors, bug fixes, and performance improvements.
2025-07-22 07:22:35 -04:00
MBucari 890747a902 Do library scan on background thread 2025-07-22 00:20:16 -06:00
Michael Bucari-Tovo 1fdcea929f Form thread safety 2025-07-21 22:52:17 -06:00
Michael Bucari-Tovo 7848366818 Write logs to text .log file instead of .zip file
The ZipFile sink could cause program hangs. Additionally, the only reason it was ever used was to package verbose AudibleApi account login errors, saving the returned Html page as a file. Otherwise, the zip file only contains a .log text file.

- Removed Serilog.Sinks.ZipFile
- Add Serilog configuration migration
- Added a custom destructure to handle logging files. If any files are logged, they will be written to "LogyyyyMM_AdditionalFiles.zip"
2025-07-21 22:19:55 -06:00
Michael Bucari-Tovo 40b4915b65 Improve download/decrypt cancellation 2025-07-21 15:56:41 -06:00
Michael Bucari-Tovo 80b86086ca Consolidate process queue view models
Remove classic and chardonnay-specific implementations
Refactor TrackedQueue into an IList with INotifyCollectionChanged
2025-07-21 15:56:30 -06:00
Michael Bucari-Tovo bff9b67b72 Remove GridEntry derrived types and interfaces
Use existing BaseUtil.LoadImage delegate, obviating need for derrived classes to load images

Since GridEntry types are no longer generic, interfaces are unnecessary and deleted.
2025-07-21 10:47:10 -06:00
Mbucari 657a7bb6bc Improve podcast episode GridEntry creation performance.
Tested on a library with ~5000 podcast episodes on an AMD Ryzen 7700X. Startup time decreases by ~400 ms in Release mode.
2025-07-21 09:49:25 -06:00
rmcrackan f0d7a7bf64 incr ver 2025-07-18 07:19:09 -04:00
rmcrackan 8bc098e7bd Merge pull request #1303 from Mbucari/master
Fix upgrade bug when Libation's working dir isn't program files dir
2025-07-18 07:16:46 -04:00
Michael Bucari-Tovo 9280b29512 Fix upgrade bug when Libation's working dir isn't program files dir
Add MockUpgrader for testing the Upgrade process.
Fixes issue #1302
2025-07-17 13:10:42 -06:00
rmcrackan d8e9b9c505 incr ver 2025-07-17 08:07:08 -04:00
rmcrackan 554b308364 Merge pull request #1299 from Mbucari/master
Bugfixes and minor improvements
2025-07-17 08:04:43 -04:00
MBucari 8d7872a376 UI tweak and optimization 2025-07-16 23:31:34 -06:00
MBucari 747451d243 Refactor Classic process queue
The queue is now more MVVM-like.
2025-07-16 22:58:03 -06:00
MBucari 7e79e98771 Fix possible cross-threading errors with MessageBoxBase 2025-07-16 22:57:25 -06:00
Michael Bucari-Tovo 4b7939541a Code cleanup and refactoring for clarity 2025-07-16 22:55:57 -06:00
MBucari a3734c76b1 Use SynchronizeInvoker's Invoke() method. 2025-07-15 23:22:42 -06:00
MBucari ced4ea6c17 Improve sorting by Liberate status by grouping books with PDFs 2025-07-15 22:50:53 -06:00
MBucari 35ca6f2621 Use built-in comparer and ReactiveObject types 2025-07-15 22:50:28 -06:00
MBucari 4dab16837e Move ProcessQueueViewModel logic into LibationUiBase
Fix UI bug in classic when queue is in popped-out mode.
2025-07-15 22:31:17 -06:00
MBucari 1cf889eed7 Move ProcessBookViewModel logic into LiationUiBase 2025-07-15 15:05:33 -06:00
MBucari b65b1e819b Consolidate queue commands into UI base 2025-07-15 13:32:42 -06:00
MBucari 3d50643ab0 Fix visible book counts being incorrect on startup
If quick filters are applied on startup, a race condition was created between the initial library load book counting and the visible books counting. Only display results of the latest book count.
2025-07-15 11:49:20 -06:00
MBucari abd18d74b0 Fix crash when setting drive root as custom directory (#1300) 2025-07-15 11:44:45 -06:00
MBucari 0e49df06b8 Add message box handler to LibationUiBase 2025-07-15 11:40:01 -06:00
MBucari 38cc3e9725 Revert change to release title 2025-07-15 08:54:22 -06:00
MBucari c9af2bba4b Reduce GitHub API calls when no upgrades are available 2025-07-14 14:43:48 -06:00
MBucari 2191c1536d Prepare Libation for win-arm64 releases
Also add support for four-part version numbers in releases.
2025-07-14 14:20:57 -06:00
MBucari 5b9bf2fbb0 Remove duplicate tests 2025-07-14 12:53:47 -06:00
MBucari 9b1ce8c1d7 Update dependencies 2025-07-14 12:43:53 -06:00
MBucari 9f8075041b Only remove a LibraryBook from queue if we are trying to re-download. 2025-07-14 12:42:05 -06:00
MBucari 944645379e Fix message box text truncation when there is no icon (#1294) 2025-07-14 12:19:26 -06:00
Mbucari cc72517284 Merge branch 'rmcrackan:master' into master 2025-07-14 11:45:44 -06:00
rmcrackan 0044820415 Update README.md 2025-07-07 16:31:09 -04:00
rmcrackan 9f24027de1 Update README.md 2025-07-07 16:29:46 -04:00
rmcrackan 24f95cb03d Update GettingStarted.md 2025-07-07 16:27:59 -04:00
rmcrackan 3aeea54615 Update FrequentlyAskedQuestions.md 2025-07-07 16:26:10 -04:00
rmcrackan f511041781 Create a cue sheet: default false 2025-06-25 12:43:50 -04:00
rmcrackan da9dc91469 incr ver for docker enhancement 2025-06-25 06:58:14 -04:00
rmcrackan e04e70d333 Merge pull request #1265 from vipervire/master
Update Books directory to use LIBATION_BOOKS_DIR if populated
2025-06-25 06:57:01 -04:00
rmcrackan e0b566ee60 Merge pull request #1277 from dev-nicolaos/patch-1
Update deb/rpm Installation Instructions
2025-06-24 07:50:35 -04:00
Nicolaos Skimas bf15d7302e Update Deb/RHEL/Fed Installation Instructions 2025-06-23 22:39:45 -07:00
rmcrackan 8f01c644c0 Update bug_report.md 2025-06-19 07:21:21 -04:00
Mbucari ebd2cc96c5 Merge branch 'rmcrackan:master' into master 2025-06-18 12:13:14 -06:00
rmcrackan 0d1cc42ca7 Bugfix #1269 : Chardonnay. Bad filter string causes infinite loop 2025-06-16 13:19:48 -04:00
vipervire e126dd09ce Update Books directory to use LIBATION_BOOKS_DIR if populated 2025-06-05 23:26:52 +00:00
Michael Bucari-Tovo ec497f4f81 Use virtualized list to improve large queue performance 2025-05-19 10:40:41 -06:00
rmcrackan 248fdfd2bc Probably unnecessary paranoid incr ver. Everything looks correct but I've never actually released relying on the ver's 4th part. I'm incrementing just in case 2025-05-10 16:53:04 -04:00
MBucari 35862d619a Increment version 2025-05-09 21:10:38 -06:00
Mbucari ac2c67985d Merge pull request #1253 from Mbucari/master
Fix download error (#1252 )

I'm merging this one and releasing ASAP.
2025-05-09 21:07:59 -06:00
MBucari f8ae303417 Fix download error (#1252 ) 2025-05-09 21:07:01 -06:00
rmcrackan 0d24caeac2 incr ver 2025-05-09 21:10:19 -04:00
rmcrackan 7f1b357c52 Merge pull request #1250 from Mbucari/master
Bug fixes and a change to license request logic
2025-05-09 21:08:19 -04:00
Michael Bucari-Tovo ef67ae9d6a Ask users to clear the accounts when enabling widevine (#1249) 2025-05-09 17:52:14 -06:00
Michael Bucari-Tovo f35c82d59d Change ApiExtended to always allow provide login option
Previously, only some calls to ApiExtended.CreateAsync() would prompt users to login if necessary. Other calls would only work if the account already had a valid identity, and they would throw exceptions otherwise.

Changed ApiExtended so that the UI registers a static ILoginChoiceEager factory delegate that ApiExtended will use in the event that a login is required.
2025-05-09 17:32:12 -06:00
Michael Bucari-Tovo 10c01f4147 Fix occasional error of audio downloads hanging. 2025-05-09 16:32:59 -06:00
Michael Bucari-Tovo 9366b3baca Default to E-AC-3 spatial audio format. 2025-05-09 13:39:59 -06:00
Michael Bucari-Tovo 20e792c589 Always change the last chapter's length to coincide with the end of the audio file. 2025-05-09 13:36:07 -06:00
Michael Bucari-Tovo dfb63d3275 Add contributor 2025-05-09 13:15:18 -06:00
Michael Bucari-Tovo 19db226f5a Use Libation settings to decide which DRM is downloaded. 2025-05-09 13:13:39 -06:00
Mbucari 203ab00865 Merge branch 'rmcrackan:master' into master 2025-05-08 12:15:26 -06:00
MBucari b11a4887d7 Pad final chapter to prevent tuncation from incorrect chapter info (#1246) 2025-05-08 12:13:55 -06:00
rmcrackan e73fc5e1eb Merge pull request #1247 from starry-shivam/patch-2
Small typo fix in DownloadOptions.Factory.cs
2025-05-08 07:12:42 -04:00
Stɑrry Shivɑm 8561a15061 Small typo fix in DownloadOptions.Factory.cs 2025-05-08 10:48:02 +05:30
MBucari 28ba62aead Fix dash files not being saved (#1236) 2025-05-07 23:15:44 -06:00
rmcrackan 176294cc55 Merge pull request #1245 from Mbucari/master
Minor bugfixes
2025-05-07 19:28:45 -04:00
Michael Bucari-Tovo 152b0e362d Update message box icons 2025-05-07 16:10:03 -06:00
Michael Bucari-Tovo 4600d029dc Re-add converter resource inadvertantly removed in 0df17a22 2025-05-07 14:23:58 -06:00
Michael Bucari-Tovo 1a5684799c Update Hangover styles and behaviors 2025-05-07 13:16:44 -06:00
Michael Bucari-Tovo 0df17a2296 Remove retired ItemsRepeater control 2025-05-07 13:12:12 -06:00
Michael Bucari-Tovo 45472abd1f Update dependencies 2025-05-07 11:15:32 -06:00
Mbucari f2ea4539f2 Merge branch 'rmcrackan:master' into master 2025-05-07 11:13:32 -06:00
Michael Bucari-Tovo 52d3b9cb67 Disable warning 2025-05-07 11:13:26 -06:00
rmcrackan 3d87f2cd9b Merge branch 'master' of https://github.com/rmcrackan/Libation 2025-05-07 12:39:10 -04:00
rmcrackan e4a3d2ac79 better logging for api errors #1240 2025-05-07 12:39:02 -04:00
Michael Bucari-Tovo 8aa157f2f6 Re-add completed audiobooks to queue (#1219) 2025-05-06 15:43:58 -06:00
Michael Bucari-Tovo 5ab6c1fe70 Update AAXClean to fix metadata reader (#1243 ) 2025-05-06 15:33:38 -06:00
Michael Bucari-Tovo b23c46f79f Fix incorrect chapters in some audiobooks (#1210) 2025-05-06 15:32:59 -06:00
Mbucari 0e987eef00 Fix error in download speed throttle (#1242) 2025-05-06 14:48:40 -06:00
rmcrackan ace3d80e41 Merge pull request #1241 from cherez/patch-1
Fixed doubled first name in templates
2025-05-06 16:29:29 -04:00
Mbucari 4bfb4e73ce Fix aax file getting inadvertently deleted (#1236) 2025-05-06 12:45:43 -06:00
Steven Wallace 7805a3ef11 Fixed broken single word name test
This expected the name duplication that the previous commit fixed to be the behavior, changed to expect the single word to be the last name.
2025-05-06 09:58:09 -05:00
Steven Wallace 08ca2a2db3 Fixed doubled first name in templates
v12.3.0 caused a regression with contributors with a single word name, causing the name to be doubled. This was caused by using that name as both the first and last name, so swap the first name with the (blank) last name rather than duplicate them.
2025-05-05 10:37:28 -05:00
rmcrackan 64a85b6aab Merge branch 'master' of https://github.com/rmcrackan/Libation 2025-05-02 22:15:36 -04:00
rmcrackan 1a38273d5f incr ver 2025-05-02 22:15:32 -04:00
rmcrackan 303dd7c471 Merge pull request #1233 from Mbucari/master
Bugfixes and Feature Requests
2025-05-02 22:14:33 -04:00
MBucari 313e3846c3 Remove AudioFormat from library book exporter (5f455182) 2025-05-02 15:39:47 -06:00
Michael Bucari-Tovo 422c86345e Add logging 2025-05-02 14:50:33 -06:00
Michael Bucari-Tovo ce952417fb Don't replace library properties in queued item with null/empty 2025-05-02 13:07:53 -06:00
Michael Bucari-Tovo 5f4551822b Remove Book.AudioFormat property
This property was set to the highest quality returned by the library scan. Since adding quality option settings, it is no longer guaranteed to reflect the file that is downloaded. Also, the library scan qualities don't contain spatial audio or widevine-specific qualities., only ADRM.
2025-05-02 12:39:12 -06:00
Michael Bucari-Tovo 3aebc7c885 Improve download performance. 2025-05-02 12:19:32 -06:00
Michael Bucari-Tovo 3982edd0f1 Add codec tag and use real bitrate/samplerate (#1227) 2025-05-02 11:20:58 -06:00
Michael Bucari-Tovo f4dafac28f Try to solve #1226 2025-05-01 13:19:03 -06:00
Michael Bucari-Tovo 1090d29f74 Add fine-grained options for downloading widevine content 2025-05-01 13:03:03 -06:00
rmcrackan 1c336e1fe9 bug fix 2025-04-28 18:55:20 -04:00
rmcrackan c7e9e9ac1e incr ver 2025-04-28 13:36:26 -04:00
rmcrackan 8232b2b5e5 Merge pull request #1223 from Mbucari/master
New features, including spatial audio support
2025-04-28 13:34:40 -04:00
MBucari 9ca879cc3d Revert "Allow re-adding completed queued items"
This reverts commit e2aae85fd7.
2025-04-27 14:31:21 -06:00
MBucari ece48eb6d7 Add spatial audio support 2025-04-27 14:31:14 -06:00
MBucari bffaea6026 Add CDM API url list 2025-04-27 13:15:50 -06:00
MBucari e2aae85fd7 Allow re-adding completed queued items 2025-04-25 19:54:19 -06:00
MBucari 1777dc5a7e Update AAXClean.Codecs and dependencies 2025-04-25 19:52:51 -06:00
Mbucari 2dfe00f428 Merge branch 'rmcrackan:master' into master 2025-04-15 00:36:11 -06:00
rmcrackan 2cd0a022ff bug fix #1212 : fix window title 2025-04-03 08:20:31 -04:00
Michael Bucari-Tovo 5d7ac699e6 Mark unreleased books as unavailable (#1079) 2025-03-25 12:35:18 -06:00
Michael Bucari-Tovo 7d806e0f3e Increase tag template options for contributor and series types
- Add template tag support for multiple series
- Add series ID and contributor ID to template tags
- <first author> and <first narrator> are now name types with name formatter support
- Properly import contributor IDs into database
- Updated docs
2025-03-25 09:34:57 -06:00
Michael Bucari-Tovo 0a9e489f48 Move contributors to UI Base 2025-03-24 13:29:02 -06:00
rmcrackan 17612dacd2 incr ver 2025-03-22 06:35:30 -04:00
rmcrackan e61ad41d5a Merge pull request #1202 from Mbucari/master
Add multiselect feature and a bugfix
2025-03-22 06:31:33 -04:00
Michael Bucari-Tovo c77f2e2162 Add multi-select context menu support (rmcrackan/Libation#1195) 2025-03-21 16:49:21 -06:00
Michael Bucari-Tovo bfcd226795 Fix libation hanging on first inport of large libraries 2025-03-21 11:08:36 -06:00
rmcrackan 0af7c4d90a fix ver 2025-03-21 09:19:03 -04:00
rmcrackan e4826388be incr ver 2025-03-21 09:18:48 -04:00
rmcrackan 98a1fa4dda Merge pull request #1193 from Mbucari/master
Add support for custom themes in chardonnay
2025-03-21 09:12:35 -04:00
Michael Bucari-Tovo 81e9ab7fb2 Fix theme not resetting properly
Change button foreground color
2025-03-20 16:30:08 -06:00
Mbucari 9c82d34ba4 Merge branch 'rmcrackan:master' into master 2025-03-20 15:30:18 -06:00
Mbucari a384bceab0 Update Readme for Chardonnay Themes 2025-03-20 15:29:46 -06:00
Michael Bucari-Tovo 545540d9a4 Improve Libation glass icons for use with dark mode. 2025-03-20 15:04:22 -06:00
MBucari f402912a92 Mark resource as dynamic and delete unused resource 2025-03-19 22:43:50 -06:00
Michael Bucari-Tovo aab4f1d9d6 Add theme import and export function 2025-03-19 21:47:24 -06:00
Michael Bucari-Tovo f183b587b8 Revert all changes if window is closed by user. 2025-03-19 16:38:58 -06:00
Michael Bucari-Tovo 733a091ebd Add theme preview dialog 2025-03-19 16:26:14 -06:00
Mbucari 9043ea6334 Merge branch 'rmcrackan:master' into master 2025-03-19 14:21:51 -06:00
Michael Bucari-Tovo 40890f242a Fix spelling errors 2025-03-19 14:16:32 -06:00
rmcrackan 6c03f525bf Update InstallOnMac.md -- minimum OS supported 2025-03-19 16:01:40 -04:00
Michael Bucari-Tovo dcda1a0cc2 Add contributors to about page 2025-03-18 21:18:25 -06:00
Michael Bucari-Tovo e509f842e4 Remove unused windows forms buttons and streamline dialogs 2025-03-18 21:18:25 -06:00
Mbucari faa2e04b9f Merge branch 'rmcrackan:master' into master 2025-03-18 21:17:30 -06:00
Robert McRackan 71afb5c9f4 incr ver 2025-03-18 21:09:27 -04:00
Michael Bucari-Tovo d90ef3f4d4 Mark IconFill as a dynamic resource 2025-03-18 12:33:01 -06:00
Michael Bucari-Tovo f84bb753e9 Revert custom window border on Windows 2025-03-13 16:44:16 -06:00
Michael Bucari-Tovo b34970bd47 Add support for custom themes in chardonnay 2025-03-13 16:05:32 -06:00
Robert McRackan a37eb383cd Merge branch 'master' of https://github.com/rmcrackan/Libation 2025-03-10 19:11:22 -04:00
Robert McRackan 614965e1ab incr ver 2025-03-10 19:09:44 -04:00
rmcrackan 52d611a74c Merge pull request #1189 from Mbucari/master
Minor bug fixes.
2025-03-10 17:30:24 -04:00
Michael Bucari-Tovo 653381b1df Fix Auto download not working sometimes (#1183) 2025-03-10 12:57:52 -06:00
Michael Bucari-Tovo 4e067f5b5b Remove inadvertently committed debugging code 2025-03-10 10:46:36 -06:00
Michael Bucari-Tovo ee05ca4eb2 Handle corrupted LibraryScans.zip file (#1185) 2025-03-10 09:49:22 -06:00
Michael Bucari-Tovo 65e12d9a8f Add default window dimensions 2025-03-10 09:07:35 -06:00
rmcrackan 5dc1bafb94 Update Docker.md 2025-03-07 10:12:05 -05:00
rmcrackan 3010f80834 Merge pull request #1181 from rmcrackan/dependabot/nuget/Source/LibationUiBase/SixLabors.ImageSharp-3.1.7
Bump SixLabors.ImageSharp from 3.1.6 to 3.1.7 in /Source/LibationUiBase
2025-03-06 20:49:34 -05:00
dependabot[bot] 6c20b85200 Bump SixLabors.ImageSharp from 3.1.6 to 3.1.7 in /Source/LibationUiBase
Bumps [SixLabors.ImageSharp](https://github.com/SixLabors/ImageSharp) from 3.1.6 to 3.1.7.
- [Release notes](https://github.com/SixLabors/ImageSharp/releases)
- [Commits](https://github.com/SixLabors/ImageSharp/compare/v3.1.6...v3.1.7)

---
updated-dependencies:
- dependency-name: SixLabors.ImageSharp
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-06 22:29:43 +00:00
rmcrackan bf87180fe9 Merge pull request #1179 from Mbucari/master
UI tweak and Linux command updates
2025-03-05 17:41:47 -05:00
Michael Bucari-Tovo ae9aac789f Use polkit (#1176) and dnf5/dnf (#1177) 2025-03-05 14:22:51 -07:00
Mbucari e6cd182872 Merge branch 'rmcrackan:master' into master 2025-03-05 11:25:50 -07:00
Michael Bucari-Tovo 7eeb2dcd7f Move encoding options above to the mp3 settings column (#764)
Additionally, add more tool tips for cryptic options.
2025-03-05 11:17:47 -07:00
rmcrackan 71bb0571d1 Merge pull request #1178 from RokeJulianLockhart/patch-1
Add instructions for Fedora to `InstallOnLinux.md`.
2025-03-05 11:32:10 -05:00
Mr. Beedell, Roke Julian Lockhart 7bb5b2968e Add instructions for Fedora to InstallOnLinux.md
Partially improves upon https://github.com/rmcrackan/Libation/issues/1177#issue-2897597653.
2025-03-05 15:17:49 +00:00
rmcrackan b051283fca Update bug_report.md 2025-03-05 09:30:43 -05:00
rmcrackan 53af2ee39e Update feature_request.md 2025-03-05 09:30:18 -05:00
rmcrackan fab32a1744 Update bug_report.md 2025-03-05 09:29:04 -05:00
rmcrackan e2dabc8a53 Update feature_request.md 2025-03-05 09:26:47 -05:00
rmcrackan fd82f7ae5a Update feature_request.md 2025-03-05 09:26:19 -05:00
rmcrackan df9535a83d Update FrequentlyAskedQuestions.md 2025-03-05 08:20:42 -05:00
rmcrackan 85b6792468 Merge pull request #1175 from Mbucari/master
Additional null safety
2025-03-04 21:32:35 -05:00
Michael Bucari-Tovo e37abbf276 Fix dark theme text color in DataGridTextColumn 2025-03-04 16:18:06 -07:00
Michael Bucari-Tovo c3938c49a9 Additional null safety 2025-03-04 15:41:26 -07:00
Michael Bucari-Tovo 7658f21d7c Fix tags font color in dark mode 2025-03-04 15:07:37 -07:00
Michael Bucari-Tovo c4827fc761 Add error logging 2025-03-04 12:54:05 -07:00
rmcrackan 649b52af1d Merge pull request #1174 from Mbucari/master
Null safety & UI tweak
2025-03-04 13:10:51 -05:00
Michael Bucari-Tovo da06511951 Only show buttons on mouse over 2025-03-04 10:34:09 -07:00
Michael Bucari-Tovo 88d3e5ff0c Null safety checks. 2025-03-04 10:33:29 -07:00
rmcrackan 5f99e594d8 Merge pull request #1172 from Mbucari/master
Thread safety and AccountSettings.json error handling
2025-03-03 19:27:45 -05:00
Michael Bucari-Tovo 981a183992 Add a border around dialogs with CanResize=true 2025-03-03 15:20:58 -07:00
Michael Bucari-Tovo ac036f65f1 Handle and notify users of invalid account settings file 2025-03-03 14:41:56 -07:00
Michael Bucari-Tovo b36e110b49 Add thread safety and comments re threading 2025-03-03 10:11:17 -07:00
Robert McRackan ef3c71a939 Incr ver 2025-03-02 20:34:45 -05:00
rmcrackan b2af93bed9 Merge pull request #1169 from Mbucari/master
12.0.1 Bug Fixes
2025-03-02 20:33:59 -05:00
Mbucari 1f427919e6 Try to solve threadding issues (#1168) 2025-03-02 11:59:35 -07:00
Mbucari c9c5bbb687 Fix errorre rmoving entries from the cache (#1167) 2025-03-02 10:55:26 -07:00
Robert McRackan efbefa2784 Increm ver 2025-03-01 10:44:49 -05:00
rmcrackan 51aabe5dd4 Merge pull request #1161 from Mbucari/master
Performance and UI tweaks
2025-02-28 22:48:49 -05:00
Michael Bucari-Tovo 1c668adff8 Deliminated category names in library exports with semicolon (#1107) 2025-02-28 17:35:58 -07:00
Michael Bucari-Tovo 4170dcc1d5 Chardonnay UI bug fixes and improvements
- Theme changes do not require restart
- Fix some text appearing black in dark mode
- Fix dialog boxes not appearing correctly on Windows
- Fix queue vertical scroll bar overlapping items
2025-02-28 17:34:55 -07:00
Michael Bucari-Tovo 68cfae1d58 Fix ever-widening Form1 when form size is restored. 2025-02-28 12:04:49 -07:00
Michael Bucari-Tovo a790c7535c Changes to default directories for file storage (#1112)
- Add My Music and Local Application Data to known directories
- Make %localappdata%\Libation the default settings folder on *nix machines
- Make %MyMusic%\Libation\Books the default books folder on *nix machines
2025-02-28 12:01:58 -07:00
Michael Bucari-Tovo 3b7d5a354f Re-add books to queue that failed or were cancelled. 2025-02-28 10:47:26 -07:00
MBucari a9375f1520 Improve file cache performance and add migration
LibraryCommands.GetCounts hits the file cache hard. The previous cache implementation was linear list, so finding an entry by ID was (n). When you consider that each book may have many files, the number of cache entries could grow to many multiples of the library size.

The new cache uses a dictionary with the ID as its key, and a CacheEntry list as its value.
2025-02-28 10:07:45 -07:00
Michael Bucari-Tovo 47c9fcb883 Improve LibrarySizeChanged performance 2025-02-27 22:56:30 -07:00
rmcrackan 5f5c9f65ed Merge pull request #1160 from Mbucari/master
Fixed stack overflow crash when movifying large databases
2025-02-27 21:41:33 -05:00
MBucari 1417a4b992 Improve library load performance 2025-02-27 19:16:36 -07:00
Michael Bucari-Tovo 2d6120f0c4 Get full library in LibrarySizeChanged event and pass as EventArgs
There are multiple subscribers to LibraryCommands.LibrarySizeChanged, and each one calls GetLibrary_Flat_NoTracking(). Passing the full library as an event argument speeds up all operations which happen after the library size changes.

Fix initial backup counts
2025-02-27 13:11:28 -07:00
Michael Bucari-Tovo 2a25b7e0ad Load MainWindow before library finishes loading like Classic 2025-02-27 11:17:18 -07:00
Michael Bucari-Tovo 4766ea7372 Improve NRE safety for quick filters 2025-02-27 10:10:26 -07:00
Michael Bucari-Tovo d195dd07dc Remove upload-release-assets package (out of support) 2025-02-27 09:30:08 -07:00
Michael Bucari-Tovo bcbb7610ad Refactor GetAllEntries methods for clarity and maintainability
d
2025-02-27 09:00:26 -07:00
Michael Bucari-Tovo 6c5773df24 Fix stack overflow exception when updating large databases (#1158) 2025-02-26 14:41:59 -07:00
rmcrackan 211f15af25 Update InstallOnMac.md 2025-02-25 10:03:11 -05:00
Robert McRackan e3b0f80016 incr ver: 12.0 2025-02-24 12:05:24 -05:00
Robert McRackan 7b2c7e49e5 fix unit tests 2025-02-23 11:11:25 -05:00
Robert McRackan 6a40d19393 Fix unit tests 2025-02-23 10:28:09 -05:00
Robert McRackan 3167744111 #1151 : default character replacement for colon is _ 2025-02-23 10:13:15 -05:00
Robert McRackan b6a3ba335a Merge branch 'master' of https://github.com/rmcrackan/Libation 2025-02-22 22:54:12 -05:00
Robert McRackan fa1ddc726a #1151 - unicode colon is causing issues with Windows Chardonnay 2025-02-22 22:54:00 -05:00
rmcrackan b3b0662dec Update InstallOnMac.md
Apple can’t check app for malicious software
2025-02-19 17:09:26 -05:00
Robert McRackan 5cb22cfd24 Update AAXClean.Codecs 2025-02-17 20:07:50 -05:00
Michael Bucari-Tovo e911344850 Workaround for DataGridView filtering internal NullReferenceException 2025-02-10 10:20:18 -07:00
Michael Bucari-Tovo 8ec7e5a9d2 Revert "DataGridView filtering internal NullReferenceException **HACK**"
This reverts commit e1f749c3da.
2025-02-10 10:19:24 -07:00
Robert McRackan e1f749c3da DataGridView filtering internal NullReferenceException **HACK** 2025-02-10 11:23:27 -05:00
Robert McRackan ba060d15aa Merge branch 'master' of https://github.com/rmcrackan/Libation 2025-02-10 09:12:32 -05:00
Robert McRackan 93fde236c8 format for clarity 2025-02-10 09:12:29 -05:00
Michael Bucari-Tovo 13aad1a7cb Restrict audio sample rate settings to allowed values (#1116) 2025-01-16 10:35:58 -07:00
rmcrackan 65c64c4504 Update Docker.md 2025-01-13 09:28:55 -05:00
rmcrackan 14ba04c28b Update Docker.md 2025-01-13 09:26:52 -05:00
rmcrackan 96e886d207 Update FrequentlyAskedQuestions.md
Brazil login
2025-01-08 10:04:55 -05:00
Robert McRackan c7279574a9 Upgrade avalonia 2025-01-07 08:00:35 -05:00
rmcrackan a522e1ff7e Merge pull request #1072 from shuvashish76/patch-1
Update InstallOnLinux.md with repology badge
2024-12-08 08:56:32 -05:00
shuvashish76 9ebc4444bd Update InstallOnLinux.md 2024-12-07 06:24:34 +00:00
shuvashish76 525afdf050 Update InstallOnLinux.md 2024-12-07 06:03:46 +00:00
shuvashish76 983cdf6ad5 Update InstallOnLinux.md with repology badge 2024-12-07 05:38:35 +00:00
Robert McRackan 09bb32a435 incr ver 2024-12-06 13:10:37 -05:00
rmcrackan 817ef33fbd Merge pull request #1071 from pixil98/master
update docker image to dotnet 9
2024-12-06 13:07:39 -05:00
Aaron Reisman be52b496a6 Update docker image to .net 9 2024-12-06 10:29:47 -06:00
Robert McRackan c0c99db6fa Incr ver 2024-12-05 14:54:16 -05:00
rmcrackan a1c8fb5921 Merge pull request #1066 from Mbucari/master
Fix chardonnay window closing (#1065)
2024-12-05 14:53:11 -05:00
MBucari 4576c0e193 Updata Avalonia to 11.2.2 2024-12-04 19:12:59 -07:00
MBucari d592e9435e Fix main window closing when dialog is closed (#1065) 2024-12-04 19:11:36 -07:00
Robert McRackan 9ce6cb54ab incr ver 2024-11-22 17:18:39 -05:00
Robert McRackan c15d49fc64 publish profiles => .net 2024-11-22 17:04:08 -05:00
Robert McRackan 99be869aa9 yaml => .net9 2024-11-22 16:56:16 -05:00
Robert McRackan a0e875a79c Merge branch 'master' of https://github.com/rmcrackan/Libation 2024-11-22 16:49:09 -05:00
Robert McRackan 6134becc70 Upgrade to .net9 2024-11-22 16:47:59 -05:00
rmcrackan eadf7cff79 Merge pull request #1050 from stickystyle/patch-1
set maxdepth to prevent traversal into subdirectories
2024-11-20 13:13:58 -05:00
Ryan Parrish 87ca76f9cb set maxdepth to prevent traversal into subdirectories 2024-11-20 11:32:02 -05:00
Robert McRackan 43d1019059 * Bug fix #1048: docker: Error when using SLEEP_TIME - "integer expression expected"
Thanks @charltonstanley !
2024-11-19 06:40:51 -05:00
Robert McRackan ed87ded77a Docker deployment fix 2024-11-14 22:51:02 -05:00
rmcrackan 56d4205360 Merge pull request #1042 from pixil98/master
Exclude docker build report artifact from release packing
2024-11-14 22:50:26 -05:00
Aaron Reisman 1f839606ae Add a pattern to exclude docker build artifact from release 2024-11-14 16:33:30 -06:00
Robert McRackan 6eebe652d4 Docker changes => pre-release 2024-11-14 15:22:28 -05:00
rmcrackan 5fff22a0e1 Merge pull request #1011 from pixil98/master
Run docker image as non-root user
2024-11-14 15:19:36 -05:00
Aaron Reisman cd7040cdc7 pretty up the workflows 2024-11-14 11:18:16 -06:00
Aaron Reisman 97b792868f Update documentation with new envvars 2024-11-14 10:54:35 -06:00
pixil98 984f931f67 Merge branch 'rmcrackan:master' into master 2024-11-14 01:04:16 -06:00
Aaron Reisman e0dd9b845a rework database handling 2024-11-14 00:59:28 -06:00
rmcrackan f1c8b320c2 Merge pull request #1039 from jwillikers/fix-metadata
Fix metainfo validation
2024-11-13 21:09:45 -05:00
Jordan Williams 9b7d0cd909 Fix metainfo validation 2024-11-13 15:14:14 -06:00
rmcrackan 99592ff84e Merge pull request #1036 from jwillikers/flatpak-files
Add some necessary files for the Flatpak
2024-11-13 15:36:18 -05:00
Jordan Williams f97cfe77f9 Add CI to validate the desktop file and appstream metainfo 2024-11-10 15:09:56 -06:00
Jordan Williams 2954cb961b Add metainfo and screenshots 2024-11-10 14:05:24 -06:00
Jordan Williams 1e29b98b82 Add categories and keywords to the desktop file 2024-11-10 14:05:24 -06:00
Robert McRackan 8b76da0dbe incr ver 2024-10-25 15:05:08 -04:00
Mbucari 0a749d2d88 Update Bundle_MacOS.sh 2024-10-25 10:51:56 -06:00
Aaron Reisman 9ed6c1fd0d cleanup 2024-10-22 10:07:37 -05:00
Aaron Reisman 9825e2b552 Build both platforms in one action 2024-10-22 09:27:00 -05:00
Aaron Reisman 011efe3676 remove unused configure step 2024-10-22 00:39:35 -05:00
Aaron Reisman 2bdcc221f5 Specify platform(?) 2024-10-22 00:28:27 -05:00
pixil98 21bedca367 Merge branch 'rmcrackan:master' into master 2024-10-21 23:55:31 -05:00
Aaron Reisman 074fe79ded Update docker workflow to try building on validate 2024-10-21 17:13:08 -05:00
Aaron Reisman ac8c090c4c Rework run script to support db mount better 2024-10-21 14:02:52 -05:00
Aaron Reisman ade693bebb Update docker readme 2024-10-19 01:54:37 -05:00
Aaron Reisman 9bc53e45cd large overhaul of docker run script 2024-10-19 01:31:03 -05:00
Aaron Reisman 7d4eaa11e7 Run docker image as non-root user 2024-10-18 00:13:19 -05:00
Robert McRackan 4521c5d5ed incr ver 2024-10-16 12:04:04 -04:00
rmcrackan eb39f994e1 Merge pull request #1006 from cbordeman/Friendly-name-filters-995
Fixed bug in main view quick filter binding.
2024-10-16 08:03:44 -04:00
Chris Bordeman c19833b34e Fixed bug in main view quick filter binding. 2024-10-15 21:46:22 -04:00
Robert McRackan 6dcf456d06 fix ver 2024-10-15 13:20:58 -04:00
rmcrackan 8a87462cf5 Merge pull request #997 from cbordeman/Friendly-name-filters-995
Implemented Name on Quick Filters.
2024-10-15 13:09:38 -04:00
Chris Bordeman 9da2a44eff Small fix 2024-10-15 00:13:40 -04:00
Chris Bordeman 7af8d8aa70 Remove some warnings. 2024-10-15 00:07:57 -04:00
Chris Bordeman 4801f37e7c Moved QuickFilters migration to AppScaffolding. 2024-10-14 23:59:05 -04:00
rmcrackan 4f5df44d40 Merge pull request #999 from cbordeman/Add-default-theme-setting
Implemented "System" option for theme.
2024-10-14 15:09:21 -04:00
Chris Bordeman 63e28b13c1 Implemented "System" option for theme. 2024-10-12 02:17:35 -04:00
Chris Bordeman f92b2b65b2 Implemented Name on Quick Filters. 2024-10-11 05:45:04 -04:00
rmcrackan f7a4a95e3b Merge pull request #994 from cbordeman/master
Disable shrink/expand on mouseover for all scrollbars.
2024-10-10 07:38:24 -04:00
Chris Bordeman 71b8e9e51c Disable shrink/expand on mouseover for all scrollbars. 2024-10-10 02:22:36 -04:00
Robert McRackan c6788ccb48 typo 2024-09-25 10:12:01 -04:00
Robert McRackan 0503ee1404 incr ver 2024-09-18 08:17:35 -04:00
rmcrackan 303192c6c3 Merge pull request #978 from muchtall/allow-UseCoverAsFolderIcon-on-linux
Allow Non-Windows installations to populate Windows folder artwork
2024-09-18 08:15:05 -04:00
muchtall 6e21e96aa2 Allow Non-Windows installations to populate Windows folder artwork (https://github.com/rmcrackan/Libation/issues/977) 2024-09-16 19:42:26 +00:00
Robert McRackan d1d0a7e487 db migration for IsFinished 2024-09-11 07:56:18 -04:00
Robert McRackan 2fd8ea91e1 New search field: Finished/IsFinished.
All work complete except db migration
2024-09-11 07:45:37 -04:00
Robert McRackan 92ee0b2e6d update dependencies 2024-09-11 07:20:54 -04:00
Robert McRackan f0b5ae1cdc New filter option: IsInSeries, InSeries 2024-09-09 14:22:05 -04:00
Robert McRackan eb659cc7d7 typo 2024-09-09 08:31:55 -04:00
Robert McRackan cdd5f229d3 incr ver 2024-09-05 09:12:19 -04:00
Robert McRackan 29edfb7c3f Merge branch 'master' of https://github.com/rmcrackan/Libation 2024-09-05 09:07:54 -04:00
Robert McRackan c0cb454d45 Make recursive file enumerations safer 2024-09-05 09:07:47 -04:00
rmcrackan 970a77c9e9 Merge pull request #946 from rmcrackan/dependabot/nuget/Source/LibationUiBase/SixLabors.ImageSharp-3.1.5
Bump SixLabors.ImageSharp from 3.1.4 to 3.1.5 in /Source/LibationUiBase
2024-07-22 14:05:40 -04:00
dependabot[bot] 3488c8e0f5 Bump SixLabors.ImageSharp from 3.1.4 to 3.1.5 in /Source/LibationUiBase
Bumps [SixLabors.ImageSharp](https://github.com/SixLabors/ImageSharp) from 3.1.4 to 3.1.5.
- [Release notes](https://github.com/SixLabors/ImageSharp/releases)
- [Commits](https://github.com/SixLabors/ImageSharp/compare/v3.1.4...v3.1.5)

---
updated-dependencies:
- dependency-name: SixLabors.ImageSharp
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-22 17:45:08 +00:00
rmcrackan 5133720cc8 InstallOnMac.md updated instructions 2024-06-30 07:22:38 -04:00
rmcrackan 4150746f45 InstallOnMac.md typo 2024-06-29 08:08:57 -04:00
Robert McRackan 3a95e1e72f incr ver 2024-06-26 08:00:48 -04:00
rmcrackan c74e26e1af Update release.yml
Release titles: don't include "v" in front of version number
2024-06-26 07:54:11 -04:00
rmcrackan ae54c95d46 Update docker.yml
Rolling back docker build push action to attempt to fix build
2024-06-26 07:51:00 -04:00
Robert McRackan 56e6bd164b By user request, other Serilog.Sink packages are included for experimental use 2024-06-26 07:07:49 -04:00
rmcrackan 9b28bdceaa Merge pull request #923 from rmcrackan/dependabot/github_actions/docker/build-push-action-6
Bump docker/build-push-action from 5 to 6
2024-06-17 16:33:34 -04:00
dependabot[bot] b7f7d9004d Bump docker/build-push-action from 5 to 6
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 5 to 6.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v5...v6)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-17 14:23:33 +00:00
rmcrackan 1be0991e62 Add Audibly to FAQ 2024-06-07 13:27:18 -04:00
rmcrackan ff8a2e59c5 Update FrequentlyAskedQuestions.md 2024-05-27 11:48:48 -04:00
Robert McRackan 453904261b Bug fix. Audible's api acts weird when page count gets to ~400 2024-05-16 07:53:19 -04:00
Robert McRackan f9340db90a update references. audible api bugfix 2024-05-15 06:55:25 -04:00
Robert McRackan 5cd329dd26 refactor 2024-05-13 15:23:37 -04:00
Robert McRackan b2a882b79d Bug fix #904 -- navigation bug with new Accessibility feature 2024-05-13 15:17:17 -04:00
Robert McRackan 75df78a2f7 Add OSVersion to logs 2024-05-13 14:01:34 -04:00
Robert McRackan 3ad52cbecc docker to .net8 2024-05-09 10:01:38 -04:00
Robert McRackan 27b2fe741c Add accessibility 2024-05-07 10:39:30 -04:00
Robert McRackan d19fe2250c Add accessibility text to grid stoplight buttons 2024-05-06 21:56:00 -04:00
Robert McRackan d16d0c8de2 Merge branch 'master' of https://github.com/rmcrackan/Libation 2024-05-05 16:24:07 -04:00
Robert McRackan c213d5d9f6 Attempt to solve networking issue by disabling ipv6 2024-05-05 16:24:00 -04:00
rmcrackan c73a023572 Update FrequentlyAskedQuestions.md 2024-04-30 22:42:34 -04:00
rmcrackan 67389917fd Merge pull request #879 from rmcrackan/dependabot/nuget/Source/LibationUiBase/SixLabors.ImageSharp-3.1.4
Bump SixLabors.ImageSharp from 3.1.3 to 3.1.4 in /Source/LibationUiBase
2024-04-15 17:03:13 -04:00
dependabot[bot] b3264d5f42 Bump SixLabors.ImageSharp from 3.1.3 to 3.1.4 in /Source/LibationUiBase
Bumps [SixLabors.ImageSharp](https://github.com/SixLabors/ImageSharp) from 3.1.3 to 3.1.4.
- [Release notes](https://github.com/SixLabors/ImageSharp/releases)
- [Commits](https://github.com/SixLabors/ImageSharp/compare/v3.1.3...v3.1.4)

---
updated-dependencies:
- dependency-name: SixLabors.ImageSharp
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-15 20:27:24 +00:00
Robert McRackan 962d9b550f "Unable to load module" should just be a warning, not error 2024-04-15 08:03:49 -04:00
Robert McRackan 91ce7272ae Bug fix #874 : Chardonnay wasn't allowing custom directories ending in "Books" 2024-04-04 08:13:37 -04:00
rmcrackan 2f64ca6856 Merge pull request #870 from ScubyG/patch-1
Update InstallOnLinux.md
2024-03-22 07:37:00 -04:00
Davy Jones cfe5db436c Update InstallOnLinux.md
Fixed typo
2024-03-22 01:23:52 +00:00
rmcrackan 3653fc8094 Merge pull request #863 from rmcrackan/dependabot/github_actions/softprops/action-gh-release-2
Bump softprops/action-gh-release from 1 to 2
2024-03-11 10:45:44 -04:00
dependabot[bot] 662c0ec871 Bump softprops/action-gh-release from 1 to 2
Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 1 to 2.
- [Release notes](https://github.com/softprops/action-gh-release/releases)
- [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)
- [Commits](https://github.com/softprops/action-gh-release/compare/v1...v2)

---
updated-dependencies:
- dependency-name: softprops/action-gh-release
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-11 14:20:12 +00:00
rmcrackan 44d39eabdb Merge pull request #861 from rmcrackan/dependabot/nuget/Source/LibationUiBase/SixLabors.ImageSharp-3.1.3
Bump SixLabors.ImageSharp from 3.1.2 to 3.1.3 in /Source/LibationUiBase
2024-03-05 11:45:59 -05:00
dependabot[bot] a0550d5c97 Bump SixLabors.ImageSharp from 3.1.2 to 3.1.3 in /Source/LibationUiBase
Bumps [SixLabors.ImageSharp](https://github.com/SixLabors/ImageSharp) from 3.1.2 to 3.1.3.
- [Release notes](https://github.com/SixLabors/ImageSharp/releases)
- [Commits](https://github.com/SixLabors/ImageSharp/compare/v3.1.2...v3.1.3)

---
updated-dependencies:
- dependency-name: SixLabors.ImageSharp
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-05 16:38:00 +00:00
Robert McRackan 14eaca6d45 Update dependency. Security update 2024-03-05 11:36:36 -05:00
Robert McRackan 93ccc206ef Update dependencies 2024-03-04 14:02:42 -05:00
Robert McRackan d3f0fd711e Remove validation check: SeriesName is null . At least 1 exception found in the wild 2024-02-29 14:44:41 -05:00
rmcrackan 3f4604e877 Update FrequentlyAskedQuestions.md
reformat
2024-02-29 10:15:47 -05:00
rmcrackan c316709af8 Update FrequentlyAskedQuestions.md
Classic vs Chardonnay
2024-02-29 10:15:01 -05:00
Robert McRackan 221d5c7f1c paypal link 2024-02-19 10:32:26 -05:00
Robert McRackan 5a86a1a27b Typo 2024-02-13 21:42:24 -05:00
rmcrackan dc5e55de68 Merge pull request #848 from patienttruth/master
Update Docker.md
2024-02-13 07:22:33 -05:00
patienttruth ee37864a42 Update Docker.md
Included an explanation that you may have to manually input the InProgress variable.
2024-02-13 06:49:33 +00:00
Robert McRackan efe347667c Better error reporting in audible api -- incl. inner exceptions 2024-01-20 21:44:29 -05:00
Robert McRackan f27a18bdbb Better error reporting in audible api 2024-01-19 09:30:48 -05:00
Robert McRackan d1834659d9 incr ver 2024-01-12 09:08:14 -05:00
Robert McRackan 7842b521d7 Update dependencies. Notes about upgrading 2024-01-12 07:44:40 -05:00
Robert McRackan 0822f0229d Revert Avalonia. Bug in 11.0.6 2024-01-04 10:03:33 -05:00
Robert McRackan 26aee4d29d Merge branch 'master' of https://github.com/rmcrackan/Libation 2024-01-03 11:43:59 -05:00
Robert McRackan 17a80a23a8 AAXClean upgrade to .net8 2024-01-03 11:43:45 -05:00
rmcrackan e26fc9ca62 Merge pull request #808 from rmcrackan/dependabot/github_actions/actions/download-artifact-4
Bump actions/download-artifact from 3 to 4
2023-12-15 09:50:25 -05:00
rmcrackan a03ccf1143 Merge pull request #807 from rmcrackan/dependabot/github_actions/actions/upload-artifact-4
Bump actions/upload-artifact from 3 to 4
2023-12-15 09:50:11 -05:00
dependabot[bot] bb8dd615db Bump actions/download-artifact from 3 to 4
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 3 to 4.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-15 14:08:26 +00:00
dependabot[bot] 9022a2889f Bump actions/upload-artifact from 3 to 4
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 3 to 4.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-15 14:08:20 +00:00
rmcrackan ef049a3b02 Merge pull request #805 from rmcrackan/dependabot/github_actions/actions/setup-dotnet-4
Bump actions/setup-dotnet from 3 to 4
2023-12-05 10:01:34 -05:00
dependabot[bot] 77409750aa Bump actions/setup-dotnet from 3 to 4
Bumps [actions/setup-dotnet](https://github.com/actions/setup-dotnet) from 3 to 4.
- [Release notes](https://github.com/actions/setup-dotnet/releases)
- [Commits](https://github.com/actions/setup-dotnet/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/setup-dotnet
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-05 14:14:17 +00:00
Robert McRackan 1702130b01 Upgrade to .net8 2023-11-15 19:57:39 -05:00
Robert McRackan b6d1a7e3ba Upgrade to .net8 2023-11-15 19:53:26 -05:00
Robert McRackan 2907ba5c13 Add FAQ 2023-10-20 08:27:20 -04:00
Robert McRackan 6df6c79ac8 New locale: Brazil 2023-10-18 22:33:24 -04:00
rmcrackan 3a9ca5d827 Merge pull request #779 from rmcrackan/dependabot/github_actions/dwenegar/upload-release-assets-2
Bump dwenegar/upload-release-assets from 1 to 2
2023-10-13 14:41:26 -04:00
dependabot[bot] e1e663e327 Bump dwenegar/upload-release-assets from 1 to 2
Bumps [dwenegar/upload-release-assets](https://github.com/dwenegar/upload-release-assets) from 1 to 2.
- [Release notes](https://github.com/dwenegar/upload-release-assets/releases)
- [Commits](https://github.com/dwenegar/upload-release-assets/compare/v1...v2)

---
updated-dependencies:
- dependency-name: dwenegar/upload-release-assets
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-13 14:37:55 +00:00
Robert McRackan 4b00d5fd84 incr ver 2023-09-18 13:58:23 -04:00
rmcrackan 02dbf8aad0 Merge pull request #751 from Mbucari/master
Minor Bug Fixes
2023-09-18 13:56:53 -04:00
rmcrackan 8326389f5c Merge pull request #732 from rmcrackan/dependabot/github_actions/actions/checkout-4
Bump actions/checkout from 3 to 4
2023-09-18 13:56:33 -04:00
dependabot[bot] 34535b3ce1 Bump actions/checkout from 3 to 4
Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-18 17:33:43 +00:00
rmcrackan 7e5366ab95 Merge pull request #738 from rmcrackan/dependabot/github_actions/docker/setup-buildx-action-3
Bump docker/setup-buildx-action from 2 to 3
2023-09-18 13:30:24 -04:00
dependabot[bot] 690de9bc5c Bump docker/setup-buildx-action from 2 to 3
Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 2 to 3.
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](https://github.com/docker/setup-buildx-action/compare/v2...v3)

---
updated-dependencies:
- dependency-name: docker/setup-buildx-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-18 17:25:20 +00:00
rmcrackan c976aa2bb2 Merge pull request #739 from rmcrackan/dependabot/github_actions/docker/login-action-3
Bump docker/login-action from 2 to 3
2023-09-18 13:25:07 -04:00
rmcrackan 27f659285d Merge pull request #740 from rmcrackan/dependabot/github_actions/docker/build-push-action-5
Bump docker/build-push-action from 4 to 5
2023-09-18 13:24:55 -04:00
rmcrackan 423a5e7720 Merge pull request #741 from rmcrackan/dependabot/github_actions/docker/setup-qemu-action-3
Bump docker/setup-qemu-action from 2 to 3
2023-09-18 13:24:44 -04:00
Michael Bucari-Tovo 9152e12fe1 Fix #748 2023-09-18 10:14:54 -06:00
Michael Bucari-Tovo f471c53139 Fix #734 2023-09-18 10:08:15 -06:00
dependabot[bot] 66d055bb90 Bump docker/setup-qemu-action from 2 to 3
Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 2 to 3.
- [Release notes](https://github.com/docker/setup-qemu-action/releases)
- [Commits](https://github.com/docker/setup-qemu-action/compare/v2...v3)

---
updated-dependencies:
- dependency-name: docker/setup-qemu-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-12 14:50:49 +00:00
dependabot[bot] 2bbb35363a Bump docker/build-push-action from 4 to 5
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 4 to 5.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v4...v5)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-12 14:50:46 +00:00
dependabot[bot] 1d3687cf9e Bump docker/login-action from 2 to 3
Bumps [docker/login-action](https://github.com/docker/login-action) from 2 to 3.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/v2...v3)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-12 14:50:42 +00:00
Mbucari daf925157f Update AppScaffolding.csproj 2023-09-02 07:59:30 -06:00
Mbucari 40eec9e674 Merge pull request #730 from Mbucari/master
Fix #729
2023-09-01 18:46:42 -06:00
MBucari 6f0782053e Restore PDF functionality (#729) 2023-09-01 16:30:35 -06:00
Michael Bucari-Tovo 04ad033ba0 Remove appsettings.json from program files dir 2023-08-31 09:36:38 -06:00
Robert McRackan f12f8ba3ee incr ver 2023-08-30 15:00:20 -04:00
rmcrackan cc6feb21ff Merge pull request #728 from Mbucari/master
Minor Bug fixes
2023-08-30 14:46:16 -04:00
Michael Bucari-Tovo c4f2ec428d Allow Settings form resizing 2023-08-30 12:38:28 -06:00
Michael Bucari-Tovo 59689cb647 Update Dependencies 2023-08-30 11:59:40 -06:00
Michael Bucari-Tovo d7f3758ebc Add support for environment variables and unix shortcuts in appsettings.json path. 2023-08-30 11:47:50 -06:00
Mbucari 49775b019c Update InstallOnMac.md 2023-08-30 09:06:57 -06:00
Michael Bucari-Tovo e55e969349 Fix issue with save button being disabled. 2023-08-30 08:59:20 -06:00
Mbucari 42a93bfac1 Update AAXClean 2023-08-27 19:47:32 -06:00
Mbucari f86c77a546 Create directory before trying to create appsettings.json 2023-08-27 19:47:00 -06:00
MBucari 88c35e2a56 Add scrolling view to settings window panels (#720) 2023-08-23 20:25:30 -06:00
MBucari b405e8b6b2 Remove unised response groups 2023-08-20 11:40:24 -06:00
MBucari 92d283187d Add support for locating mp3 audiobooks 2023-08-20 11:38:43 -06:00
Robert McRackan 51b8cfe71f incr ver 2023-08-17 14:03:40 -04:00
rmcrackan c80da5357b Merge pull request #716 from Mbucari/master
Fix NRE when item has no category ladders (#715)
2023-08-17 14:02:43 -04:00
Michael Bucari-Tovo 736d7c4a5f Fix NRE when item has no category ladders (#715) 2023-08-17 11:55:28 -06:00
Robert McRackan f175b7592e incr major ver 2023-08-12 21:45:11 -04:00
rmcrackan 415e6e7bc6 Merge pull request #710 from Mbucari/master
Batch of Fixxed Issues
2023-08-12 21:20:37 -04:00
MBucari d6a413e8d9 Update Avalonia to 11.0.3 2023-08-12 17:30:08 -06:00
Mbucari 3049de6246 Merge branch 'rmcrackan:master' into master 2023-08-12 17:20:09 -06:00
MBucari fb9b4eb77e Update audio duration on library scan (#707) 2023-08-12 17:19:56 -06:00
MBucari e65b6c76a8 Add ability to preview templates on user's books (#700)
Add template editor menu items to main grid context menu
2023-08-12 17:12:50 -06:00
Mbucari 167a021eb1 Change glass icon shading 2023-08-11 10:55:31 -06:00
Mbucari ff3ac2d6fd Fix MessageBox crash when UI has no Screens (#708) 2023-08-11 09:04:05 -06:00
Robert McRackan f733079a49 remove Moq 2023-08-10 15:24:43 -04:00
Mbucari 893d68190d Lazy load cover to improve startup time 2023-08-10 10:18:28 -06:00
Mbucari 97f94d8782 Add custom column widths to chardonnay 2023-08-07 15:54:50 -06:00
Mbucari 4b2ce0c2d1 Brighter stoplight colors (#702) 2023-08-07 11:31:22 -06:00
Mbucari ee00417c6f Add white glow to libation_glass.svg (#701) 2023-08-07 11:31:03 -06:00
Robert McRackan 768afd8ecd incr ver 2023-08-04 11:57:15 -04:00
rmcrackan 32c3fa85ce Merge pull request #699 from Mbucari/master
Fix broken template editor (#698)
2023-08-04 11:55:30 -04:00
Mbucari 6986c8f018 Fix broken template editor (#698) 2023-08-04 09:26:51 -06:00
Robert McRackan f69c2b1cfc incr ver 2023-08-02 21:55:19 -04:00
rmcrackan b11675c36a Merge pull request #696 from Mbucari/master
Bug fixes
2023-08-02 21:52:57 -04:00
Mbucari 379c2ed62d Fix account nickname retrieval (#629) 2023-08-02 13:54:49 -06:00
Mbucari 7c8489b52f Fix walkthrough causing freeze (#695) 2023-08-02 13:15:58 -06:00
rmcrackan c61a863edd Merge pull request #694 from Mbucari/master
Fix DPI scaling bug (#692)
2023-08-01 15:03:21 -04:00
Mbucari 1d54f32ef3 Fix DPI scaling bug (#692) 2023-08-01 11:55:23 -06:00
rmcrackan fabe4afd94 Merge pull request #691 from Mbucari/master
Fix #686 and enable nullable in FileManager and LibationFileManager
2023-07-30 20:22:55 -04:00
MBucari 61efa3c0c1 Update dependencies 2023-07-30 14:00:12 -06:00
MBucari fe70daf0bc Update avalonia to v11.0.1 2023-07-30 13:54:44 -06:00
MBucari 34033e7947 Enable Nullable 2023-07-30 13:31:57 -06:00
MBucari e8c63e9a6e Fix UI control overlapping label (#686) 2023-07-30 13:15:43 -06:00
Robert McRackan 9315165f80 update dependencies 2023-07-21 21:21:48 -04:00
Robert McRackan ce624399ba incr ver 2023-07-19 07:48:11 -04:00
rmcrackan 63e9700c4a Merge pull request #682 from Mbucari/master
Fix #680 and Add category ladders
2023-07-19 07:46:05 -04:00
Mbucari 914e574bf8 Improve GridView
- Remove LongDescription
- Description has the full description
- Better MyRating updating
2023-07-18 16:18:01 -06:00
Mbucari b94f9bbc15 Fix grid update bug 2023-07-18 16:11:22 -06:00
Mbucari 4e34834c35 Fix category search indexing 2023-07-18 16:00:06 -06:00
Mbucari 3211b2dc85 Improved Category Ladders 2023-07-18 15:51:02 -06:00
Mbucari ea6adeb58f Add category ladders 2023-07-17 16:50:45 -06:00
Mbucari 90eccbf2f6 Fix FilePathCache NRE (#680) 2023-07-17 08:55:55 -06:00
rmcrackan 668cd7dba8 Merge pull request #679 from Mbucari/master
Mp3 embedded cuesheet and raw metadata
2023-07-16 14:32:49 -04:00
MBucari c08b2b575c UI Tweak 2023-07-16 10:57:17 -06:00
MBucari 07eaa48e10 Save raw json metadata 2023-07-16 10:54:05 -06:00
MBucari 3cf5fc1d99 Add mp3 embedded cuesheet (#677) 2023-07-15 10:44:31 -06:00
Robert McRackan 15ad753fa1 update dependencies 2023-07-14 20:58:26 -04:00
rmcrackan 75b984bdb2 Merge pull request #678 from Mbucari/master
Fix quick filter not being applied on startup
2023-07-14 20:53:57 -04:00
Mbucari f586d1d59f Fix quick filter not being applied on startup 2023-07-13 11:00:05 -06:00
Mbucari cb91a591f0 inc ver 2023-07-13 09:58:45 -06:00
Mbucari 0c0c556c6a Merge pull request #674 from Mbucari/master
Fix #673
2023-07-13 09:31:28 -06:00
MBucari ff63b73c09 Fix #673 2023-07-13 09:30:02 -06:00
Mbucari c1d56adbd2 Add groupbox title 2023-07-12 21:29:00 -06:00
rmcrackan bcd99fd208 Merge pull request #670 from Mbucari/master
Add products grid scaling setting
2023-07-12 21:10:51 -04:00
Mbucari d1df10d060 Add products grid scaling setting
- Add Grid Scaling Settings
- Add WinForms DPI migration to remove stored form sizes
- Add textbox clear button
2023-07-12 15:32:37 -06:00
Mbucari 1fa415628f Update ProductsGrid.cs 2023-07-10 11:39:33 -06:00
rmcrackan a83fe9e532 Merge pull request #667 from Mbucari/master
Fix setting Panel2MinSize min width bug (#666)
2023-07-10 11:19:45 -04:00
Mbucari f85462ffec Fix setting Panel2MinSize min width bug (#666) 2023-07-10 09:11:38 -06:00
Robert McRackan 156349c293 incr ver 2023-07-10 09:26:26 -04:00
rmcrackan 5976706e40 Merge pull request #664 from Mbucari/startup-2
New settings, context menu, and performance improvements
2023-07-10 09:25:13 -04:00
Mbucari 1e40180f0c Fix unit test 2023-07-09 16:42:08 -06:00
Mbucari 7d09728e6b Add Re-download context menu item 2023-07-09 16:26:58 -06:00
Mbucari 4899ef3007 Add new settings and settings dialog help tips
Add CombineNestedChapterTitles setting (#663)
Add SaveMetadataToFile setting
Add extended setting descriptions for select options
2023-07-09 16:07:13 -06:00
Mbucari 296c2b43eb Remove extra library load and move comments to Main 2023-07-09 10:10:00 -06:00
Mbucari 932472cb91 Add full context menu to call columns 2023-07-09 09:53:28 -06:00
Mbucari 1bf86b05ec Download high quality cover art 2023-07-09 09:35:40 -06:00
Mbucari 5d5e3a6671 improve startup time 2023-07-09 09:23:58 -06:00
Robert McRackan 9720a573c7 incr ver 2023-07-07 20:27:57 -04:00
rmcrackan 1cf01aa92a Merge pull request #660 from Mbucari/master
Crash logging to chardonnay
2023-07-07 20:27:09 -04:00
Mbucari 4df9e5abbf Add unhandled error handling and crash logging to chardonnay 2023-07-07 14:14:12 -06:00
Mbucari 9243aa47e7 Upgrade Avalonia to v11.0.0 2023-07-07 14:13:54 -06:00
rmcrackan c69f41a2a6 Merge pull request #659 from Mbucari/master
Fix classic scaling on high dpi displays
2023-07-07 08:06:22 -04:00
Mbucari 27c74e52ca Fix classic scaling on high dpi displays 2023-07-06 21:34:29 -06:00
Robert McRackan bfa7f5cca9 Bug fix #657 : Settings dialog size was recently changed. Save and Cancel buttons were pushed outside of the dialog's bounds 2023-07-06 09:27:52 -04:00
rmcrackan 22a3dcbc1f Merge pull request #656 from Mbucari/master
Fix query parsing tags with underscores (#655)
2023-07-06 09:16:20 -04:00
Mbucari ec9d11cf52 Fix query parsing tags with underscores (#655) 2023-07-05 15:47:37 -06:00
Mbucari fbc29dfb0a Set Variety correctly 2023-07-04 09:58:39 -06:00
Robert McRackan 03d30ff6af incr. ver. 2023-07-03 22:06:00 -04:00
rmcrackan ecfe0dc033 Merge pull request #651 from Mbucari/master
Overhaul LibationCli and add Download Quality Option
2023-07-03 21:57:04 -04:00
Mbucari f2d475a9b0 Add audiobookshelf tags for m4b and mp3
Fix the following tag fields so they are correctly parsed and displayed in audiobookshelf:
Language
Publisher
Series name and number
ASIN
2023-07-03 15:57:11 -06:00
Mbucari 86124fc609 Address comments 2023-07-03 10:01:25 -06:00
Mbucari db2b10d2a4 Performance improvement 2023-07-03 07:04:29 -06:00
Mbucari 83402028fd Update Avalonia 2023-07-02 19:27:58 -06:00
Mbucari 423b5312f7 Add setting to choose downloaded audio quality ((#648) 2023-07-02 19:19:28 -06:00
Mbucari 3be7d8e825 Minor cli edits and fix potential deadlock 2023-07-02 18:29:36 -06:00
Mbucari 29803c6ba0 Overhaul LibationCli
Add version verb with option to check for upgrade
Add Search verb to search the library
Add export file type inference
Add more set-status options
Add console progress bar and ETA
Add processable option to liberate specific book IDs
Scan accounts by nickname or account ID
Improve startup performance for halp and on parsing error
More useful error messages
2023-07-02 15:01:10 -06:00
Mbucari bb05847b25 Improve finding audio file by ID 2023-07-02 14:08:27 -06:00
Robert McRackan 5219ad53e1 incr ver 2023-07-01 21:34:36 -04:00
Mbucari 30aa691aae Merge pull request #646 from Alanoll/feat-add-book-subtitles
feat: add Book subtitle capturing so TitleShort reflects titles better
2023-07-01 12:47:03 -05:00
Mbucari 83fa73cef5 Integrate new Title and Subtitle properties into Libation 2023-06-29 21:06:54 -06:00
Alanoll 2195574422 feat: add Book subtitle capturing so TitleShort reflects titles better 2023-06-26 12:18:15 -05:00
Robert McRackan 74ce408c8b incr ver 2023-06-25 21:27:59 -04:00
rmcrackan 85be15b843 Merge pull request #642 from Mbucari/master
Bug fixes and minor features
2023-06-25 21:26:24 -04:00
MBucari b4b85cd485 Change the default file timestamp source 2023-06-25 17:28:26 -06:00
Mbucari 0093968537 Merge branch 'rmcrackan:master' into master 2023-06-25 15:25:52 -06:00
MBucari 1b09b1fd48 Remove multispace instances from template filenames (#637) 2023-06-25 15:14:10 -06:00
MBucari ac87d70613 Add options to set file created/modified timestamps (#638) 2023-06-25 14:07:39 -06:00
MBucari a5d98364fa Enable auto-downloading (#636) 2023-06-25 11:12:52 -06:00
MBucari ca0e639a19 Commit account edits before saving (#639) 2023-06-25 11:11:58 -06:00
Robert McRackan b0e3022988 incr ver 2023-06-15 21:40:35 -04:00
rmcrackan 6765c2bfa7 Merge pull request #633 from Mbucari/master
User series order float (#632)
2023-06-15 21:38:02 -04:00
Mbucari 94d3742317 Update NamingTemplates.md 2023-06-15 12:33:58 -06:00
Mbucari bd3e833dc1 Use series order float (#632)
Add decimal formatter to number tag types
2023-06-15 10:42:36 -06:00
rmcrackan a386ace0e6 Update NamingTemplates.md
Add \<account nickname\>
2023-06-14 14:06:21 -04:00
rmcrackan 8221d7e202 Merge pull request #631 from Mbucari/master
Add features #626 and #627 and Fix #628
2023-06-14 14:03:24 -04:00
Robert McRackan fa92946d20 incr ver 2023-06-14 14:02:50 -04:00
Mbucari 6d13325c4f Add <account nickname> tag (#629) 2023-06-14 11:56:38 -06:00
Mbucari 7a9c6720c7 Fix Stupid 2023-06-14 11:35:11 -06:00
Mbucari 697f797509 Remove debug code 2023-06-14 11:16:53 -06:00
Mbucari ec9854212a Write error info to StdErr (#626) 2023-06-14 10:58:37 -06:00
Mbucari 46f6ba1710 Add feature #627 and fix bug #628
- Feature: Option to overwrite existing audio files when moving to Books
- Bugfix: Do not set liberated status if moving files fails.
2023-06-14 10:51:43 -06:00
rmcrackan 7347244f0a Merge pull request #630 from CLHatch/patch-1
Update Advanced.md
2023-06-14 07:17:45 -04:00
CLHatch c29c4c470c Update Advanced.md
M4B files use the `@wrt` instead of `TCOM` tag for "composer".
2023-06-14 02:33:49 -05:00
rmcrackan ee51fd9da6 Merge pull request #625 from Mbucari/master
Refactor LibationSearchEngine
2023-06-13 12:39:42 -04:00
Mbucari 2c4705de6e Address #625 comments and refactor 2023-06-13 09:05:17 -06:00
Mbucari b4aa220051 Refactor LibationSearchEngine 2023-06-12 14:02:55 -06:00
Robert McRackan 4ab6da132b Bug fix #621 2023-06-12 10:13:40 -04:00
Mbucari b006429a53 Fix #621 (#624) 2023-06-11 21:05:42 -06:00
Robert McRackan 54d157d244 another tag fail. incr ver 2023-06-11 17:07:03 -04:00
Robert McRackan a4dfdf80e4 Merge branch 'master' of https://github.com/rmcrackan/Libation 2023-06-11 17:03:55 -04:00
Robert McRackan d8c90bc745 incr ver 2023-06-11 17:03:35 -04:00
Mbucari 46accddd2d Merge pull request #623 from Mbucari/master
Redesign query sanitizer (#618)
2023-06-11 11:51:13 -06:00
Mbucari f40ecbc07e Merge branch 'rmcrackan:master' into master 2023-06-11 11:33:28 -06:00
Mbucari 536982cb5f Remove obsolete code 2023-06-11 09:44:30 -06:00
Mbucari ea3d96329b Add query sanitization unit tests 2023-06-11 09:44:21 -06:00
rmcrackan e87fcbb16f Update Settings documentation 2023-06-11 10:04:00 -04:00
Mbucari 541cf79b6f Redesign query sanitizer (#618) 2023-06-10 15:08:50 -06:00
Robert McRackan 55fa82f92e New incr ver. Previous Tag attempt did generate builds; did not draft a new release 2023-06-09 11:49:59 -04:00
Robert McRackan 4a0c2b2180 Bug fix #618 2023-06-09 11:27:40 -04:00
Mbucari c77fe5d561 Add Asin query tokenizer 2023-06-08 14:23:39 -06:00
Robert McRackan 359d082ffd incr ver 2023-06-03 15:06:12 -04:00
rmcrackan 017bdba404 Merge pull request #616 from Mbucari/master
Fix #612 and update Avalonia to v11-rc1
2023-06-03 15:04:56 -04:00
Mbucari d4bf13b3fd Update Hangover Avalonia to v11-rc1 2023-06-03 00:30:02 -06:00
Mbucari 87b695b2de Merge branch 'rmcrackan:master' into master 2023-06-03 00:01:10 -06:00
Mbucari 222b16113e Update NamingTemplates.md 2023-06-03 00:00:01 -06:00
Mbucari 75c07c3209 Fix SavePodcastsToParentFolder setting (#612) 2023-06-02 23:54:32 -06:00
Mbucari e640edee7f Use proper key name 2023-06-02 23:53:48 -06:00
Mbucari 6c48fc1f5e Update avalonia ro v11-RC1 2023-06-02 23:39:16 -06:00
Mbucari e5708a382b Use new synchronous UI invoker 2023-06-02 23:21:55 -06:00
Robert McRackan da9cb3371f incr ver 2023-05-23 13:06:09 -04:00
rmcrackan 91d0f8020e Merge pull request #606 from Mbucari/master
Corectly read and write locales
2023-05-23 13:04:35 -04:00
Mbucari 156726ca95 Corectly read and write locales 2023-05-23 09:41:28 -06:00
rmcrackan 3dad4c194b Update README.md 2023-05-20 23:12:23 -04:00
Mbucari 6025a7538a Merge pull request #604 from Mbucari/master
Fix rpm upgrade
2023-05-19 16:39:04 -06:00
Mbucari 824f65baae Fix rpm upgrade 2023-05-19 16:37:00 -06:00
Mbucari 9372a7318b inc ver 2023-05-19 13:46:26 -06:00
Mbucari ddd032c16d Fix null string in integer fields 2023-05-19 13:36:22 -06:00
Mbucari 9aaf523240 Update InstallOnMac.md 2023-05-19 13:07:33 -06:00
Mbucari 8cbdeb38fa Update InstallOnLinux.md 2023-05-19 13:05:29 -06:00
Mbucari a9258a1811 Update GettingStarted.md 2023-05-19 13:01:25 -06:00
Robert McRackan 0dbc42c407 incr ver 2023-05-19 14:43:17 -04:00
rmcrackan 2c91de1b3b Merge pull request #603 from Mbucari/master
New searches, new linux release, new Avalonia build
2023-05-19 14:23:05 -04:00
Mbucari 607cd07b74 Change IInteropFunctions.ReleaseIdentifier to ReleaseIdString 2023-05-19 12:08:22 -06:00
Mbucari 64d080336c Use correct package manager 2023-05-19 11:30:09 -06:00
Mbucari fd510861c6 Add AbsentFromLastScan (#601) LastDownloaded (#602) search 2023-05-19 11:09:57 -06:00
Mbucari 3fdfbb9e26 Improve episode sequence detection (#600) 2023-05-19 11:07:42 -06:00
Mbucari 3e74898dac Merge branch 'rmcrackan:master' into master 2023-05-19 09:31:47 -06:00
Mbucari d6fe3013ab RPM build 2023-05-19 09:30:11 -06:00
Robert McRackan 265794bae0 update dependencies 2023-05-19 11:24:47 -04:00
Mbucari 7586f7a159 Upgrade Avalonia to v11.0.0-preview8 2023-05-15 12:58:45 -06:00
Mbucari 5dfddfb549 Use avres DataGrid theme and only replace DataGridColumnHeader 2023-05-15 12:51:46 -06:00
Mbucari 98bb06378a Update Avalonia to v11.0.0-preview8 2023-05-15 10:54:56 -06:00
Robert McRackan 429367d21c incr ver 2023-04-17 21:39:18 -04:00
Mbucari ea9e36fd76 Merge pull request #588 from Mbucari/master
Use old activation bytes if present.
2023-04-17 19:34:26 -06:00
MBucari fe534b335b Update dependencies 2023-04-17 19:32:52 -06:00
MBucari 6db3a8fbf3 Use old activation bytes if present. 2023-04-17 16:09:47 -06:00
Robert McRackan 48c69a1339 Can log to zip files with new ZipFile sink 2023-04-15 15:55:53 -04:00
rmcrackan 1ab882f327 Merge pull request #587 from Mbucari/master
Serilog log to zip file
2023-04-15 15:53:41 -04:00
MBucari 019b110a8a Fix #585 2023-04-15 13:43:50 -06:00
MBucari 9e14169e15 Update dependencies 2023-04-15 13:39:43 -06:00
MBucari e08a68219d Add Serilog.Sinks.ZipFile to write logs into a zip file 2023-04-15 12:45:20 -06:00
Mbucari af24c6e07b Merge branch 'rmcrackan:master' into master 2023-04-15 10:58:06 -06:00
Robert McRackan e31847e669 Incr. ver. 2023-04-14 14:38:45 -04:00
Mbucari c4f55d2ad1 Change "Click here" link verbiage 2023-04-14 11:37:22 -06:00
rmcrackan 1439e38cb0 Merge pull request #584 from Mbucari/master
Web Browser Login for Windows
2023-04-14 13:33:23 -04:00
Mbucari 4456432116 Add WebLoginDialog for Windows Chardonnay 2023-04-13 19:16:32 -06:00
Mbucari df2936e0b6 Use WebLoginDialog as primary login method on Win10+ 2023-04-13 09:10:13 -06:00
Mbucari 53b5c1b902 Fix rare bug where episode may not sort beneath its parent 2023-04-11 14:43:01 -06:00
Mbucari 82fba7e752 Grid refresh performance and behavior improvements 2023-04-11 14:33:45 -06:00
rmcrackan 1a95f2923b Merge pull request #579 from Mbucari/master
Bug fixes and more shared code moved to UI base
2023-04-10 22:47:24 -04:00
Mbucari 1939aae81c Simplify and comment 2023-04-10 19:50:30 -06:00
Mbucari 9a663fda15 Filtering bugfix 2023-04-10 17:08:09 -06:00
Mbucari 84b2996102 Merge branch 'rmcrackan:master' into master 2023-04-10 16:17:24 -06:00
Mbucari af8e1cd5ef Change episode default sorting to SeriesOrder descending 2023-04-10 16:17:10 -06:00
Mbucari 8a1b375f0d Fix #574 (for realsies this time) 2023-04-10 15:00:32 -06:00
Mbucari 6800986f25 Update GridEntryBindingList to behave move like Chardonnay 2023-04-10 14:10:50 -06:00
Mbucari 6110b08d16 Fix typo 2023-04-10 13:05:50 -06:00
Mbucari 666b5d83df Move filter query and RowComparer into UI base 2023-04-10 13:05:38 -06:00
rmcrackan 7db5a34f1b Merge pull request #577 from Mbucari/master
Fixed your issues
2023-04-10 13:14:05 -04:00
Mbucari e52772826a Merge branch 'rmcrackan:master' into master 2023-04-09 17:45:38 -06:00
Mbucari 8ea9b2abc6 Fix #574 2023-04-09 17:41:24 -06:00
Mbucari c10bb276f5 Fix #575 2023-04-09 17:41:10 -06:00
Mbucari 9dcb3b3a25 Slight chardonnay refactor and UI tweak 2023-04-09 17:39:31 -06:00
Robert McRackan d857882220 Bug fix: logins 2023-04-07 19:58:13 -04:00
rmcrackan d731db4036 Update Docker.md 2023-04-05 08:02:42 -04:00
rmcrackan ca5b40b176 Merge pull request #571 from Mbucari/master
Chardonnay UI Refinements and Refactor
2023-04-05 08:00:44 -04:00
MBucari b29ec26f63 Remove useless interface 2023-04-04 22:38:02 -06:00
MBucari 7569b01bd0 MacOS Compatibility 2023-04-04 22:26:13 -06:00
MBucari 6465b0a885 Fix possible NRE 2023-04-04 19:17:43 -06:00
Mbucari 5e99cb6f02 Refine dialog layouts and presentation 2023-04-04 19:08:52 -06:00
Mbucari d737cd2199 Improve LinkLabel control 2023-04-04 12:10:23 -06:00
Mbucari 2d2907e076 Refactor settings dialog 2023-04-04 11:18:28 -06:00
Mbucari 05c454dce4 Fix directory select controls 2023-04-04 10:49:27 -06:00
rmcrackan e64a9d2adf Merge pull request #566 from Mbucari/master
Reattach event handlers
2023-04-03 16:23:10 -04:00
Mbucari 6252f015b3 Reattach event handlers 2023-04-03 14:09:22 -06:00
rmcrackan 7ada0082a9 Merge pull request #565 from Mbucari/master
About Dialog, mac menus, and hotkeys
2023-04-03 15:54:40 -04:00
Mbucari 826e53c9cb Remove assemblies add acknowledgements to About 2023-04-03 13:34:20 -06:00
Mbucari 2248d7b24e Sort episodes by column beneath their parents 2023-04-02 21:28:55 -06:00
Mbucari 69918c2587 Cleanup 2023-04-02 21:28:37 -06:00
Michael Bucari-Tovo 1991bf5b4d Add more info to About dialog 2023-04-02 18:16:01 -06:00
MBucari 756d387238 UI Tweaks and new application hotkeys 2023-04-02 15:08:03 -06:00
MBucari 8d73f5cc7e Add About dialog 2023-04-02 13:27:51 -06:00
MBucari 4a65d6bbd3 Add native menu for mac and refactor MainWindow 2023-04-01 23:58:22 -06:00
Robert McRackan 10a1b56b3c incr ver 2023-03-31 16:39:13 -04:00
Robert McRackan 66fb392b7f Merge branch 'master' of https://github.com/rmcrackan/Libation 2023-03-31 16:16:23 -04:00
Robert McRackan 49ef96055c update dependencies 2023-03-31 16:16:21 -04:00
rmcrackan cb4a209f69 Merge pull request #564 from Mbucari/master
Fix #563 and probably fix #534
2023-03-31 14:27:43 -04:00
Mbucari 255e18eb5e Fix external login failure error (#563) 2023-03-31 12:00:20 -06:00
Mbucari 7e1ec47b46 Tweak AccessKeyHandler 2023-03-31 11:59:48 -06:00
MBucari 40c725b8c2 Merge branch 'master' of https://github.com/Mbucari/Libation 2023-03-30 19:58:19 -06:00
MBucari 5d0937dc48 Add support for custom access keys 2023-03-30 19:57:39 -06:00
Robert McRackan bff81bfc4b update paypal links 2023-03-30 09:44:20 -04:00
MBucari aa7c159985 Define window dimensions 2023-03-29 19:44:33 -06:00
Robert McRackan 012d94a146 incr ver 2023-03-29 18:02:33 -04:00
Mbucari 22bd1ed121 Fix autoscan bug 2023-03-29 15:54:46 -06:00
Mbucari c832f26b08 Merge pull request #561 from Mbucari/master
Try fix #560
2023-03-29 15:40:52 -06:00
Mbucari efd73d334e inv ver 2023-03-29 15:39:25 -06:00
Mbucari 0db3ee6fd7 Fix library scan bug 2023-03-29 15:38:57 -06:00
Robert McRackan 6aaf4f63d1 incr major ver 2023-03-29 15:58:57 -04:00
rmcrackan ab392a9285 Merge pull request #558 from Mbucari/master
Refined Walkthrough
2023-03-29 15:54:15 -04:00
Mbucari efc9ff4bd8 Disable buttons on new row 2023-03-29 13:31:39 -06:00
Mbucari a52b466c85 Fix QuickFilter Walkthrough 2023-03-29 13:17:31 -06:00
Mbucari 5611431abf Quick Filters display moveup and movedown buttons appropriately 2023-03-29 13:06:18 -06:00
Mbucari a75932d1f4 Refine Walkthrough 2023-03-29 11:35:17 -06:00
Mbucari 6c8464b650 Use HashSet 2023-03-29 11:32:07 -06:00
rmcrackan ba4a1c5a51 Merge pull request #554 from Mbucari/master
Bug fixes and guided tour
2023-03-28 16:49:49 -04:00
Mbucari 3681c0f18f Final walkthrough tweaks 2023-03-28 14:08:51 -06:00
Mbucari e365ba7296 Use AvaloniaList properties 2023-03-28 13:29:07 -06:00
Mbucari 2afb5365dd Add search and quick filters to walkthrough 2023-03-28 12:30:05 -06:00
Mbucari 00cf7693d5 Add code comments 2023-03-28 10:02:22 -06:00
MBucari dac6877a06 Fix #556 2023-03-28 07:09:46 -06:00
MBucari 36005508a1 Allow users to cancel walkthrough 2023-03-27 20:24:15 -06:00
MBucari d9e27fd32e Bring cover viewer to front 2023-03-27 19:56:50 -06:00
MBucari d86bcbb414 Add usings 2023-03-27 19:52:26 -06:00
MBucari 00cbab5b58 Update window title 2023-03-27 19:51:10 -06:00
MBucari 807725f6ff Replace editable DataGridTextColumn with TextBox (#552) 2023-03-27 19:40:23 -06:00
MBucari ec9356b36e Do not import orphaned episodes (#553) 2023-03-27 18:58:43 -06:00
MBucari add31024da Improve book availability detection (#551) 2023-03-27 17:53:25 -06:00
MBucari 27d2ada5a4 Don't warn for blank password with external login 2023-03-27 17:23:46 -06:00
Mbucari 702219ee69 Add guided walkthrough 2023-03-27 16:18:21 -06:00
Mbucari cdf1a01457 Do not launch settings dialog after installation 2023-03-27 13:18:37 -06:00
Mbucari a71ccbac6e Add Series Order column 2023-03-27 12:13:56 -06:00
Mbucari f8c6b836c3 Merge branch 'rmcrackan:master' into master 2023-03-27 11:15:19 -06:00
Michael Bucari-Tovo 090871f50d More migrations to Avalonia 11.0.0-preview6 2023-03-27 11:14:54 -06:00
Robert McRackan e62f01d2a3 Incr ver so bug fixes can be released. New features will also be announced in upcoming new major ver 2023-03-27 08:48:53 -04:00
Mbucari 68af6a5ebb Merge branch 'rmcrackan:master' into master 2023-03-26 21:04:53 -06:00
Michael Bucari-Tovo 8bba8538d5 Recheck for partially downloaded files. 2023-03-26 20:54:29 -06:00
rmcrackan 2cd9b86930 Merge pull request #549 from Mbucari/master
Lots of Bug Fixes and 2 New Features.
2023-03-26 22:54:08 -04:00
MBucari b876d90964 Remove AudibleApi from solution 2023-03-26 08:43:33 -06:00
Mbucari 49c91c273b Merge branch 'rmcrackan:master' into master 2023-03-26 08:08:36 -06:00
MBucari c07bc88493 Update AudibleApi 2023-03-25 21:18:38 -06:00
MBucari 397a516dc1 Fix (#548) 2023-03-25 21:18:38 -06:00
Robert McRackan 1c2b51aa83 update dependencies 2023-03-25 22:25:37 -04:00
Mbucari fc6f494f0d Add dark mode support 2023-03-25 16:33:11 -06:00
Mbucari 7289459170 Migrate to Avalonia 11.0.0-preview6 2023-03-22 13:44:25 -06:00
Mbucari ed6f741a65 Fix SettingsFileIsValid 2023-03-22 11:46:11 -06:00
Mbucari 1783da3e2d Ensure series and episode DateAdded is never default (#543) 2023-03-22 11:02:57 -06:00
Mbucari e7eac7bed3 Log DTO items even if validation fails 2023-03-22 11:00:51 -06:00
MBucari 9ae1f0399b Add SeriesViewDialog 2023-03-22 08:28:20 -06:00
MBucari 784ab73a36 Add context menu to Series grid entries (#536) 2023-03-19 12:04:51 -06:00
MBucari 99687e968e Create books directory if not found (#542) 2023-03-19 10:19:38 -06:00
MBucari 565c84c4ab Add series # to grid display (#529) 2023-03-17 22:11:04 -06:00
MBucari 18cf20ecad All books that pass the filter are counted as "visible" (#536) 2023-03-17 19:52:47 -06:00
MBucari 2725340994 Suppress VisibleCountChanged firing when updating grid 2023-03-17 17:51:39 -06:00
MBucari 56de1e7659 Preserve "expanded" status when updating library 2023-03-17 17:47:27 -06:00
Mbucari fd16e97632 When book is unavailable, check other accounts (#535) 2023-03-17 14:06:02 -06:00
Robert McRackan 36076242a7 Bug fix #532 : Possible rull ref exception for pre-amazon germany 2023-03-15 13:49:11 -04:00
Robert McRackan 718e6c14d0 update dependency 2023-03-14 22:10:55 -04:00
rmcrackan eb61ba3d69 Merge pull request #531 from Mbucari/master
Bug fixes and performance improvements
2023-03-14 07:53:25 -04:00
MBucari defabf7356 Use new AudibleApi methods 2023-03-13 21:00:25 -06:00
Mbucari 1149c10cf1 Merge branch 'rmcrackan:master' into master 2023-03-13 20:49:56 -06:00
MBucari ec7dd1b54a Use new AudibleApi methods 2023-03-13 20:47:32 -06:00
Robert McRackan bb900b31ef update dependencies 2023-03-13 22:28:46 -04:00
MBucari eed42bd108 Improve grid update performance 2023-03-11 21:50:30 -07:00
MBucari 3f0e6b9ee5 Fix window restore maximize statate on secondary monitor. 2023-03-11 21:35:33 -07:00
MBucari 5ec01913d5 Fix bug where book with corrupt image cannot be queued. 2023-03-11 20:58:06 -07:00
rmcrackan 245e55782e Merge pull request #527 from Mbucari/master
Improve Library Display performance and Refactor grid viewmodels
2023-03-11 16:44:31 -05:00
MBucari cc306e0e19 Fix expand/collapse button icon in Avalonia 2023-03-11 12:28:34 -07:00
MBucari 26a9bc6bbf Merge branch 'master' of https://github.com/Mbucari/Libation 2023-03-11 11:12:05 -07:00
MBucari fb9d062545 WinForms and Avalonia now share all GridEntry view models 2023-03-11 11:10:58 -07:00
MBucari 49c6b391fd WinForms and Avalonia now share all GridEntry view models 2023-03-10 20:00:25 -07:00
MBucari e1cd8b8f94 Improve Library load and refresh performance 2023-03-10 19:01:49 -07:00
Robert McRackan ef1edf1136 AYCL bug fix: US and Italy 2023-03-10 15:37:51 -05:00
rmcrackan 0def1b426a Merge pull request #526 from Mbucari/master
Add better AYCL detection and add verbose library scan logging
2023-03-10 15:26:41 -05:00
Mbucari 230e014bb1 Add better AYCL detection and add verbose library scan logging 2023-03-10 13:09:59 -07:00
Robert McRackan 34f56d2fd7 Merge branch 'master' of https://github.com/rmcrackan/Libation 2023-03-08 14:07:51 -05:00
Robert McRackan c45ffaf4a6 Incr ver 2023-03-08 14:07:47 -05:00
rmcrackan ae43ab103e Merge pull request #524 from Mbucari/master
Improve library scan speed and Track and display book availability
2023-03-08 14:06:45 -05:00
Mbucari 559977ce0b Add 'Unavailable' book and pdf counts. 2023-03-08 11:26:07 -07:00
Mbucari ccd4d3e26d Check for null Plan array 2023-03-08 11:21:47 -07:00
MBucari e76f99ff28 Fix rmcrackan/Libation#523 2023-03-07 22:34:36 -07:00
MBucari d3607583ab Tweak episode scan 2023-03-07 20:32:50 -07:00
MBucari 3ebd4ce243 Show AbsentFromLastScan book status in grid 2023-03-07 20:02:22 -07:00
Mbucari f6dcc0db1d Add AbsentFromLastScan 2023-03-07 18:58:18 -07:00
MBucari bd49db83e4 Improve library scan performance 2023-03-07 15:30:22 -07:00
Mbucari 4140722a6d Merge branch 'master' of https://github.com/Mbucari/Libation 2023-03-06 16:56:57 -07:00
Mbucari da36f9414d Improve library scan performance 2023-03-06 16:49:52 -07:00
Mbucari 1510f71ca6 Merge branch 'rmcrackan:master' into master 2023-03-03 16:33:36 -07:00
Mbucari cdb27ef712 Add last downloaded info to exports 2023-03-03 15:06:06 -07:00
Robert McRackan 790319ed98 incr ver 2023-03-03 15:58:05 -05:00
rmcrackan 1b0fb2b316 Merge pull request #522 from Mbucari/master
Resolved Several Issues (It's not as bad as  2,453 lines suggests)
2023-03-03 15:56:59 -05:00
Mbucari 02371f2221 Deleting folders with custom icons no longer triggers system file warning 2023-03-03 10:56:31 -07:00
Mbucari 2b672f86be Fatten up the chevrons 2023-03-02 19:57:43 -07:00
Mbucari 36176bff33 Update ImageSharp 2023-03-02 19:41:59 -07:00
Mbucari 174b0c26b8 Update fileicon to latest version 2023-03-02 19:40:38 -07:00
Mbucari 26c60e8e79 Convert queue expand/collapse button text to images (rmcrackan/Libation#339) 2023-03-02 19:23:03 -07:00
Mbucari d94759d868 Add Last Download column to grid (rmcrackan/Libation#498) 2023-03-02 18:52:45 -07:00
Mbucari bd7e45ca3c Add last download into to database 2023-03-02 15:09:10 -07:00
Mbucari 52a863c62a Add audiobook Trash Bin 2023-03-02 13:12:32 -07:00
Mbucari fe55b90ee3 Fix rmcrackan/Libation#511 2023-03-01 22:14:57 -07:00
Mbucari df224cc7f3 Move TrackedQueue to LibationUiBase 2023-03-01 09:33:17 -07:00
Mbucari 2a59329350 Merge branch 'rmcrackan:master' into master 2023-02-28 16:41:14 -07:00
Mbucari abdf0e7261 Parallelize post-liberation tasks 2023-02-28 16:40:53 -07:00
Mbucari b9c2a1cce3 Add folder icon support to MacOS 2023-02-28 15:57:27 -07:00
rmcrackan aa86fca08f Update InstallOnMac.md 2023-02-28 15:46:51 -05:00
Robert McRackan cf9ec9facf did last tag incorrect. New version 2023-02-28 10:13:26 -05:00
Robert McRackan f6084ef10c v9.4.1 2023-02-28 10:04:47 -05:00
rmcrackan 740b73beb7 Merge pull request #518 from Mbucari/master
Improve Audible login and Libation Upgrade
2023-02-28 09:51:08 -05:00
Mbucari 5c45802391 Fixed review comments 2023-02-28 07:42:26 -07:00
MBucari 429aa603f5 Update workflows 2023-02-27 21:41:59 -07:00
MBucari 80ea394934 Merge branch 'master' of https://github.com/Mbucari/Libation 2023-02-27 16:33:16 -07:00
Mbucari bce4437c79 Change workflows 2023-02-27 16:18:48 -07:00
Mbucari b6ad1a289b Remove windows desktop runtime dependency from chardonnay 2023-02-27 16:13:40 -07:00
Mbucari 2a22d05f37 Remove windows desktop runtime dependency from chardonnay 2023-02-27 15:08:54 -07:00
Mbucari d787843fd2 Unify upgrade process and add update progress bar 2023-02-27 14:08:15 -07:00
Mbucari ded58f687d Update 2FA and Captcha controls 2023-02-27 14:08:14 -07:00
Mbucari 1f1f34b6ce Merge branch 'rmcrackan:master' into master 2023-02-27 09:36:53 -07:00
Mbucari ffadf90f4f Fix MFA and 2FA 2023-02-27 09:36:19 -07:00
rmcrackan 67807efacf Merge pull request #515 from Mbucari/patch-4
Update InstallOnMac.md
2023-02-26 15:29:55 -05:00
Mbucari 980f5afa54 Update InstallOnMac.md 2023-02-25 19:42:45 -07:00
Robert McRackan b2f68760b2 New audible api login 2023-02-24 15:52:14 -05:00
rmcrackan faf86711a5 Merge pull request #509 from Mbucari/master
Add More MP3 Options and improved AAXClean
2023-02-24 15:35:38 -05:00
Mbucari 4a78b9d28f Revert workflow change 2023-02-24 12:38:29 -07:00
Michael Bucari-Tovo 1b0a7f5062 New mp3 options and improved encoding performance 2023-02-24 12:12:41 -07:00
Mbucari 49982043e0 Merge branch 'rmcrackan:master' into master 2023-02-24 11:15:14 -07:00
Robert McRackan 378cf7057e updated to AudibleApi v8 2023-02-24 13:12:18 -05:00
Mbucari abdc0f018e Update build-linux.yml 2023-02-22 09:23:15 -07:00
Robert McRackan c65f61b92e Fix paypal links 2023-02-22 07:33:58 -05:00
Robert McRackan c12805c8ce incr ver for release 2023-02-19 14:55:55 -05:00
rmcrackan 67f9a6db78 Merge pull request #503 from Mbucari/master
Mac and Linux Arm64 releases and Fixed #502
2023-02-19 14:52:09 -05:00
Mbucari bb6336ce2a Update .releaseindex.json 2023-02-19 11:27:23 -07:00
Michael Bucari-Tovo af7a4a6acf Add comments 2023-02-19 11:11:28 -07:00
Michael Bucari-Tovo 21d18aa565 Final edits 2023-02-19 10:59:42 -07:00
Michael Bucari-Tovo c96875ba5d Add '-chardonnay' to build assets name 2023-02-19 10:23:49 -07:00
Michael Bucari-Tovo 6ebbfb8e59 Refactor SetReleaseIdentifier() 2023-02-19 10:20:01 -07:00
Michael Bucari-Tovo 1e6e28cd57 Start downloading asynchronously 2023-02-18 22:38:26 -07:00
Michael Bucari-Tovo defed72862 Force garbage collection after completing a Processable 2023-02-18 22:16:46 -07:00
Michael Bucari-Tovo 71503b34b5 Fix macOS crash 2023-02-18 20:29:10 -07:00
Michael Bucari-Tovo a00849fb6f Refactor InteropFactory 2023-02-18 13:57:00 -07:00
Michael Bucari-Tovo 14b63c0883 Add apple UUTYPEs 2023-02-18 10:27:37 -07:00
Michael Bucari-Tovo 59d556733e Edit Mac Build Script 2023-02-17 23:46:28 -07:00
Michael Bucari-Tovo a99a175683 Update AAXClean to fix #502 2023-02-17 23:20:35 -07:00
Michael Bucari-Tovo 26fedcfb60 Fix DirectorySelectControl not displaying known dir 2023-02-17 22:58:24 -07:00
Michael Bucari-Tovo dde8024506 More thread safety to address #492 2023-02-17 22:57:43 -07:00
Michael Bucari-Tovo 25f7c29380 New linux build workflows 2023-02-17 18:04:34 -07:00
Robert McRackan 2f347e83e8 fix linux 'can update'. upgrade aaxclean 2023-02-16 07:57:36 -05:00
rmcrackan 080a74884d Update InstallOnMac.md
new mac setup video
2023-02-16 07:44:09 -05:00
Robert McRackan 2dbeb64c38 incr ver. updates for mac and linux 2023-02-15 08:38:13 -05:00
rmcrackan bb508c0718 Merge pull request #489 from Mbucari/master
Mac App Bundle and added mp3 conversion support on mac
2023-02-15 08:33:06 -05:00
Michael Bucari-Tovo 9a450b0d63 add 'macOS' to mac bundle name 2023-02-15 06:31:09 -07:00
Michael Bucari-Tovo c1de0e60d2 Hopefully fix #492 2023-02-14 23:07:40 -07:00
Mbucari dc7c03661d Add auto update to linux and macos 2023-02-14 23:06:14 -07:00
Mbucari 952eee6d32 Merge branch 'rmcrackan:master' into master 2023-02-13 21:42:11 -07:00
Michael Bucari-Tovo 472a0f30b9 Launch hangover from Libation app bundle for mac 2023-02-13 21:40:53 -07:00
Robert McRackan 73533c58a8 update dependencies 2023-02-13 21:14:56 -05:00
Mbucari 65ef018719 Move NameListFormatter to its own class 2023-02-13 10:09:13 -07:00
Mbucari f0ca349539 Update UNSAFE_MigrationHelper with new appsettings.json getter 2023-02-13 09:03:03 -07:00
Mbucari 500b287721 Fix #490 2023-02-13 08:08:10 -07:00
Mbucari 21f3ae45d3 Delete deb.yml 2023-02-12 22:25:39 -07:00
Michael Bucari-Tovo d496564f0d Edit Mac and Linux bundle build workflows 2023-02-12 21:50:33 -07:00
Michael Bucari-Tovo 6fdd6293ce Ensure appsettings.json is created in a writable location. 2023-02-12 15:32:51 -07:00
Michael Bucari-Tovo 3bca495521 Add MacOS app bundle workflow 2023-02-11 23:38:17 -07:00
Michael Bucari-Tovo 0fb580f1a5 Ensure appsettings.json is created in a writable location. 2023-02-11 20:06:04 -07:00
Michael Bucari-Tovo a7cd47e0b1 Update AAXClean 2023-02-11 18:34:07 -07:00
Robert McRackan 30aecedfae incr ver 2023-02-10 23:16:22 -05:00
rmcrackan e72799efe5 Merge pull request #487 from Mbucari/master
Custom author and narrator names formatting and batch locate books
2023-02-10 23:14:31 -05:00
Michael Bucari-Tovo ee8c0ae27b Use new .NET regular expression source generators 2023-02-10 19:45:52 -07:00
Mbucari 5b4a4341ad More agressive garbage collection 2023-02-10 15:03:43 -07:00
Mbucari 56823c1105 Move FindAudiobooks() to AudioFileStorage 2023-02-10 14:54:29 -07:00
Mbucari 1f4ada604a Make suggested changes 2023-02-10 14:37:28 -07:00
Mbucari 3a4ab80892 Add human name parsing and formatting to naming templates 2023-02-10 12:53:12 -07:00
Mbucari bba9c2ba7b Add Locate Audiobooks function (#485) 2023-02-10 09:35:21 -07:00
Robert McRackan c4acd5d208 incr ver 2023-02-08 13:56:13 -05:00
rmcrackan 381440db4c Merge pull request #479 from Mbucari/master
Fix #478 and other stuff I'd already worked on
2023-02-08 13:43:56 -05:00
Michael Bucari-Tovo 00c8be1f7e Create LibationUiBase for shared UI code 2023-02-08 09:30:13 -07:00
rmcrackan d665122aa2 Update GettingStarted.md
Classic vs Chardonnay
2023-02-08 07:49:18 -05:00
Michael Bucari-Tovo bb40df5fa3 Fix #478 2023-02-07 22:58:29 -07:00
Mbucari e3c9f70dff Move shared GUI code into AppScaffolding 2023-02-06 16:04:58 -07:00
Mbucari b351033cec Improve download and convert speed estimate 2023-02-06 15:54:12 -07:00
Mbucari 18f69bc73d Refactor Naming Template 2023-02-06 15:24:18 -07:00
Robert McRackan 39fe7b79d2 Bug fix #474 2023-02-06 08:35:24 -05:00
rmcrackan 85769d797b Merge pull request #473 from Mbucari/master
Made changes discussed in previous PR and fixed #472
2023-02-04 17:32:53 -05:00
Michael Bucari-Tovo 9a80f18e1c Rename ConditionalTagClass to ConditionalTagCollection 2023-02-04 15:19:47 -07:00
Michael Bucari-Tovo aec8305e52 Fix #472 2023-02-04 12:49:59 -07:00
Michael Bucari-Tovo a672174a9b Refactor Naming Templates 2023-02-04 12:49:48 -07:00
Mbucari 6f490b4491 Rename TagClass to TagCollection 2023-02-03 17:14:04 -07:00
Mbucari 5917d059e4 Add Enumerable initializers 2023-02-03 17:03:15 -07:00
Robert McRackan 40602c7626 incr ver 2023-02-03 17:26:17 -05:00
rmcrackan 7d5ee2afa8 Merge pull request #471 from Mbucari/master
Add a more general NamingTemplate
2023-02-03 17:24:37 -05:00
Mbucari 08b6f8fa11 Add test 2023-02-03 14:46:48 -07:00
Mbucari 5f9699aa3b Merge branch 'master' of https://github.com/Mbucari/Libation 2023-02-03 14:43:42 -07:00
Mbucari 70607aaaf4 Documentation 2023-02-03 14:43:35 -07:00
Mbucari 1d96d39af7 Add Naming Template Documentation 2023-02-03 14:33:11 -07:00
Mbucari 5557772957 Add conditional negation 2023-02-03 11:47:55 -07:00
Mbucari 5c7db6cd23 Add <series#> tag zero padding (#466) 2023-02-03 11:31:15 -07:00
Mbucari c72b64d74c Properly truncate filenames 2023-02-03 09:53:40 -07:00
Mbucari 20474e0b3c Add a more general NamingTemplate 2023-02-02 22:48:27 -07:00
Robert McRackan 867085600c New feature #469 - <language> and <language short> template options 2023-02-01 12:12:50 -05:00
rmcrackan 74290ec609 Merge pull request #468 from rmcrackan/dependabot/github_actions/docker/build-push-action-4
Bump docker/build-push-action from 3 to 4
2023-01-31 10:18:40 -05:00
dependabot[bot] 5ee555e60c Bump docker/build-push-action from 3 to 4
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 3 to 4.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-31 14:11:36 +00:00
Robert McRackan a36c28d48f incr. ver. 2023-01-30 21:24:54 -05:00
rmcrackan 0877f2c042 Merge pull request #464 from Mbucari/master
Fix #463
2023-01-25 20:48:58 -05:00
Mbucari 2baf5243ea Fix #463 2023-01-25 14:23:02 -07:00
rmcrackan b7e71f5812 Merge pull request #462 from Mbucari/master
Refactor AaxDecrypter
2023-01-25 07:06:37 -05:00
Michael Bucari-Tovo 2ed1076fab Cleanup 2023-01-24 23:35:05 -07:00
Michael Bucari-Tovo 0b20aa751f Only Dispose of NFS on disposing 2023-01-24 23:00:07 -07:00
Michael Bucari-Tovo 05a4ece8d1 Merged 2023-01-24 22:27:31 -07:00
Michael Bucari-Tovo 25b37c6266 Refactor AaxDecrypter 2023-01-24 22:25:55 -07:00
Robert McRackan b668cff0ac Update dependenciesd. Build is broken until the ambiguous ref.s moved into Dinah.Core are resolved 2023-01-24 22:40:08 -05:00
Robert McRackan 4d6c742ae9 Bug fix #459 , New feature/setting #366 2023-01-23 22:50:37 -05:00
rmcrackan 933f663d22 Merge pull request #460 from Mbucari/master
Upgrade AAXClean.Codecs to 0.5.12, add moov relocation, and fix #459
2023-01-23 22:46:20 -05:00
Michael Bucari-Tovo 0c55f278a4 Revert Solution Changes 2023-01-23 20:32:27 -07:00
Michael Bucari-Tovo 3f567ee82e Merged 2023-01-23 20:13:19 -07:00
Michael Bucari-Tovo 8dc912c11d Add option to move the moov atom to the beginning of the file. 2023-01-23 20:11:00 -07:00
Michael Bucari-Tovo f1b4e2a17d Upgrade AAXClean.Codecs to 0.5.11 2023-01-23 19:04:15 -07:00
Michael Bucari-Tovo 630cfdeab3 Upgrade AAXClean.Codecs to 0.5.11 2023-01-23 17:39:08 -07:00
Michael Bucari-Tovo 7029409792 Upgrade AAXClean.Codecs to 0.5.10 and fix #459 2023-01-23 16:30:17 -07:00
rmcrackan d0727b5a85 Update InstallOnMac.md
Added @Mbucari 's awesome video
2023-01-23 08:17:28 -05:00
rmcrackan 9f52ad5e0a Update README.md
link to docker readme
2023-01-23 08:07:37 -05:00
rmcrackan 501ae643f7 Merge pull request #458 from pixil98/master
Deb build tweaks, Docker read me
2023-01-23 08:06:51 -05:00
Aaron Reisman 400074170e Add docker readme 2023-01-22 17:09:25 -06:00
Aaron Reisman 17103ed066 Get release id correctly 2023-01-22 15:33:27 -06:00
Aaron Reisman b6b29309c9 Go back to the old way of uploading assets 2023-01-22 15:15:56 -06:00
Aaron Reisman a04538710f Try with a different glob 2023-01-22 14:53:05 -06:00
Aaron Reisman 01f6f5c137 Add name to release 2023-01-22 14:17:08 -06:00
Aaron Reisman b1a37cbd8c Switch to a still maintained release action 2023-01-22 13:56:36 -06:00
Aaron Reisman 8c59e1280b Wait for deb to be finished before releasing 2023-01-22 13:20:59 -06:00
Aaron Reisman 00339127aa reference correct deb yaml 2023-01-22 13:15:51 -06:00
Aaron Reisman 5935b40b60 Remove output version 2023-01-22 13:03:23 -06:00
Aaron Reisman 6cfd2dea96 Move deb building out of the build pipeline 2023-01-22 13:01:12 -06:00
rmcrackan 7d3a39c693 Merge pull request #456 from Mbucari/master
Add file creation DateTime to naming templates
2023-01-20 15:18:11 -05:00
Mbucari 6e7a4ea475 Update date format regex and tests 2023-01-20 10:03:55 -07:00
Michael Bucari-Tovo 3479dbc3f0 Date format naming templates 2023-01-20 01:00:22 -07:00
Mbucari 9309aea6d9 Add file creation DateTime to naming templates
typo
2023-01-19 17:12:28 -07:00
Robert McRackan f72551fa9a incr ver 2023-01-19 08:06:18 -05:00
rmcrackan e3b237b75f Merge pull request #454 from Mbucari/master
Fixed #453
2023-01-18 22:23:55 -05:00
Mbucari b1ddf18f73 Merge branch 'rmcrackan:master' into master 2023-01-18 15:47:18 -07:00
Michael Bucari-Tovo 13f522abb8 Fix file extension detection error (#453) 2023-01-18 15:47:05 -07:00
Robert McRackan 3c3d956bf3 remove linux and mac from beta 2023-01-16 13:16:49 -05:00
Robert McRackan 8160547c11 incr ver 2023-01-16 13:06:19 -05:00
rmcrackan ef71d36dee Merge pull request #451 from Mbucari/patch-3
Updated for new deb package builds
2023-01-16 12:59:23 -05:00
Mbucari b0d8434455 Updated for new deb package builds 2023-01-16 10:41:21 -07:00
rmcrackan 9be0d58461 Merge pull request #450 from Mbucari/master
Update workflows and AAXClean
2023-01-16 10:38:18 -05:00
Michael Bucari-Tovo 1addcc8211 Update AAXClean and add better error handling 2023-01-15 21:42:03 -07:00
Mbucari 38c75dc8c5 Update workflows 2023-01-12 15:47:01 -07:00
rmcrackan 89c3ea8311 Merge pull request #444 from Mbucari/master
Build and attach deb package
2023-01-12 08:45:14 -05:00
Michael Bucari-Tovo 18ff799fb1 Update build scripts 2023-01-11 21:14:26 -07:00
Mbucari 67b6aaed99 Fix #447 2023-01-11 16:08:01 -07:00
Mbucari 08bb463560 Invoke observables directly instead of through event handler 2023-01-11 14:38:12 -07:00
Mbucari 97767dcabb GLOB pattern 2023-01-11 14:37:12 -07:00
Mbucari fb18940a5c Use DataGridMyRatingColumn for both user and product ratings. 2023-01-11 14:36:43 -07:00
Mbucari b823f5fa00 Import average rating 2023-01-11 14:35:14 -07:00
Mbucari d64fb081a0 Build and attach deb package 2023-01-11 14:15:07 -07:00
Robert McRackan 09118b1ddf nvm. I guess this has been default : true for a long time. Reverting 2023-01-10 10:13:47 -05:00
Robert McRackan de20590fd5 do not enable AutoScan by default 2023-01-10 10:04:53 -05:00
rmcrackan 1050ffdb24 Merge pull request #443 from Mbucari/master
Chardonnay Bugfix + Moved Default Settings into Configuration
2023-01-10 09:54:49 -05:00
Michael Bucari-Tovo 2e49c7f697 Commit edits before refresh 2023-01-09 18:57:16 -07:00
Mbucari 708cdcc24c Merge branch 'master' of https://github.com/Mbucari/Libation 2023-01-09 16:30:59 -07:00
Mbucari c89eafd568 Fix rating edits updating search results. 2023-01-09 16:27:19 -07:00
Michael Bucari-Tovo 10de241d53 Cache default values 2023-01-09 16:11:30 -07:00
Mbucari e58952035f Spaces 2023-01-09 16:06:37 -07:00
Mbucari 50a8c7508a Cache default values 2023-01-09 16:05:55 -07:00
Michael Bucari-Tovo 2b243a6934 Remove testing code 2023-01-09 15:28:36 -07:00
Michael Bucari-Tovo ece93cb4d7 Finish migrating default Configuration values into Configuration 2023-01-09 15:26:06 -07:00
rmcrackan 5b3ca0ed32 Merge pull request #442 from wtanksleyjr/master
Add a version parameter to DEB creation, do sanity checks, use it.
2023-01-09 16:36:48 -05:00
Robert McRackan 7474f1221a bug fix #441 -- new code with empty setting 2023-01-09 16:30:12 -05:00
William Tanksley d023a943c1 Add a version parameter to DEB creation, do sanity checks, use it. 2023-01-09 13:12:12 -08:00
Michael Bucari-Tovo 4e80af5c53 Bind MyRatingCellEditor background color to the cell's background 2023-01-09 14:06:06 -07:00
Michael Bucari-Tovo eee785377f Add default values to Configuration 2023-01-09 14:05:33 -07:00
Robert McRackan 915906e6ed test push ver 2023-01-09 11:59:24 -05:00
Robert McRackan 358c8b577e increment version 2023-01-09 11:53:44 -05:00
rmcrackan 5c450a01a4 Merge pull request #440 from Mbucari/master
Configuration Change Tracking and Bookk Records
2023-01-09 11:41:34 -05:00
Michael Bucari-Tovo 36264c6c6e Add back a check that was removed for testing 2023-01-08 13:19:21 -07:00
Michael Bucari-Tovo fca946bf15 Fix bug with long folder templates 2023-01-08 10:01:30 -07:00
Michael Bucari-Tovo 452ceef285 Tweak 2023-01-07 23:27:28 -07:00
Michael Bucari-Tovo 7fafee804d Double clicking on template item adds it to the template. 2023-01-07 23:15:38 -07:00
Michael Bucari-Tovo 3a48479435 Typos and formatting 2023-01-07 18:41:34 -07:00
Michael Bucari-Tovo cab8555ab5 Make UpgradeNotificationDialog a DialogWindow 2023-01-07 18:18:14 -07:00
Michael Bucari-Tovo e3b7cbcc2a Add proper Upgrade form 2023-01-07 18:09:37 -07:00
Michael Bucari-Tovo ed15614288 Improve character display in EditTemplateDialog 2023-01-07 14:33:49 -07:00
Michael Bucari-Tovo acb6d1b335 Use new Inline controls to selectively style TextBlock text 2023-01-07 12:05:38 -07:00
Michael Bucari-Tovo fe804796ab Use ContinueWith to set Rating changed value 2023-01-06 23:46:06 -07:00
Michael Bucari-Tovo 4725fe36d1 Add property changed filtering events to Configuration 2023-01-06 22:56:00 -07:00
Michael Bucari-Tovo 5c73beff4b Add PropertyChanged detection for Dictionary type settings 2023-01-06 19:46:55 -07:00
Michael Bucari-Tovo 1f7000c2c9 Add Configurations property change notifications 2023-01-06 16:50:20 -07:00
Mbucari f09baa1318 Merge branch 'rmcrackan:master' into master 2023-01-05 23:41:27 -07:00
Michael Bucari-Tovo 7eaa03e43c Add clip and bookmark viewer and exporter 2023-01-05 23:40:39 -07:00
Robert McRackan 26099303fa update dependencies 2023-01-05 21:44:34 -05:00
Michael Bucari-Tovo 6417aee780 Add book records dialog 2023-01-05 17:02:39 -07:00
rmcrackan f9deaba4c5 Merge pull request #438 from Mbucari/master
Linux and mac upgrade notification
2023-01-03 21:26:04 -05:00
Michael Bucari-Tovo ddd6a3b279 Change args 2023-01-03 15:17:57 -07:00
Michael Bucari-Tovo 9359950666 Formatting 2023-01-03 15:00:29 -07:00
Michael Bucari-Tovo d31b2a1b65 Merge branch 'master' of https://github.com/Mbucari/Libation 2023-01-03 14:56:09 -07:00
Michael Bucari-Tovo b89b4e0af4 Linux and mac upgrade notification 2023-01-03 14:55:58 -07:00
rmcrackan cbcde027b3 Merge pull request #436 from Mbucari/master
Add download speed limit
2023-01-02 13:07:03 -05:00
Mbucari d306e6bd22 Merge branch 'rmcrackan:master' into master 2023-01-02 02:54:09 -07:00
Michael Bucari-Tovo 9ec877999e Add download speed limit 2023-01-02 02:46:46 -07:00
rmcrackan f4189bf409 Merge pull request #432 from Mbucari/master
Add ability for users to edit book ratings from the main grid
2023-01-01 22:34:06 -05:00
Michael Bucari-Tovo 0ed5062683 Cancel rating edit on escape 2023-01-01 11:23:22 -07:00
Michael Bucari-Tovo 7ef666dc91 Add TCOM tag for narrator 2022-12-31 23:31:24 -07:00
Michael Bucari-Tovo 1ac825919a Remove old migrations 2022-12-31 22:41:11 -07:00
Michael Bucari-Tovo a7bf30954d Fix null file bug and add context menu to my ratings column 2022-12-31 21:09:30 -07:00
Michael Bucari-Tovo 613cfdd903 Automatic refiltering now works on chardonnay 2022-12-31 19:50:49 -07:00
Michael Bucari-Tovo 28802c8279 Refilter on search update 2022-12-31 18:41:55 -07:00
Michael Bucari-Tovo 6d7b3bd5f0 Improve star display on classic 2022-12-31 15:39:46 -07:00
Michael Bucari-Tovo b97d8e9403 Add ratings cell tool tips 2022-12-31 11:12:04 -07:00
Michael Bucari-Tovo b4838d364e Only show hollow stars in editing mode 2022-12-31 10:33:18 -07:00
Michael Bucari-Tovo 05ac5c63e1 Formatting 2022-12-31 10:16:54 -07:00
Michael Bucari-Tovo 874bf9e7c0 Improve classic and chardonnay rating editor simmilarity 2022-12-31 10:02:30 -07:00
Michael Bucari-Tovo c9497ef39e Make my rating column sortable 2022-12-30 19:44:16 -07:00
Michael Bucari-Tovo 496830d01d Fix cell editor to work with desktop scaling 2022-12-30 19:25:11 -07:00
Mbucari ccebcdd4c7 Merge branch 'rmcrackan:master' into master 2022-12-30 17:01:22 -07:00
Michael Bucari-Tovo c900fe8461 Add user rating editing to grid 2022-12-30 17:00:40 -07:00
rmcrackan a0158db37e Merge pull request #431 from Mbucari/master
Fix file naming template on unix systems (#430)
2022-12-30 11:05:09 -05:00
Robert McRackan b8c26b01ad update dependencies 2022-12-30 09:58:51 -05:00
Mbucari 3a44bef0d9 Lowercase command is more linux-ey 2022-12-29 16:24:41 -07:00
Mbucari 57a4ee781b .deb package build script (#390) 2022-12-29 16:04:20 -07:00
= e12f475850 Refactor 2022-12-29 15:39:48 -07:00
= f822a23daa Linux and OSX directory length limits 2022-12-29 15:29:18 -07:00
= 6901b8be35 Fix file naming template on unix systems 2022-12-29 14:12:46 -07:00
Robert McRackan 83fb2cd1d0 New feature #430 : bulk set pdf-downloaded status 2022-12-29 09:33:32 -05:00
Robert McRackan c98664d584 Bugfix #423 : Chardonnay updater fails when windows username has a space 2022-12-22 09:45:32 -05:00
Robert McRackan d098be8b03 EF: move seed data into corresponding config class 2022-12-22 09:37:21 -05:00
Robert McRackan 3f6689d032 Test release before v9 2022-12-20 12:43:04 -05:00
rmcrackan b4206fc203 Merge pull request #416 from pixil98/master
Linux runners and Docker image
2022-12-19 21:58:38 -05:00
rmcrackan cfa4a0c07f Merge pull request #417 from Mbucari/master
Improve download cancellation
2022-12-19 13:42:24 -05:00
Michael Bucari-Tovo 357b220ace Suppress warnings 2022-12-19 09:48:18 -07:00
Michael Bucari-Tovo 47968304c9 Return Download to new background thread 2022-12-19 09:15:36 -07:00
Michael Bucari-Tovo 2024d5e116 Improve download cancellation. 2022-12-18 21:52:51 -07:00
pixil98 5ae2a99c14 Docker workflow (#7)
* Refactored workflows
* Added docker build to release
* Linux and MacOS now build on Linux
2022-12-18 17:57:37 -06:00
rmcrackan 7fd002d2c9 Merge pull request #413 from Mbucari/master
Update obsolete code and fix #347
2022-12-18 09:41:31 -05:00
Michael Bucari-Tovo b7b7038244 Delete partially decrypted files from previous Libation instances 2022-12-17 12:30:26 -07:00
Michael Bucari-Tovo b5519c4875 Add option for user to choose custom temp folder 2022-12-17 12:25:13 -07:00
Michael Bucari-Tovo 44feab9eb2 Update comments 2022-12-17 11:39:37 -07:00
Michael Bucari-Tovo 96c45c33e5 Refactor NetworkFileStream replace obsolete WebRequest 2022-12-17 11:31:51 -07:00
Michael Bucari-Tovo 36efbcb812 Replace deprecated file dialogs 2022-12-16 21:08:11 -07:00
Michael Bucari-Tovo 03f44b4e9c Fix IDE class grouping 2022-12-16 19:54:31 -07:00
rmcrackan 19860e9f09 Merge pull request #412 from Mbucari/master
Fix Character Replacements and Add More Useful Error Messages
2022-12-16 21:28:36 -05:00
Michael Bucari-Tovo 0701cb3970 Reorder tabs 2022-12-16 16:45:51 -07:00
Michael Bucari-Tovo 7d6000e3b6 Bring Hangover Chardonnay into feature parity with Classic (#409) 2022-12-16 16:41:24 -07:00
Mbucari ef973ac56a Merge branch 'rmcrackan:master' into master 2022-12-16 08:55:08 -07:00
Robert McRackan 91a1033c52 makes slashes more clear 2022-12-16 09:48:00 -05:00
Robert McRackan 4197db6af9 Fix unit tests failing because of windows newlines 2022-12-16 09:27:44 -05:00
MBucari 210ab065c2 Make tests xplat 2022-12-15 23:04:27 -07:00
Mbucari 9cd10eca58 Merge branch 'rmcrackan:master' into master 2022-12-15 19:25:27 -07:00
Robert McRackan ba676be46d update dependency 2022-12-15 21:06:26 -05:00
Mbucari 665a2e1866 Merge branch 'rmcrackan:master' into master 2022-12-15 16:22:43 -07:00
Michael Bucari-Tovo 94469cae3d Add better error messages for license denial #352 2022-12-15 16:22:25 -07:00
Michael Bucari-Tovo a0dd2ccad6 Make filename character replacement more xplat and allow replacing any char, not just illegal. 2022-12-15 15:50:48 -07:00
Robert McRackan b2cf837de7 Hangover. WinForms. Restore deleted books 2022-12-15 14:11:27 -05:00
Mbucari 80bcf60b5b Merge branch 'rmcrackan:master' into master 2022-12-14 15:40:42 -07:00
Robert McRackan 7ad0ab566a New feature: 'Remove' now removes forever. Removed books won't be re-added on next scan 2022-12-14 16:19:55 -05:00
Michael Bucari-Tovo 2b16e86c7b Fix character replacement for non-windows platforms. 2022-12-13 16:33:37 -07:00
Robert McRackan f2ea02ae0b bugfix. file extension 2022-12-13 16:09:24 -05:00
Robert McRackan f65cd39040 bug fix: keyboard shortcuts 2022-12-13 15:58:54 -05:00
Robert McRackan 5ca0d2a399 New feature #406 : Right Click Menu for Stop-Light Icon (Chardonnay UI) 2022-12-13 15:32:33 -05:00
Robert McRackan d1528a095b New feature #406 : Right Click Menu for Stop-Light Icon (Classic UI) 2022-12-13 13:48:28 -05:00
rmcrackan 749173a463 Merge pull request #407 from Mbucari/master
Add dynamic context menus to products grid
2022-12-13 08:33:03 -05:00
Michael Bucari-Tovo 6fbd90a6b3 Fix hidden tag 2022-12-13 02:42:53 -07:00
Michael Bucari-Tovo f39d272e6a Make reused ContextMenu static 2022-12-12 18:23:12 -07:00
Michael Bucari-Tovo bb3854f512 Finishing touch 2022-12-12 17:21:41 -07:00
Michael Bucari-Tovo e40daecfb8 Remove old static context menu 2022-12-12 17:12:44 -07:00
Michael Bucari-Tovo 3716ab9cb5 Merged 2022-12-12 17:11:40 -07:00
Michael Bucari-Tovo 0cc6d6337a Add dynamic context menus to main grid 2022-12-12 17:10:18 -07:00
Robert McRackan ce711a36ba #398 - new feature: right-click, copy 2022-12-12 15:03:20 -05:00
rmcrackan 451af7bea9 Merge pull request #405 from Mbucari/master
Upgraded to Avalonia 11-Preview4
2022-12-12 13:18:06 -05:00
Michael Bucari-Tovo 63200592bf Ensure mandatory character replacements remain marked mandatory 2022-12-12 08:34:10 -07:00
Michael Bucari-Tovo d165dfbeb5 Fix NRE 2022-12-12 08:24:18 -07:00
Michael Bucari-Tovo eed3d84517 Add context menu 2022-12-11 19:21:49 -07:00
Michael Bucari-Tovo ba7d890966 Update hangover 2022-12-11 18:33:57 -07:00
Michael Bucari-Tovo 5140fc63d9 Merge branch 'master' of https://github.com/Mbucari/Libation 2022-12-11 18:30:56 -07:00
Michael Bucari-Tovo 78509c07e0 Remove unused files 2022-12-11 18:30:48 -07:00
Mbucari 5084141215 Delete Source/Visual Studio 2022 directory 2022-12-11 18:23:00 -07:00
Michael Bucari-Tovo 3f2ac83474 Fix copying grid contents to clipboard 2022-12-11 17:50:15 -07:00
Michael Bucari-Tovo 58a0468728 Tidy up 2022-12-11 16:58:51 -07:00
Mbucari 8e13aa7513 Merge branch 'rmcrackan:master' into master 2022-12-11 15:47:24 -07:00
Michael Bucari-Tovo 48e2d91fc8 Implement Illegal Char Replace dialog in Avalonia 2022-12-11 15:47:04 -07:00
rmcrackan a7f119217f Merge pull request #404 from pixil98/master
Fix Auto Updating
2022-12-11 09:12:10 -05:00
pixil98 865f2261fe Fix Auto Updating (#8)
Release workflow no longer includes the parent folder in the zip.
2022-12-10 00:30:08 -06:00
Michael Bucari-Tovo dfedb23efd Refactor ProductsDisplay 2022-12-09 12:27:52 -07:00
Mbucari c01e1c3e4b Merge branch 'rmcrackan:master' into master 2022-12-09 12:27:14 -07:00
Robert McRackan ad8dac5fb0 more forgiving releaseindex windows regex 2022-12-08 08:17:17 -05:00
Mbucari 84e81b6218 Merge branch 'rmcrackan:master' into master 2022-12-07 19:13:22 -07:00
Robert McRackan 86efe631fe restore yaml 2022-12-07 13:49:05 -05:00
Robert McRackan f5f1dc483b publish debugging. create new version 2022-12-07 13:34:30 -05:00
Robert McRackan 8aa4328c6c update dependencies 2022-12-07 13:09:02 -05:00
Michael Bucari-Tovo a01a8c4b19 Update Avalonia to v.11-Preview-4 2022-12-07 10:15:12 -07:00
Robert McRackan 4b2387b621 update dependencies 2022-12-07 11:53:10 -05:00
Robert McRackan 74d16d8ef9 yaml releases don't run. comment out for now 2022-12-07 07:42:11 -05:00
rmcrackan b1ea8f9fa7 Update GettingStarted.md
disclaimer: don't install in Program Files
2022-12-06 15:59:11 -05:00
rmcrackan c666fdeaff document CLI set-status 2022-12-06 15:02:26 -05:00
Robert McRackan 7068782975 Merge branch 'master' of https://github.com/rmcrackan/Libation 2022-12-06 14:58:30 -05:00
Robert McRackan c4cebbebe7 * #396 New feature : match download status to files
* UI: Visible Books \> Set 'Downloaded' status automatically. Visible books. Prompts before saving changes
  * CLI: Full library. No prompt
2022-12-06 14:58:22 -05:00
rmcrackan 53d43d9fa9 Merge pull request #401 from pixil98/master
Add validate and release workflows
2022-12-05 14:54:39 -05:00
Aaron Reisman 11d59beeed Rename happens before zipping 2022-11-28 13:08:57 -06:00
Aaron Reisman ef71e297f4 Add special handling for classic build 2022-11-28 12:54:17 -06:00
Aaron Reisman 1e4d1d1973 Lowercase OS names in releaseindex 2022-11-28 12:44:48 -06:00
pixil98 893d99854b Merge branch 'master' into master 2022-11-25 00:20:51 -06:00
Aaron Reisman db93980cd5 Rename publish to release 2022-11-24 23:54:49 -06:00
pixil98 34fac30b2b Merge official updates (#6)
Pull latest Libation updates, fix move to net7
2022-11-24 23:53:00 -06:00
pixil98 2fa0bcb765 Near final workflows
Updated workflows to release zips with the correct file names.
2022-11-23 15:48:37 -06:00
pixil98 78fd09aa91 Proper build
Builds all packages properly
2022-11-22 10:45:33 -06:00
Robert McRackan a54516b4f5 Fix pubxml hierarchy 2022-11-21 13:51:30 -05:00
Robert McRackan f193d6f376 AudibleApi fixed 2022-11-17 17:05:58 -05:00
pixil98andAaron Reisman 8a82c294a1 Fix publish workflow (#2)
* Add dotnet test workflow

* main -> master

* Try a different workflow

* Add working-directory

* use windows runner

* use env var

* Fix build and test order

* Specify configuration

* Specify sln instead of working dir

* Specify that DOTNET_SLN is an env var

* Add publish workflow

* Add env.DOTNET_SLN to publish workflow

* Add publish job

* Combine publish into one job

* Just create an artifact

* Remove unused nuget lines

* Add Publish job back

Co-authored-by: Aaron Reisman <areisman@epic.com>
2022-11-16 13:40:57 -06:00
Robert McRackan 9392cf4bf0 update dependencies 2022-11-16 13:36:23 -05:00
Robert McRackan ec4deb9099 update db dependencies 2022-11-16 12:48:22 -05:00
Robert McRackan cf0548aab9 update dependencies 2022-11-16 12:46:12 -05:00
pixil98 064801380b Add workflows (#1)
Adds basic workflows
2022-11-16 11:44:15 -06:00
Robert McRackan 9dc2a7424a DataLayer => .net7 2022-11-16 11:49:07 -05:00
Robert McRackan 4c8a56a5b9 Core, Utilities => .net7 2022-11-16 11:47:34 -05:00
Robert McRackan 9aad263996 Domain Internal Utilities => .net7 2022-11-16 11:46:26 -05:00
Robert McRackan ce1ab7c20d Domain Utilities => .net7 2022-11-16 11:45:04 -05:00
Robert McRackan c9217990cd applications => .net7 2022-11-16 11:43:35 -05:00
Robert McRackan 90cbf3b7a6 tests => .net7 2022-11-16 11:27:51 -05:00
Robert McRackan c4f1b22ddf demos => .net7 2022-11-16 11:24:30 -05:00
Robert McRackan fb612ea6ab Bug fix #394 : Scanning dir.s containing symlinks causes errors. Thanks @CharlieRussel 2022-11-14 16:22:29 -05:00
Robert McRackan bce44b6f6d Fix string interpolation bugs 2022-11-14 15:16:22 -05:00
Robert McRackan 7575736991 Bugfix #389 : Handle corrupt cache file 2022-11-08 07:22:08 -05:00
Robert McRackan 06f8d055fc update dependencies 2022-11-02 16:24:14 -04:00
Robert McRackan d64e043fe8 #367 : New template option "year": year published to audible 2022-10-21 13:41:44 -04:00
Robert McRackan 99564d9c25 update dependencies 2022-10-18 08:33:43 -04:00
rmcrackan 29bccd3e33 Update InstallOnMac.md
Gatekeeper instructions
2022-10-05 22:25:40 -04:00
Robert McRackan 20f65f6534 Fix description of poorly named AutoDownloadEpisodes 2022-09-28 15:49:16 -04:00
Robert McRackan 8ca72b2e2d incr ver 2022-09-28 13:27:04 -04:00
Robert McRackan 75429f288f update dependencies 2022-09-28 13:25:41 -04:00
Robert McRackan d1bb921346 Cache assembly fetches/resolution so that repeat errors aren't clogging the log 2022-09-24 09:48:44 -04:00
rmcrackan b979b6ddad Update README.md 2022-09-24 07:54:48 -04:00
rmcrackan 4eba41ddbb Update GettingStarted.md 2022-09-23 21:48:16 -04:00
rmcrackan 418f5062ff Update README.md
remove unofficial linux instructions
2022-09-23 21:46:45 -04:00
rmcrackan f736f7f909 Update GettingStarted.md
remove unofficial linux instructions
2022-09-23 21:46:06 -04:00
rmcrackan 96ead28246 Update Advanced.md
remove unofficial linux instructions
2022-09-23 21:45:28 -04:00
Robert McRackan 34bad7a53d fix string template 2022-09-19 14:08:46 -04:00
Robert McRackan 7ac1fff3a0 update dependencies 2022-09-09 11:53:59 -04:00
Robert McRackan a4c5c53df3 incr ver 2022-09-09 11:10:56 -04:00
Robert McRackan 87db5cfd94 revert accidental re-name of button text 2022-09-09 11:04:14 -04:00
Robert McRackan 85e7bbf366 Chardonnay readonly textboxes should be grey (as they are in Classic) 2022-09-07 13:29:41 -04:00
Robert McRackan c55c5fac23 typo 2022-09-06 12:47:44 -04:00
Robert McRackan e25e2f7211 Update documentaion for macos 2022-08-31 15:44:12 -04:00
Robert McRackan f310d583d8 Bug fix #364 - app was crashing on attempt to download PDF to which the user no longer had ownership. Eg: returned or Plus catalog 2022-08-29 15:05:56 -04:00
Robert McRackan f05465b29b incr ver 2022-08-18 13:38:23 -04:00
rmcrackan 959e31972e Merge pull request #363 from Mbucari/master
Change assembly loadig
2022-08-18 13:36:08 -04:00
Michael Bucari-Tovo 17181811f0 Remove assembly hot loading 2022-08-18 11:21:40 -06:00
Michael Bucari-Tovo 6d2624d52b Fix comment 2022-08-18 10:59:37 -06:00
Michael Bucari-Tovo 9dd5940c8c Remove trailing wild 2022-08-18 10:59:00 -06:00
Michael Bucari-Tovo 1927d19961 comments 2022-08-18 10:47:53 -06:00
Michael Bucari-Tovo 09cc838bb4 Checks 2022-08-18 10:45:07 -06:00
Michael Bucari-Tovo 8af4c71101 Change assembly loadig 2022-08-18 10:29:30 -06:00
Robert McRackan 7ffdf45164 Bug fix #361 : import would break when audible erroneous duplicates a name in the author list or a name in the narrator list. (Note: the same name as both author and narrator has always been ok.) 2022-08-17 20:05:47 -04:00
Robert McRackan e0999dc9ae Bug fix #358 : pdf downoad errors in CLI were crashing the rest of the loop 2022-08-16 15:41:12 -04:00
Robert McRackan a0f3d44e97 revert changes to DownloadDecryptBook. This is not the correct fix 2022-08-16 14:54:12 -04:00
Robert McRackan 1510a86579 Bug fix #350 : support old style of large multi-part books 2022-08-16 10:14:13 -04:00
Robert McRackan b3581455d2 incr ver. Don't re-use previously bad build number 2022-08-15 22:03:51 -04:00
Robert McRackan 8ee1019fa5 ConfigApp.s need PublishReadyToRun and RuntimeIdentifies 2022-08-15 22:01:38 -04:00
Robert McRackan 285b10a95f bug fix: WindowsConfigApp must explicitly load a type from the Dinah.Core.WindowsDesktop asm since avalonia doesn't reference it 2022-08-15 10:20:41 -04:00
Robert McRackan 0ca33f864b oops: recent bug fix introduced an infinite loop. fixed 2022-08-15 09:41:33 -04:00
Robert McRackan a0823fa26c Bug fix. Book details dialog save button should also close the form 2022-08-14 21:53:34 -04:00
Robert McRackan aa9040da5d Fix release pragma OS var.s 2022-08-14 19:35:01 -04:00
Robert McRackan 222031ecc5 avalonia ui: add new setting 2022-08-14 11:12:52 -04:00
Robert McRackan dda8f5a974 publish profiles should point to Publish dir 2022-08-14 09:32:50 -04:00
Robert McRackan e9b484df04 * LoadByOS build profiles
* incr ver
2022-08-14 09:19:14 -04:00
rmcrackan d505264e86 Merge pull request #356 from Mbucari/master
Add useCoverAsFolderIconCb setting to avalonia
2022-08-13 18:33:38 -04:00
Michael Bucari-Tovo c0b1f1dc0a Add useCoverAsFolderIconCb setting to avalonia 2022-08-12 18:37:02 -06:00
Robert McRackan 1524d558a4 * Feature #307 : New windows setting to use cover art as folder's icon. Incomplete. Need to add to avalonia settings
* Interop refactor
2022-08-12 17:55:15 -04:00
Robert McRackan aea8c11dc4 Add OS-specific interop 2022-08-12 13:49:51 -04:00
Robert McRackan 86c7f89788 update dependencies 2022-08-08 11:47:08 -04:00
Robert McRackan 3272541e81 Audible changed how scanning works. You must upgrade to scan again 2022-08-02 21:20:14 -04:00
Robert McRackan 3b3d40e4e6 Add classic/chardonnay to About box 2022-08-02 14:40:58 -04:00
Robert McRackan a47866b6f7 Open file/folder is now cross platform 2022-08-02 12:56:52 -04:00
Robert McRackan 0df4dfdef5 update dependencies 2022-08-02 09:14:36 -04:00
Robert McRackan fe2de6ecf7 recommended: System.Environment.ProcessPath 2022-08-02 07:58:42 -04:00
Robert McRackan fc25e73b1a attach avalonia primer notes 2022-08-01 20:56:08 -04:00
Robert McRackan a3df85c87e Refactor hangover 2022-08-01 11:59:55 -04:00
Robert McRackan 553a936e7e incr ver 2022-08-01 09:49:45 -04:00
Robert McRackan 635764625e incl HangoverAvalonia in sln 2022-08-01 07:46:44 -04:00
rmcrackan f5599f7c57 Merge pull request #338 from Mbucari/master
HangoverAvalonia and other fixes
2022-08-01 07:36:25 -04:00
Mbucari dc6aaf2dd6 Updated instructions for Standalone Build (no dotnet runtime required) 2022-07-31 22:37:42 -06:00
Michael Bucari-Tovo f1ba2b4ae8 Merge branch 'master' of https://github.com/Mbucari/Libation 2022-07-31 22:24:28 -06:00
Michael Bucari-Tovo 742310b8d6 Fix install workflow 2022-07-31 22:24:17 -06:00
Mbucari 073787173d Merge branch 'rmcrackan:master' into master 2022-07-31 21:59:46 -06:00
Michael Bucari-Tovo 66679ace2f Add HangoverAvalonia 2022-07-31 20:33:56 -06:00
Robert McRackan 3982537d46 Tags no longer saved outside of database 2022-07-31 21:58:53 -04:00
Robert McRackan 7cf4c63d79 OSX-specific bug fix for search engine 2022-07-31 14:24:24 -04:00
Robert McRackan 7c4575cf66 incr ver 2022-07-30 22:39:41 -04:00
rmcrackan f4749d703f Merge pull request #337 from Mbucari/master
Fixes and Improvements
2022-07-30 22:24:37 -04:00
Michael Bucari-Tovo f2f562619b Updated dependencies 2022-07-30 20:09:17 -06:00
Robert McRackan 16c019a9c6 update dependencies 2022-07-30 21:54:10 -04:00
Robert McRackan 644dcbdd4d updated dependency 2022-07-30 21:40:31 -04:00
Michael Bucari-Tovo 6b112f5248 Delete obj and bin folders on clean 2022-07-30 18:03:33 -06:00
Michael Bucari-Tovo 0bfa609058 Libation Runs on MacOS 2022-07-30 16:09:31 -06:00
Michael Bucari-Tovo 8020ded642 Add platform preprocessor definitions 2022-07-30 13:42:11 -06:00
Michael Bucari-Tovo c4cd6b16fc Add macOS ID 2022-07-30 11:04:01 -06:00
Michael Bucari-Tovo 310012fd17 Merge branch 'master' of https://github.com/Mbucari/Libation 2022-07-30 11:03:19 -06:00
Michael Bucari-Tovo 06163db6ff Merge Conflict 2022-07-30 11:03:17 -06:00
Michael Bucari-Tovo 7689eed711 Add macOS identifier 2022-07-30 10:58:53 -06:00
Mbucari d396d697d7 Fix typos 2022-07-30 10:33:04 -06:00
Michael Bucari-Tovo 27ed11d904 More universal updating 2022-07-30 09:49:11 -06:00
Michael Bucari-Tovo 9e7670b918 Fix Subdirectory being added to custom directory selection 2022-07-30 09:48:57 -06:00
Michael Bucari-Tovo 31e97defd1 Add ReleaseIdentifier to logging 2022-07-30 09:48:27 -06:00
Mbucari 1a447627c7 Merge branch 'rmcrackan:master' into master 2022-07-28 20:04:36 -06:00
Robert McRackan 962b386d07 Bug fix: update checking code 2022-07-28 21:35:59 -04:00
Michael Bucari-Tovo d69ff24c2d Modularize update process 2022-07-28 17:18:43 -06:00
Michael Bucari-Tovo 070ed1d373 Merge branch 'master' of https://github.com/Mbucari/Libation 2022-07-28 17:06:18 -06:00
Michael Bucari-Tovo 47729bf7b0 fix release getter 2022-07-28 17:06:12 -06:00
Robert McRackan ed0ce2976b Bug fix #329 : Chardonnay-beta freezes after a scan 2022-07-28 13:26:16 -04:00
rmcrackan 2224f46ed5 Merge pull request #331 from Mbucari/master
Fix MessageBox hang
2022-07-28 13:22:03 -04:00
Michael Bucari-Tovo 433974323c Remove unnecessary extensions 2022-07-28 11:17:29 -06:00
Michael Bucari-Tovo 7525d318c0 Crean up helper methods 2022-07-28 11:03:22 -06:00
Michael Bucari-Tovo 92327dcc0d Add synchronous thread extensions 2022-07-28 10:40:39 -06:00
Michael Bucari-Tovo aeaf234edd Merge branch 'master' of https://github.com/Mbucari/Libation 2022-07-28 10:13:28 -06:00
Michael Bucari-Tovo a99b644917 Fix thread hang issue#329 2022-07-28 10:12:43 -06:00
Mbucari d79a55e5c9 Merge branch 'rmcrackan:master' into master 2022-07-28 09:43:20 -06:00
Mbucari 16b0feeb82 Create feature request template 2022-07-28 09:43:11 -06:00
Mbucari 7b3a25e45a Create bug report template 2022-07-28 09:42:33 -06:00
Robert McRackan 8effdcb92d add macos publish options. standardize publish profiles 2022-07-28 10:43:00 -04:00
Robert McRackan b12bef81bd These stupid unused language packs are 40% of our disk usage. And the SatelliteResourceLanguages bug *still* isn't fixed 2022-07-28 09:36:12 -04:00
Robert McRackan f04a5e0168 tweaks to getLatestRelease 2022-07-27 16:36:18 -04:00
rmcrackan e093729707 Merge pull request #325 from Mbucari/master
Add app update to Avalonia Build
2022-07-27 15:49:41 -04:00
Michael Bucari-Tovo 369151ada2 Revert timeout time 2022-07-27 09:55:09 -06:00
Michael Bucari-Tovo 1f685ae8a0 Add release index download 2022-07-27 09:49:58 -06:00
Mbucari bbe91099cb Update .releaseindex.json 2022-07-27 09:45:29 -06:00
Mbucari 92015ba4c2 Add files via upload 2022-07-27 09:27:57 -06:00
Mbucari 3bcacabadc Delete appcasttest.xml 2022-07-27 01:03:24 -06:00
Mbucari f5736d9151 Merge branch 'rmcrackan:master' into master 2022-07-27 00:46:04 -06:00
Michael Bucari-Tovo 59015f438e Add auto app update to windows avalonia 2022-07-27 00:36:13 -06:00
Michael Bucari-Tovo 3af47ab395 Add update name pattern matching 2022-07-27 00:35:55 -06:00
Michael Bucari-Tovo 308619b01a Fix bug if MessageBox called from worker thread 2022-07-27 00:30:35 -06:00
Robert McRackan 4efce57488 gitignore bin-Avalonia 2022-07-26 22:15:23 -04:00
Robert McRackan c8ee950f7d Linux beta 2022-07-26 21:14:43 -04:00
Mbucari 0bba0f9256 Add files via upload 2022-07-26 12:53:49 -06:00
rmcrackan 05bdff5123 Merge pull request #321 from Mbucari/master
Linux Beta
2022-07-26 08:16:55 -04:00
Mbucari e58e6cfb9f Update README.md 2022-07-25 19:51:35 -06:00
Mbucari b052871004 Update README.md 2022-07-25 19:48:01 -06:00
Mbucari d738f4f35f Update README.md 2022-07-25 17:33:59 -06:00
Michael Bucari-Tovo 7286aee9dd Merge branch 'master' of https://github.com/Mbucari/Libation 2022-07-25 17:22:29 -06:00
Michael Bucari-Tovo ca455978a5 Update for Linux 2022-07-25 17:22:17 -06:00
Mbucari 9c38bea5b7 Update README.md 2022-07-25 17:21:35 -06:00
Michael Bucari-Tovo fbec1bc569 Linux pub 2022-07-25 14:45:39 -06:00
Michael Bucari-Tovo 6dd885f0b2 Wrap save and restore in tyy/catch blocks 2022-07-25 08:19:46 -06:00
Mbucari ab38eb5571 Update README.md 2022-07-25 00:05:46 -06:00
Michael Bucari-Tovo 0e4b9ab396 Build standalone 2022-07-25 00:04:52 -06:00
Michael Bucari-Tovo 7dfedbc73b Remove beta checkbox 2022-07-24 16:51:38 -06:00
Michael Bucari-Tovo 625ae1d63c Removed Avalonia from LibationWinForms 2022-07-24 16:42:38 -06:00
Michael Bucari-Tovo 71098ef02f Publish Profiles 2022-07-24 16:33:45 -06:00
Mbucari d63a6de543 Update README.md 2022-07-24 16:33:19 -06:00
Mbucari 2a71a85306 Update README.md 2022-07-24 16:19:03 -06:00
Michael Bucari-Tovo 6de3a8a2bf Linux instructions 2022-07-24 16:14:34 -06:00
Michael Bucari-Tovo 3fc1da66de Linux compat 2022-07-24 14:46:27 -06:00
Michael Bucari-Tovo 683c221ca8 Linux compatability 2022-07-24 14:18:26 -06:00
Michael Bucari-Tovo fe6cfc899b Add Avalonia setup 2022-07-24 13:04:19 -06:00
Michael Bucari-Tovo ffd947eb2e A 2022-07-23 21:04:27 -06:00
Michael Bucari-Tovo 8dd59cb08a Refactor 2022-07-23 20:54:02 -06:00
Michael Bucari-Tovo 1e4c489983 Libation Runs on Linux! 2022-07-23 18:07:04 -06:00
Michael Bucari-Tovo 17b0da358f Add LinkLabel control 2022-07-22 20:11:13 -06:00
Michael Bucari-Tovo 6aa0a1f8b9 Remove references to winforms 2022-07-22 19:28:31 -06:00
Michael Bucari-Tovo ab731a63af Tweak MessageBox 2022-07-22 19:20:47 -06:00
Michael Bucari-Tovo 07d2c656fc Add description text 2022-07-22 18:33:49 -06:00
Michael Bucari-Tovo 9ecb32c3d2 Added login dialogs 2022-07-22 18:25:47 -06:00
Michael Bucari-Tovo 503e1e143e Separate invalid char check for folders and files. Files can't have slashes. 2022-07-22 18:11:39 -06:00
Mbucari e34ce67a2c Merge branch 'rmcrackan:master' into master 2022-07-22 12:39:09 -06:00
Robert McRackan a0fd0a3de6 Book details dialog. On open, tags should be first focus 2022-07-22 11:15:04 -04:00
Robert McRackan 7f3cbc454f Bug fix #319 : in some cases mp3 chapter metadata was incorrect 2022-07-21 22:29:12 -04:00
Mbucari 30eb117fa1 Merge branch 'rmcrackan:master' into master 2022-07-21 10:05:12 -06:00
Robert McRackan 63877160aa New feature #170 : book details, added link to audible's page for that book 2022-07-21 09:02:42 -04:00
Robert McRackan 77e61479cf New feature #284 : Add bitrate, sample rate, and channels to template options and to exports 2022-07-21 08:37:04 -04:00
Michael Bucari-Tovo ca71283108 Revert 2022-07-20 20:10:07 -06:00
Michael Bucari-Tovo 285563af5e Revert 2022-07-20 20:08:53 -06:00
Michael Bucari-Tovo 62cbad0d8f Commit works in progress 2022-07-20 19:41:56 -06:00
Michael Bucari-Tovo 2cb2479d63 Added EditTemplateDialog and LibationFilesDialog 2022-07-20 13:35:30 -06:00
Mbucari e7c5b1d8dc Merge branch 'rmcrackan:master' into master 2022-07-19 14:27:11 -06:00
Robert McRackan 7f086aeaac Bug fix #318: Audible changed their API, likely in conjunction with shutting down the Windows App. DownloadQuality.Extreme and DownloadQuality.Low now throw errors 2022-07-19 15:02:31 -04:00
Robert McRackan 78186d4973 update dependencies 2022-07-19 09:32:26 -04:00
Robert McRackan 4d84174ba6 AudibleApi: Make exceptions more flexible so that less logic is needed inside catch 2022-07-19 08:19:03 -04:00
Robert McRackan 579536f65a Revert: project publish => sln publish 2022-07-19 07:43:34 -04:00
Michael Bucari-Tovo a4ff739684 Merge branch 'master' of https://github.com/Mbucari/Libation 2022-07-18 23:01:20 -06:00
Michael Bucari-Tovo 9e06c70319 Merge branch 'master' of https://github.com/Mbucari/Libation 2022-07-18 23:00:55 -06:00
Michael Bucari-Tovo 0c98ce000b Added SettingsDialog 2022-07-18 23:00:40 -06:00
Robert McRackan 230b23dc80 on startup, log BetaOptIn 2022-07-18 22:15:11 -04:00
Robert McRackan d55b8eeeba Turn 'self contained' back on 2022-07-18 20:56:09 -04:00
rmcrackan decf75411f Merge pull request #313 from Mbucari/master
Fixed hidden items being duplicated on library scan
2022-07-18 15:08:04 -04:00
Mbucari c69f14dac5 Merge branch 'rmcrackan:master' into master 2022-07-18 12:37:13 -06:00
Michael Bucari-Tovo 10359aa5e8 Fixed hidden items being duplicated on library scan 2022-07-18 12:36:53 -06:00
Robert McRackan 72e030faaf Include beta feature: cross-platform UI 2022-07-18 14:26:19 -04:00
rmcrackan b21055d0ea Merge pull request #312 from Mbucari/master
Avalonia Beta release
2022-07-18 14:15:15 -04:00
Michael Bucari-Tovo 720fd64c97 Fixed visible books count not updating 2022-07-18 10:07:13 -06:00
Michael Bucari-Tovo e9a331292a Remove Commit method 2022-07-17 01:26:18 -06:00
Michael Bucari-Tovo 51fee4ae24 Remain classes and fix adding row to EditTagsDialog 2022-07-17 00:59:26 -06:00
Michael Bucari-Tovo 4cfe72a63b Add WheelComboBox 2022-07-17 00:44:32 -06:00
Michael Bucari-Tovo 6a8476c976 Undo change 2022-07-17 00:07:04 -06:00
Michael Bucari-Tovo 8bb17d09c3 Added beta opt-in setting 2022-07-16 23:57:12 -06:00
Michael Bucari-Tovo ad6b86fcb4 Added DescriptionDisplayDialog and ImageDisplayDialog 2022-07-16 23:27:56 -06:00
Michael Bucari-Tovo 1578be2520 Added MessageBoxAlertAdmin 2022-07-16 22:04:00 -06:00
Michael Bucari-Tovo 82d8d954ef Added EditQuickFilters dialog 2022-07-16 21:24:07 -06:00
Michael Bucari-Tovo eff9c2b35d Added AccountsDialog 2022-07-16 20:47:53 -06:00
Michael Bucari-Tovo ccdd1dc9f3 Added BookDetailsDialog, LiberatedStatusBatchDialog, ScanAccountsDialog, SearchSyntaxDialog and TagsBatchDialog 2022-07-16 17:47:54 -06:00
Michael Bucari-Tovo 952173d450 Added book details dialog 2022-07-16 15:06:37 -06:00
Michael Bucari-Tovo 35f677a0fa Added gridlines 2022-07-15 20:57:22 -06:00
Michael Bucari-Tovo 51d0645699 Add stasrt time testing 2022-07-15 17:05:13 -06:00
Michael Bucari-Tovo 0189a197a8 Refactoring 2022-07-15 16:36:58 -06:00
Michael Bucari-Tovo 1ce5fedc8c Refactor ProductDisplay 2022-07-15 15:58:21 -06:00
Michael Bucari-Tovo d336848ed0 Change how large cover image viewer loads images 2022-07-15 15:42:34 -06:00
Michael Bucari-Tovo 8cd6219bd9 Performance improvements and better mvvp pattern following 2022-07-15 15:16:27 -06:00
Michael Bucari-Tovo c2a2e51bde Improve re-display function 2022-07-15 13:09:19 -06:00
Michael Bucari-Tovo d62821cd60 Refactor 2022-07-15 01:06:55 -06:00
Michael Bucari-Tovo 180d591b0a Make Form1 MVVM 2022-07-15 00:23:22 -06:00
Michael Bucari-Tovo 7b7e1d8574 Further sorting and remove books refinements 2022-07-14 21:14:40 -06:00
Michael Bucari-Tovo efd6156fa8 Fix STAThread error 2022-07-14 18:25:28 -06:00
Michael Bucari-Tovo 428ea5e864 Improve AvaloniaUI startup times 2022-07-14 17:57:46 -06:00
Michael Bucari-Tovo 2b6d1201b6 Add save and restore form size 2022-07-14 15:41:30 -06:00
Michael Bucari-Tovo de3524d688 refine message box. 2022-07-14 13:26:36 -06:00
Michael Bucari-Tovo 61a529e62b MessageBox revision and more async loading 2022-07-14 12:51:50 -06:00
Michael Bucari-Tovo a5d225dc44 Minor refactor 2022-07-14 02:46:45 -06:00
Michael Bucari-Tovo 7b28a274a8 Startup speedup 2022-07-14 02:35:38 -06:00
Michael Bucari-Tovo 26508e6a8a Speed up start time 2022-07-14 02:18:26 -06:00
Michael Bucari-Tovo c8d91032c0 Refactor 2022-07-14 01:07:07 -06:00
Michael Bucari-Tovo 7a8e910697 Add Avalonia MessageBox 2022-07-14 00:50:50 -06:00
Michael Bucari-Tovo 31d6fc8197 Refactor 2022-07-13 19:03:52 -06:00
Michael Bucari-Tovo e23e267d17 Add column customizations 2022-07-13 18:47:43 -06:00
Michael Bucari-Tovo c727286d22 Move ProcessQueue biz logic into viewmodel 2022-07-13 17:06:18 -06:00
Michael Bucari-Tovo 3a61c32881 Fix sorting and refactor 2022-07-13 16:07:05 -06:00
Michael Bucari-Tovo e33fd6ea1b Default invisible 2022-07-13 02:23:55 -06:00
Michael Bucari-Tovo aa8e3ac09b More sorting hacking 2022-07-13 02:21:05 -06:00
Michael Bucari-Tovo eb49dcfc54 Incremental prgress. 2022-07-13 01:14:05 -06:00
Michael Bucari-Tovo 6182b2bcee Improve styles and fix sotring of podcasts when they are collapsed. 2022-07-12 22:01:11 -06:00
Michael Bucari-Tovo 6e091230cf Use ReactiveUI.
Sort of fix remove book checkbox column.
2022-07-12 18:56:25 -06:00
Michael Bucari-Tovo 5f45d28b9f Refinements 2022-07-12 00:18:56 -06:00
Michael Bucari-Tovo f8e9c16bc1 Change some defaults 2022-07-11 21:57:41 -06:00
Michael Bucari-Tovo a66b7a6eab Add queue log and improve display styles 2022-07-11 21:43:20 -06:00
Michael Bucari-Tovo 3b42b52ff4 Improve sorting 2022-07-11 19:07:20 -06:00
Michael Bucari-Tovo df5293ce1e Fix bug caused by moving column before frozen "Remove" column 2022-07-11 12:58:20 -06:00
Michael Bucari-Tovo 664ff6aabd Merge branch 'master' of https://github.com/Mbucari/Libation 2022-07-11 00:13:41 -06:00
Michael Bucari-Tovo 0de62ce010 Port Form1 to Avalonia 2022-07-11 00:13:32 -06:00
Robert McRackan 9eafbacad9 Add Audible ID to BookDetailsDialog 2022-07-08 23:04:05 -04:00
Robert McRackan 058eb31110 trivial change to test local github account settings 2022-07-08 21:43:10 -04:00
Robert McRackan 29de8f5706 trivial change to test github settings 2022-07-08 21:42:17 -04:00
Robert McRackan ef869dbe09 new publish settings moved to Libation's settings in GitHubReleaser
old sizes
zipped 70.5 MB
unzipped 164 MB

new sizes
zipped 22.5 MB
unzipped 52.4 MB
2022-07-08 14:59:31 -04:00
Robert McRackan 9f8b320493 no longer needed 2022-07-07 21:43:51 -04:00
Robert McRackan ef72e04be3 Oops! I only meant to get rid of the bump, not the embedded. Reverting 2022-07-07 16:47:08 -04:00
Robert McRackan 38d280b7f4 v8.1.7 2022-07-07 14:22:05 -04:00
Robert McRackan 468356d676 increm ver 2022-07-06 16:52:37 -04:00
rmcrackan 7364700899 Merge pull request #305 from Mbucari/master
Fix some bugs with user settings.
2022-07-06 16:50:32 -04:00
Michael Bucari-Tovo e65f19cf24 Restore tool 2022-07-06 14:23:03 -06:00
Michael Bucari-Tovo 4272dfe03d Reformat for style 2022-07-06 14:18:53 -06:00
Michael Bucari-Tovo 3b739328fb Fix some bugs with user settings. 2022-07-06 13:10:37 -06:00
Robert McRackan 81c3dca740 increm ver 2022-06-26 17:08:55 -04:00
rmcrackan dceb3121b1 Merge pull request #300 from Mbucari/master
Option to combine Opening/End Credits chapters and other changes
2022-06-26 16:12:17 -04:00
Michael Bucari-Tovo cb60a97b91 Embed PDBs 2022-06-26 13:26:36 -06:00
Michael Bucari-Tovo eb658396d2 Merge branch 'master' of https://github.com/Mbucari/Libation 2022-06-26 13:16:31 -06:00
Michael Bucari-Tovo 0a1cefdb76 Update audible version 2022-06-26 13:16:27 -06:00
Robert McRackan fb618e6719 api bug fix 2022-06-26 15:09:07 -04:00
Mbucari 2d529539cd Merge branch 'rmcrackan:master' into master 2022-06-26 13:02:02 -06:00
Michael Bucari-Tovo 9d93a98a58 Update reference 2022-06-26 13:01:40 -06:00
Michael Bucari-Tovo 38dcb10a6e Update reference 2022-06-26 12:59:02 -06:00
Michael Bucari-Tovo 50651339ec Don't throw on unidentified series. 2022-06-26 11:40:48 -06:00
Robert McRackan d0b2889fec Bug fix #294 mp3s which are split by chapter 2022-06-26 12:55:19 -04:00
Michael Bucari-Tovo 3ce1f94f87 Revert preview feature 2022-06-26 10:42:52 -06:00
Michael Bucari-Tovo 888967be31 Pack files, not folder. 2022-06-26 01:22:46 -06:00
Michael Bucari-Tovo 6826237657 Use powershell script to publish and zip libation 2022-06-26 01:16:17 -06:00
Michael Bucari-Tovo a8987cf1d3 Only increment build number on debug builds 2022-06-25 17:06:28 -06:00
Michael Bucari-Tovo d48a74912a Use abstract static member, add publish script 2022-06-25 16:48:23 -06:00
Mbucari 1668b7c9a1 Merge branch 'rmcrackan:master' into master 2022-06-25 13:43:50 -06:00
Robert McRackan efa2cfb50b Bug fix #294 2022-06-25 14:50:14 -04:00
Michael Bucari-Tovo 071b1a54d5 Publish Embedded 2022-06-25 05:11:21 -06:00
Michael Bucari-Tovo 7c3bba2ffd Merge branch 'master' of https://github.com/Mbucari/Libation 2022-06-24 23:27:53 -06:00
Michael Bucari-Tovo d58092968a Add option to merge Opening/End Credits with following/preceding chapters 2022-06-24 23:26:52 -06:00
Michael Bucari-Tovo 1b20bb06ad Add some filename length headroom in case of diplicate files and " (n)" suffix. 2022-06-24 23:23:08 -06:00
Michael Bucari-Tovo 5815a04712 Add bitrate to Book 2022-06-24 23:09:20 -06:00
Robert McRackan 85c449bec0 Logging and error handling for issue #294 2022-06-24 07:27:26 -04:00
rmcrackan 10bdddb262 Merge pull request #296 from Mbucari/master
Error handling inside all click handlers
2022-06-24 07:15:32 -04:00
Michael Bucari-Tovo b65875386d Add error handling to ProductsGrid.DataGridView_CellContentClick 2022-06-23 22:32:43 -06:00
Michael Bucari-Tovo 76b5e09f72 Add error handling around all ui click handlers for book downloads. 2022-06-23 21:17:43 -06:00
Michael Bucari-Tovo 0fe07695b2 Make better use of hierarchical chapters and add test 2022-06-23 20:45:41 -06:00
Michael Bucari-Tovo 51f9b4f473 More character replacement safety 2022-06-23 20:45:09 -06:00
Robert McRackan 153e1b92bf Bug fixes, logging, options for how to handle illegal characters 2022-06-23 21:01:44 -04:00
rmcrackan fc5ae7403a Merge pull request #295 from Mbucari/master
Optional illegal character replacement and more error handling/logging
2022-06-23 20:56:58 -04:00
Michael Bucari-Tovo 13149eff08 Make better use of heirarch chapters to combine section title audio (which is usually short, eg "Part 1") with the following full-length chapter. 2022-06-23 17:29:45 -06:00
Michael Bucari-Tovo 9c53d9bf87 Better open/close quote detection 2022-06-23 16:52:13 -06:00
Michael Bucari-Tovo bc9625fece Disallow illegal chars in templates 2022-06-23 16:36:56 -06:00
Michael Bucari-Tovo 7e00162ef2 Code reuse and better naming 2022-06-23 16:28:21 -06:00
Michael Bucari-Tovo af38750e29 Fix reverted changes 2022-06-23 16:19:00 -06:00
Michael Bucari-Tovo 314f4850bc Add logging and error handling to Process Queue. and Processables 2022-06-23 15:38:39 -06:00
Michael Bucari-Tovo 9ff2a83ba3 Rename Minimum to Barebones 2022-06-23 13:11:35 -06:00
Michael Bucari-Tovo 2ab466c570 Custom illegal character replacement 2022-06-23 13:01:24 -06:00
Mbucari 184ba84600 Merge branch 'rmcrackan:master' into master 2022-06-23 11:35:09 -06:00
Michael Bucari-Tovo 99dddb1af4 Revert "* bug fix: occasional hang bug in process queue"
This reverts commit b7fd87b09c.
2022-06-23 11:34:50 -06:00
Michael Bucari-Tovo 48eca3f5af Revert "Add character replacement"
This reverts commit 1470aefd42.
2022-06-23 11:34:39 -06:00
Michael Bucari-Tovo 71192cc2ee Revert "Match rmcrackan's changes"
This reverts commit 52622fadbb.
2022-06-23 11:34:29 -06:00
Michael Bucari-Tovo 29c7344540 Revert "linux + WINE link"
This reverts commit eff2634b32.
2022-06-23 11:34:24 -06:00
Michael Bucari-Tovo 6411d23744 Revert "Non-null disposed BlockingCollection can throw exception"
This reverts commit ba722487d8.
2022-06-23 11:34:20 -06:00
Michael Bucari-Tovo 1a74736115 Revert "Improve display and function of character replacement"
This reverts commit b698697256.
2022-06-23 11:34:11 -06:00
Michael Bucari-Tovo 7c11ecb3a7 Revert "Change type"
This reverts commit 839a62cb07.
2022-06-23 11:34:07 -06:00
Michael Bucari-Tovo fd7c833de0 Revert "make auto-scan more fault-tolerant"
This reverts commit f802d1524f.
2022-06-23 11:34:00 -06:00
Michael Bucari-Tovo 7fec8b0d7e Merge branch 'master' of https://github.com/Mbucari/Libation 2022-06-23 11:07:18 -06:00
Michael Bucari-Tovo 52622fadbb Match rmcrackan's changes 2022-06-23 11:07:10 -06:00
Robert McRackan 57255e0aec comments 2022-06-23 07:53:12 -04:00
rmcrackan 17ecfa132d Merge pull request #293 from Dr-Blank/master
Spellcheck in Comments and Strings
2022-06-23 06:53:54 -04:00
Dr-Blank d1365c3d7d Spellcheck in Comments and Strings
Corrected some spellings in Display messages and Comments.
2022-06-22 23:35:54 -04:00
Robert McRackan c33891a4bc update dependencies 2022-06-22 22:13:56 -04:00
Michael Bucari-Tovo 9a63f57147 Merge branch 'master' of https://github.com/Mbucari/Libation 2022-06-22 08:01:48 -06:00
Michael Bucari-Tovo 839a62cb07 Change type 2022-06-22 08:01:39 -06:00
Mbucari dc598e466e Merge branch 'rmcrackan:master' into master 2022-06-21 23:40:21 -06:00
Michael Bucari-Tovo b698697256 Improve display and function of character replacement 2022-06-21 23:39:24 -06:00
Robert McRackan f802d1524f make auto-scan more fault-tolerant 2022-06-21 22:44:25 -04:00
Mbucari 0cb18f9e1a Merge branch 'rmcrackan:master' into master 2022-06-21 20:17:27 -06:00
Robert McRackan ba722487d8 Non-null disposed BlockingCollection can throw exception 2022-06-21 21:08:49 -04:00
rmcrackan eff2634b32 linux + WINE link 2022-06-21 20:54:38 -04:00
Michael Bucari-Tovo 1470aefd42 Add character replacement 2022-06-21 18:50:30 -06:00
Robert McRackan b7fd87b09c * bug fix: occasional hang bug in process queue
* bug fix: #283 template folders
2022-06-21 10:42:57 -04:00
rmcrackan ab82a1656d Merge pull request #282 from Mbucari/master
Fixed rare bug that would hang if an error occured while downloading
2022-06-21 10:34:31 -04:00
Michael Bucari-Tovo 71387e94d8 Fix bug if folder ended in trailing slash 2022-06-21 08:08:09 -06:00
Michael Bucari-Tovo 503379079b Fix WaitToPosition logic 2022-06-21 00:23:02 -06:00
Michael Bucari-Tovo 1ae767087f Check downloadEnded inside WaitToPosition 2022-06-20 23:13:34 -06:00
Michael Bucari-Tovo cfd2b7b7aa Fixed rare bug that would cause a hang if an error occured in the download loop 2022-06-20 22:36:14 -06:00
Robert McRackan 2c42b4c585 * #278 -- new hier. chapters format
* #281 -- template bug fix

Thanks for the quick turn-around, @MBucari !
2022-06-20 21:02:15 -04:00
rmcrackan d3a9ff539e Merge pull request #280 from Mbucari/master
Add support for Audible's new  hierarchical chapters
2022-06-20 20:57:06 -04:00
Michael Bucari-Tovo 58f01bd642 Fix possible x-thread error. 2022-06-20 18:45:44 -06:00
Michael Bucari-Tovo 38806740e1 Use Path.Join instead of string.Join 2022-06-20 18:12:29 -06:00
Michael Bucari-Tovo df583e73c2 Fixed file naming template 2022-06-20 17:37:52 -06:00
Michael Bucari-Tovo e787d33e5a Fix NRE on cancel when there's nothing to cancel. 2022-06-20 16:47:25 -06:00
Michael Bucari-Tovo 91db665428 Merge branch 'master' of https://github.com/Mbucari/Libation 2022-06-20 15:45:00 -06:00
Michael Bucari-Tovo 94d155cff2 Add support for Audible's new hierarchical chapters. 2022-06-20 15:41:37 -06:00
Robert McRackan ad79075fd7 Fix issues #183 and #186 2022-06-20 16:30:40 -04:00
rmcrackan 7baefe2f44 Merge pull request #277 from Mbucari/master
Issues #183 and #186, and a lot of other little things
2022-06-20 16:29:20 -04:00
Michael Bucari-Tovo 141a4c29bb Correct error in saving settings 2022-06-20 14:04:03 -06:00
Michael Bucari-Tovo b2992da370 Move DownloadOptions to FileLiberator 2022-06-20 10:22:21 -06:00
Michael Bucari-Tovo fdee254020 Only copy files if conversion succeeded. 2022-06-20 09:04:06 -06:00
Michael Bucari-Tovo c51489ac74 Await cancell 2022-06-19 18:49:47 -06:00
Michael Bucari-Tovo 3cd394ec10 Change unicode asterisk 2022-06-19 18:04:00 -06:00
Michael Bucari-Tovo 8374fea776 Update tests for unicode chars 2022-06-19 17:59:16 -06:00
Michael Bucari-Tovo 733ca891de Fix unicode replacement 2022-06-19 17:29:46 -06:00
Michael Bucari-Tovo 490d121db3 Add unicode replacements for illegal characters 2022-06-19 16:57:44 -06:00
Michael Bucari-Tovo 45c5efffbd Add support for multipart title naming templates 2022-06-19 15:42:21 -06:00
Michael Bucari-Tovo a24c929acf Update tests for long file paths 2022-06-19 15:38:59 -06:00
Michael Bucari-Tovo 86a39f10d1 Formatting 2022-06-19 12:59:35 -06:00
Michael Bucari-Tovo 4658afdc20 Add Track Number support and make Cancel async 2022-06-19 12:56:33 -06:00
Michael Bucari-Tovo ae6c2afb30 Improve filename template 2022-06-18 13:04:57 -06:00
Michael Bucari-Tovo a3844a3535 Add long path support 2022-06-18 11:28:48 -06:00
Michael Bucari-Tovo b710075544 Make use of unauthenticated API 2022-06-17 23:09:22 -06:00
Mbucari c4c9786050 Merge branch 'rmcrackan:master' into master 2022-06-17 16:46:31 -06:00
Robert McRackan b4cc81139a Bug fix ( #276 ): x-thread error on fresh install 2022-06-17 12:40:37 -04:00
Mbucari fb20eb9162 Merge branch 'rmcrackan:master' into master 2022-06-15 14:22:09 -06:00
Robert McRackan 263987d2c9 Merge branch 'master' of https://github.com/rmcrackan/Libation 2022-06-15 10:43:04 -04:00
Robert McRackan 0b30a35383 updated dependencies 2022-06-15 10:42:56 -04:00
Mbucari 47df1fc602 Merge branch 'rmcrackan:master' into master 2022-06-14 10:46:00 -06:00
rmcrackan d8375454b9 Merge pull request #274 from maaximal/spelling
Fix spelling error
2022-06-14 09:16:05 -04:00
Max Byszio ad535501c4 Fix spelling error 2022-06-14 14:43:21 +02:00
Michael Bucari-Tovo 159f5cbd00 Add lame options to ConvertToMp3 2022-06-13 22:18:00 -06:00
Michael Bucari-Tovo 2bc74d5378 Combine Streamable and Processable, remove unused events. 2022-06-13 21:40:37 -06:00
Robert McRackan eb513f563e Allow sorting by "Remove" column 2022-06-13 13:55:39 -04:00
rmcrackan 09dc5e9846 Merge pull request #273 from Mbucari/master
Add option to save episodes to series parent
2022-06-13 12:00:05 -04:00
Mbucari cf35a87d85 Update AppScaffolding.csproj 2022-06-12 19:48:51 -06:00
Michael Bucari-Tovo 9f25f619a8 Formatting 2022-06-12 19:37:42 -06:00
Michael Bucari-Tovo 7e989c730c Add option to save podcasts to series folder 2022-06-12 19:36:18 -06:00
Robert McRackan 0926e86956 Version 8 2022-06-12 21:20:02 -04:00
rmcrackan 75967730fd Merge pull request #271 from Mbucari/master
Move Remove Books function into main grid, added more db migrations and fixups for episodes
2022-06-12 21:14:51 -04:00
Michael Bucari-Tovo a3be3e354f Code readability changes 2022-06-12 17:30:11 -06:00
Michael Bucari-Tovo 58c52196f1 Remove Books button now on Main button row 2022-06-12 17:03:29 -06:00
Michael Bucari-Tovo b7b49a60cf Migration Exception handling 2022-06-12 16:35:48 -06:00
Michael Bucari-Tovo fa195483d6 Set Import/Esport initial directory 2022-06-12 16:29:33 -06:00
Michael Bucari-Tovo 2341f6ea3b Better display and hiding of process queue 2022-06-12 16:29:06 -06:00
Michael Bucari-Tovo ffe0f0730d Don't fire click for error books 2022-06-12 15:27:10 -06:00
Michael Bucari-Tovo 23b512910e Update 2022-06-12 15:23:55 -06:00
Michael Bucari-Tovo b1c624b104 Revised stoplight icons 2022-06-12 15:17:07 -06:00
Michael Bucari-Tovo fe35be6682 New libation icons 2022-06-12 13:39:35 -06:00
Michael Bucari-Tovo 2d3eb29bd5 Move event invoke out of lock 2022-06-11 19:10:08 -06:00
Michael Bucari-Tovo 26f0ff62df Additional safety check 2022-06-11 15:10:18 -06:00
Michael Bucari-Tovo 5e145846bd Only check non-liberated books when doing scan remove books. 2022-06-11 12:42:00 -06:00
Michael Bucari-Tovo 1ae5f99bf0 Add migration to try and fix db for incorrect or missing espiode series entries. 2022-06-11 12:41:20 -06:00
Michael Bucari-Tovo 984119c7ee Exit download loop if zero bytes are read. 2022-06-10 21:00:04 -06:00
Michael Bucari-Tovo f8f5eac109 Refactor 2022-06-10 20:45:10 -06:00
Michael Bucari-Tovo 4111d5fa48 Remove redundant declarations. 2022-06-10 19:37:50 -06:00
Michael Bucari-Tovo 2eca9056b9 Reorder api calls 2022-06-10 19:36:00 -06:00
Michael Bucari-Tovo 60e96572ff Always refresh token, regardless of expiration date. 2022-06-10 19:34:49 -06:00
Michael Bucari-Tovo 52193933b2 Add scan and remove books tomain view, remove separate dialog. 2022-06-10 19:22:54 -06:00
Michael Bucari-Tovo 7bcabdda38 FindInactiveBooks now fires ScanBegin and ScanEnd events 2022-06-10 18:30:16 -06:00
Mbucari d993941c4d Merge branch 'rmcrackan:master' into master 2022-06-10 15:41:07 -06:00
Michael Bucari-Tovo b447bff9a6 Add audible-cli import/export accounts 2022-06-10 15:19:05 -06:00
Robert McRackan 73cb5ffba4 clearly Hoopla integration isn't going to happen. delete temp files 2022-06-09 17:01:33 -04:00
Robert McRackan 7d694229c1 Prep for version release 2022-06-08 14:48:44 -04:00
rmcrackan cdb6c9a1a4 Merge pull request #268 from Mbucari/master
Address issues in 263
2022-06-08 14:46:17 -04:00
Michael Bucari-Tovo cc1d2b423f Fix an oopsie 2022-06-08 12:15:21 -06:00
Michael Bucari-Tovo 508e031143 Move all event invocations outside locks 2022-06-08 12:08:15 -06:00
Michael Bucari-Tovo 5a093a9a04 add event keyword 2022-06-08 10:53:45 -06:00
Michael Bucari-Tovo 074d647d19 Improve Query 2022-06-08 10:36:06 -06:00
Michael Bucari-Tovo 6cb98f99c5 Use new content type queries 2022-06-08 10:34:05 -06:00
Michael Bucari-Tovo 7d28681b23 Move queries into DataLayer 2022-06-08 10:08:18 -06:00
Michael Bucari-Tovo 859a8e933c Formatting 2022-06-08 09:46:11 -06:00
Michael Bucari-Tovo a476d5986d Update dependency 2022-06-08 09:44:06 -06:00
Michael Bucari-Tovo 31812bc2d9 Refactoring 2022-06-08 09:24:06 -06:00
Michael Bucari-Tovo 30ba69eca7 Minor refactoring. 2022-06-08 08:52:25 -06:00
Michael Bucari-Tovo cf1bc1c252 By defauly, only get actual books and not parents from DB 2022-06-08 08:40:25 -06:00
Michael Bucari-Tovo ee109ba67d Refactor 2022-06-08 08:39:59 -06:00
Michael Bucari-Tovo 9c6211e8e0 Improve UI speed when adding many books to queue at once. 2022-06-08 08:39:17 -06:00
Michael Bucari-Tovo 0729e4ab09 Minor refactor 2022-06-07 15:41:33 -06:00
Michael Bucari-Tovo 5cbe728631 Don't add series parents to list 2022-06-07 15:32:49 -06:00
Michael Bucari-Tovo 920f4df213 Use new ContentType.Parent to add series info to grid display 2022-06-07 15:28:16 -06:00
Michael Bucari-Tovo c48eacd9af Add ContentType.Parent
Import Series parent when only individual episodes are in library
2022-06-07 15:27:18 -06:00
Michael Bucari-Tovo 30e6deeeaa Add migration to cleans DB of 7.10.1 hack 2022-06-07 15:25:52 -06:00
Robert McRackan 5bc76a3160 New debugging tool: "Hangover". Will be packaged with all releases 2022-06-01 11:49:30 -04:00
Robert McRackan 114925ebce Global exception handling. Threadsafe MessageBoxAlertAdminDialog 2022-05-27 13:38:28 -04:00
Robert McRackan 5a80a0cc06 Second bug fix for issue 263 2022-05-27 07:15:15 -04:00
rmcrackan aebefac7e6 Merge pull request #266 from Mbucari/master
Fix my own screwup
2022-05-27 07:10:02 -04:00
Michael Bucari-Tovo b2d0ee41f2 Fix my own screwup 2022-05-26 21:26:56 -06:00
Robert McRackan 9c20250b0a increm ver 2022-05-26 21:10:12 -04:00
rmcrackan b196836fca Merge pull request #264 from Mbucari/master
Fix for episodes with no series link
2022-05-26 20:41:55 -04:00
Michael Bucari-Tovo d9fbcc615a Change flow 2022-05-26 18:06:44 -06:00
Michael Bucari-Tovo fb247fb33f Add better handling for parents and series with no children. 2022-05-26 17:29:55 -06:00
Michael Bucari-Tovo 61f4dbd896 No need to make a new list. 2022-05-26 16:50:43 -06:00
Michael Bucari-Tovo 2c86571818 Better identification of Chilv vs Parent from SeriesBook.Order 2022-05-26 16:49:03 -06:00
Michael Bucari-Tovo 1b2ec67726 Add series info for parent will null order. 2022-05-26 16:43:56 -06:00
Michael Bucari-Tovo 845af854bd Add exception handling to products display 2022-05-26 16:29:40 -06:00
Mbucari 15b6a66d98 Merge branch 'rmcrackan:master' into master 2022-05-26 16:13:13 -06:00
Michael Bucari-Tovo c95ba0764b Fix bug and add groundwork for future feature 2022-05-26 16:11:52 -06:00
Robert McRackan 42c0648ba7 Bug fix #262 : 'file not found' after moved dir 2022-05-26 16:11:03 -04:00
Robert McRackan 0a6e55dcb7 * Much faster library scans
* Libraries of unlimited size now supported (prev limit was 10k)
2022-05-26 11:33:05 -04:00
rmcrackan 99b77decff Merge pull request #260 from Mbucari/master
Throttle episode scanning to 10 concurrent scans.
2022-05-26 11:29:18 -04:00
Robert McRackan 9e2ca4e586 update dependencies 2022-05-26 10:45:57 -04:00
Michael Bucari-Tovo 2e8acfdeef Limnit episode concurrency to 5 2022-05-26 08:44:39 -06:00
Michael Bucari-Tovo 630096e06d Merge branch 'master' of https://github.com/Mbucari/Libation 2022-05-26 08:43:33 -06:00
Michael Bucari-Tovo d92d892dc7 logging 2022-05-25 20:45:18 -06:00
Michael Bucari-Tovo a8f41841bd Throttle episode scanning to 10 concurrent scans. 2022-05-25 20:43:12 -06:00
rmcrackan 76954b5a0a Merge pull request #258 from Mbucari/master
Add support for unlimited library size.
2022-05-25 22:00:22 -04:00
Michael Bucari-Tovo c57b184a09 Remove test params 2022-05-25 16:51:25 -06:00
Michael Bucari-Tovo 20ca4e0739 Refactor for clarity. 2022-05-25 16:49:22 -06:00
Mbucari a972ed5e2e Merge branch 'rmcrackan:master' into master 2022-05-25 16:05:31 -06:00
Michael Bucari-Tovo 2b15bc6ebb Count Items as they come in and log total. 2022-05-25 15:11:38 -06:00
Robert McRackan f7a482659c New feature #241 : Auto download episodes after scanning. Setting is on Import Library tab 2022-05-25 15:21:28 -04:00
Robert McRackan 99527453a7 add TODO 2022-05-25 12:56:34 -04:00
Robert McRackan 3408b4637c search engine cleanup 2022-05-25 12:49:24 -04:00
Robert McRackan 3f2899e97e * New event SearchEngineCommands.SearchEngineUpdated
* Clean up redundant event notifications
2022-05-25 10:09:27 -04:00
Michael Bucari-Tovo 562496cfaa Add more logging 2022-05-24 21:36:56 -06:00
Michael Bucari-Tovo 8283f19d6b Parallelize getChildEpisodesAsync 2022-05-24 21:17:59 -06:00
Michael Bucari-Tovo 242909b542 Don't import empty episode 2022-05-24 18:39:47 -06:00
Michael Bucari-Tovo a7b83ad5e0 Remove 10,000 book limitation and simplify episode import 2022-05-24 18:27:20 -06:00
Michael Bucari-Tovo ed66019d9a Cleanup 2022-05-24 18:24:53 -06:00
Michael Bucari-Tovo bc0009be6c Use event return value instead of passing a set delegate. 2022-05-24 15:47:30 -06:00
Michael Bucari-Tovo c88f47eed4 Merge branch 'master' of https://github.com/Mbucari/Libation 2022-05-24 15:34:09 -06:00
Michael Bucari-Tovo 59de048ced Error handling network error. 2022-05-24 15:33:52 -06:00
Robert McRackan 7987dfb819 Rename 'liberate visible' menu items. Similar names are error-prone 2022-05-24 15:45:56 -04:00
Robert McRackan 1b101106e7 Merge branch 'master' of https://github.com/rmcrackan/Libation 2022-05-24 15:32:42 -04:00
rmcrackan 7b75955aec Merge pull request #257 from Mbucari/master
Fix hang on grid update
2022-05-24 15:32:29 -04:00
Michael Bucari-Tovo 8f5467e6ca Revert stupid change. 2022-05-24 13:30:39 -06:00
Michael Bucari-Tovo 28764f92b9 Merge branch 'master' of https://github.com/Mbucari/Libation 2022-05-24 13:16:56 -06:00
Michael Bucari-Tovo 777dfe4c62 Fix hang on grid update 2022-05-24 13:16:44 -06:00
Robert McRackan 0878a704d9 search engine: podcast and episode should allow plural 2022-05-24 15:07:53 -04:00
Robert McRackan f880897542 Increm version 2022-05-24 14:04:53 -04:00
rmcrackan b37472a954 Merge pull request #255 from Mbucari/master
Implemented Episode grouping and refactored ProductsGrid
2022-05-24 13:59:12 -04:00
Michael Bucari-Tovo 68735a45dd Change episode color 2022-05-24 11:52:33 -06:00
Michael Bucari-Tovo e26deb9092 Address comments 2022-05-24 11:15:41 -06:00
Michael Bucari-Tovo 43d6ea82cd Change failure behavior to match previous implementation 2022-05-24 09:17:09 -06:00
Mbucari db1aa495ac Merge branch 'rmcrackan:master' into master 2022-05-24 08:48:32 -06:00
Michael Bucari-Tovo ee62d9ae8d Attempt to fix app hang on LogMe event 2022-05-24 07:36:17 -06:00
Robert McRackan 4001124cfa AudibleApi. Better logging around getting pdf url 2022-05-24 09:03:43 -04:00
Michael Bucari-Tovo 43a4d0d1d7 Cleanup 2022-05-23 22:24:45 -06:00
Michael Bucari-Tovo 632b432b7c Revert to old column indexing 2022-05-23 22:21:37 -06:00
Michael Bucari-Tovo e778c7a59d Create GridView namespace 2022-05-23 21:34:43 -06:00
Michael Bucari-Tovo d71cdecd35 Refactoring and addressing comments 2022-05-23 21:20:26 -06:00
Michael Bucari-Tovo 4a82541ffd Fix error while removing filter on a sorted binding list 2022-05-23 17:46:55 -06:00
Michael Bucari-Tovo f29dff3386 Fix filtering bug 2022-05-23 17:22:02 -06:00
Michael Bucari-Tovo 718d21f6cb NotifyPropertyChanged series on update 2022-05-23 16:42:05 -06:00
Michael Bucari-Tovo 440550ded9 Add binding source at design time 2022-05-23 16:35:18 -06:00
Michael Bucari-Tovo 593fe57ea1 Refactor ProductsGrid 2022-05-23 15:29:26 -06:00
Michael Bucari-Tovo e8a320dac9 Add grid categories 2022-05-22 20:00:41 -06:00
Michael Bucari-Tovo 3cb43e5d3e Improve display 2022-05-22 20:00:06 -06:00
Robert McRackan f86bdba3c3 Test in-place upgrade 2022-05-20 16:26:58 -04:00
Robert McRackan 98c3940297 New feature ( #153 ): in-place upgrade 2022-05-20 16:20:28 -04:00
Robert McRackan b9e789bbcf Merge branch 'master' of https://github.com/rmcrackan/Libation 2022-05-20 14:22:09 -04:00
Robert McRackan a108846731 Creating migrations shouldn't use file with conflicting name 2022-05-20 14:19:58 -04:00
rmcrackan 0b4ce8d6e7 Merge pull request #254 from Mbucari/master
Update installer
2022-05-18 23:02:58 -04:00
Mbucari 42df61b7dd Merge branch 'rmcrackan:master' into master 2022-05-18 17:33:10 -06:00
Michael Bucari-Tovo 6b46fa4cbc Use package installer 2022-05-18 17:32:53 -06:00
Robert McRackan c0762eba18 Minor bug fix 2022-05-18 14:54:48 -04:00
rmcrackan 036fb848e1 Merge pull request #253 from Mbucari/master
Revert that unnecessary change
2022-05-18 14:53:47 -04:00
Mbucari 7198ae9025 Merge branch 'rmcrackan:master' into master 2022-05-18 12:49:31 -06:00
Michael Bucari-Tovo d2822b06aa Revert "restore the old functionality to the stoplight"
This reverts commit 3648de3a8d.
2022-05-18 12:48:57 -06:00
Robert McRackan 17feca28b9 increm version 2022-05-18 14:48:46 -04:00
rmcrackan 898d38cb6a Merge pull request #252 from Mbucari/master
Fixed Issue #251
2022-05-18 14:47:40 -04:00
Michael Bucari-Tovo 95a99a2f0b Merge branch 'master' of https://github.com/Mbucari/Libation 2022-05-18 12:35:18 -06:00
Michael Bucari-Tovo 29a1e8ad34 MP3 settings always applicable for converting existing m4b 2022-05-18 12:35:12 -06:00
Mbucari 19f3a4f266 Update DownloadDecryptBook.cs 2022-05-18 12:31:32 -06:00
Michael Bucari-Tovo 12ddbc308a Fixed multipart book hanging 2022-05-18 12:29:16 -06:00
Mbucari 999bc7604e Merge branch 'rmcrackan:master' into master 2022-05-18 09:47:23 -06:00
Michael Bucari-Tovo 3648de3a8d restore the old functionality to the stoplight 2022-05-18 09:47:09 -06:00
Robert McRackan 051fa0a28f Bug fix #250 : recent refactor introduced a race condition for db creation on initial install. Moved db creation to before all other init/config is called 2022-05-18 08:13:18 -04:00
Robert McRackan 72e667e825 update dependencies 2022-05-17 17:13:20 -04:00
Robert McRackan 5ed59b41b5 fix image scaling bug when when scanning 2022-05-17 16:38:49 -04:00
Robert McRackan c7c0d1632e Improve how highlighted index works post-filtering 2022-05-17 12:59:30 -04:00
Robert McRackan 2dc73acd20 Bug fix: incomplete refresh 2022-05-17 09:53:23 -04:00
Robert McRackan ed71668c48 Reverted -- I might have been too hasty removing the GridEntry events 2022-05-17 08:08:53 -04:00
Robert McRackan 801e154d15 post-refactor clean up 2022-05-17 07:56:34 -04:00
rmcrackan a89b07394f Merge pull request #249 from Mbucari/master
Add FilterableSortableBindingList to handle filtering the DataGridView
2022-05-16 22:08:31 -04:00
Mbucari 982f9b7c58 Merge branch 'rmcrackan:master' into master 2022-05-16 16:38:03 -06:00
Michael Bucari-Tovo 789b9207b5 Use that fancy patterm matching 2022-05-16 15:49:02 -06:00
Michael Bucari-Tovo 133dbb7471 Update Dinah 2022-05-16 15:11:21 -06:00
Robert McRackan 5d3ec493cd update dependencies 2022-05-16 17:06:59 -04:00
Michael Bucari-Tovo 6d7f234497 Remove unnecessary base form 2022-05-16 14:32:59 -06:00
Michael Bucari-Tovo 29a50bb640 typo 2022-05-16 14:31:03 -06:00
Michael Bucari-Tovo 843fddabde Changes discussed in email 2022-05-16 14:27:34 -06:00
Michael Bucari-Tovo 109ce0dd1f overwrite cached state 2022-05-16 14:26:43 -06:00
Robert McRackan 42508a82a0 txt file rename 2022-05-16 16:04:53 -04:00
Michael Bucari-Tovo d860d39f5f Merge branch 'master' of https://github.com/Mbucari/Libation 2022-05-16 13:16:58 -06:00
Michael Bucari-Tovo 15396c611a Add documentation 2022-05-16 13:16:50 -06:00
Mbucari 41c4b12ae1 Merge branch 'rmcrackan:master' into master 2022-05-16 13:16:25 -06:00
Michael Bucari-Tovo e51c30462f Revert "Use new ProcessQueue"
This reverts commit 9b5df99a61.
2022-05-16 13:16:11 -06:00
Michael Bucari-Tovo 9b5df99a61 Use new ProcessQueue 2022-05-16 12:56:15 -06:00
Michael Bucari-Tovo 3535156ea5 Edit 2022-05-16 12:47:50 -06:00
Robert McRackan 577145096d * GridEntry.DownloadBook is no longer called. it was the only one calling UpdateLiberatedStatus(true) or using DownloadInProgress flag
* cleaned up unused code, old forms, ProcessorAutomationController...
* what's left of LogMe and ProcessorAutomationController should be moved eventually
2022-05-16 14:44:17 -04:00
Michael Bucari-Tovo 89059510fd More logical naming 2022-05-16 12:37:56 -06:00
Michael Bucari-Tovo aabc14c639 Make AllItems a method 2022-05-16 12:12:34 -06:00
Michael Bucari-Tovo c28872544c Don't call concat for every book. 2022-05-16 12:10:54 -06:00
Michael Bucari-Tovo 7b8a4e4d72 Simplify filtering 2022-05-16 12:06:56 -06:00
Michael Bucari-Tovo 5dcdf670be Simplify RemoveFilter 2022-05-16 11:58:36 -06:00
Michael Bucari-Tovo 9721890a3c Update documentation 2022-05-16 11:50:11 -06:00
Michael Bucari-Tovo 1b9c4cfc23 Remove unused usings 2022-05-16 11:47:34 -06:00
Michael Bucari-Tovo 98a552e9af Optimization 2022-05-16 11:46:42 -06:00
Michael Bucari-Tovo e1e265a101 Don't filter after every insert 2022-05-16 11:38:24 -06:00
Robert McRackan b60a854de0 Formattable UI labels 2022-05-16 13:34:49 -04:00
Michael Bucari-Tovo d1bddeccc8 Implement filtering in the sortable binding list. 2022-05-16 11:16:33 -06:00
Robert McRackan 0a106e64d8 liberate visible to use new process queue 2022-05-16 08:20:40 -04:00
Michael Bucari-Tovo 91d6181aec Better naming 2022-05-15 20:15:54 -06:00
Michael Bucari-Tovo 255c0a3359 Move filtering into SyncBindingSource 2022-05-15 19:58:59 -06:00
Robert McRackan 3a5ef999f0 Bug fix: fatal exception if no large picture 2022-05-15 15:38:36 -04:00
rmcrackan 983aa845d6 Merge pull request #247 from Mbucari/master
Fixed scaling issue
2022-05-15 15:21:05 -04:00
Robert McRackan d1779726e6 New __ARCHITECTURE NOTES.txt incl. MVVM comments 2022-05-15 15:13:25 -04:00
Michael Bucari-Tovo 8e23062d0e Fix scaling for all display scalings 2022-05-15 13:12:46 -06:00
Michael Bucari-Tovo 7efbfffd99 Fixed scaling issue. 2022-05-15 12:47:39 -06:00
rmcrackan ff4b2d2ecc Merge pull request #244 from Mbucari/master
New Processing Queue
2022-05-15 14:25:52 -04:00
Michael Bucari-Tovo e079be0ad7 Make scrll look more natural when removing items from control 2022-05-15 11:27:49 -06:00
Michael Bucari-Tovo a8a54aa443 Revert "Make scrll look more natural when removing items from control"
This reverts commit 88cbcf6baf.
2022-05-15 11:26:07 -06:00
Michael Bucari-Tovo 88cbcf6baf Make scrll look more natural when removing items from control 2022-05-15 11:25:33 -06:00
Michael Bucari-Tovo 8d6d26c9d2 Improve logging 2022-05-15 11:16:41 -06:00
Michael Bucari-Tovo a490df0f7e Fix possible index range error 2022-05-15 11:10:37 -06:00
Michael Bucari-Tovo a46041c958 More useful logging 2022-05-15 09:58:36 -06:00
Michael Bucari-Tovo 0a6a78bc58 Revert "More useful logging"
This reverts commit c9e850515e.
2022-05-15 09:56:56 -06:00
Michael Bucari-Tovo c9e850515e More useful logging 2022-05-15 09:56:46 -06:00
Michael Bucari-Tovo 0ff8da2cf0 Add await and make cancel async 2022-05-15 09:30:44 -06:00
Michael Bucari-Tovo c0ef3ccbea Tiny bugfix 2022-05-15 09:00:52 -06:00
Michael Bucari-Tovo 1ab628dee8 Better invocation. Post instead of Send 2022-05-14 23:45:13 -06:00
Michael Bucari-Tovo b24df24b10 Detect Conversion cancelled 2022-05-14 23:44:15 -06:00
Michael Bucari-Tovo 341678d979 Remove my testing code. oops. 2022-05-14 20:47:13 -06:00
Michael Bucari-Tovo 49d10273a6 Add button to hide queue 2022-05-14 20:44:53 -06:00
Michael Bucari-Tovo 5b05c018d5 Remove ValidationFail books from queue display. Nothing to see there. 2022-05-14 20:00:23 -06:00
Michael Bucari-Tovo d18d8c0ba4 Filter 2022-05-14 16:23:34 -06:00
Michael Bucari-Tovo 84a8fb0074 Minor refactor 2022-05-14 16:13:19 -06:00
Michael Bucari-Tovo a40fb7f4bd Colorsto variables 2022-05-14 15:57:36 -06:00
Michael Bucari-Tovo 84eb3a3508 Remove debug button 2022-05-14 15:33:06 -06:00
Michael Bucari-Tovo 73a5d76503 Make thread safe and integrate with Libation UI 2022-05-14 14:39:46 -06:00
Michael Bucari-Tovo 50c35ed519 Change log to gridview and new INotifyPropertyChanged event 2022-05-14 13:52:54 -06:00
Michael Bucari-Tovo a7b7e3efea Converted to INotifyPropertyChanged for more targeted view update 2022-05-14 13:52:10 -06:00
Michael Bucari-Tovo 88e892196f Merge branch 'master' of https://github.com/Mbucari/Libation 2022-05-14 11:20:30 -06:00
Michael Bucari-Tovo 7f08da96bb Documentation and organization 2022-05-14 11:20:19 -06:00
Mbucari 193f24768e Merge branch 'rmcrackan:master' into master 2022-05-14 11:15:23 -06:00
Michael Bucari-Tovo a8bca3de98 Fix progressbar wiggling 2022-05-14 11:11:51 -06:00
Michael Bucari-Tovo 9692a802d0 Update documentation and add parameters 2022-05-14 11:11:20 -06:00
Robert McRackan 28a8b2e685 Revert: only call notifyPropertyChanged if actually set to new value 2022-05-14 12:34:01 -04:00
Michael Bucari-Tovo 3c9121b4af Improve scroll visualization 2022-05-14 10:03:57 -06:00
Michael Bucari-Tovo dec1035258 Minor UI tweak 2022-05-14 04:11:44 -06:00
Michael Bucari-Tovo 9d81c86c1b Increase buffer size 2022-05-14 04:10:54 -06:00
Michael Bucari-Tovo eeb4f4681a Saved 2022-05-14 03:16:48 -06:00
Michael Bucari-Tovo 676af0210b Finalized ProcessBookControl 2022-05-14 02:54:32 -06:00
Michael Bucari-Tovo 77c6a2890b Finalized VirtualFlowControl 2022-05-14 02:54:09 -06:00
Michael Bucari-Tovo c39e748749 Finialized TrackedQueue 2022-05-14 01:33:05 -06:00
Mbucari 36e5a6ac8d Merge branch 'rmcrackan:master' into master 2022-05-13 21:00:56 -06:00
Robert McRackan 9bdcaa5eaa only call notifyPropertyChanged if actually set to new value 2022-05-13 16:30:46 -04:00
Mbucari 5511004db8 Merge branch 'rmcrackan:master' into master 2022-05-13 14:09:29 -06:00
Robert McRackan 0e46cdb514 refactor Form1. too much in 1 file 2022-05-13 13:39:49 -04:00
Mbucari b028899949 Merge branch 'rmcrackan:master' into master 2022-05-13 11:12:37 -06:00
Robert McRackan 55285427f1 Add series in default search 2022-05-13 11:42:08 -04:00
Michael Bucari-Tovo 763a6cb31a Added VirtualFlowControl and BookQueue 2022-05-13 00:21:41 -06:00
Robert McRackan 24cb1aa84f remove legacy references 2022-05-12 13:35:08 -04:00
rmcrackan 886aa4938d Merge pull request #243 from Mbucari/master
Minor mods for future UI changes
2022-05-12 13:30:30 -04:00
Michael Bucari-Tovo 8871651549 Change namespace/folder name 2022-05-12 11:17:14 -06:00
Michael Bucari-Tovo 2ae8ef87d9 Remove unised 2022-05-12 11:06:53 -06:00
Michael Bucari-Tovo de4fbe05f7 Remove old holdover 2022-05-12 11:01:41 -06:00
Michael Bucari-Tovo b8abed37c2 Merged popout with main brainch. 2022-05-12 10:52:55 -06:00
Mbucari 255e26435c Merge branch 'rmcrackan:master' into master 2022-05-12 10:32:05 -06:00
Michael Bucari-Tovo 9e0550619b Merging 2022-05-12 10:31:50 -06:00
Michael Bucari-Tovo 5c171fd0f0 Merging 2022-05-12 10:29:44 -06:00
Michael Bucari-Tovo 3dd3b710b7 merge fix 2022-05-12 10:17:29 -06:00
Robert McRackan bce3bdba7e Feature requests #229 , #148 : Bulk actions on filtered books 2022-05-12 11:57:56 -04:00
Robert McRackan 360f077da3 * fixed where the filter was being called multiple times on launch
* simplified productsGrid init means a lot of defensive code is no longer needed
2022-05-12 10:28:30 -04:00
Robert McRackan 75c5f662dc * Batch actions for visible books: 'remove from library' complete
* refactor entity properties into extension methods
* refactor shared simple message boxes => MessageBoxLib
2022-05-12 09:53:21 -04:00
Michael Bucari-Tovo 3c0485cfa9 Prepare Form1 for new docking queue 2022-05-12 00:10:13 -06:00
Michael Bucari-Tovo d5ba405de0 MatchCurrent 2022-05-11 23:44:33 -06:00
Michael Bucari-Tovo 71b8bca86d Revert "Revert "Changes for dockable process""
This reverts commit 6d6434b4d4.
2022-05-11 21:12:18 -06:00
Mbucari c53b9eabd6 Merge branch 'rmcrackan:master' into master 2022-05-11 21:11:44 -06:00
Michael Bucari-Tovo 6d6434b4d4 Revert "Changes for dockable process"
This reverts commit a447e88b86.
2022-05-11 21:11:25 -06:00
Michael Bucari-Tovo a447e88b86 Changes for dockable process 2022-05-11 21:10:02 -06:00
Michael Bucari-Tovo e2d2e00913 Fix conflict? 2022-05-11 21:07:32 -06:00
Michael Bucari-Tovo cbfea37b3a Fix conflict 2022-05-11 21:06:01 -06:00
Michael Bucari-Tovo d6de647974 Fix conflict 2022-05-11 21:04:11 -06:00
Robert McRackan b784bd6b8d Batch actions for visible books: LIberate complete 2022-05-11 22:16:15 -04:00
Robert McRackan 00df6da366 'visible books' only enabled when applicable 2022-05-11 21:47:48 -04:00
Michael Bucari-Tovo dad36c73e5 Expose grid entries 2022-05-11 18:45:57 -06:00
Michael Bucari-Tovo 936a1d60a0 Minor mods for future UI changes 2022-05-11 18:36:48 -06:00
rmcrackan e0248c2d8e Merge pull request #242 from Mbucari/master
Add option to download cover art & full-size cover art viewer
2022-05-11 10:53:11 -04:00
Robert McRackan b12731e3d5 resolve merge conflict 2022-05-11 10:52:46 -04:00
Robert McRackan 9636aca47c update grid-visible in main form 2022-05-11 10:50:19 -04:00
Robert McRackan 4138183352 improve grid 'visible' 2022-05-11 10:49:41 -04:00
Robert McRackan c3871d3bca * Bug fix: grid doesn't update correctly if all books are removed
* Beginning (incomplete) new menu for batch actions on visible books
2022-05-11 10:13:07 -04:00
Michael Bucari-Tovo dd8b0783a9 Address comments 2022-05-10 20:43:07 -06:00
Michael Bucari-Tovo 9a50aa4c7c Start task earlier. 2022-05-10 16:11:44 -06:00
Michael Bucari-Tovo c40185030f Merge branch 'master' of https://github.com/Mbucari/Libation 2022-05-10 16:11:09 -06:00
Michael Bucari-Tovo 7cba28019c Remove lambda body 2022-05-10 16:10:17 -06:00
Mbucari 926f8a957e Merge branch 'rmcrackan:master' into master 2022-05-10 16:03:52 -06:00
Michael Bucari-Tovo 59aeaf24e4 Full-size cover picture viewer 2022-05-10 16:03:02 -06:00
Michael Bucari-Tovo 64eaa157e5 Add option for downloading cover 2022-05-10 15:36:31 -06:00
Michael Bucari-Tovo 9a5d9f3867 Move cover art downloader to DownloadDecryptBook 2022-05-10 15:25:47 -06:00
Robert McRackan e368e4669b bug fix: db persistence shouldn't be a side effect. the client should say when to persist in some fairly explicit way 2022-05-10 16:48:52 -04:00
Robert McRackan c6ce814e1c Set the stage for batch processing 2022-05-10 16:18:09 -04:00
Robert McRackan dd5e162c10 db persistence shouldn't be a side effect. the client should say when to persist in some fairly explicit way 2022-05-10 16:17:12 -04:00
Robert McRackan 7af890d897 GetLibrary to include image sizes 500, 1215 2022-05-10 15:32:00 -04:00
Robert McRackan 0faeeea25f update dependencies 2022-05-10 14:50:34 -04:00
rmcrackan de9b3fd6ec Merge pull request #240 from Mbucari/master
Lots of new UI stuff!
2022-05-10 14:37:39 -04:00
Michael Bucari-Tovo 22e5c8746c Updated Api 2022-05-10 12:36:46 -06:00
Michael Bucari-Tovo 0091245734 Revert PictureID_1215 migration and add PictureIDLarge migration 2022-05-10 12:03:47 -06:00
Michael Bucari-Tovo 448c231cfa Merge branch 'master' of https://github.com/Mbucari/Libation 2022-05-10 12:02:28 -06:00
Michael Bucari-Tovo b0d1f692a3 Use new PictureIDLarge and PictureSize.Native 2022-05-10 12:01:23 -06:00
Mbucari a5ff890ea1 Delete LibationContext.db 2022-05-10 11:42:24 -06:00
Michael Bucari-Tovo df4739cbf4 Set description cell tooltip text 2022-05-10 08:40:42 -06:00
Michael Bucari-Tovo 9559109aa8 Fix liberated status cache 2022-05-10 00:27:23 -06:00
Michael Bucari-Tovo d848c1a499 Cache book and pdf statuses for faster sorting. 2022-05-10 00:04:55 -06:00
Michael Bucari-Tovo 48ffc40abb Move cover download to processable 2022-05-09 23:53:10 -06:00
Michael Bucari-Tovo 82b5daa809 Download large cover art after successfilly downloading an audiobook. 2022-05-09 23:22:21 -06:00
Michael Bucari-Tovo b320276926 Add PictureID_1215 to Book and migrate DB 2022-05-09 23:21:52 -06:00
Michael Bucari-Tovo 6ccb8d612f Merge branch 'master' of https://github.com/Mbucari/Libation 2022-05-09 22:16:24 -06:00
Michael Bucari-Tovo 23460e0137 Don't show description form in task bar 2022-05-09 22:09:47 -06:00
Mbucari 7723de7284 Update ProductsGrid.cs 2022-05-09 21:49:56 -06:00
Michael Bucari-Tovo 138f94594f Fixed cross-thread access error. 2022-05-09 21:31:21 -06:00
Michael Bucari-Tovo 81c152ddcb Add libation icon to forms 2022-05-09 21:12:41 -06:00
Michael Bucari-Tovo 04665fea36 Change default border width 2022-05-09 20:37:41 -06:00
Michael Bucari-Tovo 803eef3825 Settings are not mutually exclusive 2022-05-09 20:37:05 -06:00
Michael Bucari-Tovo e2a05761a6 Unnecessary. Cleanup of unfinished decrypts is performed by Caller 2022-05-09 20:36:48 -06:00
Michael Bucari-Tovo b1968caa0f Improve display and fix display indices 2022-05-09 20:29:08 -06:00
Michael Bucari-Tovo 6474ef98f5 Fix description form location 2022-05-09 18:10:09 -06:00
Michael Bucari-Tovo 8763d63a93 Better windows positioning 2022-05-09 17:15:16 -06:00
Michael Bucari-Tovo 201ecebda9 Show full book description when Description cell is clicked. 2022-05-09 16:44:44 -06:00
Michael Bucari-Tovo 1c9ea0a710 No text trimming since columns are enlargeable 2022-05-09 15:44:37 -06:00
Michael Bucari-Tovo 30feb42ed8 Add setting to persist ProductsGrid column widths 2022-05-09 15:30:18 -06:00
Mbucari cfe2eac351 Merge branch 'rmcrackan:master' into master 2022-05-09 14:40:18 -06:00
Michael Bucari-Tovo 725979afb0 Improve Context Menu performance. 2022-05-09 14:38:14 -06:00
Michael Bucari-Tovo 19262bceac Fix display issue if all columns are hidden on startup 2022-05-09 14:16:14 -06:00
Robert McRackan 6254585ae2 New feature: auto-library updating 2022-05-09 15:28:00 -04:00
Mbucari 5ad1e45c65 Merge branch 'rmcrackan:master' into master 2022-05-09 13:21:52 -06:00
Michael Bucari-Tovo 9fe95bbddc Add option to reorder ProductsGrid columns 2022-05-09 13:21:10 -06:00
Michael Bucari-Tovo aecc54401d Add option for user to hide columns in ProductsGrid 2022-05-09 12:58:09 -06:00
Robert McRackan 4332732cc4 update dependencies 2022-05-09 13:24:23 -04:00
Robert McRackan 15b6b673d7 Merge branch 'master' of https://github.com/rmcrackan/Libation 2022-05-09 11:21:16 -04:00
Robert McRackan cb8b5d74d7 auto-scan initial code. Feature not yet complete 2022-05-09 11:21:09 -04:00
rmcrackan 535dc7a038 Update README.md 2022-05-09 11:15:33 -04:00
rmcrackan c6f7b142ee Update README.md 2022-05-09 11:12:36 -04:00
rmcrackan 4853b26cd3 Update README.md 2022-05-09 11:09:48 -04:00
Robert McRackan c99ee56f24 documentation: getting started 2022-05-09 11:08:57 -04:00
rmcrackan f6a22db188 Update README.md 2022-05-09 11:04:29 -04:00
rmcrackan c26b31f548 Update README.md 2022-05-09 11:03:42 -04:00
Robert McRackan 96654c599b move documentation 2022-05-09 11:02:38 -04:00
rmcrackan 57be386ac7 Update README.md 2022-05-09 11:01:34 -04:00
rmcrackan 09f782bfbd Update README.md 2022-05-09 10:58:08 -04:00
rmcrackan cb673e34c1 Update README.md 2022-05-09 10:57:43 -04:00
rmcrackan 62af7ab70c Update Advanced.md 2022-05-09 10:57:08 -04:00
rmcrackan 71f2f656e8 Update Advanced.md 2022-05-09 10:56:40 -04:00
rmcrackan fddf096de6 Update Advanced.md 2022-05-09 10:55:13 -04:00
Robert McRackan 9b8cf69148 documentation: advanced 2022-05-09 10:53:50 -04:00
Robert McRackan 628c80048b fix read me 2022-05-09 10:46:47 -04:00
Robert McRackan 9daa264af4 images => Documentation/images 2022-05-09 10:42:51 -04:00
Robert McRackan 8f8a8e7340 remove duplicate image files. also in LibationWinForms\Resources 2022-05-09 10:33:51 -04:00
Robert McRackan 389fbb2371 Move source code into "Source" folder 2022-05-09 10:31:45 -04:00
Robert McRackan 1ee73fa1a7 increment version 2022-05-09 07:58:01 -04:00
Robert McRackan adbbff368f Merge branch 'master' of https://github.com/rmcrackan/Libation 2022-05-09 07:56:25 -04:00
Robert McRackan ee9d30bd56 Michael's "frame" fix from email 2022-05-09 07:56:16 -04:00
rmcrackan 5a822809a9 Merge pull request #239 from Mbucari/master
Fix temp file storage/deletion + a few new features:

* .tmp and .json files are again properly stored in DownloadsInProgressDirectory, and the are again used if resuming a download.
* Yellow stoplight works again.
* All audio files stored in DecryptInProgressDirectory are deleted if the conversion fails Partial / Complete files in %temp%\Libation are not tidied / reused #144
* Added option to retain aax file Feature Request: Allow saving the original aax #187
* Add option to remove "(Unabridged)" from metadata tags Remove "(Unabridged)" from the title? #223
* Added options for mp3 encoding
* Add option to create cue sheet
* Prevent same book being decrypted more than once at a time
* Made a new settings tab for all audio file editing/fixing options.
2022-05-08 22:13:47 -04:00
Michael Bucari-Tovo 4e587e0429 Add try block 2022-05-08 19:58:48 -06:00
Michael Bucari-Tovo 9a619186fd If keeping aaxc, write aaxc key to file 2022-05-08 19:56:59 -06:00
Michael Bucari-Tovo eab6f71a4c Don't delete temp aaxc file if download failed. 2022-05-08 17:07:10 -06:00
Michael Bucari-Tovo f68bf2d6b3 Better method for downloading only 1 book at a time. 2022-05-08 16:48:58 -06:00
Michael Bucari-Tovo 2afcaebb78 Prevent same bok being decrypted more than once at a time 2022-05-08 16:31:24 -06:00
Michael Bucari-Tovo 458ea6a377 Fix tmp file extension to aaxc 2022-05-08 16:13:35 -06:00
Michael Bucari-Tovo 0e2997d309 Merge branch 'master' of https://github.com/Mbucari/Libation 2022-05-08 15:46:57 -06:00
Michael Bucari-Tovo 420f4b9d5d Add optional cue sheet 2022-05-08 15:46:33 -06:00
Mbucari bcfa97219f Merge branch 'rmcrackan:master' into master 2022-05-08 14:49:07 -06:00
Michael Bucari-Tovo 4c66010afe Add user settings for mp3 encoding. 2022-05-08 14:48:43 -06:00
Michael Bucari-Tovo 05f25a88c6 Fix temp file reuse/cleanup. Add retain aax option. 2022-05-08 11:08:23 -06:00
rmcrackan 2c6c08fbb5 Merge pull request #238 from Mbucari/master
Add option to remove Audible branding audio
2022-05-08 12:57:21 -04:00
Michael Bucari-Tovo 8af60b56b6 Refactoring for clarity. 2022-05-08 09:40:21 -06:00
Michael Bucari-Tovo c0516772a7 Move OutputFormat to DownloadLicense 2022-05-08 09:40:08 -06:00
Michael Bucari-Tovo 77de70762c Add default for StripAudibleBrandAudio option 2022-05-08 09:39:55 -06:00
Michael Bucari-Tovo 7164100cb1 Merge branch 'master' of https://github.com/Mbucari/Libation 2022-05-07 23:46:55 -06:00
Michael Bucari-Tovo 9292a62015 Fix mutually exclusive setting options 2022-05-07 23:44:28 -06:00
Mbucari 5280e68da9 Update AaxDecrypter.csproj 2022-05-07 23:23:31 -06:00
Michael Bucari-Tovo 0f6b0bf9fe Add trim audio support to multipart files. 2022-05-07 22:34:28 -06:00
Michael Bucari-Tovo 510ed95590 Remove 500ms headroom 2022-05-07 21:42:23 -06:00
Michael Bucari-Tovo 9862593f4a Add option to strip Audible brand audio 2022-05-07 21:29:29 -06:00
Michael Bucari-Tovo d595b62f13 Update aaxclean 2022-05-06 17:16:14 -06:00
Robert McRackan 12abbb79b1 Don't allow multiple simultaneous imports 2022-05-06 16:00:37 -04:00
Robert McRackan ecaa3b9aab Scanning no longer blocks UI 2022-05-04 17:15:28 -04:00
Robert McRackan ded175f2d2 Extract 'sortable' formatting from GridEntry 2022-05-04 13:50:23 -04:00
Robert McRackan 128facec21 add/modify grid without reload 2022-05-04 13:37:25 -04:00
Robert McRackan 0bde86ebfd QuickFilters on save event 2022-05-03 11:29:21 -04:00
Robert McRackan 28625029cd code clean up 2022-05-02 16:13:35 -04:00
Robert McRackan 1816bd721c Added initial 'About' menu with version number 2022-05-02 14:59:43 -04:00
Robert McRackan 68ad627159 update dependencies 2022-04-30 21:03:40 -04:00
Robert McRackan 878a5dd36c Libary import got a complete overhaul. On a library of 1,200 titles: initial scan is 80-85% faster. Subsequent imports are 60-70% faster 2022-04-29 16:35:49 -04:00
Robert McRackan 7c144b8277 Bug fix #234 : chapters were no longer included in the m4b file 2022-04-27 11:31:13 -04:00
Robert McRackan bca8c3865b Expose a way to insert ad hoc library books to grid 2022-04-26 16:37:13 -04:00
Robert McRackan 58102acd35 Trivial refactoring 2022-04-26 16:34:59 -04:00
Robert McRackan 5e577843f7 Fixing genre metatag is conditional upon AllowLibationFixup setting 2022-04-26 09:49:21 -04:00
Robert McRackan e1d549cead update dependencies 2022-04-26 09:27:13 -04:00
Robert McRackan 323b8f2fb9 minor refactors 2022-04-26 08:18:35 -04:00
Robert McRackan 3dcbcf42ed Fix 2 for issue #202 2022-04-25 22:21:36 -04:00
Robert McRackan 825078abc6 New feature: metadata correction in converted output files 2022-04-25 13:34:22 -04:00
Robert McRackan 6be44966ad * enhancement #202 : use audible category for file's genre metatag. Thanks @MBucari ! 2022-04-25 13:23:43 -04:00
rmcrackan 66da138556 Merge pull request #233 from Mbucari/master
Update Libation to work with new AAXClean.Codecs
2022-04-25 13:16:38 -04:00
Michael Bucari-Tovo e5dd4b856e Update Libation to work with new AAXClean.Codecs 2022-04-24 19:40:34 -06:00
Robert McRackan 5caa9c5687 Improved logging for import errors 2022-04-16 16:36:49 -04:00
Robert McRackan c8c0ffeb0d Bug fix #231 : Some books without categories are not getting imported 2022-04-15 16:30:43 -04:00
Robert McRackan bfceb58d6b Merge branch 'master' of https://github.com/rmcrackan/Libation 2022-04-12 09:16:10 -04:00
Robert McRackan 2e4c4cf5f7 bug fix #228 : recover from corrupt BookTags.json 2022-04-12 09:16:02 -04:00
rmcrackan 23966c9b00 Update README.md 2022-04-11 10:06:12 -04:00
rmcrackan ef73d2243d add login details 2022-04-11 10:03:08 -04:00
Robert McRackan c95feebd39 Add images for 'alternate login' readme 2022-04-11 09:56:59 -04:00
Robert McRackan d6601fed83 Bug fix #225 : SaferEnumerateFiles will skip files with UnauthorizedAccessException 2022-04-08 09:11:36 -04:00
Robert McRackan 962e379642 Added debugging around file move and file delete 2022-03-30 09:52:39 -04:00
Robert McRackan cbc61f5a2d Files and folders cannot end with dots 2022-03-25 13:51:29 -04:00
Robert McRackan 2eaac6acc2 Bug fix #210 : if attempting to paginate more than 10,000 titles : "Implied library size is unsupported" 2022-03-17 16:14:12 -04:00
Robert McRackan 03b458765c Bug fix: getting library had errors for libraries with over 10k titles 2022-03-17 13:06:55 -04:00
Robert McRackan c8b4bc6361 Address issue #199 : Rare users can be unable to handle library scan batch size of 250. When timeout occurs, retry with batch size of 50 2022-03-06 14:21:21 -05:00
rmcrackan d9b5725ff1 Update README.md
CLI manual change to settings file no longer needed
2022-03-03 16:59:31 -05:00
Robert McRackan 0a0f60192b Better exception logging with Serilog.Exceptions library 2022-03-03 16:54:43 -05:00
Robert McRackan 424d939c15 Update dependencies 2022-03-03 13:02:15 -05:00
Robert McRackan 87f13ff8ed Incr. ver. 2022-02-21 10:26:58 -05:00
Robert McRackan 1e24df626a Add error recovery around FileLocations.json to handle file corruption 2022-02-21 10:24:56 -05:00
Robert McRackan 0312786721 Add description to exports #197 2022-02-14 13:44:54 -05:00
Robert McRackan 1f8a5b256e Bug fix: Defensive FirstOrDefault. #194 2022-02-03 08:53:41 -05:00
rmcrackan 426391f01c Update README.md
Forgot to remove .nfo from readme
2022-01-30 09:55:34 -05:00
Robert McRackan c296bff47f Bug fix #181 : if audible gives a null picture id then once that image is searched for, no further cover art was downloaded 2022-01-12 22:20:58 -05:00
Robert McRackan 6b649cf4ca Rare duplicates are making their way into the db. Defensive FirstOrDefault added to address bug #184 2022-01-11 07:34:42 -05:00
Robert McRackan 5103240a76 Bugfix: Latest AudibleAPI addresses #175 . Thank you again @mkb79 2022-01-04 11:25:49 -05:00
rmcrackan c2418b10f6 Update README.md 2022-01-04 10:53:53 -05:00
Robert McRackan d705c23472 Bug fix #158 : troublesome check is unnecessary anyway 2021-12-07 16:06:15 -05:00
Robert McRackan de45d008c7 Bug fix #167 : folders with leading or trailing whitespace will break file saving. Including paths created from templates 2021-12-07 09:24:36 -05:00
Robert McRackan c267332027 update dependencies 2021-12-06 15:12:44 -05:00
Robert McRackan 4829e85faf Bug fix #163 , #171 : pre-audible uk logins were failing. Thanks @mkb79 ! 2021-12-06 13:14:06 -05:00
Robert McRackan 2acb9ca7e5 Bug fix: Spent hours hunting down why database files weren't closing correctly. New to EF Core 6 "SQLite: Connections are pooled" " This results in database files being kept open by the process even after the ADO.NET connection object is closed." wtf microsoft?! 2021-12-06 12:00:12 -05:00
Robert McRackan b260554a2a Bug fix #173 : error when importing the same book from multiple accounts during the same import 2021-12-06 11:05:46 -05:00
Robert McRackan 41a4055cd9 init default settings 2021-12-03 14:47:21 -05:00
Robert McRackan c6e9ba9bf9 new user: init settings 2021-12-02 16:47:35 -05:00
Robert McRackan 5059333b38 Bug fix: First click on Liberated icon shows 'File not found: <temppath>'. Second click opens correct final path. #164 2021-11-30 09:54:32 -05:00
Robert McRackan b4015030cf tl;dr text on alt login. Issue #160 2021-11-29 11:12:26 -05:00
Robert McRackan 7f5cf8f018 New config setting: ShowImportedStats -- "Show number of newly imported titles? When unchecked, no pop-up will appear after library scan." 2021-11-29 11:06:23 -05:00
rmcrackan 2c9ccd9c78 Update README.md
TOC
2021-11-29 09:05:52 -05:00
rmcrackan cebf218db4 Update README.md
Add 'Installation'
2021-11-29 09:03:51 -05:00
Robert McRackan 530b44a0e6 Bug fix: in paths, double slashes are not allowed *except* at beginning. eg: \\192.168.0.1 (issue #157 ) 2021-11-24 13:42:11 -05:00
Robert McRackan b3dc5a7054 Upgrade to .net6 2021-11-24 12:59:02 -05:00
Robert McRackan 2567ccb44c Enhancement: add if-series conditional logic to custom file naming. Issue #151 2021-11-11 16:43:44 -05:00
Robert McRackan e67eac92fd Bug fix for issue #152 : individual episodes were ignored when targeted directly (as opposed to targeting the parent series) 2021-11-09 21:27:44 -05:00
Robert McRackan 6e84fd97f1 Accounts dialog: more user-friendly validation 2021-11-08 08:55:07 -05:00
Robert McRackan 9a458bf3dc Protect against blank settings.json 2021-11-05 15:25:31 -04:00
Robert McRackan 283a46e1e2 Add debugging for issue #149 2021-11-05 13:42:47 -04:00
Robert McRackan 6ff2859c39 Update dependencies 2021-11-04 16:13:43 -04:00
Robert McRackan e8df4952fc update dependencies 2021-11-03 16:51:40 -04:00
rmcrackan b19e1e8a30 Update README for Custom File Naming 2021-11-02 22:20:51 -04:00
Robert McRackan a3cf6ac40d Custom file naming: manual testing complete 2021-11-02 21:53:58 -04:00
Robert McRackan ab450c37c4 Custom File Naming complete. Final testing remains 2021-11-02 17:05:29 -04:00
Robert McRackan c837fefbdd template file naming: code complete. Clean up and testing remain 2021-11-02 14:26:11 -04:00
Robert McRackan 46b120ee41 Bug fix: slashes in template values (eg: title) breaks file management #145 2021-11-01 11:42:05 -04:00
Robert McRackan cae8ca7ef3 Template error and warning checks return specific errors/warnings in addition to bools 2021-10-29 17:05:57 -04:00
Robert McRackan 904665da7f Bug fix: #143 2021-10-28 20:58:32 -04:00
Robert McRackan 2478c61df6 Bugfix: template validation was opposite #142 2021-10-28 14:38:01 -04:00
Robert McRackan 288ed75b5d increm ver 2021-10-27 20:46:02 -04:00
Robert McRackan ad5efbd9a9 Bug fix for #141 2021-10-27 20:45:21 -04:00
Robert McRackan 7eb7b2a0f9 better formatting for download/decrypt ETA 2021-10-27 17:05:17 -04:00
Robert McRackan d0051c0f02 Add templates to settings dialog incl load validate save. Edit buttons are in place but currently do nothing 2021-10-27 16:51:31 -04:00
Robert McRackan d20517063e Settings: single screen => tabs 2021-10-27 15:50:41 -04:00
Robert McRackan bcca69a102 Bug fix. Wrong template referenced 2021-10-26 16:35:08 -04:00
Robert McRackan 35f8c05106 File naming is Configuration driven: Configuration, AudioFileStorageExt, Templates, TemplateTags, 2021-10-26 16:18:27 -04:00
Robert McRackan a3d38e082d Path.GetInvalidPathChars() acts differently in C# interactive vs live code 2021-10-26 13:54:37 -04:00
Robert McRackan b2e956e70b Update dependencies 2021-10-26 13:06:24 -04:00
Robert McRackan e5119357b2 File naming is fully template driven 2021-10-22 17:06:42 -04:00
Robert McRackan b42ff827d5 GetStandardizedExtension unit tests 2021-10-22 13:09:05 -04:00
Robert McRackan 68da9779da Expose internal to Test projects 2021-10-22 11:07:18 -04:00
Robert McRackan 8e358d8f04 expose library book to multipart decrypter for file naming 2021-10-21 16:43:49 -04:00
Robert McRackan 0a986238bc Defensive FirstOrDefault 2021-10-21 15:39:53 -04:00
Robert McRackan d636ceed8e File naming stuff is (finally) centralized under AudioFileStorageExt 2021-10-21 14:38:59 -04:00
Robert McRackan e4fc104afe Naming logic for all new files can now originate from domian logic 2021-10-20 10:56:07 -04:00
Robert McRackan 87e3075fb3 Rename InternalUtilities to AudibleUtilities 2021-10-19 10:22:42 -04:00
Robert McRackan ab44823c05 Bug fix: update book series. Defensive FirstOrDefault 2021-10-18 20:40:56 -04:00
Robert McRackan 2767f04621 split AaxcDownload single and multi 2021-10-18 14:41:57 -04:00
Robert McRackan 0f1ff0aa10 minor refactor 2021-10-18 13:56:12 -04:00
Robert McRackan c1af253300 fix partial rollback 2021-10-18 13:44:40 -04:00
Robert McRackan d08962cffa Refactor valid path/filename. Centralize validaion. Universal templating is one step closer 2021-10-18 13:36:55 -04:00
Robert McRackan 7720110460 Bug fix: tag filters stopped working on 8/22 2021-10-15 14:45:35 -04:00
Robert McRackan dfa5829cbd Safe(r)Delete, Safe(r)Move : could have infinite loop of exceptions. Fixed. Limit 3 2021-10-12 17:05:01 -04:00
Robert McRackan 648b84ee55 All audible-related file naming terminates at FileUtility
File extensions: Dinah.Core => Libation FileUtility
2021-10-12 14:48:32 -04:00
Robert McRackan 6a81b9b02d more LibationFileManager rename. and bug fix 2021-10-11 17:10:37 -04:00
Robert McRackan c43e03b228 FileManager: separate generic from Libation-specific 2021-10-11 16:06:50 -04:00
Robert McRackan 1de7edd9df Chapter splitting: file names need more leading zeros when qty >100 2021-10-09 14:20:21 -04:00
Robert McRackan df90094884 Replaced another id dependency with cache. Now safe for multi-file audiobooks. Also safe for current session not trying to move files created in a previous session or a parallel session of a different title 2021-10-08 21:34:42 -04:00
Robert McRackan c9a6c8fd35 Merge branch 'master' of https://github.com/rmcrackan/Libation 2021-10-08 11:48:05 -04:00
Robert McRackan d0b78cc501 New and moved files Upsert themselves in FileManager.FilePathCache 2021-10-08 11:47:54 -04:00
rmcrackan 0b7bc4d938 Update README.md
List all `libationcli export` options
2021-10-07 08:59:13 -04:00
Robert McRackan 18cca53968 Merge branch 'master' of https://github.com/rmcrackan/Libation 2021-10-07 08:45:19 -04:00
Robert McRackan ef9c60cc4f File splitting: omit tiny chapters 2021-10-07 08:45:02 -04:00
rmcrackan fa24831693 Merge pull request #135 from Mbucari/master
Fix chapter splitting.
2021-10-06 21:20:04 -04:00
Michael Bucari-Tovo 24370e9804 Merge branch 'master' of https://github.com/Mbucari/Libation 2021-10-06 16:02:30 -06:00
Michael Bucari-Tovo d3f82b162e Fix chapter splitting. 2021-10-06 16:01:50 -06:00
rmcrackan 5a40c7370f Merge pull request #134 from Mbucari/master
Fix splitting audiobooks on chapters
2021-10-06 15:55:02 -04:00
Mbucari 2d22855b93 Merge branch 'rmcrackan:master' into master 2021-10-06 13:47:02 -06:00
Michael Bucari-Tovo b870d562ff Only split chapters at least 15 seconds long. 2021-10-06 13:44:03 -06:00
Michael Bucari-Tovo f1c87308ea Fixed access modifier. 2021-10-06 13:43:19 -06:00
Michael Bucari-Tovo a3fac3441c Allow splitting book only if AllowLibationFixup is true. 2021-10-06 13:43:01 -06:00
Robert McRackan 5f8c672361 CLI: error when scan has new book with pdf attachment: 2021-10-06 15:35:19 -04:00
rmcrackan 40520b89d1 Merge pull request #132 from Mbucari/master
Convert IProcessable to abstract class Processable.
2021-10-06 11:06:25 -04:00
Michael Bucari-Tovo 0ac90f5a30 Discard unnused variable. 2021-10-06 08:31:37 -06:00
Michael Bucari-Tovo 4d6544d828 Revert accidental push of changes in progress. 2021-10-06 08:25:08 -06:00
Michael Bucari-Tovo 8098564926 Better naming. 2021-10-06 08:23:07 -06:00
Michael Bucari-Tovo 07c96c4994 Corrected access modifiers. 2021-10-06 08:22:50 -06:00
Michael Bucari-Tovo aa8491f205 Edited comments 2021-10-05 16:54:33 -06:00
Michael Bucari-Tovo 5c535478d1 Add note 2021-10-05 16:49:55 -06:00
Michael Bucari-Tovo f0541b498f Removed virtual 2021-10-05 16:49:06 -06:00
Michael Bucari-Tovo e466d63e76 Convert IStreamable and IAudioDecodable to abstract classes. 2021-10-05 16:41:48 -06:00
Michael Bucari-Tovo 6e66314605 Convert IProcessable to abstract class Processable. 2021-10-05 16:10:56 -06:00
Robert McRackan be5e18d977 settings descriptions 2021-10-05 11:09:36 -04:00
Robert McRackan c437a39a82 New feature: download already split into chapters 2021-10-05 10:35:41 -04:00
Robert McRackan 7b55158148 Merge branch 'master' of https://github.com/rmcrackan/Libation 2021-10-05 10:08:21 -04:00
Robert McRackan 5772d9c31e defensive FirstOrDefault 2021-10-05 10:07:58 -04:00
rmcrackan 2a1f02b095 Merge pull request #127 from seanke/feature/multi_files
To mulitple files
2021-10-05 10:01:43 -04:00
Sean Kelly 5b7cde2a9e Fixed issues 2021-10-05 17:36:37 +13:00
Sean Kelly 5e349c6662 Removed repeated code 2021-09-30 20:32:30 +13:00
Sean Kelly 4b78b757aa Move files 2021-09-30 19:44:32 +13:00
Robert McRackan 22548dc8ae bug fix: if not importing episodes, remember to remove parents from import list 2021-09-29 10:00:04 -04:00
Robert McRackan 1165f81203 bug fix in series importer 2021-09-27 07:57:24 -04:00
Sean Kelly 13294d3414 Added m4b & mp3 methods for multiple files. 2021-09-27 21:34:43 +13:00
Sean Kelly 8a74a29700 Added configuration and wired it up. 2021-09-27 20:18:50 +13:00
Sean Kelly 36f58b64d6 proof of concept 2021-09-26 23:05:17 +13:00
Robert McRackan 19369a21ef * New feature: setting to not import episodes ( #125 ) 2021-09-25 14:02:27 -04:00
Robert McRackan 611fb4d6d8 increm ver 2021-09-24 20:11:52 -04:00
Robert McRackan c77ec54035 bug fix: DownloadEpisodes logic needs parans 2021-09-24 19:59:57 -04:00
Robert McRackan c9c28c7826 oops. again 2021-09-24 16:44:49 -04:00
Robert McRackan 30e2caaff5 New feature: setting to not download episodes 2021-09-24 16:44:28 -04:00
Robert McRackan fd56017af5 dedicated lock objects for safety 2021-09-24 11:46:37 -04:00
Robert McRackan d2eaf26117 Removing books
* message box is too big when removing huge amounts of books. This scenario is typical when removing podcasts
* removing books should remove user defined entries. eg: tags and is-liberated
2021-09-24 10:00:52 -04:00
Robert McRackan 7c38e18435 Add support for unencrypted mp3 audiobooks 2021-09-24 08:26:23 -04:00
Robert McRackan bfb1dbc69a Merge branch 'master' of https://github.com/rmcrackan/Libation 2021-09-24 08:25:16 -04:00
Robert McRackan d2ff19e309 null description causes errors 2021-09-24 08:24:16 -04:00
rmcrackan aa3a7dce06 Merge pull request #123 from Mbucari/master
Add support for unencrypted mp3 audiobooks.
2021-09-24 08:23:14 -04:00
Mbucari 71075838eb Moved event logging to LibationBaseForm 2021-09-23 19:29:25 -06:00
Michael Bucari-Tovo 803a0b7ccf Comment typo. 2021-09-23 18:14:29 -06:00
Michael Bucari-Tovo d9f3fa825c Renaming and comments. 2021-09-23 18:13:43 -06:00
Michael Bucari-Tovo df42ba584e Better naming. 2021-09-23 18:06:59 -06:00
Michael Bucari-Tovo 9f09a62a1e Ensure chapter info is downloaded for unencrypted MP3s 2021-09-23 18:04:12 -06:00
Michael Bucari-Tovo e714179c30 Add support for unencrypted mp3 audiobooks. 2021-09-23 18:01:39 -06:00
Robert McRackan db84c9a7d9 unencrypted podcast downloads (incomplete) 2021-09-23 16:50:59 -04:00
Robert McRackan 937bd56fcc debug code to incl episodes 2021-09-23 16:20:08 -04:00
Robert McRackan f29968f379 conditional re-index 2021-09-23 14:44:11 -04:00
Robert McRackan 14e14ba9bd batch book status updates
bug fixes, esp. threading
2021-09-23 14:33:04 -04:00
Robert McRackan 613c97524a User get getting "bindingsource cannot be its own data source" error. Can't repro locally. Adding SyncBindingSource for datagrid views to attempt to solve it 2021-09-23 10:41:33 -04:00
Robert McRackan 4fd16f04e0 More robust error handling, especially before logging can be initialized 2021-09-23 09:19:35 -04:00
Robert McRackan 61385f0f0b more explicit book series order 2021-09-22 11:51:06 -04:00
Robert McRackan 7647882344 update audible api dependency 2021-09-22 09:48:28 -04:00
1119 changed files with 105124 additions and 18764 deletions

No files matched your search

+5
View File
@@ -0,0 +1,5 @@
{
"CdmUrls": [
"https://ollj0gz40d.execute-api.us-west-2.amazonaws.com/default/AudibleCdm"
]
}
+5
View File
@@ -0,0 +1,5 @@
# https://editorconfig.org
root = true
[*.md]
charset = utf-8
+45
View File
@@ -0,0 +1,45 @@
---
name: Bug report
about: Create a report to help us improve Libation
title: ''
labels: bug
assignees: ''
---
PLEASE FILL OUT THE FOLLOWING. Bug reports with limited information or lacking an attached log file may get limited or delayed help.
___
## Describe the bug
A clear and concise description of what the bug is.
## To Reproduce
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
## Expected behavior
A clear and concise description of what you expected to happen.
## Screenshots
If applicable, add screenshots to help explain your problem.
## Platform
[e.g. Windows 10, Windows 11, Mac, Linux (State distribution)]
## Log Files
Attach your Libation log file here. If your user folder contains the file "LibationCrash.log", attach that also.
**Default Log File Locations**
|Platform|Folder|
|-|-|
|Windows|`%userprofile%\Libation`|
|macOS|`~/Library/Application Support/Libation`|
|Linux|`~/.local/share/Libation`|
**macOS:** If that folder does not exist because Libation never starts, try launching from Terminal and say whether it works: `/Applications/Libation.app/Contents/MacOS/Libation` (see [Troubleshooting for macOS](https://github.com/rmcrackan/Libation/blob/main/docs/advanced/troubleshoot.md#macos)).
Alternative, you may open the log file folder from within Libation. Open Libation's settings, and on the first tab in Settings you can click the button 'Open log folder'.
+1
View File
@@ -0,0 +1 @@
blank_issues_enabled: false
+31
View File
@@ -0,0 +1,31 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: enhancement
assignees: ''
---
**No-go ideas**
There are lots of great ideas and many are beyond what we intend to do for Libation. Some good ideas which we do not intend to pursue:
* comprehensive api/cli
* aax/audiobook import
* bulk rename of existing files
* general metadata/tag editor
* playback features
* web gui
* supporting non-audible vendors
* official docker support
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.
+8
View File
@@ -0,0 +1,8 @@
---
version: 2
updates:
# Maintain dependencies for GitHub Actions
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
+5
View File
@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
<polyline points="7 10 12 15 17 10"/>
<line x1="12" y1="15" x2="12" y2="3"/>
</svg>

After

Width:  |  Height:  |  Size: 303 B

+10
View File
@@ -0,0 +1,10 @@
# Labels required by exempt-creators.yml and stale.yml. Sync with sync-labels workflow.
# (Other repo labels are left unchanged when prune: false.)
---
- name: stale
color: 'eeeeee'
description: 'No activity for an extended period'
- name: exempt
color: '0e8a16'
description: 'Excluded from automatic stale closure (e.g. maintainer-opened)'
+83
View File
@@ -0,0 +1,83 @@
# build-linux.yml
# Reusable workflow that builds the Linux and MacOS (x64 and arm64) versions of Libation.
---
name: build
on:
workflow_call:
inputs:
libation-version:
type: string
required: true
dotnet-version:
type: string
required: true
run-unit-tests:
type: boolean
publish-r2r:
type: boolean
retention-days:
type: number
architecture:
type: string
description: "CPU architecture targeted by the build."
required: true
OS:
type: string
description: >
The operating system targeted by the build.
There must be a corresponding Bundle_$OS.sh script file in ./Scripts
required: true
jobs:
build:
name: "${{ inputs.OS }}-${{ inputs.architecture }}"
runs-on: ubuntu-latest
env:
RUNTIME_ID: "linux-${{ inputs.architecture }}"
steps:
- uses: actions/checkout@v6
- uses: actions/setup-dotnet@v5
with:
dotnet-version: ${{ inputs.dotnet-version }}
dotnet-quality: "ga"
- name: Unit test
if: ${{ inputs.run-unit-tests }}
working-directory: ./Source
run: dotnet test
- name: Publish
id: publish
working-directory: ./Source
run: |
PUBLISH_ARGS=(
'--runtime' '${{ env.RUNTIME_ID }}'
'--configuration' 'Release'
'--output' '../bin'
'-p:PublishProtocol=FileSystem'
"-p:PublishReadyToRun=${{ inputs.publish-r2r }}"
'-p:SelfContained=true')
dotnet publish LibationAvalonia/LibationAvalonia.csproj "${PUBLISH_ARGS[@]}"
dotnet publish LoadByOS/LinuxConfigApp/LinuxConfigApp.csproj "${PUBLISH_ARGS[@]}"
dotnet publish LibationCli/LibationCli.csproj "${PUBLISH_ARGS[@]}"
dotnet publish HangoverAvalonia/HangoverAvalonia.csproj "${PUBLISH_ARGS[@]}"
- name: Build bundle
id: bundle
run: |
SCRIPT=./Scripts/Bundle_${{ inputs.OS }}.sh
chmod +rx ${SCRIPT}
${SCRIPT} ./bin "${{ inputs.libation-version }}" "${{ inputs.architecture }}"
artifact=$(ls ./bundle)
echo "artifact=${artifact}" >> "${GITHUB_OUTPUT}"
- uses: actions/upload-artifact@v7
with:
name: ${{ steps.bundle.outputs.artifact }}
path: ./bundle/${{ steps.bundle.outputs.artifact }}
if-no-files-found: error
retention-days: ${{ inputs.retention-days }}
+113
View File
@@ -0,0 +1,113 @@
# build-mac.yml
# Reusable workflow that builds the MacOS (x64 and arm64) versions of Libation.
---
name: build
on:
workflow_call:
inputs:
libation-version:
type: string
required: true
dotnet-version:
type: string
required: true
run-unit-tests:
type: boolean
publish-r2r:
type: boolean
retention-days:
type: number
sign-app:
type: boolean
description: "Wheather to sign an notorize the app bundle and dmg."
architecture:
type: string
description: "CPU architecture targeted by the build."
required: true
jobs:
build:
name: "macOS-${{ inputs.architecture }}"
runs-on: macos-latest
env:
RUNTIME_ID: "osx-${{ inputs.architecture }}"
WAIT_FOR_NOTARIZE: ${{ vars.WAIT_FOR_NOTARIZE == 'true' }}
steps:
- uses: apple-actions/import-codesign-certs@v7
if: ${{ inputs.sign-app }}
with:
p12-file-base64: ${{ secrets.DISTRIBUTION_SIGNING_CERT }}
p12-password: ${{ secrets.DISTRIBUTION_SIGNING_CERT_PW }}
- uses: actions/checkout@v6
- uses: actions/setup-dotnet@v5
with:
dotnet-version: ${{ inputs.dotnet-version }}
dotnet-quality: "ga"
- name: Unit test
if: ${{ inputs.run-unit-tests }}
working-directory: ./Source
run: dotnet test
- name: Publish
id: publish
working-directory: ./Source
run: |
PUBLISH_ARGS=(
'--runtime' '${{ env.RUNTIME_ID }}'
'--configuration' 'Release'
'--output' '../bin'
'-p:PublishProtocol=FileSystem'
"-p:PublishReadyToRun=${{ inputs.publish-r2r }}"
'-p:SelfContained=true')
dotnet publish LibationAvalonia/LibationAvalonia.csproj "${PUBLISH_ARGS[@]}"
dotnet publish LoadByOS/MacOSConfigApp/MacOSConfigApp.csproj "${PUBLISH_ARGS[@]}"
dotnet publish LibationCli/LibationCli.csproj "${PUBLISH_ARGS[@]}"
dotnet publish HangoverAvalonia/HangoverAvalonia.csproj "${PUBLISH_ARGS[@]}"
- name: Build bundle
id: bundle
run: |
SCRIPT=./Scripts/Bundle_MacOS.sh
chmod +rx ${SCRIPT}
${SCRIPT} ./bin "${{ inputs.libation-version }}" "${{ inputs.architecture }}" "${{ inputs.sign-app }}"
artifact=$(ls ./bundle)
echo "artifact=${artifact}" >> "${GITHUB_OUTPUT}"
- name: Notarize bundle
if: ${{ inputs.sign-app }}
run: |
if [ ${{ vars.WAIT_FOR_NOTARIZE == 'true' }} ]; then
WAIT="--wait"
fi
echo "::debug::Submitting the disk image for notarization"
# Capture stdout+stderr (2>&1). Use || true so that when notarytool fails (e.g. Apple TOS
# agreement required), the script does not exit before we can print RESPONSE—otherwise the
# job would fail with no visible error message in the workflow log.
RESPONSE=$(xcrun notarytool submit ./bundle/${{ steps.bundle.outputs.artifact }} $WAIT --no-progress --apple-id ${{ vars.APPLE_DEV_EMAIL }} --password ${{ secrets.APPLE_DEV_PASSWORD }} --team-id ${{ secrets.APPLE_TEAM_ID }} 2>&1) || true
echo "$RESPONSE"
SUBMISSION_ID=$(echo "$RESPONSE" | awk '/id: / { print $2;exit; }')
echo "::notice::Notary Submission Id: $SUBMISSION_ID"
# Re-fail the step if submit failed (e.g. no submission id). The job still fails, but the
# output above is now visible in the log so we can see the real error (e.g. sign agreement).
if [ -z "$SUBMISSION_ID" ]; then
echo "::error::Notarization submit failed. See output above for details (e.g. Apple TOS agreement)."
exit 1
fi
if [ ${{ vars.WAIT_FOR_NOTARIZE == 'true' }} ]; then
echo "::debug::Stapling the notarization ticket to the disk image"
xcrun stapler staple "./bundle/${{ steps.bundle.outputs.artifact }}"
fi
- uses: actions/upload-artifact@v7
with:
name: ${{ steps.bundle.outputs.artifact }}
path: ./bundle/${{ steps.bundle.outputs.artifact }}
if-no-files-found: error
retention-days: ${{ inputs.retention-days }}
+130
View File
@@ -0,0 +1,130 @@
# build-windows.yml
# Reusable workflow that builds the Windows versions of Libation.
---
name: build
on:
workflow_call:
inputs:
libation-version:
type: string
required: true
dotnet-version:
type: string
required: true
run-unit-tests:
type: boolean
publish-r2r:
type: boolean
build-installer:
type: boolean
description: "Build *-setup.exe on all Windows matrix jobs when release (zips always built for .releaseindex.json)"
default: false
retention-days:
type: number
jobs:
build:
name: "Windows-${{ matrix.release_name }}-${{ matrix.architecture }} (${{ matrix.ui }})"
runs-on: windows-latest
strategy:
matrix:
ui: [Avalonia]
architecture: [x64]
release_name: [chardonnay]
artifact_stem: [Libation]
include:
- architecture: x64
ui: WinForms
release_name: classic
artifact_stem: Libation-Classic
- architecture: arm64
ui: Avalonia
release_name: chardonnay
artifact_stem: Libation
steps:
- uses: actions/checkout@v6
- uses: actions/setup-dotnet@v5
with:
dotnet-version: ${{ inputs.dotnet-version }}
dotnet-quality: "ga"
- name: Unit test
if: ${{ inputs.run-unit-tests }}
working-directory: ./Source
run: dotnet test
- name: Publish
working-directory: ./Source
run: |
$PUBLISH_ARGS=@(
"--runtime", "win-${{ matrix.architecture }}",
"--configuration", "Release",
"--output", "../bin",
"-p:PublishProtocol=FileSystem",
"-p:PublishReadyToRun=${{ inputs.publish-r2r }}",
"-p:SelfContained=true")
dotnet publish "Libation${{ matrix.ui }}/Libation${{ matrix.ui }}.csproj" $PUBLISH_ARGS
dotnet publish "LoadByOS/WindowsConfigApp/WindowsConfigApp.csproj" $PUBLISH_ARGS
dotnet publish "LibationCli/LibationCli.csproj" $PUBLISH_ARGS
dotnet publish "Hangover${{ matrix.ui }}/Hangover${{ matrix.ui }}.csproj" $PUBLISH_ARGS
- name: Zip artifact
id: zip
working-directory: ./bin
run: |
$delfiles = @(
"WindowsConfigApp.exe",
"WindowsConfigApp.runtimeconfig.json",
"WindowsConfigApp.deps.json")
foreach ($file in $delfiles){ if (test-path $file){ Remove-Item $file } }
$artifact="${{ matrix.artifact_stem }}.${{ inputs.libation-version }}-windows-${{ matrix.release_name }}-${{ matrix.architecture }}.zip"
"artifact=$artifact" >> $env:GITHUB_OUTPUT
Compress-Archive -Path * -DestinationPath "$artifact"
- uses: actions/upload-artifact@v7
with:
name: ${{ steps.zip.outputs.artifact }}
path: ./bin/${{ steps.zip.outputs.artifact }}
if-no-files-found: error
retention-days: ${{ inputs.retention-days }}
- name: Install Inno Setup
if: ${{ inputs.build-installer }}
run: choco install innosetup -y --no-progress
- name: Build Windows installer
id: setup
if: ${{ inputs.build-installer }}
shell: pwsh
run: |
if ("${{ matrix.ui }}" -eq "WinForms") {
$setupName = "Libation-Classic.${{ inputs.libation-version }}-windows-${{ matrix.release_name }}-${{ matrix.architecture }}-setup.exe"
$ui = "WinForms"
} else {
$setupName = "Libation.${{ inputs.libation-version }}-windows-${{ matrix.release_name }}-${{ matrix.architecture }}-setup.exe"
$ui = "Avalonia"
}
./Scripts/Windows/Build-WindowsInstaller.ps1 `
-Version "${{ inputs.libation-version }}" `
-Ui $ui `
-Architecture "${{ matrix.architecture }}" `
-SkipPublish `
-BinDir "${{ github.workspace }}/bin"
if (-not (Test-Path "${{ github.workspace }}/bin/$setupName")) {
throw "Installer not found: bin/$setupName"
}
"setup=$setupName" >> $env:GITHUB_OUTPUT
- name: Upload installer artifact
if: ${{ inputs.build-installer }}
uses: actions/upload-artifact@v7
with:
name: ${{ steps.setup.outputs.setup }}
path: ./bin/${{ steps.setup.outputs.setup }}
if-no-files-found: error
retention-days: ${{ inputs.retention-days }}
+72
View File
@@ -0,0 +1,72 @@
# build.yml
# Reusable workflow that builds Libation for all platforms.
---
name: build
on:
workflow_call:
inputs:
libation-version:
type: string
description: "Libation version number"
required: true
dotnet-version:
type: string
default: "10.x"
description: ".NET version to target"
run-unit-tests:
type: boolean
description: "Whether to run unit tests prior to publishing."
publish-r2r:
type: boolean
description: "Whether to publish assemblies as ReadyToRun."
release:
type: boolean
description: "Whether this workflow is being called as a release"
retention-days:
type: number
description: "Number of days the artifacts are to be retained."
jobs:
windows:
uses: ./.github/workflows/build-windows.yml
with:
libation-version: ${{ inputs.libation-version }}
dotnet-version: ${{ inputs.dotnet-version }}
run-unit-tests: ${{ inputs.run-unit-tests }}
publish-r2r: ${{ inputs.publish-r2r }}
build-installer: ${{ inputs.release }}
retention-days: ${{ inputs.retention-days }}
macOS:
strategy:
matrix:
architecture: [x64, arm64]
uses: ./.github/workflows/build-mac.yml
with:
libation-version: ${{ inputs.libation-version }}
dotnet-version: ${{ inputs.dotnet-version }}
run-unit-tests: ${{ inputs.run-unit-tests }}
publish-r2r: ${{ inputs.publish-r2r }}
retention-days: ${{ inputs.retention-days }}
architecture: ${{ matrix.architecture }}
sign-app: ${{ inputs.release || vars.SIGN_MAC_APP_ON_VALIDATE == 'true' }}
secrets: inherit
linux:
strategy:
matrix:
OS: [Redhat, Debian]
architecture: [x64, arm64]
uses: ./.github/workflows/build-linux.yml
with:
libation-version: ${{ inputs.libation-version }}
dotnet-version: ${{ inputs.dotnet-version }}
run-unit-tests: ${{ inputs.run-unit-tests }}
publish-r2r: ${{ inputs.publish-r2r }}
retention-days: ${{ inputs.retention-days }}
architecture: ${{ matrix.architecture }}
OS: ${{ matrix.OS }}
+71
View File
@@ -0,0 +1,71 @@
name: Deploy VitePress site to Pages
on:
# Runs on pushes targeting the `main` branch. Change this to `master` if you're
# using the `master` branch as the default branch.
push:
branches: [master]
paths:
- .github/workflows/deploy.yml
- docs/**
- .vitepress/**
- index.md
- package.json
- package-lock.json
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
contents: read
pages: write
id-token: write
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
concurrency:
group: pages
cancel-in-progress: false
jobs:
# Build job
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0 # Not needed if lastUpdated is not enabled
# - uses: pnpm/action-setup@v4 # Uncomment this block if you're using pnpm
# with:
# version: 9 # Not needed if you've set "packageManager" in package.json
# - uses: oven-sh/setup-bun@v1 # Uncomment this if you're using Bun
- name: Setup Node
uses: actions/setup-node@v6
with:
node-version: 24
cache: npm # or pnpm / yarn
- name: Setup Pages
uses: actions/configure-pages@v6
- name: Install dependencies
run: npm ci # or pnpm install / yarn install / bun install
- name: Build with VitePress
run: npm run docs:build # or pnpm docs:build / yarn docs:build / bun run docs:build
- name: Upload artifact
uses: actions/upload-pages-artifact@v5
with:
path: .vitepress/dist
# Deployment job
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
needs: build
runs-on: ubuntu-latest
name: Deploy
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v5
+65
View File
@@ -0,0 +1,65 @@
# docker.yml
# Reusable workflow that builds a docker image for Libation.
---
name: docker
on:
workflow_call:
inputs:
version:
type: string
description: "Version number"
required: true
release:
type: boolean
description: "Is this a release build?"
required: true
secrets:
docker_username:
required: true
docker_token:
required: true
jobs:
build_and_push:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Set up QEMU
uses: docker/setup-qemu-action@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Login to Docker Hub
if: ${{ inputs.release }}
uses: docker/login-action@v4
with:
username: ${{ secrets.docker_username }}
password: ${{ secrets.docker_token }}
- name: Generate docker image tags
id: metadata
uses: docker/metadata-action@v6
with:
flavor: |
latest=true
images: |
name=${{ secrets.docker_username }}/libation
tags: |
type=raw,value=${{ inputs.version }},enable=${{ inputs.release }}
- name: Build and push image
uses: docker/build-push-action@v7
with:
# Avoid default git context refs/pull/*/merge (breaks after PR merge or on some re-runs).
context: .
platforms: linux/amd64,linux/arm64
push: ${{ steps.metadata.outputs.tags != ''}}
cache-from: type=gha
cache-to: type=gha,mode=max
tags: ${{ steps.metadata.outputs.tags }}
labels: ${{ steps.metadata.outputs.labels }}
@@ -0,0 +1,67 @@
# One-time or occasional backfill: add `exempt` to open issues/PRs opened by
# rmcrackan or Mbucari that predate exempt-creators.yml. Run from Actions →
# "Exempt creators backfill" → Run workflow.
---
name: Exempt creators backfill
on:
workflow_dispatch:
permissions:
issues: write
pull-requests: write
jobs:
backfill:
runs-on: ubuntu-latest
steps:
- uses: actions/github-script@v9
with:
script: |
const exemptLabel = 'exempt';
const creators = new Set(['rmcrackan', 'mbucari']);
const owner = context.repo.owner;
const repo = context.repo.repo;
const items = await github.paginate(github.rest.issues.listForRepo, {
owner,
repo,
state: 'open',
per_page: 100,
});
let labeled = 0;
let notCreator = 0;
let alreadyExempt = 0;
for (const item of items) {
const login = item.user && item.user.login;
if (!login || !creators.has(login.toLowerCase())) {
notCreator++;
continue;
}
const names = item.labels.map((l) => l.name);
if (names.some((n) => n.toLowerCase() === exemptLabel)) {
alreadyExempt++;
continue;
}
try {
await github.rest.issues.addLabels({
owner,
repo,
issue_number: item.number,
labels: [exemptLabel],
});
labeled++;
} catch (e) {
core.warning(`#${item.number}: ${e.message}`);
}
}
core.info(
`Backfill done: added exempt to ${labeled} item(s); ` +
`${alreadyExempt} already had exempt; ${notCreator} not from rmcrackan/Mbucari.`
);
+39
View File
@@ -0,0 +1,39 @@
# Assigns the `exempt` label to issues and PRs opened by maintainer accounts so
# stale.yml does not mark them stale. See issue #1532.
# For issues/PRs opened before this existed, run workflow "Exempt creators backfill".
# Pattern: https://github.com/Asperguide/asper-header/blob/main/.github/workflows/exempt-creators.yml
---
name: Exempt specific creators
on:
issues:
types: [opened]
pull_request:
types: [opened]
permissions:
issues: write
pull-requests: write
jobs:
exempt:
runs-on: ubuntu-latest
steps:
- name: Add exempt label
if: >-
(github.event_name == 'issues' &&
contains(fromJSON('["rmcrackan","Mbucari"]'), github.event.issue.user.login)) ||
(github.event_name == 'pull_request' &&
contains(fromJSON('["rmcrackan","Mbucari"]'), github.event.pull_request.user.login))
uses: actions/github-script@v9
with:
script: |
const number = context.issue?.number || context.payload.pull_request?.number;
const repo = context.repo;
if (number) {
await github.rest.issues.addLabels({
...repo,
issue_number: number,
labels: ['exempt'],
});
}
+68
View File
@@ -0,0 +1,68 @@
# release.yml
# Builds and creates the release on any tags starting with a `v`
---
name: release
on:
push:
tags:
- "v*"
jobs:
prerelease:
runs-on: ubuntu-slim
outputs:
version: ${{ steps.get_version.outputs.version }}
steps:
- name: Get tag version
id: get_version
run: |
export TAG="${{ github.ref_name }}"
echo "version=${TAG#v}" >> "${GITHUB_OUTPUT}"
docker:
needs: [prerelease]
uses: ./.github/workflows/docker.yml
with:
version: ${{ needs.prerelease.outputs.version }}
release: true
secrets:
docker_username: ${{ secrets.DOCKERHUB_USERNAME }}
docker_token: ${{ secrets.DOCKERHUB_TOKEN }}
build:
needs: [prerelease]
uses: ./.github/workflows/build.yml
secrets: inherit
with:
libation-version: ${{ needs.prerelease.outputs.version }}
publish-r2r: true
release: true
release:
needs: [prerelease, build]
runs-on: ubuntu-latest
steps:
- name: Download Chardonnay, Linux, and Mac artifacts
uses: actions/download-artifact@v8
with:
path: artifacts
pattern: "Libation.*"
merge-multiple: true
- name: Download Classic Windows artifacts
uses: actions/download-artifact@v8
with:
path: artifacts
pattern: "Libation-Classic.*"
merge-multiple: true
- name: Release
id: release
uses: softprops/action-gh-release@v3
with:
name: Libation ${{ needs.prerelease.outputs.version }}
body: "<Put a body here>"
token: ${{ secrets.GITHUB_TOKEN }}
draft: true
prerelease: false
files: |
artifacts/*
+66
View File
@@ -0,0 +1,66 @@
# Marks inactive issues/PRs stale and closes them after a further quiet period.
# Exempt labels include `enhancement`, `exempt` (from exempt-creators.yml), and others below.
# Pattern: https://github.com/Asperguide/asper-header/blob/main/.github/workflows/stale.yml
---
name: Close stale issues and PRs
on:
schedule:
- cron: '0 0 * * *'
workflow_dispatch:
permissions:
issues: write
pull-requests: write
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v10
with:
days-before-stale: 30
days-before-close: 14
operations-per-run: 100
stale-issue-message: |
This issue has been automatically marked as stale because it has not had any activity for 30 days.
It will be closed in 14 days if no further activity occurs.
If this issue is still relevant, please leave a comment to keep it open.
Thank you for your contributions to Libation.
close-issue-message: |
This issue has been automatically closed due to inactivity.
If you believe this issue is still relevant, please reopen it or create a new issue with updated information.
Thank you for your understanding.
stale-issue-label: stale
stale-pr-message: |
This pull request has been automatically marked as stale because it has not had any activity for 30 days.
It will be closed in 14 days if no further activity occurs.
If you're still working on this PR, please leave a comment to keep it open.
Thank you for your contribution.
close-pr-message: |
This pull request has been automatically closed due to inactivity.
If you'd like to continue working on this, please reopen the PR or submit a new one.
Thank you for your contribution.
stale-pr-label: stale
exempt-issue-labels: 'priority: critical,priority: high,security,help wanted,good first issue,needs-discussion,enhancement,exempt'
exempt-pr-labels: 'priority: critical,priority: high,security,enhancement,exempt'
exempt-all-milestones: true
exempt-all-assignees: false
exempt-draft-pr: true
ascending: true
remove-stale-when-updated: true
debug-only: false
+29
View File
@@ -0,0 +1,29 @@
# Ensures labels referenced by exempt-creators / stale workflows exist.
# Optional per #1532 — run workflow_dispatch if labels are missing.
# Pattern: https://github.com/Asperguide/asper-header/blob/main/.github/workflows/sync-labels.yml
---
name: Sync labels
on:
push:
branches: [master]
paths:
- '.github/labels.yml'
workflow_dispatch:
permissions:
issues: write
jobs:
sync-labels:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Sync labels
uses: micnncim/action-label-syncer@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
manifest: .github/labels.yml
prune: false
@@ -0,0 +1,22 @@
name: Validate MetaInfo
"on":
pull_request:
branches: ["master"]
paths:
- .github/workflows/validate-appstream-metainfo.yml
- Source/LoadByOS/LinuxConfigApp/com.getlibation.Libation.metainfo.xml
push:
branches: ["master"]
paths:
- .github/workflows/validate-appstream-metainfo.yml
- Source/LoadByOS/LinuxConfigApp/com.getlibation.Libation.metainfo.xml
jobs:
validate-appstream-metainfo:
runs-on: ubuntu-latest
container:
image: ghcr.io/flathub/flatpak-builder-lint:latest
steps:
- uses: actions/checkout@v6
- name: Check the MetaInfo file
run: flatpak-builder-lint appstream Source/LoadByOS/LinuxConfigApp/com.getlibation.Libation.metainfo.xml
@@ -0,0 +1,21 @@
name: Check desktop file
"on":
pull_request:
branches: ["master"]
paths:
- .github/workflows/validate-desktop-file.yml
- Source/LoadByOS/LinuxConfigApp/Libation.desktop
push:
branches: ["master"]
paths:
- .github/workflows/validate-desktop-file.yml
- Source/LoadByOS/LinuxConfigApp/Libation.desktop
jobs:
validate-desktop-file:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- run: sudo apt --yes install desktop-file-utils
- name: Check the desktop file
run: desktop-file-validate Source/LoadByOS/LinuxConfigApp/Libation.desktop
+47
View File
@@ -0,0 +1,47 @@
# validate.yml
# Validates that Libation will build on a pull request or push to master.
---
name: validate
on:
push:
branches: [master]
paths:
- Source/**
- .github/workflows/**
pull_request:
branches: [master]
paths:
- Source/**
- .github/workflows/**
jobs:
get_version:
runs-on: ubuntu-slim
outputs:
version: ${{ steps.get_version.outputs.version }}
steps:
- name: Get version
id: get_version
run: |
wget "https://raw.githubusercontent.com/${{ github.repository }}/${{ github.sha }}/Source/AppScaffolding/AppScaffolding.csproj"
version="$(grep -Eio -m 1 '<Version>.*</Version>' ./AppScaffolding.csproj | sed -r 's/<\/?Version>//g')"
echo "version=${version}" >> "${GITHUB_OUTPUT}"
build:
needs: [get_version]
uses: ./.github/workflows/build.yml
secrets: inherit
with:
libation-version: ${{ needs.get_version.outputs.version }}
retention-days: 14
run-unit-tests: true
docker:
needs: [get_version]
uses: ./.github/workflows/docker.yml
with:
version: ${{ needs.get_version.outputs.version }}
release: false
secrets:
docker_username: ${{ secrets.DOCKERHUB_USERNAME }}
docker_token: ${{ secrets.DOCKERHUB_TOKEN }}
+13 -1
View File
@@ -184,7 +184,7 @@ publish/
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
#*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
@@ -370,3 +370,15 @@ FodyWeavers.xsd
/__TODO.txt
/DataLayer/LibationContext.db
*/bin-Avalonia
# macOS Directory Info
.DS_Store
# JetBrains Rider Settings
**/.idea/
# VitePress
node_modules
.vitepress/cache
.vitepress/dist
+12
View File
@@ -0,0 +1,12 @@
{
"WindowsClassic": "(?:Classic-Libation|Libation-Classic)\\.\\d+\\.\\d+\\.\\d+(?:\\.\\d+)?-win(?:dows)?-classic-x64\\.zip",
"WindowsAvalonia": "Libation\\.\\d+\\.\\d+\\.\\d+(?:\\.\\d+)?-win(?:dows)?-chardonnay-x64\\.zip",
"WindowsAvalonia_Arm64": "Libation\\.\\d+\\.\\d+\\.\\d+(?:\\.\\d+)?-win(?:dows)?-chardonnay-arm64\\.zip",
"LinuxAvalonia": "Libation\\.\\d+\\.\\d+\\.\\d+(?:\\.\\d+)?-linux-chardonnay-amd64\\.deb",
"LinuxAvalonia_DEB": "Libation\\.\\d+\\.\\d+\\.\\d+(?:\\.\\d+)?-linux-chardonnay-amd64\\.deb",
"LinuxAvalonia_RPM": "Libation\\.\\d+\\.\\d+\\.\\d+(?:\\.\\d+)?-linux-chardonnay-amd64\\.rpm",
"MacOSAvalonia": "Libation\\.\\d+\\.\\d+\\.\\d+(?:\\.\\d+)?-macOS-chardonnay-x64\\.dmg",
"LinuxAvalonia_Arm64": "Libation\\.\\d+\\.\\d+\\.\\d+(?:\\.\\d+)?-linux-chardonnay-arm64\\.deb",
"LinuxAvalonia_Arm64_RPM": "Libation\\.\\d+\\.\\d+\\.\\d+(?:\\.\\d+)?-linux-chardonnay-arm64\\.rpm",
"MacOSAvalonia_Arm64": "Libation\\.\\d+\\.\\d+\\.\\d+(?:\\.\\d+)?-macOS-chardonnay-arm64\\.dmg"
}
+118
View File
@@ -0,0 +1,118 @@
import { defineConfig } from "vitepress";
// https://vitepress.dev/reference/site-config
export default defineConfig({
title: "Libation",
description:
"Libation: Liberate your Library - A free application for downloading your Audible audiobooks",
head: [["link", { rel: "icon", href: "/favicon.ico" }]],
cleanUrls: true,
themeConfig: {
// https://vitepress.dev/reference/default-theme-config
logo: {
light: "/libation_logo_light.svg",
dark: "/libation_logo_dark.svg",
},
footer: {
message: "Released under the GPLv3 License",
},
editLink: {
pattern: "https://github.com/rmcrackan/Libation/edit/master/:path",
},
lastUpdated: true,
nav: [
{ text: "Getting Started", link: "/docs/getting-started" },
{ text: "Docs", link: "/docs/index" },
{
text: "Download",
link: "https://github.com/rmcrackan/Libation/releases/latest",
},
{
text: "Issues & Requests",
link: "https://github.com/rmcrackan/Libation/issues",
},
{ text: "Donate", link: "https://www.paypal.com/paypalme/mcrackan" },
],
sidebar: [
{
items: [
{ text: "Overview", link: "/docs/index" },
{ text: "Getting Started", link: "/docs/getting-started" },
{ text: "FAQ", link: "/docs/frequently-asked-questions" },
{
text: "Issues & Requests",
link: "https://github.com/rmcrackan/Libation/issues",
},
{ text: "Donate", link: "https://www.paypal.com/paypalme/mcrackan" },
],
},
{
text: "Installation",
collapsed: false,
items: [
{ text: "Linux", link: "/docs/installation/linux" },
{ text: "Mac", link: "/docs/installation/mac" },
{ text: "Docker", link: "/docs/installation/docker" },
],
},
{
text: "Features",
collapsed: false,
items: [
{
text: "Audio File Formats",
link: "/docs/features/audio-file-formats",
},
{ text: "Naming Templates", link: "/docs/features/naming-templates" },
{
text: "Searching & Filtering",
link: "/docs/features/searching-and-filtering",
},
{
text: "Easy guide to searching",
link: "/docs/features/lucene",
},
],
},
{
text: "Advanced",
collapsed: false,
items: [
{ text: "Advanced Topics", link: "/docs/advanced/advanced" },
{ text: "Command Line Interface", link: "/docs/advanced/command-line-interface" },
{ text: "Troubleshooting", link: "/docs/advanced/troubleshoot" },
{ text: "Spatial Audio & DRM", link: "/docs/advanced/spatial-audio" },
],
},
{
text: "Development",
collapsed: false,
items: [
{
text: "Getting Started",
link: "/docs/development/getting-started",
},
{ text: "Contribute", link: "/docs/development/contribute" },
{ text: "Website & Docs", link: "/docs/development/website" },
{ text: "Linux Setup (Nix)", link: "/docs/development/nix-linux-setup" },
],
},
],
outline: {
level: "deep",
},
socialLinks: [
{ icon: "github", link: "https://github.com/rmcrackan/Libation" },
],
search: {
provider: "local",
},
},
});
@@ -0,0 +1,259 @@
<script setup>
import { ref, computed, onMounted, watch } from 'vue'
import { getDetectOS } from './download-detection.js'
const PREVIEW_OPTIONS = [
{ value: '', label: 'Current system' },
{ value: 'windows|x64', label: 'Windows (x64)' },
{ value: 'windows|arm64', label: 'Windows (arm64)' },
{ value: 'mac|x64', label: 'Mac (x64)' },
{ value: 'mac|arm64', label: 'Mac (arm64)' },
{ value: 'linux|x64|', label: 'Linux (x64)' },
{ value: 'linux|x64|Ubuntu', label: 'Linux Ubuntu (x64)' },
{ value: 'linux|x64|Fedora', label: 'Linux Fedora (x64)' },
{ value: 'linux|arm64|', label: 'Linux (arm64)' },
{ value: 'linux|arm64|Ubuntu', label: 'Linux Ubuntu (arm64)' },
{ value: 'linux|arm64|Fedora', label: 'Linux Fedora (arm64)' },
]
const INSTALL_MAC_URL = 'https://getlibation.com/docs/installation/mac'
const INSTALL_LINUX_URL = 'https://getlibation.com/docs/installation/linux'
const status = ref('loading') // 'loading' | 'ready' | 'error'
const errorMessage = ref('')
const cachedAssets = ref([])
const rec = ref(null)
const blockHead = ref('')
const previewValue = ref('')
const installGuideUrl = ref(null)
const installGuideLabel = ref('')
const d = ref(null)
function getPreviewOverrides() {
if (!previewValue.value) return null
const parts = previewValue.value.split('|')
const overrides = { os: parts[0], architecture: parts[1] }
if (parts.length > 2 && parts[2]) overrides.linuxFlavor = parts[2]
return overrides
}
function recommendedForLabel(overrides) {
if (!d.value) return 'Recommended download for your system'
const os = (overrides && overrides.os) || d.value.os
const ver = (overrides && overrides.osVersion) || d.value.osVersion
const arch = (overrides && overrides.architecture) || d.value.architecture
const flavor = (overrides && overrides.linuxFlavor !== undefined) ? overrides.linuxFlavor : d.value.linuxFlavor
if (os === 'windows') return 'Recommended download for Windows (' + arch + ')'
if (os === 'mac') return 'Recommended download for Mac ' + (ver ? ver + ' ' : '') + '(' + arch + ')'
if (os === 'linux') return 'Recommended download for ' + (flavor ? flavor + ' ' : '') + 'Linux (' + arch + ')'
return 'Recommended download for your system'
}
function updateRecommendation() {
if (!cachedAssets.value.length || !d.value) return
const overrides = getPreviewOverrides()
rec.value = d.value.recommendDownload(cachedAssets.value, overrides)
blockHead.value = recommendedForLabel(overrides)
const os = (overrides && overrides.os) || d.value.os
if (os === 'mac') {
installGuideUrl.value = INSTALL_MAC_URL
installGuideLabel.value = 'Install on macOS'
} else if (os === 'linux') {
installGuideUrl.value = INSTALL_LINUX_URL
installGuideLabel.value = 'Install on Linux'
} else {
installGuideUrl.value = null
installGuideLabel.value = ''
}
}
const showReasonWarn = computed(() => {
return rec.value?.reason && rec.value.reason !== 'Recommended for your system.'
})
const showAssets = computed(() => {
if (!rec.value || !d.value || status.value !== 'ready') return []
const libationAssets = cachedAssets.value
const overrides = getPreviewOverrides()
const os = (overrides && overrides.os) || d.value.os
const arch = (overrides && overrides.architecture) || d.value.architecture
return libationAssets.filter((a) => {
const p = d.value.parseAssetFilename(a.name)
if (!p) return false
if (os === 'windows' || os === 'mac' || os === 'linux') {
if (p.platform !== os) return false
}
if (arch === 'x64' || arch === 'arm64') {
if (p.arch !== arch) return false
}
return true
})
})
watch(previewValue, () => updateRecommendation())
onMounted(() => {
d.value = getDetectOS()
fetch('https://api.github.com/repos/rmcrackan/Libation/releases/latest')
.then((res) => (res.ok ? res.json() : Promise.reject(new Error('Failed to load release'))))
.then((release) => {
cachedAssets.value = (release.assets || []).map((a) => ({
name: a.name,
url: a.browser_download_url,
}))
status.value = 'ready'
updateRecommendation()
})
.catch((err) => {
status.value = 'error'
errorMessage.value = err.message || 'Could not load latest release.'
})
})
</script>
<template>
<div class="download-widget-wrapper">
<div v-if="status === 'loading'" class="download-widget recommended">
Loading latest release
</div>
<div v-else-if="status === 'error'" class="download-widget recommended">
<p class="warn">{{ errorMessage }}</p>
</div>
<div v-else class="download-widget recommended">
<div class="block-head">
<svg class="icon-download" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
<polyline points="7 10 12 15 17 10" />
<line x1="12" y1="15" x2="12" y2="3" />
</svg>
<span>{{ blockHead }}{{ rec?.windowsX64Choice ? ':' : rec?.recommended ? ':' : rec ? '.' : '' }}</span>
<select v-model="previewValue" aria-label="Find recommended download for" class="preview-select">
<option v-for="o in PREVIEW_OPTIONS" :key="o.value || 'current'" :value="o.value">
{{ o.label }}
</option>
</select>
</div>
<!-- Windows x64: Chardonnay + Classic -->
<template v-if="rec?.windowsX64Choice">
<ul class="widget-list">
<li><strong>Chardonnay</strong> (modern UI): <a :href="rec.windowsX64Choice.chardonnay.url" download>{{ rec.windowsX64Choice.chardonnay.name }}</a></li>
<li><strong>Classic</strong> (compact, screenreader-friendly): <a :href="rec.windowsX64Choice.classic.url" download>{{ rec.windowsX64Choice.classic.name }}</a></li>
</ul>
<p class="widget-link"><a :href="rec.classicVsChardonnayFaqUrl" target="_blank" rel="noopener">What's the difference between Classic and Chardonnay?</a></p>
<p v-if="showReasonWarn" class="warn">{{ rec.reason }}</p>
</template>
<!-- Single recommended -->
<template v-else-if="rec?.recommended">
<p class="widget-download"><a :href="rec.recommended.url" download>{{ rec.recommended.name }}</a></p>
<p v-if="installGuideUrl" class="widget-link">
<a :href="installGuideUrl" target="_blank" rel="noopener">{{ installGuideLabel }}</a>
</p>
<p v-if="showReasonWarn" class="warn">{{ rec.reason }}</p>
<div v-if="rec.alternatives?.length" class="alternatives">
{{ rec.alternatives.length === 1 ? 'Another option:' : 'Other options:' }}
<ul>
<li v-for="a in rec.alternatives" :key="a.name">
<a :href="a.url" download>{{ a.name }}</a>
</li>
</ul>
</div>
</template>
<!-- No match -->
<template v-else-if="rec">
<p class="warn">{{ rec.reason || 'Could not recommend a download.' }}</p>
<div class="alternatives">
Available:
<ul>
<li v-for="a in showAssets" :key="a.name">
<a :href="a.url" download>{{ a.name }}</a>
</li>
</ul>
</div>
</template>
</div>
</div>
</template>
<style scoped>
.download-widget-wrapper {
margin: 1.5rem auto;
max-width: 42rem;
}
.download-widget.recommended {
background: var(--vp-c-bg-soft);
border: 1px solid var(--vp-c-divider);
padding: 0.75rem 1rem;
border-radius: 8px;
font-weight: 600;
}
.download-widget.recommended a {
color: var(--vp-c-brand-1);
text-decoration: underline;
}
.download-widget.recommended a:hover {
text-decoration: underline;
opacity: 0.8;
}
.block-head {
display: flex;
align-items: center;
gap: 0.5rem;
flex-wrap: wrap;
margin-bottom: 0.5rem;
}
.block-head .icon-download {
flex-shrink: 0;
width: 1.25rem;
height: 1.25rem;
color: var(--vp-c-brand-1);
}
.preview-select {
margin-left: auto;
font-size: 0.85rem;
padding-right: 1.75rem;
padding-left: 0.5rem;
appearance: none;
background-color: var(--vp-c-bg-soft);
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right 0.35rem center;
border: 1px solid var(--vp-c-divider);
border-radius: 4px;
cursor: pointer;
}
.widget-list {
margin: 0 0 0 1rem;
padding-left: 0.5rem;
}
.widget-list li strong {
font-weight: 700;
}
.widget-download {
margin: 0.25rem 0;
}
.widget-link {
margin: 0.5rem 0 0;
}
.warn {
background: var(--vp-custom-block-warning-bg);
color: var(--vp-custom-block-warning-text);
padding: 0.5rem 0.75rem;
border-radius: 6px;
margin: 0.5rem 0 0;
font-size: 0.9rem;
font-weight: normal;
}
.alternatives {
font-size: 0.9rem;
font-weight: normal;
color: var(--vp-c-text-2);
margin-top: 0.5rem;
}
.alternatives ul {
margin: 0.25rem 0 0 1rem;
padding-left: 0.5rem;
}
</style>
+23
View File
@@ -0,0 +1,23 @@
<script setup>
import { ref, onMounted, defineAsyncComponent } from 'vue'
import DefaultTheme from 'vitepress/theme'
import { useData } from 'vitepress'
const { frontmatter } = useData()
const { Layout: DefaultLayout } = DefaultTheme
const mounted = ref(false)
onMounted(() => { mounted.value = true })
// Load widget only on client so download-detection.js (navigator) never runs during SSR
const DownloadSuggestionWidget = defineAsyncComponent(() =>
import('./DownloadSuggestionWidget.vue')
)
</script>
<template>
<DefaultLayout>
<template #home-hero-after>
<DownloadSuggestionWidget v-if="frontmatter.layout === 'home' && mounted" />
</template>
</DefaultLayout>
</template>
+24
View File
@@ -0,0 +1,24 @@
/* Custom styles for Libation documentation */
/* Naming Templates page: monospace in the doc column + outline only.
pageClass is applied to .Layout in VitePress; limit scope to #VPContent
so the top nav, sidebar, and site footer keep the default font. */
.Layout.naming-templates-mono #VPContent,
.Layout.naming-templates-mono #VPContent * {
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas,
"Liberation Mono", "Courier New", monospace;
}
/* Hide certain nav items on tablet devices to prevent horizontal scroll */
@media (min-width: 640px) and (max-width: 959px) {
/* Target specific nav items by their position */
/* Hide "Issues & Requests" and "Donate" links on tablet */
.VPNav .VPNavBar .nav .VPNavBarMenu .VPMenu:nth-child(3) {
display: none;
}
/* Alternative: Use a more specific selector if needed */
.VPNavBarMenuLink[href*="issues"] {
display: none;
}
}
+196
View File
@@ -0,0 +1,196 @@
/**
* Client-side OS and system detection for download recommendation.
* Uses navigator.userAgent and (when available) navigator.userAgentData.
* Call getDetectOS() in the browser only (e.g. in Vue onMounted).
*/
export function getDetectOS() {
const ua = typeof navigator !== 'undefined' ? navigator.userAgent : ''
const uaData = typeof navigator !== 'undefined' && navigator.userAgentData
function getOS() {
if (uaData?.platform) {
const p = uaData.platform.toLowerCase()
if (p === 'windows') return 'windows'
if (p === 'macos') return 'mac'
if (p === 'linux') return 'linux'
if (p === 'android') return 'android'
if (p === 'ios') return 'ios'
}
if (/\bWindows\b/i.test(ua)) return 'windows'
if (/\bMac\b/i.test(ua) || /\bMacintosh\b/i.test(ua)) return 'mac'
if (/\bLinux\b/i.test(ua) && !/\bAndroid\b/i.test(ua)) return 'linux'
if (/\bAndroid\b/i.test(ua)) return 'android'
if (/\b(iPhone|iPad|iPod)\b/i.test(ua)) return 'ios'
return 'other'
}
function getOSVersion() {
const os = getOS()
if (os === 'windows') {
const ntMatch = ua.match(/Windows NT (\d+\.\d+)/)
if (ntMatch) {
const nt = ntMatch[1]
if (nt === '10.0') return '10 or 11 (NT 10.0)'
if (nt === '6.3') return '8.1'
if (nt === '6.2') return '8'
if (nt === '6.1') return '7'
return `NT ${nt}`
}
return null
}
if (os === 'mac') {
const macMatch = ua.match(/Mac OS X (\d+[._]\d+(?:[._]\d+)?)/)
return macMatch ? macMatch[1].replace(/_/g, '.') : null
}
if (os === 'linux') {
const linuxMatch = ua.match(/Linux ([^\s;)]+)/)
return linuxMatch ? linuxMatch[1] : null
}
if (os === 'android') {
const m = ua.match(/Android (\d+(?:\.\d+)*)/)
return m ? m[1] : null
}
if (os === 'ios') {
const m = ua.match(/OS (\d+[._]\d+(?:[._]\d+)?)/)
return m ? m[1].replace(/_/g, '.') : null
}
return null
}
function getArchitecture() {
if (uaData?.architecture) {
const a = uaData.architecture.toLowerCase()
if (a === 'x86' || a === 'amd64') return a === 'amd64' ? 'x64' : 'x86'
if (a === 'arm' || a === 'arm64' || a === 'aarch64') return a === 'aarch64' ? 'arm64' : a
return a
}
if (/\b(aarch64|arm64|ARM64)\b/i.test(ua)) return 'arm64'
if (/\b(arm|aarch32)\b/i.test(ua) && !/arm64/i.test(ua)) return 'arm'
if (/\b(Wow64|Win64|x64|x86_64|amd64)\b/i.test(ua)) return 'x64'
if (/\b(WOW32|Win32|x86)\b/i.test(ua)) return 'x86'
return 'other'
}
function getLinuxFlavor() {
if (getOS() !== 'linux') return null
if (/\bUbuntu\b/i.test(ua)) return 'Ubuntu'
if (/\bFedora\b/i.test(ua)) return 'Fedora'
if (/\bDebian\b/i.test(ua)) return 'Debian'
if (/\bLinux Mint\b/i.test(ua)) return 'Linux Mint'
if (/\bOpenSUSE\b/i.test(ua)) return 'OpenSUSE'
if (/\bArch\b/i.test(ua)) return 'Arch'
if (/\bCentOS\b/i.test(ua)) return 'CentOS'
if (/\bRed Hat\b/i.test(ua)) return 'Red Hat'
if (/\bChrome OS\b/i.test(ua) || /\bCrOS\b/i.test(ua)) return 'Chrome OS'
return null
}
function parseAssetFilename(name) {
if (!name || typeof name !== 'string') return null
const lower = name.toLowerCase()
let platform = null
if (lower.includes('windows')) platform = 'windows'
else if (lower.includes('macos') || (lower.includes('mac') && !lower.includes('macos'))) platform = 'mac'
else if (lower.includes('linux')) platform = 'linux'
if (!platform) return null
let arch = null
if (lower.includes('arm64') || lower.includes('aarch64')) arch = 'arm64'
else if (lower.includes('amd64') || lower.includes('x64')) arch = 'x64'
else if (lower.includes('x86') || lower.includes('i386')) arch = 'x86'
if (!arch) return null
let packageType = null
if (lower.endsWith('.deb')) packageType = 'deb'
else if (lower.endsWith('.rpm')) packageType = 'rpm'
else if (lower.endsWith('.dmg')) packageType = 'dmg'
else if (lower.endsWith('.zip') || lower.endsWith('.msi')) packageType = 'archive'
return { platform, arch, packageType: packageType || 'unknown', name }
}
function recommendDownload(assets, overrides) {
const os = (overrides && overrides.os != null) ? overrides.os : getOS()
const arch = (overrides && overrides.architecture != null) ? overrides.architecture : getArchitecture()
const linuxFlavor = (overrides && overrides.linuxFlavor !== undefined) ? overrides.linuxFlavor : getLinuxFlavor()
let reason = ''
if (!Array.isArray(assets) || assets.length === 0) {
return { recommended: null, alternatives: [], reason: reason || 'No assets provided.' }
}
const wantArch = (arch === 'x64' || arch === 'x86') ? 'x64' : (arch === 'arm64' || arch === 'arm') ? 'arm64' : null
const wantOs = os === 'windows' ? 'windows' : os === 'mac' ? 'mac' : os === 'linux' ? 'linux' : null
const preferDeb = linuxFlavor === 'Ubuntu' || linuxFlavor === 'Debian' || linuxFlavor === 'Linux Mint' || linuxFlavor === 'Chrome OS'
const preferRpm = linuxFlavor === 'Fedora' || linuxFlavor === 'Red Hat' || linuxFlavor === 'CentOS' || linuxFlavor === 'OpenSUSE'
const parsed = []
for (let i = 0; i < assets.length; i++) {
const a = assets[i]
const name = a && (a.name != null ? a.name : a)
const url = a && a.url
const p = parseAssetFilename(name)
if (!p) continue
parsed.push({ name, url, parsed: p })
}
if (parsed.length === 0) {
return { recommended: null, alternatives: [], reason: reason || 'No recognizable asset filenames.' }
}
function score(entry) {
const p = entry.parsed
const nameLower = (entry.name || '').toLowerCase()
let s = 0
if (wantOs && p.platform === wantOs) s += 100
else if (wantOs) s -= 50
if (wantArch && p.arch === wantArch) s += 50
else if (wantArch) s -= 30
if (wantOs === 'linux' && p.packageType === 'deb' && preferDeb) s += 20
if (wantOs === 'linux' && p.packageType === 'rpm' && preferRpm) s += 20
if (wantOs === 'linux' && !preferDeb && !preferRpm && p.packageType === 'deb') s += 5
if (nameLower.includes('chardonnay')) s += 10
if (nameLower.includes('classic')) s -= 5
return s
}
parsed.sort((a, b) => score(b) - score(a))
const best = parsed[0]
const bestScore = score(best)
const recommended = bestScore >= 50 ? { name: best.name, url: best.url } : null
let altCandidates = parsed.slice(1, 4)
if (wantOs) altCandidates = altCandidates.filter(e => e.parsed.platform === wantOs)
if (wantArch) altCandidates = altCandidates.filter(e => e.parsed.arch === wantArch)
const alternatives = altCandidates.map(e => ({ name: e.name, url: e.url }))
const classicVsChardonnayFaqUrl = 'https://getlibation.com/docs/frequently-asked-questions#what-s-the-difference-between-classic-and-chardonnay'
let windowsX64Choice = null
if (wantOs === 'windows' && wantArch === 'x64') {
let winChardonnay = null
let winClassic = null
for (let j = 0; j < parsed.length; j++) {
const e = parsed[j]
if (e.parsed.platform !== 'windows' || e.parsed.arch !== 'x64') continue
const n = (e.name || '').toLowerCase()
if (n.includes('chardonnay')) winChardonnay = { name: e.name, url: e.url }
if (n.includes('classic')) winClassic = { name: e.name, url: e.url }
}
if (winChardonnay && winClassic) windowsX64Choice = { chardonnay: winChardonnay, classic: winClassic }
}
if (!recommended && wantOs) {
reason = 'No asset matched your system (OS: ' + os + ', arch: ' + arch + '). Try choosing a download manually.'
} else if (recommended && wantOs && !wantArch) {
reason = 'Matched your OS; architecture could not be detected. If this download is wrong, pick another (e.g. arm64 vs x64).'
}
return {
recommended,
alternatives,
reason: reason || (recommended ? 'Recommended for your system.' : ''),
windowsX64Choice,
classicVsChardonnayFaqUrl: windowsX64Choice ? classicVsChardonnayFaqUrl : null,
}
}
return {
os: getOS(),
osVersion: getOSVersion(),
architecture: getArchitecture(),
linuxFlavor: getLinuxFlavor(),
getOS,
getOSVersion,
getArchitecture,
getLinuxFlavor,
parseAssetFilename,
recommendDownload,
}
}
+8
View File
@@ -0,0 +1,8 @@
import DefaultTheme from 'vitepress/theme'
import Layout from './Layout.vue'
import './custom.css'
export default {
extends: DefaultTheme,
Layout,
}
+32
View File
@@ -0,0 +1,32 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": ".NET Core Launch (console) Windows",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceFolder}/Source/bin/Avalonia/Debug/Libation.dll",
"args": [],
"cwd": "${workspaceFolder}",
"stopAtEntry": false,
"console": "internalConsole"
},
{
"name": ".NET Core Launch (console) Linux",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build_linux",
"program": "${workspaceFolder}/Source/bin/Avalonia/Debug/Libation.dll",
"args": [],
"cwd": "${workspaceFolder}",
"stopAtEntry": false,
"console": "internalConsole"
}
]
}
+59
View File
@@ -0,0 +1,59 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "build",
"dependsOn": [
"build_libation",
"build_linuxconfigapp"
]
},
{
"label": "build_libation",
"type": "shell",
"command": "dotnet",
"args": [
"build",
"${workspaceFolder}/Source/LibationAvalonia/LibationAvalonia.csproj"
],
"group": "build",
"presentation": {
//"reveal": "silent"
},
"problemMatcher": "$msCompile"
},
{
"label": "build_linuxconfigapp",
"type": "shell",
"command": "dotnet",
"args": [
"build",
"${workspaceFolder}/Source/LoadByOS/LinuxConfigApp/LinuxConfigApp.csproj"
],
"group": "build",
"presentation": {
//"reveal": "silent"
},
"problemMatcher": "$msCompile"
},
{
"label": "build_linux",
"type": "shell",
"command": "dotnet",
"args": [
"build",
"${workspaceFolder}/Source/LibationAvalonia/LibationAvalonia.csproj",
"-p:TargetFramework=net9.0",
"-p:TargetFrameworks=net9.0",
"-p:RuntimeIdentifier=linux-x64"
],
"group": "build",
"presentation": {
//"reveal": "silent"
},
"problemMatcher": "$msCompile"
}
]
}
-12
View File
@@ -1,12 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AAXClean" Version="0.1.9" />
<PackageReference Include="Dinah.Core" Version="1.1.0.1" />
</ItemGroup>
</Project>
-230
View File
@@ -1,230 +0,0 @@
using AAXClean;
using Dinah.Core;
using Dinah.Core.IO;
using Dinah.Core.Net.Http;
using Dinah.Core.StepRunner;
using System;
using System.IO;
namespace AaxDecrypter
{
public enum OutputFormat { Mp4a, Mp3 }
public class AaxcDownloadConverter
{
public event EventHandler<AppleTags> RetrievedTags;
public event EventHandler<byte[]> RetrievedCoverArt;
public event EventHandler<DownloadProgress> DecryptProgressUpdate;
public event EventHandler<TimeSpan> DecryptTimeRemaining;
public string AppName { get; set; } = nameof(AaxcDownloadConverter);
private string outputFileName { get; }
private string cacheDir { get; }
private DownloadLicense downloadLicense { get; }
private AaxFile aaxFile;
private OutputFormat OutputFormat;
private StepSequence steps { get; }
private NetworkFileStreamPersister nfsPersister;
private bool isCanceled { get; set; }
private string jsonDownloadState => Path.Combine(cacheDir, Path.GetFileNameWithoutExtension(outputFileName) + ".json");
private string tempFile => PathLib.ReplaceExtension(jsonDownloadState, ".aaxc");
public AaxcDownloadConverter(string outFileName, string cacheDirectory, DownloadLicense dlLic, OutputFormat outputFormat)
{
ArgumentValidator.EnsureNotNullOrWhiteSpace(outFileName, nameof(outFileName));
outputFileName = outFileName;
var outDir = Path.GetDirectoryName(outputFileName);
if (!Directory.Exists(outDir))
throw new ArgumentNullException(nameof(outDir), "Directory does not exist");
if (File.Exists(outputFileName))
File.Delete(outputFileName);
if (!Directory.Exists(cacheDirectory))
throw new ArgumentNullException(nameof(cacheDirectory), "Directory does not exist");
cacheDir = cacheDirectory;
downloadLicense = ArgumentValidator.EnsureNotNull(dlLic, nameof(dlLic));
OutputFormat = outputFormat;
steps = new StepSequence
{
Name = "Download and Convert Aaxc To " + (outputFormat == OutputFormat.Mp4a ? "M4b" : "Mp3"),
["Step 1: Get Aaxc Metadata"] = Step1_GetMetadata,
["Step 2: Download Decrypted Audiobook"] = Step2_DownloadAndCombine,
["Step 3: Create Cue"] = Step3_CreateCue,
["Step 4: Create Nfo"] = Step4_CreateNfo,
["Step 5: Cleanup"] = Step5_Cleanup,
};
}
/// <summary>
/// Setting cover art by this method will insert the art into the audiobook metadata
/// </summary>
public void SetCoverArt(byte[] coverArt)
{
if (coverArt is null) return;
aaxFile?.AppleTags.SetCoverArt(coverArt);
RetrievedCoverArt?.Invoke(this, coverArt);
}
public bool Run()
{
var (IsSuccess, Elapsed) = steps.Run();
if (!IsSuccess)
{
Console.WriteLine("WARNING-Conversion failed");
return false;
}
var speedup = (int)(aaxFile.Duration.TotalSeconds / (long)Elapsed.TotalSeconds);
Serilog.Log.Logger.Information($"Speedup is {speedup}x realtime.");
return true;
}
public bool Step1_GetMetadata()
{
//Get metadata from the file over http
if (File.Exists(jsonDownloadState))
{
try
{
nfsPersister = new NetworkFileStreamPersister(jsonDownloadState);
//If More than ~1 hour has elapsed since getting the download url, it will expire.
//The new url will be to the same file.
nfsPersister.NetworkFileStream.SetUriForSameFile(new Uri(downloadLicense.DownloadUrl));
}
catch
{
FileExt.SafeDelete(jsonDownloadState);
FileExt.SafeDelete(tempFile);
nfsPersister = NewNetworkFilePersister();
}
}
else
{
nfsPersister = NewNetworkFilePersister();
}
aaxFile = new AaxFile(nfsPersister.NetworkFileStream);
RetrievedTags?.Invoke(this, aaxFile.AppleTags);
RetrievedCoverArt?.Invoke(this, aaxFile.AppleTags.Cover);
return !isCanceled;
}
private NetworkFileStreamPersister NewNetworkFilePersister()
{
var headers = new System.Net.WebHeaderCollection
{
{ "User-Agent", downloadLicense.UserAgent }
};
var networkFileStream = new NetworkFileStream(tempFile, new Uri(downloadLicense.DownloadUrl), 0, headers);
return new NetworkFileStreamPersister(networkFileStream, jsonDownloadState);
}
public bool Step2_DownloadAndCombine()
{
var zeroProgress = new DownloadProgress
{
BytesReceived = 0,
ProgressPercentage = 0,
TotalBytesToReceive = nfsPersister.NetworkFileStream.Length
};
DecryptProgressUpdate?.Invoke(this, zeroProgress);
if (File.Exists(outputFileName))
FileExt.SafeDelete(outputFileName);
FileStream outFile = File.Open(outputFileName, FileMode.OpenOrCreate, FileAccess.ReadWrite);
aaxFile.SetDecryptionKey(downloadLicense.AudibleKey, downloadLicense.AudibleIV);
aaxFile.ConversionProgressUpdate += AaxFile_ConversionProgressUpdate;
var decryptionResult = OutputFormat == OutputFormat.Mp4a ? aaxFile.ConvertToMp4a(outFile, downloadLicense.ChapterInfo) : aaxFile.ConvertToMp3(outFile);
aaxFile.ConversionProgressUpdate -= AaxFile_ConversionProgressUpdate;
aaxFile.Close();
downloadLicense.ChapterInfo = aaxFile.Chapters;
nfsPersister.Dispose();
DecryptProgressUpdate?.Invoke(this, zeroProgress);
return decryptionResult == ConversionResult.NoErrorsDetected && !isCanceled;
}
private void AaxFile_ConversionProgressUpdate(object sender, ConversionProgressEventArgs e)
{
var duration = aaxFile.Duration;
double remainingSecsToProcess = (duration - e.ProcessPosition).TotalSeconds;
double estTimeRemaining = remainingSecsToProcess / e.ProcessSpeed;
if (double.IsNormal(estTimeRemaining))
DecryptTimeRemaining?.Invoke(this, TimeSpan.FromSeconds(estTimeRemaining));
double progressPercent = 100 * e.ProcessPosition.TotalSeconds / duration.TotalSeconds;
DecryptProgressUpdate?.Invoke(this,
new DownloadProgress
{
ProgressPercentage = progressPercent,
BytesReceived = (long)(nfsPersister.NetworkFileStream.Length * progressPercent),
TotalBytesToReceive = nfsPersister.NetworkFileStream.Length
});
}
public bool Step3_CreateCue()
{
// not a critical step. its failure should not prevent future steps from running
try
{
File.WriteAllText(PathLib.ReplaceExtension(outputFileName, ".cue"), Cue.CreateContents(Path.GetFileName(outputFileName), downloadLicense.ChapterInfo));
}
catch (Exception ex)
{
Serilog.Log.Logger.Error(ex, $"{nameof(Step3_CreateCue)}. FAILED");
}
return !isCanceled;
}
public bool Step4_CreateNfo()
{
// not a critical step. its failure should not prevent future steps from running
try
{
File.WriteAllText(PathLib.ReplaceExtension(outputFileName, ".nfo"), NFO.CreateContents(AppName, aaxFile, downloadLicense.ChapterInfo));
}
catch (Exception ex)
{
Serilog.Log.Logger.Error(ex, $"{nameof(Step4_CreateNfo)}. FAILED");
}
return !isCanceled;
}
public bool Step5_Cleanup()
{
FileExt.SafeDelete(jsonDownloadState);
FileExt.SafeDelete(tempFile);
return !isCanceled;
}
public void Cancel()
{
isCanceled = true;
aaxFile?.Cancel();
aaxFile?.Dispose();
nfsPersister?.NetworkFileStream?.Close();
nfsPersister?.Dispose();
}
}
}
-59
View File
@@ -1,59 +0,0 @@
using System;
using System.IO;
using System.Text;
using AAXClean;
using Dinah.Core;
namespace AaxDecrypter
{
public static class Cue
{
public static string CreateContents(string filePath, ChapterInfo chapters)
{
var stringBuilder = new StringBuilder();
stringBuilder.AppendLine(GetFileLine(filePath, "MP3"));
var trackCount = 0;
foreach (var c in chapters.Chapters)
{
trackCount++;
stringBuilder.AppendLine($"TRACK {trackCount} AUDIO");
stringBuilder.AppendLine($" TITLE \"{c.Title}\"");
stringBuilder.AppendLine($" INDEX 01 {(int)c.StartOffset.TotalMinutes}:{c.StartOffset:ss\\:ff}");
}
return stringBuilder.ToString();
}
public static void UpdateFileName(FileInfo cueFileInfo, string audioFilePath)
=> UpdateFileName(cueFileInfo.FullName, audioFilePath);
public static void UpdateFileName(string cueFilePath, FileInfo audioFileInfo)
=> UpdateFileName(cueFilePath, audioFileInfo.FullName);
public static void UpdateFileName(FileInfo cueFileInfo, FileInfo audioFileInfo)
=> UpdateFileName(cueFileInfo.FullName, audioFileInfo.FullName);
public static void UpdateFileName(string cueFilePath, string audioFilePath)
{
var cueContents = File.ReadAllLines(cueFilePath);
for (var i = 0; i < cueContents.Length; i++)
{
var line = cueContents[i];
if (!line.Trim().StartsWith("FILE") || !line.Contains(" "))
continue;
var fileTypeBegins = line.LastIndexOf(" ") + 1;
cueContents[i] = GetFileLine(audioFilePath, line[fileTypeBegins..]);
break;
}
File.WriteAllLines(cueFilePath, cueContents);
}
private static string GetFileLine(string filePath, string audioType) => $"FILE {Path.GetFileName(filePath).SurroundWithQuotes()} {audioType}";
}
}
-27
View File
@@ -1,27 +0,0 @@
using AAXClean;
using Dinah.Core;
namespace AaxDecrypter
{
public class DownloadLicense
{
public string DownloadUrl { get; }
public string AudibleKey { get; }
public string AudibleIV { get; }
public string UserAgent { get; }
public ChapterInfo ChapterInfo { get; set; }
public DownloadLicense(string downloadUrl, string audibleKey, string audibleIV, string userAgent)
{
ArgumentValidator.EnsureNotNullOrEmpty(downloadUrl, nameof(downloadUrl));
ArgumentValidator.EnsureNotNullOrEmpty(audibleKey, nameof(audibleKey));
ArgumentValidator.EnsureNotNullOrEmpty(audibleIV, nameof(audibleIV));
ArgumentValidator.EnsureNotNullOrEmpty(userAgent, nameof(userAgent));
DownloadUrl = downloadUrl;
AudibleKey = audibleKey;
AudibleIV = audibleIV;
UserAgent = userAgent;
}
}
}
-54
View File
@@ -1,54 +0,0 @@
using AAXClean;
using Dinah.Core;
namespace AaxDecrypter
{
public static class NFO
{
public static string CreateContents(string ripper, Mp4File aaxcTagLib, ChapterInfo chapters)
{
var _hours = (int)aaxcTagLib.Duration.TotalHours;
var myDuration
= (_hours > 0 ? _hours + " hours, " : string.Empty)
+ aaxcTagLib.Duration.Minutes + " minutes, "
+ aaxcTagLib.Duration.Seconds + " seconds";
var nfoString
= "General Information\r\n"
+ "======================\r\n"
+ $" Title: {aaxcTagLib.AppleTags.TitleSansUnabridged?.UnicodeToAscii() ?? "[unknown]"}\r\n"
+ $" Author: {aaxcTagLib.AppleTags.FirstAuthor?.UnicodeToAscii() ?? "[unknown]"}\r\n"
+ $" Read By: {aaxcTagLib.AppleTags.Narrator?.UnicodeToAscii() ?? "[unknown]"}\r\n"
+ $" Release Date: {aaxcTagLib.AppleTags.ReleaseDate ?? "[unknown]"}\r\n"
+ $" Book Copyright: {aaxcTagLib.AppleTags.BookCopyright ?? "[unknown]"}\r\n"
+ $" Recording Copyright: {aaxcTagLib.AppleTags.RecordingCopyright ?? "[unknown]"}\r\n"
+ $" Genre: {aaxcTagLib.AppleTags.Generes ?? "[unknown]"}\r\n"
+ $" Publisher: {aaxcTagLib.AppleTags.Publisher ?? "[unknown]"}\r\n"
+ $" Duration: {myDuration}\r\n"
+ $" Chapters: {chapters.Count}\r\n"
+ "\r\n"
+ "\r\n"
+ "Media Information\r\n"
+ "======================\r\n"
+ " Source Format: Audible AAXC\r\n"
+ $" Source Sample Rate: {aaxcTagLib.TimeScale} Hz\r\n"
+ $" Source Channels: {aaxcTagLib.AudioChannels}\r\n"
+ $" Source Bitrate: {aaxcTagLib.AverageBitrate} Kbps\r\n"
+ "\r\n"
+ " Lossless Encode: Yes\r\n"
+ " Encoded Codec: AAC / M4B\r\n"
+ $" Encoded Sample Rate: {aaxcTagLib.TimeScale} Hz\r\n"
+ $" Encoded Channels: {aaxcTagLib.AudioChannels}\r\n"
+ $" Encoded Bitrate: {aaxcTagLib.AverageBitrate} Kbps\r\n"
+ "\r\n"
+ $" Ripper: {ripper}\r\n"
+ "\r\n"
+ "\r\n"
+ "Book Description\r\n"
+ "================\r\n"
+ (!string.IsNullOrWhiteSpace(aaxcTagLib.AppleTags.LongDescription) ? aaxcTagLib.AppleTags.LongDescription.UnicodeToAscii() : aaxcTagLib.AppleTags.Comment?.UnicodeToAscii());
return nfoString;
}
}
}
-446
View File
@@ -1,446 +0,0 @@
using Dinah.Core;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading;
namespace AaxDecrypter
{
/// <summary>
/// A <see cref="CookieContainer"/> for a single Uri.
/// </summary>
public class SingleUriCookieContainer : CookieContainer
{
private Uri baseAddress;
public Uri Uri
{
get => baseAddress;
set
{
baseAddress = new UriBuilder(value.Scheme, value.Host).Uri;
}
}
public CookieCollection GetCookies()
{
return GetCookies(Uri);
}
}
/// <summary>
/// A resumable, simultaneous file downloader and reader.
/// </summary>
public class NetworkFileStream : Stream, IUpdatable
{
public event EventHandler Updated;
#region Public Properties
/// <summary>
/// Location to save the downloaded data.
/// </summary>
[JsonProperty(Required = Required.Always)]
public string SaveFilePath { get; }
/// <summary>
/// Http(s) address of the file to download.
/// </summary>
[JsonProperty(Required = Required.Always)]
public Uri Uri { get; private set; }
/// <summary>
/// All cookies set by caller or by the remote server.
/// </summary>
[JsonProperty(Required = Required.Always)]
public SingleUriCookieContainer CookieContainer { get; }
/// <summary>
/// Http headers to be sent to the server with the request.
/// </summary>
[JsonProperty(Required = Required.Always)]
public WebHeaderCollection RequestHeaders { get; private set; }
/// <summary>
/// The position in <see cref="SaveFilePath"/> that has been written and flushed to disk.
/// </summary>
[JsonProperty(Required = Required.Always)]
public long WritePosition { get; private set; }
/// <summary>
/// The total length of the <see cref="Uri"/> file to download.
/// </summary>
[JsonProperty(Required = Required.Always)]
public long ContentLength { get; private set; }
#endregion
#region Private Properties
private HttpWebRequest HttpRequest { get; set; }
private FileStream _writeFile { get; }
private FileStream _readFile { get; }
private Stream _networkStream { get; set; }
private bool hasBegunDownloading { get; set; }
private bool isCancelled { get; set; }
private EventWaitHandle downloadEnded { get; set; }
private EventWaitHandle downloadedPiece { get; set; }
#endregion
#region Constants
//Download buffer size
private const int DOWNLOAD_BUFF_SZ = 4 * 1024;
//NetworkFileStream will flush all data in _writeFile to disk after every
//DATA_FLUSH_SZ bytes are written to the file stream.
private const int DATA_FLUSH_SZ = 1024 * 1024;
#endregion
#region Constructor
/// <summary>
/// A resumable, simultaneous file downloader and reader.
/// </summary>
/// <param name="saveFilePath">Path to a location on disk to save the downloaded data from <paramref name="uri"/></param>
/// <param name="uri">Http(s) address of the file to download.</param>
/// <param name="writePosition">The position in <paramref name="uri"/> to begin downloading.</param>
/// <param name="requestHeaders">Http headers to be sent to the server with the <see cref="HttpWebRequest"/>.</param>
/// <param name="cookies">A <see cref="SingleUriCookieContainer"/> with cookies to send with the <see cref="HttpWebRequest"/>. It will also be populated with any cookies set by the server. </param>
public NetworkFileStream(string saveFilePath, Uri uri, long writePosition = 0, WebHeaderCollection requestHeaders = null, SingleUriCookieContainer cookies = null)
{
ArgumentValidator.EnsureNotNullOrWhiteSpace(saveFilePath, nameof(saveFilePath));
ArgumentValidator.EnsureNotNullOrWhiteSpace(uri?.AbsoluteUri, nameof(uri));
ArgumentValidator.EnsureGreaterThan(writePosition, nameof(writePosition), -1);
if (!Directory.Exists(Path.GetDirectoryName(saveFilePath)))
throw new ArgumentException($"Specified {nameof(saveFilePath)} directory \"{Path.GetDirectoryName(saveFilePath)}\" does not exist.");
SaveFilePath = saveFilePath;
Uri = uri;
WritePosition = writePosition;
RequestHeaders = requestHeaders ?? new WebHeaderCollection();
CookieContainer = cookies ?? new SingleUriCookieContainer { Uri = uri };
_writeFile = new FileStream(SaveFilePath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite)
{
Position = WritePosition
};
_readFile = new FileStream(SaveFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
SetUriForSameFile(uri);
}
#endregion
#region Downloader
/// <summary>
/// Update the <see cref="JsonFilePersister"/>.
/// </summary>
private void Update()
{
RequestHeaders = HttpRequest.Headers;
Updated?.Invoke(this, EventArgs.Empty);
}
/// <summary>
/// Set a different <see cref="System.Uri"/> to the same file targeted by this instance of <see cref="NetworkFileStream"/>
/// </summary>
/// <param name="uriToSameFile">New <see cref="System.Uri"/> host must match existing host.</param>
public void SetUriForSameFile(Uri uriToSameFile)
{
ArgumentValidator.EnsureNotNullOrWhiteSpace(uriToSameFile?.AbsoluteUri, nameof(uriToSameFile));
if (uriToSameFile.Host != Uri.Host)
throw new ArgumentException($"New uri to the same file must have the same host.\r\n Old Host :{Uri.Host}\r\nNew Host: {uriToSameFile.Host}");
if (hasBegunDownloading)
throw new InvalidOperationException("Cannot change Uri after download has started.");
Uri = uriToSameFile;
HttpRequest = WebRequest.CreateHttp(Uri);
HttpRequest.CookieContainer = CookieContainer;
HttpRequest.Headers = RequestHeaders;
//If NetworkFileStream is resuming, Header will already contain a range.
HttpRequest.Headers.Remove("Range");
HttpRequest.AddRange(WritePosition);
}
/// <summary>
/// Begins downloading <see cref="Uri"/> to <see cref="SaveFilePath"/> in a background thread.
/// </summary>
private void BeginDownloading()
{
downloadEnded = new EventWaitHandle(false, EventResetMode.ManualReset);
if (ContentLength != 0 && WritePosition == ContentLength)
{
hasBegunDownloading = true;
downloadEnded.Set();
return;
}
if (ContentLength != 0 && WritePosition > ContentLength)
throw new WebException($"Specified write position (0x{WritePosition:X10}) is larger than {nameof(ContentLength)} (0x{ContentLength:X10}).");
var response = HttpRequest.GetResponse() as HttpWebResponse;
if (response.StatusCode != HttpStatusCode.PartialContent)
throw new WebException($"Server at {Uri.Host} responded with unexpected status code: {response.StatusCode}.");
if (response.Headers.GetValues("Accept-Ranges").FirstOrDefault(r => r.EqualsInsensitive("bytes")) is null)
throw new WebException($"Server at {Uri.Host} does not support Http ranges");
//Content length is the length of the range request, and it is only equal
//to the complete file length if requesting Range: bytes=0-
if (WritePosition == 0)
ContentLength = response.ContentLength;
_networkStream = response.GetResponseStream();
downloadedPiece = new EventWaitHandle(false, EventResetMode.AutoReset);
//Download the file in the background.
new Thread(() => DownloadFile())
{ IsBackground = true }
.Start();
hasBegunDownloading = true;
return;
}
/// <summary>
/// Downlod <see cref="Uri"/> to <see cref="SaveFilePath"/>.
/// </summary>
private void DownloadFile()
{
var downloadPosition = WritePosition;
var nextFlush = downloadPosition + DATA_FLUSH_SZ;
var buff = new byte[DOWNLOAD_BUFF_SZ];
do
{
var bytesRead = _networkStream.Read(buff, 0, DOWNLOAD_BUFF_SZ);
_writeFile.Write(buff, 0, bytesRead);
downloadPosition += bytesRead;
if (downloadPosition > nextFlush)
{
_writeFile.Flush();
WritePosition = downloadPosition;
Update();
nextFlush = downloadPosition + DATA_FLUSH_SZ;
downloadedPiece.Set();
}
} while (downloadPosition < ContentLength && !isCancelled);
_writeFile.Close();
_networkStream.Close();
WritePosition = downloadPosition;
Update();
downloadedPiece.Set();
downloadEnded.Set();
if (!isCancelled && WritePosition < ContentLength)
throw new WebException($"Downloaded size (0x{WritePosition:X10}) is less than {nameof(ContentLength)} (0x{ContentLength:X10}).");
if (WritePosition > ContentLength)
throw new WebException($"Downloaded size (0x{WritePosition:X10}) is greater than {nameof(ContentLength)} (0x{ContentLength:X10}).");
}
#endregion
#region Json Connverters
public static JsonSerializerSettings GetJsonSerializerSettings()
{
var settings = new JsonSerializerSettings();
settings.Converters.Add(new CookieContainerConverter());
settings.Converters.Add(new WebHeaderCollectionConverter());
return settings;
}
internal class CookieContainerConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
=> objectType == typeof(SingleUriCookieContainer);
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var jObj = JObject.Load(reader);
var result = new SingleUriCookieContainer()
{
Uri = new Uri(jObj["Uri"].Value<string>()),
Capacity = jObj["Capacity"].Value<int>(),
MaxCookieSize = jObj["MaxCookieSize"].Value<int>(),
PerDomainCapacity = jObj["PerDomainCapacity"].Value<int>()
};
var cookieList = jObj["Cookies"].ToList();
foreach (var cookie in cookieList)
{
result.Add(
new Cookie
{
Comment = cookie["Comment"].Value<string>(),
HttpOnly = cookie["HttpOnly"].Value<bool>(),
Discard = cookie["Discard"].Value<bool>(),
Domain = cookie["Domain"].Value<string>(),
Expired = cookie["Expired"].Value<bool>(),
Expires = cookie["Expires"].Value<DateTime>(),
Name = cookie["Name"].Value<string>(),
Path = cookie["Path"].Value<string>(),
Port = cookie["Port"].Value<string>(),
Secure = cookie["Secure"].Value<bool>(),
Value = cookie["Value"].Value<string>(),
Version = cookie["Version"].Value<int>(),
});
}
return result;
}
public override bool CanWrite => true;
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var cookies = value as SingleUriCookieContainer;
var obj = (JObject)JToken.FromObject(value);
var container = cookies.GetCookies();
var propertyNames = container.Select(c => JToken.FromObject(c));
obj.AddFirst(new JProperty("Cookies", new JArray(propertyNames)));
obj.WriteTo(writer);
}
}
internal class WebHeaderCollectionConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
=> objectType == typeof(WebHeaderCollection);
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var jObj = JObject.Load(reader);
var result = new WebHeaderCollection();
foreach (var kvp in jObj)
result.Add(kvp.Key, kvp.Value.Value<string>());
return result;
}
public override bool CanWrite => true;
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var jObj = new JObject();
var type = value.GetType();
var headers = value as WebHeaderCollection;
var jHeaders = headers.AllKeys.Select(k => new JProperty(k, headers[k]));
jObj.Add(jHeaders);
jObj.WriteTo(writer);
}
}
#endregion
#region Download Stream Reader
[JsonIgnore]
public override bool CanRead => true;
[JsonIgnore]
public override bool CanSeek => true;
[JsonIgnore]
public override bool CanWrite => false;
[JsonIgnore]
public override long Length
{
get
{
if (!hasBegunDownloading)
BeginDownloading();
return ContentLength;
}
}
[JsonIgnore]
public override long Position { get => _readFile.Position; set => Seek(value, SeekOrigin.Begin); }
[JsonIgnore]
public override bool CanTimeout => false;
[JsonIgnore]
public override int ReadTimeout { get => base.ReadTimeout; set => base.ReadTimeout = value; }
[JsonIgnore]
public override int WriteTimeout { get => base.WriteTimeout; set => base.WriteTimeout = value; }
public override void Flush() => throw new NotImplementedException();
public override void SetLength(long value) => throw new NotImplementedException();
public override void Write(byte[] buffer, int offset, int count) => throw new NotImplementedException();
public override int Read(byte[] buffer, int offset, int count)
{
if (!hasBegunDownloading)
BeginDownloading();
var toRead = Math.Min(count, Length - Position);
WaitToPosition(Position + toRead);
return _readFile.Read(buffer, offset, count);
}
public override long Seek(long offset, SeekOrigin origin)
{
var newPosition = origin switch
{
SeekOrigin.Current => Position + offset,
SeekOrigin.End => ContentLength + offset,
_ => offset,
};
WaitToPosition(newPosition);
return _readFile.Position = newPosition;
}
/// <summary>
/// Blocks until the file has downloaded to at least <paramref name="requiredPosition"/>, then returns.
/// </summary>
/// <param name="requiredPosition">The minimum required flished data length in <see cref="SaveFilePath"/>.</param>
private void WaitToPosition(long requiredPosition)
{
while (requiredPosition > WritePosition && !isCancelled && hasBegunDownloading && !downloadedPiece.WaitOne(1000)) ;
}
public override void Close()
{
isCancelled = true;
while (downloadEnded is not null && !downloadEnded.WaitOne(1000)) ;
_readFile.Close();
_writeFile.Close();
_networkStream?.Close();
Update();
}
#endregion
~NetworkFileStream()
{
downloadEnded?.Close();
downloadedPiece?.Close();
}
}
}
@@ -1,23 +0,0 @@
using Dinah.Core.IO;
using Newtonsoft.Json;
namespace AaxDecrypter
{
internal class NetworkFileStreamPersister : JsonFilePersister<NetworkFileStream>
{
/// <summary>Alias for Target </summary>
public NetworkFileStream NetworkFileStream => Target;
/// <summary>uses path. create file if doesn't yet exist</summary>
public NetworkFileStreamPersister(NetworkFileStream networkFileStream, string path, string jsonPath = null)
: base(networkFileStream, path, jsonPath) { }
/// <summary>load from existing file</summary>
public NetworkFileStreamPersister(string path, string jsonPath = null)
: base(path, jsonPath) { }
protected override JsonSerializerSettings GetSerializerSettings() => NetworkFileStream.GetJsonSerializerSettings();
}
}
-4
View File
@@ -1,4 +0,0 @@
{
"//": "https://github.com/BalassaMarton/MSBump",
BumpRevision: true
}
-21
View File
@@ -1,21 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<Version>6.0.2.1</Version>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MSBump" Version="2.3.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Octokit" Version="0.50.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\InternalUtilities\InternalUtilities.csproj" />
</ItemGroup>
</Project>
-333
View File
@@ -1,333 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using Dinah.Core;
using Dinah.Core.IO;
using Dinah.Core.Logging;
using FileManager;
using InternalUtilities;
using Newtonsoft.Json.Linq;
using Serilog;
namespace AppScaffolding
{
public static class LibationScaffolding
{
// AppScaffolding
private static Assembly _executingAssembly;
private static Assembly ExecutingAssembly
=> _executingAssembly ??= Assembly.GetExecutingAssembly();
// LibationWinForms or LibationCli
private static Assembly _entryAssembly;
private static Assembly EntryAssembly
=> _entryAssembly ??= Assembly.GetEntryAssembly();
// previously: System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
private static Version _buildVersion;
public static Version BuildVersion
=> _buildVersion
??= new[] { ExecutingAssembly.GetName(), EntryAssembly.GetName() }
.Max(a => a.Version);
/// <summary>Run migrations before loading Configuration for the first time. Then load and return Configuration</summary>
public static Configuration RunPreConfigMigrations()
{
// must occur before access to Configuration instance
Migrations.migrate_to_v5_2_0__pre_config();
//***********************************************//
// //
// do not use Configuration before this line //
// //
//***********************************************//
return Configuration.Instance;
}
public static void RunPostConfigMigrations()
{
AudibleApiStorage.EnsureAccountsSettingsFileExists();
var config = Configuration.Instance;
//
// migrations go below here
//
Migrations.migrate_to_v5_2_0__post_config(config);
Migrations.migrate_to_v5_7_1(config);
}
/// <summary>Initialize logging. Run after migration</summary>
public static void RunPostMigrationScaffolding()
{
var config = Configuration.Instance;
ensureSerilogConfig(config);
configureLogging(config);
logStartupState(config);
}
private static void ensureSerilogConfig(Configuration config)
{
if (config.GetObject("Serilog") != null)
return;
// "Serilog": {
// "MinimumLevel": "Information"
// "WriteTo": [
// {
// "Name": "Console"
// },
// {
// "Name": "File",
// "Args": {
// "rollingInterval": "Day",
// "outputTemplate": ...
// }
// }
// ],
// "Using": [ "Dinah.Core" ],
// "Enrich": [ "WithCaller" ]
// }
var serilogObj = new JObject
{
{ "MinimumLevel", "Information" },
{ "WriteTo", new JArray
{
new JObject { {"Name", "Console" } },
new JObject
{
{ "Name", "File" },
{ "Args",
new JObject
{
// for this sink to work, a path must be provided. we override this below
{ "path", Path.Combine(config.LibationFiles, "_Log.log") },
{ "rollingInterval", "Month" },
// Serilog template formatting examples
// - default: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception}"
// output example: 2019-11-26 08:48:40.224 -05:00 [DBG] Begin Libation
// - with class and method info: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] (at {Caller}) {Message:lj}{NewLine}{Exception}";
// output example: 2019-11-26 08:48:40.224 -05:00 [DBG] (at LibationWinForms.Program.init()) Begin Libation
{ "outputTemplate", "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] (at {Caller}) {Message:lj}{NewLine}{Exception}" }
}
}
}
}
},
{ "Using", new JArray{ "Dinah.Core" } }, // dll's name, NOT namespace
{ "Enrich", new JArray{ "WithCaller" } },
};
config.SetObject("Serilog", serilogObj);
}
// to restore original: Console.SetOut(origOut);
private static TextWriter origOut { get; } = Console.Out;
private static void configureLogging(Configuration config)
{
config.ConfigureLogging();
// capture most Console.WriteLine() and write to serilog. See below tests for details.
// Some dependencies print helpful info via Console.WriteLine. We'd like to log it.
//
// Serilog also writes to Console so this might be asking for trouble. ie: infinite loops.
// SerilogTextWriter needs to be more robust and tested. Esp the Write() methods.
// Empirical testing so far has shown no issues.
Console.SetOut(new MultiTextWriter(origOut, new SerilogTextWriter()));
#region Console => Serilog tests
/*
// all below apply to "Console." and "Console.Out."
// captured
Console.WriteLine("str");
Console.WriteLine(new { a = "anon" });
Console.WriteLine("{0}", "format");
Console.WriteLine("{0}{1}", "zero|", "one");
Console.WriteLine("{0}{1}{2}", "zero|", "one|", "two");
Console.WriteLine("{0}", new object[] { "arr" });
// not captured
Console.WriteLine();
Console.WriteLine(true);
Console.WriteLine('0');
Console.WriteLine(1);
Console.WriteLine(2m);
Console.WriteLine(3f);
Console.WriteLine(4d);
Console.WriteLine(5L);
Console.WriteLine((uint)6);
Console.WriteLine((ulong)7);
Console.Write("str");
Console.Write(true);
Console.Write('0');
Console.Write(1);
Console.Write(2m);
Console.Write(3f);
Console.Write(4d);
Console.Write(5L);
Console.Write((uint)6);
Console.Write((ulong)7);
Console.Write(new { a = "anon" });
Console.Write("{0}", "format");
Console.Write("{0}{1}", "zero|", "one");
Console.Write("{0}{1}{2}", "zero|", "one|", "two");
Console.Write("{0}", new object[] { "arr" });
*/
#endregion
// .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");
}
private static void logStartupState(Configuration config)
{
// begin logging session with a form feed
Log.Logger.Information("\r\n\f");
Log.Logger.Information("Begin. {@DebugInfo}", new
{
AppName = EntryAssembly.GetName().Name,
Version = BuildVersion.ToString(),
#if DEBUG
Mode = "Debug",
#else
Mode = "Release",
#endif
LogLevel_Verbose_Enabled = Log.Logger.IsVerboseEnabled(),
LogLevel_Debug_Enabled = Log.Logger.IsDebugEnabled(),
LogLevel_Information_Enabled = Log.Logger.IsInformationEnabled(),
LogLevel_Warning_Enabled = Log.Logger.IsWarningEnabled(),
LogLevel_Error_Enabled = Log.Logger.IsErrorEnabled(),
LogLevel_Fatal_Enabled = Log.Logger.IsFatalEnabled(),
config.LibationFiles,
AudibleFileStorage.BooksDirectory,
config.InProgress,
DownloadsInProgressDir = AudibleFileStorage.DownloadsInProgress,
DownloadsInProgressFiles = Directory.EnumerateFiles(AudibleFileStorage.DownloadsInProgress).Count(),
DecryptInProgressDir = AudibleFileStorage.DecryptInProgress,
DecryptInProgressFiles = Directory.EnumerateFiles(AudibleFileStorage.DecryptInProgress).Count(),
});
}
public static (bool hasUpgrade, string zipUrl, string htmlUrl, string zipName) GetLatestRelease()
{
(bool, string, string, string) isFalse = (false, null, null, null);
// timed out
var latest = getLatestRelease(TimeSpan.FromSeconds(10));
if (latest is null)
return isFalse;
var latestVersionString = latest.TagName.Trim('v');
if (!Version.TryParse(latestVersionString, out var latestRelease))
return isFalse;
// we're up to date
if (latestRelease <= BuildVersion)
return isFalse;
// we have an update
var zip = latest.Assets.FirstOrDefault(a => a.BrowserDownloadUrl.EndsWith(".zip"));
var zipUrl = zip?.BrowserDownloadUrl;
Log.Logger.Information("Update available: {@DebugInfo}", new
{
latestRelease = latestRelease.ToString(),
latest.HtmlUrl,
zipUrl
});
return (true, zipUrl, latest.HtmlUrl, zip.Name);
}
private static Octokit.Release getLatestRelease(TimeSpan timeout)
{
try
{
var task = System.Threading.Tasks.Task.Run(() => getLatestRelease());
if (task.Wait(timeout))
return task.Result;
Log.Logger.Information("Timed out");
}
catch (AggregateException aggEx)
{
Log.Logger.Error(aggEx, "Checking for new version too often");
}
return null;
}
private static Octokit.Release getLatestRelease()
{
var gitHubClient = new Octokit.GitHubClient(new Octokit.ProductHeaderValue("Libation"));
// https://octokitnet.readthedocs.io/en/latest/releases/
var releases = gitHubClient.Repository.Release.GetAll("rmcrackan", "Libation").GetAwaiter().GetResult();
var latest = releases.First(r => !r.Draft && !r.Prerelease);
return latest;
}
}
internal static class Migrations
{
#region migrate to v5.2.0
// get rid of meta-directories, combine DownloadsInProgressEnum and DecryptInProgressEnum => InProgress
public static void migrate_to_v5_2_0__pre_config()
{
{
var settingsKey = "DownloadsInProgressEnum";
if (UNSAFE_MigrationHelper.Settings_TryGet(settingsKey, out var value))
{
UNSAFE_MigrationHelper.Settings_Delete(settingsKey);
UNSAFE_MigrationHelper.Settings_Insert("InProgress", translatePath(value));
}
}
{
UNSAFE_MigrationHelper.Settings_Delete("DecryptInProgressEnum");
}
{ // appsettings.json
var appSettingsKey = UNSAFE_MigrationHelper.LIBATION_FILES_KEY;
if (UNSAFE_MigrationHelper.APPSETTINGS_TryGet(appSettingsKey, out var value))
UNSAFE_MigrationHelper.APPSETTINGS_Update(appSettingsKey, translatePath(value));
}
}
private static string translatePath(string path)
=> path switch
{
"AppDir" => @".\LibationFiles",
"MyDocs" => Path.GetFullPath(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "LibationFiles")),
"UserProfile" => Path.GetFullPath(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Libation")),
"WinTemp" => Path.GetFullPath(Path.Combine(Path.GetTempPath(), "Libation")),
_ => path
};
public static void migrate_to_v5_2_0__post_config(Configuration config)
{
if (!config.Exists(nameof(config.AllowLibationFixup)))
config.AllowLibationFixup = true;
if (!config.Exists(nameof(config.DecryptToLossy)))
config.DecryptToLossy = false;
}
#endregion
// add config.BadBook
public static void migrate_to_v5_7_1(Configuration config)
{
if (!config.Exists(nameof(config.BadBook)))
config.BadBook = Configuration.BadBookAction.Ask;
}
}
}
-151
View File
@@ -1,151 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Dinah.Core;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace AppScaffolding
{
/// <summary>
///
///
/// directly manipulates settings files without going through domain logic.
///
/// for migrations only. use with caution.
///
///
/// </summary>
internal static class UNSAFE_MigrationHelper
{
#region appsettings.json
private static string APPSETTINGS_JSON { get; } = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location), "appsettings.json");
public static bool APPSETTINGS_Json_Exists => File.Exists(APPSETTINGS_JSON);
public static bool APPSETTINGS_TryGet(string key, out string value)
{
bool success = false;
JToken val = null;
process_APPSETTINGS_Json(jObj => success = jObj.TryGetValue(key, out val), false);
value = success ? val.Value<string>() : null;
return success;
}
/// <summary>only insert if not exists</summary>
public static void APPSETTINGS_Insert(string key, string value)
=> process_APPSETTINGS_Json(jObj => jObj.TryAdd(key, value));
/// <summary>only update if exists</summary>
public static void APPSETTINGS_Update(string key, string value)
=> process_APPSETTINGS_Json(jObj => {
if (jObj.ContainsKey(key))
jObj[key] = value;
});
/// <summary>only delete if exists</summary>
public static void APPSETTINGS_Delete(string key)
=> process_APPSETTINGS_Json(jObj => {
if (jObj.ContainsKey(key))
jObj.Remove(key);
});
/// <param name="save">True: save if contents changed. False: no not attempt save</param>
private static void process_APPSETTINGS_Json(Action<JObject> action, bool save = true)
{
// only insert if not exists
if (!APPSETTINGS_Json_Exists)
return;
var startingContents = File.ReadAllText(APPSETTINGS_JSON);
var jObj = JObject.Parse(startingContents);
action(jObj);
if (!save)
return;
// only save if different
var endingContents_indented = jObj.ToString(Formatting.Indented);
var endingContents_compact = jObj.ToString(Formatting.None);
if (startingContents.EqualsInsensitive(endingContents_indented) || startingContents.EqualsInsensitive(endingContents_compact))
return;
File.WriteAllText(APPSETTINGS_JSON, endingContents_indented);
System.Threading.Thread.Sleep(100);
}
#endregion
#region Settings.json
public const string LIBATION_FILES_KEY = "LibationFiles";
private const string SETTINGS_JSON = "Settings.json";
public static string SettingsJsonPath
{
get
{
var success = APPSETTINGS_TryGet(LIBATION_FILES_KEY, out var value);
return !success || value is null ? null : Path.Combine(value, SETTINGS_JSON);
}
}
public static bool SettingsJson_Exists => SettingsJsonPath is not null && File.Exists(SettingsJsonPath);
public static bool Settings_TryGet(string key, out string value)
{
bool success = false;
JToken val = null;
process_SettingsJson(jObj => success = jObj.TryGetValue(key, out val), false);
value = success ? val.Value<string>() : null;
return success;
}
/// <summary>only insert if not exists</summary>
public static void Settings_Insert(string key, string value)
=> process_SettingsJson(jObj => jObj.TryAdd(key, value));
/// <summary>only update if exists</summary>
public static void Settings_Update(string key, string value)
=> process_SettingsJson(jObj => {
if (jObj.ContainsKey(key))
jObj[key] = value;
});
/// <summary>only delete if exists</summary>
public static void Settings_Delete(string key)
=> process_SettingsJson(jObj => {
if (jObj.ContainsKey(key))
jObj.Remove(key);
});
/// <param name="save">True: save if contents changed. False: no not attempt save</param>
private static void process_SettingsJson(Action<JObject> action, bool save = true)
{
// only insert if not exists
if (!SettingsJson_Exists)
return;
var startingContents = File.ReadAllText(SettingsJsonPath);
var jObj = JObject.Parse(startingContents);
action(jObj);
if (!save)
return;
// only save if different
var endingContents_indented = jObj.ToString(Formatting.Indented);
var endingContents_compact = jObj.ToString(Formatting.None);
if (startingContents.EqualsInsensitive(endingContents_indented) || startingContents.EqualsInsensitive(endingContents_compact))
return;
File.WriteAllText(SettingsJsonPath, endingContents_indented);
System.Threading.Thread.Sleep(100);
}
#endregion
}
}
@@ -1,17 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="CsvHelper" Version="27.1.1" />
<PackageReference Include="NPOI" Version="2.5.4" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DtoImporterService\DtoImporterService.csproj" />
<ProjectReference Include="..\LibationSearchEngine\LibationSearchEngine.csproj" />
</ItemGroup>
</Project>
-21
View File
@@ -1,21 +0,0 @@
using System;
using System.Collections.Generic;
using DataLayer;
using FileManager;
namespace ApplicationServices
{
public static class DbContexts
{
/// <summary>Use for fully functional context, incl. SaveChanges(). For query-only, use the other method</summary>
public static LibationContext GetContext()
=> LibationContext.Create(SqliteStorage.ConnectionString);
/// <summary>Use for full library querying. No lazy loading</summary>
public static List<LibraryBook> GetLibrary_Flat_NoTracking()
{
using var context = GetContext();
return context.GetLibrary_Flat_NoTracking();
}
}
}
-286
View File
@@ -1,286 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AudibleApi;
using DataLayer;
using Dinah.Core;
using DtoImporterService;
using InternalUtilities;
using Serilog;
using static DtoImporterService.PerfLogger;
namespace ApplicationServices
{
public static class LibraryCommands
{
private static LibraryOptions.ResponseGroupOptions LibraryResponseGroups = LibraryOptions.ResponseGroupOptions.ALL_OPTIONS;
public static async Task<List<LibraryBook>> FindInactiveBooks(Func<Account, Task<ApiExtended>> apiExtendedfunc, List<LibraryBook> existingLibrary, params Account[] accounts)
{
logRestart();
//These are the minimum response groups required for the
//library scanner to pass all validation and filtering.
LibraryResponseGroups =
LibraryOptions.ResponseGroupOptions.ProductAttrs |
LibraryOptions.ResponseGroupOptions.ProductDesc |
LibraryOptions.ResponseGroupOptions.Relationships;
if (accounts is null || accounts.Length == 0)
return new List<LibraryBook>();
try
{
logTime($"pre {nameof(scanAccountsAsync)} all");
var libraryItems = await scanAccountsAsync(apiExtendedfunc, accounts);
logTime($"post {nameof(scanAccountsAsync)} all");
var totalCount = libraryItems.Count;
Log.Logger.Information($"GetAllLibraryItems: Total count {totalCount}");
var missingBookList = existingLibrary.Where(b => !libraryItems.Any(i => i.DtoItem.Asin == b.Book.AudibleProductId)).ToList();
return missingBookList;
}
catch (AudibleApi.Authentication.LoginFailedException lfEx)
{
lfEx.SaveFiles(FileManager.Configuration.Instance.LibationFiles);
// nuget Serilog.Exceptions would automatically log custom properties
// However, it comes with a scary warning when used with EntityFrameworkCore which I'm not yet ready to implement:
// https://github.com/RehanSaeed/Serilog.Exceptions
// work-around: use 3rd param. don't just put exception object in 3rd param -- info overload: stack trace, etc
Log.Logger.Error(lfEx, "Error scanning library. Login failed. {@DebugInfo}", new
{
lfEx.RequestUrl,
ResponseStatusCodeNumber = (int)lfEx.ResponseStatusCode,
ResponseStatusCodeDesc = lfEx.ResponseStatusCode,
lfEx.ResponseInputFields,
lfEx.ResponseBodyFilePaths
});
throw;
}
catch (Exception ex)
{
Log.Logger.Error(ex, "Error scanning library");
throw;
}
finally
{
LibraryResponseGroups = LibraryOptions.ResponseGroupOptions.ALL_OPTIONS;
stop();
var putBreakPointHere = logOutput;
}
}
#region FULL LIBRARY scan and import
public static async Task<(int totalCount, int newCount)> ImportAccountAsync(Func<Account, Task<ApiExtended>> apiExtendedfunc, params Account[] accounts)
{
logRestart();
if (accounts is null || accounts.Length == 0)
return (0, 0);
try
{
logTime($"pre {nameof(scanAccountsAsync)} all");
var importItems = await scanAccountsAsync(apiExtendedfunc, accounts);
logTime($"post {nameof(scanAccountsAsync)} all");
var totalCount = importItems.Count;
Log.Logger.Information($"GetAllLibraryItems: Total count {totalCount}");
Log.Logger.Information("Begin long-running import");
logTime($"pre {nameof(importIntoDbAsync)}");
var newCount = await importIntoDbAsync(importItems);
logTime($"post {nameof(importIntoDbAsync)}");
Log.Logger.Information($"Import complete. New count {newCount}");
return (totalCount, newCount);
}
catch (AudibleApi.Authentication.LoginFailedException lfEx)
{
lfEx.SaveFiles(FileManager.Configuration.Instance.LibationFiles);
// nuget Serilog.Exceptions would automatically log custom properties
// However, it comes with a scary warning when used with EntityFrameworkCore which I'm not yet ready to implement:
// https://github.com/RehanSaeed/Serilog.Exceptions
// work-around: use 3rd param. don't just put exception object in 3rd param -- info overload: stack trace, etc
Log.Logger.Error(lfEx, "Error importing library. Login failed. {@DebugInfo}", new
{
lfEx.RequestUrl,
ResponseStatusCodeNumber = (int)lfEx.ResponseStatusCode,
ResponseStatusCodeDesc = lfEx.ResponseStatusCode,
lfEx.ResponseInputFields,
lfEx.ResponseBodyFilePaths
});
throw;
}
catch (Exception ex)
{
Log.Logger.Error(ex, "Error importing library");
throw;
}
finally
{
stop();
var putBreakPointHere = logOutput;
}
}
private static async Task<List<ImportItem>> scanAccountsAsync(Func<Account, Task<ApiExtended>> apiExtendedfunc, Account[] accounts)
{
var tasks = new List<Task<List<ImportItem>>>();
foreach (var account in accounts)
{
// get APIs in serial b/c of logins. do NOT move inside of parallel (Task.WhenAll)
var apiExtended = await apiExtendedfunc(account);
// add scanAccountAsync as a TASK: do not await
tasks.Add(scanAccountAsync(apiExtended, account));
}
// import library in parallel
var arrayOfLists = await Task.WhenAll(tasks);
var importItems = arrayOfLists.SelectMany(a => a).ToList();
return importItems;
}
private static async Task<List<ImportItem>> scanAccountAsync(ApiExtended apiExtended, Account account)
{
ArgumentValidator.EnsureNotNull(account, nameof(account));
Log.Logger.Information("ImportLibraryAsync. {@DebugInfo}", new
{
Account = account?.MaskedLogEntry ?? "[null]"
});
logTime($"pre scanAccountAsync {account.AccountName}");
var dtoItems = await apiExtended.GetLibraryValidatedAsync(LibraryResponseGroups);
logTime($"post scanAccountAsync {account.AccountName} qty: {dtoItems.Count}");
return dtoItems.Select(d => new ImportItem { DtoItem = d, AccountId = account.AccountId, LocaleName = account.Locale?.Name }).ToList();
}
private static async Task<int> importIntoDbAsync(List<ImportItem> importItems)
{
logTime("importIntoDbAsync -- pre db");
using var context = DbContexts.GetContext();
var libraryImporter = new LibraryBookImporter(context);
var newCount = await Task.Run(() => libraryImporter.Import(importItems));
logTime("importIntoDbAsync -- post Import()");
var qtyChanges = context.SaveChanges();
logTime("importIntoDbAsync -- post SaveChanges");
if (qtyChanges > 0)
await Task.Run(() => finalizeLibrarySizeChange());
logTime("importIntoDbAsync -- post finalizeLibrarySizeChange");
return newCount;
}
#endregion
#region remove books
public static Task<List<LibraryBook>> RemoveBooksAsync(List<string> idsToRemove) => Task.Run(() => removeBooks(idsToRemove));
private static List<LibraryBook> removeBooks(List<string> idsToRemove)
{
using var context = DbContexts.GetContext();
var libBooks = context.GetLibrary_Flat_NoTracking();
var removeLibraryBooks = libBooks.Where(lb => idsToRemove.Contains(lb.Book.AudibleProductId)).ToList();
context.LibraryBooks.RemoveRange(removeLibraryBooks);
var qtyChanges = context.SaveChanges();
if (qtyChanges > 0)
finalizeLibrarySizeChange();
return removeLibraryBooks;
}
#endregion
// call this whenever books are added or removed from library
private static void finalizeLibrarySizeChange()
{
SearchEngineCommands.FullReIndex();
LibrarySizeChanged?.Invoke(null, null);
}
/// <summary>Occurs when books are added or removed from library</summary>
public static event EventHandler LibrarySizeChanged;
/// <summary>
/// Occurs when <see cref="UserDefinedItem.Tags"/>, <see cref="UserDefinedItem.BookStatus"/>, or <see cref="UserDefinedItem.PdfStatus"/>
/// changed values are successfully persisted.
/// </summary>
public static event EventHandler<string> BookUserDefinedItemCommitted;
#region Update book details
public static int UpdateUserDefinedItem(Book book)
{
try
{
using var context = DbContexts.GetContext();
// Attach() NoTracking entities before SaveChanges()
context.Attach(book.UserDefinedItem).State = Microsoft.EntityFrameworkCore.EntityState.Modified;
var qtyChanges = context.SaveChanges();
if (qtyChanges > 0)
{
SearchEngineCommands.UpdateLiberatedStatus(book);
BookUserDefinedItemCommitted?.Invoke(null, book.AudibleProductId);
}
return qtyChanges;
}
catch (Exception ex)
{
Log.Logger.Error(ex, $"Error updating {nameof(book.UserDefinedItem)}");
throw;
}
}
#endregion
// must be here instead of in db layer due to AaxcExists
public static LiberatedStatus Liberated_Status(Book book)
=> book.Audio_Exists ? book.UserDefinedItem.BookStatus
: FileManager.AudibleFileStorage.AaxcExists(book.AudibleProductId) ? LiberatedStatus.PartialDownload
: LiberatedStatus.NotLiberated;
// exists here for feature predictability. It makes sense for this to be where Liberated_Status is
public static LiberatedStatus? Pdf_Status(Book book) => book.UserDefinedItem.PdfStatus;
// below are queries, not commands. maybe I should make a LibraryQueries. except there's already one of those...
public record LibraryStats(int booksFullyBackedUp, int booksDownloadedOnly, int booksNoProgress, int booksError, int pdfsDownloaded, int pdfsNotDownloaded) { }
public static LibraryStats GetCounts()
{
var libraryBooks = DbContexts.GetLibrary_Flat_NoTracking();
var results = libraryBooks
.AsParallel()
.Select(lb => Liberated_Status(lb.Book))
.ToList();
var booksFullyBackedUp = results.Count(r => r == LiberatedStatus.Liberated);
var booksDownloadedOnly = results.Count(r => r == LiberatedStatus.PartialDownload);
var booksNoProgress = results.Count(r => r == LiberatedStatus.NotLiberated);
var booksError = results.Count(r => r == LiberatedStatus.Error);
Log.Logger.Information("Book counts. {@DebugInfo}", new { total = results.Count, booksFullyBackedUp, booksDownloadedOnly, booksNoProgress, booksError });
var boolResults = libraryBooks
.AsParallel()
.Where(lb => lb.Book.HasPdf)
.Select(lb => Pdf_Status(lb.Book))
.ToList();
var pdfsDownloaded = boolResults.Count(r => r == LiberatedStatus.Liberated);
var pdfsNotDownloaded = boolResults.Count(r => r == LiberatedStatus.NotLiberated);
Log.Logger.Information("PDF counts. {@DebugInfo}", new { total = boolResults.Count, pdfsDownloaded, pdfsNotDownloaded });
return new(booksFullyBackedUp, booksDownloadedOnly, booksNoProgress, booksError, pdfsDownloaded, pdfsNotDownloaded);
}
}
}
-281
View File
@@ -1,281 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using CsvHelper;
using CsvHelper.Configuration.Attributes;
using DataLayer;
using NPOI.XSSF.UserModel;
using Serilog;
namespace ApplicationServices
{
public class ExportDto
{
public static string GetName(string fieldName)
{
var property = typeof(ExportDto).GetProperty(fieldName);
var attribute = property.GetCustomAttributes(typeof(NameAttribute), true)[0];
var description = (NameAttribute)attribute;
var text = description.Names;
return text[0];
}
[Name("Account")]
public string Account { get; set; }
[Name("Date Added to library")]
public DateTime DateAdded { get; set; }
[Name("Audible Product Id")]
public string AudibleProductId { get; set; }
[Name("Locale")]
public string Locale { get; set; }
[Name("Title")]
public string Title { get; set; }
[Name("Authors")]
public string AuthorNames { get; set; }
[Name("Narrators")]
public string NarratorNames { get; set; }
[Name("Length In Minutes")]
public int LengthInMinutes { get; set; }
[Name("Publisher")]
public string Publisher { get; set; }
[Name("Has PDF")]
public bool HasPdf { get; set; }
[Name("Series Names")]
public string SeriesNames { get; set; }
[Name("Series Order")]
public string SeriesOrder { get; set; }
[Name("Community Rating: Overall")]
public float? CommunityRatingOverall { get; set; }
[Name("Community Rating: Performance")]
public float? CommunityRatingPerformance { get; set; }
[Name("Community Rating: Story")]
public float? CommunityRatingStory { get; set; }
[Name("Cover Id")]
public string PictureId { get; set; }
[Name("Is Abridged?")]
public bool IsAbridged { get; set; }
[Name("Date Published")]
public DateTime? DatePublished { get; set; }
[Name("Categories")]
public string CategoriesNames { get; set; }
[Name("My Rating: Overall")]
public float? MyRatingOverall { get; set; }
[Name("My Rating: Performance")]
public float? MyRatingPerformance { get; set; }
[Name("My Rating: Story")]
public float? MyRatingStory { get; set; }
[Name("My Libation Tags")]
public string MyLibationTags { get; set; }
[Name("Book Liberated Status")]
public string BookStatus { get; set; }
[Name("PDF Liberated Status")]
public string PdfStatus { get; set; }
[Name("Content Type")]
public string ContentType { get; set; }
}
public static class LibToDtos
{
public static List<ExportDto> ToDtos(this IEnumerable<LibraryBook> library)
=> library.Select(a => new ExportDto
{
Account = a.Account,
DateAdded = a.DateAdded,
AudibleProductId = a.Book.AudibleProductId,
Locale = a.Book.Locale,
Title = a.Book.Title,
AuthorNames = a.Book.AuthorNames,
NarratorNames = a.Book.NarratorNames,
LengthInMinutes = a.Book.LengthInMinutes,
Publisher = a.Book.Publisher,
HasPdf = a.Book.HasPdf,
SeriesNames = a.Book.SeriesNames,
SeriesOrder = a.Book.SeriesLink.Any() ? a.Book.SeriesLink?.Select(sl => $"{sl.Index} : {sl.Series.Name}").Aggregate((a, b) => $"{a}, {b}") : "",
CommunityRatingOverall = a.Book.Rating?.OverallRating,
CommunityRatingPerformance = a.Book.Rating?.PerformanceRating,
CommunityRatingStory = a.Book.Rating?.StoryRating,
PictureId = a.Book.PictureId,
IsAbridged = a.Book.IsAbridged,
DatePublished = a.Book.DatePublished,
CategoriesNames = a.Book.CategoriesNames.Any() ? a.Book.CategoriesNames.Aggregate((a, b) => $"{a}, {b}") : "",
MyRatingOverall = a.Book.UserDefinedItem.Rating.OverallRating,
MyRatingPerformance = a.Book.UserDefinedItem.Rating.PerformanceRating,
MyRatingStory = a.Book.UserDefinedItem.Rating.StoryRating,
MyLibationTags = a.Book.UserDefinedItem.Tags,
BookStatus = a.Book.UserDefinedItem.BookStatus.ToString(),
PdfStatus = a.Book.UserDefinedItem.PdfStatus.ToString(),
ContentType = a.Book.ContentType.ToString()
}).ToList();
}
public static class LibraryExporter
{
public static void ToCsv(string saveFilePath)
{
var dtos = DbContexts.GetLibrary_Flat_NoTracking().ToDtos();
if (!dtos.Any())
return;
using var writer = new System.IO.StreamWriter(saveFilePath);
using var csv = new CsvWriter(writer, System.Globalization.CultureInfo.CurrentCulture);
csv.WriteHeader(typeof(ExportDto));
csv.NextRecord();
csv.WriteRecords(dtos);
}
public static void ToJson(string saveFilePath)
{
var dtos = DbContexts.GetLibrary_Flat_NoTracking().ToDtos();
var json = Newtonsoft.Json.JsonConvert.SerializeObject(dtos, Newtonsoft.Json.Formatting.Indented);
System.IO.File.WriteAllText(saveFilePath, json);
}
public static void ToXlsx(string saveFilePath)
{
var dtos = DbContexts.GetLibrary_Flat_NoTracking().ToDtos();
var workbook = new XSSFWorkbook();
var sheet = workbook.CreateSheet("Library");
var detailSubtotalFont = workbook.CreateFont();
detailSubtotalFont.IsBold = true;
var detailSubtotalCellStyle = workbook.CreateCellStyle();
detailSubtotalCellStyle.SetFont(detailSubtotalFont);
// headers
var rowIndex = 0;
var row = sheet.CreateRow(rowIndex);
var columns = new[] {
nameof (ExportDto.Account),
nameof (ExportDto.DateAdded),
nameof (ExportDto.AudibleProductId),
nameof (ExportDto.Locale),
nameof (ExportDto.Title),
nameof (ExportDto.AuthorNames),
nameof (ExportDto.NarratorNames),
nameof (ExportDto.LengthInMinutes),
nameof (ExportDto.Publisher),
nameof (ExportDto.HasPdf),
nameof (ExportDto.SeriesNames),
nameof (ExportDto.SeriesOrder),
nameof (ExportDto.CommunityRatingOverall),
nameof (ExportDto.CommunityRatingPerformance),
nameof (ExportDto.CommunityRatingStory),
nameof (ExportDto.PictureId),
nameof (ExportDto.IsAbridged),
nameof (ExportDto.DatePublished),
nameof (ExportDto.CategoriesNames),
nameof (ExportDto.MyRatingOverall),
nameof (ExportDto.MyRatingPerformance),
nameof (ExportDto.MyRatingStory),
nameof (ExportDto.MyLibationTags),
nameof (ExportDto.BookStatus),
nameof (ExportDto.PdfStatus),
nameof (ExportDto.ContentType)
};
var col = 0;
foreach (var c in columns)
{
var cell = row.CreateCell(col++);
var name = ExportDto.GetName(c);
cell.SetCellValue(name);
cell.CellStyle = detailSubtotalCellStyle;
}
var dateFormat = workbook.CreateDataFormat();
var dateStyle = workbook.CreateCellStyle();
dateStyle.DataFormat = dateFormat.GetFormat("MM/dd/yyyy HH:mm:ss");
rowIndex++;
// Add data rows
foreach (var dto in dtos)
{
col = 0;
row = sheet.CreateRow(rowIndex);
row.CreateCell(col++).SetCellValue(dto.Account);
var dateAddedCell = row.CreateCell(col++);
dateAddedCell.CellStyle = dateStyle;
dateAddedCell.SetCellValue(dto.DateAdded);
row.CreateCell(col++).SetCellValue(dto.AudibleProductId);
row.CreateCell(col++).SetCellValue(dto.Locale);
row.CreateCell(col++).SetCellValue(dto.Title);
row.CreateCell(col++).SetCellValue(dto.AuthorNames);
row.CreateCell(col++).SetCellValue(dto.NarratorNames);
row.CreateCell(col++).SetCellValue(dto.LengthInMinutes);
row.CreateCell(col++).SetCellValue(dto.Publisher);
row.CreateCell(col++).SetCellValue(dto.HasPdf);
row.CreateCell(col++).SetCellValue(dto.SeriesNames);
row.CreateCell(col++).SetCellValue(dto.SeriesOrder);
col = createCell(row, col, dto.CommunityRatingOverall);
col = createCell(row, col, dto.CommunityRatingPerformance);
col = createCell(row, col, dto.CommunityRatingStory);
row.CreateCell(col++).SetCellValue(dto.PictureId);
row.CreateCell(col++).SetCellValue(dto.IsAbridged);
var datePubCell = row.CreateCell(col++);
datePubCell.CellStyle = dateStyle;
if (dto.DatePublished.HasValue)
datePubCell.SetCellValue(dto.DatePublished.Value);
else
datePubCell.SetCellValue("");
row.CreateCell(col++).SetCellValue(dto.CategoriesNames);
col = createCell(row, col, dto.MyRatingOverall);
col = createCell(row, col, dto.MyRatingPerformance);
col = createCell(row, col, dto.MyRatingStory);
row.CreateCell(col++).SetCellValue(dto.MyLibationTags);
row.CreateCell(col++).SetCellValue(dto.BookStatus);
row.CreateCell(col++).SetCellValue(dto.PdfStatus);
row.CreateCell(col++).SetCellValue(dto.ContentType);
rowIndex++;
}
using var fileData = new System.IO.FileStream(saveFilePath, System.IO.FileMode.Create);
workbook.Write(fileData);
}
private static int createCell(NPOI.SS.UserModel.IRow row, int col, float? nullableFloat)
{
if (nullableFloat.HasValue)
row.CreateCell(col++).SetCellValue(nullableFloat.Value);
else
row.CreateCell(col++).SetCellValue("");
return col;
}
}
}
@@ -1,57 +0,0 @@
using System;
using System.IO;
using DataLayer;
using LibationSearchEngine;
namespace ApplicationServices
{
public static class SearchEngineCommands
{
public static void FullReIndex(SearchEngine engine = null)
{
engine ??= new SearchEngine();
var library = DbContexts.GetLibrary_Flat_NoTracking();
engine.CreateNewIndex(library);
}
public static SearchResultSet Search(string searchString) => performSearchEngineFunc_safe(e =>
e.Search(searchString)
);
public static void UpdateBookTags(Book book) => performSearchEngineAction_safe(e =>
e.UpdateTags(book.AudibleProductId, book.UserDefinedItem.Tags)
);
public static void UpdateLiberatedStatus(Book book) => performSearchEngineAction_safe(e =>
e.UpdateLiberatedStatus(book)
);
private static void performSearchEngineAction_safe(Action<SearchEngine> action)
{
var engine = new SearchEngine();
try
{
action(engine);
}
catch (FileNotFoundException)
{
FullReIndex(engine);
action(engine);
}
}
private static T performSearchEngineFunc_safe<T>(Func<SearchEngine, T> func)
{
var engine = new SearchEngine();
try
{
return func(engine);
}
catch (FileNotFoundException)
{
FullReIndex(engine);
return func(engine);
}
}
}
}
-71
View File
@@ -1,71 +0,0 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace DataLayer.Configurations
{
internal class BookConfig : IEntityTypeConfiguration<Book>
{
public void Configure(EntityTypeBuilder<Book> entity)
{
entity.HasKey(b => b.BookId);
entity.HasIndex(b => b.AudibleProductId);
entity.OwnsOne(b => b.Rating);
//
// CRUCIAL: ignore unmapped collections, even get-only
//
entity.Ignore(nameof(Book.Authors));
entity.Ignore(nameof(Book.Narrators));
//// these don't seem to matter
//entity.Ignore(nameof(Book.AuthorNames));
//entity.Ignore(nameof(Book.NarratorNames));
//entity.Ignore(nameof(Book.HasPdfs));
// OwnsMany: "Can only ever appear on navigation properties of other entity types.
// Are automatically loaded, and can only be tracked by a DbContext alongside their owner."
entity
.OwnsMany(b => b.Supplements, b_s =>
{
b_s.WithOwner(s => s.Book)
.HasForeignKey(s => s.BookId);
b_s.HasKey(s => s.SupplementId);
});
// even though it's owned, we need to map its backing field
entity
.Metadata
.FindNavigation(nameof(Book.Supplements))
.SetPropertyAccessMode(PropertyAccessMode.Field);
// owns it 1:1, store in separate table
entity
.OwnsOne(b => b.UserDefinedItem, b_udi =>
{
b_udi.WithOwner(udi => udi.Book)
.HasForeignKey(udi => udi.BookId);
b_udi.Property(udi => udi.BookId).ValueGeneratedNever();
b_udi.ToTable(nameof(Book.UserDefinedItem));
// owns it 1:1, store in same table
b_udi.OwnsOne(udi => udi.Rating);
});
entity
.Metadata
.FindNavigation(nameof(Book.ContributorsLink))
// PropertyAccessMode.Field : Contributions is a get-only property, not a field, so use its backing field
.SetPropertyAccessMode(PropertyAccessMode.Field);
entity
.Metadata
.FindNavigation(nameof(Book.SeriesLink))
// PropertyAccessMode.Field : Series is a get-only property, not a field, so use its backing field
.SetPropertyAccessMode(PropertyAccessMode.Field);
entity
.HasOne(b => b.Category)
.WithMany()
.HasForeignKey(b => b.CategoryId);
}
}
}
@@ -1,25 +0,0 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace DataLayer.Configurations
{
internal class BookContributorConfig : IEntityTypeConfiguration<BookContributor>
{
public void Configure(EntityTypeBuilder<BookContributor> entity)
{
entity.HasKey(bc => new { bc.BookId, bc.ContributorId, bc.Role });
entity.HasIndex(b => b.BookId);
entity.HasIndex(b => b.ContributorId);
entity
.HasOne(bc => bc.Book)
.WithMany(b => b.ContributorsLink)
.HasForeignKey(bc => bc.BookId);
entity
.HasOne(bc => bc.Contributor)
.WithMany(c => c.BooksLink)
.HasForeignKey(bc => bc.ContributorId);
}
}
}
@@ -1,14 +0,0 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace DataLayer.Configurations
{
internal class CategoryConfig : IEntityTypeConfiguration<Category>
{
public void Configure(EntityTypeBuilder<Category> entity)
{
entity.HasKey(c => c.CategoryId);
entity.HasIndex(c => c.AudibleCategoryId);
}
}
}
@@ -1,22 +0,0 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace DataLayer.Configurations
{
internal class ContributorConfig : IEntityTypeConfiguration<Contributor>
{
public void Configure(EntityTypeBuilder<Contributor> entity)
{
entity.HasKey(c => c.ContributorId);
entity.HasIndex(c => c.Name);
//entity.OwnsOne(b => b.AuthorProperty);
// ... in separate table
entity
.Metadata
.FindNavigation(nameof(Contributor.BooksLink))
.SetPropertyAccessMode(PropertyAccessMode.Field);
}
}
}
@@ -1,32 +0,0 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace DataLayer.Configurations
{
internal class LibraryBookConfig : IEntityTypeConfiguration<LibraryBook>
{
public void Configure(EntityTypeBuilder<LibraryBook> entity)
{
// to allow same book (incl region) with diff acct.s:
//
// this file:
// - composite key:
// entity.HasKey(b => new { b.BookId, b.Account });
// entity.HasIndex(b => b.BookId);
// entity.HasIndex(b => b.Account);
// - change the below relationship since Book+LibraryBook would no longer be 1:1
//
// other files:
// - change Book class since Book+LibraryBook would no longer be 1:1
// - update LibraryBook import code
// - would likely challenge assumptions throughout Libation which have been true up until now
entity.HasKey(b => b.BookId);
entity
.HasOne(le => le.Book)
.WithOne()
.HasForeignKey<LibraryBook>(le => le.BookId);
}
}
}
@@ -1,25 +0,0 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace DataLayer.Configurations
{
internal class SeriesBookConfig : IEntityTypeConfiguration<SeriesBook>
{
public void Configure(EntityTypeBuilder<SeriesBook> entity)
{
entity.HasKey(bc => new { bc.SeriesId, bc.BookId });
entity.HasIndex(b => b.SeriesId);
entity.HasIndex(b => b.BookId);
entity
.HasOne(sb => sb.Series)
.WithMany(s => s.BooksLink)
.HasForeignKey(sb => sb.SeriesId);
entity
.HasOne(sb => sb.Book)
.WithMany(b => b.SeriesLink)
.HasForeignKey(sb => sb.BookId);
}
}
}
-19
View File
@@ -1,19 +0,0 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace DataLayer.Configurations
{
internal class SeriesConfig : IEntityTypeConfiguration<Series>
{
public void Configure(EntityTypeBuilder<Series> entity)
{
entity.HasKey(b => b.SeriesId);
entity.HasIndex(b => b.AudibleSeriesId);
entity
.Metadata
.FindNavigation(nameof(Series.BooksLink))
.SetPropertyAccessMode(PropertyAccessMode.Field);
}
}
}
-264
View File
@@ -1,264 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Dinah.Core;
using Microsoft.EntityFrameworkCore;
namespace DataLayer
{
public class AudibleProductId
{
public string Id { get; }
public AudibleProductId(string id)
{
ArgumentValidator.EnsureNotNullOrWhiteSpace(id, nameof(id));
Id = id;
}
}
// enum will be easier than bool to extend later
public enum ContentType { Unknown = 0, Product = 1, Episode = 2 }
public class Book
{
// implementation detail. set by db only. only used by data layer
internal int BookId { get; private set; }
// immutable
public string AudibleProductId { get; private set; }
public string Title { get; private set; }
public string Description { get; private set; }
public int LengthInMinutes { get; private set; }
public ContentType ContentType { get; private set; }
public string Locale { get; private set; }
// mutable
public string PictureId { get; set; }
// book details
public bool IsAbridged { get; private set; }
public DateTime? DatePublished { get; private set; }
// non-null. use "empty pattern"
internal int CategoryId { get; private set; }
public Category Category { get; private set; }
public string[] CategoriesNames
=> Category == null ? new string[0]
: Category.ParentCategory == null ? new[] { Category.Name }
: new[] { Category.ParentCategory.Name, Category.Name };
public string[] CategoriesIds
=> Category == null ? null
: Category.ParentCategory == null ? new[] { Category.AudibleCategoryId }
: new[] { Category.ParentCategory.AudibleCategoryId, Category.AudibleCategoryId };
// is owned, not optional 1:1
public UserDefinedItem UserDefinedItem { get; private set; }
// UserDefinedItem convenience properties
/// <summary>True if IsLiberated or Error. False if NotLiberated</summary>
public bool Audio_Exists => UserDefinedItem.BookStatus != LiberatedStatus.NotLiberated;
/// <summary>True if exists and IsLiberated. Else false</summary>
public bool PDF_Exists => UserDefinedItem.PdfStatus == LiberatedStatus.Liberated;
// is owned, not optional 1:1
/// <summary>The product's aggregate community rating</summary>
public Rating Rating { get; private set; } = new Rating(0, 0, 0);
// ef-ctor
private Book() { }
// non-ef ctor
/// <param name="audibleProductId">special id class b/c it's too easy to get string order mixed up</param>
public Book(
AudibleProductId audibleProductId,
string title,
string description,
int lengthInMinutes,
ContentType contentType,
IEnumerable<Contributor> authors,
IEnumerable<Contributor> narrators,
Category category,
string localeName)
{
// validate
ArgumentValidator.EnsureNotNull(audibleProductId, nameof(audibleProductId));
var productId = audibleProductId.Id;
ArgumentValidator.EnsureNotNullOrWhiteSpace(productId, nameof(productId));
// assign as soon as possible. stuff below relies on this
AudibleProductId = productId;
Locale = localeName;
ArgumentValidator.EnsureNotNullOrWhiteSpace(title, nameof(title));
// non-ef-ctor init.s
UserDefinedItem = new UserDefinedItem(this);
_contributorsLink = new HashSet<BookContributor>();
_seriesLink = new HashSet<SeriesBook>();
_supplements = new HashSet<Supplement>();
Category = category;
// simple assigns
Title = title.Trim();
Description = description?.Trim();
LengthInMinutes = lengthInMinutes;
ContentType = contentType;
// assigns with biz logic
ReplaceAuthors(authors);
ReplaceNarrators(narrators);
}
#region contributors, authors, narrators
// use uninitialised backing fields - this means we can detect if the collection was loaded
private HashSet<BookContributor> _contributorsLink;
// i'd like this to be internal but migration throws this exception when i try:
// Value cannot be null.
// Parameter name: property
public IEnumerable<BookContributor> ContributorsLink
=> _contributorsLink?
.OrderBy(bc => bc.Order)
.ToList();
public IEnumerable<Contributor> Authors => getContributions(Role.Author).Select(bc => bc.Contributor).ToList();
public string AuthorNames => string.Join(", ", Authors.Select(a => a.Name));
public IEnumerable<Contributor> Narrators => getContributions(Role.Narrator).Select(bc => bc.Contributor).ToList();
public string NarratorNames => string.Join(", ", Narrators.Select(n => n.Name));
public string Publisher => getContributions(Role.Publisher).SingleOrDefault()?.Contributor.Name;
public void ReplaceAuthors(IEnumerable<Contributor> authors, DbContext context = null)
=> replaceContributors(authors, Role.Author, context);
public void ReplaceNarrators(IEnumerable<Contributor> narrators, DbContext context = null)
=> replaceContributors(narrators, Role.Narrator, context);
public void ReplacePublisher(Contributor publisher, DbContext context = null)
=> replaceContributors(new List<Contributor> { publisher }, Role.Publisher, context);
private void replaceContributors(IEnumerable<Contributor> newContributors, Role role, DbContext context = null)
{
ArgumentValidator.EnsureEnumerableNotNullOrEmpty(newContributors, nameof(newContributors));
// the edge cases of doing local-loaded vs remote-only got weird. just load it
if (_contributorsLink is null)
getEntry(context).Collection(s => s.ContributorsLink).Load();
var roleContributions = getContributions(role);
var isIdentical = roleContributions.Select(c => c.Contributor).SequenceEqual(newContributors);
if (isIdentical)
return;
_contributorsLink.RemoveWhere(bc => bc.Role == role);
addNewContributors(newContributors, role);
}
private void addNewContributors(IEnumerable<Contributor> newContributors, Role role)
{
byte order = 0;
var newContributionsEnum = newContributors.Select(c => new BookContributor(this, c, role, order++));
var newContributions = new HashSet<BookContributor>(newContributionsEnum);
_contributorsLink.UnionWith(newContributions);
}
private List<BookContributor> getContributions(Role role)
=> ContributorsLink
.Where(a => a.Role == role)
.OrderBy(a => a.Order)
.ToList();
#endregion
private Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry<Book> getEntry(DbContext context)
{
ArgumentValidator.EnsureNotNull(context, nameof(context));
var entry = context.Entry(this);
if (!entry.IsKeySet)
throw new InvalidOperationException("Could not load a valid Book from database");
return entry;
}
#region series
private HashSet<SeriesBook> _seriesLink;
public IEnumerable<SeriesBook> SeriesLink => _seriesLink?.ToList();
public string SeriesNames
{
get
{
// first: alphabetical by name
var withNames = _seriesLink
.Where(s => !string.IsNullOrWhiteSpace(s.Series.Name))
.Select(s => s.Series.Name)
.OrderBy(a => a)
.ToList();
// then un-named are alpha by series id
var nullNames = _seriesLink
.Where(s => string.IsNullOrWhiteSpace(s.Series.Name))
.Select(s => s.Series.AudibleSeriesId)
.OrderBy(a => a)
.ToList();
var all = withNames.Union(nullNames).ToList();
return string.Join(", ", all);
}
}
public void UpsertSeries(Series series, float? index = null, DbContext context = null)
{
ArgumentValidator.EnsureNotNull(series, nameof(series));
// our add() is conditional upon what's already included in the collection.
// therefore if not loaded, a trip is required. might as well just load it
if (_seriesLink is null)
getEntry(context).Collection(s => s.SeriesLink).Load();
var singleSeriesBook = _seriesLink.SingleOrDefault(sb => sb.Series == series);
if (singleSeriesBook == null)
_seriesLink.Add(new SeriesBook(series, this, index));
else
singleSeriesBook.UpdateIndex(index);
}
#endregion
#region supplements
private HashSet<Supplement> _supplements;
public IEnumerable<Supplement> Supplements => _supplements?.ToList();
public bool HasPdf => Supplements.Any();
public void AddSupplementDownloadUrl(string url)
{
// supplements are owned by Book, so no need to Load():
// Are automatically loaded, and can only be tracked by a DbContext alongside their owner.
ArgumentValidator.EnsureNotNullOrWhiteSpace(url, nameof(url));
if (_supplements.Any(s => url.EqualsInsensitive(url)))
return;
_supplements.Add(new Supplement(this, url));
UserDefinedItem.PdfStatus ??= LiberatedStatus.NotLiberated;
}
#endregion
public void UpdateProductRating(float overallRating, float performanceRating, float storyRating)
=> Rating.Update(overallRating, performanceRating, storyRating);
public void UpdateBookDetails(bool isAbridged, DateTime? datePublished)
{
// don't overwrite with default values
IsAbridged |= isAbridged;
DatePublished = datePublished ?? DatePublished;
}
public void UpdateCategory(Category category, DbContext context = null)
{
// since category is never null, nullity means it hasn't been loaded
if (Category is null)
getEntry(context).Reference(s => s.Category).Load();
Category = category;
}
public override string ToString() => $"[{AudibleProductId}] {Title}";
}
}
-31
View File
@@ -1,31 +0,0 @@
using Dinah.Core;
namespace DataLayer
{
public enum Role { Author = 1, Narrator = 2, Publisher = 3 }
public class BookContributor
{
internal int BookId { get; private set; }
internal int ContributorId { get; private set; }
public Role Role { get; private set; }
public byte Order { get; private set; }
public Book Book { get; private set; }
public Contributor Contributor { get; private set; }
private BookContributor() { }
internal BookContributor(Book book, Contributor contributor, Role role, byte order)
{
ArgumentValidator.EnsureNotNull(book, nameof(book));
ArgumentValidator.EnsureNotNull(contributor, nameof(contributor));
Book = book;
Contributor = contributor;
Role = role;
Order = order;
}
public override string ToString() => $"{Book} {Contributor} {Role} {Order}";
}
}
-53
View File
@@ -1,53 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Dinah.Core;
using Microsoft.EntityFrameworkCore;
namespace DataLayer
{
public class AudibleCategoryId
{
public string Id { get; }
public AudibleCategoryId(string id)
{
ArgumentValidator.EnsureNotNullOrWhiteSpace(id, nameof(id));
Id = id;
}
}
public class Category
{
// Empty is a special case. use private ctor w/o validation
public static Category GetEmpty() => new Category { CategoryId = -1, AudibleCategoryId = "", Name = "" };
internal int CategoryId { get; private set; }
public string AudibleCategoryId { get; private set; }
public string Name { get; private set; }
public Category ParentCategory { get; private set; }
private Category() { }
/// <summary>special id class b/c it's too easy to get string order mixed up</summary>
public Category(AudibleCategoryId audibleSeriesId, string name, Category parentCategory = null)
{
ArgumentValidator.EnsureNotNull(audibleSeriesId, nameof(audibleSeriesId));
var id = audibleSeriesId.Id;
ArgumentValidator.EnsureNotNullOrWhiteSpace(id, nameof(id));
ArgumentValidator.EnsureNotNullOrWhiteSpace(name, nameof(name));
AudibleCategoryId = id;
Name = name;
UpdateParentCategory(parentCategory);
}
public void UpdateParentCategory(Category parentCategory)
{
// don't overwrite with null but not an error
if (parentCategory != null)
ParentCategory = parentCategory;
}
public override string ToString() => $"[{AudibleCategoryId}] {Name}";
}
}
-51
View File
@@ -1,51 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using Dinah.Core;
namespace DataLayer
{
public class Contributor
{
// Empty is a special case. use private ctor w/o validation
public static Contributor GetEmpty() => new Contributor { ContributorId = -1, Name = "" };
// contributors search links are just name with url-encoding. space can be + or %20
// author search link: /search?searchAuthor=Robert+Bevan
// narrator search link: /search?searchNarrator=Robert+Bevan
// can also search multiples. concat with comma before url encode
// id.s
// ----
// https://www.audible.com/author/Neil-Gaiman/B000AQ01G2 == https://www.audible.com/author/B000AQ01G2
// goes to summary page
// at bottom "See all titles by Neil Gaiman" goes to https://www.audible.com/search?searchAuthor=Neil+Gaiman
// some authors have no id. simply goes to https://www.audible.com/search?searchAuthor=Rufus+Fears
// all narrators have no id: https://www.audible.com/search?searchNarrator=Neil+Gaiman
internal int ContributorId { get; private set; }
public string Name { get; private set; }
private HashSet<BookContributor> _booksLink;
public IEnumerable<BookContributor> BooksLink => _booksLink?.ToList();
public string AudibleContributorId { get; private set; }
private Contributor() { }
public Contributor(string name)
{
ArgumentValidator.EnsureNotNullOrWhiteSpace(name, nameof(name));
_booksLink = new HashSet<BookContributor>();
Name = name;
}
public Contributor(string name, string audibleContributorId) : this(name)
{
// don't overwrite with null or whitespace but not an error
if (!string.IsNullOrWhiteSpace(audibleContributorId))
AudibleContributorId = audibleContributorId;
}
public override string ToString() => Name;
}
}
-27
View File
@@ -1,27 +0,0 @@
using System;
using Dinah.Core;
namespace DataLayer
{
public class LibraryBook
{
internal int BookId { get; private set; }
public Book Book { get; private set; }
public DateTime DateAdded { get; private set; }
public string Account { get; private set; }
private LibraryBook() { }
public LibraryBook(Book book, DateTime dateAdded, string account)
{
ArgumentValidator.EnsureNotNull(book, nameof(book));
ArgumentValidator.EnsureNotNull(account, nameof(account));
Book = book;
DateAdded = dateAdded;
Account = account;
}
public override string ToString() => $"{DateAdded:d} {Book}";
}
}
-78
View File
@@ -1,78 +0,0 @@
using System;
using System.Collections.Generic;
using Dinah.Core;
namespace DataLayer
{
/// <summary>Parameterless ctor and setters should be used by EF only. Everything else should treat it as immutable</summary>
public class Rating : ValueObject_Static<Rating>
{
public float OverallRating { get; private set; }
public float PerformanceRating { get; private set; }
public float StoryRating { get; private set; }
private Rating() { }
internal Rating(float overallRating, float performanceRating, float storyRating)
{
OverallRating = overallRating;
PerformanceRating = performanceRating;
StoryRating = storyRating;
}
// EF magically tracks this owned object. by replacing it with a new() immutable object, stuff gets weird. update instead
internal void Update(float overallRating, float performanceRating, float storyRating)
{
// don't overwrite with all 0
if (overallRating + performanceRating + storyRating == 0)
return;
OverallRating = overallRating;
PerformanceRating = performanceRating;
StoryRating = storyRating;
}
protected override IEnumerable<object> GetEqualityComponents()
{
yield return OverallRating;
yield return PerformanceRating;
yield return StoryRating;
}
public float FirstScore
=> OverallRating > 0 ? OverallRating
: PerformanceRating > 0 ? PerformanceRating
: StoryRating;
/// <summary>character: ★</summary>
const char STAR = '\u2605';
/// <summary>character: ½</summary>
const char HALF = '\u00BD';
string getStars(float score)
{
var fullStars = (int)Math.Floor(score);
var starString = "".PadLeft(fullStars, STAR);
if (score - fullStars == 0.5f)
starString += HALF;
return starString;
}
public string ToStarString()
{
var items = new List<string>();
if (OverallRating > 0)
items.Add($"Overall: {getStars(OverallRating)}");
if (PerformanceRating > 0)
items.Add($"Perform: {getStars(PerformanceRating)}");
if (StoryRating > 0)
items.Add($"Story: {getStars(StoryRating)}");
return string.Join("\r\n", items);
}
public override string ToString() => $"Overall={OverallRating} Perf={PerformanceRating} Story={StoryRating}";
}
}
-72
View File
@@ -1,72 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Dinah.Core;
using Microsoft.EntityFrameworkCore;
namespace DataLayer
{
public class AudibleSeriesId
{
public string Id { get; }
public AudibleSeriesId(string id)
{
ArgumentValidator.EnsureNotNullOrWhiteSpace(id, nameof(id));
Id = id;
}
}
public class Series
{
internal int SeriesId { get; private set; }
public string AudibleSeriesId { get; private set; }
/// <summary>optional</summary>
public string Name { get; private set; }
private HashSet<SeriesBook> _booksLink;
public IEnumerable<SeriesBook> BooksLink
=> _booksLink?
.OrderBy(sb => sb.Index)
.ToList();
private Series() { }
/// <summary>special id class b/c it's too easy to get string order mixed up</summary>
public Series(AudibleSeriesId audibleSeriesId, string name = null)
{
ArgumentValidator.EnsureNotNull(audibleSeriesId, nameof(audibleSeriesId));
var id = audibleSeriesId.Id;
ArgumentValidator.EnsureNotNullOrWhiteSpace(id, nameof(id));
AudibleSeriesId = id;
_booksLink = new HashSet<SeriesBook>();
UpdateName(name);
}
public void UpdateName(string name)
{
// don't overwrite with null or whitespace but not an error
if (!string.IsNullOrWhiteSpace(name))
Name = name;
}
public void AddBook(Book book, float? index = null, DbContext context = null)
{
ArgumentValidator.EnsureNotNull(book, nameof(book));
// our add() is conditional upon what's already included in the collection.
// therefore if not loaded, a trip is required. might as well just load it
if (_booksLink == null)
{
ArgumentValidator.EnsureNotNull(context, nameof(context));
if (!context.Entry(this).IsKeySet)
throw new InvalidOperationException("Could not add series");
context.Entry(this).Collection(s => s.BooksLink).Load();
}
if (_booksLink.SingleOrDefault(sb => sb.Book == book) == null)
_booksLink.Add(new SeriesBook(this, book, index));
}
public override string ToString() => Name;
}
}
-40
View File
@@ -1,40 +0,0 @@
using Dinah.Core;
namespace DataLayer
{
public class SeriesBook
{
internal int SeriesId { get; private set; }
internal int BookId { get; private set; }
/// <summary>
/// <para>"index" not "order". This is both for sequence and display</para>
/// <para>Float allows for in-between books. eg: 2.5</para>
/// <para>To show 2 editions as the same book in a series, give them the same index</para>
/// <para>null IS NOT the same as 0. Some series call a book "book 0"</para>
/// </summary>
public float? Index { get; private set; }
public Series Series { get; private set; }
public Book Book { get; private set; }
private SeriesBook() { }
internal SeriesBook(Series series, Book book, float? index = null)
{
ArgumentValidator.EnsureNotNull(series, nameof(series));
ArgumentValidator.EnsureNotNull(book, nameof(book));
Series = series;
Book = book;
Index = index;
}
public void UpdateIndex(float? index)
{
if (index.HasValue)
Index = index.Value;
}
public override string ToString() => $"Series={Series} Book={Book}";
}
}
-26
View File
@@ -1,26 +0,0 @@
using Dinah.Core;
namespace DataLayer
{
/// <summary>PDF/ZIP files only. Although book download info could be the same format, they're substantially different and subject to change</summary>
public class Supplement
{
internal int SupplementId { get; private set; }
internal int BookId { get; private set; }
public Book Book { get; private set; }
public string Url { get; private set; }
private Supplement() { }
public Supplement(Book book, string url)
{
ArgumentValidator.EnsureNotNull(book, nameof(book));
ArgumentValidator.EnsureNotNullOrWhiteSpace(url, nameof(url));
Book = book;
Url = url;
}
public override string ToString() => $"{Book} {Url.Substring(Url.Length - 4)}";
}
}
-144
View File
@@ -1,144 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using Dinah.Core;
namespace DataLayer
{
/// <summary>
/// Do not track in-process state. In-process state is determined by the presence of temp file.
/// </summary>
public enum LiberatedStatus
{
NotLiberated = 0,
Liberated = 1,
/// <summary>Error occurred during liberation. Don't retry</summary>
Error = 2,
/// <summary>Application-state only. Not a valid persistence state.</summary>
PartialDownload = 0x1000
}
public class UserDefinedItem
{
internal int BookId { get; private set; }
public Book Book { get; private set; }
private UserDefinedItem() { }
internal UserDefinedItem(Book book)
{
ArgumentValidator.EnsureNotNull(book, nameof(book));
Book = book;
// import previously saved tags
ArgumentValidator.EnsureNotNullOrWhiteSpace(book.AudibleProductId, nameof(book.AudibleProductId));
Tags = FileManager.TagsPersistence.GetTags(book.AudibleProductId);
}
#region Tags
private string _tags = "";
public string Tags
{
get => _tags;
set
{
var newTags = sanitize(value);
if (_tags != newTags)
{
_tags = newTags;
ItemChanged?.Invoke(this, nameof(Tags));
}
}
}
public IEnumerable<string> TagsEnumerated => Tags == "" ? new string[0] : Tags.Split(null as char[], StringSplitOptions.RemoveEmptyEntries);
#region sanitize tags: space delimited. Inline/denormalized. Lower case. Alpha numeric and hyphen
// only legal chars are letters numbers underscores and separating whitespace
//
// technically, the only char.s which aren't easily supported are \ [ ]
// however, whitelisting is far safer than blacklisting (eg: new lines, non-printable character)
// it's easy to expand whitelist as needed
// for lucene, ToLower() isn't needed because search is case-inspecific. for here, it prevents duplicates
//
// there are also other allowed but misleading characters. eg: the ^ operator defines a 'boost' score
// full list of characters which must be escaped:
// + - && || ! ( ) { } [ ] ^ " ~ * ? : \
static Regex regex { get; } = new Regex(@"[^\w\d\s_]", RegexOptions.Compiled);
private static string sanitize(string input)
{
if (string.IsNullOrWhiteSpace(input))
return "";
var str = input
.Trim()
.ToLowerInvariant()
// assume a hyphen is supposed to be an underscore
.Replace("-", "_");
var unique = regex
// turn illegal characters into a space. this will also take care of turning new lines into spaces
.Replace(str, " ")
// split and remove excess spaces
.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)
// de-dup
.Distinct()
// this will prevent order from being relevant
.OrderBy(a => a);
// currently, the string is the canonical set. if we later make the collection into the canonical set:
// var tags = new Hashset<string>(list); // de-dup, order doesn't matter but can seem random due to hashing algo
// var isEqual = tagsNew.SetEquals(tagsOld);
return string.Join(" ", unique);
}
#endregion
#endregion
#region Rating
// owned: not an optional one-to-one
/// <summary>The user's individual book rating</summary>
public Rating Rating { get; private set; } = new Rating(0, 0, 0);
public void UpdateRating(float overallRating, float performanceRating, float storyRating)
=> Rating.Update(overallRating, performanceRating, storyRating);
#endregion
#region LiberatedStatuses
private LiberatedStatus _bookStatus;
private LiberatedStatus? _pdfStatus;
public LiberatedStatus BookStatus
{
get => _bookStatus;
set
{
if (_bookStatus != value)
{
_bookStatus = value;
ItemChanged?.Invoke(this, nameof(BookStatus));
}
}
}
public LiberatedStatus? PdfStatus
{
get => _pdfStatus;
set
{
if (_pdfStatus != value)
{
_pdfStatus = value;
ItemChanged?.Invoke(this, nameof(PdfStatus));
}
}
}
#endregion
/// <summary>
/// Occurs when <see cref="Tags"/>, <see cref="BookStatus"/>, or <see cref="PdfStatus"/> values change.
/// This signals the change of the in-memory value; it does not ensure that the new value has been persisted.
/// </summary>
public static event EventHandler<string> ItemChanged;
public override string ToString() => $"{Book} {Rating} {Tags}";
}
}
-72
View File
@@ -1,72 +0,0 @@
using DataLayer.Configurations;
using Dinah.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
namespace DataLayer
{
public class LibationContext : InterceptableDbContext
{
// IMPORTANT: USING DbSet<>
// ========================
// these run against the db. linq queries against these MUST be translatable to sql. primatives only. no POCOs or this error occurs:
// Unable to create a constant value of type 'DataLayer.Contributor'. Only primitive types or enumeration types are supported in this context.
// to use full object-linq, load and use local
// load full table:
// List<Contributor> contributors = ...;
// Contributors.Load();
// Contributors.Local.Where(a => contributors.Contains(a));
// load only those in object:
// // overwrite collection
// Entry(product).Collection(x => x.Narrators).Load();
// product.Narrators = narrators;
public DbSet<LibraryBook> LibraryBooks { get; private set; }
public DbSet<Book> Books { get; private set; }
public DbSet<Contributor> Contributors { get; private set; }
public DbSet<Series> Series { get; private set; }
public DbSet<Category> Categories { get; private set; }
public static LibationContext Create(string connectionString)
{
var factory = new LibationContextFactory();
var context = factory.Create(connectionString);
return context;
}
// see DesignTimeDbContextFactoryBase for info about ctors and connection strings/OnConfiguring()
internal LibationContext(DbContextOptions options) : base(options) { }
// called on each instantiation
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
AddInterceptor(new TagPersistenceInterceptor());
base.OnConfiguring(optionsBuilder);
}
// typically only called once per execution; NOT once per instantiation
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.ApplyConfiguration(new BookConfig());
modelBuilder.ApplyConfiguration(new ContributorConfig());
modelBuilder.ApplyConfiguration(new BookContributorConfig());
modelBuilder.ApplyConfiguration(new LibraryBookConfig());
modelBuilder.ApplyConfiguration(new SeriesConfig());
modelBuilder.ApplyConfiguration(new SeriesBookConfig());
modelBuilder.ApplyConfiguration(new CategoryConfig());
// seeds go here. examples in Dinah.EntityFrameworkCore.Tests\DbContextFactoryExample.cs
modelBuilder
.Entity<Category>()
.HasData(Category.GetEmpty());
modelBuilder
.Entity<Contributor>()
.HasData(Contributor.GetEmpty());
// views are now supported via "keyless entity types" (instead of "entity types" or the prev "query types"):
// https://docs.microsoft.com/en-us/ef/core/modeling/keyless-entity-types
}
}
}
-11
View File
@@ -1,11 +0,0 @@
using Dinah.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
namespace DataLayer
{
public class LibationContextFactory : DesignTimeDbContextFactoryBase<LibationContext>
{
protected override LibationContext CreateNewInstance(DbContextOptions<LibationContext> options) => new LibationContext(options);
protected override void UseDatabaseEngine(DbContextOptionsBuilder optionsBuilder, string connectionString) => optionsBuilder.UseSqlite(connectionString);
}
}
@@ -1,294 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
namespace DataLayer.Migrations
{
public partial class Fresh : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Categories",
columns: table => new
{
CategoryId = table.Column<int>(nullable: false)
.Annotation("Sqlite:Autoincrement", true),
AudibleCategoryId = table.Column<string>(nullable: true),
Name = table.Column<string>(nullable: true),
ParentCategoryCategoryId = table.Column<int>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Categories", x => x.CategoryId);
table.ForeignKey(
name: "FK_Categories_Categories_ParentCategoryCategoryId",
column: x => x.ParentCategoryCategoryId,
principalTable: "Categories",
principalColumn: "CategoryId",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "Contributors",
columns: table => new
{
ContributorId = table.Column<int>(nullable: false)
.Annotation("Sqlite:Autoincrement", true),
Name = table.Column<string>(nullable: true),
AudibleContributorId = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Contributors", x => x.ContributorId);
});
migrationBuilder.CreateTable(
name: "Series",
columns: table => new
{
SeriesId = table.Column<int>(nullable: false)
.Annotation("Sqlite:Autoincrement", true),
AudibleSeriesId = table.Column<string>(nullable: true),
Name = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Series", x => x.SeriesId);
});
migrationBuilder.CreateTable(
name: "Books",
columns: table => new
{
BookId = table.Column<int>(nullable: false)
.Annotation("Sqlite:Autoincrement", true),
AudibleProductId = table.Column<string>(nullable: true),
Title = table.Column<string>(nullable: true),
Description = table.Column<string>(nullable: true),
LengthInMinutes = table.Column<int>(nullable: false),
PictureId = table.Column<string>(nullable: true),
IsAbridged = table.Column<bool>(nullable: false),
DatePublished = table.Column<DateTime>(nullable: true),
CategoryId = table.Column<int>(nullable: false),
Rating_OverallRating = table.Column<float>(nullable: true),
Rating_PerformanceRating = table.Column<float>(nullable: true),
Rating_StoryRating = table.Column<float>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Books", x => x.BookId);
table.ForeignKey(
name: "FK_Books_Categories_CategoryId",
column: x => x.CategoryId,
principalTable: "Categories",
principalColumn: "CategoryId",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "BookContributor",
columns: table => new
{
BookId = table.Column<int>(nullable: false),
ContributorId = table.Column<int>(nullable: false),
Role = table.Column<int>(nullable: false),
Order = table.Column<byte>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_BookContributor", x => new { x.BookId, x.ContributorId, x.Role });
table.ForeignKey(
name: "FK_BookContributor_Books_BookId",
column: x => x.BookId,
principalTable: "Books",
principalColumn: "BookId",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_BookContributor_Contributors_ContributorId",
column: x => x.ContributorId,
principalTable: "Contributors",
principalColumn: "ContributorId",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "Library",
columns: table => new
{
BookId = table.Column<int>(nullable: false),
DateAdded = table.Column<DateTime>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Library", x => x.BookId);
table.ForeignKey(
name: "FK_Library_Books_BookId",
column: x => x.BookId,
principalTable: "Books",
principalColumn: "BookId",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "SeriesBook",
columns: table => new
{
SeriesId = table.Column<int>(nullable: false),
BookId = table.Column<int>(nullable: false),
Index = table.Column<float>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_SeriesBook", x => new { x.SeriesId, x.BookId });
table.ForeignKey(
name: "FK_SeriesBook_Books_BookId",
column: x => x.BookId,
principalTable: "Books",
principalColumn: "BookId",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_SeriesBook_Series_SeriesId",
column: x => x.SeriesId,
principalTable: "Series",
principalColumn: "SeriesId",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "Supplement",
columns: table => new
{
SupplementId = table.Column<int>(nullable: false)
.Annotation("Sqlite:Autoincrement", true),
BookId = table.Column<int>(nullable: false),
Url = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Supplement", x => x.SupplementId);
table.ForeignKey(
name: "FK_Supplement_Books_BookId",
column: x => x.BookId,
principalTable: "Books",
principalColumn: "BookId",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "UserDefinedItem",
columns: table => new
{
BookId = table.Column<int>(nullable: false),
Tags = table.Column<string>(nullable: true),
Rating_OverallRating = table.Column<float>(nullable: true),
Rating_PerformanceRating = table.Column<float>(nullable: true),
Rating_StoryRating = table.Column<float>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_UserDefinedItem", x => x.BookId);
table.ForeignKey(
name: "FK_UserDefinedItem_Books_BookId",
column: x => x.BookId,
principalTable: "Books",
principalColumn: "BookId",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.InsertData(
table: "Categories",
columns: new[] { "CategoryId", "AudibleCategoryId", "Name", "ParentCategoryCategoryId" },
values: new object[] { -1, "", "", null });
migrationBuilder.InsertData(
table: "Contributors",
columns: new[] { "ContributorId", "AudibleContributorId", "Name" },
values: new object[] { -1, null, "" });
migrationBuilder.CreateIndex(
name: "IX_BookContributor_BookId",
table: "BookContributor",
column: "BookId");
migrationBuilder.CreateIndex(
name: "IX_BookContributor_ContributorId",
table: "BookContributor",
column: "ContributorId");
migrationBuilder.CreateIndex(
name: "IX_Books_AudibleProductId",
table: "Books",
column: "AudibleProductId");
migrationBuilder.CreateIndex(
name: "IX_Books_CategoryId",
table: "Books",
column: "CategoryId");
migrationBuilder.CreateIndex(
name: "IX_Categories_AudibleCategoryId",
table: "Categories",
column: "AudibleCategoryId");
migrationBuilder.CreateIndex(
name: "IX_Categories_ParentCategoryCategoryId",
table: "Categories",
column: "ParentCategoryCategoryId");
migrationBuilder.CreateIndex(
name: "IX_Contributors_Name",
table: "Contributors",
column: "Name");
migrationBuilder.CreateIndex(
name: "IX_Series_AudibleSeriesId",
table: "Series",
column: "AudibleSeriesId");
migrationBuilder.CreateIndex(
name: "IX_SeriesBook_BookId",
table: "SeriesBook",
column: "BookId");
migrationBuilder.CreateIndex(
name: "IX_SeriesBook_SeriesId",
table: "SeriesBook",
column: "SeriesId");
migrationBuilder.CreateIndex(
name: "IX_Supplement_BookId",
table: "Supplement",
column: "BookId");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "BookContributor");
migrationBuilder.DropTable(
name: "Library");
migrationBuilder.DropTable(
name: "SeriesBook");
migrationBuilder.DropTable(
name: "Supplement");
migrationBuilder.DropTable(
name: "UserDefinedItem");
migrationBuilder.DropTable(
name: "Contributors");
migrationBuilder.DropTable(
name: "Series");
migrationBuilder.DropTable(
name: "Books");
migrationBuilder.DropTable(
name: "Categories");
}
}
}
@@ -1,31 +0,0 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace DataLayer.Migrations
{
public partial class AddLocaleAndAccount : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "Account",
table: "Library",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "Locale",
table: "Books",
nullable: true);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "Account",
table: "Library");
migrationBuilder.DropColumn(
name: "Locale",
table: "Books");
}
}
}
@@ -1,33 +0,0 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace DataLayer.Migrations
{
public partial class AddAaxcDecryptionKeys : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "AudibleIV",
table: "Books",
type: "TEXT",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "AudibleKey",
table: "Books",
type: "TEXT",
nullable: true);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "AudibleIV",
table: "Books");
migrationBuilder.DropColumn(
name: "AudibleKey",
table: "Books");
}
}
}
@@ -1,33 +0,0 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace DataLayer.Migrations
{
public partial class RemoveAaxcDecryptionKeys : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "AudibleIV",
table: "Books");
migrationBuilder.DropColumn(
name: "AudibleKey",
table: "Books");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "AudibleIV",
table: "Books",
type: "TEXT",
nullable: true);
migrationBuilder.AddColumn<string>(
name: "AudibleKey",
table: "Books",
type: "TEXT",
nullable: true);
}
}
}
@@ -1,44 +0,0 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace DataLayer.Migrations
{
public partial class AddLiberatedStatus : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "BookLocation",
table: "UserDefinedItem",
type: "TEXT",
nullable: true);
migrationBuilder.AddColumn<int>(
name: "BookStatus",
table: "UserDefinedItem",
type: "INTEGER",
nullable: false,
defaultValue: 0);
migrationBuilder.AddColumn<int>(
name: "PdfStatus",
table: "UserDefinedItem",
type: "INTEGER",
nullable: true);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "BookLocation",
table: "UserDefinedItem");
migrationBuilder.DropColumn(
name: "BookStatus",
table: "UserDefinedItem");
migrationBuilder.DropColumn(
name: "PdfStatus",
table: "UserDefinedItem");
}
}
}
@@ -1,23 +0,0 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace DataLayer.Migrations
{
public partial class RemoveUdiBookLocation : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "BookLocation",
table: "UserDefinedItem");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "BookLocation",
table: "UserDefinedItem",
type: "TEXT",
nullable: true);
}
}
}
@@ -1,24 +0,0 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace DataLayer.Migrations
{
public partial class BookIsEpisode : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<int>(
name: "ContentType",
table: "Books",
type: "INTEGER",
nullable: false,
defaultValue: 0);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "ContentType",
table: "Books");
}
}
}
@@ -1,63 +0,0 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace DataLayer.Migrations
{
public partial class RenameLibraryBooks : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_Library_Books_BookId",
table: "Library");
migrationBuilder.DropPrimaryKey(
name: "PK_Library",
table: "Library");
migrationBuilder.RenameTable(
name: "Library",
newName: "LibraryBooks");
migrationBuilder.AddPrimaryKey(
name: "PK_LibraryBooks",
table: "LibraryBooks",
column: "BookId");
migrationBuilder.AddForeignKey(
name: "FK_LibraryBooks_Books_BookId",
table: "LibraryBooks",
column: "BookId",
principalTable: "Books",
principalColumn: "BookId",
onDelete: ReferentialAction.Cascade);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_LibraryBooks_Books_BookId",
table: "LibraryBooks");
migrationBuilder.DropPrimaryKey(
name: "PK_LibraryBooks",
table: "LibraryBooks");
migrationBuilder.RenameTable(
name: "LibraryBooks",
newName: "Library");
migrationBuilder.AddPrimaryKey(
name: "PK_Library",
table: "Library",
column: "BookId");
migrationBuilder.AddForeignKey(
name: "FK_Library_Books_BookId",
table: "Library",
column: "BookId",
principalTable: "Books",
principalColumn: "BookId",
onDelete: ReferentialAction.Cascade);
}
}
}
-38
View File
@@ -1,38 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Microsoft.EntityFrameworkCore;
namespace DataLayer
{
// only library importing should use tracking. All else should be NoTracking.
// only library importing should directly query Book. All else should use LibraryBook
public static class BookQueries
{
public static Book GetBook_Flat_NoTracking(this LibationContext context, string productId)
=> context
.Books
.AsNoTrackingWithIdentityResolution()
.GetBook(productId);
public static Book GetBook(this IQueryable<Book> books, string productId)
=> books
.GetBooks()
.SingleOrDefault(b => b.AudibleProductId == productId);
/// <summary>This is still IQueryable. YOU MUST CALL ToList() YOURSELF</summary>
public static IQueryable<Book> GetBooks(this IQueryable<Book> books, Expression<Func<Book, bool>> predicate)
=> books
.GetBooks()
.Where(predicate);
/// <summary>This is still IQueryable. YOU MUST CALL ToList() YOURSELF</summary>
public static IQueryable<Book> GetBooks(this IQueryable<Book> books)
=> books
// owned items are always loaded. eg: book.UserDefinedItem, book.Supplements
.Include(b => b.SeriesLink).ThenInclude(sb => sb.Series)
.Include(b => b.ContributorsLink).ThenInclude(c => c.Contributor)
.Include(b => b.Category).ThenInclude(c => c.ParentCategory);
}
}
@@ -1,44 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using Microsoft.EntityFrameworkCore;
namespace DataLayer
{
// only library importing should use tracking. All else should be NoTracking.
// only library importing should directly query Book. All else should use LibraryBook
public static class LibraryBookQueries
{
//// tracking is a bad idea for main grid. it prevents anything else from updating entities unless getting them from the grid
//public static List<LibraryBook> GetLibrary_Flat_WithTracking(this LibationContext context)
// => context
// .Library
// .GetLibrary()
// .ToList();
public static List<LibraryBook> GetLibrary_Flat_NoTracking(this LibationContext context)
=> context
.LibraryBooks
.AsNoTrackingWithIdentityResolution()
.GetLibrary()
.ToList();
public static LibraryBook GetLibraryBook_Flat_NoTracking(this LibationContext context, string productId)
=> context
.LibraryBooks
.AsNoTrackingWithIdentityResolution()
.GetLibraryBook(productId);
public static LibraryBook GetLibraryBook(this IQueryable<LibraryBook> library, string productId)
=> library
.GetLibrary()
.SingleOrDefault(lb => lb.Book.AudibleProductId == productId);
/// <summary>This is still IQueryable. YOU MUST CALL ToList() YOURSELF</summary>
public static IQueryable<LibraryBook> GetLibrary(this IQueryable<LibraryBook> library)
=> library
// owned items are always loaded. eg: book.UserDefinedItem, book.Supplements
.Include(le => le.Book).ThenInclude(b => b.SeriesLink).ThenInclude(sb => sb.Series)
.Include(le => le.Book).ThenInclude(b => b.ContributorsLink).ThenInclude(c => c.Contributor)
.Include(le => le.Book).ThenInclude(b => b.Category).ThenInclude(c => c.ParentCategory);
}
}
-30
View File
@@ -1,30 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Dinah.Core.Collections.Generic;
using Dinah.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
namespace DataLayer
{
internal class TagPersistenceInterceptor : IDbInterceptor
{
public void Executed(DbContext context) { }
public void Executing(DbContext context)
{
var tagsCollection
= context
.ChangeTracker
.Entries()
.Where(e => e.State.In(EntityState.Modified, EntityState.Added))
.Select(e => e.Entity as UserDefinedItem)
.Where(udi => udi != null)
// do NOT filter out entires with blank tags. blank is the valid way to show the absence of tags
.Select(t => (t.Book.AudibleProductId, t.Tags))
.ToList();
FileManager.TagsPersistence.Save(tagsCollection);
}
}
}
-38
View File
@@ -1,38 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace DataLayer.Utilities
{
public static class LocalDatabaseInfo
{
public static List<string> GetLocalDBInstances()
{
// Start the child process.
using var p = new System.Diagnostics.Process
{
StartInfo = new System.Diagnostics.ProcessStartInfo
{
UseShellExecute = false,
RedirectStandardOutput = true,
FileName = "cmd.exe",
Arguments = "/C sqllocaldb info",
CreateNoWindow = true,
WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden
}
};
p.Start();
var output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
// if LocalDb is not installed then it will return that 'sqllocaldb' is not recognized as an internal or external command operable program or batch file
return string.IsNullOrWhiteSpace(output) || output.Contains("not recognized")
? new List<string>()
: output
.Split(new string[] { Environment.NewLine }, StringSplitOptions.None)
.Select(i => i.Trim())
.Where(i => !string.IsNullOrEmpty(i))
.ToList();
}
}
}
-6
View File
@@ -1,6 +0,0 @@
{
"ConnectionStrings": {
"// this connection string is ONLY used for DataLayer's Migrations. this appsettings.json file is NOT used at all by application; it is overwritten": "",
"LibationContext": "Data Source=LibationContext.db;Foreign Keys=False;"
}
}
+5
View File
@@ -0,0 +1,5 @@
<Project>
<PropertyGroup>
<EnableMSTestRunner>true</EnableMSTestRunner>
</PropertyGroup>
</Project>
+3
View File
@@ -0,0 +1,3 @@
{
"LibationFiles": "/config-internal"
}
+201
View File
@@ -0,0 +1,201 @@
#!/bin/bash
error() {
log "ERROR" "$1"
}
warn() {
log "WARNING" "$1"
}
info() {
log "info" "$1"
}
debug() {
if [ "${LOG_LEVEL}" = "debug" ]; then
log "debug" "$1"
fi
}
log() {
LEVEL=$1
MESSAGE=$2
printf "$(date '+%F %T') %s: %s\n" "${LEVEL}" "${MESSAGE}"
}
init_config_file() {
FILE=$1
FULLPATH=${LIBATION_CONFIG_DIR}/${FILE}
if [ -f ${FULLPATH} ]; then
info "loading ${FILE}"
cp ${FULLPATH} ${LIBATION_CONFIG_INTERNAL}/
return 0
else
warn "${FULLPATH} not found, creating empty file"
echo "{}" > ${LIBATION_CONFIG_INTERNAL}/${FILE}
return 1
fi
}
update_settings() {
FILE=$1
KEY=$2
VALUE=$3
info "setting ${KEY} to ${VALUE}"
echo $(jq --arg k "${KEY}" --arg v "${VALUE}" '.[$k] = $v' ${LIBATION_CONFIG_INTERNAL}/${FILE}) > ${LIBATION_CONFIG_INTERNAL}/${FILE}.tmp
mv ${LIBATION_CONFIG_INTERNAL}/${FILE}.tmp ${LIBATION_CONFIG_INTERNAL}/${FILE}
}
is_mounted() {
DIR=$1
if grep -qs "${DIR} " /proc/mounts;
then
return 0
else
return 1
fi
}
create_db() {
DBFILE=$1
if [ -f "${DBFILE}" ]; then
warn "prexisting database found when creating"
return 0
else
if ! touch "${DBFILE}"; then
error "unable to create database, check permissions on host"
exit 1
fi
return 1
fi
}
setup_db() {
local DBPATH=$1
local dbpattern="*.db"
local FILE LINK LINK_ORIGIN
local -a files
debug "using database directory ${DBPATH}"
# Figure out the right databse file
if [[ -z $LIBATION_DB_FILE ]]
then
shopt -s nullglob # files shall be empty if no match is found
files=( "${DBPATH}"/${dbpattern} )
shopt -u nullglob
case ${#files[@]} in
0)
FILE="${DBPATH}/LibationContext.db"
;;
1)
FILE="${files[0]}"
;;
*)
debug "found ${#files[@]} database files matching '${dbpattern}'"
error "too many database files found, set LIBATION_DB_FILE to the filename you wish to use"
exit 1
;;
esac
else
FILE="${DBPATH}/${LIBATION_DB_FILE}"
fi
debug "planning to use database '${FILE}'"
if [[ -f $FILE ]]
then
info "database found at ${FILE}"
elif [[ $LIBATION_CREATE_DB == "true" ]]
then
warn "database not found, creating one at ${FILE}"
create_db "${FILE}"
else
error "database not found and creation is disabled"
exit 1
fi
LINK="${LIBATION_CONFIG_INTERNAL}/LibationContext.db"
if [[ -L $LINK ]]
then
# check if the link is correct
LINK_ORIGIN=$(readlink -fn "$LINK")
if [[ $LINK_ORIGIN == $(readlink -fn "$FILE") ]]
then
warn "symlink '${LINK_ORIGIN}' to '${LINK}' already established"
return 0
fi
warn "removing existing symlink '${LINK_ORIGIN}' to '${LINK}'"
rm -f "$LINK"
elif [[ -e $LINK ]]
then
error "found blocking file at '${LINK}' - can't create symlink"
exit 1
fi
ln -s "${FILE}" "${LINK}"
}
run() {
info "scanning accounts"
/libation/LibationCli scan
info "liberating books"
/libation/LibationCli liberate
}
main() {
info "initializing libation"
init_config_file AccountsSettings.json
init_config_file Settings.json
info "loading settings"
update_settings Settings.json Books "${LIBATION_BOOKS_DIR:-/data}"
update_settings Settings.json InProgress /tmp
info "loading database"
# If user provides a separate database mount, use that
if is_mounted "${LIBATION_DB_DIR}";
then
DB_LOCATION=${LIBATION_DB_DIR}
# Otherwise, use the config directory
else
DB_LOCATION=${LIBATION_CONFIG_DIR}
fi
setup_db ${DB_LOCATION}
# Try to warn if books dir wasn't mounted in
if ! is_mounted "${LIBATION_BOOKS_DIR}";
then
warn "${LIBATION_BOOKS_DIR} does not appear to be mounted, books will not be saved"
fi
# Let the user know what the run type will be
if [[ -z "${SLEEP_TIME}" ]]; then
SLEEP_TIME=-1
fi
if [ "${SLEEP_TIME}" == -1 ]; then
info "running once"
else
info "running every ${SLEEP_TIME}"
fi
# loop
while true
do
run
# Liberate only once if SLEEP_TIME was set to -1
if [ "${SLEEP_TIME}" == -1 ]; then
break
fi
sleep "${SLEEP_TIME}"
done
info "exiting"
}
main
+42
View File
@@ -0,0 +1,42 @@
# Dockerfile
FROM --platform=${BUILDPLATFORM} mcr.microsoft.com/dotnet/sdk:10.0 AS build
ARG TARGETARCH
COPY Source /Source
RUN dotnet publish \
/Source/LibationCli/LibationCli.csproj \
--os linux \
--arch ${TARGETARCH} \
--configuration Release \
--output /Source/bin/Publish/Linux-chardonnay \
-p:PublishProtocol=FileSystem \
-p:PublishReadyToRun=true \
-p:SelfContained=true
FROM mcr.microsoft.com/dotnet/runtime:10.0
ARG USER_UID=1001
ARG USER_GID=1001
# Set the character set that will be used for folder and filenames when liberating
ENV LANG=C.UTF-8
ENV LC_ALL=C.UTF-8
ENV SLEEP_TIME=-1
ENV LIBATION_CONFIG_INTERNAL=/config-internal
ENV LIBATION_CONFIG_DIR=/config
ENV LIBATION_DB_DIR=/db
ENV LIBATION_DB_FILE=
ENV LIBATION_CREATE_DB=true
ENV LIBATION_BOOKS_DIR=/data
RUN apt-get update && apt-get -y upgrade && \
apt-get install -y jq && \
mkdir -m777 ${LIBATION_CONFIG_INTERNAL} ${LIBATION_BOOKS_DIR}
COPY --from=build /Source/bin/Publish/Linux-chardonnay /libation
COPY Docker/* /libation
USER ${USER_UID}:${USER_GID}
CMD ["/libation/liberate.sh"]
+3
View File
@@ -0,0 +1,3 @@
# This page has been moved to https://getlibation.com/docs/advanced/advanced
([page in github](https://github.com/rmcrackan/Libation/blob/master/docs/advanced/advanced.md))
+3
View File
@@ -0,0 +1,3 @@
# This page has been moved to https://getlibation.com/docs/features/audio-file-formats
([page in github](https://github.com/rmcrackan/Libation/blob/master/docs/features/audio-file-formats.md))
+3
View File
@@ -0,0 +1,3 @@
# This page has been moved to https://getlibation.com/docs/installation/docker
([page in github](https://github.com/rmcrackan/Libation/blob/master/docs/installation/docker.md))
@@ -0,0 +1,3 @@
# This page has been moved to https://getlibation.com/docs/frequently-asked-questions
([page in github](https://github.com/rmcrackan/Libation/blob/master/docs/frequently-asked-questions.md))
+3
View File
@@ -0,0 +1,3 @@
# This page has been moved to https://getlibation.com/docs/getting-started
([page in github](https://github.com/rmcrackan/Libation/blob/master/docs/getting-started.md))
+3
View File
@@ -0,0 +1,3 @@
# This page has been moved to https://getlibation.com/docs/installation/linux
([page in github](https://github.com/rmcrackan/Libation/blob/master/docs/installation/linux.md))
+3
View File
@@ -0,0 +1,3 @@
# This page has been moved to https://getlibation.com/docs/installation/mac
([page in github](https://github.com/rmcrackan/Libation/blob/master/docs/installation/mac.md))
@@ -0,0 +1,3 @@
# This page has been moved to https://getlibation.com/docs/development/nix-linux-setup
([page in github](https://github.com/rmcrackan/Libation/blob/master/docs/development/nix-linux-setup.md))
+3
View File
@@ -0,0 +1,3 @@
# This page has been moved to https://getlibation.com/docs/features/naming-templates
([page in github](https://github.com/rmcrackan/Libation/blob/master/docs/features/naming-templates.md))
+3
View File
@@ -0,0 +1,3 @@
# This page has been moved to https://getlibation.com/docs/features/searching-and-filtering
([page in github](https://github.com/rmcrackan/Libation/blob/master/docs/features/searching-and-filtering.md))
-184
View File
@@ -1,184 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using AudibleApi.Common;
using DataLayer;
using InternalUtilities;
namespace DtoImporterService
{
public class BookImporter : ItemsImporterBase
{
public BookImporter(LibationContext context) : base(context) { }
public override IEnumerable<Exception> Validate(IEnumerable<ImportItem> importItems) => new BookValidator().Validate(importItems.Select(i => i.DtoItem));
protected override int DoImport(IEnumerable<ImportItem> importItems)
{
// pre-req.s
new ContributorImporter(DbContext).Import(importItems);
new SeriesImporter(DbContext).Import(importItems);
new CategoryImporter(DbContext).Import(importItems);
// get distinct
var productIds = importItems.Select(i => i.DtoItem.ProductId).Distinct().ToList();
// load db existing => .Local
loadLocal_books(productIds);
// upsert
var qtyNew = upsertBooks(importItems);
return qtyNew;
}
private void loadLocal_books(List<string> productIds)
{
// if this context has already loaded books, don't need to reload them. vestige from when context was long-lived. in practice, we now typically use a fresh context. this is quick though so no harm in leaving it.
var localProductIds = DbContext.Books.Local.Select(b => b.AudibleProductId).ToList();
var remainingProductIds = productIds
.Except(localProductIds)
.ToList();
#region // explanation of DbContext.Books.GetBooks(b => remainingProductIds.Contains(b.AudibleProductId)).ToList();
/*
articles suggest loading to Local with
context.Books.Load();
we want Books and associated fields
context.Books.GetBooks(b => remainingProductIds.Contains(b.AudibleProductId)).ToList();
this is emulating Load() but with also getting associated fields
from: Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions
// Summary:
// Enumerates the query. When using Entity Framework, this causes the results of
// the query to be loaded into the associated context. This is equivalent to calling
// ToList and then throwing away the list (without the overhead of actually creating
// the list).
public static void Load<TSource>([NotNullAttribute] this IQueryable<TSource> source);
*/
#endregion
// GetBooks() eager loads Series, category, et al
if (remainingProductIds.Any())
DbContext.Books.GetBooks(b => remainingProductIds.Contains(b.AudibleProductId)).ToList();
}
private int upsertBooks(IEnumerable<ImportItem> importItems)
{
var qtyNew = 0;
foreach (var item in importItems)
{
var book = DbContext.Books.Local.SingleOrDefault(p => p.AudibleProductId == item.DtoItem.ProductId);
if (book is null)
{
book = createNewBook(item);
qtyNew++;
}
updateBook(item, book);
}
return qtyNew;
}
private Book createNewBook(ImportItem importItem)
{
var item = importItem.DtoItem;
var contentType = item.IsEpisodes ? DataLayer.ContentType.Episode : DataLayer.ContentType.Product;
// absence of authors is very rare, but possible
if (!item.Authors?.Any() ?? true)
item.Authors = new[] { new Person { Name = "", Asin = null } };
// nested logic is required so order of names is retained. else, contributors may appear in the order they were inserted into the db
var authors = item
.Authors
.Select(a => DbContext.Contributors.Local.Single(c => a.Name == c.Name))
.ToList();
var narrators
= item.Narrators is null || !item.Narrators.Any()
// if no narrators listed, author is the narrator
? authors
// nested logic is required so order of names is retained. else, contributors may appear in the order they were inserted into the db
: item
.Narrators
.Select(n => DbContext.Contributors.Local.Single(c => n.Name == c.Name))
.ToList();
// categories are laid out for a breadcrumb. category is 1st, subcategory is 2nd
// absence of categories is also possible
// CATEGORY HACK: only use the 1st 2 categories
// (real impl: var lastCategory = item.Categories.LastOrDefault()?.CategoryId ?? "";)
var lastCategory
= item.Categories.Length == 0 ? ""
: item.Categories.Length == 1 ? item.Categories[0].CategoryId
// 2+
: item.Categories[1].CategoryId;
var category = DbContext.Categories.Local.SingleOrDefault(c => c.AudibleCategoryId == lastCategory);
var book = DbContext.Books.Add(new Book(
new AudibleProductId(item.ProductId),
item.TitleWithSubtitle,
item.Description,
item.LengthInMinutes,
contentType,
authors,
narrators,
category,
importItem.LocaleName)
).Entity;
var publisherName = item.Publisher;
if (!string.IsNullOrWhiteSpace(publisherName))
{
var publisher = DbContext.Contributors.Local.Single(c => publisherName == c.Name);
book.ReplacePublisher(publisher);
}
book.UpdateBookDetails(item.IsAbridged, item.DatePublished);
if (item.PdfUrl is not null)
book.AddSupplementDownloadUrl(item.PdfUrl.ToString());
return book;
}
private void updateBook(ImportItem importItem, Book book)
{
var item = importItem.DtoItem;
// set/update book-specific info which may have changed
book.PictureId = item.PictureId;
book.UpdateProductRating(item.Product_OverallStars, item.Product_PerformanceStars, item.Product_StoryStars);
// important to update user-specific info. this will have changed if user has rated/reviewed the book since last library import
book.UserDefinedItem.UpdateRating(item.MyUserRating_Overall, item.MyUserRating_Performance, item.MyUserRating_Story);
// update series even for existing books. these are occasionally updated
// these will upsert over library-scraped series, but will not leave orphans
if (item.Series != null)
{
foreach (var seriesEntry in item.Series)
{
var series = DbContext.Series.Local.Single(s => seriesEntry.SeriesId == s.AudibleSeriesId);
var index = 0f;
try
{
index = seriesEntry.Index;
}
catch (Exception ex)
{
Serilog.Log.Logger.Error(ex, $"Error parsing series index. Title: {item.Title}. ASIN: {item.Asin}. Series index: {seriesEntry.Sequence}");
}
book.UpsertSeries(series, index);
}
}
}
}
}
-85
View File
@@ -1,85 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using AudibleApi.Common;
using DataLayer;
using InternalUtilities;
namespace DtoImporterService
{
public class CategoryImporter : ItemsImporterBase
{
public CategoryImporter(LibationContext context) : base(context) { }
public override IEnumerable<Exception> Validate(IEnumerable<ImportItem> importItems) => new CategoryValidator().Validate(importItems.Select(i => i.DtoItem));
protected override int DoImport(IEnumerable<ImportItem> importItems)
{
// get distinct
var categoryIds = importItems
.Select(i => i.DtoItem)
.GetCategoriesDistinct()
.Select(c => c.CategoryId).ToList();
// load db existing => .Local
loadLocal_categories(categoryIds);
// upsert
var categoryPairs = importItems
.Select(i => i.DtoItem)
.GetCategoryPairsDistinct()
.ToList();
var qtyNew = upsertCategories(categoryPairs);
return qtyNew;
}
private void loadLocal_categories(List<string> categoryIds)
{
var localIds = DbContext.Categories.Local.Select(c => c.AudibleCategoryId).ToList();
var remainingCategoryIds = categoryIds
.Distinct()
.Except(localIds)
.ToList();
// load existing => local
// remember to include default/empty/missing
var emptyName = Contributor.GetEmpty().Name;
if (remainingCategoryIds.Any())
DbContext.Categories.Where(c => remainingCategoryIds.Contains(c.AudibleCategoryId) || c.Name == emptyName).ToList();
}
// only use after loading contributors => local
private int upsertCategories(List<Ladder[]> categoryPairs)
{
var qtyNew = 0;
foreach (var pair in categoryPairs)
{
for (var i = 0; i < pair.Length; i++)
{
// CATEGORY HACK: not yet supported: depth beyond 0 and 1
if (i > 1)
break;
var id = pair[i].CategoryId;
var name = pair[i].CategoryName;
Category parentCategory = null;
if (i == 1)
parentCategory = DbContext.Categories.Local.Single(c => c.AudibleCategoryId == pair[0].CategoryId);
var category = DbContext.Categories.Local.SingleOrDefault(c => c.AudibleCategoryId == id);
if (category is null)
{
category = DbContext.Categories.Add(new Category(new AudibleCategoryId(id), name)).Entity;
qtyNew++;
}
category.UpdateParentCategory(parentCategory);
}
}
return qtyNew;
}
}
}
-107
View File
@@ -1,107 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using AudibleApi.Common;
using DataLayer;
using InternalUtilities;
namespace DtoImporterService
{
public class ContributorImporter : ItemsImporterBase
{
public ContributorImporter(LibationContext context) : base(context) { }
public override IEnumerable<Exception> Validate(IEnumerable<ImportItem> importItems) => new ContributorValidator().Validate(importItems.Select(i => i.DtoItem));
protected override int DoImport(IEnumerable<ImportItem> importItems)
{
// get distinct
var authors = importItems
.Select(i => i.DtoItem)
.GetAuthorsDistinct()
.ToList();
var narrators = importItems
.Select(i => i.DtoItem)
.GetNarratorsDistinct()
.ToList();
var publishers = importItems
.Select(i => i.DtoItem)
.GetPublishersDistinct()
.ToList();
// load db existing => .Local
var allNames = publishers
.Union(authors.Select(n => n.Name))
.Union(narrators.Select(n => n.Name))
.Where(name => !string.IsNullOrWhiteSpace(name))
.ToList();
loadLocal_contributors(allNames);
// upsert
var qtyNew = 0;
qtyNew += upsertPeople(authors);
qtyNew += upsertPeople(narrators);
qtyNew += upsertPublishers(publishers);
return qtyNew;
}
private void loadLocal_contributors(List<string> contributorNames)
{
// must include default/empty/missing
contributorNames.Add(Contributor.GetEmpty().Name);
//// BAD: very inefficient
// var x = context.Contributors.Local.Where(c => !contribNames.Contains(c.Name));
// GOOD: Except() is efficient. Due to hashing, it's close to O(n)
var localNames = DbContext.Contributors.Local.Select(c => c.Name).ToList();
var remainingContribNames = contributorNames
.Distinct()
.Except(localNames)
.ToList();
// load existing => local
if (remainingContribNames.Any())
DbContext.Contributors.Where(c => remainingContribNames.Contains(c.Name)).ToList();
}
// only use after loading contributors => local
private int upsertPeople(List<Person> people)
{
var localNames = DbContext.Contributors.Local.Select(c => c.Name).ToList();
var newPeople = people
.Select(p => p.Name)
.Distinct()
.Except(localNames)
.ToList();
var groupby = people.GroupBy(
p => p.Name,
p => p,
(key, g) => new { Name = key, People = g.ToList() }
);
foreach (var name in newPeople)
{
var p = groupby.Single(g => g.Name == name).People.First();
DbContext.Contributors.Add(new Contributor(p.Name, p.Asin));
}
return newPeople.Count;
}
// only use after loading contributors => local
private int upsertPublishers(List<string> publishers)
{
var localNames = DbContext.Contributors.Local.Select(c => c.Name).ToList();
var newPublishers = publishers
.Distinct()
.Except(localNames)
.ToList();
foreach (var pub in newPublishers)
DbContext.Contributors.Add(new Contributor(pub));
return newPublishers.Count;
}
}
}
@@ -1,12 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\DataLayer\DataLayer.csproj" />
<ProjectReference Include="..\InternalUtilities\InternalUtilities.csproj" />
</ItemGroup>
</Project>
-12
View File
@@ -1,12 +0,0 @@
using System;
using AudibleApi.Common;
namespace DtoImporterService
{
public class ImportItem
{
public Item DtoItem { get; set; }
public string AccountId { get; set; }
public string LocaleName { get; set; }
}
}
-57
View File
@@ -1,57 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using DataLayer;
using Dinah.Core;
using InternalUtilities;
namespace DtoImporterService
{
public abstract class ImporterBase<T>
{
protected LibationContext DbContext { get; }
protected ImporterBase(LibationContext context)
{
ArgumentValidator.EnsureNotNull(context, nameof(context));
DbContext = context;
}
/// <summary>LONG RUNNING. call with await Task.Run</summary>
public int Import(T param) => Run(DoImport, param);
public TResult Run<TResult>(Func<T, TResult> func, T param)
{
try
{
var exceptions = Validate(param);
if (exceptions != null && exceptions.Any())
throw new AggregateException($"Importer validation failed", exceptions);
}
catch (Exception ex)
{
Serilog.Log.Logger.Error(ex, "Import error: validation");
throw;
}
try
{
var result = func(param);
return result;
}
catch (Exception ex)
{
Serilog.Log.Logger.Error(ex, "Import error: post-validation importing");
throw;
}
}
protected abstract int DoImport(T elements);
public abstract IEnumerable<Exception> Validate(T param);
}
public abstract class ItemsImporterBase : ImporterBase<IEnumerable<ImportItem>>
{
protected ItemsImporterBase(LibationContext context) : base(context) { }
}
}
Loaded 100 of 1119 files, more files were not shown because too many files have changed in this diff. Show more