RSSHub/lib/v2/huxiu/utils.js

155 lines
4.5 KiB
JavaScript

const cheerio = require('cheerio');
const { parseDate } = require('@/utils/parse-date');
const got = require('@/utils/got');
const { art } = require('@/utils/render');
const path = require('path');
const CryptoJS = require('crypto-js');
const accountApi = 'https://account-api.huxiu.com';
const articleApi = 'https://api-article.huxiu.com';
const baseUrl = 'https://www.huxiu.com';
const briefApi = 'https://api-brief.huxiu.com';
const momentApi = 'https://moment-api.huxiu.com';
const searchApi = 'https://search-api.huxiu.com';
const ProcessFeed = (list, cache) =>
Promise.all(
list.map((item) =>
cache.tryGet(item.link, async () => {
const response = await got(item.link, {
https: {
rejectUnauthorized: false,
},
});
const $ = cheerio.load(response.data);
const initialState = parseInitialState($);
if (item.link.startsWith(`${baseUrl}/article/`)) {
fetchArticle(initialState, item);
} else if (item.link.startsWith(`${baseUrl}/brief/`)) {
fetchBrief(initialState, item);
}
return item;
})
)
);
const fetchArticle = (initialState, item) => {
const { articleDetail } = initialState.articleDetail;
const topImg = art(path.join(__dirname, 'templates/img.art'), {
img: articleDetail.pic_path.split('?')[0],
});
let video = '';
if (articleDetail.video_info) {
video = art(path.join(__dirname, 'templates/video.art'), {
video_info: articleDetail.video_info,
});
}
const $ = cheerio.load(articleDetail.content, null, false);
$('.text-big-title').each((_, e) => (e.tagName = 'h3'));
fixImg($);
removeExtraLinebreak($);
// $('img.dialog_add_wxxy_qrcode_icon').remove();
item.description = video + topImg + $.html();
item.author = articleDetail.author;
item.category = articleDetail.tags_info.map((tag) => tag.name);
};
const fetchBrief = (initialState, item) => {
const { brief_detail } = initialState.briefStoreModule;
const { brief_column } = brief_detail;
const description = art(path.join(__dirname, 'templates/brief.art'), {
brief: brief_detail.brief,
});
const $ = cheerio.load(description, null, false);
$('button.black-dot').remove();
fixImg($);
removeExtraLinebreak($);
item.description = $.html();
item.author = brief_detail.brief.publisher_list.map((item) => item.username).join(', ');
item.pubDate = parseDate(brief_column.update_time, 'X');
};
const parseInitialState = ($) =>
JSON.parse(
$('script')
.text()
.match(/window\.__INITIAL_STATE__=(\{.*?\});\(function\(\)/)[1]
);
const fixImg = ($) => {
$('img.lazyImg, img.js-preview').each((_, e) => {
if (e.attribs._src) {
e.attribs.src = e.attribs._src.split('?')[0];
delete e.attribs._src;
}
if (e.attribs.src.includes('?')) {
e.attribs.src = e.attribs.src.split('?')[0];
}
if (e.attribs['data-w']) {
e.attribs.width = e.attribs['data-w'];
delete e.attribs['data-w'];
}
if (e.attribs['data-h']) {
e.attribs.height = e.attribs['data-h'];
delete e.attribs['data-h'];
}
});
};
const removeExtraLinebreak = ($) => {
$('p').each((_, e) => {
e = $(e);
if (e.find('img').length === 0 && e.text().match(/^\s*$/)) {
e.remove();
}
});
};
const generateNonce = () => {
let nonce = '';
const e = 'abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ';
const t = 16;
for (let i = 0; i < t; i++) {
nonce += e.charAt(Math.floor(Math.random() * e.length));
}
return nonce;
};
const generateSignature = () => {
const timestamp = Math.round(new Date().getTime() / 1000).toString();
// const appSecret = '4nHzGgGt7WX4zFTsTKocpxg4dzU6-wUi';
const appSecret = 'hUzaVKtNfDE-6UiyaJdfsmjW-8dwoyVc'; // appid: 'hx_search'
const nonce = generateNonce();
const r = [appSecret, timestamp, nonce].sort();
return {
nonce,
timestamp,
signature: CryptoJS.SHA1(r[0] + r[1] + r[2]).toString(),
};
};
module.exports = {
accountApi,
articleApi,
baseUrl,
briefApi,
momentApi,
searchApi,
ProcessFeed,
fetchArticle,
fetchBrief,
parseInitialState,
fixImg,
removeExtraLinebreak,
generateSignature,
};