Skip to content

Commit

Permalink
feat: ComicInfo.xml
Browse files Browse the repository at this point in the history
  • Loading branch information
yinyanfr committed Mar 17, 2023
1 parent 9cd0ecb commit 471c3e7
Show file tree
Hide file tree
Showing 9 changed files with 245 additions and 39 deletions.
18 changes: 17 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
# Changelog

# 1.5.0

`2023-03-18`

### Features

- You can now download or embbed a ComicInfo.xml in chapters
- `getSerieInfo` and `list`(CLI) now displays ComicInfo fields
- [Library] added `info` (boolean) as an option for serie, you can also pass it to chapter download, but you need to provide the info object
- [Library] Added options for list so that you can generate and write ComicInfo.xml
- [CLI] added `-i, --info` flag for `dl` to write ComicInfo.xml and for `ls` to display it, use `-o` for `ls` to write the ComicInfo.xml

### Fix

- [CLI] Fixed a bug that would cause folder name to be wrongly set when downloading a single chapter

## 1.4.1

`2023-03-17`
Expand All @@ -12,7 +28,7 @@
- chapters: Only downloading given list of chapter indexes, for CLI: -c, --chapters 1,2,4,7
- Better logs when partially downloading serie
- Improved type consistency
- Add uri to `DownloadProgress`
- Added uri to `DownloadProgress`

## 1.3.0

Expand Down
28 changes: 20 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ This library is not for browsers.
- Chapter list
- Download as ZIP/CBZ, or just a folder of pictures
- Downloading progress watch
- Generates [ComicInfo.xml](https://anansi-project.github.io/docs/comicinfo/intro)

## :green_book: Quick Start

Expand All @@ -29,7 +30,7 @@ npx zerobyw-dl help
## :wrench: Cli

```
Usage: zerobyw dl [options] [command]
Usage: zerobyw-dl [options] [command]
Commands:
chapter, c, ch Download images from one chapter.
Expand All @@ -45,9 +46,10 @@ Options:
-c, --cookie Optional (but recommanded): Provide the path to a text file that contains your cookie.
-f, --from Optional: Starting chapter when downloading a serie, default to 0.
-h, --help Output usage information
-i, --info Optional: Generate ComicInfo.xml.
-m, --max-title-length Optional: restrict the length of title as the folder name.
-n, --name Optional: Proride the serie title and override the folder name.
-o, --output Optional: The path where downloaded files are saved (default to .).
-o, --output Optional: The path where downloaded files are saved (default to .), setting this flag when using list will save a ComicInfo.xml to the path.
-r, --retry Optional: Automatically re-download chapters with failed images.
-s, --slience Optional: Silence the console output.
-T, --timeout Optional: Override the default 10s request timeout.
Expand All @@ -59,8 +61,8 @@ Options:
-z, --zip-level Optional: zip level for archive, default to 5.
Examples:
- Download a serie from its 10th chapter to 20th chapter to the given destination, output zip archives by chapter.
$ npx zerobyw-dl dl -u serie_url -c cookie.txt -f 10 -t 20 -o ~/Download/zerobyw -a zip
- Download a serie from its 10th chapter to 20th chapter to the given destination, output zip archives with ComicInfo.xml by chapter, retry if a chapter is not properly downloaded.
$ npx zerobyw-dl dl -c cookie.txt -f 10 -t 20 -o ~/Download/zerobyw -a zip -r -i -u serie_url
- List all chapters of the given serie.
$ npx zerobyw-dl ls -u serie_url
Expand Down Expand Up @@ -106,6 +108,13 @@ const downloader = new ZeroBywDownloader(destination, configs);
### :scroll: Getting serie info

```typescript
const options = {
output: "output_path", // Optional: Set this to write a ComicInfo.xml to the path, use true to output to the inherited destination folder
// By default, the file is downloaded to destination/serie_title/ComicInfo.xml
rename: "serie_title", // Optional: Override the serie title folder name
filename: "ComicInfo.xml", // Optional: Overrides the default file name
};

const info = await downloader.getSerieInfo("serie_url");
// info
// {
Expand All @@ -114,7 +123,8 @@ const info = await downloader.getSerieInfo("serie_url");
// index: 0,
// name: "Chapter Name",
// uri: "chapter_uri", // without baseUrl
// }]
// }],
// info: {} // please refer to ComicInfo's Documentations
// }
```

Expand All @@ -127,7 +137,8 @@ const options = {
confirm: false, // Optional: Launch a console prompt asking for user's confirmation before starting downloading, default to false
rename: undefined, // Optional: Changing the folder name, default to undefined
retry: false, // Optional: Automatically re-download chapters with failed images.
chapters: undefined, // Optional: Automatically re-download chapters with failed images.
info: true, // Optional: Generates ComicInfo.xml, default to **false**
chapters: undefined, // Optional: Automatically re-download chapters with failed images
onProgress: (progress) => {
console.log(progress);
}, // Optional: Called when a chapter is downloaded or failed to do so
Expand Down Expand Up @@ -156,6 +167,7 @@ await downloader.downloadSerie("serie_url", options);
const options = {
index: 0, // chapter index
title: "Serie Title",
info: ComicInfo, // Optional: Generates ComicInfo.xml, please refer to ComicInfo's Documentations
onProgress: (progress) => {}, // Optional: Called when a chapter is downloaded or failed to do so, the same as in serie options
}; // Optional

Expand All @@ -175,6 +187,6 @@ downloader.setConfig("archive", "cbz");
downloader.setConfigs({ archive: "cbz" }); // Will merge
```

## :information_source: Credits
## :information_source: Information

- [zero 漫画下载](https://greasyfork.org/zh-CN/scripts/459982-zero%E6%BC%AB%E7%94%BB%E4%B8%8B%E8%BD%BD)
- [ComicInfo.xml Documentations](https://anansi-project.github.io/docs/comicinfo/intro)
20 changes: 18 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "zerobyw-dl",
"version": "1.4.1",
"version": "1.5.0",
"description": "Yet another batch downloader for zerobyw",
"main": "dist/index.js",
"bin": "dist/cli.js",
Expand Down Expand Up @@ -30,13 +30,15 @@
"@types/args": "^5.0.0",
"@types/jsdom": "^21.1.0",
"@types/node": "^18.15.0",
"@types/xml": "^1.0.8",
"typescript": "^4.9.5"
},
"dependencies": {
"archiver": "^5.3.1",
"args": "^5.0.3",
"axios": "^1.3.4",
"jsdom": "^21.1.1",
"xml": "^1.0.1",
"yesno": "^0.4.0"
}
}
11 changes: 8 additions & 3 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ args
)
.option(
"output",
"Optional: The path where downloaded files are saved (default to .)."
"Optional: The path where downloaded files are saved (default to .), setting this flag when using list will save a ComicInfo.xml to the path."
)
.option(
"cookie",
Expand Down Expand Up @@ -67,9 +67,14 @@ args
"chapters",
"Optional: Only downloading given list of chapters, example: -C 1,2,4,7"
)
.option("info", "Optional: Generate ComicInfo.xml.")
.example(
"npx zerobyw-dl dl -u serie_url -c cookie.txt -f 10 -t 20 -o ~/Download/zerobyw -a zip",
"Download a serie from its 10th chapter to 20th chapter to the given destination, output zip archives by chapter."
"npx zerobyw-dl dl -c cookie.txt -f 10 -t 20 -o ~/Download/zerobyw -a zip -r -i -u serie_url",
"Download a serie from its 10th chapter to 20th chapter to the given destination, output zip archives with ComicInfo.xml by chapter, retry if a chapter is not properly downloaded."
)
.example(
"npx zerobyw-dl dl -c cookie.txt -o ~/Download/zerobyw -i -u serie_url -c 0,4,12",
"Download chapter index 0, 4, 12 from a serie"
)
.example(
"npx zerobyw-dl ls -u serie_url",
Expand Down
38 changes: 26 additions & 12 deletions src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,20 +32,26 @@ function buildDownloader(options: Partial<CliOptions> = {}) {
}

export const listCommand: Command = async (name, sub, options = {}) => {
const { url, verbose } = options;
const { url, verbose, silence, output, name: rename } = options;
const downloader = buildDownloader(options);

try {
if (url) {
const info = await downloader.getSerieInfo(url);
if (info) {
console.log(`Title: ${info.title}`);
console.log("----");
info.chapters?.forEach((e) => {
console.log(`${e.index} ${e.name}`);
console.log(`${e.uri}`);
const serie = await downloader.getSerieInfo(url, { output, rename });
if (serie) {
if (!silence) {
console.log(`Title: ${serie.title}`);
console.log("----");
});
serie.chapters?.forEach((e) => {
console.log(`${e.index} ${e.name}`);
console.log(`${e.uri}`);
console.log("----");
});

Object.keys(serie.info).forEach((e) => {
console.log(`${e}: ${serie.info[e]}`);
});
}
} else {
console.log("Please Provide URL.");
}
Expand All @@ -71,6 +77,7 @@ export const downloadCommand: Command = async (name, sub, options = {}) => {
name: rename,
retry,
chapters,
info,
} = options;
const downloader = buildDownloader(options);
let current: Partial<DownloadProgress> = {};
Expand All @@ -83,6 +90,7 @@ export const downloadCommand: Command = async (name, sub, options = {}) => {
confirm: !yes,
rename,
retry,
info,
chapters: chapters
? chapters.split(",").map((e) => parseInt(e))
: undefined,
Expand Down Expand Up @@ -118,12 +126,18 @@ export const downloadCommand: Command = async (name, sub, options = {}) => {
};

export const chapterCommand: Command = async (name, sub, options = {}) => {
const { url, name: chapterName, verbose } = options;
const { url, name: chapterName, verbose, output } = options;
const downloader = buildDownloader(options);

try {
if (url) {
await downloader.downloadChapter(chapterName ?? "Untitled", url);
let serie: SerieInfo | undefined;
if (output) {
serie = await downloader.getSerieInfo(url);
}
await downloader.downloadChapter(chapterName ?? "Untitled", url, {
info: serie?.info,
});
} else {
console.log("Please Provide URL.");
}
Expand All @@ -132,7 +146,7 @@ export const chapterCommand: Command = async (name, sub, options = {}) => {
console.error(error);
} else {
console.log(
`Failed to download ${name}. (Use -v or --verbose flag for detailed error messages.)`
`Failed to download ${chapterName}. (Use -v or --verbose flag for detailed error messages.)`
);
}
}
Expand Down
42 changes: 42 additions & 0 deletions src/global.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,45 @@ interface Chapter {
uri?: string;
}

/**
* ComicInfo.xml
* https://anansi-project.github.io/docs/comicinfo/documentation
*/
interface ComicInfo {
Serie?: string; // serie title
Summary?: string;
Writer?: string;
Penciller?: string;
Language?: string;
Genre?: string;
Year?: string;
Month?: string;
Day?: string;
Location?: string;
Count?: string | number;
Tags?: string;
Web?: string;
Note?: string;
Manga?: "YesAndRightToLeft";
Status?: "Ongoing" | "End" | "Abandoned" | "Hiatus"; // This one isn't in the schema but it should
[Key: string]: any; // and many more
}

interface SerieInfoOptions {
output?: boolean | string;
rename?: string;
filename?: string;
}

/**
* This is what getSerieInfo returns
*/
interface SerieInfo {
title: string;
chapters: Chapter[];
info: ComicInfo;
}

interface DownloadProgress {
index?: number;
name: string;
Expand All @@ -31,6 +70,7 @@ interface SerieDownloadOptions {
retry?: boolean;
chapters?: number[];
confirm?: boolean;
info?: boolean;
onProgress?: (progress: DownloadProgress) => void;
}

Expand All @@ -43,6 +83,7 @@ interface ImageDownloadOptions {
interface ChapterDownloadOptions {
index?: number;
title?: string;
info?: ComicInfo;
onProgress?: (progress: DownloadProgress) => void;
}

Expand All @@ -63,6 +104,7 @@ interface CliOptions {
zipLevel: number; // zip-level
retry: boolean;
chapters: string; // 1,2,4,7
info?: boolean;
}

type Command = (
Expand Down
Loading

0 comments on commit 471c3e7

Please sign in to comment.