diff --git a/assets/radar-rules.js b/assets/radar-rules.js index 2edac4ae1..aa23064a1 100644 --- a/assets/radar-rules.js +++ b/assets/radar-rules.js @@ -801,4 +801,21 @@ }, ], }, + + 'yuancheng.work': { + _name: '远程.work', + '.': [ + { + title: '招聘信息', + docs: 'https://docs.rsshub.app/other.html#yuan-cheng-work', + source: '/:caty', + target: (params, url) => { + if (!url) { + return '/remote-work'; + } + return '/remote-work/' + /\w+-(\w+)-\w+/.exec(url)[1]; + }, + }, + ], + }, }); diff --git a/docs/en/other.md b/docs/en/other.md index 055deaf0f..e691ab0b8 100644 --- a/docs/en/other.md +++ b/docs/en/other.md @@ -66,3 +66,15 @@ EZTV provides an official RSS feed of all torrents: https://eztv.ag/ezrss.xml ### Hermes UK + +## Remote.work + +### Remote.work Job Information + + + +| All Jobs | Development | Design | Operation | Product | Other | Marketing | Sales | +| :------: | :---------: | :----: | :-------: | :-----: | :---: | :-------: | :---: | +| all | development | design | operation | product | other | marketing | sales | + + diff --git a/docs/other.md b/docs/other.md index 92f3b5120..ce3d3cf1f 100644 --- a/docs/other.md +++ b/docs/other.md @@ -420,6 +420,18 @@ type 为 all 时,category 参数不支持 cost 和 free +## 远程.work + +### 远程.work 招聘信息 + + + +| 所有职位 | 技术 | 设计 | 运营 | 产品 | 其他 | 市场 | 销售 | +| :------: | :---------: | :----: | :-------: | :-----: | :---: | :-------: | :---: | +| all | development | design | operation | product | other | marketing | sales | + + + ## 正版中国 ### 分类列表 diff --git a/lib/router.js b/lib/router.js index ff63d0f74..b58962100 100644 --- a/lib/router.js +++ b/lib/router.js @@ -1988,4 +1988,7 @@ router.get('/fanfou/favorites/:uid', require('./routes/fanfou/favorites')); router.get('/fanfou/trends', require('./routes/fanfou/trends')); router.get('/fanfou/public_timeline/:keyword', require('./routes/fanfou/public_timeline')); +// Remote Work +router.get('/remote-work/:caty?', require('./routes/remote-work/index')); + module.exports = router; diff --git a/lib/routes/remote-work/index.js b/lib/routes/remote-work/index.js new file mode 100644 index 000000000..973ca4711 --- /dev/null +++ b/lib/routes/remote-work/index.js @@ -0,0 +1,91 @@ +const url = require('url'); +const got = require('@/utils/got'); +const cheerio = require('cheerio'); + +const root_url = 'https://yuancheng.work/'; + +const config = { + all: { + link: '/', + title: 'Remote Work|远程工作', + }, + development: { + link: '/remote-development-jobs', + title: 'Remote Work-Development|远程工作-技术', + }, + design: { + link: '/remote-design-jobs', + title: 'Remote Work-Design|远程工作-设计', + }, + operation: { + link: '/remote-operation-jobs', + title: 'Remote Work-Operation|远程工作-运营', + }, + product: { + link: '/remote-product-jobs', + title: 'Remote Work-Product|远程工作-产品', + }, + other: { + link: '/remote-other-jobs', + title: 'Remote Work-Other|远程工作-其他', + }, + marketing: { + link: '/remote-marketing-jobs', + title: 'Remote Work-Marketing|远程工作-市场', + }, + sales: { + link: '/remote-sales-jobs', + title: 'Remote Work-Sales|远程工作-销售', + }, +}; + +module.exports = async (ctx) => { + const cfg = config[ctx.params.caty || 'all']; + if (!cfg) { + throw Error('Bad category'); + } + + const current_url = url.resolve(root_url, cfg.link); + const response = await got({ + method: 'get', + url: current_url, + }); + + const $ = cheerio.load(response.data); + const list = $('div.list-group div.job') + .slice(0, 10) + .map((_, item) => { + item = $(item); + const a = item.find('a.job-title'); + let title = a.attr('title'); + item.find('div.job-meta span.job-meta-value').each((_, tag) => { + title += '|' + $(tag).text(); + }); + return { + title: title, + link: a.attr('href'), + pubDate: new Date(item.find('div.job-foot div.job-date').attr('date') + ' GMT+8').toUTCString(), + }; + }) + .get(); + + const items = await Promise.all( + list.map( + async (item) => + await ctx.cache.tryGet('remote-work' + item.link, async () => { + const res = await got({ method: 'get', url: url.resolve(root_url, item.link) }); + const content = cheerio.load(res.data); + item.description = content('div.container div.main div.job-section') + .first() + .html(); + return item; + }) + ) + ); + + ctx.state.data = { + title: cfg.title, + link: current_url, + item: items, + }; +};