ttydal 1.0.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.
- ttydal-1.0.2/PKG-INFO +240 -0
- ttydal-1.0.2/README.md +215 -0
- ttydal-1.0.2/pyproject.toml +41 -0
- ttydal-1.0.2/src/ttydal/__init__.py +47 -0
- ttydal-1.0.2/src/ttydal/api_logger.py +331 -0
- ttydal-1.0.2/src/ttydal/app.py +604 -0
- ttydal-1.0.2/src/ttydal/components/__init__.py +1 -0
- ttydal-1.0.2/src/ttydal/components/albums_list.py +366 -0
- ttydal-1.0.2/src/ttydal/components/cache_modal.py +178 -0
- ttydal-1.0.2/src/ttydal/components/login_modal.py +251 -0
- ttydal-1.0.2/src/ttydal/components/player_bar.py +165 -0
- ttydal-1.0.2/src/ttydal/components/search_modal.py +358 -0
- ttydal-1.0.2/src/ttydal/components/tracks_list.py +531 -0
- ttydal-1.0.2/src/ttydal/config.py +126 -0
- ttydal-1.0.2/src/ttydal/credentials.py +68 -0
- ttydal-1.0.2/src/ttydal/exceptions.py +302 -0
- ttydal-1.0.2/src/ttydal/logger.py +129 -0
- ttydal-1.0.2/src/ttydal/pages/__init__.py +1 -0
- ttydal-1.0.2/src/ttydal/pages/config_page.py +241 -0
- ttydal-1.0.2/src/ttydal/pages/player_page.py +176 -0
- ttydal-1.0.2/src/ttydal/player.py +244 -0
- ttydal-1.0.2/src/ttydal/services/__init__.py +188 -0
- ttydal-1.0.2/src/ttydal/services/playback_service.py +92 -0
- ttydal-1.0.2/src/ttydal/services/tracks_cache.py +175 -0
- ttydal-1.0.2/src/ttydal/tidal_client.py +427 -0
ttydal-1.0.2/PKG-INFO
ADDED
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ttydal
|
|
3
|
+
Version: 1.0.2
|
|
4
|
+
Summary: Tidal in your terminal!
|
|
5
|
+
Author: Bouteiller [a2n] Alan
|
|
6
|
+
Author-email: Bouteiller [a2n] Alan <a2n.dev@pm.me>
|
|
7
|
+
License-Expression: AGPL-3.0-or-later
|
|
8
|
+
Requires-Dist: appdirs>=1.4.4
|
|
9
|
+
Requires-Dist: cachetools>=6.2.4
|
|
10
|
+
Requires-Dist: fuzzysearch>=0.8.1
|
|
11
|
+
Requires-Dist: keyring>=25.7.0
|
|
12
|
+
Requires-Dist: mpv>=1.0.8
|
|
13
|
+
Requires-Dist: platformdirs>=4.5.1
|
|
14
|
+
Requires-Dist: pydantic>=2.12.5
|
|
15
|
+
Requires-Dist: pyperclip>=1.9.0
|
|
16
|
+
Requires-Dist: rich>=14.2.0
|
|
17
|
+
Requires-Dist: textual>=7.0.1
|
|
18
|
+
Requires-Dist: textual-dev>=1.8.0
|
|
19
|
+
Requires-Dist: tidalapi>=0.8.10
|
|
20
|
+
Requires-Python: >=3.13
|
|
21
|
+
Project-URL: Homepage, https://github.com/results-may-vary-org/ttydal
|
|
22
|
+
Project-URL: Issues, https://github.com/results-may-vary-org/ttydal/issues
|
|
23
|
+
Project-URL: Repository, https://github.com/results-may-vary-org/ttydal
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
|
|
26
|
+
<p align="center">
|
|
27
|
+
<a href="https://github.com/results-may-vary-org/ttydal">
|
|
28
|
+
<img alt="ttydal screenshot" src="assets/ttydalscreen.png"/>
|
|
29
|
+
</a>
|
|
30
|
+
</p>
|
|
31
|
+
<h1 align="center">ttydal - Tidal in your termial!</h1>
|
|
32
|
+
|
|
33
|
+
<img alt="Static Badge" src="https://img.shields.io/badge/Still_maintained-Yes_%3A)-green">
|
|
34
|
+
|
|
35
|
+
## Inspiration
|
|
36
|
+
|
|
37
|
+
This project is heavily inspired by what [Maxteabag](https://github.com/Maxteabag) have done on is awesome project [sqlit](https://github.com/Maxteabag/sqlit).
|
|
38
|
+
|
|
39
|
+
## Features
|
|
40
|
+
|
|
41
|
+
- Browse your favorite albums, playlists, and tracks
|
|
42
|
+
- Fuzzy search across all loaded albums and tracks (`/` key)
|
|
43
|
+
- High-quality audio playback with three quality levels:
|
|
44
|
+
- Max: Hi-Res Lossless (up to 24bit/192kHz)
|
|
45
|
+
- High: Lossless (16bit/44.1kHz)
|
|
46
|
+
- Low: AAC 320kbps
|
|
47
|
+
- Real-time stream quality verification showing actual bit depth and sample rate
|
|
48
|
+
- Auto-play next track
|
|
49
|
+
- Shuffle mode for randomized playback
|
|
50
|
+
- Visual indicators showing currently playing track and source album/playlist
|
|
51
|
+
- Playback controls with seeking support
|
|
52
|
+
- Smart tracks caching for faster navigation and search
|
|
53
|
+
- Player bar displaying track info, artist, album, playback time, and quality metrics
|
|
54
|
+
- Multiple theme options for interface customization
|
|
55
|
+
- Fully keyboard-driven interface
|
|
56
|
+
- Settings auto-save on change
|
|
57
|
+
|
|
58
|
+
## Requirements
|
|
59
|
+
|
|
60
|
+
- Python 3.13 or higher
|
|
61
|
+
- [uv](https://docs.astral.sh/uv/) for development
|
|
62
|
+
- Active Tidal subscription
|
|
63
|
+
- MPV media player (for audio playback)
|
|
64
|
+
|
|
65
|
+
## Installation
|
|
66
|
+
|
|
67
|
+
### For users
|
|
68
|
+
|
|
69
|
+
Package deployement in progess :)
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
# pipx
|
|
73
|
+
pipx install sqlit-tui
|
|
74
|
+
|
|
75
|
+
# uv
|
|
76
|
+
uv tool install sqlit-tui
|
|
77
|
+
|
|
78
|
+
# pip
|
|
79
|
+
pip install sqlit-tui
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### For development
|
|
83
|
+
|
|
84
|
+
1. Clone the repository:
|
|
85
|
+
```bash
|
|
86
|
+
git clone https://github.com/results-may-vary-org/ttydal.git
|
|
87
|
+
cd ttydal
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
2. Install dependencies using uv:
|
|
91
|
+
```bash
|
|
92
|
+
uv sync
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
3. Run the application:
|
|
96
|
+
```bash
|
|
97
|
+
uv run ttydal
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
4. For development with auto-reload (optional):
|
|
101
|
+
|
|
102
|
+
Install watchdog for automatic restart on file changes:
|
|
103
|
+
```bash
|
|
104
|
+
uv add --dev watchdog
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Run with the development watcher:
|
|
108
|
+
```bash
|
|
109
|
+
python dev.py
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
This will automatically restart the application whenever you save changes to Python files.
|
|
113
|
+
|
|
114
|
+
## Getting started
|
|
115
|
+
|
|
116
|
+
1. Launch ttydal
|
|
117
|
+
2. On first run, you'll see a login modal
|
|
118
|
+
3. Press `o` to open the Tidal login URL in your browser
|
|
119
|
+
4. Complete the authentication in your browser
|
|
120
|
+
5. Press `l` to check login status
|
|
121
|
+
6. Once logged in, your favorite albums, playlists, and tracks will load automatically
|
|
122
|
+
|
|
123
|
+
## Keybindings
|
|
124
|
+
|
|
125
|
+
### Navigation
|
|
126
|
+
|
|
127
|
+
| Key | Action |
|
|
128
|
+
|-----|--------|
|
|
129
|
+
| `p` | Switch to Player page |
|
|
130
|
+
| `c` | Switch to Config page |
|
|
131
|
+
| `a` | Focus Albums/Playlists list |
|
|
132
|
+
| `t` | Focus Tracks list |
|
|
133
|
+
| `up/down` | Navigate through lists |
|
|
134
|
+
| `enter` | Select item / Play track (always starts from beginning) |
|
|
135
|
+
| `/` | Open fuzzy search |
|
|
136
|
+
|
|
137
|
+
### Search Modal
|
|
138
|
+
|
|
139
|
+
| Key | Action |
|
|
140
|
+
|-----|--------|
|
|
141
|
+
| `enter` | Navigate to selected album/track |
|
|
142
|
+
| `space` | Play selected track (tracks only) |
|
|
143
|
+
| `escape` | Close search |
|
|
144
|
+
|
|
145
|
+
### Playback Controls
|
|
146
|
+
|
|
147
|
+
| Key | Action |
|
|
148
|
+
|-----|--------|
|
|
149
|
+
| `space` | Toggle play/pause (works anywhere on player page) |
|
|
150
|
+
| `shift+left` | Seek backward 10 seconds |
|
|
151
|
+
| `shift+right` | Seek forward 10 seconds |
|
|
152
|
+
| `N` (shift+n) | Play next track |
|
|
153
|
+
| `P` (shift+p) | Play previous track |
|
|
154
|
+
| `n` | Toggle auto-play next track on/off |
|
|
155
|
+
| `s` | Toggle shuffle mode on/off |
|
|
156
|
+
| `r` | Refresh current list (also clears relevant cache) |
|
|
157
|
+
| `i` | Open cache info modal |
|
|
158
|
+
|
|
159
|
+
### Login Modal
|
|
160
|
+
|
|
161
|
+
| Key | Action |
|
|
162
|
+
|-----|--------|
|
|
163
|
+
| `o` | Open login URL in browser |
|
|
164
|
+
| `c` | Copy login URL to clipboard |
|
|
165
|
+
| `l` | Check login status |
|
|
166
|
+
| `escape` | Close modal |
|
|
167
|
+
|
|
168
|
+
### Application
|
|
169
|
+
|
|
170
|
+
| Key | Action |
|
|
171
|
+
|-----|--------|
|
|
172
|
+
| `q` | Quit application |
|
|
173
|
+
|
|
174
|
+
## Configuration
|
|
175
|
+
|
|
176
|
+
All settings are accessible via the Config page (press `c`).
|
|
177
|
+
|
|
178
|
+
### Settings
|
|
179
|
+
|
|
180
|
+
- **Theme**: choose from 12 built-in themes
|
|
181
|
+
- **Audio Quality**: select default quality for your playback (max, high, or low)
|
|
182
|
+
- **Auto-Play**: enable or disable automatic playback of next track
|
|
183
|
+
- **Shuffle**: enable or disable shuffle mode
|
|
184
|
+
- **Debug Logging**: enable or disable debug logging to `~/.ttydal/debug.log`
|
|
185
|
+
- **API Logging**: *these logs can contains sensitive data* enable or disable API request/response logging to `~/.ttydal/debug-api.log`
|
|
186
|
+
|
|
187
|
+
All settings are automatically saved when changed.
|
|
188
|
+
|
|
189
|
+
## Tracks cache
|
|
190
|
+
|
|
191
|
+
ttydal uses an intelligent caching system for tracks to improve performance and enable smart search.
|
|
192
|
+
|
|
193
|
+
### How it works
|
|
194
|
+
|
|
195
|
+
- In-memory cache: tracks are cached in memory (lost on app restart)
|
|
196
|
+
- TTL of 1 hour: each cached album/playlist expires after 1 hour
|
|
197
|
+
- Max 50,000 tracks: cache is limited by total track count, not album count.
|
|
198
|
+
- LRU eviction: when cache is full, oldest entries are evicted first
|
|
199
|
+
- Auto-preload: on startup, all albums are automatically preloaded into cache in the background (mostly for the search feature)
|
|
200
|
+
|
|
201
|
+
### Cache info modal
|
|
202
|
+
|
|
203
|
+
Press `i` to open the cache info modal and see current cache statistics.
|
|
204
|
+
|
|
205
|
+
### Cache invalidation
|
|
206
|
+
|
|
207
|
+
If you make changes to your playlists/favorites on the Tidal website:
|
|
208
|
+
|
|
209
|
+
- Press `r` on *Albums* list that clears the entire tracks cache and reloads albums
|
|
210
|
+
- Press `r` on *Tracks* list that invalidates only the current album/playlist cache and reloads
|
|
211
|
+
|
|
212
|
+
## Code of conduct, license, authors, changelog, contributing
|
|
213
|
+
|
|
214
|
+
See the following file :
|
|
215
|
+
- [code of conduct](CODE_OF_CONDUCT.md)
|
|
216
|
+
- [license](LICENSE)
|
|
217
|
+
- [authors](AUTHORS)
|
|
218
|
+
- [contributing](CONTRIBUTING.md)
|
|
219
|
+
- [changelog](CHANGELOG)
|
|
220
|
+
- [security](SECURITY.md)
|
|
221
|
+
|
|
222
|
+
## Want to participate? Have a bug or a request feature?
|
|
223
|
+
|
|
224
|
+
Do not hesitate to open a pr or an issue. I reply when I can.
|
|
225
|
+
|
|
226
|
+
### This project is possible because another cool projects exist
|
|
227
|
+
|
|
228
|
+
- [sqlit](https://github.com/Maxteabag/sqlit)
|
|
229
|
+
- [textual](https://textual.textualize.io/)
|
|
230
|
+
- [uv](https://docs.astral.sh/uv/)
|
|
231
|
+
- [tidalapi](https://pypi.org/project/tidalapi/)
|
|
232
|
+
|
|
233
|
+
## Want to support my work?
|
|
234
|
+
|
|
235
|
+
- [Give me a tips](https://github.com/sponsors/bouteillerAlan)
|
|
236
|
+
- [Give a star on github](https://github.com/results-may-vary-org/ttydal)
|
|
237
|
+
- Or just participate to the development :D
|
|
238
|
+
|
|
239
|
+
### Thanks !
|
|
240
|
+
|
ttydal-1.0.2/README.md
ADDED
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<a href="https://github.com/results-may-vary-org/ttydal">
|
|
3
|
+
<img alt="ttydal screenshot" src="assets/ttydalscreen.png"/>
|
|
4
|
+
</a>
|
|
5
|
+
</p>
|
|
6
|
+
<h1 align="center">ttydal - Tidal in your termial!</h1>
|
|
7
|
+
|
|
8
|
+
<img alt="Static Badge" src="https://img.shields.io/badge/Still_maintained-Yes_%3A)-green">
|
|
9
|
+
|
|
10
|
+
## Inspiration
|
|
11
|
+
|
|
12
|
+
This project is heavily inspired by what [Maxteabag](https://github.com/Maxteabag) have done on is awesome project [sqlit](https://github.com/Maxteabag/sqlit).
|
|
13
|
+
|
|
14
|
+
## Features
|
|
15
|
+
|
|
16
|
+
- Browse your favorite albums, playlists, and tracks
|
|
17
|
+
- Fuzzy search across all loaded albums and tracks (`/` key)
|
|
18
|
+
- High-quality audio playback with three quality levels:
|
|
19
|
+
- Max: Hi-Res Lossless (up to 24bit/192kHz)
|
|
20
|
+
- High: Lossless (16bit/44.1kHz)
|
|
21
|
+
- Low: AAC 320kbps
|
|
22
|
+
- Real-time stream quality verification showing actual bit depth and sample rate
|
|
23
|
+
- Auto-play next track
|
|
24
|
+
- Shuffle mode for randomized playback
|
|
25
|
+
- Visual indicators showing currently playing track and source album/playlist
|
|
26
|
+
- Playback controls with seeking support
|
|
27
|
+
- Smart tracks caching for faster navigation and search
|
|
28
|
+
- Player bar displaying track info, artist, album, playback time, and quality metrics
|
|
29
|
+
- Multiple theme options for interface customization
|
|
30
|
+
- Fully keyboard-driven interface
|
|
31
|
+
- Settings auto-save on change
|
|
32
|
+
|
|
33
|
+
## Requirements
|
|
34
|
+
|
|
35
|
+
- Python 3.13 or higher
|
|
36
|
+
- [uv](https://docs.astral.sh/uv/) for development
|
|
37
|
+
- Active Tidal subscription
|
|
38
|
+
- MPV media player (for audio playback)
|
|
39
|
+
|
|
40
|
+
## Installation
|
|
41
|
+
|
|
42
|
+
### For users
|
|
43
|
+
|
|
44
|
+
Package deployement in progess :)
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
# pipx
|
|
48
|
+
pipx install sqlit-tui
|
|
49
|
+
|
|
50
|
+
# uv
|
|
51
|
+
uv tool install sqlit-tui
|
|
52
|
+
|
|
53
|
+
# pip
|
|
54
|
+
pip install sqlit-tui
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### For development
|
|
58
|
+
|
|
59
|
+
1. Clone the repository:
|
|
60
|
+
```bash
|
|
61
|
+
git clone https://github.com/results-may-vary-org/ttydal.git
|
|
62
|
+
cd ttydal
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
2. Install dependencies using uv:
|
|
66
|
+
```bash
|
|
67
|
+
uv sync
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
3. Run the application:
|
|
71
|
+
```bash
|
|
72
|
+
uv run ttydal
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
4. For development with auto-reload (optional):
|
|
76
|
+
|
|
77
|
+
Install watchdog for automatic restart on file changes:
|
|
78
|
+
```bash
|
|
79
|
+
uv add --dev watchdog
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Run with the development watcher:
|
|
83
|
+
```bash
|
|
84
|
+
python dev.py
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
This will automatically restart the application whenever you save changes to Python files.
|
|
88
|
+
|
|
89
|
+
## Getting started
|
|
90
|
+
|
|
91
|
+
1. Launch ttydal
|
|
92
|
+
2. On first run, you'll see a login modal
|
|
93
|
+
3. Press `o` to open the Tidal login URL in your browser
|
|
94
|
+
4. Complete the authentication in your browser
|
|
95
|
+
5. Press `l` to check login status
|
|
96
|
+
6. Once logged in, your favorite albums, playlists, and tracks will load automatically
|
|
97
|
+
|
|
98
|
+
## Keybindings
|
|
99
|
+
|
|
100
|
+
### Navigation
|
|
101
|
+
|
|
102
|
+
| Key | Action |
|
|
103
|
+
|-----|--------|
|
|
104
|
+
| `p` | Switch to Player page |
|
|
105
|
+
| `c` | Switch to Config page |
|
|
106
|
+
| `a` | Focus Albums/Playlists list |
|
|
107
|
+
| `t` | Focus Tracks list |
|
|
108
|
+
| `up/down` | Navigate through lists |
|
|
109
|
+
| `enter` | Select item / Play track (always starts from beginning) |
|
|
110
|
+
| `/` | Open fuzzy search |
|
|
111
|
+
|
|
112
|
+
### Search Modal
|
|
113
|
+
|
|
114
|
+
| Key | Action |
|
|
115
|
+
|-----|--------|
|
|
116
|
+
| `enter` | Navigate to selected album/track |
|
|
117
|
+
| `space` | Play selected track (tracks only) |
|
|
118
|
+
| `escape` | Close search |
|
|
119
|
+
|
|
120
|
+
### Playback Controls
|
|
121
|
+
|
|
122
|
+
| Key | Action |
|
|
123
|
+
|-----|--------|
|
|
124
|
+
| `space` | Toggle play/pause (works anywhere on player page) |
|
|
125
|
+
| `shift+left` | Seek backward 10 seconds |
|
|
126
|
+
| `shift+right` | Seek forward 10 seconds |
|
|
127
|
+
| `N` (shift+n) | Play next track |
|
|
128
|
+
| `P` (shift+p) | Play previous track |
|
|
129
|
+
| `n` | Toggle auto-play next track on/off |
|
|
130
|
+
| `s` | Toggle shuffle mode on/off |
|
|
131
|
+
| `r` | Refresh current list (also clears relevant cache) |
|
|
132
|
+
| `i` | Open cache info modal |
|
|
133
|
+
|
|
134
|
+
### Login Modal
|
|
135
|
+
|
|
136
|
+
| Key | Action |
|
|
137
|
+
|-----|--------|
|
|
138
|
+
| `o` | Open login URL in browser |
|
|
139
|
+
| `c` | Copy login URL to clipboard |
|
|
140
|
+
| `l` | Check login status |
|
|
141
|
+
| `escape` | Close modal |
|
|
142
|
+
|
|
143
|
+
### Application
|
|
144
|
+
|
|
145
|
+
| Key | Action |
|
|
146
|
+
|-----|--------|
|
|
147
|
+
| `q` | Quit application |
|
|
148
|
+
|
|
149
|
+
## Configuration
|
|
150
|
+
|
|
151
|
+
All settings are accessible via the Config page (press `c`).
|
|
152
|
+
|
|
153
|
+
### Settings
|
|
154
|
+
|
|
155
|
+
- **Theme**: choose from 12 built-in themes
|
|
156
|
+
- **Audio Quality**: select default quality for your playback (max, high, or low)
|
|
157
|
+
- **Auto-Play**: enable or disable automatic playback of next track
|
|
158
|
+
- **Shuffle**: enable or disable shuffle mode
|
|
159
|
+
- **Debug Logging**: enable or disable debug logging to `~/.ttydal/debug.log`
|
|
160
|
+
- **API Logging**: *these logs can contains sensitive data* enable or disable API request/response logging to `~/.ttydal/debug-api.log`
|
|
161
|
+
|
|
162
|
+
All settings are automatically saved when changed.
|
|
163
|
+
|
|
164
|
+
## Tracks cache
|
|
165
|
+
|
|
166
|
+
ttydal uses an intelligent caching system for tracks to improve performance and enable smart search.
|
|
167
|
+
|
|
168
|
+
### How it works
|
|
169
|
+
|
|
170
|
+
- In-memory cache: tracks are cached in memory (lost on app restart)
|
|
171
|
+
- TTL of 1 hour: each cached album/playlist expires after 1 hour
|
|
172
|
+
- Max 50,000 tracks: cache is limited by total track count, not album count.
|
|
173
|
+
- LRU eviction: when cache is full, oldest entries are evicted first
|
|
174
|
+
- Auto-preload: on startup, all albums are automatically preloaded into cache in the background (mostly for the search feature)
|
|
175
|
+
|
|
176
|
+
### Cache info modal
|
|
177
|
+
|
|
178
|
+
Press `i` to open the cache info modal and see current cache statistics.
|
|
179
|
+
|
|
180
|
+
### Cache invalidation
|
|
181
|
+
|
|
182
|
+
If you make changes to your playlists/favorites on the Tidal website:
|
|
183
|
+
|
|
184
|
+
- Press `r` on *Albums* list that clears the entire tracks cache and reloads albums
|
|
185
|
+
- Press `r` on *Tracks* list that invalidates only the current album/playlist cache and reloads
|
|
186
|
+
|
|
187
|
+
## Code of conduct, license, authors, changelog, contributing
|
|
188
|
+
|
|
189
|
+
See the following file :
|
|
190
|
+
- [code of conduct](CODE_OF_CONDUCT.md)
|
|
191
|
+
- [license](LICENSE)
|
|
192
|
+
- [authors](AUTHORS)
|
|
193
|
+
- [contributing](CONTRIBUTING.md)
|
|
194
|
+
- [changelog](CHANGELOG)
|
|
195
|
+
- [security](SECURITY.md)
|
|
196
|
+
|
|
197
|
+
## Want to participate? Have a bug or a request feature?
|
|
198
|
+
|
|
199
|
+
Do not hesitate to open a pr or an issue. I reply when I can.
|
|
200
|
+
|
|
201
|
+
### This project is possible because another cool projects exist
|
|
202
|
+
|
|
203
|
+
- [sqlit](https://github.com/Maxteabag/sqlit)
|
|
204
|
+
- [textual](https://textual.textualize.io/)
|
|
205
|
+
- [uv](https://docs.astral.sh/uv/)
|
|
206
|
+
- [tidalapi](https://pypi.org/project/tidalapi/)
|
|
207
|
+
|
|
208
|
+
## Want to support my work?
|
|
209
|
+
|
|
210
|
+
- [Give me a tips](https://github.com/sponsors/bouteillerAlan)
|
|
211
|
+
- [Give a star on github](https://github.com/results-may-vary-org/ttydal)
|
|
212
|
+
- Or just participate to the development :D
|
|
213
|
+
|
|
214
|
+
### Thanks !
|
|
215
|
+
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "ttydal"
|
|
3
|
+
version = "1.0.2"
|
|
4
|
+
description = "Tidal in your terminal!"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = "AGPL-3.0-or-later"
|
|
7
|
+
authors = [
|
|
8
|
+
{ name = "Bouteiller [a2n] Alan", email = "a2n.dev@pm.me" }
|
|
9
|
+
]
|
|
10
|
+
requires-python = ">=3.13"
|
|
11
|
+
dependencies = [
|
|
12
|
+
"appdirs>=1.4.4",
|
|
13
|
+
"cachetools>=6.2.4",
|
|
14
|
+
"fuzzysearch>=0.8.1",
|
|
15
|
+
"keyring>=25.7.0",
|
|
16
|
+
"mpv>=1.0.8",
|
|
17
|
+
"platformdirs>=4.5.1",
|
|
18
|
+
"pydantic>=2.12.5",
|
|
19
|
+
"pyperclip>=1.9.0",
|
|
20
|
+
"rich>=14.2.0",
|
|
21
|
+
"textual>=7.0.1",
|
|
22
|
+
"textual-dev>=1.8.0",
|
|
23
|
+
"tidalapi>=0.8.10",
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
[project.urls]
|
|
27
|
+
Homepage = "https://github.com/results-may-vary-org/ttydal"
|
|
28
|
+
Repository = "https://github.com/results-may-vary-org/ttydal"
|
|
29
|
+
Issues = "https://github.com/results-may-vary-org/ttydal/issues"
|
|
30
|
+
|
|
31
|
+
[project.scripts]
|
|
32
|
+
ttydal = "ttydal:main"
|
|
33
|
+
|
|
34
|
+
[build-system]
|
|
35
|
+
requires = ["uv_build>=0.9.22,<0.10.0"]
|
|
36
|
+
build-backend = "uv_build"
|
|
37
|
+
|
|
38
|
+
[dependency-groups]
|
|
39
|
+
dev = [
|
|
40
|
+
"watchdog>=6.0.0",
|
|
41
|
+
]
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"""ttydal - Tidal in your terminal!"""
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
import traceback
|
|
5
|
+
from ttydal.logger import log
|
|
6
|
+
from ttydal.app import TtydalApp
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def main() -> None:
|
|
10
|
+
"""Launch the ttydal TUI application."""
|
|
11
|
+
log("="*80)
|
|
12
|
+
log("Starting ttydal application")
|
|
13
|
+
log("="*80)
|
|
14
|
+
|
|
15
|
+
app = None
|
|
16
|
+
try:
|
|
17
|
+
log("Creating TtydalApp instance...")
|
|
18
|
+
app = TtydalApp()
|
|
19
|
+
log("TtydalApp instance created successfully")
|
|
20
|
+
|
|
21
|
+
log("Starting app.run()...")
|
|
22
|
+
app.run()
|
|
23
|
+
log("App.run() completed normally")
|
|
24
|
+
except KeyboardInterrupt:
|
|
25
|
+
log("Received KeyboardInterrupt (Ctrl+C)")
|
|
26
|
+
except Exception as e:
|
|
27
|
+
log(f"ERROR: Exception caught in main: {e}")
|
|
28
|
+
log(f"Exception type: {type(e).__name__}")
|
|
29
|
+
log("Full traceback:")
|
|
30
|
+
log(traceback.format_exc())
|
|
31
|
+
|
|
32
|
+
print(f"Error starting ttydal: {e}", file=sys.stderr)
|
|
33
|
+
traceback.print_exc()
|
|
34
|
+
sys.exit(1)
|
|
35
|
+
finally:
|
|
36
|
+
log("Performing final cleanup...")
|
|
37
|
+
if app is not None:
|
|
38
|
+
try:
|
|
39
|
+
# Ensure player is shutdown
|
|
40
|
+
if hasattr(app, 'player'):
|
|
41
|
+
log(" - Final player shutdown check...")
|
|
42
|
+
app.player.shutdown()
|
|
43
|
+
except Exception as e:
|
|
44
|
+
log(f" - Error during final cleanup: {e}")
|
|
45
|
+
log("Application exited")
|
|
46
|
+
log("="*80)
|
|
47
|
+
|