Skip to content

Commit

Permalink
feat: 添加规则导入
Browse files Browse the repository at this point in the history
  • Loading branch information
aooiuu committed May 31, 2024
1 parent ca49114 commit f48d3ba
Show file tree
Hide file tree
Showing 10 changed files with 190 additions and 20 deletions.
1 change: 1 addition & 0 deletions packages/shared/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"dependencies": {
"@any-reader/core": "workspace:^",
"@any-reader/epub": "workspace:^",
"axios": "^1.7.2",
"chardet": "^2.0.0",
"fs-extra": "^11.1.1",
"iconv-lite": "^0.6.3",
Expand Down
1 change: 1 addition & 0 deletions packages/shared/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const external = [
// 'lodash-es',
'lowdb',
'uuid',
'axios',
]

const plugins = [
Expand Down
1 change: 1 addition & 0 deletions packages/shared/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -252,4 +252,5 @@ export function useApi(register: any, { CONFIG_PATH, bookDir }: any) {
register('post@batchUpdateRules', async (data: any) => success(await batchUpdateRules(data)))
register('post@delRules', async (data: any) => success(await delRules(data)))
register('post@updateRuleSort', async (data: any) => success(await ruleFileManager.updateRuleSort(data && data.id)))
register('post@importRules', async (data: any) => success(await ruleFileManager.importRules(data && data.url)))
}
31 changes: 31 additions & 0 deletions packages/shared/src/ruleFileManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { v4 as uuidV4 } from 'uuid'
import _ from 'lodash-es'
import type { Low } from 'lowdb/lib'
import { JSONFilePreset } from 'lowdb/node'
import axios from 'axios'
import type { Rule } from '@any-reader/core'
import { BOOK_SOURCE_PATH } from './constants'

Expand Down Expand Up @@ -83,3 +84,33 @@ export async function updateRuleSort(ids: string[]) {
}
writeDB()
}

/**
*
* @param rule
* @returns {boolean}
*/
export function isRule(rule: any): boolean {
if (typeof rule === 'string')
return rule.startsWith('eso://:')

if (typeof rule !== 'object')
return false

return rule.id && rule.host && rule.contentType
}

export async function importRules(url: string) {
const res = await axios.create().get(url).catch((e) => {
console.warn(e)
})
if (!res || Array.isArray(res?.data))
return

for (const rule of res.data) {
if (isRule(rule))
await update(rule).catch(() => {})
}

return res.data.length
}
6 changes: 5 additions & 1 deletion packages/web/electron/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ app.whenReady().then(async () => {
const win = new BrowserWindow({
title: 'AnyReader',
titleBarStyle: 'hidden',
webPreferences: { nodeIntegration: true, contextIsolation: false }
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
webSecurity: false
}
});

api.init();
Expand Down
9 changes: 9 additions & 0 deletions packages/web/src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,3 +187,12 @@ export function updateRuleSort(data: any) {
data
});
}

// 导入规则
export function importRules(data: any) {
return request({
method: 'post',
url: 'importRules',
data
});
}
40 changes: 40 additions & 0 deletions packages/web/src/pages/pc/rules/ImportRules.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<template>
<div>
<div class="flex mb-10">
<a-input v-model="url" :disabled="loading" placeholder="https://" class="flex-1 mr-5" />
<a-button :disabled="!canSubmit" type="primary" :loading="loading" @click="submit">确定</a-button>
</div>
<div class="op-70">
<icon-exclamation-circle-fill />
网络不佳可能导致导入不成功
</div>
</div>
</template>

<script setup>
import { Message } from '@arco-design/web-vue';
import { importRules } from '@/api';
const emit = defineEmits(['done']);
const loading = ref(false);
const url = ref('');
const canSubmit = computed(() => url.value && /https?:\/\/.{3,}/.test(url.value));
async function submit() {
loading.value = true;
const res = await importRules({ url: url.value }).catch(() => {});
loading.value = false;
if (res.code === 0) {
emit('done', res.data);
} else {
Message.warning({
content: `导入失败`,
closable: true,
resetOnHover: true
});
}
}
</script>
87 changes: 68 additions & 19 deletions packages/web/src/pages/pc/rules/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,17 @@
</a-checkbox-group>
</div>
</div>
<input ref="fileInputRef" type="file" class="hidden" @change="changeFile" />
<div class="mb-10 flex gap-10">
<a-button type="primary" @click="addRule">
<template #icon>
<icon-plus />
<a-dropdown position="bottom">
<a-button type="primary">添加规则<icon-down /></a-button>
<template #content>
<a-doption @click="addRule">单个添加</a-doption>
<a-doption @click="addRuleFile">从文件导入</a-doption>
<a-doption @click="addRuleUrl">从URL导入</a-doption>
</template>
添加规则
</a-button>
</a-dropdown>

<div class="flex-1" />
<a-button type="primary" @click="pingAll">测速</a-button>
<a-button type="primary" status="danger" @click="delTimeoutRules">一键删除超时规则</a-button>
Expand All @@ -39,7 +43,12 @@
:loading="loading"
:draggable="{ type: 'handle', width: 40 }"
row-key="id"
:pagination="true"
:pagination="{
showTotal: true,
showJumper: true,
showPageSize: true,
pageSizeOptions: [10, 20, 50, 100, 500]
}"
:row-selection="{
type: 'checkbox',
showCheckedAll: true,
Expand Down Expand Up @@ -68,14 +77,17 @@ import { CONTENT_TYPES } from '@/constants';
import { useRulesStore } from '@/stores/rules';
import { ping, batchUpdateRules, delRules, updateRuleSort, createRule } from '@/api';
import { timeoutWith } from '@/utils/promise';
import { isRule } from '@/utils/rule';
import { useRuleExtra } from './hooks/useRuleExtra';
import ImportRules from './ImportRules.vue';
const router = useRouter();
const rulesStore = useRulesStore();
const ruleExtra = useRuleExtra();
const pingIds = ref([]);
const selectedKeys = ref([]);
const loading = ref(false);
const fileInputRef = ref();
rulesStore.sync();
ruleExtra.sync();
Expand Down Expand Up @@ -115,12 +127,22 @@ const tableColumns = ref([
tooltip: true,
sortable: {
sortDirections: ['ascend', 'descend']
},
render: ({ record }) => {
return (
<a-link
onClick={() => {
window.open(record.host);
}}>
{record.host}
</a-link>
);
}
},
{
title: '延迟',
dataIndex: 'extra.ping',
width: 100,
width: 90,
align: 'center',
render: ({ record }) => {
const extra = record.extra;
Expand Down Expand Up @@ -159,7 +181,7 @@ const tableColumns = ref([
},
{
title: '启用搜索',
width: 120,
width: 100,
align: 'center',
filterable: {
filters: [
Expand All @@ -183,14 +205,11 @@ const tableColumns = ref([
})
}
/>
),
sortable: {
sortDirections: ['ascend', 'descend']
}
)
},
{
title: '启用发现',
width: 120,
width: 100,
align: 'center',
filterable: {
filters: [
Expand All @@ -215,10 +234,7 @@ const tableColumns = ref([
})
}
/>
),
sortable: {
sortDirections: ['ascend', 'descend']
}
)
},
{
title: '操作',
Expand Down Expand Up @@ -257,6 +273,33 @@ function addRule() {
});
}
function addRuleFile() {
fileInputRef.value.click();
}
function addRuleUrl() {
const modal = Modal.open({
draggable: true,
mask: true,
width: 400,
footer: false,
title: '导入规则',
content: (
<ImportRules
onDone={(count = 0) => {
rulesStore.sync();
Message.success({
content: `导入${count}条数据`,
closable: true,
resetOnHover: true
});
modal.close();
}}
/>
)
});
}
async function pingAll() {
const rows = _.chunk(tableDataFilter.value, 5);
for (const row of rows) {
Expand Down Expand Up @@ -322,6 +365,7 @@ async function handleChange(data, extra, currentData) {
}
async function drop(event) {
event.preventdefault();
const files = event.dataTransfer.files;
for (const file of files) {
await dropFile(file);
Expand All @@ -345,8 +389,6 @@ function readFile(file) {
});
}
const isRule = (data) => data.id && data.host && data.contentType;
async function dropFile(file) {
let count = 0;
const rules = await readFile(file);
Expand All @@ -363,4 +405,11 @@ async function dropFile(file) {
resetOnHover: true
});
}
async function changeFile(e) {
const files = e.target.files;
for (const file of files) {
await dropFile(file);
}
}
</script>
9 changes: 9 additions & 0 deletions packages/web/src/utils/rule.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export const isRule = (rule: any) => {
if (typeof rule === 'string') {
return rule.startsWith('eso://:');
}

if (typeof rule !== 'object') return false;

return rule.id && rule.host && rule.contentType;
};
25 changes: 25 additions & 0 deletions pnpm-lock.yaml

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

0 comments on commit f48d3ba

Please sign in to comment.