feat (backend): Add preview API

- POST /api/preview/sub for previewing subs
- POST /api/preview/collection for previewing collection
This commit is contained in:
Peng-YM 2022-07-01 17:36:48 +08:00
parent bb87a6c41e
commit 606cfed8da
8 changed files with 120 additions and 11 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,6 @@
{
"name": "sub-store",
"version": "2.2.3",
"version": "2.3.0",
"description": "Advanced Subscription Manager for QX, Loon, Surge, Stash and ShadowRocket.",
"main": "src/main.js",
"scripts": {

View File

@ -276,7 +276,6 @@ async function produceArtifact({ type, item, platform, noProcessor }) {
// parse proxies
let proxies = ProxyUtils.parse(raw);
if (!noProcessor) {
console.log('Processing proxy...');
// apply processors
proxies = await ProxyUtils.process(
proxies,

View File

@ -14,6 +14,7 @@ import registerCollectionRoutes from './collections';
import registerArtifactRoutes from './artifacts';
import registerDownloadRoutes from './download';
import registerSettingRoutes from './settings';
import registerPreviewRoutes from './preview';
export default function serve() {
const $app = express({ substore: $ });
@ -22,6 +23,7 @@ export default function serve() {
registerCollectionRoutes($app);
registerSubscriptionRoutes($app);
registerDownloadRoutes($app);
registerPreviewRoutes($app);
registerSettingRoutes($app);
registerArtifactRoutes($app);

View File

@ -0,0 +1,108 @@
import { InternalServerError, NetworkError } from './errors';
import { ProxyUtils } from '@/core/proxy-utils';
import { success, failed } from './response';
import download from '@/utils/download';
import { SUBS_KEY } from './constants';
import $ from '@/core/app';
export default function register($app) {
$app.post('/api/preview/sub', compareSub);
$app.post('/api/preview/collection', compareCollection);
}
async function compareSub(req, res) {
const sub = req.body;
const target = req.query.target || 'JSON';
let content;
if (sub.source === 'local') {
content = sub.content;
} else {
try {
content = await download(sub.url, sub.ua);
} catch (err) {
failed(
res,
new NetworkError(
'FAILED_TO_DOWNLOAD_RESOURCE',
'无法下载远程资源',
`Reason: ${err}`,
),
);
return;
}
}
// parse proxies
const original = ProxyUtils.parse(content);
// add id
original.forEach((proxy, i) => {
proxy.id = i;
});
// apply processors
const processed = await ProxyUtils.process(
original,
sub.process || [],
target,
);
// produce
success(res, { original, processed });
}
async function compareCollection(req, res) {
const allSubs = $.read(SUBS_KEY);
const collection = req.body;
const subnames = collection['subscriptions'];
const results = {};
await Promise.all(
subnames.map(async (name) => {
const sub = allSubs[name];
try {
let raw;
if (sub.source === 'local') {
raw = sub.content;
} else {
raw = await download(sub.url, sub.ua);
}
// parse proxies
let currentProxies = ProxyUtils.parse(raw);
// apply processors
currentProxies = await ProxyUtils.process(
currentProxies,
sub.process || [],
'JSON',
);
results[name] = currentProxies;
} catch (err) {
failed(
res,
new InternalServerError(
'PROCESS_FAILED',
`处理子订阅 ${name} 失败`,
`Reason: ${err}`,
),
);
}
}),
);
// merge proxies with the original order
const original = Array.prototype.concat.apply(
[],
subnames.map((name) => results[name]),
);
original.forEach((proxy, i) => {
proxy.id = i;
});
const processed = await ProxyUtils.process(
original,
collection.process || [],
'JSON',
);
success(res, { original, processed });
}

File diff suppressed because one or more lines are too long