Skip to content

Commit

Permalink
feat: 批量禁用启用规则
Browse files Browse the repository at this point in the history
  • Loading branch information
aooiuu committed May 28, 2024
1 parent d6d885d commit 571c681
Show file tree
Hide file tree
Showing 22 changed files with 254 additions and 392 deletions.
54 changes: 52 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# any-reader

[![vsc version][vsc-src]][vsc-href]
[![npm version][npm-version-src]][npm-version-href]
[![JSDocs][jsdocs-src]][jsdocs-href]
[![satr][satr-src]][satr-href]
Expand All @@ -12,13 +11,64 @@
## VSCode 插件

<p align="left">
<a href="https://github.com/aooiuu/any-reader">
<img
src="https://img.shields.io/visual-studio-marketplace/v/aooiu.any-reader"
alt=""
/>
</a>
<a href="https://github.com/aooiuu/any-reader">
<img
src="https://img.shields.io/visual-studio-marketplace/d/aooiu.any-reader"
alt=""
/>
</a>
<a href="https://github.com/aooiuu/any-reader">
<img
src="https://img.shields.io/visual-studio-marketplace/i/aooiu.any-reader"
alt=""
/>
</a>
</p>

[文档](https://aooiuu.github.io/any-reader/vsc/)

### 功能

- [x] 本地小说阅读
- [x] txt格式
- [x] epub格式
- [x] 小说章节识别
- [x] 在线小说阅读
- [x] 自定义书源规则
- [x] 自定义热键
- [x] 漫画
- [x] 聚合搜索
- [x] 发现页分类排行榜
- [x] 侧边栏阅读(可拖动到底部栏)
- [x] 收藏
- [x] 历史记录

## 桌面端

[文档](https://aooiuu.github.io/any-reader/desktop/)

🚧 开发中
### 功能

- [x] 本地小说阅读
- [x] txt格式
- [x] epub格式
- [x] 小说章节识别
- [x] 在线小说阅读
- [x] 自定义书源规则
- [x] 自定义热键
- [x] 漫画
- [x] 视频
- [x] 聚合搜索
- [x] 发现页分类排行榜
- [x] 收藏
- [x] 历史记录

<img src="https://github.com/aooiuu/any-reader/assets/28108111/d4629d6f-b0c0-48cd-830f-f4b1ea4e4a2c" width="600"/>

Expand Down
10 changes: 3 additions & 7 deletions packages/server/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,16 @@ import Koa from 'koa'
import { bodyParser } from '@koa/bodyparser'
import cors from '@koa/cors'
import serve from 'koa-static'
import { favoritesManager, historyManager, ruleFileManager } from '@any-reader/shared'
import { router } from './router'
import { api } from '@any-reader/shared'
import { router } from './routes'

const __filename = fileURLToPath(import.meta.url)
const __dirname = path.resolve(path.dirname(__filename), '..')

const app = new Koa()

async function start() {
await Promise.all([
ruleFileManager.init(),
favoritesManager.init(),
historyManager.init(),
])
await api.init()
app
.use(bodyParser())
.use(cors())
Expand Down
76 changes: 0 additions & 76 deletions packages/server/src/router/index.ts

This file was deleted.

22 changes: 22 additions & 0 deletions packages/server/src/routes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import Router from 'koa-router'
import { CONSTANTS, api } from '@any-reader/shared'

export const router = new Router()

api.useApi(
async (path: string, cb: any) => {
if (path.startsWith('get')) {
router.get(path.replace(/get@/, '/'), async (ctx) => {
ctx.body = await cb(ctx.query)
})
}
else if (path.startsWith('post')) {
router.get(path.replace(/post@/, '/'), async (ctx) => {
ctx.body = await cb(ctx.request.body)
})
}
},
{
CONFIG_PATH: '',
bookDir: CONSTANTS.LOCAL_BOOK_DIR,
})
44 changes: 40 additions & 4 deletions packages/shared/src/api.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { ensureFile, readJson, writeJson } from 'fs-extra'
// @ts-expect-error
import { ensureFile, readJson, writeJson } from 'fs-extra/esm'
import type { Rule } from '@any-reader/core'
import { ContentType, RuleManager } from '@any-reader/core'
import * as ruleFileManager from './ruleFileManager'
Expand Down Expand Up @@ -85,13 +86,17 @@ export function rules() {
return ruleFileManager.list()
}

export function batchUpdateRules(data: { ids: string[]; rule: Rule }) {
return ruleFileManager.batchUpdate(data)
}

/**
* 根据规则ID获取规则
* @param ruleId
* @returns
*/
export function getRuleById(ruleId: string) {
const rules = ruleFileManager.list()
export async function getRuleById(ruleId: string) {
const rules = await ruleFileManager.list()
return rules.find(e => e.id === ruleId)
}

Expand Down Expand Up @@ -134,7 +139,7 @@ export async function content({ filePath, chapterPath, ruleId }: any) {
if (ruleId) {
const rule = await ruleFileManager.findById(ruleId)
const rm = new RuleManager(rule)
const content = await rm.getContent(chapterPath).catch(() => [])
const content: string[] = await rm.getContent(chapterPath).catch(() => [])
let text = ''
if (rule.contentType === ContentType.MANGA)
text = content.map(src => `<img src="${src}"/>`).join('')
Expand Down Expand Up @@ -205,3 +210,34 @@ export function getRuleExtras() {
export function ping(data: { id: string; host: string }) {
return ruleExtraManager.ping(data.id, data.host)
}

function success(data: any, msg = '') {
return {
code: 0,
data,
msg,
}
}

// vscode 、electron、服务端通用注册接口
export function useApi(register: any, { CONFIG_PATH, bookDir }: any) {
register('get@discoverMap', async ({ ruleId = '' } = {}) => success(await discoverMap(ruleId)))
register('get@getFavorites', async () => success(await getFavorites()))
register('get@getHistory', async () => success(await getHistory()))
register('get@getLocalBooks', async () => success(await getLocalBooks(bookDir)))
register('post@discover', async (data: any) => success(await discover(data)))
register('post@star', async (data: any) => success(await star(data)))
register('post@unstar', async (data: any) => success(await unstar(data)))
register('get@rules', async () => success(await rules()))
register('get@getRuleById', async ({ id = '' } = {}) => success(await getRuleById(id)))
register('post@createRule', async (data: any) => success(await createRule(data)))
register('post@updateRule', async (data: any) => success(await updateRule(data)))
register('post@searchByRuleId', async (data: any) => success(await searchByRuleId(data)))
register('post@content', async (data: any) => success(await content(data)))
register('post@getChapter', async (data: any) => success(await getChapter(data)))
register('get@readConfig', async () => success(await readConfig(CONFIG_PATH)))
register('post@updateConfig', async (data: any) => success(await updateConfig(CONFIG_PATH, data)))
register('get@getRuleExtras', async () => success(await getRuleExtras()))
register('post@ping', async (data: any) => success(await ping(data)))
register('post@batchUpdateRules', async (data: any) => success(await batchUpdateRules(data)))
}
6 changes: 3 additions & 3 deletions packages/shared/src/ruleExtraManager.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// @ts-expect-error
import { readJson } from 'fs-extra/esm'
import debounce from 'lodash-es/debounce'
import _ from 'lodash-es'
import { JSONFilePreset } from 'lowdb/node'
import type { Low } from 'lowdb/lib'
import { RULE_EXTRA_PATH } from './constants'
Expand All @@ -24,10 +24,10 @@ async function getDb() {
return mDb
}

const writeDB = debounce(async () => {
const writeDB = _.throttle(async () => {
const db = await getDb()
db.write()
}, 500)
}, 1000)

export async function ping(id: string, host: string) {
const db = await getDb()
Expand Down
79 changes: 41 additions & 38 deletions packages/shared/src/ruleFileManager.ts
Original file line number Diff line number Diff line change
@@ -1,65 +1,68 @@
// @ts-expect-error
import { ensureFile, readJson, writeJson } from 'fs-extra/esm'
import { readJson } from 'fs-extra/esm'
import { v4 as uuidV4 } from 'uuid'
import _ from 'lodash-es'
import type { Low } from 'lowdb/lib'
import { JSONFilePreset } from 'lowdb/node'
import type { Rule } from '@any-reader/core'
import { decodeRule } from '@any-reader/core'
import { BOOK_SOURCE_PATH } from './constants'

let ruleList: Rule[] = []
let mDb: Low<Rule[]>

async function readRuleList(): Promise<Rule[]> {
try {
const list = await readJson(BOOK_SOURCE_PATH)
for (let i = 0; i < list.length; i++) {
const rule = list[i]
if (typeof rule === 'string' && rule.includes('eso://'))
list[i] = decodeRule(rule)
}
return list
}
catch (e) {
return []
}
async function getDb() {
if (mDb)
return mDb
const data = await readJson(BOOK_SOURCE_PATH).catch(() => ([]))
mDb = await JSONFilePreset<Rule[]>(BOOK_SOURCE_PATH, data)
return mDb
}

// 初始化
export async function init() {
await ensureFile(BOOK_SOURCE_PATH)
ruleList = await readRuleList()
}
const writeDB = _.throttle(async () => {
const db = await getDb()
db.write()
}, 1000)

// 保存配置文件
async function writeFile() {
await ensureFile(BOOK_SOURCE_PATH)
return writeJson(BOOK_SOURCE_PATH, ruleList, { spaces: 2 })
}
// 初始化
export async function init() {}

export function list(): Rule[] {
return ruleList
export async function list(): Promise<Rule[]> {
const db = await getDb()
return db.data
}

// 删除记录
export async function del(id: string, saveFile = true) {
ruleList = ruleList.filter(e => e.id !== id)
const db = await getDb()
db.data = db.data.filter(e => e.id !== id)
if (saveFile)
await writeFile()
await writeDB()
}

// 更新记录
export async function update(rule: Rule) {
if (!rule.id)
rule.id = uuidV4()

const findIdx = ruleList.findIndex(e => e.id === rule.id)
if (findIdx === -1)
ruleList.push(rule)
const db = await getDb()
const row = db.data.find(e => e.id === rule.id)
if (!row)
db.data.push(rule)
else
ruleList[findIdx] = rule
Object.assign(row, rule)

await writeFile()
writeDB()
}

export async function batchUpdate({ ids, rule }: { ids: string[];rule: Rule }) {
const db = await getDb()
for (let i = 0; i < db.data.length; i++) {
const row = db.data[i]
if (ids.includes(row.id))
Object.assign(row, rule)
}
writeDB()
}

export async function findById(id: string): Promise<Rule> {
const list: Rule[] = await readRuleList()
return list.find(e => e.id === id) as Rule
const db = await getDb()
return db.data.find(e => e.id === id) as Rule
}
Loading

0 comments on commit 571c681

Please sign in to comment.