chore(deps-dev): bump eslint-plugin-unicorn from 74.0.0 to 75.0.0 (#23338)

* chore(deps-dev): bump eslint-plugin-unicorn from 74.0.0 to 75.0.0

Bumps [eslint-plugin-unicorn](https://github.com/sindresorhus/eslint-plugin-unicorn) from 74.0.0 to 75.0.0.
- [Release notes](https://github.com/sindresorhus/eslint-plugin-unicorn/releases)
- [Commits](https://github.com/sindresorhus/eslint-plugin-unicorn/compare/v74.0.0...v75.0.0)

---
updated-dependencies:
- dependency-name: eslint-plugin-unicorn
  dependency-version: 75.0.0
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

* style: fix unicorn-js/prefer-combined-guards

* style: fix prefer-smaller-scope

* style: fix prefer-continue

* style: fix prefer-early-return

* style: fix prefer-iterator-helpers

* style: add v75 recommended preset

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Tony <TonyRL@users.noreply.github.com>
This commit is contained in:
dependabot[bot]
2026-09-22 07:08:43 +08:00
committed by GitHub
co-authored by Tony
parent 5f591da5b3
commit a84b41faa3
151 changed files with 1127 additions and 1012 deletions
+8 -1
View File
@@ -195,6 +195,7 @@
"unicorn-js/no-array-sort-for-min-max": "error",
"unicorn-js/no-array-splice": "error",
"unicorn-js/no-async-promise-finally": "error",
"unicorn-js/no-async-iterator-callback": "error",
// "unicorn/no-await-expression-member": "error",
"unicorn/no-await-in-promise-methods": "error",
// "unicorn-js/no-blob-to-file": "error", // unused
@@ -292,7 +293,8 @@
"unicorn-js/no-unsafe-property-key": "error",
// "unicorn-js/no-unsafe-sqlite-interpolation": "error", // unused
"unicorn-js/no-unsafe-string-replacement": "error",
"unicorn-js/no-unused-array-method-return": "error",
"unicorn-js/no-unused-builtin-method-return": "error",
"unicorn-js/no-unused-iterator-helper": "error",
"unicorn-js/no-useless-boolean-cast": "error",
"unicorn-js/no-useless-coercion": "error",
"unicorn/no-useless-collection-argument": "error",
@@ -311,9 +313,11 @@
"unicorn-js/no-useless-re-export": "error",
// "unicorn-js/no-useless-recursion": "error", unopinionated
"unicorn/no-useless-spread": "error",
"unicorn-js/no-useless-set-construction": "error",
// "unicorn/no-useless-switch-case": "error",
"unicorn-js/no-useless-template-literals": "error",
// "unicorn/no-useless-undefined": "error",
"unicorn-js/no-using-resource-escape": "error",
"unicorn-js/no-xor-as-exponentiation": "error",
"unicorn/no-zero-fractions": "error",
// "unicorn/number-literal-case": "error",
@@ -342,6 +346,7 @@
"unicorn-js/prefer-block-statement-over-iife": "error",
"unicorn-js/prefer-boolean-return": "error",
"unicorn/prefer-class-fields": "error",
"unicorn-js/prefer-combined-guards": "error",
// "unicorn/prefer-classlist-toggle": "error", // unused
// "unicorn/prefer-code-point": "error",
"unicorn-js/prefer-continue": "error",
@@ -372,6 +377,7 @@
"unicorn-js/prefer-iterable-in-constructor": "error",
"unicorn-js/prefer-iterator-helpers": "error",
"unicorn-js/prefer-iterator-to-array": "error",
"unicorn-js/prefer-iterator-zip": "error",
// "unicorn-js/prefer-iterator-to-array-at-end": "error",
// "unicorn/prefer-keyboard-event-key": "error", // unused
"unicorn-js/prefer-location-assign": "error",
@@ -431,6 +437,7 @@
// "unicorn/prefer-string-starts-ends-with": "error", use typescript/prefer-string-starts-ends-with
"unicorn/prefer-string-trim-start-end": "error",
"unicorn/prefer-structured-clone": "error",
"unicorn-js/prefer-temporal-conversion": "error",
// "unicorn/prefer-switch": "error",
"unicorn/prefer-ternary": "error",
"unicorn-js/prefer-then-catch": "error",
+58 -56
View File
@@ -141,71 +141,73 @@ export default eslintCompatPlugin({
const routeDeclaration = node.declaration.declarations[0];
const routeObject = routeDeclaration.init;
if (routeObject && routeObject.type === 'ObjectExpression') {
let featuresProperty = null;
let nsfwProperty = null;
if (!routeObject || routeObject.type !== 'ObjectExpression') {
return;
}
// 查找 features 属性
for (const prop of routeObject.properties) {
if (!(prop.type === 'Property' && prop.key && prop.key.name === 'features')) {
continue;
}
let featuresProperty = null;
let nsfwProperty = null;
featuresProperty = prop;
// 查找 features 属性
for (const prop of routeObject.properties) {
if (!(prop.type === 'Property' && prop.key && prop.key.name === 'features')) {
continue;
}
// 在 features 中查找 nsfw 属性
if (prop.value && prop.value.type === 'ObjectExpression') {
for (const featureProp of prop.value.properties) {
if (!(featureProp.type === 'Property' && featureProp.key && featureProp.key.name === 'nsfw')) {
continue;
}
featuresProperty = prop;
nsfwProperty = featureProp;
break;
// 在 features 中查找 nsfw 属性
if (prop.value && prop.value.type === 'ObjectExpression') {
for (const featureProp of prop.value.properties) {
if (!(featureProp.type === 'Property' && featureProp.key && featureProp.key.name === 'nsfw')) {
continue;
}
nsfwProperty = featureProp;
break;
}
break;
}
break;
}
// 检查是否需要添加或修复 nsfw 标志
if (!featuresProperty) {
// 没有 features 属性,需要添加整个 features 对象
context.report({
node: routeObject,
messageId: 'missingNsfwFlag',
fix(fixer) {
// 在对象的最后添加 features 属性
const lastProperty = routeObject.properties.at(-1);
// 检查是否需要添加或修复 nsfw 标志
if (!featuresProperty) {
// 没有 features 属性,需要添加整个 features 对象
context.report({
node: routeObject,
messageId: 'missingNsfwFlag',
fix(fixer) {
// 在对象的最后添加 features 属性
const lastProperty = routeObject.properties.at(-1);
return lastProperty
? fixer.insertTextAfter(lastProperty, ',\n features: {\n nsfw: true,\n }')
: // 空对象的情况
fixer.insertTextAfter(routeObject.properties.length > 0 ? routeObject.properties.at(-1) : routeObject, '\n features: {\n nsfw: true,\n }\n');
},
});
} else if (!nsfwProperty) {
// 有 features 属性但没有 nsfw 属性
context.report({
node: featuresProperty.value,
messageId: 'missingNsfwFlag',
fix(fixer) {
const featuresObject = featuresProperty.value;
if (featuresObject.properties.length > 0) {
const lastFeatureProp = featuresObject.properties.at(-1);
return fixer.insertTextAfter(lastFeatureProp, ',\n nsfw: true');
}
// features 是空对象
return fixer.replaceTextRange([featuresObject.range[0] + 1, featuresObject.range[1] - 1], '\n nsfw: true,\n ');
},
});
} else if (nsfwProperty.value && (nsfwProperty.value.type !== 'Literal' || nsfwProperty.value.value !== true)) {
// nsfw 属性存在但不是 true
context.report({
node: nsfwProperty.value,
messageId: 'missingNsfwFlag',
fix: (fixer) => fixer.replaceText(nsfwProperty.value, 'true'),
});
}
return lastProperty
? fixer.insertTextAfter(lastProperty, ',\n features: {\n nsfw: true,\n }')
: // 空对象的情况
fixer.insertTextAfter(routeObject.properties.length > 0 ? routeObject.properties.at(-1) : routeObject, '\n features: {\n nsfw: true,\n }\n');
},
});
} else if (!nsfwProperty) {
// 有 features 属性但没有 nsfw 属性
context.report({
node: featuresProperty.value,
messageId: 'missingNsfwFlag',
fix(fixer) {
const featuresObject = featuresProperty.value;
if (featuresObject.properties.length > 0) {
const lastFeatureProp = featuresObject.properties.at(-1);
return fixer.insertTextAfter(lastFeatureProp, ',\n nsfw: true');
}
// features 是空对象
return fixer.replaceTextRange([featuresObject.range[0] + 1, featuresObject.range[1] - 1], '\n nsfw: true,\n ');
},
});
} else if (nsfwProperty.value && (nsfwProperty.value.type !== 'Literal' || nsfwProperty.value.value !== true)) {
// nsfw 属性存在但不是 true
context.report({
node: nsfwProperty.value,
messageId: 'missingNsfwFlag',
fix: (fixer) => fixer.replaceText(nsfwProperty.value, 'true'),
});
}
},
}),
+19 -18
View File
@@ -21,25 +21,26 @@ export const getRadarRules = async (): Promise<Record<string, RadarDomain>> => {
const parsedDomain = parse(new URL('https://' + radarItem.source[0]).hostname);
const subdomain = parsedDomain.subdomain || '.';
const domain = parsedDomain.domain;
if (domain) {
if (!Object.hasOwn(rules, domain)) {
rules[domain] = {
_name: namespaces[namespace].name,
} as RadarDomain;
}
if (!Object.hasOwn(rules[domain], subdomain)) {
rules[domain][subdomain] = [];
}
rules[domain][subdomain].push({
title: radarItem.title || data.name,
docs: `https://docs.rsshub.app/routes/${data.categories?.[0] || 'other'}`,
source: radarItem.source.map((source) => {
const sourceURL = new URL('https://' + source);
return sourceURL.pathname + sourceURL.search + sourceURL.hash;
}),
target: radarItem.target ? `/${namespace}${radarItem.target}` : realPath,
});
if (!domain) {
continue;
}
if (!Object.hasOwn(rules, domain)) {
rules[domain] = {
_name: namespaces[namespace].name,
} as RadarDomain;
}
if (!Object.hasOwn(rules[domain], subdomain)) {
rules[domain][subdomain] = [];
}
rules[domain][subdomain].push({
title: radarItem.title || data.name,
docs: `https://docs.rsshub.app/routes/${data.categories?.[0] || 'other'}`,
source: radarItem.source.map((source) => {
const sourceURL = new URL('https://' + source);
return sourceURL.pathname + sourceURL.search + sourceURL.hash;
}),
target: radarItem.target ? `/${namespace}${radarItem.target}` : realPath,
});
}
}
}
+36 -32
View File
@@ -64,12 +64,14 @@ const replaceUrl = (template?: string, url?: string) => {
const replaceUrls = ($: CheerioAPI, selector: string, template: string, attribute = 'src') => {
$(selector).each((_, el) => {
const oldSrc = $(el).attr(attribute);
if (oldSrc) {
const url = parseUrl(oldSrc);
if (url && url.protocol !== 'data:') {
// Cheerio will do the right thing to prohibit XSS.
$(el).attr(attribute, interpolate(template, url));
}
if (!oldSrc) {
return;
}
const url = parseUrl(oldSrc);
if (url && url.protocol !== 'data:') {
// Cheerio will do the right thing to prohibit XSS.
$(el).attr(attribute, interpolate(template, url));
}
});
};
@@ -137,37 +139,39 @@ const middleware: MiddlewareHandler = async (ctx, next) => {
// Use Cheerio to load the description as html and filter all
// image link
const data: Data = ctx.get('data');
if (data) {
if (data.image) {
data.image = replaceUrl(imageHotlinkTemplate, data.image);
}
if (data.description) {
data.description = process(data.description, imageHotlinkTemplate, multimediaHotlinkTemplate);
}
if (!data) {
return;
}
if (data.item) {
for (const item of data.item) {
if (item.description) {
item.description = process(item.description, imageHotlinkTemplate, multimediaHotlinkTemplate);
}
if (item.enclosure_url && item.enclosure_type) {
if (item.enclosure_type.startsWith('image/')) {
item.enclosure_url = replaceUrl(imageHotlinkTemplate, item.enclosure_url);
} else if (/^(?:video|audio)\//.test(item.enclosure_type)) {
item.enclosure_url = replaceUrl(multimediaHotlinkTemplate, item.enclosure_url);
}
}
if (item.image) {
item.image = replaceUrl(imageHotlinkTemplate, item.image);
}
if (item.itunes_item_image) {
item.itunes_item_image = replaceUrl(imageHotlinkTemplate, item.itunes_item_image);
if (data.image) {
data.image = replaceUrl(imageHotlinkTemplate, data.image);
}
if (data.description) {
data.description = process(data.description, imageHotlinkTemplate, multimediaHotlinkTemplate);
}
if (data.item) {
for (const item of data.item) {
if (item.description) {
item.description = process(item.description, imageHotlinkTemplate, multimediaHotlinkTemplate);
}
if (item.enclosure_url && item.enclosure_type) {
if (item.enclosure_type.startsWith('image/')) {
item.enclosure_url = replaceUrl(imageHotlinkTemplate, item.enclosure_url);
} else if (/^(?:video|audio)\//.test(item.enclosure_type)) {
item.enclosure_url = replaceUrl(multimediaHotlinkTemplate, item.enclosure_url);
}
}
if (item.image) {
item.image = replaceUrl(imageHotlinkTemplate, item.image);
}
if (item.itunes_item_image) {
item.itunes_item_image = replaceUrl(imageHotlinkTemplate, item.itunes_item_image);
}
}
ctx.set('data', data);
}
ctx.set('data', data);
};
export default middleware;
+12 -11
View File
@@ -79,17 +79,18 @@ const middleware: MiddlewareHandler = async (ctx, next) => {
Math.floor(item.itunes_duration / 3600) + ':' + (Math.floor((item.itunes_duration % 3600) / 60) / 100).toFixed(2).slice(-2) + ':' + (((item.itunes_duration % 3600) % 60) / 100).toFixed(2).slice(-2);
}
if (outputType !== 'rss') {
try {
item.pubDate &&= convertDateToISO8601(item.pubDate) || '';
} catch {
item.pubDate = '';
}
try {
item.updated &&= convertDateToISO8601(item.updated) || '';
} catch {
item.updated = '';
}
if (outputType === 'rss') {
continue;
}
try {
item.pubDate &&= convertDateToISO8601(item.pubDate) || '';
} catch {
item.pubDate = '';
}
try {
item.updated &&= convertDateToISO8601(item.updated) || '';
} catch {
item.updated = '';
}
}
}
+17 -15
View File
@@ -174,22 +174,24 @@ export function registerRssRoutes(app: Hono, namespaces: NamespacesType): void {
for (const [path, routeData] of sortedRoutes) {
const wrappedHandler: Handler = async (ctx) => {
logger.debug(`Matched route: ${routePath(ctx)}`);
if (!ctx.get('data')) {
if (!routeData.handler) {
if (process.env.NODE_ENV === 'test') {
const { route } = await import(`./routes/${namespace}/${routeData.location}`);
routeData.handler = route.handler;
} else if (routeData.module) {
const { route } = await routeData.module();
routeData.handler = route.handler;
}
}
const response = await routeData.handler(ctx);
if (response instanceof Response) {
return response;
}
ctx.set('data', response);
if (ctx.get('data')) {
return;
}
if (!routeData.handler) {
if (process.env.NODE_ENV === 'test') {
const { route } = await import(`./routes/${namespace}/${routeData.location}`);
routeData.handler = route.handler;
} else if (routeData.module) {
const { route } = await routeData.module();
routeData.handler = route.handler;
}
}
const response = await routeData.handler(ctx);
if (response instanceof Response) {
return response;
}
ctx.set('data', response);
};
subApp.get(path, wrappedHandler);
}
+5 -3
View File
@@ -8,10 +8,12 @@ const processImages = ($) => {
$('a').each((_, elem) => {
const $elem = $(elem);
const largePhotoUrl = $elem.attr('href')?.replace('i0.wp.com', '').replace('pic.4khd.com', 'yt4.googleusercontent.com').replace('AsHYQ', 'AsYHQ').replace('l/AAA', 'I/AAA');
if (largePhotoUrl) {
$elem.attr('href', largePhotoUrl);
$elem.find('img').attr('src', largePhotoUrl);
if (!largePhotoUrl) {
return;
}
$elem.attr('href', largePhotoUrl);
$elem.find('img').attr('src', largePhotoUrl);
});
};
+2 -6
View File
@@ -45,12 +45,8 @@ export async function processItems(ctx, baseURL, exclude) {
const pubDate = timezone(parseDate($(item).find('span').text().replaceAll(/[[\]]/g, ''), 'MM-DD'), 8);
const text = link.text();
if (href === undefined) {
return;
}
if (exclude && exclude.some((e) => e.test(text))) {
// 过滤掉满足正则的标题条目
// 过滤掉满足正则的标题条目
if (href === undefined || (exclude && exclude.some((e) => e.test(text)))) {
return;
}
+14 -12
View File
@@ -97,19 +97,21 @@ export const handler = async (ctx: Context): Promise<Data> => {
const mediaUrl: string | undefined = $$el.prop('src');
const mediaType: string | undefined = mediaUrl?.split(/\./).pop();
if (mediaType && mediaUrl) {
media[mediaType] = { url: mediaUrl };
pEl.replaceWith(
renderDescription({
images: [
{
src: mediaUrl,
},
],
})
);
if (!(mediaType && mediaUrl)) {
return;
}
media[mediaType] = { url: mediaUrl };
pEl.replaceWith(
renderDescription({
images: [
{
src: mediaUrl,
},
],
})
);
});
}
+1 -1
View File
@@ -42,7 +42,7 @@ async function handler(ctx) {
const response = await got.get(pageUrl);
const $ = load(response.data);
let title = '';
const titleLinks = $('.container .regsiter a').toArray().slice(1); // what a typo... drop "首页"
const titleLinks = $('.container .regsiter a').slice(1).toArray(); // what a typo... drop "首页"
for (const link of titleLinks) {
const linkText = $(link).text();
title = title ? `${title} - ${linkText}` : linkText;
+1 -1
View File
@@ -54,8 +54,8 @@ async function handler(ctx: Context) {
// get rest ul article links
const restItems: DataItem[] = $('.threecol li')
.toArray()
.slice(0, 10)
.toArray()
.map((article) => {
const $article = load(article);
+4 -3
View File
@@ -295,10 +295,11 @@ const renderEmbedImages = (block: Block, index: number): JSX.Element | null => {
const rawImageBlock = findBlocksByType(imageBlock.model?.blocks ?? imageBlock.blocks ?? imageBlock.items, 'rawImage')[0];
const width = rawImageBlock?.model?.width;
if (width && width > maxWidth) {
maxWidth = width;
largestImage = imageBlock;
if (!(width && width > maxWidth)) {
continue;
}
maxWidth = width;
largestImage = imageBlock;
}
if (!largestImage) {
+1 -1
View File
@@ -170,8 +170,8 @@ const getMonthlyRankings = (year: string, month: string): Promise<RankingItem[]>
// Additional info (contributors, created date)
const additionalInfo = $tr
.find('td:nth-child(3) > div')
.toArray()
.slice(1)
.toArray()
.map((el) => $(el).text().trim())
.join('; ');
return {
+4 -3
View File
@@ -28,10 +28,11 @@ const getConfiguredCookie = () => {
// Update b_lsid in cookies
for (const key of Object.keys(config.bilibili.cookies)) {
const cookie = config.bilibili.cookies[key];
if (cookie) {
const updatedCookie = cookie.replace(/b_lsid=[0-9A-F]+_[0-9A-F]+/, () => `b_lsid=${utils.lsid()}`);
config.bilibili.cookies[key] = updatedCookie;
if (!cookie) {
continue;
}
const updatedCookie = cookie.replace(/b_lsid=[0-9A-F]+_[0-9A-F]+/, () => `b_lsid=${utils.lsid()}`);
config.bilibili.cookies[key] = updatedCookie;
}
return config.bilibili.cookies[Object.keys(config.bilibili.cookies)[Math.floor(Math.random() * Object.keys(config.bilibili.cookies).length)]] || '';
+7 -5
View File
@@ -392,12 +392,14 @@
sp >>>= 0;
const id = this.mem.getUint32(sp + 8, true);
this._goRefCounts[id]--;
if (this._goRefCounts[id] === 0) {
const v = this._values[id];
this._values[id] = null;
this._ids.delete(v);
this._idPool.push(id);
if (this._goRefCounts[id] !== 0) {
return;
}
const v = this._values[id];
this._values[id] = null;
this._ids.delete(v);
this._idPool.push(id);
},
// func stringVal(value string) ref
+13 -11
View File
@@ -287,18 +287,20 @@ const processLedeMedia = async (story_json) => {
}
return '';
}
if (story_json.type === 'Lede') {
const props = story_json.props;
const media = {
kind: props.media,
caption: props.caption?.replaceAll(capRegex, '') ?? '',
description: props.dek?.replaceAll(capRegex, '') ?? '',
credit: props.credit?.replaceAll(capRegex, '') ?? '',
src: props.url,
};
return renderLedeMedia(media);
if (story_json.type !== 'Lede') {
return;
}
const props = story_json.props;
const media = {
kind: props.media,
caption: props.caption?.replaceAll(capRegex, '') ?? '',
description: props.dek?.replaceAll(capRegex, '') ?? '',
credit: props.credit?.replaceAll(capRegex, '') ?? '',
src: props.url,
};
return renderLedeMedia(media);
};
const processBody = async (body_html, story_json) => {
+1 -1
View File
@@ -17,7 +17,7 @@ async function handler() {
const rootUrl = 'https://www.blowstudio.es';
const response = await ofetch(`${rootUrl}/work/`);
const $ = load(response);
const list = $('.portfolios.normal > ul > li').toArray().slice(0, 10);
const list = $('.portfolios.normal > ul > li').slice(0, 10).toArray();
const videostyle = 'width="640" height="360"';
const imgstyle = 'style="max-width: 650px; height: auto; object-fit: contain; flex: 0 0 auto;"';
+1 -1
View File
@@ -66,8 +66,8 @@ async function getList(url) {
const { data } = await got(url);
const $ = load(data);
const title = $('.nytit .fr a')
.toArray()
.slice(1)
.toArray()
.map((item) => $(item).text().trim())
.join(' - ');
const list = $("div[class='Newslist'] > ul > li")
+1 -1
View File
@@ -27,8 +27,8 @@ async function handler() {
const $ = load(response);
const list = $('div[class=subPage] div ul li')
.toArray()
.slice(0, 25)
.toArray()
.map((item) => {
const $item = $(item);
const aTag = $item.find('a');
+1 -4
View File
@@ -11,10 +11,7 @@ const rsaPrivateKey =
'-----BEGIN PRIVATE KEY-----MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCLci8q2u3NGFyFlMUwjCP91PsvGjHdRAq9fmqZLxvue+n+RhzNxnKKYOv35pLgFKWXsGq2TV+5Xrv6xZgNx36IUkqbmrO+eCa8NFmti04wvMfG3DCNdKA7Lue880daNiK3BOhlQlZPykUXt1NftMNS/z+e70W+Vpv1ZxCx5BipqZkdoceM3uin0vUQmqmHqjxi5qKUuov90dXLaMxypCA0TDsIDnX8RPvPtqKff1p2TMW2a0XYe7CPYhRggaQMpmo0TcFutgrM1Vywyr2TPxYR+H/tpuuWRET7tUIQykBYoO1WKfL2dX6cxarjAJfnYnod3sMzppHouyp8Pt7gHVG7AgMBAAECggEAEFshSy6IrADKgWSUyH/3jMNZfwnchW6Ar/9O847CAPQJ2yhQIpa/Qpnhs58Y5S2myqcHrUBgFPcWp3BbyGn43naAh8XahWHEcVjWl/N6BV9vM1UKYN0oGikDR3dljCBDbCIoPBBO3WcFOaXoIpaqPmbwCG1aSdwQyPUA0UzG08eDbuHK6L5jvbe3xv5kLpWTVddrocW+SakbZRAX1Ykp7IujOce235nM7GOfoq4b8jmK5CLg6VIZGQV20wnn9YxuFOndRSjneFberzfzBMhVLpPsQ16M2xDLpZaDTggZnq2L6nZygds8Hda++ga3WbD3TcgjJNYuENu1S88IowYhSQKBgQDFqRA+38mo6KsxVDCNWcuEk2hSq8NEUzRHJpS7/QjZmEIYpFzDXgSGwhZJ0WNsQtaxJeBbc7B/OOqh8TL1reLl5AdTimS1OLHWVf/MUsLVS7Y82hx/hpYWxZnRSq41oI3P8FO/53FiQMYo2wbwqF6uQjB1y8h58aqL3OYpTH/5xQKBgQC0mobALJ+bU4nCPzkVDZuD6RyNWPwS1aE3+925wDSN2rJ0iLIb4N5czWZmHb66VlAtfGbp2q+amsCV4r6UR19A/y8k9SFB0mdtxix6mjEfaGhVJm4B1mkvsn0OHMAanKkohUvCjROQc3sziyp2gqSEQ98G7//VMPx/3dhgyQpVfwKBgQCycsqu6N0n+D6t/0MCKiJaI7bYhCd7JN8aqVM4UN5PjG2Hz8PLwbK2cr0qkbaAA+vN7NMb3Vtn0FvMLnUCZqVlRTP0EQqQrYmoZuXUcpdhd8QkNgnqe/g+wND4qcKTucquA1uo8mtj9/Su5+bhGDC6hBk6D+uDZFHDiX/loyIavQKBgQCXF6AcLjjpDZ52b8Yloti0JtXIOuXILAlQeNoqiG5vLsOVUrcPM7VUFlLQo5no8kTpiOXgRyAaS9VKkAO4sW0zR0n9tUY5dvkokV6sw0rNZ9/BPQFTcDlXug99OvhMSzwJtlqHTNdNRg+QM6E2vF0+ejmf6DEz/mN/5e0cK5UFqQKBgCR2hVfbRtDz9Cm/P8chPqaWFkH5ulUxBpc704Igc6bVH5DrEoWo6akbeJixV2obAZO3sFyeJqBUqaCvqG17Xei6jn3Hc3WMz9nLrAJEI9BTCfwvuxCOyY0IxqAAYT28xYv42I4+ADT/PpCq2Dj5u43X0dapAjZBZDfVVis7q1Bw-----END PRIVATE KEY-----';
export async function getFulltext(url: string) {
if (!config.caixin.cookie) {
return;
}
if (!/\d+\.html/.test(url)) {
if (!config.caixin.cookie || !/\d+\.html/.test(url)) {
return;
}
const articleID = url.match(/(\d+)\.html/)![1];
+11 -7
View File
@@ -98,14 +98,18 @@ export async function fetchArticles(path) {
// Remove srcset attribute
$img.removeAttr('srcset');
if (src && src.startsWith('/_next/image')) {
// Extract the original URL from the Next.js image URL
const urlMatch = src.match(/url=([^&]+)/);
if (urlMatch && urlMatch[1]) {
const originalUrl = decodeURIComponent(urlMatch[1]);
$img.attr('src', originalUrl);
}
if (!src?.startsWith('/_next/image')) {
return;
}
// Extract the original URL from the Next.js image URL
const urlMatch = src.match(/url=([^&]+)/);
if (!urlMatch?.[1]) {
return;
}
const originalUrl = decodeURIComponent(urlMatch[1]);
$img.attr('src', originalUrl);
});
return {
title,
+1 -1
View File
@@ -38,8 +38,8 @@ async function handler(ctx: Context) {
link: pageUrl,
title: category === 'all' ? baseTitle : `${baseTitle} ${$('title').text()}`,
item: $('div[id^="wp_news_w"] a')
.toArray()
.slice(0, 10)
.toArray()
.filter((elem) => entryUrlRegex.test(elem.attribs.href))
.map((elem) => ({
link: new URL(elem.attribs.href, pageUrl).href,
+1 -1
View File
@@ -35,8 +35,8 @@ async function handler(ctx: Context) {
link: pageUrl,
title: category === 'all' ? baseTitle : `${baseTitle} ${$('title').text()}`,
item: $('.news_title a')
.toArray()
.slice(0, 10)
.toArray()
.filter((elem) => entryUrlRegex.test(elem.attribs.href))
.map((elem) => ({
link: new URL(elem.attribs.href, pageUrl).href,
+12 -8
View File
@@ -245,14 +245,18 @@ function parseLinkData($: CheerioAPI) {
function getVideoIframe($ele: Cheerio<Element>) {
const setup = $ele.find('video').data('setup') as VideoSetup;
if (setup) {
const youtubeSource = setup.sources.find((i) => i.type === 'video/youtube');
if (youtubeSource) {
const videoId = youtubeSource.src.match(/\?v=([^&]+)/)?.[1];
if (videoId) {
return `<iframe src="https://www.youtube-nocookie.com/embed/${videoId}" width="640" height="360" frameborder="0" allowfullscreen referrerpolicy="strict-origin-when-cross-origin"></iframe>`;
}
}
if (!setup) {
return;
}
const youtubeSource = setup.sources.find((i) => i.type === 'video/youtube');
if (!youtubeSource) {
return;
}
const videoId = youtubeSource.src.match(/\?v=([^&]+)/)?.[1];
if (videoId) {
return `<iframe src="https://www.youtube-nocookie.com/embed/${videoId}" width="640" height="360" frameborder="0" allowfullscreen referrerpolicy="strict-origin-when-cross-origin"></iframe>`;
}
}
+1 -1
View File
@@ -23,8 +23,8 @@ async function handler() {
$('.cg-pic').parent().remove();
const list = $('.cg-title h3')
.toArray()
.slice(0, 15)
.toArray()
.map((item): DataItem => {
const a = $(item).find('a');
return {
+1 -1
View File
@@ -100,8 +100,8 @@ async function handler(ctx) {
return {
title: $('caption').text().trim(),
items: $('.datalist tr')
.toArray()
.slice(1)
.toArray()
.map((item): DataItem => {
const $item = $(item);
const title = $item.find('td').eq(1).text();
+5 -3
View File
@@ -94,10 +94,12 @@ async function handler(ctx) {
});
article.find('.article-a-attach-body a').each((i, ele) => {
const $ele = $(ele);
if ($ele.attr('onclick')?.startsWith("location.href=encodeURI($('#fileDownUrl').val()+'fileDownLoad.do")) {
$ele.attr('href', `${baseUrl}/dqs/cm-s-notice-query/fileDownLoad.do?mode=open&contentId=${item.contentId}&priority=${i}`);
$ele.removeAttr('onclick');
if (!$ele.attr('onclick')?.startsWith("location.href=encodeURI($('#fileDownUrl').val()+'fileDownLoad.do")) {
return;
}
$ele.attr('href', `${baseUrl}/dqs/cm-s-notice-query/fileDownLoad.do?mode=open&contentId=${item.contentId}&priority=${i}`);
$ele.removeAttr('onclick');
});
item.description = article.html();
+14 -12
View File
@@ -111,19 +111,21 @@ const fetchTargetElements = async (cleanType: string, subtype: string | undefine
for (const el of pageElements) {
const $item = $(el).closest('li');
if ($item.length > 0) {
const rawLink = $(el).attr('href') || '';
const rawZtzl = $(el).attr('ztzlurl') || ''; // some exhibition links have a separate detailed page, use ztzlurl to get the detailed exhibition link if available
// Use exhibitionLink to remove the repeat ones
const itemLink = buildItemLink(rawLink, contextUrl, baseUrl);
const exhibitionLink = buildExhibitionLink(rawZtzl, itemLink, baseUrl);
if (exhibitionLink && !seenLinks.has(exhibitionLink)) {
seenLinks.add(exhibitionLink);
items.push({ $item, contextUrl, itemLink, exhibitionLink, rawZtzl });
}
if ($item.length === 0) {
continue;
}
const rawLink = $(el).attr('href') || '';
const rawZtzl = $(el).attr('ztzlurl') || ''; // some exhibition links have a separate detailed page, use ztzlurl to get the detailed exhibition link if available
// Use exhibitionLink to remove the repeat ones
const itemLink = buildItemLink(rawLink, contextUrl, baseUrl);
const exhibitionLink = buildExhibitionLink(rawZtzl, itemLink, baseUrl);
if (!exhibitionLink || seenLinks.has(exhibitionLink)) {
continue;
}
seenLinks.add(exhibitionLink);
items.push({ $item, contextUrl, itemLink, exhibitionLink, rawZtzl });
}
};
+1 -1
View File
@@ -122,8 +122,8 @@ async function handler(ctx) {
});
const $ = load(response);
const list = $('tr')
.toArray()
.slice(1)
.toArray()
.map((item) => {
const title = $(item).find('a.fz14').text();
const filename = $(item).find('a.icon-collect').attr('data-filename');
+5 -3
View File
@@ -66,10 +66,12 @@ async function handler(ctx) {
const header = $('.article-img-blk');
header.find('img').each((_, ele) => {
const $ele = $(ele);
if ($ele.attr('src') && $ele.attr('srcset')) {
$ele.removeAttr('srcset');
$ele.attr('src', $ele.attr('src')!.replace(/\/\d+c\d+\//, '/0p0/'));
if (!($ele.attr('src') && $ele.attr('srcset'))) {
return;
}
$ele.removeAttr('srcset');
$ele.attr('src', $ele.attr('src')!.replace(/\/\d+c\d+\//, '/0p0/'));
});
item.description = header.html()! + $('article .ckec').html()!;
+5 -3
View File
@@ -97,10 +97,12 @@ async function handler(ctx) {
const regex = /downloads.fanbox.cc/;
$('a').each((_, el) => {
const link = $(el).attr('href');
if (regex.test(link!)) {
count++;
$(el).replaceWith(coomerFiles[count]);
if (!regex.test(link!)) {
return;
}
count++;
$(el).replaceWith(coomerFiles[count]);
});
desc = (coomerFiles.length > 0 ? coomerFiles[0] : '') + $.html();
const remainingCoomerFiles = coomerFiles.slice(count + 1);
+1 -1
View File
@@ -36,8 +36,8 @@ async function handler(ctx: Context) {
link,
description: $('meta[name="description"]').attr('content') || '重科教务处',
item: $('li[id^="lineu"]')
.toArray()
.slice(0, 10)
.toArray()
.map((item) => {
const $item = $(item);
return {
+1 -1
View File
@@ -39,8 +39,8 @@ async function handler(ctx: Context) {
link,
description: $('meta[name="description"]').attr('content') || '重科图书馆公告',
item: $('div[class="newsList"] li')
.toArray()
.slice(0, 10)
.toArray()
.map((item) => {
const $item = $(item);
return {
+1 -1
View File
@@ -29,8 +29,8 @@ async function handler(ctx: Context) {
const $ = load(response);
const list: DataItem[] = $('h2[itemprop="headline"] a, .post-header .archive__article__title a')
.toArray()
.slice(0, 15)
.toArray()
.map((item) => {
const $item = $(item);
return {
+6 -4
View File
@@ -55,11 +55,13 @@ async function handler(ctx): Promise<Data> {
$('.c-lazy-image__img').each((_, img) => {
const $img = $(img);
if ($img.attr('data-lazy-src')) {
$img.attr('src', $img.attr('data-lazy-src')!.split('?', 1)[0]);
$img.removeAttr('data-lazy-src');
$img.removeAttr('data-lazy-srcset');
if (!$img.attr('data-lazy-src')) {
return;
}
$img.attr('src', $img.attr('data-lazy-src')!.split('?', 1)[0]);
$img.removeAttr('data-lazy-src');
$img.removeAttr('data-lazy-srcset');
});
$('[class^="lrv-a-crop-"]').contents().unwrap();
+1 -1
View File
@@ -40,8 +40,8 @@ async function handler(ctx: Context) {
link: `${host}${urlType}/index.shtml`,
description: `东莞理工学院 ${name} ${info}`,
item: $('#paging > ul li')
.toArray()
.slice(0, 10)
.toArray()
.map((item) => {
const $item = $(item);
return {
+6 -4
View File
@@ -64,11 +64,13 @@ async function loadContent(itemLink, charset, header) {
// fix lazyload image
post.find('img').each((_, img) => {
const $img = $(img);
if ($img.attr('src')?.endsWith('none.gif') && $img.attr('file')) {
$img.attr('src', $img.attr('file') || $img.attr('zoomfile'));
$img.removeAttr('file');
$img.removeAttr('zoomfile');
if (!($img.attr('src')?.endsWith('none.gif') && $img.attr('file'))) {
return;
}
$img.attr('src', $img.attr('file') || $img.attr('zoomfile'));
$img.removeAttr('file');
$img.removeAttr('zoomfile');
});
// 只抓取论坛1楼消息
+4 -3
View File
@@ -80,10 +80,11 @@ function decodeCipherText(p, a, c, k, e, d) {
}
while (c--) {
const replacement = k[c];
if (replacement) {
const token = e(c.toString());
p = p.replaceAll(new RegExp(String.raw`\b` + token + String.raw`\b`, 'g'), () => replacement);
if (!replacement) {
continue;
}
const token = e(c.toString());
p = p.replaceAll(new RegExp(String.raw`\b` + token + String.raw`\b`, 'g'), () => replacement);
}
return p;
}
+1 -1
View File
@@ -41,8 +41,8 @@ async function handler(ctx) {
const $ = load(response);
// 列表
const list = $('#posts-table>tbody>tr')
.toArray()
.slice(1)
.toArray()
.map((item): DataItem => {
const $item = $(item);
const a = $item.find('a').first();
+8 -6
View File
@@ -34,13 +34,15 @@ async function loadContent(link) {
const $video = $(video);
const dataSrc = $video.attr('data-src');
if (!$video.attr('src') && dataSrc) {
$video.attr('src', dataSrc);
$video.removeAttr('data-src');
$video.removeAttr('data-video-small');
$video.removeAttr('data-video-medium');
$video.removeAttr('data-video-large');
if ($video.attr('src') || !dataSrc) {
return;
}
$video.attr('src', dataSrc);
$video.removeAttr('data-src');
$video.removeAttr('data-video-small');
$video.removeAttr('data-video-medium');
$video.removeAttr('data-video-large');
});
object.find('img').each((_, img) => {
const $img = $(img);
+5 -3
View File
@@ -63,10 +63,12 @@ const getPost = (item) =>
$img.attr('src', hsrc);
$img.removeAttr('data-hsrc');
}
if (osrc) {
$img.attr('src', osrc);
$img.removeAttr('data-osrc');
if (!osrc) {
return;
}
$img.attr('src', osrc);
$img.removeAttr('data-osrc');
});
item.description = $.html();
+40 -36
View File
@@ -108,36 +108,38 @@ async function parsePage(cache, data, get_bittorrent: string | boolean = false,
thumbnail = await ehgot_thumb(cache, thumbnail);
}
const description = `<img src='${thumbnail}' alt='thumbnail'>`;
if (title && link) {
const item: DataItem & { bittorrent_page_url?: string } = {
title,
description,
pubDate,
link,
};
if (get_bittorrent) {
const el_down = el.find('div.gldown');
const bittorrent_page_url = el_down.find('a').attr('href');
if (bittorrent_page_url) {
const bittorrent_url = await getBittorrent(cache, bittorrent_page_url);
if (bittorrent_url) {
item.enclosure_url = bittorrent_url;
item.enclosure_type = 'application/x-bittorrent';
item.bittorrent_page_url = bittorrent_page_url;
}
if (!title || !link) {
return;
}
const item: DataItem & { bittorrent_page_url?: string } = {
title,
description,
pubDate,
link,
};
if (get_bittorrent) {
const el_down = el.find('div.gldown');
const bittorrent_page_url = el_down.find('a').attr('href');
if (bittorrent_page_url) {
const bittorrent_url = await getBittorrent(cache, bittorrent_page_url);
if (bittorrent_url) {
item.enclosure_url = bittorrent_url;
item.enclosure_type = 'application/x-bittorrent';
item.bittorrent_page_url = bittorrent_page_url;
}
}
if ('le'.includes(layout)) {
// artist tags will only show in Compact or Extended layout
// get artist names as author
item.author = $(el)
.find('div.gt[title^="artist:"]')
.toArray()
.map((tag) => $(tag).text())
.join(' / ');
}
return item;
}
if ('le'.includes(layout)) {
// artist tags will only show in Compact or Extended layout
// get artist names as author
item.author = $(el)
.find('div.gt[title^="artist:"]')
.toArray()
.map((tag) => $(tag).text())
.join(' / ');
}
return item;
}
const item_Promises: Array<Promise<any>> = [];
@@ -167,15 +169,17 @@ function getBittorrent(cache, bittorrent_page_url) {
for (const el_form of el_forms) {
const el_a = $(el_form).find('a');
const onclick = el_a.attr('onclick');
if (onclick) {
const match = onclick.match(/'(.*?)'/);
if (match) {
bittorrent_url = match[1];
const match_p = bittorrent_url.match(/torrent\?p=(.*)$/);
if (match_p) {
p = match_p[1];
}
}
if (!onclick) {
continue;
}
const match = onclick.match(/'(.*?)'/);
if (!match) {
continue;
}
bittorrent_url = match[1];
const match_p = bittorrent_url.match(/torrent\?p=(.*)$/);
if (match_p) {
p = match_p[1];
}
}
return bittorrent_url;
+12 -10
View File
@@ -68,17 +68,19 @@ async function handler(ctx) {
// fix lazyload image
$('a').each((_, e) => {
const $e = $(e);
if ($e.attr('href') && $e.attr('href')!.endsWith('.jpg')) {
$e.after(
renderToString(
<figure>
<img src={$e.attr('href')} alt={$e.attr('title') ?? ''} title={$e.attr('title') ?? ''} />
<figcaption>{$e.attr('title') ?? ''}</figcaption>
</figure>
)
);
$e.remove();
if (!$e.attr('href')?.endsWith('.jpg')) {
return;
}
$e.after(
renderToString(
<figure>
<img src={$e.attr('href')} alt={$e.attr('title') ?? ''} title={$e.attr('title') ?? ''} />
<figcaption>{$e.attr('title') ?? ''}</figcaption>
</figure>
)
);
$e.remove();
});
$('img').each((_, e) => {
const $e = $(e);
+11 -9
View File
@@ -119,15 +119,17 @@ export const route: Route = {
if (junkPattern.test(name)) {
$(ele).remove();
}
if (mediaPattern.test(name)) {
const mediaType = name.match(mediaPattern)![1] === 'photo' ? 'images' : 'video';
const mediaIndex = Number.parseInt(name.match(mediaPattern)![2]) - 1;
const media = article.content[mediaType][mediaIndex];
if (media) {
$(ele).replaceWith(renderMedia(media));
} else {
$(ele).remove();
}
if (!mediaPattern.test(name)) {
return;
}
const mediaType = name.match(mediaPattern)![1] === 'photo' ? 'images' : 'video';
const mediaIndex = Number.parseInt(name.match(mediaPattern)![2]) - 1;
const media = article.content[mediaType][mediaIndex];
if (media) {
$(ele).replaceWith(renderMedia(media));
} else {
$(ele).remove();
}
});
+1 -1
View File
@@ -39,8 +39,8 @@ async function handler() {
// 页面新闻消息列表
const list = $('.body_zb ul .body_zb_li .zb_word')
.find('.list_font_pic > a:first-child')
.toArray()
.slice(0, 30)
.toArray()
.map((e) => $(e).attr('href'));
const out = await Promise.all(
+1 -1
View File
@@ -36,8 +36,8 @@ async function handler(ctx) {
const $ = load(front_data);
return [
...$('a.brSCsc')
.toArray()
.slice(3) // skip Home, For you and Following
.toArray()
.map((item) => {
const $item = $(item);
return {
+1 -1
View File
@@ -53,8 +53,8 @@ async function handler(ctx: Context) {
const $ = load(response);
const list = $('div.weinei_left_con div.weinei_left_con_line')
.toArray()
.slice(0, 10)
.toArray()
.map((item): DataItem => {
const $item = $(item);
const a = $item.find('a[title]');
+11 -9
View File
@@ -58,16 +58,18 @@ export const parseNewsList = async (url, selector, ctx) => {
const changeTrCookie = async () => {
const cookies = await cookieJar.getCookies(rootUrl);
const c = cookies.find((c) => c.key === 'HOY_TR');
if (c) {
const value = c.value;
const tr_array = value.split(',');
const csr = tr_array[0];
const cnv = [...tr_array[1]];
const otr = [...tr_array[2]];
otr[0] = csr.charAt(Number.parseInt(cnv[0], 16));
const nc = new Cookie({ key: 'HOY_TR', value: csr + ',' + cnv.join('') + ',' + otr.join('') + ',0' });
await cookieJar.setCookie(nc, rootUrl);
if (!c) {
return;
}
const value = c.value;
const tr_array = value.split(',');
const csr = tr_array[0];
const cnv = [...tr_array[1]];
const otr = [...tr_array[2]];
otr[0] = csr.charAt(Number.parseInt(cnv[0], 16));
const nc = new Cookie({ key: 'HOY_TR', value: csr + ',' + cnv.join('') + ',' + otr.join('') + ',0' });
await cookieJar.setCookie(nc, rootUrl);
};
export const parseArticle = async (item) => {
+1 -1
View File
@@ -112,8 +112,8 @@ async function handler(ctx) {
return {
item: items,
title: `国家自然科学基金委员会 - ${$('#ess_essBREADCRUMB_lblBreadCrumb a.break')
.toArray()
.slice(1)
.toArray()
.map((a) => $(a).text())
.join(' - ')}`,
link: currentUrl,
+1 -1
View File
@@ -23,8 +23,8 @@ async function handler() {
const $ = load(response);
const list = $('article.news-card')
.toArray()
.slice(0, 10)
.toArray()
.map((item) => {
const $item = $(item);
const a = $item.find('h2.news-title a');
+8 -6
View File
@@ -21,12 +21,14 @@ async function handler(): Promise<Data> {
let redirectPath = DEFAULT_REDIRECT_PATH;
$scripts.each((_, el) => {
const redirectScript = $entry(el).text();
if (redirectScript !== null) {
// Get the real index page by JS redirection href. The path may change.
const match = redirectScript.match(/window\.location\.href\s*=\s*["']([^"']+)["']/);
if (match) {
redirectPath = match[1];
}
if (redirectScript === null) {
return;
}
// Get the real index page by JS redirection href. The path may change.
const match = redirectScript.match(/window\.location\.href\s*=\s*["']([^"']+)["']/);
if (match) {
redirectPath = match[1];
}
});
const redirectURL = `${BASE_URL}${redirectPath}`;
+6 -4
View File
@@ -36,11 +36,13 @@ async function handler(ctx: Context) {
$('script').each((_, el) => {
const text = $(el).text();
const match = text.match(/\\"appID\\":\\"(\w+)\\",\\"apiKey\\":\\"(\w+)\\"/);
if (match) {
appId = match[1];
apiKey = match[2];
return false;
if (!match) {
return;
}
appId = match[1];
apiKey = match[2];
return false;
});
if (!appId || !apiKey) {
throw new Error('Failed to extract Algolia credentials from iapp.org');
+1 -4
View File
@@ -50,11 +50,8 @@ export const parseJpy = (text: string | null): number | null => {
if (/無償|なし|無し/.test(s)) {
return 0;
}
if (isUnknown(s)) {
return null;
}
// Without 円 / 万 only a bare number is accepted ('3ヶ月' is not an amount).
if (!/[円万億]/.test(s) && !/^\d+(?:\.\d+)?$/.test(s)) {
if (isUnknown(s) || (!/[円万億]/.test(s) && !/^\d+(?:\.\d+)?$/.test(s))) {
return null;
}
const oku = s.match(/^(\d+(?:\.\d+)?)億(?:(\d+(?:\.\d+)?)万)?/);
+5 -3
View File
@@ -63,10 +63,12 @@ export const handler = async (ctx) => {
const src = $el.prop('data-original');
if (src) {
const alt = $el.prop('alt');
$el.replaceWith(renderToString(<figure>{alt ? <img src={src} alt={alt} /> : <img src={src} />}</figure>));
if (!src) {
return;
}
const alt = $el.prop('alt');
$el.replaceWith(renderToString(<figure>{alt ? <img src={src} alt={alt} /> : <img src={src} />}</figure>));
});
const title = $$('h1').text();
+14 -12
View File
@@ -38,17 +38,19 @@ async function handler(ctx) {
const data = await constructTopicEntry(ctx, topicUrl);
if (data) {
const result = data.result;
result.item = data.posts.map((item) => {
const date = dayjs(item.createdAt);
return {
title: `${data.topic.content} ${date.format('MM月DD日')}`,
description: item.content.replaceAll('\n', '<br>'),
pubDate: date.toDate(),
link: `https://m.okjike.com/originalPosts/${item.id}`,
};
});
return result;
if (!data) {
return;
}
const result = data.result;
result.item = data.posts.map((item) => {
const date = dayjs(item.createdAt);
return {
title: `${data.topic.content} ${date.format('MM月DD日')}`,
description: item.content.replaceAll('\n', '<br>'),
pubDate: date.toDate(),
link: `https://m.okjike.com/originalPosts/${item.id}`,
};
});
return result;
}
+33 -31
View File
@@ -51,36 +51,38 @@ async function handler(ctx) {
const data = await constructTopicEntry(ctx, topicUrl);
if (data) {
const result = data.result;
result.item = topicDataHanding(data, ctx);
if (id === '553870e8e4b0cafb0a1bef68' || id === '55963702e4b0d84d2c30ce6f') {
result.item = await Promise.all(
result.item.map(async (one) => {
const item = { ...one };
const regResult = /https:\/\/www\.okjike\.com\/medium\/[\dA-Za-z]*/.exec(item.description);
if (regResult) {
const newsUrl = regResult[0];
item.description = await cache.tryGet(newsUrl, async () => {
const { data } = await got(newsUrl);
const $ = load(data);
const upper = $('ul.main > li.item');
const links = upper.find('a').map((_, ele) => $(ele).attr('href'));
const texts = upper.find('span.text').map((_, ele) => $(ele).text());
let description = '';
for (let i = 0; i < links.length; i++) {
description += `${i + 1}、<a href="${links[i]}">${texts[i]}</a><br>`;
}
description = description.replace(/<br>$/, '');
return description;
});
}
item.description = item.description.replaceAll(urlRegex, (url) => `<a href="${url}">${url}</a>`);
item.title = `${data.topic.content} ${dayjs(one.pubDate).format('MM月DD日')}`;
return item;
})
);
}
return result;
if (!data) {
return;
}
const result = data.result;
result.item = topicDataHanding(data, ctx);
if (id === '553870e8e4b0cafb0a1bef68' || id === '55963702e4b0d84d2c30ce6f') {
result.item = await Promise.all(
result.item.map(async (one) => {
const item = { ...one };
const regResult = /https:\/\/www\.okjike\.com\/medium\/[\dA-Za-z]*/.exec(item.description);
if (regResult) {
const newsUrl = regResult[0];
item.description = await cache.tryGet(newsUrl, async () => {
const { data } = await got(newsUrl);
const $ = load(data);
const upper = $('ul.main > li.item');
const links = upper.find('a').map((_, ele) => $(ele).attr('href'));
const texts = upper.find('span.text').map((_, ele) => $(ele).text());
let description = '';
for (let i = 0; i < links.length; i++) {
description += `${i + 1}、<a href="${links[i]}">${texts[i]}</a><br>`;
}
description = description.replace(/<br>$/, '');
return description;
});
}
item.description = item.description.replaceAll(urlRegex, (url) => `<a href="${url}">${url}</a>`);
item.title = `${data.topic.content} ${dayjs(one.pubDate).format('MM月DD日')}`;
return item;
})
);
}
return result;
}
+1 -1
View File
@@ -20,8 +20,8 @@ async function handler() {
const $ = load(response);
const items = $('.areaZslist li')
.toArray()
.slice(0, 10)
.toArray()
.map((item) => {
const $item = $(item);
return {
+13 -9
View File
@@ -164,13 +164,15 @@ function generateEnclosureInfo(htmlContent: string): { enclosure_url?: string; e
const extension = extractFileExtension(src);
const mimeType = MIME_TYPE_MAP[extension as keyof typeof MIME_TYPE_MAP];
if (mimeType) {
enclosureInfo = {
enclosure_url: new URL(src, KEMONO_ROOT_URL).href,
enclosure_type: mimeType,
};
return false;
if (!mimeType) {
return;
}
enclosureInfo = {
enclosure_url: new URL(src, KEMONO_ROOT_URL).href,
enclosure_type: mimeType,
};
return false;
});
return enclosureInfo;
@@ -332,10 +334,12 @@ function processPosts(posts: KemonoPost[], authorName: string, limit: number) {
const fanboxRegex = /downloads\.fanbox\.cc/;
$('a').each((_, el) => {
const link = $(el).attr('href');
if (link && fanboxRegex.test(link)) {
$(el).replaceWith(kemonoFileElements[replacementCount] || '');
replacementCount++;
if (!(link && fanboxRegex.test(link))) {
return;
}
$(el).replaceWith(kemonoFileElements[replacementCount] || '');
replacementCount++;
});
description = (kemonoFileElements[0] || '') + $.html();
+1 -1
View File
@@ -63,8 +63,8 @@ async function handler(ctx: Context) {
const $ = load(response);
const list = $('.entry-title a')
.toArray()
.slice(0, 10)
.toArray()
.map((item): DataItem & { link: string } => {
const $item = $(item);
return {
+6 -4
View File
@@ -192,11 +192,13 @@ function getDescription($) {
// handle lazyload image
descriptionEl.find('img').each((_, img) => {
const $img = $(img);
if ($img.attr('src')?.endsWith('none.gif') && $img.attr('file')) {
$img.attr('src', $img.attr('file'));
$img.removeAttr('file');
$img.removeAttr('zoomfile');
if (!($img.attr('src')?.endsWith('none.gif') && $img.attr('file'))) {
return;
}
$img.attr('src', $img.attr('file'));
$img.removeAttr('file');
$img.removeAttr('zoomfile');
});
return descriptionEl.length > 0 ? descriptionEl.html() : $('div.alert_info').html();
@@ -58,8 +58,8 @@ export const getProductPage = (url: string): Promise<DataItem> =>
const category = [
...$('.breadcrump .breadcrump-link')
.toArray()
.slice(1)
.toArray()
.map((x) => $(x).text().trim()),
product
.find('.addetailslist--detail')
+1 -1
View File
@@ -23,8 +23,8 @@ async function handler() {
const list = $('div.article-list')
.find('h3.article-title')
.toArray()
.slice(0, 20)
.toArray()
.map((item): DataItem & { link: string } => {
const a = $(item).find('a');
return {
+11 -9
View File
@@ -78,16 +78,18 @@ const cleanHtml = (htmlString) => {
const bvid = $(e)
.attr('src')!
.match(/bvid=(.*?)&/)![1];
if (bvid) {
const url = `https://www.bilibili.com/video/${bvid}`;
$(e).after(
renderToString(
<p>
<a href={url}>{url}</a>
</p>
)
);
if (!bvid) {
return;
}
const url = `https://www.bilibili.com/video/${bvid}`;
$(e).after(
renderToString(
<p>
<a href={url}>{url}</a>
</p>
)
);
});
// 用户头像
+1 -1
View File
@@ -53,8 +53,8 @@ async function handler(ctx: Context) {
list = $('.list-block ul li, .firstCon-r ul li')
.find('a')
.toArray()
.slice(0, 10)
.toArray()
.map((item) => ({
link: `https:${$(item).attr('href')}`,
}));
+5 -4
View File
@@ -407,11 +407,12 @@ async function fetchFeedData(communityId: number, community: string, session: st
}
const existing = items.get(item.link);
if (existing) {
existing.category = [...new Set([...(existing.category ?? []), ...(item.category ?? [])])];
existing.description ||= item.description;
existing.itunes_item_image ||= item.itunes_item_image;
if (!existing) {
continue;
}
existing.category = [...new Set([...(existing.category ?? []), ...(item.category ?? [])])];
existing.description ||= item.description;
existing.itunes_item_image ||= item.itunes_item_image;
}
}
+5 -3
View File
@@ -161,10 +161,12 @@ async function handler(ctx) {
article.find('.inlineImage').each((_, el) => {
const inlineImageSrc = $(el).attr('src');
const inlineAttachment = item.inline_attachments.find((inlineAttachment) => inlineAttachment.url === inlineImageSrc);
if (inlineAttachment && inlineAttachment.description) {
$(el).wrap('<figure></figure>');
$(el).after(`<figcaption>${inlineAttachment.description}</figcaption>`);
if (!(inlineAttachment && inlineAttachment.description)) {
return;
}
$(el).wrap('<figure></figure>');
$(el).after(`<figcaption>${inlineAttachment.description}</figcaption>`);
});
}
item.description = renderToString(
+1 -1
View File
@@ -27,8 +27,8 @@ export const route: Route = {
const response = await ofetch(targetLink);
const $ = load(response);
const links = $('.archives-group article')
.toArray()
.slice(0, 10)
.toArray()
.map((item): DataItem => {
const $item = $(item);
const a = $item.find('a').first();
+1 -1
View File
@@ -32,7 +32,7 @@ const handler = async (ctx) => {
const data = response.body;
const $ = load(data);
const list = $('.list_products > li').toArray().slice(0, 10);
const list = $('.list_products > li').slice(0, 10).toArray();
const result = list.map((item) => {
const $ = load(item);
+9 -7
View File
@@ -99,14 +99,16 @@ export const route: Route = {
const sudyfileAttr = ($el.attr('sudyfile-attr') || '{}').replaceAll("'", '"');
const sudyfileAttrJson = JSON.parse(sudyfileAttr);
const fileName = sudyfileAttrJson.title || '未命名文件.pdf';
if (pdfSrc) {
let pdfUrl = pdfSrc;
if (!pdfUrl.startsWith('http')) {
pdfUrl = `${baseUrl}${pdfUrl}`;
}
// 替换PDF播放器为下载链接
$el.replaceWith(`<p><a href="${pdfUrl}" target="_blank">📄 ${fileName}</a></p>`);
if (!pdfSrc) {
return;
}
let pdfUrl = pdfSrc;
if (!pdfUrl.startsWith('http')) {
pdfUrl = `${baseUrl}${pdfUrl}`;
}
// 替换PDF播放器为下载链接
$el.replaceWith(`<p><a href="${pdfUrl}" target="_blank">📄 ${fileName}</a></p>`);
});
}
+26 -18
View File
@@ -11,32 +11,40 @@ const fixFigure = (html) => {
html('picture source').each((_, i) => {
const $i = html(i);
if (
$i.attr('srcset') &&
($i.attr('srcset').startsWith('//media.springernature.com/lw685/') ||
$i.attr('srcset').startsWith('//media.springernature.com/m312/') ||
$i.attr('srcset').startsWith('//media.springernature.com/relative-r300-703_m1050/') ||
$i.attr('srcset').startsWith('//media.springernature.com/w300/'))
!(
$i.attr('srcset') &&
($i.attr('srcset').startsWith('//media.springernature.com/lw685/') ||
$i.attr('srcset').startsWith('//media.springernature.com/m312/') ||
$i.attr('srcset').startsWith('//media.springernature.com/relative-r300-703_m1050/') ||
$i.attr('srcset').startsWith('//media.springernature.com/w300/'))
)
) {
$i.attr('srcset', $i.attr('srcset').replace('//media.springernature.com/lw685/', '//media.springernature.com/full/'));
$i.attr('srcset', $i.attr('srcset').replace('//media.springernature.com/m312/', '//media.springernature.com/full/'));
$i.attr('srcset', $i.attr('srcset').replace('//media.springernature.com/relative-r300-703_m1050/', '//media.springernature.com/full/'));
$i.attr('srcset', $i.attr('srcset').replace('//media.springernature.com/w300/', '//media.springernature.com/full/'));
return;
}
$i.attr('srcset', $i.attr('srcset').replace('//media.springernature.com/lw685/', '//media.springernature.com/full/'));
$i.attr('srcset', $i.attr('srcset').replace('//media.springernature.com/m312/', '//media.springernature.com/full/'));
$i.attr('srcset', $i.attr('srcset').replace('//media.springernature.com/relative-r300-703_m1050/', '//media.springernature.com/full/'));
$i.attr('srcset', $i.attr('srcset').replace('//media.springernature.com/w300/', '//media.springernature.com/full/'));
});
html('img').each((_, i) => {
const $i = html(i);
if (
$i.attr('src') &&
($i.attr('src').startsWith('//media.springernature.com/lw685/') ||
$i.attr('src').startsWith('//media.springernature.com/m312/') ||
$i.attr('src').startsWith('//media.springernature.com/relative-r300-703_m1050/') ||
$i.attr('src').startsWith('//media.springernature.com/w300/'))
!(
$i.attr('src') &&
($i.attr('src').startsWith('//media.springernature.com/lw685/') ||
$i.attr('src').startsWith('//media.springernature.com/m312/') ||
$i.attr('src').startsWith('//media.springernature.com/relative-r300-703_m1050/') ||
$i.attr('src').startsWith('//media.springernature.com/w300/'))
)
) {
$i.attr('src', $i.attr('src').replace('//media.springernature.com/lw685/', '//media.springernature.com/full/'));
$i.attr('src', $i.attr('src').replace('//media.springernature.com/m312/', '//media.springernature.com/full/'));
$i.attr('src', $i.attr('src').replace('//media.springernature.com/relative-r300-703_m1050/', '//media.springernature.com/full/'));
$i.attr('src', $i.attr('src').replace('//media.springernature.com/w300/', '//media.springernature.com/full/'));
return;
}
$i.attr('src', $i.attr('src').replace('//media.springernature.com/lw685/', '//media.springernature.com/full/'));
$i.attr('src', $i.attr('src').replace('//media.springernature.com/m312/', '//media.springernature.com/full/'));
$i.attr('src', $i.attr('src').replace('//media.springernature.com/relative-r300-703_m1050/', '//media.springernature.com/full/'));
$i.attr('src', $i.attr('src').replace('//media.springernature.com/w300/', '//media.springernature.com/full/'));
});
};
+2 -10
View File
@@ -170,11 +170,7 @@ function extractGenericItem(segment: string, templateId: string) {
bodyText = cleanText(bodyMatch[1]);
}
if (!title || !link) {
return null;
}
if (['더보기', '관련도순', '최신순'].includes(title)) {
if (!title || !link || ['더보기', '관련도순', '최신순'].includes(title)) {
return null;
}
@@ -252,11 +248,7 @@ function parseKoreanRelativeTime(timeText: string): Date | undefined {
}
const match = timeText.match(/(\d+)\s*(시간|[분일주]) 전|(\d+)분 이내|(\d+)시간 이내|방금/);
if (!match) {
return;
}
if (match[0] === '방금') {
if (!match || match[0] === '방금') {
return;
}
+5 -3
View File
@@ -74,10 +74,12 @@ async function handler(): Promise<Data> {
attachments.each((_, el) => {
const href = $detail(el).attr('href');
const text = $detail(el).text().trim();
if (href && text) {
const absoluteHref = href.startsWith('http') ? href : new URL(href, baseUrl).href;
description += `<li><a href="${absoluteHref}">${text}</a></li>`;
if (!href || !text) {
return;
}
const absoluteHref = href.startsWith('http') ? href : new URL(href, baseUrl).href;
description += `<li><a href="${absoluteHref}">${text}</a></li>`;
});
description += '</ul>';
}
+15 -13
View File
@@ -120,20 +120,22 @@ const cleanEntryContent = ($) => {
entry.find('.wp_video_player').each((_, el) => {
const div = $(el);
const src = div.attr('sudy-wp-src');
if (src) {
const videoUrl = BASE_URL + src;
const widthMatch = div.attr('style')?.match(/width:\s*(\d+)px/);
const width = widthMatch && widthMatch[1] ? widthMatch[1] : '600';
const heightMatch = div.attr('style')?.match(/height:\s*(\d+)px/);
const height = heightMatch && heightMatch[1] ? heightMatch[1] : '400';
const videoTag = `
<video controls width="${width}" height="${height}" style="max-width: 100%;margin-left: auto;margin-right: auto;">
<source src="${videoUrl}" type="video/mp4">
您的浏览器不支持 video 标签。
</video>
`;
div.replaceWith(videoTag);
if (!src) {
return;
}
const videoUrl = BASE_URL + src;
const widthMatch = div.attr('style')?.match(/width:\s*(\d+)px/);
const width = widthMatch && widthMatch[1] ? widthMatch[1] : '600';
const heightMatch = div.attr('style')?.match(/height:\s*(\d+)px/);
const height = heightMatch && heightMatch[1] ? heightMatch[1] : '400';
const videoTag = `
<video controls width="${width}" height="${height}" style="max-width: 100%;margin-left: auto;margin-right: auto;">
<source src="${videoUrl}" type="video/mp4">
您的浏览器不支持 video 标签。
</video>
`;
div.replaceWith(videoTag);
});
return entry.html();
};
+1 -1
View File
@@ -12,8 +12,8 @@ const handler: Route['handler'] = async () => {
const item = await Promise.all(
$('article')
.toArray()
.slice(0, 20)
.toArray()
.map((item) => {
const $ = load(item);
const link = `https://nextjs.org${$('a[href^="/blog"]').attr('href')}`;
+1 -1
View File
@@ -24,8 +24,8 @@ const handler: Route['handler'] = async () => {
// archive
const item = await Promise.all(
$('div[class^="releasePreviewsSection"] h3 a[href^="/releases/"]')
.toArray()
.slice(0, 5)
.toArray()
.map((item) => {
const link = `https://notion.so${item.attribs.href}`;
+8 -6
View File
@@ -24,13 +24,15 @@ function generateEnclosureInfo(htmlContent: string): { enclosure_url?: string; e
const extension = src.replace(/.*\./, '').toLowerCase();
const mimeType = MIME_TYPE_MAP[extension as keyof typeof MIME_TYPE_MAP];
if (mimeType) {
enclosureInfo = {
enclosure_url: src,
enclosure_type: mimeType,
};
return false;
if (!mimeType) {
return;
}
enclosureInfo = {
enclosure_url: src,
enclosure_type: mimeType,
};
return false;
});
return enclosureInfo;
+1 -3
View File
@@ -89,8 +89,6 @@ async function handler(ctx) {
const items = await Promise.all(
list.map((item) =>
cache.tryGet(item.link, async () => {
let media = '';
if (item.slideOrVideo) {
const page = await context.newPage();
await page.route('**/*', (route) => {
@@ -105,7 +103,7 @@ async function handler(ctx) {
const html = await page.content();
const $ = load(html);
media = $('.slide-item').length
const media = $('.slide-item').length
? $('.slide-item div:first-of-type')
.toArray()
.map((item) => {
+1 -4
View File
@@ -55,11 +55,8 @@ async function handler(ctx): Promise<Data> {
const seriesInfo: SeriesDetail = seriesInfoResponse.data;
// xRestrict: 0=All ages, 1=R18, 2=R18G
if (seriesInfo.body.xRestrict > 0) {
return await getNSFWSeriesNovels(id, limit);
}
// All-ages: prefer NSFW handler if authenticated
if (hasPixivAuth()) {
if (seriesInfo.body.xRestrict > 0 || hasPixivAuth()) {
return await getNSFWSeriesNovels(id, limit);
}
return await getSFWSeriesNovels(id, limit);
+12 -10
View File
@@ -47,17 +47,19 @@ const pixivGot = got.extend({
logger.warn(`No IPv4 address resolved from ${config.pixiv.bypassCdnHostname}`);
}
}
if (hostname) {
const actualHost = options.url.host;
options.headers = {
...options.headers,
host: actualHost,
};
options.url.hostname = hostname;
options.checkServerIdentity = function (host, certificate) {
return tls.checkServerIdentity(actualHost, certificate);
};
if (!hostname) {
return;
}
const actualHost = options.url.host;
options.headers = {
...options.headers,
host: actualHost,
};
options.url.hostname = hostname;
options.checkServerIdentity = function (host, certificate) {
return tls.checkServerIdentity(actualHost, certificate);
};
},
],
},
+22 -18
View File
@@ -58,25 +58,29 @@ export function processContent($: CheerioAPI, lang: string): string {
const $link = $elem.find('blockquote > a');
const href = $link.attr('href');
if (href) {
const match = href.match(/\/status\/(\d+)/);
if (match) {
const tweetId = match[1];
$elem.html(`
<iframe
scrolling="no"
frameborder="0"
allowtransparency="true"
allowfullscreen="true"
class=""
style="position: static; visibility: visible; display: block; width: 550px; height: 1000px; flex-grow: 1;"
title="X Post"
src="https://platform.twitter.com/embed/Tweet.html?id=${tweetId}"
></iframe>
`);
$elem.find('blockquote').remove();
}
if (!href) {
return;
}
const match = href.match(/\/status\/(\d+)/);
if (!match) {
return;
}
const tweetId = match[1];
$elem.html(`
<iframe
scrolling="no"
frameborder="0"
allowtransparency="true"
allowfullscreen="true"
class=""
style="position: static; visibility: visible; display: block; width: 550px; height: 1000px; flex-grow: 1;"
title="X Post"
src="https://platform.twitter.com/embed/Tweet.html?id=${tweetId}"
></iframe>
`);
$elem.find('blockquote').remove();
});
return (
+5 -3
View File
@@ -32,10 +32,12 @@ const getPlurk = (plurkGuid, item, author) => {
$('img').each((_, e) => {
const $e = $(e);
$e.removeAttr('height').removeAttr('width');
if ($e.attr('alt') && $e.attr('alt')!.startsWith('http')) {
$e.attr('src', $e.attr('alt'));
$e.removeAttr('alt');
if (!($e.attr('alt') && $e.attr('alt')!.startsWith('http'))) {
return;
}
$e.attr('src', $e.attr('alt'));
$e.removeAttr('alt');
});
return {
+1 -1
View File
@@ -29,8 +29,8 @@ async function handler(ctx: Context) {
const $ = load(response);
const list: DataItem[] = $('.archive-item-link')
.toArray()
.slice(0, 15)
.toArray()
.map((item) => {
const $item = $(item);
return {
+1 -1
View File
@@ -28,8 +28,8 @@ async function handler(ctx: Context) {
const $ = load(response);
const list: DataItem[] = $('.release-notes-content__versions li')
.toArray()
.slice(0, 20)
.toArray()
.map((item) => {
const $item = $(item);
return {
+1 -1
View File
@@ -32,8 +32,8 @@ async function handler(ctx: Context) {
$('a.news-more').remove();
const list = $('li.clearfix div.news-right a')
.toArray()
.slice(0, 10)
.toArray()
.map((item): DataItem => {
const $item = $(item);
return {
+1 -1
View File
@@ -12,8 +12,8 @@ const handler: Route['handler'] = async () => {
const item = await Promise.all(
$('a[href^="/blog/"]')
.toArray()
.slice(0, 20)
.toArray()
.map((item) => {
const link = `https://react.dev${item.attribs.href}`;
+1 -1
View File
@@ -77,8 +77,8 @@ Parsing of \`routeParams\` parameter:
const rssTitle = routeParams.get('title') || $('title').text();
const item = routeParams.get('item') || 'html';
let items: DataItem[] = $(item)
.toArray()
.slice(0, 20)
.toArray()
.map((item) => {
try {
const $item = $(item);
+8 -6
View File
@@ -105,13 +105,15 @@ async function fetchContent(url) {
stubS.find('img').each((_, el) => {
const img = subind(el);
const file = img.attr('file');
if (file) {
img.attr('src', file);
img.removeAttr('zoomfile');
img.removeAttr('file');
img.removeAttr('onmouseover');
img.removeAttr('onclick');
if (!file) {
return;
}
img.attr('src', file);
img.removeAttr('zoomfile');
img.removeAttr('file');
img.removeAttr('onmouseover');
img.removeAttr('onclick');
});
return stubS.html();
+1 -1
View File
@@ -50,8 +50,8 @@ async function handler(ctx) {
const staticUrl = new URL('/image/common/none.gif', host);
staticUrl.hostname = `static.${staticUrl.hostname.split('.').slice(-2).join('.')}`;
const resultItems = list
.toArray()
.slice(0, 20)
.toArray()
.map((post) => {
const each = $(post);
const floor = each.find('td.plc .pi a > em').text();
+1 -1
View File
@@ -60,8 +60,8 @@ async function handler() {
};
});
const paperTable = $('tbody tr')
.toArray()
.slice(1) // skip table header
.toArray()
.map((item) => {
const $item = $(item);
const title = $item.find('td').eq(0).text().trim();
+9 -7
View File
@@ -68,13 +68,15 @@ async function handler() {
const text = span.html();
span.remove();
if (spanClass !== undefined) {
const type = spanClass.split(' ', 2)[1];
if (type === 'empty') {
$li.wrap('<ul></ul>');
} else {
$li.prepend(`<b style='color:${textColor[type]}'>${text}: </b>`);
}
if (spanClass === undefined) {
return;
}
const type = spanClass.split(' ', 2)[1];
if (type === 'empty') {
$li.wrap('<ul></ul>');
} else {
$li.prepend(`<b style='color:${textColor[type]}'>${text}: </b>`);
}
});
+1 -1
View File
@@ -38,8 +38,8 @@ async function handler(ctx: Context) {
const threads = $('form table')
.last()
.find('tbody')
.toArray()
.slice(1) // skip first empty row
.toArray()
.map((item) => {
const $item = $(item);
return {
+6 -4
View File
@@ -6,11 +6,13 @@ export const parseSearchDate = (value: string, now = new Date()): Date | undefin
if (/^\d{2}:\d{2}$/.test(value)) {
return parseDateInTimezone(`${today}T${value}`, 8);
}
if (/^\d{2}-\d{2} \d{2}:\d{2}$/.test(value)) {
// Search results omit the year; a later month/day belongs to last year.
const year = Number(today.slice(0, 4)) - Number(value.slice(0, 5) > today.slice(5));
return parseDateInTimezone(`${year}-${value}`, 8);
if (!/^\d{2}-\d{2} \d{2}:\d{2}$/.test(value)) {
return;
}
// Search results omit the year; a later month/day belongs to last year.
const year = Number(today.slice(0, 4)) - Number(value.slice(0, 5) > today.slice(5));
return parseDateInTimezone(`${year}-${value}`, 8);
};
export const getHeaders = () => ({
+1 -1
View File
@@ -58,7 +58,7 @@ export const route: Route = {
const configTarget = urlMap[type] || urlMap.tzgg;
const response = await ofetch(configTarget.url);
const $ = load(response);
const list = $('.lunwen dl dd').toArray().slice(0, 10);
const list = $('.lunwen dl dd').slice(0, 10).toArray();
const items = await Promise.all(
list.map((item) => {
+1 -1
View File
@@ -31,7 +31,7 @@ export const route: Route = {
const url = 'https://www.snnu.edu.cn/tzgg.htm';
const response = await ofetch(url);
const $ = load(response);
const list = $('.ul-txtq3 li').toArray().slice(0, 10);
const list = $('.ul-txtq3 li').slice(0, 10).toArray();
const items = await Promise.all(
list.map((item) => {
+1 -1
View File
@@ -31,7 +31,7 @@ export const route: Route = {
const url = 'https://newyjs.snnu.edu.cn/tzgg1.htm';
const response = await ofetch(url);
const $ = load(response);
const list = $('.n_bt li').toArray().slice(0, 10);
const list = $('.n_bt li').slice(0, 10).toArray();
const items = await Promise.all(
list.map((item) => {
+1 -1
View File
@@ -29,7 +29,7 @@ async function handler() {
link: a.attr('href')!,
};
});
const uniqueList = new Map(list.map((item) => [item.link, item])).values().toArray().slice(0, 15);
const uniqueList = new Map(list.map((item) => [item.link, item])).values().take(15).toArray();
const items = await Promise.all(
uniqueList.map((item) =>
+5 -3
View File
@@ -89,10 +89,12 @@ function fetchArticle(item) {
});
article.find('img').each((_, e) => {
const $e = $(e);
if ($e.attr('data-src') && !$e.attr('src')) {
$e.attr('src', decryptImageUrl($e.attr('data-src')));
$e.removeAttr('data-src');
if (!$e.attr('data-src') || $e.attr('src')) {
return;
}
$e.attr('src', decryptImageUrl($e.attr('data-src')));
$e.removeAttr('data-src');
});
item.description = article.html();
+1 -2
View File
@@ -5,9 +5,8 @@ import { parseDate } from '@/utils/parse-date';
import timezone from '@/utils/timezone';
export default async function get_article(url) {
const domain = 'https://www.solidot.org';
if (/^\/.*$/.test(url)) {
const domain = 'https://www.solidot.org';
url = domain + url;
}
const response = await got({
+5 -3
View File
@@ -24,10 +24,12 @@ const fixImages = ($) => {
const hdImage = (img) => {
img.attribs.src = img.attribs.src.replace('_thm', '').replace('_small', '');
if (img.parentNode.name === 'a' && img.parentNode.attribs['data-width'] && img.parentNode.attribs['data-height']) {
img.attribs.width = img.parentNode.attribs['data-width'];
img.attribs.height = img.parentNode.attribs['data-height'];
if (!(img.parentNode.name === 'a' && img.parentNode.attribs['data-width'] && img.parentNode.attribs['data-height'])) {
return;
}
img.attribs.width = img.parentNode.attribs['data-width'];
img.attribs.height = img.parentNode.attribs['data-height'];
};
const removeFigureStyle = (f) => {
delete f.attribs.style;
+1 -4
View File
@@ -50,10 +50,7 @@ function ExpandInlineBytes(bytes: Buffer) {
}
function sortThumb(thumb: Api.TypePhotoSize) {
if (thumb instanceof Api.PhotoStrippedSize) {
return thumb.bytes.length;
}
if (thumb instanceof Api.PhotoCachedSize) {
if (thumb instanceof Api.PhotoStrippedSize || thumb instanceof Api.PhotoCachedSize) {
return thumb.bytes.length;
}
if (thumb instanceof Api.PhotoSize) {

Some files were not shown because too many files have changed in this diff Show More