tbr-deal-finder 0.3.1__tar.gz → 0.3.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/.github/workflows/build-release-dmg.yml +1 -0
  2. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/.github/workflows/build-release-exe.yml +3 -3
  3. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/CHANGELOG.md +12 -0
  4. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/PKG-INFO +1 -1
  5. tbr_deal_finder-0.3.2/docs/desktop-app.md +133 -0
  6. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/pyproject.toml +1 -1
  7. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/scripts/packaging/create_dmg.sh +4 -1
  8. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/__init__.py +1 -1
  9. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/gui/main.py +29 -0
  10. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/gui/pages/all_books.py +7 -0
  11. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/gui/pages/base_book_page.py +1 -2
  12. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/gui/pages/latest_deals.py +6 -0
  13. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/gui/pages/settings.py +1 -0
  14. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/retailer_deal.py +20 -29
  15. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/utils.py +28 -19
  16. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/uv.lock +1 -1
  17. tbr_deal_finder-0.3.1/docs/desktop-app.md +0 -251
  18. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/.github/workflows/publish-to-pypi.yaml +0 -0
  19. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/.gitignore +0 -0
  20. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/.python-version +0 -0
  21. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/DESIGN.md +0 -0
  22. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/LICENSE +0 -0
  23. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/Makefile +0 -0
  24. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/README.md +0 -0
  25. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/assets/icon.ico +0 -0
  26. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/assets/icon.png +0 -0
  27. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/docs/development.md +0 -0
  28. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/docs/python-cli.md +0 -0
  29. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/__main__.py +0 -0
  30. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/book.py +0 -0
  31. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/cli.py +0 -0
  32. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/config.py +0 -0
  33. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/desktop_updater.py +0 -0
  34. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/gui/__init__.py +0 -0
  35. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/gui/pages/__init__.py +0 -0
  36. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/gui/pages/all_deals.py +0 -0
  37. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/gui/pages/book_details.py +0 -0
  38. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/migrations.py +0 -0
  39. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/owned_books.py +0 -0
  40. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/queries/get_active_deals.sql +0 -0
  41. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/queries/get_deals_found_at.sql +0 -0
  42. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/queries/latest_deal_last_ran_most_recent_success.sql +0 -0
  43. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/queries/latest_unknown_book_sync.sql +0 -0
  44. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/retailer/__init__.py +0 -0
  45. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/retailer/amazon.py +0 -0
  46. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/retailer/amazon_custom_auth.py +0 -0
  47. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/retailer/audible.py +0 -0
  48. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/retailer/chirp.py +0 -0
  49. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/retailer/kindle.py +0 -0
  50. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/retailer/librofm.py +0 -0
  51. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/retailer/models.py +0 -0
  52. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/tracked_books.py +0 -0
  53. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/version_check.py +0 -0
  54. {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder.py +0 -0
@@ -13,6 +13,7 @@ jobs:
13
13
  env:
14
14
  HAS_MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE != '' }}
15
15
  HAS_MACOS_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PASSWORD != '' }}
16
+ VERSION: ${{ github.event.release.tag_name }}
16
17
 
17
18
  steps:
18
19
  - name: Checkout code
@@ -138,7 +138,7 @@ jobs:
138
138
  DefaultGroupName=${{ env.APP_DISPLAY_NAME }}
139
139
  AllowNoIcons=yes
140
140
  OutputDir=.
141
- OutputBaseFilename=${{ env.APP_FILENAME_BASE }}-${{ steps.app-info.outputs.app_version }}-Setup
141
+ OutputBaseFilename=${{ env.APP_FILENAME_BASE }}-${{ steps.app-info.outputs.app_version }}-Windows-Setup
142
142
  SetupIconFile=assets\icon.ico
143
143
  Compression=lzma2/normal
144
144
  SolidCompression=no
@@ -184,13 +184,13 @@ jobs:
184
184
  with:
185
185
  certificate: '${{ secrets.WINDOWS_CERTIFICATE }}'
186
186
  password: '${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }}'
187
- files: '${{ env.APP_FILENAME_BASE }}-${{ steps.app-info.outputs.app_version }}-Setup.exe'
187
+ files: '${{ env.APP_FILENAME_BASE }}-${{ steps.app-info.outputs.app_version }}-Windows-Setup.exe'
188
188
 
189
189
  - name: Upload Installer to Release
190
190
  env:
191
191
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
192
192
  run: |
193
- $installerFile = "${{ env.APP_FILENAME_BASE }}-${{ steps.app-info.outputs.app_version }}-Setup.exe"
193
+ $installerFile = "${{ env.APP_FILENAME_BASE }}-${{ steps.app-info.outputs.app_version }}-Windows-Setup.exe"
194
194
 
195
195
  gh release upload ${{ github.event.release.tag_name }} `
196
196
  $installerFile `
@@ -3,6 +3,18 @@
3
3
 
4
4
  ---
5
5
 
6
+ ## 0.3.2 (September 8, 2025)
7
+
8
+ Notes:
9
+ * Disable nav bar buttons when performing certain operations
10
+ * Added config check to CLI location when running the desktop app for backwards compatibility
11
+ * Improved performance when retrieving "latest deals"
12
+
13
+ BUG FIXES:
14
+ * Fixed issue with scroll bar in the "all deals" page
15
+
16
+ ---
17
+
6
18
  ## 0.3.1 (September 5, 2025)
7
19
 
8
20
  Notes:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tbr-deal-finder
3
- Version: 0.3.1
3
+ Version: 0.3.2
4
4
  Summary: Track price drops and find deals on books in your TBR list across audiobook and ebook formats.
5
5
  License: MIT
6
6
  License-File: LICENSE
@@ -0,0 +1,133 @@
1
+ # Desktop App Guide
2
+
3
+ Everything you need to know about installing, using, and updating the TBR Deal Finder desktop application.
4
+
5
+ ## Installation
6
+
7
+ The desktop app provides a beautiful graphical interface for managing your book deals without any command line knowledge required.
8
+
9
+ ### 🍎 macOS Installation
10
+
11
+ #### Download & Install
12
+ 1. Go to the [latest release](https://github.com/yourusername/tbr-deal-finder/releases/latest)
13
+ 2. Download `TBRDealFinder-{version}-macOS.dmg`
14
+ 3. **Open the DMG**: Double-click the downloaded `.dmg` file
15
+ 4. **Handle Security Warning**: macOS will show "Cannot verify developer"
16
+ - Click Done to handle the warning before continuing with the install
17
+ - [Follow guide from Apple](https://support.apple.com/guide/mac-help/open-a-mac-app-from-an-unknown-developer-mh40616/mac)
18
+ 5. **Install**: Drag the TBR Deal Finder app to your Applications folder
19
+ 6. **Launch**: Double-click the app in Applications
20
+ 7. **Wait for loader**: The app has a special loader and can take a minute to load for the first time
21
+
22
+ #### Troubleshooting macOS
23
+ - **"App can't be opened"**: Use right-click → Open instead of double-clicking
24
+ - **Still getting warnings**: Go to System Preferences → Security & Privacy → General → Click "Open Anyway"
25
+
26
+ ### 🪟 Windows Installation
27
+
28
+ #### Download & Install
29
+ 1. Go to the [latest release](https://github.com/yourusername/tbr-deal-finder/releases/latest)
30
+ 2. Download `TBRDealFinder-{version}-Windows.exe`
31
+ 3. **Run the Installer**: Double-click the downloaded `.exe` file
32
+ 4. **Handle Security Warning**: Windows will show "Unknown publisher"
33
+ - **Solution**: Click "More info" → Click "Run anyway"
34
+ 5. **Install**: Follow the installation wizard
35
+ 6. **Launch**: The app will be available in your Start Menu or Desktop
36
+ 7. **Wait for loader**: The app has a special loader and can take a minute to load for the first time
37
+
38
+ #### Troubleshooting Windows
39
+ - **Windows Defender blocks**: Click "More info" → "Run anyway"
40
+ - **Still blocked**: Temporarily disable real-time protection, install, then re-enable
41
+
42
+ ## 🎯 First Time Setup
43
+
44
+ ### Getting Your Reading Lists
45
+ Before using the app, export your reading lists:
46
+
47
+ #### StoryGraph Export
48
+ 1. Open [StoryGraph](https://app.thestorygraph.com/)
49
+ 2. Click your profile icon → "Manage Account"
50
+ 3. Scroll to "Manage Your Data" → "Export StoryGraph Library"
51
+ 4. Click "Generate export" → Wait and refresh → Download CSV
52
+
53
+ #### Goodreads Export
54
+ 1. Visit [Goodreads Export](https://www.goodreads.com/review/import)
55
+ 2. Click "Export Library" → Wait for email → Download CSV
56
+
57
+ #### Custom CSV
58
+ Create your own with these columns:
59
+ - `Title` (required)
60
+ - `Authors` (required)
61
+ - `Read Status` (optional: set to "to-read" for tracking)
62
+
63
+ ### Setup Wizard
64
+ 1. **Launch the App** for the first time
65
+ 2. **Follow the Setup Wizard**:
66
+ - Upload your CSV file(s)
67
+ - Select your country/region
68
+ - Set maximum price for deals
69
+ - Set minimum discount percentage
70
+ 3. **Start Finding Deals**: The app begins searching automatically
71
+
72
+ ## 🔄 Updating the Desktop App
73
+
74
+ ### Checking for Updates
75
+ Currently, updates require manual download:
76
+ 1. **Check Current Version**: Look in Settings/About section
77
+ 2. **Visit Releases**: Go to [latest releases](https://github.com/yourusername/tbr-deal-finder/releases/latest)
78
+ 3. **Compare Versions**: See if a newer version is available
79
+
80
+ ### Installing Updates
81
+
82
+ #### All Platforms
83
+ 1. **Download Latest Version**:
84
+ - macOS: `TBRDealFinder-{version}-macOS.dmg`
85
+ - Windows: `TBRDealFinder-{version}-Windows.exe`
86
+ 2. **Install Over Existing**: Follow same installation steps
87
+ - If prompted, choose to replace files or overwrite the existing application
88
+ 3. **Preserve Settings**: Your configuration and data are automatically preserved
89
+ 4. **Verify Update**: Check version in Settings after installation
90
+
91
+ ## ❓ Troubleshooting
92
+
93
+ ### App Won't Launch
94
+ - **macOS**: Right-click app → Open, check Security & Privacy settings
95
+ - **Windows**: Run as administrator, check Windows Defender
96
+
97
+ ### No Deals Found
98
+ - **Check CSV Format**: Ensure titles and authors are correct
99
+ - **Adjust Filters**: Lower discount threshold or raise price limit
100
+ - **Wait**: Deals fluctuate - check back regularly
101
+
102
+ ### Performance Issues
103
+ #### Initial Run
104
+ When the app initially starts the app may be white up to a minute while the tbr deal finder package loads.
105
+
106
+ #### Getting latest deals
107
+ Getting pricing info for Kindle can take up to a second per book.
108
+ It doesn't sound like a lot, but if you have 400 books in your tbr it may take around 7 minutes.
109
+ If you're not checking for deals on Kindle, getting deals should only take a couple minutes.
110
+ Don't close the app while getting deals or progress may be lost.
111
+
112
+ #### Still having issues
113
+ - **Restart App**: Close and reopen to clear memory
114
+ - **Update**: Ensure you're running the latest version
115
+ - **System**: Close other applications to free resources
116
+
117
+ ## 🆘 Getting Help
118
+
119
+ ### Community Support
120
+ 1. **GitHub Issues**: [Report bugs or ask questions](https://github.com/yourusername/tbr-deal-finder/issues)
121
+ 2. **Search First**: Someone might have had the same issue
122
+ 3. **Provide Details**: Include OS version, error messages, screenshots
123
+
124
+ ### What to Include in Bug Reports
125
+ - **Operating System**: macOS 12.1, Windows 11, Ubuntu 22.04, etc.
126
+ - **App Version**: Found in Settings/About
127
+ - **Error Messages**: Exact text of any errors
128
+ - **Screenshots**: Visual problems are easier to diagnose
129
+ - **Steps to Reproduce**: What you did when the problem occurred
130
+
131
+ ---
132
+
133
+ **Ready to discover amazing book deals? Download the desktop app and start saving money on your reading list!** 📚💰
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "tbr-deal-finder"
3
- version = "0.3.1"
3
+ version = "0.3.2"
4
4
  description = "Track price drops and find deals on books in your TBR list across audiobook and ebook formats."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.13"
@@ -13,11 +13,14 @@
13
13
 
14
14
  DIST_DIR="gui_dist"
15
15
  APP_NAME="TBR Deal Finder"
16
- DMG_NAME="TBR-Deal-Finder-0.2.1"
16
+ DMG_NAME="TBR-Deal-Finder-${VERSION#v}-mac"
17
17
  VOLUME_NAME="TBR Deal Finder"
18
18
  SOURCE_APP="${DIST_DIR}/app/${APP_NAME}.app"
19
19
  OUTPUT_DMG="${DIST_DIR}/${DMG_NAME}.dmg"
20
20
 
21
+ echo "📋 Using version: ${VERSION}"
22
+ echo "📦 DMG name will be: ${DMG_NAME}.dmg"
23
+
21
24
  # Determine signing approach
22
25
  if [ -z "$CODESIGN_IDENTITY" ]; then
23
26
  # Default to ad-hoc signing for local development
@@ -1,5 +1,5 @@
1
1
  from pathlib import Path
2
2
 
3
- __VERSION__ = "0.3.1"
3
+ __VERSION__ = "0.3.2"
4
4
 
5
5
  QUERY_PATH = Path(__file__).parent.joinpath("queries")
@@ -26,6 +26,7 @@ class TBRDealFinderApp:
26
26
  self.current_page = "all_deals"
27
27
  self.selected_book = None
28
28
  self.update_info = None # Store update information
29
+ self.nav_disabled = False # Track navigation disabled state
29
30
 
30
31
  # Initialize pages
31
32
  self.settings_page = SettingsPage(self)
@@ -258,6 +259,16 @@ class TBRDealFinderApp:
258
259
 
259
260
  def nav_changed(self, e):
260
261
  """Handle navigation rail selection changes"""
262
+ # Prevent navigation if disabled
263
+ if self.nav_disabled:
264
+ # Reset to current page selection to prevent visual change
265
+ current_indices = {"all_deals": 0, "latest_deals": 1, "all_books": 2}
266
+ self.nav_rail.selected_index = current_indices.get(self.current_page, 0)
267
+ # Reapply disabled state after page update
268
+ self.nav_rail.disabled = True
269
+ self.page.update()
270
+ return
271
+
261
272
  destinations = ["all_deals", "latest_deals", "all_books"]
262
273
  if e.control.selected_index < len(destinations):
263
274
  self.current_page = destinations[e.control.selected_index]
@@ -289,6 +300,23 @@ class TBRDealFinderApp:
289
300
  self.latest_deals_page.refresh_page_state()
290
301
  self.all_books_page.refresh_page_state()
291
302
 
303
+ def disable_navigation(self):
304
+ """Disable navigation rail during background operations"""
305
+ self.nav_disabled = True
306
+ if hasattr(self, 'nav_rail'):
307
+ self.nav_rail.disabled = True
308
+ self.page.update()
309
+
310
+ def enable_navigation(self):
311
+ """Enable navigation rail after background operations complete"""
312
+ if not self.nav_disabled:
313
+ return
314
+
315
+ self.nav_disabled = False
316
+ if hasattr(self, 'nav_rail'):
317
+ self.nav_rail.disabled = False
318
+ self.page.update()
319
+
292
320
  def get_current_page_content(self):
293
321
  """Get content for the current page"""
294
322
  if self.config is None and self.current_page != "settings":
@@ -309,6 +337,7 @@ class TBRDealFinderApp:
309
337
 
310
338
  def get_config_prompt(self):
311
339
  """Show config setup prompt when no config exists"""
340
+ self.disable_navigation()
312
341
  return ft.Container(
313
342
  content=ft.Column([
314
343
  ft.Icon(ft.Icons.SETTINGS, size=64, color=ft.Colors.GREY_400),
@@ -39,6 +39,9 @@ class AllBooksPage(BaseBookPage):
39
39
 
40
40
  async def _async_load_items(self):
41
41
  """Load TBR books asynchronously using Flet's async support"""
42
+ # Disable navigation during the loading operation
43
+ self.app.disable_navigation()
44
+
42
45
  try:
43
46
  # Run the async operation directly
44
47
  await self.app.auth_all_configured_retailers()
@@ -50,6 +53,10 @@ class AllBooksPage(BaseBookPage):
50
53
  self.filtered_items = []
51
54
  finally:
52
55
  self.set_loading(False)
56
+
57
+ # Re-enable navigation after the operation completes
58
+ self.app.enable_navigation()
59
+
53
60
  # Update the page to reflect the loaded data
54
61
  self.app.page.update()
55
62
 
@@ -142,8 +142,7 @@ class BaseBookPage(ABC):
142
142
  item_tiles.append(tile)
143
143
 
144
144
  return ft.Container(
145
- content=ft.ListView(item_tiles, spacing=5),
146
- height=700,
145
+ content=ft.Column(item_tiles, spacing=5),
147
146
  border=ft.border.all(1, ft.Colors.OUTLINE),
148
147
  border_radius=8,
149
148
  padding=10
@@ -274,6 +274,9 @@ class LatestDealsPage(BaseBookPage):
274
274
  self.progress_container.visible = True
275
275
  self.run_button.disabled = True
276
276
 
277
+ # Disable navigation during the operation
278
+ self.app.disable_navigation()
279
+
277
280
  # Update the page to show loading state
278
281
  self.app.page.update()
279
282
 
@@ -299,6 +302,9 @@ class LatestDealsPage(BaseBookPage):
299
302
  self.run_button.disabled = False
300
303
  self.check_last_run() # Refresh the status
301
304
 
305
+ # Re-enable navigation after the operation
306
+ self.app.enable_navigation()
307
+
302
308
  # Update the page to reset loading state
303
309
  self.app.page.update()
304
310
 
@@ -309,6 +309,7 @@ class SettingsPage:
309
309
  clear_unknown_books()
310
310
 
311
311
  self.show_success("Configuration saved successfully!")
312
+ self.app.enable_navigation()
312
313
  self.app.config_updated(self.config)
313
314
 
314
315
  except Exception as ex:
@@ -2,16 +2,14 @@ import asyncio
2
2
  import copy
3
3
  from collections import defaultdict
4
4
 
5
- import click
6
5
  import pandas as pd
7
- from tqdm.asyncio import tqdm_asyncio
8
6
 
9
7
  from tbr_deal_finder.book import Book, get_active_deals, BookFormat
10
8
  from tbr_deal_finder.config import Config
11
9
  from tbr_deal_finder.tracked_books import get_tbr_books, get_unknown_books, set_unknown_books
12
10
  from tbr_deal_finder.retailer import RETAILER_MAP
13
11
  from tbr_deal_finder.retailer.models import Retailer
14
- from tbr_deal_finder.utils import get_duckdb_conn, echo_info, echo_err, is_gui_env
12
+ from tbr_deal_finder.utils import get_duckdb_conn, echo_info, echo_err
15
13
 
16
14
 
17
15
  def update_retailer_deal_table(config: Config, new_deals: list[Book]):
@@ -67,6 +65,13 @@ async def _get_books(
67
65
  Returns:
68
66
  List of Book objects with updated pricing and availability
69
67
  """
68
+
69
+ echo_info(f"Getting deals from {retailer.name}")
70
+ books = _get_retailer_relevant_tbr_books(
71
+ retailer,
72
+ books,
73
+ )
74
+
70
75
  semaphore = asyncio.Semaphore(retailer.max_concurrency)
71
76
  response = []
72
77
  unknown_books = []
@@ -81,11 +86,7 @@ async def _get_books(
81
86
  if book.deal_id not in ignored_deal_ids
82
87
  ]
83
88
 
84
- if is_gui_env():
85
- results = await asyncio.gather(*tasks)
86
- else:
87
- results = await tqdm_asyncio.gather(*tasks, desc=f"Getting latest prices from {retailer.name}")
88
-
89
+ results = await asyncio.gather(*tasks)
89
90
  for book in results:
90
91
  if not book:
91
92
  """Cases where we know the retailer has the book but it's not coming back.
@@ -99,9 +100,7 @@ async def _get_books(
99
100
  elif not book.exists:
100
101
  unknown_books.append(book)
101
102
 
102
- click.echo()
103
- for book in unknown_books:
104
- echo_info(f"{book.title} by {book.authors} not found")
103
+ echo_info(f"Finished getting deals from {retailer.name}")
105
104
 
106
105
  return response, unknown_books
107
106
 
@@ -184,34 +183,26 @@ async def _get_latest_deals(config: Config):
184
183
  ignore_books: list[Book] = get_unknown_books(config)
185
184
  ignored_deal_ids: set[str] = {book.deal_id for book in ignore_books}
186
185
 
186
+ tasks = []
187
187
  for retailer_str in config.tracked_retailers:
188
188
  retailer = RETAILER_MAP[retailer_str]()
189
189
  await retailer.set_auth()
190
190
 
191
- relevant_tbr_books = _get_retailer_relevant_tbr_books(
192
- retailer,
193
- tbr_books,
191
+ tasks.append(
192
+ _get_books(
193
+ config,
194
+ retailer,
195
+ tbr_books,
196
+ ignored_deal_ids
197
+ )
194
198
  )
195
199
 
196
- echo_info(f"Getting deals from {retailer.name}")
197
- click.echo("\n---------------")
198
- retailer_books, u_books = await _get_books(
199
- config,
200
- retailer,
201
- relevant_tbr_books,
202
- ignored_deal_ids
203
- )
200
+ results = await asyncio.gather(*tasks)
201
+ for retailer_books, u_books in results:
204
202
  books.extend(retailer_books)
205
203
  unknown_books.extend(u_books)
206
- click.echo("---------------\n")
207
204
 
208
205
  _apply_proper_list_prices(books)
209
-
210
- books = [
211
- book
212
- for book in books
213
- ]
214
-
215
206
  update_retailer_deal_table(config, books)
216
207
  set_unknown_books(config, unknown_books)
217
208
 
@@ -27,25 +27,34 @@ def get_data_dir() -> Path:
27
27
  app_name = "TBR Deal Finder"
28
28
 
29
29
  if custom_path := os.getenv("TBR_DEAL_FINDER_CUSTOM_PATH"):
30
- path = Path(custom_path)
31
-
32
- elif not is_gui_env():
33
- path = Path.home() / ".tbr_deal_finder"
34
-
35
- elif sys.platform == "win32":
36
- # Windows: C:\Users\Username\AppData\Local\AppAuthor\AppName
37
- base = os.environ.get("LOCALAPPDATA", os.path.expanduser("~\\AppData\\Local"))
38
- path = Path(base) / app_author / app_name
39
-
40
- elif sys.platform == "darwin":
41
- # macOS: ~/Library/Application Support/AppName
42
- path = Path.home() / "Library" / "Application Support" / app_name
43
-
44
- else: # Linux and others
45
- # Linux: ~/.local/share/appname (following XDG spec)
46
- xdg_data_home = os.environ.get("XDG_DATA_HOME",
47
- os.path.expanduser("~/.local/share"))
48
- path = Path(xdg_data_home) / app_name.lower()
30
+ path = Path(custom_path).expanduser()
31
+ else:
32
+ cli_path = Path.home() / ".tbr_deal_finder"
33
+ if sys.platform == "win32":
34
+ # Windows: C:\Users\Username\AppData\Local\AppAuthor\AppName
35
+ base = os.environ.get("LOCALAPPDATA", os.path.expanduser("~\\AppData\\Local"))
36
+ gui_path = Path(base) / app_author / app_name
37
+
38
+ elif sys.platform == "darwin":
39
+ # macOS: ~/Library/Application Support/AppName
40
+ gui_path = Path.home() / "Library" / "Application Support" / app_name
41
+
42
+ else: # Linux and others
43
+ # Linux: ~/.local/share/appname (following XDG spec)
44
+ xdg_data_home = os.environ.get("XDG_DATA_HOME",
45
+ os.path.expanduser("~/.local/share"))
46
+ gui_path = Path(xdg_data_home) / app_name.lower()
47
+
48
+ if is_gui_env():
49
+ path = gui_path
50
+ if cli_path.exists() and not path.exists():
51
+ # Use the cli path if it exists and the gui path does not
52
+ path = cli_path
53
+ else:
54
+ path = cli_path
55
+ if gui_path.exists() and not path.exists():
56
+ # Use the gui path if it exists and the cli path does not
57
+ path = gui_path
49
58
 
50
59
  # Create directory if it doesn't exist
51
60
  path.mkdir(parents=True, exist_ok=True)
@@ -1181,7 +1181,7 @@ wheels = [
1181
1181
 
1182
1182
  [[package]]
1183
1183
  name = "tbr-deal-finder"
1184
- version = "0.3.1"
1184
+ version = "0.3.2"
1185
1185
  source = { editable = "." }
1186
1186
  dependencies = [
1187
1187
  { name = "aiohttp" },
@@ -1,251 +0,0 @@
1
- # Desktop App Guide
2
-
3
- Everything you need to know about installing, using, and updating the TBR Deal Finder desktop application.
4
-
5
- ## Installation
6
-
7
- The desktop app provides a beautiful graphical interface for managing your book deals without any command line knowledge required.
8
-
9
- ### 🍎 macOS Installation
10
-
11
- #### Download & Install
12
- 1. Go to the [latest release](https://github.com/yourusername/tbr-deal-finder/releases/latest)
13
- 2. Download `TBRDealFinder-{version}-macOS.dmg`
14
- 3. **Open the DMG**: Double-click the downloaded `.dmg` file
15
- 4. **Handle Security Warning**: macOS will show "Cannot verify developer"
16
- - [Opening app from unknown developer](https://support.apple.com/guide/mac-help/open-a-mac-app-from-an-unknown-developer-mh40616/mac)
17
- 5. **Install**: Drag the TBR Deal Finder app to your Applications folder
18
- 6. **Launch**: Double-click the app in Applications
19
-
20
- #### Troubleshooting macOS
21
- - **"App can't be opened"**: Use right-click → Open instead of double-clicking
22
- - **Still getting warnings**: Go to System Preferences → Security & Privacy → General → Click "Open Anyway"
23
-
24
- ### 🪟 Windows Installation
25
-
26
- #### Download & Install
27
- 1. Go to the [latest release](https://github.com/yourusername/tbr-deal-finder/releases/latest)
28
- 2. Download `TBRDealFinder-{version}-Windows.exe`
29
- 3. **Run the Installer**: Double-click the downloaded `.exe` file
30
- 4. **Handle Security Warning**: Windows will show "Unknown publisher"
31
- - **Solution**: Click "More info" → Click "Run anyway"
32
- 5. **Install**: Follow the installation wizard
33
- 6. **Launch**: The app will be available in your Start Menu or Desktop
34
-
35
- #### Troubleshooting Windows
36
- - **Windows Defender blocks**: Click "More info" → "Run anyway"
37
- - **Still blocked**: Temporarily disable real-time protection, install, then re-enable
38
-
39
- ### 🐧 Linux Installation
40
-
41
- #### Download & Install
42
- 1. Go to the [latest release](https://github.com/yourusername/tbr-deal-finder/releases/latest)
43
- 2. Download `TBRDealFinder-{version}-Linux`
44
- 3. **Make Executable**:
45
- ```bash
46
- chmod +x TBRDealFinder-{version}-Linux
47
- ```
48
- 4. **Move to Applications** (optional):
49
- ```bash
50
- sudo mv TBRDealFinder-{version}-Linux /usr/local/bin/tbr-deal-finder
51
- ```
52
- 5. **Launch**:
53
- ```bash
54
- ./TBRDealFinder-{version}-Linux
55
- # Or if moved: tbr-deal-finder
56
- ```
57
-
58
- #### Create Desktop Entry (Linux)
59
- For easier launching, create a desktop entry:
60
- ```bash
61
- cat > ~/.local/share/applications/tbr-deal-finder.desktop << EOF
62
- [Desktop Entry]
63
- Name=TBR Deal Finder
64
- Comment=Track price drops and find deals on books
65
- Exec=/path/to/TBRDealFinder-{version}-Linux
66
- Icon=applications-office
67
- Terminal=false
68
- Type=Application
69
- Categories=Office;Utility;
70
- EOF
71
- ```
72
-
73
- ## 🎯 First Time Setup
74
-
75
- ### Getting Your Reading Lists
76
- Before using the app, export your reading lists:
77
-
78
- #### StoryGraph Export
79
- 1. Open [StoryGraph](https://app.thestorygraph.com/)
80
- 2. Click your profile icon → "Manage Account"
81
- 3. Scroll to "Manage Your Data" → "Export StoryGraph Library"
82
- 4. Click "Generate export" → Wait and refresh → Download CSV
83
-
84
- #### Goodreads Export
85
- 1. Visit [Goodreads Export](https://www.goodreads.com/review/import)
86
- 2. Click "Export Library" → Wait for email → Download CSV
87
-
88
- #### Custom CSV
89
- Create your own with these columns:
90
- - `Title` (required)
91
- - `Authors` (required)
92
- - `Read Status` (optional: set to "to-read" for tracking)
93
-
94
- ### Setup Wizard
95
- 1. **Launch the App** for the first time
96
- 2. **Follow the Setup Wizard**:
97
- - Upload your CSV file(s)
98
- - Select your country/region
99
- - Set maximum price for deals
100
- - Set minimum discount percentage
101
- 3. **Start Finding Deals**: The app begins searching automatically
102
-
103
- ## 📖 Using the Desktop App
104
-
105
- ### Main Interface
106
-
107
- #### 🆕 Latest Deals View
108
- - **Purpose**: Shows newly discovered deals since your last check
109
- - **Features**: Book covers, titles, authors, current and original prices
110
- - **Actions**: Click any book for detailed information and purchase links
111
-
112
- #### 📚 All Active Deals View
113
- - **Purpose**: Browse all currently active deals
114
- - **Features**: Filter by retailer, price range, discount percentage
115
- - **Sorting**: By discount amount, price, or date discovered
116
- - **Best For**: Weekly browsing of all available deals
117
-
118
- #### 📖 All Books View
119
- - **Purpose**: Manage your tracked books library
120
- - **Features**: See all books being tracked for deals
121
- - **Actions**: Add new books or remove books from tracking
122
- - **Status**: See which books currently have active deals
123
-
124
- #### ⚙️ Settings View
125
- - **Configuration**: Update deal preferences and price limits
126
- - **Data Management**: Add new CSV files or update existing ones
127
- - **Notifications**: Configure how you want to be alerted about deals
128
- - **Account**: Manage your locale and retailer preferences
129
-
130
- ### Navigation Tips
131
- - **Side Menu**: Quick switching between views
132
- - **Search Bar**: Find specific books or authors instantly
133
- - **Filter Panel**: Narrow results by price, discount, or retailer
134
- - **Book Details**: Click any book for comprehensive information
135
-
136
- ### Understanding Deal Information
137
- Each deal displays:
138
- - **Book cover and title**
139
- - **Author name(s)**
140
- - **Original price** vs **Sale price**
141
- - **Discount percentage**
142
- - **Retailer** (Audible, Kindle, Chirp, Libro.fm)
143
- - **Deal expiration** (when available)
144
-
145
- ## 🔄 Regular Usage Workflow
146
-
147
- ### Daily Deal Checking (5 minutes)
148
- 1. **Open the App**
149
- 2. **Check Latest Deals View**
150
- 3. **Review New Discoveries**
151
- 4. **Click Through** to purchase interesting deals
152
-
153
- ### Weekly Management (15 minutes)
154
- 1. **Browse All Active Deals** for comprehensive view
155
- 2. **Update Your Library** by adding new books to track
156
- 3. **Remove Purchased Books** to keep library current
157
- 4. **Adjust Settings** if your preferences have changed
158
-
159
- ### Monthly Maintenance (30 minutes)
160
- 1. **Export Fresh Reading Lists** from StoryGraph/Goodreads
161
- 2. **Upload Updated CSVs** via Settings
162
- 3. **Review Price Limits** and adjust for seasonal sales
163
- 4. **Clean Up Library** by removing uninteresting books
164
-
165
- ## 🔄 Updating the Desktop App
166
-
167
- ### Checking for Updates
168
- Currently, updates require manual download:
169
- 1. **Check Current Version**: Look in Settings/About section
170
- 2. **Visit Releases**: Go to [latest releases](https://github.com/yourusername/tbr-deal-finder/releases/latest)
171
- 3. **Compare Versions**: See if a newer version is available
172
-
173
- ### Installing Updates
174
-
175
- #### All Platforms
176
- 1. **Download Latest Version**:
177
- - macOS: `TBRDealFinder-{version}-macOS.dmg`
178
- - Windows: `TBRDealFinder-{version}-Windows.exe`
179
- - Linux: `TBRDealFinder-{version}-Linux`
180
- 2. **Install Over Existing**: Follow same installation steps
181
- 3. **Preserve Settings**: Your configuration and data are automatically preserved
182
- 4. **Verify Update**: Check version in Settings after installation
183
-
184
- ## ❓ Troubleshooting
185
-
186
- ### App Won't Launch
187
- - **macOS**: Right-click app → Open, check Security & Privacy settings
188
- - **Windows**: Run as administrator, check Windows Defender
189
- - **Linux**: Verify file permissions (`chmod +x`)
190
-
191
- ### No Deals Found
192
- - **Check CSV Format**: Ensure titles and authors are correct
193
- - **Adjust Filters**: Lower discount threshold or raise price limit
194
- - **Wait**: Deals fluctuate - check back regularly
195
-
196
- ### Performance Issues
197
- - **Restart App**: Close and reopen to clear memory
198
- - **Update**: Ensure you're running the latest version
199
- - **System**: Close other applications to free resources
200
-
201
- ### Settings Not Saving
202
- - **Permissions**: Ensure app can write to user directory
203
- - **Restart**: Close app completely and reopen
204
- - **Reinstall**: Download fresh copy if issues persist
205
-
206
- ## 📊 System Requirements
207
-
208
- ### Minimum Requirements
209
- - **macOS**: 10.14 or later
210
- - **Windows**: Windows 10 or later
211
- - **Linux**: Modern distribution with GUI support
212
-
213
- ## 💡 What Makes This App Special
214
-
215
- ### Smart Deal Discovery
216
- - **Automated Searching**: Checks multiple retailers automatically
217
- - **Intelligent Matching**: Finds your books across different platforms
218
- - **Price Tracking**: Monitors for temporary sales and price drops
219
-
220
- ### User-Friendly Design
221
- - **No Command Line**: Everything through visual interface
222
- - **Beautiful Interface**: Modern design with book covers
223
- - **Easy Setup**: Wizard guides you through configuration
224
-
225
- ### Comprehensive Coverage
226
- - **Multiple Retailers**: Audible, Kindle, Chirp, Libro.fm
227
- - **Global Support**: Works in US, CA, UK, AU, FR, DE, JP, IT, IN, ES, BR
228
- - **Both Formats**: Audiobooks and ebooks in one place
229
-
230
- ## 🆘 Getting Help
231
-
232
- ### Self-Help Resources
233
- 1. **Check This Guide**: Most questions are answered here
234
- 2. **Try Troubleshooting**: Common issues have solutions above
235
- 3. **Update App**: Many issues are fixed in newer versions
236
-
237
- ### Community Support
238
- 1. **GitHub Issues**: [Report bugs or ask questions](https://github.com/yourusername/tbr-deal-finder/issues)
239
- 2. **Search First**: Someone might have had the same issue
240
- 3. **Provide Details**: Include OS version, error messages, screenshots
241
-
242
- ### What to Include in Bug Reports
243
- - **Operating System**: macOS 12.1, Windows 11, Ubuntu 22.04, etc.
244
- - **App Version**: Found in Settings/About
245
- - **Error Messages**: Exact text of any errors
246
- - **Screenshots**: Visual problems are easier to diagnose
247
- - **Steps to Reproduce**: What you did when the problem occurred
248
-
249
- ---
250
-
251
- **Ready to discover amazing book deals? Download the desktop app and start saving money on your reading list!** 📚💰
File without changes