mirror of
https://github.com/DIYgod/RSSHub.git
synced 2026-09-24 23:12:34 +08:00
Merge branch 'DIYgod:master' into master
This commit is contained in:
@@ -7,15 +7,26 @@ on:
|
||||
paths:
|
||||
- '.github/workflows/scrape.yml'
|
||||
- 'docs/**'
|
||||
workflow_dispatch: ~
|
||||
|
||||
jobs:
|
||||
scrape-docs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Wait for Netlify to finish
|
||||
run: sleep 3m
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Use Node.js v16
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
cache: 'yarn'
|
||||
- name: Install dependencies (yarn)
|
||||
run: yarn
|
||||
- name: Pull image
|
||||
run: docker pull getmeili/docs-scraper
|
||||
- name: Wait for Netlify to finish
|
||||
run: sleep 3m
|
||||
if: github.event_name == 'push'
|
||||
- name: Run docs-scraper
|
||||
env:
|
||||
HOST_URL: ${{ secrets.MEILISEARCH_HOST_URL }}
|
||||
@@ -27,3 +38,14 @@ jobs:
|
||||
-e MEILISEARCH_API_KEY=$API_KEY \
|
||||
-v $CONFIG_FILE_PATH:/docs-scraper/config.json \
|
||||
getmeili/docs-scraper pipenv run ./docs_scraper config.json
|
||||
- name: Update meilisearch settings
|
||||
uses: actions/github-script@v6
|
||||
env:
|
||||
HOST_URL: ${{ secrets.MEILISEARCH_HOST_URL }}
|
||||
API_KEY: ${{ secrets.MEILISEARCH_API_KEY }}
|
||||
with:
|
||||
script: |
|
||||
const meilisearchHost = process.env.HOST_URL
|
||||
const meilisearchApiKey = process.env.API_KEY
|
||||
const script = require(`${process.env.GITHUB_WORKSPACE}/scripts/docs-scraper/settings.js`)
|
||||
await script({ core }, meilisearchHost, meilisearchApiKey)
|
||||
|
||||
@@ -34,21 +34,6 @@
|
||||
s: [{ title: '热搜榜', docs: 'https://docs.rsshub.app/social-media.html#wei-bo', source: '/top/summary', target: '/weibo/search/hot' }],
|
||||
},
|
||||
'weibo.cn': { _name: '微博', m: [{ title: '博主', docs: 'https://docs.rsshub.app/social-media.html#wei-bo', source: ['/u/:uid', '/profile/:uid'], target: '/weibo/user/:uid' }] },
|
||||
'pixiv.net': {
|
||||
_name: 'Pixiv',
|
||||
www: [
|
||||
{ title: '用户收藏', docs: 'https://docs.rsshub.app/social-media.html#pixiv', source: '/users/:id/bookmarks/artworks', target: '/pixiv/user/bookmarks/:id' },
|
||||
{ title: '用户动态', docs: 'https://docs.rsshub.app/social-media.html#pixiv', source: '/users/:id', target: '/pixiv/user/:id' },
|
||||
{ title: '排行榜', docs: 'https://docs.rsshub.app/social-media.html#pixiv', source: '/ranking.php', target: (params, url) => `/pixiv/ranking/${new URL(url).searchParams.get('mode') || 'daily'}` },
|
||||
{
|
||||
title: '关键词',
|
||||
docs: 'https://docs.rsshub.app/social-media.html#pixiv',
|
||||
source: ['/tags/:keyword', '/tags/:keyword/:type?'],
|
||||
target: (params, url) => `/pixiv/search/:keyword/${new URL(url).searchParams.get('order')}/${new URL(url).searchParams.get('mode')}`,
|
||||
},
|
||||
{ title: '关注的新作品', docs: 'https://docs.rsshub.app/social-media.html#pixiv', source: '/bookmark_new_illust.php', target: '/pixiv/user/illustfollows' },
|
||||
],
|
||||
},
|
||||
'github.com': {
|
||||
_name: 'GitHub',
|
||||
'.': [
|
||||
@@ -322,17 +307,6 @@
|
||||
],
|
||||
sites: [{ title: 'Sites', docs: 'https://docs.rsshub.app/blog.html#google-sites', source: ['/site/:id/*', '/site/:id'], target: '/google/sites/:id' }],
|
||||
},
|
||||
'qidian.com': {
|
||||
_name: '起点',
|
||||
book: [
|
||||
{ title: '章节', docs: 'https://docs.rsshub.app/reading.html#qi-dian', source: '/info/:id', target: '/qidian/chapter/:id' },
|
||||
{ title: '讨论区', docs: 'https://docs.rsshub.app/reading.html#qi-dian', source: '/info/:id', target: '/qidian/forum/:id' },
|
||||
],
|
||||
www: [
|
||||
{ title: '限免', docs: 'https://docs.rsshub.app/reading.html#qi-dian', source: '/free', target: '/qidian/free' },
|
||||
{ title: '女生限免', docs: 'https://docs.rsshub.app/reading.html#qi-dian', source: '/mm/free', target: '/qidian/free/mm' },
|
||||
],
|
||||
},
|
||||
'hackerone.com': { _name: 'HackerOne', '.': [{ title: 'HackerOne Hacker Activity', docs: 'https://docs.rsshub.app/other.html#hackerone-hacker-activity', source: '/hacktivity', target: '/hackerone/hacktivity' }] },
|
||||
'cowlevel.net': { _name: '奶牛关', '.': [{ title: '元素文章', docs: 'https://docs.rsshub.app/game.html#nai-niu-guan', source: ['/element/:id', '/element/:id/article'], target: '/cowlevel/element/:id' }] },
|
||||
'beijing.gov.cn': { wjw: [{ title: '北京卫生健康委员会', docs: 'https://docs.rsshub.app/government.html#bei-jing-shi-wei-sheng-jian-kang-wei-yuan-hui', source: '/xwzx_20031/:caty', target: '/gov/beijing/mhc/:caty' }] },
|
||||
|
||||
+15
-1
@@ -363,7 +363,21 @@ Sources
|
||||
|
||||
### Love Live 官网最新 News
|
||||
|
||||
<Route author="axojhf" example="/lovelive-anime/news" path="/lovelive-anime/news/:option?" :paramsDesc="['`option` 为 `detail` 时抓取全文']" />
|
||||
<Route author="axojhf" example="/lovelive-anime/news" path="/lovelive-anime/news/:option?" :paramsDesc="['`option` 为 `detail` 时抓取全文']" radar="1"/>
|
||||
|
||||
### Love Live 官网分类 Topics
|
||||
|
||||
<Route author="axojhf" example="/lovelive-anime/topics/otonokizaka" path="/lovelive-anime/topics/:abbr/:category?/:option?" :paramsDesc="['Love Live系列子企划在官网的路径,详见下表', '官网列出的Topics分类,`category` 为 `detail` 时抓取全文,其他分类详见下表', '`option` 为 `detail` 时抓取全文']" radar="1">
|
||||
|
||||
| 子企划名(非全称) | Lovelive! | Lovelive! Sunshine!! | Lovelive! Nijigasaki High School Idol Club | Lovelive! Superstar!! |
|
||||
| --------- | ----------- | -------------------- | ------------------------------------------ | --------------------- |
|
||||
| `abbr`参数 | otonokizaka | uranohoshi | nijigasaki | yuigaoka |
|
||||
|
||||
| 分类名 | 全てのニュース | 音楽商品 | アニメ映像商品 | キャスト映像商品 | 劇場 | アニメ放送 / 配信 | キャスト配信 / ラジオ | ライブ / イベント | ブック | グッズ | ゲーム | メディア | ご当地情報 | その他 | キャンペーン |
|
||||
| ------------ | ------------ | ----- | ----------- | ---------- | ------- | ---------- | ------------ | ---------- | ----- | ----- | ---- | ----- | ----- | ----- | -------- |
|
||||
| `category`参数 | <u>*无参数*</u> | music | anime_movie | cast_movie | theater | onair | radio | event | books | goods | game | media | local | other | campaign |
|
||||
|
||||
</Route>
|
||||
|
||||
## Mox.moe
|
||||
|
||||
|
||||
+16
-1
@@ -72,7 +72,22 @@ When `posts` is selected as the value of the parameter **source**, the parameter
|
||||
|
||||
### Love Live! Official Website Latest NEWS
|
||||
|
||||
<RouteEn author="axojhf" example="/lovelive-anime/news" path="/lovelive-anime/news/:option?" :paramsDesc="['Crawl full text when `option` is `detail`.']" />
|
||||
<RouteEn author="axojhf" example="/lovelive-anime/news" path="/lovelive-anime/news/:option?" :paramsDesc="['Crawl full text when `option` is `detail`.']" radar="1"/>
|
||||
|
||||
### Love Live Official Website Categories Topics
|
||||
|
||||
<RouteEn author="axojhf" example="/lovelive-anime/topics/otonokizaka" path="/lovelive-anime/topics/:abbr/:category?/:option?" :paramsDesc="['The path to the Love Live series of sub-projects on the official website is detailed in the table below', 'The official website lists the Topics category, `category` is `detail` when crawling the full text, other categories see the following table for details', 'Crawl full text when `option` is `detail`.']" radar="1">
|
||||
|
||||
| Sub-project name (not full name) | Lovelive! | Lovelive! Sunshine!! | Lovelive! Nijigasaki High School Idol Club | Lovelive! Superstar!! |
|
||||
| -------------------------------- | ----------- | -------------------- | ------------------------------------------ | --------------------- |
|
||||
| `abbr`parameter | otonokizaka | uranohoshi | nijigasaki | yuigaoka |
|
||||
|
||||
|
||||
| category name | 全てのニュース | 音楽商品 | アニメ映像商品 | キャスト映像商品 | 劇場 | アニメ放送/配信 | キャスト配信/ラジオ | ライブ/イベント | ブック | グッズ | ゲーム | メディア | ご当地情報 | その他 | キャンペーン |
|
||||
| -------------- | --------------- | -------- | -------------- | ---------------- | ------- | --------------- | ------------------- | --------------- | ------ | ------ | ------ | -------- | ---------- | ------ | ------------ |
|
||||
| `category`parameter | <u>*No parameter*</u> | music | anime_movie | cast_movie | theater | onair | radio | event | books | goods | game | media | local | other | campaign |
|
||||
|
||||
</RouteEn>
|
||||
|
||||
## Touhougarakuta
|
||||
|
||||
|
||||
@@ -236,7 +236,7 @@ Language
|
||||
|
||||
### Script Update
|
||||
|
||||
<RouteEn author="imlonghao" path="/greasyfork/:language/:domain?" example="/greasyfork/en/google.com" :paramsDesc="['language, located on the top right corner of Greasy Fork\'s search page, set to `all` for including all languages', 'the script\'s target domain']" />
|
||||
<RouteEn author="imlonghao" path="/greasyfork/:language/:domain?" example="/greasyfork/en/google.com" :paramsDesc="['language, located on the top right corner of Greasy Fork\'s search page, set to `all` for including all languages', 'the script\'s target domain']" radar="1" />
|
||||
|
||||
## Hugo
|
||||
|
||||
|
||||
@@ -214,6 +214,10 @@ Though, every Story expires after 24 hours, so it may be not so serious.
|
||||
|
||||
<RouteEn author="EYHN" path="/pixiv/user/:id" example="/pixiv/user/15288095" :paramsDesc="['user id, available in user\'s homepage URL']" radar="1" rssbud="1"/>
|
||||
|
||||
### User Novels
|
||||
|
||||
<RouteEn author="TonyRL" example="/pixiv/user/novels/27104704" path="/pixiv/user/novels/:id" :paramsDesc="['User id, available in user\'s homepage URL']" radar="1" rssbud="1"/>
|
||||
|
||||
### Rankings
|
||||
|
||||
<RouteEn author="EYHN" path="/pixiv/ranking/:mode/:date?" example="/pixiv/ranking/week" :paramsDesc="['rank type', 'format: `2018-4-25`']" radar="1" rssbud="1">
|
||||
|
||||
@@ -268,7 +268,7 @@ pageClass: routes
|
||||
|
||||
### 脚本更新
|
||||
|
||||
<Route author="imlonghao" example="/greasyfork/zh-CN/bilibili.com" path="/greasyfork/:language/:domain?" :paramsDesc="['语言, 可在网站右上角找到, `all` 为所有语言', '按脚本生效域名过滤, 可选']"/>
|
||||
<Route author="imlonghao" example="/greasyfork/zh-CN/bilibili.com" path="/greasyfork/:language/:domain?" :paramsDesc="['语言, 可在网站右上角找到, `all` 为所有语言', '按脚本生效域名过滤, 可选']" radar="1"/>
|
||||
|
||||
## Hugo
|
||||
|
||||
|
||||
@@ -399,6 +399,10 @@ count 的取值范围为 1-12,为防止请求次数过多,推荐设置为 5
|
||||
|
||||
<Route author="LogicJake" example="/qidian/free-next" path="/qidian/free-next/:type?" :paramsDesc="['默认不填为起点中文网,填 mm 为起点女生网']"/>
|
||||
|
||||
### 作者
|
||||
|
||||
<Route author="miles170" example="/qidian/author/9639927" path="/qidian/author/:id" :paramsDesc="['作者 id, 可在作者页面 URL 找到']"/>
|
||||
|
||||
## 起点图
|
||||
|
||||
### 首订
|
||||
|
||||
@@ -562,6 +562,10 @@ Instagram Stories 没有可靠的 guid,你的 RSS 阅读器可能将同一条
|
||||
|
||||
<Route author="DIYgod" example="/pixiv/user/11" path="/pixiv/user/:id" :paramsDesc="['用户 id, 可在用户主页 URL 中找到']" radar="1" rssbud="1"/>
|
||||
|
||||
### 用户小说
|
||||
|
||||
<Route author="TonyRL" example="/pixiv/user/novels/27104704" path="/pixiv/user/novels/:id" :paramsDesc="['用户 id, 可在用户主页 URL 中找到']" radar="1" rssbud="1"/>
|
||||
|
||||
### 排行榜
|
||||
|
||||
<Route author="EYHN" example="/pixiv/ranking/week" path="/pixiv/ranking/:mode/:date?" :paramsDesc="['排行榜类型' ,'日期, 取值形如 `2018-4-25`']" radar="1" rssbud="1">
|
||||
|
||||
@@ -1152,6 +1152,18 @@ Type 栏目:
|
||||
|
||||
</Route>
|
||||
|
||||
## 華視
|
||||
|
||||
### 新聞
|
||||
|
||||
<Route author="miles170" example="/cts/real" path="/cts/:category" :paramsDesc="['类别']" radar="1">
|
||||
|
||||
| 即時 | 氣象 | 政治 | 國際 | 社會 | 運動 | 生活 | 財經 | 台語 | 地方 | 產業 | 綜合 | 藝文 | 娛樂 |
|
||||
| ---- | ------- | -------- | ------------- | ------- | ------ | ---- | ----- | --------- | ----- | -- | ------- | ---- | --------- |
|
||||
| real | weather | politics | international | society | sports | life | money | taiwanese | local | pr | general | arts | entertain |
|
||||
|
||||
</Route>
|
||||
|
||||
## 环球网
|
||||
|
||||
### 分类
|
||||
@@ -1364,6 +1376,18 @@ category 对应的关键词有
|
||||
|
||||
<Route author="shunf4" example="/zaobao/interactive-graphics" path="/zaobao/interactive-graphics" />
|
||||
|
||||
## 聯合新聞網
|
||||
|
||||
### 即時新聞
|
||||
|
||||
<Route author="miles170" example="/udn/news/breakingnews/99" path="/udn/news/breakingnews/:id" :paramsDesc="['类别']" radar="1">
|
||||
|
||||
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 99 |
|
||||
| -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | --- |
|
||||
| 精選 | 要聞 | 社會 | 地方 | 兩岸 | 國際 | 財經 | 運動 | 娛樂 | 生活 | 股市 | 文教 | 數位 | 不分類 |
|
||||
|
||||
</Route>
|
||||
|
||||
## 路透社
|
||||
|
||||
::: warning 迁移说明
|
||||
|
||||
+20
-12
@@ -1811,7 +1811,7 @@ jsjxy.hbut.edu.cn 证书链不全,自建 RSSHub 可设置环境变量 NODE_TLS
|
||||
|
||||
### 教务处
|
||||
|
||||
<Route author="arcosx Seiry qrzbing" example="/nuaa/jwc/tzgg" path="/nuaa/jwc/:type/:getDescription?" :paramsDesc="['分类名', '是否获取描述']" puppeteer="1">
|
||||
<Route author="arcosx Seiry qrzbing Xm798" example="/nuaa/jwc/tzgg/getDescription" path="/nuaa/jwc/:type/:getDescription?" :paramsDesc="['分类名,见下表', '是否获取全文']" puppeteer="1" radar="1">
|
||||
|
||||
| 通知公告 | 教学服务 | 教学建设 | 学生培养 | 教学资源 |
|
||||
| ---- | ---- | ---- | ---- | ---- |
|
||||
@@ -1819,9 +1819,27 @@ jsjxy.hbut.edu.cn 证书链不全,自建 RSSHub 可设置环境变量 NODE_TLS
|
||||
|
||||
</Route>
|
||||
|
||||
### 研究生院
|
||||
|
||||
<Route author="junfengP Seiry Xm798" example="/nuaa/yjsy/tzgg/getDescription" path="/nuaa/yjsy/:type/:getDescription?" :paramsDesc="['分类名,见下表', '是否获取全文']" puppeteer="1" radar="1">
|
||||
|
||||
| 通知公告 | 新闻动态 | 学术信息 | 师生风采 |
|
||||
| ---- | ---- | ---- | ---- |
|
||||
| tzgg | xwdt | xsxx | ssfc |
|
||||
|
||||
</Route>
|
||||
|
||||
### 自动化学院
|
||||
|
||||
<Route author="Xm798" example="/nuaa/cae/zhxw" path="/nuaa/cs/:type/:getDescription?" :paramsDesc="['分类名,见下表', '是否获取全文']" puppeteer="1" radar="1">
|
||||
|
||||
| 综合新闻 | 党委行政 | 人事 / 合作 | 研究生培养 | 本科生培养 | 学生工作 | 通知公告 | 学术信息 | 答辩公告 |
|
||||
| ---- | ---- | ------- | ----- | ----- | ---- | ---- | ---- | ---- |
|
||||
| zhxw | dwxz | rshz | yjs | bks | xsgz | tzgg | xsxx | dbgg |
|
||||
|
||||
### 计算机科学与技术学院
|
||||
|
||||
<Route author="LogicJake Seiry qrzbing" example="/nuaa/cs/jxdt" path="/nuaa/cs/:type/:getDescription?" :paramsDesc="['分类名', '是否获取描述']" puppeteer="1">
|
||||
<Route author="LogicJake Seiry qrzbing Xm798" example="/nuaa/cs/jxdt" path="/nuaa/cs/:type/:getDescription?" :paramsDesc="['分类名,见下表', '是否获取全文']" puppeteer="1" radar="1">
|
||||
|
||||
| 通知公告 | 热点新闻 | 学科科研 | 教学动态 | 本科生培养 | 研究生培养 | 学生工作 |
|
||||
| ---- | ---- | ---- | ---- | ----- | ----- | ---- |
|
||||
@@ -1829,16 +1847,6 @@ jsjxy.hbut.edu.cn 证书链不全,自建 RSSHub 可设置环境变量 NODE_TLS
|
||||
|
||||
</Route>
|
||||
|
||||
### 研究生院
|
||||
|
||||
<Route author="junfengP Seiry" example="/nuaa/yjsy/latest" path="/nuaa/yjsy/:type?" :paramsDesc="['分类名']"/>
|
||||
|
||||
| 最近动态 | 研院新闻 | 上级文件 | 管理文件 | 信息服务 |
|
||||
| ------ | ---- | ---- | ---- | ---- |
|
||||
| latest | yyxw | sjwj | glwj | xxfw |
|
||||
|
||||
</Route>
|
||||
|
||||
## 南京理工大学
|
||||
|
||||
### 教务处
|
||||
|
||||
@@ -45,41 +45,6 @@ module.exports = {
|
||||
},
|
||||
],
|
||||
},
|
||||
'pixiv.net': {
|
||||
_name: 'Pixiv',
|
||||
www: [
|
||||
{
|
||||
title: '用户收藏',
|
||||
docs: 'https://docs.rsshub.app/social-media.html#pixiv',
|
||||
source: '/users/:id/bookmarks/artworks',
|
||||
target: '/pixiv/user/bookmarks/:id',
|
||||
},
|
||||
{
|
||||
title: '用户动态',
|
||||
docs: 'https://docs.rsshub.app/social-media.html#pixiv',
|
||||
source: '/users/:id',
|
||||
target: '/pixiv/user/:id',
|
||||
},
|
||||
{
|
||||
title: '排行榜',
|
||||
docs: 'https://docs.rsshub.app/social-media.html#pixiv',
|
||||
source: '/ranking.php',
|
||||
target: (params, url) => `/pixiv/ranking/${new URL(url).searchParams.get('mode') || 'daily'}`,
|
||||
},
|
||||
{
|
||||
title: '关键词',
|
||||
docs: 'https://docs.rsshub.app/social-media.html#pixiv',
|
||||
source: ['/tags/:keyword', '/tags/:keyword/:type?'],
|
||||
target: (params, url) => `/pixiv/search/:keyword/${new URL(url).searchParams.get('order')}/${new URL(url).searchParams.get('mode')}`,
|
||||
},
|
||||
{
|
||||
title: '关注的新作品',
|
||||
docs: 'https://docs.rsshub.app/social-media.html#pixiv',
|
||||
source: '/bookmark_new_illust.php',
|
||||
target: '/pixiv/user/illustfollows',
|
||||
},
|
||||
],
|
||||
},
|
||||
'smzdm.com': {
|
||||
_name: '什么值得买',
|
||||
www: [
|
||||
@@ -782,37 +747,6 @@ module.exports = {
|
||||
},
|
||||
],
|
||||
},
|
||||
'qidian.com': {
|
||||
_name: '起点',
|
||||
book: [
|
||||
{
|
||||
title: '章节',
|
||||
docs: 'https://docs.rsshub.app/reading.html#qi-dian',
|
||||
source: '/info/:id',
|
||||
target: '/qidian/chapter/:id',
|
||||
},
|
||||
{
|
||||
title: '讨论区',
|
||||
docs: 'https://docs.rsshub.app/reading.html#qi-dian',
|
||||
source: '/info/:id',
|
||||
target: '/qidian/forum/:id',
|
||||
},
|
||||
],
|
||||
www: [
|
||||
{
|
||||
title: '限免',
|
||||
docs: 'https://docs.rsshub.app/reading.html#qi-dian',
|
||||
source: '/free',
|
||||
target: '/qidian/free',
|
||||
},
|
||||
{
|
||||
title: '女生限免',
|
||||
docs: 'https://docs.rsshub.app/reading.html#qi-dian',
|
||||
source: '/mm/free',
|
||||
target: '/qidian/free/mm',
|
||||
},
|
||||
],
|
||||
},
|
||||
'hackerone.com': {
|
||||
_name: 'HackerOne',
|
||||
'.': [
|
||||
|
||||
+13
-13
@@ -116,12 +116,12 @@ router.get('/mzitu/category/:category', lazyloadRouteHandler('./routes/mzitu/cat
|
||||
router.get('/mzitu/post/:id', lazyloadRouteHandler('./routes/mzitu/post'));
|
||||
router.get('/mzitu/tag/:tag', lazyloadRouteHandler('./routes/mzitu/tag'));
|
||||
|
||||
// pixiv
|
||||
router.get('/pixiv/user/bookmarks/:id', lazyloadRouteHandler('./routes/pixiv/bookmarks'));
|
||||
router.get('/pixiv/user/illustfollows', lazyloadRouteHandler('./routes/pixiv/illustfollow'));
|
||||
router.get('/pixiv/user/:id', lazyloadRouteHandler('./routes/pixiv/user'));
|
||||
router.get('/pixiv/ranking/:mode/:date?', lazyloadRouteHandler('./routes/pixiv/ranking'));
|
||||
router.get('/pixiv/search/:keyword/:order?/:mode?', lazyloadRouteHandler('./routes/pixiv/search'));
|
||||
// pixiv migrated to v2
|
||||
// router.get('/pixiv/user/bookmarks/:id', lazyloadRouteHandler('./routes/pixiv/bookmarks'));
|
||||
// router.get('/pixiv/user/illustfollows', lazyloadRouteHandler('./routes/pixiv/illustfollow'));
|
||||
// router.get('/pixiv/user/:id', lazyloadRouteHandler('./routes/pixiv/user'));
|
||||
// router.get('/pixiv/ranking/:mode/:date?', lazyloadRouteHandler('./routes/pixiv/ranking'));
|
||||
// router.get('/pixiv/search/:keyword/:order?/:mode?', lazyloadRouteHandler('./routes/pixiv/search'));
|
||||
|
||||
// pixiv-fanbox
|
||||
router.get('/fanbox/:user?', lazyloadRouteHandler('./routes/fanbox/main'));
|
||||
@@ -338,11 +338,11 @@ router.get('/mi/bbs/board/:boardId', lazyloadRouteHandler('./routes/mi/board'));
|
||||
// Keep
|
||||
// router.get('/keep/user/:id', lazyloadRouteHandler('./routes/keep/user'));
|
||||
|
||||
// 起点
|
||||
router.get('/qidian/chapter/:id', lazyloadRouteHandler('./routes/qidian/chapter'));
|
||||
router.get('/qidian/forum/:id', lazyloadRouteHandler('./routes/qidian/forum'));
|
||||
router.get('/qidian/free/:type?', lazyloadRouteHandler('./routes/qidian/free'));
|
||||
router.get('/qidian/free-next/:type?', lazyloadRouteHandler('./routes/qidian/free-next'));
|
||||
// 起点 migrated to v2
|
||||
// router.get('/qidian/chapter/:id', lazyloadRouteHandler('./routes/qidian/chapter'));
|
||||
// router.get('/qidian/forum/:id', lazyloadRouteHandler('./routes/qidian/forum'));
|
||||
// router.get('/qidian/free/:type?', lazyloadRouteHandler('./routes/qidian/free'));
|
||||
// router.get('/qidian/free-next/:type?', lazyloadRouteHandler('./routes/qidian/free-next'));
|
||||
|
||||
// 纵横
|
||||
router.get('/zongheng/chapter/:id', lazyloadRouteHandler('./routes/zongheng/chapter'));
|
||||
@@ -387,8 +387,8 @@ router.get('/xuangubao/subject/:subject_id', lazyloadRouteHandler('./routes/xuan
|
||||
// router.get('/xueqiu/hots', lazyloadRouteHandler('./routes/xueqiu/hots'));
|
||||
// router.get('/xueqiu/stock_comments/:id/:titleLength?', lazyloadRouteHandler('./routes/xueqiu/stock_comments'));
|
||||
|
||||
// Greasy Fork
|
||||
router.get('/greasyfork/:language/:domain?', lazyloadRouteHandler('./routes/greasyfork/scripts'));
|
||||
// Greasy Fork migrated to v2
|
||||
// router.get('/greasyfork/:language/:domain?', lazyloadRouteHandler('./routes/greasyfork/scripts'));
|
||||
|
||||
// Gwern Branwen
|
||||
router.get('/gwern/:category', lazyloadRouteHandler('./routes/gwern/category'));
|
||||
|
||||
@@ -85,6 +85,7 @@ module.exports = async (ctx) => {
|
||||
ctx.state.data = {
|
||||
title,
|
||||
link,
|
||||
image: 'https://www.bbc.com/favicon.ico',
|
||||
description: title,
|
||||
item: items,
|
||||
};
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
const config = require('@/config').value;
|
||||
const logger = require('@/utils/logger');
|
||||
const got = require('./pixiv-got');
|
||||
const { maskHeader } = require('./constants');
|
||||
|
||||
let token = null;
|
||||
|
||||
const authorizationInfo = {
|
||||
client_id: 'MOBrBDS8blbauoSck0ZfDbtuzpyT',
|
||||
client_secret: 'lsACyCD94FhDUtGTXi3QzcFE2uU1hqtDaKeqrdwj',
|
||||
hash_secret: '28c1fdd170a5204386cb1313c7077b34f83e4aaf4aa829ce78c231e05b0bae2c',
|
||||
};
|
||||
|
||||
const refreshToken = () =>
|
||||
got({
|
||||
method: 'post',
|
||||
url: 'https://oauth.secure.pixiv.net/auth/token',
|
||||
form: {
|
||||
...authorizationInfo,
|
||||
get_secure_url: 1,
|
||||
grant_type: 'refresh_token',
|
||||
refresh_token: config.pixiv.refreshToken,
|
||||
},
|
||||
headers: {
|
||||
...maskHeader,
|
||||
},
|
||||
responseType: 'json',
|
||||
resolveBodyOnly: true,
|
||||
}).catch((e) => {
|
||||
logger.error('Pixiv refresh token failed.');
|
||||
logger.debug(e);
|
||||
});
|
||||
|
||||
async function tickToken() {
|
||||
const result = await refreshToken();
|
||||
let expireTime;
|
||||
if (result && result.access_token) {
|
||||
logger.debug('Pixiv refresh token success.');
|
||||
token = result.access_token;
|
||||
expireTime = result.expires_in;
|
||||
} else {
|
||||
expireTime = 30;
|
||||
logger.error(`Pixiv refresh token failed, retry in ${expireTime} seconds.`);
|
||||
}
|
||||
// If is package, the mock server should be closed after request, needn't to refresh
|
||||
if (!config.isPackage) {
|
||||
setTimeout(tickToken, expireTime);
|
||||
}
|
||||
}
|
||||
|
||||
let tickTokenStarted = false;
|
||||
|
||||
async function startTickToken() {
|
||||
if (!tickTokenStarted) {
|
||||
// 如果tickToken没启动
|
||||
tickTokenStarted = true;
|
||||
await tickToken(); // 启动tickToken
|
||||
}
|
||||
}
|
||||
|
||||
async function waitForToken() {
|
||||
while (!token) {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
module.exports = async () => {
|
||||
await startTickToken();
|
||||
return waitForToken();
|
||||
};
|
||||
|
||||
module.exports.tickToken = tickToken;
|
||||
@@ -39,13 +39,12 @@ module.exports = async (ctx) => {
|
||||
.toArray()
|
||||
.map((element) => {
|
||||
const item = $(element);
|
||||
return `<img src="${item.attr('bpic').split('?tbpicau')[0]}">`;
|
||||
return `<img src="${item.attr('bpic')?.split('?tbpicau')[0]}">`;
|
||||
})
|
||||
.join('');
|
||||
|
||||
return {
|
||||
title,
|
||||
// description: `<p>${details}</p><p>${medias}</p><p>作者:${author_name}</p>`,
|
||||
description: art(path.join(__dirname, '../templates/forum.art'), {
|
||||
details,
|
||||
medias,
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
module.exports = {
|
||||
'/:category': ['miles170'],
|
||||
};
|
||||
@@ -0,0 +1,40 @@
|
||||
const got = require('@/utils/got');
|
||||
const cheerio = require('cheerio');
|
||||
const { parseDate } = require('@/utils/parse-date');
|
||||
const asyncPool = require('tiny-async-pool');
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const category = ctx.params.category;
|
||||
const currentUrl = `https://news.cts.com.tw/${category}/index.html`;
|
||||
const response = await got(currentUrl);
|
||||
const $ = cheerio.load(response.data);
|
||||
const items = [];
|
||||
for await (const data of asyncPool(5, $('#newslist-top a[title]').slice(0, ctx.query.limit ? parseInt(ctx.query.limit) : 20), (item) => {
|
||||
item = $(item);
|
||||
const link = item.attr('href');
|
||||
return ctx.cache.tryGet(link, async () => {
|
||||
const response = await got(link);
|
||||
const $ = cheerio.load(response.data);
|
||||
const author = $('.artical-content p:eq(0)').text().trim();
|
||||
$('.artical-content p:eq(0), .artical-content .flexbox').remove();
|
||||
|
||||
return {
|
||||
title: item.attr('title'),
|
||||
author,
|
||||
description: $('.artical-content').html(),
|
||||
category: $('meta[property="article:section"]').attr('content'),
|
||||
pubDate: parseDate($('meta[property="article:published_time"]').attr('content')),
|
||||
link,
|
||||
};
|
||||
});
|
||||
})) {
|
||||
items.push(data);
|
||||
}
|
||||
|
||||
ctx.state.data = {
|
||||
title: $('title').text(),
|
||||
link: currentUrl,
|
||||
description: $('meta[name="description"]').attr('content'),
|
||||
item: items,
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,13 @@
|
||||
module.exports = {
|
||||
'cts.com.tw': {
|
||||
_name: '華視',
|
||||
news: [
|
||||
{
|
||||
title: '新聞',
|
||||
docs: 'https://docs.rsshub.app/traditional-media.html#hua-shi-xin-wen',
|
||||
source: '/:category/index.html',
|
||||
target: '/cts/:category',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,3 @@
|
||||
module.exports = function (router) {
|
||||
router.get('/:category', require('./news'));
|
||||
};
|
||||
@@ -0,0 +1,3 @@
|
||||
module.exports = {
|
||||
'/:language/:domain?': ['imlonghao', 'miles170'],
|
||||
};
|
||||
@@ -0,0 +1,13 @@
|
||||
module.exports = {
|
||||
'greasyfork.org': {
|
||||
_name: 'Greasy Fork',
|
||||
'.': [
|
||||
{
|
||||
title: 'User scripts',
|
||||
docs: 'https://docs.rsshub.app/program-update.html#greasy-fork',
|
||||
source: ['/:language', '/:language/scripts/by-site/:domain?'],
|
||||
target: '/greasyfork/:language/:domain?',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,3 @@
|
||||
module.exports = (router) => {
|
||||
router.get('/:language/:domain?', require('./scripts'));
|
||||
};
|
||||
@@ -7,10 +7,10 @@ module.exports = async (ctx) => {
|
||||
const domain = ctx.params.domain;
|
||||
const filter_locale = ctx.params.language === 'all' ? 0 : 1;
|
||||
const url = domain ? `by-site/${domain}` : '';
|
||||
|
||||
const currentUrl = `https://greasyfork.org/${language}/scripts/${url}`;
|
||||
const res = await got({
|
||||
method: 'get',
|
||||
url: `https://greasyfork.org/${language}/scripts/${url}`,
|
||||
url: currentUrl,
|
||||
searchParams: queryString.stringify({
|
||||
filter_locale,
|
||||
sort: 'updated',
|
||||
@@ -21,12 +21,12 @@ module.exports = async (ctx) => {
|
||||
|
||||
ctx.state.data = {
|
||||
title: $('title').first().text(),
|
||||
link: `https://greasyfork.org/${language}/scripts/${url}`,
|
||||
link: currentUrl,
|
||||
description: $('meta[name=description]').attr('content'),
|
||||
item:
|
||||
list &&
|
||||
list
|
||||
.map((index, item) => {
|
||||
.map((_, item) => {
|
||||
item = $(item);
|
||||
return {
|
||||
title: item.find('a').text(),
|
||||
@@ -1,3 +1,4 @@
|
||||
module.exports = {
|
||||
'/news/:option?': ['axojhf'],
|
||||
'/topics/:abbr/:category?': ['axojhf'],
|
||||
};
|
||||
|
||||
@@ -3,11 +3,20 @@ module.exports = {
|
||||
_name: 'Love Live 官网',
|
||||
www: [
|
||||
{
|
||||
title: '最新NEWS',
|
||||
docs: 'https://docs.rsshub.app/anime.html#lovelive-anime',
|
||||
source: ['/'],
|
||||
title: '最新 NEWS',
|
||||
docs: 'https://docs.rsshub.app/anime.html#lovelive-anime-love-live-guan-wang-zui-xin-news',
|
||||
source: ['/', '/news'],
|
||||
target: '/lovelive-anime/news',
|
||||
},
|
||||
{
|
||||
title: '分类 Topics',
|
||||
docs: 'https://docs.rsshub.app/anime.html#lovelive-anime-love-live-guan-wang-fen-lei-topics',
|
||||
source: ['/:abbr/topics/', '/:abbr/topics.php'],
|
||||
target: (params, url) => {
|
||||
const cat = url.match(/\?cat=(.*)/);
|
||||
return `/lovelive-anime/topics/${params.abbr}/${null !== cat && cat.length === 2 ? cat[1] : ''}`;
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
module.exports = (router) => {
|
||||
router.get('/news/:option?', require('./news'));
|
||||
router.get('/topics/:abbr/:category?/:option?', require('./topics'));
|
||||
};
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
const got = require('@/utils/got');
|
||||
const cheerio = require('cheerio');
|
||||
const path = require('path');
|
||||
const { art } = require('@/utils/render');
|
||||
const { parseDate } = require('@/utils/parse-date');
|
||||
const renderDescription = (desc) => art(path.join(__dirname, 'templates/description.art'), desc);
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const abbr = ctx.params.abbr;
|
||||
const rootUrl = `https://www.lovelive-anime.jp/${abbr}`;
|
||||
const topicsUrlPart = 'yuigaoka' === abbr ? 'topics/' : 'topics.php';
|
||||
const baseUrl = `${rootUrl}/${'yuigaoka' === abbr ? 'topics/' : ''}`;
|
||||
const abbrDetail = {
|
||||
otonokizaka: 'ラブライブ!',
|
||||
uranohoshi: 'サンシャイン!!',
|
||||
nijigasaki: '虹ヶ咲学園',
|
||||
yuigaoka: 'スーパースター!!',
|
||||
};
|
||||
let url;
|
||||
|
||||
if (ctx.params.hasOwnProperty('category') && ctx.params.category !== 'detail') {
|
||||
url = `${rootUrl}/${topicsUrlPart}?cat=${ctx.params.category}`;
|
||||
} else {
|
||||
url = `${rootUrl}/${topicsUrlPart}`;
|
||||
}
|
||||
|
||||
const response = await got(url);
|
||||
|
||||
const $ = cheerio.load(response.data);
|
||||
|
||||
const categoryName = 'uranohoshi' === abbr ? $('div.llbox > p').text() : $('div.category_title > h2').text();
|
||||
|
||||
let items = $('ul.listbox > li')
|
||||
.map((_, item) => {
|
||||
item = $(item);
|
||||
|
||||
const link = `${baseUrl}${item.find('div > a').attr('href')}`;
|
||||
const pubDate = parseDate(item.find('a > p.date').text(), 'YYYY/MM/DD');
|
||||
const title = item.find('a > p.title').text();
|
||||
const category = item.find('a > p.category').text();
|
||||
const imglink = `${baseUrl}${
|
||||
item
|
||||
.find('a > img')
|
||||
.attr('style')
|
||||
.match(/background-image:url\((.*)\)/)[1]
|
||||
}`;
|
||||
|
||||
return {
|
||||
link,
|
||||
pubDate,
|
||||
title,
|
||||
category,
|
||||
description: renderDescription({
|
||||
title,
|
||||
imglink,
|
||||
}),
|
||||
};
|
||||
})
|
||||
.get();
|
||||
|
||||
if (ctx.params.option === 'detail' || ctx.params.category === 'detail') {
|
||||
items = await Promise.all(
|
||||
items.map((item) =>
|
||||
ctx.cache.tryGet(item.link, async () => {
|
||||
const detailResp = await got(item.link);
|
||||
const $ = cheerio.load(detailResp.data);
|
||||
|
||||
const content = $('div.p-page__detail.p-article');
|
||||
for (const v of content.find('img')) {
|
||||
v.attribs.src = `${baseUrl}${v.attribs.src}`;
|
||||
}
|
||||
item.description = content.html();
|
||||
return item;
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
ctx.state.data = {
|
||||
title: `${categoryName} - ${abbrDetail[abbr]} - Love Live Official Website Topics`,
|
||||
link: url,
|
||||
item: items,
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,79 @@
|
||||
const got = require('@/utils/got');
|
||||
const cheerio = require('cheerio');
|
||||
const { parseDate } = require('@/utils/parse-date');
|
||||
const getCookie = require('../utils/pypasswaf');
|
||||
const host = 'https://cae.nuaa.edu.cn/';
|
||||
|
||||
const map = new Map([
|
||||
['zhxw', { title: '综合新闻 | 南京航空航天大学自动化学院', suffix: '5399/list.htm' }],
|
||||
['dwxz', { title: '党委行政 | 南京航空航天大学自动化学院', suffix: '13266/list.htm' }],
|
||||
['rshz', { title: '人事/合作 | 南京航空航天大学自动化学院', suffix: '13267/list.htm' }],
|
||||
['yjs', { title: '研究生培养 | 南京航空航天大学自动化学院', suffix: '13271/list.htm' }],
|
||||
['bks', { title: '本科生培养 | 南京航空航天大学自动化学院', suffix: '13270/list.htm' }],
|
||||
['xsgz', { title: '学生工作 | 南京航空航天大学自动化学院', suffix: '13268/list.htm' }],
|
||||
['tzgg', { title: '通知公告 | 南京航空航天大学自动化学院', suffix: '13264/list.htm' }],
|
||||
['xsxx', { title: '学术信息 | 南京航空航天大学自动化学院', suffix: '13265/list.htm' }],
|
||||
['dbgg', { title: '答辩公告 | 南京航空航天大学自动化学院', suffix: 'dbgg/list.htm' }],
|
||||
]);
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const type = ctx.params.type;
|
||||
const suffix = map.get(type).suffix;
|
||||
const getDescription = Boolean(ctx.params.getDescription) || false;
|
||||
const link = new URL(suffix, host).href;
|
||||
const cookie = await getCookie(host);
|
||||
const gotConfig = {
|
||||
headers: {
|
||||
cookie,
|
||||
},
|
||||
};
|
||||
const response = await got(link, gotConfig);
|
||||
const $ = cheerio.load(response.data);
|
||||
|
||||
const list = $('#wp_news_w6 ul li')
|
||||
.slice(0, 10)
|
||||
.map(function () {
|
||||
const info = {
|
||||
title: $(this).find('a').text(),
|
||||
link: $(this).find('a').attr('href'),
|
||||
date: $(this).find('span').text(),
|
||||
};
|
||||
return info;
|
||||
})
|
||||
.get();
|
||||
|
||||
const out = await Promise.all(
|
||||
list.map(async (info) => {
|
||||
const title = info.title || 'tzgg';
|
||||
const date = info.date;
|
||||
const itemUrl = new URL(info.link, host).href;
|
||||
let description = title + '<br><a href="' + itemUrl + '" target="_blank">查看原文</a>';
|
||||
|
||||
if (getDescription) {
|
||||
description = await ctx.cache.tryGet(itemUrl, async () => {
|
||||
const arr = itemUrl.split('.');
|
||||
const pageType = arr[arr.length - 1];
|
||||
if (pageType === 'htm' || pageType === 'html') {
|
||||
const response = await got(itemUrl, gotConfig);
|
||||
const $ = cheerio.load(response.data);
|
||||
return $('.wp_articlecontent').html() + '<br><hr /><a href="' + itemUrl + '" target="_blank">查看原文</a>';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
title,
|
||||
link: itemUrl,
|
||||
description,
|
||||
pubDate: parseDate(date),
|
||||
};
|
||||
})
|
||||
);
|
||||
|
||||
ctx.state.data = {
|
||||
title: map.get(type).title,
|
||||
link,
|
||||
description: '南京航空航天大学自动化学院RSS',
|
||||
item: out,
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,78 @@
|
||||
const got = require('@/utils/got');
|
||||
const cheerio = require('cheerio');
|
||||
const { parseDate } = require('@/utils/parse-date');
|
||||
const getCookie = require('../utils/pypasswaf');
|
||||
const host = 'https://cs.nuaa.edu.cn/';
|
||||
|
||||
const map = new Map([
|
||||
['tzgg', { title: '通知公告 | 南京航空航天大学计算机科学与技术学院', suffix: 'tzgg/list.htm' }],
|
||||
['rdxw', { title: '热点新闻 | 南京航空航天大学计算机科学与技术学院', suffix: '10846/list.htm' }],
|
||||
['xkky', { title: '学科科研 | 南京航空航天大学计算机科学与技术学院', suffix: '10849/list.htm' }],
|
||||
['be', { title: '本科生培养 | 南京航空航天大学计算机科学与技术学院', suffix: '10850/list.htm' }],
|
||||
['me', { title: '研究生培养 | 南京航空航天大学计算机科学与技术学院', suffix: '10851/list.htm' }],
|
||||
['jxdt', { title: '教学动态 | 南京航空航天大学计算机科学与技术学院', suffix: '1977/list.htm' }],
|
||||
['xsgz', { title: '学生工作 | 南京航空航天大学计算机科学与技术学院', suffix: '1959/list.htm' }],
|
||||
]);
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const type = ctx.params.type;
|
||||
const getDescription = Boolean(ctx.params.getDescription) || false;
|
||||
const suffix = map.get(type).suffix;
|
||||
|
||||
const link = new URL(suffix, host).href;
|
||||
const cookie = await getCookie(host);
|
||||
const gotConfig = {
|
||||
headers: {
|
||||
cookie,
|
||||
},
|
||||
};
|
||||
const response = await got(link, gotConfig);
|
||||
const $ = cheerio.load(response.data);
|
||||
|
||||
const list = $('#news_list ul li')
|
||||
.slice(0, Math.min(parseInt($('.per_count', '#wp_paging_w6').text()), parseInt($('.all_count', '#wp_paging_w6').slice(1).text())))
|
||||
.map(function () {
|
||||
const info = {
|
||||
title: $(this).find('a').attr('title'),
|
||||
link: $(this).find('a').attr('href'),
|
||||
date: $(this).find('span').text(),
|
||||
};
|
||||
return info;
|
||||
})
|
||||
.get();
|
||||
|
||||
const out = await Promise.all(
|
||||
list.map(async (info) => {
|
||||
const title = info.title || 'tzgg';
|
||||
const date = info.date;
|
||||
const itemUrl = new URL(info.link, host).href;
|
||||
let description = title + '<br><a href="' + itemUrl + '" target="_blank">查看原文</a>';
|
||||
|
||||
if (getDescription) {
|
||||
description = await ctx.cache.tryGet(itemUrl, async () => {
|
||||
const arr = itemUrl.split('.');
|
||||
const pageType = arr[arr.length - 1];
|
||||
if (pageType === 'htm' || pageType === 'html') {
|
||||
const response = await got(itemUrl, gotConfig);
|
||||
const $ = cheerio.load(response.data);
|
||||
return $('.wp_articlecontent').html() + '<br><hr /><a href="' + itemUrl + '" target="_blank">查看原文</a>';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
title,
|
||||
link: itemUrl,
|
||||
description,
|
||||
pubDate: parseDate(date),
|
||||
};
|
||||
})
|
||||
);
|
||||
|
||||
ctx.state.data = {
|
||||
title: map.get(type).title,
|
||||
link,
|
||||
description: '南京航空航天大学计算机科学与技术学院RSS',
|
||||
item: out,
|
||||
};
|
||||
};
|
||||
@@ -1,87 +0,0 @@
|
||||
const got = require('@/utils/got');
|
||||
const cheerio = require('cheerio');
|
||||
const { parseDate } = require('@/utils/parse-date');
|
||||
const getCookie = require('../utils/pypasswaf');
|
||||
const host = 'http://cs.nuaa.edu.cn/';
|
||||
|
||||
const map = new Map([
|
||||
['tzgg', { title: '南京航空航天大学计算机科学与技术学院 -- 通知公告', suffix: 'tzgg/list.htm' }],
|
||||
['rdxw', { title: '南京航空航天大学计算机科学与技术学院 -- 热点新闻', suffix: '10846/list.htm' }],
|
||||
['xkky', { title: '南京航空航天大学计算机科学与技术学院 -- 学科科研', suffix: '10849/list.htm' }],
|
||||
['be', { title: '南京航空航天大学计算机科学与技术学院 -- 本科生培养', suffix: '10850/list.htm' }],
|
||||
['me', { title: '南京航空航天大学计算机科学与技术学院 -- 研究生培养', suffix: '10851/list.htm' }],
|
||||
['jxdt', { title: '南京航空航天大学计算机科学与技术学院 -- 教学动态', suffix: '1977/list.htm' }],
|
||||
['xsgz', { title: '南京航空航天大学计算机科学与技术学院 -- 学生工作', suffix: '1959/list.htm' }],
|
||||
]);
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const type = ctx.params.type;
|
||||
const getDescription = Boolean(ctx.params.getDescription) || false;
|
||||
const suffix = map.get(type).suffix;
|
||||
|
||||
const link = new URL(suffix, host).href;
|
||||
const cookie = await getCookie();
|
||||
const gotConfig = {
|
||||
headers: {
|
||||
cookie,
|
||||
},
|
||||
};
|
||||
const response = await got(link, gotConfig);
|
||||
const $ = cheerio.load(response.data);
|
||||
|
||||
const list = $('#news_list ul li')
|
||||
.slice(0, Math.min(parseInt($('.per_count', '#wp_paging_w6').text()), parseInt($('.all_count', '#wp_paging_w6').slice(1).text())))
|
||||
.map(function () {
|
||||
const info = {
|
||||
title: $(this).find('a').attr('title'),
|
||||
link: $(this).find('a').attr('href'),
|
||||
date: $(this).find('span').text(),
|
||||
};
|
||||
return info;
|
||||
})
|
||||
.get();
|
||||
|
||||
const out = await Promise.all(
|
||||
list.map((info) => {
|
||||
const title = info.title || 'tzgg';
|
||||
const date = info.date;
|
||||
const itemUrl = new URL(info.link, host).href;
|
||||
|
||||
return ctx.cache.tryGet(itemUrl, async () => {
|
||||
const arr = itemUrl.split('.');
|
||||
const pageType = arr[arr.length - 1];
|
||||
|
||||
// 南航新 WAF 过于敏感
|
||||
// 目前 description 需要遍历页面,会被 WAF 拦截导致无法输出
|
||||
// 考虑换一种获取 description 的方式或者将标题当作 title。
|
||||
let description = title;
|
||||
if (getDescription) {
|
||||
description = itemUrl;
|
||||
if (pageType === 'htm' || pageType === 'html') {
|
||||
const response = await got.get(itemUrl, gotConfig);
|
||||
const $ = cheerio.load(response.data);
|
||||
description = $('.wp_articlecontent')
|
||||
.html()
|
||||
.replace(/src="\//g, `src="${new URL('.', host).href}`)
|
||||
.trim();
|
||||
}
|
||||
}
|
||||
|
||||
const single = {
|
||||
title,
|
||||
link: itemUrl,
|
||||
description,
|
||||
pubDate: parseDate(date),
|
||||
};
|
||||
return single;
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
ctx.state.data = {
|
||||
title: map.get(type).title,
|
||||
link,
|
||||
description: '南京航空航天大学计算机科学与技术学院RSS',
|
||||
item: out,
|
||||
};
|
||||
};
|
||||
+21
-27
@@ -5,11 +5,11 @@ const getCookie = require('../utils/pypasswaf');
|
||||
const host = 'http://aao.nuaa.edu.cn/';
|
||||
|
||||
const map = new Map([
|
||||
['tzgg', { title: '南京航空航天大学教务处 -- 通知公告', suffix: '8222/list.htm' }],
|
||||
['jxfw', { title: '南京航空航天大学教务处 -- 教学服务', suffix: '8230/list.htm' }],
|
||||
['xspy', { title: '南京航空航天大学教务处 -- 学生培养', suffix: '8231/list.htm' }],
|
||||
['jxjs', { title: '南京航空航天大学教务处 -- 教学建设', suffix: '8232/list.htm' }],
|
||||
['jxzy', { title: '南京航空航天大学教务处 -- 教学资源', suffix: '8233/list.htm' }],
|
||||
['tzgg', { title: '通知公告 | 南京航空航天大学教务处', suffix: '8222/list.htm' }],
|
||||
['jxfw', { title: '教学服务 | 南京航空航天大学教务处', suffix: '8230/list.htm' }],
|
||||
['xspy', { title: '学生培养 | 南京航空航天大学教务处', suffix: '8231/list.htm' }],
|
||||
['jxjs', { title: '教学建设 | 南京航空航天大学教务处', suffix: '8232/list.htm' }],
|
||||
['jxzy', { title: '教学资源 | 南京航空航天大学教务处', suffix: '8233/list.htm' }],
|
||||
]);
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
@@ -18,7 +18,7 @@ module.exports = async (ctx) => {
|
||||
const getDescription = Boolean(ctx.params.getDescription) || false;
|
||||
|
||||
const link = new URL(suffix, host).href;
|
||||
const cookie = await getCookie();
|
||||
const cookie = await getCookie(host);
|
||||
const gotConfig = {
|
||||
headers: {
|
||||
cookie,
|
||||
@@ -40,36 +40,30 @@ module.exports = async (ctx) => {
|
||||
.get();
|
||||
|
||||
const out = await Promise.all(
|
||||
list.map((info) => {
|
||||
list.map(async (info) => {
|
||||
const title = info.title || 'tzgg';
|
||||
const date = info.date;
|
||||
const itemUrl = new URL(info.link, host).href;
|
||||
let description = title + '<br><a href="' + itemUrl + '" target="_blank">查看原文</a>';
|
||||
|
||||
return ctx.cache.tryGet(itemUrl, async () => {
|
||||
const arr = itemUrl.split('.');
|
||||
const pageType = arr[arr.length - 1];
|
||||
|
||||
// 南航新 WAF 过于敏感
|
||||
// 目前 description 需要遍历页面,会被 WAF 拦截导致无法输出
|
||||
// 考虑换一种获取 description 的方式或者将标题当作 title。
|
||||
let description = title;
|
||||
if (getDescription) {
|
||||
description = itemUrl;
|
||||
if (getDescription) {
|
||||
description = await ctx.cache.tryGet(itemUrl, async () => {
|
||||
const arr = itemUrl.split('.');
|
||||
const pageType = arr[arr.length - 1];
|
||||
if (pageType === 'htm' || pageType === 'html') {
|
||||
const response = await got(itemUrl, gotConfig);
|
||||
const $ = cheerio.load(response.data);
|
||||
description = $('.wp_articlecontent').html();
|
||||
return $('.wp_articlecontent').html() + '<br><hr /><a href="' + itemUrl + '" target="_blank">查看原文</a>';
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const single = {
|
||||
title,
|
||||
link: itemUrl,
|
||||
description,
|
||||
pubDate: parseDate(date),
|
||||
};
|
||||
return single;
|
||||
});
|
||||
return {
|
||||
title,
|
||||
link: itemUrl,
|
||||
description,
|
||||
pubDate: parseDate(date),
|
||||
};
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
module.exports = {
|
||||
'/cs/:type/:getDescription?': ['LogicJake', 'Seiry', 'qrzbing'],
|
||||
'/jwc/:type/:getDescription?': ['arcosx', 'Seiry', 'qrzbing'],
|
||||
'/yjsy/:type?': ['junfengP', 'Seiry'],
|
||||
'/cae/:type/:getDescription?': ['Xm798'],
|
||||
'/cs/:type/:getDescription?': ['LogicJake', 'Seiry', 'qrzbing', 'Xm798'],
|
||||
'/jwc/:type/:getDescription?': ['arcosx', 'Seiry', 'qrzbing', 'Xm798'],
|
||||
'/yjsy/:type/:getDescription?': ['junfengP', 'Seiry', 'Xm798'],
|
||||
};
|
||||
|
||||
@@ -7,6 +7,12 @@ module.exports = {
|
||||
docs: 'https://docs.rsshub.app/university.html#nan-jing-hang-kong-hang-tian-da-xue',
|
||||
},
|
||||
],
|
||||
cae: [
|
||||
{
|
||||
title: '自动化学院',
|
||||
docs: 'https://docs.rsshub.app/university.html#nan-jing-hang-kong-hang-tian-da-xue',
|
||||
},
|
||||
],
|
||||
cs: [
|
||||
{
|
||||
title: '计算机科学与技术学院',
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
module.exports = (router) => {
|
||||
router.get('/cs/:type/:getDescription?', require('./cs/index'));
|
||||
router.get('/cae/:type/:getDescription?', require('./college/cae'));
|
||||
router.get('/cs/:type/:getDescription?', require('./college/cs'));
|
||||
router.get('/jwc/:type/:getDescription?', require('./jwc/jwc'));
|
||||
router.get('/yjsy/:type?', require('./yjsy/yjsy'));
|
||||
router.get('/yjsy/:type/:getDescription?', require('./yjsy/yjsy'));
|
||||
};
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
const host = 'http://aao.nuaa.edu.cn/';
|
||||
|
||||
/**
|
||||
* async function 获取cookie
|
||||
* @desc 返回一个可用的cookie,使用 `got` 发起请求的时候,传入到`options.headers.cookie`即可
|
||||
*/
|
||||
module.exports = async function getCookie() {
|
||||
module.exports = async function getCookie(host) {
|
||||
const browser = await require('@/utils/puppeteer')({ stealth: true });
|
||||
const page = await browser.newPage();
|
||||
await page.setRequestInterception(true);
|
||||
|
||||
+60
-41
@@ -1,55 +1,74 @@
|
||||
const got = require('@/utils/got');
|
||||
const cheerio = require('cheerio');
|
||||
const host = 'http://www.graduate.nuaa.edu.cn/';
|
||||
const { parseDate } = require('@/utils/parse-date');
|
||||
const getCookie = require('../utils/pypasswaf');
|
||||
const host = 'http://www.graduate.nuaa.edu.cn/';
|
||||
|
||||
const map = {
|
||||
latest: '2146/list.htm',
|
||||
yyxw: 'yyxw/list.htm',
|
||||
sjwj: 'sjwj/list.htm',
|
||||
glwj: '2017/list.htm',
|
||||
xxfw: '2147/list.htm',
|
||||
};
|
||||
|
||||
const load = (link, ctx) =>
|
||||
ctx.cache.tryGet(link, async () => {
|
||||
const response = await got(host + link);
|
||||
const $ = cheerio.load(response.data);
|
||||
const images = $('img');
|
||||
for (let k = 0; k < images.length; k++) {
|
||||
$(images[k]).replaceWith(`<img src="${new URL($(images[k]).attr('src'), host).href}" />`);
|
||||
}
|
||||
const description = $('.wp_articlecontent').html();
|
||||
return { description };
|
||||
});
|
||||
const map = new Map([
|
||||
['tzgg', { title: '通知公告 | 南京航空航天大学研究生院', suffix: '2145/list.htm' }],
|
||||
['xwdt', { title: '新闻动态 | 南京航空航天大学研究生院', suffix: '13276/list.htm' }],
|
||||
['xsxx', { title: '学术信息 | 南京航空航天大学研究生院', suffix: '13277/list.htm' }],
|
||||
['ssfc', { title: '师生风采 | 南京航空航天大学研究生院', suffix: '13278/list.htm' }],
|
||||
]);
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const type = ctx.params.type ?? 'latest';
|
||||
const response = await got({
|
||||
method: 'get',
|
||||
url: host + map[type],
|
||||
});
|
||||
const type = ctx.params.type;
|
||||
const suffix = map.get(type).suffix;
|
||||
const getDescription = Boolean(ctx.params.getDescription) || false;
|
||||
const link = new URL(suffix, host).href;
|
||||
const cookie = await getCookie(host);
|
||||
const gotConfig = {
|
||||
headers: {
|
||||
cookie,
|
||||
},
|
||||
};
|
||||
const response = await got(link, gotConfig);
|
||||
const $ = cheerio.load(response.data);
|
||||
const list = $('#news_list ul.news_ul > li').slice(0, 10).get();
|
||||
const process = await Promise.all(
|
||||
list.map(async (item) => {
|
||||
const a = $(item).find('a');
|
||||
const t = $(item).find('span');
|
||||
const itemUrl = a.attr('href');
|
||||
const single = {
|
||||
title: a.text(),
|
||||
link: new URL(itemUrl, host).href,
|
||||
pubDate: parseDate(t.text(), 'YYYY-MM-DD'),
|
||||
|
||||
const list = $('#wp_news_w6 ul li')
|
||||
.slice(0, 10)
|
||||
.map(function () {
|
||||
const info = {
|
||||
title: $(this).find('a').text(),
|
||||
link: $(this).find('a').attr('href'),
|
||||
date: $(this).find('span').text(),
|
||||
};
|
||||
return info;
|
||||
})
|
||||
.get();
|
||||
|
||||
const out = await Promise.all(
|
||||
list.map(async (info) => {
|
||||
const title = info.title || 'tzgg';
|
||||
const date = info.date;
|
||||
const itemUrl = new URL(info.link, host).href;
|
||||
let description = title + '<br><a href="' + itemUrl + '" target="_blank">查看原文</a>';
|
||||
|
||||
if (getDescription) {
|
||||
description = await ctx.cache.tryGet(itemUrl, async () => {
|
||||
const arr = itemUrl.split('.');
|
||||
const pageType = arr[arr.length - 1];
|
||||
if (pageType === 'htm' || pageType === 'html') {
|
||||
const response = await got(itemUrl, gotConfig);
|
||||
const $ = cheerio.load(response.data);
|
||||
return $('.wp_articlecontent').html() + '<br><hr /><a href="' + itemUrl + '" target="_blank">查看原文</a>';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
title,
|
||||
link: itemUrl,
|
||||
description,
|
||||
pubDate: parseDate(date),
|
||||
};
|
||||
const other = await load(itemUrl, ctx);
|
||||
return { ...single, ...other };
|
||||
})
|
||||
);
|
||||
|
||||
ctx.state.data = {
|
||||
title: '南航研究生院',
|
||||
link: host,
|
||||
description: '南航研究生院RSS',
|
||||
item: process,
|
||||
title: map.get(type).title,
|
||||
link,
|
||||
description: '南京航空航天大学研究生院RSS',
|
||||
item: out,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -10,9 +10,7 @@ const queryString = require('query-string');
|
||||
* @returns {Promise<got.AxiosResponse<{illusts: illust[]}>>}
|
||||
*/
|
||||
module.exports = function getBookmarks(user_id, token) {
|
||||
return got({
|
||||
method: 'get',
|
||||
url: 'https://app-api.pixiv.net/v1/user/bookmarks/illust',
|
||||
return got('https://app-api.pixiv.net/v1/user/bookmarks/illust', {
|
||||
headers: {
|
||||
...maskHeader,
|
||||
Authorization: 'Bearer ' + token,
|
||||
@@ -8,9 +8,7 @@ const queryString = require('query-string');
|
||||
* @returns {Promise<got.AxiosResponse<{illusts: illust[]}>>}
|
||||
*/
|
||||
module.exports = function getUserIllustFollows(token) {
|
||||
return got({
|
||||
method: 'get',
|
||||
url: 'https://app-api.pixiv.net/v2/illust/follow',
|
||||
return got('https://app-api.pixiv.net/v2/illust/follow', {
|
||||
headers: {
|
||||
...maskHeader,
|
||||
Authorization: 'Bearer ' + token,
|
||||
@@ -9,9 +9,7 @@ const queryString = require('query-string');
|
||||
* @returns {Promise<got.AxiosResponse<{illusts: illust[]}>>}
|
||||
*/
|
||||
module.exports = function getIllusts(user_id, token) {
|
||||
return got({
|
||||
method: 'get',
|
||||
url: 'https://app-api.pixiv.net/v1/user/illusts',
|
||||
return got('https://app-api.pixiv.net/v1/user/illusts', {
|
||||
headers: {
|
||||
...maskHeader,
|
||||
Authorization: 'Bearer ' + token,
|
||||
@@ -14,9 +14,7 @@ const allowMode = ['day', 'week', 'month', 'day_male', 'day_female', 'week_origi
|
||||
*/
|
||||
module.exports = function getRanking(mode, date, token) {
|
||||
assert(allowMode.includes(mode), 'Mode not allow.');
|
||||
return got({
|
||||
method: 'get',
|
||||
url: 'https://app-api.pixiv.net/v1/illust/ranking',
|
||||
return got('https://app-api.pixiv.net/v1/illust/ranking', {
|
||||
headers: {
|
||||
...maskHeader,
|
||||
Authorization: 'Bearer ' + token,
|
||||
@@ -15,9 +15,7 @@ const queryString = require('query-string');
|
||||
* @returns {Promise<got.AxiosResponse<userDetail>>}
|
||||
*/
|
||||
module.exports = function getUserDetail(user_id, token) {
|
||||
return got({
|
||||
method: 'get',
|
||||
url: 'https://app-api.pixiv.net/v1/user/detail',
|
||||
return got('https://app-api.pixiv.net/v1/user/detail', {
|
||||
headers: {
|
||||
...maskHeader,
|
||||
Authorization: 'Bearer ' + token,
|
||||
@@ -9,9 +9,7 @@ const queryString = require('query-string');
|
||||
* @returns {Promise<got.AxiosResponse<{illusts: illust[]}>>}
|
||||
*/
|
||||
module.exports = function searchIllust(keyword, token) {
|
||||
return got({
|
||||
method: 'get',
|
||||
url: 'https://app-api.pixiv.net/v1/search/illust',
|
||||
return got('https://app-api.pixiv.net/v1/search/illust', {
|
||||
headers: {
|
||||
...maskHeader,
|
||||
Authorization: 'Bearer ' + token,
|
||||
+1
-3
@@ -9,9 +9,7 @@ const queryString = require('query-string');
|
||||
* @returns {Promise<got.AxiosResponse<{illusts: illust[]}>>}
|
||||
*/
|
||||
module.exports = function searchPopularIllust(keyword, token) {
|
||||
return got({
|
||||
method: 'get',
|
||||
url: 'https://app-api.pixiv.net/v1/search/popular-preview/illust',
|
||||
return got('https://app-api.pixiv.net/v1/search/popular-preview/illust', {
|
||||
headers: {
|
||||
...maskHeader,
|
||||
Authorization: 'Bearer ' + token,
|
||||
@@ -1,8 +1,9 @@
|
||||
const getToken = require('./token');
|
||||
const { getToken } = require('./token');
|
||||
const getBookmarks = require('./api/getBookmarks');
|
||||
const getUserDetail = require('./api/getUserDetail');
|
||||
const config = require('@/config').value;
|
||||
const pixivUtils = require('./utils');
|
||||
const { parseDate } = require('@/utils/parse-date');
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
if (!config.pixiv || !config.pixiv.refreshToken) {
|
||||
@@ -11,7 +12,7 @@ module.exports = async (ctx) => {
|
||||
|
||||
const id = ctx.params.id;
|
||||
|
||||
const token = await getToken();
|
||||
const token = await getToken(ctx.cache.tryGet);
|
||||
if (!token) {
|
||||
throw 'pixiv not login';
|
||||
}
|
||||
@@ -30,7 +31,7 @@ module.exports = async (ctx) => {
|
||||
return {
|
||||
title: illust.title,
|
||||
author: illust.user.name,
|
||||
pubDate: new Date(illust.create_date).toUTCString(),
|
||||
pubDate: parseDate(illust.create_date),
|
||||
description: `<p>画师:${illust.user.name} - 阅览数:${illust.total_view} - 收藏数:${illust.total_bookmarks}</p>${images.join('')}`,
|
||||
link: `https://www.pixiv.net/artworks/${illust.id}`,
|
||||
};
|
||||
@@ -1,15 +1,16 @@
|
||||
const getToken = require('./token');
|
||||
const { getToken } = require('./token');
|
||||
const getIllustFollows = require('./api/getIllustFollows');
|
||||
const config = require('@/config').value;
|
||||
const pixivUtils = require('./utils');
|
||||
const { parseDate } = require('@/utils/parse-date');
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
if (!config.pixiv || !config.pixiv.refreshToken) {
|
||||
throw 'pixiv RSS is disabled due to the lack of <a href="https://docs.rsshub.app/install/#pei-zhi-bu-fen-rss-mo-kuai-pei-zhi">relevant config</a>';
|
||||
}
|
||||
|
||||
const token = await getToken();
|
||||
if (!(await getToken())) {
|
||||
const token = await getToken(ctx.cache.tryGet);
|
||||
if (!token) {
|
||||
throw 'pixiv not login';
|
||||
}
|
||||
|
||||
@@ -24,7 +25,7 @@ module.exports = async (ctx) => {
|
||||
return {
|
||||
title: illust.title,
|
||||
author: illust.user.name,
|
||||
pubDate: new Date(illust.create_date).toUTCString(),
|
||||
pubDate: parseDate(illust.create_date),
|
||||
description: `<p>画师:${illust.user.name} - 阅览数:${illust.total_view} - 收藏数:${illust.total_bookmarks}</p>${images.join('')}`,
|
||||
link: `https://www.pixiv.net/artworks/${illust.id}`,
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
module.exports = {
|
||||
'/ranking/:mode/:date?': ['EYHN'],
|
||||
'/search/:keyword/:order?/:mode?': ['DIYgod'],
|
||||
'/user/bookmarks/:id': ['EYHN'],
|
||||
'/user/illustfollows': ['ClarkeCheng'],
|
||||
'/user/novels/:id': ['TonyRL'],
|
||||
'/user/:id': ['DIYgod'],
|
||||
};
|
||||
@@ -0,0 +1,35 @@
|
||||
const got = require('@/utils/got');
|
||||
const { parseDate } = require('@/utils/parse-date');
|
||||
const baseUrl = 'https://www.pixiv.net';
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const { id } = ctx.params;
|
||||
const { data } = await got(`${baseUrl}/ajax/user/${id}/profile/all`);
|
||||
|
||||
const items = [
|
||||
...data.body.novelSeries.map((item) => ({
|
||||
title: item.title,
|
||||
description: item.caption,
|
||||
link: `https://www.pixiv.net/novel/series/${item.id}`,
|
||||
author: item.userName,
|
||||
pubDate: parseDate(item.createDate),
|
||||
updated: parseDate(item.updateDate),
|
||||
category: item.tags,
|
||||
})),
|
||||
...data.body.pickup.map((item) => ({
|
||||
title: item.title,
|
||||
description: item.description,
|
||||
link: item.contentUrl,
|
||||
author: item.userName,
|
||||
pubDate: parseDate(item.createDate),
|
||||
updated: parseDate(item.updateDate),
|
||||
category: item.tags,
|
||||
})),
|
||||
];
|
||||
|
||||
ctx.state.data = {
|
||||
title: `${data.body.novelSeries[0].userName || data.body.pickup[0].userName} 的小说`,
|
||||
link: `${baseUrl}/users/${id}/novels`,
|
||||
item: items,
|
||||
};
|
||||
};
|
||||
@@ -6,7 +6,7 @@ const pixivConfig = require('@/config').value.pixiv;
|
||||
|
||||
async function dohResolve(name, jsonDohEndpoint) {
|
||||
try {
|
||||
const response = await got.get(jsonDohEndpoint, {
|
||||
const response = await got(jsonDohEndpoint, {
|
||||
searchParams: {
|
||||
name,
|
||||
type: 'A',
|
||||
@@ -0,0 +1,43 @@
|
||||
module.exports = {
|
||||
'pixiv.net': {
|
||||
_name: 'Pixiv',
|
||||
www: [
|
||||
{
|
||||
title: '用户收藏',
|
||||
docs: 'https://docs.rsshub.app/social-media.html#pixiv',
|
||||
source: '/users/:id/bookmarks/artworks',
|
||||
target: '/pixiv/user/bookmarks/:id',
|
||||
},
|
||||
{
|
||||
title: '用户动态',
|
||||
docs: 'https://docs.rsshub.app/social-media.html#pixiv',
|
||||
source: '/users/:id',
|
||||
target: '/pixiv/user/:id',
|
||||
},
|
||||
{
|
||||
title: '用户小说',
|
||||
docs: 'https://docs.rsshub.app/social-media.html#pixiv',
|
||||
source: '/users/:id/novels',
|
||||
target: '/pixiv/user/novels/:id',
|
||||
},
|
||||
{
|
||||
title: '排行榜',
|
||||
docs: 'https://docs.rsshub.app/social-media.html#pixiv',
|
||||
source: '/ranking.php',
|
||||
target: (params, url) => `/pixiv/ranking/${new URL(url).searchParams.get('mode') || 'daily'}`,
|
||||
},
|
||||
{
|
||||
title: '关键词',
|
||||
docs: 'https://docs.rsshub.app/social-media.html#pixiv',
|
||||
source: ['/tags/:keyword', '/tags/:keyword/:type?'],
|
||||
target: (params, url) => `/pixiv/search/:keyword/${new URL(url).searchParams.get('order')}/${new URL(url).searchParams.get('mode')}`,
|
||||
},
|
||||
{
|
||||
title: '关注的新作品',
|
||||
docs: 'https://docs.rsshub.app/social-media.html#pixiv',
|
||||
source: '/bookmark_new_illust.php',
|
||||
target: '/pixiv/user/illustfollows',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
@@ -1,7 +1,8 @@
|
||||
const getToken = require('./token');
|
||||
const { getToken } = require('./token');
|
||||
const getRanking = require('./api/getRanking');
|
||||
const config = require('@/config').value;
|
||||
const pixivUtils = require('./utils');
|
||||
const { parseDate } = require('@/utils/parse-date');
|
||||
|
||||
const titles = {
|
||||
day: 'pixiv 日排行',
|
||||
@@ -56,7 +57,7 @@ module.exports = async (ctx) => {
|
||||
const mode = alias[ctx.params.mode] ? alias[ctx.params.mode] : ctx.params.mode;
|
||||
const date = ctx.params.date ? new Date(ctx.params.date) : new Date();
|
||||
|
||||
const token = await getToken();
|
||||
const token = await getToken(ctx.cache.tryGet);
|
||||
if (!token) {
|
||||
throw 'pixiv not login';
|
||||
}
|
||||
@@ -75,7 +76,7 @@ module.exports = async (ctx) => {
|
||||
const images = pixivUtils.getImgs(illust);
|
||||
return {
|
||||
title: `#${index + 1} ${illust.title}`,
|
||||
pubDate: new Date(illust.create_date).toUTCString(),
|
||||
pubDate: parseDate(illust.create_date),
|
||||
description: `<p>画师:${illust.user.name} - 阅览数:${illust.total_view} - 收藏数:${illust.total_bookmarks}</p><br>${images.join('')}`,
|
||||
link: `https://www.pixiv.net/artworks/${illust.id}`,
|
||||
author: illust.user.name,
|
||||
@@ -0,0 +1,8 @@
|
||||
module.exports = (router) => {
|
||||
router.get('/ranking/:mode/:date?', require('./ranking'));
|
||||
router.get('/search/:keyword/:order?/:mode?', require('./search'));
|
||||
router.get('/user/bookmarks/:id', require('./bookmarks'));
|
||||
router.get('/user/illustfollows', require('./illustfollow'));
|
||||
router.get('/user/novels/:id', require('./novels'));
|
||||
router.get('/user/:id', require('./user'));
|
||||
};
|
||||
@@ -1,8 +1,9 @@
|
||||
const getToken = require('./token');
|
||||
const { getToken } = require('./token');
|
||||
const searchPopularIllust = require('./api/searchPopularIllust');
|
||||
const searchIllust = require('./api/searchIllust');
|
||||
const config = require('@/config').value;
|
||||
const pixivUtils = require('./utils');
|
||||
const { parseDate } = require('@/utils/parse-date');
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
if (!config.pixiv || !config.pixiv.refreshToken) {
|
||||
@@ -13,7 +14,7 @@ module.exports = async (ctx) => {
|
||||
const order = ctx.params.order || 'date';
|
||||
const mode = ctx.params.mode;
|
||||
|
||||
const token = await getToken();
|
||||
const token = await getToken(ctx.cache.tryGet);
|
||||
if (!token) {
|
||||
throw 'pixiv not login';
|
||||
}
|
||||
@@ -40,7 +41,7 @@ module.exports = async (ctx) => {
|
||||
return {
|
||||
title: illust.title,
|
||||
author: illust.user.name,
|
||||
pubDate: new Date(illust.create_date).toUTCString(),
|
||||
pubDate: parseDate(illust.create_date),
|
||||
description: `<p>画师:${illust.user.name} - 阅览数:${illust.total_view} - 收藏数:${illust.total_bookmarks}</p>${images.join('')}`,
|
||||
link: `https://www.pixiv.net/artworks/${illust.id}`,
|
||||
};
|
||||
@@ -0,0 +1,86 @@
|
||||
const config = require('@/config').value;
|
||||
const logger = require('@/utils/logger');
|
||||
const got = require('./pixiv-got');
|
||||
const { maskHeader } = require('./constants');
|
||||
|
||||
let token = null;
|
||||
|
||||
const authorizationInfo = {
|
||||
client_id: 'MOBrBDS8blbauoSck0ZfDbtuzpyT',
|
||||
client_secret: 'lsACyCD94FhDUtGTXi3QzcFE2uU1hqtDaKeqrdwj',
|
||||
hash_secret: '28c1fdd170a5204386cb1313c7077b34f83e4aaf4aa829ce78c231e05b0bae2c',
|
||||
};
|
||||
|
||||
const refreshToken = (tryGet) =>
|
||||
tryGet(
|
||||
'pixiv:accessToken',
|
||||
() =>
|
||||
got
|
||||
.post('https://oauth.secure.pixiv.net/auth/token', {
|
||||
form: {
|
||||
...authorizationInfo,
|
||||
get_secure_url: 1,
|
||||
grant_type: 'refresh_token',
|
||||
refresh_token: config.pixiv.refreshToken,
|
||||
},
|
||||
headers: {
|
||||
...maskHeader,
|
||||
},
|
||||
responseType: 'json',
|
||||
resolveBodyOnly: true,
|
||||
})
|
||||
.catch((e) => {
|
||||
logger.error('Pixiv refresh token failed.');
|
||||
logger.error(e);
|
||||
}),
|
||||
3600,
|
||||
false
|
||||
);
|
||||
|
||||
async function getToken(tryGet) {
|
||||
const result = await refreshToken(tryGet);
|
||||
// let expireTime;
|
||||
if (result && result.access_token) {
|
||||
logger.debug('Pixiv refresh token success.');
|
||||
token = result.access_token;
|
||||
// expireTime = result.expires_in;
|
||||
}
|
||||
// } else {
|
||||
// expireTime = 30;
|
||||
// logger.error(`Pixiv refresh token failed, retry in ${expireTime} seconds.`);
|
||||
// }
|
||||
// If is package, the mock server should be closed after request, needn't to refresh
|
||||
// if (!config.isPackage) {
|
||||
// setTimeout(tickToken, expireTime * 1000);
|
||||
// }
|
||||
return token;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getToken,
|
||||
};
|
||||
|
||||
// let tickTokenStarted = false;
|
||||
|
||||
// async function startTickToken(tryGet) {
|
||||
// if (!tickTokenStarted) {
|
||||
// // 如果tickToken没启动
|
||||
// tickTokenStarted = true;
|
||||
// await tickToken(tryGet); // 启动tickToken
|
||||
// }
|
||||
// }
|
||||
|
||||
// async function waitForToken() {
|
||||
// while (!token) {
|
||||
// // eslint-disable-next-line no-await-in-loop
|
||||
// await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
// }
|
||||
// return token;
|
||||
// }
|
||||
|
||||
// module.exports = async (tryGet) => {
|
||||
// await startTickToken(tryGet);
|
||||
// return waitForToken();
|
||||
// };
|
||||
|
||||
// module.exports.tickToken = tickToken;
|
||||
@@ -1,7 +1,8 @@
|
||||
const getToken = require('./token');
|
||||
const { getToken } = require('./token');
|
||||
const getIllusts = require('./api/getIllusts');
|
||||
const config = require('@/config').value;
|
||||
const pixivUtils = require('./utils');
|
||||
const { parseDate } = require('@/utils/parse-date');
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
if (!config.pixiv || !config.pixiv.refreshToken) {
|
||||
@@ -9,7 +10,7 @@ module.exports = async (ctx) => {
|
||||
}
|
||||
|
||||
const id = ctx.params.id;
|
||||
const token = await getToken();
|
||||
const token = await getToken(ctx.cache.tryGet);
|
||||
if (!token) {
|
||||
throw 'pixiv not login';
|
||||
}
|
||||
@@ -28,7 +29,7 @@ module.exports = async (ctx) => {
|
||||
return {
|
||||
title: illust.title,
|
||||
author: username,
|
||||
pubDate: new Date(illust.create_date).toUTCString(),
|
||||
pubDate: parseDate(illust.create_date),
|
||||
description: `<p>画师:${username} - 阅览数:${illust.total_view} - 收藏数:${illust.total_bookmarks}</p>${images.join('')}`,
|
||||
link: `https://www.pixiv.net/artworks/${illust.id}`,
|
||||
};
|
||||
@@ -0,0 +1,41 @@
|
||||
const got = require('@/utils/got');
|
||||
const cheerio = require('cheerio');
|
||||
const { parseDate, parseRelativeDate } = require('@/utils/parse-date');
|
||||
const { art } = require('@/utils/render');
|
||||
const path = require('path');
|
||||
const timezone = require('@/utils/timezone');
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const id = ctx.params.id;
|
||||
const rootUrl = 'https://my.qidian.com';
|
||||
const currentUrl = `${rootUrl}/author/${id}/`;
|
||||
const response = await got(currentUrl);
|
||||
const $ = cheerio.load(response.data);
|
||||
const authorName = $('.header-msg h1').contents().first().text().trim();
|
||||
const items = $('.author-work .author-item')
|
||||
.toArray()
|
||||
.map((item) => {
|
||||
item = $(item);
|
||||
const messageItem = item.find('.author-item-msg');
|
||||
const updatedDate = messageItem.find('.author-item-update span').text().replace('·', '').trim();
|
||||
|
||||
return {
|
||||
title: messageItem.find('.author-item-title').text().trim(),
|
||||
author: authorName,
|
||||
category: messageItem.find('.author-item-exp a').first().text().trim(),
|
||||
description: art(path.join(__dirname, 'templates/description.art'), {
|
||||
description: messageItem.find('.author-item-update a').attr('title'),
|
||||
image: item.find('a img').attr('src'),
|
||||
}),
|
||||
pubDate: timezone(/(今|昨)/.test(updatedDate) ? parseRelativeDate(updatedDate) : parseDate(updatedDate, 'YYYY-MM-DD HH:mm'), +8),
|
||||
link: messageItem.find('.author-item-update a').attr('href'),
|
||||
};
|
||||
});
|
||||
|
||||
ctx.state.data = {
|
||||
title: `${authorName} - 起点中文网`,
|
||||
description: $('.header-msg-desc').text().trim(),
|
||||
link: currentUrl,
|
||||
item: items,
|
||||
};
|
||||
};
|
||||
@@ -1,13 +1,11 @@
|
||||
const got = require('@/utils/got');
|
||||
const cheerio = require('cheerio');
|
||||
const { parseDate } = require('@/utils/parse-date');
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const id = ctx.params.id;
|
||||
|
||||
const response = await got({
|
||||
method: 'get',
|
||||
url: `https://book.qidian.com/info/${id}#Catalog`,
|
||||
});
|
||||
const response = await got(`https://book.qidian.com/info/${id}/#Catalog`);
|
||||
const $ = cheerio.load(response.data);
|
||||
|
||||
const name = $('.book-info>h1>em').text();
|
||||
@@ -15,10 +13,7 @@ module.exports = async (ctx) => {
|
||||
|
||||
const csrfToken = response.headers['set-cookie'].find((s) => s.startsWith('_csrfToken=')).split(';')[0];
|
||||
|
||||
const chapters_response = await got({
|
||||
method: 'get',
|
||||
url: `https://book.qidian.com/ajax/book/category?${csrfToken}&bookId=${id}`,
|
||||
});
|
||||
const chapters_response = await got(`https://book.qidian.com/ajax/book/category?${csrfToken}&bookId=${id}`);
|
||||
const chapter_item = [];
|
||||
|
||||
for (let i = 0; i < chapters_response.data.data.vs.length; i++) {
|
||||
@@ -27,7 +22,7 @@ module.exports = async (ctx) => {
|
||||
const chapter = chapters[j];
|
||||
chapter_item.push({
|
||||
title: chapter.cN,
|
||||
pubDate: new Date(chapter.uT).toUTCString(),
|
||||
pubDate: parseDate(chapter.uT),
|
||||
link: `https://vipreader.qidian.com/chapter/${id}/${chapter.id}`,
|
||||
});
|
||||
}
|
||||
@@ -7,9 +7,7 @@ module.exports = async (ctx) => {
|
||||
|
||||
const url = `https://forum.qidian.com/NewForum/List.aspx?BookId=${id}`;
|
||||
|
||||
const forum_response = await got({
|
||||
method: 'get',
|
||||
url,
|
||||
const forum_response = await got(url, {
|
||||
headers: {
|
||||
Referer: `https://book.qidian.com/info/${id}`,
|
||||
},
|
||||
@@ -13,10 +13,7 @@ module.exports = async (ctx) => {
|
||||
title = '起点中文网';
|
||||
}
|
||||
|
||||
const response = await got({
|
||||
method: 'get',
|
||||
url: link,
|
||||
});
|
||||
const response = await got(link);
|
||||
const $ = cheerio.load(response.data);
|
||||
|
||||
const list = $('div.other-rec-wrap li');
|
||||
@@ -1,5 +1,6 @@
|
||||
const got = require('@/utils/got');
|
||||
const cheerio = require('cheerio');
|
||||
const parseDate = require('@/utils/date');
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const type = ctx.params.type;
|
||||
@@ -13,10 +14,7 @@ module.exports = async (ctx) => {
|
||||
title = '起点中文网';
|
||||
}
|
||||
|
||||
const response = await got({
|
||||
method: 'get',
|
||||
url: link,
|
||||
});
|
||||
const response = await got(link);
|
||||
const $ = cheerio.load(response.data);
|
||||
|
||||
const list = $('#limit-list li');
|
||||
@@ -31,7 +29,7 @@ module.exports = async (ctx) => {
|
||||
return {
|
||||
title: item.find('.book-mid-info h4 a').text(),
|
||||
description: img + rank + update + '<br>' + item.find('p.intro').html(),
|
||||
pubDate: new Date(item.find('p.update span').text()).toUTCString(),
|
||||
pubDate: parseDate(item.find('p.update span').text()),
|
||||
link: 'https:' + item.find('.book-mid-info h4 a').attr('href'),
|
||||
author: item.find('p.author a.name').text(),
|
||||
};
|
||||
@@ -0,0 +1,7 @@
|
||||
module.exports = {
|
||||
'/author/:id': ['miles170'],
|
||||
'/chapter/:id': ['Chingyat'],
|
||||
'/forum/:id': ['Chingyat'],
|
||||
'/free/:type?': ['LogicJake'],
|
||||
'/free-next/:type?': ['LogicJake'],
|
||||
};
|
||||
@@ -0,0 +1,41 @@
|
||||
module.exports = {
|
||||
'qidian.com': {
|
||||
_name: '起点',
|
||||
book: [
|
||||
{
|
||||
title: '章节',
|
||||
docs: 'https://docs.rsshub.app/reading.html#qi-dian',
|
||||
source: '/info/:id',
|
||||
target: '/qidian/chapter/:id',
|
||||
},
|
||||
{
|
||||
title: '讨论区',
|
||||
docs: 'https://docs.rsshub.app/reading.html#qi-dian',
|
||||
source: '/info/:id',
|
||||
target: '/qidian/forum/:id',
|
||||
},
|
||||
],
|
||||
my: [
|
||||
{
|
||||
title: '作者',
|
||||
docs: 'https://docs.rsshub.app/reading.html#qi-dian',
|
||||
source: '/author/:id',
|
||||
target: '/qidian/author/:id',
|
||||
},
|
||||
],
|
||||
www: [
|
||||
{
|
||||
title: '限免',
|
||||
docs: 'https://docs.rsshub.app/reading.html#qi-dian',
|
||||
source: '/free',
|
||||
target: '/qidian/free',
|
||||
},
|
||||
{
|
||||
title: '女生限免',
|
||||
docs: 'https://docs.rsshub.app/reading.html#qi-dian',
|
||||
source: '/mm/free',
|
||||
target: '/qidian/free/mm',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,7 @@
|
||||
module.exports = (router) => {
|
||||
router.get('/author/:id', require('./author'));
|
||||
router.get('/chapter/:id', require('./chapter'));
|
||||
router.get('/forum/:id', require('./forum'));
|
||||
router.get('/free/:type?', require('./free'));
|
||||
router.get('/free-next/:type?', require('./free-next'));
|
||||
};
|
||||
@@ -0,0 +1,5 @@
|
||||
<p>{{ description }}</p>
|
||||
{{ if image }}
|
||||
<img src="{{ image }}">
|
||||
{{ /if }}
|
||||
{{ author }}
|
||||
@@ -0,0 +1,85 @@
|
||||
const got = require('@/utils/got');
|
||||
const { parseDate } = require('@/utils/parse-date');
|
||||
const timezone = require('@/utils/timezone');
|
||||
const cheerio = require('cheerio');
|
||||
const { art } = require('@/utils/render');
|
||||
const path = require('path');
|
||||
|
||||
module.exports = async (ctx) => {
|
||||
const id = ctx.params.id;
|
||||
const link = `/news/breaknews/1/${id}#breaknews`;
|
||||
const name = await getLinkName(ctx, link);
|
||||
const rootUrl = 'https://udn.com';
|
||||
const response = await got(`${rootUrl}/api/more?page=1&channelId=1&cate_id=${id}&type=breaknews`);
|
||||
const items = await Promise.all(
|
||||
response.data.lists.map((item) => {
|
||||
let link = item.titleLink.indexOf('http://') === 0 || item.titleLink.indexOf('https://') === 0 ? item.titleLink : `${rootUrl}${item.titleLink}`;
|
||||
const linkUrl = new URL(link);
|
||||
// cleanup query paramter
|
||||
linkUrl.query = linkUrl.search = '';
|
||||
link = linkUrl.toString();
|
||||
return ctx.cache.tryGet(link, async () => {
|
||||
let result = await got(link);
|
||||
// VIP article requires redirection
|
||||
// e.g. https://udn.com/news/story/7331/6576320
|
||||
const vip = result.data.match(/<script language=javascript>window\.location\.href="(https?:\/\/[^"]+")/);
|
||||
if (vip) {
|
||||
result = await got(vip[1]);
|
||||
}
|
||||
const $ = cheerio.load(result.data);
|
||||
const metadata = $('script[type="application/ld+json"]').eq(0).text().trim();
|
||||
const data = metadata.startsWith('[') ? JSON.parse(metadata)[0] : JSON.parse(metadata);
|
||||
// e.g. https://udn.com/news/story/7331/6576320
|
||||
const content = $('.article-content__editor');
|
||||
// e.g. https://udn.com/news/story/7240/6576424
|
||||
const body = $('.article-body__editor');
|
||||
let description = '';
|
||||
if (data.image) {
|
||||
description += art(path.join(__dirname, 'templates/figure.art'), {
|
||||
src: data.image.contentUrl,
|
||||
alt: data.image.name,
|
||||
});
|
||||
}
|
||||
if (content.length) {
|
||||
description += content.html();
|
||||
} else if (body.length) {
|
||||
description += body.html();
|
||||
}
|
||||
return {
|
||||
title: item.title,
|
||||
author: data.author.name,
|
||||
description,
|
||||
pubDate: timezone(parseDate(item.time.date, 'YYYY-MM-DD HH:mm'), +8),
|
||||
category: [data.articleSelection, ...data.keywords.split(',')],
|
||||
link,
|
||||
};
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
ctx.state.data = {
|
||||
title: `即時${name} - 聯合新聞網`,
|
||||
link: `${rootUrl}${link}`,
|
||||
description: 'udn.com 提供即時新聞以及豐富的政治、社會、地方、兩岸、國際、財經、數位、運動、NBA、娛樂、生活、健康、旅遊新聞,以最即時、多元的內容,滿足行動世代的需求',
|
||||
item: items,
|
||||
};
|
||||
};
|
||||
|
||||
const getLinkName = async (ctx, link) => {
|
||||
const url = 'https://udn.com/news/breaknews';
|
||||
const links = await ctx.cache.tryGet(url, async () => {
|
||||
const result = await got(url);
|
||||
const $ = cheerio.load(result.data);
|
||||
const data = $('.cate-list__subheader a')
|
||||
.get()
|
||||
.map((item) => {
|
||||
item = $(item);
|
||||
return { [item.attr('href')]: item.text().trim() };
|
||||
});
|
||||
return Object.assign({}, ...data);
|
||||
});
|
||||
if (link in links) {
|
||||
return links[link];
|
||||
}
|
||||
return '列表';
|
||||
};
|
||||
@@ -0,0 +1,3 @@
|
||||
module.exports = {
|
||||
'/news/breakingnews/:id': ['miles170'],
|
||||
};
|
||||
@@ -0,0 +1,13 @@
|
||||
module.exports = {
|
||||
'udn.com': {
|
||||
_name: '聯合新聞網',
|
||||
'.': [
|
||||
{
|
||||
title: '即時新聞',
|
||||
docs: 'https://docs.rsshub.app/new-media.html#lian-he-xin-wen-wang-ji-shi-xin-wen',
|
||||
source: '/news/breaknews/1/:id',
|
||||
target: '/udn/news/breakingnews/:id',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,3 @@
|
||||
module.exports = (router) => {
|
||||
router.get('/news/breakingnews/:id', require('./breaking-news'));
|
||||
};
|
||||
@@ -0,0 +1,4 @@
|
||||
<figure>
|
||||
<picture><img src={{ src }} alt={{ alt }}></picture>
|
||||
<figurecaption>{{ alt }}</figurecaption>
|
||||
</figure>
|
||||
@@ -31,6 +31,7 @@ module.exports = async (ctx) => {
|
||||
ctx.state.json = {
|
||||
title: response.data.title,
|
||||
link: response.data.feed_url,
|
||||
image: 'https://mp.weixin.qq.com/favicon.ico',
|
||||
description: response.data.title,
|
||||
item: items,
|
||||
};
|
||||
|
||||
+4
-3
@@ -49,12 +49,13 @@
|
||||
"@vuepress/plugin-pwa": "1.9.7",
|
||||
"@vuepress/shared-utils": "1.9.7",
|
||||
"cross-env": "7.0.3",
|
||||
"eslint": "8.22.0",
|
||||
"eslint": "8.23.0",
|
||||
"eslint-config-prettier": "8.5.0",
|
||||
"eslint-plugin-prettier": "4.2.1",
|
||||
"eslint-plugin-yml": "1.1.0",
|
||||
"fs-extra": "10.1.0",
|
||||
"jest": "29.0.1",
|
||||
"meilisearch": "0.27.0",
|
||||
"mockdate": "3.0.5",
|
||||
"nock": "13.2.9",
|
||||
"nodemon": "2.0.19",
|
||||
@@ -91,7 +92,7 @@
|
||||
"crypto-js": "4.1.1",
|
||||
"currency-symbol-map": "5.1.0",
|
||||
"dayjs": "1.11.5",
|
||||
"dotenv": "16.0.1",
|
||||
"dotenv": "16.0.2",
|
||||
"emailjs-imap-client": "3.1.0",
|
||||
"entities": "3.0.1",
|
||||
"etag": "1.8.1",
|
||||
@@ -124,7 +125,7 @@
|
||||
"puppeteer-extra": "3.3.4",
|
||||
"puppeteer-extra-plugin-stealth": "2.11.1",
|
||||
"query-string": "7.1.1",
|
||||
"rand-user-agent": "1.0.78",
|
||||
"rand-user-agent": "1.0.79",
|
||||
"re2": "1.17.7",
|
||||
"require-all": "3.0.0",
|
||||
"rss-parser": "3.12.0",
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
const { MeiliSearch } = require('meilisearch');
|
||||
|
||||
module.exports = async ({ core }, host, apiKey) => {
|
||||
const client = new MeiliSearch({
|
||||
host,
|
||||
apiKey,
|
||||
});
|
||||
core.info('Updating displayed attributes');
|
||||
core.info(
|
||||
await client
|
||||
.index('rsshub')
|
||||
.updateDisplayedAttributes([
|
||||
'hierarchy_radio_lvl1',
|
||||
'hierarchy_radio_lvl2',
|
||||
'hierarchy_radio_lvl3',
|
||||
'hierarchy_radio_lvl4',
|
||||
'hierarchy_radio_lvl5',
|
||||
'hierarchy_lvl0',
|
||||
'hierarchy_lvl1',
|
||||
'hierarchy_lvl2',
|
||||
'hierarchy_lvl3',
|
||||
'hierarchy_lvl4',
|
||||
'hierarchy_lvl5',
|
||||
'hierarchy_lvl6',
|
||||
'anchor',
|
||||
'url',
|
||||
'content',
|
||||
])
|
||||
);
|
||||
|
||||
core.info('Updating searchable attributes');
|
||||
core.info(
|
||||
await client
|
||||
.index('rsshub')
|
||||
.updateSearchableAttributes([
|
||||
'hierarchy_radio_lvl1',
|
||||
'hierarchy_radio_lvl2',
|
||||
'hierarchy_radio_lvl3',
|
||||
'hierarchy_radio_lvl4',
|
||||
'hierarchy_radio_lvl5',
|
||||
'hierarchy_lvl0',
|
||||
'hierarchy_lvl1',
|
||||
'hierarchy_lvl2',
|
||||
'hierarchy_lvl3',
|
||||
'hierarchy_lvl4',
|
||||
'hierarchy_lvl5',
|
||||
'hierarchy_lvl6',
|
||||
'anchor',
|
||||
'content',
|
||||
])
|
||||
);
|
||||
|
||||
core.info('Updating sortable attributes');
|
||||
core.info(await client.index('rsshub').updateSortableAttributes(['anchor']));
|
||||
};
|
||||
@@ -983,14 +983,14 @@
|
||||
enabled "2.0.x"
|
||||
kuler "^2.0.0"
|
||||
|
||||
"@eslint/eslintrc@^1.3.0":
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.0.tgz#29f92c30bb3e771e4a2048c95fa6855392dfac4f"
|
||||
integrity sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==
|
||||
"@eslint/eslintrc@^1.3.1":
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.1.tgz#de0807bfeffc37b964a7d0400e0c348ce5a2543d"
|
||||
integrity sha512-OhSY22oQQdw3zgPOOwdoj01l/Dzl1Z+xyUP33tkSN+aqyEhymJCcPHyXt+ylW8FSe0TfRC2VG+ROQOapD0aZSQ==
|
||||
dependencies:
|
||||
ajv "^6.12.4"
|
||||
debug "^4.3.2"
|
||||
espree "^9.3.2"
|
||||
espree "^9.4.0"
|
||||
globals "^13.15.0"
|
||||
ignore "^5.2.0"
|
||||
import-fresh "^3.2.1"
|
||||
@@ -1049,6 +1049,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz#316b0a63b91c10e53f242efb4ace5c3b34e8728d"
|
||||
integrity sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==
|
||||
|
||||
"@humanwhocodes/module-importer@^1.0.1":
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c"
|
||||
integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==
|
||||
|
||||
"@humanwhocodes/object-schema@^1.2.1":
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45"
|
||||
@@ -5218,10 +5223,10 @@ dot-prop@^5.2.0:
|
||||
dependencies:
|
||||
is-obj "^2.0.0"
|
||||
|
||||
dotenv@16.0.1:
|
||||
version "16.0.1"
|
||||
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.1.tgz#8f8f9d94876c35dac989876a5d3a82a267fdce1d"
|
||||
integrity sha512-1K6hR6wtk2FviQ4kEiSjFiH5rpzEVi8WW0x96aztHVMhEspNpc4DVOUTEHtEva5VThQ8IaBX1Pe4gSzpVVUsKQ==
|
||||
dotenv@16.0.2:
|
||||
version "16.0.2"
|
||||
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.2.tgz#0b0f8652c016a3858ef795024508cddc4bffc5bf"
|
||||
integrity sha512-JvpYKUmzQhYoIFgK2MOnF3bciIZoItIIoryihy0rIA+H4Jy0FmgyKYAHCTN98P5ybGSJcIFbh6QKeJdtZd1qhA==
|
||||
|
||||
dotenv@^6.2.0:
|
||||
version "6.2.0"
|
||||
@@ -5743,14 +5748,15 @@ eslint-visitor-keys@^3.0.0, eslint-visitor-keys@^3.3.0:
|
||||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826"
|
||||
integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==
|
||||
|
||||
eslint@8.22.0:
|
||||
version "8.22.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.22.0.tgz#78fcb044196dfa7eef30a9d65944f6f980402c48"
|
||||
integrity sha512-ci4t0sz6vSRKdmkOGmprBo6fmI4PrphDFMy5JEq/fNS0gQkJM3rLmrqcp8ipMcdobH3KtUP40KniAE9W19S4wA==
|
||||
eslint@8.23.0:
|
||||
version "8.23.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.23.0.tgz#a184918d288820179c6041bb3ddcc99ce6eea040"
|
||||
integrity sha512-pBG/XOn0MsJcKcTRLr27S5HpzQo4kLr+HjLQIyK4EiCsijDl/TB+h5uEuJU6bQ8Edvwz1XWOjpaP2qgnXGpTcA==
|
||||
dependencies:
|
||||
"@eslint/eslintrc" "^1.3.0"
|
||||
"@eslint/eslintrc" "^1.3.1"
|
||||
"@humanwhocodes/config-array" "^0.10.4"
|
||||
"@humanwhocodes/gitignore-to-minimatch" "^1.0.2"
|
||||
"@humanwhocodes/module-importer" "^1.0.1"
|
||||
ajv "^6.10.0"
|
||||
chalk "^4.0.0"
|
||||
cross-spawn "^7.0.2"
|
||||
@@ -5760,7 +5766,7 @@ eslint@8.22.0:
|
||||
eslint-scope "^7.1.1"
|
||||
eslint-utils "^3.0.0"
|
||||
eslint-visitor-keys "^3.3.0"
|
||||
espree "^9.3.3"
|
||||
espree "^9.4.0"
|
||||
esquery "^1.4.0"
|
||||
esutils "^2.0.2"
|
||||
fast-deep-equal "^3.1.3"
|
||||
@@ -5786,12 +5792,11 @@ eslint@8.22.0:
|
||||
strip-ansi "^6.0.1"
|
||||
strip-json-comments "^3.1.0"
|
||||
text-table "^0.2.0"
|
||||
v8-compile-cache "^2.0.3"
|
||||
|
||||
espree@^9.3.2, espree@^9.3.3:
|
||||
version "9.3.3"
|
||||
resolved "https://registry.yarnpkg.com/espree/-/espree-9.3.3.tgz#2dd37c4162bb05f433ad3c1a52ddf8a49dc08e9d"
|
||||
integrity sha512-ORs1Rt/uQTqUKjDdGCyrtYxbazf5umATSf/K4qxjmZHORR6HJk+2s/2Pqe+Kk49HHINC/xNIrGfgh8sZcll0ng==
|
||||
espree@^9.4.0:
|
||||
version "9.4.0"
|
||||
resolved "https://registry.yarnpkg.com/espree/-/espree-9.4.0.tgz#cd4bc3d6e9336c433265fc0aa016fc1aaf182f8a"
|
||||
integrity sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==
|
||||
dependencies:
|
||||
acorn "^8.8.0"
|
||||
acorn-jsx "^5.3.2"
|
||||
@@ -9585,7 +9590,7 @@ media-typer@0.3.0:
|
||||
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
|
||||
integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==
|
||||
|
||||
meilisearch@^0.27.0:
|
||||
meilisearch@0.27.0, meilisearch@^0.27.0:
|
||||
version "0.27.0"
|
||||
resolved "https://registry.yarnpkg.com/meilisearch/-/meilisearch-0.27.0.tgz#8bd57ddb77b975f93e054cb977b951c488ece297"
|
||||
integrity sha512-kZOZFIuSO7c6xRf+Y2/9/h6A9pl0sCl/G44X4KuaSwxGbruOZPhmxbeVEgLHBv4pUFvQ56rNVTA/2d/5GCU1YA==
|
||||
@@ -11721,10 +11726,10 @@ ramda@^0.26.1:
|
||||
resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.26.1.tgz#8d41351eb8111c55353617fc3bbffad8e4d35d06"
|
||||
integrity sha512-hLWjpy7EnsDBb0p+Z3B7rPi3GDeRG5ZtiI33kJhTt+ORCd38AbAIjB/9zRIUoeTbE/AVX5ZkU7m6bznsvrf8eQ==
|
||||
|
||||
rand-user-agent@1.0.78:
|
||||
version "1.0.78"
|
||||
resolved "https://registry.yarnpkg.com/rand-user-agent/-/rand-user-agent-1.0.78.tgz#5472e954b06ab1ef8b7b080ebc0db6fd3a9a142d"
|
||||
integrity sha512-atAfPjApMtpHK6pz+1zD1NYc8rV4ixqz4UtkYw17LSxKvOaaiLZBeUz6keJuTTNoTUjdYFZXAFBy29WHdvxwAw==
|
||||
rand-user-agent@1.0.79:
|
||||
version "1.0.79"
|
||||
resolved "https://registry.yarnpkg.com/rand-user-agent/-/rand-user-agent-1.0.79.tgz#1472d536fdced3e2e2b64cccafafc20651599d91"
|
||||
integrity sha512-M/KwE9V2ILytCmKNyg8g/ExrQspUUZcBNFbfryLyJuNcPC/x9IYy+9LEZnSio0a5Rfjv/iHXQYTSEqavL0aZrw==
|
||||
|
||||
randexp@0.4.6:
|
||||
version "0.4.6"
|
||||
@@ -14043,11 +14048,6 @@ uuid@^8.0.0, uuid@^8.3.2:
|
||||
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
|
||||
integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
|
||||
|
||||
v8-compile-cache@^2.0.3:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee"
|
||||
integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==
|
||||
|
||||
v8-to-istanbul@^9.0.1:
|
||||
version "9.0.1"
|
||||
resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz#b6f994b0b5d4ef255e17a0d17dc444a9f5132fa4"
|
||||
|
||||
Reference in New Issue
Block a user