gerdur 2.12.0 → 2.13.0

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.13.0 - 2026-08-31
4
+
5
+ ### Added
6
+
7
+ - **`--fast`** — skip the expensive per-track metadata: full studio credits, BPM,
8
+ and the Musixmatch fallback for tracks Deezer has no lyrics for. Tagging is
9
+ what actually burns Deezer's rate limit (a 14-track album costs ~54 requests to
10
+ tag against 2 to fetch), and this takes that album to **7 requests — 81% fewer
11
+ against the quota**. Audio, cover, Deezer lyrics and `.lrc` sidecars are
12
+ unchanged; you lose credits, BPM and non-Deezer lyrics.
13
+ - **`gerdur-core@^2.16.0`** for the underlying `lyricsFallback` option.
14
+
3
15
  ## 2.12.0 - 2026-08-31
4
16
 
5
17
  ### Changed
package/README.md CHANGED
@@ -166,6 +166,7 @@ All options are optional; the interactive prompt fills in the rest. Provide
166
166
  | `--search-limit` | | number | How many results to fetch (default 50) |
167
167
  | `--preview` | | — | Download 30-second `.preview.mp3` clips — no `--quality`, no `arl` |
168
168
  | `--enrich` | | — | Embed a higher-res cover from the Cover Art Archive (by ISRC) |
169
+ | `--fast` | | — | Skip per-track credits, BPM and the Musixmatch lyrics fallback — **~81% fewer Deezer requests** |
169
170
  | `--update` | `-U` | — | Self-update (prebuilt binary only) |
170
171
  | `--help` | `-h` | — | Full help |
171
172
 
@@ -245,6 +246,30 @@ at 1800 px). No match or the services are down? It silently keeps Deezer's cover
245
246
  gerdur --enrich -q flac -u https://deezer.com/album/302127
246
247
  ```
247
248
 
249
+ ### Downloading a lot at once (`--fast`)
250
+
251
+ Tagging, not downloading, is what burns through Deezer's rate limit: a 14-track
252
+ album costs about **54 requests to tag** and 2 to fetch. Most of that is per-track
253
+ — full credits and BPM (`song.getData` + a public lookup each), plus a Musixmatch
254
+ scrape for every track Deezer has no lyrics for, which fails outright on many
255
+ networks.
256
+
257
+ `--fast` skips exactly those. Same audio, same cover, same Deezer lyrics, same
258
+ `.lrc` sidecars:
259
+
260
+ ```bash
261
+ gerdur --fast -q flac -u https://deezer.com/album/302127
262
+ ```
263
+
264
+ | 14-track album | requests | against Deezer's quota |
265
+ | :--- | ---: | ---: |
266
+ | default | 54 | 36 |
267
+ | `--fast` | **7** | **7** |
268
+
269
+ You lose full studio credits, BPM, and lyrics for tracks Deezer doesn't carry.
270
+ Worth it when you're pulling a large library and getting rate-limited; leave it
271
+ off for a handful of tracks you care about.
272
+
248
273
  ### Output templates
249
274
 
250
275
  `--output` (or `saveLayout` in the config) is a path template. `{TOKEN}`s are
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gerdur",
3
- "version": "2.12.0",
3
+ "version": "2.13.0",
4
4
  "description": "Command-line music downloader for Deezer (Spotify/Tidal links resolved via ISRC matching) with automatic MP3/FLAC tagging, synced lyrics and a side-effect-free programmatic API.",
5
5
  "keywords": [
6
6
  "deezer",
@@ -63,7 +63,7 @@
63
63
  "adm-zip": "^0.5.16",
64
64
  "chalk": "^4.1.2",
65
65
  "commander": "^9.5.0",
66
- "gerdur-core": "^2.15.0",
66
+ "gerdur-core": "^2.16.0",
67
67
  "dot-prop": "^6.0.1",
68
68
  "got": "^11.8.6",
69
69
  "gradient-string": "^2.0.2",
@@ -60,7 +60,8 @@ const cmd = new commander_1.Command()
60
60
  .option('--dur-max <seconds>', 'Search filter: maximum duration')
61
61
  .option('--search-limit <n>', 'Max search results to fetch', '50')
62
62
  .option('--preview', 'Download the 30-second preview clips instead of full tracks', false)
63
- .option('--enrich', 'Embed a higher-res cover from the Cover Art Archive (looked up by ISRC)', false);
63
+ .option('--enrich', 'Embed a higher-res cover from the Cover Art Archive (looked up by ISRC)', false)
64
+ .option('--fast', 'Skip per-track credits, BPM and the Musixmatch lyrics fallback (~81% fewer Deezer requests)', false);
64
65
  if (process.pkg) {
65
66
  cmd.option('-U, --update', 'Update this program to latest version');
66
67
  }
@@ -486,6 +487,7 @@ const startDownload = async (saveLayout, url, skipPrompt) => {
486
487
  message: `(${index}/${data.tracks.length})`,
487
488
  lrc,
488
489
  enrich: Boolean(options.enrich),
490
+ fast: Boolean(options.fast),
489
491
  prefetched: prefetchedUrls.get(track.SNG_ID) ?? null,
490
492
  });
491
493
  // Add to saved list
@@ -27,6 +27,13 @@ interface downloadTrackProps {
27
27
  * to Deezer's cover if there's no match. Off by default.
28
28
  */
29
29
  enrich?: boolean;
30
+ /**
31
+ * Skip the expensive per-track metadata: full credits, BPM, and the Musixmatch
32
+ * fallback for tracks Deezer has no lyrics for. Measured on a 14-track album
33
+ * that is 54 requests down to 7 — 81% fewer against Deezer's rate limit — at
34
+ * the cost of those fields. Off by default.
35
+ */
36
+ fast?: boolean;
30
37
  /**
31
38
  * A download URL already resolved for this track by a batch `resolveDownloadUrls`
32
39
  * pass. When set, the per-track `get_url` request and quality-fallback round-trips
@@ -40,5 +47,5 @@ interface downloadTrackProps {
40
47
  format: string;
41
48
  } | null;
42
49
  }
43
- declare const downloadTrack: ({ track, quality, info, coverSizes, path, totalTracks, trackNumber, fallbackTrack, fallbackQuality, isFallback, isQualityFallback, overwrite, message, lrc, enrich, prefetched, }: downloadTrackProps) => Promise<string | undefined>;
50
+ declare const downloadTrack: ({ track, quality, info, coverSizes, path, totalTracks, trackNumber, fallbackTrack, fallbackQuality, isFallback, isQualityFallback, overwrite, message, lrc, enrich, fast, prefetched, }: downloadTrackProps) => Promise<string | undefined>;
44
51
  export default downloadTrack;
@@ -17,7 +17,7 @@ const pipeline = (0, util_1.promisify)(stream_1.default.pipeline);
17
17
  const simulate = process.env.SIMULATE;
18
18
  /** media-API format string -> gerdur's numeric quality */
19
19
  const FORMAT_TO_QUALITY = { FLAC: 9, MP3_320: 3, MP3_256: 3, MP3_128: 1, MP3_64: 1 };
20
- const downloadTrack = async ({ track, quality, info, coverSizes, path, totalTracks, trackNumber = true, fallbackTrack = true, fallbackQuality = true, isFallback = false, isQualityFallback = false, overwrite = false, message = '', lrc = true, enrich = false, prefetched = null, }) => {
20
+ const downloadTrack = async ({ track, quality, info, coverSizes, path, totalTracks, trackNumber = true, fallbackTrack = true, fallbackQuality = true, isFallback = false, isQualityFallback = false, overwrite = false, message = '', lrc = true, enrich = false, fast = false, prefetched = null, }) => {
21
21
  (0, log_update_1.default)(signale_1.default.pending(track.SNG_TITLE + ' by ' + track.ART_NAME + ' from ' + track.ALB_TITLE));
22
22
  try {
23
23
  let ext = '.mp3', fileSize = 0, downloaded = 0, coverSize = 500;
@@ -159,6 +159,7 @@ const downloadTrack = async ({ track, quality, info, coverSizes, path, totalTrac
159
159
  // written by a stream, so the track is never held in memory.
160
160
  const model = await (0, gerdur_core_1.resolveTagModel)(track, {
161
161
  coverSize,
162
+ ...(fast ? { richCredits: false, lyricsFallback: false } : {}),
162
163
  ...(enrichedCover ? { cover: enrichedCover } : {}),
163
164
  });
164
165
  (0, log_update_1.default)(signale_1.default.pending('Saving ' + track.SNG_TITLE + ' by ' + track.ART_NAME));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gerdur",
3
- "version": "2.12.0",
3
+ "version": "2.13.0",
4
4
  "description": "Command-line music downloader for Deezer (Spotify/Tidal links resolved via ISRC matching) with automatic MP3/FLAC tagging, synced lyrics and a side-effect-free programmatic API.",
5
5
  "keywords": [
6
6
  "deezer",
@@ -63,7 +63,7 @@
63
63
  "adm-zip": "^0.5.16",
64
64
  "chalk": "^4.1.2",
65
65
  "commander": "^9.5.0",
66
- "gerdur-core": "^2.15.0",
66
+ "gerdur-core": "^2.16.0",
67
67
  "dot-prop": "^6.0.1",
68
68
  "got": "^11.8.6",
69
69
  "gradient-string": "^2.0.2",