pylrclib-cli 0.4.1__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 (49) hide show
  1. pylrclib_cli-0.4.1/LICENSE +21 -0
  2. pylrclib_cli-0.4.1/PKG-INFO +474 -0
  3. pylrclib_cli-0.4.1/README.md +442 -0
  4. pylrclib_cli-0.4.1/pylrclib/__init__.py +4 -0
  5. pylrclib_cli-0.4.1/pylrclib/__main__.py +3 -0
  6. pylrclib_cli-0.4.1/pylrclib/api/__init__.py +3 -0
  7. pylrclib_cli-0.4.1/pylrclib/api/client.py +93 -0
  8. pylrclib_cli-0.4.1/pylrclib/api/http.py +64 -0
  9. pylrclib_cli-0.4.1/pylrclib/api/pow.py +17 -0
  10. pylrclib_cli-0.4.1/pylrclib/api/publish.py +92 -0
  11. pylrclib_cli-0.4.1/pylrclib/api/retry.py +28 -0
  12. pylrclib_cli-0.4.1/pylrclib/cli/__init__.py +0 -0
  13. pylrclib_cli-0.4.1/pylrclib/cli/main.py +52 -0
  14. pylrclib_cli-0.4.1/pylrclib/commands/__init__.py +0 -0
  15. pylrclib_cli-0.4.1/pylrclib/commands/cleanse.py +56 -0
  16. pylrclib_cli-0.4.1/pylrclib/commands/doctor.py +91 -0
  17. pylrclib_cli-0.4.1/pylrclib/commands/down.py +107 -0
  18. pylrclib_cli-0.4.1/pylrclib/commands/inspect.py +65 -0
  19. pylrclib_cli-0.4.1/pylrclib/commands/search.py +67 -0
  20. pylrclib_cli-0.4.1/pylrclib/commands/up.py +143 -0
  21. pylrclib_cli-0.4.1/pylrclib/config.py +124 -0
  22. pylrclib_cli-0.4.1/pylrclib/discovery.py +33 -0
  23. pylrclib_cli-0.4.1/pylrclib/exceptions.py +10 -0
  24. pylrclib_cli-0.4.1/pylrclib/fs/__init__.py +4 -0
  25. pylrclib_cli-0.4.1/pylrclib/fs/cleaner.py +17 -0
  26. pylrclib_cli-0.4.1/pylrclib/fs/mover.py +32 -0
  27. pylrclib_cli-0.4.1/pylrclib/i18n.py +28 -0
  28. pylrclib_cli-0.4.1/pylrclib/interaction.py +73 -0
  29. pylrclib_cli-0.4.1/pylrclib/logging_utils.py +19 -0
  30. pylrclib_cli-0.4.1/pylrclib/lrc/__init__.py +29 -0
  31. pylrclib_cli-0.4.1/pylrclib/lrc/matcher.py +114 -0
  32. pylrclib_cli-0.4.1/pylrclib/lrc/parser.py +175 -0
  33. pylrclib_cli-0.4.1/pylrclib/lyrics/__init__.py +18 -0
  34. pylrclib_cli-0.4.1/pylrclib/lyrics/loader.py +234 -0
  35. pylrclib_cli-0.4.1/pylrclib/lyrics/writer.py +60 -0
  36. pylrclib_cli-0.4.1/pylrclib/models/__init__.py +10 -0
  37. pylrclib_cli-0.4.1/pylrclib/models/lyrics.py +97 -0
  38. pylrclib_cli-0.4.1/pylrclib/models/track.py +137 -0
  39. pylrclib_cli-0.4.1/pylrclib/workflows/down.py +98 -0
  40. pylrclib_cli-0.4.1/pylrclib/workflows/search.py +54 -0
  41. pylrclib_cli-0.4.1/pylrclib/workflows/up.py +278 -0
  42. pylrclib_cli-0.4.1/pylrclib_cli.egg-info/PKG-INFO +474 -0
  43. pylrclib_cli-0.4.1/pylrclib_cli.egg-info/SOURCES.txt +47 -0
  44. pylrclib_cli-0.4.1/pylrclib_cli.egg-info/dependency_links.txt +1 -0
  45. pylrclib_cli-0.4.1/pylrclib_cli.egg-info/entry_points.txt +2 -0
  46. pylrclib_cli-0.4.1/pylrclib_cli.egg-info/requires.txt +10 -0
  47. pylrclib_cli-0.4.1/pylrclib_cli.egg-info/top_level.txt +1 -0
  48. pylrclib_cli-0.4.1/pyproject.toml +51 -0
  49. pylrclib_cli-0.4.1/setup.cfg +4 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Harmonese
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,474 @@
1
+ Metadata-Version: 2.4
2
+ Name: pylrclib-cli
3
+ Version: 0.4.1
4
+ Summary: A multi-command CLI for searching, downloading, inspecting, cleansing, and publishing lyrics around LRCLIB.
5
+ Author: Harmonese
6
+ License-Expression: MIT
7
+ Keywords: lrclib,lyrics,lrc,karaoke,cli,music
8
+ Classifier: Development Status :: 4 - Beta
9
+ Classifier: Environment :: Console
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Intended Audience :: End Users/Desktop
12
+ Classifier: Operating System :: OS Independent
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Topic :: Multimedia :: Sound/Audio
18
+ Classifier: Topic :: Utilities
19
+ Requires-Python: >=3.10
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Requires-Dist: requests>=2.31.0
23
+ Requires-Dist: mutagen>=1.47.0
24
+ Requires-Dist: PyYAML>=6.0.0
25
+ Provides-Extra: dev
26
+ Requires-Dist: pytest>=8.0; extra == "dev"
27
+ Requires-Dist: build>=1.2.0; extra == "dev"
28
+ Requires-Dist: twine>=5.0.0; extra == "dev"
29
+ Requires-Dist: ruff>=0.6.0; extra == "dev"
30
+ Requires-Dist: mypy>=1.10.0; extra == "dev"
31
+ Dynamic: license-file
32
+
33
+ # pylrclib
34
+
35
+ A multi-command CLI around LRCLIB for searching, downloading, inspecting, cleansing, and publishing lyrics.
36
+
37
+ `pylrclib` treats lyrics as four explicit states:
38
+
39
+ - `plain`: unsynced plain-text lyrics
40
+ - `synced`: timed LRC lyrics
41
+ - `mixed`: both plain and synced lyrics are available
42
+ - `instrumental`: instrumental / no-vocals track
43
+
44
+ That shared model drives all major commands:
45
+
46
+ - `pylrclib search`: search LRCLIB and preview remote results
47
+ - `pylrclib down`: download lyrics from LRCLIB to local files
48
+ - `pylrclib up`: publish local lyrics to LRCLIB
49
+ - `pylrclib inspect`: inspect local matching and classification without publishing
50
+ - `pylrclib cleanse`: normalize `.lrc` files
51
+ - `pylrclib doctor`: diagnose workspace and configuration issues
52
+
53
+ ---
54
+
55
+ ## Installation
56
+
57
+ ### From PyPI (Recommended)
58
+
59
+ ```bash
60
+ pip install pylrclib-cli
61
+ ```
62
+
63
+ ### From source
64
+
65
+ ```bash
66
+ pip install -e .
67
+ ```
68
+
69
+ ### Entry points
70
+
71
+ ```bash
72
+ pylrclib --help
73
+ python -m pylrclib --help
74
+ ```
75
+
76
+ ---
77
+
78
+ ## Command overview
79
+
80
+ ```bash
81
+ pylrclib search ...
82
+ pylrclib down ...
83
+ pylrclib up ...
84
+ pylrclib inspect ...
85
+ pylrclib cleanse ...
86
+ pylrclib doctor ...
87
+ ```
88
+
89
+ ---
90
+
91
+ ## `search`: search LRCLIB and preview remote records
92
+
93
+ Use `search` when you want to inspect LRCLIB results before downloading or publishing.
94
+
95
+ ### Query search
96
+
97
+ ```bash
98
+ pylrclib search --query "song title"
99
+ pylrclib search --title "Song Title" --artist "Artist Name"
100
+ ```
101
+
102
+ ### Lookup by LRCLIB id
103
+
104
+ ```bash
105
+ pylrclib search --lrclib-id 12345
106
+ ```
107
+
108
+ ### Useful parameters
109
+
110
+ ```bash
111
+ --query TEXT
112
+ --title TEXT
113
+ --artist TEXT
114
+ --album TEXT
115
+ --lrclib-id N
116
+ --limit N
117
+ --preview-lines N
118
+ --json
119
+ --api-base URL
120
+ ```
121
+
122
+ ---
123
+
124
+ ## `down`: download lyrics from LRCLIB
125
+
126
+ `down` supports three input modes:
127
+
128
+ 1. Scan local audio / YAML metadata and query LRCLIB
129
+ 2. Manually specify artist/title metadata
130
+ 3. Fetch one exact record with `--lrclib-id`
131
+
132
+ ### Download based on local music metadata
133
+
134
+ ```bash
135
+ pylrclib down \
136
+ --tracks ./music \
137
+ --output-dir ./lyrics_downloaded
138
+ ```
139
+
140
+ ### Download one song manually
141
+
142
+ ```bash
143
+ pylrclib down \
144
+ --artist "Artist Name" \
145
+ --title "Song Title" \
146
+ --album "Album Name" \
147
+ --duration 180 \
148
+ --output-dir ./lyrics_downloaded
149
+ ```
150
+
151
+ ### Download one exact LRCLIB record
152
+
153
+ ```bash
154
+ pylrclib down \
155
+ --lrclib-id 12345 \
156
+ --output-dir ./lyrics_downloaded \
157
+ --save-mode both
158
+ ```
159
+
160
+ ### Save strategy
161
+
162
+ ```bash
163
+ --save-mode auto|plain|synced|both
164
+ ```
165
+
166
+ Default behavior:
167
+
168
+ - `auto`
169
+ - if LRCLIB provides synced lyrics, save `.lrc`
170
+ - if only plain lyrics exist, save `.txt`
171
+ - if instrumental, report it and do not write lyric files
172
+ - `plain`: save only `.txt`
173
+ - `synced`: save only `.lrc`
174
+ - `both`: save both `.txt` and `.lrc` when available
175
+
176
+ ### Naming strategy
177
+
178
+ ```bash
179
+ --naming auto|track-basename|artist-title
180
+ ```
181
+
182
+ When scanning local files, `auto` prefers the track basename. In manual or id-based downloads, `auto` falls back to `Artist - Title`.
183
+
184
+ ---
185
+
186
+ ## `up`: publish local lyrics to LRCLIB
187
+
188
+ `up` runs the full upload workflow:
189
+
190
+ 1. Discover audio files or YAML metadata
191
+ 2. Check LRCLIB cached and external matches
192
+ 3. Resolve local plain and synced lyric candidates
193
+ 4. Classify lyrics as `plain`, `synced`, `mixed`, `instrumental`, or `invalid`
194
+ 5. Build an upload plan from `--lyrics-mode`
195
+ 6. Publish lyrics or mark the track instrumental
196
+ 7. Optionally move or rename processed files
197
+
198
+ ### Basic usage
199
+
200
+ ```bash
201
+ pylrclib up --tracks ./music --lyrics-dir ./lyrics
202
+ ```
203
+
204
+ ### Recommended split-directory usage
205
+
206
+ ```bash
207
+ pylrclib up \
208
+ --tracks ./music \
209
+ --plain-dir ./lyrics_plain \
210
+ --synced-dir ./lyrics_lrc \
211
+ --done-lrc ./done_lyrics \
212
+ --lyrics-mode auto \
213
+ --cleanse
214
+ ```
215
+
216
+ ### Upload strategy
217
+
218
+ ```bash
219
+ --lyrics-mode auto|plain|synced|mixed|instrumental
220
+ ```
221
+
222
+ Behavior summary:
223
+
224
+ - `auto`
225
+ - plain + synced => publish both
226
+ - only synced => publish synced and optionally derive plain text
227
+ - only plain => publish plain only
228
+ - explicit instrumental markers => publish as instrumental
229
+ - invalid lyrics => skip
230
+ - `plain`: publish plain lyrics only
231
+ - `synced`: publish synced lyrics and optionally derived plain text
232
+ - `mixed`: require both plain and synced lyrics
233
+ - `instrumental`: force instrumental upload
234
+
235
+ ### Local lyric matching
236
+
237
+ `up` searches for two lyric types separately:
238
+
239
+ - plain candidates:
240
+ - `.txt`
241
+ - `.lyrics`
242
+ - `.lyric`
243
+ - synced candidates:
244
+ - `.lrc`
245
+
246
+ Matching sources include:
247
+
248
+ 1. same basename as the audio / YAML file
249
+ 2. YAML-declared filenames
250
+ 3. normalized `Artist - Title.*` matches
251
+ 4. interactive selection when multiple candidates exist
252
+
253
+ ### Important parameters
254
+
255
+ ```bash
256
+ --tracks PATH
257
+ --lyrics-dir PATH
258
+ --plain-dir PATH
259
+ --synced-dir PATH
260
+ --done-tracks PATH
261
+ --done-lrc PATH
262
+ -f, --follow
263
+ -r, --rename
264
+ -c, --cleanse
265
+ --cleanse-write
266
+ --lyrics-mode auto|plain|synced|mixed|instrumental
267
+ --allow-derived-plain / --no-derived-plain
268
+ --ignore-duration-mismatch
269
+ --yes
270
+ --non-interactive
271
+ ```
272
+
273
+ ### YAML input format
274
+
275
+ ```yaml
276
+ track: Song Title
277
+ artist: Artist Name
278
+ album: Album Name
279
+ duration: 180
280
+ plain_file: song.txt
281
+ synced_file: song.lrc
282
+ lyrics_file: song.lrc
283
+ lrc_file: song.lrc
284
+ ```
285
+
286
+ ---
287
+
288
+ ## `inspect`: inspect local matching and classification
289
+
290
+ `inspect` shows what the tool would use locally, without publishing.
291
+
292
+ ```bash
293
+ pylrclib inspect \
294
+ --tracks ./music \
295
+ --plain-dir ./lyrics_plain \
296
+ --synced-dir ./lyrics_lrc \
297
+ --show-all-candidates
298
+ ```
299
+
300
+ This is useful for debugging why a track resolved to `plain`, `mixed`, or `invalid`.
301
+
302
+ ---
303
+
304
+ ## `cleanse`: normalize `.lrc` files
305
+
306
+ `cleanse` cleans synced lyrics safely.
307
+
308
+ ```bash
309
+ pylrclib cleanse ./lyrics_lrc
310
+ pylrclib cleanse ./lyrics_lrc --write
311
+ ```
312
+
313
+ Recommended behavior:
314
+
315
+ - use `cleanse` to preview / analyze normalization
316
+ - use `--write` only when you really want to rewrite files in place
317
+
318
+ Invalid files are not blindly rewritten into empty files.
319
+
320
+ ---
321
+
322
+ ## `doctor`: diagnose the current workspace
323
+
324
+ ```bash
325
+ pylrclib doctor \
326
+ --tracks ./music \
327
+ --plain-dir ./lyrics_plain \
328
+ --synced-dir ./lyrics_lrc
329
+ ```
330
+
331
+ `doctor` prints resolved configuration, counts discovered inputs, and highlights obvious workflow conflicts.
332
+
333
+ ---
334
+
335
+ ## Environment variables
336
+
337
+ Supported environment variables include:
338
+
339
+ ```text
340
+ PYLRCLIB_TRACKS_DIR
341
+ PYLRCLIB_LYRICS_DIR
342
+ PYLRCLIB_PLAIN_DIR
343
+ PYLRCLIB_SYNCED_DIR
344
+ PYLRCLIB_DONE_TRACKS_DIR
345
+ PYLRCLIB_DONE_LRC_DIR
346
+ PYLRCLIB_OUTPUT_DIR
347
+ PYLRCLIB_ARTIST
348
+ PYLRCLIB_TITLE
349
+ PYLRCLIB_ALBUM
350
+ PYLRCLIB_DURATION
351
+ PYLRCLIB_LRCLIB_ID
352
+ PYLRCLIB_API_BASE
353
+ PYLRCLIB_USER_AGENT
354
+ PYLRCLIB_PREVIEW_LINES
355
+ PYLRCLIB_MAX_HTTP_RETRIES
356
+ ```
357
+
358
+ ---
359
+
360
+ ## Development
361
+
362
+ Install dev dependencies:
363
+
364
+ ```bash
365
+ pip install -e .[dev]
366
+ ```
367
+
368
+ ---
369
+
370
+ ## 中文说明
371
+
372
+ `pylrclib` 是一个围绕 LRCLIB 的多子命令命令行工具,可用于搜索、下载、检查、清洗和上传歌词。
373
+
374
+ 它把歌词明确建模成四种状态:
375
+
376
+ - `plain`:纯文本歌词,无时间轴
377
+ - `synced`:滚动歌词,带时间轴(LRC)
378
+ - `mixed`:同时拥有纯文本歌词和滚动歌词
379
+ - `instrumental`:纯音乐 / 无人声
380
+
381
+ 对应的主要命令是:
382
+
383
+ - `pylrclib search`:搜索 LRCLIB 并预览远端结果
384
+ - `pylrclib down`:从 LRCLIB 下载歌词到本地
385
+ - `pylrclib up`:把本地歌词上传到 LRCLIB
386
+ - `pylrclib inspect`:只检查本地匹配与分类结果
387
+ - `pylrclib cleanse`:清洗和标准化 `.lrc`
388
+ - `pylrclib doctor`:诊断工作区和配置问题
389
+
390
+ ### `search`
391
+
392
+ ```bash
393
+ pylrclib search --query "歌名"
394
+ pylrclib search --title "歌名" --artist "歌手"
395
+ pylrclib search --lrclib-id 12345
396
+ ```
397
+
398
+ 适合用来先确认 LRCLIB 上到底有哪些候选结果,再决定是否下载或上传。
399
+
400
+ ### `down`
401
+
402
+ `down` 现在支持三种输入方式:
403
+
404
+ 1. 读取本地音频 / YAML 元数据后去 LRCLIB 查询
405
+ 2. 手动指定 `--artist` / `--title`
406
+ 3. 通过 `--lrclib-id` 精确抓取某一条 LRCLIB 记录
407
+
408
+ 示例:
409
+
410
+ ```bash
411
+ pylrclib down --tracks ./music --output-dir ./lyrics_downloaded
412
+ pylrclib down --artist "歌手" --title "歌名" --output-dir ./lyrics_downloaded
413
+ pylrclib down --lrclib-id 12345 --output-dir ./lyrics_downloaded --save-mode both
414
+ ```
415
+
416
+ 保存策略:
417
+
418
+ ```bash
419
+ --save-mode auto|plain|synced|both
420
+ ```
421
+
422
+ - `auto`:有滚动歌词就保存 `.lrc`;只有纯文本就保存 `.txt`
423
+ - `plain`:只保存 `.txt`
424
+ - `synced`:只保存 `.lrc`
425
+ - `both`:两种都保存
426
+
427
+ ### `up`
428
+
429
+ `up` 会按以下步骤工作:
430
+
431
+ 1. 扫描音频文件或 YAML 元数据
432
+ 2. 查询 LRCLIB 缓存与外部歌词候选
433
+ 3. 分别查找本地 plain / synced 歌词
434
+ 4. 自动识别歌词类型
435
+ 5. 根据 `--lyrics-mode` 决定上传策略
436
+ 6. 上传成功后按配置移动或重命名文件
437
+
438
+ 推荐用法:
439
+
440
+ ```bash
441
+ pylrclib up \
442
+ --tracks ./music \
443
+ --plain-dir ./lyrics_plain \
444
+ --synced-dir ./lyrics_lrc \
445
+ --done-lrc ./done_lyrics \
446
+ --lyrics-mode auto \
447
+ --cleanse
448
+ ```
449
+
450
+ 上传策略:
451
+
452
+ ```bash
453
+ --lyrics-mode auto|plain|synced|mixed|instrumental
454
+ ```
455
+
456
+ 默认 `auto` 的逻辑是:
457
+
458
+ - 同时有 plain 和 synced:一起上传
459
+ - 只有 synced:上传滚动歌词,并可从中派生纯文本歌词
460
+ - 只有 plain:只上传纯文本歌词
461
+ - 明确识别为纯音乐:按纯音乐上传
462
+ - 无效歌词:跳过,不再自动当成纯音乐
463
+
464
+ ### `inspect` / `cleanse` / `doctor`
465
+
466
+ - `inspect`:查看本地匹配到了哪些歌词文件、最终被识别为什么类型
467
+ - `cleanse`:清洗 `.lrc`,并避免把无效文件误清空
468
+ - `doctor`:查看解析后的配置和当前目录中的可用输入数量
469
+
470
+ ---
471
+
472
+ ## License
473
+
474
+ MIT