Skip to content

Commit

Permalink
feat: support search by comic id
Browse files Browse the repository at this point in the history
  • Loading branch information
justorez committed Feb 1, 2024
1 parent 1dae01a commit 5f1ea0f
Show file tree
Hide file tree
Showing 12 changed files with 104 additions and 35 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/task.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ on:
- favorites
- leaderboard
PICA_DL_SEARCH_KEYWORDS:
description: '搜索关键字,多个用 # 隔开'
description: '搜索关键字或者漫画ID (多个用 # 隔开)'
type: string
OUTPUT_ZIP:
description: '每个章节打成独立压缩包'
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "pica-cli",
"author": "justorez",
"version": "1.2.0",
"version": "1.3.0",
"description": "😉 哔咔漫画下载器",
"packageManager": "[email protected]",
"type": "module",
Expand All @@ -17,7 +17,7 @@
"start:zip": "node dist/zip.js",
"build": "rimraf dist && rollup --config rollup.config.js",
"test": "vitest",
"pub": "pnpm build && pnpm publish",
"pub": "pnpm build && npm publish",
"check": "tsc --incremental --noEmit",
"lint": "eslint --cache --ext js,cjs,ts, --ignore-path .gitignore .",
"lint:fix": "eslint --cache --fix --ignore-path .gitignore .",
Expand Down Expand Up @@ -86,6 +86,7 @@
"eslint": "^8.56.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.1.3",
"figures": "^6.0.1",
"lint-staged": "^15.2.0",
"mime": "^4.0.1",
"ora": "^8.0.1",
Expand Down
10 changes: 10 additions & 0 deletions pnpm-lock.yaml

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

17 changes: 8 additions & 9 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,16 @@

😉 哔咔漫画下载器

![演示](https://s2.loli.net/2024/01/29/rhcOo4GBD8kLEqv.gif)
![演示](https://s2.loli.net/2024/02/01/Qc7L3qGZOWBPmkR.gif)

- 交互式命令行
- 排行榜:下载当前排行榜的全部漫画
- 收藏夹:下载当前用户收藏夹的全部漫画
- 关键词搜索:支持多选
- 搜索:支持关键字和漫画ID (多个用 # 隔开)。访问哔咔电脑端网站,进入漫画详情,地址栏链接里的 `cid` 就是漫画ID
- 自动过滤已下载的章节和图片,不会重复下载
- 如果没有相关环境变量,则启动交互命令界面;若有则直接执行
- 通过 `pica-zip` 命令分章节批量压缩,配合支持 zip 包的漫画阅读软件使用,比如 [Perfect Viewer](https://play.google.com/store/apps/details?id=com.rookiestudio.perfectviewer)。<br>
不限于 `pica-cli` 下载的漫画使用,只要符合 [cmoics/漫画标题/漫画章节/漫画图片](#) 的目录结构即可。
- 借助 github action 实现飞速下载,支持从 github artifact 和 file.io(无需注册和科学上网)两种方式下载完整漫画包。<br>
file.io 文件保存两周,单文件最大 2GB,注意链接只能下载**一次**,下载后文件会自动删除
- 通过 `pica-zip` 命令分章节批量压缩,配合支持 zip 的漫画阅读软件使用,比如 [Perfect Viewer](https://play.google.com/store/apps/details?id=com.rookiestudio.perfectviewer)。不限于 `pica-cli` 下载的漫画,只要符合 [cmoics/漫画标题/漫画章节/漫画图片](#) 的目录结构即可。
- 借助 github action 实现飞速下载,支持从 github artifact 和 file.io 两种方式下载完整漫画包。file.io 无需注册,无需科学上网,文件保存两周,单文件最大 2GB,注意链接只能下载**一次**,下载后文件会自动删除

如果用的开心,求个 star 支持一下,比心 ~ ❤️

Expand All @@ -35,11 +33,11 @@ PICA_ACCOUNT
PICA_PASSWORD
```

fork 一份本仓库,将上面三个环境变量,设置为仓库密钥:
fork 一份[本仓库](https://github.com/justorez/pica-cli),将上面三个环境变量,设置为仓库密钥:

![action secret](https://s2.loli.net/2024/01/30/5FxU7olyWC3VAe1.png)

然后点击 Actions,再点击左侧的 `task` 工作流,再点击右侧的 `Run workflow`,输入相关的信息,点击运行即可
然后点击 Actions,再点击左侧的 `task` 工作流,再点击右侧的 `Run workflow`,输入相关的信息,点击运行

![action run](https://s2.loli.net/2024/01/30/PmfublZKLFQrth9.png)

Expand All @@ -51,7 +49,7 @@ fork 一份本仓库,将上面三个环境变量,设置为仓库密钥:

![file.io](https://s2.loli.net/2024/01/31/UT4i6zpGjYvDxL3.png)

如果你想自定义过程,请自行修改 [.github/workflows/task.yaml](.github/workflows/task.yaml)
如果你想自定义过程,请自行修改 [.github/workflows/task.yml](.github/workflows/task.yml)

### 方式二:直接安装

Expand Down Expand Up @@ -110,6 +108,7 @@ pnpm dev:zip

## 更新日志

- 2024/02/01 支持通过漫画ID精确下载
- 2024/01/31 github action 同时将漫画包上传到 file.io
- 2024/01/30 提供 github action 的下载方式
- 2024/01/29 下载完成后,提供命令把漫画按章节批量压缩
Expand Down
Binary file added resource/1-1.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed resource/1.gif
Binary file not shown.
Binary file added resource/2-6.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 13 additions & 3 deletions scripts/upload.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,28 @@ import axios from 'axios'
import mime from 'mime'
import AdmZip from 'adm-zip'
import pico from 'picocolors'
import figures from 'figures'

const __dirname = path.dirname(fileURLToPath(import.meta.url))
const MAX_SIZE = 2 * 1024 * 1024 * 1024 // 2GB

const log = {
log: (...msg) => console.log(...msg),
info: (...msg) => console.log(pico.cyan('➡️'), ...msg),
warn: (...msg) =>
console.log(pico.yellow(`${figures.warning} ${msg.join(' ')}`)),
error: (...msg) =>
console.log(pico.red(`${figures.cross} ${msg.join(' ')}`))
}

// https://file.io/
async function main() {
let root = path.resolve(__dirname, '../comics-zip')

if (!existsSync(root)) {
root = path.resolve(__dirname, '../comics')
if (!existsSync(root)) {
console.log(pico.yellow('没有发现已下载的漫画'))
log.warn('没有发现已下载的漫画')
return
}
}
Expand All @@ -41,11 +51,11 @@ async function main() {
`https://file.io?title=${filename}`,
form
)
console.log(
log.log(
`${pico.cyan(filename)} 已上传到 file.io. 下载地址:${pico.green(data.link)}`
)
} else {
console.log(pico.yellow(`${filename} 大小超过了 2GB`))
log.warn(`${filename} 大小超过了 2GB`)
}
} catch (error) {
console.error(error)
Expand Down
51 changes: 37 additions & 14 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
import { Pica } from './sdk'
import { filterEpisodes, filterPictures, loadEnv, mark } from './utils'
import {
log,
mark,
loadEnv,
filterEpisodes,
filterPictures,
isValidComicId
} from './utils'
import ora from 'ora'
import { select, checkbox, input } from '@inquirer/prompts'
import ProgressBar from 'progress'
import { Comic } from './types'
import pLimit from 'p-limit'
import picos from 'picocolors'
import pico from 'picocolors'

loadEnv()

Expand Down Expand Up @@ -42,25 +49,42 @@ async function main() {

if (answer === 'search') {
if (PICA_IS_GITHUB && !PICA_DL_SEARCH_KEYWORDS) {
console.log(picos.yellow('没有输入搜索关键字'))
log.warn('没有输入搜索关键字')
return
}

let searchRes: Comic[] = []

const keywords =
const inputStr =
PICA_DL_SEARCH_KEYWORDS ||
(await input({
message: '请输入关键字(多个用 # 隔开',
message: '请输入关键字或者漫画ID (多个用 # 隔开)',
transformer: (val) => val.trim()
}))

if (!keywords) {
console.log(picos.yellow('没有输入搜索关键字'))
if (!inputStr) {
log.warn('没有输入搜索关键字')
return
}

for (const keyword of keywords.split('#')) {
const inputKeys = inputStr.split('#')

// 根据漫画ID查询
const bookIds = inputKeys.filter((k: string) => isValidComicId(k))
for (const id of bookIds) {
try {
const info = await pica.comicInfo(id)
info.title = info.title.trim()
comics.push(info)
log.info(`${info.title} 已加入下载队列`)
} catch (error) {
log.error(`无效漫画ID ${id}`)
}
}

// 根据关键字查询
const keywords = inputKeys.filter((k: string) => !isValidComicId(k))
for (const keyword of keywords) {
spinner.start(`正在搜索 ${keyword}`)
searchRes = await pica.searchAll(keyword)
spinner.stop()
Expand Down Expand Up @@ -91,9 +115,7 @@ async function main() {
episodes = filterEpisodes(episodes, cid)
spinner.stop()

console.log(
`${picos.cyan('➡️')} ${title} 查询到 ${episodes.length} 个章节`
)
log.info(`${title} 查询到 ${episodes.length} 个章节`)

for (const ep of episodes) {
spinner.start(`正在获取章节 ${ep.title} 的图片信息`)
Expand All @@ -102,7 +124,7 @@ async function main() {
spinner.stop()

const bar = new ProgressBar(
`${picos.cyan('➡️')} ${title} ${ep.title} [:bar] :current/:total`,
`${pico.cyan('➡️')} ${title} ${ep.title} [:bar] :current/:total`,
{
incomplete: ' ',
width: 20,
Expand All @@ -129,12 +151,13 @@ async function main() {
mark(cid, ep.id)
}

console.log(picos.green(`✓ ${picos.bold(title)} 下载完成`))
log.success(`${title} 下载完成`)
}
}

process.on('uncaughtException', (err) => {
console.log(`\n${picos.red(err.message)}`)
console.log('\n')
log.error(`${err.message}`)
process.exit(0)
})

Expand Down
2 changes: 1 addition & 1 deletion src/sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ export class Pica {
*/
async comicInfo(bookId: string) {
const url = `comics/${bookId}`
const res = await this.request('get', url)
const res = await this.request<Comic>('get', url)
return res.comic
}

Expand Down
23 changes: 23 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,15 @@ import dotenv from 'dotenv'
import fs from 'node:fs'
import { Episode, Picture } from './types'
import Debug from 'debug'
import pico from 'picocolors'
import figures from 'figures'

export const debug = Debug('pica')

export function isValidComicId(cid: string) {
return /^[0-9a-zA-Z]{24}$/.test(cid)
}

/**
* 标记某章节已下载完成,并记录到本地临时文件
*/
Expand Down Expand Up @@ -81,3 +87,20 @@ export function normalizeName(s: string) {
.replace(/>/g, '>')
.replace(/:/g, '-')
}

type LogMsg = string[] | number[]
// √ ✕
export const log = {
log: (...msg: LogMsg) => console.log(...msg),
info: (...msg: LogMsg) => console.log(pico.cyan('➡️'), ...msg),
warn: (...msg: LogMsg) =>
console.log(pico.yellow(`${figures.warning} ${msg.join(' ')}`)),
error: (...msg: LogMsg) =>
console.log(pico.red(`${figures.cross} ${msg.join(' ')}`)),
success: (...msg: LogMsg) =>
console.log(pico.green(`${figures.tick} ${msg.join(' ')}`))
}

export function sleep(s: number) {
return new Promise((r) => setTimeout(r, s * 1000))
}
13 changes: 8 additions & 5 deletions src/zip.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import AdmZip from 'adm-zip'
import path from 'node:path'
import fs from 'node:fs'
import pico from 'picocolors'
import ProgressBar from 'progress'
import pico from 'picocolors'
import { log } from './utils'

function main() {
const root = path.resolve(process.cwd(), 'comics')
const dest = path.resolve(process.cwd(), 'comics-zip')

if (!fs.existsSync(root)) {
console.log(pico.yellow('没有发现已下载的漫画'))
log.warn('没有发现已下载的漫画')
return
}

Expand All @@ -18,11 +19,11 @@ function main() {
})

if (comics.length === 0) {
console.log(pico.yellow('没有发现已下载的漫画'))
log.warn('没有发现已下载的漫画')
return
}

console.log(
log.info(
`${pico.cyan(comics.length)} 本漫画等待打包:${pico.cyan(comics.join(', '))}`
)

Expand Down Expand Up @@ -50,8 +51,10 @@ function main() {
bar.tick()
}

console.log(pico.green(`✓ ${comic} 打包完成`))
// log.success(`${comic} 打包完成`)
}

log.success(`打包完成`)
}

main()

0 comments on commit 5f1ea0f

Please sign in to comment.