audiolibrarian 0.16.2__py3-none-any.whl
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.
- audiolibrarian/__init__.py +19 -0
- audiolibrarian/audiofile/__init__.py +23 -0
- audiolibrarian/audiofile/audiofile.py +114 -0
- audiolibrarian/audiofile/formats/__init__.py +1 -0
- audiolibrarian/audiofile/formats/flac.py +207 -0
- audiolibrarian/audiofile/formats/m4a.py +221 -0
- audiolibrarian/audiofile/formats/mp3.py +259 -0
- audiolibrarian/audiofile/tags.py +48 -0
- audiolibrarian/audiosource.py +215 -0
- audiolibrarian/base.py +433 -0
- audiolibrarian/cli.py +123 -0
- audiolibrarian/commands.py +283 -0
- audiolibrarian/genremanager.py +176 -0
- audiolibrarian/musicbrainz.py +465 -0
- audiolibrarian/output.py +57 -0
- audiolibrarian/records.py +259 -0
- audiolibrarian/settings.py +79 -0
- audiolibrarian/sh.py +55 -0
- audiolibrarian/text.py +115 -0
- audiolibrarian-0.16.2.dist-info/METADATA +334 -0
- audiolibrarian-0.16.2.dist-info/RECORD +28 -0
- audiolibrarian-0.16.2.dist-info/WHEEL +4 -0
- audiolibrarian-0.16.2.dist-info/entry_points.txt +2 -0
- audiolibrarian-0.16.2.dist-info/licenses/COPYING +674 -0
- audiolibrarian-0.16.2.dist-info/licenses/LICENSE +674 -0
- picard_src/README.md +11 -0
- picard_src/__init__.py +7 -0
- picard_src/textencoding.py +495 -0
@@ -0,0 +1,334 @@
|
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: audiolibrarian
|
3
|
+
Version: 0.16.2
|
4
|
+
Summary: Manage my audio library.
|
5
|
+
Project-URL: Repository, https://bitbucket.org/toadstule/audiolibrarian/
|
6
|
+
Author-email: Steve Jibson <steve@jibson.com>
|
7
|
+
License-File: COPYING
|
8
|
+
License-File: LICENSE
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
10
|
+
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
11
|
+
Classifier: Programming Language :: Python
|
12
|
+
Requires-Python: ==3.13.*
|
13
|
+
Requires-Dist: ansicolors
|
14
|
+
Requires-Dist: discid
|
15
|
+
Requires-Dist: filelock
|
16
|
+
Requires-Dist: fuzzywuzzy
|
17
|
+
Requires-Dist: musicbrainzngs
|
18
|
+
Requires-Dist: mutagen
|
19
|
+
Requires-Dist: pydantic-settings
|
20
|
+
Requires-Dist: python-levenshtein
|
21
|
+
Requires-Dist: pyyaml
|
22
|
+
Requires-Dist: requests
|
23
|
+
Requires-Dist: xdg-base-dirs
|
24
|
+
Description-Content-Type: text/markdown
|
25
|
+
|
26
|
+
# audiolibrarian #
|
27
|
+
|
28
|
+
## Overview ##
|
29
|
+
|
30
|
+
`audiolibrarian` is a powerful command-line tool for managing digital music libraries. It provides a streamlined
|
31
|
+
workflow for ripping, converting, organizing, and tagging audio files with high-quality metadata from MusicBrainz.
|
32
|
+
|
33
|
+
### Key Features ###
|
34
|
+
|
35
|
+
- **CD Ripping**: Extract audio from CDs with accurate metadata lookup
|
36
|
+
- **Audio Conversion**: Convert between multiple audio formats (FLAC, M4A, MP3)
|
37
|
+
- **Metadata Management**: Automatically fetch and apply rich metadata from MusicBrainz
|
38
|
+
- **File Organization**: Intelligently organize music files into a clean directory structure
|
39
|
+
- **Batch Processing**: Handle multiple files and directories efficiently
|
40
|
+
- **Genre Management**: Work with MusicBrainz genres and tags
|
41
|
+
- **Flexible Configuration**: Customize behavior through config files and environment variables
|
42
|
+
|
43
|
+
### Why audiolibrarian? ###
|
44
|
+
|
45
|
+
- **Consistent Quality**: Maintains audio quality through the conversion process
|
46
|
+
- **Accurate Metadata**: Leverages MusicBrainz for comprehensive music information
|
47
|
+
- **Automated Workflow**: Reduces manual work in organizing and tagging music
|
48
|
+
- **Scriptable**: Perfect for automating large music library management tasks
|
49
|
+
- **Open Source**: Free to use and modify under the GPL-3.0 license
|
50
|
+
|
51
|
+
Whether you're digitizing a CD collection, organizing existing music files, or managing a large digital library,
|
52
|
+
`audiolibrarian` provides the tools you need to keep your music collection well-organized and properly tagged.
|
53
|
+
|
54
|
+
|
55
|
+
## Installation ##
|
56
|
+
|
57
|
+
### External Requirements ###
|
58
|
+
|
59
|
+
`audiolibrarian` uses a few command-line tools to run:
|
60
|
+
|
61
|
+
* `cd-paranoia`: [cd-paranoia](https://www.gnu.org/software/libcdio/)
|
62
|
+
* `eject`: [util-linux](https://github.com/util-linux/util-linux)
|
63
|
+
* `faad`: [faad2](https://github.com/knik0/faad2)
|
64
|
+
* `fdkaac`: [fdkaac](https://github.com/nu774/fdkaac)
|
65
|
+
* `flac`: [flac](https://github.com/xiph/flac)
|
66
|
+
* `lame`: [lame](https://lame.sourceforge.io/)
|
67
|
+
* `mpg123`: [mpg123](https://www.mpg123.de/)
|
68
|
+
* `sndfile-convert`: [libsndfile](https://github.com/libsndfile/libsndfile)
|
69
|
+
* `wavegain`: [wavegain](https://rarewares.org/others.php)
|
70
|
+
|
71
|
+
### Install from PyPI ###
|
72
|
+
|
73
|
+
`audiolibrarian` is not available on PyPI, but it can be installed from a local PyPI.
|
74
|
+
|
75
|
+
```bash
|
76
|
+
pip install --user --extra-index-url=https://pypi.example.com/simple audiolibrarian
|
77
|
+
```
|
78
|
+
|
79
|
+
### Install from Bitbucket ###
|
80
|
+
|
81
|
+
```bash
|
82
|
+
pip install --user git+https://bitbucket.org/toadstule/audiolibrarian
|
83
|
+
```
|
84
|
+
|
85
|
+
## Configuration ##
|
86
|
+
|
87
|
+
`audiolibrarian` uses a flexible configuration system that supports multiple configuration sources, listed in order of precedence:
|
88
|
+
|
89
|
+
1. **Environment Variables** (highest precedence)
|
90
|
+
- Prefix: `AUDIOLIBRARIAN__`
|
91
|
+
- Nested fields: Use `__` as delimiter (e.g., `AUDIOLIBRARIAN__MUSICBRAINZ__USERNAME`)
|
92
|
+
- Example:
|
93
|
+
```bash
|
94
|
+
# Override library directory
|
95
|
+
export AUDIOLIBRARIAN__LIBRARY_DIR="/mnt/music/library"
|
96
|
+
|
97
|
+
# Set MusicBrainz credentials
|
98
|
+
export AUDIOLIBRARIAN__MUSICBRAINZ__USERNAME="your_username"
|
99
|
+
export AUDIOLIBRARIAN__MUSICBRAINZ__PASSWORD="your_password"
|
100
|
+
```
|
101
|
+
|
102
|
+
2. **YAML Configuration File**
|
103
|
+
- Location: `~/.config/audiolibrarian/config.yaml` (or `$XDG_CONFIG_HOME/audiolibrarian/config.yaml` if set)
|
104
|
+
- Example:
|
105
|
+
```yaml
|
106
|
+
# Base directory for your music library
|
107
|
+
library_dir: "~/music/library"
|
108
|
+
|
109
|
+
# Cache and working directory
|
110
|
+
work_dir: "~/.cache/audiolibrarian"
|
111
|
+
|
112
|
+
# CD/DVD device path (use null for default device)
|
113
|
+
discid_device: null
|
114
|
+
|
115
|
+
# Audio normalization settings
|
116
|
+
normalize_gain: 5 # dB gain for normalization
|
117
|
+
normalize_preset: "radio" # "album" or "radio"
|
118
|
+
|
119
|
+
# MusicBrainz API settings (optional)
|
120
|
+
musicbrainz:
|
121
|
+
username: "your_username" # For personal genre preferences
|
122
|
+
password: "your_password" # Will be stored securely
|
123
|
+
rate_limit: 1.5 # Seconds between API requests
|
124
|
+
```
|
125
|
+
|
126
|
+
3. **Default Values** (lowest precedence)
|
127
|
+
- Built-in defaults from the application
|
128
|
+
|
129
|
+
### Available Settings ###
|
130
|
+
|
131
|
+
| Setting | Default | Description |
|
132
|
+
|--------------------------|----------------------------------|-------------------------------------------|
|
133
|
+
| `library_dir` | `library` (in the current dir) | Directory for storing audio files |
|
134
|
+
| `work_dir` | `$XDG_CACHE_HOME/audiolibrarian` | Directory for temporary files |
|
135
|
+
| `discid_device` | `null` | CD device path (null for default device) |
|
136
|
+
| `normalize_gain` | `5` | Normalization gain in dB |
|
137
|
+
| `normalize_preset` | `"radio"` | Normalization preset ("album" or "radio") |
|
138
|
+
| `musicbrainz.username` | (not set) | MusicBrainz username |
|
139
|
+
| `musicbrainz.password` | (not set) | MusicBrainz password |
|
140
|
+
| `musicbrainz.rate_limit` | `1.5` | Seconds between requests |
|
141
|
+
|
142
|
+
> **Note**: The `musicbrainz` section is optional but recommended for accessing personal genre preferences on [MusicBrainz](https://musicbrainz.org/).
|
143
|
+
|
144
|
+
## Usage ##
|
145
|
+
|
146
|
+
### Basic Commands ###
|
147
|
+
|
148
|
+
```bash
|
149
|
+
# Rip audio from a CD
|
150
|
+
audiolibrarian rip
|
151
|
+
|
152
|
+
# Convert audio files
|
153
|
+
audiolibrarian convert /path/to/audio/files
|
154
|
+
|
155
|
+
# Create or update manifest files
|
156
|
+
audiolibrarian manifest /path/to/audio/files
|
157
|
+
|
158
|
+
# Reconvert files from existing source
|
159
|
+
audiolibrarian reconvert /path/to/source/directories
|
160
|
+
|
161
|
+
# Rename files based on tags
|
162
|
+
audiolibrarian rename /path/to/audio/directories
|
163
|
+
|
164
|
+
# Manage MusicBrainz genres
|
165
|
+
audiolibrarian genre /path/to/audio/directories --tag # Update tags with MB genres
|
166
|
+
|
167
|
+
# Show help for all commands
|
168
|
+
audiolibrarian --help
|
169
|
+
```
|
170
|
+
|
171
|
+
### Combining Configuration Sources ###
|
172
|
+
|
173
|
+
Configuration sources are combined with the following precedence (highest to lowest):
|
174
|
+
1. Environment variables
|
175
|
+
2. YAML configuration file
|
176
|
+
3. Default values
|
177
|
+
|
178
|
+
For example, with this `config.yaml`:
|
179
|
+
|
180
|
+
```yaml
|
181
|
+
# config.yaml
|
182
|
+
library_dir: /media/music/library
|
183
|
+
normalize_gain: 5.0
|
184
|
+
```
|
185
|
+
|
186
|
+
And this environment variable:
|
187
|
+
```bash
|
188
|
+
export AUDIOLIBRARIAN__NORMALIZE_GAIN="8.0"
|
189
|
+
```
|
190
|
+
|
191
|
+
The effective value of `normalize_gain` will be `8.0` (from the environment variable), while `library_dir` will be set to `/media/music/library` from the YAML file.
|
192
|
+
|
193
|
+
### Advanced Usage ###
|
194
|
+
|
195
|
+
1. **Ripping CDs**
|
196
|
+
|
197
|
+
```bash
|
198
|
+
# Basic CD rip
|
199
|
+
audiolibrarian rip
|
200
|
+
|
201
|
+
# Specify artist and album
|
202
|
+
audiolibrarian rip --artist "Artist Name" --album "Album Name"
|
203
|
+
|
204
|
+
# Specify MusicBrainz release ID (for better metadata)
|
205
|
+
audiolibrarian rip --mb-release-id "12345678-1234-1234-1234-123456789012"
|
206
|
+
|
207
|
+
# Specify disc number for multi-disc sets
|
208
|
+
audiolibrarian rip --disc "1/2" # First disc of two
|
209
|
+
```
|
210
|
+
|
211
|
+
2. **Converting Audio Files**
|
212
|
+
|
213
|
+
```bash
|
214
|
+
# Convert with specific artist and album
|
215
|
+
audiolibrarian convert --artist "Artist Name" --album "Album Name" /path/to/audio/files
|
216
|
+
|
217
|
+
# Convert with MusicBrainz release ID
|
218
|
+
audiolibrarian convert --mb-release-id "12345678-1234-1234-1234-123456789012" /path/to/audio/files
|
219
|
+
|
220
|
+
# Convert multi-disc release
|
221
|
+
audiolibrarian convert --disc "1/2" /path/to/disc1/files
|
222
|
+
```
|
223
|
+
|
224
|
+
2. **Working with Manifests**
|
225
|
+
|
226
|
+
```bash
|
227
|
+
# Create manifest for existing files
|
228
|
+
audiolibrarian manifest /path/to/audio/files
|
229
|
+
|
230
|
+
# Specify CD as source
|
231
|
+
audiolibrarian manifest --cd /path/to/audio/files
|
232
|
+
|
233
|
+
# Specify MusicBrainz artist and release IDs
|
234
|
+
audiolibrarian manifest --mb-artist-id "12345678-1234-1234-1234-123456789012" \
|
235
|
+
--mb-release-id "12345678-1234-1234-1234-123456789012" /path/to/audio/files
|
236
|
+
```
|
237
|
+
|
238
|
+
3. **Reconverting Files**
|
239
|
+
|
240
|
+
```bash
|
241
|
+
# Reconvert all files in directory
|
242
|
+
audiolibrarian reconvert /path/to/source/directories
|
243
|
+
|
244
|
+
# Reconvert with dry run (no changes)
|
245
|
+
audiolibrarian reconvert --dry-run /path/to/source/directories
|
246
|
+
```
|
247
|
+
|
248
|
+
4. **Renaming Files**
|
249
|
+
|
250
|
+
```bash
|
251
|
+
# Rename files based on tags
|
252
|
+
audiolibrarian rename /path/to/audio/directories
|
253
|
+
|
254
|
+
# Preview renames without making changes
|
255
|
+
audiolibrarian rename --dry-run /path/to/audio/directories
|
256
|
+
```
|
257
|
+
|
258
|
+
5. **Using Different Normalization Presets**
|
259
|
+
|
260
|
+
```bash
|
261
|
+
# Use radio normalization preset (default)
|
262
|
+
export AUDIOLIBRARIAN__NORMALIZE_PRESET="radio"
|
263
|
+
|
264
|
+
# Use album normalization preset
|
265
|
+
export AUDIOLIBRARIAN__NORMALIZE_PRESET="album"
|
266
|
+
```
|
267
|
+
|
268
|
+
### Troubleshooting ###
|
269
|
+
|
270
|
+
1. **Increasing Verbosity**
|
271
|
+
|
272
|
+
```bash
|
273
|
+
# Show more detailed output
|
274
|
+
audiolibrarian --log-level INFO cd
|
275
|
+
|
276
|
+
# Show debug information
|
277
|
+
audiolibrarian --log-level DEBUG cd
|
278
|
+
```
|
279
|
+
|
280
|
+
2. **Checking Dependencies**
|
281
|
+
|
282
|
+
```bash
|
283
|
+
# Verify all required tools are installed
|
284
|
+
audiolibrarian --log-level DEBUG cd
|
285
|
+
```
|
286
|
+
|
287
|
+
3. **MusicBrainz Issues**
|
288
|
+
|
289
|
+
If you encounter MusicBrainz-related errors:
|
290
|
+
|
291
|
+
1. Verify your credentials are correct
|
292
|
+
2. Check your internet connection
|
293
|
+
3. Use the debug log level to get more information
|
294
|
+
4. Increase the rate limit if you're hitting rate limits
|
295
|
+
|
296
|
+
```bash
|
297
|
+
export AUDIOLIBRARIAN__MUSICBRAINZ__RATE_LIMIT="2.0"
|
298
|
+
```
|
299
|
+
|
300
|
+
### Directory Structure ###
|
301
|
+
|
302
|
+
`audiolibrarian` organizes files in the following structure:
|
303
|
+
|
304
|
+
1. **Source files** (original audio files):
|
305
|
+
```
|
306
|
+
library/source/
|
307
|
+
└── Artist/
|
308
|
+
└── YYYY__Album/
|
309
|
+
├── 01__Track_Title.flac
|
310
|
+
├── 02__Another_Track.flac
|
311
|
+
└── Manifest.yaml
|
312
|
+
```
|
313
|
+
|
314
|
+
2. **Processed audio files** (organized by format):
|
315
|
+
```
|
316
|
+
library/
|
317
|
+
├── flac/
|
318
|
+
│ └── Artist/
|
319
|
+
│ └── YYYY__Album/
|
320
|
+
│ ├── 01__Track_Title.flac
|
321
|
+
│ └── 02__Another_Track.flac
|
322
|
+
├── m4a/
|
323
|
+
│ └── Artist/
|
324
|
+
│ └── YYYY__Album/
|
325
|
+
│ ├── 01__Track_Title.m4a
|
326
|
+
│ └── 02__Another_Track.m4a
|
327
|
+
└── mp3/
|
328
|
+
└── Artist/
|
329
|
+
└── YYYY__Album/
|
330
|
+
├── 01__Track_Title.mp3
|
331
|
+
└── 02__Another_Track.mp3
|
332
|
+
```
|
333
|
+
|
334
|
+
Each track filename follows the format: `track_number__track_name.extension` (e.g., `01__Call_to_Arms.flac`).
|
@@ -0,0 +1,28 @@
|
|
1
|
+
audiolibrarian/__init__.py,sha256=NAyvdXQNHBEMka12z9FEosPLDRdFPkrB6aPPdZ2MweM,787
|
2
|
+
audiolibrarian/audiosource.py,sha256=EtoSQb6R2zfHUwxiR9ZqGwjxrX2mTB5gPpmKangps4s,8573
|
3
|
+
audiolibrarian/base.py,sha256=54s_NacDvyGpvc_uOJO5apmQin4HKUGfPrlw0XFiJoI,19428
|
4
|
+
audiolibrarian/cli.py,sha256=azX49RO2t4q8qyUJ9WTOlDqUO13p17mq0wNmEdl6QGw,4211
|
5
|
+
audiolibrarian/commands.py,sha256=8R9aagOaaLE798lGYPWknW-NiIHkxEbQbiM43RZrPTU,11166
|
6
|
+
audiolibrarian/genremanager.py,sha256=ZciuJb3GoaM31h33_khowNg8iv4MVGkjJM-beijSF3k,7357
|
7
|
+
audiolibrarian/musicbrainz.py,sha256=DAodaLVySqq6nSbGCLfUktXSAm95OfPhkOXyyexMj6w,19312
|
8
|
+
audiolibrarian/output.py,sha256=JHuttwEMEzUxty7P8e2jaL6702q52fTWAdZEgb85bxQ,1702
|
9
|
+
audiolibrarian/records.py,sha256=BovHwNVd0nTTwQPYkhOAOIVASWz9l47j6cGdXAx5VjM,7929
|
10
|
+
audiolibrarian/settings.py,sha256=qKQ9JYfKr2k_JceWfYPiMlpBKylujCQI_2pmxWpsGFo,2550
|
11
|
+
audiolibrarian/sh.py,sha256=tVTuKXlMH738jTopjnMWqidTaH02_EyHau3q9kQ6mYE,1912
|
12
|
+
audiolibrarian/text.py,sha256=05q_E22w9hMsy01_A5XlU2pqQIMlM5RF4DXzYuLCcYo,4026
|
13
|
+
audiolibrarian/audiofile/__init__.py,sha256=BRjf4iu_cogB3A5oIVE4BjIgUGCH0dAzPG4A_48rOUM,894
|
14
|
+
audiolibrarian/audiofile/audiofile.py,sha256=IhTIzFzYeKfJmsgOG7bN62KWD06ehOGRoVv3eCf-_vw,4352
|
15
|
+
audiolibrarian/audiofile/tags.py,sha256=42oyqHZ6jRokmQskD2p53NMgKxJR7xkidXImOhUzszY,1785
|
16
|
+
audiolibrarian/audiofile/formats/__init__.py,sha256=ZV5urTtQQ4ZX_K2s9qFsSzDunvdQaQ43K7CE-BPPtEo,25
|
17
|
+
audiolibrarian/audiofile/formats/flac.py,sha256=3MfzdgnAqTVSbAraAVde2BSHwdAyi-fKkc55OvuRNSc,9708
|
18
|
+
audiolibrarian/audiofile/formats/m4a.py,sha256=S0aFZxMzgwpzkwYE2D_K_US0Dnh0objK21ph1S_8rJk,10552
|
19
|
+
audiolibrarian/audiofile/formats/mp3.py,sha256=ipuanK7CIYSk9LqW0AvAgKAUZeU9ecwK0uZf2AhAGXo,12881
|
20
|
+
picard_src/README.md,sha256=TTnzIGmZ8_G11G1VCz5DHdlidIrtkGFYxWFooyTKcbI,403
|
21
|
+
picard_src/__init__.py,sha256=acu0-oac_qfEgiB0rw0RvuL---O15-rOckWboVMxWtM,198
|
22
|
+
picard_src/textencoding.py,sha256=0MRHFwhqEwauQbjTTz6gpgzo6YH1VDPfdJqQoCWHtjM,26234
|
23
|
+
audiolibrarian-0.16.2.dist-info/METADATA,sha256=EIrFJiGcWJVgqQcCCO8dwKDtiWU52kEA3Bp2I_l5WP8,10756
|
24
|
+
audiolibrarian-0.16.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
25
|
+
audiolibrarian-0.16.2.dist-info/entry_points.txt,sha256=reubnr_SGbTTDXji8j7z8aTmIL0AEQKVSLcnmFG3YYY,59
|
26
|
+
audiolibrarian-0.16.2.dist-info/licenses/COPYING,sha256=WJ7YI-moTFb-uVrFjnzzhGJrnL9P2iqQe8NuED3hutI,35141
|
27
|
+
audiolibrarian-0.16.2.dist-info/licenses/LICENSE,sha256=WJ7YI-moTFb-uVrFjnzzhGJrnL9P2iqQe8NuED3hutI,35141
|
28
|
+
audiolibrarian-0.16.2.dist-info/RECORD,,
|