podcast-dl 7.1.0 → 7.2.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/README.md +4 -2
- package/bin/async.js +8 -4
- package/bin/util.js +5 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# podcast-dl
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A CLI for downloading podcasts with a focus on archiving.
|
|
4
4
|
|
|
5
5
|
## How to Use
|
|
6
6
|
|
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
|
|
11
11
|
`npx podcast-dl --url <PODCAST_RSS_URL>`
|
|
12
12
|
|
|
13
|
+
### [More Examples](./docs/examples.md)
|
|
14
|
+
|
|
13
15
|
## Options
|
|
14
16
|
|
|
15
17
|
Type values surrounded in square brackets (`[]`) can be used as used as boolean options (no argument required).
|
|
@@ -18,6 +20,7 @@ Type values surrounded in square brackets (`[]`) can be used as used as boolean
|
|
|
18
20
|
| ------------------------ | ------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
19
21
|
| --url | String | true | URL to podcast RSS feed. |
|
|
20
22
|
| --out-dir | String | false | Specify output directory for episodes and metadata. Defaults to "./{{podcast_title}}". See "Templating" for more details. |
|
|
23
|
+
| --threads | Number | false | Determines the number of downloads that will happen concurrently. Default is 1. |
|
|
21
24
|
| --archive | [String] | false | Download or write out items not listed in archive file. Generates archive file at path if not found. Defaults to "./{{podcast_title}}/archive.json" when used as a boolean option. See "Templating" for more details. |
|
|
22
25
|
| --episode-template | String | false | Template for generating episode related filenames. See "Templating" for details. |
|
|
23
26
|
| --include-meta | | false | Write out podcast metadata to JSON. |
|
|
@@ -36,7 +39,6 @@ Type values surrounded in square brackets (`[]`) can be used as used as boolean
|
|
|
36
39
|
| --info | | false | Print retrieved podcast info instead of downloading. |
|
|
37
40
|
| --list | [String] | false | Print episode list instead of downloading. Defaults to "table" when used as a boolean option. "json" is also supported. |
|
|
38
41
|
| --exec | String | false | Execute a command after each episode is downloaded. |
|
|
39
|
-
| --threads | Number | false | Determines the number of downloads that will happen concurrently. Default is 1. |
|
|
40
42
|
| --filter-url-tacking | | false | Attempts to extract the direct download link of an episode if detected (**experimental**). |
|
|
41
43
|
| --version | | false | Output the version number. |
|
|
42
44
|
| --help | | false | Output usage information. |
|
package/bin/async.js
CHANGED
|
@@ -16,6 +16,7 @@ import { getArchiveFilename, getFilename } from "./naming.js";
|
|
|
16
16
|
import {
|
|
17
17
|
getEpisodeAudioUrlAndExt,
|
|
18
18
|
getArchiveKey,
|
|
19
|
+
getTempPath,
|
|
19
20
|
runFfmpeg,
|
|
20
21
|
runExec,
|
|
21
22
|
writeItemMeta,
|
|
@@ -63,9 +64,10 @@ const download = async ({
|
|
|
63
64
|
},
|
|
64
65
|
});
|
|
65
66
|
|
|
67
|
+
const tempOutputPath = getTempPath(outputPath);
|
|
66
68
|
const removeFile = () => {
|
|
67
|
-
if (fs.existsSync(
|
|
68
|
-
fs.unlinkSync(
|
|
69
|
+
if (fs.existsSync(tempOutputPath)) {
|
|
70
|
+
fs.unlinkSync(tempOutputPath);
|
|
69
71
|
}
|
|
70
72
|
};
|
|
71
73
|
|
|
@@ -101,14 +103,14 @@ const download = async ({
|
|
|
101
103
|
|
|
102
104
|
await pipeline(
|
|
103
105
|
got.stream(finalUrl).on("downloadProgress", onDownloadProgress),
|
|
104
|
-
fs.createWriteStream(
|
|
106
|
+
fs.createWriteStream(tempOutputPath)
|
|
105
107
|
);
|
|
106
108
|
} catch (error) {
|
|
107
109
|
removeFile();
|
|
108
110
|
throw error;
|
|
109
111
|
}
|
|
110
112
|
|
|
111
|
-
const fileSize = fs.statSync(
|
|
113
|
+
const fileSize = fs.statSync(tempOutputPath).size;
|
|
112
114
|
|
|
113
115
|
if (fileSize === 0) {
|
|
114
116
|
removeFile();
|
|
@@ -121,6 +123,8 @@ const download = async ({
|
|
|
121
123
|
return;
|
|
122
124
|
}
|
|
123
125
|
|
|
126
|
+
fs.renameSync(tempOutputPath, outputPath);
|
|
127
|
+
|
|
124
128
|
if (expectedSize && !isNaN(expectedSize) && expectedSize !== fileSize) {
|
|
125
129
|
logMessage(
|
|
126
130
|
"File size differs from expected content length. Suggestion: verify file works as expected",
|
package/bin/util.js
CHANGED
|
@@ -15,6 +15,10 @@ const parser = new rssParser({
|
|
|
15
15
|
defaultRSS: 2.0,
|
|
16
16
|
});
|
|
17
17
|
|
|
18
|
+
const getTempPath = (path) => {
|
|
19
|
+
return `${path}.tmp`;
|
|
20
|
+
};
|
|
21
|
+
|
|
18
22
|
const getArchiveKey = ({ prefix, name }) => {
|
|
19
23
|
return `${prefix}-${name}`;
|
|
20
24
|
};
|
|
@@ -569,6 +573,7 @@ export {
|
|
|
569
573
|
getFeed,
|
|
570
574
|
getImageUrl,
|
|
571
575
|
getItemsToDownload,
|
|
576
|
+
getTempPath,
|
|
572
577
|
getUrlExt,
|
|
573
578
|
getUrlEmbed,
|
|
574
579
|
logFeedInfo,
|