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.
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/.github/workflows/build-release-dmg.yml +1 -0
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/.github/workflows/build-release-exe.yml +3 -3
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/CHANGELOG.md +12 -0
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/PKG-INFO +1 -1
- tbr_deal_finder-0.3.2/docs/desktop-app.md +133 -0
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/pyproject.toml +1 -1
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/scripts/packaging/create_dmg.sh +4 -1
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/__init__.py +1 -1
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/gui/main.py +29 -0
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/gui/pages/all_books.py +7 -0
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/gui/pages/base_book_page.py +1 -2
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/gui/pages/latest_deals.py +6 -0
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/gui/pages/settings.py +1 -0
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/retailer_deal.py +20 -29
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/utils.py +28 -19
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/uv.lock +1 -1
- tbr_deal_finder-0.3.1/docs/desktop-app.md +0 -251
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/.github/workflows/publish-to-pypi.yaml +0 -0
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/.gitignore +0 -0
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/.python-version +0 -0
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/DESIGN.md +0 -0
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/LICENSE +0 -0
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/Makefile +0 -0
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/README.md +0 -0
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/assets/icon.ico +0 -0
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/assets/icon.png +0 -0
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/docs/development.md +0 -0
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/docs/python-cli.md +0 -0
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/__main__.py +0 -0
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/book.py +0 -0
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/cli.py +0 -0
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/config.py +0 -0
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/desktop_updater.py +0 -0
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/gui/__init__.py +0 -0
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/gui/pages/__init__.py +0 -0
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/gui/pages/all_deals.py +0 -0
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/gui/pages/book_details.py +0 -0
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/migrations.py +0 -0
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/owned_books.py +0 -0
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/queries/get_active_deals.sql +0 -0
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/queries/get_deals_found_at.sql +0 -0
- {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
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/queries/latest_unknown_book_sync.sql +0 -0
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/retailer/__init__.py +0 -0
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/retailer/amazon.py +0 -0
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/retailer/amazon_custom_auth.py +0 -0
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/retailer/audible.py +0 -0
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/retailer/chirp.py +0 -0
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/retailer/kindle.py +0 -0
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/retailer/librofm.py +0 -0
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/retailer/models.py +0 -0
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/tracked_books.py +0 -0
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/version_check.py +0 -0
- {tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder.py +0 -0
@@ -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:
|
@@ -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!** 📚💰
|
@@ -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-
|
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
|
@@ -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.
|
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
|
|
@@ -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
|
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
|
-
|
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
|
-
|
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
|
-
|
192
|
-
|
193
|
-
|
191
|
+
tasks.append(
|
192
|
+
_get_books(
|
193
|
+
config,
|
194
|
+
retailer,
|
195
|
+
tbr_books,
|
196
|
+
ignored_deal_ids
|
197
|
+
)
|
194
198
|
)
|
195
199
|
|
196
|
-
|
197
|
-
|
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
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
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)
|
@@ -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
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/queries/get_active_deals.sql
RENAMED
File without changes
|
{tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/queries/get_deals_found_at.sql
RENAMED
File without changes
|
File without changes
|
{tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/queries/latest_unknown_book_sync.sql
RENAMED
File without changes
|
File without changes
|
File without changes
|
{tbr_deal_finder-0.3.1 → tbr_deal_finder-0.3.2}/tbr_deal_finder/retailer/amazon_custom_auth.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|