feat(route): add oshwhub.com support (#12094)
* feat(route): add oshwhub.com support * Update docs/en/other.md * Update docs/other.md * feat(route): fix cache logic and radar target * Update lib/v2/oshwhub/radar.js * fix typo ---------
This commit is contained in:
parent
331764e88a
commit
e4ae95e9f2
|
|
@ -214,6 +214,12 @@ For example:
|
|||
|
||||
</RouteEn>
|
||||
|
||||
## oshwhub
|
||||
|
||||
### OpenSource Square
|
||||
|
||||
<RouteEn author="tylinux" example="/oshwhub" path="/oshwhub/:sortType?" :paramsDesc="['sortType']" radar="1" rssbud="1"/>
|
||||
|
||||
## Panda
|
||||
|
||||
### Feeds
|
||||
|
|
|
|||
|
|
@ -629,6 +629,12 @@ type 为 all 时,category 参数不支持 cost 和 free
|
|||
|
||||
<Route author="SettingDust Halcao" example="/uraaka-joshi/_rrwq" path="/uraaka-joshi/:id" :paramsDesc="['用户名']" radar="1" rssbud="1" puppeteer="1"/>
|
||||
|
||||
## 立创开源硬件平台
|
||||
|
||||
### 开源广场
|
||||
|
||||
<Route author="tylinux" example="/oshwhub" path="/oshwhub/:sortType?" :paramsDesc="['排序类型']" radar="1" rssbud="1"/>
|
||||
|
||||
## 律师事务所文章
|
||||
|
||||
### 君合
|
||||
|
|
|
|||
|
|
@ -0,0 +1,116 @@
|
|||
const got = require('@/utils/got');
|
||||
const cheerio = require('cheerio');
|
||||
const path = require('path');
|
||||
const { art } = require('@/utils/render');
|
||||
const timezone = require('@/utils/timezone');
|
||||
const { parseDate } = require('@/utils/parse-date');
|
||||
const md = require('markdown-it')({
|
||||
html: true,
|
||||
linkify: true,
|
||||
});
|
||||
|
||||
const requestImages = (url, tryGet) =>
|
||||
tryGet(url, async () => {
|
||||
const response = await got({
|
||||
method: 'get',
|
||||
url,
|
||||
});
|
||||
|
||||
const images = {};
|
||||
const boms = [];
|
||||
|
||||
const imgData = response.data;
|
||||
imgData?.result?.boards?.forEach((board) => {
|
||||
const name = board.name;
|
||||
if (images[name] === undefined) {
|
||||
images[name] = [];
|
||||
}
|
||||
|
||||
board.schematic?.documents?.forEach((val) => {
|
||||
if (val.thumb) {
|
||||
images[name].push(val.thumb);
|
||||
}
|
||||
});
|
||||
|
||||
if (board.pcb_info?.thumb) {
|
||||
images[name].push(board.pcb_info.thumb);
|
||||
}
|
||||
if (board.pcb_info?.boms?.boms) {
|
||||
boms.push(...JSON.parse(board.pcb_info.boms.boms));
|
||||
}
|
||||
});
|
||||
return { images, boms };
|
||||
});
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const baseUrl = 'https://oshwhub.com';
|
||||
const sortType = ctx.params.sortType ?? 'updatedTime';
|
||||
|
||||
const url = `${baseUrl}/explore?projectSort=${sortType}`;
|
||||
const response = await got({
|
||||
method: 'get',
|
||||
url,
|
||||
});
|
||||
|
||||
const html = response.data;
|
||||
const $ = cheerio.load(html);
|
||||
const title = $('title').text();
|
||||
const projects = $('a[class="project-link"]');
|
||||
|
||||
const items = await Promise.all(
|
||||
projects.map((id, item) => {
|
||||
const detailUrl = `${baseUrl}${item.attribs.href}`;
|
||||
return ctx.cache.tryGet(detailUrl, async () => {
|
||||
const response = await got({
|
||||
method: 'get',
|
||||
url: detailUrl,
|
||||
});
|
||||
|
||||
const html = response.data;
|
||||
const $$ = cheerio.load(html);
|
||||
const projectDetail = $$('div[class="projects-left-top"]');
|
||||
|
||||
const title = $$(projectDetail).find('span[class="title"]').text();
|
||||
const author = $$(projectDetail).find('div[class="member-items"] > ul > li > a > span').first().text().trim();
|
||||
const publishTime = $$(projectDetail).find('div[class="issue-time"] > span').text();
|
||||
const pubDate = timezone(parseDate(publishTime.trim().split('\n')[1].trim(), 'YYYY/MM/DD HH:mm:ss'), 0);
|
||||
|
||||
const coverImg = $$(projectDetail).find('div[class="img-cover"] > img').attr('src').trim();
|
||||
const introduction = $$(projectDetail).find('p[class="introduction"]').text().trim();
|
||||
const content = $$(projectDetail).find('div[class*="html-content"]').attr('data-markdown');
|
||||
|
||||
// request images
|
||||
const dataUuid = $$('div[class="projects-detail"]').attr()['data-uuid'];
|
||||
const { images, boms } = await requestImages(`${baseUrl}/api/project/${dataUuid}/pro_images`, ctx.cache.tryGet);
|
||||
|
||||
const description = art(path.join(__dirname, 'templates/description.art'), {
|
||||
title,
|
||||
author,
|
||||
publishTime,
|
||||
coverImg,
|
||||
introduction,
|
||||
content: md.render(content) || 'No Content',
|
||||
images,
|
||||
boms,
|
||||
});
|
||||
|
||||
const single = {
|
||||
title,
|
||||
description,
|
||||
pubDate,
|
||||
link: detailUrl,
|
||||
author,
|
||||
};
|
||||
|
||||
return single;
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
ctx.state.data = {
|
||||
title,
|
||||
link: url,
|
||||
description: title,
|
||||
item: items,
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
module.exports = {
|
||||
'/:sortType?': ['tylinux'],
|
||||
};
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
module.exports = {
|
||||
'oshwhub.com': {
|
||||
_name: '立创开源硬件平台',
|
||||
'.': [
|
||||
{
|
||||
title: '开源广场',
|
||||
docs: 'https://docs.rsshub.app/other.html#li-chuang-kai-yuan-ying-jian-ping-tai',
|
||||
source: ['/explore'],
|
||||
target: (_, url) => {
|
||||
const sortType = new URL(url).searchParams.get('projectSort');
|
||||
return sortType ? `/oshwhub/${sortType}` : '';
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
module.exports = function (router) {
|
||||
router.get('/:sortType?', require('./explore'));
|
||||
};
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
<div>
|
||||
<div>
|
||||
<img src={{coverImg}} /><br><br>
|
||||
<span>{{publishTime}}</span><br>
|
||||
<span>作者:{{author}}</span><br>
|
||||
<span>{{introduction}}</span><br>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h1> 描述 </h1>
|
||||
{{@ content}}
|
||||
</div>
|
||||
|
||||
{{ if images }}
|
||||
<div>
|
||||
<h1> PCB && schematic </h1>
|
||||
{{each images $imgs $key}}
|
||||
{{each $imgs $img}}
|
||||
<img src={{$img}} /><br>
|
||||
{{/each}}
|
||||
{{/each}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{ if boms }}
|
||||
<div>
|
||||
<h1> BOM </h1>
|
||||
<table class="table">
|
||||
<tr>
|
||||
<th>No</th>
|
||||
<th>Quantity</th>
|
||||
<th>Device</th>
|
||||
<th>Designator</th>
|
||||
<th>Footprint</th>
|
||||
<th>Value</th>
|
||||
<th>Manufacturer Part</th>
|
||||
<th>Manufacturer</th>
|
||||
<th>Supplier Part</th>
|
||||
<th>Supplier</th>
|
||||
</tr>
|
||||
{{each boms}}
|
||||
<tr>
|
||||
<th>{{$value.No}}</th>
|
||||
<th>{{$value.Quantity}}</th>
|
||||
<th>{{$value.Device}}</th>
|
||||
<th>{{$value.Designator}}</th>
|
||||
<th>{{$value.Footprint}}</th>
|
||||
<th>{{$value.Value}}</th>
|
||||
<th>{{$value['Manufacturer Part']}}</th>
|
||||
<th>{{$value.Manufacturer}}</th>
|
||||
<th>{{$value['Supplier Part']}}</th>
|
||||
<th>{{$value.Supplier}}</th>
|
||||
</tr>
|
||||
{{/each}}
|
||||
</table>
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
Loading…
Reference in New Issue