kabooz 0.1.0__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 (66) hide show
  1. kabooz-0.1.0/.github/workflows/publish.yml +75 -0
  2. kabooz-0.1.0/.gitignore +3 -0
  3. kabooz-0.1.0/CREDITS.md +150 -0
  4. kabooz-0.1.0/DEVLOG.md +40 -0
  5. kabooz-0.1.0/LICENSE +661 -0
  6. kabooz-0.1.0/PKG-INFO +372 -0
  7. kabooz-0.1.0/README.md +336 -0
  8. kabooz-0.1.0/docs/architecture.md +197 -0
  9. kabooz-0.1.0/docs/authentication.md +112 -0
  10. kabooz-0.1.0/docs/cli.md +460 -0
  11. kabooz-0.1.0/docs/configuration.md +160 -0
  12. kabooz-0.1.0/docs/contributing.md +123 -0
  13. kabooz-0.1.0/docs/installation.md +43 -0
  14. kabooz-0.1.0/docs/library.md +405 -0
  15. kabooz-0.1.0/docs/naming.md +162 -0
  16. kabooz-0.1.0/kabooz/__init__.py +32 -0
  17. kabooz-0.1.0/kabooz/auth/__init__.py +3 -0
  18. kabooz-0.1.0/kabooz/auth/credentials.py +234 -0
  19. kabooz-0.1.0/kabooz/auth/session.py +111 -0
  20. kabooz-0.1.0/kabooz/cli.py +2036 -0
  21. kabooz-0.1.0/kabooz/client.py +1338 -0
  22. kabooz-0.1.0/kabooz/config.py +280 -0
  23. kabooz-0.1.0/kabooz/data/__init__.py +0 -0
  24. kabooz-0.1.0/kabooz/data/dev_audio.opus +0 -0
  25. kabooz-0.1.0/kabooz/dev.py +310 -0
  26. kabooz-0.1.0/kabooz/download/__init__.py +12 -0
  27. kabooz-0.1.0/kabooz/download/credits.py +174 -0
  28. kabooz-0.1.0/kabooz/download/downloader.py +604 -0
  29. kabooz-0.1.0/kabooz/download/lyrics.py +156 -0
  30. kabooz-0.1.0/kabooz/download/musicbrainz.py +152 -0
  31. kabooz-0.1.0/kabooz/download/naming.py +289 -0
  32. kabooz-0.1.0/kabooz/download/tagger.py +493 -0
  33. kabooz-0.1.0/kabooz/exceptions.py +103 -0
  34. kabooz-0.1.0/kabooz/local/__init__.py +38 -0
  35. kabooz-0.1.0/kabooz/local/export.py +582 -0
  36. kabooz-0.1.0/kabooz/local/playlist.py +211 -0
  37. kabooz-0.1.0/kabooz/local/store.py +421 -0
  38. kabooz-0.1.0/kabooz/models/__init__.py +24 -0
  39. kabooz-0.1.0/kabooz/models/album.py +195 -0
  40. kabooz-0.1.0/kabooz/models/artist.py +80 -0
  41. kabooz-0.1.0/kabooz/models/common.py +183 -0
  42. kabooz-0.1.0/kabooz/models/favorites.py +123 -0
  43. kabooz-0.1.0/kabooz/models/playlist.py +164 -0
  44. kabooz-0.1.0/kabooz/models/release.py +223 -0
  45. kabooz-0.1.0/kabooz/models/search.py +202 -0
  46. kabooz-0.1.0/kabooz/models/track.py +179 -0
  47. kabooz-0.1.0/kabooz/models/user.py +143 -0
  48. kabooz-0.1.0/kabooz/quality.py +48 -0
  49. kabooz-0.1.0/kabooz/session.py +1734 -0
  50. kabooz-0.1.0/kabooz/tui.py +1178 -0
  51. kabooz-0.1.0/kabooz/tui_curses.py +1067 -0
  52. kabooz-0.1.0/kabooz/url.py +93 -0
  53. kabooz-0.1.0/pyproject.toml +62 -0
  54. kabooz-0.1.0/scratch.py +453 -0
  55. kabooz-0.1.0/scripts/make_dev_audio.py +82 -0
  56. kabooz-0.1.0/tests/test_catalog.py +358 -0
  57. kabooz-0.1.0/tests/test_client.py +221 -0
  58. kabooz-0.1.0/tests/test_downloader.py +280 -0
  59. kabooz-0.1.0/tests/test_imports.py +429 -0
  60. kabooz-0.1.0/tests/test_local.py +425 -0
  61. kabooz-0.1.0/tests/test_models.py +390 -0
  62. kabooz-0.1.0/tests/test_new_models.py +366 -0
  63. kabooz-0.1.0/tests/test_session_persistence.py +108 -0
  64. kabooz-0.1.0/tests/test_tagger.py +338 -0
  65. kabooz-0.1.0/tests/test_url.py +61 -0
  66. kabooz-0.1.0/tools/devlog.py +721 -0
@@ -0,0 +1,75 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*" # triggers on v0.1.0, v1.2.3, etc.
7
+
8
+ jobs:
9
+ build:
10
+ name: Build distribution
11
+ runs-on: ubuntu-latest
12
+
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+
16
+ - name: Set up Python
17
+ uses: actions/setup-python@v5
18
+ with:
19
+ python-version: "3.11"
20
+
21
+ - name: Install build tools
22
+ run: pip install build
23
+
24
+ - name: Build wheel and sdist
25
+ run: python -m build
26
+
27
+ - name: Store distribution artifacts
28
+ uses: actions/upload-artifact@v4
29
+ with:
30
+ name: dist
31
+ path: dist/
32
+
33
+ publish-pypi:
34
+ name: Publish to PyPI
35
+ needs: build
36
+ runs-on: ubuntu-latest
37
+
38
+ steps:
39
+ - name: Download distribution artifacts
40
+ uses: actions/download-artifact@v4
41
+ with:
42
+ name: dist
43
+ path: dist/
44
+
45
+ - name: Publish to PyPI
46
+ uses: pypa/gh-action-pypi-publish@release/v1
47
+ with:
48
+ password: ${{ secrets.PYPI_API_TOKEN }}
49
+
50
+ github-release:
51
+ name: Create GitHub release
52
+ needs: build
53
+ runs-on: ubuntu-latest
54
+
55
+ permissions:
56
+ contents: write
57
+
58
+ steps:
59
+ - uses: actions/checkout@v4
60
+
61
+ - name: Download distribution artifacts
62
+ uses: actions/download-artifact@v4
63
+ with:
64
+ name: dist
65
+ path: dist/
66
+
67
+ - name: Create GitHub release
68
+ env:
69
+ GITHUB_TOKEN: ${{ github.token }}
70
+ run: |
71
+ gh release create "${{ github.ref_name }}" \
72
+ --title "Kabooz ${{ github.ref_name }}" \
73
+ --generate-notes \
74
+ dist/*
75
+
@@ -0,0 +1,3 @@
1
+ *.pyc
2
+ *.txt
3
+ .devlog*
@@ -0,0 +1,150 @@
1
+ # Credits
2
+
3
+ Kabooz exists because of the people and services below. This file is an attempt
4
+ to give proper credit rather than just a bullet list.
5
+
6
+ ---
7
+
8
+ ## Qobuz
9
+
10
+ *https://www.qobuz.com*
11
+
12
+ Kabooz would be a meaningless piece of software without Qobuz. It is worth saying
13
+ that plainly, even in a tool that talks to Qobuz's API without official sanction.
14
+
15
+ Qobuz is one of the few streaming services that has genuinely cared about music as
16
+ an art form rather than as content. In an industry that spent years training people
17
+ to think music was worth nothing — a monthly fee for infinite disposable background
18
+ noise — Qobuz held a different position. It insisted that the recording quality
19
+ mattered, that the people who made the music deserved to be paid properly, and that
20
+ the listeners who wanted more than a compressed MP3 deserved to get it.
21
+
22
+ The catalog is serious. Not just the obvious canonical recordings, but deep cuts,
23
+ obscure chamber music, early music on period instruments, jazz from labels most
24
+ people have never heard of, folk traditions from places most streaming algorithms
25
+ would never surface. The kind of catalog that a person who actually listens to music
26
+ built, not one assembled by a recommendation engine optimizing for passive listening
27
+ time.
28
+
29
+ The hi-res audio is real. Not upsampled. The bit depths and sampling rates on offer
30
+ correspond to actual source material, which matters in ways that are hard to explain
31
+ to someone who hasn't heard the difference but immediately obvious to someone who has.
32
+ A 24-bit 96 kHz transfer of an analogue master sounds different from a 16-bit 44.1 kHz
33
+ version of the same recording. Sometimes profoundly so. Qobuz provides that access.
34
+
35
+ The business model is honest. You pay a subscription. Qobuz pays the labels and
36
+ through them, artists. There are no advertisements. The service does not harvest and
37
+ sell your listening data as its primary product. The money flows from the person who
38
+ wants to listen to music toward the people who made it, which is how it should work.
39
+
40
+ The Qobuz editorial team is worth mentioning separately. The reviews and listening
41
+ guides on the platform are written by people who know music — not auto-generated
42
+ summaries, not marketing copy, but actual critical writing about recordings and
43
+ composers and performers and why a particular release is worth your time. That is
44
+ increasingly rare and it deserves to be noticed.
45
+
46
+ None of this means Kabooz is endorsed by or affiliated with Qobuz. It is not. Kabooz
47
+ is an unofficial tool built by someone who uses Qobuz and wanted a way to work with
48
+ it from the command line. In the meantime, if you use Kabooz and you do not already
49
+ have a Qobuz subscription, please consider getting one. The service deserves the revenue.
50
+
51
+ ---
52
+
53
+ ## MusicBrainz
54
+
55
+ *https://musicbrainz.org*
56
+
57
+ MusicBrainz is the open music encyclopedia. It is a community-maintained database of
58
+ recordings, releases, artists, labels, works, and the relationships between all of them
59
+ — maintained not by a corporation but by volunteers who care about music metadata being
60
+ correct and complete.
61
+
62
+ Kabooz uses MusicBrainz to enrich audio tags beyond what the Qobuz API provides. When
63
+ you have an ISRC code for a track, MusicBrainz can tell you the official MusicBrainz
64
+ recording ID, the release group it belongs to, whether it is a live recording or a
65
+ studio take, which label released it in which country, and a great deal more. That
66
+ information ends up embedded in your audio files, where it can be used by any player
67
+ or library manager that knows how to read it.
68
+
69
+ The MusicBrainz project is not glamorous work. Correcting metadata, merging duplicate
70
+ entries, adding missing releases, standardizing artist names across scripts and
71
+ transliterations — it is painstaking and unglamorous and the people who do it are
72
+ rarely thanked. They should be.
73
+
74
+ ---
75
+
76
+ ## LRCLIB
77
+
78
+ *https://lrclib.net*
79
+
80
+ LRCLIB is a free, open, no-authentication-required database of synced lyrics in LRC
81
+ format. LRC is the format where each line of lyrics is tagged with a timestamp — the
82
+ format that makes lyrics scroll in sync with the music in players that support it.
83
+
84
+ Kabooz uses LRCLIB to fetch synced lyrics and embed them in downloaded audio files,
85
+ both as synced LRC data for players that can display it in time and as plain text for
86
+ players that cannot. The result is that your local files have lyrics without requiring
87
+ any additional software or service.
88
+
89
+ LRCLIB asks nothing in return. No account, no API key, no rate limit that requires
90
+ you to prove you are a legitimate user. It simply has a database of lyrics and an
91
+ HTTP endpoint that returns them. That straightforward, non-extractive approach to
92
+ providing a useful service is worth appreciating explicitly.
93
+
94
+ ---
95
+
96
+ ## tmxkwpn
97
+
98
+ *@tmxkwpn on Telegram*
99
+
100
+ Technical help and guidance during development. Kabooz would have taken longer and
101
+ worked worse without it.
102
+
103
+ ---
104
+
105
+ ## Python dependencies
106
+
107
+ These libraries do the actual work underneath Kabooz's surface.
108
+
109
+ **httpx** *(github.com/encode/httpx)* — the HTTP client that handles all communication
110
+ with the Qobuz API and the CDN. Reliable, well-documented, and a genuine improvement
111
+ over the alternatives.
112
+
113
+ **mutagen** *(github.com/quodlibet/mutagen)* — reads and writes audio metadata for
114
+ FLAC and MP3 files. The Quod Libet project has maintained this library for a long time
115
+ and it handles edge cases that simpler libraries miss.
116
+
117
+ **Typer** *(github.com/tiangolo/typer)* — the CLI framework that turns Python function
118
+ signatures into command-line interfaces. It makes the CLI code read like what it does
119
+ rather than like argument parsing boilerplate.
120
+
121
+ **Rich** *(github.com/Textualize/rich)* — terminal formatting. The progress bars,
122
+ colored output, tables, and panels that make Kabooz's output readable rather than a
123
+ wall of plain text.
124
+
125
+ **tomli-w** *(github.com/hukkin/tomli-w)* — writes TOML configuration files. Small,
126
+ does one thing, does it correctly.
127
+
128
+ ---
129
+
130
+ ## A note on the name
131
+
132
+ Kabooz is phonetically close to Qobuz. That is intentional. The connection should be
133
+ legible to anyone who sees it. The distance from the real name is also intentional —
134
+ it is not Qobuz, it is not affiliated with Qobuz, and the name reflects both of those
135
+ things at once.
136
+
137
+ ---
138
+
139
+ ## License
140
+
141
+ Kabooz is released under the AGPL-3.0-or-later license. The full text is in the
142
+ LICENSE file. The short version: you can use it, study it, modify it, and distribute
143
+ it, but if you distribute a modified version you must make the source available under
144
+ the same terms.
145
+
146
+ This is not a legal barrier to tinkering. Modify the code. Add features. Fix bugs.
147
+ Make it work better for your use case. The AGPL is designed to keep improvements in
148
+ the commons rather than allowing them to disappear into proprietary forks, which
149
+ seems like the right disposition for a tool like this.
150
+
kabooz-0.1.0/DEVLOG.md ADDED
@@ -0,0 +1,40 @@
1
+ \
2
+ # DEV LOGS
3
+
4
+ This file records logs written by the developer for future reference (self or collaborators).
5
+ This is NOT user documentation; it exists purely for developer reference.
6
+ Entries may be incomplete, outdated, or inaccurate.
7
+
8
+ ## Format
9
+ 1. An entry should be made every session.
10
+ A session usually corresponds to a single day.
11
+ 2. All dates must be in UTC. Mentioning time is discouraged; if used, it must also be in UTC.
12
+ 3. This file should be updated in the last commit of a session, and should be omitted in **Commits Made** list.
13
+ 4. A single session entry must follow this format:
14
+
15
+ ### YYYY-MM-DD
16
+ **Author**: [Your name / alias]
17
+ **Commits Made**: commit list or range
18
+
19
+ - Use bullet points.
20
+ - Use explicit sub-headings (####) such as:
21
+ - TODO
22
+ - DONE
23
+ - NOTES
24
+ - BUGS
25
+ - IDEAS
26
+
27
+ ---
28
+
29
+
30
+ ### 2026-03-17
31
+ **Author**: [TchaikovskyCannonsAPI]
32
+ **Commits Made**: 6a88b36..c477381
33
+ #### DONE
34
+ - [x] Lets leave it, cuz it would be soo long
35
+ - [x] Fixed dev.py to be better in dev audio integrity. We don't wanna loose the rick roll in any case.
36
+ - [x] Made cover.jpg for singles copy the track file name instead of cover.jog
37
+ #### BUGS
38
+ - When downloading MP3, the template adds this in the folder name `Billie Jean [FLAC 16bit 44.1kHz] [2026]`
39
+ - When running TUI curses, and clicking on Mozart's Don Giovanni album by Carlo ... remastered 2016, it returns the error ` Overture [24bit/96kHz] Philharmonia Orchestra — Mozart : Don Giovanni (2016 Remastered) █░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0:18 / 6:18 ⏸ PAUSED space=pause n=next p=prev r=radio [/]=vol 100% ←/→=±10s q=quit Loading: Mozart : Don Giovanni (2016 Remastered)… [DEV] GET /album/get params=['album_id', 'limit', 'offset'] → fetching… [DEV] GET /album/get params=['album_id', 'limit', 'offset'] → fetching… [DEV] GET /album/get → HTTP 200 (cached) ✗ Load error: 'TrackSummary' object has no attribute 'performer' [DEV] GET /album/get → HTTP 200 (cached)`
40
+