diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
index 11a6d970d557..1e855e49533b 100644
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -2,10 +2,11 @@
// https://github.com/devcontainers/images/blob/v0.4.19/src/typescript-node/.devcontainer/devcontainer.json
{
"name": "Node.js & TypeScript",
- "image": "mcr.microsoft.com/devcontainers/typescript-node:24-bookworm",
+ "image": "mcr.microsoft.com/devcontainers/typescript-node:24-trixie",
"features": {
"ghcr.io/devcontainers/features/docker-in-docker": {
- "version": "latest"
+ "version": "latest",
+ "moby": false
},
"ghcr.io/devcontainers/features/github-cli": {
"version": "latest"
@@ -40,7 +41,7 @@
}
},
- "onCreateCommand": "sudo apt-get update && export DEBIAN_FRONTEND=noninteractive && sudo apt-get -y install --no-install-recommends ca-certificates fonts-liberation libasound2 libatk-bridge2.0-0 libatk1.0-0 libatspi2.0-0 libcairo2 libcups2 libdbus-1-3 libexpat1 libgbm1 libglib2.0-0 libnspr4 libnss3 libpango-1.0-0 libx11-6 libxcb1 libxcomposite1 libxdamage1 libxext6 libxfixes3 libxkbcommon0 libxrandr2 wget xdg-utils redis-server default-jre-headless && sudo apt-get autoremove -y && sudo apt-get clean -y && sudo rm -rf /var/lib/apt/lists/*",
+ "onCreateCommand": "sudo apt-get update && export DEBIAN_FRONTEND=noninteractive && sudo apt-get -y install --no-install-recommends ca-certificates fonts-liberation libasound2t64 libatk-bridge2.0-0t64 libatk1.0-0t64 libatspi2.0-0t64 libcairo2 libcups2t64 libdbus-1-3 libexpat1 libgbm1 libglib2.0-0t64 libnspr4 libnss3 libpango-1.0-0 libx11-6 libxcb1 libxcomposite1 libxdamage1 libxext6 libxfixes3 libxkbcommon0 libxrandr2 wget xdg-utils redis-server default-jre-headless && sudo apt-get autoremove -y && sudo apt-get clean -y && sudo rm -rf /var/lib/apt/lists/*",
"updateContentCommand": "export JAVA_HOME=/usr/lib/jvm/default-java && pnpm config set store-dir ~/.local/share/pnpm/store && pnpm i && pnpm rb && pnpx rebrowser-puppeteer browsers install chrome",
diff --git a/.dockerignore b/.dockerignore
index 8354e45cdd62..7c2ba2290604 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -1,7 +1,6 @@
# folders
.devcontainer
.github
-.husky
.idea
.idx
.vscode
diff --git a/.github/VOUCHED.td b/.github/VOUCHED.td
index 280c46e6ae89..4fa5e4986100 100644
--- a/.github/VOUCHED.td
+++ b/.github/VOUCHED.td
@@ -7,6 +7,7 @@
# - Optional platform prefix: platform:username (e.g., github:user).
# - Denounce with minus prefix: -username or -platform:username.
# - Optional details after a space following the handle.
+-an-lee impersonate as enpitsulin and DIYgod in #22205, 3a07e45a99c5300f47dadb2e91b40334626759d5. 2nd offense in #22929, b19ede356a535b36db10cbba3e8798045dc1a12e. 3rd offense in #22931, 41c4b80f7b57bbe13b2cc80eb98a54f4c6282668.
-betterandbetterii impersonate as dvorak0, goestav, Kjasn, Loongphy, TonyRL, ttttmr and xbot. https://github.com/DIYgod/RSSHub/commit/9e6f84df79bc9efcfabb0ca0768d7fded6775a1a.
diygod
henryqw
@@ -14,4 +15,5 @@ hyoban
neverbehave
pseudoyu
tonyrl
+-weixshaw impersonate as magazian in #23333. 23f8a7a8509f6620a79503a45370a7339a157bcb
zhenlonghe
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 073aae6491d2..b6aaf6ad09d0 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -10,15 +10,21 @@ updates:
- dependencies
ignore:
# pin to version before it is sold to potential suspicious party
- # https://github.com/goofychris/art-template/issues/660 the issue created from original author stating v4.13.3
+ # https://github.com/goofychris/art-template/issues/660 the issue created from original author stating v4.13.3 (March, 2025)
# contains suspicious code and related issues (#658, #659) were deleted
# related:
# https://github.com/fastify/point-of-view/issues/463 https://github.com/fastify/point-of-view/pull/461#issuecomment-2718888986
# https://github.com/cnpm/bug-versions/pull/266 https://github.com/cnpm/cnpmcore/issues/777
# https://github.com/yoimiya-kokomi/Miao-Yunzai/pull/515 https://github.com/zhangfisher/flex-tools/commit/09b565dfe6e2932bb829613ddbe09f6d0acbccd4
+ # v4.13.5, v4.13.6 (May, 2026)
+ # https://web.archive.org/web/20260521024725/https://github.com/goofychris/art-template/issues/665
+ # https://safedep.io/art-template-npm-supply-chain-compromise/ https://github.com/ossf/malicious-packages/pull/1265
- dependency-name: art-template
versions: ['>=4.13.3']
groups:
+ bbob:
+ patterns:
+ - '@bbob/*'
cloudflare:
patterns:
- '@cloudflare/*'
@@ -27,12 +33,23 @@ updates:
patterns:
- 'eslint'
- '@eslint/*'
+ hono:
+ patterns:
+ - '@hono/*'
+ - '@scalar/hono-api-reference'
+ - 'hono'
+ msw:
+ patterns:
+ - '@mswjs/*'
+ - 'msw'
opentelemetry:
patterns:
- '@opentelemetry/*'
oxc:
patterns:
+ - '@oxc-parser/*'
- '@oxlint/*'
+ - 'oxc-parser'
- 'oxfmt'
- 'oxlint'
- 'oxlint-plugin-eslint'
@@ -58,6 +75,10 @@ updates:
open-pull-requests-limit: 100
labels:
- dependencies
+ groups:
+ nix:
+ patterns:
+ - '*'
- package-ecosystem: 'github-actions'
directory: '/'
diff --git a/.github/labeler.yml b/.github/labeler.yml
index 4b6c2602e5e0..48db57424d54 100644
--- a/.github/labeler.yml
+++ b/.github/labeler.yml
@@ -1,7 +1,7 @@
'route: deprecated':
- changed-files:
- any-glob-to-any-file: ['lib/router.js']
- - all-globs-to-any-file: ['lib/routes-deprecated/**/*.js', '!lib/routes-deprecated/index.js']
+ - all-globs-to-any-file: ['lib/routes-deprecated/**']
'Route':
- changed-files:
@@ -10,7 +10,7 @@
core enhancement:
- changed-files:
- any-glob-to-any-file: ['lib/routes/index.ts']
- - all-globs-to-any-file: ['lib/**', '!lib/config.ts', '!lib/router.js', '!lib/routes/**', '!lib/routes-deprecated/**']
+ - all-globs-to-any-file: ['lib/**', '!lib/config.ts', '!lib/routes/**']
dependencies:
- changed-files:
diff --git a/.github/prompts/pr_review_rules.md b/.github/prompts/pr_review_rules.md
index a162ccec99df..433fb1b1f602 100644
--- a/.github/prompts/pr_review_rules.md
+++ b/.github/prompts/pr_review_rules.md
@@ -47,4 +47,3 @@ Only report **clear and actionable** violations in changed lines/files. Do not r
- Report only violated rules.
- Each bullet should include: file path, problem, and concrete fix.
- Group repeated issues across files into one concise bullet when possible.
-- If no rule is clearly violated, do not comment.
diff --git a/.github/workflows/build-assets.yml b/.github/workflows/build-assets.yml
index 44e45a852264..13cab5abd336 100644
--- a/.github/workflows/build-assets.yml
+++ b/.github/workflows/build-assets.yml
@@ -18,15 +18,15 @@ jobs:
contents: write
steps:
- name: Checkout
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Install pnpm
- uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8
+ uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
- name: Use Node.js Active LTS
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
+ uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: lts/*
cache: 'pnpm'
- - name: Install dependencies (yarn)
+ - name: Install dependencies
run: pnpm i
# assets
@@ -44,14 +44,14 @@ jobs:
# docs
- name: Build docs
- run: pnpm build:docs
+ run: pnpm exec tsx scripts/workflow/build-docs.ts
- id: check-docs-env
env:
DOCS_API_TOKEN: ${{ secrets.DOCS_API_TOKEN }}
if: ${{ env.DOCS_API_TOKEN != '' }}
run: echo "defined=true" >> $GITHUB_OUTPUT
- name: Checkout docs
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
if: steps.check-docs-env.outputs.defined == 'true'
with:
repository: 'RSSNext/rsshub-docs'
diff --git a/.github/workflows/cleanup-pr-cache.yml b/.github/workflows/cleanup-pr-cache.yml
new file mode 100644
index 000000000000..747db1f93654
--- /dev/null
+++ b/.github/workflows/cleanup-pr-cache.yml
@@ -0,0 +1,34 @@
+name: Clean up PR cache
+
+on:
+ pull_request_target:
+ types:
+ - closed
+ workflow_dispatch:
+ inputs:
+ pr_number:
+ description: 'Pull request number'
+ required: true
+ type: number
+
+jobs:
+ cleanup:
+ runs-on: ubuntu-slim
+ timeout-minutes: 5
+ permissions:
+ actions: write
+ steps:
+ - name: Delete caches of the PR
+ run: gh cache delete --all --repo "$REPO" --ref "$REF" --succeed-on-no-caches
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ REPO: ${{ github.repository }}
+ REF: refs/pull/${{ github.event.pull_request.number || inputs.pr_number }}/merge
+
+ - name: Delete caches of the PR branch
+ if: github.event_name == 'pull_request_target' && github.event.pull_request.head.repo.full_name == github.repository
+ run: gh cache delete --all --repo "$REPO" --ref "$REF" --succeed-on-no-caches
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ REPO: ${{ github.repository }}
+ REF: refs/heads/${{ github.event.pull_request.head.ref }}
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
index a870789efa99..3edda4f7d8b7 100644
--- a/.github/workflows/codeql.yml
+++ b/.github/workflows/codeql.yml
@@ -48,7 +48,7 @@ jobs:
steps:
- name: Checkout repository
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
# Initializes the CodeQL tools for scanning.
# TODO: use hash pinning when https://github.com/dependabot/dependabot-core/pull/13007 pass
diff --git a/.github/workflows/comment-on-issue.yml b/.github/workflows/comment-on-issue.yml
index 06d6825c0088..de6a197096c5 100644
--- a/.github/workflows/comment-on-issue.yml
+++ b/.github/workflows/comment-on-issue.yml
@@ -26,9 +26,9 @@ jobs:
outputs:
closed: ${{ steps.check.outputs.closed }}
steps:
- - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- - uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8
- - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
+ - uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
+ - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: lts/*
cache: 'pnpm'
@@ -60,9 +60,9 @@ jobs:
(needs.checkIssue.result == 'success' || needs.checkIssue.result == 'skipped') &&
needs.checkIssue.outputs.closed != 'true'
steps:
- - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- - uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8
- - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
+ - uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
+ - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: lts/*
cache: 'pnpm'
diff --git a/.github/workflows/dependabot-fork.yml b/.github/workflows/dependabot-fork.yml
index 40494f4e0b40..ab0c6354d717 100644
--- a/.github/workflows/dependabot-fork.yml
+++ b/.github/workflows/dependabot-fork.yml
@@ -10,7 +10,7 @@ jobs:
timeout-minutes: 5
steps:
- name: Checkout
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Comment Dependabot PR
uses: thollander/actions-comment-pull-request@24bffb9b452ba05a4f3f77933840a6a841d1b32b # v3.0.1
diff --git a/.github/workflows/docker-release.yml b/.github/workflows/docker-release.yml
index 9c542fad47ad..1bbf8afbc885 100644
--- a/.github/workflows/docker-release.yml
+++ b/.github/workflows/docker-release.yml
@@ -39,21 +39,25 @@ jobs:
- platform: linux/amd64
runner: ubuntu-latest
- platform: linux/arm64
- runner: ubuntu-24.04-arm
+ runner: ubuntu-26.04-arm
permissions:
packages: write
id-token: write
attestations: write
steps:
- name: Enable ZRAM
+ id: zram
# Reduce memory pressure
# PERCENT=100 is safe: https://fedoraproject.org/wiki/Changes/Scale_ZRAM_to_full_memory_size
run: |
sudo apt-get update -yq
- sudo apt-get install -yq "linux-modules-extra-$(uname -r)" zram-tools
+ sudo apt-get install -yq zram-tools
+ # TODO: remove when runner is 26.0
+ modinfo zram > /dev/null 2>&1 || sudo apt-get install -yq "linux-modules-extra-$(uname -r)"
echo -e 'ALGO=zstd\nPERCENT=100' | sudo tee -a /etc/default/zramswap
sudo systemctl restart zramswap
swapon
+ background: true
- name: Prepare
run: |
@@ -61,7 +65,7 @@ jobs:
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
- name: Checkout
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Extract repository name
id: repo-name
@@ -71,16 +75,16 @@ jobs:
echo "repo-name=$REPO_NAME_LOWER" >> "$GITHUB_OUTPUT"
- name: Set up Docker Buildx
- uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0
+ uses: docker/setup-buildx-action@594f3bf4285d9ea8dc53c9a0c9c4092420091003 # v4.4.0
- name: Log in to Docker Hub
- uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
+ uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
with:
username: ${{ vars.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Log in to the Container registry
- uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
+ uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
with:
registry: ghcr.io
username: ${{ github.actor }}
@@ -88,7 +92,7 @@ jobs:
- name: Extract Docker metadata (ordinary version)
id: meta-ordinary
- uses: docker/metadata-action@80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9 # v6.1.0
+ uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6.2.0
with:
images: |
${{ vars.DOCKER_USERNAME }}/${{ steps.repo-name.outputs.repo-name }}
@@ -105,9 +109,12 @@ jobs:
tags=$(jq -r '.target["docker-metadata-action"].args.DOCKER_META_IMAGES' "$DOCKER_METADATA_OUTPUT_BAKE_FILE_TAGS")
echo "tags=$tags" >> "$GITHUB_OUTPUT"
+ - name: Wait for ZRAM
+ wait: zram
+
- name: Build and push Docker image (ordinary version)
id: build-and-push
- uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0
+ uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0
with:
context: .
tags: ${{ steps.image-name-ordinary.outputs.tags }}
@@ -118,7 +125,7 @@ jobs:
outputs: type=image,compression=zstd,force-compression=true,push-by-digest=true,name-canonical=true,push=true
- name: Attest (ordinary version)
- uses: actions/attest@59d89421af93a897026c735860bf21b6eb4f7b26 # v4.1.0
+ uses: actions/attest@1e69f48acb82d1966a394da916b4c1698aa569d6 # v4.2.2
with:
subject-name: |
${{ vars.DOCKER_USERNAME }}/${{ steps.repo-name.outputs.repo-name }}
@@ -141,7 +148,7 @@ jobs:
- name: Extract Docker metadata (Chromium-bundled version)
id: meta-chromium-bundled
- uses: docker/metadata-action@80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9 # v6.1.0
+ uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6.2.0
with:
images: |
${{ vars.DOCKER_USERNAME }}/${{ steps.repo-name.outputs.repo-name }}
@@ -160,7 +167,7 @@ jobs:
- name: Build and push Docker image (Chromium-bundled version)
id: build-and-push-chromium
- uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0
+ uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0
with:
context: .
build-args: PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=0
@@ -173,7 +180,7 @@ jobs:
outputs: type=image,compression=zstd,force-compression=true,push-by-digest=true,name-canonical=true,push=true
- name: Attest (Chromium-bundled version)
- uses: actions/attest@59d89421af93a897026c735860bf21b6eb4f7b26 # v4.1.0
+ uses: actions/attest@1e69f48acb82d1966a394da916b4c1698aa569d6 # v4.2.2
with:
subject-name: |
${{ vars.DOCKER_USERNAME }}/${{ steps.repo-name.outputs.repo-name }}
@@ -204,16 +211,16 @@ jobs:
id-token: write
steps:
- name: Set up Docker Buildx
- uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0
+ uses: docker/setup-buildx-action@594f3bf4285d9ea8dc53c9a0c9c4092420091003 # v4.4.0
- name: Log in to Docker Hub
- uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
+ uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
with:
username: ${{ vars.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Log in to the Container registry
- uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
+ uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
with:
registry: ghcr.io
username: ${{ github.actor }}
@@ -228,7 +235,7 @@ jobs:
- name: Extract Docker metadata (ordinary version)
id: meta-ordinary-merge
- uses: docker/metadata-action@80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9 # v6.1.0
+ uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6.2.0
with:
images: |
${{ vars.DOCKER_USERNAME }}/${{ needs.release.outputs.repo-name }}
@@ -254,7 +261,7 @@ jobs:
- name: Extract Docker metadata (Chromium-bundled version)
id: meta-chromium-bundled-merge
- uses: docker/metadata-action@80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9 # v6.1.0
+ uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6.2.0
with:
images: |
${{ vars.DOCKER_USERNAME }}/${{ needs.release.outputs.repo-name }}
@@ -271,13 +278,48 @@ jobs:
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
$(printf '${{ vars.DOCKER_USERNAME }}/${{ needs.release.outputs.repo-name }}@sha256:%s ' *)
+ github-release:
+ runs-on: ubuntu-slim
+ needs: [release, merge]
+ timeout-minutes: 5
+ permissions:
+ contents: write
+ steps:
+ - name: Prepare release notes
+ id: notes
+ env:
+ IMAGE_REPOSITORY: ${{ needs.release.outputs.repo-name }}
+ DOCKER_USERNAME: ${{ vars.DOCKER_USERNAME }}
+ run: |
+ echo "tag=v$(date -u +%Y.%m.%d)-${GITHUB_RUN_NUMBER}.${GITHUB_SHA:0:7}" >> "$GITHUB_OUTPUT"
+ image_repository="${GITHUB_REPOSITORY,,}"
+ cat > "$RUNNER_TEMP/release-notes.md" <

${text.slice(0, brief)}…
` : `${text}
`; + if (!item.description) { + continue; } + + const text = sanitizeHtml(item.description, { allowedTags: [], allowedAttributes: {} }); + item.description = text.length > brief ? `${text.slice(0, brief)}…
` : `${text}
`; } } else { throw new Error('Invalid parameter brief. Please check the doc https://docs.rsshub.app/guide/parameters#shu-chu-jian-xun'); diff --git a/lib/middleware/sentry.test.ts b/lib/middleware/sentry.test.ts index 50c88bac0050..b53792311a84 100644 --- a/lib/middleware/sentry.test.ts +++ b/lib/middleware/sentry.test.ts @@ -1,18 +1,25 @@ +import { Context } from 'hono'; import { afterEach, describe, expect, it, vi } from 'vitest'; type Scope = { setTag: ReturnType\[?\(?The above text.*this podcast.*?em.*?p>/g, '');
- const track = capture('.podcasts__media > div > a').attr('href');
- const single = {
- title,
- description: contents,
- enclosure_url: track,
- enclosure_type: 'audio/mpeg',
- link: address,
- guid: address,
- author,
- pubDate: new Date(time).toUTCString(),
- };
- ctx.cache.set(address, JSON.stringify(single));
- return single;
- })
- );
- ctx.state.data = {
- itunes_author: 'Scientific American',
- itunes_category: 'Science',
- image: cover,
- title: '60-Second Science',
- link: url,
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/755/user.js b/lib/routes-deprecated/755/user.js
deleted file mode 100644
index aa59f130cf9a..000000000000
--- a/lib/routes-deprecated/755/user.js
+++ /dev/null
@@ -1,71 +0,0 @@
-const got = require('@/utils/got');
-
-const postTypes = {
- 1: '文字',
- 2: '表情',
- 3: '纯图片',
- 4: '评论',
- 5: '转发',
- 6: '纯视频',
- 7: '图片文字',
- 8: '视频文字',
-};
-
-module.exports = async (ctx) => {
- const username = ctx.params.username;
-
- const url = `https://api.7gogo.jp/web/v2/talks/${username}/posts?talkId=${username}&direction=PREV`;
-
- const response = await got.get(url);
- const list = response.data.data;
-
- const user_display_name = list[0].user.name;
- const user_description = list[0].user.description;
- const user_image = list[0].user.coverImageUrl;
-
- const GetContent = (post) =>
- post.body &&
- post.body
- .map((item) => {
- switch (item.bodyType) {
- case 1:
- return ` ${item.text.replaceAll(/\n/gm, ' ${data.paper.title} ${data.paper.author.toString()} ${data.paper.publish_time} ${data.paper.description} ${data.paper.userInfo.nickname} : ${data.paper.recommend_reason} ${name} [${keywords}] ${element.text} 价格: ¥${item.price} 地址: ${item.address} ${item.content} 价格: ¥${item.price} 地址: ${item.address} ${item.content} ${item.text()} ${item.description}
- ${s_author} Invalid 所輸入 所输入 ${title} ${name} ${album} ${$(this).html()} ' + item.excerpt + ' ${item.split(`\r\n${bar}\r\n`)[1].replaceAll('\r\n', ' ')} ${tmp.html()} Viewer: ${viewerurl} niconico: ${niconicourl} ${author.role}:${author.name} ${fe.contents} Index:${href(index.title, index.url, language)} ${item.num} ${item.title} ${item.date} ${item.desc} ${note.pp.dg} ${note.pp.dg} 时长: {itunes_duration}
查看节目
@@ -50,9 +57,6 @@ const ProcessFeed = (id, limit, offset) =>
`163:music:djradio:${id}:${limit}:${offset}`,
async () =>
await got.post('https://music.163.com/api/dj/program/byradio', {
- headers: {
- Referer: 'https://music.163.com/',
- },
form: {
radioId: id,
limit,
diff --git a/lib/routes/163/music/playlist.ts b/lib/routes/163/music/playlist.ts
index 8585b120194d..0f89fe37519f 100644
--- a/lib/routes/163/music/playlist.ts
+++ b/lib/routes/163/music/playlist.ts
@@ -19,10 +19,17 @@ export const route: Route = {
],
requirePuppeteer: false,
antiCrawler: true,
+ supportRadar: true,
supportBT: false,
supportPodcast: false,
supportScihub: false,
},
+ radar: [
+ {
+ source: ['music.163.com/playlist'],
+ target: '/music/playlist/:id',
+ },
+ ],
name: '歌单歌曲',
maintainers: ['DIYgod'],
handler,
@@ -33,16 +40,12 @@ async function handler(ctx) {
const response = await got.get(`https://music.163.com/api/v3/playlist/detail?id=${id}`, {
headers: {
- Referer: 'https://music.163.com/',
Cookie: config.ncm.cookies,
},
});
const data = response.data.playlist;
const songinfo = await got('https://music.163.com/api/song/detail', {
- headers: {
- Referer: 'https://music.163.com',
- },
searchParams: {
ids: `[${data.trackIds.slice(0, 201).map((item) => item.id)}]`,
},
@@ -55,10 +58,14 @@ async function handler(ctx) {
description: `网易云音乐歌单 - ${data.name}`,
item: data.trackIds.slice(0, 201).map((item) => {
const thisSong = songs.find((element) => element.id === item.id);
- const singer = thisSong.artists.length === 1 ? thisSong.artists[0].name : thisSong.artists.reduce((prev, cur) => (prev.name || prev) + '/' + cur.name);
+ let singer = thisSong.artists[0].name;
+ for (const artist of thisSong.artists.slice(1)) {
+ singer += '/' + artist.name;
+ }
return {
title: `${thisSong.name} - ${singer}`,
description: renderPlaylistDescription({
+ songId: item.id,
singer,
album: thisSong.album.name,
date: new Date(thisSong.album.publishTime).toLocaleDateString(),
diff --git a/lib/routes/163/music/userevents.tsx b/lib/routes/163/music/userevents.tsx
index 6174be14b4fd..8472dadb0e84 100644
--- a/lib/routes/163/music/userevents.tsx
+++ b/lib/routes/163/music/userevents.tsx
@@ -23,6 +23,16 @@ const renderDescription = ({ description, pics }) => {
export const route: Route = {
path: '/music/user/events/:id',
categories: ['multimedia'],
+ example: '/163/music/user/events/585804522',
+ parameters: {
+ id: '用户 uid, 可在用户主页 URL 中找到',
+ },
+ radar: [
+ {
+ source: ['music.163.com/user/event'],
+ target: '/music/user/events/:id',
+ },
+ ],
name: '用户动态',
maintainers: ['Master-Hash'],
handler,
@@ -31,13 +41,7 @@ export const route: Route = {
async function handler(ctx) {
const id = ctx.req.param('id');
- const response = await got(`https://music.163.com/api/event/get/${id}`, {
- headers: {
- Referer: 'https://music.163.com/',
- },
- });
-
- const { data } = response;
+ const { data } = await got(`https://music.163.com/api/event/get/${id}`);
const { nickname, signature, avatarUrl } = data.events[0].user;
return {
diff --git a/lib/routes/163/music/userplaylist.tsx b/lib/routes/163/music/userplaylist.tsx
index 4dcf677fb42d..2389be59ebc9 100644
--- a/lib/routes/163/music/userplaylist.tsx
+++ b/lib/routes/163/music/userplaylist.tsx
@@ -1,7 +1,7 @@
import { renderToString } from 'hono/jsx/dom/server';
import type { Route } from '@/types';
-import got from '@/utils/got';
+import ofetch from '@/utils/ofetch';
const renderDescription = (image, description, src) =>
renderToString(
@@ -31,10 +31,17 @@ export const route: Route = {
requireConfig: false,
requirePuppeteer: false,
antiCrawler: false,
+ supportRadar: true,
supportBT: false,
supportPodcast: false,
supportScihub: false,
},
+ radar: [
+ {
+ source: ['music.163.com/user/home'],
+ target: '/music/user/playlist/:id',
+ },
+ ],
name: '用户歌单',
maintainers: ['DIYgod'],
handler,
@@ -43,22 +50,20 @@ export const route: Route = {
async function handler(ctx) {
const uid = ctx.req.param('uid');
- const response = await got.post('https://music.163.com/api/user/playlist', {
- headers: {
- Referer: 'https://music.163.com/',
- },
- form: {
+ const response = await ofetch.raw('https://music.163.com/api/user/playlist', {
+ method: 'POST',
+ body: new URLSearchParams({
uid,
- limit: 1000,
- offset: 0,
- },
+ limit: '1000',
+ offset: '0',
+ }),
+ // The API responds with text/plain
+ responseType: 'json',
});
- const playlist = response.data.playlist || [];
-
- const creator = (playlist[0] || {}).creator;
+ const playlist = response._data.playlist || [];
- const { nickname, signature, avatarUrl } = creator;
+ const { nickname, signature, avatarUrl } = (playlist[0] || {}).creator;
return {
title: `${nickname} 的所有歌单`,
@@ -66,7 +71,7 @@ async function handler(ctx) {
subtitle: signature,
description: signature,
author: nickname,
- updated: response.headers.date,
+ updated: response.headers.get('date') ?? undefined,
icon: avatarUrl,
image: avatarUrl,
item: playlist.map((pl) => {
diff --git a/lib/routes/163/music/userplayrecords.tsx b/lib/routes/163/music/userplayrecords.tsx
index 41bf521040b9..8698a87e58bb 100644
--- a/lib/routes/163/music/userplayrecords.tsx
+++ b/lib/routes/163/music/userplayrecords.tsx
@@ -2,11 +2,10 @@ import { renderToString } from 'hono/jsx/dom/server';
import { config } from '@/config';
import type { Route } from '@/types';
-import got from '@/utils/got';
+import ofetch from '@/utils/ofetch';
const headers = {
- cookie: config.ncm.cookies,
- Referer: 'https://music.163.com/',
+ cookie: config.ncm.cookies ?? '',
};
const renderDescription = (record, song, index) =>
@@ -88,14 +87,14 @@ async function handler(ctx) {
const type = Number.parseInt(ctx.req.param('type')) || 0;
const url = `https://music.163.com/api/v1/play/record?uid=${uid}&type=${type}`;
- const response = await got(url, { headers });
+ const response = await ofetch.raw(url, { headers });
- const records = type === 1 ? response.data.weekData : response.data.allData;
+ const records = type === 1 ? response._data.weekData : response._data.allData;
return {
title: `${type === 1 ? '听歌榜单(最近一周)' : '听歌榜单(所有时间}'} - ${uid}}`,
link: `https://music.163.com/user/home?id=${uid}`,
- updated: response.headers.date,
+ updated: response.headers.get('date') ?? undefined,
item: getItem(records),
};
}
diff --git a/lib/routes/163/news/rank.ts b/lib/routes/163/news/rank.ts
index d7643a8d3aa0..270cad77048b 100644
--- a/lib/routes/163/news/rank.ts
+++ b/lib/routes/163/news/rank.ts
@@ -2,7 +2,7 @@ import { load } from 'cheerio';
import iconv from 'iconv-lite';
import InvalidParameterError from '@/errors/types/invalid-parameter';
-import type { Route } from '@/types';
+import type { DataItem, Route } from '@/types';
import cache from '@/utils/cache';
import got from '@/utils/got';
import { parseDate } from '@/utils/parse-date';
@@ -122,7 +122,8 @@ async function handler(ctx) {
const cfg = config[category];
if (!cfg) {
throw new InvalidParameterError('Bad category. See docs');
- } else if ((category !== 'whole' && type === 'click' && time === 'month') || (category === 'whole' && type === 'click' && time === 'hour') || (type === 'follow' && time === 'hour')) {
+ }
+ if ((category !== 'whole' && type === 'click' && time === 'month') || (category === 'whole' && type === 'click' && time === 'hour') || (type === 'follow' && time === 'hour')) {
throw new InvalidParameterError('Bad timeRange range. See docs');
}
@@ -139,24 +140,25 @@ async function handler(ctx) {
.eq(timeRange[time].index + (category === 'whole' ? (type === 'click' ? -1 : 2) : type === 'click' ? 0 : 2))
.find('table tbody tr td a')
.toArray()
- .map((item) => {
- item = $(item);
+ .map((item): DataItem => {
+ const $item = $(item);
return {
- link: item.attr('href'),
+ link: $item.attr('href'),
+ title: '',
};
});
const items = await Promise.all(
list.map((item) =>
- cache.tryGet(item.link, async () => {
+ cache.tryGet(item.link!, async () => {
try {
let link;
- if (category === 'auto' || category === 'house' || category === 'travel') {
- const category = item.link.split('.163.com')[0].split('//').pop().split('.').pop();
- link = `https://3g.163.com/${category}/article/${item.link.split('/').pop()}`;
+ if (['auto', 'house', 'travel'].includes(category)) {
+ const category = item.link!.split('.163.com', 1)[0].split('//').pop()!.split('.').pop();
+ link = `https://3g.163.com/${category}/article/${item.link!.split('/').pop()}`;
} else {
- const pathname = new URL(item.link).pathname;
+ const pathname = new URL(item.link!).pathname;
link = `https://3g.163.com${pathname}`;
}
@@ -174,8 +176,8 @@ async function handler(ctx) {
elem.attribs.src = elem.attribs['data-src'] ?? elem.attribs.src;
});
- item.title = content('meta[property="og:title"]').attr('content').replace('_手机网易网', '');
- item.pubDate = parseDate(content('meta[property="og:release_date"]').attr('content'));
+ item.title = content('meta[property="og:title"]').attr('content')!.replace('_手机网易网', '');
+ item.pubDate = parseDate(content('meta[property="og:release_date"]').attr('content')!);
item.description = content('.article-body').html();
} catch {
return '';
@@ -189,6 +191,6 @@ async function handler(ctx) {
return {
title: `网易新闻${timeRange[time].title}${type === 'click' ? '点击' : '跟帖'}榜 - ${cfg.title}`,
link: currentUrl,
- item: items.filter(Boolean),
+ item: items.filter((item): item is DataItem => Boolean(item)),
};
}
diff --git a/lib/routes/163/news/special.ts b/lib/routes/163/news/special.ts
index ea7d1948c278..86f93caba8df 100644
--- a/lib/routes/163/news/special.ts
+++ b/lib/routes/163/news/special.ts
@@ -102,7 +102,7 @@ async function handler(ctx) {
const url = `https://3g.163.com/touch/reconstruct/article/list/${type}/0-20.html`;
const response = await got(url);
const data = response.data;
- const matches = data.replaceAll(/\s/g, '').match(/artiList\((.*?)]}\)/);
+ const matches = data.replaceAll(/\s/g, '').match(/artiList\((.*?)\]\}\)/);
const articlelist0 = matches[1].replace(/".*?wangning/, '"articles') + ']}';
const articlelist = JSON.parse(articlelist0);
const articles = articlelist.articles;
@@ -112,7 +112,7 @@ async function handler(ctx) {
let url = article.url;
if (url === null || article.skipType === 'video') {
const skipurl = article.skipURL;
- const vid = skipurl.match(/vid=(.*?)$/);
+ const vid = skipurl.match(/vid=(.*)$/);
if (vid !== null) {
url = `https://3g.163.com/exclusive/video/${vid[1]}.html`;
}
diff --git a/lib/routes/163/open/vip.tsx b/lib/routes/163/open/vip.tsx
index 4ee699dbc0dd..dd67f230d050 100644
--- a/lib/routes/163/open/vip.tsx
+++ b/lib/routes/163/open/vip.tsx
@@ -2,7 +2,7 @@ import { load } from 'cheerio';
import { raw } from 'hono/html';
import { renderToString } from 'hono/jsx/dom/server';
-import type { Route } from '@/types';
+import type { DataItem, Route } from '@/types';
import cache from '@/utils/cache';
import got from '@/utils/got';
import { parseDate } from '@/utils/parse-date';
@@ -31,6 +31,17 @@ export const route: Route = {
url: 'vip.open.163.com/',
};
+interface CourseModule {
+ name: string;
+ contents: Array<{
+ title: string;
+ subtitle: string;
+ authorName: string;
+ publishTime: number;
+ courseUid: string;
+ }>;
+}
+
const renderDescription = (data, description) => {
const chapterList = data.movieChapterList.length ? data.movieChapterList : data.audioChapterList;
@@ -65,11 +76,11 @@ async function handler() {
const initialState = JSON.parse(
$('script')
.text()
- .match(/window\.__INITIAL_STATE__=(.*);\(function\(\){var/)[1]
+ .match(/window\.__INITIAL_STATE__=(.*);\(function\(\)\{var/)![1]
);
- const list = Object.values(initialState.courseindex.myModules).flatMap((mod) =>
- mod.contents.map((item) => ({
+ const list = Object.values ${item.digest}
+ 地点:
+ {location || '参考详情'}
+
+ 开展:
+ {startDate || '未定/常设'}
+
+ 闭展:
+ {endDate || '未定/常设'}
+
+ 原始展期:{fullDuration}
+ ${item.text.replaceAll('\n', ' ').text(`比赛时间:${matchTime}`));
+ }
+ $description.append($body.html() ?? '');
+
+ return {
+ ...item,
+ description: $description.html(),
+ };
+ })
+ )
+ );
+
+ return {
+ title: '足球集锦 - 98直播吧',
+ link: currentUrl,
+ language: 'zh-CN',
+ item: items,
+ };
+}
diff --git a/lib/routes/99percentinvisible/namespace.ts b/lib/routes/99percentinvisible/namespace.ts
new file mode 100644
index 000000000000..5d8d85e242ab
--- /dev/null
+++ b/lib/routes/99percentinvisible/namespace.ts
@@ -0,0 +1,8 @@
+import type { Namespace } from '@/types';
+
+export const namespace: Namespace = {
+ name: '99% Invisible',
+ url: '99percentinvisible.org',
+ categories: ['multimedia'],
+ lang: 'en',
+};
diff --git a/lib/routes/99percentinvisible/transcript.ts b/lib/routes/99percentinvisible/transcript.ts
new file mode 100644
index 000000000000..c03d468dd2f9
--- /dev/null
+++ b/lib/routes/99percentinvisible/transcript.ts
@@ -0,0 +1,53 @@
+import { load } from 'cheerio';
+
+import type { Route } from '@/types';
+import cache from '@/utils/cache';
+import ofetch from '@/utils/ofetch';
+import { parseDate } from '@/utils/parse-date';
+
+export const route: Route = {
+ path: '/transcript',
+ categories: ['multimedia'],
+ example: '/99percentinvisible/transcript',
+ name: 'Transcript',
+ maintainers: ['Ji4n1ng'],
+ handler,
+};
+
+const host = 'https://99percentinvisible.org/';
+
+async function handler() {
+ const link = new URL('archives/', host).href;
+ const response = await ofetch(link);
+
+ const $ = load(response);
+
+ const episodePrefix = new URL('episode/', host).href;
+ const list = $('.content .post-blocks a.post-image')
+ .toArray()
+ .map((e) => `${$(e).attr('href')}transcript/`)
+ .filter((e) => e.startsWith(episodePrefix));
+
+ const items = await Promise.all(
+ list.map((itemUrl) =>
+ cache.tryGet(itemUrl, async () => {
+ const response = await ofetch(itemUrl);
+ const $ = load(response);
+
+ return {
+ title: $('article header h1').text(),
+ link: itemUrl,
+ author: '99% Invisible',
+ description: $('article .page-content').html(),
+ pubDate: parseDate($('article header .entry-meta time').attr('datetime')!),
+ };
+ })
+ )
+ );
+
+ return {
+ title: '99% Invisible Transcript',
+ link,
+ item: items,
+ };
+}
diff --git a/lib/routes/9to5/subsite.ts b/lib/routes/9to5/subsite.ts
index 07b65cc641a7..abc22c4d6f96 100644
--- a/lib/routes/9to5/subsite.ts
+++ b/lib/routes/9to5/subsite.ts
@@ -7,9 +7,20 @@ import utils from './utils';
export const route: Route = {
path: '/:subsite/:tag?',
- name: 'Unknown',
- maintainers: [],
+ categories: ['new-media'],
+ example: '/9to5/mac/aapl',
+ parameters: {
+ subsite: 'Subsite name',
+ tag: 'Tag name inside the url of the tag page',
+ },
+ name: 'Sub-site',
+ maintainers: ['HenryQW'],
handler,
+ description: `Supported sub-sites:
+
+| 9To5Mac | 9To5Google | 9To5Toys |
+| ------- | ---------- | -------- |
+| Mac | Google | Toys |`,
};
async function handler(ctx) {
@@ -41,17 +52,19 @@ async function handler(ctx) {
}
if (ctx.req.param('tag')) {
- link = `${link}/guides/${ctx.req.param('tag')}/feed/`;
+ link += `/guides/${ctx.req.param('tag')}/feed/`;
title = `${ctx.req.param('tag')} | ${title}`;
} else {
- link = `${link}/feed/`;
+ link += '/feed/';
}
const feed = await parser.parseURL(link);
+ const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit')) : 10;
+
const items = await Promise.all(
- feed.items.splice(0, ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit')) : 10).map((item) =>
- cache.tryGet(item.link, async () => {
+ feed.items.slice(0, limit).map((item) =>
+ cache.tryGet(item.link!, async () => {
const response = await got({
method: 'get',
url: item.link,
@@ -59,7 +72,7 @@ async function handler(ctx) {
const description = utils.ProcessFeed(response.data);
const single = {
- title: item.title,
+ title: item.title!,
description,
pubDate: item.pubDate,
link: item.link,
diff --git a/lib/routes/9to5/utils.ts b/lib/routes/9to5/utils.ts
index 3cbb329b1fc7..6a1da82a34a5 100644
--- a/lib/routes/9to5/utils.ts
+++ b/lib/routes/9to5/utils.ts
@@ -6,7 +6,7 @@ const ProcessFeed = (data) => {
const cover = $('meta[property="og:image"]');
if (cover.length > 0) {
- $(` ${attachment.filename} ${attachment.filename}
')}`;
- case 3:
- return `
`;
- case 4:
- return `
${item.comment.user.name}:
`;
- case 7:
- return `
${item.comment.comment.body.replaceAll(/\n/gm, '
')}${item.talk.name}:
`;
- case 8:
- return `
${GetContent(item.post)}
- `;
- author = data.user.nickname;
- link = `https://www.yanxishe.com/TextTranslation/${id}`;
- break;
- case 'paper': // 论文
- description = ` `;
- for (const element of data.paragraphs) {
- description += ` ${data.title} ${data.zh_title} `;
- }
- description += ` ${element.content} ${element.zh_content.content} 标题
作者
下载地址
`;
- description += `发布时间
摘要
推荐理由
${info.title}
${content('div.unicodebidi').text()}`;
- item.pubDate = new Date(`${ymd.split('.')[2]}-${ymd.split('.')[1]}-${ymd.split('.')[0]} ${date.split(' ')[1]}`).toUTCString();
- return item;
- })
- )
- );
-
- return {
- title: `${$('title').text().split('|')[0]} | Amazfit Watch Faces`,
- link: currentUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/amd/graphicsdrivers.js b/lib/routes-deprecated/amd/graphicsdrivers.js
deleted file mode 100644
index 220907b76499..000000000000
--- a/lib/routes-deprecated/amd/graphicsdrivers.js
+++ /dev/null
@@ -1,114 +0,0 @@
-const got = require('@/utils/got');
-const config = require('@/config').value;
-const cheerio = require('cheerio');
-const url = 'https://download.amd.com/drivers/xml/driver_09_us.xml';
-
-// 06/10/2020 -> Wed Jun 10 2020 00:00:00
-function convertDate(dateStr) {
- const [month, day, year] = dateStr.split('/').map((x) => Number.parseInt(x, 10));
- const date = new Date();
- date.setFullYear(year, month - 1, day);
- date.setHours(0, 0, 0, 0);
- return date;
-}
-
-function versionToRss(info, isBeta) {
- const date = convertDate(info.releaseDate);
- return {
- title: `Radeon Software ${info.edition} Edition ${info.version}` + (isBeta ? ' Beta' : ''),
- description: `内部版本: ${info.internal}
发布时间: ${date.getFullYear()}-${date.getMonth() + 1}-${date.getDay()}`,
- pubDate: date.toUTCString(),
- link: info.releaseNotes,
- };
-}
-
-module.exports = async (ctx) => {
- let data = await ctx.cache.get(url, false);
- if (!data) {
- const res = await got.get(url);
- data = res.data;
- ctx.cache.set(url, data, config.cache.contentExpire);
- }
-
- const $ = cheerio.load(data, { xmlMode: true });
- const productfamily = $('driverSelector > platform > productfamily')[0];
-
- let product;
- for (const node of productfamily.childNodes) {
- if (node.tagName !== 'product') {
- continue;
- }
-
- const ids = node.attribs.ids.split(', ');
- if (!ids.includes(ctx.params.id)) {
- continue;
- }
-
- if (ctx.params.rid && node.attribs.rid !== ctx.params.rid) {
- continue;
- }
-
- product = node;
- break;
- }
-
- if (product) {
- let latestWHQL = '';
- let latestBeta = '';
- let whql, beta;
- for (const node of product.childNodes) {
- if (node.tagName !== 'version') {
- continue;
- }
-
- if (node.attribs.number > latestWHQL) {
- latestWHQL = node.attribs.number;
- whql = {
- version: node.attribs.number,
- internal: node.attribs.internal,
- edition: node.attribs.WHQLEdition,
- releaseDate: node.attribs.whqlreleasedate,
- releaseNotes: node.attribs.rnoteswin,
- };
- }
-
- if (node.attribs.betaname > latestBeta) {
- latestBeta = node.attribs.betaname;
- beta = {
- version: node.attribs.betaname,
- internal: node.attribs.beta,
- edition: node.attribs.BETAEdition,
- releaseDate: node.attribs.betareleasedate,
- releaseNotes: node.attribs.betarnoteswin,
- };
- }
- }
-
- const item = [];
- if (whql || beta) {
- if (whql) {
- try {
- item.push(versionToRss(whql, false));
- } catch {
- // ignore
- }
- }
- if (beta) {
- try {
- item.push(versionToRss(beta, true));
- } catch {
- // ignore
- }
- }
- }
-
- ctx.state.data = {
- title: `${product.attribs.label} (ids:${product.attribs.ids} rid:${product.attribs.rid})`,
- link: 'https://www.amd.com/zh-hans/support',
- allowEmpty: true,
- item,
- };
- } else {
- ctx.throw(404, 'Product Not Found');
- }
-};
diff --git a/lib/routes-deprecated/anytxt/release-notes.js b/lib/routes-deprecated/anytxt/release-notes.js
deleted file mode 100644
index da2ea9dcbe66..000000000000
--- a/lib/routes-deprecated/anytxt/release-notes.js
+++ /dev/null
@@ -1,33 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const rootUrl = 'https://anytxt.net';
- const currentUrl = `${rootUrl}/download`;
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
-
- const $ = cheerio.load(response.data);
-
- const items = $('.has-medium-font-size')
- .map((_, item) => {
- item = $(item);
- const date = item.text().replace(':', '');
-
- return {
- title: date,
- link: currentUrl,
- pubDate: new Date(date).toUTCString(),
- description: `${item.next().html()}
`,
- };
- })
- .get();
-
- ctx.state.data = {
- title: 'Release Notes - AnyTXT',
- link: currentUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/aozora/newbook.js b/lib/routes-deprecated/aozora/newbook.js
deleted file mode 100644
index b7f2cf614afd..000000000000
--- a/lib/routes-deprecated/aozora/newbook.js
+++ /dev/null
@@ -1,93 +0,0 @@
-// Warning: The author knows nothing about javascript!
-
-// params:
-// count? : count of new-books
-
-const got = require('@/utils/got'); // get web content
-const cheerio = require('cheerio'); // html parser
-const entities = require('entities');
-
-const base_url = 'https://www.aozora.gr.jp/index_pages/';
-module.exports = async (ctx) => {
- // get the update list
- const response = await got({
- method: 'get',
- url: base_url + 'whatsnew1.html',
- });
- const data = response.data; // content is html format
-
- const $ = cheerio.load(data);
- const list = $('table.list tr');
-
- // get how many new-books. amount in this page is 50
- let count = Number.parseInt(ctx.params.count);
- if (Number.isNaN(count) || count < 1) {
- count = 10; // default count of new-book list
- } else if (count > 50) {
- count = 50;
- }
-
- // parse book urls
- const detail_urls = [];
- for (let i = 1; i < count + 1; ++i) {
- // i = 1: first tr is table title, ignore
- const link = base_url + $(list[i]).find('a').attr('href');
- detail_urls.push(link);
- }
-
- // get book-cards
- const responses = await Promise.all(detail_urls.map((url) => got(url)));
- const cards = responses.map(({ data }) => data);
-
- // get real data to feed
- const book_list = [];
- for (let i = 0; i < count; ++i) {
- const $ = cheerio.load(cards[i]);
- const link = $('meta[property="og:url"]').attr('content');
- const link_dir = link.replaceAll(/\/[^/]*$/g, '/');
- const title_info = $('table[summary="タイトルデータ"] > tbody > tr');
- let author = '';
- let title = '';
- let title_sub = '';
- for (const element of title_info) {
- const tmp = entities.decodeXML($(element).html()); // should convert from escaped to unicode
- if (tmp.includes('作品名:')) {
- title = $(element).find('td:nth-child(2)').text();
- }
- if (tmp.includes('副題:')) {
- title_sub = $(element).find('td:nth-child(2)').text();
- }
- if (tmp.includes('著者名:')) {
- author = $(element).find('td:nth-child(2)').text();
- }
- }
- if (title_sub !== '') {
- title += ' —— ' + title_sub;
- }
- const pub_date_raw = $('table[summary="底本データ"] > tbody > tr:nth-child(3) > td:nth-child(2)').text();
- const pub_date_num = pub_date_raw.replaceAll(/(.*)|日/g, '').replaceAll(/[年月]/g, '-');
- const pub_date = new Date(pub_date_num).toUTCString();
- const full_text_relative_link = $('table.download > tbody > tr:nth-child(3) > td:nth-child(3) > a').attr('href');
- const full_text_link = link_dir + full_text_relative_link;
- const full_text_link_html = 'いますぐXHTML版で読む
';
- const summury = $('table[summary="作品データ"]')
- .html()
- .replaceAll('href="', 'href="' + link_dir);
-
- const item = {
- title,
- author,
- pubDate: pub_date,
- link,
- description: full_text_link_html + summury,
- };
- book_list.push(item);
- }
-
- // feed the data
- ctx.state.data = {
- title: '青空文庫新着リスト',
- link: base_url + 'whatsnew1.html',
- item: book_list,
- };
-};
diff --git a/lib/routes-deprecated/appsales/index.js b/lib/routes-deprecated/appsales/index.js
deleted file mode 100644
index e0df591574c7..000000000000
--- a/lib/routes-deprecated/appsales/index.js
+++ /dev/null
@@ -1,66 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- ctx.params.caty = ctx.params.caty || 'highlights';
- ctx.params.time = ctx.params.time || '24h';
-
- const times = ['24h', 'week', 'alltime'];
- const rootUrl = `https://www.app-sales.net/${ctx.params.caty}/#!`;
- const response = await got({
- method: 'get',
- url: rootUrl,
- });
-
- const $ = cheerio.load(response.data);
-
- if (ctx.params.caty === 'mostwanted') {
- for (const i of times) {
- if (i !== ctx.params.time) {
- $(`#charts-${i}`).remove();
- }
- }
- }
-
- $('i,img.play-icon-small').remove();
-
- const items = $('div.sale-list-item')
- .map((_, item) => {
- item = $(item);
-
- const icon = item.find('div.app-icon').html();
- const name = item.find('p.app-name').text();
- const developer = item.find('p.app-dev').text();
- const oldPrice = item.find('div.price-old').text();
- const newPrice = item.find('div.price-new').text();
- const discount = item.find('div.price-disco').text();
- const rating = item.find('p.rating').text();
- const downloads = item.find('p.downloads').text();
- const bookmarks = item.find('p.bookmarks').text();
-
- const description =
- `${icon}` +
- `
';
-
- return {
- title: `${name} ${newPrice ? '[' + newPrice + ']' : ''}`,
- link: item.find('a.waves-effect').attr('href'),
- description,
- author: developer,
- };
- })
- .get();
-
- ctx.state.data = {
- title: $('title').text(),
- link: rootUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/aqicn/index.js b/lib/routes-deprecated/aqicn/index.js
deleted file mode 100644
index fa04af24a9ee..000000000000
--- a/lib/routes-deprecated/aqicn/index.js
+++ /dev/null
@@ -1,46 +0,0 @@
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- const city = ctx.params.city;
- const pollution = ctx.params.pollution || [];
- const pollutionType = {
- so2: 'so2',
- no2: 'no2',
- co: 'co',
- o3: 'O3',
- pm25: 'PM2.5',
- pm10: 'PM10',
- };
- const area = isNaN(city) ? city : `@${city}`;
-
- const response = await got({
- method: 'get',
- url: `http://aqicn.org/aqicn/json/android/${area}/json`,
- });
- const data = response.data;
-
- const pollutionDetailed =
- pollution.length === 0
- ? ''
- : pollution.split(',').reduce((result, item) => {
- result += `${pollutionType[item].toUpperCase()}:${
- typeof data.historic[pollutionType[item]] === 'object' ? data.historic[pollutionType[item]][Object.keys(data.historic[pollutionType[item]])[0]] : data.historic[pollutionType[item]][0]
- } ` +
- ` Developer ${developer} ` +
- (rating ? ` Bookmarks ${bookmarks} ` : '') +
- (downloads ? ` Rating ${rating} ` : '') +
- (discount ? ` Downloads ${downloads} ` : '') +
- (oldPrice ? ` Discount ${discount} ` : '') +
- (newPrice ? ` Old Price ${oldPrice} ` : '') +
- ' New Price ${newPrice}
`;
- return result;
- }, '');
-
- ctx.state.data = {
- title: `${data.namena}AQI`,
- link: `https://aqicn.org/city/${data.ids.path}`,
- description: `${data.namena}AQI-aqicn.org`,
- item: [
- {
- title: `${data.namena}实时空气质量(AQI)${data.utimecn}`,
- description: `${data.infocn}
风力:${data.cwind[0]}级
AQI:${data.aqi}
${pollutionDetailed}`,
- pubDate: new Date(data.time * 1000).toUTCString(),
- guid: data.time,
- link: `https://aqicn.org/city/${data.ids.path}`,
- },
- ],
- };
-};
diff --git a/lib/routes-deprecated/archdaily/home.js b/lib/routes-deprecated/archdaily/home.js
deleted file mode 100644
index 16c9f4257d4c..000000000000
--- a/lib/routes-deprecated/archdaily/home.js
+++ /dev/null
@@ -1,47 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const parser = require('@/utils/rss-parser');
-
-module.exports = async (ctx) => {
- const feed = await parser.parseURL('https://feeds.feedburner.com/ArchdailyCN');
-
- const ProcessFeed = async (link) => {
- const response = await got({
- method: 'get',
- url: link,
- });
-
- const $ = cheerio.load(response.data);
-
- // 提取内容
- return $('#single-content').html();
- };
-
- const items = await Promise.all(
- feed.items.map(async (item) => {
- const cache = await ctx.cache.get(item.link);
- if (cache) {
- return JSON.parse(cache);
- }
-
- const description = await ProcessFeed(item.link);
-
- const single = {
- title: item.title,
- description,
- pubDate: item.pubDate,
- link: item.link,
- author: item.author,
- };
- ctx.cache.set(item.link, JSON.stringify(single));
- return single;
- })
- );
-
- ctx.state.data = {
- title: feed.title,
- link: feed.link,
- description: feed.description,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/arxiv/query.js b/lib/routes-deprecated/arxiv/query.js
deleted file mode 100644
index af519be77cf4..000000000000
--- a/lib/routes-deprecated/arxiv/query.js
+++ /dev/null
@@ -1,28 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const currentUrl = `http://export.arxiv.org/api/query?${ctx.params.query}`;
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
- const $ = cheerio.load(response.data);
- const list = $('entry')
- .map((_, item) => {
- item = $(item);
- return {
- title: item.find('title').text(),
- link: item.find('link[type="text/html"]').attr('href'),
- pubDate: new Date(item.find('published').text()).toUTCString(),
- description: item.find('summary').text(),
- };
- })
- .get();
-
- ctx.state.data = {
- title: 'arXiv (' + ctx.params.query + ')',
- link: currentUrl,
- item: list,
- };
-};
diff --git a/lib/routes-deprecated/asahi/index.js b/lib/routes-deprecated/asahi/index.js
deleted file mode 100644
index 99afa07b94be..000000000000
--- a/lib/routes-deprecated/asahi/index.js
+++ /dev/null
@@ -1,90 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-const categories = {
- obituaries: '/obituaries',
- yoron: '/politics/yoron',
- baseball: '/sports/baseball',
- soccer: '/sports/soccer',
- sumo: '/sports/sumo',
- winter_figureskate: '/sports/winter/figureskate',
- golf: '/sports/golf',
- general: '/sports/general',
- olympics: '/olympics',
- paralympics: '/paralympics',
- eco: '/eco',
- igo: '/igo',
- shougi: '/shougi',
- eldercare: '/national/eldercare',
- hataraku: '/special/hataraku',
- food: '/culture/food',
- gassho: '/edu/gassho',
- suisogaku: '/edu/suisogaku',
- hagukumu: '/edu/hagukumu',
- msta: '/msta',
-};
-
-module.exports = async (ctx) => {
- const genre = ctx.params.genre || '';
- const category = ctx.params.category || '';
-
- const rootUrl = 'https://www.asahi.com';
- let currentUrl;
- if (genre) {
- if (category) {
- currentUrl = category in categories ? `${rootUrl}${categories[category]}` : `${rootUrl}/${genre}/list/${category}.html`;
- } else {
- currentUrl = `${rootUrl}/${genre}`;
- }
- } else {
- currentUrl = `${rootUrl}${'/news/history.html'}`;
- }
-
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
-
- const $ = cheerio.load(response.data);
-
- $('.Time').remove();
-
- const list = $('#MainInner .Section .List li a')
- .slice(0, 6)
- .map((_, item) => {
- item = $(item);
- const link = item.attr('href');
-
- return {
- link: link.includes('//') ? `https:${link}` : `${rootUrl}${link}`,
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: item.link,
- });
- const content = cheerio.load(detailResponse.data);
-
- content('._30SFw, .-Oj2D, .notPrint').remove();
-
- item.description = content('._3YqJ1').html();
- item.title = content('meta[name="TITLE"]').attr('content');
- item.pubDate = Date.parse(content('meta[name="pubdate"]').attr('content'));
-
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: $('title').text(),
- link: currentUrl,
- item: items,
- description: '朝日新聞社のニュースサイト、朝日新聞デジタルの社会ニュースについてのページです',
- };
-};
diff --git a/lib/routes-deprecated/asml/press-releases.js b/lib/routes-deprecated/asml/press-releases.js
deleted file mode 100644
index ce3bfd09d1ec..000000000000
--- a/lib/routes-deprecated/asml/press-releases.js
+++ /dev/null
@@ -1,39 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const rootUrl = 'https://www.asml.com';
- const currentUrl = `${rootUrl}/en/news/press-releases`;
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
-
- const list = response.data.match(//g).map((item) => ({
- link: `${rootUrl}${item.split('href="')[1].replace('">', '')}`,
- }));
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: item.link,
- });
- const content = cheerio.load(detailResponse.data);
-
- item.title = content('title').text().replace('| ASML', '');
- item.description = content('.longcopy').html();
- item.pubDate = new Date(detailResponse.data.match(/"datePublished": "(.*)",/)[1]).toUTCString();
-
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: 'Press releases | ASML',
- link: currentUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/autotrader/index.js b/lib/routes-deprecated/autotrader/index.js
deleted file mode 100644
index 25f03e385e0e..000000000000
--- a/lib/routes-deprecated/autotrader/index.js
+++ /dev/null
@@ -1,69 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const link = `https://www.autotrader.co.uk/results-car-search?${ctx.params.query}`;
- const response = await got.get(link);
-
- const $ = cheerio.load(response.data.html);
-
- const idList = $('li.search-page__result').slice(0, 10).get();
-
- const items = await Promise.all(
- idList.map(async (item) => {
- const link = `https://www.autotrader.co.uk/classified/advert/${item.attribs.id}`;
-
- const cache = await ctx.cache.get(link);
-
- if (cache) {
- return JSON.parse(cache);
- }
-
- const response = await got.get(link);
- const $ = cheerio.load(response.data);
-
- let keyFacts = '
';
- $('.keyFacts__list .keyFacts__label').each((i, e) => {
- keyFacts += ` ${$(e).text()} `;
- if ((i + 1) % 4 === 0) {
- keyFacts += '';
- }
- });
- keyFacts += ' ';
-
- $('.fpaSpecifications__economy .fpaSpecifications__listItem').each((i, e) => {
- keyFacts += ` ${$(e).find('.fpaSpecifications__term').text()}: ${$(e).find('.fpaSpecifications__description').text()} `;
- if ((i + 1) % 4 === 0) {
- keyFacts += '';
- }
- });
-
- keyFacts += '
';
-
- let images = '';
-
- $('.fpa-image-overlay img').each((i, e) => {
- images += `
`;
- });
-
- const description = keyFacts + images + $('meta[name="og:description"]').attr('content');
-
- const title = `「${$('.fpaGallery__priceLabel').text()}」${$('meta[name="og:title"]').attr('content')}`;
-
- const single = {
- title,
- description,
- pubDate: new Date().toISOString(),
- link,
- };
- ctx.cache.set(link, JSON.stringify(single));
- return single;
- })
- );
-
- ctx.state.data = {
- title: 'Auto Trader',
- link,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/av01/actor.js b/lib/routes-deprecated/av01/actor.js
deleted file mode 100644
index d5530a0f0658..000000000000
--- a/lib/routes-deprecated/av01/actor.js
+++ /dev/null
@@ -1,36 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const name = ctx.params.name;
- const url = ctx.params.type ? `https://www.av01.tv/actor/${name}&o=${ctx.params.type}` : `https://www.av01.tv/actor/${name}`;
-
- const response = await got({
- method: 'get',
- url,
- });
-
- const data = response.data;
-
- const $ = cheerio.load(data);
- const list = $('div.col-sm-6.col-md-4.col-lg-4');
-
- ctx.state.data = {
- title: `${name}的影片`,
- description: `${name}的影片`,
- link: `https://www.av01.tv/actor/${name}`,
- item:
- list &&
- list
- .map((index, item) => {
- item = $(item);
- const itemPicUrl = item.find('img').attr('data-src');
- return {
- title: item.find('span.video-title.title-truncate.m-t-5').text(),
- description: `翻译${item.find('div.video-added.title-truncate').text()}`,
- link: `https://www.av01.tv/${item.find('a').attr('href')}`,
- };
- })
- .get(),
- };
-};
diff --git a/lib/routes-deprecated/av01/tag.js b/lib/routes-deprecated/av01/tag.js
deleted file mode 100644
index bbea8663d44b..000000000000
--- a/lib/routes-deprecated/av01/tag.js
+++ /dev/null
@@ -1,36 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const name = ctx.params.name;
- const url = ctx.params.type ? `https://www.av01.tv/tag/${name}&o=${ctx.params.type}` : `https://www.av01.tv/tag/${name}`;
-
- const response = await got({
- method: 'get',
- url,
- });
-
- const data = response.data;
-
- const $ = cheerio.load(data);
- const list = $('div.col-sm-6.col-md-4.col-lg-4');
-
- ctx.state.data = {
- title: `${name}类型的影片`,
- description: `${name}类型的影片`,
- link: `https://www.av01.tv/tag/${name}`,
- item:
- list &&
- list
- .map((index, item) => {
- item = $(item);
- const itemPicUrl = item.find('img').attr('data-src');
- return {
- title: item.find('span.video-title.title-truncate.m-t-5').text(),
- description: `翻译${item.find('div.video-added.title-truncate').text()}
`,
- link: `https://www.av01.tv/${item.find('a').attr('href')}`,
- };
- })
- .get(),
- };
-};
diff --git a/lib/routes-deprecated/axis-studios/work.js b/lib/routes-deprecated/axis-studios/work.js
deleted file mode 100755
index 02fa74ecf0c2..000000000000
--- a/lib/routes-deprecated/axis-studios/work.js
+++ /dev/null
@@ -1,75 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const { type, tag } = ctx.params || '';
- const response = await got(`https://axisstudiosgroup.com/${type}/${tag}`);
- const data = response.data;
- const $ = cheerio.load(data); // 使用 cheerio 加载返回的 HTML
- const list = $('a.overlay-link')
- .toArray()
- .map((item) => {
- item = $(item);
- return {
- title: item.find('h2').text().trim(),
- link: new URL(item.attr('href'), 'https://axisstudiosgroup.com').href,
- };
- });
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const response2 = await got(item.link);
-
- const $2 = cheerio.load(response2.data);
-
- $2('.slider-nav').remove(); // 图片导航
- $2('.social-wrapper').remove(); // 社交按钮
- $2('source').remove(); // 莫名其妙的图片
- $2('video').remove(); // 视频标签
- $2('button').remove(); // 按钮
- $2('div.modal.fade').remove(); // 莫名奇妙的图片
- $2('i').remove();
- $2('*')
- .contents()
- .filter((_, el) => el.type === 'comment')
- .remove();
-
- const mcdrPlaylistControl = $2('.mcdr.playlist-control a');
- const youtube = mcdrPlaylistControl.data('video-type') === 'video/youtube' ? mcdrPlaylistControl.data('video-url').replace('https://www.youtube.com/watch?v=', '') : '';
- const mp4 = mcdrPlaylistControl.data('video-type') === 'video/mp4' ? mcdrPlaylistControl.data('video-url') : '';
-
- const content = $2('.container-fluid>div:nth-child(2)');
- content.find('video').attr('controls', 'controls');
- content.find('picture').each((_, el) => {
- el = $2(el);
- el.replaceWith(el.html());
- });
- content.find('div').each((_, el) => {
- el = $2(el);
- if (el.children().length) {
- el.replaceWith(el.children());
- }
- });
-
- let video = '';
- if (mp4) {
- video = `
`;
- }
- if (youtube) {
- video = `
`;
- }
-
- item.description = video + content.html();
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: `Axis Studios | ${type} ${tag ?? ''}`,
- link: 'http://axisstudiosgroup.com',
- description: $('description').text(),
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/babykingdom/index.js b/lib/routes-deprecated/babykingdom/index.js
deleted file mode 100644
index 953c204e4edc..000000000000
--- a/lib/routes-deprecated/babykingdom/index.js
+++ /dev/null
@@ -1,64 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const url = require('url');
-
-const host = 'https://www.baby-kingdom.com';
-
-module.exports = async (ctx) => {
- const id = ctx.params.id;
- const order = ctx.params.order;
-
- let link = `https://www.baby-kingdom.com/forum.php?mod=forumdisplay&fid=${id}`;
-
- switch (order) {
- case 'dateline':
- link += '&filter=author&orderby=dateline';
-
- break;
-
- case 'reply':
- link += '&filter=reply&orderby=replies';
-
- break;
-
- case 'view':
- link += '&filter=reply&orderby=views';
-
- break;
-
- case 'lastpost':
- link += '&filter=lastpost&orderby=lastpost';
-
- break;
-
- case 'heat':
- link += '&filter=heat&orderby=heats';
-
- break;
-
- default:
- // Do nothing
- }
-
- const response = await got.get(link);
- const $ = cheerio.load(response.data);
-
- const title = $('h1.xs2 a').text();
- const out = $('tbody[id^="normalthread"]')
- .slice(0, 10)
- .map(function () {
- const info = {
- title: $(this).find('td:nth-child(2) > a:nth-child(1)').text(),
- link: url.resolve(host, $(this).find('td:nth-child(2) > a:nth-child(1)').attr('href')),
- author: $(this).find('td.by.by_author cite a').text(),
- };
- return info;
- })
- .get();
-
- ctx.state.data = {
- title: `${title}-親子王國`,
- link,
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/bahamut/creation-index.js b/lib/routes-deprecated/bahamut/creation-index.js
deleted file mode 100644
index 64425d0885f0..000000000000
--- a/lib/routes-deprecated/bahamut/creation-index.js
+++ /dev/null
@@ -1,73 +0,0 @@
-const utils = require('./utils');
-
-const type_map = {
- 0: '達人專欄',
- 1: '達人專欄',
- 2: '最新創作',
- 3: '最新推薦',
- 4: '熱門創作',
- 5: '精選閣樓',
-};
-
-const category_map = {
- 0: '不限',
- 1: '日誌',
- 2: '小說',
- 3: '繪圖',
- 4: 'Cosplay',
- 5: '同人商品',
-};
-
-const subcategory_map = {
- 0: '不限',
- 1: 'ACG相關',
- 2: '生活休閒',
- 3: '巴哈相關',
- 4: '歡樂惡搞',
- 5: '心情日記',
- 6: '模型/公仔',
- 7: '視聽娛樂',
- 8: '興趣嗜好',
- 9: '其他',
- 10: '愛情',
- 11: '奇幻',
- 12: '科幻',
- 13: '武俠',
- 14: '推理驚悚',
- 15: '歡樂惡搞',
- 16: 'BL/GL',
- 17: '輕小說',
- 18: '其他',
- 19: '紙上塗鴉',
- 20: '草稿/線稿',
- 21: '單色人物',
- 22: '彩色人物',
- 23: '完稿作品',
- 24: '漫畫',
- 25: '勇者造型',
- 26: '其他',
- 27: 'ACG相關',
- 28: '特攝',
- 29: '布袋戲',
- 30: '電影',
- 31: '其他',
- 32: '男性向',
- 33: '女性向',
- 34: '其他',
-};
-
-module.exports = async (ctx) => {
- const type = ctx.params.type ?? '1';
- const category = ctx.params.category ?? '0';
- const subcategory = ctx.params.subcategory ?? '0';
-
- const url = `https://home.gamer.com.tw/index.php?k1=${category}&k2=${subcategory}&vt=${type}&sm=3`;
-
- const { items } = await utils.ProcessFeed(url, ctx);
-
- ctx.state.data = {
- title: `巴哈姆特创作大厅${category === '0' ? '' : ' - ' + category_map[category]}${subcategory === '0' ? '' : ' - ' + subcategory_map[subcategory]} - ${type_map[type]}`,
- link: url,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/bahamut/creation.js b/lib/routes-deprecated/bahamut/creation.js
deleted file mode 100644
index 571eccbb9f0e..000000000000
--- a/lib/routes-deprecated/bahamut/creation.js
+++ /dev/null
@@ -1,15 +0,0 @@
-const utils = require('./utils');
-
-module.exports = async (ctx) => {
- const author = ctx.params.author;
-
- const url = ctx.params.category ? `https://home.gamer.com.tw/creationCategory.php?owner=${author}&c=${ctx.params.category}` : `https://home.gamer.com.tw/creation.php?owner=${author}`;
-
- const { title, items } = await utils.ProcessFeed(url, ctx);
-
- ctx.state.data = {
- title,
- link: url,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/bahamut/utils.js b/lib/routes-deprecated/bahamut/utils.js
deleted file mode 100644
index 2f4cf6842c87..000000000000
--- a/lib/routes-deprecated/bahamut/utils.js
+++ /dev/null
@@ -1,65 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-const base = 'https://home.gamer.com.tw/';
-
-module.exports = {
- ProcessFeed: async (url, ctx) => {
- const response = await got.get(url);
- const $ = cheerio.load(response.data);
-
- const title = $('title').text();
- const list = $('.BH-lbox > .HOME-mainbox1').toArray();
-
- const parseContent = (htmlString) => {
- const $ = cheerio.load(htmlString);
- const content = $('.MSG-list8C');
-
- const images = $('img');
- for (const image of images) {
- $(image).attr('src', $(image).attr('data-src'));
- }
-
- return {
- description: content.html(),
- };
- };
-
- const items = await Promise.all(
- list.map(async (item) => {
- const $ = cheerio.load(item);
- const title = $('.HOME-mainbox1b > h1 > a');
- const link = base + title.attr('href');
- const author = $('.HOME-mainbox1b > .ST1 > a').text();
- const time = $('.HOME-mainbox1b > .ST1').text().split('│')[1];
-
- const cache = await ctx.cache.get(link);
- if (cache) {
- return JSON.parse(cache);
- }
-
- const topic = {
- title: title.text().trim(),
- link,
- author,
- pubDate: new Date(time),
- };
-
- try {
- const detail_response = await got.get(link);
- const result = parseContent(detail_response.data);
- if (!result.description) {
- return '';
- }
- topic.description = result.description;
- } catch {
- return '';
- }
- ctx.cache.set(link, JSON.stringify(topic));
- return topic;
- })
- );
-
- return { title, items };
- },
-};
diff --git a/lib/routes-deprecated/bandisoft/index.js b/lib/routes-deprecated/bandisoft/index.js
deleted file mode 100644
index ac71cef6f6a0..000000000000
--- a/lib/routes-deprecated/bandisoft/index.js
+++ /dev/null
@@ -1,42 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const { isValidHost } = require('@/utils/valid-host');
-
-module.exports = async (ctx) => {
- const lang = ctx.params.lang || 'en';
- const id = ctx.params.id || 'bandizip';
- if (!isValidHost(lang)) {
- throw new Error('Invalid language code');
- }
-
- const rootUrl = `https://${lang}.bandisoft.com`;
- const currentUrl = `${rootUrl}/${id}/history/`;
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
-
- const $ = cheerio.load(response.data);
-
- const items = $('h2')
- .map((_, item) => {
- item = $(item);
-
- const title = item.text();
- item.children('font').remove();
-
- return {
- title,
- link: currentUrl,
- description: item.next().html(),
- pubDate: new Date(item.text()).toUTCString(),
- };
- })
- .get();
-
- ctx.state.data = {
- title: $('title').text(),
- link: currentUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/banyuetan/byt.js b/lib/routes-deprecated/banyuetan/byt.js
deleted file mode 100644
index 9299a906bbd0..000000000000
--- a/lib/routes-deprecated/banyuetan/byt.js
+++ /dev/null
@@ -1,50 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const time = ctx.params.time || 'shishidashiku';
-
- const rootUrl = 'http://www.banyuetan.org';
- const currentUrl = `${rootUrl}/byt/${time}/index.html`;
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
-
- const $ = cheerio.load(response.data);
-
- const list = $('.byt_mian_image_list_con ul li a')
- .slice(0, 10)
- .map((_, item) => {
- item = $(item);
- return {
- link: item.attr('href'),
- title: item.attr('title'),
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: item.link,
- });
- const content = cheerio.load(detailResponse.data);
-
- item.description = content('#detail_content').html();
- item.author = content('.detail_tit_source').text().replace('来源:', '');
- item.pubDate = new Date(content('meta[property="og:release_date"]').attr('content')).toUTCString();
-
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: $('title').text(),
- link: currentUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/banyuetan/index.js b/lib/routes-deprecated/banyuetan/index.js
deleted file mode 100644
index c872ab834946..000000000000
--- a/lib/routes-deprecated/banyuetan/index.js
+++ /dev/null
@@ -1,56 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const name = ctx.params.name;
-
- const link = `http://www.banyuetan.org/byt/${name}/index.html`;
- const response = await got.get(link);
-
- const $ = cheerio.load(response.data);
-
- const list = $('ul.clearFix li')
- .slice(0, 10)
- .map(function () {
- const info = {
- title: $(this).find('h3 a').text(),
- link: $(this).find('h3 a').attr('href'),
- date: $(this).find('span.tag3').text(),
- };
- return info;
- })
- .get();
-
- const out = await Promise.all(
- list.map(async (info) => {
- const title = info.title;
- const date = info.date;
- const itemUrl = info.link;
-
- const cache = await ctx.cache.get(itemUrl);
- if (cache) {
- return JSON.parse(cache);
- }
-
- const response = await got.get(itemUrl);
-
- const $ = cheerio.load(response.data);
- const description = $('div.detail_content').html() || '文章已被删除';
-
- const single = {
- title,
- link: itemUrl,
- description,
- pubDate: new Date(date).toUTCString(),
- };
- ctx.cache.set(itemUrl, JSON.stringify(single));
- return single;
- })
- );
-
- ctx.state.data = {
- title: `${name}-半月谈`,
- link,
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/benedictevans/recent.js b/lib/routes-deprecated/benedictevans/recent.js
deleted file mode 100644
index 3f159fec367f..000000000000
--- a/lib/routes-deprecated/benedictevans/recent.js
+++ /dev/null
@@ -1,41 +0,0 @@
-const cheerio = require('cheerio');
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- const url = `https://www.ben-evans.com/benedictevans/`;
-
- const res = await got.get(url);
- const $ = cheerio.load(res.data);
- const list = $('section > article').get();
-
- const out = await Promise.all(
- list.map(async (item) => {
- const $ = cheerio.load(item);
- const title = $('.BlogList-item-title').text();
- const address = 'https://www.ben-evans.com' + $('.BlogList-item-title').attr('href');
- const time = $('.Blog-meta-item--date').text();
- const cache = await ctx.cache.get(address);
- if (cache) {
- return JSON.parse(cache);
- }
- const res = await got.get(address);
- const capture = cheerio.load(res.data);
- const contents = capture('.col.sqs-col-12.span-12').html();
- const single = {
- title,
- author: 'Benedict Evans',
- description: contents,
- link: address,
- guid: address,
- pubDate: new Date(time).toUTCString(),
- };
- ctx.cache.set(address, JSON.stringify(single));
- return single;
- })
- );
- ctx.state.data = {
- title: `Benedict Evans`,
- link: url,
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/bibgame/category.js b/lib/routes-deprecated/bibgame/category.js
deleted file mode 100644
index d86620b4332a..000000000000
--- a/lib/routes-deprecated/bibgame/category.js
+++ /dev/null
@@ -1,56 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const timezone = require('@/utils/timezone');
-
-module.exports = async (ctx) => {
- const category = ctx.params.category || 'pcgame';
- const type = ctx.params.type || '';
-
- const rootUrl = 'https://www.bibgame.com';
- const currentUrl = `${rootUrl}/${category}/${type}`;
-
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
-
- const $ = cheerio.load(response.data);
-
- const list = $('.info_box a')
- .slice(0, 15)
- .map((_, item) => {
- item = $(item);
- const link = item.attr('href');
-
- return {
- title: item.text(),
- link: link.includes('http') ? link : `${rootUrl}${link}`,
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: item.link,
- });
- const content = cheerio.load(detailResponse.data);
-
- content('#comment').parent().remove();
-
- item.description = content('.abstract').html();
- item.pubDate = timezone(new Date(content('.time_box').text().trim()), +8);
-
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: $('title').text(),
- link: currentUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/blogs/jingwei-link.js b/lib/routes-deprecated/blogs/jingwei-link.js
deleted file mode 100644
index 07d09f352a23..000000000000
--- a/lib/routes-deprecated/blogs/jingwei-link.js
+++ /dev/null
@@ -1,31 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const url = 'https://jingwei.link/';
- const response = await got({
- method: 'get',
- url,
- });
- const $ = cheerio.load(response.data);
- const resultItem = $("article[class='article-item']")
- .map((index, elem) => {
- elem = $(elem);
-
- const $esction = elem.find('section[class="post-preview"]');
-
- return {
- title: $esction.find('h2').text(),
- description: $esction.find('h3').text(),
- link: $esction.find('a').attr('href'),
- author: '敬维',
- };
- })
- .get();
-
- ctx.state.data = {
- title: '敬维-以认真的态度做完美的事情',
- link: url,
- item: resultItem,
- };
-};
diff --git a/lib/routes-deprecated/blogs/leemeng.js b/lib/routes-deprecated/blogs/leemeng.js
deleted file mode 100644
index c90f5e98a69d..000000000000
--- a/lib/routes-deprecated/blogs/leemeng.js
+++ /dev/null
@@ -1,30 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const url = 'https://leemeng.tw/blog.html';
- const response = await got({
- method: 'get',
- url,
- });
- const $ = cheerio.load(response.data);
- const resultItem = $('article')
- .map((index, elem) => {
- elem = $(elem);
- const $link = elem.find('[rel="bookmark"]');
- const title = $link.text();
- const link = $link.attr('href');
-
- return {
- title,
- link,
- };
- })
- .get();
-
- ctx.state.data = {
- title: 'LeeMeng - 部落格',
- link: url,
- item: resultItem,
- };
-};
diff --git a/lib/routes-deprecated/blogs/wang54.js b/lib/routes-deprecated/blogs/wang54.js
deleted file mode 100644
index 875d6212762f..000000000000
--- a/lib/routes-deprecated/blogs/wang54.js
+++ /dev/null
@@ -1,24 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const id = ctx.params.id || 2020;
- const url = `https://wangwusiwj.blogspot.com/${id}`;
- const response = await got({ method: 'get', url });
- const $ = cheerio.load(response.data);
-
- const list = $('div.post')
- .map((i, e) => ({
- title: $(e).find('h3 > a').text(),
- description: $(e).find('.post-body').html(),
- link: $(e).find('h3 > a').attr('href'),
- author: '王五四',
- }))
- .get();
-
- ctx.state.data = {
- title: '王五四文集',
- link: url,
- item: list,
- };
-};
diff --git a/lib/routes-deprecated/blogs/wangyin.js b/lib/routes-deprecated/blogs/wangyin.js
deleted file mode 100644
index bfe892fafc74..000000000000
--- a/lib/routes-deprecated/blogs/wangyin.js
+++ /dev/null
@@ -1,50 +0,0 @@
-const { parseDate } = require('@/utils/parse-date');
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const url = 'https://www.yinwang.org';
- const response = await got({ method: 'get', url });
- const $ = cheerio.load(response.data);
-
- const list = $("li[class='list-group-item title']")
- .map((i, e) => {
- const element = $(e);
- const title = element.find('a').text();
- const link = url + element.find('a').attr('href');
- const dateraw = /\d{4}(?:\/\d{2}){2}/.exec(link)[0];
-
- return {
- title,
- description: '',
- link,
- author: '王垠',
- pubDate: parseDate(dateraw, 'YYYY/MM/DD'),
- };
- })
- .get();
-
- const result = await Promise.all(
- list.map(async (item) => {
- const link = item.link;
-
- const cache = await ctx.cache.get(link);
- if (cache) {
- return JSON.parse(cache);
- }
-
- const itemReponse = await got.get(link);
- const itemElement = cheerio.load(itemReponse.data);
- item.description = itemElement('.inner').html();
-
- ctx.cache.set(link, JSON.stringify(item));
- return item;
- })
- );
-
- ctx.state.data = {
- title: '王垠的博客 - 当然我在扯淡',
- link: url,
- item: result,
- };
-};
diff --git a/lib/routes-deprecated/blow-studio/work.js b/lib/routes-deprecated/blow-studio/work.js
deleted file mode 100755
index 930677dabea4..000000000000
--- a/lib/routes-deprecated/blow-studio/work.js
+++ /dev/null
@@ -1,71 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const response = await got({
- method: 'get',
- url: `https://www.blowstudio.es/work/`,
- });
- const data = response.data;
- const $ = cheerio.load(data); // 使用 cheerio 加载返回的 HTML
- const list = $('.portfolios.normal > ul > li').get().slice(0, 10);
- const articledata = await Promise.all(
- list.map(async (item) => {
- const link = `https://www.blowstudio.es${$(item).find('a').attr('href')}/`;
-
- const cache = await ctx.cache.get(link);
- if (cache) {
- return JSON.parse(cache);
- }
-
- const response2 = await got({
- method: 'get',
- url: link,
- });
-
- const articleHtml = response2.data;
- const $2 = cheerio.load(articleHtml);
- const imglist = $2('div.attachment-grid img').get();
- const mainvideo = $2('.single-page-vimeo-div').attr('data-video-id');
-
- const img = imglist.map((item) => ({
- img: $2(item).attr('src'),
- }));
- const single = {
- mainvideo,
- describe: $2('div.portfolio-content > div:nth-child(2)').html(),
- title: $2('div.portfolio-content > div:nth-child(1)').text(),
- images: img,
- link,
- };
- ctx.cache.set(link, JSON.stringify(single));
- return single;
- })
- );
-
- ctx.state.data = {
- title: 'Blow Studio',
- link: 'http://blowstudio.es',
- description: $('description').text(),
- item: list.map((item, index) => {
- let content = '';
- const videostyle = `width="640" height="360"`;
- const imgstyle = `style="max-width: 650px; height: auto; object-fit: contain; flex: 0 0 auto;"`;
-
- content += `
`;
- content += articledata[index].describe;
-
- if (articledata[index].images) {
- for (let p = 0; p < articledata[index].images.length; p++) {
- content += `
`;
- }
- }
-
- return {
- title: articledata[index].title,
- description: content,
- link: articledata[index].link,
- };
- }),
- };
-};
diff --git a/lib/routes-deprecated/blur-studio/index.js b/lib/routes-deprecated/blur-studio/index.js
deleted file mode 100755
index fca85e18bae5..000000000000
--- a/lib/routes-deprecated/blur-studio/index.js
+++ /dev/null
@@ -1,79 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const response = await got({
- method: 'get',
- url: `http://blur.com`,
- });
- const data = response.data;
- const $ = cheerio.load(data); // 使用 cheerio 加载返回的 HTML
- const list = $('.page-title a').get();
- const articledata = await Promise.all(
- list.map(async (item) => {
- const link = $(item).attr('href');
- const cache = await ctx.cache.get(link);
- if (cache) {
- return JSON.parse(cache);
- }
- const response2 = await got({
- method: 'get',
- url: link,
- });
-
- const articleHtml = response2.data;
- const $2 = cheerio.load(articleHtml);
- const imglist = $2('.gridded img').get();
- const videolist = $2('.gridded iframe').get();
- const img = imglist.map((item) => ({
- img: $2(item).attr('src'),
- }));
- const video = videolist.map((item) => ({
- video: $2(item).attr('src'),
- }));
- const single = {
- mainvideo: $2('div.project-title').attr('data-video'),
- describe: $2('p').text(),
- title: $2('h1.page-title').text(),
- client: $2('div.client').text(),
- images: img,
- video,
- link,
- };
- ctx.cache.set(link, JSON.stringify(single));
- return single;
- })
- );
-
- ctx.state.data = {
- title: 'Blur Studio',
- link: 'http://blur.com',
- description: $('description').text(),
- item: list.map((item, index) => {
- const Num = /\d+/;
- let content = '';
- const videostyle = `width="640" height="360"`;
- const imgstyle = `style="max-width: 650px; height: auto; object-fit: contain; flex: 0 0 auto;"`;
- content += `Client:${articledata[index].client}
${articledata[index].describe}`;
- content += Num.test(articledata[index].mainvideo)
- ? `
`
- : `
`;
- if (articledata[index].images) {
- for (let p = 0; p < articledata[index].images.length; p++) {
- content += `
`;
- }
- }
- if (articledata[index].video) {
- for (let v = 0; v < articledata[index].video.length; v++) {
- content += `
`;
- }
- }
-
- return {
- title: articledata[index].title,
- description: content,
- link: articledata[index].link,
- };
- }),
- };
-};
diff --git a/lib/routes-deprecated/bookwalkertw/news.js b/lib/routes-deprecated/bookwalkertw/news.js
deleted file mode 100644
index 5db85cb44a02..000000000000
--- a/lib/routes-deprecated/bookwalkertw/news.js
+++ /dev/null
@@ -1,32 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const response = await got({
- method: 'get',
- url: 'https://www.bookwalker.com.tw/search?order=sell_desc&series_display=1&d=1',
- });
-
- const data = response.data;
-
- const $ = cheerio.load(data);
- const list = $('div[class="bwbookitem"]');
- let bookid;
- ctx.state.data = {
- title: 'BOOKWALKERTW热门新书',
- link: 'https://www.bookwalker.com.tw/search?order=sell_desc&series_display=1&d=1',
- item:
- list &&
- list
- .map((index, item) => {
- item = $(item);
- bookid = item.find('img').attr('data-src').split('/')[4];
- return {
- title: item.find('.bookname').text(),
- description: `${item.find('.booknamesub').text()} | ${item.find('.bprice').text()}
`,
- link: item.find('a').attr('href'),
- };
- })
- .get(),
- };
-};
diff --git a/lib/routes-deprecated/booth-pm/shop.js b/lib/routes-deprecated/booth-pm/shop.js
deleted file mode 100644
index 6577e600ac66..000000000000
--- a/lib/routes-deprecated/booth-pm/shop.js
+++ /dev/null
@@ -1,58 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const { isValidHost } = require('@/utils/valid-host');
-const maxPages = 5;
-
-module.exports = async (ctx) => {
- const { subdomain } = ctx.params;
- if (!isValidHost(subdomain)) {
- throw new Error('Invalid subdomain');
- }
- const shopUrl = `https://${subdomain}.booth.pm`;
-
- let shopName;
- const items = [];
- for (let page = 1; page <= maxPages; page++) {
- const pageUrl = `${shopUrl}/items?page=${page}`;
- // eslint-disable-next-line no-await-in-loop
- const response = await got({
- method: 'get',
- url: pageUrl,
- });
-
- const data = response.data;
-
- const $ = cheerio.load(data);
- shopName = $('div.shop-name > span').text();
- const pageItems = $('li.item');
-
- if (pageItems.length === 0) {
- break;
- }
-
- for (const pageItem of pageItems) {
- // extract item name
- const itemName = $('h2.item-name > a', pageItem).text();
-
- // extract item url
- const itemUrl = shopUrl + $('h2.item-name > a', pageItem).attr('href');
-
- // extract item preview url
- const itemPreviewUrl = $('div.swap-image > img', pageItem).attr('src');
-
- items.push({
- title: itemName,
- description: ``,
- link: itemUrl,
- });
- }
- }
-
- ctx.state.data = {
- title: shopName,
- link: shopUrl,
- description: shopName,
- allowEmpty: true,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/bsblog123/index.js b/lib/routes-deprecated/bsblog123/index.js
deleted file mode 100644
index e1aa98fe9dbd..000000000000
--- a/lib/routes-deprecated/bsblog123/index.js
+++ /dev/null
@@ -1,29 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const baseUrl = 'https://bsblog123.com/';
- const response = await got({
- method: 'get',
- url: baseUrl,
- });
- const $ = cheerio.load(response.data); // 使用 cheerio 加载返回的 HTML
- const list = $('div[class="whitebg bloglist"] li');
- ctx.state.data = {
- title: `冰山博客 ~ 资讯`,
- link: `https://bsblog123.com`,
- description: '冰山博客 ~ 资讯',
- item:
- list &&
- list
- .map((index, item) => {
- item = $(item);
- return {
- title: $('h3.blogtitle', item).text(),
- link: $('h3 a', item).attr('href'),
- description: $('p', item).text(),
- };
- })
- .get(),
- };
-};
diff --git a/lib/routes-deprecated/cbndata/information.js b/lib/routes-deprecated/cbndata/information.js
deleted file mode 100644
index f69573986691..000000000000
--- a/lib/routes-deprecated/cbndata/information.js
+++ /dev/null
@@ -1,52 +0,0 @@
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- const category = ctx.params.category || '';
-
- const rootUrl = 'https://www.cbndata.com';
- const apiUrl = `${rootUrl}/api/v3/informations?page=1&per_page=10${category ? `&tag_id=${category}` : ''}`;
-
- const response = await got({
- method: 'get',
- url: apiUrl,
- });
-
- const list = response.data.data.map((item) => ({
- title: item.id,
- link: `${rootUrl}/api/v3/informations/show?id=${item.id}`,
- pubDate: Date.parse(item.date),
- }));
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: item.link,
- });
-
- item.link = `${rootUrl}/information/${item.title}`;
-
- item.title = detailResponse.data.data.title;
- item.author = detailResponse.data.data.author;
- item.description = detailResponse.data.data.content;
-
- return item;
- })
- )
- );
-
- let title = '看点';
-
- for (const tag of response.data.home_tags) {
- if (tag.id.toString() === category) {
- title = tag.name;
- break;
- }
- }
- ctx.state.data = {
- title: `${title} - CBNData消费站`,
- link: `${rootUrl}/information${category ? `?tag_id=${category}` : ''}`,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/ccg/index.js b/lib/routes-deprecated/ccg/index.js
deleted file mode 100644
index d22bdbd8ab81..000000000000
--- a/lib/routes-deprecated/ccg/index.js
+++ /dev/null
@@ -1,49 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const category = ctx.params.category || 'news';
-
- const rootUrl = 'http://www.ccg.org.cn';
- const currentUrl = `${rootUrl}/${category}`;
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
-
- const $ = cheerio.load(response.data);
-
- const list = $('.huodong-list li a')
- .slice(0, 10)
- .map((_, item) => {
- item = $(item);
- return {
- link: item.attr('href'),
- title: item.find('h5').text(),
- pubDate: new Date(item.find('span').text().replaceAll(/年|月/g, '-').replace(/日/, '')).toUTCString(),
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: item.link,
- });
- const content = cheerio.load(detailResponse.data);
-
- item.description = content('.pinpai-page').html();
-
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: `${$('title').text()} - 全球化智库`,
- link: currentUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/cell/cell/index.js b/lib/routes-deprecated/cell/cell/index.js
deleted file mode 100644
index 95f7df67541e..000000000000
--- a/lib/routes-deprecated/cell/cell/index.js
+++ /dev/null
@@ -1,113 +0,0 @@
-// cell.com is extremely slow, and redirect too many times.
-// Thus, the content page are replaced by www.sciencedirect.com.
-
-const cheerio = require('cheerio');
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- const baseURL = 'https://www.cell.com';
- const category = ctx.params.category;
- let pageURL = `${baseURL}/cell/current.rss`;
- let categoryTitle = 'Latest issue';
- if (category === 'inpress') {
- pageURL = `${baseURL}/cell/inpress.rss`;
- categoryTitle = 'Articles in press';
- }
-
- const alternativeURL = 'https://www.sciencedirect.com/science/article/pii/';
- const pageResponse = await got.get(pageURL);
- const pageCapture = cheerio.load(pageResponse.data);
-
- const list = pageCapture('item')
- .get()
- .filter((item) => {
- const $ = cheerio.load(item);
- const section = $('prism\\:section').text();
-
- return ['Article', 'Resource'].includes(section);
- });
-
- const out = await Promise.all(
- list.map(async (item) => {
- const $ = cheerio.load(item);
- const section = $('prism\\:section').text();
- const address = alternativeURL + $('item').attr('rdf:about').replace('?rss=yes', '').split('/').pop();
- const title = $('dc\\:title').text();
- const author = $('dc\\:creator').text();
- const pubDate = new Date($('dc\\:date').text()).toUTCString();
- const cache = await ctx.cache.get(address);
- if (cache) {
- return JSON.parse(cache);
- }
- const itemPage = await got.get(address);
- const itemCapture = cheerio.load(itemPage.data);
- // section + keywords content
- const keywords = itemCapture('div.keywords-section > div.keyword')
- .map((i, el) => $(el).text())
- .get()
- .join('; ');
- const sectionContents = `
-
- Graphical Abstract
-
-
Highlights
- ${highlight}
- Summary
- ${summary}
- `, desc].join('
'),
- };
- })
- .get();
- ctx.state.data = {
- title: `中国日报 - ${categoryName}`,
- description: `中国日报 - ${categoryName}`,
- link: url,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/chinafile/index.js b/lib/routes-deprecated/chinafile/index.js
deleted file mode 100644
index 5cc5bf179057..000000000000
--- a/lib/routes-deprecated/chinafile/index.js
+++ /dev/null
@@ -1,71 +0,0 @@
-const Parser = require('rss-parser');
-const cheerio = require('cheerio');
-const got = require('@/utils/got');
-const dayjs = require('dayjs');
-
-module.exports = async (ctx) => {
- const category = ctx.params.category || 'all';
- const rssUrl = `https://feeds.feedburner.com/chinafile/${category}`;
-
- // The custom UA in @/utils/parser (mimic browser) results in a HTML page
- // which cannot be parsed
- const parser = new Parser();
- const feed = await parser.parseURL(rssUrl);
-
- const items = await Promise.all(
- feed.items.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- let url = item.link;
- const response = await got({ url });
- const html = response.body;
- const $ = cheerio.load(html);
- const content = $('article');
-
- // Cover
- const cover = $('.view-featured-photo');
-
- if (cover.length > 0) {
- cover.insertBefore(content[0].childNodes[0]);
- $(cover).remove();
- }
-
- // Summary
- const summary = $('meta[name="description"]').attr('content');
- const updatedAt = $('meta[name="og:updated_time"]').attr('content');
-
- const categories = $('meta[name="news_keywords"]')
- .attr('content')
- .split(',')
- .map((c) => c.trim());
-
- url = $('link[rel="canonical"]').attr('href');
-
- const pubDate = dayjs(item.pubDate.replace(' - ', ' ').replace('am', ' am').replace('pm', ' pm'));
-
- return {
- title: item.title,
- id: item.guid,
- pubDate,
- updated: updatedAt,
- author: item.creator,
- link: url,
- summary,
- description: content.html(),
- category: categories,
- icon: 'https://www.chinafile.com/sites/default/files/chinafile_favicon.png',
- logo: 'https://www.chinafile.com/sites/all/themes/cftwo/assets/images/logos/logo-large.png',
- };
- })
- )
- );
-
- ctx.state.data = {
- title: feed.title,
- link: feed.link,
- description: feed.description,
- item: items,
- language: 'en-us',
- icon: 'https://www.chinafile.com/sites/default/files/chinafile_favicon.png',
- logo: 'https://www.chinafile.com/sites/all/themes/cftwo/assets/images/logos/logo-large.png',
- };
-};
diff --git a/lib/routes-deprecated/chocolatey/software.js b/lib/routes-deprecated/chocolatey/software.js
deleted file mode 100644
index ac4770284c45..000000000000
--- a/lib/routes-deprecated/chocolatey/software.js
+++ /dev/null
@@ -1,55 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-async function get_software_raw_html(link) {
- const response = await got({
- method: 'get',
- url: link,
- });
- return response.body;
-}
-
-function pick_versions(raw_html) {
- const $ = cheerio.load(raw_html);
- const items = [];
- $('#versionhistory table tbody tr').each((_row_index, row) => {
- const software = {};
- $('td', row).each((col_index, col) => {
- if ($(col).hasClass('version')) {
- const href = $('a', col).attr('href');
- let version = '';
- if (href) {
- version = href.split('/').at(-1);
- }
- software.version = version;
- }
- if (col_index === 0) {
- software.software = $(col).text().trim();
- }
- if (col_index === 2) {
- software.time = $(col).text();
- }
- });
- items.push(software);
- });
- return items;
-}
-
-module.exports = async (ctx) => {
- const software_name = ctx.params.name;
-
- const software_link = `https://chocolatey.org/packages/${software_name}`;
- const raw = await get_software_raw_html(software_link);
- const items = pick_versions(raw);
-
- const rsshub_object = {
- title: software_name,
- link: software_link,
- item: items.map((i) => {
- const link = `https://chocolatey.org/packages/${software_name}/${i.version}`;
- const ret = { title: i.software, link, description: `update_time: ${i.time}` };
- return ret;
- }),
- };
- ctx.state.data = rsshub_object;
-};
diff --git a/lib/routes-deprecated/chouti/index.js b/lib/routes-deprecated/chouti/index.js
deleted file mode 100644
index 97fcee0c3e5c..000000000000
--- a/lib/routes-deprecated/chouti/index.js
+++ /dev/null
@@ -1,35 +0,0 @@
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- const subject = ctx.params.subject || 'hot';
- const host = 'https://m.chouti.com';
- let api = `${host}/api/m/zone/${subject}?afterTime=0`;
- let pageUrl = `https://m.chouti.com/zone/${subject}`;
- if (subject === 'hot') {
- api = `${host}/api/m/link/hot?afterTime=0`;
- pageUrl = `https://m.chouti.com/all/hot`;
- }
-
- const response = await got({
- method: 'get',
- url: api,
- headers: {
- Referer: host,
- },
- });
-
- const resultItem = response.data.data.map((item) => ({
- title: item.title,
- author: item.nick,
- description: `${item.title}
评论`,
- link: item.url,
- pubDate: new Date(item.created_time / 1000).toUTCString(),
- }));
-
- ctx.state.data = {
- title: '抽屉新热榜',
- description: '抽屉新热榜,汇聚每日搞笑段子、热门图片、有趣新闻。它将微博、门户、社区、bbs、社交网站等海量内容聚合在一起,通过用户推荐生成最热榜单。看抽屉新热榜,每日热门、有趣资讯尽收眼底。',
- link: pageUrl,
- item: resultItem,
- };
-};
diff --git a/lib/routes-deprecated/chouti/top.js b/lib/routes-deprecated/chouti/top.js
deleted file mode 100644
index ced62f5514b6..000000000000
--- a/lib/routes-deprecated/chouti/top.js
+++ /dev/null
@@ -1,28 +0,0 @@
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- const hour = ctx.params.hour || '24';
-
- const response = await got({
- method: 'get',
- url: `https://dig.chouti.com/top/${hour}hr?_=${Date.now()}`,
- headers: {
- Referer: 'https://dig.chouti.com/',
- },
- });
-
- const resultItem = response.data.data.map((item) => ({
- title: item.title,
- author: item.nick,
- description: `${item.title}
评论`,
- link: item.url,
- pubDate: new Date(item.created_time / 1000).toUTCString(),
- }));
-
- ctx.state.data = {
- title: `抽屉新热榜-${hour}小时最热榜`,
- description: '抽屉新热榜,汇聚每日搞笑段子、热门图片、有趣新闻。它将微博、门户、社区、bbs、社交网站等海量内容聚合在一起,通过用户推荐生成最热榜单。看抽屉新热榜,每日热门、有趣资讯尽收眼底。',
- link: 'https://dig.chouti.com/',
- item: resultItem,
- };
-};
diff --git a/lib/routes-deprecated/chsi/zszcgd.js b/lib/routes-deprecated/chsi/zszcgd.js
deleted file mode 100644
index b96605aa5c26..000000000000
--- a/lib/routes-deprecated/chsi/zszcgd.js
+++ /dev/null
@@ -1,51 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const category = ctx.params.category || 'dnzszc';
-
- const rootUrl = 'https://gaokao.chsi.com.cn';
- const currentUrl = `${rootUrl}/gkxx/zszcgd/${category}`;
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
-
- const $ = cheerio.load(response.data);
-
- const list = $('.list ul li a')
- .slice(0, 15)
- .map((_, item) => {
- item = $(item);
- const link = item.attr('href');
-
- return {
- title: item.text(),
- pubDate: new Date(item.prev().text()).toUTCString(),
- link: link.includes('http') ? link : `${rootUrl}${link}`,
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: item.link,
- });
- const content = cheerio.load(detailResponse.data);
-
- item.description = content('.list').html();
-
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: `${$('.backb').text()} - 教育部阳光高考信息公开平台`,
- link: currentUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/chuhaibiji/index.js b/lib/routes-deprecated/chuhaibiji/index.js
deleted file mode 100644
index 2ff03882a818..000000000000
--- a/lib/routes-deprecated/chuhaibiji/index.js
+++ /dev/null
@@ -1,30 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const baseUrl = 'https://www.chuhaibiji.com/';
- const response = await got({
- method: 'get',
- url: baseUrl,
- });
- const $ = cheerio.load(response.data); // 使用 cheerio 加载返回的 HTML
- const list = $('ul[class="post-loop post-loop-default tab-wrap clearfix active"] li[class="item"]');
- ctx.state.data = {
- title: `出海笔记 ~ 资讯`,
- link: `https://www.secshi.com/`,
- description: '出海笔记 ~ 资讯',
- item:
- list &&
- list
- .map((index, item) => {
- item = $(item);
- return {
- title: $('h2 a', item).text(),
- link: $('h2 a', item).attr('href'),
- description: $('p', item).text(),
- pubDate: new Date($('span[class="item-meta-li date"]', item).text()).toUTCString(),
- };
- })
- .get(),
- };
-};
diff --git a/lib/routes-deprecated/citavi/index.js b/lib/routes-deprecated/citavi/index.js
deleted file mode 100644
index b308ca646744..000000000000
--- a/lib/routes-deprecated/citavi/index.js
+++ /dev/null
@@ -1,52 +0,0 @@
-const url = require('url');
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const { parseRelativeDate } = require('@/utils/parse-date');
-
-module.exports = async (ctx) => {
- ctx.params.caty = ctx.params.caty || '';
- ctx.params.caty = ctx.params.caty === '' ? '' : `/navi/${ctx.params.caty}`;
-
- const rootUrl = 'http://forum.softhead-citavi.com';
- const currentUrl = `${rootUrl}${ctx.params.caty}`;
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
-
- const $ = cheerio.load(response.data);
-
- const list = $('h5.media-heading a')
- .slice(0, 10)
- .map((_, item) => {
- item = $(item);
- return {
- title: item.text(),
- link: url.resolve(currentUrl, item.attr('href')),
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: item.link,
- });
- const content = cheerio.load(detailResponse.data);
-
- item.description = content('div.panel-body').html();
- item.pubDate = parseRelativeDate(content('small.gray').eq(0).text().split(' • ')[1]);
-
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: `${$('a.current').text()} - Citavi 中文网站论坛`,
- link: currentUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/clb/commentary.js b/lib/routes-deprecated/clb/commentary.js
deleted file mode 100644
index cb98ebf2476f..000000000000
--- a/lib/routes-deprecated/clb/commentary.js
+++ /dev/null
@@ -1,48 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const lang = ctx.params.lang || '';
-
- const rootUrl = 'https://clb.org.hk';
- const currentUrl = `${rootUrl}/${lang === '' ? '/zh-hans/section/%E8%AF%84%E8%AE%BA%E4%B8%8E%E7%89%B9%E5%86%99' : 'commentary-and-analysis'}`;
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
- const $ = cheerio.load(response.data);
-
- const list = $('.field-content a')
- .slice(0, 10)
- .map((_, item) => {
- item = $(item);
- return {
- title: item.text(),
- link: `${rootUrl}${item.attr('href')}`,
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: item.link,
- });
- const content = cheerio.load(detailResponse.data);
-
- item.description = content('.field-name-body').html();
- item.pubDate = new Date(content('meta[property="article:published_time"]').attr('content')).toUTCString();
-
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: $('title').text(),
- link: currentUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/cninfo/announcement.js b/lib/routes-deprecated/cninfo/announcement.js
deleted file mode 100644
index 9645d796705d..000000000000
--- a/lib/routes-deprecated/cninfo/announcement.js
+++ /dev/null
@@ -1,73 +0,0 @@
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- const column = ctx.params.column; // szse 深圳证券交易所; sse 上海证券交易所; hke 港股; fund 基金
- const code = ctx.params.code; // 股票代码
- const orgId = ctx.params.orgId;
- const category = ctx.params.category || 'all'; // 分类
- const searchKey = ctx.params.search || ''; // 标题关键字
- let plate = '';
-
- const url = `http://www.cninfo.com.cn/new/disclosure/stock?stockCode=${code}&orgId=${orgId}`;
- const apiUrl = `http://www.cninfo.com.cn/new/hisAnnouncement/query`;
- switch (column) {
- case 'szse':
- plate = 'sz';
- break;
- case 'sse':
- plate = 'sh';
- break;
- case 'third':
- plate = 'neeq';
- break;
- case 'hke':
- plate = 'hke';
- break;
- case 'fund':
- plate = 'fund';
- break;
- }
- const response = await got.post(apiUrl, {
- headers: {
- Referer: url,
- },
- form: {
- stock: `${code},${orgId}`,
- tabName: 'fulltext',
- pageSize: 30,
- pageNum: 1,
- column,
- category: category === 'all' ? '' : category,
- plate,
- seDate: '',
- searchkey: searchKey,
- secid: '',
- sortName: '',
- sortType: '',
- isHLtitle: true,
- },
- });
- const announcementsList = response.data.announcements;
-
- let name = '';
- const out = announcementsList.map((item) => {
- const title = item.announcementTitle;
- const date = item.announcementTime;
- const announcementTime = new Date(item.announcementTime).toISOString().slice(0, 10);
- const link = 'http://www.cninfo.com.cn/new/disclosure/detail' + `?plate=${plate}` + `&orgId=${orgId}` + `&stockCode=${code}` + `&announcementId=${item.announcementId}` + `&announcementTime=${announcementTime}`;
- name = item.secName;
-
- const single = {
- title,
- link,
- pubDate: new Date(date).toUTCString(),
- };
-
- return single;
- });
- ctx.state.data = {
- title: `${name}公告-巨潮资讯`,
- link: url,
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/cnu/discovery.js b/lib/routes-deprecated/cnu/discovery.js
deleted file mode 100644
index b0681139dc74..000000000000
--- a/lib/routes-deprecated/cnu/discovery.js
+++ /dev/null
@@ -1,59 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const utils = require('./utils');
-
-const types = {
- hot: '热门',
- recommend: '推荐',
- recent: '最新',
-};
-
-module.exports = async (ctx) => {
- const type = ctx.params.type ?? 'hot';
- const category = ctx.params.category ?? '0';
- const category_name = category === '0' ? '全部' : category;
-
- const url = `http://www.cnu.cc/discoveryPage/${type}-${encodeURIComponent(category)}`;
-
- const list_response = await got.get(url);
- const $ = cheerio.load(list_response.data);
-
- const list = $('.grid-item.work-thumbnail').toArray();
-
- const out = await Promise.all(
- list.map(async (item) => {
- const $ = cheerio.load(item);
- const title = $('.title');
- const link = $('a.thumbnail').attr('href');
-
- const cache = await ctx.cache.get(link);
- if (cache) {
- return JSON.parse(cache);
- }
-
- const rssitem = {
- title: title.text().trim(),
- link,
- };
-
- try {
- const response = await got.get(link);
- const result = utils.parseContent(response.data);
-
- rssitem.author = result.author;
- rssitem.description = result.description;
- rssitem.pubDate = result.pubDate;
- } catch {
- return '';
- }
- ctx.cache.set(link, JSON.stringify(rssitem));
- return rssitem;
- })
- );
-
- ctx.state.data = {
- title: `CNU视觉联盟 - ${types[type]} - ${category_name}`,
- link: url,
- item: out.filter((item) => item !== ''),
- };
-};
diff --git a/lib/routes-deprecated/cnu/selected.js b/lib/routes-deprecated/cnu/selected.js
deleted file mode 100644
index bb569f893302..000000000000
--- a/lib/routes-deprecated/cnu/selected.js
+++ /dev/null
@@ -1,52 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const utils = require('./utils');
-
-module.exports = async (ctx) => {
- const url = 'http://www.cnu.cc/selectedPage';
-
- const list_response = await got.get(url);
- const $ = cheerio.load(list_response.data);
-
- const list = $('.selectedUL > .bannerLi').toArray();
-
- const out = await Promise.all(
- list.map(async (item) => {
- const $ = cheerio.load(item);
- const title = $('.workTitle');
- const link = title.parent().attr('href');
-
- const cache = await ctx.cache.get(link);
- if (cache) {
- return JSON.parse(cache);
- }
-
- const rssitem = {
- title: title.text().trim(),
- link,
- };
-
- try {
- const response = await got.get(link);
- const result = utils.parseContent(response.data);
- if (!result.description) {
- return '';
- }
-
- rssitem.author = result.author;
- rssitem.description = result.description;
- rssitem.pubDate = result.pubDate;
- } catch {
- return '';
- }
- ctx.cache.set(link, JSON.stringify(rssitem));
- return rssitem;
- })
- );
-
- ctx.state.data = {
- title: `CNU视觉联盟 - 每日精选`,
- link: url,
- item: out.filter((item) => item !== ''),
- };
-};
diff --git a/lib/routes-deprecated/cnu/utils.js b/lib/routes-deprecated/cnu/utils.js
deleted file mode 100644
index a32278fba3ee..000000000000
--- a/lib/routes-deprecated/cnu/utils.js
+++ /dev/null
@@ -1,28 +0,0 @@
-const cheerio = require('cheerio');
-
-const pic_base_url = 'http://imgoss.cnu.cc/';
-
-const parseContent = (htmlString) => {
- const $ = cheerio.load(htmlString);
-
- const author = $('.author-info > a');
- const time = $('.author-info > .timeago');
- const content = $('#work_body');
-
- const imgs_json = JSON.parse($('#imgs_json').text());
- for (const element of imgs_json) {
- content.append(``);
- content.append(`
-
- ${item.summary}
- 价格: ${item.price}元
- `,
- })),
- };
-};
diff --git a/lib/routes-deprecated/cowlevel/element.js b/lib/routes-deprecated/cowlevel/element.js
deleted file mode 100644
index ebec7aaa86cd..000000000000
--- a/lib/routes-deprecated/cowlevel/element.js
+++ /dev/null
@@ -1,30 +0,0 @@
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- const id = ctx.params.id;
-
- const url = `https://cowlevel.net/element/${id}/article`;
-
- const response = await got({
- method: 'get',
- url: `https://cowlevel.net/search/article-search?tag_id=${id}&game_url_slug=&per_page=10&page=1&q=&sort=&sort_type=desc&is_rich_content=1&url_slug=`,
- headers: {
- Referer: url,
- },
- });
-
- const element_name = response.data.data.aggs.tags[0].tag.name;
- const list = response.data.data.list;
-
- ctx.state.data = {
- title: `奶牛关 - ${element_name}`,
- link: url,
- item: list.map((item) => ({
- title: item.title,
- author: item.user.name,
- description: item.content,
- pubDate: new Date(item.update_time * 1000),
- link: `https://cowlevel.net/article/${item.id}`,
- })),
- };
-};
diff --git a/lib/routes-deprecated/cpython/index.js b/lib/routes-deprecated/cpython/index.js
deleted file mode 100644
index 794716b8fe6d..000000000000
--- a/lib/routes-deprecated/cpython/index.js
+++ /dev/null
@@ -1,30 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const dayjs = require('dayjs');
-
-module.exports = async (ctx) => {
- const includePreRelease = ctx.params.pre;
- const response = await got(`https://www.python.org/downloads`);
- const $ = cheerio.load(response.data);
- const items = [];
- $('.list-row-container.menu li').each(function () {
- const $listElement = $(this);
- const title = $listElement.find('span.release-number').text();
- if (title) {
- if (!includePreRelease && title.includes('rc')) {
- return;
- }
- items.push({
- title: $listElement.find('span.release-number').text(),
- description: title,
- link: $listElement.find('.release-enhancements a').attr('href'),
- pubDate: dayjs($listElement.find('.release-date').text()),
- });
- }
- });
- ctx.state.data = {
- title: 'cpython',
- link: 'https://www.python.org/',
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/creaders/headline.js b/lib/routes-deprecated/creaders/headline.js
deleted file mode 100644
index c0c85121a8f9..000000000000
--- a/lib/routes-deprecated/creaders/headline.js
+++ /dev/null
@@ -1,45 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const iconv = require('iconv-lite');
-
-module.exports = async (ctx) => {
- const currentUrl = 'http://news.creaders.net/headline/';
-
- const response = await got.get(currentUrl, {
- responseType: 'buffer',
- });
-
- const $ = cheerio.load(iconv.decode(response.data, 'gbk'));
- const list = $('ul.newslist li')
- .slice(0, 10)
- .map((_, item) => {
- item = $(item);
- const a = item.find('a').eq(1);
- return {
- title: a.text(),
- link: a.attr('href'),
- pubDate: new Date(item.find('time').text() + ' GMT+8').toUTCString(),
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const res = await got.get(item.link, {
- responseType: 'buffer',
- });
- const content = cheerio.load(iconv.decode(res.data, 'gbk'));
-
- item.description = content('#newsContent').html();
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: '万维读者 - 焦点新闻',
- link: currentUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/csc/notice.js b/lib/routes-deprecated/csc/notice.js
deleted file mode 100644
index 8e74541a0d4b..000000000000
--- a/lib/routes-deprecated/csc/notice.js
+++ /dev/null
@@ -1,99 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const url = require('url');
-const iconv = require('iconv-lite');
-
-const baseUrl = 'https://www.csc.edu.cn';
-
-const typeMap = {
- lxtz: {
- name: '遴选通知',
- url: '/chuguo/list/24',
- },
- xmzl: {
- name: '综合项目专栏',
- url: '/chuguo/list/26',
- },
- wtjd: {
- name: '常见问题解答',
- url: '/chuguo/list/27',
- },
- lqgg: {
- name: '录取公告',
- url: '/chuguo/list/28',
- },
- xwzx: {
- name: '新闻资讯',
- url: '/news',
- },
- xwgg: {
- name: '新闻公告',
- url: '/news/gonggao',
- },
-};
-
-module.exports = async (ctx) => {
- const type = ctx.params.type || 'jjyw';
- const link = baseUrl + typeMap[type].url;
- const response = await got({
- method: 'get',
- url: link,
- headers: {
- Referer: baseUrl,
- },
- responseType: 'buffer',
- });
- const responseHtml = iconv.decode(response.data, 'gbk');
- const $ = cheerio.load(responseHtml);
-
- const urlList = $('.list-a li')
- .slice(0, 10)
- .map((i, e) => $('a', e).attr('href'))
- .get();
-
- const titleList = $('.list-a li')
- .slice(0, 10)
- .map((i, e) => $('a', e).attr('title'))
- .get();
-
- const dateList = $('.list-a li')
- .slice(0, 10)
- .map((i, e) => $('span', e).text())
- .get();
-
- const out = await Promise.all(
- urlList.map(async (itemUrl, index) => {
- itemUrl = url.resolve(baseUrl, itemUrl);
-
- const cache = await ctx.cache.get(itemUrl);
- if (cache) {
- return JSON.parse(cache);
- }
- const response = await got({
- method: 'get',
- url: itemUrl,
- responseType: 'buffer',
- });
- const responseHtmlItem = iconv.decode(response.data, 'gbk');
- const $ = cheerio.load(responseHtmlItem);
- const single = {
- title: titleList[index],
- link: itemUrl,
- description: $('.contents')
- .html()
- .replaceAll('src="/', `src="${url.resolve(baseUrl, '.')}`)
- .replaceAll('href="/', `href="${url.resolve(baseUrl, '.')}`)
- .trim(),
- pubDate: dateList[index],
- };
- ctx.cache.set(itemUrl, JSON.stringify(single));
- return single;
- })
- );
-
- ctx.state.data = {
- title: '国家留学网-' + typeMap[type].name,
- link,
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/ctei/news.js b/lib/routes-deprecated/ctei/news.js
deleted file mode 100644
index 625c9e7226cb..000000000000
--- a/lib/routes-deprecated/ctei/news.js
+++ /dev/null
@@ -1,50 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const { parseDate } = require('@/utils/parse-date');
-
-module.exports = async (ctx) => {
- const id = ctx.params.id || 'bwzq';
-
- const rootUrl = 'http://news.ctei.cn';
- const currentUrl = `${rootUrl}/${id}`;
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
-
- const $ = cheerio.load(response.data);
-
- const list = $('.news_text ul li a')
- .map((_, item) => {
- item = $(item);
-
- return {
- title: item.text(),
- link: `${currentUrl}${item.attr('href').replace(/\./, '')}`,
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: item.link,
- });
- const content = cheerio.load(detailResponse.data);
-
- item.description = content('.TRS_Editor').html();
- item.pubDate = parseDate(item.link.match(/\/t(\d{8})_\d+.htm/)[1], 'YYYYMMDD');
-
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: $('title').text(),
- link: currentUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/ctfhub/search.js b/lib/routes-deprecated/ctfhub/search.js
deleted file mode 100644
index 20b094ec3531..000000000000
--- a/lib/routes-deprecated/ctfhub/search.js
+++ /dev/null
@@ -1,59 +0,0 @@
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- const host = 'https://api.ctfhub.com';
- const opt = { like: {} };
- for (const i of ['title', 'form', 'class']) {
- if (ctx.params[i] !== undefined) {
- opt.like[i] = ctx.params[i];
- }
- }
-
- if (opt.like.class !== undefined) {
- const types = await got
- .post(`${host}/User_API/Event/getType`, {
- headers: {
- 'content-type': 'application/json',
- },
- body: '{}',
- })
- .json();
- opt.like.class = types.data[opt.like.class];
- }
- if (opt.like.form !== undefined) {
- opt.like.form = ['线上', '线下'][Number.parseInt(opt.like.form)];
- }
-
- if (Object.keys(opt.like).length === 0) {
- delete opt.like;
- }
-
- opt.offset = 0;
- opt.limit = Number.parseInt(ctx.params.limit) || 10;
-
- const response = await got
- .post(`${host}/User_API/Event/getAll`, {
- headers: {
- 'content-type': 'application/json',
- },
- body: JSON.stringify(opt),
- })
- .json();
-
- if (response.status !== true) {
- return;
- }
- const data = response.data;
-
- ctx.state.data = {
- title: 'CTFHub Calendar',
- link: 'https://www.ctfhub.com/#/calendar',
- description: '提供全网最全最新的 CTF 赛事信息,关注赛事定制自己专属的比赛日历吧。',
- item: data.items.map((item) => ({
- title: item.title,
- description: '',
- pubDate: new Date(item.start_time * 1000).toUTCString(),
- link: item.official_url,
- })),
- };
-};
diff --git a/lib/routes-deprecated/ctfhub/upcoming.js b/lib/routes-deprecated/ctfhub/upcoming.js
deleted file mode 100644
index 35604177811a..000000000000
--- a/lib/routes-deprecated/ctfhub/upcoming.js
+++ /dev/null
@@ -1,58 +0,0 @@
-const got = require('@/utils/got');
-const md5 = require('@/utils/md5');
-
-const host = 'https://api.ctfhub.com';
-
-async function get_details(event_id) {
- const res = await got
- .post(`${host}/User_API/Event/getInfo`, {
- headers: {
- 'content-type': 'application/json',
- },
- body: JSON.stringify({ event_id }),
- })
- .json();
- if (res.status !== true) {
- return '';
- }
- return res.data;
-}
-
-module.exports = async (ctx) => {
- const opt = {
- offset: 0,
- limit: Number.parseInt(ctx.params.limit) || 5,
- };
-
- const response = await got
- .post(`${host}/User_API/Event/getUpcoming`, {
- headers: {
- 'content-type': 'application/json',
- },
- body: JSON.stringify(opt),
- })
- .json();
-
- if (response.status !== true) {
- return;
- }
- const items = await Promise.all(
- response.data.items.map(async (item) => {
- const det = await get_details(item.id);
- return {
- title: item.title,
- description: det.details,
- pubDate: new Date(item.start_time * 1000).toUTCString(),
- link: det.official_url,
- guid: md5(item.title + item.start_time),
- };
- })
- );
-
- ctx.state.data = {
- title: 'CTFHub Calendar',
- link: 'https://www.ctfhub.com/#/calendar',
- description: '提供全网最全最新的 CTF 赛事信息,关注赛事定制自己专属的比赛日历吧。',
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/dailyart/index.js b/lib/routes-deprecated/dailyart/index.js
deleted file mode 100644
index 28a1de397065..000000000000
--- a/lib/routes-deprecated/dailyart/index.js
+++ /dev/null
@@ -1,33 +0,0 @@
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- const { body } = await got.post('https://panel.getdailyart.com/APIMobile/artworks/query', {
- headers: {
- Language: ctx.params.language || 'en',
- AuthSalt: 'ZG9jY29tcGFuaW9uc2FsdA==',
- },
- json: {
- take: 10,
- skip: 0,
- local_date: new Date().toISOString().split('T')[0],
- },
- responseType: 'json',
- });
-
- const data = body.entities;
-
- ctx.state.data = {
- title: `DailyArt`,
- link: 'https://www.getdailyart.com/',
- item: data.map((item) => ({
- title: item.title,
- description: `
-${item.info}
-${item.size || ''}
-${item.genre && item.genre.name ? item.genre.name : ''}
-${item.museum && item.museum.name ? item.museum.name : ''}`,
- pubDate: new Date(item.publish_date).toUTCString(),
- link: item.photo_retina,
- })),
- };
-};
diff --git a/lib/routes-deprecated/daodu/index.js b/lib/routes-deprecated/daodu/index.js
deleted file mode 100644
index 56b064bac361..000000000000
--- a/lib/routes-deprecated/daodu/index.js
+++ /dev/null
@@ -1,51 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const caty = ctx.params.caty || 'all';
-
- const rootUrl = 'https://daodu.tech';
- const currentUrl = `${rootUrl}${caty === 'all' ? '' : '/archive_' + caty}`;
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
-
- const $ = cheerio.load(response.data);
-
- const list = $('h2[itemprop="headline"] a, .post-header .archive__article__title a')
- .slice(0, 15)
- .map((_, item) => {
- item = $(item);
- return {
- title: item.text(),
- link: item.attr('href'),
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: item.link,
- });
- const content = cheerio.load(detailResponse.data);
-
- content('.member-only').remove();
-
- item.description = content('.post-entry-text').html();
- item.pubDate = new Date(content('meta[property="article:published_time"]').attr('content')).toUTCString();
-
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: $('title').text().replace('一覽表', ''),
- link: currentUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/daxiaamu/home.js b/lib/routes-deprecated/daxiaamu/home.js
deleted file mode 100644
index 96e08975d0ea..000000000000
--- a/lib/routes-deprecated/daxiaamu/home.js
+++ /dev/null
@@ -1,45 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const parser = require('@/utils/rss-parser');
-
-module.exports = async (ctx) => {
- const feed = await parser.parseURL('http://www.daxiaamu.com/rss');
-
- const ProcessFeed = async (link) => {
- const response = await got({
- method: 'get',
- url: link,
- });
- const $ = cheerio.load(response.data);
-
- return $('.main-content').html();
- };
-
- const items = await Promise.all(
- feed.items.map(async (item) => {
- const cache = await ctx.cache.get(item.link);
- if (cache) {
- return JSON.parse(cache);
- }
-
- const description = await ProcessFeed(item.link);
-
- const single = {
- title: item.title,
- description,
- pubDate: item.pubDate,
- link: item.link,
- author: item.author,
- };
- ctx.cache.set(item.link, JSON.stringify(single));
- return single;
- })
- );
-
- ctx.state.data = {
- title: feed.title,
- link: feed.link,
- description: feed.description,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/dbaplus/activity.js b/lib/routes-deprecated/dbaplus/activity.js
deleted file mode 100644
index f57c4296edcf..000000000000
--- a/lib/routes-deprecated/dbaplus/activity.js
+++ /dev/null
@@ -1,35 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const timezone = require('@/utils/timezone');
-
-module.exports = async (ctx) => {
- const type = ctx.params.type || 'online';
-
- const rootUrl = 'https://dbaplus.cn';
- const currentUrl = `${rootUrl}/activity-${type === 'online' ? '12' : '48'}-1.html`;
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
-
- const $ = cheerio.load(response.data);
-
- const items = $('.media')
- .map((_, item) => {
- item = $(item);
-
- return {
- title: item.find('.media-heading').text(),
- link: item.find('.pull-left').attr('href'),
- description: ``,
- pubDate: timezone(new Date(item.find('.time').text().replace('时间:', '')), +8),
- };
- })
- .get();
-
- ctx.state.data = {
- title: $('title').text().split(':')[0],
- link: currentUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/dbaplus/tab.js b/lib/routes-deprecated/dbaplus/tab.js
deleted file mode 100644
index 8f7326ebb134..000000000000
--- a/lib/routes-deprecated/dbaplus/tab.js
+++ /dev/null
@@ -1,50 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const tab = ctx.params.tab || 'All';
-
- const rootUrl = 'https://dbaplus.cn';
- const response = await got({
- method: 'get',
- url: rootUrl,
- });
-
- const $ = cheerio.load(response.data);
-
- const list = $(`#tab${tab} li`)
- .slice(0, 15)
- .map((_, item) => {
- item = $(item);
-
- return {
- link: item.find('a').eq(0).attr('href'),
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: item.link,
- });
- const content = cheerio.load(detailResponse.data);
-
- item.title = content('h2.title').text();
- item.author = content('span.user').text();
- item.description = content('.new-detailed').html();
- item.pubDate = new Date(content('span.time').eq(0).text()).toUTCString();
-
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: `${response.data.match(`(.*)`)[1]} - dbaplus社群`,
- link: rootUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/dcinside/board.js b/lib/routes-deprecated/dcinside/board.js
deleted file mode 100644
index 5b0ec04e78c7..000000000000
--- a/lib/routes-deprecated/dcinside/board.js
+++ /dev/null
@@ -1,66 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const url = require('url');
-
-const domain = 'https://m.dcinside.com';
-
-const headers = {
- Accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
- 'Accept-Encoding': 'gzip, deflate, br',
- 'Accept-Language': 'ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7',
- 'Cache-Control': 'max-age=0',
- Connection: 'keep-alive',
- Host: 'm.dcinside.com',
- 'Sec-Fetch-Dest': 'document',
- 'Sec-Fetch-Mode': 'navigate',
- 'Sec-Fetch-Site': 'none',
- 'Sec-Fetch-User': '?1',
- 'Upgrade-Insecure-Requests': '1',
- 'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Mobile Safari/537.36',
-};
-
-async function getData(ctx, link) {
- const { body } = await got.get(link, { headers });
- const $ = cheerio.load(body);
- const { path } = url.parse(link);
- const key = `dcinside${path}`;
-
- let result = await ctx.cache.get(key);
- if (result) {
- return result;
- }
-
- result = {
- title: $('head title').text().trim(),
- pubDate: new Date($('body > div.container > div > div > section > div.gallview-tit-box > div > ul > li:nth-child(2)').text()),
- link,
- description: $('body > div.container > div > div > section > div.gall-thum-btm > div > div.thum-txt').html(),
- };
-
- ctx.cache.set(key, result);
- return result;
-}
-
-function getItems(ctx, $) {
- return Promise.all(
- $('body > div > div > div > section > ul.gall-detail-lst > li:not([class]) > div > a.lt')
- .toArray()
- .map((row) => getData(ctx, row.attribs.href))
- );
-}
-
-module.exports = async (ctx) => {
- const { id } = ctx.params;
- const link = `${domain}/board/${id}`;
-
- const { body } = await got.get(link, { headers });
- const $ = cheerio.load(body);
- const rss = {
- title: $('head title').text(),
- description: $('head title').text(),
- link,
- item: await getItems(ctx, $),
- };
- rss.item = rss.item.sort((a, b) => b.pubDate - a.pubDate);
- ctx.state.data = rss;
-};
diff --git a/lib/routes-deprecated/ddrk/index.js b/lib/routes-deprecated/ddrk/index.js
deleted file mode 100644
index 6ae8af31a766..000000000000
--- a/lib/routes-deprecated/ddrk/index.js
+++ /dev/null
@@ -1,32 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const name = ctx.params.name;
- const season = ctx.params.season;
-
- let link = `https://ddys.pro/${name}/`;
-
- if (season) {
- link += `${season}/`;
- }
-
- const response = await got(link);
- const $ = cheerio.load(response.body);
-
- const title = $('title').html();
- const description = $('.abstract').html();
- const tracks = JSON.parse($('.wp-playlist-script').html()).tracks.reverse();
- const total = tracks.length;
-
- ctx.state.data = {
- title,
- link,
- description,
- item: tracks.map(({ caption, description }, index) => ({
- title: caption,
- link: `${link}?ep=${total - index}`,
- description,
- })),
- };
-};
diff --git a/lib/routes-deprecated/ddrk/list.js b/lib/routes-deprecated/ddrk/list.js
deleted file mode 100644
index d9be441c8728..000000000000
--- a/lib/routes-deprecated/ddrk/list.js
+++ /dev/null
@@ -1,37 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const md5 = require('@/utils/md5');
-
-module.exports = async (ctx) => {
- const url = ctx.params.tag ? `https://ddys.pro/tag/${encodeURIComponent(ctx.params.tag)}/` : ctx.params.category ? `https://ddrk.me/category/${ctx.params.category}/` : 'https://ddys.pro/';
-
- const response = await got(url);
- const $ = cheerio.load(response.data);
-
- const title = $('title').html();
- const list = $('.post-box-list .post-box-container').toArray();
-
- ctx.state.data = {
- title,
- link: url,
- item: list.map((single, index) => {
- const item = $(single);
- const name = item.find('.post-box-title').text();
- const poster = item
- .find('.post-box-image')
- .attr('style')
- .match(/url\((.*?)\)/)[1];
- const text = item.find('.post-box-text p').html();
- const time = new Date();
- time.setMinutes(time.getMinutes() - index);
- return {
- title: name,
- author: '低端影视',
- description: `
${text ?? ''}`,
- link: item.find('.post-box-title a').attr('href'),
- pubDate: time,
- guid: md5(name),
- };
- }),
- };
-};
diff --git a/lib/routes-deprecated/deepl/blog.js b/lib/routes-deprecated/deepl/blog.js
deleted file mode 100644
index 2e002710f4ed..000000000000
--- a/lib/routes-deprecated/deepl/blog.js
+++ /dev/null
@@ -1,34 +0,0 @@
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- const lang = ctx.params.lang || 'en';
-
- const rootUrl = 'https://www.deepl.com';
- const currentUrl = `${rootUrl}/zh/blog`;
- const blogUrl = `${rootUrl}/gatsby/locales/${lang}/blog.json`;
- const response = await got({
- method: 'get',
- url: blogUrl,
- });
-
- const items = [];
- const data = response.data;
- for (const key in data) {
- const matches = key.match(/post_content_(\d{8})/);
- if (matches) {
- const date = matches[1];
- items.push({
- description: data[key],
- link: `${currentUrl}/${date}`,
- title: data['post_title_' + date],
- pubDate: new Date(`${date.slice(0, 4)}-${date.slice(4, 6)}-${date.slice(6, 8)}`).toUTCString(),
- });
- }
- }
-
- ctx.state.data = {
- title: response.data.title,
- link: currentUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/dekudeals/index.js b/lib/routes-deprecated/dekudeals/index.js
deleted file mode 100644
index 21f71ed1d207..000000000000
--- a/lib/routes-deprecated/dekudeals/index.js
+++ /dev/null
@@ -1,44 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const url = require('url');
-
-module.exports = async (ctx) => {
- const type = ctx.params.type;
-
- const host = 'https://www.dekudeals.com/';
- const link = url.resolve(host, type);
-
- const response = await got.get(link);
- const $ = cheerio.load(response.data);
-
- const title = $('#search-title').text();
- const list = $('.search-main > .item-grid2 > div.cell');
-
- const out = await Promise.all(
- list
- .map((index, item) => {
- item = $(item);
- const title = item.find('.name').text();
- const link = url.resolve(host, item.find('.main-link').attr('href'));
- const img = item.find('.main-link img').attr('src');
- const price = item.find('strong').html();
- const oldprice = item.find('s.text-muted').html();
- const description = `
${oldprice}
${price}`;
-
- const single = {
- title,
- link,
- description,
- };
-
- return Promise.resolve(single);
- })
- .get()
- );
-
- ctx.state.data = {
- title: `${title}—dekudeals`,
- link,
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/deloitte/industries.js b/lib/routes-deprecated/deloitte/industries.js
deleted file mode 100644
index c5b7cd406eb0..000000000000
--- a/lib/routes-deprecated/deloitte/industries.js
+++ /dev/null
@@ -1,62 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const category = ctx.params.category || 'energy-resources-industrials';
- const options = {
- consumer: {
- icid: 'top_consumer',
- label: '消费行业',
- },
- 'energy-resources-industrials': {
- icid: 'top_energy-resources-industrials',
- label: '能源、资源及工业行业',
- },
- 'financial-services': {
- icid: 'top_financial-services',
- label: '金融服务行业',
- },
- 'government-public-services': {
- icid: 'top_government-public-services',
- label: '政府及公共服务',
- },
- 'life-sciences-healthcare': {
- icid: 'top_life-sciences-healthcare',
- label: '生命科学与医疗行业',
- },
- 'technology-media-telecommunications': {
- icid: 'top_technology-media-telecommunications',
- label: '科技、传媒及电信行业',
- },
- };
- const response = await got({
- url: 'https://www2.deloitte.com/cn/zh/industries/energy-resources-industrials.html',
- searchParams: {
- icid: options[category].icid,
- },
- });
- const $ = cheerio.load(response.data);
- const articles = $('.featuredpromo a.promo-focus')
- .map((index, ele) => ({
- title: $(ele).text().trim(),
- link: $(ele).attr('href'),
- }))
- .get();
-
- const item = await Promise.all(
- articles.slice(0, 10).map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got.get(`https://www2.deloitte.com/${item.link}`);
- const s = cheerio.load(detailResponse.data);
- item.description = s('.two-columns-c0').html();
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: `Deloitte - ${options[category].label}`,
- link: `https://www2.deloitte.com/cn/zh/industries/energy-resources-industrials.html?icid=top_energy-resources-`,
- item,
- };
-};
diff --git a/lib/routes-deprecated/dgtle/index.js b/lib/routes-deprecated/dgtle/index.js
deleted file mode 100644
index 30e606726445..000000000000
--- a/lib/routes-deprecated/dgtle/index.js
+++ /dev/null
@@ -1,57 +0,0 @@
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- const response = await got({
- method: 'get',
- url: 'https://opser.api.dgtle.com/v1/app/index?page=1',
- });
-
- const article_items = response.data.items.filter((item) => item.type in { 1: '', 4: '' });
-
- const items = await Promise.all(
- article_items.map(async (item) => {
- let title = '';
- let olink = ''; // 原始链接
- let dlink = ''; // description 链接
- let category = '';
- let description = '';
-
- if (1 === item.type) {
- title = item.title;
- dlink = `https://opser.api.dgtle.com/v1/article/view/${item.aid}`;
- olink = `https://www.dgtle.com/article-${item.aid}-1.html`;
- category = '文章';
- description = await ctx.cache.tryGet(dlink, async () => {
- const resp = await got.get(dlink);
- return resp.data.content;
- });
- } else if (4 === item.type) {
- title = item.summary;
- dlink = `https://opser.api.dgtle.com/v1/feeds/inst/${item.aid}`;
- olink = `https://www.dgtle.com/inst-${item.aid}-1.html`;
- category = '兴趣动态';
- description = await ctx.cache.tryGet(dlink, async () => {
- const resp = await got.get(dlink);
-
- return resp.data.imgs_url.reduce((content, dimg) => (content += ``), resp.data.content);
- });
- }
-
- return {
- title,
- description,
- pubDate: new Date(item.send_at * 1000).toUTCString(),
- link: olink,
- category,
- author: item.author.username,
- };
- })
- );
-
- ctx.state.data = {
- title: '数字尾巴 - 首页',
- link: 'https://www.dgtle.com',
- description: '数字尾巴首页内容',
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/dgtle/keyword.js b/lib/routes-deprecated/dgtle/keyword.js
deleted file mode 100644
index 2c05c9053863..000000000000
--- a/lib/routes-deprecated/dgtle/keyword.js
+++ /dev/null
@@ -1,30 +0,0 @@
-const got = require('@/utils/got');
-const sanitizeHtml = require('sanitize-html');
-
-module.exports = async (ctx) => {
- const keyword = ctx.params.keyword;
-
- const url = `https://www.dgtle.com/search?search_word=${encodeURIComponent(keyword)}`;
-
- const response = await got({
- method: 'get',
- url: `https://www.dgtle.com/search/sale?search_word=${encodeURIComponent(keyword)}&page=1`,
- headers: {
- Referer: url,
- },
- });
-
- const list = response.data.data.dataList;
-
- ctx.state.data = {
- title: `数字尾巴 - 闲置 - ${keyword}`,
- link: url,
- item: list.map((item) => ({
- title: sanitizeHtml(item.title, { allowedTags: [], allowedAttributes: {} }),
- author: item.author.username,
- description: `
`,
- pubDate: new Date(item.created_at * 1000),
- link: `https://www.dgtle.com/sale-${item.id}-1.html`,
- })),
- };
-};
diff --git a/lib/routes-deprecated/dgtle/trade.js b/lib/routes-deprecated/dgtle/trade.js
deleted file mode 100644
index c2c96a550c91..000000000000
--- a/lib/routes-deprecated/dgtle/trade.js
+++ /dev/null
@@ -1,42 +0,0 @@
-const got = require('@/utils/got');
-
-const type_names = {
- 0: '全部',
- 109: '手机',
- 110: '平板',
- 111: '电脑',
- 112: '生活',
- 113: '相机',
- 114: '影音',
- 115: '外设',
- 116: '公告',
-};
-
-module.exports = async (ctx) => {
- const typeId = ctx.params.typeId ?? '0';
-
- const url = 'https://www.dgtle.com/sale';
-
- const response = await got({
- method: 'get',
- url: `https://www.dgtle.com/sale/getList/${typeId}?page=1&last_id=0`,
- headers: {
- Referer: url,
- },
- });
-
- const type_name = type_names[typeId] ?? typeId;
- const list = response.data.data.dataList;
-
- ctx.state.data = {
- title: `数字尾巴 - 闲置 - ${type_name}`,
- link: url,
- item: list.map((item) => ({
- title: item.title,
- author: item.user.username,
- description: `
`,
- pubDate: new Date(item.created_at * 1000),
- link: `https://www.dgtle.com/sale-${item.id}-1.html`,
- })),
- };
-};
diff --git a/lib/routes-deprecated/dgtle/whale-rank.js b/lib/routes-deprecated/dgtle/whale-rank.js
deleted file mode 100644
index e247d6ab4c16..000000000000
--- a/lib/routes-deprecated/dgtle/whale-rank.js
+++ /dev/null
@@ -1,40 +0,0 @@
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- const type = ctx.params.type;
- const rule = ctx.params.rule;
-
- const stype = {
- download: '下载',
- like: '点赞',
- };
-
- const srule = {
- day: '日排行',
- week: '周排行',
- month: '月排行',
- amount: '总排行',
- };
-
- const host = 'https://www.dgtle.com';
-
- const response = await got({
- method: 'get',
- url: `https://opser.api.dgtle.com/v1/whale-rank/list?rule=${rule}&type=${type}`,
- });
-
- const items = response.data.items.map((item) => ({
- title: item.content,
- pubDate: new Date(item.updated_at * 1000).toUTCString(),
- author: item.author.username,
- description: `
`,
- link: item.attachment.pic_url.split('?')[0],
- }));
-
- ctx.state.data = {
- title: `数字尾巴 - 鲸图 - ${stype[type]}${srule[rule]}`,
- description: '鲸图排行榜',
- link: host,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/dgtle/whale.js b/lib/routes-deprecated/dgtle/whale.js
deleted file mode 100644
index 33d30c59e517..000000000000
--- a/lib/routes-deprecated/dgtle/whale.js
+++ /dev/null
@@ -1,29 +0,0 @@
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- const cid = Number(ctx.params.category);
-
- const categories = ['精选', '人物', '静物', '二次元', '黑白', '自然', '美食', '电影与游戏', '科技与艺术', '城市与建筑', '萌物', '美女'];
-
- const host = 'https://www.dgtle.com';
-
- const response = await got({
- method: 'get',
- url: `https://opser.api.dgtle.com/v1/whale/index?category_id=${cid}&page=1&per-page=10`,
- });
-
- const items = response.data.items.map((item) => ({
- title: item.content,
- pubDate: new Date(item.updated_at * 1000).toUTCString(),
- author: item.author.username,
- description: `
`,
- link: item.attachment.pic_url.split('?')[0],
- }));
-
- ctx.state.data = {
- title: `数字尾巴 - 鲸图 - ${categories[cid]}`,
- description: '分类鲸图',
- link: host,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/dida365/habit-checkins.js b/lib/routes-deprecated/dida365/habit-checkins.js
deleted file mode 100644
index 0d8a78e15bcf..000000000000
--- a/lib/routes-deprecated/dida365/habit-checkins.js
+++ /dev/null
@@ -1,84 +0,0 @@
-const got = require('@/utils/got');
-const { CookieJar } = require('tough-cookie');
-const config = require('@/config').value;
-const logger = require('@/utils/logger');
-
-let loginFlag;
-const cookieJar = new CookieJar();
-
-if (config.dida365.username && config.dida365.password) {
- got({
- method: 'post',
- url: 'https://api.dida365.com/api/v2/user/signon?wc=true&remember=true',
- cookieJar,
- json: {
- username: config.dida365.username,
- password: config.dida365.password,
- },
- })
- .then(() => {
- loginFlag = true;
- logger.info('Dida365 login success.');
- })
- .catch(() => {
- logger.error('Dida365 login fail.');
- });
-}
-
-module.exports = async (ctx) => {
- if (loginFlag) {
- const habitsRes = await got.get({
- url: 'https://api.dida365.com/api/v2/habits',
- cookieJar,
- });
- const habits = habitsRes.data;
-
- const paramsList = [];
- for (const item of habits) {
- paramsList.push(['habitIds', item.id]);
- }
- const searchParams = new URLSearchParams(paramsList);
-
- const habitCheckinsRes = await got.get({
- url: 'https://api.dida365.com/api/v2/habitCheckins',
- cookieJar,
- searchParams,
- });
- const checkins = habitCheckinsRes.data;
- const habitRecordsRes = await got.get({
- url: 'https://api.dida365.com/api/v2/habitRecords',
- cookieJar,
- searchParams,
- });
- const records = habitRecordsRes.data;
-
- let list = [];
- for (const habitId in checkins.checkins) {
- const info = habits.find((item) => item.id === habitId);
- list = [
- ...list,
- ...checkins.checkins[habitId]
- .sort((a, b) => a.checkinStamp - b.checkinStamp)
- .filter((checkin) => checkin.value)
- .map((checkin, index) => {
- const record = records.habitRecords[checkin.habitId].find((re) => re.stamp === checkin.checkinStamp);
- return {
- title: `第${index + 1}天${info.name}打卡`,
- description: record && record.content,
- pubDate: `${(checkin.checkinStamp + '').slice(0, 4)}-${(checkin.checkinStamp + '').slice(4, 6)}-${(checkin.checkinStamp + '').slice(6, 8)}`,
- link: `https://dida365.com/webapp/#q/all/habit/${checkin.habitId}`,
- guid: checkin.id,
- };
- }),
- ];
- }
-
- ctx.state.data = {
- title: '滴答清单打卡',
- link: 'https://dida365.com/webapp/#q/all/habit/',
- item: list,
- };
- } else {
- throw new Error('Login required');
- }
-};
diff --git a/lib/routes-deprecated/digitaling/article.js b/lib/routes-deprecated/digitaling/article.js
deleted file mode 100644
index e644c3e2c106..000000000000
--- a/lib/routes-deprecated/digitaling/article.js
+++ /dev/null
@@ -1,71 +0,0 @@
-const cheerio = require('cheerio');
-const got = require('@/utils/got');
-
-// 分类标题
-const categoryTitle = new Map([
- ['latest', { name: '最新文章', type: {} }],
- ['headline', { name: '头条', type: {} }],
- [
- 'hot',
- {
- name: '热文',
- type: {
- views: '近期热门文章',
- collects: '近期最多收藏',
- zan: '近期最多赞',
- },
- },
- ],
- ['choice', { name: '精选', type: {} }],
-]);
-module.exports = async (ctx) => {
- let category = ctx.params.category || 'latest';
- const subcate = ctx.params.subcate;
- // 获取分类标题
- let title = categoryTitle.get(category).name;
- if (category === 'latest') {
- // 获取最新文章
- category = '';
- }
- let link = `https://www.digitaling.com/articles/${category}/`;
- // 二级子分类
- if (subcate !== undefined) {
- link = link + subcate;
- title = title + '/' + categoryTitle.get(category).type[subcate];
- }
- const res = await got.get(link);
- const $ = cheerio.load(res.data);
- // 文章列表
- const list = $('.con_list li h3')
- .find('a')
- .map((i, e) => $(e).attr('href'))
- .get();
- const out = await Promise.all(
- list.map(async (itemUrl) => {
- const cache = await ctx.cache.get(itemUrl);
- // 判断缓存
- if (cache) {
- return JSON.parse(cache);
- }
- const res = await got.get(itemUrl);
- const $ = cheerio.load(res.data);
-
- const item = {
- title: $('.clearfix h2').text(),
- author: $('#avatar_by').find('a').text(),
- link: itemUrl,
- description: $('#article_con').html(),
- pubDate: new Date().toUTCString(),
- };
- ctx.cache.set(itemUrl, JSON.stringify(item));
-
- return item;
- })
- );
-
- ctx.state.data = {
- title: `数英网-文章专题-${title}`,
- link,
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/digitaling/index.js b/lib/routes-deprecated/digitaling/index.js
deleted file mode 100644
index 2f088d8516b4..000000000000
--- a/lib/routes-deprecated/digitaling/index.js
+++ /dev/null
@@ -1,42 +0,0 @@
-const cheerio = require('cheerio');
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- const link = 'https://www.digitaling.com';
- const res = await got.get(link);
- const $ = cheerio.load(res.data);
- // 文章列表
- const list = $('#home_latest li h3')
- .find('a')
- .map((i, e) => $(e).attr('href'))
- .get();
-
- const out = await Promise.all(
- list.map(async (itemUrl) => {
- const cache = await ctx.cache.get(itemUrl);
- // 判断缓存
- if (cache) {
- return JSON.parse(cache);
- }
- const res = await got.get(itemUrl);
- const $ = cheerio.load(res.data);
-
- const item = {
- title: $('.clearfix h2').text(),
- author: $('#avatar_by').find('a').text(),
- link: itemUrl,
- description: $('#article_con').html(),
- pubDate: new Date().toUTCString(),
- };
- ctx.cache.set(itemUrl, JSON.stringify(item));
-
- return item;
- })
- );
-
- ctx.state.data = {
- title: '数英网-最新文章',
- link,
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/digitaling/project.js b/lib/routes-deprecated/digitaling/project.js
deleted file mode 100644
index afb6e57871eb..000000000000
--- a/lib/routes-deprecated/digitaling/project.js
+++ /dev/null
@@ -1,55 +0,0 @@
-const cheerio = require('cheerio');
-const got = require('@/utils/got');
-
-// 分类标题
-const categoryTitle = new Map([
- ['all', { name: '全部' }],
- ['weekly', { name: '每周项目精选' }],
- ['monthly', { name: '每月项目精选' }],
- ['international', { name: '海外项目精选' }],
- ['hot', { name: '近期热门项目' }],
- ['favorite', { name: '近期最多收藏' }],
-]);
-
-module.exports = async (ctx) => {
- const category = ctx.params.category;
- const link = `https://www.digitaling.com/projects/${category}`;
- const res = await got.get(link);
- const $ = cheerio.load(res.data);
- // 标题
- const title = categoryTitle.get(category).name;
- // 文章列表
- const list = $('#pro_list .works_title h3')
- .find('a')
- .map((i, e) => $(e).attr('href'))
- .get();
-
- const out = await Promise.all(
- list.map(async (itemUrl) => {
- const cache = await ctx.cache.get(itemUrl);
- // 判断缓存
- if (cache) {
- return JSON.parse(cache);
- }
- const res = await got.get(itemUrl);
- const $ = cheerio.load(res.data);
-
- const item = {
- title: $('.clearfix h2').text(),
- author: $('#avatar_by').find('a').text(),
- link: itemUrl,
- description: $('#article_con').html(),
- pubDate: new Date().toUTCString(),
- };
- ctx.cache.set(itemUrl, JSON.stringify(item));
-
- return item;
- })
- );
-
- ctx.state.data = {
- title: `数英网-项目专题-${title}`,
- link,
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/discuss/index.js b/lib/routes-deprecated/discuss/index.js
deleted file mode 100644
index b3b1ed23631e..000000000000
--- a/lib/routes-deprecated/discuss/index.js
+++ /dev/null
@@ -1,71 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const timezone = require('@/utils/timezone');
-const { parseDate } = require('@/utils/parse-date');
-
-module.exports = async (ctx) => {
- const fid = ctx.params.fid;
-
- const rootUrl = 'https://www.discuss.com.hk';
- const currentUrl = `${rootUrl}/archiver/?fid-${fid}.html`;
-
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
-
- const $ = cheerio.load(response.data);
-
- const list = $('li a')
- .slice(0, ctx.query.limit ? Number.parseInt(ctx.query.limit) : 15)
- .map((_, item) => {
- item = $(item);
-
- return {
- title: item.text(),
- link: `${rootUrl}/${item.attr('href')}`,
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: item.link,
- });
-
- const data = detailResponse.data
- .replaceAll('[img]https://www.discuss.com.hk/images/common/back.gif[/img]', '')
- .replaceAll(/\[url=(.*?)]/gm, '')
- .replaceAll(/\[(\w+)=(.*?)]/gm, '')
- .replaceAll(/\[\/(color|size)]/gm, '')
- .replaceAll(/\[\/url]/gm, '')
- .replaceAll(/\[(\w+)]/gm, '<$1>')
- .replaceAll(/\[\/(\w+)]/gm, '$1>');
-
- const content = cheerio.load(data);
-
- const cite = content('cite');
- item.author = cite.eq(0).text();
- const firstAuthorParent = cite.eq(0).parent();
-
- item.description = content('.archiver_post').html();
-
- cite.remove();
-
- item.link = `${rootUrl}/viewthread.php?tid=${item.link.match(/tid-(\d+)\.html/)[1]}`;
- item.pubDate = timezone(parseDate(firstAuthorParent.text().trim(), 'YYYY-M-D hh:mm A'), +8);
-
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: `${$('h1 a').text().replace('查看完整版本 : ', '')} - 香港討論區`,
- link: `${rootUrl}/forumdisplay.php?fid=${fid}`,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/disqus/posts.js b/lib/routes-deprecated/disqus/posts.js
deleted file mode 100644
index 28e72e887ced..000000000000
--- a/lib/routes-deprecated/disqus/posts.js
+++ /dev/null
@@ -1,53 +0,0 @@
-const got = require('@/utils/got');
-const config = require('@/config').value;
-
-module.exports = async (ctx) => {
- if (!config.disqus || !config.disqus.api_key) {
- throw new Error('Disqus RSS is disabled due to the lack of relevant config');
- }
- const forum = ctx.params.forum;
-
- const response = await got({
- method: 'get',
- url: `https://disqus.com/api/3.0/forums/listPosts.json?api_key=${config.disqus.api_key}&forum=${forum}`,
- headers: {
- Referer: 'https://disqus.com/',
- },
- });
-
- const data = response.data.response;
-
- const threadsObj = {};
- for (const item of data) {
- threadsObj[item.thread] = 1;
- }
- let threadsQuery = '';
- for (const item of Object.keys(threadsObj)) {
- threadsQuery += `&thread=${item}`;
- }
-
- const responseThreads = await got({
- method: 'get',
- url: `https://disqus.com/api/3.0/forums/listThreads.json?api_key=${config.disqus.api_key}&forum=${forum}${threadsQuery}`,
- headers: {
- Referer: 'https://disqus.com/',
- },
- });
-
- const threads = responseThreads.data.response;
-
- ctx.state.data = {
- title: `${forum} 的评论`,
- link: `https://disqus.com/home/forums/${forum}`,
- description: `${forum} 的 disqus 评论`,
- item: data.map((item) => {
- const thread = threads.find((i) => i.id === item.thread);
- return {
- title: `${item.author.name}: ${item.raw_message}`,
- description: `${item.author.name} 在《${thread.clean_title}》中发表评论: ${item.message}`,
- pubDate: new Date(item.createdAt).toUTCString(),
- link: `${thread.link}/#comment-${item.id}`,
- };
- }),
- };
-};
diff --git a/lib/routes-deprecated/ditto/changes.js b/lib/routes-deprecated/ditto/changes.js
deleted file mode 100644
index 4f33908f24f7..000000000000
--- a/lib/routes-deprecated/ditto/changes.js
+++ /dev/null
@@ -1,36 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const type = ctx.params.type || '';
-
- const rootUrl = 'https://ditto-cp.sourceforge.io';
- const currentUrl = `${rootUrl}/${type === '' ? 'changeHistory.php' : `${type}/changes.php`}`;
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
-
- const $ = cheerio.load(type === '' ? response.data : `
`,
- pubDate: new Date(item.created_at).toUTCString(),
- }));
-
- ctx.state.data = {
- title: `思维导图社区 - ${search === '' ? (classId === '' ? '全部' : classes[ctx.params.classId]) : search}`,
- link: currentUrl,
- item: list,
- };
-};
diff --git a/lib/routes-deprecated/eeo/index.js b/lib/routes-deprecated/eeo/index.js
deleted file mode 100644
index f7e5c70b57f4..000000000000
--- a/lib/routes-deprecated/eeo/index.js
+++ /dev/null
@@ -1,79 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const timezone = require('@/utils/timezone');
-
-const legacyUrls = {
- 1: '/yaowen/dashi',
- 2: '/yaowen/hfggzc',
- 3: '/jinrong/zhengquan',
- 4: '/jinrong/ziben',
- 5: '/jinrong/licai',
- 6: '/shangye/xinnengyuan',
- 7: '/shangye/yiliao',
- 8: '/fcqcxf/dichan',
- 9: '/fcqcxf/qiche',
- 10: '/fcqcxf/xiaofei',
- 11: '/yule/yingshi',
- 12: '/yule/yule',
- 13: '/yule/tiyu',
- 14: '/yule/jiaoyu',
- 15: '/gcj/guanchajia',
- 16: '/gcj/zhuanlan',
- 17: '/gcj/shuping',
- 18: '/gcj/lishi',
- 19: '/yaowen/hfshuju',
-};
-
-module.exports = async (ctx) => {
- const column = ctx.params.column || 'shangyechanye';
- const category = ctx.params.category || '';
-
- const rootUrl = 'http://www.eeo.com.cn';
- let currentUrl = rootUrl;
-
- currentUrl += Number.parseInt(column) ? legacyUrls[Number.parseInt(column)] : `/${column}/${category}`;
-
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
-
- const $ = cheerio.load(response.data);
-
- const list = $('#lyp_article li div span a')
- .slice(0, 15)
- .map((_, item) => {
- item = $(item);
- return {
- link: item.attr('href'),
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: item.link,
- });
- const content = cheerio.load(detailResponse.data);
-
- content('.xd-xd-xd-rwm, .xd_zuozheinfo, .xd-lj, .xd-gg').remove();
-
- item.title = content('h1').text();
- item.description = content('.xd-nr').html();
- item.pubDate = timezone(new Date(content('.thiszihao-box-add').nextUntil('.cls').find('span').eq(0).text()), +8);
-
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: $('title').text().replace('_', ' - '),
- link: currentUrl,
- item: items,
- description: '经济观察网是《经济观察报》社倾力制作的全新商业资讯平台,经济观察网冷静理智的报道风格,并糅合最新的网络技术,拥有专业的采编力量以及独家的新闻报道,为您提供及时、便捷、专业的信息服务。',
- };
-};
diff --git a/lib/routes-deprecated/eleme/open/announce.js b/lib/routes-deprecated/eleme/open/announce.js
deleted file mode 100644
index dfd890745fff..000000000000
--- a/lib/routes-deprecated/eleme/open/announce.js
+++ /dev/null
@@ -1,32 +0,0 @@
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- const { data } = await got({
- method: 'post',
- url: 'https://app-api.shop.ele.me/arena/invoke/?method=NoticeKeeperService.getBroadcastList',
- json: {
- id: '5CC2B32FA6F24CF78CB300DDE2F370BE|1565511577423',
- metas: {
- appName: 'Odin',
- appVersion: '4.4.0',
- },
- service: 'NoticeKeeperService',
- method: 'getBroadcastList',
- params: {
- offset: 0,
- limit: 999,
- },
- ncp: '2.0.0',
- },
- });
- ctx.state.data = {
- title: '饿了么商家开放平台-公告',
- link: 'https://open.shop.ele.me/openapi/publicnotice/0',
- item: data.result.broadcastList.map((item) => ({
- title: item.title,
- description: '',
- pubDate: item.beginDate,
- link: `https://open.shop.ele.me/openapi/publicnotice/${item.templateId}`,
- })),
- };
-};
diff --git a/lib/routes-deprecated/emi-nitta/home.js b/lib/routes-deprecated/emi-nitta/home.js
deleted file mode 100644
index 776d6afe5e7a..000000000000
--- a/lib/routes-deprecated/emi-nitta/home.js
+++ /dev/null
@@ -1,69 +0,0 @@
-const url = require('url');
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-const root_url = 'https://emi-nitta.net';
-
-const config = {
- updates: {
- link: '/updates',
- title: 'Emi Nitta - Updates',
- description: 'Recent update of Emi Nitta official website',
- },
-
- news: {
- link: '/contents/news',
- title: 'Emi Nitta - News',
- description: 'News of Emi Nitta',
- },
-};
-
-const get_date = (o) => {
- const match = /(\d{4}\.\d+\.\d+)/.exec(o.text().trim());
- const date = match ? match[1] : o.attr('datetime');
- return new Date(date + ' GMT+9').toUTCString();
-};
-
-module.exports = async (ctx) => {
- const cfg = config[ctx.params.type];
- if (!cfg) {
- throw new Error('Bad type');
- }
-
- const response = await got({
- method: 'get',
- url: url.resolve(root_url, cfg.link),
- });
-
- const $ = cheerio.load(response.data);
- const list = $('article.details ul.list-unstyled li a')
- .slice(0, 10)
- .map((_, item) => {
- item = $(item);
- return {
- title: item.find('div.title h3').text(),
- link: item.attr('href'),
- pubDate: get_date(item.find('time')),
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet('emi-nitta' + 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('article.details div.body').html();
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: cfg.title,
- description: cfg.description,
- link: root_url,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/enclavebooks/category.js b/lib/routes-deprecated/enclavebooks/category.js
deleted file mode 100644
index 18bff50c1977..000000000000
--- a/lib/routes-deprecated/enclavebooks/category.js
+++ /dev/null
@@ -1,76 +0,0 @@
-const got = require('@/utils/got');
-const host = 'https://www.enclavebooks.cn';
-
-module.exports = async (ctx) => {
- const id = ctx.params.id;
-
- const categorys = (
- await got({
- method: 'get',
- url: 'https://app.enclavebooks.cn/v2/discovery',
- headers: {
- Referer: host,
- },
- })
- ).data.result.category;
-
- let category_name, description;
- for (const item of categorys) {
- if (item.cateId === Number.parseInt(id)) {
- category_name = item.cateName;
- description = item.cateDescription;
- break;
- }
- }
-
- const list = (
- await got({
- method: 'get',
- url: `https://app.enclavebooks.cn/v1_9/getCategoryList?cateId=${id}&page=1`,
- headers: {
- Referer: host,
- },
- })
- ).data.result.data;
-
- const out = await Promise.all(
- list.map(async (item) => {
- const title = item.artTitle;
- const date = item.artTime;
- const author = item.artEditor;
- const itemUrl = `https://app.enclavebooks.cn/v2/article?id=${item.artId}`;
-
- const cache = await ctx.cache.get(itemUrl);
- if (cache) {
- return JSON.parse(cache);
- }
-
- const response = await got({
- method: 'get',
- url: itemUrl,
- headers: {
- Referer: host,
- },
- });
-
- const description = response.data.result.artContent;
-
- const single = {
- title,
- link: `http://www.enclavebooks.cn/article.html?art_id=${item.artId}`,
- description,
- author,
- pubDate: new Date(date * 1000).toUTCString(),
- };
- ctx.cache.set(itemUrl, JSON.stringify(single));
- return single;
- })
- );
-
- ctx.state.data = {
- title: `${category_name}-飞地`,
- link: host,
- description,
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/enclavebooks/collection.js b/lib/routes-deprecated/enclavebooks/collection.js
deleted file mode 100644
index 81ad64a8b519..000000000000
--- a/lib/routes-deprecated/enclavebooks/collection.js
+++ /dev/null
@@ -1,44 +0,0 @@
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- const uid = ctx.params.uid;
-
- const authorUrl = 'https://app.enclavebooks.cn/v2/getOtherUserInformation?otherUserId%5B%5D=' + uid;
- const authorResponse = await got(authorUrl);
- const autherName = authorResponse.data.result[0].nickname;
-
- const url = 'https://app.enclavebooks.cn/v2/getCollectionList?page=1&userId=' + uid;
- const response = await got({ method: 'get', url });
- const responseList = response.data.result.data;
-
- const list = responseList.map((item) => ({
- artId: item.artId,
- title: item.artTitle,
- description: item.artDescription,
- // pubDate: new Date(item.artTime * 1000).toUTCString(),// 收藏顺序不是文章的创作时间
- link: `http://www.enclavebooks.cn/article.html?art_id=${item.artId}`,
- }));
-
- const result = await Promise.all(
- list.map(async (item) => {
- const link = 'https://app.enclavebooks.cn/v2/article?id=' + item.artId;
-
- const cache = await ctx.cache.get(link);
- if (cache) {
- return JSON.parse(cache);
- }
-
- const itemReponse = await got.get(link);
- item.description = itemReponse.data.result.artContent;
-
- ctx.cache.set(link, JSON.stringify(item));
- return item;
- })
- );
-
- ctx.state.data = {
- title: '飞地 - ' + autherName + '的收藏',
- link: url,
- item: result.reverse(),
- };
-};
diff --git a/lib/routes-deprecated/enclavebooks/user.js b/lib/routes-deprecated/enclavebooks/user.js
deleted file mode 100644
index 8deaaed7d540..000000000000
--- a/lib/routes-deprecated/enclavebooks/user.js
+++ /dev/null
@@ -1,44 +0,0 @@
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- const uid = ctx.params.uid;
-
- const authorUrl = 'https://app.enclavebooks.cn/v2/getOtherUserInformation?otherUserId%5B%5D=' + uid;
- const authorResponse = await got(authorUrl);
- const autherName = authorResponse.data.result[0].nickname;
-
- const url = 'https://app.enclavebooks.cn/v2/writeListByOther?page=1&otherUserId=' + uid;
- const response = await got({ method: 'get', url });
- const responseList = response.data.result.data;
-
- const list = responseList.map((item) => ({
- artId: item.artId,
- title: item.artTitle,
- description: item.artDescription,
- pubDate: new Date(item.artTime * 1000).toUTCString(),
- link: `http://www.enclavebooks.cn/article.html?art_id=${item.artId}`,
- }));
-
- const result = await Promise.all(
- list.map(async (item) => {
- const link = 'https://app.enclavebooks.cn/v2/article?id=' + item.artId;
-
- const cache = await ctx.cache.get(link);
- if (cache) {
- return JSON.parse(cache);
- }
-
- const itemReponse = await got.get(link);
- item.description = itemReponse.data.result.artContent;
-
- ctx.cache.set(link, JSON.stringify(item));
- return item;
- })
- );
-
- ctx.state.data = {
- title: '飞地 - ' + autherName,
- link: url,
- item: result,
- };
-};
diff --git a/lib/routes-deprecated/engadget/home.js b/lib/routes-deprecated/engadget/home.js
deleted file mode 100644
index 61f5ba437360..000000000000
--- a/lib/routes-deprecated/engadget/home.js
+++ /dev/null
@@ -1,67 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const parser = require('@/utils/rss-parser');
-const allowLang = new Set(['chinese', 'cn', 'us', 'japanese', 'www']);
-
-module.exports = async (ctx) => {
- const lang = ctx.params.lang === 'us' ? 'www' : ctx.params.lang || 'cn';
- if (!allowLang.has(lang)) {
- throw new Error('Invalid lang');
- }
- const rssUrl = `https://${lang}.engadget.com/rss.xml`;
- const feed = await parser.parseURL(rssUrl);
-
- const ProcessFeed = (data) => {
- const $ = cheerio.load(data);
- if (ctx.params.lang === 'us') {
- $('div#engadget-article-footer').remove();
- $('div#right-ads-rail').remove();
- $('.t-meta.c-gray-3.mb-35').remove();
- return $('div#page_body').html();
- } else {
- $('span#end-legacy-contents').remove();
- $('#post-slideshow figcaption').remove();
- $('#post-slideshow div.pagination button').remove();
- $('#post-slideshow img.scrollview-image-embedded').each((i, el) => {
- $(el).attr('src', $(el).data('wf-src'));
- });
- $('#post-slideshow li.list-item-embedded')
- .children()
- .each((i, el) => {
- $(el).insertAfter($(el).parent());
- });
- $('#post-slideshow li.list-item-embedded').remove();
- return $('#post-center-col > div:nth-child(1)').html();
- }
- };
-
- const items = await Promise.all(
- feed.items.map(async (item) => {
- const cache = await ctx.cache.get(item.link);
- if (cache) {
- return JSON.parse(cache);
- }
-
- const response = await got.get(item.link);
-
- const description = ProcessFeed(response.data);
- const single = {
- title: item.title,
- description,
- pubDate: item.pubDate,
- link: item.link,
- author: item.author,
- };
- ctx.cache.set(item.link, JSON.stringify(single));
- return single;
- })
- );
-
- ctx.state.data = {
- title: feed.title,
- link: feed.link,
- description: feed.description,
- language: feed.language,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/etherscan/transactions.js b/lib/routes-deprecated/etherscan/transactions.js
deleted file mode 100644
index 9c8bb64dda23..000000000000
--- a/lib/routes-deprecated/etherscan/transactions.js
+++ /dev/null
@@ -1,37 +0,0 @@
-const got = require('@/utils/got');
-const { parseDate } = require('@/utils/parse-date');
-
-module.exports = async (ctx) => {
- const { address } = ctx.params;
-
- const response = await got({
- method: 'get',
- url: `https://api.etherscan.io/api?module=account&action=txlist&address=${address}&page=1&offset=0&sort=desc`,
- });
-
- const list = response.data.result.slice(0, 20);
-
- ctx.state.data = {
- title: 'etherscan transactions',
- link: 'https://etherscan.io/',
- language: 'en',
- description: 'ethereum address transactions',
- item:
- list &&
- list.map((item) => {
- const title = ` TransactionHash: ${item.hash} `;
- const value = (Number.parseFloat(item.value) / 10 ** 18).toFixed(8);
- const description = `
- From: ${item.from}
To: ${item.to}
Value: ${value}
Block: ${item.blockNumber}`;
- const link = `https://etherscan.io/tx/${item.hash}`;
-
- return {
- title,
- description,
- link,
- pubDate: parseDate(item.timestamp),
- guid: item.hash,
- };
- }),
- };
-};
diff --git a/lib/routes-deprecated/etoland/board.js b/lib/routes-deprecated/etoland/board.js
deleted file mode 100644
index 2d93d4146e71..000000000000
--- a/lib/routes-deprecated/etoland/board.js
+++ /dev/null
@@ -1,46 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const iconv = require('iconv-lite');
-const { parseDate } = require('@/utils/parse-date');
-
-module.exports = async (ctx) => {
- const { bo_table } = ctx.params;
-
- const response = await got({
- method: 'get',
- url: `http://www.etoland.co.kr/bbs/board.php?bo_table=${bo_table}`,
- responseType: 'buffer',
- });
-
- const data = iconv.decode(response.data, 'euc-kr');
-
- const $ = cheerio.load(data);
- const list = $('form[name="fboardlist"]>table tr[align="center"]').filter((index, item) => {
- item = $(item);
- return item.find('td').first().find('span.mw_basic_list_num').length > 0;
- });
-
- ctx.state.data = {
- title: 'eTOLAND',
- link: 'http://www.etoland.co.kr',
- language: 'ko-KR',
- description: 'eTOLAND',
- item:
- list &&
- list
- .map((index, item) => {
- item = $(item);
- const title = item.find('td.mw_basic_list_subject a:nth-child(3) span').text();
- const description = `点赞数:${item.find('td.mw_basic_list_good').text()}
浏览数:${item.find('td.mw_basic_list_hit').text()}`;
- const link = item.find('td.mw_basic_list_subject a:nth-child(3)').attr('href');
-
- return {
- title,
- description,
- link,
- pubDate: parseDate(item.find('td.mw_basic_list_datetime').text(), 'HH:mm'),
- };
- })
- .get(),
- };
-};
diff --git a/lib/routes-deprecated/europapress/index.js b/lib/routes-deprecated/europapress/index.js
deleted file mode 100644
index 756735d98c3f..000000000000
--- a/lib/routes-deprecated/europapress/index.js
+++ /dev/null
@@ -1,52 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const { parseDate } = require('@/utils/parse-date');
-
-module.exports = async (ctx) => {
- const category = ctx.params.category || '';
-
- const rootUrl = 'https://www.europapress.es';
- const currentUrl = `${rootUrl}${category ? `/${category}` : ''}`;
-
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
-
- const $ = cheerio.load(response.data);
-
- const list = $('.articulo-titulo, .c-item__title, .home-articulo-titulo')
- .find('a')
- .map((_, item) => {
- item = $(item);
-
- return {
- title: item.text(),
- link: item.attr('href'),
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: item.link,
- });
- const content = cheerio.load(detailResponse.data);
-
- item.description = content('.full644').html() + content('.NormalTextoNoticia').html();
- item.pubDate = parseDate(content('meta[name="date"]').attr('content').replace(' ', ''));
-
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: $('title').text(),
- link: currentUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/everything/changes.js b/lib/routes-deprecated/everything/changes.js
deleted file mode 100644
index e7c61f995a2c..000000000000
--- a/lib/routes-deprecated/everything/changes.js
+++ /dev/null
@@ -1,33 +0,0 @@
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- const rootUrl = 'https://www.voidtools.com/Changes.txt';
-
- const response = await got({
- method: 'get',
- url: rootUrl,
- });
-
- const items = response.data
- .replaceAll(/\t\n\n|\t\n/g, '\n\n')
- .split('\n\n')
- .map((item) => {
- item = item.indexOf('\n') === 0 ? item.slice(2, 2 + item.length - 2) : item;
-
- const title = item.split('\n')[0].split(':');
- const description = `${item.split(title[1])[1].replaceAll('\t', '
`;
-
- return {
- description,
- link: rootUrl,
- title: title[1],
- pubDate: new Date(title[0]).toUTCString(),
- };
- });
-
- ctx.state.data = {
- title: 'Everything - Changes',
- link: rootUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/eztv/imdb.js b/lib/routes-deprecated/eztv/imdb.js
deleted file mode 100644
index f744b88ae0f2..000000000000
--- a/lib/routes-deprecated/eztv/imdb.js
+++ /dev/null
@@ -1,35 +0,0 @@
-const dayjs = require('dayjs');
-
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- const { imdb_id } = ctx.params;
-
- const response = await got({
- method: 'get',
- url: `https://eztv.it/api/get-torrents?imdb_id=${imdb_id}`,
- headers: {
- Referer: 'https://eztv.it',
- },
- });
-
- let torrents = [];
- if (response.data.torrents_count !== 0) {
- torrents = response.data.torrents;
- }
-
- ctx.state.data = {
- title: `EZTV's Torrents of IMBD ID: ${imdb_id}`,
- link: 'https://eztv.it',
- description: `EZTV's Torrents of IMBD ID: ${imdb_id}`,
- allowEmpty: true,
- item: torrents.map((item) => ({
- title: item.title,
- description: ``,
- enclosure_url: item.magnet_url,
- enclosure_type: 'application/x-bittorrent',
- pubDate: dayjs.unix(item.date_released_unix).toDate(),
- link: item.torrent_url,
- })),
- };
-};
diff --git a/lib/routes-deprecated/fanfou/favorites.js b/lib/routes-deprecated/fanfou/favorites.js
deleted file mode 100644
index 7131ef498748..000000000000
--- a/lib/routes-deprecated/fanfou/favorites.js
+++ /dev/null
@@ -1,36 +0,0 @@
-const config = require('@/config').value;
-const utils = require('./utils');
-
-module.exports = async (ctx) => {
- if (!config.fanfou || !config.fanfou.consumer_key || !config.fanfou.consumer_secret || !config.fanfou.username || !config.fanfou.password) {
- throw new Error('Fanfou RSS is disabled due to the lack of relevant config');
- }
-
- const uid = ctx.params.uid;
- const fanfou = await utils.getFanfou();
- const timeline = await fanfou.get(`/favorites/${encodeURIComponent(uid)}`, { id: uid, mode: 'lite', format: 'html' });
-
- const result = timeline.map((item) => {
- let img_html = '';
- if (item.photo) {
- img_html = `
`;
- }
- return {
- title: item.text,
- author: item.user.name,
- description: item.text + img_html,
- pubDate: item.created_at,
- link: `https://fanfou.com/statuses/${item.id}`,
- };
- });
-
- const users = await fanfou.get(`/users/show`, { id: uid });
- const authorName = users.screen_name;
-
- ctx.state.data = {
- title: `${authorName}的饭否收藏`,
- link: `https://fanfou.com/favorites/${encodeURIComponent(uid)}`,
- description: `${authorName}的饭否收藏`,
- item: result,
- };
-};
diff --git a/lib/routes-deprecated/fanfou/home-timeline.js b/lib/routes-deprecated/fanfou/home-timeline.js
deleted file mode 100644
index 4c97e848a6dc..000000000000
--- a/lib/routes-deprecated/fanfou/home-timeline.js
+++ /dev/null
@@ -1,32 +0,0 @@
-const config = require('@/config').value;
-const utils = require('./utils');
-
-module.exports = async (ctx) => {
- if (!config.fanfou || !config.fanfou.consumer_key || !config.fanfou.consumer_secret || !config.fanfou.username || !config.fanfou.password) {
- throw new Error('Fanfou RSS is disabled due to the lack of relevant config');
- }
-
- const fanfou = await utils.getFanfou();
- const timeline = await fanfou.get('/statuses/home_timeline', { mode: 'lite', format: 'html' });
-
- const result = timeline.map((item) => {
- let img_html = '';
- if (item.photo) {
- img_html = `
`;
- }
- return {
- title: item.plain_text,
- author: item.user.name,
- description: item.text + img_html,
- pubDate: item.created_at,
- link: `http://fanfou.com/statuses/${item.id}`,
- };
- });
-
- ctx.state.data = {
- title: `我的饭否动态`,
- link: `https://fanfou.com/home`,
- description: `我的饭否动态`,
- item: result,
- };
-};
diff --git a/lib/routes-deprecated/fanfou/public-timeline.js b/lib/routes-deprecated/fanfou/public-timeline.js
deleted file mode 100644
index 90e41bf03fb7..000000000000
--- a/lib/routes-deprecated/fanfou/public-timeline.js
+++ /dev/null
@@ -1,34 +0,0 @@
-const config = require('@/config').value;
-const utils = require('./utils');
-
-module.exports = async (ctx) => {
- if (!config.fanfou || !config.fanfou.consumer_key || !config.fanfou.consumer_secret || !config.fanfou.username || !config.fanfou.password) {
- throw new Error('Fanfou RSS is disabled due to the lack of relevant config');
- }
-
- const keyword = ctx.params.keyword;
- const fanfou = await utils.getFanfou();
- const timeline = await fanfou.get('/search/public_timeline', { q: keyword, mode: 'lite', format: 'html' });
-
- const result = timeline.map((item) => {
- let img_html = '';
- if (item.photo) {
- img_html = `
`;
- }
-
- return {
- title: item.plain_text,
- author: item.user.name,
- description: item.text + img_html,
- pubDate: item.created_at,
- link: `https://fanfou.com/statuses/${item.id}`,
- };
- });
-
- ctx.state.data = {
- title: `饭否搜索-${keyword}`,
- link: `https://fanfou.com/q/${keyword}`,
- description: `饭否搜索-${keyword}`,
- item: result,
- };
-};
diff --git a/lib/routes-deprecated/fanfou/trends.js b/lib/routes-deprecated/fanfou/trends.js
deleted file mode 100644
index ebe151389ff4..000000000000
--- a/lib/routes-deprecated/fanfou/trends.js
+++ /dev/null
@@ -1,21 +0,0 @@
-const utils = require('./utils');
-
-module.exports = async (ctx) => {
- const fanfou = await utils.getFanfou();
- const response = await fanfou.get(`/trends/list`);
-
- const result = response.trends.map((item) => ({
- title: item.name,
- description: item.name,
- pubDate: new Date(),
- link: item.url,
- }));
-
- ctx.state.data = {
- title: `饭否热门话题`,
- link: `https://fanfou.com/q/`,
- description: `饭否热门话题`,
- item: result,
- allowEmpty: true,
- };
-};
diff --git a/lib/routes-deprecated/fanfou/user-timeline.js b/lib/routes-deprecated/fanfou/user-timeline.js
deleted file mode 100644
index 3644f7c34b64..000000000000
--- a/lib/routes-deprecated/fanfou/user-timeline.js
+++ /dev/null
@@ -1,35 +0,0 @@
-const config = require('@/config').value;
-const utils = require('./utils');
-
-module.exports = async (ctx) => {
- if (!config.fanfou || !config.fanfou.consumer_key || !config.fanfou.consumer_secret || !config.fanfou.username || !config.fanfou.password) {
- throw new Error('Fanfou RSS is disabled due to the lack of relevant config');
- }
-
- const uid = ctx.params.uid;
- const fanfou = await utils.getFanfou();
- const timeline = await fanfou.get('/statuses/user_timeline', { id: uid, mode: 'lite', format: 'html' });
-
- const result = timeline.map((item) => {
- let img_html = '';
- if (item.photo) {
- img_html = `
`;
- }
- return {
- title: item.plain_text,
- author: item.user.name,
- description: item.text + img_html,
- pubDate: item.created_at,
- link: `https://fanfou.com/statuses/${item.id}`,
- };
- });
-
- const authorName = result[0].author;
-
- ctx.state.data = {
- title: `${authorName}的饭否`,
- link: `https://fanfou.com/${uid}`,
- description: `${authorName}的饭否`,
- item: result,
- };
-};
diff --git a/lib/routes-deprecated/fanfou/utils.js b/lib/routes-deprecated/fanfou/utils.js
deleted file mode 100644
index 579b2cdf82d0..000000000000
--- a/lib/routes-deprecated/fanfou/utils.js
+++ /dev/null
@@ -1,40 +0,0 @@
-const logger = require('@/utils/logger');
-const config = require('@/config').value;
-import Fanfou from 'fanfou-sdk';
-
-const consumerKey = config.fanfou.consumer_key;
-const consumerSecret = config.fanfou.consumer_secret;
-const username = config.fanfou.username;
-const password = config.fanfou.password;
-
-let fanfou_client;
-let authed = false;
-
-const getFanfou = async () => {
- if (authed === true) {
- return fanfou_client;
- } else {
- fanfou_client = new Fanfou({
- consumerKey,
- consumerSecret,
- username,
- password,
- protocol: 'https:',
- hooks: {
- baseString(str) {
- return str.replace('https', 'http');
- },
- },
- });
-
- await fanfou_client.xauth();
- logger.info('Fanfou login success.');
-
- authed = true;
- return fanfou_client;
- }
-};
-
-module.exports = {
- getFanfou,
-};
diff --git a/lib/routes-deprecated/fashionnetwork/headline.js b/lib/routes-deprecated/fashionnetwork/headline.js
deleted file mode 100644
index 9b0fae713ad0..000000000000
--- a/lib/routes-deprecated/fashionnetwork/headline.js
+++ /dev/null
@@ -1,56 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const { isValidHost } = require('@/utils/valid-host');
-
-module.exports = async (ctx) => {
- const country = ctx.params.country || 'ww';
- if (!isValidHost(country)) {
- throw new Error('Invalid country');
- }
-
- const rootUrl = `https://${country}.fashionnetwork.com`;
- const response = await got({
- method: 'get',
- url: rootUrl,
- });
-
- const $ = cheerio.load(response.data);
-
- const list = $('.point-carousel__item')
- .slice(5, 10)
- .map((_, item) => {
- item = $(item);
- const a = item.find('.family-title a');
-
- return {
- title: a.text(),
- link: `${rootUrl}${a.attr('href')}`,
- pubDate: Date.parse(item.find('.time-ago').attr('data-value')),
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: item.link,
- });
- const content = cheerio.load(detailResponse.data);
-
- content('.newsTitle, .ads').remove();
-
- item.description = content('div[itemprop="text"]').html();
-
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: `${$('.category-label').eq(0).text()} - FashionNetwork`,
- link: rootUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/fashionnetwork/news.js b/lib/routes-deprecated/fashionnetwork/news.js
deleted file mode 100644
index 73f7d725bb96..000000000000
--- a/lib/routes-deprecated/fashionnetwork/news.js
+++ /dev/null
@@ -1,74 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const { isValidHost } = require('@/utils/valid-host');
-
-module.exports = async (ctx) => {
- const country = ctx.params.country || 'ww';
- let sectors = ctx.params.sectors || '';
- let categories = ctx.params.categories || '';
-
- sectors = sectors === 'all' ? '' : sectors;
- categories = categories === 'all' ? '' : categories;
-
- const sectorsUrl = sectors ? 'sectors%5B%5D=' + sectors.split(',').join('§ors%5B%5D=') : '';
- const categoriesUrl = categories ? 'categs%5B%5D=' + categories.split(',').join('&categs%5B%5D=') : '';
-
- if (!isValidHost(country)) {
- throw new Error('Invalid country');
- }
-
- const rootUrl = `https://${country}.fashionnetwork.com`;
- const currentUrl = `${rootUrl}/news/s.jsonp?${sectorsUrl}&${categoriesUrl}`;
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
-
- const $ = cheerio.load(
- unescape(response.data.match(/"html":"(.*)","relatedUrl"/)[1].replaceAll(/\\(u[\dA-Fa-f]{4})/gm, '%$1'))
- .replaceAll('\\n', '')
- .replaceAll('\\/', '/')
- );
-
- const list = $('.list-ui__title')
- .slice(0, 10)
- .map((_, item) => {
- item = $(item);
- return {
- title: item.text(),
- link: item.attr('href'),
- pubDate: Date.parse(item.parent().find('time').attr('datetime')),
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: item.link,
- });
- const content = cheerio.load(detailResponse.data);
-
- content('.newsTitle, .ads').remove();
-
- item.description = content('div[itemprop="text"]').html();
-
- return item;
- })
- )
- );
-
- const labels = [];
-
- $('.filter__label').each(function () {
- labels.push($(this).text());
- });
-
- ctx.state.data = {
- title: `${labels.join(',') || 'All'} - FashionNetwork`,
- link: `${rootUrl}/news/s?${sectorsUrl}&${categoriesUrl}`,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/fgo/news.js b/lib/routes-deprecated/fgo/news.js
deleted file mode 100644
index 4ffad30ddcd4..000000000000
--- a/lib/routes-deprecated/fgo/news.js
+++ /dev/null
@@ -1,37 +0,0 @@
-const url = require('url');
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const newsUrl = 'https://news.fate-go.jp/';
- const response = await got({
- method: 'get',
- url: newsUrl,
- });
- const $ = cheerio.load(response.data);
- const list = $('ul.list_news li')
- .map((_, item) => {
- item = $(item);
- return {
- title: item.find('p.title').text(),
- link: url.resolve(newsUrl, item.find('a').attr('href')),
- pubDate: new Date(item.find('p.date').text()).toUTCString(),
- };
- })
- .get();
-
- ctx.state.data = {
- title: 'Fate Grand Order News',
- link: newsUrl,
- item: await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const res = await got({ method: 'get', url: item.link });
- const content = cheerio.load(res.data);
- item.description = content('div.article').html();
- return item;
- })
- )
- ),
- };
-};
diff --git a/lib/routes-deprecated/fnal/news.js b/lib/routes-deprecated/fnal/news.js
deleted file mode 100644
index 14b11a637fe3..000000000000
--- a/lib/routes-deprecated/fnal/news.js
+++ /dev/null
@@ -1,50 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const { parseDate } = require('@/utils/parse-date');
-
-module.exports = async (ctx) => {
- const category = ctx.params.category || 'allnews';
-
- const rootUrl = 'https://news.fnal.gov';
- const currentUrl = `${rootUrl}/newsroom/news/?se=&c=${category}`;
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
-
- const $ = cheerio.load(response.data);
-
- const list = $('.post-title a')
- .map((_, item) => {
- item = $(item);
- return {
- title: item.text(),
- link: item.attr('href'),
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: item.link,
- });
- const content = cheerio.load(detailResponse.data);
-
- item.author = content('.author').text();
- item.description = content('.entry-content, .article-content').html();
- item.pubDate = content('meta[property="article:published_time"]').length > 0 ? Date.parse(content('meta[property="article:published_time"]').attr('content')) : parseDate(content('.teaser-date').text(), 'MM/DD/YY');
-
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: `${$('title').text()} - Fermilab`,
- link: currentUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/gab/user.js b/lib/routes-deprecated/gab/user.js
deleted file mode 100644
index 8cb350ff7d17..000000000000
--- a/lib/routes-deprecated/gab/user.js
+++ /dev/null
@@ -1,32 +0,0 @@
-const cheerio = require('cheerio');
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- const username = ctx.params.username;
-
- const response = await got.get('https://gab.com/api/v1/account_by_username/' + username);
- const id = response.data.id;
- const gabs = await got.get(`https://gab.com/api/v1/accounts/${id}/statuses?exclude_replies=true`);
-
- const result = await Promise.all(
- gabs.data
- .filter((item) => !item.reblog)
- .map((item) => {
- const media = item.media_attachments.map((item) => `
`).join('
');
- const $ = cheerio.load(item.content);
-
- return {
- title: $.text() || 'Untitled',
- description: item.content + (media && '
' + media),
- link: item.url || `https://gab.com/${username}`,
- pubDate: new Date(item.created_at).toISOString(),
- };
- })
- );
-
- ctx.state.data = {
- title: `Gab - ${username}`,
- link: `https://gab.com/${username}`,
- item: result,
- };
-};
diff --git a/lib/routes-deprecated/galaxylab/index.js b/lib/routes-deprecated/galaxylab/index.js
deleted file mode 100644
index e7e04d21eaee..000000000000
--- a/lib/routes-deprecated/galaxylab/index.js
+++ /dev/null
@@ -1,35 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- let host = 'http://galaxylab.com.cn/';
-
- host = `${host}/posts/`;
-
- const response = await got.get(host);
-
- const $ = cheerio.load(response.data);
-
- const list = $('#scroll > section > ul > li');
-
- ctx.state.data = {
- title: '平安银河实验室',
- link: 'http://galaxylab.com.cn/',
- item:
- list &&
- list
- .map((index, item) => {
- item = $(item);
- return {
- title: item.find('article > a[title]').attr('title'),
- link: item.find('article > a[title]').attr('href'),
- description: item.find('article > div.excerpt').text(),
- pubDate: new Date(item.find('article > div.postinfo > div.left > span.date > b').text().replace('日', '').replaceAll(/\D/g, '-')).toUTCString(),
- author: item.find('article > div.postinfo > div.left > span.author > a[title]').attr('title'),
- };
- })
- .get(),
- };
-};
-
-// 虽然有很多分类,但是更新不勤,就不写分类了。
diff --git a/lib/routes-deprecated/game4399/forum.js b/lib/routes-deprecated/game4399/forum.js
deleted file mode 100644
index 6f2285fc47cb..000000000000
--- a/lib/routes-deprecated/game4399/forum.js
+++ /dev/null
@@ -1,46 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const config = require('@/config').value;
-
-module.exports = async (ctx) => {
- const mtag = ctx.params.mtag;
- const cookie = config.game4399.cookie;
- const response = await got({
- method: 'get',
- url: `http://my.4399.com/forums/${mtag}`,
- headers: {
- Cookie: cookie,
- },
- });
- const data = response.data;
- const dex = cheerio.load(data);
- const fname = dex('div.about .title').text();
- const list = dex('li div.listtitle')
- .map((index, item) => {
- item = dex(item);
- const author = item.parent().find('.author').text();
- const link = 'http://my.4399.com' + item.parent().find('.thread_link').attr('href');
- const title = item.parent().find('div.title').text() + ' ---------------最后回复->' + item.parent().find('.rtime span').text().trim() + ':' + item.parent().find('.rtime a').text().trim();
- return {
- title,
- link,
- author,
- };
- })
- .get();
- const items = await Promise.all(
- list.map(async (item) => {
- const res = await got({ method: 'get', url: item.link, headers: { Cookie: cookie } });
- const content = cheerio.load(res.data);
- content('div.host_content.j-thread-content img').not('.post_emoji').remove();
- item.description = content('div.host_content.j-thread-content').html();
- return item;
- })
- );
-
- ctx.state.data = {
- title: `${fname}群组`,
- link: 'http://my.4399.com/forums',
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/gameres/hot.js b/lib/routes-deprecated/gameres/hot.js
deleted file mode 100644
index 908d837e72d6..000000000000
--- a/lib/routes-deprecated/gameres/hot.js
+++ /dev/null
@@ -1,7 +0,0 @@
-const utils = require('./utils');
-
-module.exports = async (ctx) => {
- const rootUrl = 'https://www.gameres.com';
-
- ctx.state.data = await utils(ctx, rootUrl, '.hot-item h3');
-};
diff --git a/lib/routes-deprecated/gameres/list.js b/lib/routes-deprecated/gameres/list.js
deleted file mode 100644
index 8ef97ee4f9ce..000000000000
--- a/lib/routes-deprecated/gameres/list.js
+++ /dev/null
@@ -1,8 +0,0 @@
-const utils = require('./utils');
-
-module.exports = async (ctx) => {
- const rootUrl = 'https://www.gameres.com';
- const currentUrl = `${rootUrl}/list/${ctx.params.id}`;
-
- ctx.state.data = await utils(ctx, currentUrl, '.feed-item-right a h3');
-};
diff --git a/lib/routes-deprecated/gameres/utils.js b/lib/routes-deprecated/gameres/utils.js
deleted file mode 100644
index 067dabba1a52..000000000000
--- a/lib/routes-deprecated/gameres/utils.js
+++ /dev/null
@@ -1,58 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx, currentUrl, query) => {
- const rootUrl = `https://www.gameres.com`;
-
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
-
- const $ = cheerio.load(response.data);
-
- const list = $(query)
- .slice(0, 20)
- .map((_, item) => {
- item = $(item);
- item = item.parent().get(0).tagName === 'a' ? item.parent() : item.children();
-
- return {
- link: `${rootUrl}${item.attr('href')}`,
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: item.link,
- });
- const content = cheerio.load(detailResponse.data);
-
- const description = content('#maincontent');
- const info = description.prev().text().trim().split('\n');
- info.pop();
- const pubDate = info.pop();
-
- item.description = description.html();
- item.title = content('.article-title').text();
- item.pubDate = new Date(pubDate).toUTCString();
- item.author = info
- .join(' ')
- .replace(/作者:/, '')
- .replace(/原创/, '');
-
- return item;
- })
- )
- );
-
- return {
- title: $('title').text(),
- link: rootUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/gaoqing/latest.js b/lib/routes-deprecated/gaoqing/latest.js
deleted file mode 100644
index a41e014841a2..000000000000
--- a/lib/routes-deprecated/gaoqing/latest.js
+++ /dev/null
@@ -1,28 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const util = require('./utils');
-
-module.exports = async (ctx) => {
- const response = await got({
- method: 'get',
- url: 'https://gaoqing.fm/',
- headers: {
- Referer: 'https://gaoqing.fm/',
- },
- });
-
- const data = response.data;
-
- const $ = cheerio.load(data);
- const list = $('#result1 > li').get();
-
- let result = await util.ProcessFeed(list, ctx.cache);
- result = result.slice(0, 10);
-
- ctx.state.data = {
- title: '高清电台',
- link: 'https://gaoqing.fm',
- description: $('meta[name="description"]').attr('content'),
- item: result,
- };
-};
diff --git a/lib/routes-deprecated/gaoqing/utils.js b/lib/routes-deprecated/gaoqing/utils.js
deleted file mode 100644
index 1bd5a35c37f8..000000000000
--- a/lib/routes-deprecated/gaoqing/utils.js
+++ /dev/null
@@ -1,57 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-// 加载详情页
-async function load(link) {
- const response = await got.get(link);
- const $ = cheerio.load(response.data);
-
- // 提取标题
- const title = $('#mainrow > div:nth-child(2) > div.col-md-9 > div.row > div.col-md-12').html();
-
- // 提取图片
- const img = $('.x-m-poster').html();
-
- // 提取资料
- $('#viewfilm').find('img').remove();
- const info = $('#viewfilm').html();
-
- // 提取简介
- const intro = $('#des-ex').html() || $('#des-full').html();
-
- // 合并为描述
- const description = title + img + info + intro;
-
- return { description };
-}
-
-const ProcessFeed = (list, caches) =>
- Promise.all(
- list.map(async (item) => {
- const $ = cheerio.load(item);
-
- // 获取链接
- const $title = $('div.item-desc.pull-left > p > a');
- const itemUrl = $title.attr('href');
-
- // 获取评分
- const rate = $('div.item-desc.pull-left > p > span').text();
-
- // 列表上提取到的信息
- const single = {
- title: $title.text() + ' - ' + rate,
- link: itemUrl,
- guid: itemUrl,
- };
-
- // 缓存
- const other = await caches.tryGet(itemUrl, () => load(itemUrl));
-
- // 合并结果
- return Object.assign({}, single, other);
- })
- );
-
-module.exports = {
- ProcessFeed,
-};
diff --git a/lib/routes-deprecated/geektime/column.js b/lib/routes-deprecated/geektime/column.js
deleted file mode 100644
index 66f081099599..000000000000
--- a/lib/routes-deprecated/geektime/column.js
+++ /dev/null
@@ -1,55 +0,0 @@
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- const column_id = ctx.params.cid;
-
- // Get column introduction including column name and description
- const intro_response = await got({
- method: 'post',
- url: 'https://time.geekbang.org/serv/v1/column/intro',
- headers: {
- Referer: 'https://time.geekbang.org/',
- },
- json: {
- cid: column_id,
- },
- });
-
- const intro_data = intro_response.data.data;
-
- // Get latest articles
- const latest_response = await got({
- method: 'post',
- url: 'https://time.geekbang.org/serv/v1/column/articles/latest',
- headers: {
- Referer: 'https://time.geekbang.org/',
- },
- json: {
- cid: column_id,
- },
- });
-
- const articles = latest_response.data.data.list;
-
- const out = articles.map((item) => {
- const title = item.article_title;
- const pubDate = new Date(item.article_ctime * 1000).toUTCString();
- const link = `https://time.geekbang.org/column/article/${item.id}`;
- const description = item.article_summary;
-
- return {
- title,
- pubDate,
- link,
- description,
- };
- });
-
- out.reverse();
- ctx.state.data = {
- title: intro_data.column_title,
- link: `https://time.geekbang.org/column/intro/${column_id}`,
- description: intro_data.column_subtitle,
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/gitlab/common.js b/lib/routes-deprecated/gitlab/common.js
deleted file mode 100644
index 5ad06ad4ebba..000000000000
--- a/lib/routes-deprecated/gitlab/common.js
+++ /dev/null
@@ -1,5 +0,0 @@
-const allowHost = ['gitlab.com'];
-
-module.exports = {
- allowHost,
-};
diff --git a/lib/routes-deprecated/gitlab/explore.js b/lib/routes-deprecated/gitlab/explore.js
deleted file mode 100644
index 0bb6ba43b312..000000000000
--- a/lib/routes-deprecated/gitlab/explore.js
+++ /dev/null
@@ -1,43 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const config = require('@/config').value;
-const { allowHost } = require('./common');
-
-module.exports = async (ctx) => {
- let { type, host } = ctx.params;
- type = type === 'all' ? '' : type;
- host = host ?? 'gitlab.com';
- const typename = {
- trending: 'Trending',
- starred: 'Most stars',
- all: 'All',
- };
- if (!config.feature.allow_user_supply_unsafe_domain && !allowHost.includes(new URL(`https://${host}/`).hostname)) {
- ctx.throw(403, `This RSS is disabled unless 'ALLOW_USER_SUPPLY_UNSAFE_DOMAIN' is set to 'true'.`);
- }
-
- const res = await got({
- method: 'get',
- url: `https://${host}/explore/projects/${type}`,
- });
- const $ = cheerio.load(res.data);
- const list = $('ul.projects-list').find('li');
-
- ctx.state.data = {
- title: `${typename[type]} - Explore - Gitlab`,
- link: `https://${host}/explore/projects/${type}`,
- item:
- list &&
- list
- .map((index, item) => {
- item = $(item);
- return {
- title: item.find('.project-full-name').text(),
- author: item.find('.namespace-name').text().slice(0, -1).split('\n').join('').trim(),
- description: item.find('.description').text(),
- link: `https://${host}${item.find('a.text-plain').attr('href')}`,
- };
- })
- .get(),
- };
-};
diff --git a/lib/routes-deprecated/gitlab/release.js b/lib/routes-deprecated/gitlab/release.js
deleted file mode 100644
index 094493e1cb45..000000000000
--- a/lib/routes-deprecated/gitlab/release.js
+++ /dev/null
@@ -1,35 +0,0 @@
-const got = require('@/utils/got');
-const { parseDate } = require('@/utils/parse-date');
-const config = require('@/config').value;
-const { allowHost } = require('./common');
-
-module.exports = async (ctx) => {
- const { namespace, project, host } = ctx.params;
- if (!config.feature.allow_user_supply_unsafe_domain && !allowHost.includes(host)) {
- ctx.throw(403, `This RSS is disabled unless 'ALLOW_USER_SUPPLY_UNSAFE_DOMAIN' is set to 'true'.`);
- }
-
- const host_ = host ?? 'gitlab.com';
- const namespace_ = encodeURIComponent(namespace);
-
- const api_url = `https://${host_}/api/v4/projects/${namespace_}%2F${project}/releases`;
-
- const response = await got({
- method: 'get',
- url: api_url,
- });
- const data = response.data;
-
- ctx.state.data = {
- title: `${project} - Releases - Gitlab`,
- link: `https://${host_}/${namespace}/${project}/-/releases`,
- description: `${namespace}/${project} Releases`,
- item: data.map((item) => ({
- title: item.name,
- author: item.author.name,
- description: item.description_html,
- pubDate: parseDate(item.released_at),
- link: item._links.self,
- })),
- };
-};
diff --git a/lib/routes-deprecated/gitlab/tag.js b/lib/routes-deprecated/gitlab/tag.js
deleted file mode 100644
index 68252e8fca1a..000000000000
--- a/lib/routes-deprecated/gitlab/tag.js
+++ /dev/null
@@ -1,35 +0,0 @@
-const got = require('@/utils/got');
-const { parseDate } = require('@/utils/parse-date');
-const config = require('@/config').value;
-const { allowHost } = require('./common');
-
-module.exports = async (ctx) => {
- const { namespace, project, host } = ctx.params;
- if (!config.feature.allow_user_supply_unsafe_domain && !allowHost.includes(host)) {
- ctx.throw(403, `This RSS is disabled unless 'ALLOW_USER_SUPPLY_UNSAFE_DOMAIN' is set to 'true'.`);
- }
-
- const host_ = host ?? 'gitlab.com';
- const namespace_ = encodeURIComponent(namespace);
-
- const api_url = `https://${host_}/api/v4/projects/${namespace_}%2F${project}/repository/tags`;
-
- const response = await got({
- method: 'get',
- url: api_url,
- });
- const data = response.data;
-
- ctx.state.data = {
- title: `${project} - Tags - Gitlab`,
- link: `https://${host_}/${namespace}/${project}/-/tags`,
- description: `${namespace}/${project} Tags`,
- item: data.map((item) => ({
- title: item.name,
- author: item.commit.author_name,
- description: item.message,
- pubDate: parseDate(item.commit.created_at),
- link: item.commit.web_url,
- })),
- };
-};
diff --git a/lib/routes-deprecated/gnn/gnn.js b/lib/routes-deprecated/gnn/gnn.js
deleted file mode 100644
index 80b7765b89aa..000000000000
--- a/lib/routes-deprecated/gnn/gnn.js
+++ /dev/null
@@ -1,36 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const response = await got({
- method: 'get',
- url: 'https://gnn.gamer.com.tw/',
- headers: {
- Referer: 'hhttps://gnn.gamer.com.tw/',
- },
- });
-
- const data = response.data;
-
- const $ = cheerio.load(data);
- const list = $('.GN-lbox2 .GN-lbox2B');
-
- ctx.state.data = {
- title: 'GNN 新聞網 - 巴哈姆特 edited by monner',
- link: 'https://gnn.gamer.com.tw/',
- description: '巴 哈 姆 特 電 玩 資 訊 站 https://www.gamer.com.tw',
- item:
- list &&
- list
- .map((index, item) => {
- item = $(item);
- return {
- title: item.find('.GN-lbox2D').text(),
- description: item.find('.GN-lbox2C').text() + '',
- pubDate: new Date(item.find('.time').data('shared-at')).toUTCString(),
- link: item.find('.GN-lbox2D a').attr('href'),
- };
- })
- .get(),
- };
-};
diff --git a/lib/routes-deprecated/go.jp/mofa/main.js b/lib/routes-deprecated/go.jp/mofa/main.js
deleted file mode 100644
index cfbb451a9387..000000000000
--- a/lib/routes-deprecated/go.jp/mofa/main.js
+++ /dev/null
@@ -1,94 +0,0 @@
-// Japan government page
-
-// params:
-// [null]
-
-const got = require('@/utils/got'); // get web content
-const cheerio = require('cheerio'); // html parser
-const path = require('path');
-
-const base_url = 'https://www.mofa.go.jp';
-const index_url = path.join(base_url, '/mofaj/press/kaiken/bn/index.html');
-module.exports = async (ctx) => {
- // get the update list
- const response = await got({
- method: 'get',
- url: index_url,
- });
- const data = response.data; // content is html format
-
- const $ = cheerio.load(data);
- const list = $('dl.title-list dt.list-title a');
-
- // parse meeting urls
- const detail_urls = [];
- for (const a of list) {
- // for (let i = 0; i < 1; ++i) {
- if ($(a).text() === 'テキスト版要旨') {
- let l = $(a).attr('href');
- l = path.join(base_url, l);
- detail_urls.push(l);
- }
- }
-
- // get meetings
- const responses = await Promise.all(detail_urls.map((url) => got(url)));
- const meetings = responses.map(({ data }) => data);
-
- // get real data to feed
- const article_list = [];
- for (const meeting of meetings) {
- const $ = cheerio.load(meeting);
- $('script').remove();
- $('div.social-btn-top').remove();
- const link = $('meta[property="og:url"]').attr('content');
- const title = $('meta[property="og:title"]').attr('content');
- const author = '外務省';
- const content = $('h3.title3').html() + '
' + $('div#maincontents').html();
-
- let pub_date_num = '1970-01-01T00:00Z';
- try {
- const date_str = $('h3.title3').text();
- const m = date_str.match(/((..)(\d+)年(\d+)月(\d+)日((.)曜日)(\d+)時(\d+)分.*)/);
- const era = m[1];
- let yy = Number.parseInt(m[2]);
- const mm = m[3];
- const dd = m[4];
- // const ww = m[5];
- const HH = m[6];
- const MM = m[7];
- switch (era) {
- case '昭和':
- yy += 1925;
- break;
- case '平成':
- yy += 1988;
- break;
- case '令和':
- yy += 2018;
- break;
- }
- pub_date_num = yy.toString() + '-' + mm + '-' + dd + ' ' + HH + ':' + MM + ' +09';
- // console.log(pub_date_num);
- } catch (error) {
- error;
- }
- const pub_date = new Date(pub_date_num).toUTCString();
-
- const item = {
- title,
- author,
- pubDate: pub_date,
- link,
- description: content,
- };
- article_list.push(item);
- }
-
- // feed the data
- ctx.state.data = {
- title: '日本国外務省記者会見',
- link: index_url,
- item: article_list,
- };
-};
diff --git a/lib/routes-deprecated/gocomics/index.js b/lib/routes-deprecated/gocomics/index.js
deleted file mode 100644
index 39be14595785..000000000000
--- a/lib/routes-deprecated/gocomics/index.js
+++ /dev/null
@@ -1,64 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const baseURL = 'https://www.gocomics.com';
- const name = ctx.params.name;
- const limit = ctx.query.limit || 5;
- const url = `${baseURL}/${name}/`;
- const response = await got({
- method: 'get',
- url,
- });
-
- const data = response.data;
- const $ = cheerio.load(data);
-
- // Determine Comic and Author from main page
- const comic = $('.media-heading').eq(0).text();
- const author = $('.media-subheading').eq(0).text().replace('By ', '');
-
- // Load previous comic URL
- const items = [];
- let previous = $('.gc-deck--cta-0 a').attr('href');
-
- if (!previous) {
- throw new Error(`Comic Not Found - ${name}`);
- }
-
- while (items.length < limit) {
- const link = `${baseURL}${previous}`;
- /* eslint-disable no-await-in-loop */
- const item = await ctx.cache.tryGet(link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: link,
- });
- const content = cheerio.load(detailResponse.data);
-
- const title = content('h1.m-0').eq(0).text();
- const image = content('.comic.container').eq(0).attr('data-image');
- const description = ``;
- // Pull the date out of the URL
- const pubDate = new Date(link.split('/').slice(-3).join('/')).toUTCString();
- const previous = content('.js-previous-comic').eq(0).attr('href');
-
- return {
- title,
- author,
- category: 'comic',
- description,
- pubDate,
- link,
- previous,
- };
- });
- items.push(item);
- previous = item.previous;
- }
- ctx.state.data = {
- title: `${comic} - GoComics`,
- link: url,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/gov/beijing/eea.js b/lib/routes-deprecated/gov/beijing/eea.js
deleted file mode 100644
index 6ef1cb1141e3..000000000000
--- a/lib/routes-deprecated/gov/beijing/eea.js
+++ /dev/null
@@ -1,92 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-const baseUrl = 'https://www.bjeea.cn/';
-const siteTitle = '北京教育考试院--';
-
-const categoryMap = {
- bjeeagg: { title: '首页 / 通知公告', suffix: 'html/bjeeagg' },
- zkzc: { title: '首页 / 招考政策', suffix: 'html/zkzc' },
- zkkd: { title: '首页 / 自考快递', suffix: 'html/zkkd' },
-};
-
-// 专门定义一个function用于加载文章内容
-async function load(link) {
- // 异步请求文章
- const response = await got.get(link);
- // 加载文章内容
- const $ = cheerio.load(response.data);
- // 提取文章内容
- const description = $('div.info-txt').html();
- // 返回解析的结果
- return { description };
-}
-
-module.exports = async (ctx) => {
- // 默认 正常规定 然后获取列表页面
- const type = ctx.params.type || 'bjeeagg';
-
- const listPageUrl = baseUrl + categoryMap[type].suffix;
- const response = await got({
- method: 'get',
- url: listPageUrl,
- headers: {
- Referer: baseUrl,
- },
- });
- const $ = cheerio.load(response.data);
-
- // 获取当前页面的 list
- const list = $('ul.com-list>li');
-
- const result = await Promise.all(
- // 遍历每一篇文章
- list
- .map(async (item) => {
- const $ = cheerio.load(list[item]); // 将列表项加载成 html
- const $rel_url = $('a').attr('href'); // 获取 每一项的url
-
- let $item_url, $is_interior;
- if ($rel_url.startsWith('http')) {
- $item_url = $rel_url;
- $is_interior = false;
- } else {
- $item_url = baseUrl.substring(0, baseUrl.length - 1) + $rel_url;
- $is_interior = true;
- }
-
- const $title = $('a').text(); // 获取每个的标题
-
- const date_txt = $('span').text(); // 匹配 yyyy-mm-dd格式时间
- const $pubdate = new Date(date_txt); // 正则匹配发布时间 然后转换成时间
-
- // 列表上提取到的信息
- // 标题 链接
- const single = {
- title: $title,
- pubDate: $pubdate,
- link: $item_url,
- guid: $item_url,
- description: $title,
- };
-
- // 对于列表的每一项, 单独获取 时间与详细内容
- try {
- // 文章可能存在404错误,错误则直接使用title当作内容
- const other = $is_interior ? await ctx.cache.tryGet($item_url, () => load($item_url)) : $title;
- // 合并解析后的结果集作为该篇文章最终的输出结果
- return Object.assign({}, single, other);
- } catch {
- return single;
- }
- })
- .get()
- );
-
- ctx.state.data = {
- title: siteTitle + categoryMap[type].title,
- link: baseUrl,
- description: siteTitle + categoryMap[type].title,
- item: result,
- };
-};
diff --git a/lib/routes-deprecated/gov/beijing/mhc.js b/lib/routes-deprecated/gov/beijing/mhc.js
deleted file mode 100644
index ee58ee654c30..000000000000
--- a/lib/routes-deprecated/gov/beijing/mhc.js
+++ /dev/null
@@ -1,68 +0,0 @@
-const url = require('url');
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-const root_url = 'http://wjw.beijing.gov.cn/';
-
-const config = {
- wnxw: {
- link: '/xwzx_20031/wnxw/',
- title: '委内新闻',
- },
- jcdt: {
- link: '/xwzx_20031/jcdt/',
- title: '基层动态',
- },
- mtjj: {
- link: '/xwzx_20031/mtjj/',
- title: '媒体聚焦',
- },
- rdxws: {
- link: '/xwzx_20031/rdxws/',
- title: '热点新闻',
- },
-};
-
-module.exports = async (ctx) => {
- const cfg = config[ctx.params.caty];
- if (!cfg) {
- throw new Error('Bad category. See docs');
- }
-
- 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.weinei_left_con div.weinei_left_con_line')
- .slice(0, 10)
- .map((_, item) => {
- item = $(item);
- const a = item.find('a[title]');
- return {
- title: a.text(),
- link: url.resolve(current_url, a.attr('href')),
- pubDate: new Date(item.find('div.weinei_left_con_line_date').text() + ' GMT+8').toUTCString(),
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const res = await got({ method: 'get', url: item.link });
- const content = cheerio.load(res.data);
-
- item.description = content('div.weinei_left').html();
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: '北京卫健委 - ' + cfg.title,
- link: root_url,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/gov/caict/bps.js b/lib/routes-deprecated/gov/caict/bps.js
deleted file mode 100644
index 259495a7466c..000000000000
--- a/lib/routes-deprecated/gov/caict/bps.js
+++ /dev/null
@@ -1,40 +0,0 @@
-const url = require('url');
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const link = `http://www.caict.ac.cn/kxyj/qwfb/bps/`;
- const response = await got({
- method: 'get',
- url: link,
- });
- const $ = cheerio.load(response.data);
- const list = $('td[width="540"]')
- .map((_, item) => {
- item = $(item);
- const a = item.find('a');
- return {
- title: a.text(),
- link: url.resolve(link, a.attr('href')),
- pubDate: item.next().find('span.kxyj_text').text(),
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const res = await got({ method: 'get', url: item.link });
- const content = cheerio.load(res.data);
- item.description = content('div.pagemain').parent().parent().parent().html();
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: '中国信息通信研究院 - 白皮书',
- link,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/gov/caict/caictgd.js b/lib/routes-deprecated/gov/caict/caictgd.js
deleted file mode 100644
index f185e5c45fb9..000000000000
--- a/lib/routes-deprecated/gov/caict/caictgd.js
+++ /dev/null
@@ -1,40 +0,0 @@
-const url = require('url');
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const link = `http://www.caict.ac.cn/kxyj/caictgd/`;
- const response = await got({
- method: 'get',
- url: link,
- });
- const $ = cheerio.load(response.data);
- const list = $('td[width="600"]')
- .map((_, item) => {
- item = $(item);
- const a = item.find('a');
- return {
- title: a.text(),
- link: url.resolve(link, a.attr('href')),
- pubDate: item.next().find('span.kxyj_text').text(),
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const res = await got({ method: 'get', url: item.link });
- const content = cheerio.load(res.data);
- item.description = content('div.pagemaintext').html();
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: '中国信息通信研究院 - CAICT观点',
- link,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/gov/caict/qwsj.js b/lib/routes-deprecated/gov/caict/qwsj.js
deleted file mode 100644
index 29434d3ca468..000000000000
--- a/lib/routes-deprecated/gov/caict/qwsj.js
+++ /dev/null
@@ -1,29 +0,0 @@
-const url = require('url');
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const link = `http://www.caict.ac.cn/kxyj/qwfb/qwsj/`;
- const response = await got({
- method: 'get',
- url: link,
- });
- const $ = cheerio.load(response.data);
- const list = $('td[width="540"]')
- .map((_, item) => {
- item = $(item);
- const a = item.find('a');
- return {
- title: a.text(),
- link: url.resolve(link, a.attr('href')),
- pubDate: item.next().find('span.kxyj_text').text(),
- };
- })
- .get();
-
- ctx.state.data = {
- title: '中国信息通信研究院 - 权威数据',
- link,
- item: list,
- };
-};
diff --git a/lib/routes-deprecated/gov/chongqing/ljxq/dwgk.js b/lib/routes-deprecated/gov/chongqing/ljxq/dwgk.js
deleted file mode 100644
index f3ca3a82a214..000000000000
--- a/lib/routes-deprecated/gov/chongqing/ljxq/dwgk.js
+++ /dev/null
@@ -1,47 +0,0 @@
-const url = require('url');
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const rootUrl = 'http://ljxq.cq.gov.cn/dwgk/';
-
- const response = await got({
- method: 'get',
- url: rootUrl,
- });
- const $ = cheerio.load(response.data);
- const list = $('div.gl-c-r-content ul li')
- .slice(0, 10)
- .map((_, item) => {
- item = $(item);
- const a = item.find('a');
-
- return {
- title: a.text(),
- link: url.resolve(rootUrl, a.attr('href')),
- pubDate: new Date(item.find('span').text() + ' GMT+8').toUTCString(),
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: item.link,
- });
- const content = cheerio.load(detailResponse.data);
-
- item.description = content('div.zwxl-article').html();
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: '两江新区信息公开网 - 党务公开',
- link: rootUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/gov/chongqing/ljxq/zwgk.js b/lib/routes-deprecated/gov/chongqing/ljxq/zwgk.js
deleted file mode 100644
index 04bbc698c4fb..000000000000
--- a/lib/routes-deprecated/gov/chongqing/ljxq/zwgk.js
+++ /dev/null
@@ -1,67 +0,0 @@
-const url = require('url');
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-const rootUrl = 'http://ljxq.cq.gov.cn';
-
-const config = {
- lzyj: {
- link: '/zwgk_199/fdzdgknr/zcwj/',
- title: '履职依据',
- },
- gsgg: {
- link: '/zwgk_199/fdzdgknr/gggs/',
- title: '公示公告',
- },
-};
-
-module.exports = async (ctx) => {
- const cfg = config[ctx.params.caty];
- if (!cfg) {
- throw new Error('Bad category. See docs');
- }
-
- const currentUrl = url.resolve(rootUrl, cfg.link);
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
- const $ = cheerio.load(response.data);
-
- $('tr.cwx-tit').remove();
-
- const list = $('table.cwx-table tbody tr')
- .slice(0, 10)
- .map((_, item) => {
- item = $(item);
- const a = item.find('a');
-
- return {
- title: a.text(),
- link: url.resolve(currentUrl, a.attr('href')),
- pubDate: new Date(item.find('td').eq(2).text() + ' GMT+8').toUTCString(),
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: item.link,
- });
- const content = cheerio.load(detailResponse.data);
-
- item.description = content('div.zwxl-main').html();
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: `两江新区信息公开网 - ${cfg.title}`,
- link: rootUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/gov/city/index.js b/lib/routes-deprecated/gov/city/index.js
deleted file mode 100644
index ca25fcf7c528..000000000000
--- a/lib/routes-deprecated/gov/city/index.js
+++ /dev/null
@@ -1,28 +0,0 @@
-const logger = require('@/utils/logger');
-
-module.exports = async (ctx) => {
- const { name, category } = ctx.params;
- let url = '';
-
- switch (name) {
- case 'nanjing':
- url = 'http://www.nanjing.gov.cn';
- break;
- default:
- logger.error('URL pattern not matched');
- }
-
- if (url === '') {
- ctx.throw(404, 'Cannot find page');
- return;
- }
-
- try {
- const getRSS = require(`./${name}`);
- const responseData = await getRSS(url, category);
- ctx.state.data = responseData;
- } catch (error) {
- logger.error(error);
- ctx.throw(404, 'Cannot find page');
- }
-};
diff --git a/lib/routes-deprecated/gov/city/nanjing/get-content.js b/lib/routes-deprecated/gov/city/nanjing/get-content.js
deleted file mode 100644
index c09117f6a789..000000000000
--- a/lib/routes-deprecated/gov/city/nanjing/get-content.js
+++ /dev/null
@@ -1,69 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const logger = require('@/utils/logger');
-
-module.exports = async (link, totalPage = 1) => {
- let title = '';
- let description = '';
- let item = [];
- try {
- const result = await extract(link);
- title = result.title;
- description = result.description;
- item = result.item;
-
- const promises = [];
- for (let page = 2; page <= totalPage; page++) {
- promises.push(extract(link, page));
- }
- const pageContent = await Promise.all(promises);
- for (const content of pageContent) {
- if (Array.isArray(content)) {
- item = [...item, ...content];
- }
- }
- } catch {
- logger.error('Cannot load page content');
- }
-
- return { title, link, description, item };
-};
-
-async function extract(url, page = 1) {
- let pageLink = `${url}index.html`;
- if (page !== 1) {
- pageLink = `${url}index_${page - 1}.html`;
- }
-
- const response = await got.get(pageLink);
-
- const data = response.data;
- const $ = cheerio.load(data);
- const list = $('.center ul li');
-
- const resultItem = list.map((index, item) => {
- const $item = $(item);
- const $aTag = $item.find('a');
-
- const title = $aTag.text();
- const description = $aTag.attr('title');
- let pubDate = $item.find('span').text();
- pubDate = new Date(pubDate).toUTCString();
- let link = $aTag.attr('href');
- link = `${url}${link.substring(2)}`;
-
- return { title, description, pubDate, link };
- });
-
- if (page === 1) {
- const name = $('head title');
- const category = $('.zxft_title span').text();
- return {
- title: category,
- description: `${category} - ${name}`,
- item: resultItem.get(),
- };
- }
-
- return resultItem.get();
-}
diff --git a/lib/routes-deprecated/gov/city/nanjing/index.js b/lib/routes-deprecated/gov/city/nanjing/index.js
deleted file mode 100644
index a1a5f2fdc274..000000000000
--- a/lib/routes-deprecated/gov/city/nanjing/index.js
+++ /dev/null
@@ -1,32 +0,0 @@
-const getContent = require('./get-content');
-const logger = require('@/utils/logger');
-
-const TOTAL_PAGE = 3;
-
-module.exports = async (homePage, category) => {
- let url = '';
-
- switch (category) {
- case 'news':
- url = `${homePage}/njxx/`;
- break;
- case 'department':
- url = `${homePage}/bmdt/`;
- break;
- case 'district':
- url = `${homePage}/gqdt/`;
- break;
- case 'livelihood':
- url = `${homePage}/mszx/`;
- break;
- default:
- logger.error('URL pattern not matched');
- }
-
- if (url === '') {
- throw new Error('Nanjing, Cannot find page');
- }
-
- const responseData = await getContent(url, TOTAL_PAGE);
- return responseData;
-};
diff --git a/lib/routes-deprecated/gov/cnca/hydt.js b/lib/routes-deprecated/gov/cnca/hydt.js
deleted file mode 100644
index ff77b624dea7..000000000000
--- a/lib/routes-deprecated/gov/cnca/hydt.js
+++ /dev/null
@@ -1,54 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const base_url = 'http://www.cnca.gov.cn/xxgk/hydt/';
- const response = await got.get(base_url);
- const $ = cheerio.load(response.data);
- const list = $('.liebiao li').get();
-
- const ProcessFeed = (data) => {
- const $ = cheerio.load(data);
-
- const content = $('.TRS_Editor p');
- return content.text();
- };
-
- const items = await Promise.all(
- list.map(async (item) => {
- const $ = cheerio.load(item);
- const $a = $('a');
- let link = $a.attr('href');
- if (link.startsWith('.')) {
- link = base_url + link;
- }
-
- const cache = await ctx.cache.get(link);
- if (cache) {
- return JSON.parse(cache);
- }
-
- const response = await got({
- method: 'get',
- url: link,
- });
-
- const single = {
- title: $a.text(),
- description: ProcessFeed(response.data),
- pubDate: $('span').html(),
- link,
- };
-
- ctx.cache.set(link, JSON.stringify(single));
- return single;
- })
- );
-
- ctx.state.data = {
- title: '中国国家认证认可监管管理员会',
- link: 'http://www.cnca.gov.cn/',
- description: '行业动态',
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/gov/cnca/jgdt.js b/lib/routes-deprecated/gov/cnca/jgdt.js
deleted file mode 100644
index d38369829d94..000000000000
--- a/lib/routes-deprecated/gov/cnca/jgdt.js
+++ /dev/null
@@ -1,54 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const base_url = 'http://www.cnca.gov.cn/xxgk/jgdt/';
- const response = await got.get(base_url);
- const $ = cheerio.load(response.data);
- const list = $('.liebiao li').get();
-
- const ProcessFeed = (data) => {
- const $ = cheerio.load(data);
-
- const content = $('.TRS_Editor p');
- return content.text();
- };
-
- const items = await Promise.all(
- list.map(async (item) => {
- const $ = cheerio.load(item);
- const $a = $('a');
- let link = $a.attr('href');
- if (link.startsWith('.')) {
- link = base_url + link;
- }
-
- const cache = await ctx.cache.get(link);
- if (cache) {
- return JSON.parse(cache);
- }
-
- const response = await got({
- method: 'get',
- url: link,
- });
-
- const single = {
- title: $a.text(),
- description: ProcessFeed(response.data),
- pubDate: $('span').html(),
- link,
- };
-
- ctx.cache.set(link, JSON.stringify(single));
- return single;
- })
- );
-
- ctx.state.data = {
- title: '中国国家认证认可监管管理员会',
- link: 'http://www.cnca.gov.cn/',
- description: '监管动态',
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/gov/cnca/zxtz.js b/lib/routes-deprecated/gov/cnca/zxtz.js
deleted file mode 100644
index 1447bf665cb5..000000000000
--- a/lib/routes-deprecated/gov/cnca/zxtz.js
+++ /dev/null
@@ -1,63 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const base_url = 'http://www.cnca.gov.cn/xxgk/zxtz/2019/';
- const response = await got.get(base_url);
- const $ = cheerio.load(response.data);
- const list = $('.liebiao li').get();
-
- const ProcessFeed = (data) => {
- const $ = cheerio.load(data);
-
- const content = $('.TRS_Editor p');
- return content.text();
- };
-
- const items = await Promise.all(
- list.map(async (item) => {
- const $ = cheerio.load(item);
- const $a = $('a');
- let link = $a.attr('href');
- if (link.startsWith('.')) {
- link = base_url + link;
- }
-
- const cache = await ctx.cache.get(link);
- if (cache) {
- return JSON.parse(cache);
- }
-
- try {
- const response = await got({
- method: 'get',
- url: link,
- });
- const single = {
- title: $a.text(),
- description: ProcessFeed(response.data),
- pubDate: $('span').html(),
- link,
- };
-
- ctx.cache.set(link, JSON.stringify(single));
- return single;
- } catch {
- const single = {
- title: $a.text(),
- description: '',
- pubDate: $('span').html(),
- link,
- };
- return single;
- }
- })
- );
-
- ctx.state.data = {
- title: '中国国家认证认可监管管理员会',
- link: 'http://www.cnca.gov.cn/',
- description: '最新通知',
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/gov/cppcc/index.js b/lib/routes-deprecated/gov/cppcc/index.js
deleted file mode 100644
index 343349f847ea..000000000000
--- a/lib/routes-deprecated/gov/cppcc/index.js
+++ /dev/null
@@ -1,48 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const slug = ctx.params.slug || 'zxww-newcppcc-zxyw-index';
-
- const rootUrl = 'http://www.cppcc.gov.cn';
- const currentUrl = `${rootUrl}/${slug.replaceAll('-', '/')}.shtml`;
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
-
- const list = response.data
- .match(/new title_array\('(.*)','(.*)','\d{4}-\d{2}-\d{2}'\);/g)
- .slice(0, 15)
- .map((item) => {
- const array = item.replaceAll(/new title_array\(|\);|'/g, '').split(',');
- return {
- link: array[0],
- title: array[1],
- pubDate: new Date(array[2]).toUTCString(),
- };
- });
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: item.link,
- });
- const content = cheerio.load(detailResponse.data);
-
- item.description = content('.cnt_box .con').html();
- item.author = content('.info em').text().split(':')[1];
-
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: `${response.data.match(/><\/span>(.*)<\/p>/)[1]} - 中国政协网`,
- link: currentUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/gov/guangdong/edu.js b/lib/routes-deprecated/gov/guangdong/edu.js
deleted file mode 100644
index 70ae423703a4..000000000000
--- a/lib/routes-deprecated/gov/guangdong/edu.js
+++ /dev/null
@@ -1,83 +0,0 @@
-const url = require('url');
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-const rootUrl = 'http://edu.gd.gov.cn/';
-
-const config = {
- tzgg: {
- link: '/zxzx/tzgg/',
- title: '通知公告',
- },
- btxx: {
- link: '/zxzx/btxx/',
- title: '本厅信息',
- },
- xwfb: {
- link: '/zxzx/xwfb/',
- title: '新闻发布',
- },
- mtjj: {
- link: '/zxzx/mtjj/',
- title: '媒体聚焦',
- },
- gdjy: {
- link: '/zxzx/gdjy/',
- title: '广东教育',
- },
- jydt: {
- link: '/zxzx/jydt/',
- title: '教育动态',
- },
- tpxw: {
- link: '/zxzx/tpxw/',
- title: '图片新闻',
- },
- zscd: {
- link: '/zxzx/tzgg/',
- title: '政声传递',
- },
-};
-
-module.exports = async (ctx) => {
- const cfg = config[ctx.params.caty];
- if (!cfg) {
- throw new Error('Bad category. See docs');
- }
-
- const currentUrl = url.resolve(rootUrl, cfg.link);
- const response = await got({ method: 'get', url: currentUrl });
-
- const $ = cheerio.load(response.data);
- const list = $('div.list_list ul li')
- .map((_, item) => {
- item = $(item).find('a');
- return {
- title: item.text(),
- link: item.attr('href'),
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({ method: 'get', url: item.link });
- const content = cheerio.load(detailResponse.data);
- item.description = content('div.concent_center').html();
- item.pubDate = new Date(
- content('td[align="right"]')
- .text()
- .replace(/发布日期:/, '') + ' GMT+8'
- ).toUTCString();
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: '广东省教育厅 - ' + cfg.title,
- link: currentUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/gov/guangdong/eea.js b/lib/routes-deprecated/gov/guangdong/eea.js
deleted file mode 100644
index 5fd675a41345..000000000000
--- a/lib/routes-deprecated/gov/guangdong/eea.js
+++ /dev/null
@@ -1,59 +0,0 @@
-const url = require('url');
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const timezone = require('@/utils/timezone');
-const { parseDate } = require('@/utils/parse-date');
-const rootUrl = 'http://eea.gd.gov.cn/';
-
-const config = {
- kszs: { link: '/bmbk/kszs/', title: '考试招生' },
- shks: { link: '/shks/', title: '社会考试' },
- zkgs: { link: '/zwgk_zkgs/', title: '招考公示' },
- bkzn: { link: '/bmbk/bkzn/', title: '报考指南' },
- ywdt: { link: '/news/', title: '要闻动态' },
- gkzl: { link: '/zwgk/gkzl/', title: '公开专栏' },
- zcwj: { link: '/zwgk/zwwj/', title: '政策文件' },
- zcjd: { link: '/zcjd/', title: '政策解读' },
-};
-
-module.exports = async (ctx) => {
- const cfg = config[ctx.params.caty];
- if (!cfg) {
- throw new Error('Bad category. See docs');
- }
-
- const currentUrl = url.resolve(rootUrl, cfg.link);
- const response = await got({ method: 'get', url: currentUrl });
-
- const $ = cheerio.load(response.data);
- const list = $('div.main>div.content>ul>li')
- .map((_, item) => {
- item = $(item).find('a');
- return {
- title: item.text(),
- link: item.attr('href'),
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- if (item.link.includes('weixin.qq.com')) {
- return item;
- }
- const detailResponse = await got({ method: 'get', url: item.link });
- const content = cheerio.load(detailResponse.data);
- item.description = content('div.article').html();
- item.pubDate = timezone(parseDate(content('span.time').text()), +8);
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: '广东省教育考试院 - ' + cfg.title,
- link: currentUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/gov/harbin/kjj.js b/lib/routes-deprecated/gov/harbin/kjj.js
deleted file mode 100644
index e41514ef5854..000000000000
--- a/lib/routes-deprecated/gov/harbin/kjj.js
+++ /dev/null
@@ -1,39 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const url = require('url');
-
-const baseUrl = 'http://xxgk.harbin.gov.cn';
-
-module.exports = async (ctx) => {
- const response = await got({
- headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
- method: 'post',
- url: `${baseUrl}/module/xxgk/search.jsp?infotypeId=&vc_title=&vc_number=&area=002276772`,
- body: 'infotypeId=0&jdid=2&divid=div11565&vc_title=&vc_number=&currpage=&vc_filenumber=&vc_all=&texttype=&fbtime=&infotypeId=&vc_title=&vc_number=&area=002276772',
- });
- const data = response.data;
-
- const $ = cheerio.load(data);
- const list = $('.tr_main_value_odd, .tr_main_value_even');
- let items = list.map((_, e) => ({ title: $('a', e).attr('title'), link: $('a', e).attr('href'), pubDate: $('td:nth-child(3)', e).text() })).get();
- items = await Promise.all(
- items.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const result = await got({ method: 'get', url: item.link });
- const content = cheerio.load(result.data);
- item.description = content('.bt_content')
- .html()
- .replaceAll('src="/', `src="${url.resolve(baseUrl, '.')}`)
- .replaceAll('href="/', `href="${url.resolve(baseUrl, '.')}`)
- .trim();
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: '哈尔滨市科技局',
- link: `${baseUrl}/col/col11565/index.html`,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/gov/hubei/hbsia.js b/lib/routes-deprecated/gov/hubei/hbsia.js
deleted file mode 100644
index 7458e83a4a2c..000000000000
--- a/lib/routes-deprecated/gov/hubei/hbsia.js
+++ /dev/null
@@ -1,101 +0,0 @@
-const url = require('url');
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const { parseDate } = require('@/utils/parse-date');
-
-const root_url = 'http://www.hbsia.org/';
-
-const config = {
- zxzx: { title: '最新资讯' },
- hdtz: { title: '活动通知' },
- hdbd: { title: '活动报道' },
- gsgg: { title: '公示公告' },
-
- xyjj: { title: '行业聚焦' },
- cszc: { title: '财税政策' },
- cyzc: { title: '产业政策' },
- cyyj: { title: '产业研究' },
- sjxx: { title: '数据信息' },
- zjgd: { title: '专家观点' },
-
- jrxh: { title: '加入协会' },
- tsfw: { title: '特色服务' },
- hyhd: { title: '会员活动' },
- hyfc: { title: '会员风采' },
- hyqyzp: { title: '会员企业招聘' },
- mqmp: { title: '名企/名品推荐' },
-
- srgg: { title: '双软公告' },
- srdt: { title: '双软动态' },
- qypg: { title: '企业评估' },
- cppg: { title: '产品评估' },
- tgxc: { title: '推广宣传' },
- xgxz2: { title: '双软相关下载' },
-
- rjzzq: { title: '软件著作权' },
- flfg: { title: '法律法规' },
-
- tzgg: { title: 'ITSS通知公告' },
- ITSSdt: { title: 'ITSS动态' },
- ITSSjs: { title: 'ITSS介绍' },
- ITSSbz: { title: 'ITSS标准' },
- ITSSyb: { title: 'ITSS月报' },
- yyal: { title: '应用案例' },
- xgxzi: { title: 'ITSS相关下载' },
-
- xydjpj: { title: '信用等级评价' },
- kjcgpj: { title: '科技成果评价' },
- dbpc: { title: '等保评测' },
- rjzj: { title: '软件造价' },
- txrz: { title: '体系认证' },
- zxjsfw: { title: '专项技术服务' },
-
- shzzdj: { title: '社会组织党建' },
- xyzl: { title: '行业自律' },
- xhkw: { title: '协会刊物' },
-};
-
-module.exports = async (ctx) => {
- const cfg = config[ctx.params.caty];
- if (!cfg) {
- throw new Error('Bad category. See docs');
- }
-
- const current_url = url.resolve(root_url, `/${ctx.params.caty}/index.jhtml`);
- const response = await got({
- method: 'get',
- url: current_url,
- });
- const $ = cheerio.load(response.data);
- const list = $('div.i_content li')
- .slice(0, 20)
- .map((_, item) => {
- item = $(item);
- const a = item.find('a[href]');
- const span = item.find('span');
- return {
- title: a.text(),
- link: url.resolve(current_url, a.attr('href')),
- pubDate: parseDate(span.text(), 'YYYY-MM-DD'),
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const res = await got({ method: 'get', url: item.link });
- const content = cheerio.load(res.data);
-
- item.description = content('div.article').html();
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: '湖北软协 - ' + cfg.title,
- link: root_url,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/gov/hunan/notice.js b/lib/routes-deprecated/gov/hunan/notice.js
deleted file mode 100644
index 819c98ecc654..000000000000
--- a/lib/routes-deprecated/gov/hunan/notice.js
+++ /dev/null
@@ -1,80 +0,0 @@
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- const type = ctx.params.type || 'all';
- const rssData = {
- isType: !!ctx.params.type,
- Title: `湖南省政府采购网`,
- Desc: `湖南省政府采购网`,
- Link: `http://www.ccgp-hunan.gov.cn/page/notice/more.jsp`,
- Category: new Map([
- ['all', { name: '全部', id: '' }],
- ['cg', { name: '采购公告', id: 'prcmNotices' }],
- ['zb', { name: '中标(成交)公告', id: 'dealNotices' }],
- ['fb', { name: '废标公告', id: 'invalidNotices' }],
- ['ht', { name: '合同公告', id: 'contractNotices' }],
- ['gz', { name: '更正公告', id: 'modfiyNotices' }],
- ['zz', { name: '终止公告', id: 'endNotices' }],
- ['qt', { name: '其他公告', id: 'otherNotices' }],
- ]),
- typeName(type) {
- return rssData.Category.get(type).name;
- },
- typeid(type) {
- return rssData.Category.get(type).id;
- },
- ProcessFeed: async (id) => {
- const response = await got({
- method: 'get',
- url: `http://www.ccgp-hunan.gov.cn/mvc/viewNoticeContent.do?noticeId=` + id,
- headers: {
- Referer: rssData.itemUrl + id,
- },
- });
- const htmlContent = response.data;
- return htmlContent;
- },
- async ItemsSingle(item) {
- const cache = await ctx.cache.get(rssData.itemUrl + item.NOTICE_ID);
- if (cache) {
- return JSON.parse(cache);
- }
-
- const single = {
- title: item.NOTICE_TITLE,
- link: rssData.itemUrl + item.NOTICE_ID,
- author: item.NOTICE_NAME,
- description: await rssData.ProcessFeed(item.NOTICE_ID),
- guid: item.NOTICE_ID,
- category: item.NOTICE_NAME,
- pubDate: new Date(`${item.NEWWORK_DATE} GMT`).toUTCString(),
- };
- ctx.cache.set(rssData.itemUrl + item.NOTICE_ID, JSON.stringify(single));
- return single;
- },
- referUrl: `http://www.ccgp-hunan.gov.cn/page/notice/more.jsp`,
- apiUrl: `http://www.ccgp-hunan.gov.cn/mvc/getNoticeList4Web.do`,
- itemUrl: `http://www.ccgp-hunan.gov.cn/page/notice/notice.jsp?noticeId=`,
- };
- // 结束rssData定义
- // 配置api日期参数
- const now = new Date();
- const startDate = now.getFullYear() + '-01-01';
- const endDate = now.getFullYear() + '-' + (now.getMonth() + 1) + '-' + now.getDate();
- rssData.apiResponse = await got({
- method: 'post',
- url: `http://www.ccgp-hunan.gov.cn/mvc/getNoticeList4Web.do?nType=${rssData.typeid(type)}&startDate=${startDate}&endDate=${endDate}&page=1&pageSize=18`,
- responseType: 'buffer',
- headers: {
- Referer: rssData.referUrl,
- },
- });
- rssData.apiData = rssData.apiResponse.data.rows;
- rssData.Items = await Promise.all(rssData.apiData.map((item) => rssData.ItemsSingle(item)));
- ctx.state.data = {
- title: rssData.Title,
- link: rssData.Link,
- description: rssData.Desc,
- item: rssData.Items,
- };
-};
diff --git a/lib/routes-deprecated/gov/mohrss/sbjm.js b/lib/routes-deprecated/gov/mohrss/sbjm.js
deleted file mode 100644
index 68bce6dbda8d..000000000000
--- a/lib/routes-deprecated/gov/mohrss/sbjm.js
+++ /dev/null
@@ -1,59 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const category = ctx.params.category || 'ydxw';
-
- const rootUrl = 'http://www.mohrss.gov.cn';
- const currentUrl = `${rootUrl}/SYrlzyhshbzb/rdzt/jfjf/${category}`;
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
-
- const $ = cheerio.load(response.data);
-
- const list = $('.rsb_jfjf_cont2 ul li a')
- .slice(0, 15)
- .map((_, item) => {
- item = $(item);
- let link = item.attr('href');
- if (link.includes('../../../')) {
- link = `${rootUrl}/SYrlzyhshbzb/${link.replace('../../../', '')}`;
- } else if (link.includes('./')) {
- link = `${currentUrl}/${link.replace('./', '')}`;
- }
- return {
- title: item.text(),
- link,
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: item.link,
- });
- const content = cheerio.load(detailResponse.data);
-
- item.description = content('#insMainConTxt').html() || content('.TRS_Editor').html() || content('#UCAP-CONTENT').html() || content('.weixinBox').html();
- item.pubDate = new Date(
- content('meta[name="PubDate"]').attr('content') ||
- content('meta[name="publishdate"]').attr('content') ||
- (content('meta[name="firstpublishedtime"]').attr('content') ? content('meta[name="others"]').attr('content').replace('页面生成时间 ', '') : '')
- ).toUTCString();
-
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: $('title').text(),
- link: currentUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/gov/mohurd/policy.js b/lib/routes-deprecated/gov/mohurd/policy.js
deleted file mode 100644
index b83e5dc9e8e1..000000000000
--- a/lib/routes-deprecated/gov/mohurd/policy.js
+++ /dev/null
@@ -1,39 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const link = `http://www.mohurd.gov.cn/wjfb/index.html`;
- const response = await got({ method: 'get', url: link });
-
- const $ = cheerio.load(response.data);
- const list = $('body table tbody tr')
- .eq(3)
- .find('td table tbody tr')
- .eq(2)
- .find('td table tbody tr')
- .map((_, item) => {
- const a = $(item).find('a');
- const subtitle = $(item).find('td').eq(2).text();
- return {
- title: a.text() + (subtitle === '' ? '' : ' - ' + subtitle),
- link: a.attr('href'),
- pubDate: new Date($(item).find('td').eq(3).text().slice(1, 11) + ' GMT+8').toUTCString(),
- };
- })
- .get();
-
- ctx.state.data = {
- title: '中华人民共和国住房和城乡建设部 - 政策发布',
- link,
- item: await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({ method: 'get', url: item.link });
- const content = cheerio.load(detailResponse.data);
- item.description = content('table[bgcolor="#ffffff"]').html();
- return item;
- })
- )
- ),
- };
-};
diff --git a/lib/routes-deprecated/gov/ngd/index.js b/lib/routes-deprecated/gov/ngd/index.js
deleted file mode 100644
index 45958dd09279..000000000000
--- a/lib/routes-deprecated/gov/ngd/index.js
+++ /dev/null
@@ -1,51 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const slug = ctx.params.slug || 'xwzx-ywdt-index';
-
- const rootUrl = 'http://www.ngd.org.cn';
- const currentUrl = `${rootUrl}/${slug.replaceAll('-', '/')}.htm`;
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
-
- const $ = cheerio.load(response.data);
-
- const list = $('.gp-ellipsis a')
- .slice(0, 15)
- .map((_, item) => {
- item = $(item);
- return {
- title: item.text(),
- link: `${currentUrl.replace('/index.htm', '')}/${item.attr('href')}`,
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: item.link,
- });
- const content = cheerio.load(detailResponse.data);
- const info = content('.articleAuthor').text().split('|');
-
- item.author = info[0].replace('来源:', '');
- item.description = content('.gp-article').html();
- item.pubDate = new Date(info.at(-1).replace('发布时间:', '')).toUTCString();
-
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: $('title').text(),
- link: currentUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/gov/nppa/channels.js b/lib/routes-deprecated/gov/nppa/channels.js
deleted file mode 100644
index bf3e5621c9dc..000000000000
--- a/lib/routes-deprecated/gov/nppa/channels.js
+++ /dev/null
@@ -1,58 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const { parseRelativeDate } = require('@/utils/parse-date');
-const timezone = require('@/utils/timezone');
-
-module.exports = async (ctx) => {
- const { channel } = ctx.params;
- const host = `http://www.nppa.gov.cn`;
- const link = host + `/nppa/channels/${channel}.shtml`;
- const fullpage = await got.get(link + '?' + Date.now()); // 避免CDN缓存
- if (~fullpage.data.indexOf('-404')) {
- ctx.throw(404);
- }
- const $ = cheerio.load(fullpage.data);
- const target = $('ul.m2c2ul li, ul.m2nrul li');
- ctx.state.data = {
- title: '国家新闻出版署 - ' + $('.m2nRt, .m2Top_em').text().trim(),
- link,
- item: await Promise.all(
- target
- .map(async (index, item) => {
- item = $(item);
- const href = item.find('a').attr('href');
- let contenlUrl,
- description = '';
- if (/^https?:\/\//.test(href)) {
- contenlUrl = href;
- } else {
- contenlUrl = host + href;
- description = await ctx.cache.tryGet(contenlUrl, async () => {
- const fullText = await got.get(contenlUrl);
- const $$ = cheerio.load(fullText.data);
- if (~$$('.m2pos').text().indexOf('游戏审批结果')) {
- let fullTextData = '';
- $$('.m3pageCon table.trStyle tbody tr')
- .slice(1)
- .each((index, item) => {
- item = $$(item).find('td');
- fullTextData += $$(item[1]).text().trim() + ' | ';
- });
- return fullTextData.slice(0, -3);
- } else {
- $$('.m3pageCon style, .m3pageCon script').remove();
- return $$('.m3pageCon').text().trim().slice(0, 1024);
- }
- });
- }
- return {
- title: item.find('a').text().trim(),
- description,
- pubDate: timezone(parseRelativeDate(item.find('span').text()), 8),
- link: contenlUrl,
- };
- })
- .get()
- ),
- };
-};
diff --git a/lib/routes-deprecated/gov/nppa/contents.js b/lib/routes-deprecated/gov/nppa/contents.js
deleted file mode 100644
index 4ce146424901..000000000000
--- a/lib/routes-deprecated/gov/nppa/contents.js
+++ /dev/null
@@ -1,38 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const { parseRelativeDate } = require('@/utils/parse-date');
-const timezone = require('@/utils/timezone');
-
-module.exports = async (ctx) => {
- const { channel, content } = ctx.params;
- const host = `http://www.nppa.gov.cn`;
- const link = host + `/nppa/contents/${channel}/${content}.shtml`;
- const fullpage = await got.get(link + '?' + Date.now()); // 避免CDN缓存
- if (~fullpage.data.indexOf('-404')) {
- ctx.throw(404);
- }
- const $ = cheerio.load(fullpage.data);
- const list = $('.m3pageCon table.trStyle tbody tr');
-
- ctx.state.data = {
- title: '国家新闻出版署 - ' + $('.m3page_t').text().trim(),
- link,
- item: await Promise.all(
- list
- .slice(1)
- .map((index, item) => {
- item = $(item).find('td');
- return {
- title: $(item[1]).text().trim(),
- category: $(item[2]).text().trim(),
- description: $(item[5]).text().trim(),
- author: $(item[3]).text().trim() + ' | ' + $(item[4]).text().trim(),
- pubDate: timezone(parseRelativeDate($(item[7]).text().trim()), 8),
- guid: $(item[6]).text().trim(),
- link,
- };
- })
- .get()
- ),
- };
-};
diff --git a/lib/routes-deprecated/gov/province/index.js b/lib/routes-deprecated/gov/province/index.js
deleted file mode 100644
index 40eeb07c7675..000000000000
--- a/lib/routes-deprecated/gov/province/index.js
+++ /dev/null
@@ -1,28 +0,0 @@
-const logger = require('@/utils/logger');
-
-module.exports = async (ctx) => {
- const { name, category } = ctx.params;
- let url = '';
-
- switch (name) {
- case 'jiangsu':
- url = 'http://www.jiangsu.gov.cn';
- break;
- default:
- logger.error('URL pattern not matched');
- }
-
- if (url === '') {
- ctx.throw(404, 'Cannot find page');
- return;
- }
-
- try {
- const getRSS = require(`./${name}`);
- const responseData = await getRSS(url, category);
- ctx.state.data = responseData;
- } catch (error) {
- logger.error(error);
- ctx.throw(404, 'Cannot find page');
- }
-};
diff --git a/lib/routes-deprecated/gov/province/jiangsu/get-content.js b/lib/routes-deprecated/gov/province/jiangsu/get-content.js
deleted file mode 100644
index f2edcf1276ab..000000000000
--- a/lib/routes-deprecated/gov/province/jiangsu/get-content.js
+++ /dev/null
@@ -1,77 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const logger = require('@/utils/logger');
-
-const urlTemplate = (homePage, cid, uid) => {
- let template = `${homePage}/col/col${cid}/index.html`;
- if (uid) {
- template += `?uid=${uid}&pageNum=`;
- }
- return template;
-};
-
-module.exports = async (homePage, cid, uid, totalPage = 1) => {
- let title = '';
- let description = '';
- let item = [];
- try {
- const result = await extract(homePage, cid, uid);
- title = result.title;
- description = result.description;
- item = result.item;
-
- const promises = [];
- for (let page = 2; page <= totalPage; page++) {
- promises.push(extract(homePage, cid, uid, page));
- }
- const pageContent = await Promise.all(promises);
- for (const content of pageContent) {
- if (Array.isArray(content)) {
- item = [...item, ...content];
- }
- }
- } catch {
- logger.error('Cannot load page content');
- }
-
- const link = urlTemplate(homePage, cid);
-
- return { title, link, description, item };
-};
-
-async function extract(homePage, cid, uid, page = 1) {
- const pageLink = urlTemplate(homePage, cid, uid);
-
- const response = await got.get(`${pageLink}${page}`);
-
- const data = response.data;
- const $ = cheerio.load(data);
- const list = $(`#${uid}`)
- .html()
- .match(/
`,
- link: item.find('.stretched-link').attr('href'),
- };
- })
- .get(),
- };
-};
diff --git a/lib/routes-deprecated/grandchallenge/user.js b/lib/routes-deprecated/grandchallenge/user.js
deleted file mode 100644
index 767ea9f92b14..000000000000
--- a/lib/routes-deprecated/grandchallenge/user.js
+++ /dev/null
@@ -1,34 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const id = ctx.params.id;
- const response = await got({
- method: 'get',
- url: `https://grand-challenge.org/users/${id}`,
- });
-
- const data = response.data;
-
- const $ = cheerio.load(data);
- const list = $('.card');
-
- ctx.state.data = {
- title: `${id}'s participations`,
- link: `https://grand-challenge.org/users/${id}`,
- item:
- list &&
- list
- .map((index, item) => {
- item = $(item);
- const itemPicUrl = item.find('img').attr('src');
- const description = item.find('.card-text').text() || 'No description';
- return {
- title: item.find('h5').text(),
- description: `${description}
`,
- link: item.find('.stretched-link').attr('href'),
- };
- })
- .get(),
- };
-};
diff --git a/lib/routes-deprecated/guanggoo/index.js b/lib/routes-deprecated/guanggoo/index.js
deleted file mode 100644
index d5344337e190..000000000000
--- a/lib/routes-deprecated/guanggoo/index.js
+++ /dev/null
@@ -1,81 +0,0 @@
-const url = require('url');
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-const rootUrl = 'http://www.guanggoo.com/';
-
-const config = {
- index: {
- link: '',
- title: '首页',
- },
- qna: {
- link: '/node/qna',
- title: '你问我答',
- },
- lowshine: {
- link: '/node/lowshine',
- title: '同城活动',
- },
- it: {
- link: '/node/IT',
- title: 'IT技术',
- },
- finance: {
- link: '/node/finance',
- title: '金融财经',
- },
- startup: {
- link: '/node/startup',
- title: '创业创客',
- },
- city: {
- link: '/node/city',
- title: '城市建设',
- },
-};
-
-module.exports = async (ctx) => {
- const category = ctx.params.category || 'index';
-
- const cfg = config[category];
- if (!cfg) {
- throw new Error('Bad category. See docs');
- }
-
- const currentUrl = url.resolve(rootUrl, cfg.link);
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
-
- const $ = cheerio.load(response.data);
- const list = $('div.topic-item h3 a')
- .slice(0, 10)
- .map((_, item) => {
- item = $(item);
- return {
- title: item.text(),
- link: url.resolve(rootUrl, item.attr('href').split('#')[0]),
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const res = await got({ method: 'get', url: item.link });
- const content = cheerio.load(res.data);
-
- item.description = content('div.sidebar-left').html();
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: '光谷社区 - ' + cfg.title,
- link: rootUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/guardian/guardian.js b/lib/routes-deprecated/guardian/guardian.js
deleted file mode 100644
index 5a04f3d7f0a1..000000000000
--- a/lib/routes-deprecated/guardian/guardian.js
+++ /dev/null
@@ -1,45 +0,0 @@
-const got = require('@/utils/got');
-const parser = require('@/utils/rss-parser');
-const utils = require('./utils');
-
-const config = {
- editorial: {
- link: `https://www.theguardian.com/profile/editorial`,
- title: 'Editorial',
- rss: 'https://www.theguardian.com/tone/editorials/rss',
- },
- china: {
- link: `https://www.theguardian.com/world/china`,
- title: 'China',
- rss: 'https://www.theguardian.com/world/china/rss',
- },
-};
-
-module.exports = async (ctx) => {
- const type = config[ctx.params.type];
- const feed = await parser.parseURL(type.rss);
- const items = await Promise.all(
- feed.items.splice(0, 10).map(async (item) => {
- const response = await got({
- method: 'get',
- url: item.link,
- });
- const description = utils.ProcessFeed(response.data);
-
- const single = {
- title: item.title,
- description: description ?? item.content,
- pubDate: item.pubDate,
- link: item.link,
- };
- return single;
- })
- );
-
- ctx.state.data = {
- title: 'The Guardian - ' + type.title,
- link: type.link,
- description: 'The Guardian - ' + type.title,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/guardian/utils.js b/lib/routes-deprecated/guardian/utils.js
deleted file mode 100644
index 857c85037419..000000000000
--- a/lib/routes-deprecated/guardian/utils.js
+++ /dev/null
@@ -1,42 +0,0 @@
-const cheerio = require('cheerio');
-
-const ProcessFeed = (data) => {
- const $ = cheerio.load(data);
- const content = $('div.content__article-body');
-
- if (content.length === 0) {
- return '';
- }
-
- // remove useless DOMs
- content.find('aside, .ad-slot, .after-article, .contributions__epic, .submeta, .inline-expand-image, inline-triangle, .block-share').each((i, e) => {
- $(e).remove();
- });
-
- content.find('.element-image').each((i, e) => {
- const pic = $(e).find('img');
- let rpic = `
' +
- 'Brand: '.bold() +
- videoBrand +
- '
' +
- 'Tags: '.bold() +
- videoTags +
- '
' +
- 'Description: '.bold() +
- videoDescription +
- '
' +
- '' +
- '
' +
- '
',
- link: videoUrl,
- };
- }),
- };
-};
diff --git a/lib/routes-deprecated/haohaozhu/discover.js b/lib/routes-deprecated/haohaozhu/discover.js
deleted file mode 100644
index e19524fd4547..000000000000
--- a/lib/routes-deprecated/haohaozhu/discover.js
+++ /dev/null
@@ -1,42 +0,0 @@
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- const keyword = ctx.params.keyword && ctx.params.keyword !== 'all' && ctx.params.keyword !== '全部' ? ctx.params.keyword : '';
-
- const url = 'https://www.haohaozhu.cn/community/discover';
-
- const response = await got({
- method: 'post',
- url: 'https://www.haohaozhu.cn/f/y/api/Share/AllPhotoInPc',
- headers: {
- Referer: url,
- },
- form: {
- keyword,
- page: 1,
- time: Date.now(),
- },
- });
-
- const list = response.data.data.rows;
-
- ctx.state.data = {
- title: `好好住 - 发现${keyword ? ' - ' + keyword : ''}`,
- link: url,
- item: list
- .map((item) => {
- if (item.is_advertisement !== 0 || !item.photo || !item.photo.photo_info) {
- return '';
- }
- return {
- title: item.photo.photo_info.remark,
- author: item.photo.user_info.nick,
- description: item.photo.photo_info.image_list.map((image) => ``).join(''),
- link: url,
- guid: item.photo.photo_info.id,
- pubDate: new Date(item.photo.photo_info.addtime * 1000),
- };
- })
- .filter((item) => item !== ''),
- };
-};
diff --git a/lib/routes-deprecated/haohaozhu/whole-house.js b/lib/routes-deprecated/haohaozhu/whole-house.js
deleted file mode 100644
index fd6435b096a8..000000000000
--- a/lib/routes-deprecated/haohaozhu/whole-house.js
+++ /dev/null
@@ -1,75 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const keyword = ctx.params.keyword && ctx.params.keyword !== 'all' && ctx.params.keyword !== '全部' ? ctx.params.keyword : '';
-
- const url = 'https://www.haohaozhu.cn/community/whole-house';
-
- const response = await got({
- method: 'post',
- url: 'https://www.haohaozhu.cn/f/y/api/Share/GetArticle',
- headers: {
- Referer: url,
- },
- form: {
- keyword,
- page: 1,
- },
- });
-
- const list = response.data.data.rows;
-
- const parseContent = (htmlString) => {
- const $ = cheerio.load(htmlString);
-
- const content = $('.whole-header').parent();
- $('.whole-title').remove();
- $('.whole-user').remove();
- $('.question').appendTo(content);
-
- return {
- description: content.html(),
- };
- };
-
- const out = await Promise.all(
- list.map(async (item, index) => {
- const link = `https://www.haohaozhu.cn/community/whole-house-detail/${item.article_id}`;
-
- const time = new Date();
- time.setMinutes(time.getMinutes() - index);
-
- const cache = await ctx.cache.get(link);
- if (cache) {
- return JSON.parse(cache);
- }
-
- const rssitem = {
- title: item.article_info.title,
- link,
- author: item.user_info.nick,
- pubDate: time,
- };
-
- try {
- const response = await got.get(link);
- const result = parseContent(response.data);
- if (!result.description) {
- return '';
- }
- rssitem.description = result.description;
- } catch {
- return '';
- }
- ctx.cache.set(link, JSON.stringify(rssitem));
- return rssitem;
- })
- );
-
- ctx.state.data = {
- title: `好好住 - 整屋案例${keyword ? ' - ' + keyword : ''}`,
- link: url,
- item: out.filter((item) => item !== ''),
- };
-};
diff --git a/lib/routes-deprecated/hatena/anonymous_diary/archive.js b/lib/routes-deprecated/hatena/anonymous_diary/archive.js
deleted file mode 100644
index f542b35edd6d..000000000000
--- a/lib/routes-deprecated/hatena/anonymous_diary/archive.js
+++ /dev/null
@@ -1,52 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const url = require('url');
-
-function getPubDate(yyyyMMddhhmmss) {
- const yyyy = yyyyMMddhhmmss.slice(0, 4);
- const MM = yyyyMMddhhmmss.slice(4, 6);
- const dd = yyyyMMddhhmmss.slice(6, 8);
- const hh = yyyyMMddhhmmss.slice(8, 10);
- const mm = yyyyMMddhhmmss.slice(10, 12);
- const ss = yyyyMMddhhmmss.slice(12, 14);
- return new Date(`${yyyy}-${MM}-${dd}T${hh}:${mm}:${ss}+0900`);
-}
-
-module.exports = async (ctx) => {
- const baseURL = 'https://anond.hatelabo.jp';
-
- const archiveIndex = await got({
- method: 'get',
- url: url.resolve(baseURL, '/archive'),
- });
-
- const latestURL = url.resolve(baseURL, cheerio.load(archiveIndex.data)('.archives a').first().attr('href'));
- const response = await got({
- method: 'get',
- url: latestURL,
- });
-
- const $ = cheerio.load(response.data);
- const list = $('.archives li');
-
- ctx.state.data = {
- title: 'はてな匿名ダイアリー - 人気記事アーカイブ',
- link: 'https://anond.hatelabo.jp/archive',
- language: 'ja',
- item:
- list &&
- list
- .map((idx, item) => {
- item = $(item);
- const a = item.find('a').first();
- const yyyyMMddhhmmss = a.attr('href').replace('/', '');
- return {
- title: a.text(),
- description: item.find('blockquote p').first().text(),
- link: url.resolve(baseURL, a.attr('href')),
- pubDate: getPubDate(yyyyMMddhhmmss).toUTCString(),
- };
- })
- .get(),
- };
-};
diff --git a/lib/routes-deprecated/hdx/explore.js b/lib/routes-deprecated/hdx/explore.js
deleted file mode 100644
index 64f0bdeb8cb8..000000000000
--- a/lib/routes-deprecated/hdx/explore.js
+++ /dev/null
@@ -1,57 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const URL = require('url');
-
-module.exports = async (ctx) => {
- const response = await got({
- method: 'get',
- url: 'https://www.huodongxing.com/eventlist',
- });
-
- const data = response.data;
- const $ = cheerio.load(data);
-
- const list = $('div.search-tab-content-item').get();
-
- const ProcessFeed = async (link) => {
- const response = await got({
- method: 'get',
- url: link,
- });
- const $ = cheerio.load(response.data);
- const content = $('#event_desc_page');
-
- return content.html();
- };
-
- const host = 'https://www.huodongxing.com';
-
- const items = await Promise.all(
- list.map(async (item) => {
- const $ = cheerio.load(item);
- const $a = $('.item-title');
- const link = URL.resolve(host, $a.attr('href'));
-
- const cache = await ctx.cache.get(link);
- if (cache) {
- return JSON.parse(cache);
- }
-
- const single = {
- title: $a.text(),
- description: await ProcessFeed(link),
- link,
- author: $('.user-name').text(),
- };
-
- ctx.cache.set(link, JSON.stringify(single));
- return single;
- })
- );
-
- ctx.state.data = {
- title: '活动行',
- link: 'https://www.huodongxing.com/eventlist',
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/hentai-cosplays/porn-images-xxx.js b/lib/routes-deprecated/hentai-cosplays/porn-images-xxx.js
deleted file mode 100644
index b16829c20b81..000000000000
--- a/lib/routes-deprecated/hentai-cosplays/porn-images-xxx.js
+++ /dev/null
@@ -1,11 +0,0 @@
-const { processFeed } = require('./utils');
-
-module.exports = async (ctx) => {
- const url = ctx.params.type ? `https://ja.porn-images-xxx.com/search/${ctx.params.type}/${encodeURIComponent(ctx.params.name)}/` : 'https://ja.porn-images-xxx.com/search/';
- const items = await processFeed(ctx, url);
- ctx.state.data = {
- title: `${ctx.params.name || '新着画像一覧'} - エロ画像`,
- link: url,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/hentai-cosplays/utils.js b/lib/routes-deprecated/hentai-cosplays/utils.js
deleted file mode 100644
index c7ea42617652..000000000000
--- a/lib/routes-deprecated/hentai-cosplays/utils.js
+++ /dev/null
@@ -1,52 +0,0 @@
-const cheerio = require('cheerio');
-const got = require('@/utils/got');
-
-const host = 'https://ja.porn-images-xxx.com/';
-
-exports.processFeed = async function processFeed(ctx, link) {
- const response = await got.get(link);
- const $ = cheerio.load(response.body);
- const list = $('ul#image-list li')
- .map((index, item) => {
- item = $(item);
- return {
- title: item.find('.image-list-item-title').text(),
- link: item.find('.image-list-item-title > a').attr('href'),
- date: item.find('.image-list-item-regist-date > span').text(),
- };
- })
- .get();
- return Promise.all(
- list.map(async (info) => {
- const title = info.title.trim();
- const date = info.date;
- const itemUrl = host + 'story' + info.link.replace('/image', '');
-
- const cache = await ctx.cache.get(itemUrl);
- if (cache) {
- return JSON.parse(cache);
- }
-
- const response = await got.get(itemUrl);
- const $ = cheerio.load(response.data);
- const images = $('amp-img')
- .map((index, element) => {
- element = $(element);
- const img_src = element.attr('src');
- return `
`;
- })
- .get()
- .join(' ');
- const item = {
- title,
- link: itemUrl,
- description: images,
- pubDate: new Date(date).toUTCString(),
- };
- if (images) {
- ctx.cache.set(itemUrl, JSON.stringify(item));
- }
- return item;
- })
- );
-};
diff --git a/lib/routes-deprecated/hentaimama/videos.js b/lib/routes-deprecated/hentaimama/videos.js
deleted file mode 100644
index 5683a330215e..000000000000
--- a/lib/routes-deprecated/hentaimama/videos.js
+++ /dev/null
@@ -1,32 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const response = await got({
- method: 'get',
- url: 'http://hentaimama.io/recent-episodes/',
- });
-
- const data = response.data;
-
- const $ = cheerio.load(data);
- const list = $('.item.episodes');
-
- ctx.state.data = {
- title: 'Hentaimama - Recent Videos',
- link: 'http://hentaimama.io/recent-episodes/',
- language: 'en-us',
- item: list
- .map((index, item) => {
- item = $(item);
- return {
- title: item.find('img').attr('alt'),
- description: '
',
- pubDate: item.find('.data span').text(),
- guid: new Date(item.find('.data span').text()),
- link: item.find('a').attr('href'),
- };
- })
- .get(),
- };
-};
diff --git a/lib/routes-deprecated/hexo/fluid.js b/lib/routes-deprecated/hexo/fluid.js
deleted file mode 100644
index cae0672f6ea3..000000000000
--- a/lib/routes-deprecated/hexo/fluid.js
+++ /dev/null
@@ -1,49 +0,0 @@
-const cheerio = require('cheerio');
-const got = require('@/utils/got');
-const config = require('@/config').value;
-
-module.exports = async (ctx) => {
- if (!config.feature.allow_user_supply_unsafe_domain) {
- ctx.throw(403, `This RSS is disabled unless 'ALLOW_USER_SUPPLY_UNSAFE_DOMAIN' is set to 'true'.`);
- }
- const url = `http://${ctx.params.url}`;
- const res = await got.get(`${url}/archives/`);
- const $ = cheerio.load(res.data);
-
- const list = $('.list-group-item');
-
- const count = [];
- for (let i = 0; i < Math.min(list.length, 5); i++) {
- count.push(i);
- }
- const out = await Promise.all(
- count.map(async (i) => {
- const each = $(list[i]);
- const storyLink = each.attr('href');
- const item = {
- title: each.find('.archive-post-title').text(),
- link: new URL(storyLink, url),
- };
- const key = item.link;
- const value = await ctx.cache.get(key);
-
- if (value) {
- item.description = value;
- } else {
- const storyDeatil = await got.get(item.link);
- const data = storyDeatil.data;
- const $ = cheerio.load(data);
- item.pubDate = $('time').attr('datetime');
- item.description = $('.markdown-body').html();
- ctx.cache.set(key, item.description);
- }
- return item;
- })
- );
- ctx.state.data = {
- title: $('.navbar-brand strong').text(),
- link: url,
- description: $('[name=description]').attr('content'),
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/hexo/next.js b/lib/routes-deprecated/hexo/next.js
deleted file mode 100644
index 46c44887abc4..000000000000
--- a/lib/routes-deprecated/hexo/next.js
+++ /dev/null
@@ -1,49 +0,0 @@
-const cheerio = require('cheerio');
-const got = require('@/utils/got');
-const config = require('@/config').value;
-
-module.exports = async (ctx) => {
- if (!config.feature.allow_user_supply_unsafe_domain) {
- ctx.throw(403, `This RSS is disabled unless 'ALLOW_USER_SUPPLY_UNSAFE_DOMAIN' is set to 'true'.`);
- }
- const url = `http://${ctx.params.url}`;
- const res = await got.get(`${url}/archives/`);
- const $ = cheerio.load(res.data);
-
- const list = $('.post-header');
-
- const count = [];
- for (let i = 0; i < Math.min(list.length, 5); i++) {
- count.push(i);
- }
- const out = await Promise.all(
- count.map(async (i) => {
- const each = $(list[i]);
- const storyLink = each.find('.post-title-link').attr('href');
- const item = {
- title: each.find('[itemprop=name]').text(),
- link: new URL(storyLink, url),
- };
- const key = item.link;
- const value = await ctx.cache.get(key);
-
- if (value) {
- item.description = value;
- } else {
- const storyDeatil = await got.get(item.link);
- const data = storyDeatil.data;
- const $ = cheerio.load(data);
- item.pubDate = $('time').attr('datetime');
- item.description = $('.post-body').html();
- ctx.cache.set(key, item.description);
- }
- return item;
- })
- );
- ctx.state.data = {
- title: $('.site-title').text(),
- link: url,
- description: $('[name=description]').attr('content'),
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/hexo/yilia.js b/lib/routes-deprecated/hexo/yilia.js
deleted file mode 100644
index c55544f8e785..000000000000
--- a/lib/routes-deprecated/hexo/yilia.js
+++ /dev/null
@@ -1,34 +0,0 @@
-const cheerio = require('cheerio');
-const got = require('@/utils/got');
-const config = require('@/config').value;
-
-module.exports = async (ctx) => {
- if (!config.feature.allow_user_supply_unsafe_domain) {
- ctx.throw(403, `This RSS is disabled unless 'ALLOW_USER_SUPPLY_UNSAFE_DOMAIN' is set to 'true'.`);
- }
- const url = `http://${ctx.params.url}`;
- const res = await got.get(url);
- const $ = cheerio.load(res.data);
- const authorInfo = $('.left-col').find('#header');
- const title = authorInfo.find('.header-author').text();
- const subtitle = authorInfo.find('.header-subtitle').text();
- const articleNodeList = $('article');
- const articles = [...articleNodeList].map((article) => {
- const each = $(article);
- const titleEl = each.find('.article-title');
-
- return {
- title: titleEl.text(),
- link: encodeURI(`${url}${titleEl.attr('href')}`),
- description: each.find('.article-entry').text(),
- pubDate: each.find('time').attr('datetime'),
- };
- });
-
- ctx.state.data = {
- title,
- link: url,
- description: subtitle,
- item: articles,
- };
-};
diff --git a/lib/routes-deprecated/hkej/index.js b/lib/routes-deprecated/hkej/index.js
deleted file mode 100644
index 46b2dadcd627..000000000000
--- a/lib/routes-deprecated/hkej/index.js
+++ /dev/null
@@ -1,138 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const dayjs = require('dayjs');
-const utc = require('dayjs/plugin/utc');
-const { parseDate } = require('@/utils/parse-date');
-const timezone = require('@/utils/timezone');
-
-const categories = {
- index: {
- name: '',
- link: '/instantnews/',
- title: '即時香港中國 國際金融 股市經濟新聞',
- description: '全天候即時港股、香港財經、國際金融和經濟新聞、中國經濟新聞資訊和分析',
- },
- stock: {
- name: '港股直擊',
- link: '/instantnews/stock',
- title: '即時香港股市 股份板塊 攻略分析',
- description: '全天候即時港股追蹤和直擊分析,股份異動、大行報告、沽空、速評',
- },
- hongkong: {
- name: '香港財經',
- link: '/instantnews/hongkong',
- title: '即時香港經濟 中港經濟融合追蹤分析',
- description: '香港經濟和焦點行業 中港融合和商機的分析',
- },
- china: {
- name: '中國財經',
- link: '/instantnews/china',
- title: '即時中國經濟 國策焦點 中港融合追蹤分析',
- description: '香港經濟和焦點行業 中港融合和商機的分析',
- },
- international: {
- name: '國際財經',
- link: '/instantnews/international',
- title: '即時國際財經 股市匯市 央行政策',
- description: '國際財經 金融股市 央行政策的新聞和分析',
- },
- property: {
- name: '地產新聞',
- link: '/property/news',
- title: '地產投資',
- description: '即時地產新聞, 新盤資訊, 樓市分析, 藍籌屋苑數據及室內設計鑑賞',
- },
- current: {
- name: '時事脈搏',
- link: '/instantnews/current',
- title: '即時香港中國 國際金融 股市經濟新聞',
- description: '全天候即時香港股市、金融、經濟新聞資訊和分析,致力與讀者一起剖釋香港、關注兩岸、放眼全球政經格局',
- },
-};
-
-module.exports = async (ctx) => {
- const category = ctx.params.category ?? 'index';
- const cat = categories[category];
- const baseUrl = 'https://www2.hkej.com';
-
- dayjs.extend(utc);
- const yesterday = dayjs().utcOffset(8).subtract(1, 'day').format('YYYY-MM-DD');
- const today = dayjs().utcOffset(8).format('YYYY-MM-DD');
-
- const response = await got({
- method: 'get',
- url: baseUrl + cat.link,
- headers: {
- Referer: baseUrl,
- },
- });
-
- const $ = cheerio.load(response.data);
-
- const list = $('h3.in_news_u_t a, h4.hkej_hl-news_topic_2014 a, div.hkej_toc_listingAll_news2_2014 h3 a, div.hkej_toc_cat_top_detail h3 a, div.allNews div.news h1 a, div#div_listingAll div.news2 h3 a')
- .map((_, item) => {
- item = $(item);
- return {
- title: item.text().trim(),
- link: baseUrl + item.attr('href').substring(0, item.attr('href').lastIndexOf('/')),
- };
- })
- .get();
-
- const items = await Promise.all(
- list &&
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const article = await got({
- method: 'get',
- url: item.link,
- headers: {
- Referer: cat.link,
- },
- });
- const content = cheerio.load(article.data);
-
- // remove unwanted elements
- content('#ad_popup').remove();
- content('[class^=ad-]').remove();
- content('[id^=ad-]').remove();
- content('[id^=div-gpt-ad-]').remove();
- content('.hkej_sub_ex_article_nonsubscriber_ad_2014').remove();
-
- // fix article image
- content('div.hkej_detail_thumb_2014 a').each((_, e) => {
- e = $(e);
- if (e.attr('href')) {
- content(e).after(`
${item.note}`,
- // 文章发布时间
- pubDate: new Date(new Date(item.dateline) - 8 * 60 * 60 * 1000),
- // 文章链接
- link: `http://news.iciba.com/views/dailysentence/daily.html#!/detail/title/${item.dateline}`,
- itunes_item_image: item.picture3, // 每个track单独的图片
- enclosure_url: item.tts, // 音频链接
- enclosure_type: `audio/mpeg`,
- })),
- };
-};
diff --git a/lib/routes-deprecated/icity/index.js b/lib/routes-deprecated/icity/index.js
deleted file mode 100644
index c6ec0f34dd07..000000000000
--- a/lib/routes-deprecated/icity/index.js
+++ /dev/null
@@ -1,30 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const rootUrl = `https://icity.ly/u/${ctx.params.id}`;
- const response = await got({
- method: 'get',
- url: rootUrl,
- });
-
- const $ = cheerio.load(response.data);
- const items = $('li.diary')
- .map((_, item) => {
- item = $(item);
- return {
- link: `https://icity.ly${item.find('a.timeago').attr('href')}`,
- title: item.prev('li.day-cut').text(),
- description: item.find('div.line').html(),
- pubDate: new Date(item.find('time.hours').attr('datetime')).toUTCString(),
- };
- })
- .get();
-
- ctx.state.data = {
- title: $('title').text(),
- link: rootUrl,
- item: items,
- description: $('div.bio').text(),
- };
-};
diff --git a/lib/routes-deprecated/icourse163/newest.js b/lib/routes-deprecated/icourse163/newest.js
deleted file mode 100644
index 47d12e89ea96..000000000000
--- a/lib/routes-deprecated/icourse163/newest.js
+++ /dev/null
@@ -1,77 +0,0 @@
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- const link = 'https://www.icourse163.org/category/all';
- const homePage = await got({
- method: 'get',
- url: link,
- });
- const csrfKey = homePage.headers['set-cookie'][0].split(';')[0].split('=')[1];
-
- const response = await got({
- method: 'post',
- url: `https://www.icourse163.org/web/j/courseBean.getCoursePanelListByFrontCategory.rpc?csrfKey=${csrfKey}`,
- headers: {
- Cookie: `NTESSTUDYSI=${csrfKey};`,
- },
- form: {
- categoryId: -1,
- type: 30,
- orderBy: 10,
- pageIndex: 1,
- pageSize: 20,
- },
- });
-
- const items = response.data.result.result.map((item) => {
- const title = item.name;
- const link = `https://www.icourse163.org/course/${item.schoolPanel.shortName}-${item.id}`;
- const lectors = item.termPanel.lectorPanels.reduce((lectors, lector) => {
- lectors += `${lector.realName || lector.nickName}、`;
- return lectors;
- }, '');
- const tags = (item.mocTagDtos || []).reduce((tags, tag) => {
- tags += `${tag.name}、`;
- return tags;
- }, '');
- const startTime = new Date(item.termPanel.startTime);
- const startYear = startTime.getFullYear();
- const startMonth = (startTime.getMonth() + 1).toString().padStart(2, '0');
- const startDate = startTime.getDate();
- const startTimeString = item.termPanel.startTime === 32_503_651_201_000 ? '待定' : `${startYear}-${startMonth}-${startDate}`;
- const media = item.VideoUrl
- ? `
-
`;
- const description = `
- ${title}
- ${tags}
- ${item.schoolPanel.name} ${lectors}
- 开课时间: ${startTimeString}
- ${media}
- ${(item.termPanel.jsonContent || '').replace('spContent=', '')}
- `;
-
- return {
- title,
- link,
- description,
- };
- });
-
- ctx.state.data = {
- title: '中国大学MOOC(慕课)-最新',
- link,
- description:
- '中国大学MOOC(慕课) 是爱课程网携手网易云课堂打造的在线学习平台,每一个有提升愿望的人,都可以在这里学习中国优质的大学课程,学完还能获得认证证书。中国大学MOOC是国内优质的中文MOOC学习平台,拥有众多985高校的大学课程,与名师零距离。',
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/idownloadblog/index.js b/lib/routes-deprecated/idownloadblog/index.js
deleted file mode 100644
index e7b9a7fecc04..000000000000
--- a/lib/routes-deprecated/idownloadblog/index.js
+++ /dev/null
@@ -1,51 +0,0 @@
-const got = require('@/utils/got');
-const parser = require('@/utils/rss-parser');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const feed = await parser.parseURL('https://www.idownloadblog.com/feed');
-
- const ProcessFeed = (data) => {
- const $ = cheerio.load(data);
-
- const content = $('div.post-content');
-
- content.find('.lazy-hidden').each((i, e) => {
- $(``).insertBefore(e);
- $(e).remove();
- });
-
- content.find('.code-block, noscript').each((i, e) => {
- $(e).remove();
- });
-
- return content.html();
- };
-
- const items = await Promise.all(
- feed.items.map(async (item) => {
- const response = await got({
- method: 'get',
- url: item.link,
- });
-
- const description = ProcessFeed(response.data);
-
- const single = {
- title: item.title,
- description,
- pubDate: item.pubDate,
- link: item.link,
- author: item['dc:creator'],
- };
- return single;
- })
- );
-
- ctx.state.data = {
- title: 'iDownloadBlog',
- link: 'https://www.idownloadblog.com/',
- description: 'iDownloadBlog',
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/ifnews/column.js b/lib/routes-deprecated/ifnews/column.js
deleted file mode 100644
index 9e1b4316aa9d..000000000000
--- a/lib/routes-deprecated/ifnews/column.js
+++ /dev/null
@@ -1,76 +0,0 @@
-const cheerio = require('cheerio');
-const got = require('@/utils/got');
-const { parseRelativeDate } = require('@/utils/parse-date');
-const timezone = require('@/utils/timezone');
-
-module.exports = async (ctx) => {
- const cid = ctx.params.cid;
- const url = 'http://www.ifnews.com';
- const respones = await got({
- method: 'get',
- url: `http://api.ifnews.com/api/getArticles?cid=${cid}`,
- headers: {
- Referer: `${url}/column.html?cid=${cid}`,
- },
- });
- const data = respones.data;
-
- const list = data.list.map((item) => ({
- title: item.title,
- author: item.createUser,
- link: `${url}/news.html?aid=${item.fileID}`,
- pubDate: timezone(parseRelativeDate(item.publishTime), +8),
- aid: item.fileID,
- }));
-
- const result = await Promise.all(
- list.map(async (item) => {
- const link = item.link;
-
- const cache = await ctx.cache.get(link);
- if (cache) {
- return JSON.parse(cache);
- }
-
- // 页面数据
- const contentResponse = await got({
- method: 'get',
- url: `http://api.ifnews.com/api/getArticle?aid=${item.aid}`,
- headers: {
- Referer: item.link,
- },
- });
- const content = contentResponse.data;
-
- // 页面框架
- const pageResponse = await got.get(item.link);
- const pageElement = cheerio.load(pageResponse.data);
- const pageHTML = pageElement('.content').html();
-
- // 填充页面框架使其变成真正的文章
- // 主要处理一些被{{xxx}}框起来的变量
- // 确实, 一排replace看起来很吓人, 如果有人有更好的方法实现就好了
- // 我也试过用MDN上eval()页面教的构造function对象的方法来直接执行{{}}内的js代码, 但是好像效果不佳...
- item.description = pageHTML
- .replace(/'));
-
- item.author = content('.creator').eq(0).text();
- item.description = content('.post').eq(0).html();
-
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: `${response.data.topic_list.tags[0].name} - MarginNote 中文论坛`,
- link: currentUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/mathpix/blog.js b/lib/routes-deprecated/mathpix/blog.js
deleted file mode 100644
index aa151bdc6a73..000000000000
--- a/lib/routes-deprecated/mathpix/blog.js
+++ /dev/null
@@ -1,52 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const rootUrl = 'https://mathpix.com';
- const currentUrl = `${rootUrl}/blog`;
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
-
- const $ = cheerio.load(response.data);
-
- const list = $('.articles__text-content a')
- .slice(0, 10)
- .map((_, item) => {
- item = $(item);
- return {
- title: item.text(),
- link: `${rootUrl}${item.attr('href')}`,
- pubDate: new Date(item.parent().find('.articles__date').text()).toUTCString(),
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: item.link,
- });
- const content = cheerio.load(detailResponse.data);
-
- const titleImage = content('.article__image-area img');
- titleImage.attr('src', `${rootUrl}${titleImage.attr('srcset')}`);
- titleImage.removeAttr('srcset');
-
- item.author = content('.article__titles-wrapper summary').text().replace('By ', '');
- item.description = content('.article__image-area').html() + content('.article__content').html();
-
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: 'Mathpix Blog',
- link: currentUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/mathunion/fields-medal.js b/lib/routes-deprecated/mathunion/fields-medal.js
deleted file mode 100644
index e019065d980e..000000000000
--- a/lib/routes-deprecated/mathunion/fields-medal.js
+++ /dev/null
@@ -1,38 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const rootUrl = 'https://www.mathunion.org';
- const currentUrl = `${rootUrl}/imu-awards/fields-medal`;
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
-
- const $ = cheerio.load(response.data);
-
- const items = $('div.main-section')
- .eq(2)
- .find('.list__group')
- .map((_, item) => {
- item = $(item);
- const year = item.find('h3').text();
- const detailUrl = item.find('ul li a').attr('href');
-
- item.find('h3, ul').remove();
-
- return {
- title: year,
- link: detailUrl || currentUrl,
- description: `
${item.html()}
`,
- pubDate: new Date(`${year}-12-31`).toUTCString(),
- };
- })
- .get();
-
- ctx.state.data = {
- title: $('title').text(),
- link: currentUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/mcbbs/forum.js b/lib/routes-deprecated/mcbbs/forum.js
deleted file mode 100644
index dcd52d02091f..000000000000
--- a/lib/routes-deprecated/mcbbs/forum.js
+++ /dev/null
@@ -1,61 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const utils = require('./utils');
-const queryString = require('query-string');
-
-module.exports = async (ctx) => {
- const type = ctx.params.type;
-
- const response = await got(utils.forumUrl, {
- method: 'get',
- searchParams: queryString.stringify({
- mod: 'forumdisplay',
- fid: type,
- // 最新帖子
- filter: 'lastpost',
- orderby: 'lastpost',
- }),
- prefixUrl: utils.host,
- });
- const data = response.data;
- const $ = cheerio.load(data);
-
- const title = $('title').text();
- const list = $('#separatorline ~ tbody');
- const description = $('meta[name="description"]').attr('content');
- const item = list
- .map((index, element) => {
- const title = $('.s', element).text();
- const href = $('.icn > a', element).attr('href');
- const link = `${utils.host}/${href}`;
- const postBy = $('.by', element);
- const author = $('cite', postBy[0]);
- const postDate = $('em', postBy[0]);
- const endAuthor = $('cite', postBy[1]);
- const endDate = $('em', postBy[1]);
- const description = `${author.html()}发表于${postDate.html()},最后由${endAuthor.html()}于${endDate.html()}回复。`;
- // mcbbs 表示时间有两种格式
- const dateText = $('span[title]', endDate).attr('title') || endDate.text();
- const pubDate = new Date(`${dateText} GMT+0800`).toUTCString();
- const category = $('.new > em', element).text();
-
- const signle = {
- title,
- link,
- author: author.text(),
- description,
- pubDate,
- category,
- };
- return signle;
- })
- .get();
-
- ctx.state.data = {
- title,
- link: response.url,
- description,
- allowEmpty: true,
- item,
- };
-};
diff --git a/lib/routes-deprecated/mcbbs/post.js b/lib/routes-deprecated/mcbbs/post.js
deleted file mode 100644
index 61820e1fa09b..000000000000
--- a/lib/routes-deprecated/mcbbs/post.js
+++ /dev/null
@@ -1,58 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const utils = require('./utils');
-const queryString = require('query-string');
-
-module.exports = async (ctx) => {
- const tid = ctx.params.tid;
- const authorid = ctx.params.authorid;
- const response = await got(utils.forumUrl, {
- method: 'get',
- searchParams: queryString.stringify({
- mod: 'viewthread',
- tid,
- authorid,
- // 倒序查看帖子
- ordertype: 1,
- }),
- prefixUrl: utils.host,
- });
- const data = response.data;
- const $ = cheerio.load(data);
- const title = $('title').text();
- const description = $('meta[name="description"]').attr('content');
- // const description = $('div[id^=post_] > .t_f').html();
- const postPan = authorid ? $('#postlist > div[id^=post_]') : $('#postlist > div[id^=post_]').nextAll();
- const item = postPan
- .map((index, element) => {
- const link = utils.host + '/' + $('[id^=postnum]', element).attr('href');
- const xw1 = $('.authi > .xw1', element);
- const author = xw1.text();
- const description = $('.t_f', element).html();
- const em = $('[id^=authorposton]', element);
- const date = em.text();
- const span = $('span[title]', em);
- // mcbbs 表示时间有两种格式
- const postDate = span.attr('title') || date;
- const title = `${xw1.html()} ${em.html()}`;
- const pubDate = new Date(`${postDate} GMT+0800`).toUTCString();
-
- const signle = {
- title,
- link,
- author,
- description,
- pubDate,
- };
- return signle;
- })
- .get();
-
- ctx.state.data = {
- title,
- link: response.url,
- description,
- allowEmpty: true,
- item,
- };
-};
diff --git a/lib/routes-deprecated/mcbbs/utils.js b/lib/routes-deprecated/mcbbs/utils.js
deleted file mode 100644
index 5b1e89e41687..000000000000
--- a/lib/routes-deprecated/mcbbs/utils.js
+++ /dev/null
@@ -1,6 +0,0 @@
-const utils = {
- host: 'https://www.mcbbs.net',
- forumUrl: 'forum.php',
-};
-
-module.exports = utils;
diff --git a/lib/routes-deprecated/mcdonalds/news.js b/lib/routes-deprecated/mcdonalds/news.js
deleted file mode 100644
index 8de7a539b8e1..000000000000
--- a/lib/routes-deprecated/mcdonalds/news.js
+++ /dev/null
@@ -1,53 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const category_param = ctx.params.category || 'news_list';
- const categories = category_param.split('+');
- const baseUrl = 'https://www.mcdonalds.com.cn/news/';
-
- const get_news_list = (cates) =>
- Promise.all(
- cates.map(async (cate) => {
- const response = await got.get(baseUrl + cate);
- const $ = cheerio.load(response.data);
- // console.log($('title').text());
- const news = $('.news_list .box-container > div')
- .slice(0, 10)
- .map((idx, item) => {
- item = $(item);
- return item.find('a[target]').attr('href');
- })
- .get();
- // console.log(news);
- return news;
- })
- );
- const all_news = (await get_news_list(categories)).flat();
-
- const out = await Promise.all(
- all_news.map(async (news_url) => {
- const news_detail = await ctx.cache.tryGet(news_url, async () => {
- const result = await got.get(news_url);
- const $ = cheerio.load(result.data);
-
- // console.log($('h3 ~ time').text(), news_url);
-
- return {
- title: $('h3').text(),
- link: news_url,
- // author,
- pubDate: new Date($('h3 ~ time').text()).toUTCString(),
- description: $('.cmsPage').html(),
- };
- });
- return news_detail;
- })
- );
-
- ctx.state.data = {
- title: '麦当劳资讯',
- link: baseUrl,
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/mediadigest/category.js b/lib/routes-deprecated/mediadigest/category.js
deleted file mode 100644
index 472d61bab69f..000000000000
--- a/lib/routes-deprecated/mediadigest/category.js
+++ /dev/null
@@ -1,130 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-function getArticle(ctx, list) {
- const now = list.map((line) =>
- ctx.cache.tryGet(line, async () => {
- const a_r = await got.get(`https://app3.rthk.hk/mediadigest/${line}`);
- const $ = cheerio.load(a_r.data);
- // title
- const h1 = $('h1.story-title').text();
- // author
- const author_list = $('div.story-author');
- const authors = author_list.map((_index, author) => $(author).text());
- const author = authors.map((_index, author) => `${author}
`);
- const s_author = author.toArray().join('');
- const author_block = `
`;
- // date
- const date = $('div.story-calendar').text();
- // desc
- const desc = `${$(author_block)}${$('div.story-content').html()}`;
-
- return {
- title: h1,
- description: desc,
- pubDate: new Date(`${date}T09:00:00+0800`).toUTCString(),
- link: line,
- };
- })
- );
- // 執行一個切片 (20 個文章 URL) 的任務並將結果資料推至 rss 値
- return Promise.all(now);
-}
-
-module.exports = async (ctx) => {
- const range = ctx.params.range || 'latest';
- const category = ctx.params.category || 'all';
-
- // for range validation
- const num = /^[1-9]\d{3}$/;
- const current_year = new Date().getFullYear();
- // placeholders
- let title = '傳媒透視';
- let rss = [
- {
- description: ':range input.:range參數有誤。:range参数有误。`;
-
- // 列表上提取到的信息
- return {
- title: $title.text(),
- description: text,
- link: itemUrl,
- author: $('.feed-name').text(),
- guid: itemUrl,
- };
- });
-};
-
-module.exports = {
- ProcessFeed,
-};
diff --git a/lib/routes-deprecated/meituan/open/announce.js b/lib/routes-deprecated/meituan/open/announce.js
deleted file mode 100644
index d320bc2b45ef..000000000000
--- a/lib/routes-deprecated/meituan/open/announce.js
+++ /dev/null
@@ -1,45 +0,0 @@
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- const response = await got({
- method: 'get',
- url: 'https://developer.meituan.com/api/v1/announcement/menu-page?docKey=anno-all&pageSize=100&pageNum=1',
- });
- const docList = response.data.data.docList;
-
- const url = 'https://developer.meituan.com/api/v1/doc/content';
-
- // https://developer.meituan.com/api/v1/doc/content?docKey=announcement-468
- const articleList = await Promise.all(
- docList.map(async (item) => {
- const articleUrl = `${url}?docKey=${item.docKey}`;
- const cacheKey = `${articleUrl}_${item.modifyTime}`;
-
- const cache = await ctx.cache.get(cacheKey);
- if (cache) {
- return JSON.parse(cache);
- } else {
- const articleResp = await got.get(articleUrl);
- const article = {
- title: item.title,
- link: `https://developer.meituan.com/isv/announcement/detail?dockey=anno-all&id=${item.docKey}`,
- description: articleResp.data.data.docDataItemDtos[0].content,
- pubDate: item.modifyTime,
- };
- ctx.cache.set(cacheKey, JSON.stringify(article));
- return article;
- }
- })
- );
-
- ctx.state.data = {
- title: '美团开放平台-公告',
- link: 'https://developer.meituan.com/isv/announcement/list',
- item: articleList.map((item) => ({
- title: item.title,
- description: item.description,
- pubDate: item.modifyTime,
- link: item.link,
- })),
- };
-};
diff --git a/lib/routes-deprecated/melon/chart.js b/lib/routes-deprecated/melon/chart.js
deleted file mode 100644
index e7388c8fc39d..000000000000
--- a/lib/routes-deprecated/melon/chart.js
+++ /dev/null
@@ -1,41 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const category = ctx.params.category;
-
- const rootUrl = 'https://www.melon.com';
- const currentUrl = `${rootUrl}/chart/${category ? category + '/' : ''}index.htm`;
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
-
- const $ = cheerio.load(response.data);
-
- const items = $('tr[data-song-no]')
- .map((_, item) => {
- item = $(item);
-
- const image = item
- .find('.image_typeAll img')
- .attr('src')
- .split(/\/melon\//)[0];
- const title = item.find('.rank01').text();
- const name = item.find('.rank02').text();
- const album = item.find('.rank03').text();
-
- return {
- link: currentUrl,
- title: item.find('.rank01').text(),
- description: `
`;
- }
-
- return {
- title,
- description,
- link: item.link,
- author: 'MONSTER HUNTER WORLD: ICEBORNE',
- };
- })
- )
- );
-
- ctx.state.data = {
- title: '怪物猎人世界最新消息',
- link: url,
- item: result,
- };
-};
diff --git a/lib/routes-deprecated/mhw/update.js b/lib/routes-deprecated/mhw/update.js
deleted file mode 100644
index a8090fa90392..000000000000
--- a/lib/routes-deprecated/mhw/update.js
+++ /dev/null
@@ -1,65 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const url1 = 'http://game.capcom.com/world/cn/infomation.html';
- const response1 = await got({
- method: 'get',
- url: url1,
- });
- let $ = cheerio.load(response1.data);
- const result1 = $('.version')
- .map((index, item) => {
- item = $(item);
- return {
- title: item.find('h3').text(),
- description: item.children('div').html(),
- link: url1,
- author: 'MONSTER HUNTER: WORLD',
- };
- })
- .get();
-
- const url2 = 'https://www.monsterhunter.com/update/mhw/cn/';
- const response2 = await got({
- method: 'get',
- url: url2,
- });
-
- $ = cheerio.load(response2.data);
- let result2 = $('.panel-list a')
- .map((index, item) => {
- item = $(item);
- return {
- title: item.find('h3').text().trim(),
- link: url2 + item.attr('href'),
- };
- })
- .get();
-
- result2 = await Promise.all(
- result2.map(
- async (item) =>
- await ctx.cache.tryGet(item.link, async () => {
- const response = await got.get(item.link);
- const $ = cheerio.load(response.data);
- const title = $('.page-ttl').text().trim();
- $('.page-ttl').remove();
-
- return {
- title: title || item.title,
- description: $('.conts').html(),
- link: item.link,
- pubDate: item.pubDate,
- author: 'MONSTER HUNTER WORLD: ICEBORNE',
- };
- })
- )
- );
-
- ctx.state.data = {
- title: '怪物猎人世界更新情报',
- link: url2,
- item: [...result2, ...result1],
- };
-};
diff --git a/lib/routes-deprecated/micmicidol/article.js b/lib/routes-deprecated/micmicidol/article.js
deleted file mode 100644
index 49bb20717635..000000000000
--- a/lib/routes-deprecated/micmicidol/article.js
+++ /dev/null
@@ -1,28 +0,0 @@
-const Cheerio = require('cheerio');
-const got = require('@/utils/got');
-const { parseDate } = require('@/utils/parse-date');
-const regStripAnchor = /(?:
*)?<\/a>(?: *
)?/i;
-
-async function loadArticle(link) {
- const resp = await got(link);
- const $ = Cheerio.load(resp.body);
- const matchResult = $('#post-header-top > script')
- .html()
- .match(/var timestamp="\w+,(.+)";/i)[1]
- .trim();
- // Ex. "August 20, 2021"
- const pubDate = parseDate(matchResult + '+0000', 'MMMM D, YYYYZ');
-
- const labels = $('.post-labels a')
- .text()
- .split('\n')
- .filter((item) => item !== '');
- return {
- title: $('.entry-title').text().trim(),
- description: $('.post-body.entry-content').html().replace(regStripAnchor, ''),
- category: labels,
- pubDate,
- link,
- };
-}
-module.exports = loadArticle;
diff --git a/lib/routes-deprecated/micmicidol/latest.js b/lib/routes-deprecated/micmicidol/latest.js
deleted file mode 100644
index 28d60e0dbffc..000000000000
--- a/lib/routes-deprecated/micmicidol/latest.js
+++ /dev/null
@@ -1,3 +0,0 @@
-const parse = require('./parse');
-
-module.exports = (ctx) => parse(ctx, '', 'Latest');
diff --git a/lib/routes-deprecated/micmicidol/parse.js b/lib/routes-deprecated/micmicidol/parse.js
deleted file mode 100644
index 95063775f9f0..000000000000
--- a/lib/routes-deprecated/micmicidol/parse.js
+++ /dev/null
@@ -1,22 +0,0 @@
-const got = require('@/utils/got');
-const Cheerio = require('cheerio');
-const loadArticle = require('./article');
-
-module.exports = async (ctx, urlParam, title) => {
- const link = new URL(urlParam, 'https://www.micmicidol.com/').toString();
- const response = await got(link);
- ctx.state.data = {
- title: `micmicidol-${title}`,
- link,
- item:
- response.body &&
- (await Promise.all(
- Cheerio.load(response.body)('.post.hentry')
- .map((_, entry) => {
- const { href } = Cheerio.load(entry)('.post-title.entry-title a')[0].attribs;
- return ctx.cache.tryGet(href, () => loadArticle(href));
- })
- .toArray()
- )),
- };
-};
diff --git a/lib/routes-deprecated/micmicidol/search.js b/lib/routes-deprecated/micmicidol/search.js
deleted file mode 100644
index f39fc6a5385d..000000000000
--- a/lib/routes-deprecated/micmicidol/search.js
+++ /dev/null
@@ -1,7 +0,0 @@
-const parse = require('./parse');
-
-module.exports = (ctx) => {
- const max = ctx.query.limit || 50;
- const { label } = ctx.params;
- return parse(ctx, `search/label/${label}?max-results=${max}`, label);
-};
diff --git a/lib/routes-deprecated/microsoft-store/updates.js b/lib/routes-deprecated/microsoft-store/updates.js
deleted file mode 100644
index a3a0f41c13a0..000000000000
--- a/lib/routes-deprecated/microsoft-store/updates.js
+++ /dev/null
@@ -1,30 +0,0 @@
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- const { market = 'CN', productid } = ctx.params;
-
- const { data } = await got({
- method: 'get',
- url: `https://displaycatalog.mp.microsoft.com/v7.0/products/${productid}/?fieldsTemplate=&market=${market}&languages=en`,
- headers: {
- 'Content-Type': 'application/json',
- 'MS-CV': `${Array(16)
- .join(',')
- .split(',')
- .map(() => 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'.charAt(Math.floor(Math.random() * 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'.length)))
- .join('')}.1`,
- },
- });
-
- ctx.state.data = {
- title: `${data.Product.LocalizedProperties[0].ProductTitle} - Microsoft Store Updates`,
- link: `https://www.microsoft.com/store/productId/${productid}`,
- item: [
- {
- title: data.Product.DisplaySkuAvailabilities[0].Sku.Properties.Packages[0].PackageFullName,
- pubDate: new Date(data.Product.DisplaySkuAvailabilities[0].Sku.LastModifiedDate),
- link: `https://www.microsoft.com/store/productId/${productid}`,
- },
- ],
- };
-};
diff --git a/lib/routes-deprecated/mihoyo/bh2.js b/lib/routes-deprecated/mihoyo/bh2.js
deleted file mode 100644
index db4d367934aa..000000000000
--- a/lib/routes-deprecated/mihoyo/bh2.js
+++ /dev/null
@@ -1,43 +0,0 @@
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- const url = 'https://www.mihoyo.com/news/getNotice';
- let type = ctx.params.type;
-
- const typeArr = ['new', 'version', 'gach', 'event'];
-
- if (!typeArr.includes(type)) {
- type = typeArr[0];
- }
-
- const index = typeArr.indexOf(type) + 1 || 1;
-
- const response = await got({
- method: 'post',
- url,
- headers: {
- Referer: url,
- 'x-requested-with': 'XMLHttpRequest',
- },
- });
-
- const data = response.data.data[type] || [];
-
- const title = `崩坏2-${type}`;
-
- ctx.state.data = {
- title,
- link: 'http://www.mihoyo.com/news',
- description: title,
- item: data.map((item) => {
- const pubDate = new Date(item.time);
- pubDate.setTime(pubDate.getTime() + 8 * 60 * 60 * 1000);
- return {
- title: item.title,
- description: item.title,
- pubDate: pubDate.toUTCString(),
- link: `http://www.mihoyo.com/news?para=${index}_${item.id}`,
- };
- }),
- };
-};
diff --git a/lib/routes-deprecated/mihoyo/bh3.js b/lib/routes-deprecated/mihoyo/bh3.js
deleted file mode 100644
index dd3ec61af9ac..000000000000
--- a/lib/routes-deprecated/mihoyo/bh3.js
+++ /dev/null
@@ -1,60 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-const rootUrl = 'https://www.bh3.com/content/bh3Cn/getContentList?pageSize=10&pageNum=1&channelId=';
-
-const config = {
- latest: {
- id: '171',
- title: '最新',
- },
- news: {
- id: '172',
- title: '动态',
- },
- notice: {
- id: '173',
- title: '公告',
- },
- activity: {
- id: '174',
- title: '活动',
- },
- strategy: {
- id: '175',
- title: '补给',
- },
-};
-
-module.exports = async (ctx) => {
- const cfg = config[ctx.params.type];
- if (!cfg) {
- throw new Error(`Bad type: ${ctx.params.type}. See docs`);
- }
-
- const response = await got({
- method: 'get',
- url: rootUrl + cfg.id,
- });
-
- const list = response.data.data.list.map((item) => ({
- title: item.title,
- link: `https://www.bh3.com/news/${item.contentId}`,
- pubDate: new Date(item.start_time).toUTCString(),
- }));
-
- ctx.state.data = {
- title: `崩坏3作战资讯 - ${cfg.title}`,
- link: `https://www.bh3.com/news/cate/${cfg.id}`,
- item: await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const contentResponse = await got({ method: 'get', url: item.link });
- const content = cheerio.load(contentResponse.data);
- item.description = content('div.article__bd').html();
- return item;
- })
- )
- ),
- };
-};
diff --git a/lib/routes-deprecated/missevan/drama.js b/lib/routes-deprecated/missevan/drama.js
deleted file mode 100644
index 5e3048559a82..000000000000
--- a/lib/routes-deprecated/missevan/drama.js
+++ /dev/null
@@ -1,40 +0,0 @@
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- const id = ctx.params.id;
- const host = 'www.missevan.com';
- const dramaUrl = `https://${host}/dramaapi/getdrama?drama_id=${id}`;
- const dramaResp = await got(dramaUrl);
-
- const items = await Promise.all(
- dramaResp.data.info.episodes.episode.map((item) =>
- ctx.cache.tryGet(`https://www.missevan.com/sound/getsound?soundid=${item.sound_id}`, async () => {
- const soundResponse = await got({
- method: 'get',
- url: `https://www.missevan.com/sound/getsound?soundid=${item.sound_id}`,
- });
- const soundData = soundResponse.data.info.sound;
- return {
- title: item.name,
- enclosure_url: soundData.soundurl,
- itunes_duration: Math.trunc(soundData.duration / 1000),
- enclosure_type: 'audio/mpeg',
- image: dramaResp.data.info.drama.cover,
- itunes_author: soundData.username,
- itunes_category: '',
- link: `https://www.missevan.com/sound/player?id=${item.sound_id}`,
- description: `
${soundData.intro}`,
- pubDate: new Date(soundData.last_update_time * 1000).toUTCString(),
- };
- })
- )
- );
-
- ctx.state.data = {
- title: dramaResp.data.info.drama.name,
- link: `https://${host}/mdrama/drama/${id}`,
- image: dramaResp.data.info.drama.cover,
- description: dramaResp.data.info.drama.abstract,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/missevan/latest.js b/lib/routes-deprecated/missevan/latest.js
deleted file mode 100644
index 7a707fa32452..000000000000
--- a/lib/routes-deprecated/missevan/latest.js
+++ /dev/null
@@ -1,47 +0,0 @@
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- const link = `https://www.missevan.com/dramaapi/filter?filters=0_0_0_0_0&page=1&order=1&page_size=20`;
- const response = await got({
- method: 'get',
- url: link,
- });
-
- const items = await Promise.all(
- response.data.info.Datas.map(async (item) => {
- const dramaUrl = `https://www.missevan.com/dramaapi/getdrama?drama_id=${item.id}`;
- const dramaResponse = await got({
- method: 'get',
- url: dramaUrl,
- });
- try {
- const soundUrl = `https://www.missevan.com/sound/getsound?soundid=${dramaResponse.data.info.episodes.episode[0].sound_id}`;
- const soundResponse = await got({
- method: 'get',
- url: soundUrl,
- });
- const soundData = soundResponse.data.info.sound;
- return {
- title: item.name + (item.integrity === 3 ? '(已完结)' : '(更新至 ' + item.newest + ')'),
- enclosure_url: soundData.soundurl,
- itunes_duration: Math.trunc(soundData.duration / 1000),
- enclosure_type: 'audio/mpeg',
- image: item.cover,
- itunes_author: soundData.username,
- itunes_category: '',
- link: `https://www.missevan.com/sound/player?id=${dramaResponse.data.info.episodes.episode[0].sound_id}`,
- description: `
${soundData.intro}`,
- pubDate: new Date(soundData.last_update_time * 1000).toUTCString(),
- };
- } catch {
- return '';
- }
- })
- );
-
- ctx.state.data = {
- title: `猫耳FM - 最新广播剧`,
- link: `https://www.missevan.com/mdrama`,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/mofish/index.js b/lib/routes-deprecated/mofish/index.js
deleted file mode 100644
index f8cff5dfb08f..000000000000
--- a/lib/routes-deprecated/mofish/index.js
+++ /dev/null
@@ -1,50 +0,0 @@
-const got = require('@/utils/got');
-const { parseDate } = require('@/utils/parse-date');
-const { renderToString } = require('hono/jsx/dom/server');
-const { jsx } = require('hono/jsx');
-
-const renderImageDescription = (imageUrl) =>
- renderToString(
- jsx(
- 'p',
- null,
- jsx('img', {
- src: imageUrl,
- referrerpolicy: 'no-referrer',
- }),
- jsx('br', null)
- )
- );
-
-module.exports = async (ctx) => {
- const id = ctx.params.id;
- const page = ctx.query.page || 0;
-
- const url = `https://api.tophub.fun/v2/GetAllInfoGzip?id=${id}&page=${page}`;
-
- const response = await got({
- method: 'get',
- url,
- });
-
- const data = response.data.Data.data;
-
- const title = '鱼塘热榜';
-
- ctx.state.data = {
- title,
- link: 'https://mo.fish/',
- item: data.map((item) => {
- const isImage = Number(id) === 136 && item.Url.endsWith('.gif');
- const description = isImage ? renderImageDescription(item.Url) : title;
-
- return {
- title: item.Title,
- description,
- pubDate: parseDate(item.CreateTime * 1000),
- link: item.Url,
- guid: item.id,
- };
- }),
- };
-};
diff --git a/lib/routes-deprecated/monotype/article.js b/lib/routes-deprecated/monotype/article.js
deleted file mode 100644
index 6ebe38deb8f7..000000000000
--- a/lib/routes-deprecated/monotype/article.js
+++ /dev/null
@@ -1,38 +0,0 @@
-const url = require('url');
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const rootUrl = 'https://www.monotype.com/resources';
-
- const response = await got({
- method: 'get',
- url: rootUrl,
- });
- const $ = cheerio.load(response.data);
- const list = $('h3.component-title')
- .map((_, item) => {
- item = $(item);
- return {
- title: item.find('a').text(),
- link: url.resolve(rootUrl, item.find('a').attr('href')),
- };
- })
- .get();
-
- ctx.state.data = {
- title: 'Monotype - Feature Articles',
- link: rootUrl,
- item: await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const res = await got({ method: 'get', url: item.link });
- const content = cheerio.load(res.data);
- item.pubDate = new Date(content('meta[itemprop="acquia_lift:published_date"]').attr('content') * 1000).toUTCString();
- item.description = content('div.left-region').html();
- return item;
- })
- )
- ),
- };
-};
diff --git a/lib/routes-deprecated/moxingfans/index.js b/lib/routes-deprecated/moxingfans/index.js
deleted file mode 100644
index dade25c60926..000000000000
--- a/lib/routes-deprecated/moxingfans/index.js
+++ /dev/null
@@ -1,50 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const baseUrl = 'http://www.moxingfans.com/';
- const response = await got({
- method: 'get',
- url: baseUrl + 'new',
- });
- const $ = cheerio.load(response.data);
- const list = $('article').get();
-
- const ProcessFeed = (data) => {
- const $ = cheerio.load(data);
- return {
- desc: $('article.article-content').html(),
- publish_time: $('time').text(),
- };
- };
-
- const out = await Promise.all(
- list.map(async (item) => {
- const $ = cheerio.load(item);
- const $a = $('header > h2 > a');
- const link = baseUrl + $a.attr('href');
- const cache = await ctx.cache.get(link);
- if (cache) {
- return JSON.parse(cache);
- }
-
- const response = await got({
- method: 'get',
- url: link,
- });
- const feed = ProcessFeed(response.data);
- const description = feed.desc;
- const pubDate = feed.publish_time;
-
- const single = {
- title: $a.text(),
- description,
- link,
- pubDate,
- };
- ctx.cache.set(link, JSON.stringify(single));
- return single;
- })
- );
- ctx.state.data = { title: '静态模型爱好者', link: baseUrl, item: out };
-};
diff --git a/lib/routes-deprecated/mubu/explore.js b/lib/routes-deprecated/mubu/explore.js
deleted file mode 100644
index fe5ea6bc1544..000000000000
--- a/lib/routes-deprecated/mubu/explore.js
+++ /dev/null
@@ -1,78 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const title = ctx.params.title || '';
- const category = ctx.params.category || '0';
-
- const rootUrl = 'https://mubu.com';
- const apiUrl = 'https://api2.mubu.com';
- const exploreUrl = `${apiUrl}/v3/api/explore/get_explore_doc_list`;
- const documentUrl = `${apiUrl}/v3/api/explore/get`;
-
- const response = await got({
- method: 'post',
- url: exploreUrl,
- json: {
- categoryId: '3',
- pageSize: '20',
- start: '',
- type: category === '0' ? 0 : 1,
- },
- });
-
- const h = (nodes) => {
- const list = nodes
- .map((node) => {
- let ele = '';
- if (Array.isArray(node.children)) {
- ele = h(node.children);
- }
- if (Array.isArray(node.images)) {
- ele += node.images
- .map((pic) => `${apiUrl}/v3/${pic.url}`)
- .map((url) => `${list}
`;
- };
-
- const items = await Promise.all(
- response.data.data.rows.slice(0, 20).map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'post',
- url: documentUrl,
- json: {
- exploreDocId: item.exploreDocId,
- },
- });
- const content = JSON.parse(detailResponse.data.data.definition);
- const description = h(content.nodes);
-
- const $ = cheerio.load(description);
- $('.bold').css('font-weight', 'bold');
- $('.text-color-red').css('color', '#dc2d1e');
-
- return {
- title: item.title,
- author: item.userName,
- pubDate: new Date(item.submitTime),
- link: `${rootUrl}/explore/${item.exploreDocId}`,
- description: `${item.title}
` + $('*').html(),
- };
- })
- )
- );
-
- ctx.state.data = {
- title: `${title ? `${title} - ` : ''}幕布精选社区`,
- link: `${rootUrl}/explore?categoryId=${category}`,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/muchong/index.js b/lib/routes-deprecated/muchong/index.js
deleted file mode 100644
index 08a1f319dcd9..000000000000
--- a/lib/routes-deprecated/muchong/index.js
+++ /dev/null
@@ -1,55 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const iconv = require('iconv-lite');
-
-module.exports = async (ctx) => {
- const id = ctx.params.id || '';
- const sort = ctx.params.sort || '';
- const type = ctx.params.type || 'all';
-
- const rootUrl = 'http://muchong.com';
- const currentUrl = `${rootUrl}/f-${id}-1${sort === '' ? '' : '-' + sort}${type === 'all' ? '' : '-typeid-' + type}`;
- const response = await got({
- method: 'get',
- url: currentUrl,
- responseType: 'buffer',
- });
-
- const $ = cheerio.load(iconv.decode(response.data, 'gbk'));
-
- const list = $('.xmc_bpt tbody .forum_list')
- .slice(1, 10)
- .map((_, item) => {
- item = $(item);
- return {
- author: item.find('.by cite a').text(),
- link: `${rootUrl}${item.find('.a_subject').attr('href')}`,
- title: item.find('.thread-name span').eq(0).text() + item.find('.a_subject').text(),
- pubDate: new Date(sort === '' ? item.find('.by cite nobr').text() : item.find('.by .xmc_b9').eq(0).text()).toUTCString(),
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: item.link,
- responseType: 'buffer',
- });
- const content = cheerio.load(iconv.decode(detailResponse.data, 'gbk'));
-
- item.description = content('#pid1').find('.t_fsz').html();
-
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: $('title').text().replace('-学术科研互动平台', ''),
- link: currentUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/muchong/journal.js b/lib/routes-deprecated/muchong/journal.js
deleted file mode 100644
index 613cdc0a449d..000000000000
--- a/lib/routes-deprecated/muchong/journal.js
+++ /dev/null
@@ -1,52 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const iconv = require('iconv-lite');
-
-module.exports = async (ctx) => {
- const type = ctx.params.type || '';
-
- const rootUrl = 'http://muchong.com';
- const currentUrl = `${rootUrl}/${type === '' ? 'bbs/journal' : 'journal_cn'}.php`;
-
- const response = await got({
- method: 'get',
- url: currentUrl,
- responseType: 'buffer',
- });
- const $ = cheerio.load(iconv.decode(response.data, 'gbk'));
-
- const list = $('.jname a, .journal_list a')
- .slice(0, 15)
- .map((_, item) => {
- item = $(item);
- const link = item.attr('href');
- return {
- title: item.text(),
- link: link.includes('http') ? link : `${rootUrl}/bbs/${item.attr('href')}`,
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: item.link,
- responseType: 'buffer',
- });
- const content = cheerio.load(iconv.decode(detailResponse.data, 'gbk'));
-
- item.description = content('.forum_explan dl table').eq(1).html();
-
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: $('title').text(),
- link: currentUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/nace/blog.js b/lib/routes-deprecated/nace/blog.js
deleted file mode 100644
index 4725ec6b35aa..000000000000
--- a/lib/routes-deprecated/nace/blog.js
+++ /dev/null
@@ -1,52 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const sort = ctx.params.sort || '';
-
- const rootUrl = 'https://community.naceweb.org';
- const currentUrl = `${rootUrl}/browse/blogs/${sort}`;
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
-
- const $ = cheerio.load(response.data);
-
- const list = $('.BlogTitle')
- .slice(0, 10)
- .map((_, item) => {
- item = $(item);
- const link = item.attr('href');
- const split = link.split('/');
-
- return {
- link,
- title: item.text(),
- pubDate: new Date(`${split[5]}-${split[6]}-${split[7]}`).toUTCString(),
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: item.link,
- });
- const content = cheerio.load(detailResponse.data);
-
- item.description = content('.blogs-block .col-md-12').html();
-
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: $('title').text(),
- link: currentUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/navisec/index.js b/lib/routes-deprecated/navisec/index.js
deleted file mode 100644
index 3bd0c3ede25b..000000000000
--- a/lib/routes-deprecated/navisec/index.js
+++ /dev/null
@@ -1,29 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const baseUrl = 'https://bowen.navisec.it/';
- const response = await got({
- method: 'get',
- url: baseUrl,
- });
- const $ = cheerio.load(response.data); // 使用 cheerio 加载返回的 HTML
- const list = $('tbody tr');
- ctx.state.data = {
- title: `纳威安全导航 ~ 资讯`,
- link: `https://bowen.navisec.it/`,
- description: '纳威安全导航 ~ 资讯',
- item:
- list &&
- list
- .map((index, item) => {
- item = $(item);
- return {
- title: $('a', item).text(),
- link: $('a', item).attr('href'),
- pubDate: new Date($('td', item).last().text()).toUTCString(),
- };
- })
- .get(),
- };
-};
diff --git a/lib/routes-deprecated/nobelprize/index.js b/lib/routes-deprecated/nobelprize/index.js
deleted file mode 100644
index 7270bda7d6e0..000000000000
--- a/lib/routes-deprecated/nobelprize/index.js
+++ /dev/null
@@ -1,79 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-const config = {
- physics: {
- link: 'all-nobel-prizes-in-physics',
- title: 'Physics',
- },
- chemistry: {
- link: 'all-nobel-prizes-in-chemistry',
- title: 'Chemistry',
- },
- 'physiology-or-medicine': {
- link: 'all-nobel-laureates-in-physiology-or-medicine',
- title: 'Physiology or Medicine',
- },
- literature: {
- link: 'all-nobel-prizes-in-literature',
- title: 'Literature',
- },
- peace: {
- link: 'all-nobel-peace-prizes',
- title: 'Peace',
- },
- 'economic-sciences': {
- link: 'all-prizes-in-economic-sciences',
- title: 'Economic Science',
- },
-};
-
-module.exports = async (ctx) => {
- let rootUrl = 'https://www.nobelprize.org/prizes/lists/all-nobel-prizes/';
-
- const cfg = config[ctx.params.caty];
- if (cfg) {
- rootUrl = `https://www.nobelprize.org/prizes/lists/${cfg.link}/`;
- }
-
- const response = await got({
- method: 'get',
- url: rootUrl,
- });
-
- const $ = cheerio.load(response.data);
-
- const items = $('div.by_year h3')
- .map((_, item) => {
- item = $(item);
- if (item.text().length === 4) {
- return Promise.resolve('');
- }
-
- const a = item.find('a');
-
- let description = '';
-
- item.nextAll().each(function () {
- if ($(this).get(0).tagName === 'p') {
- description += `${item.summary || ''}`,
- link: `${rootUrl(item.newsSource.replace('now', ''))}${sources[item.newsSource]}${item.newsId}`,
- }));
-
- ctx.state.data = {
- title: '熱門 | Now 新聞',
- link: rootUrl('news'),
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/nvidia/webdriverupdate.js b/lib/routes-deprecated/nvidia/webdriverupdate.js
deleted file mode 100644
index 67ae4eaf8df6..000000000000
--- a/lib/routes-deprecated/nvidia/webdriverupdate.js
+++ /dev/null
@@ -1,29 +0,0 @@
-const got = require('@/utils/got');
-const plist = require('plist');
-
-module.exports = async (ctx) => {
- const url = 'https://gfe.nvidia.com/mac-update';
-
- const res = await got({
- method: 'get',
- url,
- });
-
- const list = plist.parse(res.data).updates;
-
- const resultItem = list.map((i) => {
- const item = {};
- item.title = i.version;
-
- item.description = i.version;
- item.guid = i.checksum;
- item.link = i.downloadURL;
- return item;
- });
-
- ctx.state.data = {
- title: 'Nvidia WebDriver Update',
- link: url,
- item: resultItem,
- };
-};
diff --git a/lib/routes-deprecated/nwpu/index.js b/lib/routes-deprecated/nwpu/index.js
deleted file mode 100644
index 4fca846b601c..000000000000
--- a/lib/routes-deprecated/nwpu/index.js
+++ /dev/null
@@ -1,26 +0,0 @@
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- const column = ctx.params.column;
-
- const response = await got({
- method: 'get',
- url: `https://service-ajsh9ixx-1304010583.bj.apigw.tencentcs.com/release/nwpu-ecampus-news?column=${column}`,
- });
- const data = response.data.body.data.data.data;
- const name = data.extras.channel.name;
-
- ctx.state.data = {
- title: `西北工业大学 - ${name}`,
- link: 'https://ecampus.nwpu.edu.cn/portal-web',
- description: `西北工业大学翱翔门户 - ${name}`,
- item: data.aaData.map((item) => ({
- title: item.title,
- description: item.contentDetail.body,
- pubDate: new Date(item.releaseDate),
- link: `https://ecampus.nwpu.edu.cn/portal-web/html/index.html?id=${item.id}#/news-detail`,
- category: item.releaseOrgName,
- author: item.contentDetail.textUser,
- })),
- };
-};
diff --git a/lib/routes-deprecated/ofweek/news.js b/lib/routes-deprecated/ofweek/news.js
deleted file mode 100644
index 6f57e468acb8..000000000000
--- a/lib/routes-deprecated/ofweek/news.js
+++ /dev/null
@@ -1,44 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const iconv = require('iconv-lite');
-
-module.exports = async (ctx) => {
- const response = await got({
- method: 'get',
- url: 'https://www.ofweek.com/CATList-8100-CHANGYIEXINWE.html',
- responseType: 'buffer',
- });
-
- const $ = cheerio.load(iconv.decode(response.data, 'gbk'));
- const list = $('div.list-left div.con-details h3 > a')
- .slice(0, 20)
- .map((_, item) => {
- item = $(item);
- return {
- title: item.text(),
- link: item.attr('href'),
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const res = await got({ method: 'get', url: item.link, responseType: 'buffer' });
- const content = cheerio.load(iconv.decode(res.data, 'gbk'));
- const artical = content('div.artical');
- item.description = artical.find('#articleC').html();
- item.author = artical.find('div.source-name').text();
- item.pubDate = artical.find('div.time.fl').text();
- item.pubDate = new Date(item.pubDate + ' GMT+8').toUTCString();
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: '高科技行业门户',
- link: 'https://www.ofweek.com/CATList-8100-CHANGYIEXINWE.html',
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/one/index.js b/lib/routes-deprecated/one/index.js
deleted file mode 100644
index 483fa0caea18..000000000000
--- a/lib/routes-deprecated/one/index.js
+++ /dev/null
@@ -1,48 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const response = await got({
- method: 'get',
- url: 'http://wufazhuce.com/',
- headers: {
- Referer: 'http://wufazhuce.com/',
- },
- });
-
- const data = response.data;
- const $ = cheerio.load(data);
-
- const list = [$('.item.active'), $('.corriente')[0], $('.corriente')[1]];
- const itemMap = ['「图片」', '「文字」', '「问答」'];
-
- const out = await Promise.all(
- list.map(async (item, i) => {
- const url = $(item).find('a').attr('href');
- const single = {
- title: itemMap[i] + $(item).find('a').text().replaceAll(/\s+/g, ' ').trim(),
- link: url,
- description: '',
- };
- const detail = await got({
- method: 'get',
- url,
- headers: {
- Referer: 'http://wufazhuce.com/',
- },
- });
- {
- const data = detail.data;
- const $ = cheerio.load(data);
- single.description = $('.tab-content').html();
- }
- return single;
- })
- );
- ctx.state.data = {
- title: $('title').text(),
- link: 'http://wufazhuce.com/',
- item: out,
- description: '复杂世界里, 一个就够了. One is all.',
- };
-};
diff --git a/lib/routes-deprecated/onejav/one.js b/lib/routes-deprecated/onejav/one.js
deleted file mode 100644
index 77aa5cb3000c..000000000000
--- a/lib/routes-deprecated/onejav/one.js
+++ /dev/null
@@ -1,37 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const type = ctx.params.type || 'new';
- const key = type === 'day' ? ctx.params.key.slice(0, 4) + '/' + ctx.params.key.slice(4, 6) + '/' + ctx.params.key.slice(6, 8) : ctx.params.key || '';
- const link = 'https://onejav.com' + `/${type === 'day' ? '' : type}${type === 'new' ? '' : '/' + key}`.replace('//', '/');
- const response = await got({
- method: 'get',
- url: link,
- });
-
- const $ = cheerio.load(response.data);
- const list = $('div.columns');
-
- let itemPicUrl;
-
- ctx.state.data = {
- title: `OneJAV - ${type} ${key}`,
- link,
- item:
- list &&
- list
- .map((index, item) => {
- item = $(item);
- itemPicUrl = item.find('img').attr('src');
- return {
- title: '【' + item.find('div.card-content.is-flex > h5 > a').text() + '】' + item.find('div.card-content.is-flex > h5 > span').text(),
- description: `
Time: ${item.find('p.subtitle.is-6 > a').text()}
Desc: ${item.find('p.level.has-text-grey-dark').text()}`,
- link: item.find('div.card-content.is-flex > h5 > a').attr('href'),
- enclosure_url: 'https://onejav.com' + item.find('p.control.is-expanded > a').attr('href'),
- enclosure_type: 'application/x-bittorrent',
- };
- })
- .get(),
- };
-};
diff --git a/lib/routes-deprecated/onenotegem/release.js b/lib/routes-deprecated/onenotegem/release.js
deleted file mode 100644
index eb22892f4ad1..000000000000
--- a/lib/routes-deprecated/onenotegem/release.js
+++ /dev/null
@@ -1,49 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const rootUrl = 'http://www.onenotegem.com';
- const currentUrl = `${rootUrl}/a/release`;
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
-
- const $ = cheerio.load(response.data);
-
- const list = $('.paragraph ul li a')
- .slice(0, 10)
- .map((_, item) => {
- item = $(item);
- return {
- title: item.text(),
- link: `${rootUrl}${item.attr('href')}`,
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: item.link,
- });
- const content = cheerio.load(detailResponse.data);
-
- const title = content('h1.wsite-content-title');
-
- item.description = title.next().next().next().html();
- item.pubDate = new Date(title.next().text()).toUTCString();
-
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: 'OneNote Gem Addins Release History',
- link: currentUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/ornl/news.js b/lib/routes-deprecated/ornl/news.js
deleted file mode 100644
index 2fa0d8b7e053..000000000000
--- a/lib/routes-deprecated/ornl/news.js
+++ /dev/null
@@ -1,47 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const rootUrl = 'https://www.ornl.gov';
- const currentUrl = `${rootUrl}/news`;
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
-
- const $ = cheerio.load(response.data);
-
- const list = $('.list-item-title h2 a')
- .slice(0, 15)
- .map((_, item) => {
- item = $(item);
- return {
- title: item.text(),
- link: `${rootUrl}${item.attr('href')}`,
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: item.link,
- });
- const content = cheerio.load(detailResponse.data);
-
- item.description = content('article').html();
- item.pubDate = new Date(content('time').attr('datetime')).toUTCString();
-
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: $('title').text(),
- link: currentUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/owspace/read.js b/lib/routes-deprecated/owspace/read.js
deleted file mode 100644
index 67703ffa8373..000000000000
--- a/lib/routes-deprecated/owspace/read.js
+++ /dev/null
@@ -1,141 +0,0 @@
-const got = require('@/utils/got');
-const md5 = require('@/utils/md5');
-const qs = require('querystring');
-const cheerio = require('cheerio');
-
-const secret = 'fk4iy@98(*Y98fh-^o)re+wg=';
-
-const typeMap = {
- 1: '文字',
- 2: '影像',
- 3: '声音',
- 4: '单向历',
- 6: '谈论',
-};
-
-const signQuery = (query) => {
- query.sign = md5(['apiname=', query.a, 'device_id=', query.device_id, 'time=', query.time, secret].join(''));
-};
-
-const generateFullText = async (item) => {
- const model = Number.parseInt(item.model);
- const fullTextResponse = await got.get(item.html5);
- const $ = cheerio.load(fullTextResponse.data);
-
- const content = $('#singleArticle');
- const describe = $('.articleTit>.describe');
-
- let intro = '';
-
- if (item.excerpt) {
- intro += '' + describe.html() + '
';
- }
-
- if (intro) {
- intro += '
';
- }
-
- // hide redundant meta
- content.find('.articleTit').remove();
-
- if (model === 2) {
- // make video visible
- content.find('.vBox').removeAttr('style');
-
- content.find('.vBox video').attr('preload', 'metadata');
- }
-
- if (model === 3) {
- // make audio visible
- const audioContainer = content.find('.fmCon').removeAttr('style');
-
- // generate audio player
- $('').attr('src', item.fm).attr('preload', 'metadata').prependTo(audioContainer);
-
- content.find('.fmCon>.graphic').remove();
- content.find('.fmCon>.fmDetail').remove();
- }
-
- return intro + content.html();
-};
-
-const handleItem = (ctx) => async (item) => {
- if (Number.parseInt(item.model) === 4) {
- const result = {
- title: item.title.substring(0, 4) + '年' + Number.parseInt(item.title.substring(4, 6)) + '月' + Number.parseInt(item.title.substring(6, 8)) + '日',
- link: item.html5,
- description: ``,
- pubDate: new Date(Number(item.create_time) * 1000).toUTCString(),
- author: item.author,
- };
-
- return result;
- } else {
- const url = item.html5;
- const cache = await ctx.cache.get(url);
- if (cache) {
- return JSON.parse(cache);
- }
-
- const result = {
- title: item.title.replace('\r\n', ''),
- link: item.html5,
- description: await generateFullText(item),
- pubDate: new Date(Number(item.create_time) * 1000).toUTCString(),
- author: item.author,
- };
-
- ctx.cache.set(url, JSON.stringify(result));
- return result;
- }
-};
-
-module.exports = async (ctx) => {
- const selectedType = ctx.params.type === undefined ? 0 : Number.parseInt(ctx.params.type);
-
- const queryData = {
- c: 'api2',
- a: 'getList',
- p: '1',
- model: selectedType,
- client: 'android',
- version: '1.6.3',
- time: Math.round(Date.now() / 1000),
- device_id: 'null',
- show_sdv: '0',
- };
-
- signQuery(queryData);
- const response = await got({
- method: 'get',
- url: 'http://static.owspace.com/',
- searchParams: qs.stringify(queryData),
- headers: {
- 'User-Agent': 'com.onewaystreet.weread/14',
- },
- });
-
- if (!response.data.status || response.data.status !== 'ok') {
- throw response.data.msg ? 'api error: ' + response.data.msg : 'api error';
- }
-
- const responseItemArray = response.data.datas.filter((item) => Number.parseInt(item.model) !== 5);
-
- const feedItemArray = await Promise.all(responseItemArray.map(handleItem(ctx)));
-
- const selectedTypeName = typeMap[selectedType];
-
- ctx.state.data = {
- title: selectedTypeName ? `${selectedTypeName} - 单读` : '单读',
- link: 'http://www.owspace.com/read.html',
- item: feedItemArray,
- };
-};
diff --git a/lib/routes-deprecated/paidai/bbs.js b/lib/routes-deprecated/paidai/bbs.js
deleted file mode 100644
index 6300218cac74..000000000000
--- a/lib/routes-deprecated/paidai/bbs.js
+++ /dev/null
@@ -1,41 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const utils = require('./utils');
-
-const host = 'http://bbs.paidai.com/hot';
-
-module.exports = async (ctx) => {
- const link = host;
- const response = await got({
- method: 'get',
- url: link,
- 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:62.0) Gecko/20100101 Firefox/62.0',
- });
-
- const $ = cheerio.load(response.data);
-
- const list = $('#index_topic_list ul li')
- .slice(0, 11)
- .map(function () {
- const info = {
- title: $(this).find('span.m2-li-r-1 a').attr('title'),
- link: $(this).find('span.m2-li-r-1 a').attr('href'),
- date: $(this).find('span.m2-li-r-2').text(),
- };
- return info;
- })
- .get();
-
- const out = await Promise.all(
- list.map((info) => {
- const link = info.link;
- return ctx.cache.tryGet(link, () => utils.ProcessFeed(info));
- })
- );
-
- ctx.state.data = {
- title: `论坛-派代`,
- link,
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/paidai/index.js b/lib/routes-deprecated/paidai/index.js
deleted file mode 100644
index c3fbda2698b5..000000000000
--- a/lib/routes-deprecated/paidai/index.js
+++ /dev/null
@@ -1,41 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const utils = require('./utils');
-
-const host = 'http://www.paidai.com/';
-
-module.exports = async (ctx) => {
- const link = host;
- const response = await got({
- method: 'get',
- url: link,
- 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:62.0) Gecko/20100101 Firefox/62.0',
- });
-
- const $ = cheerio.load(response.data);
-
- const list = $('#topic_list ul li')
- .slice(0, 11)
- .map(function () {
- const info = {
- title: $(this).find('a.i_title').attr('title'),
- link: $(this).find('div.li_1').find('a.i_title').attr('href'),
- date: $(this).find('em.li_s').text(),
- };
- return info;
- })
- .get();
-
- const out = await Promise.all(
- list.map((info) => {
- const link = info.link;
- return ctx.cache.tryGet(link, () => utils.ProcessFeed(info));
- })
- );
-
- ctx.state.data = {
- title: `首页-派代`,
- link,
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/paidai/news.js b/lib/routes-deprecated/paidai/news.js
deleted file mode 100644
index 5a930b8ea29b..000000000000
--- a/lib/routes-deprecated/paidai/news.js
+++ /dev/null
@@ -1,41 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const utils = require('./utils');
-
-const host = 'http://www.paidai.com/';
-
-module.exports = async (ctx) => {
- const link = host;
- const response = await got({
- method: 'get',
- url: link,
- 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:62.0) Gecko/20100101 Firefox/62.0',
- });
-
- const $ = cheerio.load(response.data);
-
- const list = $('#topic_list ul li.topic')
- .slice(0, 11)
- .map(function () {
- const info = {
- title: $('.li_1 a.i_title', this).attr('title'),
- link: $('.li_1 a.i_title', this).attr('href'),
- date: $('.li_2 .li_s', this).text(),
- };
- return info;
- })
- .get();
-
- const out = await Promise.all(
- list.map((info) => {
- const link = info.link;
- return ctx.cache.tryGet(link, () => utils.ProcessFeed(info));
- })
- );
-
- ctx.state.data = {
- title: `商道-派代`,
- link,
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/paidai/utils.js b/lib/routes-deprecated/paidai/utils.js
deleted file mode 100644
index 6ea640523f3a..000000000000
--- a/lib/routes-deprecated/paidai/utils.js
+++ /dev/null
@@ -1,26 +0,0 @@
-const cheerio = require('cheerio');
-const got = require('@/utils/got');
-const { parseRelativeDate } = require('@/utils/parse-date');
-
-const ProcessFeed = async (info) => {
- const title = info.title;
- const itemUrl = info.link;
- const itemDate = info.date;
-
- const response = await got.get(itemUrl);
-
- const $ = cheerio.load(response.data);
- const description = $('#topic_content').html().trim();
-
- const single = {
- title,
- link: itemUrl,
- description,
- pubDate: parseRelativeDate(itemDate),
- };
- return single;
-};
-
-module.exports = {
- ProcessFeed,
-};
diff --git a/lib/routes-deprecated/parcel/hermesuk.js b/lib/routes-deprecated/parcel/hermesuk.js
deleted file mode 100644
index 454694c8bf13..000000000000
--- a/lib/routes-deprecated/parcel/hermesuk.js
+++ /dev/null
@@ -1,50 +0,0 @@
-const got = require('@/utils/got');
-const dayjs = require('dayjs');
-
-module.exports = async (ctx) => {
- const tracking = ctx.params.tracking;
-
- let single;
-
- const cache = await ctx.cache.get(tracking);
- if (cache) {
- single = JSON.parse(cache);
- } else {
- const response = await got({
- method: 'get',
- url: `https://www.myhermes.co.uk/ajax/ref/trackParcelByBarcode?barcode=${tracking}`,
- });
-
- let parcel = response.data;
- let message = '';
-
- if (parcel.length > 0) {
- parcel = parcel[0];
-
- if (parcel.point) {
- message += parcel.point.description;
- }
-
- if (parcel.location) {
- message += ` at ${parcel.location.description}`;
- }
-
- if (parcel.estimatedDeliveryDate) {
- message += ` ETA: ${dayjs(parcel.estimatedDeliveryDate).format('MMM DD')}`;
- }
-
- single = {
- pubDate: new Date(parcel.dateTime).toISOString(),
- title: message,
- };
- }
-
- ctx.cache.set(tracking, JSON.stringify(single));
- }
-
- ctx.state.data = {
- title: `Hermes Tracking ${tracking}`,
- link: `https://www.myhermes.co.uk/tracking-results.html?trackingNumber=${tracking}`,
- item: [single],
- };
-};
diff --git a/lib/routes-deprecated/patchwork.kernel.org/cache.js b/lib/routes-deprecated/patchwork.kernel.org/cache.js
deleted file mode 100644
index b7001f1a4806..000000000000
--- a/lib/routes-deprecated/patchwork.kernel.org/cache.js
+++ /dev/null
@@ -1,17 +0,0 @@
-const got = require('@/utils/got');
-
-module.exports = {
- getPatchnameFromID: async (ctx, id) => {
- const key = 'patchwork-kernel-org-patchname-from-id-' + id;
- let name = await ctx.cache.get(key);
- if (!name) {
- const patchDetail = await got({
- method: 'get',
- url: `https://patchwork.kernel.org/api/patches/${id}/`,
- });
- name = patchDetail.data.name;
- ctx.cache.set(key, name);
- }
- return name;
- },
-};
diff --git a/lib/routes-deprecated/patchwork.kernel.org/comments.js b/lib/routes-deprecated/patchwork.kernel.org/comments.js
deleted file mode 100644
index aefdb22cd452..000000000000
--- a/lib/routes-deprecated/patchwork.kernel.org/comments.js
+++ /dev/null
@@ -1,33 +0,0 @@
-const got = require('@/utils/got');
-const cache = require('./cache');
-const entities = require('entities');
-const queryString = require('query-string');
-
-module.exports = async (ctx) => {
- const id = ctx.params.id;
-
- const name = await cache.getPatchnameFromID(ctx, id);
-
- const host = `https://patchwork.kernel.org/patch/${id}/`;
- const url = `https://patchwork.kernel.org/api/patches/${id}/comments/`;
-
- const response = await got({
- method: 'get',
- url,
- searchParams: queryString.stringify({
- order: '-date',
- }),
- });
- const data = response.data;
-
- ctx.state.data = {
- title: `${name} - Comments`,
- link: host,
- item: data.map((item) => ({
- title: item.subject,
- description: entities.escape(entities.escape(item.content)).replaceAll('\n', '
'),
- pubDate: new Date(item.date).toUTCString(),
- link: item.web_url,
- })),
- };
-};
diff --git a/lib/routes-deprecated/phrack/index.js b/lib/routes-deprecated/phrack/index.js
deleted file mode 100644
index 2310a3050c29..000000000000
--- a/lib/routes-deprecated/phrack/index.js
+++ /dev/null
@@ -1,39 +0,0 @@
-const cheerio = require('cheerio');
-const got = require('@/utils/got');
-module.exports = async (ctx) => {
- const response = await got({
- method: 'get',
- url: 'http://www.phrack.org/',
- });
-
- const data = response.data;
- let $ = cheerio.load(data);
- const a = $('a[title="Paper Feed"]');
- const url = 'http://www.phrack.org/' + a.attr('href');
- const feed_data = await ctx.cache.tryGet(url, async () => {
- const result = await got.get(url);
-
- return result.data;
- });
-
- $ = cheerio.load(feed_data); // 使用 cheerio 加载返回的 HTML
-
- ctx.state.data = {
- title: 'phrack', // 项目的标题
- link: 'http://www.phrack.org/', // 指向项目的链接
- description: 'phrack magazine', // 描述项目
- allowEmpty: false, // 默认 false,设为 true 可以允许 item 为空
- item: [
- // 其中一篇文章或一项内容
- {
- title: $('div[id="article"]').text(), // 文章标题
- author: '', // 文章作者
- category: '', // 文章分类
- // category: [''], // 多个分类
- description: $('div[class="around"]').children().first().next().children('pre').text(), // 文章摘要或全文
- pubDate: '', // 文章发布时间
- link: url, // 指向文章的链接
- },
- ],
- };
-};
diff --git a/lib/routes-deprecated/piapro/public.js b/lib/routes-deprecated/piapro/public.js
deleted file mode 100644
index aecf88692547..000000000000
--- a/lib/routes-deprecated/piapro/public.js
+++ /dev/null
@@ -1,54 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const utils = require('./utils');
-
-const base = 'https://piapro.jp';
-
-const selectors = {
- music: '.snd_list li .title',
- illust: '#itemcont .i_main',
- text: '.txt_list li .title',
-};
-
-module.exports = async (ctx) => {
- const type = selectors[ctx.params.type] ? ctx.params.type : 'music';
- const tag = ctx.params.tag ?? '';
- const category = ctx.params.category ?? '';
-
- const url = `${base}/${type}/?tag=${encodeURIComponent(tag)}&categoryId=${category}`;
-
- const list_response = await got.get(url);
- const $ = cheerio.load(list_response.data);
-
- const type_name = $('#top_titlebox img').first().attr('alt');
- const category_name = $('#_filterbox_category .name').text();
- const tag_name = $('#_filterbox_character .name').text();
-
- const list = $(selectors[type])
- .map(function () {
- return base + $(this).find('a').first().attr('href');
- })
- .toArray();
-
- const out = await Promise.all(
- list.slice(0, 10).map(async (url) => {
- const cache = await ctx.cache.get(url);
- if (cache) {
- return JSON.parse(cache);
- }
-
- const response = await got.get(url);
- const item = utils.parseContent(response.data);
- item.link = url;
-
- ctx.cache.set(url, JSON.stringify(item));
- return item;
- })
- );
-
- ctx.state.data = {
- title: `piapro - ${type_name}${tag ? ' - ' + tag_name : ''}${category ? ' - ' + category_name : ''}`,
- link: url,
- item: out.filter((item) => item !== ''),
- };
-};
diff --git a/lib/routes-deprecated/piapro/user.js b/lib/routes-deprecated/piapro/user.js
deleted file mode 100644
index 25c397e86ec5..000000000000
--- a/lib/routes-deprecated/piapro/user.js
+++ /dev/null
@@ -1,47 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const utils = require('./utils');
-
-const base = 'https://piapro.jp';
-
-module.exports = async (ctx) => {
- const pid = ctx.params.pid;
-
- const url = `${base}/my_page/?view=content&pid=${pid}`;
-
- const list_response = await got.get(url);
-
- const $ = cheerio.load(list_response.data);
-
- const user_name = $('#main_name h2').text();
- const user_description = $('#main_name p').text();
-
- const list = $('#itemcont .i_main')
- .map(function () {
- return base + $(this).find('a').last().attr('href');
- })
- .toArray();
-
- const out = await Promise.all(
- list.slice(0, 10).map(async (url) => {
- const cache = await ctx.cache.get(url);
- if (cache) {
- return JSON.parse(cache);
- }
-
- const response = await got.get(url);
- const item = utils.parseContent(response.data);
- item.link = url;
-
- ctx.cache.set(url, JSON.stringify(item));
- return item;
- })
- );
-
- ctx.state.data = {
- title: `piapro - ${user_name}の投稿作品`,
- description: user_description,
- link: url,
- item: out.filter((item) => item !== ''),
- };
-};
diff --git a/lib/routes-deprecated/piapro/utils.js b/lib/routes-deprecated/piapro/utils.js
deleted file mode 100644
index 9b8143860bc3..000000000000
--- a/lib/routes-deprecated/piapro/utils.js
+++ /dev/null
@@ -1,45 +0,0 @@
-const cheerio = require('cheerio');
-
-const parseContent = (htmlString) => {
- const $ = cheerio.load(htmlString);
-
- const title = $('h1.cd_works-title');
- const author = $('.cd_user-box-main a.cd_user-name');
- const time = $('.cd_dtl_data')
- .text()
- .match(/\d+\/\d+\/\d+ \d+:\d+:\d+/)[0];
-
- const blank = cheerio.load('');
- const content = blank('div');
-
- // description
- $('p.cd_dtl_cap').appendTo(content);
-
- // image
- $('.illust-whole').appendTo(content);
-
- // audio
- const testAudio = htmlString.match(/initNotLoginAudioFunc\(([\S\s]*?)\);/m);
- if (testAudio) {
- const audioInfo = testAudio[1];
- const contentId = audioInfo.match(/contentId:\s*'(.*?)',/)[1];
- const createDate = audioInfo.match(/createDate:\s*'(.*?)',/)[1];
- const audio_url = `https://cdn.piapro.jp/mp3_a/${contentId.substring(0, 2)}/${contentId}_${createDate}_audition.mp3`;
- $(``).appendTo(content);
- $('img#bigJacket_1').appendTo(content);
- }
-
- // text
- $('.main_txt').appendTo(content);
-
- return {
- title: title.text().trim(),
- author: author.text().trim(),
- description: content.html(),
- pubDate: new Date(time),
- };
-};
-
-module.exports = {
- parseContent,
-};
diff --git a/lib/routes-deprecated/pmcaff/feed.js b/lib/routes-deprecated/pmcaff/feed.js
deleted file mode 100644
index cce234b7806b..000000000000
--- a/lib/routes-deprecated/pmcaff/feed.js
+++ /dev/null
@@ -1,51 +0,0 @@
-const got = require('@/utils/got');
-const map = new Map([
- ['1', { code: '%E5%8F%91%E7%8E%B0', name: '发现' }],
- ['2', { code: '%E5%BE%85%E5%9B%9E%E7%AD%94', name: '待回答' }],
- ['3', { code: '%E6%9C%80%E7%83%AD', name: '最热' }],
- ['4', { code: '%E9%97%AE%E7%AD%94%E4%B8%93%E5%9C%BA', name: '问答专场' }],
- ['5', { code: '%E6%8A%95%E7%A8%BF', name: '投稿' }],
- ['6', { code: '%E6%B7%B1%E5%BA%A6', name: '深度' }],
- ['7', { code: '%E4%B8%93%E6%A0%8F', name: '专栏' }],
-]);
-
-module.exports = async (ctx) => {
- const typeid = ctx.params.typeid || '1';
- const type_code = map.get(typeid).code;
- const type_name = map.get(typeid).name;
- const response = await got({
- method: 'get',
- url: `https://api.pmcaff.com/api/v0/communities/feed?page=1&column=${type_code}`,
- });
-
- const result = [];
- for (const item of response.data.data) {
- const title = item.title;
- const guid = item.id;
- const pubDate = new Date(item.ctime).toUTCString();
-
- let link = '';
- let description = '';
- if (item.entity_type === 'question') {
- link = `https://www.pmcaff.com/discuss/index/${guid}/?newwindow=1`;
- description = item.content;
- } else if (item.entity_type === 'article') {
- link = `https://www.pmcaff.com/article/index/${guid}/?newwindow=1`;
- description = item.content;
- } else {
- link = 'https://www.pmcaff.com/feed/';
- description = '不支持的类型';
- }
-
- const single = {
- title,
- link,
- guid,
- pubDate,
- description,
- };
-
- result.push(single);
- }
- ctx.state.data = { title: `${type_name} - PMCAFF互联网产品社区`, link: 'https://www.pmcaff.com/feed/', description: `PMCAFF互联网产品社区 - 产品经理人气组织::专注于互联网产品研究`, item: result };
-};
diff --git a/lib/routes-deprecated/pmcaff/list.js b/lib/routes-deprecated/pmcaff/list.js
deleted file mode 100644
index a1037d6773e2..000000000000
--- a/lib/routes-deprecated/pmcaff/list.js
+++ /dev/null
@@ -1,67 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const map = new Map([
- ['1', { name: '今日推荐' }],
- ['2', { name: '精选' }],
-]);
-module.exports = async (ctx) => {
- const typeid = ctx.params.typeid || '2';
- const OutName = map.get(typeid).name;
- const url = `https://coffee.pmcaff.com/list?type=${typeid}`;
- const response = await got({
- method: 'post',
- url: `https://coffee.pmcaff.com/list`,
- headers: {
- Referer: url,
- },
- json: {
- page: 1,
- feed_sum: 15,
- type: typeid,
- times: 0,
- user_id: 0,
- },
- });
- const list = response.data.data;
- // console.log(list.length);
- const out = await Promise.all(
- list.map(async (info) => {
- const title = info.title;
- const date = info.created_at;
- const id = info.id;
- const author = info.author;
- const itemUrl = `https://coffee.pmcaff.com/article/${id}`;
- const cache = await ctx.cache.get(itemUrl);
- if (cache) {
- return JSON.parse(cache);
- }
- const response = await got({
- method: 'get',
- url: itemUrl,
- headers: {
- Referer: url,
- },
- });
- const data = response.data;
- const $ = cheerio.load(data);
- $('#articleCont img').attr('referrerpolicy', 'no-referrer');
- const description = $('#articleCont').html();
-
- const single = {
- title,
- author,
- link: itemUrl,
- description,
- pubDate: new Date(date + ' GMT').toUTCString(),
- };
- ctx.cache.set(itemUrl, JSON.stringify(single));
- return single;
- })
- );
- ctx.state.data = {
- title: `${OutName}-PMCAFF互联网产品社区`,
- description: `PMCAFF互联网产品社区 - 产品经理人气组织::专注于互联网产品研究`,
- link: url,
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/polimi/news.js b/lib/routes-deprecated/polimi/news.js
deleted file mode 100644
index 84717343e007..000000000000
--- a/lib/routes-deprecated/polimi/news.js
+++ /dev/null
@@ -1,22 +0,0 @@
-const buildData = require('@/utils/common-config');
-
-module.exports = async (ctx) => {
- let link = `https://www.polimi.it/tutte-le-news/`;
- if (ctx.params.language === 'en') {
- link = `https://www.polimi.it/en/all-news/`;
- }
- ctx.state.data = await buildData({
- link,
- url: link,
- title: `Polimi News`,
- params: {
- homeLink: 'https://www.polimi.it',
- },
- item: {
- item: '.container .no',
- title: `$('h3').text()`,
- link: `'%homeLink%' + $('p span a').attr('href')`,
- description: `$('p').text() + '' + 'Full Article {
- const language = ctx.params.language || 'en';
- const bar = '-'.repeat(language.length > 2 ? 74 : 58);
-
- const rootUrl = 'https://potplayer.daum.net';
- const currentUrl = `${rootUrl}/?lang=${language}`;
-
- const link = await ctx.cache.tryGet(currentUrl, async () => {
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
- return response.data.match(//)[1];
- });
-
- const response = await got({
- method: 'get',
- url: link,
- });
-
- const list = response.data.split(`\r\n\r\n${bar}\r\n`);
-
- const items = list.slice(1, 10).map((item) => {
- const pubDate = parseDate(item.slice(1, 7), 'YYMMDD');
-
- return {
- pubDate,
- link: currentUrl,
- title: item.slice(1, 7),
- description: ``,
- pubDate: new Date(item.stockInDate.replace(/(\d{4})(\d{2})(\d{2})/, '$1-$2-$3')),
- link: `https://www.ptpress.com.cn/shopping/buy?bookId=${item.bookId}`,
- })),
- };
-};
diff --git a/lib/routes-deprecated/qnap/release-notes.js b/lib/routes-deprecated/qnap/release-notes.js
deleted file mode 100644
index a7b74e8e77db..000000000000
--- a/lib/routes-deprecated/qnap/release-notes.js
+++ /dev/null
@@ -1,50 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const rootUrl = 'https://www.qnap.com';
- const currentUrl = `${rootUrl}/en/release-notes/${ctx.params.id}`;
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
-
- const $ = cheerio.load(response.data);
- const list = $('.tier1-menu li.active .tier2-menu li .tier3-menu li a')
- .slice(0, 20)
- .map((_, item) => {
- item = $(item);
- return {
- title: item.text().trim(),
- link: `${rootUrl}/en/release-notes/${item.attr('data-os')}/${item.attr('data-version')}/${item.attr('data-build-number')}`,
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const links = item.link.split('/');
- const apiUrl = `${rootUrl}/api/v1/release-notes/${links[4]}?locale=en&version=${links[5]}&build_number=${links[6]}`;
-
- const detailResponse = await got({
- method: 'get',
- url: apiUrl,
- });
-
- const content = cheerio.load(detailResponse.data.result);
-
- item.description = content('.content').html();
- item.pubDate = new Date(content('.title-container p').text()).toUTCString();
-
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: `${$('.tier1-menu li.active span').eq(0).text()} - QNAP`,
- link: currentUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/qttabbar/change-log.js b/lib/routes-deprecated/qttabbar/change-log.js
deleted file mode 100644
index f562580980b3..000000000000
--- a/lib/routes-deprecated/qttabbar/change-log.js
+++ /dev/null
@@ -1,33 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const rootUrl = 'http://qttabbar.wikidot.com/change-log';
- const response = await got({
- method: 'get',
- url: rootUrl,
- });
-
- const $ = cheerio.load(response.data);
-
- $('p strong a').parent().parent().remove();
-
- const items = $('#page-content')
- .children('p')
- .map((_, item) => {
- item = $(item);
- return {
- link: rootUrl,
- title: item.text(),
- description: item.next().html(),
- pubDate: new Date(item.text().match(/\((.*)\)/)).toUTCString(),
- };
- })
- .get();
-
- ctx.state.data = {
- title: 'Change Log - QTTabBar',
- link: rootUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/queshu/book.js b/lib/routes-deprecated/queshu/book.js
deleted file mode 100644
index c016eac813b9..000000000000
--- a/lib/routes-deprecated/queshu/book.js
+++ /dev/null
@@ -1,22 +0,0 @@
-const buildData = require('@/utils/common-config');
-
-module.exports = async (ctx) => {
- const bookid = ctx.params.bookid;
- const link = `http://www.queshu.com/book/${bookid}`;
- const host = `http://www.queshu.com`;
- ctx.state.data = await buildData({
- link,
- url: link,
- title: `%title%`,
- allowEmpty: true,
- params: {
- title: `$('#book_left > #h1').text().trim() + ' - 单品活动信息 - 缺书网'`,
- host,
- },
- item: {
- item: '.stacked.right_state > a',
- title: `$('.right_item .bodycol_258').text()`,
- link: `'%host%' + $('.right_item').parent().attr('href')`,
- },
- });
-};
diff --git a/lib/routes-deprecated/queshu/sale.js b/lib/routes-deprecated/queshu/sale.js
deleted file mode 100644
index 1a2a0ea58521..000000000000
--- a/lib/routes-deprecated/queshu/sale.js
+++ /dev/null
@@ -1,28 +0,0 @@
-const buildData = require('@/utils/common-config');
-
-module.exports = async (ctx) => {
- const link = `http://www.queshu.com/sale/`;
- const host = `http://www.queshu.com`;
- ctx.state.data = await buildData({
- link,
- url: link,
- title: `%title%`,
- params: {
- title: '图书促销 - 缺书网',
- host,
- },
- item: {
- item: '#tb_sale tr',
- title: `$('.news_sale_detail .sale_btn').text() + ':' + $('.news_sale_title a').text()`,
- link: `'%host%' + $('.news_sale_title a').attr('href')`,
- description: `$('.news_sale_detail .sale_btn').text() + ':' + $('.news_sale_title a').text()
- + '
'
- + $('.news_sale_detail .sale_time_end').first().text()
- + '
'
- + '发布时间:' + $('.news_sale_detail .sale_time_end.inline_right').text()
-
- `,
- pubDate: `date($('.news_sale_detail .sale_time_end.inline_right').text())`,
- },
- });
-};
diff --git a/lib/routes-deprecated/qutoutiao/category.js b/lib/routes-deprecated/qutoutiao/category.js
deleted file mode 100644
index f759863367c3..000000000000
--- a/lib/routes-deprecated/qutoutiao/category.js
+++ /dev/null
@@ -1,42 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const cid = ctx.params.cid;
- const url = `http://api.1sapp.com/content/outList?cid=${cid}&tn=1&page=1&limit=10`;
- const response = await got.get(url);
- const result = response.data.data.data;
-
- const out = await Promise.all(
- result.map(async (item) => {
- const title = item.title;
- const date = item.show_time;
- const itemUrl = item.url;
-
- const cache = await ctx.cache.get(itemUrl);
- if (cache) {
- return JSON.parse(cache);
- }
-
- const response = await got.get(itemUrl);
- const $ = cheerio.load(response.data);
- const description = $('.content').html().replaceAll('data-src', `src`);
-
- const single = {
- title,
- link: itemUrl,
- description,
- pubDate: new Date(date * 1000).toUTCString(),
- };
- ctx.cache.set(itemUrl, JSON.stringify(single));
- return single;
- })
- );
-
- ctx.state.data = {
- title: '趣头条',
- link: 'http://home.qutoutiao.net',
- description: '趣头条',
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/qzcea/index.js b/lib/routes-deprecated/qzcea/index.js
deleted file mode 100644
index b0090f6ead63..000000000000
--- a/lib/routes-deprecated/qzcea/index.js
+++ /dev/null
@@ -1,51 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- ctx.params.caty = ctx.params.caty || '1';
-
- const rootUrl = 'http://www.qzcea.org';
- const currentUrl = `${rootUrl}/usernewscatname_nc${ctx.params.caty}`;
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
-
- const $ = cheerio.load(response.data);
-
- $('a.news-more').remove();
-
- const list = $('li.clearfix div.news-right a')
- .slice(0, 10)
- .map((_, item) => {
- item = $(item);
- return {
- title: item.text(),
- link: `${rootUrl}${item.attr('href')}`,
- pubDate: new Date(item.next().text().replace('时间 :', '') + ' GMT+8').toUTCString(),
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: item.link,
- });
- const content = cheerio.load(detailResponse.data);
-
- item.description = content('div.newm').html();
-
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: `${$('title').text()} - 泉州市跨境电子商务协会`,
- link: currentUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/react/react-native-weekly.js b/lib/routes-deprecated/react/react-native-weekly.js
deleted file mode 100644
index 9a470e5529b2..000000000000
--- a/lib/routes-deprecated/react/react-native-weekly.js
+++ /dev/null
@@ -1,35 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const host = 'https://reactnative.cc';
- const response = await got({
- method: 'get',
- url: `${host}/issues.html`,
- });
- const data = response.data;
- const $ = cheerio.load(data);
- const newestHref = $('.past-issues-header>ul').first().find('li a').attr('href');
- const detailResponse = await got({
- method: 'get',
- url: `${host}${newestHref}`,
- });
- const $2 = cheerio.load(detailResponse.data);
- const list = $2('.mcnCaptionBottomContent .mcnTextContent a', 'body');
-
- ctx.state.data = {
- title: 'react-native-weekly',
- link: 'https://reactnative.cc',
- item:
- list &&
- list
- .map((index, item) => {
- item = $(item);
- return {
- title: item.text().replaceAll(/\s{2}/g, ''),
- link: item.attr('href'),
- };
- })
- .get(),
- };
-};
diff --git a/lib/routes-deprecated/remote-work/index.js b/lib/routes-deprecated/remote-work/index.js
deleted file mode 100644
index f0abe05aec90..000000000000
--- a/lib/routes-deprecated/remote-work/index.js
+++ /dev/null
@@ -1,88 +0,0 @@
-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 new 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,
- 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((item) =>
- 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,
- };
-};
diff --git a/lib/routes-deprecated/rescuetime/release-notes.js b/lib/routes-deprecated/rescuetime/release-notes.js
deleted file mode 100644
index a1b65e18b338..000000000000
--- a/lib/routes-deprecated/rescuetime/release-notes.js
+++ /dev/null
@@ -1,37 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const os = ctx.params.os || 'mac';
-
- const rootUrl = 'https://www.rescuetime.com/release-notes';
- const currentUrl = `${rootUrl}/${os}`;
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
-
- const $ = cheerio.load(response.data.replaceAll('', '
'));
-
- const items = $('.release')
- .map((_, item) => {
- item = $(item);
-
- const title = item.find('h2').text();
- item.find('h2').remove();
-
- return {
- title,
- link: currentUrl,
- description: item.html(),
- pubDate: new Date(title.match(/(\d{4}(?:\/\d{2}){2})/)[1]),
- };
- })
- .get();
-
- ctx.state.data = {
- title: $('h1').text(),
- link: currentUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/rf/article.js b/lib/routes-deprecated/rf/article.js
deleted file mode 100644
index 582d0302ba9a..000000000000
--- a/lib/routes-deprecated/rf/article.js
+++ /dev/null
@@ -1,39 +0,0 @@
-const url = require('url');
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const rootUrl = 'https://rf.eefocus.com/article/list-all';
- const response = await got({
- method: 'get',
- url: rootUrl,
- });
- const $ = cheerio.load(response.data);
- const list = $('h3.media-heading')
- .slice(0, 10)
- .map((_, item) => {
- item = $(item);
- const a = item.find('a');
- return {
- title: a.text(),
- link: url.resolve('https://rf.eefocus.com/', a.attr('href')),
- };
- })
- .get();
-
- ctx.state.data = {
- title: 'RF技术社区 - 文章',
- link: rootUrl,
- item: await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const res = await got({ method: 'get', url: item.link });
- const content = cheerio.load(res.data);
- item.pubDate = new Date(content('div.article-subline-desc').eq(0).text().replace('发布时间:', '')).toUTCString();
- item.description = content('div.clearfix.article-content').html();
- return item;
- })
- )
- ),
- };
-};
diff --git a/lib/routes-deprecated/rmlt/idea.js b/lib/routes-deprecated/rmlt/idea.js
deleted file mode 100644
index 892a4a6cf612..000000000000
--- a/lib/routes-deprecated/rmlt/idea.js
+++ /dev/null
@@ -1,54 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const timezone = require('@/utils/timezone');
-const { parseDate } = require('@/utils/parse-date');
-
-module.exports = async (ctx) => {
- const category = ctx.params.category || '';
-
- const rootUrl = 'http://www.rmlt.com.cn';
- const currentUrl = `${rootUrl}/idea/${category}`;
-
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
-
- const $ = cheerio.load(response.data);
-
- const list = $(category ? '.txt-list' : '.hot-news')
- .find('a')
- .slice(0, 15)
- .map((_, item) => {
- item = $(item);
-
- return {
- link: item.attr('href'),
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: item.link,
- });
- const content = cheerio.load(detailResponse.data);
-
- item.title = content('.article-title').text();
- item.description = content('.article-content').html();
- item.pubDate = timezone(parseDate(content('.date').text(), 'YYYY-MM-DD HH:ss'), +8);
-
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: $('title').text(),
- link: currentUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/rthk-news/index.js b/lib/routes-deprecated/rthk-news/index.js
deleted file mode 100644
index 729a6b7d6889..000000000000
--- a/lib/routes-deprecated/rthk-news/index.js
+++ /dev/null
@@ -1,60 +0,0 @@
-const got = require('@/utils/got');
-const parser = require('@/utils/rss-parser');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- let category = ctx.params.category.toLowerCase();
- const language = ctx.params.lang.toLowerCase();
- let languageUrlKey;
- switch (language) {
- case 'hk':
- languageUrlKey = 'c';
- break;
- case 'en':
- languageUrlKey = 'e';
- break;
- default:
- languageUrlKey = 'c';
- break;
- }
- if (languageUrlKey !== 'c' || category !== 'greaterchina') {
- category = languageUrlKey + category;
- }
- const rssUrl = `https://rthk.hk/rthk/news/rss/${languageUrlKey}_expressnews_${category}.xml`;
- const feed = await parser.parseURL(rssUrl);
- const title = feed.title;
- const link = feed.link;
- const description = feed.description;
-
- const items = await Promise.all(
- feed.items.map(async (item) => {
- const description = await ctx.cache.tryGet(item.guid, async () => {
- const response = await got({
- method: 'get',
- url: item.guid,
- });
- const $ = cheerio.load(response.data);
-
- const $descriptionRoot = cheerio.load('
'));
-
- return $descriptionRoot.html();
- });
- const single = {
- title: item.title,
- description,
- pubDate: item.pubDate,
- link: item.guid,
- };
- return single;
- })
- );
-
- ctx.state.data = {
- title,
- link,
- description,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/ruby-china/constants.js b/lib/routes-deprecated/ruby-china/constants.js
deleted file mode 100644
index c92771487cd1..000000000000
--- a/lib/routes-deprecated/ruby-china/constants.js
+++ /dev/null
@@ -1,5 +0,0 @@
-const RUBY_CHINA_HOST = 'https://ruby-china.org';
-
-module.exports = {
- RUBY_CHINA_HOST,
-};
diff --git a/lib/routes-deprecated/ruby-china/jobs.js b/lib/routes-deprecated/ruby-china/jobs.js
deleted file mode 100644
index 5cfca5cfd05f..000000000000
--- a/lib/routes-deprecated/ruby-china/jobs.js
+++ /dev/null
@@ -1,23 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-const { RUBY_CHINA_HOST } = require('./constants');
-const utils = require('./utils');
-
-module.exports = async (ctx) => {
- const title = 'Ruby China - 招聘';
- const link = `${RUBY_CHINA_HOST}/jobs`;
-
- const response = await got.get(link);
- const $ = cheerio.load(response.data);
- const list = $('.topics .topic').get();
-
- const result = await utils.processTopics2Feed(list, ctx.cache);
-
- ctx.state.data = {
- title,
- link,
- description: title,
- item: result,
- };
-};
diff --git a/lib/routes-deprecated/ruby-china/topics.js b/lib/routes-deprecated/ruby-china/topics.js
deleted file mode 100644
index 749ce793b3b4..000000000000
--- a/lib/routes-deprecated/ruby-china/topics.js
+++ /dev/null
@@ -1,48 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-const { RUBY_CHINA_HOST } = require('./constants');
-const utils = require('./utils');
-
-module.exports = async (ctx) => {
- const { type } = ctx.params;
-
- let title = 'Ruby China';
- let link = `${RUBY_CHINA_HOST}/topics`;
- switch (type) {
- case 'excellent':
- title += ' - 精华贴';
- link += '/excellent';
- break;
- case 'popular':
- title += ' - 优质帖子';
- link += '/popular';
- break;
- case 'no_reply':
- title += ' - 无人问津';
- link += '/no_reply';
- break;
- case 'last_reply':
- title += ' - 最新回复';
- link += '/last_reply';
- break;
- case 'last':
- title += ' - 最新发布';
- link += '/last';
- break;
- default:
- }
-
- const response = await got.get(link);
- const $ = cheerio.load(response.data);
- const list = $('.topics .topic').get();
-
- const result = await utils.processTopics2Feed(list, ctx.cache);
-
- ctx.state.data = {
- title,
- link,
- description: title,
- item: result,
- };
-};
diff --git a/lib/routes-deprecated/ruby-china/utils.js b/lib/routes-deprecated/ruby-china/utils.js
deleted file mode 100644
index 5cc5a501969e..000000000000
--- a/lib/routes-deprecated/ruby-china/utils.js
+++ /dev/null
@@ -1,42 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const url = require('url');
-
-const { RUBY_CHINA_HOST } = require('./constants');
-
-async function loadAndParseTopic(link) {
- const response = await got.get(link);
- const $ = cheerio.load(response.data);
-
- const title = $('.topic-detail .title').text();
- const author = $('.topic-detail .user-name').text();
- const description = $('.topic-detail .card-body').html();
- const pubDate = new Date();
-
- return {
- title,
- link,
- author,
- guid: link,
- description,
- pubDate,
- };
-}
-
-function processTopics2Feed(list, cache) {
- return Promise.all(
- list.map(async (item) => {
- const $ = cheerio.load(item);
- const $title = $('.title a');
-
- const itemUrl = url.resolve(RUBY_CHINA_HOST, $title.attr('href'));
- const itemFeed = await cache.tryGet(itemUrl, () => loadAndParseTopic(itemUrl));
-
- return itemFeed;
- })
- );
-}
-
-module.exports = {
- processTopics2Feed,
-};
diff --git a/lib/routes-deprecated/samsungmembers/latest.js b/lib/routes-deprecated/samsungmembers/latest.js
deleted file mode 100644
index 83bcddcf1ca6..000000000000
--- a/lib/routes-deprecated/samsungmembers/latest.js
+++ /dev/null
@@ -1,41 +0,0 @@
-const url = require('url');
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const currentUrl = 'http://www.samsungmembers.cn/bbs/';
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
- const $ = cheerio.load(response.data);
- const list = $('div.ImgList dl dt')
- .slice(0, 15)
- .map((_, item) => {
- item = $(item);
- const a = item.find('a');
- return {
- title: a.text(),
- link: url.resolve('http://www.samsungmembers.cn/', a.attr('href')),
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const res = await got({ method: 'get', url: item.link });
- const content = cheerio.load(res.data);
- item.pubDate = new Date(content('p.data').text() + ' GMT+8').toUTCString();
- item.description = content('div.BSHARE_POP').html();
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: '三星盖乐世社区 - 最新帖子',
- link: currentUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/scboy/thread.js b/lib/routes-deprecated/scboy/thread.js
deleted file mode 100644
index 48a80af81eec..000000000000
--- a/lib/routes-deprecated/scboy/thread.js
+++ /dev/null
@@ -1,50 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const { parseRelativeDate } = require('@/utils/parse-date');
-const config = require('@/config').value;
-
-module.exports = async (ctx) => {
- const tid = ctx.params.tid;
- const link = `https://www.scboy.com/?thread-${tid}.htm`;
- let cookieString = 'postlist_orderby=desc';
- if (config.scboy.token) {
- cookieString = `postlist_orderby=desc; bbs_token=${config.scboy.token}`;
- }
-
- const res = await got.get({
- method: 'get',
- url: link,
- responseType: 'buffer',
- headers: {
- Cookie: cookieString,
- },
- });
-
- const $ = cheerio.load(res.data);
- const title = $('h4 > span:nth-of-type(1)').text();
-
- const list = $('li.media.post');
- const count = [];
-
- for (let i = 0; i < Math.min(list.length, 30); i++) {
- count.push(i);
- }
-
- const resultItems = count.map((i) => {
- const each = $(list[i]);
- const floor = each.find('span.floor-parent').text();
- return {
- title: `${title} #${floor ?? ' 热门回复'}`,
- link: `https://www.scboy.com/?thread-${tid}`,
- description: each.find('div.message.mt-1.break-all > div:nth-of-type(1)').html(),
- author: each.find('username').text(),
- pubDate: parseRelativeDate(each.find('.date').text()),
- };
- });
-
- ctx.state.data = {
- title,
- link: `https://www.scboy.com/?thread-${tid}.htm`,
- item: resultItems,
- };
-};
diff --git a/lib/routes-deprecated/secshi/index.js b/lib/routes-deprecated/secshi/index.js
deleted file mode 100644
index c7b21e3620f3..000000000000
--- a/lib/routes-deprecated/secshi/index.js
+++ /dev/null
@@ -1,29 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const baseUrl = 'https://www.secshi.com/';
- const response = await got({
- method: 'get',
- url: baseUrl,
- });
- const $ = cheerio.load(response.data); // 使用 cheerio 加载返回的 HTML
- const list = $('ul[class="b2_gap"] li[class="post-3-li post-list-item"]');
- ctx.state.data = {
- title: `安全师 ~ 资讯`,
- link: `https://www.secshi.com/`,
- description: '安全师 ~ 资讯',
- item:
- list &&
- list
- .map((index, item) => {
- item = $(item);
- return {
- title: $('h2', item).text(),
- link: $('h2 a', item).attr('href'),
- description: $('div[class="post-excerpt"]', item).text(),
- };
- })
- .get(),
- };
-};
diff --git a/lib/routes-deprecated/security/pulses.js b/lib/routes-deprecated/security/pulses.js
deleted file mode 100644
index 8628668de75d..000000000000
--- a/lib/routes-deprecated/security/pulses.js
+++ /dev/null
@@ -1,32 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const url = require('url');
-
-const host = 'https://sec.today';
-
-module.exports = async (ctx) => {
- const link = 'https://sec.today/pulses/';
- const response = await got.get(link);
- const $ = cheerio.load(response.data);
-
- const out = $('div.endless_page_template div.card')
- .slice(0, 10)
- .map(function () {
- const author = $(this).find('div.card-body small.text-muted').text().trim().split('•')[0];
- const itemUrl = $(this).find('h5.card-title > a').attr('href');
- const info = {
- link: url.resolve(host, itemUrl),
- description: $(this).find('p.card-text.my-1').html(),
- title: $(this).find('h5.card-title').text(),
- author,
- };
- return info;
- })
- .get();
-
- ctx.state.data = {
- title: '每日安全推送',
- link,
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/semiconductors/latest-news.js b/lib/routes-deprecated/semiconductors/latest-news.js
deleted file mode 100644
index d5a6d0314cb1..000000000000
--- a/lib/routes-deprecated/semiconductors/latest-news.js
+++ /dev/null
@@ -1,47 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const rootUrl = 'https://www.semiconductors.org';
- const currentUrl = `${rootUrl}/news-events/latest-news`;
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
-
- const $ = cheerio.load(response.data);
-
- const list = $('h3')
- .slice(0, 15)
- .map((_, item) => {
- item = $(item).parent();
- return {
- title: item.text(),
- link: item.attr('href'),
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: item.link,
- });
- const content = cheerio.load(detailResponse.data);
-
- item.description = content('#main').html();
- item.pubDate = new Date(content('meta[property="article:published_time"]').attr('content')).toUTCString();
-
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: $('title').text(),
- link: currentUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/sesame/release-notes.js b/lib/routes-deprecated/sesame/release-notes.js
deleted file mode 100644
index 01fa08b16847..000000000000
--- a/lib/routes-deprecated/sesame/release-notes.js
+++ /dev/null
@@ -1,30 +0,0 @@
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- const rootUrl = 'https://sesame.ninja/release_notes.txt';
- const response = await got({
- method: 'get',
- url: rootUrl,
- });
-
- const items = response.data
- .split('\r\n\r\n')
- .slice(0, 20)
- .map((item) => {
- const splits = item.split('\r\n - ');
- const title = splits.shift().replace(':', '');
-
- return {
- title,
- link: rootUrl,
- pubDate: title.match(/\((.*),/)[1],
- description: `
`,
- };
- });
-
- ctx.state.data = {
- title: 'Sesame Release Notes',
- link: rootUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/sexinsex/index.js b/lib/routes-deprecated/sexinsex/index.js
deleted file mode 100644
index 14b2f419b147..000000000000
--- a/lib/routes-deprecated/sexinsex/index.js
+++ /dev/null
@@ -1,101 +0,0 @@
-const cheerio = require('cheerio');
-const got = require('@/utils/got');
-const iconv = require('iconv-lite');
-const url = require('url');
-
-const base = 'http://sexinsex.net';
-const section = '/bbs/forumdisplay.php?fid=';
-const got_ins = got.extend({
- headers: {
- Referer: base,
- },
- responseType: 'buffer',
-});
-
-const sourceTimezoneOffset = -8;
-module.exports = async (ctx) => {
- const typefilter = ctx.params.type ? `&filter=type&typeid=${ctx.params.type}` : '';
- const location = `${section}${ctx.params.id}${typefilter}`;
- let title = '';
-
- let out = [];
- const parseContent = (htmlString) => {
- htmlString = iconv.decode(htmlString, 'gbk');
- let $ = cheerio.load(htmlString, { decodeEntities: false });
- const author = $('#wrapper > div:nth-child(1) > form > div:nth-child(2) > table > tbody > tr:nth-child(1) > td.postauthor > cite > a').text();
- let time = $('.postinfo').text();
- const regex = /\d{4}(?:-\d{1,2}){2} \d{1,2}:\d{1,2}/;
- const regRes = regex.exec(time);
- time = regRes.length === 0 ? new Date() : new Date(regRes[0]);
- time.setTime(time.getTime() + (sourceTimezoneOffset - time.getTimezoneOffset() / 60) * 60 * 60 * 1000);
-
- const content = $('.postmessage').html();
- $ = cheerio.load(content, { decodeEntities: false });
- $('.postratings').remove();
- $('div.quote').remove();
-
- return {
- author,
- description: $('body').html(),
- pubDate: time.toUTCString(),
- };
- };
- const fetch = async (pageindex) => {
- const pageUrl = url.resolve(base, `${location}&page=${pageindex}`);
- const res = await got_ins.get(pageUrl);
- const data = iconv.decode(res.data, 'gbk');
- const $ = cheerio.load(data);
- title = (ctx.params.type ? `[${$('.threadlist .headactions strong').text()}]` : '') + $('title').text();
- const list = $(`#forum_${ctx.params.id}:last-child tbody tr th`).get();
-
- const result = await Promise.all(
- list.map(async (item) => {
- const $ = cheerio.load(item);
- const guid = $('span').attr('id'); // thread_7836473
- let title = $('span a');
- const catalog = $('em').text(); // http://sexinsex.net/bbs/thread-7988706-1-1.html
- title = title.text();
- const link = url.resolve(base, `/bbs/${guid.replace('_', '-')}-1-1.html`);
-
- // Check cache
- const cache = await ctx.cache.get(link);
- if (cache) {
- return JSON.parse(cache);
- }
-
- const single = {
- title: `${catalog} ${title}`,
- link,
- guid,
- };
-
- try {
- const response = await got_ins.get(link, {
- headers: {
- Referer: pageUrl,
- },
- });
- const result = parseContent(response.data);
-
- single.author = result.author;
- single.description = result.description;
- single.pubDate = result.pubDate;
- } catch {
- return '';
- }
- ctx.cache.set(link, JSON.stringify(single));
- return single;
- })
- );
- out = [...out, ...result];
- };
-
- // 一次读取两页的内容
- await Promise.all([1, 2].map((value) => fetch(value)));
-
- ctx.state.data = {
- title,
- link: url.resolve(base, `${section}${ctx.params.id}${typefilter}`),
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/shanbay/checkin.js b/lib/routes-deprecated/shanbay/checkin.js
deleted file mode 100644
index 2e6a2f8b4793..000000000000
--- a/lib/routes-deprecated/shanbay/checkin.js
+++ /dev/null
@@ -1,48 +0,0 @@
-const got = require('../../utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const id = ctx.params.id;
-
- const username = await ctx.cache.tryGet(`shanbayuser${id}`, async () => {
- const response = await got({
- method: 'get',
- url: `https://web.shanbay.com/web/checkin/achievement?user_id=${id}`,
- });
- const $ = cheerio.load(response.data);
- return $('#user-info-area .name').text();
- });
-
- const response = await got({
- method: 'get',
- url: `https://apiv3.shanbay.com/uc/checkin/logs?page=1&user_id=${id}`,
- headers: {
- Referer: `https://web.shanbay.com/web/wechat/calendar/?user_id=${id}`,
- },
- });
-
- const data = response.data.objects;
-
- ctx.state.data = {
- title: `${username} 的扇贝打卡`,
- link: `https://web.shanbay.com/web/wechat/calendar/?user_id=${id}`,
- item:
- data &&
- data.map((item) => {
- let action = '';
- item.tasks = item.tasks.sort((a, b) => b.used_time - a.used_time);
- for (const [index, task] of item.tasks.entries()) {
- const minute = Math.floor(task.used_time / 60);
- const second = task.used_time - minute * 60;
- action += `${index === 0 ? '' : ';'}${task.operation}了 ${task.num} ${task.unit}${task.name},学习时间 ${minute} 分 ${second} 秒`;
- }
- return {
- title: `${username} 的第 ${item.checkin_days_num} 天扇贝打卡`,
- pubDate: new Date(`${item.date} 00:00:00+08`),
- guid: item.id + (+new Date(`${item.date} 00:00:00+08`) >= 1_596_729_600_000 ? action : ''),
- description: action,
- link: `https://web.shanbay.com/web/wechat/calendar/?user_id=${id}`,
- };
- }),
- };
-};
diff --git a/lib/routes-deprecated/shanbay/footprints.js b/lib/routes-deprecated/shanbay/footprints.js
deleted file mode 100644
index dbbd7b8a18a5..000000000000
--- a/lib/routes-deprecated/shanbay/footprints.js
+++ /dev/null
@@ -1,42 +0,0 @@
-const cheerio = require('cheerio');
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- const cat = ctx.params.category;
- const host = 'https://www.shanbay.com';
- const url = cat ? `${host}/footprints/?category=${cat}` : `${host}/footprints/`;
- const res = await got.get(url);
- const $ = cheerio.load(res.data);
- const list = $('div.articles div.article-item').get();
-
- const out = await Promise.all(
- list.map(async (item) => {
- const $ = cheerio.load(item);
- const time = $('p.article-publish-day').text() + $('span.article-publish-month-year').text();
- const title = $('h3.article-title a').text();
- const itemUrl = host + $('h3.article-title a').attr('href');
- const cache = await ctx.cache.get(itemUrl);
- if (cache) {
- return JSON.parse(cache);
- }
-
- const responses = await got.get(itemUrl);
- const $d = cheerio.load(responses.data);
-
- const single = {
- title,
- pubDate: new Date(time).toUTCString(),
- link: itemUrl,
- guid: itemUrl,
- description: $d('#content .content').html(),
- };
- ctx.cache.set(itemUrl, JSON.stringify(single));
- return single;
- })
- );
- ctx.state.data = {
- title: '扇贝精选文章',
- link: url,
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/simonsfoundation/articles.js b/lib/routes-deprecated/simonsfoundation/articles.js
deleted file mode 100644
index 53831b50f436..000000000000
--- a/lib/routes-deprecated/simonsfoundation/articles.js
+++ /dev/null
@@ -1,48 +0,0 @@
-const cheerio = require('cheerio');
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- const url = `https://www.simonsfoundation.org/news/articles`;
-
- const res = await got.get(url);
- const $ = cheerio.load(res.data);
- const list = $('.news-links-wrapper').get();
-
- const out = await Promise.all(
- list.map(async (item) => {
- const $ = cheerio.load(item);
- const title = $('a.news-title').text();
- const address = $('a.news-title').attr('href');
- const time = $('.news-date').text();
-
- const cache = await ctx.cache.get(address);
- if (cache) {
- return JSON.parse(cache);
- }
-
- const res = await got.get(address);
- const capture = cheerio.load(res.data);
- const banner = capture('div.o-page-header__hero').html();
- const author = capture('.m-meta__inherit').text();
- capture('.m-block-info__animation').remove();
- capture('.o-blocks__left').remove();
- capture('.m-tags').remove();
- const contents = banner === null ? capture('.o-blocks').html() : banner + capture('.o-blocks').html();
- const single = {
- title,
- author,
- description: contents,
- link: address,
- guid: address,
- pubDate: new Date(time).toUTCString(),
- };
- ctx.cache.set(address, JSON.stringify(single));
- return single;
- })
- );
- ctx.state.data = {
- title: 'Simons Foundation | Articles',
- link: url,
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/simonsfoundation/recommend.js b/lib/routes-deprecated/simonsfoundation/recommend.js
deleted file mode 100644
index 19d1792d9f94..000000000000
--- a/lib/routes-deprecated/simonsfoundation/recommend.js
+++ /dev/null
@@ -1,27 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-const baseUrl = 'https://www.simonsfoundation.org/news/what-were-reading';
-
-module.exports = async (ctx) => {
- const response = await got({
- method: 'get',
- url: baseUrl,
- });
-
- const $ = cheerio.load(response.data);
- ctx.state.data = {
- title: `Simons Foundation | What We're Reading`,
- link: baseUrl,
- description: `Simons Foundation - What We're Reading`,
- item: $('.o-dated-list__row')
- .map((index, item) => ({
- title: $(item).find('.m-post__title').text(),
- description: $(item).find('.m-post__aside').html(),
- pubDate: new Date($(item).find('.o-dated-list__day').text() + ' ' + $(item).find('.o-dated-list__month').text() + ' ' + $(item).find('.o-dated-list__year').text()).toUTCString(),
-
- link: $(item).find('.m-post__block-link').attr('href'),
- }))
- .get(),
- };
-};
diff --git a/lib/routes-deprecated/simpread/changelog.js b/lib/routes-deprecated/simpread/changelog.js
deleted file mode 100644
index 3592e05e663d..000000000000
--- a/lib/routes-deprecated/simpread/changelog.js
+++ /dev/null
@@ -1,79 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const url = 'http://ksria.com/simpread/changelog.html';
- const response = await got.get(url);
- const data = response.data;
- const $ = cheerio.load(data);
- ctx.state.data = {
- title: 'SimpRead 更新日志',
- link: 'https://simpread.pro/changelog.html',
- description: $('body > div.container.changelog > div.desc').html(),
- item: $('.version')
- .map((index, item) => {
- const year = $(item).find('.year').html();
- const month_day = $(item).find('.day').html();
- let version = '';
- let detail = '';
- // 版本名称处理
- version = $(item).find('.num > a').clone().children().remove().end().text();
- // detail处理
- detail = $(item).find('.details');
- if (version === '') {
- version = $(item).find('.num').clone().children().remove().end().text();
- }
- let version_type = $(item).find('.num > a > i').attr('class');
- // 部分结构不一致处理
- if (version_type === undefined) {
- version_type = $(item).find('.num > i').attr('class');
- }
- if (version_type.includes('chrome')) {
- version_type = 'Chrome';
- }
- if (version_type.includes('apple')) {
- version_type = 'Safari';
- }
- if (version_type.includes('code')) {
- version_type = 'UserScript';
- }
- if (version_type.includes('firefox')) {
- version_type = 'Firefox';
- }
-
- // detail
- const text_color = {
- important: '#9c27b0',
- add: '#4caf50',
- change: '#ffc107',
- fix: '#f44336',
- complete: '#03a9f4',
- };
- $(detail)
- .find('li')
- .map((index, item) => {
- let span_class = $(item).find('span').attr('class');
- const text = $(item).find('span').html();
- $(item).find('span').remove();
- if (span_class !== undefined) {
- span_class = span_class.split(' ');
- if (span_class[1] === 'empty') {
- $(item).wrap('');
- } else {
- $(item).prepend(`${text}: `);
- }
- }
- return {};
- });
-
- return {
- description: $(detail).html(),
- link: 'https://simpread.pro/changelog.html',
- pubDate: `${year}-${month_day.replace('.', '-')} 00:00:00 GMT`,
- title: `${version_type}${version}`,
- author: 'SimpRead',
- };
- })
- .get(),
- };
-};
diff --git a/lib/routes-deprecated/simpread/notice.js b/lib/routes-deprecated/simpread/notice.js
deleted file mode 100644
index 79dd7950efa9..000000000000
--- a/lib/routes-deprecated/simpread/notice.js
+++ /dev/null
@@ -1,20 +0,0 @@
-const got = require('@/utils/got');
-const md = require('markdown-it')();
-
-module.exports = async (ctx) => {
- const url = 'https://static.simp.red/notice';
- const response = await got.get(url);
- const data = response.data.notice;
- ctx.state.data = {
- title: 'SimpRead 消息通知',
- link: 'https://simpread.pro/changelog.html',
- description: 'SimpRead 消息通知',
- item: data.map((item) => ({
- description: md.render(item.content),
- link: 'https://simpread.pro/changelog.html',
- pubDate: item.date,
- title: `${item.category.name}-${item.title}`,
- author: 'SimpRead',
- })),
- };
-};
diff --git a/lib/routes-deprecated/siren/index.js b/lib/routes-deprecated/siren/index.js
deleted file mode 100644
index c5e24d478493..000000000000
--- a/lib/routes-deprecated/siren/index.js
+++ /dev/null
@@ -1,33 +0,0 @@
-const got = require('@/utils/got');
-const { parseDate } = require('@/utils/parse-date');
-
-module.exports = async (ctx) => {
- const response = await got({
- method: 'get',
- url: `https://monster-siren.hypergryph.com/api/news`,
- headers: {
- Referer: `https://monster-siren.hypergryph.com/info`,
- },
- });
-
- const data = response.data.data.list;
- ctx.state.data = {
- // 源标题
- title: `塞壬唱片新闻`,
- // 源链接
- link: `https://monster-siren.hypergryph.com/info/`,
- // 源说明
- description: `塞壬唱片新闻`,
- // 遍历此前获取的数据
- item: data.map((item) => ({
- // 文章标题
- title: item.title,
- // 文章正文
- description: `${item.title}
${item.date}`,
- // 文章发布时间
- pubDate: parseDate(item.date),
- // 文章链接
- link: `https://monster-siren.hypergryph.com/info/${item.cid}`,
- })),
- };
-};
diff --git a/lib/routes-deprecated/sketch/beta.js b/lib/routes-deprecated/sketch/beta.js
deleted file mode 100644
index cd1a968cc880..000000000000
--- a/lib/routes-deprecated/sketch/beta.js
+++ /dev/null
@@ -1,30 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const response = await got.get('https://www.sketch.com/beta/');
- const data = response.data;
- const $ = cheerio.load(data);
- // 获取版本
- const version = $('.small.beta__release-info')
- .text()
- .replace(/\)\s.*/, ')');
-
- const item = [
- {
- title: version,
- description: $('.beta__release-notes').html(),
- link: `https://www.sketch.com/beta/`,
- pubDate: new Date($('.beta__release-info time').text()),
- guid: version,
- },
- ];
-
- ctx.state.data = {
- title: `Sketch Beta`,
- link: 'https://www.sketch.com/beta/',
- description: 'Sketch is a design toolkit built to help you create your best work — from your earliest ideas, through to final artwork.',
- image: 'https://cdn.sketchapp.com/assets/components/block-buy/logo.png',
- item,
- };
-};
diff --git a/lib/routes-deprecated/sketch/updates.js b/lib/routes-deprecated/sketch/updates.js
deleted file mode 100644
index 4a6a8d0a6dcf..000000000000
--- a/lib/routes-deprecated/sketch/updates.js
+++ /dev/null
@@ -1,40 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const response = await got({
- method: 'get',
- url: 'https://cdn.sketchapp.com/releases.html',
- });
- const data = response.data;
- const $ = cheerio.load(data);
- const list = $('div.update');
- ctx.state.data = {
- title: 'Sketch Release版本',
- link: response.url,
- description: 'Sketch is a design toolkit built to help you create your best work — from your earliest ideas, through to final artwork.',
- image: 'https://cdn.sketchapp.com/assets/components/block-buy/logo.png',
-
- item:
- list &&
- list
- .map((index, item) => {
- item = $(item);
- // sketch update 提供的时间 年月反了.要重新调整
- const pubday = item.find('section.update-highlights time').attr('datetime').slice(0, 2);
- const pubmonth = item.find('section.update-highlights time').attr('datetime').slice(3, 5);
- const pubyear = item.find('section.update-highlights time').attr('datetime').slice(-4);
- const pubdateString = pubmonth + `-` + pubday + `-` + pubyear;
- return {
- title: item.find('h2.update-version-title').first().text().trim(),
- description: `${item.find('section.update-highlights .lead').html()}
- ${item.find('section.update-highlights footer').html()}
- ${item.find('aside.update-details .mask').html()}`,
- link: `https://www.sketch.com/updates/${item.find('.update-version-title a').attr('href')}`,
- pubDate: new Date(pubdateString),
- guid: item.find('h2.update-version-title').first().text().trim(),
- };
- })
- .get(),
- };
-};
diff --git a/lib/routes-deprecated/socialbeta/home.js b/lib/routes-deprecated/socialbeta/home.js
deleted file mode 100644
index bf36c7f7104e..000000000000
--- a/lib/routes-deprecated/socialbeta/home.js
+++ /dev/null
@@ -1,42 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const currentUrl = `https://socialbeta.com/`;
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
- const $ = cheerio.load(response.data);
- const list = $('ul.post li')
- .find('h3.mt10')
- .slice(0, 15)
- .map((_, item) => {
- item = $(item);
- const a = item.find('a');
- return {
- title: a.text(),
- link: a.attr('href'),
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const res = await got({ method: 'get', url: item.link });
- const content = cheerio.load(res.data);
- const pubDate = content('div.meta').eq(0).text().split('|')[1].replaceAll(/\s+/g, '');
- item.pubDate = new Date(pubDate.slice(0, 10) + ' ' + pubDate.slice(-5, pubDate.length) + ' GMT+8').toUTCString();
- item.description = content('div.content').html();
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: 'SocialBeta - 首页',
- link: currentUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/socialclub/events.js b/lib/routes-deprecated/socialclub/events.js
deleted file mode 100644
index 5d4e71016e11..000000000000
--- a/lib/routes-deprecated/socialclub/events.js
+++ /dev/null
@@ -1,28 +0,0 @@
-const got = require('@/utils/got');
-const { CookieJar } = require('tough-cookie');
-const gameList = new Set(['GTAV', 'RDR2']);
-const eventTypeName = { InGameBonus: '游戏内奖励', InGameUnlock: '游戏内解锁', InGameDiscount: '游戏内折扣' };
-
-module.exports = async (ctx) => {
- const gameId = gameList.has(ctx.params.game) ? ctx.params.game : '';
- const res = await got({
- url: `https://zh-cn.socialclub.rockstargames.com/events/eventlisting?pageId=1&gameId=${gameId}&_=${Date.now()}`,
- headers: { 'accept-language': 'zh-CN,zh;q=0.9' },
- cookieJar: new CookieJar(),
- });
- const { events } = res.data;
-
- ctx.state.data = {
- title: '在线活动 - Rockstar Games Social Club',
- link: 'https://zh-cn.socialclub.rockstargames.com/events?gameId=' + gameId,
- item:
- events &&
- events.map((x) => ({
- title: x.headerText,
- category: eventTypeName[x.eventType] || x.eventType,
- description: (x.imgUrl ? `
` : '') + x.description,
- pubDate: new Date(x.startDate).getTime() / 1000,
- link: x.linkToUrl ? `https://zh-cn.socialclub.rockstargames.com/${x.linkToUrl}/${x.urlHash}` : `https://zh-cn.socialclub.rockstargames.com/events/${x.urlHash}/${x.slug}/1`,
- })),
- };
-};
diff --git a/lib/routes-deprecated/soul/hot.js b/lib/routes-deprecated/soul/hot.js
deleted file mode 100644
index e5540813b3d1..000000000000
--- a/lib/routes-deprecated/soul/hot.js
+++ /dev/null
@@ -1,86 +0,0 @@
-const got = require('@/utils/got');
-const { parseDate } = require('@/utils/parse-date');
-
-const generateResponse = (items) => ({
- // 源标题
- title: 'Soul 热门瞬间',
- // 源链接
- link: 'https://api-h5.soulapp.cn/html/v2/post/hot?postIdEcpt',
- item: items.map((item) => ({
- title: `「${item.uName}」的瞬间:${item.pureContent}`,
- author: item.uName,
- description: item.content,
- pubDate: parseDate(item.createTime),
- guid: item.pId,
- link: `https://w3.soulsmile.cn/activity/#/web/topic/detail?postIdEcpt=${item.pId}`,
- })),
-});
-
-module.exports = async (ctx) => {
- // 根据不同用户瞬间会得到不同的结果,这里提供一些例子
- const defaultPid = 'NXJiSlM5V21kamJWVlgvZUh1NEExdz09';
- const userPid = ctx.params.pid || defaultPid;
- const examplePids = userPid.split('/');
-
- const rsps = await Promise.all(
- examplePids.map((pId) =>
- got({
- method: 'get',
- url: `https://api-h5.soulapp.cn/html/v2/post/hot?postIdEcpt=${pId}`,
- })
- )
- );
-
- const allItems = [];
- for (const response of rsps) {
- // 瞬间信息(数组)
- let items = response.data.data.posts;
-
- items = items.map((item) => {
- const pureContent = item.content;
- let content = pureContent.replace(/\n/, '
');
-
- if (item.attachments) {
- for (const attachment of item.attachments) {
- switch (attachment.type) {
- case 'IMAGE':
- content += '
';
- content += ``;
-
- break;
-
- case 'VIDEO':
- content += '
';
- content += `
';
- content += ``;
-
- break;
-
- default:
- throw new Error(`Unknown attachment type: ${attachment.type}`);
- }
- }
- }
-
- return {
- pId: item.postIdEcpt,
- pureContent,
- content,
- createTime: item.createTime,
- uId: item.authorIdEcpt,
- uName: item.signature,
- };
- });
-
- allItems.push(...items);
- }
-
- const uniqAllItems = allItems.filter((value, idx, arr) => arr.findIndex((item) => item.pId === value.pId) === idx);
-
- ctx.state.data = generateResponse(uniqAllItems);
-};
diff --git a/lib/routes-deprecated/soul/index.js b/lib/routes-deprecated/soul/index.js
deleted file mode 100644
index d8035ad98cc1..000000000000
--- a/lib/routes-deprecated/soul/index.js
+++ /dev/null
@@ -1,71 +0,0 @@
-const got = require('@/utils/got');
-
-const generateResponse = (info, items) => ({
- // 源标题
- title: `「${info.name}」的瞬间`,
- // 源链接
- link: `https://w3.soulsmile.cn/activity/#/web/user?userIdEcpt=${info.id}`,
- item: items.map((item) => ({
- title: `「${info.name}」的新瞬间:${item.pureContent}`,
- author: info.name,
- description: item.content,
- pubDate: new Date(item.createTime).toUTCString(),
- guid: item.id,
- link: `https://w3.soulsmile.cn/activity/#/web/topic/detail?postIdEcpt=${item.id}`,
- })),
-});
-
-module.exports = async (ctx) => {
- const userIdEcpt = ctx.params.id;
- const response = await got({
- method: 'get',
- url: 'https://api-h5.soulapp.cn/html/v2/post/homepage?userIdEcpt=' + userIdEcpt,
- });
-
- // 瞬间信息(数组)
- let items = response.data.data;
-
- // 用户信息
- const info = {
- id: userIdEcpt,
- name: null,
- };
-
- if (items.length === 0) {
- // 未发表过任何瞬间
- const infoResponse = await got({
- method: 'get',
- url: 'https://api-h5.soulapp.cn/html/v2/user/info?userIdEcpt=' + userIdEcpt,
- });
-
- const infoData = infoResponse.data.data;
-
- info.name = infoData.signature;
- } else {
- // 发表过瞬间 -> 直接从瞬间信息取用户名
- info.name = items[0].signature;
- }
-
- items = items.map((item) => {
- const pureContent = item.content;
- let content = pureContent.replace(/\n/, '
');
-
- if (item.attachments) {
- for (const attachment of item.attachments) {
- if (attachment.type === 'IMAGE') {
- content += '
';
- content += ``;
- }
- }
- }
-
- return {
- id: item.postIdEcpt,
- pureContent,
- content,
- createTime: item.createTime,
- };
- });
-
- ctx.state.data = generateResponse(info, items);
-};
diff --git a/lib/routes-deprecated/soundcloud/tracks.js b/lib/routes-deprecated/soundcloud/tracks.js
deleted file mode 100644
index d22921505031..000000000000
--- a/lib/routes-deprecated/soundcloud/tracks.js
+++ /dev/null
@@ -1,28 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const util = require('./utils');
-
-module.exports = async (ctx) => {
- const user = ctx.params.user;
-
- const response = await got({
- method: 'get',
- url: `https://soundcloud.com/${user}/tracks`,
- headers: {
- Referer: `https://soundcloud.com/${user}/tracks`,
- },
- });
-
- const data = response.data;
-
- const $ = cheerio.load(data, { xmlMode: true });
- const list = $('body article.audible').get();
- const result = await util.ProcessFeed(list, ctx.cache);
-
- ctx.state.data = {
- title: $('title').text(),
- link: `https://soundcloud.com/${user}/tracks`,
- description: $('meta[name="description"]').attr('content') || $('title').text(),
- item: result,
- };
-};
diff --git a/lib/routes-deprecated/soundcloud/utils.js b/lib/routes-deprecated/soundcloud/utils.js
deleted file mode 100644
index 044f3f1c0c2a..000000000000
--- a/lib/routes-deprecated/soundcloud/utils.js
+++ /dev/null
@@ -1,47 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const url = require('url');
-
-async function load(link) {
- const response = await got.get(link);
- const $ = cheerio.load(response.data, { xmlMode: true });
- let result = '';
- const tmp = $('noscript article p');
- result += `
'));
-
- const items = $('content')
- .map((_, item) => {
- item = $(item);
- return {
- link: currentUrl,
- title: item.find('h3').text(),
- description: item.find('p').html(),
- pubDate: parseRelativeDate(item.find('b').text().split(':')[0]),
- };
- })
- .get();
-
- ctx.state.data = {
- title: $('title').text(),
- link: currentUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/touhougarakuta/index.js b/lib/routes-deprecated/touhougarakuta/index.js
deleted file mode 100644
index 66895cdbffa0..000000000000
--- a/lib/routes-deprecated/touhougarakuta/index.js
+++ /dev/null
@@ -1,68 +0,0 @@
-const got = require('@/utils/got');
-const j2h = require('./json2html');
-
-const languageCodes = {
- cn: 'zh-cn',
- ko: 'ko',
- ja: 'ja',
-};
-
-const getBaseUrl = (language) => (language === 'ja' ? 'https://touhougarakuta.com' : `https://${language}.touhougarakuta.com`);
-
-module.exports = async (ctx) => {
- const { language, type } = ctx.params;
- if (!Object.keys(languageCodes).includes(language)) {
- throw new Error('Invalid language');
- }
-
- const baseUrl = getBaseUrl(language);
-
- const response = await got({
- method: 'get',
- url: `${baseUrl}/page-data/${type === 'interviews' ? 'tags/interviews' : type}/page-data.json`,
- });
-
- ctx.state.data = {
- title: `東方我楽多叢誌 - ${type}`,
- link: `${baseUrl}/${type === 'index' ? '' : type}`,
- description: `東方我楽多叢誌 〜strange article of the outer world〜 - ${type}`,
- language: languageCodes[language],
- allowEmpty: true,
- item: response.data.result.pageContext.articles.map((article, i) => {
- const result = {};
- result.title = article.title;
- result.pubDate = article.date;
- result.link = `${baseUrl}/${article.type}/${article.slug}`;
- try {
- switch (article.type) {
- case 'index_interview':
- case 'column':
- result.description = j2h.indexInterview(article, language);
- break;
- case 'index_comic':
- result.description = j2h.indexComic(article, language);
- break;
- case 'index_novel':
- result.description = j2h.indexNovel(article, language);
- break;
- case 'interview':
- case 'report':
- result.description = j2h.interview(article, language);
- break;
- case 'novel':
- result.description = j2h.novel(article, language);
- break;
- case 'comic':
- result.description = j2h.comic(article, language);
- break;
- default:
- result.description = j2h.uncategorized(article);
- }
- } catch (error) {
- error.message += `(at article ${i}: ${article.title})`;
- throw error;
- }
- return result;
- }),
- };
-};
diff --git a/lib/routes-deprecated/touhougarakuta/json2html.js b/lib/routes-deprecated/touhougarakuta/json2html.js
deleted file mode 100644
index e5123088026f..000000000000
--- a/lib/routes-deprecated/touhougarakuta/json2html.js
+++ /dev/null
@@ -1,113 +0,0 @@
-const indexInterview = (article, language) => {
- if (Object.hasOwn(article, 'index')) {
- return ogpImage(article) + article.ogpSettings.ogp.description + index(article, language);
- }
- return ogpImage(article);
-};
-
-const indexComic = (article, language) => ogpImage(article) + article.index.about + authors(article.index.authors) + `
` + index(article, language);
-
-const indexNovel = (article, language) => ogpImage(article) + article.index.about + authors(article.index.authors) + `
` + index(article, language);
-
-const interview = (article, language) => {
- if (Object.hasOwn(article, 'interviewContents')) {
- const leading = article.interviewContents.leading;
-
- let result = ogpImage(article) + linkToIndex(article, language) + '
' + (leading ?? '');
- for (const block of article.interviewContents.block) {
- result += `${block.head}
` + block.content;
- }
- return result;
- }
-
- return ogpImage(article) + linkToIndex(article, language);
-};
-
-const novel = (article, language) =>
- ogpImage(article) + linkToIndex(article, language) + `` + authors(article.novelContent.authors) + freeEntry(article.novelContent.freeentry) + article.novelContent.contents;
-
-const comic = (article, language) => {
- const viewerurl = article.comicContents.viewerurl;
- const niconicourl = article.comicContents.niconicourl;
-
- let result =
- ogpImage(article) +
- linkToIndex(article, language) +
- `
` +
- authors(article.comicContents.authors) +
- (viewerurl ? `
`;
- }
- return result;
-};
-
-const uncategorized = (article, language) => ogpImage(article) + linkToIndex(article, language) + '
' + article.contents.texts;
-
-/**
- * 生成超链接,并将 edit 替换为对应语言; 从 article.index.item 会有带 edit 的 url 进来
- */
-const href = (text, url, language) => `${text}`;
-
-/**
- * 处理 authors
- */
-const authors = (data) => {
- let result = '';
- for (const author of data) {
- result += `${fe.subject}
`;
-
-/**
- * 处理 linkToIndex
- */
-const linkToIndex = (article, language) => {
- if (Object.hasOwn(article, 'linkToIndex') && article.linkToIndex.linktoindex !== null) {
- const index = article.linkToIndex.linktoindex;
- return `
`,
- pubDate,
- };
- }),
- };
-};
diff --git a/lib/routes-deprecated/ui-cn/article.js b/lib/routes-deprecated/ui-cn/article.js
deleted file mode 100644
index b55c7deb4a67..000000000000
--- a/lib/routes-deprecated/ui-cn/article.js
+++ /dev/null
@@ -1,44 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const response = await got('https://www.ui.cn/');
- const $ = cheerio.load(response.data);
- const postList = $('#article').find('.h-article-list').find('li').get();
- const result = await Promise.all(
- postList.map(async (item) => {
- const title = $(item).find('.ellipsis').text();
- const link = 'https://www.ui.cn' + $(item).find('.ellipsis').attr('href');
- const guid = link;
-
- const single = {
- title,
- link,
- guid,
- pubDate: '',
- description: '',
- };
-
- const description_key = 'ui-cn_description' + guid;
- const description_value = await ctx.cache.get(description_key);
-
- const pubDate_key = 'ui-cn_pubDate' + guid;
- const pubDate_value = await ctx.cache.get(pubDate_key);
-
- if (description_value && pubDate_value) {
- single.description = description_value;
- single.pubDate = pubDate_value;
- } else {
- const temp = await got(link);
- single.description = $(temp.data).find('.works-cont').html();
- single.pubDate = new Date($(temp.data).find('.works-top').find('.time').find('em').text().replaceAll('更新于:', '')).toUTCString();
-
- ctx.cache.set(description_key, single.description);
- ctx.cache.set(pubDate_key, single.pubDate);
- }
-
- return single;
- })
- );
- ctx.state.data = { title: '推荐文章 - UI 中国', link: 'https://www.ui.cn/', item: result };
-};
diff --git a/lib/routes-deprecated/ui-cn/user.js b/lib/routes-deprecated/ui-cn/user.js
deleted file mode 100644
index cf9d5205b594..000000000000
--- a/lib/routes-deprecated/ui-cn/user.js
+++ /dev/null
@@ -1,29 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const id = ctx.params.id;
- const response = await got(`https://i.ui.cn/ucenter/${id}.html`);
- const $ = cheerio.load(response.data);
- const name = $('.person_name').text();
- const intro = $('.person_intro').text();
- const response2 = await got({
- method: 'get',
- url: `https://i.ui.cn/index.php/Uweb/Api/projectlst?uid=${id}&type=&size=12&page=0`,
- headers: {
- Referer: `https://i.ui.cn/ucenter/${id}.html`,
- },
- });
- const postList = response2.data.data.list;
- ctx.state.data = {
- title: `${name} 的设计作品 - UI 中国`,
- link: `https://i.ui.cn/ucenter/${id}.html`,
- description: intro,
- item: postList.map((item) => ({
- title: item.name,
- description: `${item.name}
`,
- link: `https://www.ui.cn/detail/${item.id}.html`,
- guid: item.id,
- })),
- };
-};
diff --git a/lib/routes-deprecated/uisdc/hangye.js b/lib/routes-deprecated/uisdc/hangye.js
deleted file mode 100644
index b251dd451b1d..000000000000
--- a/lib/routes-deprecated/uisdc/hangye.js
+++ /dev/null
@@ -1,49 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const caty = ctx.params.caty || '';
-
- const rootUrl = 'https://www.uisdc.com';
- const currentUrl = `${rootUrl}/category/hangye${caty === '' ? '' : '/' + caty}`;
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
-
- const $ = cheerio.load(response.data);
-
- const list = $('.item-div a')
- .slice(0, 10)
- .map((_, item) => {
- item = $(item);
- return {
- link: item.attr('href'),
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: item.link,
- });
- const content = cheerio.load(detailResponse.data);
-
- item.title = content('#post_title').text();
- item.description = content('.article').html();
- item.pubDate = new Date(content('.time').attr('title')).toUTCString();
-
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: `${$('.current').text()} - 优设网 - UISDC`,
- link: currentUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/umass/amherst/csnews.js b/lib/routes-deprecated/umass/amherst/csnews.js
deleted file mode 100644
index 4534ac0cc708..000000000000
--- a/lib/routes-deprecated/umass/amherst/csnews.js
+++ /dev/null
@@ -1,32 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const response = await got({
- method: 'get',
- url: 'https://www.cics.umass.edu/news',
- });
-
- const data = response.data;
-
- const $ = cheerio.load(data);
- const list = $('.view-mt-latest-news .views-row');
- let itemPicUrl;
- ctx.state.data = {
- title: 'UMAmherst-CSNews',
- link: 'https://www.cics.umass.edu/news',
- item:
- list &&
- list
- .map((index, item) => {
- item = $(item);
- itemPicUrl = item.find('.views-field-field-image img').attr('src');
- return {
- title: item.find('.views-field-title a').first().text(),
- description: `
` + item.find('.views-field-body .field-content').first(),
- link: item.find('.views-more-link').attr('href'),
- };
- })
- .get(),
- };
-};
diff --git a/lib/routes-deprecated/umass/amherst/ecenews.js b/lib/routes-deprecated/umass/amherst/ecenews.js
deleted file mode 100644
index 1c70551e005a..000000000000
--- a/lib/routes-deprecated/umass/amherst/ecenews.js
+++ /dev/null
@@ -1,33 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const response = await got({
- method: 'get',
- url: 'https://ece.umass.edu/news',
- });
-
- const data = response.data;
-
- const $ = cheerio.load(data);
- const list = $('.view-news .views-row');
- let itemPicUrl;
-
- ctx.state.data = {
- title: 'UMAmherst-ECENews',
- link: 'https://ece.umass.edu/news',
- item:
- list &&
- list
- .map((index, item) => {
- item = $(item);
- itemPicUrl = item.find('.image-style-thumbnail').attr('src');
- return {
- title: item.find('.views-field-title a').first().text(),
- description: `
` + item.find('div.field-content').last(),
- link: item.find('.views-field-title a').attr('href'),
- };
- })
- .get(),
- };
-};
diff --git a/lib/routes-deprecated/umass/amherst/eceseminar.js b/lib/routes-deprecated/umass/amherst/eceseminar.js
deleted file mode 100644
index ae9b5a09a14b..000000000000
--- a/lib/routes-deprecated/umass/amherst/eceseminar.js
+++ /dev/null
@@ -1,40 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const response = await got({
- method: 'get',
- url: 'http://ece.umass.edu/seminars',
- });
-
- const data = response.data;
-
- const $ = cheerio.load(data);
- const list = $('.view-seminar-events .views-row');
-
- ctx.state.data = {
- title: 'UMAmherst-ECESeminar',
- link: 'https://ece.umass.edu/seminars',
- item:
- list &&
- list
- .map((index, item) => {
- item = $(item);
-
- const eventDate = item.find('.views-field-field-datetime .date-display-single').first().attr('content');
- return {
- title: item.find('.views-field-title').first().text() + ' | ' + item.find('.views-field-field-title2').first().text(),
- description:
- '
Presenter: ' +
- item.find('.views-field-field-presenter').first().text() +
- '
Date:' +
- item.find('.views-field-field-datetime').first().text() +
- '
Location:' +
- item.find('.views-field-field-location').first().text(),
- link: item.find('.views-field-title a').attr('href'),
- pubDate: new Date(Date.parse(eventDate)).toUTCString(),
- };
- })
- .get(),
- };
-};
diff --git a/lib/routes-deprecated/umass/amherst/ipoevents.js b/lib/routes-deprecated/umass/amherst/ipoevents.js
deleted file mode 100644
index c9c12028dc09..000000000000
--- a/lib/routes-deprecated/umass/amherst/ipoevents.js
+++ /dev/null
@@ -1,44 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const response = await got({
- method: 'get',
- url: 'https://www.umass.edu/ipo/iss/events',
- });
-
- const data = response.data;
-
- const $ = cheerio.load(data);
- const list = $('.view-content .ed-abroad-events');
-
- ctx.state.data = {
- title: 'UMAmherst-IpoEvents',
- link: 'https://www.umass.edu/ipo/iss/events',
- item:
- list &&
- list
- .map((index, item) => {
- item = $(item);
- const eventDateTxt = item.find('.views-field-field-event-date .date-display-single').first();
- const eventStartDateTxt = item.find('.views-field-field-event-date .date-display-single .date-display-start').first().attr('content');
-
- $.fn.ignore = function (sel) {
- return this.clone()
- .find(sel || '>*')
- .remove()
- .end();
- };
-
- const descTxt = item.find('.views-field-body').first();
-
- return {
- title: item.find('.views-field-title a').first().text(),
- description: eventDateTxt + '
' + descTxt,
- link: item.find('.views-field-title a').attr('href'),
- pubDate: new Date(Date.parse(eventStartDateTxt)).toUTCString(),
- };
- })
- .get(),
- };
-};
diff --git a/lib/routes-deprecated/umass/amherst/ipostories.js b/lib/routes-deprecated/umass/amherst/ipostories.js
deleted file mode 100644
index ed37b7d6077f..000000000000
--- a/lib/routes-deprecated/umass/amherst/ipostories.js
+++ /dev/null
@@ -1,34 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const response = await got({
- method: 'get',
- url: 'https://www.umass.edu/ipo/iss/featured-stories',
- });
-
- const data = response.data;
-
- const $ = cheerio.load(data);
- const list = $('.view-content .individualNews');
- let itemPicUrl;
-
- ctx.state.data = {
- title: 'UMAmherst-IpoStories',
- link: 'https://www.umass.edu/ipo/iss/featured-stories',
- item:
- list &&
- list
- .map((index, item) => {
- item = $(item);
- itemPicUrl = item.find('.views-field-field-image img').attr('src');
-
- return {
- title: item.find('.views-field-title a').first().text(),
- description: `
` + item.find('.views-field-field-news-body .field-content').first(),
- link: item.find('.views-field-title a').attr('href'),
- };
- })
- .get(),
- };
-};
diff --git a/lib/routes-deprecated/un/scveto.js b/lib/routes-deprecated/un/scveto.js
deleted file mode 100644
index a16b6660f960..000000000000
--- a/lib/routes-deprecated/un/scveto.js
+++ /dev/null
@@ -1,55 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const url = 'https://www.un.org/depts/dhl/resguide/scact_veto_table_en.htm';
-
- const response = await got({
- method: 'get',
- url,
- });
-
- const $ = cheerio.load(response.data);
- const list = $('.tablefont > tbody > tr').slice(3);
-
- const items = [];
-
- for (let i = 0; i < list.length - 1; i++) {
- const content = cheerio.load(list[i]);
-
- let date = content('td:nth-child(1)').text();
- if (date.includes('-')) {
- date = date.split('-')[1];
- }
-
- const resolution = content('td:nth-child(2)');
- const meeting = content('td:nth-child(3)');
- const agenda = content('td:nth-child(4)');
- let country = content('td:nth-child(5)');
- country = cheerio.load(country.html().replace('
', ' and '));
-
- const item = {
- title: `${country.text().trim()} vetoed a Resolution`,
- desc: `${country('body').html()} vetoed ${agenda.html()}.
Resolution: ${resolution.html()}
Meeting Record: ${meeting.html()}`,
- url: resolution.find('a').attr('href'),
- guid: `scveto:${resolution.text()}`,
- pubDate: new Date(date).toISOString(),
- };
-
- items.push(item);
- }
-
- ctx.state.data = {
- title: 'United Nations Security Council Vetoed Resolutions',
- link: 'http://research.un.org/en/docs/sc/quick/veto',
- description:
- 'The United Nations Security Council "veto power" refers to the power of the permanent members of the UN Security Council (China, France, Russia, United Kingdom, and United States) to veto any "substantive" resolution. Aka, abuse of power.',
- item: items.map((item) => ({
- title: item.title,
- description: item.desc,
- link: item.url,
- guid: item.guid,
- pubDate: item.pubDate,
- })),
- };
-};
diff --git a/lib/routes-deprecated/unit-image/films.js b/lib/routes-deprecated/unit-image/films.js
deleted file mode 100755
index 760bdf09bf96..000000000000
--- a/lib/routes-deprecated/unit-image/films.js
+++ /dev/null
@@ -1,141 +0,0 @@
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- const type = ctx.params.type ? `?filter=${ctx.params.type}` : '';
- const dataurl = `https://www.unit-image.fr/data/en/wp-json/unitimage/v1/films${type}`;
- const response = await got({
- method: 'get',
- url: dataurl,
- });
- const data = response.data;
- const list = data.content.posts.slice(0, 5);
- const articledata = await Promise.all(
- list.map(async (item) => {
- const url = `https://www.unit-image.fr/data/en/wp-json/unitimage/v1${item.href}`; // 获取所有文章URL
- const cache = await ctx.cache.get(url); // 这里是不是单单缓存 URL?
- if (cache) {
- return JSON.parse(cache); // 如果有 URL 的缓存,则返回 JSON.phrase 的数据
- }
- const response2 = await got({
- method: 'get',
- url,
- });
- // data2为每文章数据
- const data2 = response2.data;
-
- const infosdata = data2.infos || []; // 文章数据返回为data
- const slideshowdata = data2.caseStudy.slideshow || [];
- const storyboarddata = data2.caseStudy.storyboard || [];
- const bhtsdata = data2.behindTheScene[0] || {};
- const compare0 = data2.caseStudy.compare[0] || {};
- const compare1 = data2.caseStudy.compare[1] || {};
- const infos = infosdata.map((item) => ({
- infolabel: item.label, // 项目信息
- infovalue: item.value,
- }));
- const images = slideshowdata.map((item) => ({
- image: item.img, // 图片组
- }));
- const storyboard = storyboarddata.map((item) => ({
- storyboard0: item.items[0].img, // 故事板上
- storyboard1: item.items[1].img, // 故事板下
- }));
- const video = {
- // 主视频
- mp4: data2.video.mp4.url,
- youtube: data2.video.youtube,
- vimeo: data2.video.vimeo,
- };
- const compare = {
- // 对比视频 感谢@piggy_usera 教我用 ["值"] 选择带有横杠的值!但是不能一开始就const不知道为什么。
- compare0: compare0['video-mp4'],
- compare1: compare1['video-mp4'],
- };
- const bhts = {
- // Behind The Scene
- mp4: bhtsdata['video-mp4'],
- youtube: bhtsdata['youtube-id'],
- vimeo: bhtsdata['vimeo-id'],
- };
-
- const single = {
- infos,
- images,
- storyboard,
- video,
- compare,
- bhts,
- };
- ctx.cache.set(url, JSON.stringify(single)); // 设定缓存为序列化文章数据
- return single; // 返回 articledata 为序列化文章数据。
- })
- );
-
- ctx.state.data = {
- // 源标题
- title: `Unit Image | ${ctx.params.type}`,
- // 源链接
- link: `https://www.unit-image.fr/films`,
- // 源说明
- description: `Unit Images Films`,
- // 遍历此前获取的数据
- item: list.map((item, index) => {
- let content = '';
- const videostyle = `width="640" height="360"`;
- const imgstyle = `style="max-width: 650px; height: auto; object-fit: contain; flex: 0 0 auto;"`;
-
- // 运用index数组ID来匹配文章ID!参考来自instagram!
- // 项目信息
- if (articledata[index].infos) {
- for (let i = 0; i < articledata[index].infos.length; i++) {
- content += `${articledata[index].infos[i].infolabel}:${articledata[index].infos[i].infovalue}
`;
- }
- }
- // 不同源主视频
- if (articledata[index].video.mp4) {
- content += `
`;
- } else if (articledata[index].video.vimeo) {
- content += `
`;
- } else if (articledata[index].video.youtube) {
- content += `
`;
- }
- // 不同源幕后视频
-
- if (articledata[index].bhts.mp4) {
- content += `Behind The Scene:
`;
- } else if (articledata[index].bhts.vimeo) {
- content += `Behind The Scene:
`;
- } else if (articledata[index].bhts.youtube) {
- content += `Behind The Scene:
`;
- }
-
- // 项目图片
- if (articledata[index].images) {
- for (let p = 0; p < articledata[index].images.length; p++) {
- content += `
`;
- }
- }
- // 故事板
- if (articledata[index].storyboard.length > 0) {
- let storyboard = '';
- for (let s = 0; s < articledata[index].storyboard.length; s++) {
- storyboard += ` `;
- }
- content += ` ${storyboard}Storyboard
`;
- }
-
- // 对比视频
- if (articledata[index].compare.compare0) {
- content += `Compare:
`;
- }
- return {
- title: item.title,
- description: content,
- link: `https://www.unit-image.fr${item.href}`,
- pubDate: item.preview.mp4.date,
- };
- }),
- };
-};
-// 数据返回样式:http://www.unit-image.fr/data/en/wp-json/unitimage/v1/film/baldurs-gate-3-intro
-// 非常感谢@xunco @johnson_Flex @lemonplusplus @yeFoenix @piggy_user
diff --git a/lib/routes-deprecated/universities/ahau/cs_news/index.js b/lib/routes-deprecated/universities/ahau/cs_news/index.js
deleted file mode 100644
index b571a3c62ac6..000000000000
--- a/lib/routes-deprecated/universities/ahau/cs_news/index.js
+++ /dev/null
@@ -1,39 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const util = require('./utils');
-
-module.exports = async (ctx) => {
- const type = ctx.params.type;
- let title, path;
- switch (type) {
- case 'xxtg':
- title = '信息通告';
- path = 'xxtg.htm';
- break;
- case 'xwddyn':
- title = '新闻动态';
- path = 'xwddyn.htm';
- break;
- }
-
- const response = await got({
- method: 'get',
- url: 'http://computer.ahau.edu.cn/xyxub/' + path,
- headers: {
- Referer: 'http://computer.ahau.edu.cn/index.htm',
- },
- });
-
- const $ = cheerio.load(response.data);
-
- const list = $('.n_right .n_listxx1 .cleafix').slice(0, 15).get();
-
- const result = await util.ProcessFeed(list, ctx.cache);
-
- ctx.state.data = {
- title: '安徽农业大学计算机学院 - ' + title,
- link: 'http://computer.ahau.edu.cn/xyxub/' + path,
- description: '安徽农业大学计算机学院 - ' + title,
- item: result,
- };
-};
diff --git a/lib/routes-deprecated/universities/ahau/cs_news/utils.js b/lib/routes-deprecated/universities/ahau/cs_news/utils.js
deleted file mode 100644
index c8fb902c5f89..000000000000
--- a/lib/routes-deprecated/universities/ahau/cs_news/utils.js
+++ /dev/null
@@ -1,50 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const url = require('url');
-
-async function load(link) {
- const response = await got.get(link);
- const $ = cheerio.load(response.data);
-
- // DATE
- const date = new Date(
- $('div.contain > form > h3 span:nth-of-type(1)')
- .text()
- .match(/\d{4}-\d{2}-\d{2}/)
- );
- const timeZone = 8;
- const serverOffset = date.getTimezoneOffset() / 60;
- const pubDate = new Date(date.getTime() - 60 * 60 * 1000 * (timeZone + serverOffset)).toUTCString();
-
- const description = $('#vsb_content > .v_news_content').html();
-
- return { description, pubDate };
-}
-
-const ProcessFeed = (list, caches) => {
- const host = 'http://computer.ahau.edu.cn/';
-
- return Promise.all(
- list.map(async (item) => {
- const $ = cheerio.load(item);
-
- const $title = $('a');
- const itemUrl = url.resolve(host, $title.attr('href'));
-
- const single = {
- title: $title.text(),
- link: itemUrl,
- author: '安农大信息与计算机学院',
- guid: itemUrl,
- };
-
- const other = await caches.tryGet(itemUrl, () => load(itemUrl));
-
- return Object.assign({}, single, other);
- })
- );
-};
-
-module.exports = {
- ProcessFeed,
-};
diff --git a/lib/routes-deprecated/universities/ahau/jwc/index.js b/lib/routes-deprecated/universities/ahau/jwc/index.js
deleted file mode 100644
index 53d2cd249a2e..000000000000
--- a/lib/routes-deprecated/universities/ahau/jwc/index.js
+++ /dev/null
@@ -1,39 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const util = require('./utils');
-
-module.exports = async (ctx) => {
- const type = ctx.params.type;
- let title, path;
- switch (type) {
- case 'jwyw':
- title = '教务要闻';
- path = 'jwyw.htm';
- break;
- case 'tzgg':
- title = '通知公告';
- path = 'tzgg.htm';
- break;
- }
-
- const response = await got({
- method: 'get',
- url: 'http://jwc.ahau.edu.cn/' + path,
- headers: {
- Referer: 'http://jwc.ahau.edu.cn/jwyw.htm',
- },
- });
-
- const $ = cheerio.load(response.data);
-
- const list = $('.pageList li .clearfix').slice(0, 20).get();
-
- const result = await util.ProcessFeed(list, ctx.cache);
-
- ctx.state.data = {
- title: '安徽农业大学教务处 - ' + title,
- link: 'http://jwc.ahau.edu.cn/' + path,
- description: '安徽农业大学教务处 - ' + title,
- item: result,
- };
-};
diff --git a/lib/routes-deprecated/universities/ahau/jwc/utils.js b/lib/routes-deprecated/universities/ahau/jwc/utils.js
deleted file mode 100644
index fe3b6f365f4c..000000000000
--- a/lib/routes-deprecated/universities/ahau/jwc/utils.js
+++ /dev/null
@@ -1,50 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const url = require('url');
-
-async function load(link) {
- const response = await got.get(link);
- const $ = cheerio.load(response.data);
-
- const date = new Date(
- $('.introTime span:nth-of-type(2)')
- .text()
- .match(/\d{4}-\d{2}-\d{2}/)
- );
- const timeZone = 8;
- const serverOffset = date.getTimezoneOffset() / 60;
- const pubDate = new Date(date.getTime() - 60 * 60 * 1000 * (timeZone + serverOffset)).toUTCString();
-
- const description = $('#vsb_content > .v_news_content').html();
-
- return { description, pubDate };
-}
-
-const ProcessFeed = (list, caches) => {
- const host = 'http://jwc.ahau.edu.cn/';
-
- return Promise.all(
- list.map(async (item) => {
- const $ = cheerio.load(item);
-
- const $title = $('a');
- const $title_pretty = $title.attr('title').trim();
- const itemUrl = url.resolve(host, $title.attr('href'));
-
- const single = {
- title: $title_pretty,
- link: itemUrl,
- author: '安农大教务处',
- guid: itemUrl,
- };
-
- const other = await caches.tryGet(itemUrl, () => load(itemUrl));
-
- return Object.assign({}, single, other);
- })
- );
-};
-
-module.exports = {
- ProcessFeed,
-};
diff --git a/lib/routes-deprecated/universities/ahau/main/index.js b/lib/routes-deprecated/universities/ahau/main/index.js
deleted file mode 100644
index e0782c92a041..000000000000
--- a/lib/routes-deprecated/universities/ahau/main/index.js
+++ /dev/null
@@ -1,39 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const util = require('./utils');
-
-module.exports = async (ctx) => {
- const type = ctx.params.type;
- let title, path;
- switch (type) {
- case 'xnyw':
- title = '校内要闻';
- path = 'xnyw.htm';
- break;
- case 'xydt':
- title = '学院动态';
- path = 'xydt.htm';
- break;
- }
-
- const response = await got({
- method: 'get',
- url: 'http://news.ahau.edu.cn/' + path,
- headers: {
- Referer: 'http://news.ahau.edu.cn/',
- },
- });
-
- const $ = cheerio.load(response.data);
-
- const list = $('.listbox .title').slice(0, 10).get();
-
- const result = await util.ProcessFeed(list, ctx.cache);
-
- ctx.state.data = {
- title: '安徽农业大学新闻网 - ' + title,
- link: 'http://news.ahau.edu.cn/' + path,
- description: '安徽农业大学新闻网 - ' + title,
- item: result,
- };
-};
diff --git a/lib/routes-deprecated/universities/ahau/main/utils.js b/lib/routes-deprecated/universities/ahau/main/utils.js
deleted file mode 100644
index 379f1d8b678e..000000000000
--- a/lib/routes-deprecated/universities/ahau/main/utils.js
+++ /dev/null
@@ -1,50 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const url = require('url');
-
-async function load(link) {
- const response = await got.get(link);
- const $ = cheerio.load(response.data);
-
- const date = new Date(
- $('.info')
- .text()
- .match(/\d{4}-\d{2}-\d{2}/)
- );
- const timeZone = 8;
- const serverOffset = date.getTimezoneOffset() / 60;
- const pubDate = new Date(date.getTime() - 60 * 60 * 1000 * (timeZone + serverOffset)).toUTCString();
-
- const description = $('#vsb_content > .v_news_content').html();
-
- return { description, pubDate };
-}
-
-const ProcessFeed = (list, caches) => {
- const host = 'http://news.ahau.edu.cn/';
-
- return Promise.all(
- list.map(async (item) => {
- const $ = cheerio.load(item);
-
- const $title_href = $('a');
- const $title = $('a span').text().trim();
- const itemUrl = url.resolve(host, $title_href.attr('href'));
-
- const single = {
- title: $title,
- link: itemUrl,
- author: '安农大新闻',
- guid: itemUrl,
- };
-
- const other = await caches.tryGet(itemUrl, () => load(itemUrl));
-
- return Object.assign({}, single, other);
- })
- );
-};
-
-module.exports = {
- ProcessFeed,
-};
diff --git a/lib/routes-deprecated/universities/ahmu/news.js b/lib/routes-deprecated/universities/ahmu/news.js
deleted file mode 100644
index 36fcaea571eb..000000000000
--- a/lib/routes-deprecated/universities/ahmu/news.js
+++ /dev/null
@@ -1,51 +0,0 @@
-const got = require('@/utils/got');
-const { parseRelativeDate } = require('@/utils/parse-date');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const url = 'http://yjsxy.ahmu.edu.cn/_s62/1840/list.psp';
- const response = await got({ method: 'get', url });
- const $ = cheerio.load(response.data);
-
- const list = $('#wp_news_w3 table tbody')
- .map((i, e) => {
- const element = $(e);
- const title = element.find('a').text();
- const link = element.find('a').attr('href');
- const dateraw = /(\d{4})\/(\d{2})(\d{2})/.exec(link);
-
- return {
- title,
- description: '',
- link: url + link,
- author: '安徽医科大学研究生学院',
- pubDate: parseRelativeDate(`${dateraw[1]}-${dateraw[2]}-${dateraw[3]}`),
- };
- })
- .get();
-
- const result = await Promise.all(
- list.map(async (item) => {
- const link = item.link;
-
- const cache = await ctx.cache.get(link);
- if (cache) {
- return JSON.parse(cache);
- }
-
- const itemReponse = await got.get(link);
- const itemElement = cheerio.load(itemReponse.data);
-
- item.description = itemElement('.content').html();
-
- ctx.cache.set(link, JSON.stringify(item));
- return item;
- })
- );
-
- ctx.state.data = {
- title: '安徽医科大学研究生学院',
- link: url,
- item: result,
- };
-};
diff --git a/lib/routes-deprecated/universities/ahut/cstzgg.js b/lib/routes-deprecated/universities/ahut/cstzgg.js
deleted file mode 100644
index f81790a34bcc..000000000000
--- a/lib/routes-deprecated/universities/ahut/cstzgg.js
+++ /dev/null
@@ -1,45 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const url = require('url');
-
-module.exports = async (ctx) => {
- const response = await got.get('http://jsjxy.ahut.edu.cn/index/tzgg.htm');
- const $ = cheerio.load(response.data);
-
- // 获取列表
- const list = $('a.c259382')
- .map((index, ele) => ({
- title: $(ele).attr('title'),
- link: url.resolve('http://jsjxy.ahut.edu.cn/', $(ele).attr('href')),
- }))
- .get();
-
- // 定义输出的item
- const out = await Promise.all(
- // 遍历列表,筛选出自己想要的内容
- list.map(async (item) => {
- const cache = await ctx.cache.get(item.link); // 得到全局中的缓存信息
- // 判断缓存是否存在,如果存在即跳过此次获取的信息
- if (cache) {
- return JSON.parse(cache);
- }
- // 获取详情页面的介绍
- const detail_response = await got.get(item.link);
- const $ = cheerio.load(detail_response.data);
-
- // 设置 RSS feed item
- item.description = $('.contentstyle47853 > div').html();
- item.pubDate = new Date($('.timestyle47853').text().trim());
-
- // 设置缓存
- ctx.cache.set(item.link, JSON.stringify(item));
- return item;
- })
- );
- ctx.state.data = {
- title: `安徽工业大学 - 计算机学院公告`,
- link: 'http://jsjxy.ahut.edu.cn/list.jsp?urltype=tree.TreeTempUrl&wbtreeid=1887',
- description: `安徽工业大学 - 计算机学院公告`,
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/universities/ahut/jwc.js b/lib/routes-deprecated/universities/ahut/jwc.js
deleted file mode 100644
index 24f7ee792cba..000000000000
--- a/lib/routes-deprecated/universities/ahut/jwc.js
+++ /dev/null
@@ -1,43 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const url = require('url');
-
-module.exports = async (ctx) => {
- const response = await got.get('http://jwc.ahut.edu.cn/list.jsp?urltype=tree.TreeTempUrl&wbtreeid=1082');
- const $ = cheerio.load(response.data);
-
- // 获取列表
- const list = $('.winstyle44566 tr')
- .map((index, ele) => ({
- title: $('a', ele).attr('title'),
- link: url.resolve('http://jwc.ahut.edu.cn/', $('a', ele).attr('href')),
- }))
- .get();
-
- // 定义输出的item
- const out = await Promise.all(
- // 遍历列表,筛选出自己想要的内容
- list.map(async (item) => {
- const cache = await ctx.cache.get(item.link); // 得到全局中的缓存信息
- // 判断缓存是否存在,如果存在即跳过此次获取的信息
- if (cache) {
- return JSON.parse(cache);
- }
- // 获取详情页面的介绍
- const detail_response = await got.get(item.link);
- const $ = cheerio.load(detail_response.data);
- // 设置 RSS feed item
- item.description = $('.winstyle44457 > tbody').html();
- item.pubDate = new Date($('.timestyle44457').text().trim());
- // 设置缓存
- ctx.cache.set(item.link, JSON.stringify(item));
- return item;
- })
- );
- ctx.state.data = {
- title: `安徽工业大学 - 教务处`,
- link: 'http://jwc.ahut.edu.cn/list.jsp?urltype=tree.TreeTempUrl&wbtreeid=1082',
- description: `安徽工业大学 - 教务处`,
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/universities/ahut/news.js b/lib/routes-deprecated/universities/ahut/news.js
deleted file mode 100644
index 67942d385d6a..000000000000
--- a/lib/routes-deprecated/universities/ahut/news.js
+++ /dev/null
@@ -1,44 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const url = require('url');
-
-module.exports = async (ctx) => {
- const response = await got.get('http://news.ahut.edu.cn/list.jsp?urltype=tree.TreeTempUrl&wbtreeid=1002');
- const $ = cheerio.load(response.data);
-
- // 获取列表
- const list = $('.winstyle247968 a.c247968')
- .map((index, ele) => ({
- title: $(ele).attr('title'),
- link: url.resolve('http://news.ahut.edu.cn/', $(ele).attr('href')),
- }))
- .get();
- // 定义输出的item
- const out = await Promise.all(
- // 遍历列表,筛选出自己想要的内容
- list.map(async (item) => {
- const cache = await ctx.cache.get(item.link); // 得到全局中的缓存信息
- // 判断缓存是否存在,如果存在即跳过此次获取的信息
- if (cache) {
- return JSON.parse(cache);
- }
- // 获取详情页面的介绍
- const detail_response = await got.get(item.link);
- const $ = cheerio.load(detail_response.data);
-
- // 设置 RSS feed item
- item.description = $('.winstyle1023').html();
- item.pubDate = new Date($('.timestyle1023').text().trim());
-
- // 设置缓存
- ctx.cache.set(item.link, JSON.stringify(item));
- return item;
- })
- );
- ctx.state.data = {
- title: `安徽工业大学 - 学校要闻`,
- link: 'http://news.ahut.edu.cn/list.jsp?urltype=tree.TreeTempUrl&wbtreeid=1002',
- description: `安徽工业大学 - 学校要闻`,
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/universities/bupt/funbox.js b/lib/routes-deprecated/universities/bupt/funbox.js
deleted file mode 100644
index 595bd003b15b..000000000000
--- a/lib/routes-deprecated/universities/bupt/funbox.js
+++ /dev/null
@@ -1,40 +0,0 @@
-const config = require('@/config').value;
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const cookie = config.btbyr.cookies;
- const url = config.btbyr.host || 'https://bt.byr.cn/';
- const response = await got({
- method: 'get',
- url: url + `log.php?action=funbox`,
- headers: {
- Referer: url,
- Cookie: cookie,
- },
- });
- const $ = cheerio.load(response.data);
-
- const list = $('td.outer > table > tbody')
- .slice(2)
- .map((i, e) => ({
- title: $(e).find('tr > td.rowfollow').eq(0).text(),
- pubDate: new Date($(e).find('tr > td.rowfollow > span').attr('title')).toUTCString(),
- description: $(e)
- .find('tr > td.rowfollow')
- .eq(2)
- .html()
- .replaceAll(/https:\/\/bt.byr.cn\//g, url)
- .replaceAll(/onclick=.*findPosition\(this\)\[1]-58\);"/g, '')
- .replaceAll(/.thumb.jpg/g, ''),
- link: url + `log.php?action=funbox`,
- guid: new Date($(e).find('tr > td.rowfollow > span').attr('title')).getTime() / 1000,
- }))
- .get();
-
- ctx.state.data = {
- title: 'BTBYR - 趣味盒',
- link: url + `log.php?action=funbox`,
- item: list,
- };
-};
diff --git a/lib/routes-deprecated/universities/bupt/grs.js b/lib/routes-deprecated/universities/bupt/grs.js
deleted file mode 100644
index 6c106b8a6565..000000000000
--- a/lib/routes-deprecated/universities/bupt/grs.js
+++ /dev/null
@@ -1,64 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const url = require('url');
-
-const base = 'https://grs.bupt.edu.cn';
-const sourceTimezoneOffset = -8;
-
-module.exports = async (ctx) => {
- let out = [];
-
- const fetch = async (pageIndex) => {
- const pageUrl = url.resolve(base, `/list/list.php?p=16_1_${pageIndex}`);
- const response = await got({
- method: 'get',
- url: pageUrl,
- });
-
- const $ = cheerio.load(response.data);
- const list = $('#news li').get();
-
- const result = await Promise.all(
- list.map(async (i) => {
- const item = $(i);
- const itemUrl = url.resolve(base, $(item).find('a').attr('href'));
-
- const cache = await ctx.cache.get(itemUrl);
- if (cache) {
- return JSON.parse(cache);
- }
-
- const title = $(item).find('a').attr('title');
- const itemResponse = await got.get(itemUrl);
- const itemElement = cheerio.load(itemResponse.data);
- const description = itemElement('#news #article').html();
-
- const pageInfo = itemElement('#news #date').text();
- const regex = /\d{4}-\d{2}-\d{2}/;
- const regRes = regex.exec(pageInfo);
- const time = regRes === null ? new Date() : new Date(regRes[0]);
- time.setTime(time.getTime() + (sourceTimezoneOffset - time.getTimezoneOffset() / 60) * 60 * 60 * 1000);
-
- const single = {
- title,
- description,
- pubDate: time.toUTCString(),
- link: itemUrl,
- guid: itemUrl,
- };
-
- ctx.cache.set(itemUrl, JSON.stringify(single));
- return single;
- })
- );
- out = [...out, ...result];
- };
-
- await Promise.all([1, 2].map((value) => fetch(value)));
-
- ctx.state.data = {
- title: '北京邮电大学研究生院',
- link: 'https://grs.bupt.edu.cn/list/list.php?p=16_1_1',
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/universities/bupt/news.js b/lib/routes-deprecated/universities/bupt/news.js
deleted file mode 100644
index 0fd48b9723b4..000000000000
--- a/lib/routes-deprecated/universities/bupt/news.js
+++ /dev/null
@@ -1,34 +0,0 @@
-const config = require('@/config').value;
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- const cookie = config.bupt.portal_cookie;
- const headers = {};
- if (cookie) {
- headers.cookie = cookie;
- }
- const response = await got({
- method: 'get',
- url: `https://webapp.bupt.edu.cn/extensions/wap/news/get-list.html?p=1&type=xnxw`,
- headers,
- });
- const out = [];
- const data = response.data.data;
- for (const value of Object.values(data)) {
- for (const item of value) {
- out.push({
- title: item.title,
- description: item.desc,
- pubDate: new Date(item.created * 1000).toUTCString(),
- link: `https://webapp.bupt.edu.cn/extensions/wap/news/detail.html?id=${item.id}&classify_id=xnxw`,
- author: item.author,
- });
- }
- }
-
- ctx.state.data = {
- title: '北京邮电大学校校园新闻',
- link: 'https://webapp.bupt.edu.cn/extensions/wap/news/list.html?p=1&type=xnxw',
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/universities/bupt/portal.js b/lib/routes-deprecated/universities/bupt/portal.js
deleted file mode 100644
index 3d15e5396827..000000000000
--- a/lib/routes-deprecated/universities/bupt/portal.js
+++ /dev/null
@@ -1,34 +0,0 @@
-const config = require('@/config').value;
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- const cookie = config.bupt.portal_cookie;
- const headers = {};
- if (cookie) {
- headers.cookie = cookie;
- }
- const response = await got({
- method: 'get',
- url: `https://webapp.bupt.edu.cn/extensions/wap/news/get-list.html?p=1&type=tzgg`,
- headers,
- });
- const out = [];
- const data = response.data.data;
- for (const value of Object.values(data)) {
- for (const item of value) {
- out.push({
- title: item.title,
- description: item.text,
- pubDate: new Date(item.created * 1000).toUTCString(),
- link: `https://webapp.bupt.edu.cn/extensions/wap/news/detail.html?id=${item.id}&classify_id=tzgg`,
- author: item.author,
- });
- }
- }
-
- ctx.state.data = {
- title: '北京邮电大学信息门户',
- link: 'https://webapp.bupt.edu.cn/extensions/wap/news/list.html?p=1&type=tzgg',
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/universities/bupt/utils.js b/lib/routes-deprecated/universities/bupt/utils.js
deleted file mode 100644
index b2a6bda34509..000000000000
--- a/lib/routes-deprecated/universities/bupt/utils.js
+++ /dev/null
@@ -1,67 +0,0 @@
-const cheerio = require('cheerio');
-const got = require('@/utils/got');
-const url = require('url');
-
-const ProcessFeed = (list, cache, current, type) =>
- Promise.all(
- list
- .filter((item) => {
- // 如果不包含链接说明不是新闻item,如表头的tr
- const $ = cheerio.load(item);
- if ($('a').length > 0) {
- return true;
- }
- return false;
-
- // return typeof ($('a').attr('href')) !== undefined;
- // return false;
- })
- .map(async (item) => {
- let $ = cheerio.load(item);
-
- const $url = url.resolve(current.url, $('a').attr('href'));
-
- // 加载新闻内容页面
- const response = await got({
- method: 'get',
- url: $url,
- });
-
- const data = response.data;
- $ = cheerio.load(data); // 使用 cheerio 加载返回的 HTML
-
- // 还原图片地址
- $(`${current.selector.content} img`).each((index, elem) => {
- const $elem = $(elem);
- const src = $elem.attr('src');
- if (src) {
- $elem.attr('src', url.resolve(current.url, src));
- }
- });
- // 还原链接地址
- $(`${current.selector.content} a`).each((index, elem) => {
- const $elem = $(elem);
- const src = $elem.attr('href');
- if (src) {
- $elem.attr('href', url.resolve(current.url, src));
- }
- });
- // 去除样式
- $('img, div, span, p, table, td, tr').removeAttr('style');
- $('style, script').remove();
-
- const title = type === 'sci' ? $('#timu').text() : $('title').text();
- // 列表上提取到的信息
- return {
- title,
- description: $(current.selector.content).html(),
- link: $url,
- author: '北京邮电大学研究院',
- guid: $url, // 文章唯一标识
- };
- })
- );
-
-module.exports = {
- ProcessFeed,
-};
diff --git a/lib/routes-deprecated/universities/bupt/yz.js b/lib/routes-deprecated/universities/bupt/yz.js
deleted file mode 100644
index 44207f75de81..000000000000
--- a/lib/routes-deprecated/universities/bupt/yz.js
+++ /dev/null
@@ -1,154 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const util = require('./utils');
-
-/* 研究生官网招生信息*/
-
-module.exports = async (ctx) => {
- const type = ctx.params.type;
-
- const struct = {
- all: {
- selector: {
- list: '.list ul',
- item: 'li',
- content: '.aticle',
- },
- url: 'https://yzb.bupt.edu.cn/list/list.php?p=2_1_1',
- },
- sice: {
- selector: {
- list: '.list',
- item: 'li',
- content: '#content',
- },
- url: 'https://sice.bupt.edu.cn/xygk/zygg.htm',
- },
- see: {
- selector: {
- list: '.list',
- item: 'li',
- content: '.article',
- },
- url: 'https://see.bupt.edu.cn/list/list.php?p=1_2_1',
- },
- scs: {
- selector: {
- list: '#ctl00_ctl00_ph_content_ph_2_content_noteMainPagePanel1_noteMainPage1_GridView1 tbody',
- item: 'tr',
- content: '#conten_2',
- },
- url: 'https://scs.bupt.edu.cn/cs_web/',
- },
- sa: {
- selector: {
- list: '.list',
- item: 'li',
- content: '.v_news_content',
- },
- url: 'https://sa.bupt.edu.cn/index/ybgl.htm',
- },
- sse: {
- selector: {
- list: '.main_conRCb ul',
- item: 'li',
- content: '.main_conDiv',
- },
- url: 'https://sse.bupt.edu.cn/jxgl/jwtzygg.htm',
- },
- sdmda: {
- selector: {
- list: '.list',
- item: 'li',
- content: '.article',
- },
- url: 'https://sdmda.bupt.edu.cn/?cat=33',
- },
- scss: {
- selector: {
- list: '.main_conRCb ul',
- item: 'li',
- content: '.main_conDiv',
- },
- url: 'https://scss.bupt.edu.cn/zsjy1/yjszs1.htm',
- },
- sci: {
- selector: {
- list: '#right_common ul',
- item: 'li',
- content: '#newscontent',
- },
- url: 'https://sci.bupt.edu.cn/list/list.php?p=2_6_1',
- },
- sem: {
- selector: {
- list: '#zs .index_list_lu',
- item: 'li',
- content: '#vsb_content',
- },
- url: 'https://sem.bupt.edu.cn/index.htm',
- },
- sh: {
- selector: {
- list: '.list ul',
- item: 'li',
- content: '.content',
- },
- url: 'https://sh.bupt.edu.cn/list/list.php?p=3_3_1',
- },
- mtri: {
- selector: {
- list: '.list ul',
- item: 'li',
- content: '.content',
- },
- url: 'https://mtri.bupt.edu.cn/list/list.php?p=1_3_1',
- },
- int: {
- selector: {
- list: '.list ul',
- item: 'li',
- content: '.content',
- },
- url: 'https://int.bupt.edu.cn/list/list.php?p=1_3_1',
- },
- ipoc: {
- selector: {
- list: '.content',
- item: 'li',
- content: '#content',
- },
- url: 'https://ipoc.bupt.edu.cn/zytz.htm',
- },
- };
-
- const url = struct[type].url;
- const response = await got({
- method: 'get',
- url,
- headers: {
- Referer: 'https://www.baidu.com/',
- },
- });
- const data = response.data;
-
- const $ = cheerio.load(data); // 使用 cheerio 加载返回的 HTML
- const list = $(struct[type].selector.list).find(struct[type].selector.item).get();
-
- const name = $('title').text();
- const result = await util.ProcessFeed(list, ctx.cache, struct[type], type);
-
- // 使用 cheerio 选择器,选择 class="note-list" 下的所有 "li"元素,返回 cheerio node 对象数组
- // cheerio get() 方法将 cheerio node 对象数组转换为 node 对象数组
-
- // 注:每一个 cheerio node 对应一个 HTML DOM
- // 注:cheerio 选择器与 jquery 选择器几乎相同
- // 参考 cheerio 文档:https://cheerio.js.org/
-
- ctx.state.data = {
- title: `${name}又有更新了`,
- link: url,
- description: name,
- item: result,
- };
-};
diff --git a/lib/routes-deprecated/universities/bwu/news.js b/lib/routes-deprecated/universities/bwu/news.js
deleted file mode 100644
index 83df42f24eb1..000000000000
--- a/lib/routes-deprecated/universities/bwu/news.js
+++ /dev/null
@@ -1,29 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const util = require('./utils');
-
-module.exports = async (ctx) => {
- const title = '通知公告';
- const host = 'https://news.bwu.edu.cn/';
- const path = 'tzgg.htm';
-
- const response = await got({
- method: 'get',
- url: host + path,
- headers: {
- Referer: host,
- },
- });
-
- const $ = cheerio.load(response.data);
- const list = $('div[class=subPage] div ul li').slice(0, 25).get();
-
- const result = await util.ProcessFeed(list, ctx.cache);
-
- ctx.state.data = {
- title: title + ' - 物院新闻',
- link: host + path,
- description: title + ' - 北京物资学院新闻中心',
- item: result,
- };
-};
diff --git a/lib/routes-deprecated/universities/bwu/utils.js b/lib/routes-deprecated/universities/bwu/utils.js
deleted file mode 100644
index c171e22bac22..000000000000
--- a/lib/routes-deprecated/universities/bwu/utils.js
+++ /dev/null
@@ -1,50 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const { parseDate } = require('@/utils/parse-date');
-const timezone = require('@/utils/timezone');
-
-// Processing full text
-async function load(link) {
- const response = await got.get(link);
- const $ = cheerio.load(response.data);
- const author = $('div[class=articleAuthor] p span').eq(1).text() || 'null';
- const authorName = author.includes(':') ? author.split(':')[1].trim() : author;
- const validAuthor = 'xcb@bwu.edu.cn (' + authorName + ')';
- // Extracting text
- const description = $('div[id^=vsb_content]').html();
-
- return {
- description,
- author: validAuthor,
- };
-}
-
-const ProcessFeed = (list, cache) => {
- const host = 'https://news.bwu.edu.cn/';
-
- return Promise.all(
- list.map(async (item) => {
- const $ = cheerio.load(item);
- const aTag = $('a');
- const title = aTag.text();
- const link = new URL(aTag.attr('href'), host);
- // Parsing the date
- const pubDate = timezone(parseDate($('span[class=rightDate]').text(), 'YYYY-MM-DD'), +8);
-
- const single = {
- title,
- link,
- guid: link,
- pubDate,
- };
- // Try caching
- const other = await cache.tryGet(link, () => load(link));
- // Return article information
- return { ...single, ...other };
- })
- );
-};
-
-module.exports = {
- ProcessFeed,
-};
diff --git a/lib/routes-deprecated/universities/cczu/jwc.js b/lib/routes-deprecated/universities/cczu/jwc.js
deleted file mode 100644
index dedf2e3c5510..000000000000
--- a/lib/routes-deprecated/universities/cczu/jwc.js
+++ /dev/null
@@ -1,36 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const url = require('url');
-
-const baseTitle = '常大教务处';
-const baseUrl = 'http://jwc.cczu.edu.cn';
-const entryUrlRegex = /^\/(20\d{2})\/(\d{2})(\d{2})\/.*$/;
-
-module.exports = async (ctx) => {
- const category = ctx.params.category || 'all';
- const pageUrl = baseUrl + (category === 'all' ? '/' : `/${category}/list.htm`);
-
- const response = await got({
- method: 'get',
- url: pageUrl,
- headers: {
- Referer: baseUrl,
- },
- });
-
- const $ = cheerio.load(response.data);
-
- ctx.state.data = {
- link: pageUrl,
- title: category === 'all' ? baseTitle : `${baseTitle} ${$('title').text()}`,
- item: $('div[id^="wp_news_w"] a')
- .slice(0, 10)
- .filter((_, elem) => elem.attribs.href.match(entryUrlRegex))
- .map((_, elem) => ({
- link: url.resolve(pageUrl, elem.attribs.href),
- title: elem.attribs.title,
- pubDate: new Date(elem.attribs.href.replace(entryUrlRegex, '$1-$2-$3')).toUTCString(),
- }))
- .get(),
- };
-};
diff --git a/lib/routes-deprecated/universities/cczu/news.js b/lib/routes-deprecated/universities/cczu/news.js
deleted file mode 100644
index 61fb7fd6524f..000000000000
--- a/lib/routes-deprecated/universities/cczu/news.js
+++ /dev/null
@@ -1,36 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const url = require('url');
-
-const baseTitle = '常大新闻网';
-const baseUrl = 'http://news.cczu.edu.cn';
-const entryUrlRegex = /^\/(20\d{2})\/(\d{2})(\d{2})\/.*$/;
-
-module.exports = async (ctx) => {
- const category = ctx.params.category || 'all';
- const pageUrl = baseUrl + (category === 'all' ? '/' : `/${category}/list.htm`);
-
- const response = await got({
- method: 'get',
- url: pageUrl,
- headers: {
- Referer: baseUrl,
- },
- });
-
- const $ = cheerio.load(response.data);
-
- ctx.state.data = {
- link: pageUrl,
- title: category === 'all' ? baseTitle : `${baseTitle} ${$('title').text()}`,
- item: $('div[id^="wp_news_w"] a')
- .slice(0, 10)
- .filter((_, elem) => elem.attribs.href.match(entryUrlRegex))
- .map((_, elem) => ({
- link: url.resolve(pageUrl, elem.attribs.href),
- title: elem.attribs.title,
- pubDate: new Date(elem.attribs.href.replace(entryUrlRegex, '$1-$2-$3')).toUTCString(),
- }))
- .get(),
- };
-};
diff --git a/lib/routes-deprecated/universities/cpu/home.js b/lib/routes-deprecated/universities/cpu/home.js
deleted file mode 100644
index 517f94e93850..000000000000
--- a/lib/routes-deprecated/universities/cpu/home.js
+++ /dev/null
@@ -1,52 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const url = 'http://www.cpu.edu.cn/4133/list.htm';
-
- const response = await got({
- method: 'get',
- url,
- headers: {
- Referer: 'http://www.cpu.edu.cn',
- },
- });
-
- const data = response.data;
- const $ = cheerio.load(data);
-
- const $list = $('div#wp_news_w3 a').get();
-
- const resultItem = await Promise.all(
- $list.map(async (item) => {
- const title = $(item).attr('title');
- const href = $(item).attr('href');
- const detail_url = href.startsWith('/') ? `http://www.cpu.edu.cn${href}` : href;
- const single = {
- title,
- link: detail_url,
- description: '',
- };
- const detail = await got({
- method: 'get',
- url: detail_url,
- headers: {
- Referer: 'http://www.cpu.edu.cn',
- },
- });
- {
- const detail_data = detail.data;
- const $ = cheerio.load(detail_data);
- single.description = $('table[bgcolor="#FFFFFF"]').html() || $('table.nyxx').html() || $('div.inner div.article').html();
- }
- return single;
- })
- );
-
- ctx.state.data = {
- title: '中国药科大学 | 最新公告',
- link: url,
- item: resultItem,
- description: '中国药科大学 | 最新公告',
- };
-};
diff --git a/lib/routes-deprecated/universities/cpu/jwc.js b/lib/routes-deprecated/universities/cpu/jwc.js
deleted file mode 100644
index 37fd06581bb4..000000000000
--- a/lib/routes-deprecated/universities/cpu/jwc.js
+++ /dev/null
@@ -1,52 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const url = 'http://jwc.cpu.edu.cn/851/list.htm';
-
- const response = await got({
- method: 'get',
- url,
- headers: {
- Referer: 'http://jwc.cpu.edu.cn',
- },
- });
-
- const data = response.data;
- const $ = cheerio.load(data);
-
- const $list = $('div#wp_news_w6 ul.news_list li a').slice(0, 10).get();
-
- const resultItem = await Promise.all(
- $list.map(async (item) => {
- const title = $(item).attr('title');
- const href = $(item).attr('href');
- const detail_url = 'http://jwc.cpu.edu.cn' + href;
- const single = {
- title,
- link: detail_url,
- description: '',
- };
- const detail = await got({
- method: 'get',
- url: detail_url,
- headers: {
- Referer: 'http://jwc.cpu.edu.cn',
- },
- });
- {
- const detail_data = detail.data;
- const $ = cheerio.load(detail_data);
- single.description = $('div.article').html();
- }
- return single;
- })
- );
-
- ctx.state.data = {
- title: '中国药科大学 - 教务处 | 最新通知',
- link: url,
- item: resultItem,
- description: '中国药科大学 | 教务处',
- };
-};
diff --git a/lib/routes-deprecated/universities/cpu/yjsy.js b/lib/routes-deprecated/universities/cpu/yjsy.js
deleted file mode 100644
index 0f5f4f56ff52..000000000000
--- a/lib/routes-deprecated/universities/cpu/yjsy.js
+++ /dev/null
@@ -1,52 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const url = 'http://yjsy.cpu.edu.cn/6335/list.htm';
-
- const response = await got({
- method: 'get',
- url,
- headers: {
- Referer: 'http://yjsy.cpu.edu.cn',
- },
- });
-
- const data = response.data;
- const $ = cheerio.load(data);
-
- const $list = $('div.listbox tbody td a').slice(0, 10).get();
-
- const resultItem = await Promise.all(
- $list.map(async (item) => {
- const title = $(item).attr('title');
- const href = $(item).attr('href');
- const detail_url = 'http://yjsy.cpu.edu.cn' + href;
- const single = {
- title,
- link: detail_url,
- description: '',
- };
- const detail = await got({
- method: 'get',
- url: detail_url,
- headers: {
- Referer: 'http://yjsy.cpu.edu.cn',
- },
- });
- {
- const detail_data = detail.data;
- const $ = cheerio.load(detail_data);
- single.description = $('div#content2').html();
- }
- return single;
- })
- );
-
- ctx.state.data = {
- title: '中国药科大学 - 研究生院 | 最新通知',
- link: url,
- item: resultItem,
- description: '中国药科大学 | 研究生院',
- };
-};
diff --git a/lib/routes-deprecated/universities/cqu/jwc/announcement.js b/lib/routes-deprecated/universities/cqu/jwc/announcement.js
deleted file mode 100644
index 7e2ddcd7e3fa..000000000000
--- a/lib/routes-deprecated/universities/cqu/jwc/announcement.js
+++ /dev/null
@@ -1,53 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const category = ctx.params.path || 'index/tzgg';
- const baseUrl = `http://jwc.cqu.edu.cn/${category.replace(/[^/]*$/, '')}`;
- const url = `http://jwc.cqu.edu.cn/${category}.htm`;
- const response = await got({
- method: 'get',
- url,
- });
- const { parseDate } = require('@/utils/parse-date');
- const $ = cheerio.load(response.data);
- const links = $('li.pot-r', 'div.page-contner.fl')
- .map((index, item) => {
- item = $(item);
- const a = item.find('a.no-wrap')[0];
- return {
- date: parseDate(item.find('span.fr').text(), 'YYYY-MM-DD'),
- title: a.attribs.title,
- link: baseUrl + a.attribs.href,
- };
- })
- .get();
- const items = await Promise.all(
- links.map(async ({ date, title, link }) => {
- const item = {
- title,
- link,
- pubDate: date,
- };
- const cache = await ctx.cache.get(link);
- if (cache) {
- return JSON.parse(cache);
- }
- const response = await got({
- method: 'get',
- url: link,
- });
-
- const content = cheerio.load(response.data)('div#vsb_content', 'form[name=_newscontent_fromname]');
- item.description = content.find('div.v_news_content').html();
- ctx.cache.set(item.link, item);
- return item;
- })
- );
- ctx.state.data = {
- title: $('title').text(),
- link: url,
- description: $.title,
- item: items.filter(Boolean),
- };
-};
diff --git a/lib/routes-deprecated/universities/cqu/net/info.js b/lib/routes-deprecated/universities/cqu/net/info.js
deleted file mode 100644
index 489faaf7c473..000000000000
--- a/lib/routes-deprecated/universities/cqu/net/info.js
+++ /dev/null
@@ -1,60 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const category = ctx.params.category;
-
- const baseUrl = `http://net.cqu.edu.cn/index/`;
- const url = `http://net.cqu.edu.cn/index/${category}.htm`;
- const response = await got({
- method: 'get',
- url,
- });
-
- const data = response.data;
- const $ = cheerio.load(data);
-
- const links = $('li[id]', 'div[class=index]')
- .find('p[class=detail]', 'a[href]')
- .map((index, item) => {
- item = $(item);
- return {
- title: item.text(),
- link: baseUrl + item.parent().attr('href'),
- };
- })
- .get();
-
- const items = await Promise.all(
- [...links].map(async ({ title, link }) => {
- const item = {
- title,
- link,
- };
- const cache = await ctx.cache.get(link);
- if (cache) {
- return JSON.parse(cache);
- }
- const response = await got({
- method: 'get',
- url: link,
- });
- const newsContent = cheerio.load(response.data)('form[name=_newscontent_fromname]');
- const dateP = newsContent.find('h1', 'div[class=cont]').nextAll().filter('p');
-
- const date = dateP.text().match(/日期:(\d{4})年(\d\d)月(\d\d)日/);
- item.pubDate = `${date[1]}-${date[2]}-${date[3]}T00:00+08:00`;
- item.description = newsContent.find('div[class=v_news_content]', 'div[class=contentd]').html();
-
- ctx.cache.set(item.link, JSON.stringify(item));
- return item;
- })
- );
-
- ctx.state.data = {
- title: $('title').text(),
- link: url,
- description: $.title,
- item: items.filter(Boolean),
- };
-};
diff --git a/lib/routes-deprecated/universities/cqu/news/jzyg.js b/lib/routes-deprecated/universities/cqu/news/jzyg.js
deleted file mode 100644
index c9a5bd8d5264..000000000000
--- a/lib/routes-deprecated/universities/cqu/news/jzyg.js
+++ /dev/null
@@ -1,23 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const util = require('./utils');
-
-module.exports = async (ctx) => {
- const response = await got({
- method: 'get',
- url: 'http://news.cqu.edu.cn/newsv2/info-24.html',
- });
-
- const data = response.data;
- const $ = cheerio.load(data);
- const list = $('.item').get();
-
- const result = await util.ProcessFeed(list, ctx.cache);
-
- ctx.state.data = {
- title: '重庆大学新闻网-讲座预告',
- link: 'http://news.cqu.edu.cn/newsv2/info-24.html',
- description: '重庆大学新闻网-讲座预告',
- item: result,
- };
-};
diff --git a/lib/routes-deprecated/universities/cqu/news/tz.js b/lib/routes-deprecated/universities/cqu/news/tz.js
deleted file mode 100644
index 53b22df63103..000000000000
--- a/lib/routes-deprecated/universities/cqu/news/tz.js
+++ /dev/null
@@ -1,71 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- // const category = ctx.params.category;
-
- const baseUrl = 'https://news.cqu.edu.cn/';
- const url = 'https://news.cqu.edu.cn/newsv2/list-18.html';
- const response = await got({
- method: 'get',
- url,
- });
-
- const data = response.data;
- const $ = cheerio.load(data);
- const nowDate = new Date(new Date().toLocaleString('en-US', { timeZone: 'Asia/Shanghai' }));
- const links = $('div[class=lists]', 'div[class="container newslist"]')
- .find('div[class="content w100"]', 'div[class="item"]')
- .map((index, item) => {
- item = $(item);
- const a = item.find('a[href]');
- const dateText = item.find('div[class=rdate]').text().trim();
- const month = dateText.slice(0, 2);
- const day = dateText.slice(2, 4);
- const year = String((Number(month) === nowDate.getMonth() + 1 && Number(day) <= nowDate.getDate()) || Number(month) < nowDate.getMonth() + 1 ? nowDate.getFullYear() : nowDate.getFullYear() - 1);
- return {
- title: a.text(),
- link: a.attr('href'),
- pubDate: `${year}-${month}-${day}T00:00+08:00`,
- };
- })
- .get();
-
- const items = await Promise.all(
- [...links].map(async ({ title, link, pubDate }) => {
- const item = {
- title,
- link,
- pubDate,
- };
- const cache = await ctx.cache.get(link);
- if (cache) {
- return JSON.parse(cache);
- }
- const response = await got({
- method: 'get',
- url: baseUrl + link,
- });
- const $ = cheerio.load(response.data);
- const newsContent = $('div[class=content]', 'div[class="container detail"]');
-
- item.description = newsContent.find('div[class=acontent]').html();
-
- const authorStrings = newsContent
- .find('p', 'div[class=dinfoa]')
- .find('a[href="javascript:;"]')
- .map((index, item) => $(item).text());
- item.author = `${authorStrings[0]}-${authorStrings[1]}`;
-
- ctx.cache.set(item.link, JSON.stringify(item));
- return item;
- })
- );
-
- ctx.state.data = {
- title: $('title').text(),
- link: url,
- description: $.title,
- item: items.filter(Boolean),
- };
-};
diff --git a/lib/routes-deprecated/universities/cqu/news/utils.js b/lib/routes-deprecated/universities/cqu/news/utils.js
deleted file mode 100644
index 9a8566c2ee34..000000000000
--- a/lib/routes-deprecated/universities/cqu/news/utils.js
+++ /dev/null
@@ -1,48 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-// 加载文章页
-async function load(link) {
- const response = await got.get(link);
- const $ = cheerio.load(response.data);
-
- // 提取内容
- const description = $('.dinfo').html() + $('.acontent').html();
-
- return { description };
-}
-
-const ProcessFeed = (list, caches) =>
- Promise.all(
- list.map(async (item) => {
- const $ = cheerio.load(item);
-
- const $title1 = $('.title a').eq(0);
- const $title2 = $('.title a').eq(1);
- let itemUrl = $title2.attr('href');
- let title = $title1.text() + ' - ' + $title2.text();
-
- if (itemUrl === undefined) {
- itemUrl = $title1.attr('href');
- title = $title1.text();
- }
-
- // 列表上提取到的信息
- const single = {
- title,
- link: itemUrl,
- guid: itemUrl,
- };
-
- // 使用tryGet方法从缓存获取内容。
- // 当缓存中无法获取到链接内容的时候,则使用load方法加载文章内容。
- const other = await caches.tryGet(itemUrl, () => load(itemUrl));
-
- // 合并解析后的结果集作为该篇文章最终的输出结果
- return Object.assign({}, single, other);
- })
- );
-
-module.exports = {
- ProcessFeed,
-};
diff --git a/lib/routes-deprecated/universities/cqu/sci/info.js b/lib/routes-deprecated/universities/cqu/sci/info.js
deleted file mode 100644
index faaf05800c7d..000000000000
--- a/lib/routes-deprecated/universities/cqu/sci/info.js
+++ /dev/null
@@ -1,62 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const category = ctx.params.category;
-
- const baseUrl = 'http://sci.cqu.edu.cn/';
- const url = `http://sci.cqu.edu.cn/list.jsp?urltype=tree.TreeTempUrl&wbtreeid=${category}`;
- const response = await got({
- method: 'get',
- url,
- });
-
- const data = response.data;
- const $ = cheerio.load(data);
-
- const links = $('div[class=subcontent]')
- .find('a[target=_blank]', 'ul[class=subNewsList]')
- .map((index, item) => ({
- title: item.attribs.title,
- link: baseUrl + item.attribs.href,
- }))
- .get();
-
- const items = await Promise.all(
- [...links].map(async ({ title, link }) => {
- const item = {
- title,
- link,
- };
- const cache = await ctx.cache.get(link);
- if (cache) {
- return JSON.parse(cache);
- }
- const response = await got({
- method: 'get',
- url: link,
- });
- const newsContent = cheerio.load(response.data)('form[name=_newscontent_fromname]');
-
- const [dateText] = newsContent
- .find('div[align=center]')
- .text()
- .split(/\u00A0+/, 1); // \xA0+:
-
- item.pubDate = dateText.replace(/ /, 'T') + '+08:00';
- const newsText = newsContent.find('div[class=v_news_content]');
- const attedText = newsText.parent().nextAll().filter('ul[style="list-style-type:none;"]');
- item.description = newsText.html() + (newsContent.html(attedText).html() || '');
-
- ctx.cache.set(item.link, JSON.stringify(item));
- return item;
- })
- );
-
- ctx.state.data = {
- title: $('title').text(),
- link: url,
- description: $.title,
- item: items.filter(Boolean),
- };
-};
diff --git a/lib/routes-deprecated/universities/cqu/youth/info.js b/lib/routes-deprecated/universities/cqu/youth/info.js
deleted file mode 100644
index b37614b5bfed..000000000000
--- a/lib/routes-deprecated/universities/cqu/youth/info.js
+++ /dev/null
@@ -1,65 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const category = ctx.params.category;
-
- const baseUrl = 'http://youth.cqu.edu.cn/index/';
- const url = `http://youth.cqu.edu.cn/index/${category}.htm`;
- const response = await got({
- method: 'get',
- url,
- });
-
- const data = response.data;
- const $ = cheerio.load(data);
-
- const links = $('div[class=nwes_list]') // nwes_list 原文如此
- .find('a[target=_blank]', 'ul[style]')
- .map((index, item) => ({
- title: item.attribs.title,
- link: baseUrl + item.attribs.href,
- }))
- .get();
-
- const items = await Promise.all(
- [...links].map(async ({ title, link }) => {
- const item = {
- title,
- link,
- };
- const cache = await ctx.cache.get(link);
- if (cache) {
- return JSON.parse(cache);
- }
- const response = await got({
- method: 'get',
- url: link,
- });
- const newsContent = cheerio.load(response.data)('form[name=_newscontent_fromname]');
-
- const [dateText, authorText] = newsContent
- .find('div[align=center]')
- .text()
- .split(/\u00A0+/, 2); // \xA0+:
-
- item.pubDate = dateText.replace(/ /, 'T') + '+08:00';
- if (authorText && authorText.slice(0, 4) === '拟稿人:') {
- item.author = authorText.slice(4);
- }
- const newsText = newsContent.find('div[class=v_news_content]');
- const attedText = newsText.parent().nextAll().filter('ul[style="list-style-type:none;"]');
- item.description = newsText.html() + (newsContent.html(attedText).html() || '');
-
- ctx.cache.set(item.link, JSON.stringify(item));
- return item;
- })
- );
-
- ctx.state.data = {
- title: $('title').text(),
- link: url,
- description: $.title,
- item: items.filter(Boolean),
- };
-};
diff --git a/lib/routes-deprecated/universities/cqust/jw.js b/lib/routes-deprecated/universities/cqust/jw.js
deleted file mode 100644
index 4ec8ddf9a0ad..000000000000
--- a/lib/routes-deprecated/universities/cqust/jw.js
+++ /dev/null
@@ -1,36 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const url = require('url').resolve;
-
-const host = 'http://jw.cqust.edu.cn';
-const map = {
- notify: '/tzgg/tz.htm',
- news: '/xwdt/xxyw.htm',
-};
-
-module.exports = async (ctx) => {
- const type = ctx.params.type || 'notify';
- const link = host + map[type];
- const response = await got.get(link);
- const $ = cheerio.load(response.data);
- const list = $('li[id^="lineu"]').slice(0, 10);
-
- ctx.state.data = {
- title: '重科教务处',
- link,
- description: $('meta[name="description"]').attr('content') || '重科教务处',
- item:
- list &&
- list
- .map((index, item) => {
- item = $(item);
- return {
- title: item.find('a').text(),
- description: item.find('p').text() + ' [...]',
- pubDate: new Date(item.find('.shijian').text().replace('》', '')).toUTCString(),
- link: url(host, item.find('a').attr('href')),
- };
- })
- .get(),
- };
-};
diff --git a/lib/routes-deprecated/universities/cqust/lib.js b/lib/routes-deprecated/universities/cqust/lib.js
deleted file mode 100644
index bf2082a0c05c..000000000000
--- a/lib/routes-deprecated/universities/cqust/lib.js
+++ /dev/null
@@ -1,39 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const url = require('url').resolve;
-
-const host = 'http://lib.cqust.edu.cn';
-const map = {
- news: '/node/410.jspx',
-};
-
-module.exports = async (ctx) => {
- const type = ctx.params.type || 'news';
- const link = host + map[type];
- const response = await got.get(link, {
- headers: {
- Cookie: 'JSESSIONID=' + Math.random(),
- },
- });
- const $ = cheerio.load(response.data);
- const list = $('div[class="newsList"]').find('li').slice(0, 10);
-
- ctx.state.data = {
- title: '重科图书馆',
- link,
- description: $('meta[name="description"]').attr('content') || '重科图书馆公告',
- item:
- list &&
- list
- .map((index, item) => {
- item = $(item);
- return {
- title: item.find('a').text(),
- description: '重科图书馆公告',
- pubDate: new Date(item.find('span[class="time"]').text()).toUTCString(),
- link: url(host, item.find('a').attr('href')),
- };
- })
- .get(),
- };
-};
diff --git a/lib/routes-deprecated/universities/cqut/cqut-libnews.js b/lib/routes-deprecated/universities/cqut/cqut-libnews.js
deleted file mode 100644
index deb42f135faf..000000000000
--- a/lib/routes-deprecated/universities/cqut/cqut-libnews.js
+++ /dev/null
@@ -1,32 +0,0 @@
-const cheerio = require('cheerio');
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- const response = await got({
- method: 'get',
- url: 'https://libnews.cqut.edu.cn/',
- });
-
- const data = response.data;
-
- const $ = cheerio.load(data); // 使用 cheerio 加载返回的 HTML
- const list = $('#infoList').find('div');
-
- ctx.state.data = {
- title: '重庆理工大学中山图书馆资讯',
- link: 'https://libnews.cqut.edu.cn',
- item:
- list &&
- list
- .map((index, item) => {
- item = $(item);
- return {
- title: item.find('a').text().trim(),
- description: item.find('a').text().trim(),
- link: item.find('a').attr('href'),
- pubDate: new Date(item.find('span').text().trim().slice(1, -1)).toUTCString(),
- };
- })
- .get(),
- };
-};
diff --git a/lib/routes-deprecated/universities/cqut/cqut-news.js b/lib/routes-deprecated/universities/cqut/cqut-news.js
deleted file mode 100644
index f25eae78666c..000000000000
--- a/lib/routes-deprecated/universities/cqut/cqut-news.js
+++ /dev/null
@@ -1,31 +0,0 @@
-const cheerio = require('cheerio');
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- const response = await got({
- method: 'get',
- url: 'https://tz.cqut.edu.cn/',
- });
-
- const data = response.data;
- const $ = cheerio.load(data); // 使用 cheerio 加载返回的 HTML
- const list = $('#container').find('.record');
-
- ctx.state.data = {
- title: 'CQUT',
- link: 'https://tz.cqut.edu.cn/',
- item:
- list &&
- list
- .map((index, item) => {
- item = $(item);
- return {
- title: item.find('a').attr('title'),
- description: item.find('a').attr('title'),
- link: item.find('a').attr('href'),
- pubDate: new Date(item.find('.date').text().trim()).toUTCString(),
- };
- })
- .get(),
- };
-};
diff --git a/lib/routes-deprecated/universities/cug/gcxy/index.js b/lib/routes-deprecated/universities/cug/gcxy/index.js
deleted file mode 100644
index 2b3a5a452908..000000000000
--- a/lib/routes-deprecated/universities/cug/gcxy/index.js
+++ /dev/null
@@ -1,114 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const host = 'http://gcxy.cug.edu.cn';
-
- const typeUrl = [
- {
- name: '所有',
- url: '',
- },
- {
- name: '学院新闻',
- url: '/index/xyxw.htm',
- },
- {
- name: '通知公告',
- url: '/index/tzgg.htm',
- },
- {
- name: '党建工作',
- url: '/index/djgz.htm',
- },
- {
- name: '学术动态',
- url: '/index/xsdt.htm',
- },
- {
- name: '本科生教育',
- url: '/index/bksjy.htm',
- },
- {
- name: '研究生教育',
- url: '/index/yjsjy.htm',
- },
- {
- name: '教工之家',
- url: '/index/jgzj.htm',
- },
- ];
-
- let type = ctx.params && ctx.params.type;
- if (type === undefined) {
- type = 0;
- } else {
- type = Number(type);
- if (type >= typeUrl.length) {
- return false;
- }
- }
-
- let typeList = [];
-
- if (type === 0) {
- // 获取所有的
- typeList = Object.keys(Array.apply(null, { length: typeUrl.length }));
- } else {
- typeList.push(type);
- }
-
- // console.log(typeList);
-
- const getItems = async function (url) {
- try {
- const response = await got({
- method: 'get',
- url: host + url,
- headers: {
- Referer: host,
- },
- });
- const $ = cheerio.load(response.data);
- const items = $('div.right_list > ul > li');
- return Promise.all(
- items
- .map(async (index, item) => {
- item = $(item);
- const a = item.find('a');
- const link = host + a.attr('href').replace('..', '');
- // console.log(link);
- return {
- title: a.attr('title'),
- link,
- description: await got({
- method: 'get',
- url: link,
- headers: {
- Referer: host,
- },
- })
- .then((res) => {
- const $ = cheerio.load(res.data);
- return $('.v_news_content').html();
- })
- .catch(() => ''),
- pubDate: item.find('span').text(),
- };
- })
- .get()
- );
- } catch {
- return [];
- }
- };
-
- const outList = await Promise.all(typeList.map((t) => getItems(typeUrl[t].url)));
-
- ctx.state.data = {
- title: '[' + typeUrl[type].name + ']' + 'CUG-工程学院',
- link: host + typeUrl[type].url,
- description: '中国地质大学(武汉)工程学院-' + typeUrl[type].name,
- item: outList.reduce((p, n) => [...p, ...n]),
- };
-};
diff --git a/lib/routes-deprecated/universities/cug/graduate.js b/lib/routes-deprecated/universities/cug/graduate.js
deleted file mode 100644
index 40b5545bf327..000000000000
--- a/lib/routes-deprecated/universities/cug/graduate.js
+++ /dev/null
@@ -1,46 +0,0 @@
-const cheerio = require('cheerio');
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- const baseUrl = 'http://graduate.cug.edu.cn';
- const reqUrl = `${baseUrl}/zhtzgg.htm`;
- const res = await got(reqUrl);
- const selector = 'div.mainWrap > div.main_con > div.main_conR.main_conRa > div.main_conRCb > ul > li';
- const links = cheerio
- .load(res.data)(selector)
- .map((_, ele) => {
- const $item = cheerio.load(ele);
- const link = `${baseUrl}/${$item('a').attr('href')}`;
- return link;
- })
- .get();
- const item = await Promise.all(
- links.map((link) =>
- ctx.cache.tryGet(`cug/${link}`, async () => {
- const res = await got(link);
- const $ = cheerio.load(res.data);
- const mainNode = $('.main_content');
- const description = mainNode.find('.main_conDiv').html();
- const title = mainNode.find('.main_contit h2').text();
- const pubTime = mainNode
- .find('.main_contit p')
- .text()
- .split(' ')
- .find((s) => s.includes('时间'))
- .replace('时间:', '');
- return {
- title,
- description,
- pubDate: new Date(pubTime).toUTCString(),
- };
- })
- )
- );
-
- ctx.state.data = {
- title: '中国地址大学(武汉)研究生院 - 综合通知公告',
- description: '中国地址大学(武汉)研究生院 - 综合通知公告',
- link: `${baseUrl}/zhtzgg.htm`,
- item,
- };
-};
diff --git a/lib/routes-deprecated/universities/cug/news.js b/lib/routes-deprecated/universities/cug/news.js
deleted file mode 100644
index 7d9f2ce1dbdf..000000000000
--- a/lib/routes-deprecated/universities/cug/news.js
+++ /dev/null
@@ -1,63 +0,0 @@
-const cheerio = require('cheerio');
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- // 发起 HTTP GET 请求
-
- const host = 'http://xxhb.cug.edu.cn/zqxt/zqjsjg.jsp?wbtreeid=1283&selectType=1&searchScope=0';
-
- const response = await got({
- method: 'get',
- url: host,
- });
-
- const data = response.data;
-
- const $ = cheerio.load(data);
- const list = $('form[id=searchlistform1] > table.listFrame > tbody > tr > td');
- const results = [];
- let item = {};
- for (const element of list) {
- const d = $(element);
- d.find('i').remove();
- const title = d.find('span.titlefontstyle206274');
- const from = d.find('span.sourcesitefontstyle206274');
- const description = d.find('span.contentfontstyle206274');
- const time = d.find('span.timefontstyle206274');
-
- if (title.length) {
- item.title = from.text() + title.text();
- item.link = d.find('a').attr('href');
- } else if (description.length) {
- item.description = item.description ? item.description + d.text() : d.text();
- } else if (time.length) {
- item.pubDate = new Date(time.text().replace('发表时间:', '').replace('年', '-').replace('月', '-').replace('日', '')).toUTCString();
- results.push(item);
- item = {};
- }
- }
-
- let out = await Promise.all(
- results.map(async (element) => {
- const link = element.link;
- try {
- const result = await got.get(link);
- const $ = cheerio.load(result.data);
- element.description = $('.v_news_content').html();
- element.enabled = true;
- } catch {
- element.enabled = false;
- }
- return element;
- })
- );
-
- out = out.filter((item) => item.enabled === true);
-
- ctx.state.data = {
- title: 'CUG-今日文章',
- link: host,
- description: '中国地质大学(武汉) 每日文章,几乎包含全校站点最新信息。',
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/universities/cug/undergraduate.js b/lib/routes-deprecated/universities/cug/undergraduate.js
deleted file mode 100644
index 360e1ed3373c..000000000000
--- a/lib/routes-deprecated/universities/cug/undergraduate.js
+++ /dev/null
@@ -1,86 +0,0 @@
-const cheerio = require('cheerio');
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- // 发起 HTTP GET 请求
-
- const baseUrl = 'http://www.cug.edu.cn/index/tzgg.htm';
-
- const response = await got({
- method: 'get',
- url: baseUrl,
- });
-
- const data = response.data;
-
- const $ = cheerio.load(data);
- const list = $('#container > div > div > div.col-news > div.col-news-con > ul > li');
-
- const out = await Promise.all(
- list
- .map(async (index, element) => {
- element = $(element);
- const link = element.find('a').attr('href');
- const description = await ctx.cache.tryGet(link, async () => {
- const result = await got.get(link[0] === '.' ? `${baseUrl}/../${link}` : link);
- const $ = cheerio.load(result.data);
- return $('.read').html();
- });
- const item = {
- title: element.find('a').text(),
- link,
- pubDate: new Date(element.find('span').text().replace('年', '-').replace('月', '-').replace('日', '')).toUTCString(),
- description,
- };
- return item;
- })
- .get()
- );
-
- ctx.state.data = {
- title: '中国地质大学(武汉) - 综合通知公告',
- link: baseUrl,
- item: out,
- };
-
- /*
-
- async function getDescription(_link) {
- try {
- const response = await got({
- method: 'get',
- url: _link[0] === '.' ? `${baseUrl}/../${_link}` : _link,
- });
- const data = response.data;
- const $ = cheerio.load(data);
- return $('.read span').text();
- } catch (e) {
- return '未取到数据';
- }
- }
-
- const descriptionPromises = list.map((index, item) => getDescription($(item).find('a').attr('href'))).get();
-
- const descriptions = await Promise.all(descriptionPromises);
-
- ctx.state.data = {
- title: '中国地质大学(武汉) - 综合通知公告',
- link: baseUrl,
- item:
- list &&
- list
- .map((index, item) => {
- item = $(item);
- const _link = item.find('a').attr('href');
- return {
- title: item.find('a').text(),
- link: _link,
- pubDate: new Date(item.find('span').text().replace('年', '-').replace('月', '-').replace('日', '')).toUTCString(),
- description: descriptions[index],
- };
- })
- .get(),
- };
-
- */
-};
diff --git a/lib/routes-deprecated/universities/cug/xgxy.js b/lib/routes-deprecated/universities/cug/xgxy.js
deleted file mode 100644
index ebb9228c3bd2..000000000000
--- a/lib/routes-deprecated/universities/cug/xgxy.js
+++ /dev/null
@@ -1,35 +0,0 @@
-const cheerio = require('cheerio');
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- // 发起 HTTP GET 请求
-
- const baseUrl = 'http://xgxy.cug.edu.cn/index/tzgg.htm';
-
- const response = await got({
- method: 'get',
- url: baseUrl,
- });
-
- const data = response.data;
-
- const $ = cheerio.load(data);
- const list = $('#content > section.section.full-width-bg.gray-bg > div > div > div > ul > li');
-
- ctx.state.data = {
- title: '中国地质大学(武汉)地理与信息工程学院 - 综合通知公告',
- link: baseUrl,
- item:
- list &&
- list
- .map((index, item) => {
- item = $(item);
- return {
- title: item.find('a').text(),
- link: item.find('a').attr('href'),
- pubDate: new Date(item.find('span').text().replace('年', '-').replace('月', '-').replace('日', '')).toUTCString(),
- };
- })
- .get(),
- };
-};
diff --git a/lib/routes-deprecated/universities/cuit/cxxww.js b/lib/routes-deprecated/universities/cuit/cxxww.js
deleted file mode 100644
index 8943f0acfea2..000000000000
--- a/lib/routes-deprecated/universities/cuit/cxxww.js
+++ /dev/null
@@ -1,63 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const url = require('url');
-
-const host = 'https://www.cuit.edu.cn/';
-
-module.exports = async (ctx) => {
- const type = ctx.params.type || '1';
- const link = host + 'NewsList?id=' + type;
-
- const response = await got.get(link);
- const $ = cheerio.load(response.data);
-
- const list = $('.news1-links-ul a')
- .slice(0, 10)
- .map((i, e) => $(e).attr('href'))
- .get();
-
- const out = await Promise.all(
- list.map(async (itemUrl) => {
- // list item is itemUrl
- itemUrl = url.resolve(host, itemUrl);
- const cache = await ctx.cache.get(itemUrl);
- if (cache) {
- return JSON.parse(cache);
- }
-
- const response = await got.get(itemUrl);
- const $ = cheerio.load(response.data);
-
- let contentUrl = $('#NewsContent').attr('src');
- contentUrl = url.resolve(host, contentUrl);
- const response_content = await got.get(contentUrl);
- const $$ = cheerio.load(response_content.data);
- const time = $('#NewsAuthor').text().indexOf('日期:') + 3;
- const name = $('#NewsAuthor').text().indexOf('作者:') + 3;
-
- const single = {
- title: $('.news-content-title-text').text(),
- link: itemUrl,
- author: $('#NewsAuthor')
- .text()
- .substring(name, name + 3),
- description: $$('body').html(),
- pubDate: new Date(
- $('#NewsAuthor')
- .text()
- .substring(time, time + 10)
- .replace('/', '-')
- .replace('/', '-')
- ).toUTCString(),
- };
- ctx.cache.set(itemUrl, JSON.stringify(single)); //
- return single;
- })
- );
-
- ctx.state.data = {
- title: $('#NewsTypeName').text(),
- link,
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/universities/dgut/jwc.js b/lib/routes-deprecated/universities/dgut/jwc.js
deleted file mode 100644
index dc2f5fe38138..000000000000
--- a/lib/routes-deprecated/universities/dgut/jwc.js
+++ /dev/null
@@ -1,54 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const base_host = 'http://jwc.dgut.edu.cn/';
- const host = base_host + 'dglgjwc/';
- const name = '教务处';
- const type = ctx.params.type;
- let info, url_type;
- switch (type) {
- case '1':
- info = '教务公告';
- url_type = 'jwgg';
- break;
- case '2':
- info = '教学信息';
- url_type = 'jxxx';
- break;
- default:
- info = '教学信息';
- url_type = 'jxxx';
- }
-
- const response = await got({
- method: 'get',
- url: host + url_type + '/list.shtml',
- headers: {
- Referer: base_host,
- },
- });
-
- const $ = cheerio.load(response.data);
- const text = $('div.con-right').find('div.list_div').slice(0, 10);
-
- ctx.state.data = {
- title: `东莞理工学院 ${name} ${info}`,
- link: host + url_type + '/list.shtml',
- description: `东莞理工学院 ${name} ${info}`,
- item:
- text &&
- text
- .map((index, item) => {
- item = $(item);
- return {
- title: item.find('a').text(),
- description: item.find('a').text(),
- category: item.find('.column-name').text(),
- pubDate: $('td[align="left"]', item).slice(5).text().trim(),
- link: host + item.find('a').attr('href').slice(1),
- };
- })
- .get(),
- };
-};
diff --git a/lib/routes-deprecated/universities/dgut/xsc.js b/lib/routes-deprecated/universities/dgut/xsc.js
deleted file mode 100644
index 919cdba744f4..000000000000
--- a/lib/routes-deprecated/universities/dgut/xsc.js
+++ /dev/null
@@ -1,56 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const host = 'http://xsc.dgut.edu.cn/';
- const name = '学生工作部(学生处)';
- const type = ctx.params.type;
- let info, url_type;
- switch (type) {
- case '1':
- info = '学工动态';
- url_type = 'bgfw/xgdt';
- break;
- case '2':
- info = '通知公告';
- url_type = 'bgfw/tzgg';
- break;
- case '4':
- info = '网上公示';
- url_type = 'bgfw/wsgs';
- break;
- default:
- info = '通知公告';
- url_type = 'bgfw/tzgg';
- }
-
- const response = await got({
- method: 'get',
- url: host + url_type + '/',
- headers: {
- Referer: host,
- },
- });
-
- const $ = cheerio.load(response.data);
- const text = $('#paging > ul').find('li').slice(0, 10);
-
- ctx.state.data = {
- title: `东莞理工学院 ${name} ${info}`,
- link: host + url_type + '/index.shtml',
- description: `东莞理工学院 ${name} ${info}`,
- item:
- text &&
- text
- .map((index, item) => {
- item = $(item);
- return {
- title: item.find('a').attr('title'),
- description: item.find('a').text(),
- pubDate: item.find('.time').text(),
- link: host + item.find('a').attr('href').slice(1),
- };
- })
- .get(),
- };
-};
diff --git a/lib/routes-deprecated/universities/dlmu/grs/zsgz.js b/lib/routes-deprecated/universities/dlmu/grs/zsgz.js
deleted file mode 100644
index 481298cc1996..000000000000
--- a/lib/routes-deprecated/universities/dlmu/grs/zsgz.js
+++ /dev/null
@@ -1,34 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const link = `http://grs.dlmu.edu.cn/zsgz/${ctx.params.type}.htm`;
- const response = await got({ method: 'get', url: link });
-
- const $ = cheerio.load(response.data);
- const list = $('div.main_conRCb ul li')
- .map((_, item) => {
- const a = $(item).find('a');
- return {
- title: a.text(),
- link: `http://grs.dlmu.edu.cn/` + a.attr('href').replace('..', ''),
- pubDate: new Date($(item).find('span').text() + ' GMT+8').toUTCString(),
- };
- })
- .get();
-
- ctx.state.data = {
- title: $('title').text(),
- link,
- item: await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({ method: 'get', url: item.link });
- const content = cheerio.load(detailResponse.data);
- item.description = content('div.main_conDiv').html();
- return item;
- })
- )
- ),
- };
-};
diff --git a/lib/routes-deprecated/universities/dlmu/news.js b/lib/routes-deprecated/universities/dlmu/news.js
deleted file mode 100644
index ad6d25e05ce3..000000000000
--- a/lib/routes-deprecated/universities/dlmu/news.js
+++ /dev/null
@@ -1,42 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const resolve_url = require('url').resolve;
-
-const base_url = 'http://news.dlmu.edu.cn';
-
-const map = {
- hdyw: '/hdyw.htm',
- mthd: '/mthd.htm',
- zhxw: '/zhxw.htm',
- yxfc: '/yxfc.htm',
- hdxb: '/hdxb.htm',
- llyd: '/llyd.htm',
- hdjt: '/hdjt.htm',
- ywhc: '/ywhc.htm',
-};
-module.exports = async (ctx) => {
- const type = ctx.params.type;
- const link = Object.hasOwn(map, type) ? `${base_url}${map[type]}` : `${base_url}/hdyw.htm`;
- const response = await got({
- method: 'get',
- url: link,
- headers: {
- Referer: base_url,
- },
- });
-
- const $ = cheerio.load(response.data);
- ctx.state.data = {
- link: base_url,
- title: '大连海事大学新闻',
- item: $('.n-Box .n-right .n-pic-box .n-news dl')
- .slice(0, 10)
- .map((_, element) => ({
- link: resolve_url(base_url, $('dd a', element).attr('href')),
- title: $('dd a', element).text(),
- description: $('dd p', element).text(),
- pubDate: new Date($('i', element).text().slice(1, -1)),
- }))
- .get(),
- };
-};
diff --git a/lib/routes-deprecated/universities/dlu/jiaowu/news.js b/lib/routes-deprecated/universities/dlu/jiaowu/news.js
deleted file mode 100644
index 45fb0bea957f..000000000000
--- a/lib/routes-deprecated/universities/dlu/jiaowu/news.js
+++ /dev/null
@@ -1,36 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const { parseDate } = require('@/utils/parse-date');
-const timezone = require('@/utils/timezone');
-
-const baseUrl = 'http://jwc1.dlu.edu.cn/';
-
-module.exports = async (ctx) => {
- const resp = await got({ url: baseUrl });
- const index = cheerio.load(resp.data);
-
- const items = index('td[valign="top"]>table[cellspacing="3"][width="100%"] tr')
- .toArray()
- .map((elem) => {
- const link = new URL(index('a', elem).attr('href'), baseUrl).href;
- return ctx.cache.tryGet(link, async () => {
- const resp = await got({ url: link });
- const article = cheerio.load(resp.data);
- return {
- link: link.toString(),
- title: index('a', elem).attr('title'),
- pubDate: timezone(parseDate(article('td[height="28"]').text(), 'YYYY年MM月DD日 HH:mm'), +8).toUTCString(),
- description: article('form[name="_newscontent_fromname"] > div > *:not(table)')
- .toArray()
- .map((it) => article(it).html())
- .join('\n'),
- };
- });
- });
-
- ctx.state.data = {
- link: baseUrl,
- title: '大连大学教务处',
- item: await Promise.all(items),
- };
-};
diff --git a/lib/routes-deprecated/universities/dpu/jiaowu/news.js b/lib/routes-deprecated/universities/dpu/jiaowu/news.js
deleted file mode 100644
index ecd906220055..000000000000
--- a/lib/routes-deprecated/universities/dpu/jiaowu/news.js
+++ /dev/null
@@ -1,45 +0,0 @@
-const got = require('@/utils/got');
-const iconv = require('iconv-lite');
-const cheerio = require('cheerio');
-const resolve_url = require('url').resolve;
-
-const base_url = 'http://jiaowu.dlpu.edu.cn';
-
-const map = {
- 2: '/more/2',
- 3: '/more/3',
- 4: '/more/4',
-};
-
-module.exports = async (ctx) => {
- const type = ctx.params.type || '2';
- const link = `${base_url}${map[type]}`;
-
- const response = await got({
- method: 'get',
- url: link,
- responseType: 'buffer',
- headers: {
- Referer: base_url,
- },
- });
-
- const $ = cheerio.load(iconv.decode(response.data, 'gb2312'));
-
- ctx.state.data = {
- link,
- title: $('#more>h1').text(),
- item: $('.more_list>li')
- .slice(0, 10)
- .map((_, elem) => ({
- link: resolve_url(base_url, $('a', elem).attr('href')),
- title: $('a', elem).text(),
- pubDate: new Date(
- $('a>span', elem)
- .text()
- .replace(/.(\d+)年(\d+)月(\d+)日./, '$1-$2-$3')
- ).toUTCString(),
- }))
- .get(),
- };
-};
diff --git a/lib/routes-deprecated/universities/dpu/wlfw/news.js b/lib/routes-deprecated/universities/dpu/wlfw/news.js
deleted file mode 100644
index 25f7b52d9b06..000000000000
--- a/lib/routes-deprecated/universities/dpu/wlfw/news.js
+++ /dev/null
@@ -1,44 +0,0 @@
-const got = require('@/utils/got');
-const iconv = require('iconv-lite');
-const cheerio = require('cheerio');
-const resolve_url = require('url').resolve;
-
-const base_url = 'http://wlfw.dlpu.edu.cn';
-
-const map = {
- 1: '/more/1',
- 2: '/more/2',
-};
-
-module.exports = async (ctx) => {
- const type = ctx.params.type || '1';
- const link = `${base_url}${map[type]}`;
-
- const response = await got({
- method: 'get',
- url: link,
- responseType: 'buffer',
- headers: {
- Referer: base_url,
- },
- });
-
- const $ = cheerio.load(iconv.decode(response.data, 'gb2312'));
-
- ctx.state.data = {
- link,
- title: $('#more>h1').text(),
- item: $('.more_list>li')
- .slice(0, 10)
- .map((_, elem) => ({
- link: resolve_url(base_url, $('a', elem).attr('href')),
- title: $('a', elem).text(),
- pubDate: new Date(
- $('a>span', elem)
- .text()
- .replace(/.(\d+)年(\d+)月(\d+)日./, '$1-$2-$3')
- ).toUTCString(),
- }))
- .get(),
- };
-};
diff --git a/lib/routes-deprecated/universities/fudan/cce.js b/lib/routes-deprecated/universities/fudan/cce.js
deleted file mode 100644
index 664f3f20bd22..000000000000
--- a/lib/routes-deprecated/universities/fudan/cce.js
+++ /dev/null
@@ -1,52 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-const host = 'http://www.cce.fudan.edu.cn';
-const link = 'http://www.cce.fudan.edu.cn/14096/list.htm';
-
-module.exports = async (ctx) => {
- const response = await got({
- method: 'get',
- url: link,
- headers: {
- Referer: host,
- },
- });
-
- const $ = cheerio.load(response.data);
-
- const urlList = $('.Article_Title a')
- .get()
- .map((i) => host + $(i).attr('href'));
-
- const out = await Promise.all(
- urlList.map(async (itemUrl) => {
- const cache = await ctx.cache.get(itemUrl);
- if (cache) {
- return JSON.parse(cache);
- }
- const response = await got.get(itemUrl);
- const $ = cheerio.load(response.data);
- const targetDate = $('.arti_update')
- .text()
- .match(/(\d{4}-\d{2})-\d{2}/);
-
- if (targetDate) {
- const single = {
- title: $('.arti_title').text(),
- link: itemUrl,
- description: $('.wp_articlecontent').html(),
- pubDate: targetDate[0],
- };
- ctx.cache.set(itemUrl, JSON.stringify(single));
- return single;
- }
- })
- );
-
- ctx.state.data = {
- title: '复旦大学继续教育学院 - 通知公告',
- link,
- item: out.filter(Boolean),
- };
-};
diff --git a/lib/routes-deprecated/universities/fzu/news-min.js b/lib/routes-deprecated/universities/fzu/news-min.js
deleted file mode 100644
index 41ff8ce5fceb..000000000000
--- a/lib/routes-deprecated/universities/fzu/news-min.js
+++ /dev/null
@@ -1,44 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-const title_map = {
- jxtz: '教学通知',
- zjjz: '专家讲座',
-};
-const description_map = {
- jxtz: '教学通知',
- zjjz: '嘉锡讲坛/信息素养讲座通知',
-};
-
-module.exports = async (ctx) => {
- const type = ctx.params.type || '';
- const response = await got({
- method: 'get',
- url: `https://jwch.fzu.edu.cn/${type}.htm`,
- });
- const data = response.data; // 获取页面 html 数据
-
- const $ = cheerio.load(data);
- const list = $('ul.list-gl').find('li'); //
地点:${school_name ? `${school_name}-${address}` : address}
类别:${company_property}
行业类别:${industry_category}`,
- link: url.resolve(baseUrl, `/detail/career?id=${career_talk_id}`),
- };
- }),
- };
-};
diff --git a/lib/routes-deprecated/universities/kmust/job/jobfairs.js b/lib/routes-deprecated/universities/kmust/job/jobfairs.js
deleted file mode 100644
index 98d42335cf81..000000000000
--- a/lib/routes-deprecated/universities/kmust/job/jobfairs.js
+++ /dev/null
@@ -1,32 +0,0 @@
-const got = require('@/utils/got');
-const url = require('url');
-
-const baseUrl = 'http://job.kmust.edu.cn';
-
-module.exports = async (ctx) => {
- const title = '双选会-昆明理工大学就业网';
- const pageUrl = url.resolve(baseUrl, `/module/getjobfairs?start_page=1&keyword=&count=20&start=1&_=${Date.now()}`);
- const response = await got({
- method: 'get',
- url: pageUrl,
- headers: {
- Referer: baseUrl,
- },
- });
- const data = response.data || {};
-
- ctx.state.data = {
- title,
- link: url.resolve(baseUrl, '/module/jobfairs'),
- item:
- data.data &&
- data.data.slice(0, 10).map((item) => {
- const { meet_day = '', meet_time = '', title = '', school_name = '', address = '', fair_id = '' } = item;
- return {
- title: `【${meet_day} ${meet_time}】${title}`,
- description: `时间:${meet_day} ${meet_time}
地点:${school_name ? `${school_name}-${address}` : address}`,
- link: url.resolve(baseUrl, `/detail/jobfair?id=${fair_id}`),
- };
- }),
- };
-};
diff --git a/lib/routes-deprecated/universities/kmust/jwc.js b/lib/routes-deprecated/universities/kmust/jwc.js
deleted file mode 100644
index 3a2f5ec1d92e..000000000000
--- a/lib/routes-deprecated/universities/kmust/jwc.js
+++ /dev/null
@@ -1,44 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const url = require('url');
-
-const baseUrl = 'http://jwc.kmust.edu.cn';
-const dataRegex = /20\d{2}(?:\/\d{2}){2}/;
-const typeProps = {
- notify: {
- url: '/html/jwtz/1.html',
- title: '教务通知',
- },
- news: {
- url: '/html/jwxw/1.html',
- title: '教务新闻',
- },
-};
-
-module.exports = async (ctx) => {
- const type = ctx.params.type || 'notify';
- const pageUrl = url.resolve(baseUrl, typeProps[type].url);
- const title = `${typeProps[type].title}-昆明理工大学`;
- const response = await got({
- method: 'get',
- url: pageUrl,
- headers: {
- Referer: baseUrl,
- },
- });
-
- const $ = cheerio.load(response.data);
-
- ctx.state.data = {
- link: pageUrl,
- title,
- item: $('table[width="92%"] a[target="_blank"]')
- .slice(0, 10)
- .map((_, elem) => ({
- link: url.resolve(baseUrl, elem.attribs.href),
- title: elem.children[0].data,
- pubDate: new Date(elem.attribs.href.match(dataRegex)[0].split('/').join('-')).toUTCString(),
- }))
- .get(),
- };
-};
diff --git a/lib/routes-deprecated/universities/lit/jwc.js b/lib/routes-deprecated/universities/lit/jwc.js
deleted file mode 100644
index e2d60328039a..000000000000
--- a/lib/routes-deprecated/universities/lit/jwc.js
+++ /dev/null
@@ -1,50 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const url = require('url');
-
-const baseUrl = 'http://www.lit.edu.cn/jwc/';
-module.exports = async (ctx) => {
- const response = await got.get(baseUrl);
-
- const $ = cheerio.load(response.data);
- const list = $('article.post_box').get();
-
- const out = await Promise.all(
- list.map(async (item) => {
- item = $(item);
- const link = url.resolve(baseUrl, item.find('a').attr('href'));
- const single = {
- title: item.find('a').attr('title'),
- link,
- };
-
- const other = await ctx.cache.tryGet(link, async () => {
- const result = await got.get(link);
- const $ = cheerio.load(result.data);
-
- $('img[src="/system/resource/images/fileTypeImages/icon_xls.gif"]').remove();
- $('img[src="/system/resource/images/fileTypeImages/icon_doc.gif"]').remove();
- $('img[src="/system/resource/images/fileTypeImages/icon_ppt.gif"]').remove();
- $('img[src="/system/resource/images/fileTypeImages/icon_pdf.gif"]').remove();
-
- const description = $('article.entry-content').html();
- const pubDate = $('time').text();
- const author = $('aside > span:nth-child(1)').text();
- return {
- description,
- pubDate,
- author,
- };
- });
-
- return Object.assign({}, single, other);
- })
- );
-
- ctx.state.data = {
- title: `教务处 - 洛阳理工学院`,
- link: baseUrl,
- description: `洛阳理工教务在线 RSS`,
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/universities/lit/tw.js b/lib/routes-deprecated/universities/lit/tw.js
deleted file mode 100644
index 92c77e2baf7e..000000000000
--- a/lib/routes-deprecated/universities/lit/tw.js
+++ /dev/null
@@ -1,56 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const url = require('url');
-
-const baseUrl = 'http://www.lit.edu.cn/tw/';
-const nameProps = {
- tntz: '团内通知',
- qnkx: '青年快讯',
-};
-
-module.exports = async (ctx) => {
- const name = ctx.params.name || 'all';
- const urla = name === 'all' ? baseUrl : url.resolve(baseUrl, `${name}.htm`);
- const response = await got.get(urla);
- const $ = cheerio.load(response.data);
- const list = name === 'all' ? $('.con_wap').find('li').get() : $('ul.caselist li').get();
-
- const out = await Promise.all(
- list.map(async (item) => {
- item = $(item);
- const link = url.resolve(baseUrl, item.find('a').attr('href'));
- const pubDate = name === 'all' ? item.find('span').text() : item.children('.time').text();
-
- const other = await ctx.cache.tryGet(link, async () => {
- const result = await got.get(link);
- const $ = cheerio.load(result.data);
-
- $('img[src="/system/resource/images/fileTypeImages/icon_xls.gif"]').remove();
- $('img[src="/system/resource/images/fileTypeImages/icon_doc.gif"]').remove();
- $('img[src="/system/resource/images/fileTypeImages/icon_ppt.gif"]').remove();
- $('img[src="/system/resource/images/fileTypeImages/icon_pdf.gif"]').remove();
-
- const description = $('#textarea').html();
- const title = $('article > section > form > h2').text();
- return {
- description,
- title,
- };
- });
-
- const single = {
- link,
- pubDate,
- };
-
- return Object.assign({}, single, other);
- })
- );
-
- ctx.state.data = {
- title: name === 'all' ? `团委 - 洛阳理工学院` : `${nameProps[name]} - 洛理团委`,
- link: urla,
- description: `洛阳理工学院团委 RSS`,
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/universities/lit/xwzx.js b/lib/routes-deprecated/universities/lit/xwzx.js
deleted file mode 100644
index a8169a7b8cba..000000000000
--- a/lib/routes-deprecated/universities/lit/xwzx.js
+++ /dev/null
@@ -1,73 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const url = require('url');
-
-const host = 'http://www.lit.edu.cn/';
-const baseUrl = 'http://www.lit.edu.cn/xwzx/';
-const nameProps = {
- ggtz: '公告通知',
- xwkx: '新闻快讯',
- xsxx: '学术信息',
- mtxw: '媒体新闻',
-};
-
-module.exports = async (ctx) => {
- const name = ctx.params.name || 'all';
- const urla = name === 'all' ? host : url.resolve(baseUrl, `${name}.htm`);
- const response = await got.get(urla);
- const $ = cheerio.load(response.data);
- $('.xxlibottom').remove();
- const list = name === 'all' ? $('.xxlcleft ul li').get() : $('li.list_item').get();
-
- const out = await Promise.all(
- list.map(async (item) => {
- item = $(item);
- const link = url.resolve(host, item.find('a').attr('href'));
- const single = {
- title: item.find('a').attr('title'),
- link,
- };
-
- const other = await ctx.cache.tryGet(link, async () => {
- const result = await got.get(link);
- const $ = cheerio.load(result.data);
-
- $('img[src="/system/resource/images/fileTypeImages/icon_xls.gif"]').remove();
- $('img[src="/system/resource/images/fileTypeImages/icon_doc.gif"]').remove();
- $('img[src="/system/resource/images/fileTypeImages/icon_ppt.gif"]').remove();
- $('img[src="/system/resource/images/fileTypeImages/icon_pdf.gif"]').remove();
-
- $('.nr_text').find('hr').remove();
- const delp = $('.nr_text').find('p');
- delp.eq(-1).remove();
- delp.eq(-2).remove();
-
- const description = $('.nr_text').html();
-
- const time = $('h6').text();
- let pubDate = time.match(/\d{4}(?:-\d{1,2}){2}/g);
- if (pubDate === null) {
- pubDate = time
- .match(/\d{4}年\d{1,2}月\d{1,2}日 \d{1,2}:\d{1,2}/g)
- .toString()
- .replace('年', '-')
- .replace('月', '-')
- .replace('日', '');
- }
- return {
- description,
- pubDate,
- };
- });
-
- return Object.assign({}, single, other);
- })
- );
-
- ctx.state.data = {
- title: name === 'all' ? `新闻中心 - 洛阳理工学院` : `${nameProps[name]} - 洛理新闻中心`,
- link: urla,
- description: `洛阳理工学院新闻中心 RSS`,
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/universities/lntu/jwnews.js b/lib/routes-deprecated/universities/lntu/jwnews.js
deleted file mode 100644
index 1b10927f57f0..000000000000
--- a/lib/routes-deprecated/universities/lntu/jwnews.js
+++ /dev/null
@@ -1,46 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const url = require('url');
-
-module.exports = async (ctx) => {
- const link = 'http://jwzx.lntu.edu.cn/index/jwgg.htm';
- const response = await got.get(link);
-
- const $ = cheerio.load(response.data);
- const list = $('.tr-ri ul').find('li').get();
-
- const res = await Promise.all(
- list.map(async (item) => {
- let $ = cheerio.load(item);
- // 通过解析后的子项地址
- const item_link = url.resolve(link, $('a').attr('href'));
-
- const description = await ctx.cache.tryGet(item_link, async () => {
- const result = await got.get(item_link);
-
- $ = cheerio.load(result.data);
- // remove style
- $('img, div, span, p, table, td, tr').removeAttr('style');
- $('style, script').remove();
-
- return $('.v_news_content')
- .html()
- .replaceAll(/(]*>|<\/span>)/g, '');
- });
-
- const rssitem = {
- title: $('title').text().split('-')[0],
- description,
- link: item_link,
- author: '辽宁工程技术大学教务处',
- };
- return rssitem;
- })
- );
-
- ctx.state.data = {
- title: '辽宁工程技术大学教务公告',
- link,
- item: res,
- };
-};
diff --git a/lib/routes-deprecated/universities/lyu/news/index.js b/lib/routes-deprecated/universities/lyu/news/index.js
deleted file mode 100644
index 9ee4d6ad5485..000000000000
--- a/lib/routes-deprecated/universities/lyu/news/index.js
+++ /dev/null
@@ -1,40 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const util = require('./utils');
-const baseUrl = 'https://www.lyu.edu.cn/';
-
-module.exports = async (ctx) => {
- const type = ctx.params.type;
- let title, path;
- switch (type) {
- case 'ldyw':
- title = '临大要闻';
- path = '8125';
- break;
- case 'xxgg':
- title = '信息公告';
- path = '8126';
- break;
- }
-
- // 完整url
- const fullUrl = baseUrl + path + '/list.htm';
-
- const response = await got({
- method: 'get',
- url: fullUrl,
- });
-
- const data = response.data;
- const $ = cheerio.load(data);
- const list = $('.column-news-item').get();
-
- const result = await util.ProcessFeed(baseUrl, list, ctx.cache);
-
- ctx.state.data = {
- title: '临沂大学 - ' + title,
- link: fullUrl,
- description: '临沂大学 - ' + title,
- item: result,
- };
-};
diff --git a/lib/routes-deprecated/universities/lyu/news/utils.js b/lib/routes-deprecated/universities/lyu/news/utils.js
deleted file mode 100644
index 5faa1b9c3dce..000000000000
--- a/lib/routes-deprecated/universities/lyu/news/utils.js
+++ /dev/null
@@ -1,42 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const url = require('url');
-
-// 获取完整文章内容
-async function load(link) {
- const response = await got.get(link);
- const $ = cheerio.load(response.data);
-
- // 提取内容
- const description = $('.wp-container').html();
- // 返回结果
- return { description };
-}
-
-const ProcessFeed = (baseUrl, list, caches) =>
- Promise.all(
- // 遍历每一篇文章
- list.map(async (item) => {
- const $ = cheerio.load(item);
- // 还原相对链接为绝对链接
- const itemUrl = url.resolve(baseUrl, $('a').attr('href'));
-
- // 提取列表信息
- const single = {
- title: $('.column-news-title').text(),
- link: itemUrl,
- author: '临沂大学',
- pubDate: new Date($('.news-date-hide').text()).toUTCString(),
- guid: itemUrl,
- };
-
- // 使用tryGet方法从缓存获取内容。
- // 当缓存中无法获取到链接内容的时候,则使用load方法加载文章内容。
- const other = await caches.tryGet(itemUrl, () => load(itemUrl));
- // 合并解析后的结果集作为该篇文章最终的输出结果
- return Object.assign({}, single, other);
- })
- );
-module.exports = {
- ProcessFeed,
-};
diff --git a/lib/routes-deprecated/universities/mit/csail/news.js b/lib/routes-deprecated/universities/mit/csail/news.js
deleted file mode 100644
index ce52cbba5f7d..000000000000
--- a/lib/routes-deprecated/universities/mit/csail/news.js
+++ /dev/null
@@ -1,51 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const rootUrl = 'https://www.csail.mit.edu';
- const currentUrl = `${rootUrl}/news`;
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
-
- const $ = cheerio.load(response.data);
-
- $('.featured-person').remove();
-
- const list = $('article[role="article"]')
- .slice(0, 15)
- .map((_, item) => {
- item = $(item);
- return {
- link: `${rootUrl}${item.attr('about')}`,
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: item.link,
- });
- const content = cheerio.load(detailResponse.data);
-
- content('.sidebar-right, .sidebar-item').remove();
-
- item.title = content('.page-title').text();
- item.description = content('.content-container-inner').html();
- item.pubDate = new Date(content('time').attr('datetime')).toUTCString();
-
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: 'News - MIT CSAIL',
- link: currentUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/universities/mit/graduateadmissions.js b/lib/routes-deprecated/universities/mit/graduateadmissions.js
deleted file mode 100644
index 31a5c5ec610c..000000000000
--- a/lib/routes-deprecated/universities/mit/graduateadmissions.js
+++ /dev/null
@@ -1,63 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-const host = 'https://gradadmissions.mit.edu';
-
-module.exports = async (ctx) => {
- const type = ctx.params.type;
- const name = ctx.params.name;
-
- let link = host + '';
- switch (type) {
- case 'index':
- link = host + '/blog';
- break;
- case 'category':
- link = host + `/blog/browse/category/${name}`;
- break;
- case 'department':
- link = host + `/blog/browse/department/${name}`;
- break;
- }
- const response = await got.get(link);
- const $ = cheerio.load(response.data);
-
- const title = $('#page-title').text();
- const list = $('div.views-row');
- const out = await Promise.all(
- list
- .slice(0, 10)
- .map(async (_, elem) => {
- const $elem = $(elem);
-
- const title = $elem.find('h3.item-title a').text() + '-' + $elem.find('h4.item-subtitle').text();
- const itemUrl = host + $elem.find('h3.item-title a').attr('href');
- const author = $elem.find('div.item-info a').text();
-
- const cache = await ctx.cache.get(itemUrl);
- if (cache) {
- return JSON.parse(cache);
- }
-
- const response = await got.get(itemUrl);
- const $$ = cheerio.load(response.data);
- const description = $$('div.field-name-body div.field-items').html().replaceAll('src="', `src="${host}`);
-
- const single = {
- title,
- link: itemUrl,
- author,
- description,
- };
- ctx.cache.set(itemUrl, JSON.stringify(single));
- return single;
- })
- .get()
- );
-
- ctx.state.data = {
- title: `${title}-MIT`,
- link,
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/universities/mit/ocw-top.js b/lib/routes-deprecated/universities/mit/ocw-top.js
deleted file mode 100644
index 5d7f562647d4..000000000000
--- a/lib/routes-deprecated/universities/mit/ocw-top.js
+++ /dev/null
@@ -1,39 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const link = 'https://ocw.mit.edu/courses/most-visited-courses/';
-
- const getHTML = async () => {
- const response = await got({
- method: 'get',
- url: link,
- });
-
- return response.data;
- };
-
- const html = await ctx.cache.tryGet(link, getHTML);
- const courses = [];
-
- const $ = cheerio.load(html);
- $('.courseList tbody')
- .children()
- .each(function () {
- const course = {
- title: $('td', this).eq(1).text(),
- link: `https://ocw.mit.edu${$('td a', this).eq(1).attr('href')}`,
- description: $('td', this).eq(2).text(),
- };
-
- courses.push(course);
- });
-
- ctx.state.data = {
- title: 'MIT OCW top courses of the month',
- link,
- description: 'Most visited courses based on the site traffic of the previous month',
- language: 'en-us',
- item: courses,
- };
-};
diff --git a/lib/routes-deprecated/universities/nchu/jwc.js b/lib/routes-deprecated/universities/nchu/jwc.js
deleted file mode 100644
index 647a3f7c8c81..000000000000
--- a/lib/routes-deprecated/universities/nchu/jwc.js
+++ /dev/null
@@ -1,48 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const iconv = require('iconv-lite');
-
-const host = 'http://jwc.nchu.edu.cn';
-
-const map = {
- notice: '3',
- news: '1',
-};
-
-module.exports = async (ctx) => {
- const type = ctx.params.type || 'notice';
- const link = `${host}/Topic.asp?secondColumnID=${map[type]}`;
- const response = await got({
- method: 'get',
- url: link,
- headers: {
- Referer: host,
- },
- responseType: 'buffer',
- });
- const responseHtml = iconv.decode(response.data, 'GBK');
- const $ = cheerio.load(responseHtml);
-
- const linkList = $('td[width=515]')
- .find('a')
- .slice(0, 10)
- .map((_, e) => ({
- title: $(e).text(),
- link: `${host}/${$(e).attr('href')}`,
- }))
- .get();
- $('td[width=85]')
- .map((i, e) => (linkList[i].pubDate = new Date($(e).text().replace('[', '').replace(']', '').split('/').join('-')).toUTCString()))
- .get();
-
- let info = '教务公告';
- if (type === 'news') {
- info = '教务新闻';
- }
-
- ctx.state.data = {
- link,
- title: `南昌航空大学教务处 - ${info}`,
- item: linkList,
- };
-};
diff --git a/lib/routes-deprecated/universities/nciae/news.js b/lib/routes-deprecated/universities/nciae/news.js
deleted file mode 100644
index 8f869e0e593f..000000000000
--- a/lib/routes-deprecated/universities/nciae/news.js
+++ /dev/null
@@ -1,58 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const url = `http://nciae.edu.cn/index/xw2.htm`;
- const response = await got({
- method: 'get',
- url,
- });
- const $ = cheerio.load(response.data);
- // ## 获取列表
- const list = $('#container > ul > li > a').get();
- // ## 定义输出的item
- const out = await Promise.all(
- // ### 遍历列表,筛选出自己想要的内容
- list.map(async (item) => {
- const itemSingle = cheerio.load(item);
- const title = itemSingle.text();
- const re = /]*href=["']([^"]*)["'][^>]*>(.*?)<\/a>/g;
- let singleUrl = '';
- if (re.exec(itemSingle.html()) !== null) {
- singleUrl = RegExp.$1;
- }
- singleUrl = singleUrl.replace('..', 'http://nciae.edu.cn');
- const cache = await ctx.cache.get(singleUrl); // ### 得到全局中的缓存信息
- // ### 判断缓存是否存在,如果存在即跳过此次获取的信息
- if (cache) {
- return JSON.parse(cache);
- }
- // 获取详情页面的介绍
- const detail_response = await got({
- method: 'get',
- url: singleUrl,
- });
- const $ = cheerio.load(detail_response.data);
- const detail_content = $('#content > form').html();
- // ### 设置 RSS feed item
- const single = {
- title,
- link: singleUrl,
- // author,
- description: detail_content,
- // pubDate: updateDate,
- };
- // // ### 设置缓存
- ctx.cache.set(singleUrl, JSON.stringify(single));
- return single;
- // }
- })
- );
-
- ctx.state.data = {
- title: `新闻 - 北华航天工业学院`,
- link: 'http://nciae.edu.cn/index/xw2.htm',
- description: `新闻 - 北华航天工业学院`,
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/universities/nciae/tzgg.js b/lib/routes-deprecated/universities/nciae/tzgg.js
deleted file mode 100644
index 895f8839f135..000000000000
--- a/lib/routes-deprecated/universities/nciae/tzgg.js
+++ /dev/null
@@ -1,58 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const url = `http://nciae.edu.cn/index/tzgg.htm`;
- const response = await got({
- method: 'get',
- url,
- });
- const $ = cheerio.load(response.data);
- // ## 获取列表
- const list = $('#container > ul > li > a').get();
- // ## 定义输出的item
- const out = await Promise.all(
- // ### 遍历列表,筛选出自己想要的内容
- list.map(async (item) => {
- const itemSingle = cheerio.load(item);
- const title = itemSingle.text();
- const re = /]*href=["']([^"]*)["'][^>]*>(.*?)<\/a>/g;
- let singleUrl = '';
- if (re.exec(itemSingle.html()) !== null) {
- singleUrl = RegExp.$1;
- }
- singleUrl = singleUrl.replace('..', 'http://nciae.edu.cn');
- const cache = await ctx.cache.get(singleUrl); // ### 得到全局中的缓存信息
- // ### 判断缓存是否存在,如果存在即跳过此次获取的信息
- if (cache) {
- return JSON.parse(cache);
- }
- // 获取详情页面的介绍
- const detail_response = await got({
- method: 'get',
- url: singleUrl,
- });
- const $ = cheerio.load(detail_response.data);
- const detail_content = $('#content > form').html();
- // ### 设置 RSS feed item
- const single = {
- title,
- link: singleUrl,
- // author,
- description: detail_content,
- // pubDate: updateDate,
- };
- // // ### 设置缓存
- ctx.cache.set(singleUrl, JSON.stringify(single));
- return single;
- // }
- })
- );
-
- ctx.state.data = {
- title: `通知公告 - 北华航天工业学院`,
- link: 'http://nciae.edu.cn/index/xw2.htm',
- description: `通知公告 - 北华航天工业学院`,
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/universities/nciae/xsxx.js b/lib/routes-deprecated/universities/nciae/xsxx.js
deleted file mode 100644
index 3ef9e1ce94e3..000000000000
--- a/lib/routes-deprecated/universities/nciae/xsxx.js
+++ /dev/null
@@ -1,58 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const url = `http://nciae.edu.cn/index/xsxx.htm`;
- const response = await got({
- method: 'get',
- url,
- });
- const $ = cheerio.load(response.data);
- // ## 获取列表
- const list = $('#container > ul > li > a').get();
- // ## 定义输出的item
- const out = await Promise.all(
- // ### 遍历列表,筛选出自己想要的内容
- list.map(async (item) => {
- const itemSingle = cheerio.load(item);
- const title = itemSingle.text();
- const re = /]*href=["']([^"]*)["'][^>]*>(.*?)<\/a>/g;
- let singleUrl = '';
- if (re.exec(itemSingle.html()) !== null) {
- singleUrl = RegExp.$1;
- }
- singleUrl = singleUrl.replace('..', 'http://nciae.edu.cn');
- const cache = await ctx.cache.get(singleUrl); // ### 得到全局中的缓存信息
- // ### 判断缓存是否存在,如果存在即跳过此次获取的信息
- if (cache) {
- return JSON.parse(cache);
- }
- // 获取详情页面的介绍
- const detail_response = await got({
- method: 'get',
- url: singleUrl,
- });
- const $ = cheerio.load(detail_response.data);
- const detail_content = $('#content > form').html();
- // ### 设置 RSS feed item
- const single = {
- title,
- link: singleUrl,
- // author,
- description: detail_content,
- // pubDate: updateDate,
- };
- // // ### 设置缓存
- ctx.cache.set(singleUrl, JSON.stringify(single));
- return single;
- // }
- })
- );
-
- ctx.state.data = {
- title: `学术信息 - 北华航天工业学院`,
- link: 'http://nciae.edu.cn/index/xw2.htm',
- description: `学术信息 - 北华航天工业学院`,
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/universities/njfu/jwc.js b/lib/routes-deprecated/universities/njfu/jwc.js
deleted file mode 100644
index 88f2923a51a7..000000000000
--- a/lib/routes-deprecated/universities/njfu/jwc.js
+++ /dev/null
@@ -1,47 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-const url = 'http://jwc.njfu.edu.cn/sy/';
-const map = {
- xjfw: '校级发文',
- tzgg: '通知公告',
- sjfw: '上级发文',
- xzzq: '下载专区',
-};
-
-module.exports = async (ctx) => {
- const category = ctx.params.category ?? 'tzgg';
- const link = category === 'xzzq' ? 'http://jwc.njfu.edu.cn/xzzq/' : `${url}${category}/`;
-
- const response = await got(link, {
- method: 'get',
- hooks: {
- beforeRedirect: [
- (options, response) => {
- const cookie = response.headers['set-cookie'];
- if (cookie) {
- const cook = cookie.map((c) => c.split(';')[0]).join('; ');
- options.headers.Cookie = cook;
- options.headers.Referer = response.url;
- }
- },
- ],
- },
- });
- const $ = cheerio.load(response.data);
- const list = $('.List_R4');
-
- ctx.state.data = {
- title: '南京林业大学教务处-' + map[category],
- link,
- description: `南京林业大学教务处-${map[category]}`,
- item: list
- .map((index, item) => ({
- title: $(item).find('a').attr('title'),
- description: $(item).find('a').attr('title'),
- pubDate: $(item).find('.List_R4_R').text().replaceAll(/\[|]/g, ''),
- link: $(item).find('a').attr('href'),
- }))
- .get(),
- };
-};
diff --git a/lib/routes-deprecated/universities/njtech/jwc.js b/lib/routes-deprecated/universities/njtech/jwc.js
deleted file mode 100644
index 2a61eaf7e86d..000000000000
--- a/lib/routes-deprecated/universities/njtech/jwc.js
+++ /dev/null
@@ -1,54 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-const host = 'http://jwc.njtech.edu.cn';
-
-const link = host + '/index/tzgg.htm';
-
-module.exports = async (ctx) => {
- const response = await got({
- method: 'get',
- url: link,
- headers: {
- Referer: host,
- },
- });
-
- const $ = cheerio.load(response.data);
-
- const urlList = $('#mainRight li a')
- .get()
- .map((i) => host + $(i).attr('href').replace('..', ''));
-
- const out = await Promise.all(
- urlList.map(async (itemUrl) => {
- const cache = await ctx.cache.get(itemUrl);
- if (cache) {
- return JSON.parse(cache);
- }
- const response = await got.get(itemUrl);
- const $ = cheerio.load(response.data);
- const targetDate = $('.time')
- .text()
- .match(/(\d{4}-\d{2})-\d{2}/);
-
- if (targetDate) {
- const single = {
- title: $('#mainRight .title').text(),
- link: itemUrl,
- description: $('#vsb_content').html(),
- pubDate: targetDate[0],
- };
- ctx.cache.set(itemUrl, JSON.stringify(single));
- return single;
- }
- })
- );
- const info = '教务公告';
-
- ctx.state.data = {
- title: '南京工业大学教务处 - ' + info,
- link,
- item: out.filter(Boolean),
- };
-};
diff --git a/lib/routes-deprecated/universities/nku/jwc/index.js b/lib/routes-deprecated/universities/nku/jwc/index.js
deleted file mode 100644
index 2c751765970f..000000000000
--- a/lib/routes-deprecated/universities/nku/jwc/index.js
+++ /dev/null
@@ -1,47 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const type = ctx.params && ctx.params.type;
- let index;
- if (type === undefined) {
- index = 24;
- } else if (type === 2) {
- index = 20;
- } else {
- index = 24;
- }
- const dirname = 'http://jwc.nankai.edu.cn/';
- const response = await got({
- method: 'get',
- url: `${dirname}${index}/list.htm`,
- responseType: 'buffer',
- headers: {
- Referer: 'http://jwc.nankai.edu.cn/',
- },
- });
-
- const $ = cheerio.load(response.data);
-
- const list = $('#wp_news_w6 ul li').slice(0, 10);
-
- ctx.state.data = {
- title: '南开大学教务处',
- link: 'http://www.nankai.edu.cn',
- description: $('meta[name="description"]').attr('content'),
- item:
- list &&
- list
- .map((index, item) => {
- item = $(item);
-
- return {
- title: $(item.find('a')).text(),
- pubDate: $(item.find('.Article_PublishDate')).text(),
- description: `发布日期:${$(item.find('.Article_PublishDate')).text()}`,
- link: `${dirname}${$(item.find('a')).attr('href')}`,
- };
- })
- .get(),
- };
-};
diff --git a/lib/routes-deprecated/universities/nuc/index.js b/lib/routes-deprecated/universities/nuc/index.js
deleted file mode 100644
index 4efc4bc67904..000000000000
--- a/lib/routes-deprecated/universities/nuc/index.js
+++ /dev/null
@@ -1,91 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const types = {
- zbxw: {
- name: '中北新闻',
- url: 'http://www.nuc.edu.cn/index/zbxw.htm',
- },
- tzgg: {
- name: '通知公告',
- url: 'http://www.nuc.edu.cn/index/tzgg.htm',
- },
- xshd: {
- name: '学术活动',
- url: 'http://www.nuc.edu.cn/index/xshd.htm',
- },
- jwtz: {
- name: '教务通知',
- url: 'http://jwc.nuc.edu.cn/index/jwtz.htm',
- },
-};
-const config = {
- jwtz: {
- selector: {
- list: '.winstyle54561 > tbody > tr > td > a',
- title: 'body > center > table:nth-child(2) > tbody > tr > td.bk > table > tbody > tr:nth-child(2) > td > form > div > p:nth-child(1) > span',
- date: 'body > center > table:nth-child(2) > tbody > tr > td.bk > table > tbody > tr:nth-child(2) > td > form > div > div:nth-child(2) > span.c205277_date',
- content: '#vsb_content',
- },
- basePath: 'http://jwc.nuc.edu.cn/',
- },
- other: {
- selector: {
- list: 'body > div.list > div.list_con > div.list_con_rightlist > ul > li',
- title: 'body > div.list > div.list_con > form > div > h2',
- date: 'body > div.list > div.list_con > form > div > div:nth-child(4)',
- content: 'body > div.list > div.list_con > form > div > div:nth-child(6)',
- },
- basePath: 'http://www.nuc.edu.cn/',
- },
-};
-module.exports = async (ctx) => {
- const type = ctx.params.type || 'zbxw';
- const typeConfig = config[type] || config.other;
- const response = await got({
- method: 'get',
- url: `${typeConfig.basePath}index/${type}.htm`,
- });
- const $ = cheerio.load(response.data);
- const list = $(typeConfig.selector.list).get();
- const out = await Promise.all(
- list.map(async (item) => {
- const liItem = cheerio.load(item);
- const aTag = liItem('a');
- const articleUrl = aTag.attr('href').replace(/\.\./, typeConfig.basePath);
- const cache = await ctx.cache.get(articleUrl);
- if (cache) {
- return JSON.parse(cache);
- }
- const response = await got({
- method: 'get',
- url: articleUrl,
- });
- const $ = cheerio.load(response.data);
- const title = $(typeConfig.selector.title).text();
- const dateText = $(typeConfig.selector.date)
- .text()
- .split(' ')[0]
- .replace(/时间:/, '')
- .replaceAll(/[年日月]/g, '/')
- .trim();
- let content = $(typeConfig.selector.content).html();
- content = content.replaceAll('/__local', 'http://www.nuc.edu.cn/__local');
- const data = {
- title,
- link: articleUrl,
- // author,
- description: content,
- pubDate: new Date(dateText),
- };
- ctx.cache.set(articleUrl, JSON.stringify(data));
- return data;
- })
- );
-
- ctx.state.data = {
- title: `${types[type].name} - 中北大学`,
- link: types[type].url,
- description: `${types[type].name} - 中北大学`,
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/universities/nudt/yjszs.js b/lib/routes-deprecated/universities/nudt/yjszs.js
deleted file mode 100644
index 7947d5748b8a..000000000000
--- a/lib/routes-deprecated/universities/nudt/yjszs.js
+++ /dev/null
@@ -1,60 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- ctx.params.id = ctx.params.id || '0';
-
- const rootUrl = 'http://yjszs.nudt.edu.cn/';
-
- const currentUrl = ctx.params.id === '0' ? `${rootUrl}/pubweb/homePageList/searchContent.view` : `${rootUrl}/pubweb/homePageList/recruitStudents.view?keyId=${ctx.params.id}`;
-
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
-
- const $ = cheerio.load(response.data);
-
- $('div.info').remove();
-
- const list = $('div.news-list ul li a')
- .slice(0, 10)
- .map((_, item) => {
- item = $(item);
- return {
- link: item.attr('href'),
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: item.link,
- });
- const content = cheerio.load(detailResponse.data);
-
- item.title = content('h1').text();
- item.pubDate = new Date(content('p.time').eq(0).text() + ' GMT+8').toUTCString();
-
- content('h1').remove();
- content('div.time-browse').remove();
-
- item.description = content('div.content').html();
-
- return item;
- })
- )
- );
-
- let title = $('h2').text();
- title = title || '通知公告';
-
- ctx.state.data = {
- title: `${title} - 国防科技大学研究生招生信息网`,
- link: currentUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/universities/sctu/information-engineer-faculty/context.js b/lib/routes-deprecated/universities/sctu/information-engineer-faculty/context.js
deleted file mode 100644
index e5857890c5bc..000000000000
--- a/lib/routes-deprecated/universities/sctu/information-engineer-faculty/context.js
+++ /dev/null
@@ -1,44 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const iconv = require('iconv-lite');
-
-module.exports = async (ctx) => {
- const response = await got({
- method: 'get',
- url: `http://it.sctu.edu.cn/data.asp?fa=2&fl=12&zi=0&id=${ctx.params.id}`,
- responseType: 'buffer',
- headers: {
- Referer: 'http://it.sctu.edu.cn/',
- },
- });
-
- const formal = (buffer) => {
- // HTML-buffer转为gb2312
- const data = iconv.decode(buffer, 'gb2312');
-
- return cheerio.load(data);
- };
-
- const $ = formal(response.data);
-
- const list = $('.data').slice(0, 10);
-
- ctx.state.data = {
- title: '四川旅游学院',
- link: 'http://www.sctu.edu.cn',
- description: $('meta[name="description"]').attr('content'),
- item:
- list &&
- list
- .map((index, item) => {
- item = $(item);
-
- return {
- title: $(item.find('.data_bt')).text(),
- pubDate: $(item.find('.data_in')).text(),
- description: item.find('.data_co').html(),
- };
- })
- .get(),
- };
-};
diff --git a/lib/routes-deprecated/universities/sctu/information-engineer-faculty/index.js b/lib/routes-deprecated/universities/sctu/information-engineer-faculty/index.js
deleted file mode 100644
index 0143c99477ad..000000000000
--- a/lib/routes-deprecated/universities/sctu/information-engineer-faculty/index.js
+++ /dev/null
@@ -1,39 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const iconv = require('iconv-lite');
-
-module.exports = async (ctx) => {
- const response = await got({
- method: 'get',
- url: 'http://it.sctu.edu.cn/list.asp?fa=2&fl=12&zi=0',
- responseType: 'buffer',
- headers: {
- Referer: 'http://it.sctu.edu.cn/',
- },
- });
- // HTML-buffer转为gb2312
- const data = iconv.decode(response.data, 'gb2312');
-
- const $ = cheerio.load(data);
-
- const list = $('.list_dt a').slice(0, 10);
-
- ctx.state.data = {
- title: '四川旅游学院信息与工程系',
- link: 'http://www.sctu.edu.cn',
- description: $('meta[name="description"]').attr('content'),
- item:
- list &&
- list
- .map((index, item) => {
- item = $(item);
-
- return {
- title: $(item.find('div')[0]).text(),
- description: $(item.find('div')[1]).text(),
- link: `http://it.sctu.edu.cn/${item.attr('href')}`,
- };
- })
- .get(),
- };
-};
diff --git a/lib/routes-deprecated/universities/sctu/jwc/context.js b/lib/routes-deprecated/universities/sctu/jwc/context.js
deleted file mode 100644
index a1cfd4845b04..000000000000
--- a/lib/routes-deprecated/universities/sctu/jwc/context.js
+++ /dev/null
@@ -1,44 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const iconv = require('iconv-lite');
-
-module.exports = async (ctx) => {
- const response = await got({
- method: 'get',
- url: `http://www.sctu.edu.cn/jwc/content.asp?type=12&fl=${ctx.params.type}&id=${ctx.params.id}`,
- responseType: 'buffer',
- headers: {
- Referer: 'http://sctu.edu.cn/',
- },
- });
-
- const formal = (buffer) => {
- // HTML-buffer转为gb2312
- const data = iconv.decode(buffer, 'gb2312');
-
- return cheerio.load(data);
- };
-
- const $ = formal(response.data);
-
- const list = $('#list2').slice(0, 10);
-
- ctx.state.data = {
- title: '四川旅游学院信息与工程学院',
- link: 'http://www.sctu.edu.cn',
- description: $('meta[name="description"]').attr('content'),
- item:
- list &&
- list
- .map((index, item) => {
- item = $(item);
-
- return {
- title: $(item.find('.title')).text(),
- pubDate: $(item.find('.info')).text(),
- description: item.html(),
- };
- })
- .get(),
- };
-};
diff --git a/lib/routes-deprecated/universities/sctu/jwc/index.js b/lib/routes-deprecated/universities/sctu/jwc/index.js
deleted file mode 100644
index 96b0aecb5c2c..000000000000
--- a/lib/routes-deprecated/universities/sctu/jwc/index.js
+++ /dev/null
@@ -1,46 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const iconv = require('iconv-lite');
-
-module.exports = async (ctx) => {
- const dirname = 'http://www.sctu.edu.cn/jwc/';
- const response = await got({
- method: 'get',
- url: `${dirname}list.asp?type=12&fl=${+ctx.params.type === 14 ? 14 : 13}`,
- responseType: 'buffer',
- headers: {
- Referer: 'http://www.sctu.edu.cn',
- },
- });
-
- const formal = (buffer) => {
- // HTML-buffer转为gb2312
- const data = iconv.decode(buffer, 'gb2312');
-
- return cheerio.load(data);
- };
-
- const $ = formal(response.data);
-
- const list = $('#list1 ul li').slice(0, 10);
-
- ctx.state.data = {
- title: '四川旅游学院',
- link: 'http://www.sctu.edu.cn',
- description: $('meta[name="description"]').attr('content'),
- item:
- list &&
- list
- .map((index, item) => {
- item = $(item);
-
- return {
- title: $(item.find('a')).text(),
- pubDate: $(item.find('dl')).text(),
- description: `发布日期:${$(item.find('dl')).text()}`,
- link: dirname + $(item.find('a')).attr('href'),
- };
- })
- .get(),
- };
-};
diff --git a/lib/routes-deprecated/universities/scu/jwc.js b/lib/routes-deprecated/universities/scu/jwc.js
deleted file mode 100644
index 9866d7826463..000000000000
--- a/lib/routes-deprecated/universities/scu/jwc.js
+++ /dev/null
@@ -1,50 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const url_resolve = require('url').resolve;
-
-// 获取通知详情
-function load_detail(list, cache) {
- return Promise.all(
- list.map((item) => {
- const notice_item = cheerio.load(item);
- const url = url_resolve('http://jwc.scu.edu.cn', notice_item('a').attr('href'));
- return cache.tryGet(url, async () => {
- const detail_response = await got({
- method: 'get',
- url,
- headers: {
- Referer: url,
- },
- });
- const detail = cheerio.load(detail_response.data);
- const date_part = detail('.page-date > span').text().slice(5, 15).split('-');
- const date = new Date(date_part[0], date_part[1] - 1, date_part[2]);
- return {
- title: detail('.page-title').text(),
- description: detail('.page-content').html(),
- pubDate: date,
- link: url,
- };
- });
- })
- );
-}
-
-module.exports = async (ctx) => {
- const url = 'http://jwc.scu.edu.cn';
- const response = await got({
- method: 'get',
- url,
- headers: {
- Referer: url,
- },
- });
- const $ = cheerio.load(response.data);
- const list = $('.list-ll-b > .edit_option >.list-llb-box > .list-llb-s > .list-llb-list').get();
- const detail = await load_detail(list, ctx.cache);
- ctx.state.data = {
- title: '四川大学教务处 - 通知公告',
- link: url,
- item: detail,
- };
-};
diff --git a/lib/routes-deprecated/universities/scu/xg.js b/lib/routes-deprecated/universities/scu/xg.js
deleted file mode 100644
index 9db7b56e6759..000000000000
--- a/lib/routes-deprecated/universities/scu/xg.js
+++ /dev/null
@@ -1,65 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-function load_detail(list, cache) {
- return Promise.all(
- list.map((item) => {
- const notice_item = cheerio.load(item);
- const url = 'http://xsc.scu.edu.cn' + notice_item('a').attr('href');
-
- const date_part = notice_item('a > span').text().split('-');
- const date = new Date(new Date().getFullYear(), date_part[0] - 1, date_part[1]);
- return cache.tryGet(url, async () => {
- const detail_response = await got({
- method: 'get',
- url,
- headers: {
- Referer: 'http://xsc.scu.edu.cn/WEBSITE/XG',
- Host: 'xsc.scu.edu.cn',
- },
- });
- const detail = cheerio.load(detail_response.data);
- return {
- title: notice_item('a').attr('title'),
- description: detail('.news-content').html(),
- pubDate: date,
- link: url,
- };
- });
- })
- );
-}
-
-module.exports = async (ctx) => {
- const index_response = await got({
- method: 'get',
- url: 'http://xsc.scu.edu.cn/WEBSITE/XG',
- headers: {
- Host: 'xsc.scu.edu.cn',
- },
- });
-
- const index_data = index_response.data;
- const $_ = cheerio.load(index_data);
- const notice_url = 'http://xsc.scu.edu.cn' + $_('.news-pannel.notice-news > .news-head > a').attr('href');
-
- const response = await got({
- method: 'get',
- url: notice_url,
- headers: {
- Host: 'xsc.scu.edu.cn',
- },
- });
-
- const data = response.data;
- const $ = cheerio.load(data);
- const list = $('.news-list > ul > li').get();
-
- const detail = await load_detail(list, ctx.cache);
-
- ctx.state.data = {
- title: '四川大学学工部 - 通知公告',
- link: 'http://xsc.scu.edu.cn/WEBSITE/XG',
- item: detail,
- };
-};
diff --git a/lib/routes-deprecated/universities/shanghaitech/activity.js b/lib/routes-deprecated/universities/shanghaitech/activity.js
deleted file mode 100644
index 70e28984432a..000000000000
--- a/lib/routes-deprecated/universities/shanghaitech/activity.js
+++ /dev/null
@@ -1,34 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const link = 'http://www.shanghaitech.edu.cn/qb/list.htm';
- const response = await got({ method: 'get', url: link });
-
- const $ = cheerio.load(response.data);
-
- const list = $('ul.news_list.clearfix li')
- .map((i, e) => ({
- link: `http://www.shanghaitech.edu.cn` + $(e).find('a').attr('href'),
- title: $(e).find('a').text(),
- pubDate: $(e).find('div.news_time').attr('data-time'),
- }))
- .get();
-
- ctx.state.data = {
- title: '上海科技大学 - 活动',
- link,
- item: await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- if (!item.link.includes('_redirect?')) {
- const detailResponse = await got({ method: 'get', url: item.link });
- const content = cheerio.load(detailResponse.data);
- item.description = content('div.wp_articlecontent').html();
- }
- return item;
- })
- )
- ),
- };
-};
diff --git a/lib/routes-deprecated/universities/shanghaitech/sist/activity.js b/lib/routes-deprecated/universities/shanghaitech/sist/activity.js
deleted file mode 100644
index de9bb8b0db5e..000000000000
--- a/lib/routes-deprecated/universities/shanghaitech/sist/activity.js
+++ /dev/null
@@ -1,51 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const url = require('url');
-
-const host = 'http://sist.shanghaitech.edu.cn/';
-
-module.exports = async (ctx) => {
- const link = url.resolve(host, 'cn/News.asp?mid=102');
- const response = await got.get(link);
-
- const $ = cheerio.load(response.data);
-
- const list = $('.pagebv tr')
- .slice(0, 10)
- .map((i, e) => ({
- link: $(e).find('td:nth-of-type(2) a').attr('href'),
- date: $(e).find('td:last-of-type').text().replace('[', '').replace(']', ''),
- }))
- .get();
-
- const out = await Promise.all(
- list.map(async (item) => {
- const itemUrl = url.resolve(host, `cn/${item.link}`);
- const cache = await ctx.cache.get(itemUrl);
- if (cache) {
- return JSON.parse(cache);
- }
-
- const response = await got.get(itemUrl);
- const $ = cheerio.load(response.data);
- const single = {
- title: $('.pagebv tr:first-of-type').text().trim(),
- link: itemUrl,
- author: '上海科技大学信息科技与技术学院',
- description: $('.pagebv tr:last-of-type')
- .html()
- .replaceAll('src="/', `src="${url.resolve(host, '.')}`)
- .trim(),
- pubDate: new Date(item.date),
- };
- ctx.cache.set(itemUrl, JSON.stringify(single));
- return single;
- })
- );
-
- ctx.state.data = {
- title: '上海科技大学信息科技与技术学院 -- 活动',
- link,
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/universities/shou/www.js b/lib/routes-deprecated/universities/shou/www.js
deleted file mode 100644
index 686a4946565e..000000000000
--- a/lib/routes-deprecated/universities/shou/www.js
+++ /dev/null
@@ -1,64 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const url = require('url');
-const host = 'https://www.shou.edu.cn';
-
-async function GetDesc(link) {
- const response = await got.get(link);
- const $ = cheerio.load(response.data);
-
- const description = $('.wp_articlecontent').text();
- return { description };
-}
-
-const ProcessFeed = (list, caches) =>
- Promise.all(
- list.map(async (item) => {
- const $ = cheerio.load(item);
-
- const itemUrl = url.resolve(host, $('a').attr('href'));
-
- const fetched = {
- title: $('.col_news_title').text().trim(),
- link: itemUrl,
- guid: itemUrl,
- pubDate: new Date($('.col_news_date').text()).toUTCString(),
- };
-
- const cached = await caches.tryGet(itemUrl, () => GetDesc(itemUrl));
-
- return Object.assign({}, fetched, cached);
- })
- );
-
-module.exports = async (ctx) => {
- const type = ctx.params.type;
- const dict = {
- zbxx: '招标信息',
- tzgg: '通知公告',
- yw: '要闻',
- mtjj: '媒体聚焦',
- xsjz: '学术讲座',
- xsqy: '科技前沿',
- };
- const readableType = dict[type];
- const response = await got({
- method: 'get',
- url: `${host}/${type}/list.htm`,
- headers: {
- Referer: host,
- },
- });
-
- const $ = cheerio.load(response.data);
- const list = $('a.col_news_item').slice(0, 10).get();
-
- const result = await ProcessFeed(list, ctx.cache);
-
- ctx.state.data = {
- title: `上海海洋大学 ${readableType}`,
- link: `${host}/${type}/list.htm`,
- description: '上海海洋大学 官网信息',
- item: result,
- };
-};
diff --git a/lib/routes-deprecated/universities/slu/csggxy.js b/lib/routes-deprecated/universities/slu/csggxy.js
deleted file mode 100644
index 86a1b73d5f79..000000000000
--- a/lib/routes-deprecated/universities/slu/csggxy.js
+++ /dev/null
@@ -1,13 +0,0 @@
-const utils = require('./utils');
-const baseurl = 'http://csggxy.lixin.edu.cn';
-
-module.exports = async (ctx) => {
- const link = baseurl + `/info/iList.jsp?cat_id=${ctx.params.id}`;
- const { list, title } = await utils.fetchMain(link, 'body > div.details > div.contentright > div.rightlist > ul > li');
- ctx.state.data = {
- title: `${title} - 财税与公共管理学院 - 上海立信会计金融学院`,
- link,
- description: `${title} - 财税与公共管理学院 - 上海立信会计金融学院`,
- item: await utils.fetchDetail(list, baseurl, 'body > div.neirong > div.rong', ctx.cache),
- };
-};
diff --git a/lib/routes-deprecated/universities/slu/jwc.js b/lib/routes-deprecated/universities/slu/jwc.js
deleted file mode 100644
index 3c24c0e4a9aa..000000000000
--- a/lib/routes-deprecated/universities/slu/jwc.js
+++ /dev/null
@@ -1,13 +0,0 @@
-const utils = require('./utils');
-const baseurl = 'http://jwc.lixin.edu.cn';
-
-module.exports = async (ctx) => {
- const link = baseurl + `/info/iList.jsp?cat_id=${ctx.params.id}`;
- const { list, title } = await utils.fetchMain(link, 'body > div.details > div.contentright > div.rightlist > ul > li');
- ctx.state.data = {
- title: `${title} - 教务处 - 上海立信会计金融学院`,
- link,
- description: `${title} - 教务处 - 上海立信会计金融学院`,
- item: await utils.fetchDetail(list, baseurl, 'body > div.neirong > div.rong', ctx.cache),
- };
-};
diff --git a/lib/routes-deprecated/universities/slu/kjxy.js b/lib/routes-deprecated/universities/slu/kjxy.js
deleted file mode 100644
index 1cdde4a00623..000000000000
--- a/lib/routes-deprecated/universities/slu/kjxy.js
+++ /dev/null
@@ -1,14 +0,0 @@
-const utils = require('./utils');
-const baseurl = 'http://kjxy.lixin.edu.cn';
-
-module.exports = async (ctx) => {
- const link = baseurl + `/info/iList.jsp?cat_id=${ctx.params.id}`;
- const { list, title } = await utils.fetchMain(link, 'body > div.erji > div.erjiright > div.rightlist > ul > li');
-
- ctx.state.data = {
- title: `${title} - 会计学院 - 上海立信会计金融学院`,
- link,
- description: `${title} - 会计学院 - 上海立信会计金融学院`,
- item: await utils.fetchDetail(list, baseurl, 'body > div.wrapper > div.ContentPage > div.words > div.text', ctx.cache),
- };
-};
diff --git a/lib/routes-deprecated/universities/slu/tyyjkxy.js b/lib/routes-deprecated/universities/slu/tyyjkxy.js
deleted file mode 100644
index 3cd4d17a00b8..000000000000
--- a/lib/routes-deprecated/universities/slu/tyyjkxy.js
+++ /dev/null
@@ -1,14 +0,0 @@
-const utils = require('./utils');
-const baseurl = 'http://tiyu.lixin.edu.cn';
-
-module.exports = async (ctx) => {
- const link = baseurl + `/info/iList.jsp?cat_id=${ctx.params.id}`;
- const { list, title } = await utils.fetchMain(link, 'body > div.erji > div.erjiright > div.rightlist > ul > li');
-
- ctx.state.data = {
- title: `${title} - 体育与健康学院 - 上海立信会计金融学院`,
- link,
- description: `${title} - 体育与健康学院 - 上海立信会计金融学院`,
- item: await utils.fetchDetail(list, baseurl, 'body > div.wrapper > div.ContentPage > div.words > div.text', ctx.cache),
- };
-};
diff --git a/lib/routes-deprecated/universities/slu/tzgg.js b/lib/routes-deprecated/universities/slu/tzgg.js
deleted file mode 100644
index ab9ff02053d1..000000000000
--- a/lib/routes-deprecated/universities/slu/tzgg.js
+++ /dev/null
@@ -1,14 +0,0 @@
-const utils = require('./utils');
-const baseurl = 'http://www.lixin.edu.cn';
-
-module.exports = async (ctx) => {
- const link = baseurl + `/info/iList.jsp?cat_id=${ctx.params.id}`;
- const { list, title } = await utils.fetchMain(link, 'body > table > tbody > tr > td:nth-child(2) > div.xjr_list > ul > li');
-
- ctx.state.data = {
- title: `${title} - 官网 - 上海立信会计金融学院`,
- link,
- description: `${title} - 官网 - 上海立信会计金融学院`,
- item: await utils.fetchDetail(list, baseurl, 'body > table > tbody > tr > td:nth-child(2) > div.xjr_content', ctx.cache),
- };
-};
diff --git a/lib/routes-deprecated/universities/slu/utils.js b/lib/routes-deprecated/universities/slu/utils.js
deleted file mode 100644
index 94f347a8637e..000000000000
--- a/lib/routes-deprecated/universities/slu/utils.js
+++ /dev/null
@@ -1,62 +0,0 @@
-const dayjs = require('dayjs');
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = {
- fetchMain: async (url, dataElement) => {
- const response = await got(url);
- const $ = cheerio.load(response.data);
- // 获取列表
- return {
- list: $(dataElement)
- .map((i, e) => ({
- href: $(e).children('a').attr('href'),
- publish_date: $(e).children('span').text(),
- }))
- .get(),
- title: $('title').text(),
- };
- },
- fetchDetail: (list, baseUrl, contentElement, cache) =>
- // 定义输出的item
- Promise.all(
- list.map(async (item) => {
- let { href } = item;
- const { publish_date } = item;
- if (href.indexOf('http') !== 0) {
- href = baseUrl + href;
- }
- const site_cache = await cache.get(href); // 得到全局中的缓存信息
- // 判断缓存是否存在,如果存在即跳过此次获取的信息
-
- if (site_cache) {
- return JSON.parse(site_cache);
- }
-
- // 获取详情页面的介绍
- const detail_response = await got(href);
- const $ = cheerio.load(detail_response.data);
- const title = $('title').text();
- let detail_content = $(contentElement).html();
-
- if (!detail_content) {
- // Unable to extract content
- // this might be caused by external website referenced
- // or this is a file
- detail_content = `无法解析公告, 这可能是因为这是一个外部链接或者文件. 请点击查看`;
- }
-
- // 设置 RSS feed item
- const single = {
- title,
- link: href,
- description: detail_content,
- pubDate: dayjs(`${publish_date} +0800`, 'YYYY-MM-DD ZZ'),
- };
-
- // 设置缓存
- cache.set(href, JSON.stringify(single));
- return single;
- })
- ),
-};
diff --git a/lib/routes-deprecated/universities/slu/xsc.js b/lib/routes-deprecated/universities/slu/xsc.js
deleted file mode 100644
index d121dbc09027..000000000000
--- a/lib/routes-deprecated/universities/slu/xsc.js
+++ /dev/null
@@ -1,14 +0,0 @@
-const utils = require('./utils');
-const baseurl = 'http://xsc.lixin.edu.cn';
-
-module.exports = async (ctx) => {
- const link = baseurl + `/info/iList.jsp?cat_id=${ctx.params.id}`;
- const { list, title } = await utils.fetchMain(link, 'body > div.details > div.contentright > div.rightlist > ul > li');
-
- ctx.state.data = {
- title: `${title} - 学生处 - 上海立信会计金融学院`,
- link,
- description: `${title} - 学生处 - 上海立信会计金融学院`,
- item: await utils.fetchDetail(list, baseurl, 'body > div.neirong > div.rong', ctx.cache),
- };
-};
diff --git a/lib/routes-deprecated/universities/swufe/seie/index.js b/lib/routes-deprecated/universities/swufe/seie/index.js
deleted file mode 100644
index f968aa8b4294..000000000000
--- a/lib/routes-deprecated/universities/swufe/seie/index.js
+++ /dev/null
@@ -1,71 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const url = require('url');
-
-const listUrl = 'https://it.swufe.edu.cn/index/';
-const baseUrl = 'https://it.swufe.edu.cn/';
-
-const map = new Map([
- ['xyxw', { title: '西南财经大学经济信息工程学院 -- 学院新闻', suffix: 'xyxw.htm' }],
- ['tzgg', { title: '西南财经大学经济信息工程学院 -- 通知公告', suffix: 'tzgg.htm' }],
-]);
-
-module.exports = async (ctx) => {
- const type = ctx.params.type || 'tzgg';
- const suffix = map.get(type).suffix;
-
- const link = listUrl + suffix;
-
- const response = await got.get(link);
-
- const data = response.data;
-
- const $ = cheerio.load(data);
-
- const list = $('.article-list li a')
- .slice(0, 10)
- .map((_, elem) => {
- const info = {
- link: $(elem).attr('href').slice(2),
- title: $(elem).children('span').first().text(),
- date: $(elem).children('span').last().text(),
- };
- return info;
- })
- .get();
-
- const out = await Promise.all(
- list.map(async (info) => {
- const title = info.title;
- const date = info.date;
- const itemUrl = url.resolve(baseUrl, info.link);
-
- const cache = await ctx.cache.get(itemUrl);
- if (cache) {
- return JSON.parse(cache);
- }
-
- const response = await got.get(itemUrl);
- const $ = cheerio.load(response.data);
-
- const single = {
- title,
- link: itemUrl,
- description: $('.article-main')
- .html()
- .replaceAll('src="/', `src="${url.resolve(baseUrl, '.')}`)
- .trim(),
- pubDate: new Date(date).toUTCString(),
- };
- ctx.cache.set(itemUrl, JSON.stringify(single));
- return single;
- })
- );
-
- ctx.state.data = {
- title: map.get(type).title,
- link,
- description: '西南财经大学经济信息工程学院RSS',
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/universities/swust/cs.js b/lib/routes-deprecated/universities/swust/cs.js
deleted file mode 100644
index caa32f76c9e9..000000000000
--- a/lib/routes-deprecated/universities/swust/cs.js
+++ /dev/null
@@ -1,77 +0,0 @@
-const cheerio = require('cheerio');
-const { instance } = require('./helper');
-const host = 'http://www.cs.swust.edu.cn/';
-
-module.exports = async (ctx) => {
- const type = ctx.params.type || '1';
- let info;
- let word;
- switch (type) {
- case '2':
- info = '学术动态';
- word = 'academic';
-
- break;
-
- case '3':
- info = '通知公告';
- word = 'notice';
-
- break;
-
- case '4':
- info = '教研动态';
- word = 'Teach_Research';
-
- break;
-
- case '1':
- default:
- info = '新闻动态';
- word = 'news';
- break;
- }
-
- const response = await instance.get(host + word);
- const $ = cheerio.load(response.body);
- const text = $('a', '.list.list3');
- const resultItems = await Promise.all(
- text.toArray().map(async (item) => {
- const $item = $(item);
- const link = host + $item.attr('href');
- let resultItem = {};
-
- const value = await ctx.cache.get(link);
-
- if (value) {
- resultItem = JSON.parse(value);
- } else {
- const date = $('.imgdesc', $item)
- .contents()
- .filter(function () {
- return this.nodeType === 3;
- })
- .text()
- .replace(']', '')
- .replace('[', '');
- resultItem = {
- title: $('.imgdesc', $item).find('.imgtitle').text(),
- description: $('.imgdesc', $item).find('.imgtext').text(),
- pubDate: new Date(date).toUTCString(),
- link,
- };
-
- ctx.cache.set(link, JSON.stringify(resultItem));
- }
- return resultItem;
- })
- );
-
- ctx.state.data = {
- allowEmpty: true,
- title: `西南科技大学 计科学院 ${info}`,
- link: host + word,
- description: `西南科技大学 计科学院 ${info}`,
- item: resultItems,
- };
-};
diff --git a/lib/routes-deprecated/universities/swust/helper.js b/lib/routes-deprecated/universities/swust/helper.js
deleted file mode 100644
index d3595b0ce62a..000000000000
--- a/lib/routes-deprecated/universities/swust/helper.js
+++ /dev/null
@@ -1,47 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-function evil(fn) {
- const Fn = Function; // 一个变量指向Function,防止有些前端编译工具报错
- return new Fn('return ' + fn)();
-}
-const userAgent = 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1';
-
-const instance = got.extend({
- headers: {
- 'User-Agent': userAgent,
- },
- hooks: {
- afterResponse: [
- (response) => {
- try {
- JSON.parse(response.body);
- return response;
- } catch {
- const $ = cheerio.load(response.body);
- const redirect = $('meta[http-equiv="refresh"]');
- if (!(redirect.length > 0)) {
- return response;
- }
- let [, url] = redirect.attr('content').split(';');
- url = url.trim();
- if (url.startsWith('url=')) {
- url = url.slice(4);
- }
-
- return instance.get({
- url,
- headers: {
- Referer: response.url,
- },
- });
- }
- },
- ],
- },
- mutableDefaults: true,
-});
-
-module.exports = {
- instance,
- evil,
-};
diff --git a/lib/routes-deprecated/universities/swust/jwc-news.js b/lib/routes-deprecated/universities/swust/jwc-news.js
deleted file mode 100644
index 1214859fceef..000000000000
--- a/lib/routes-deprecated/universities/swust/jwc-news.js
+++ /dev/null
@@ -1,45 +0,0 @@
-const { instance, evil } = require('./helper');
-
-const api = 'http://www.dean.swust.edu.cn/cms/portal/news.json';
-const host = 'http://www.dean.swust.edu.cn/';
-const page = 'http://www.dean.swust.edu.cn/news/';
-
-module.exports = async (ctx) => {
- const response = await instance.get(api);
- const data = evil(response.body);
-
- const resultItems = await Promise.all(
- data.map(async (item) => {
- const title = item.title;
- const date = item.outdate;
- const link = page + item.id;
- const author = item.publisher;
-
- let resultItem = {};
-
- const value = await ctx.cache.get(link);
- if (value) {
- resultItem = JSON.parse(value);
- } else {
- resultItem = {
- title,
- link,
- pubDate: new Date(date).toUTCString(),
- author,
- };
-
- ctx.cache.set(link, JSON.stringify(resultItem));
- }
-
- return resultItem;
- })
- );
-
- ctx.state.data = {
- allowEmpty: true,
- title: '西南科技大学教务处 新闻',
- link: host,
- description: '西南科技大学教务处 新闻',
- item: resultItems,
- };
-};
diff --git a/lib/routes-deprecated/universities/swust/jwc-notice.js b/lib/routes-deprecated/universities/swust/jwc-notice.js
deleted file mode 100644
index 47103fdfe43c..000000000000
--- a/lib/routes-deprecated/universities/swust/jwc-notice.js
+++ /dev/null
@@ -1,51 +0,0 @@
-const { instance, evil } = require('./helper');
-
-const api = 'http://www.dean.swust.edu.cn/cms/portal/notice.json';
-const page = 'http://www.dean.swust.edu.cn/notice/page/';
-const tag = 'http://www.dean.swust.edu.cn/notice/tag/';
-
-module.exports = async (ctx) => {
- const type = ctx.params.type || 1;
-
- const response = await instance.get(api);
- const responseData = evil(response.body);
- const data = responseData[type - 1];
-
- const info = data.name || '';
- const tag_url = data.id || '';
-
- const resultItems = await Promise.all(
- data.items.map(async (item) => {
- const link = page + item.id;
- const author = item.publisher;
- const date = item.outdate;
- const title = item.title;
-
- let resultItem = {};
-
- const value = await ctx.cache.get(link);
- if (value) {
- resultItem = JSON.parse(value);
- } else {
- resultItem = {
- title,
- link,
- pubDate: new Date(date).toUTCString(),
- author,
- };
-
- ctx.cache.set(link, JSON.stringify(resultItem));
- }
-
- return resultItem;
- })
- );
-
- ctx.state.data = {
- allowEmpty: true,
- title: '西南科技大学教务处 ' + info,
- link: tag + tag_url,
- description: `西南科技大学教务处 ${info}`,
- item: resultItems,
- };
-};
diff --git a/lib/routes-deprecated/universities/thu/career.js b/lib/routes-deprecated/universities/thu/career.js
deleted file mode 100644
index 60f8de9c7662..000000000000
--- a/lib/routes-deprecated/universities/thu/career.js
+++ /dev/null
@@ -1,57 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const { parseDate } = require('@/utils/parse-date');
-
-const base_url = 'https://career.cic.tsinghua.edu.cn/';
-const route = 'xsglxt/f/jyxt/anony/xxfb';
-
-module.exports = async (ctx) => {
- const list = await fetchPage(1);
-
- const title = '招聘信息';
- ctx.state.data = {
- title: '清华大学 - ' + title,
- link: base_url + route,
- description: '清华大学学生职业发展指导中心 - ' + title,
- item: await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const res = await got.get(item.link);
- const content = cheerio.load(res.data);
- item.description = content('div.sideleft.left, div.content.teacher').html();
- return item;
- })
- )
- ),
- };
-};
-
-async function fetchPage(page) {
- const response = await got({
- method: 'post',
- url: base_url + route,
- body: `pgno=${page}`,
- headers: {
- accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
- 'accept-language': 'zh-CN,zh;q=0.9',
- 'cache-control': 'max-age=0',
- 'content-type': 'application/x-www-form-urlencoded',
- 'proxy-connection': 'keep-alive',
- 'upgrade-insecure-requests': '1',
- },
- });
-
- const $ = cheerio.load(response.data);
- return $('#ts_div .list li')
- .map((_, item) => {
- item = $(item);
- const a = item.find('a');
- const date = parseDate(item.find('span').text());
- return {
- title: a.text(),
- link: new URL(a.attr('ahref'), base_url),
- pubDate: date,
- };
- })
- .get();
-}
diff --git a/lib/routes-deprecated/universities/thu/index.js b/lib/routes-deprecated/universities/thu/index.js
deleted file mode 100644
index 4c31cd144d97..000000000000
--- a/lib/routes-deprecated/universities/thu/index.js
+++ /dev/null
@@ -1,102 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const resolve_url = require('url').resolve;
-
-const base_url = 'http://info.tsinghua.edu.cn/';
-const news_url = 'http://postinfo.tsinghua.edu.cn/f/';
-
-module.exports = async (ctx) => {
- const type = ctx.params.type;
- let title,
- path,
- kind = 0;
- switch (type) {
- case 'zhongyao':
- title = '重要公告';
- path = 'zhongyaogonggao/more';
- kind = 1;
- break;
- case 'keyan':
- title = '科研通知';
- path = 'keyantongzhi/more';
- break;
- case 'bangong':
- title = '办公通知';
- path = 'bangongtongzhi/more';
- break;
- case 'jiaowu':
- title = '教务公告';
- path = 'jiaowugonggao/more';
- break;
- case 'haibao':
- title = '海报列表';
- path = 'haibao/more';
- break;
- case 'yiqing':
- title = '疫情防控';
- path = 'yiqingfangkong/more';
- kind = 1;
- break;
- default:
- title = '重要公告';
- path = 'zhongyaogonggao/more';
- kind = 1;
- }
-
- const response = await got({
- method: 'get',
- url: news_url + path,
- headers: {
- Referer: base_url,
- },
- });
-
- const $ = cheerio.load(response.data);
- ctx.state.data =
- kind === 1
- ? {
- title: '清华大学 - ' + title,
- link: news_url + path,
- description: '清华大学内网信息发布平台 - ' + title,
- item: $('table>tbody>tr')
- .slice(0, 10)
- .map((_, elem) => ({
- link: get_link($('td>a', elem).attr('href'), news_url + path),
- title: get_title($('td>a', elem).text(), $('td', elem).text()),
- pubDate: new Date(
- $('td>font>span', elem)
- .text()
- .replace(/(\d+).(\d+).(\d+).(\d+)/, '2020-$1-$2T$3:$4')
- ).toUTCString(),
- }))
- .get(),
- }
- : {
- title: '清华大学 - ' + title,
- link: news_url + path,
- description: '清华大学内网信息发布平台 - ' + title,
- item: $('.cont_list>li')
- .slice(0, 10)
- .map((_, elem) => ({
- link: get_link($('a', elem).attr('href'), news_url + path),
- title: get_title($('a', elem).text(), $.text()),
- pubDate: new Date(
- $('time', elem)
- .text()
- .replace(/(\d+).(\d+).(\d+)/, '$1-$2-$3')
- ).toUTCString(),
- }))
- .get(),
- };
-};
-
-function get_link(url, alter_url) {
- return url === undefined ? alter_url : resolve_url(news_url, url);
-}
-
-function get_title(title, data) {
- if (title) {
- return title;
- }
- return data;
-}
diff --git a/lib/routes-deprecated/universities/usst/jwc.js b/lib/routes-deprecated/universities/usst/jwc.js
deleted file mode 100644
index e9dcc37c2033..000000000000
--- a/lib/routes-deprecated/universities/usst/jwc.js
+++ /dev/null
@@ -1,62 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const url = `http://jwc.usst.edu.cn`;
- const response = await got({
- method: 'get',
- url,
- });
- const $ = cheerio.load(response.data);
- $('td[width="30px"]').remove();
- $('td[width="195"]').remove();
- // ## 获取列表
- const list = $('#container-2 > .inner .post1 > .con > ul > li ').get();
- // ## 定义输出的item
- const out = await Promise.all(
- // ### 遍历列表,筛选出自己想要的内容
- list.map(async (item) => {
- const itemSingle = cheerio.load(item);
- const title = itemSingle.text();
- const re = /]*href=["']([^"]*)["'][^>]*>(.*?)<\/a>/g;
- let singleUrl = '';
- if (re.exec(itemSingle.html()) !== null) {
- singleUrl = RegExp.$1;
- }
- if (singleUrl.search('http') === -1) {
- singleUrl = `http://jwc.usst.edu.cn/` + singleUrl;
- }
- const cache = await ctx.cache.get(singleUrl); // ### 得到全局中的缓存信息
- // ### 判断缓存是否存在,如果存在即跳过此次获取的信息
- if (cache) {
- return JSON.parse(cache);
- }
- // 获取详情页面的介绍
- const detail_response = await got({
- method: 'get',
- url: singleUrl,
- });
- const $ = cheerio.load(detail_response.data);
- const detail_content = $('.wp_articlecontent').html();
- // ### 设置 RSS feed item
- const single = {
- title,
- link: singleUrl,
- // author,
- description: detail_content,
- // pubDate: updateDate,
- };
- // // ### 设置缓存
- ctx.cache.set(singleUrl, JSON.stringify(single));
- return single;
- // }
- })
- );
-
- ctx.state.data = {
- title: `上海理工大学 - 教务处`,
- link: 'http://jwc.usst.edu.cn/',
- description: `上海理工大学 - 教务处`,
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/universities/utdallas/isso.js b/lib/routes-deprecated/universities/utdallas/isso.js
deleted file mode 100644
index 6918b569d650..000000000000
--- a/lib/routes-deprecated/universities/utdallas/isso.js
+++ /dev/null
@@ -1,54 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-const notice_type = {
- isso: { title: 'UTDallas - International Student Services', url: 'https://www.utdallas.edu/ic/isso/' },
-};
-
-module.exports = async (ctx) => {
- // const type = ctx.params.type || 'isso';
- const type = 'isso';
- // 发起 HTTP GET 请求
- const response = await got({
- method: 'get',
- headers: {
- 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36',
- // cookie: await getCookie(ctx),
- },
- url: notice_type[type].url,
- });
-
- const $ = cheerio.load(response.data);
-
- const list = $('.c6 > p ')
- .map(function () {
- if ($(this).find('span').text() === '') {
- return null;
- } else {
- const info = {
- title: $(this).find('span').text(),
- description: $(this).next().text(),
- // link: ,
- // date: new Date().toUTCString(),
- };
- return info;
- }
- })
- .get();
-
- // console.log(list);
-
- const out = list.map((item) => ({
- title: item.title,
- description: item.description,
- }));
-
- // console.log(out);
-
- ctx.state.data = {
- title: notice_type[type].title,
- description: notice_type[type].title,
- link: notice_type[type].url,
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/universities/wzbc/news.js b/lib/routes-deprecated/universities/wzbc/news.js
deleted file mode 100644
index 2256a9ce8c92..000000000000
--- a/lib/routes-deprecated/universities/wzbc/news.js
+++ /dev/null
@@ -1,100 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-const host = 'http://www.wzbc.edu.cn';
-
-const parserAbb = ($) => {
- const items = $('.newslist li').slice(0, 10);
- return {
- title: $('title').text(),
- item:
- items &&
- items
- .map((index, item) => {
- item = $(item);
- return {
- title: item.text(),
- link: `${host}${item.find('a').attr('href')}`,
- description: item.text(),
- pubDate: item.find('span').text(),
- };
- })
- .get(),
- };
-};
-
-const parserFull = ($) => {
- const items = $('.picnewlist li').slice(0, 10);
- return {
- title: $('title').text(),
- item:
- items &&
- items
- .map((index, item) => {
- item = $(item);
- return {
- title: item.find('.title').text(),
- link: `${host}${item.find('a').attr('href')}`,
- description: item.find('p').text(),
- pubDate: item.find('.time').text(),
- };
- })
- .get(),
- };
-};
-
-const MAP = {
- // 校园新闻
- news: {
- path: 'Col80',
- func: parserFull,
- },
- // 媒体商院
- media: {
- path: 'Col98',
- func: parserFull,
- },
- // 通知公告
- notice: {
- path: 'Col13',
- func: parserAbb,
- },
- // 人才招聘
- jobs: {
- path: 'Col14',
- func: parserAbb,
- },
- // 行事历
- workday: {
- path: 'Col282',
- func: parserAbb,
- },
- // 招标公告
- tender: {
- path: 'Col541',
- func: parserAbb,
- },
- // 学术动态
- activity: {
- path: 'Col16',
- func: parserAbb,
- },
-};
-
-module.exports = async (ctx) => {
- let type = ctx.params && ctx.params.type;
-
- if (!(type in MAP)) {
- type = 'notice';
- }
-
- const response = await got({
- method: 'get',
- url: `${host}/Col/${MAP[type].path}/Index.aspx`,
- headers: {
- Referer: host,
- },
- });
- const $ = cheerio.load(response.data);
- ctx.state.data = MAP[type].func($);
-};
diff --git a/lib/routes-deprecated/universities/xmu/aero.js b/lib/routes-deprecated/universities/xmu/aero.js
deleted file mode 100644
index fd56adfb1712..000000000000
--- a/lib/routes-deprecated/universities/xmu/aero.js
+++ /dev/null
@@ -1,63 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const { parseDate } = require('@/utils/parse-date');
-
-const host = 'https://aerospace.xmu.edu.cn';
-
-const urlMap = {
- tzgg: '/xydt/tzgg.htm',
- bksjw: '/jwxx/bksjw.htm',
- yjsjw: '/jwxx/yjsjw.htm',
-};
-
-const titleMap = {
- tzgg: '通知公告',
- bksjw: '本科生教务',
- yjsjw: '研究生教务',
-};
-
-module.exports = async (ctx) => {
- const type = ctx.params.type || '';
- const response = await got({
- method: 'get',
- url: host + urlMap[type],
- });
- const data = response.data;
-
- const $ = cheerio.load(data, { decodeEntities: false });
-
- const list = $('body > div.centers > div.other_right > ul > li')
- .map((index, item) => {
- item = $(item);
- const $a = item.find('a');
- return {
- title: $a.attr('title'),
- link: host + $a.attr('href').slice(2),
- };
- })
- .get();
-
- const result = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: item.link,
- });
- const content = cheerio.load(detailResponse.data, { decodeEntities: false });
-
- item.description = content('#vsb_content > div').html();
-
- const date = content('body > div.centers > div.other_right > form > div > div.news-info.clearfix > span:nth-child(2)').text();
- item.pubDate = parseDate(date, '发布时间:YYYY年MM月DD日');
-
- return item;
- })
- )
- );
- ctx.state.data = {
- title: titleMap[type],
- link: host,
- item: result,
- };
-};
diff --git a/lib/routes-deprecated/universities/xynu/zkb/index.js b/lib/routes-deprecated/universities/xynu/zkb/index.js
deleted file mode 100644
index b44fb8d8a073..000000000000
--- a/lib/routes-deprecated/universities/xynu/zkb/index.js
+++ /dev/null
@@ -1,58 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const baseUrl = 'http://zkb.xynu.edu.cn/';
- const categoryList = [
- // 分类栏目
- 'zkzy', // 主考专业
- 'gzzd', // 规章制度
- 'sjkc', // 实践课程
- 'bylw', // 毕业论文
- 'xsxw', // 学士学位
- 'zkby', // 自考毕业
- 'zkjc', // 自考教材
- 'zkzn', // 自考指南
- 'lxwm', // 联系我们
- // 首页板块
- 'zkzx', // 自考资讯
- 'bmzn', // 报名指南
- 'rcap', // 日程安排
- 'xsrm', // 新生入门
- 'zkmk', // 转考免考
- 'fxzl', // 复习资料
- ];
- const category = ctx.params.category;
- const path = categoryList.includes(category) ? `${category}.htm` : 'zkzx.htm';
-
- const response = await got({
- method: 'get',
- url: baseUrl + path,
- });
-
- const $ = cheerio.load(response.data);
- const list = $('.gg ul > li');
- const categoryTitle = $('title').text();
-
- ctx.state.data = {
- title: categoryTitle,
- link: baseUrl + path,
- item:
- list &&
- list
- .map((index, item) => {
- item = $(item);
- let link = item.find('a').attr('href');
- if (!link.startsWith('http')) {
- link = baseUrl + link;
- }
- return {
- title: item.find('a').text(),
- description: item.find('a').text(),
- link,
- pubDate: item.find('span').text(),
- };
- })
- .get(),
- };
-};
diff --git a/lib/routes-deprecated/universities/ynnu/edu/base64.js b/lib/routes-deprecated/universities/ynnu/edu/base64.js
deleted file mode 100644
index a73a8c08a036..000000000000
--- a/lib/routes-deprecated/universities/ynnu/edu/base64.js
+++ /dev/null
@@ -1,354 +0,0 @@
-/* eslint-disable unicorn/no-array-push-push */
-/* eslint-disable unicorn/prefer-string-slice */
-/* eslint-disable unicorn/prefer-spread */
-// https://gitee.com/slice30k/base64-js
-
-const BASE64_MAPPING = [
- 'A',
- 'B',
- 'C',
- 'D',
- 'E',
- 'F',
- 'G',
- 'H',
- 'I',
- 'J',
- 'K',
- 'L',
- 'M',
- 'N',
- 'O',
- 'P',
- 'Q',
- 'R',
- 'S',
- 'T',
- 'U',
- 'V',
- 'W',
- 'X',
- 'Y',
- 'Z',
- 'a',
- 'b',
- 'c',
- 'd',
- 'e',
- 'f',
- 'g',
- 'h',
- 'i',
- 'j',
- 'k',
- 'l',
- 'm',
- 'n',
- 'o',
- 'p',
- 'q',
- 'r',
- 's',
- 't',
- 'u',
- 'v',
- 'w',
- 'x',
- 'y',
- 'z',
- '0',
- '1',
- '2',
- '3',
- '4',
- '5',
- '6',
- '7',
- '8',
- '9',
- '+',
- '/',
-];
-const URLSAFE_BASE64_MAPPING = [
- 'A',
- 'B',
- 'C',
- 'D',
- 'E',
- 'F',
- 'G',
- 'H',
- 'I',
- 'J',
- 'K',
- 'L',
- 'M',
- 'N',
- 'O',
- 'P',
- 'Q',
- 'R',
- 'S',
- 'T',
- 'U',
- 'V',
- 'W',
- 'X',
- 'Y',
- 'Z',
- 'a',
- 'b',
- 'c',
- 'd',
- 'e',
- 'f',
- 'g',
- 'h',
- 'i',
- 'j',
- 'k',
- 'l',
- 'm',
- 'n',
- 'o',
- 'p',
- 'q',
- 'r',
- 's',
- 't',
- 'u',
- 'v',
- 'w',
- 'x',
- 'y',
- 'z',
- '0',
- '1',
- '2',
- '3',
- '4',
- '5',
- '6',
- '7',
- '8',
- '9',
- '-',
- '_',
-];
-
-const _toBinary = function (ascii) {
- const binary = [];
- while (ascii > 0) {
- const b = ascii % 2;
- ascii = Math.floor(ascii / 2);
- binary.push(b);
- }
- binary.reverse();
- return binary;
-};
-
-const _toDecimal = function (binary) {
- let dec = 0;
- let p = 0;
- for (let i = binary.length - 1; i >= 0; --i) {
- const b = binary[i];
- if (b === 1) {
- dec += Math.pow(2, p);
- }
- ++p;
- }
- return dec;
-};
-
-const _toUTF8Binary = function (c, binaryArray) {
- const mustLen = 8 - (c + 1) + (c - 1) * 6;
- const fatLen = binaryArray.length;
- let diff = mustLen - fatLen;
- while (--diff >= 0) {
- binaryArray.unshift(0);
- }
- const binary = [];
- let _c = c;
- while (--_c >= 0) {
- binary.push(1);
- }
- binary.push(0);
- let i = 0;
- const len = 8 - (c + 1);
- for (; i < len; ++i) {
- binary.push(binaryArray[i]);
- }
-
- for (let j = 0; j < c - 1; ++j) {
- binary.push(1);
- binary.push(0);
- let sum = 6;
- while (--sum >= 0) {
- binary.push(binaryArray[i++]);
- }
- }
- return binary;
-};
-
-const _toBinaryArray = function (str) {
- let binaryArray = [];
- let i = 0;
- const len = str.length;
- for (; i < len; ++i) {
- const unicode = str.charCodeAt(i);
- const _tmpBinary = _toBinary(unicode);
- if (unicode < 0x80) {
- let _tmpdiff = 8 - _tmpBinary.length;
- while (--_tmpdiff >= 0) {
- _tmpBinary.unshift(0);
- }
- binaryArray = binaryArray.concat(_tmpBinary);
- } else if (unicode >= 0x80 && unicode <= 0x7ff) {
- binaryArray = binaryArray.concat(_toUTF8Binary(2, _tmpBinary));
- } else if (unicode >= 0x800 && unicode <= 0xffff) {
- // UTF-8 3byte
- binaryArray = binaryArray.concat(_toUTF8Binary(3, _tmpBinary));
- } else if (unicode >= 0x1_00_00 && unicode <= 0x1f_ff_ff) {
- // UTF-8 4byte
- binaryArray = binaryArray.concat(_toUTF8Binary(4, _tmpBinary));
- } else if (unicode >= 0x20_00_00 && unicode <= 0x3_ff_ff_ff) {
- // UTF-8 5byte
- binaryArray = binaryArray.concat(_toUTF8Binary(5, _tmpBinary));
- } else if (unicode >= 4_000_000 && unicode <= 0x7f_ff_ff_ff) {
- // UTF-8 6byte
- binaryArray = binaryArray.concat(_toUTF8Binary(6, _tmpBinary));
- }
- }
- return binaryArray;
-};
-
-const _toUnicodeStr = function (binaryArray) {
- let unicode;
- let unicodeBinary = [];
- let str = '';
- let i = 0;
- const len = binaryArray.length;
- for (; i < len; i++) {
- if (binaryArray[i] === 0) {
- unicode = _toDecimal(binaryArray.slice(i, i + 8));
- str += String.fromCharCode(unicode);
- i += 8;
- } else {
- let sum = 0;
- while (i < len) {
- if (binaryArray[i] === 1) {
- ++sum;
- } else {
- break;
- }
- ++i;
- }
- unicodeBinary = unicodeBinary.concat(binaryArray.slice(i + 1, i + 8 - sum));
- i += 8 - sum;
- while (sum > 1) {
- unicodeBinary = unicodeBinary.concat(binaryArray.slice(i + 2, i + 8));
- i += 8;
- --sum;
- }
- unicode = _toDecimal(unicodeBinary);
- str += String.fromCharCode(unicode);
- unicodeBinary = [];
- }
- }
- return str;
-};
-
-const _encode = function (str, url_safe) {
- const base64_Index = [];
- const binaryArray = _toBinaryArray(str);
- const dictionary = url_safe ? URLSAFE_BASE64_MAPPING : BASE64_MAPPING;
-
- let extra_Zero_Count = 0;
- for (let i = 0, len = binaryArray.length; i < len; i += 6) {
- const diff = i + 6 - len;
- if (diff === 2) {
- extra_Zero_Count = 2;
- } else if (diff === 4) {
- extra_Zero_Count = 4;
- }
- let _tmpExtra_Zero_Count = extra_Zero_Count;
- while (--_tmpExtra_Zero_Count >= 0) {
- binaryArray.push(0);
- }
- base64_Index.push(_toDecimal(binaryArray.slice(i, i + 6)));
- }
-
- let base64 = '';
- for (let i = 0, len = base64_Index.length; i < len; ++i) {
- base64 += dictionary[base64_Index[i]];
- }
-
- for (let i = 0, len = extra_Zero_Count / 2; i < len; ++i) {
- base64 += '=';
- }
- return base64;
-};
-
-const _decode = function (_base64Str, url_safe) {
- const _len = _base64Str.length;
- let extra_Zero_Count = 0;
- const dictionary = url_safe ? URLSAFE_BASE64_MAPPING : BASE64_MAPPING;
-
- if (_base64Str.charAt(_len - 1) === '=') {
- if (_base64Str.charAt(_len - 2) === '=') {
- // 两个等号说明补了4个0
- extra_Zero_Count = 4;
- _base64Str = _base64Str.substring(0, _len - 2);
- } else {
- // 一个等号说明补了2个0
- extra_Zero_Count = 2;
- _base64Str = _base64Str.substring(0, _len - 1);
- }
- }
-
- let binaryArray = [];
- let i = 0;
- const len = _base64Str.length;
- for (; i < len; ++i) {
- const c = _base64Str.charAt(i);
- let j = 0;
- const size = dictionary.length;
- for (; j < size; ++j) {
- if (c === dictionary[j]) {
- const _tmp = _toBinary(j);
-
- /* 不足6位的补0*/
- const _tmpLen = _tmp.length;
- if (6 - _tmpLen > 0) {
- for (let k = 6 - _tmpLen; k > 0; --k) {
- _tmp.unshift(0);
- }
- }
- binaryArray = binaryArray.concat(_tmp);
- break;
- }
- }
- }
- if (extra_Zero_Count > 0) {
- binaryArray = binaryArray.slice(0, binaryArray.length - extra_Zero_Count);
- }
- const str = _toUnicodeStr(binaryArray);
- return str;
-};
-
-const __BASE64 = {
- encode(str) {
- return _encode(str, false);
- },
- decode(base64Str) {
- return _decode(base64Str, false);
- },
- urlsafe_encode(str) {
- return _encode(str, true);
- },
- urlsafe_decode(base64Str) {
- return _decode(base64Str, true);
- },
-};
-
-module.exports = __BASE64;
diff --git a/lib/routes-deprecated/universities/ynnu/edu/news.js b/lib/routes-deprecated/universities/ynnu/edu/news.js
deleted file mode 100644
index 36b900341043..000000000000
--- a/lib/routes-deprecated/universities/ynnu/edu/news.js
+++ /dev/null
@@ -1,109 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const { parseDate } = require('@/utils/parse-date');
-const { encode } = require('./base64');
-const timezone = require('@/utils/timezone');
-
-module.exports = async (ctx) => {
- const baseUrl = 'https://ostudy.ynnedu.cn/';
- const denylist = new Set(['ynnu-mv.html', 'https://chjiao.ynnu.edu.cn/zsgz/zsjz.htm', 'https://chjiao.ynnu.edu.cn/info/1006/1404.htm', 'https://chjiao.ynnu.edu.cn/zsgz/dksw.htm']);
- const { body } = await got(baseUrl);
- const $index = cheerio.load(body);
- ctx.state.data = {
- title: '云南师范大学继续教育学院 #通知',
- link: baseUrl,
- item: await Promise.all([
- // 顶部幻灯片抓取
- Promise.all(
- $index('div[carousel-item] > div')
- .filter((_, element) => !denylist.has($index(element).find('a').attr('href')))
- .map((_, element) => {
- const $element = $index(element);
- const $a = $element.find('a');
- let link = $a.attr('href');
- if (!$a.attr('href').startsWith('http')) {
- link = new URL(link, baseUrl).toString();
- }
- if (link.endsWith('.pdf')) {
- return Promise.resolve({
- title: $element.find('p').text(),
- link,
- });
- }
- return ctx.cache.tryGet(link, async () => {
- const { body: articleBody } = await got(link);
- const $article = cheerio.load(articleBody, { decodeEntities: false });
- return {
- title: $article('#noticeSubject, #inform-content > div:nth-child(1)').text(),
- link,
- description: $article('#noticeContent, .oinform-content').html() + $article('.notice-attachment').html(),
- };
- });
- })
- .get()
- ),
- // 中部新闻抓取
- Promise.all(
- cheerio
- .load($index('#serviceInform-tpl').html())('.news-li:not(:last-child)')
- .filter((_, element) => !denylist.has($index(element).find('a').attr('href')))
- .map((_, element) => {
- const $element = $index(element);
- const $a = $element.find('a');
- let link = $a.attr('href');
- if (!$a.attr('href').startsWith('http')) {
- link = new URL(link, baseUrl).toString();
- }
- if (link.endsWith('.pdf')) {
- return Promise.resolve({
- title: $a.text(),
- link,
- pubDate: parseDate($element.find('span').text(), '发布时间: YYYY-MM-DD'),
- });
- }
- return ctx.cache.tryGet(link, async () => {
- const { body: articleBody } = await got(link);
- const $article = cheerio.load(articleBody, { decodeEntities: false });
- return {
- title: $article('#noticeSubject, #inform-content > div:nth-child(1)').text(),
- link,
- description: $article('#noticeContent, .oinform-content').html() + $article('.notice-attachment').html(),
- pubDate: parseDate($element.find('span').text(), '发布时间: YYYY-MM-DD'),
- };
- });
- })
- .get()
- ),
- got(`${baseUrl}/serviceNotice/queryRecentServiceNotices`, {
- method: 'post',
- headers: {
- 'content-type': 'application/x-www-form-urlencoded',
- },
- body: 'top=10&organizationCode=ORG-CN-EDU-YNNU',
- }).then(({ data: { data } }) =>
- data.map(({ createTime, noticeSubject, noticeContent, noticeCode, publishUnit }) => ({
- title: noticeSubject,
- description: noticeContent,
- pubDate: timezone(parseDate(createTime), +8),
- link: `${baseUrl}/notice-detail.html?c=${encode(noticeCode)}`,
- author: publishUnit,
- }))
- ),
- got(`${baseUrl}/newsInformation/queryRecentNewsInformations`, {
- method: 'post',
- headers: {
- 'content-type': 'application/x-www-form-urlencoded',
- },
- body: 'top=10&organizationCode=ORG-CN-EDU-YNNU',
- }).then(({ data: { data } }) =>
- data.map(({ createTime, title, newsContent, newsCode, publishUnit }) => ({
- title,
- description: newsContent,
- pubDate: timezone(parseDate(createTime), +8),
- link: `${baseUrl}/news-detail.html?c=${encode(newsCode)}`,
- author: publishUnit,
- }))
- ),
- ]).then((items) => items.flat()),
- };
-};
diff --git a/lib/routes-deprecated/universities/ynu/grs/qttz.js b/lib/routes-deprecated/universities/ynu/grs/qttz.js
deleted file mode 100644
index a169f9a7495e..000000000000
--- a/lib/routes-deprecated/universities/ynu/grs/qttz.js
+++ /dev/null
@@ -1,35 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const utils = require('../utils');
-
-// 云南大学研究生院其他通知
-module.exports = async (ctx) => {
- const host = 'http://www.grs.ynu.edu.cn/';
- const category = ctx.params.category;
- const dep = ['招生工作', '研究生培养', '质量管理', '学位工作', '综合办公室', '相关下载'];
-
- const response = await got({
- method: 'get',
- url: 'http://www.grs.ynu.edu.cn/index.htm',
- headers: {
- Referer: host,
- },
- });
-
- const $ = cheerio.load(response.data);
- const list = $('#con3:nth-of-type(' + category + ') ul li')
- .slice(0, 6)
- .map((i, e) => ({
- path: $('a', e).attr('href'),
- title: $('a', e).attr('title'),
- author: dep[category - 1],
- }))
- .get();
- const out = await utils.processPages({ list, caches: ctx.cache, host, department: 'grs' });
- ctx.state.data = {
- title: '云南大学研究生院' + dep[category - 1] + '通知',
- link: host,
- description: '云南大学研究生院' + dep[category - 1],
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/universities/ynu/grs/zytz.js b/lib/routes-deprecated/universities/ynu/grs/zytz.js
deleted file mode 100644
index 5c9e4a9f6bb7..000000000000
--- a/lib/routes-deprecated/universities/ynu/grs/zytz.js
+++ /dev/null
@@ -1,34 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const utils = require('../utils');
-
-// 云南大学研究生院重要通知
-module.exports = async (ctx) => {
- const host = 'http://www.grs.ynu.edu.cn/';
-
- const response = await got({
- method: 'get',
- url: 'http://www.grs.ynu.edu.cn/index.htm',
- headers: {
- Referer: host,
- },
- });
-
- const $ = cheerio.load(response.data);
- const list = $('#news table table tbody tr')
- .slice(0, 9)
- .map((i, e) => ({
- path: $('td a', e).attr('href'),
- title: $('td a', e).attr('title'),
- author: '研究生院',
- }))
- .get();
- const out = await utils.processPages({ list, caches: ctx.cache, host, department: 'grs' });
-
- ctx.state.data = {
- title: '云南大学研究生院重要通知',
- link: host + 'zytz.htm',
- description: '云南大学研究生院重要通知',
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/universities/ynu/home/main.js b/lib/routes-deprecated/universities/ynu/home/main.js
deleted file mode 100644
index e6156ad52f50..000000000000
--- a/lib/routes-deprecated/universities/ynu/home/main.js
+++ /dev/null
@@ -1,34 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const utils = require('../utils');
-
-// 云南大学主页通知公告
-module.exports = async (ctx) => {
- const host = 'http://www.ynu.edu.cn/';
-
- const response = await got({
- method: 'get',
- url: 'http://www.ynu.edu.cn/tzgg.htm',
- headers: {
- Referer: host,
- },
- });
-
- const $ = cheerio.load(response.data);
- const list = $('.list_cont_rigB.fl ul li')
- .slice(0, 8)
- .map((i, e) => ({
- path: $('a', e).attr('href'),
- title: $('a', e).attr('title'),
- author: '云南大学',
- }))
- .get();
-
- const out = await utils.processPages({ list, caches: ctx.cache, host, department: 'home' });
- ctx.state.data = {
- title: '云南大学主页通知公告',
- link: host,
- description: '云南大学主页通知公告',
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/universities/ynu/jwc/zytz.js b/lib/routes-deprecated/universities/ynu/jwc/zytz.js
deleted file mode 100644
index a96b38bf5327..000000000000
--- a/lib/routes-deprecated/universities/ynu/jwc/zytz.js
+++ /dev/null
@@ -1,41 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const utils = require('../utils');
-
-// 云南大学教务处主要通知
-module.exports = async (ctx) => {
- const host = 'http://www.jwc.ynu.edu.cn/';
- const category = ctx.params.category;
- const dep = ['教务科', '学籍科', '教学研究科', '实践教学科'];
-
- const response = await got({
- method: 'get',
- url: 'http://www.jwc.ynu.edu.cn/',
- headers: {
- Referer: host,
- },
- });
-
- const $ = cheerio.load(response.data);
- const firstRow = category < 3 ? 0 : 1;
- const secondRow = category % 2 === 0 ? 2 : 1;
-
- const list = $('.index-row3')
- .eq(firstRow)
- .find('.c' + secondRow + ' .text-list ul li')
- .slice(0, 8)
- .map((i, e) => ({
- path: $('a', e).attr('href'),
- title: $('a', e).attr('title'),
- author: dep[category - 1],
- }))
- .get();
-
- const out = await utils.processPages({ list, caches: ctx.cache, host, department: 'jwc' });
- ctx.state.data = {
- title: '云南大学教务处' + dep[category - 1] + '通知',
- link: host,
- description: '云南大学教务处' + dep[category - 1],
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/universities/ynu/utils.js b/lib/routes-deprecated/universities/ynu/utils.js
deleted file mode 100644
index 3e39b3a0cf5f..000000000000
--- a/lib/routes-deprecated/universities/ynu/utils.js
+++ /dev/null
@@ -1,64 +0,0 @@
-const url = require('url');
-const cheerio = require('cheerio');
-const got = require('@/utils/got');
-
-const processPages = ({ list, caches, host, department }) =>
- Promise.all(
- list.map(async (item) => {
- const { path, title, author } = item;
- const link = path.includes('http://') ? path : host + path;
- const cache = await caches.get(link);
- if (cache) {
- return JSON.parse(cache);
- }
- const response = await got({
- method: 'get',
- url: link,
- headers: {
- Referer: host,
- },
- });
-
- const $ = cheerio.load(response.data);
- let dateString = '';
- switch (department) {
- case 'grs':
- dateString = $('#times').text().slice(5);
- break;
- case 'home':
- dateString = $('.dateAadDian').text().slice(6, 17).replace(/年/, '-').replace(/月/, '-').replace(/日/, '');
- break;
- case 'jwc':
- dateString = $('.taitshj').text().slice(5, 15);
- }
- let description =
- $('.v_news_content').html() &&
- $('.v_news_content')
- .html()
- .replaceAll('src="/', `src="${url.resolve(host, '.')}`)
- .replaceAll('href="/', `href="${url.resolve(host, '.')}`)
- .trim();
- if (department === 'jwc' && $('#vsb_content').siblings().has('ul li').length > 0) {
- const attachment = $('#vsb_content')
- .siblings('ul')
- .html()
- .replaceAll('src="/', `src="${url.resolve(host, '.')}`)
- .replaceAll('href="/', `href="${url.resolve(host, '.')}`)
- .trim();
- description = [...description, '\n' + attachment];
- }
- const single = {
- pubDate: new Date(dateString).toUTCString(),
- author,
- link,
- title,
- description,
- };
- caches.set(link, JSON.stringify(single));
- return single;
- })
- );
-
-module.exports = {
- processPages,
-};
diff --git a/lib/routes-deprecated/universities/yzu/home.js b/lib/routes-deprecated/universities/yzu/home.js
deleted file mode 100644
index 9bbcd7d74fb6..000000000000
--- a/lib/routes-deprecated/universities/yzu/home.js
+++ /dev/null
@@ -1,83 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const url = require('url');
-const host = 'http://www.yzu.edu.cn/';
-
-const map = new Map([
- ['xxyw', { title: '扬州大学 -- 学校要闻', suffix: 'col/col37745/index.html', id: 37745 }],
- ['xyxw', { title: '扬州大学 -- 校园新闻', suffix: 'col/col37746/index.html', id: 37746 }],
- ['xxgg', { title: '扬州大学 -- 信息公告', suffix: 'col/col37747/index.html', id: 37747 }],
- ['xshd', { title: '扬州大学 -- 学术活动', suffix: 'col/col37748/index.html', id: 37748 }],
- ['mtyd', { title: '扬州大学 -- 媒体扬大', suffix: 'col/col45661/index.html', id: 45661 }],
-]);
-
-module.exports = async (ctx) => {
- const type = ctx.params.type;
- const suffix = map.get(type).suffix;
-
- const link = url.resolve(host, suffix);
- const response = await got({
- method: 'post',
- url: 'http://www.yzu.edu.cn/module/web/jpage/dataproxy.jsp?startrecord=1&endrecord=10&perpage=10',
- headers: {
- 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
- Accept: 'application/xml',
- },
- data: `columnid=${map.get(type).id}&unitid=54996`,
- });
- const $ = cheerio.load(response.data, { xmlMode: true });
-
- const list = $('record')
- .slice(0, 10)
- .map(function () {
- const $$ = cheerio.load($(this).html());
- const info = {
- title: $$('a').attr('title'),
- link: $$('a').attr('href'),
- date: $$('span').text(),
- };
- return info;
- })
- .get();
-
- const out = await Promise.all(
- list.map(async (info) => {
- const title = info.title;
- const date = info.date;
- const itemUrl = url.resolve(host, info.link);
-
- const cache = await ctx.cache.get(itemUrl);
- if (cache) {
- return JSON.parse(cache);
- }
-
- let description;
- if (itemUrl.includes('yzu.edu.cn/art')) {
- const response = await got.get(itemUrl);
- const $ = cheerio.load(response.data);
- description = $('#zoom')
- .html()
- .replaceAll('src="/', `src="${url.resolve(host, '.')}`)
- .trim();
- } else {
- description = '站外链接无法抓取全文';
- }
-
- const single = {
- title,
- link: itemUrl,
- description,
- pubDate: new Date(date).toUTCString(),
- };
- ctx.cache.set(itemUrl, JSON.stringify(single));
- return single;
- })
- );
-
- ctx.state.data = {
- title: map.get(type).title,
- link,
- description: '扬州大学 RSS',
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/universities/yzu/yjszs.js b/lib/routes-deprecated/universities/yzu/yjszs.js
deleted file mode 100644
index fbcb71ca4467..000000000000
--- a/lib/routes-deprecated/universities/yzu/yjszs.js
+++ /dev/null
@@ -1,81 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const url = require('url');
-const host = 'http://yjszs.yzu.edu.cn/';
-
-const map = new Map([
- ['tzgg', { title: '扬州大学研究生招生 -- 通知公告', suffix: 'col/col37091/index.html', id: 37091 }],
- ['bszs', { title: '扬州大学研究生招生 -- 博士招生', suffix: 'col/col37129/index.html', id: 37129 }],
- ['sszs', { title: '扬州大学研究生招生 -- 硕士招生', suffix: 'col/col37130/index.html', id: 37130 }],
-]);
-
-module.exports = async (ctx) => {
- const type = ctx.params.type;
- const suffix = map.get(type).suffix;
-
- const link = url.resolve(host, suffix);
- const response = await got({
- method: 'post',
- url: 'http://yjszs.yzu.edu.cn/module/web/jpage/dataproxy.jsp?startrecord=1&endrecord=10&perpage=10',
- headers: {
- 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
- Accept: 'application/xml',
- },
- data: `columnid=${map.get(type).id}&unitid=54996`,
- });
- const $ = cheerio.load(response.data, { xmlMode: true });
-
- const list = $('record')
- .slice(0, 10)
- .map(function () {
- const $$ = cheerio.load($(this).html());
- const info = {
- title: $$('a').attr('title'),
- link: $$('a').attr('href'),
- date: $$('span').text(),
- };
- return info;
- })
- .get();
-
- const out = await Promise.all(
- list.map(async (info) => {
- const title = info.title;
- const date = info.date;
- const itemUrl = url.resolve(host, info.link);
-
- const cache = await ctx.cache.get(itemUrl);
- if (cache) {
- return JSON.parse(cache);
- }
-
- let description;
- if (itemUrl.includes('yzu.edu.cn/art')) {
- const response = await got.get(itemUrl);
- const $ = cheerio.load(response.data);
- description = $('#zoom')
- .html()
- .replaceAll('src="/', `src="${url.resolve(host, '.')}`)
- .trim();
- } else {
- description = '站外链接无法抓取全文';
- }
-
- const single = {
- title,
- link: itemUrl,
- description,
- pubDate: new Date(date).toUTCString(),
- };
- ctx.cache.set(itemUrl, JSON.stringify(single));
- return single;
- })
- );
-
- ctx.state.data = {
- title: map.get(type).title,
- link,
- description: '扬州大学研究生招生 RSS',
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/universities/zjgsu/gsgg/scripts.js b/lib/routes-deprecated/universities/zjgsu/gsgg/scripts.js
deleted file mode 100644
index 90ba32dbfdb2..000000000000
--- a/lib/routes-deprecated/universities/zjgsu/gsgg/scripts.js
+++ /dev/null
@@ -1,35 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const iconv = require('iconv-lite');
-
-module.exports = async (ctx) => {
- const res = await got({
- method: 'get',
- url: 'http://jww.zjgsu.edu.cn/ArticleList.asp?nid=83',
- responseType: 'buffer',
- });
- res.data = iconv.decode(res.data, 'gb2312');
- const $ = cheerio.load(res.data);
- const list = $('table').eq(19).find('tr');
-
- ctx.state.data = {
- title: '浙江工商大学教务处-公示公告',
- link: 'http://jww.zjgsu.edu.cn/ArticleList.asp?nid=83',
- description: '浙江工商大学教务处-公示公告',
- item:
- list &&
- list
- .map((index, item) => {
- item = $(item);
- const date = new Date(item.find('td').eq(2).text());
- const serverOffset = date.getTimezoneOffset() / 60;
- return {
- title: item.find('a').text(),
- description: item.find('a').text(),
- link: `http://jww.zjgsu.edu.cn/${item.find('a').attr('href')}`,
- pubDate: new Date(date.getTime() - 60 * 60 * 1000 * serverOffset).toUTCString(),
- };
- })
- .get(),
- };
-};
diff --git a/lib/routes-deprecated/universities/zjgsu/tzgg/scripts.js b/lib/routes-deprecated/universities/zjgsu/tzgg/scripts.js
deleted file mode 100644
index fd5fa028af49..000000000000
--- a/lib/routes-deprecated/universities/zjgsu/tzgg/scripts.js
+++ /dev/null
@@ -1,23 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const util = require('./utils');
-
-module.exports = async (ctx) => {
- const response = await got({
- method: 'get',
- url: 'http://news.zjgsu.edu.cn/18/',
- });
-
- const data = response.data;
- const $ = cheerio.load(data);
- const list = $('ul.list-1 li').get();
-
- const result = await util.ProcessFeed(list, ctx.cache);
-
- ctx.state.data = {
- title: '浙江工商大学新闻网-通知公告',
- link: 'http://news.zjgsu.edu.cn/18/',
- description: '浙江工商大学新闻网-通知公告',
- item: result,
- };
-};
diff --git a/lib/routes-deprecated/universities/zjgsu/tzgg/utils.js b/lib/routes-deprecated/universities/zjgsu/tzgg/utils.js
deleted file mode 100644
index 2e82976b07db..000000000000
--- a/lib/routes-deprecated/universities/zjgsu/tzgg/utils.js
+++ /dev/null
@@ -1,54 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const url = require('url');
-
-// 加载文章页
-async function load(link) {
- const response = await got.get(link);
- const $ = cheerio.load(response.data);
-
- const date = new Date(
- $('p')
- .text()
- .match(/\d{4}-\d{2}-\d{2}/)
- );
-
- const pubDate = new Date(date.getTime()).toUTCString();
-
- // 提取内容
- const description = $('dd').html();
-
- return { description, pubDate };
-}
-
-const ProcessFeed = (list, caches) => {
- const host = 'http://news.zjgsu.edu.cn';
-
- return Promise.all(
- list.map(async (item) => {
- const $ = cheerio.load(item);
-
- const $title = $('a');
- // 还原相对链接为绝对链接
- const itemUrl = url.resolve(host, $title.attr('href'));
-
- // 列表上提取到的信息
- const single = {
- title: $title.text(),
- link: itemUrl,
- guid: itemUrl,
- };
-
- // 使用tryGet方法从缓存获取内容。
- // 当缓存中无法获取到链接内容的时候,则使用load方法加载文章内容。
- const other = await caches.tryGet(itemUrl, () => load(itemUrl));
-
- // 合并解析后的结果集作为该篇文章最终的输出结果
- return Object.assign({}, single, other);
- })
- );
-};
-
-module.exports = {
- ProcessFeed,
-};
diff --git a/lib/routes-deprecated/universities/zjgsu/xszq/scripts.js b/lib/routes-deprecated/universities/zjgsu/xszq/scripts.js
deleted file mode 100644
index 0ba696bb08a7..000000000000
--- a/lib/routes-deprecated/universities/zjgsu/xszq/scripts.js
+++ /dev/null
@@ -1,35 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const iconv = require('iconv-lite');
-
-module.exports = async (ctx) => {
- const res = await got({
- method: 'get',
- url: 'http://jww.zjgsu.edu.cn/ArticleList.asp?nid=6',
- responseType: 'buffer',
- });
- res.data = iconv.decode(res.data, 'gb2312');
- const $ = cheerio.load(res.data);
- const list = $('table').eq(20).find('tr');
-
- ctx.state.data = {
- title: '浙江工商大学教务处-学生专区',
- link: 'http://jww.zjgsu.edu.cn/ArticleList.asp?nid=6',
- description: '浙江工商大学教务处-学生专区',
- item:
- list &&
- list
- .map((index, item) => {
- item = $(item);
- const date = new Date(item.find('td').eq(2).text());
- const serverOffset = date.getTimezoneOffset() / 60;
- return {
- title: item.find('a').text(),
- description: item.find('a').text(),
- link: `http://jww.zjgsu.edu.cn/${item.find('a').attr('href')}`,
- pubDate: new Date(date.getTime() - 60 * 60 * 1000 * serverOffset).toUTCString(),
- };
- })
- .get(),
- };
-};
diff --git a/lib/routes-deprecated/universities/zjut/design.js b/lib/routes-deprecated/universities/zjut/design.js
deleted file mode 100644
index c95f8dcdcaf0..000000000000
--- a/lib/routes-deprecated/universities/zjut/design.js
+++ /dev/null
@@ -1,59 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const iconv = require('iconv-lite');
-const host = 'http://www.design.zjut.edu.cn';
-
-module.exports = async (ctx) => {
- const bigClassId = ctx.params.type;
- const url = host + '/BigClass.jsp?bigclassid=' + bigClassId;
-
- const response = await got({ method: 'get', url, responseType: 'buffer' });
- response.data = iconv.decode(response.data, 'gbk');
- const $ = cheerio.load(response.data);
-
- const htmlTitle = $("span[class='title1']").text().replace('\n', '').trim();
-
- const list = $("td[class='newstd']")
- .map((i, e) => {
- const element = $(e);
- const title = element.find('a').text();
- let link = element.find('a').attr('href');
- if (!link.startsWith('http')) {
- link = host + '/' + link;
- }
- const date = element.find("span[class='datetime']").text().replace('[', '').replace(']', '');
-
- return {
- title,
- description: '',
- link,
- pubDate: new Date(date).toUTCString(),
- };
- })
- .get()
- .slice(0, 20);
-
- const result = await Promise.all(
- list.map(async (item) => {
- const link = item.link;
-
- const cache = await ctx.cache.get(link);
- if (cache) {
- return JSON.parse(cache);
- }
-
- const itemReponse = await got({ method: 'get', url: link });
- const itemElement = cheerio.load(itemReponse.data);
- item.description = itemElement('div[style="line-height:27px;"]').html();
-
- ctx.cache.set(link, JSON.stringify(item));
- return item;
- })
- );
-
- ctx.state.data = {
- title: '浙江工业大学设计与建筑学院 - ' + htmlTitle,
- link: url,
- item: result,
- };
-};
diff --git a/lib/routes-deprecated/universities/zjut/index.js b/lib/routes-deprecated/universities/zjut/index.js
deleted file mode 100644
index 305c0b541280..000000000000
--- a/lib/routes-deprecated/universities/zjut/index.js
+++ /dev/null
@@ -1,59 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const iconv = require('iconv-lite');
-const host = 'http://www.zjut.edu.cn';
-
-module.exports = async (ctx) => {
- const bigClassId = ctx.params.type;
- const url = host + '/BigClass.jsp?bigclassid=' + bigClassId;
-
- const response = await got({ method: 'get', url, responseType: 'buffer' });
- response.data = iconv.decode(response.data, 'gbk');
- const $ = cheerio.load(response.data);
-
- const htmlTitle = $("span[class='lefttitle1']").text().replace('\n', '').trim();
-
- const list = $("td[class='newstd']")
- .map((i, e) => {
- const element = $(e);
- const title = element.find('a').text();
- let link = element.find('a').attr('href');
- if (!link.startsWith('http')) {
- link = host + '/' + link;
- }
- const date = element.find("span[class='datetime']").text();
-
- return {
- title,
- description: '',
- link,
- pubDate: new Date(date).toUTCString(),
- };
- })
- .get()
- .slice(0, 20);
-
- const result = await Promise.all(
- list.map(async (item) => {
- const link = item.link;
-
- const cache = await ctx.cache.get(link);
- if (cache) {
- return JSON.parse(cache);
- }
-
- const itemReponse = await got({ method: 'get', url: link, responseType: 'buffer' });
- const itemElement = cheerio.load(iconv.decode(itemReponse.data, 'gbk'));
- item.description = itemElement('#jiacu').html();
-
- ctx.cache.set(link, JSON.stringify(item));
- return item;
- })
- );
-
- ctx.state.data = {
- title: '浙江工业大学 - ' + htmlTitle,
- link: url,
- item: result,
- };
-};
diff --git a/lib/routes-deprecated/universities/zucc/cssearch/index.js b/lib/routes-deprecated/universities/zucc/cssearch/index.js
deleted file mode 100644
index a2752ea76760..000000000000
--- a/lib/routes-deprecated/universities/zucc/cssearch/index.js
+++ /dev/null
@@ -1,47 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-const baseUrl = 'http://jsxy.zucc.edu.cn/';
-const vpnUrl = 'http://jsxy.webvpn.zucc.edu.cn/';
-const maps = {
- search: '/module/sitesearch/index.jsp?keyword=vc_title&columnid=0&webid=2&modalunitid=13014',
-};
-
-function convert(raw) {
- return unescape(raw.replaceAll('', '%u').replaceAll(';', ''));
-}
-
-module.exports = async (ctx) => {
- const keyVal = ctx.params.key || encodeURIComponent('白卡');
- const pageNum = 1;
- const vpnBool = Number.parseInt(ctx.params.webVpn) || 0;
- const response = await got({
- method: 'get',
- url: baseUrl + maps.search.concat('&keyvalue=', encodeURIComponent(keyVal), '&currpage=', pageNum.toString()),
- });
-
- const data = response.data;
- const $ = cheerio.load(data);
- const resItem = [];
- $('a').each((index, el) => {
- if ($(el).attr('target') === '_blank') {
- const item = {};
- item.title = convert($(el).html());
- item.link = vpnBool === 0 ? $(el).attr('href') : vpnUrl + $(el).attr('href').slice(24);
- const dateList = $(el)
- .attr('href')
- .match(/\/\d+/g)
- .map((ele) => ele.toString().replace('/', ''));
- item.pubDate = new Date(dateList.join('-')).toUTCString();
- item.description = '
' + $(el).attr('title') + '
部分全文内容需使用校园网或VPN获取';
- item.guid = convert($(el).html());
- resItem.push(item);
- }
- });
-
- ctx.state.data = {
- title: '浙江大学城市学院计算分院全站搜索:' + keyVal,
- link: vpnBool === 0 ? baseUrl : vpnUrl,
- item: resItem,
- };
-};
diff --git a/lib/routes-deprecated/universities/zucc/news/index.js b/lib/routes-deprecated/universities/zucc/news/index.js
deleted file mode 100644
index 13b4dc6923f6..000000000000
--- a/lib/routes-deprecated/universities/zucc/news/index.js
+++ /dev/null
@@ -1,66 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-const baseUrl = 'http://www.zucc.edu.cn';
-const maps = {
- news: '/col/col16/index.html?uid=457',
-};
-
-module.exports = async (ctx) => {
- const response = await got({
- method: 'get',
- url: baseUrl + maps.news,
- });
-
- const data = response.data;
- const $ = cheerio.load(data);
-
- const xml = $('#457 > script');
- const xmlGet = xml.html().toString();
- const match = '
-
${title}
- ${match}
- ${detail}
- ${date}
- `.trim(),
- link,
- pubDate: new Date(date).toUTCString(),
- };
- })
- .get();
- ctx.state.data = {
- title,
- link,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/vscode/marketplace.js b/lib/routes-deprecated/vscode/marketplace.js
deleted file mode 100644
index 1efcb3196db1..000000000000
--- a/lib/routes-deprecated/vscode/marketplace.js
+++ /dev/null
@@ -1,39 +0,0 @@
-const got = require('got');
-const url = require('url');
-
-module.exports = async (ctx) => {
- const type = ctx.params.type || 'featured';
- const category = {
- featured: { id: 0, section: 'Featured' },
- trending: { id: 1, section: 'Trending Weekly' },
- trending_w: { id: 1, section: 'Trending Weekly' },
- trending_d: { id: 2, section: 'Trending Daily' },
- trending_m: { id: 3, section: 'Trending Monthly' },
- popular: { id: 4, section: 'Most Popular' },
- new: { id: 5, section: 'Recently Added' },
- };
-
- const rootLink = 'https://marketplace.visualstudio.com/';
- const response = await got('https://marketplace.visualstudio.com/getextensionspercategory?Product=vscode&RemoveFirstSetCategories=true');
- const jsonData = JSON.parse(response.body);
- const extensionsList = jsonData.epc[category[type].id].e;
- const out =
- extensionsList &&
- extensionsList.map((item) => {
- const title = item.t;
- const description = item.s;
- const link = url.resolve(rootLink, item.l);
- const author = item.a;
- return {
- title,
- description,
- link,
- author,
- };
- });
- ctx.state.data = {
- title: 'VS Code Extensions: ' + category[type].section,
- link: 'https://marketplace.visualstudio.com/',
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/vulture/index.js b/lib/routes-deprecated/vulture/index.js
deleted file mode 100644
index 789b45eaf1b4..000000000000
--- a/lib/routes-deprecated/vulture/index.js
+++ /dev/null
@@ -1,14 +0,0 @@
-const utils = require('./utils');
-
-module.exports = async (ctx) => {
- const url = `https://www.vulture.com/news/${ctx.params.tag}/`;
- const tagsToExclude = ctx.params.excludetags;
-
- let title = `Vulture - tag ${ctx.params.tag}`;
- if (tagsToExclude !== undefined) {
- title += ' - excluding tags ';
- title += tagsToExclude.split(',').join(', ');
- }
-
- ctx.state.data = await utils.getData(ctx, url, title, tagsToExclude);
-};
diff --git a/lib/routes-deprecated/vulture/utils.js b/lib/routes-deprecated/vulture/utils.js
deleted file mode 100644
index 3f92c4f58902..000000000000
--- a/lib/routes-deprecated/vulture/utils.js
+++ /dev/null
@@ -1,113 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-async function load(articleURL) {
- const response = await got.get(articleURL);
- const $ = cheerio.load(response.data);
-
- // get the metadata
- const title = $('meta[property="og:title"]').attr('content');
- const pubDate = $('meta[property="article:published_time"]').attr('content');
- const bylineString = 'by ' + $('meta[name="author"]').attr('content');
- const tags = $('meta[property="article:tag"]').attr('content').split(', ');
-
- // get the contents of the article
- const description = $('div.article-content');
-
- // remove the content that we don't want to show
- description.find('aside.related').remove();
- description.find('aside.article-details_heading-with-paragraph').remove();
- description.find('section.package-list').remove();
- description.find('div.source-links h2').remove();
- description.find('div.source-links svg').remove();
- description.find('div.mobile-secondary-area').remove();
- description.find('aside.newsletter-flex-text').remove();
-
- // add the tags to the end
- description.append('
tags: ' + tags.join(', '));
-
- return {
- title,
- author: bylineString,
- pubDate,
- link: articleURL,
- guid: articleURL,
- description: description.html(),
- tags,
- };
-}
-
-function ProcessFeed(htmlData, caches) {
- const $ = cheerio.load(htmlData);
- const allArticles = $('section.paginated-feed li.article');
-
- // limit the list to only 25 articles, to make sure that load times remain reasonable
- const articles = allArticles.slice(0, 25);
-
- const articleURLs = [];
- $(articles).each((index, article) => {
- const articleLink = $(article).find('a.link-text');
-
- let articleURL = articleLink.attr('href');
- if (articleURL.startsWith('//www.')) {
- articleURL = 'https:' + articleURL;
- } else if (articleURL.startsWith('www.')) {
- articleURL = 'https://' + articleURL;
- }
- articleURLs.push(articleURL);
- });
-
- return Promise.all(
- articleURLs.map(async (articleURL) => {
- const data = await caches.tryGet(articleURL, () => load(articleURL));
- return Object.assign({}, data);
- })
- );
-}
-
-function FilterItemsWithTags(feed, tagsToExclude) {
- return feed.filter((item) => {
- for (const index in tagsToExclude) {
- const tagToExclude = tagsToExclude[index];
- const itemTags = item.tags;
- if (itemTags !== undefined && itemTags.includes(tagToExclude)) {
- return false;
- }
- }
- return true;
- });
-}
-
-const getData = async (ctx, url, title, tagsToExclude) => {
- const htmlResponse = await got({
- method: 'get',
- url,
- headers: {
- Referer: url,
- },
- });
-
- const htmlData = htmlResponse.data;
- let result = await ProcessFeed(htmlData, ctx.cache);
-
- // filter out specified tags
- if (tagsToExclude !== undefined) {
- const tagsToExcludeArray = tagsToExclude.split(',');
- result = FilterItemsWithTags(result, tagsToExcludeArray);
- }
-
- // get the description
- const $ = cheerio.load(htmlData);
- const description = $('meta[name="description"]').attr('content');
-
- return {
- title,
- link: url,
- description,
- item: result,
- };
-};
-
-module.exports = {
- getData,
-};
diff --git a/lib/routes-deprecated/wainao/index.js b/lib/routes-deprecated/wainao/index.js
deleted file mode 100644
index b48c0c292da3..000000000000
--- a/lib/routes-deprecated/wainao/index.js
+++ /dev/null
@@ -1,46 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-// 找到那个对象存储的是需要的数据
-const findData = (list) => {
- const target = list.filter((item) => item.method === 'replaceWith' || item.method === 'infiniteScrollInsertView');
- if (!target.length) {
- return {};
- }
- return target[0];
-};
-
-module.exports = async (ctx) => {
- // 如果在国内运行,需要在这里配置代理(agent)方可请求歪脑读接口。
- const response = await got({
- method: 'post',
- url: `https://www.wainao.me/views/ajax?_wrapper_format=drupal_ajax`,
- body: `view_name=wainao_reads_all_articles&view_display_id=page_2&view_args=&view_path=%2Fwainao-reads%2Fall-articles&view_base_path=wainao-reads%2Fall-articles&view_dom_id=0ae93d7cdc29110b720a459d259ee376b5cdfd8caa02ce79d3468a5d3084b1a1&pager_element=0&sort_by=created&page=0&_drupal_ajax=1&ajax_page_state%5Btheme%5D=wainaome&ajax_page_state%5Btheme_token%5D=&ajax_page_state%5Blibraries%5D=addtoany%2Faddtoany%2Cbetter_exposed_filters%2Fauto_submit%2Cbetter_exposed_filters%2Fgeneral%2Cbootstrap%2Fpopover%2Cbootstrap%2Ftooltip%2Ccore%2Fhtml5shiv%2Ccore%2Fpicturefill%2Cextlink%2Fdrupal.extlink%2Cfontawesome%2Ffontawesome.svg.shim%2Cgoogle_analytics%2Fgoogle_analytics%2Cmasonry%2Fmasonry.layout%2Csystem%2Fbase%2Cviews%2Fviews.module%2Cviews_infinite_scroll%2Fviews-infinite-scroll%2Cwainao_votes%2Fwainao_votes%2Cwainaome%2Fdefault-layout%2Cwn_custom%2Fwn_custom`,
- headers: {
- accept: 'application/json, text/javascript, */*; q=0.01',
- 'content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
- },
- });
- const _body = response.data;
- const data = findData(_body).data;
- if (!data) {
- return;
- }
- const $ = cheerio.load(data);
-
- const titles = $('.view-content .views-row').map((_, item) => {
- const $item = $(item);
- return {
- title: $item.find('.field_title a').text(),
- description: $item.find('.field_teaser').text().trim(),
- link: 'https://www.wainao.me' + $item.find('.field_title a').attr('href'),
- pubDate: $item.find('.field_date').text().trim(),
- };
- });
- ctx.state.data = {
- title: `歪脑读 - 所有文章`,
- link: 'https://www.wainao.me/wainao-reads/all-articles',
- description: '歪脑读 - 所有文章...',
- item: titles.toArray(),
- };
-};
diff --git a/lib/routes-deprecated/watchface/update.js b/lib/routes-deprecated/watchface/update.js
deleted file mode 100644
index a6769dcb00cc..000000000000
--- a/lib/routes-deprecated/watchface/update.js
+++ /dev/null
@@ -1,42 +0,0 @@
-const got = require('@/utils/got');
-
-const watch_names = {
- mi4: '小米手环4',
- gtr47: '华米GTR 47mm',
- gvlite: '华米智能手表青春版',
-};
-
-const list_names = {
- 0: '最新上传',
- 1: '最多下载',
- 2: '试试手气',
- recommends: '编辑推荐',
-};
-
-module.exports = async (ctx) => {
- const watch_type = ctx.params.watch_type ?? 'mi4';
- const list_type = ctx.params.list_type ?? '0';
- const watch_name = watch_names[watch_type] ?? watch_type;
- const list_name = list_names[list_type] ?? list_type;
-
- const response = await got({
- method: 'get',
- url: `http://212.64.68.41:8081/watchface/list/${list_type}/1/10`,
- headers: {
- type: watch_type,
- },
- });
- const list = response.data.data;
-
- ctx.state.data = {
- title: `米坛社区表盘 - ${watch_name} - ${list_name}`,
- link: 'http://watchface.pingx.tech/h5/',
- item: list.map((item) => ({
- title: item.name,
- author: item.nickname,
- description: ``,
- link: `https://weidian.com/item.html?itemID=${good.itemId}`,
- };
- return item;
- });
-
- ctx.state.data = {
- title: `${shopname || id} 商铺上新`,
- link,
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/wenxuecity/bbs.js b/lib/routes-deprecated/wenxuecity/bbs.js
deleted file mode 100644
index 04cbc00045fd..000000000000
--- a/lib/routes-deprecated/wenxuecity/bbs.js
+++ /dev/null
@@ -1,40 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const url = require('url');
-
-module.exports = async (ctx) => {
- const elite = ctx.params.elite === undefined ? 0 : ctx.params.elite;
- const base_url = `https://bbs.wenxuecity.com/${ctx.params.cat}/?elite=${elite}`;
- const response = await got(base_url);
- const data = response.data;
- const $ = cheerio.load(data);
- const list = $('div.odd,div.even');
- const out = list
- .slice(0, 10)
- .map(async (i, item) => {
- const link = url.resolve(base_url, $(item).find('a.post').attr('href'));
- const description = await ctx.cache.tryGet(link, async () => {
- const result = await got(link, {
- headers: {
- Referer: base_url,
- },
- });
- const content = cheerio.load(result.data);
- return content('div#content').html();
- });
- const post = {
- title: $(item).find('a.post').text(),
- link,
- author: $(item).find('span.b > a.b').text(),
- description,
- };
- return post;
- })
- .get();
- ctx.state.data = {
- allowEmpty: true,
- title: $('title').text(),
- link: base_url,
- item: await Promise.all(out),
- };
-};
diff --git a/lib/routes-deprecated/wenxuecity/blog.js b/lib/routes-deprecated/wenxuecity/blog.js
deleted file mode 100644
index 28361afdac90..000000000000
--- a/lib/routes-deprecated/wenxuecity/blog.js
+++ /dev/null
@@ -1,40 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const url = require('url');
-
-module.exports = async (ctx) => {
- const blog_id = ctx.params.id;
- const base_url = `https://blog.wenxuecity.com/myblog/${blog_id}/all.html`;
- const response = await got(base_url);
- const data = response.data;
- const $ = cheerio.load(data);
- const list = $('div.articleCell.BLK_j_linedot1');
- const author = $('strong#username').text();
- const out = list
- .map(async (i, item) => {
- const link = url.resolve('https://blog.wenxuecity.com', $(item).find('a').attr('href'));
- const description = await ctx.cache.tryGet(link, async () => {
- const result = await got(link, {
- headers: {
- Referer: base_url,
- },
- });
- const content = cheerio.load(result.data);
- return content('div.articalContent').html();
- });
- const post = {
- title: $(item).find('a').text(),
- link,
- author,
- pubDate: $(item).find('span.atc_tm.BLK_txtc').text(),
- description,
- };
- return post;
- })
- .get();
- ctx.state.data = {
- title: $('head > title').text(),
- link: base_url,
- item: await Promise.all(out),
- };
-};
diff --git a/lib/routes-deprecated/wenxuecity/hot.js b/lib/routes-deprecated/wenxuecity/hot.js
deleted file mode 100644
index f22e2b243927..000000000000
--- a/lib/routes-deprecated/wenxuecity/hot.js
+++ /dev/null
@@ -1,40 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const url = require('url');
-
-module.exports = async (ctx) => {
- const cid = ctx.params.cid;
- const base_url = `https://bbs.wenxuecity.com/?cid=${cid}/`;
- const response = await got(base_url,);
- const data = response.data;
- const $ = cheerio.load(data);
- const list = $('div.item');
- const out = list
- .slice(0, 10)
- .map(async (i, item) => {
- const link = url.resolve('https://bbs.wenxuecity.com/', $(item).find('div.title > a').attr('href'));
- const description = await ctx.cache.tryGet(link, async () => {
- const result = await got(link, {
- headers: {
- Referer: base_url,
- },
- });
- const content = cheerio.load(result.data);
- return content('div#content').html();
- });
- const post = {
- title: $(item).find('div.title > a').text(),
- link,
- author: $(item).find('span.user > a').text(),
- description,
- };
- return post;
- })
- .get();
- ctx.state.data = {
- allowEmpty: true,
- title: $('title').text(),
- link: base_url,
- item: await Promise.all(out),
- };
-};
diff --git a/lib/routes-deprecated/wenxuecity/news.js b/lib/routes-deprecated/wenxuecity/news.js
deleted file mode 100644
index 92ef32827e63..000000000000
--- a/lib/routes-deprecated/wenxuecity/news.js
+++ /dev/null
@@ -1,44 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const rootUrl = 'https://www.wenxuecity.com';
- const currentUrl = `${rootUrl}/news/`;
- const response = await got(currentUrl);
- const $ = cheerio.load(response.data);
-
- const list = $('div.mainwrap div.block div.wrapper ul li a')
- .slice(0, 15)
- .map((_, item) => {
- item = $(item);
- return {
- title: item.text(),
- link: `${rootUrl}${item.attr('href')}`,
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got(item.link, {
- headers: {
- Referer: currentUrl,
- },
- });
- const content = cheerio.load(detailResponse.data);
-
- item.description = content('#articleContent').html();
- item.pubDate = new Date(content('time[itemprop="datePublished"]').text() + ' GMT+8').toUTCString();
-
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: '焦点新闻 - 文学城',
- link: currentUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/whb/zhuzhan.js b/lib/routes-deprecated/whb/zhuzhan.js
deleted file mode 100644
index cfa2d990daed..000000000000
--- a/lib/routes-deprecated/whb/zhuzhan.js
+++ /dev/null
@@ -1,76 +0,0 @@
-const got = require('@/utils/got');
-const { parseDate } = require('@/utils/parse-date');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const category = ctx.params.category;
-
- const base = 'http://www.whb.cn';
- const url = `${base}/zhuzhan/${category}/index.html`;
-
- const list_response = await got.get(url);
- const $ = cheerio.load(list_response.data);
-
- const category_name = $('.title_jingpinhui > a').first().text();
- const list = $('.info_jingpinhui').toArray();
-
- const parseContent = (htmlString) => {
- const $ = cheerio.load(htmlString);
-
- const date_and_author = $('.content_other').text();
- // the format is "日期:YYYY年MM月DD日 HH:mm:ss\n\s+作者:xxx"
- // The timezone is GMT+8.
- const dateString = date_and_author.split('\n')[0].slice(3);
- const date = parseDate(`${dateString}+0800`, 'YYYY年MM月DD日 HH:mm:ssZZ');
- const author = date_and_author.split(':').at(-1);
-
- const content = $('.content_info');
-
- return {
- author,
- description: content.html(),
- pubDate: date,
- };
- };
-
- const out = await Promise.all(
- list.map(async (item) => {
- const $ = cheerio.load(item);
- const title = $('.title > a');
- const path = title.attr('href');
- const link = `${base}${path}`;
-
- const cache = await ctx.cache.get(link);
- if (cache) {
- return JSON.parse(cache);
- }
-
- const rssitem = {
- title: title.text().trim(),
- link,
- };
-
- try {
- const response = await got.get(link);
- const result = parseContent(response.data);
- if (!result.description) {
- return '';
- }
-
- rssitem.author = result.author;
- rssitem.description = result.description;
- rssitem.pubDate = result.pubDate;
- } catch {
- return '';
- }
- ctx.cache.set(link, JSON.stringify(rssitem));
- return rssitem;
- })
- );
-
- ctx.state.data = {
- title: `文汇报 - ${category_name}`,
- link: url,
- item: out.filter((item) => item !== ''),
- };
-};
diff --git a/lib/routes-deprecated/wikipedia/mainland.js b/lib/routes-deprecated/wikipedia/mainland.js
deleted file mode 100644
index e981397c7b78..000000000000
--- a/lib/routes-deprecated/wikipedia/mainland.js
+++ /dev/null
@@ -1,28 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const url = 'https://zh.wikipedia.org/wiki/Portal:%E4%B8%AD%E5%9C%8B%E5%A4%A7%E9%99%B8%E6%96%B0%E8%81%9E%E5%8B%95%E6%85%8B';
-
- const response = await got({
- method: 'get',
- url,
- headers: {
- 'Accept-Language': 'zh-Hans;q=0.9,zh-Hant;q=0.8',
- },
- });
-
- const $ = cheerio.load(response.data);
- const items = $('#mw-content-text > div > table > tbody > tr:nth-child(1) > td > table:nth-child(3) > tbody > tr:nth-child(2) > td > div:nth-child(1) > ul > li').get().slice(0, 10);
-
- ctx.state.data = {
- title: '维基百科 - 中国大陆新闻动态',
- link: url,
- description: '维基百科 - 中国大陆新闻动态',
- item: items.map((item) => ({
- title: $(item).text(),
- desc: $(item).text(),
- link: url,
- })),
- };
-};
diff --git a/lib/routes-deprecated/worldhappiness/archive.js b/lib/routes-deprecated/worldhappiness/archive.js
deleted file mode 100644
index 34b1d742a3fd..000000000000
--- a/lib/routes-deprecated/worldhappiness/archive.js
+++ /dev/null
@@ -1,49 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const { parseDate } = require('@/utils/parse-date');
-
-module.exports = async (ctx) => {
- const rootUrl = 'https://worldhappiness.report';
- const currentUrl = `${rootUrl}/archive`;
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
-
- const $ = cheerio.load(response.data);
-
- const list = $('.archived-report a')
- .map((_, item) => {
- item = $(item);
- return {
- title: item.text(),
- link: `${rootUrl}${item.attr('href')}`,
- pubDate: parseDate(item.text().split(' ').pop(), 'YYYY'),
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: item.link,
- });
- const content = cheerio.load(detailResponse.data);
-
- content('.report-title').remove();
-
- item.description = content('.report-meta').html() + content('.report-body').html();
-
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: $('title').text(),
- link: currentUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/worldhappiness/blog.js b/lib/routes-deprecated/worldhappiness/blog.js
deleted file mode 100644
index 3f2f914f1e65..000000000000
--- a/lib/routes-deprecated/worldhappiness/blog.js
+++ /dev/null
@@ -1,47 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const { parseDate } = require('@/utils/parse-date');
-
-module.exports = async (ctx) => {
- const rootUrl = 'https://worldhappiness.report';
- const currentUrl = `${rootUrl}/blog`;
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
-
- const $ = cheerio.load(response.data);
-
- const list = $('.post-link')
- .map((_, item) => {
- item = $(item);
- return {
- title: item.children('h3').text(),
- link: `${rootUrl}${item.attr('href')}`,
- pubDate: parseDate(item.children('.post-date').attr('datetime')),
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: item.link,
- });
- const content = cheerio.load(detailResponse.data);
-
- item.description = content('.post-body').html();
-
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: $('title').text(),
- link: currentUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/wto/dispute-settlement.js b/lib/routes-deprecated/wto/dispute-settlement.js
deleted file mode 100644
index 3f09f30ea5de..000000000000
--- a/lib/routes-deprecated/wto/dispute-settlement.js
+++ /dev/null
@@ -1,37 +0,0 @@
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- ctx.params.year = ctx.params.year || new Date().getFullYear();
-
- const rootUrl = 'https://www.wto.org';
- const currentUrl = `${rootUrl}/library/news/news_${ctx.params.year}_e.js`;
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
-
- const data = response.data.split('] = {');
-
- data.shift();
-
- const items = data.map((item) => {
- item = '{' + item.split('news_item[')[0].replace('};', '}');
- return {
- title: item.match(/ni_head:"(.*)",/)[1],
- link: item.match(/nl_url:"(.*)",/)[1],
- description: item.match(/ni_intro:"(.*)",/)[1],
- pubDate: new Date(
- item
- .match(/ni_date:"(.*)",/)[1]
- .replaceAll('.', '-')
- .replace('_', ' ')
- ).toUTCString(),
- };
- });
-
- ctx.state.data = {
- title: `Dispute settlement news archive ${ctx.params.year} - WTO`,
- link: currentUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/x410/news.js b/lib/routes-deprecated/x410/news.js
deleted file mode 100644
index ab13d176e926..000000000000
--- a/lib/routes-deprecated/x410/news.js
+++ /dev/null
@@ -1,46 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const rootUrl = 'https://x410.dev';
- const currentUrl = `${rootUrl}/news`;
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
-
- const $ = cheerio.load(response.data);
-
- const list = $('.entry-title a')
- .map((_, item) => {
- item = $(item);
- return {
- title: item.text(),
- link: item.attr('href'),
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: item.link,
- });
- const content = cheerio.load(detailResponse.data);
-
- item.description = content('.fusion-content-tb').html();
- item.pubDate = Date.parse(content('meta[property="article:published_time"]').attr('content'));
-
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: $('title').text(),
- link: currentUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/xclient/app.js b/lib/routes-deprecated/xclient/app.js
deleted file mode 100644
index 20682556836b..000000000000
--- a/lib/routes-deprecated/xclient/app.js
+++ /dev/null
@@ -1,37 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const name = ctx.params.name;
-
- const response = await got({
- method: 'get',
- url: `http://xclient.info/s/${name}.html`,
- });
-
- const data = response.data;
-
- const $ = cheerio.load(data);
- const list = $('#versions tbody tr');
-
- ctx.state.data = {
- title: $('title').text(),
- link: `http://xclient.info/s/${name}.html`,
- description: $('meta[name="description"]').attr('content') || $('title').text(),
- item:
- list &&
- list
- .map((index, item) => {
- item = $(item);
- const td = item.find('td');
- return {
- title: td.eq(0).text(),
- description: `版本号:${td.eq(0).text()}
更新日期:${td.eq(2).text()}
文件大小:${td.eq(3).text()}`,
- pubDate: new Date(td.eq(2).text()).toUTCString(),
- link: `http://xclient.info/s/${name}.html`,
- guid: td.eq(0).text(),
- };
- })
- .get(),
- };
-};
diff --git a/lib/routes-deprecated/xiachufang/popular.js b/lib/routes-deprecated/xiachufang/popular.js
deleted file mode 100644
index bb24844b92b6..000000000000
--- a/lib/routes-deprecated/xiachufang/popular.js
+++ /dev/null
@@ -1,5 +0,0 @@
-const { generatePopularData } = require('./utils');
-
-module.exports = async (ctx) => {
- ctx.state.data = await generatePopularData(ctx.params.timeframe);
-};
diff --git a/lib/routes-deprecated/xiachufang/user/cooked.js b/lib/routes-deprecated/xiachufang/user/cooked.js
deleted file mode 100644
index acfc3751941f..000000000000
--- a/lib/routes-deprecated/xiachufang/user/cooked.js
+++ /dev/null
@@ -1,8 +0,0 @@
-const { generateUserData } = require('../utils');
-
-module.exports = async (ctx) => {
- ctx.state.data = await generateUserData({
- id: ctx.params.id,
- path: 'cooked',
- });
-};
diff --git a/lib/routes-deprecated/xiachufang/user/created.js b/lib/routes-deprecated/xiachufang/user/created.js
deleted file mode 100644
index 77af85174c6f..000000000000
--- a/lib/routes-deprecated/xiachufang/user/created.js
+++ /dev/null
@@ -1,8 +0,0 @@
-const { generateUserData } = require('../utils');
-
-module.exports = async (ctx) => {
- ctx.state.data = await generateUserData({
- id: ctx.params.id,
- path: 'created',
- });
-};
diff --git a/lib/routes-deprecated/xiachufang/utils.js b/lib/routes-deprecated/xiachufang/utils.js
deleted file mode 100644
index 25074fe81c5a..000000000000
--- a/lib/routes-deprecated/xiachufang/utils.js
+++ /dev/null
@@ -1,95 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-const generateItems = ($, timeframe) => {
- const selector = ['week', 'rising', 'monthhonor'].includes(timeframe) ? '.normal-recipe-list li' : '.ias-container .pure-u';
-
- return $(selector)
- .map(function () {
- const $item = $(this);
- const $link = $item.find('.name a');
- const title = $link.text();
- const link = `https://www.xiachufang.com${$link.attr('href')}`;
- const img = $item.find('.cover img').attr('data-src').replaceAll(/\?.+/g, '');
- let desc = $item.find('.ing').text();
- if (!desc) {
- desc = $item.find('.desc').text().replaceAll('\n', '
');
- }
-
- return {
- title,
- link,
- description: `
-
- ${title}
- ${desc}
- `,
- };
- })
- .get();
-};
-
-const fetchPage = (url) =>
- got({
- method: 'get',
- url,
- headers: {
- Referer: url,
- },
- });
-
-module.exports = {
- async generateUserData({ id = 0, path = 'created' }) {
- const url = `https://www.xiachufang.com/cook/${id}/${path}/`;
- const response = await fetchPage(url);
-
- const $ = cheerio.load(response.data);
- const author = $('.page-title').text().trim();
-
- return {
- title: `下厨房-${author}`,
- link: url,
- item: generateItems($),
- };
- },
-
- async generatePopularData(timeframe = '') {
- const mapper = {
- '': '最新上传',
- hot: '正在流行',
- pop: '24小时最佳',
- week: '本周最受欢迎',
- rising: '新秀菜谱',
- monthhonor: '月度最佳',
- };
- let url;
-
- switch (timeframe) {
- case 'hot':
- case 'pop':
- url = `https://www.xiachufang.com/activity/site/?order=${timeframe}`;
- break;
-
- case 'rising':
- case 'monthhonor':
- url = `https://www.xiachufang.com/explore/${timeframe}/`;
- break;
-
- case 'week':
- url = 'https://www.xiachufang.com/explore/';
- break;
-
- default:
- url = 'https://www.xiachufang.com/activity/site/?order=';
- }
-
- const response = await fetchPage(url);
- const $ = cheerio.load(response.data);
-
- return {
- title: `下厨房-${mapper[timeframe]}`,
- link: url,
- item: generateItems($, timeframe),
- };
- },
-};
diff --git a/lib/routes-deprecated/xiaomieu/releases.js b/lib/routes-deprecated/xiaomieu/releases.js
deleted file mode 100644
index 7c2587c56d0b..000000000000
--- a/lib/routes-deprecated/xiaomieu/releases.js
+++ /dev/null
@@ -1,29 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const res = await got.get('https://xiaomi.eu/community/forums/miui-rom-releases.103/');
- const $ = cheerio.load(res.data);
- const threads = await Promise.all(
- $('.structItem--thread')
- .map(async (idx, th) => {
- const $th = $(th);
- const $ver = $th.find('.structItem-title>a:nth-child(1)');
- const $title = $th.find('.structItem-title>a:nth-child(2)');
- const title = `[${$ver.text()}] ${$title.text()}`;
- const link = `https://xiaomi.eu${$title.attr('href')}`;
- const res = await got.get(link);
- const $$ = cheerio.load(res.data);
- const floors = $$('.bbWrapper');
- const description = $$(floors[0]).html() + $$(floors[1]).html();
- const pubDate = new Date($$('time').attr('datetime')).toUTCString();
- return { title, description, link, pubDate };
- })
- .toArray()
- );
- ctx.state.data = {
- title: 'Xiaomi.eu ROM Releases',
- link: 'https://xiaomi.eu/community/forums/miui-rom-releases.103/',
- item: threads,
- };
-};
diff --git a/lib/routes-deprecated/xinwenlianbo/index.js b/lib/routes-deprecated/xinwenlianbo/index.js
deleted file mode 100644
index e4c9a06bb478..000000000000
--- a/lib/routes-deprecated/xinwenlianbo/index.js
+++ /dev/null
@@ -1,33 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-const root_url = 'https://cn.govopendata.com/xinwenlianbo/';
-
-module.exports = async (ctx) => {
- const response = await got({
- method: 'get',
- url: root_url,
- });
-
- const $ = cheerio.load(response.data);
- const list = $('table.table.table-bordered > tbody > tr > td')
- .slice(0, 10)
- .map((_, item) => {
- item = $(item);
- const a = item.find('a');
- const title = a.text();
- return {
- title,
- link: a.attr('href'),
- description: item.find('ul').html(),
- pubDate: new Date(/(\d{4}-\d+-\d+)/.exec(title)[1] + ' 19:00 GMT+8').toUTCString(),
- };
- })
- .get();
-
- ctx.state.data = {
- title: '新闻联播 文字版',
- link: root_url,
- item: list,
- };
-};
diff --git a/lib/routes-deprecated/xmind/mindmap.js b/lib/routes-deprecated/xmind/mindmap.js
deleted file mode 100644
index 531dcfb5df0c..000000000000
--- a/lib/routes-deprecated/xmind/mindmap.js
+++ /dev/null
@@ -1,23 +0,0 @@
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- const rootUrl = `https://www.xmind.net/_api/share/featured-maps?limit=20&lang=${ctx.params.lang}`;
- const response = await got({
- method: 'get',
- url: rootUrl,
- });
-
- const list = response.data.mapList.map((item) => ({
- title: item.topic,
- link: `https://www.xmind.net/${item.id}`,
- description: ``,
- pubDate: new Date(item.created).toUTCString(),
- author: item.profileName,
- }));
-
- ctx.state.data = {
- title: 'Mindmap Gallery - XMind',
- link: 'https://www.xmind.net/share',
- item: list,
- };
-};
diff --git a/lib/routes-deprecated/xuangubao/subject.js b/lib/routes-deprecated/xuangubao/subject.js
deleted file mode 100644
index 84407555868f..000000000000
--- a/lib/routes-deprecated/xuangubao/subject.js
+++ /dev/null
@@ -1,42 +0,0 @@
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- const subject_id = ctx.params.subject_id;
-
- const response = await got({
- method: 'get',
- url: `https://api.xuangubao.cn/api/pc/subj/${subject_id}?limit=20`,
- headers: {
- Referer: `https://xuangubao.cn/subject/${subject_id}`,
- },
- });
-
- const subject = response.data.Subject;
- const subject_title = subject.Title;
- const subject_desc = subject.Desc;
-
- const messages = response.data.Messages;
-
- const out = messages.map((item) => {
- const date = item.CreatedAt;
- const link = item.Url;
- const title = item.Title;
- const description = item.Summary;
-
- const single = {
- title,
- link,
- pubDate: date,
- description,
- };
-
- return single;
- });
-
- ctx.state.data = {
- title: `${subject_title} - 主题 - 选股宝`,
- link: `https://xuangubao.cn/subject/${subject_id}`,
- description: subject_desc,
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/xuetangx/course-info.js b/lib/routes-deprecated/xuetangx/course-info.js
deleted file mode 100644
index 108447e5d49d..000000000000
--- a/lib/routes-deprecated/xuetangx/course-info.js
+++ /dev/null
@@ -1,51 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const { cid, type } = ctx.params;
- const link = `http://www.xuetangx.com/courses/${cid}/about`;
- const res = await got(link);
- const $ = cheerio.load(res.data);
-
- const courseTitle = $('#title1').text();
- const infoTag = $('#course_data');
- let title,
- description = '',
- startTime,
- endTime,
- status;
- switch (type) {
- case 'start':
- title = '开课时间';
- startTime = infoTag.attr('data-start');
- description = `开课时间: ${startTime ? new Date(startTime).toUTCString() : '暂无'}`;
- break;
- case 'end':
- title = '结课时间';
- endTime = infoTag.attr('data-end');
- description = `结课时间: ${endTime ? new Date(endTime).toUTCString() : '永久开课'}`;
- break;
- case 'status':
- title = '课程进度';
- status = infoTag.attr('data-serialized');
- description = `课程进度: ${Number(status) > -1 ? `连载至第${status}讲` : '暂无'}`;
- break;
- }
- const item = [];
- if (title && description) {
- item.push({
- title,
- description,
- link,
- guid: description,
- });
- }
-
- ctx.state.data = {
- title: `${courseTitle} - ${title}`,
- description: `${courseTitle} - ${title}`,
- link,
- item,
- allowEmpty: true,
- };
-};
diff --git a/lib/routes-deprecated/xuetangx/course-list.js b/lib/routes-deprecated/xuetangx/course-list.js
deleted file mode 100644
index 363ad0705073..000000000000
--- a/lib/routes-deprecated/xuetangx/course-list.js
+++ /dev/null
@@ -1,54 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const { type = '', credential, mode, status } = ctx.params;
- const baseUrl = 'http://www.xuetangx.com';
- const link = `${baseUrl}/courses`;
- const query = {
- page_type: type,
- course_mode: mode,
- process: status,
- credential,
- };
- for (const key of Object.keys(query)) {
- Number(query[key]) === -1 && (query[key] = '');
- }
- const res = await got(link, {
- query,
- });
- const $ = cheerio.load(res.data);
-
- const item = $('#list_style .list_inner')
- .map((_, node) => {
- const $item = cheerio.load(node);
- const title = $item('.coursetitle').text();
- const link = `${baseUrl}${$item('.coursename > a').attr('href')}`;
- const posterImg = baseUrl + $item('.course-cover').attr('src');
- const baseInfo = $item('.coursename_ref').text().trim().replaceAll(/\s+/g, '/');
- const teacherInfo = $item('div.fl.name > ul > li:nth-child(1)').text();
- const extraInfo = $item('div.fl.name > ul > li:nth-child(2)').text().replace('$', '');
- const description = `
- ${baseInfo}
- ${teacherInfo}
- ${extraInfo}
- ${$item('.txt')}
- ${$item('.ctxt')}
-
- `;
- return {
- title,
- link,
- description,
- };
- })
- .get();
-
- ctx.state.data = {
- title: `学堂在线-课程列表`,
- description: `学堂在线-课程列表`,
- link,
- item,
- allowEmpty: true,
- };
-};
diff --git a/lib/routes-deprecated/xyplorer/whatsnew.js b/lib/routes-deprecated/xyplorer/whatsnew.js
deleted file mode 100644
index 243c39a24735..000000000000
--- a/lib/routes-deprecated/xyplorer/whatsnew.js
+++ /dev/null
@@ -1,32 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const { parseRelativeDate } = require('@/utils/parse-date');
-
-module.exports = async (ctx) => {
- const rootUrl = 'https://www.xyplorer.com';
- const currentUrl = `${rootUrl}/whatsnew.php`;
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
-
- const $ = cheerio.load(response.data);
-
- const items = $('.waznu')
- .map((_, item) => {
- item = $(item);
- return {
- link: currentUrl,
- description: `${item.html()}
`,
- title: item.prev().prev().text(),
- pubDate: parseRelativeDate(item.prev().text().replace('released ', '')),
- };
- })
- .get();
-
- ctx.state.data = {
- title: $('title').text(),
- link: currentUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/yahoo-author/index.js b/lib/routes-deprecated/yahoo-author/index.js
deleted file mode 100644
index 37bfd9ea673c..000000000000
--- a/lib/routes-deprecated/yahoo-author/index.js
+++ /dev/null
@@ -1,67 +0,0 @@
-const cheerio = require('cheerio');
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- const author = ctx.params.author;
-
- const response = await got({
- method: 'get',
- url: `https://www.yahoo.com/author/${author}/`,
- });
- const url = response.url; // got will make sure that this is the final URL after redirects
-
- const data = response.data;
-
- const $ = cheerio.load(data);
- const title = $('meta[property="og:title"]').attr('content');
- const description = $('meta[property="og:description"]').attr('content');
-
- const list = $('li.js-stream-content h3 a')
- .slice(0, 10)
- .map((_, item) => {
- item = $(item);
- const itemURL = new URL(item.attr('href'), url).href;
- return {
- link: itemURL,
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: item.link,
- });
- const content = cheerio.load(detailResponse.data);
-
- const body = content('div.caas-body');
-
- // remove extra body content that we don't want to see
- body.find('div.caas-iframe-wrapper').remove();
- body.find('div.caas-readmore').remove();
- body.find('ul.caas-list').remove();
- body.find('strong:contains("More from Yahoo Sports:")').parent().remove();
-
- // fix all img srcs
- body.find('img').attr('src', function () {
- return cheerio(this).attr('data-src');
- });
-
- item.title = content('meta[property="og:title"]').attr('content');
- item.description = body.html();
- item.pubDate = new Date(content('div.caas-attr-time-style time').attr('datetime')).toUTCString();
-
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title,
- link: url,
- description,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/yidoutang/case.js b/lib/routes-deprecated/yidoutang/case.js
deleted file mode 100644
index 1d5e48356936..000000000000
--- a/lib/routes-deprecated/yidoutang/case.js
+++ /dev/null
@@ -1,46 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const { type = 'default' } = ctx.params;
- const urlPath = {
- default: '',
- hot: '/0-2-0-0-0-0/',
- new: '/0-1-0-0-0-0/',
- }[type];
- const url = `http://www.yidoutang.com/case${urlPath}`;
- const response = await got(url);
- const $ = cheerio.load(response.data);
-
- const items = $('.main .case-items > .case-item')
- .map((_, ele) => {
- const $item = cheerio.load(ele);
- const baseInfoNode = $item('.info > .text');
- const title = baseInfoNode.find('.title').text();
- const desc = baseInfoNode.find('.desc').text();
- const link = baseInfoNode.find('a').attr('href');
-
- const thumbnail = $item('.img-box img').attr('src');
- const author = $item('.user a').text();
-
- return {
- title,
- link,
- description: [`简介: ${desc}`, ``].join('
'),
- author,
- };
- })
- .get();
-
- const typeLabel = {
- default: '默认',
- hot: '热门',
- new: '最新',
- }[type];
- ctx.state.data = {
- title: `一兜糖 - 全屋记 - ${typeLabel}`,
- description: `一兜糖 - 全屋记 - ${typeLabel}`,
- link: url,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/yidoutang/guide.js b/lib/routes-deprecated/yidoutang/guide.js
deleted file mode 100644
index ccc94c8d939d..000000000000
--- a/lib/routes-deprecated/yidoutang/guide.js
+++ /dev/null
@@ -1,34 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const url = 'http://www.yidoutang.com/guide.html';
- const response = await got(url);
- const $ = cheerio.load(response.data);
-
- const items = $('.main .guide-items > .guide-item')
- .map((_, ele) => {
- const $item = cheerio.load(ele);
- const titleNode = $item('.title > a').first();
- const title = titleNode.text();
- const link = titleNode.attr('href');
- const thumbnail = $item('a > img').first().attr('src');
-
- const infoNode = $item('.info');
- const desc = infoNode.find('.desc').text();
- const author = infoNode.find('.user a').text();
- return {
- title,
- link,
- description: [`简介: ${desc}`, ``].join('
'),
- author,
- };
- })
- .get();
- ctx.state.data = {
- title: '一兜糖 - 文章',
- description: '一兜糖 - 文章',
- link: url,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/yidoutang/mtest.js b/lib/routes-deprecated/yidoutang/mtest.js
deleted file mode 100644
index 89891580579d..000000000000
--- a/lib/routes-deprecated/yidoutang/mtest.js
+++ /dev/null
@@ -1,31 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const url = 'http://www.yidoutang.com/mtest';
- const response = await got(url);
- const $ = cheerio.load(response.data);
-
- const items = $('.zc-bd .zc-bd-left > .clearfix > a')
- .map((_, ele) => {
- const $item = cheerio.load(ele);
- const link = ele.attribs.href;
- const thumbnail = $item('.top > img').attr('src');
- const deadline = $item('.top > .time').text();
- const otherInfoArr = $item('.bottom').text().trim().split('\n');
- const title = otherInfoArr[0];
-
- return {
- title,
- link,
- description: [deadline, ...otherInfoArr, ``].filter((str) => !!str.trim()).join('
'),
- };
- })
- .get();
- ctx.state.data = {
- title: '一兜糖 - 众测',
- description: '一兜糖 - 众测',
- link: url,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/yinxiang/card.js b/lib/routes-deprecated/yinxiang/card.js
deleted file mode 100644
index a891e4ddd148..000000000000
--- a/lib/routes-deprecated/yinxiang/card.js
+++ /dev/null
@@ -1,41 +0,0 @@
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- const id = ctx.params.id || '32';
-
- const apiUrl = `https://app.yinxiang.com/third/discovery/client/restful/public/discovery/card-holder?cardHolderId=${id}`;
- const response = await got({
- method: 'get',
- url: apiUrl,
- });
-
- const list = response.data.card.map((item) => ({
- title: item.title,
- link: item.url,
- author: item.userNickname,
- }));
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: `https://app.yinxiang.com/third/discovery/client/restful/public/blog-note?noteGuid=${item.link.split('/note/')[1]}`,
- });
-
- item.pubDate = new Date(Number.parseInt(detailResponse.data.blogNote.publishTime)).toUTCString();
-
- const description = detailResponse.data.blogNote.htmlContent;
- item.description = description.includes('(.*)<\/en-note>/)[1] : description;
-
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: `${response.data.name} - 印象识堂`,
- link: 'https://www.yinxiang.com/everhub/',
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/yinxiang/category.js b/lib/routes-deprecated/yinxiang/category.js
deleted file mode 100644
index 80834911d8ff..000000000000
--- a/lib/routes-deprecated/yinxiang/category.js
+++ /dev/null
@@ -1,42 +0,0 @@
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- const id = ctx.params.id;
-
- const apiUrl = `https://app.yinxiang.com/third/discovery/client/restful/public/category/page?notePageSize=20&lastBlogNoteGuid=&cateGoryId=${id}`;
- const response = await got({
- method: 'get',
- url: apiUrl,
- });
-
- const list = response.data.categoryNoteSnapshotReply.map((item) => ({
- title: item.title,
- link: item.noteGuid,
- author: item.userNickname,
- }));
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: `https://app.yinxiang.com/third/discovery/client/restful/public/blog-note?noteGuid=${item.link}`,
- });
-
- item.link = `https://www.yinxiang.com/everhub/note/${item.link}`;
- item.pubDate = new Date(Number.parseInt(detailResponse.data.blogNote.publishTime)).toUTCString();
-
- const description = detailResponse.data.blogNote.htmlContent;
- item.description = description.includes('(.*)<\/en-note>/)[1] : description;
-
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: `${response.data.categoryName} - 印象识堂`,
- link: `https://www.yinxiang.com/everhub/category/${id}`,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/yinxiang/note.js b/lib/routes-deprecated/yinxiang/note.js
deleted file mode 100644
index ac67925dfdc1..000000000000
--- a/lib/routes-deprecated/yinxiang/note.js
+++ /dev/null
@@ -1,37 +0,0 @@
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- const apiUrl = 'https://app.yinxiang.com/third/discovery/client/restful/public/v2/discovery/homepage?notePageSize=20';
- const response = await got({
- method: 'get',
- url: apiUrl,
- });
-
- const list = response.data.blogNote.slice(0, 5).map((item) => ({
- title: item.title,
- link: `https://www.yinxiang.com/everhub/note/${item.noteGuid}`,
- pubDate: new Date(Number.parseInt(item.publishTime)).toUTCString(),
- }));
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: `https://app.yinxiang.com/third/discovery/client/restful/public/blog-note?noteGuid=${item.link.split('/note/')[1]}`,
- });
-
- const description = detailResponse.data.blogNote.htmlContent;
- item.description = description.includes('(.*)<\/en-note>/)[1] : description;
-
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: '印象剪藏 - 印象识堂',
- link: 'https://www.yinxiang.com/everhub/',
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/yinxiang/personal.js b/lib/routes-deprecated/yinxiang/personal.js
deleted file mode 100644
index 3f22002922ef..000000000000
--- a/lib/routes-deprecated/yinxiang/personal.js
+++ /dev/null
@@ -1,43 +0,0 @@
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- const id = ctx.params.id;
-
- const apiUrl = `https://app.yinxiang.com/third/discovery/client/restful/public/blog-user/homepage?encryptedUserId=${id}&lastNoteGuid=¬ePageSize=20`;
- const response = await got({
- method: 'get',
- url: apiUrl,
- });
-
- const list = response.data.blogNote.map((item) => ({
- title: item.title,
- link: item.noteGuid,
- author: item.userNickname,
- }));
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: `https://app.yinxiang.com/third/discovery/client/restful/public/blog-note?noteGuid=${item.link}`,
- });
-
- item.link = `https://www.yinxiang.com/everhub/note/${item.link}`;
- item.pubDate = new Date(Number.parseInt(detailResponse.data.blogNote.publishTime)).toUTCString();
-
- const description = detailResponse.data.blogNote.htmlContent;
- item.description = description.includes('(.*)<\/en-note>/)[1] : description;
-
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: `${response.data.blogUser.nickname} - 印象识堂`,
- link: `https://www.yinxiang.com/everhub/category/${id}`,
- description: response.data.blogUser.introduction,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/yinxiang/tag.js b/lib/routes-deprecated/yinxiang/tag.js
deleted file mode 100644
index c462e9d201a4..000000000000
--- a/lib/routes-deprecated/yinxiang/tag.js
+++ /dev/null
@@ -1,42 +0,0 @@
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- const id = ctx.params.id;
-
- const apiUrl = `https://app.yinxiang.com/third/discovery/client/restful/public/tag/note?pageSize=20&tagName=${id}`;
- const response = await got({
- method: 'get',
- url: apiUrl,
- });
-
- const list = response.data.blogNote.map((item) => ({
- title: item.title,
- link: item.noteGuid,
- author: item.userNickname,
- }));
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: `https://app.yinxiang.com/third/discovery/client/restful/public/blog-note?noteGuid=${item.link}`,
- });
-
- item.link = `https://www.yinxiang.com/everhub/note/${item.link}`;
- item.pubDate = new Date(Number.parseInt(detailResponse.data.blogNote.publishTime)).toUTCString();
-
- const description = detailResponse.data.blogNote.htmlContent;
- item.description = description.includes('(.*)<\/en-note>/)[1] : description;
-
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: `${response.data.tagInfo.name} - 印象识堂`,
- link: `https://www.yinxiang.com/everhub/tagtheme/${id}`,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/youdao/latest.js b/lib/routes-deprecated/youdao/latest.js
deleted file mode 100644
index aa5b2dd932d4..000000000000
--- a/lib/routes-deprecated/youdao/latest.js
+++ /dev/null
@@ -1,47 +0,0 @@
-const got = require('@/utils/got');
-
-module.exports = async (ctx) => {
- const rootUrl = 'http://xueba.youdao.com';
- const apiUrl = `${rootUrl}/yws/mapi/xueba/library?method=realTimeCollect&count=10`;
- const response = await got({
- method: 'get',
- url: apiUrl,
- });
-
- const list = response.data.Clt.map((item) => ({
- title: `${item.name} 保存了 ${item.title}`,
- pubDate: new Date(item.time).toUTCString(),
- link: `http://note.youdao.com/publicshare/?id=${item.shareKey}`,
- }));
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const id = item.link.split('?id=')[1];
- try {
- const contentResponse = await got({
- method: 'get',
- url: `http://note.youdao.com/yws/public/notebook/${id}`,
- });
- item.description = '';
- for (const note of contentResponse.data[2]) {
- item.description += `${note.tl}
${note.tl}
`,
- link: `https://detail.youzan.com/show/goods?alias=${good.alias}`,
- };
- return item;
- });
-
- ctx.state.data = {
- title: `${shopname || id} 商铺上新`,
- link,
- item: out,
- };
-};
diff --git a/lib/routes-deprecated/yuanliao/index.js b/lib/routes-deprecated/yuanliao/index.js
deleted file mode 100644
index c2e373215750..000000000000
--- a/lib/routes-deprecated/yuanliao/index.js
+++ /dev/null
@@ -1,42 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-
-module.exports = async (ctx) => {
- const tag = ctx.params.tag || 'utools';
- const sort = ctx.params.sort || '';
-
- const rootUrl = 'https://yuanliao.info';
- const currentUrl = `${rootUrl}/api/discussions?tags=${tag}&sort=${sort}`;
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
-
- const list = response.data.data.map((item) => ({
- title: item.attributes.title,
- link: `${rootUrl}/d/${item.id}-${item.attributes.slug}`,
- pubDate: new Date(item.attributes.lastPostedAt).toUTCString(),
- }));
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: item.link,
- });
- const content = cheerio.load(detailResponse.data);
-
- item.description = content('#flarum-content').html();
-
- return item;
- })
- )
- );
-
- ctx.state.data = {
- title: `${tag} - 猿料`,
- link: currentUrl,
- item: items,
- };
-};
diff --git a/lib/routes-deprecated/yuzu-emu/entry.js b/lib/routes-deprecated/yuzu-emu/entry.js
deleted file mode 100644
index b0d743255798..000000000000
--- a/lib/routes-deprecated/yuzu-emu/entry.js
+++ /dev/null
@@ -1,52 +0,0 @@
-const got = require('@/utils/got');
-const cheerio = require('cheerio');
-const { parseDate } = require('@/utils/parse-date');
-
-module.exports = async (ctx) => {
- const rootUrl = 'https://yuzu-emu.org';
- const currentUrl = `${rootUrl}/entry`;
-
- const response = await got({
- method: 'get',
- url: currentUrl,
- });
-
- const $ = cheerio.load(response.data);
-
- const list = $('.blog-entry-header')
- .map((_, item) => {
- item = $(item);
-
- return {
- link: item.attr('data-href'),
- };
- })
- .get();
-
- const items = await Promise.all(
- list.map((item) =>
- ctx.cache.tryGet(item.link, async () => {
- const detailResponse = await got({
- method: 'get',
- url: item.link,
- });
- const content = cheerio.load(detailResponse.data.replaceAll('
) : null}
- {item.find('div.p-row').text() ?
{item.find('div.p-row').text()}
: null}
+ {$item.find('div.p-row').text() ? {$item.find('div.p-row').text()}
: null}
>
);
return {
title,
description,
- pubDate: parseDate(item.find('span.time').text()),
- link: new URL(item.find('h3 a').prop('href'), rootUrl).href,
+ pubDate: parseDate($item.find('span.time').text()),
+ link: new URL($item.find('h3 a').prop('href')!, rootUrl).href,
content: {
html: description,
- text: item.find('div.p-row').text(),
+ text: $item.find('div.p-row').text(),
},
image,
banner: image,
@@ -66,11 +66,11 @@ export const handler = async (ctx) => {
const description = $$('div.articleContent').html();
item.title = title;
- item.description = description;
- item.pubDate = timezone(parseDate($$('.time').text()), +8);
+ item.description = description ?? '';
+ item.pubDate = timezone(parseDate($$('.time').text()), 8);
item.category = $$('meta[name="keywords"]').prop('content').split(/,/);
item.content = {
- html: description,
+ html: description ?? '',
text: $$('div.articleContent').text(),
};
item.language = language;
@@ -85,7 +85,7 @@ export const handler = async (ctx) => {
return {
title,
- description: title.split(/_/)[0],
+ description: title.split(/_/, 1)[0],
link: currentUrl,
item: items,
allowEmpty: true,
@@ -99,7 +99,7 @@ export const route: Route = {
path: '/:category?',
name: '资讯',
url: '005.tv',
- maintainers: ['nczitzk'],
+ maintainers: ['junfengP', 'nczitzk'],
handler,
example: '/005/zx',
parameters: { category: '分类,可在对应分类页 URL 中找到,默认为二次元资讯' },
diff --git a/lib/routes/0818tuan/index.ts b/lib/routes/0818tuan/index.ts
index a6df25136051..347f81aee072 100644
--- a/lib/routes/0818tuan/index.ts
+++ b/lib/routes/0818tuan/index.ts
@@ -1,6 +1,6 @@
import { load } from 'cheerio';
-import type { Route } from '@/types';
+import type { DataItem, Route } from '@/types';
import cache from '@/utils/cache';
import got from '@/utils/got';
import { parseDate } from '@/utils/parse-date';
@@ -37,25 +37,25 @@ async function handler(ctx) {
const list = $(listId === '3' ? '.col-xs-12 .thumbnail > a' : '.col-md-8 .list-group > a')
.toArray()
- .map((item) => {
- item = $(item);
+ .map((item): DataItem => {
+ const $item = $(item);
return {
- title: item.attr('title'),
- link: item.attr('href').startsWith('http') ? item.attr('href') : `${baseUrl}${item.attr('href')}`,
+ title: $item.attr('title')!,
+ link: $item.attr('href')!.startsWith('http') ? $item.attr('href') : `${baseUrl}${$item.attr('href')}`,
};
})
- .filter((i) => !i.link.includes('m.0818tuan.com/tb1111.php'));
+ .filter((i) => !i.link!.includes('m.0818tuan.com/tb1111.php') && !i.link!.includes('www.0818tuan.com/pdd/zudui.php'));
const items = await Promise.all(
list.map((item) =>
- cache.tryGet(item.link, async () => {
+ cache.tryGet(item.link!, async () => {
const { data: response } = await got(item.link);
const $ = load(response);
$('.pageLink, .alert, p[style="margin:15px;"]').remove();
item.description = $('.post-content').html();
- item.pubDate = timezone(parseDate($('.panel-body > .text-center').text().replace('时间:', ''), 'YYYY-MM-DD HH:mm:ss'), +8);
+ item.pubDate = timezone(parseDate($('.panel-body > .text-center').text().replace('时间:', ''), 'YYYY-MM-DD HH:mm:ss'), 8);
return item;
})
diff --git a/lib/routes/0x80/index.ts b/lib/routes/0x80/index.ts
index c59a1cf0785c..f4069561d3a8 100644
--- a/lib/routes/0x80/index.ts
+++ b/lib/routes/0x80/index.ts
@@ -1,6 +1,6 @@
import { load } from 'cheerio';
-import type { Route } from '@/types';
+import type { DataItem, Route } from '@/types';
import cache from '@/utils/cache';
import got from '@/utils/got';
import { parseDate } from '@/utils/parse-date';
@@ -37,11 +37,11 @@ async function handler() {
const list = alist
.toArray()
- .map((item) => {
- item = $(item);
+ .map((item): DataItem & { link: string } => {
+ const $item = $(item);
- const link = item.attr('href') || '';
- const title = item.text() || '';
+ const link = $item.attr('href') || '';
+ const title = $item.text();
const pubDate = extractDateFromURL(link);
return {
diff --git a/lib/routes/0xxx/index.ts b/lib/routes/0xxx/index.ts
index 78ff90a68380..a79156976e13 100644
--- a/lib/routes/0xxx/index.ts
+++ b/lib/routes/0xxx/index.ts
@@ -3,7 +3,7 @@ import { load } from 'cheerio';
import type { Element } from 'domhandler';
import type { Context } from 'hono';
-import type { Data, DataItem, Route } from '@/types';
+import type { Data, DataItem, Language, Route } from '@/types';
import { ViewType } from '@/types';
import cache from '@/utils/cache';
import ofetch from '@/utils/ofetch';
@@ -13,19 +13,19 @@ import { renderDescription } from './templates/description';
export const handler = async (ctx: Context): Promise => {
const { filter } = ctx.req.param();
- const limit: number = Number.parseInt(ctx.req.query('limit') ?? '100', 10);
+ const limit = Number(ctx.req.query('limit') ?? '100');
const baseUrl = 'https://0xxx.ws';
const targetUrl: string = new URL(filter ? `?${filter}` : '', baseUrl).href;
const response = await ofetch(targetUrl);
const $: CheerioAPI = load(response);
- const language = $('html').attr('lang') ?? 'en';
+ const language = ($('html').attr('lang') ?? 'en') as Language;
let items: DataItem[] = $('table#home-table tr:not(.gore)')
.slice(0, limit)
.toArray()
- .map((el): Element => {
+ .map((el) => {
const $el: Cheerio : null}
@@ -163,7 +158,7 @@ async function handler(ctx) {
});
return {
- title: `141PPV - ${$('title').text().split('-')[0].trim()}`,
+ title: `141PPV - ${$('title').text().split('-', 1)[0].trim()}`,
link: currentUrl,
item: items,
};
diff --git a/lib/routes/163/dy.ts b/lib/routes/163/dy.ts
index 8b77df942391..2720d00520fb 100644
--- a/lib/routes/163/dy.ts
+++ b/lib/routes/163/dy.ts
@@ -1,5 +1,4 @@
import type { Route } from '@/types';
-import cache from '@/utils/cache';
import got from '@/utils/got';
import { parseDate } from '@/utils/parse-date';
import timezone from '@/utils/timezone';
@@ -40,7 +39,7 @@ async function handler(ctx) {
imgsrc: e.imgsrc,
}));
- const items = await Promise.all(list.map((e) => parseDyArticle(e, cache.tryGet)));
+ const items = await Promise.all(list.map((e) => parseDyArticle(e)));
return {
title: `网易号 - ${list[0].author}`,
diff --git a/lib/routes/163/dy2.ts b/lib/routes/163/dy2.ts
index 6c65b2878279..cfd448129d8e 100644
--- a/lib/routes/163/dy2.ts
+++ b/lib/routes/163/dy2.ts
@@ -1,7 +1,6 @@
import { load } from 'cheerio';
import type { Route } from '@/types';
-import cache from '@/utils/cache';
import got from '@/utils/got';
import { parseDate } from '@/utils/parse-date';
import timezone from '@/utils/timezone';
@@ -39,17 +38,17 @@ async function handler(ctx) {
.slice(0, limit)
.toArray()
.map((item) => {
- item = $(item);
- const itemImg = item.find('a.img img');
+ const $item = $(item);
+ const itemImg = $item.find('a.img img');
return {
- title: item.find('h4 a').text(),
- link: item.find('a').first().attr('href'),
- pubDate: timezone(parseDate(item.find('.time').text()), 8),
+ title: $item.find('h4 a').text(),
+ link: $item.find('a').first().attr('href'),
+ pubDate: timezone(parseDate($item.find('.time').text()), 8),
imgsrc: itemImg.attr('src') ?? itemImg.attr('_src'),
};
});
- const items = await Promise.all(list.map((item) => parseDyArticle(item, cache.tryGet)));
+ const items = await Promise.all(list.map((item) => parseDyArticle(item)));
return {
title: `${$('head title').text()} - 网易号`,
diff --git a/lib/routes/163/exclusive.ts b/lib/routes/163/exclusive.ts
index ef265de1b503..881efdb75046 100644
--- a/lib/routes/163/exclusive.ts
+++ b/lib/routes/163/exclusive.ts
@@ -134,7 +134,7 @@ async function handler(ctx) {
title: item.title,
author: item.source,
link: item.skipURL || item.url || `${rootUrl}/dy/article/${item.docid}.html`,
- pubDate: timezone(parseDate(item.ptime), +8),
+ pubDate: timezone(parseDate(item.ptime), 8),
videoId: item.skipType === 'video' ? item.stitle : '',
}));
diff --git a/lib/routes/163/music/artist-songs.ts b/lib/routes/163/music/artist-songs.ts
index 3ebf5cb07b47..ff8f4dce0a88 100644
--- a/lib/routes/163/music/artist-songs.ts
+++ b/lib/routes/163/music/artist-songs.ts
@@ -12,10 +12,17 @@ export const route: Route = {
requireConfig: false,
requirePuppeteer: false,
antiCrawler: false,
+ supportRadar: true,
supportBT: false,
supportPodcast: false,
supportScihub: false,
},
+ radar: [
+ {
+ source: ['music.163.com/artist'],
+ target: '/music/artist/songs/:id',
+ },
+ ],
name: '歌手歌曲',
maintainers: ['ZhongMingKun'],
handler,
@@ -25,9 +32,6 @@ async function handler(ctx) {
const id = ctx.req.param('id');
const { data } = await got('https://music.163.com/api/v1/artist/songs', {
- headers: {
- Referer: 'https://music.163.com/',
- },
searchParams: {
id,
private_cloud: 'true',
@@ -42,6 +46,7 @@ async function handler(ctx) {
const items = data.songs.map((song) => ({
title: `${song.name} - ${song.ar.map(({ name }) => name).join(' / ')}`,
description: renderPlaylistDescription({
+ songId: song.id,
singer: song.ar.map(({ name }) => name).join(' / '),
album: song.al.name,
picUrl: song.al.picUrl,
diff --git a/lib/routes/163/music/artist.ts b/lib/routes/163/music/artist.ts
index a555357f4390..76c40dee7b5a 100644
--- a/lib/routes/163/music/artist.ts
+++ b/lib/routes/163/music/artist.ts
@@ -12,10 +12,17 @@ export const route: Route = {
requireConfig: false,
requirePuppeteer: false,
antiCrawler: false,
+ supportRadar: true,
supportBT: false,
supportPodcast: false,
supportScihub: false,
},
+ radar: [
+ {
+ source: ['music.163.com/artist/album'],
+ target: '/music/artist/:id',
+ },
+ ],
name: '歌手专辑',
maintainers: ['metowolf'],
handler,
@@ -24,11 +31,7 @@ export const route: Route = {
async function handler(ctx) {
const id = ctx.req.param('id');
- const response = await got(`https://music.163.com/api/artist/albums/${id}`, {
- headers: {
- Referer: 'https://music.163.com/',
- },
- });
+ const response = await got(`https://music.163.com/api/artist/albums/${id}`);
const data = response.data;
@@ -38,7 +41,10 @@ async function handler(ctx) {
description: `网易云音乐歌手专辑 - ${data.artist.name}`,
image: data.artist.img1v1Url || data.artist.picUrl,
item: data.hotAlbums.map((item) => {
- const singer = item.artists.length === 1 ? item.artists[0].name : item.artists.reduce((prev, cur) => (prev.name || prev) + '/' + cur.name);
+ let singer = item.artists[0].name;
+ for (const artist of item.artists.slice(1)) {
+ singer += '/' + artist.name;
+ }
return {
title: `${item.name} - ${singer}`,
description: renderPlaylistDescription({
diff --git a/lib/routes/163/music/djradio.tsx b/lib/routes/163/music/djradio.tsx
index ab876b54b95b..e97e96a120a7 100644
--- a/lib/routes/163/music/djradio.tsx
+++ b/lib/routes/163/music/djradio.tsx
@@ -15,10 +15,17 @@ export const route: Route = {
requireConfig: false,
requirePuppeteer: false,
antiCrawler: false,
+ supportRadar: true,
supportBT: false,
supportPodcast: true,
supportScihub: false,
},
+ radar: [
+ {
+ source: ['music.163.com/djradio'],
+ target: '/music/djradio/:id',
+ },
+ ],
name: '电台节目',
maintainers: ['magic-akari'],
handler,
@@ -35,7 +42,7 @@ const renderDescription = (pg, description, itunes_duration, info) =>
{info ? (
+ {songId ? : null}
>
);
diff --git a/lib/routes/163/today.ts b/lib/routes/163/today.ts
index d259642cefb1..5ccefa8625cc 100644
--- a/lib/routes/163/today.ts
+++ b/lib/routes/163/today.ts
@@ -48,7 +48,7 @@ async function handler(ctx) {
let items = response.data.data.items.map((item) => ({
title: item.title,
author: item.source,
- pubDate: timezone(parseDate(item.ptime), +8),
+ pubDate: timezone(parseDate(item.ptime), 8),
description: `
`,
link: item.url || `https://c.m.163.com/news/a/${item.docid}.html`,
}));
diff --git a/lib/routes/163/utils.tsx b/lib/routes/163/utils.tsx
index df91f2032298..aa995215ffbd 100644
--- a/lib/routes/163/utils.tsx
+++ b/lib/routes/163/utils.tsx
@@ -2,6 +2,7 @@ import { load } from 'cheerio';
import { raw } from 'hono/html';
import { renderToString } from 'hono/jsx/dom/server';
+import cache from '@/utils/cache';
import got from '@/utils/got';
const renderDescription = (imgsrc, postBody) =>
@@ -17,8 +18,8 @@ const renderDescription = (imgsrc, postBody) =>
>
);
-const parseDyArticle = (item, tryGet) =>
- tryGet(item.link, async () => {
+const parseDyArticle = (item) =>
+ cache.tryGet(item.link, async () => {
const response = await got(item.link, {
responseType: 'buffer',
});
@@ -31,7 +32,7 @@ const parseDyArticle = (item, tryGet) =>
}
const url = new URL(i.attribs.src);
if (url.host === 'nimg.ws.126.net') {
- i.attribs.src = url.searchParams.get('url');
+ i.attribs.src = url.searchParams.get('url') ?? '';
}
});
diff --git a/lib/routes/18comic/album.ts b/lib/routes/18comic/album.ts
index c7a5f9a0dab6..4f5029887331 100644
--- a/lib/routes/18comic/album.ts
+++ b/lib/routes/18comic/album.ts
@@ -1,4 +1,4 @@
-import type { Route } from '@/types';
+import type { DataItem, Route } from '@/types';
import cache from '@/utils/cache';
import { renderDescription } from './templates/description';
@@ -70,7 +70,7 @@ async function handler(ctx) {
cache.tryGet(`18comic:album:${item.id}`, async () => {
const chapterApiUrl = `${getApiUrl()}/chapter?id=${item.id}`;
const chapterResult = await processApiItems(chapterApiUrl);
- const result = {};
+ const result: DataItem = { title: '' };
const chapterNum = index + 1;
result.title = `第${chapterNum}話 ${item.name === '' ? chapterNum : item.name}`;
result.link = `${rootUrl}/photo/${item.id}`;
diff --git a/lib/routes/18comic/blogs.ts b/lib/routes/18comic/blogs.ts
index 0f127d966982..d3aafe958e05 100644
--- a/lib/routes/18comic/blogs.ts
+++ b/lib/routes/18comic/blogs.ts
@@ -1,6 +1,6 @@
import { load } from 'cheerio';
-import type { Route } from '@/types';
+import type { DataItem, Route } from '@/types';
import cache from '@/utils/cache';
import got from '@/utils/got';
import { parseDate } from '@/utils/parse-date';
@@ -53,13 +53,13 @@ async function handler(ctx) {
let items = $('.title')
.toArray()
- .map((item) => {
- item = $(item);
+ .map((item): DataItem & { guid: string } => {
+ const $item = $(item);
return {
- title: item.text(),
- link: `${rootUrl}${item.parent().attr('href')}`,
- guid: `https://18comic.org${item.parent().attr('href')}`,
+ title: $item.text(),
+ link: `${rootUrl}${$item.parent().attr('href')}`,
+ guid: `https://18comic.org${$item.parent().attr('href')}`,
};
});
@@ -91,7 +91,7 @@ async function handler(ctx) {
return {
title: $('title')
.text()
- .replace(/最新的/, $('.article-nav .active').text()),
+ .replace(/最新的/, () => $('.article-nav .active').text()),
link: currentUrl,
item: items,
description: $('meta[property="og:description"]').attr('content'),
diff --git a/lib/routes/18comic/search.ts b/lib/routes/18comic/search.ts
index ffd8324b8070..2ed8b8bd120d 100644
--- a/lib/routes/18comic/search.ts
+++ b/lib/routes/18comic/search.ts
@@ -1,4 +1,4 @@
-import type { Route } from '@/types';
+import type { DataItem, Route } from '@/types';
import cache from '@/utils/cache';
import { parseDate } from '@/utils/parse-date';
@@ -56,7 +56,7 @@ async function handler(ctx) {
let apiUrl = getApiUrl();
order = time === 'a' ? order : `${order}_${time}`;
- apiUrl = `${apiUrl}/search?search_query=${encodedKeyword}&o=${order}`;
+ apiUrl += `/search?search_query=${encodedKeyword}&o=${order}`;
const apiResult = await processApiItems(apiUrl);
let filteredItemsByCategory = apiResult.content;
// Filter items by category if not 'all'
@@ -67,11 +67,17 @@ async function handler(ctx) {
const results = await Promise.all(
filteredItemsByCategory.map((item) =>
cache.tryGet(`18comic:search:${item.id}`, async () => {
- const result = { title: item.name, link: `${rootUrl}/album/${item.id}`, guid: `18comic:/album/${item.id}`, updated: parseDate(item.update_at) };
+ const result: DataItem = {
+ title: item.name,
+ link: `${rootUrl}/album/${item.id}`,
+ guid: `18comic:/album/${item.id}`,
+ updated: parseDate(item.update_at),
+ };
const apiUrl = `${getApiUrl()}/album?id=${item.id}`;
const apiResult = await processApiItems(apiUrl);
result.pubDate = new Date(apiResult.addtime * 1000);
- result.category = apiResult.tags.map((tag) => tag);
+ const tags = apiResult.tags.map((tag) => tag);
+ result.category = tags;
result.author = apiResult.author.map((a) => a).join(', ');
result.description = renderDescription({
introduction: apiResult.description,
@@ -83,7 +89,7 @@ async function handler(ctx) {
// `https://cdn-msp3.${domain}/media/photos/${item.id}/00003.webp`,
],
cover: `https://cdn-msp3.${domain}/media/albums/${item.id}_3x4.jpg`,
- category: result.category,
+ category: tags,
});
return result;
})
diff --git a/lib/routes/18comic/utils.ts b/lib/routes/18comic/utils.ts
index a210ab843df1..ae62a2b26e2e 100644
--- a/lib/routes/18comic/utils.ts
+++ b/lib/routes/18comic/utils.ts
@@ -3,6 +3,7 @@ import CryptoJS from 'crypto-js';
import { config } from '@/config';
import ConfigNotFoundError from '@/errors/types/config-not-found';
+import type { DataItem } from '@/types';
import cache from '@/utils/cache';
import got from '@/utils/got';
import md5 from '@/utils/md5';
@@ -99,13 +100,13 @@ const ProcessItems = async (ctx, currentUrl, rootUrl) => {
let items = $('.video-title')
.slice(0, ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit')) : 20)
.toArray()
- .map((item) => {
- item = $(item);
+ .map((item): DataItem & { guid: string } => {
+ const $item = $(item);
return {
- title: item.text().trim(),
- link: `${rootUrl}${item.prev().find('a').attr('href')}`,
- guid: `18comic:${item.prev().find('a').attr('href')}`,
+ title: $item.text().trim(),
+ link: `${rootUrl}${$item.prev().find('a').attr('href')}`,
+ guid: `18comic:${$item.prev().find('a').attr('href')}`,
};
});
@@ -116,8 +117,8 @@ const ProcessItems = async (ctx, currentUrl, rootUrl) => {
const content = load(detailResponse.data);
- item.pubDate = parseDate(content('div[itemprop="datePublished"]').first().attr('content'));
- item.updated = parseDate(content('div[itemprop="datePublished"]').last().attr('content'));
+ item.pubDate = parseDate(content('div[itemprop="datePublished"]').first().attr('content')!);
+ item.updated = parseDate(content('div[itemprop="datePublished"]').last().attr('content')!);
item.category = content('span[data-type="tags"]')
.first()
.find('a')
@@ -133,7 +134,7 @@ const ProcessItems = async (ctx, currentUrl, rootUrl) => {
introduction: content('#intro-block .p-t-5').text(),
images: content('.img_zoom_img img')
.toArray()
- .map((image) => content(image).attr('data-original')),
+ .map((image) => content(image).attr('data-original')!),
cover: content('.thumb-overlay img').first().attr('src'),
category: item.category,
});
diff --git a/lib/routes/199it/index.tsx b/lib/routes/199it/index.tsx
index 39d540fd3a32..f56c4ed963e1 100644
--- a/lib/routes/199it/index.tsx
+++ b/lib/routes/199it/index.tsx
@@ -4,7 +4,7 @@ import type { Element } from 'domhandler';
import type { Context } from 'hono';
import { renderToString } from 'hono/jsx/dom/server';
-import type { Data, DataItem, Route } from '@/types';
+import type { Data, DataItem, Language, Route } from '@/types';
import { ViewType } from '@/types';
import cache from '@/utils/cache';
import ofetch from '@/utils/ofetch';
@@ -12,19 +12,19 @@ import { parseDate } from '@/utils/parse-date';
export const handler = async (ctx: Context): Promise => {
const { category = 'newly' } = ctx.req.param();
- const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10);
+ const limit = Number(ctx.req.query('limit') ?? '30');
const baseUrl = 'https://www.199it.com';
- const targetUrl: string = new URL(category, baseUrl).href;
+ const targetUrl = `${baseUrl}/${category}`;
const response = await ofetch(targetUrl);
const $: CheerioAPI = load(response);
- const language = $('html').attr('lang') ?? 'zh-CN';
+ const language = ($('html').attr('lang') ?? 'zh-CN') as Language;
let items: DataItem[] = $('article.newsplus')
.slice(0, limit)
.toArray()
- .map((el): Element => {
+ .map((el) => {
const $el: Cheerio
`);
});
- item.author = content('.fl.black').first().text();
- item.pubDate = timezone(parseDate(content('span.fl.gray').first().attr('title')), +8);
+ item.author = content('.fl.black').text();
+ item.pubDate = timezone(parseDate(content('span.fl.gray').attr('title')!), 8);
const readTpc = content('#read_tpc').first();
const copyLink = content('#copytext')?.first()?.text();
@@ -151,7 +157,7 @@ async function handler(ctx) {
const magnetText = readTpc.find('.magnet-text').first().text().trim();
// Extract enclosure: rmdown.com (fetch page for magnet) | magnet from 哈希校验 | copyLink
- const rmdownLink = readTpc.find('a[href*="rmdown.com/link.php"]').first().attr('href');
+ const rmdownLink = readTpc.find('a[href*="rmdown.com/link.php"]').attr('href');
const enclosureHref = rmdownLink?.startsWith('http') ? rmdownLink : rmdownLink ? `https://www.rmdown.com/${rmdownLink}` : null;
if (enclosureHref) {
@@ -164,7 +170,7 @@ async function handler(ctx) {
}
}
if (!item.enclosure_url) {
- const hashMatch = readTpcHtml.match(/哈希校验[^;]*;\s*([a-fA-F0-9]{40})\s*[;;]/);
+ const hashMatch = readTpcHtml.match(/哈希校验[^;]*;\s*([a-f0-9]{40})\s*[;;]/i);
const magnetFromHash = hashMatch ? `magnet:?xt=urn:btih:${hashMatch[1]}` : null;
const magnetFromText = magnetText.match(/magnet:\?xt=urn:btih:[^\s"'<>]+/)?.[0];
const magnetLink = magnetFromText ?? readTpcHtml.match(/magnet:\?xt=urn:btih:[^\s"'<>]+/)?.[0] ?? magnetFromHash ?? copyLink;
diff --git a/lib/routes/21caijing/channel.ts b/lib/routes/21caijing/channel.ts
index 0ec8a3dc6a2d..13dcb109b9dc 100644
--- a/lib/routes/21caijing/channel.ts
+++ b/lib/routes/21caijing/channel.ts
@@ -3,7 +3,7 @@ import { load } from 'cheerio';
import type { Context } from 'hono';
import InvalidParameterError from '@/errors/types/invalid-parameter';
-import type { Data, DataItem, Route } from '@/types';
+import type { Data, DataItem, Language, Route } from '@/types';
import { ViewType } from '@/types';
import cache from '@/utils/cache';
import ofetch from '@/utils/ofetch';
@@ -43,7 +43,7 @@ const processMenu = (data: any[]) => {
export const handler = async (ctx: Context): Promise => {
const { name = '热点' } = ctx.req.param();
- const limit: number = Number.parseInt(ctx.req.query('limit') ?? '30', 10);
+ const limit = Number(ctx.req.query('limit') ?? '30');
const domain = 'm.21jingji.com';
const baseUrl = `https://${domain}`;
@@ -65,7 +65,7 @@ export const handler = async (ctx: Context): Promise => {
const targetResponse = await ofetch(targetUrl);
const $: CheerioAPI = load(targetResponse);
- const language: string = $('html').attr('lang') ?? 'zh-CN';
+ const language = ($('html').attr('lang') ?? 'zh-CN') as Language;
const authResponse = await ofetch(authUrl, {
method: 'POST',
@@ -91,7 +91,7 @@ export const handler = async (ctx: Context): Promise => {
const title: string = item.title;
const pubDate: string = item.inputtime;
const linkUrl: string | undefined = item.url;
- const categories: string[] = [...new Set(((item.keywords ?? '') as string)?.split(/,/).filter(Boolean))];
+ const categories: string[] = [...new Set
+ {featured.caption?.rendered ?
+
+
')[0] ?? '', { allowedTags: [] }),
+ title: thread.sub ?? sanitizeHtml(thread.com?.split('
', 1)[0] ?? '', { allowedTags: [] }),
}));
};
diff --git a/lib/routes/4gamers/category.ts b/lib/routes/4gamers/category.ts
index e2584f699402..f64867b84218 100644
--- a/lib/routes/4gamers/category.ts
+++ b/lib/routes/4gamers/category.ts
@@ -5,25 +5,28 @@ import got from '@/utils/got';
import { getCategories, parseItem, parseList } from './utils';
export const route: Route = {
- path: ['/', '/category/:category'],
+ path: '/category/:category',
+ categories: ['game'],
+ example: '/4gamers/category/352',
+ parameters: { category: '分类 ID,可从分类 URL 中找到' },
radar: [
{
- source: ['www.4gamers.com.tw/news', 'www.4gamers.com.tw/'],
- target: '',
+ source: ['www.4gamers.com.tw/news/category/:category/:categoryName'],
+ target: '/category/:category',
},
],
- name: 'Unknown',
+ name: '分类',
maintainers: ['TonyRL'],
handler,
url: 'www.4gamers.com.tw/news',
};
-async function handler(ctx) {
+export async function handler(ctx) {
const category = ctx.req.param('category');
const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit')) : 25;
const isLatest = !category;
- const { data: response } = await got(`https://www.4gamers.com.tw/site/api/news/${isLatest ? 'latest' : `by-category/${category}`}`, {
+ const { data: response } = await got(`https://www.4gamers.com.tw/site/api/news/${isLatest ? 'latest' : `of-category/${category}`}`, {
searchParams: {
nextStart: 0,
pageSize: limit,
@@ -35,7 +38,7 @@ async function handler(ctx) {
let categoryName = '最新消息';
if (!isLatest) {
- const categories = await getCategories(cache.tryGet);
+ const categories = await getCategories();
categoryName = categories.find((c) => c.id === Number.parseInt(category)).name;
}
diff --git a/lib/routes/4gamers/index.ts b/lib/routes/4gamers/index.ts
new file mode 100644
index 000000000000..9a55d4a121a4
--- /dev/null
+++ b/lib/routes/4gamers/index.ts
@@ -0,0 +1,19 @@
+import type { Route } from '@/types';
+
+import { handler } from './category';
+
+export const route: Route = {
+ path: '/',
+ categories: ['game'],
+ example: '/4gamers',
+ radar: [
+ {
+ source: ['www.4gamers.com.tw/news', 'www.4gamers.com.tw/'],
+ target: '/',
+ },
+ ],
+ name: '最新消息',
+ maintainers: ['TonyRL'],
+ handler,
+ url: 'www.4gamers.com.tw/news',
+};
diff --git a/lib/routes/4gamers/utils.tsx b/lib/routes/4gamers/utils.tsx
index ca7ea1404d9d..a3358f3b465a 100644
--- a/lib/routes/4gamers/utils.tsx
+++ b/lib/routes/4gamers/utils.tsx
@@ -2,11 +2,12 @@ import { raw } from 'hono/html';
import { renderToString } from 'hono/jsx/dom/server';
import InvalidParameterError from '@/errors/types/invalid-parameter';
+import cache from '@/utils/cache';
import got from '@/utils/got';
import { parseDate } from '@/utils/parse-date';
-const getCategories = (tryGet) =>
- tryGet('4gamers:categories', async () => {
+const getCategories = () =>
+ cache.tryGet('4gamers:categories', async () => {
const { data: response } = await got('https://www.4gamers.com.tw/site/api/news/category');
return response.data.map((category) => ({
diff --git a/lib/routes/4khd/article.ts b/lib/routes/4khd/article.ts
index 75a2a585b03b..575700ea78a3 100644
--- a/lib/routes/4khd/article.ts
+++ b/lib/routes/4khd/article.ts
@@ -8,10 +8,12 @@ const processImages = ($) => {
$('a').each((_, elem) => {
const $elem = $(elem);
const largePhotoUrl = $elem.attr('href')?.replace('i0.wp.com', '').replace('pic.4khd.com', 'yt4.googleusercontent.com').replace('AsHYQ', 'AsYHQ').replace('l/AAA', 'I/AAA');
- if (largePhotoUrl) {
- $elem.attr('href', largePhotoUrl);
- $elem.find('img').attr('src', largePhotoUrl);
+ if (!largePhotoUrl) {
+ return;
}
+
+ $elem.attr('href', largePhotoUrl);
+ $elem.find('img').attr('src', largePhotoUrl);
});
};
@@ -21,7 +23,7 @@ function loadArticle(item: WPPost) {
return {
title: item.title.rendered,
- description: article.html() ?? '',
+ description: article.html(),
pubDate: parseDate(item.date_gmt),
link: item.link,
};
diff --git a/lib/routes/4khd/category.ts b/lib/routes/4khd/category.ts
index 34d93d5d856d..92576f658851 100644
--- a/lib/routes/4khd/category.ts
+++ b/lib/routes/4khd/category.ts
@@ -3,7 +3,6 @@ import got from '@/utils/got';
import loadArticle from './article';
import { SUB_NAME_PREFIX, SUB_URL } from './const';
-import type { WPPost } from './types';
export const route: Route = {
path: '/category/:category',
@@ -37,14 +36,13 @@ async function handler(ctx) {
const categoryUrl = `${SUB_URL}pages/${category}/`;
const slug = category === 'album' ? 'photo' : category;
- const {
- data: [{ id: categoryId }],
- } = await got(`${SUB_URL}wp-json/wp/v2/categories?slug=${slug}`);
+ const { data } = await got(`${SUB_URL}wp-json/wp/v2/categories?slug=${slug}`);
+ const categoryId = data[0].id;
const { data: posts } = await got(`${SUB_URL}wp-json/wp/v2/posts?categories=${categoryId}&per_page=${limit}`);
return {
title: `${SUB_NAME_PREFIX} - Category: ${category}`,
link: categoryUrl,
- item: posts.map((post) => loadArticle(post as WPPost)),
+ item: posts.map((post) => loadArticle(post)),
};
}
diff --git a/lib/routes/4khd/latest.ts b/lib/routes/4khd/latest.ts
index 62774ef8577b..006e399a776f 100644
--- a/lib/routes/4khd/latest.ts
+++ b/lib/routes/4khd/latest.ts
@@ -33,11 +33,11 @@ export const route: Route = {
async function handler(ctx) {
const limit = Number.parseInt(ctx.req.query('limit')) || 20;
- const { data: posts } = await got(`${SUB_URL}wp-json/wp/v2/posts?per_page=${limit}`);
+ const { data: posts }: { data: WPPost[] } = await got(`${SUB_URL}wp-json/wp/v2/posts?per_page=${limit}`);
return {
title: `${SUB_NAME_PREFIX} - Latest`,
link: SUB_URL,
- item: posts.map((post) => loadArticle(post as WPPost)),
+ item: posts.map((post) => loadArticle(post)),
};
}
diff --git a/lib/routes/4ksj/forum.tsx b/lib/routes/4ksj/forum.tsx
index 4762c3e87bb8..f328d2b404d2 100644
--- a/lib/routes/4ksj/forum.tsx
+++ b/lib/routes/4ksj/forum.tsx
@@ -2,12 +2,14 @@ import { load } from 'cheerio';
import { raw } from 'hono/html';
import { renderToString } from 'hono/jsx/dom/server';
-import type { Route } from '@/types';
+import InvalidParameterError from '@/errors/types/invalid-parameter';
+import type { DataItem, Language, Route } from '@/types';
import cache from '@/utils/cache';
import md5 from '@/utils/md5';
import ofetch from '@/utils/ofetch';
import { parseDate } from '@/utils/parse-date';
import timezone from '@/utils/timezone';
+import { isValidHost } from '@/utils/valid-host';
const renderDescription = ({ images, title, keys, details, description, info, links }) =>
renderToString(
@@ -79,6 +81,10 @@ function stringtoHex(acSTR) {
async function handler(ctx) {
const { id = '4k-uhd-1' } = ctx.req.param();
+ if (!isValidHost(id)) {
+ throw new InvalidParameterError('Invalid id');
+ }
+
const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit')) : 25;
const rootUrl = 'https://www.4ksj.com';
@@ -92,17 +98,18 @@ async function handler(ctx) {
const $ = load(decoder.decode(response));
- const language = 'zh';
+ const language = 'zh' as const satisfies Language;
const image = $('div.nexlogo img').prop('src');
let items = $('div.nex_cmo_piv a')
.slice(0, limit)
.toArray()
- .map((item) => {
- item = $(item);
+ .map((item): DataItem & { link: string } => {
+ const $item = $(item);
return {
- link: new URL(item.prop('href'), rootUrl).href,
+ link: new URL($item.prop('href')!, rootUrl).href,
+ title: '',
};
});
@@ -114,7 +121,7 @@ async function handler(ctx) {
const scriptUrl = new URL(scriptPath, rootUrl).href;
const scriptResponse = await ofetch(scriptUrl);
- const key = scriptResponse.match(/{var key="(.*?)"/)?.[1];
+ const key = scriptResponse.match(/\{var key="(.*?)"/)?.[1];
const value = scriptResponse.match(/",value="(.*?)"/)?.[1];
const getPath = scriptResponse.match(/\.get\("(.*?&key=)"/)?.[1];
@@ -125,7 +132,7 @@ async function handler(ctx) {
const cookieResponse = await ofetch.raw(`${rootUrl}${getPath}${key}&value=${md5(stringtoHex(value))}`);
return cookieResponse.headers
.getSetCookie()
- .map((c) => c.split(';')[0])
+ .map((c) => c.split(';', 1)[0])
.join('; ');
});
@@ -137,7 +144,7 @@ async function handler(ctx) {
const detailResponse = await ofetch(item.link, {
responseType: 'arrayBuffer',
headers: {
- Cookie: cookie as string,
+ Cookie: cookie,
},
});
@@ -145,28 +152,28 @@ async function handler(ctx) {
$$('div.nex_drama_intros em').first().remove();
$$('strong font').each((_, el) => {
- el = $$(el);
+ const $el = $$(el);
- el.parent().remove();
+ $el.parent().remove();
});
const title = $$('div.nex_drama_Top h5').text();
const description = $$('div.nex_drama_intros').html();
const picture =
$$('div.nex_drama_pic')
- .html()
+ .html()!
.match(/background:url\((.*?)\)/)?.[1] ?? '';
const details = $$('li.nex_drama_Detail_li, li.nex_drama_Detail_lis dd')
.toArray()
.map((li) => {
- li = $$(li);
+ const $li = $$(li);
- const key = li
+ const key = $li
.find('em')
.text()
.replaceAll(/:|\s/g, '');
- const value = li.find('span').length === 0 ? li.contents().last().text().trim() : li.find('span').text().trim();
+ const value = $li.find('span').length === 0 ? $li.contents().last().text().trim() : $li.find('span').text().trim();
return { [key]: value };
});
@@ -177,18 +184,18 @@ async function handler(ctx) {
? $$('td.t_f strong')
.toArray()
.map((l) => {
- l = $$(l);
+ const $l = $$(l);
- const title = l.contents().first().text();
- const link = l.next().prop('href') ?? l.nextUntil('a').next().prop('href');
+ const title = $l.contents().first().text();
+ const link = $l.next().prop('href') ?? $l.nextUntil('a').next().prop('href');
- item.enclosure_url = item.enclosure_url ?? link;
- item.enclosure_type = item.enclosure_type ?? 'application/x-bittorrent';
- item.enclosure_title = item.enclosure_title ?? title;
+ item.enclosure_url ??= link;
+ item.enclosure_type ??= 'application/x-bittorrent';
+ item.enclosure_title ??= title;
return {
title,
- tags: l
+ tags: $l
.contents()
.last()
.text()
@@ -199,15 +206,15 @@ async function handler(ctx) {
: $$('div.newfujian')
.toArray()
.map((l) => {
- l = $$(l);
+ const $l = $$(l);
return {
- title: l.find('p.filename').prop('title') || l.find('p.filename').text(),
- tags: l
+ title: $l.find('p.filename').prop('title') || $l.find('p.filename').text(),
+ tags: $l
.find('div.fileaq')
.text()
.match(/【(.*?)】/g),
- link: l.find('div.down_2 a').prop('href'),
+ link: $l.find('div.down_2 a').prop('href'),
};
});
@@ -237,8 +244,8 @@ async function handler(ctx) {
info: $$('div.nex_drama_sums').html(),
links,
});
- item.pubDate = timezone(parseDate(pubDate, 'YYYY-M-D HH:mm:ss'), +8);
- item.category = Object.values(mergedDetails)
+ item.pubDate = timezone(parseDate(pubDate, 'YYYY-M-D HH:mm:ss'), 8);
+ item.category = Object.values
))}
diff --git a/lib/routes/591/list.tsx b/lib/routes/591/list.tsx
index 76bbe7c99af1..a9e7f5a3887b 100644
--- a/lib/routes/591/list.tsx
+++ b/lib/routes/591/list.tsx
@@ -24,7 +24,7 @@ function appendRentalAPIParams(urlString) {
}
async function getToken() {
- const html = await client('https://rent.591.com.tw').text();
+ const { body: html } = await client('https://rent.591.com.tw');
const $ = load(html);
const csrfToken = $('meta[name="csrf-token"]').attr('content');
@@ -39,12 +39,12 @@ async function getToken() {
async function getHouseList(houseListURL) {
const csrfToken = await getToken();
- const data = await client({
+ const { data } = await client({
url: houseListURL,
headers: {
'X-CSRF-TOKEN': csrfToken,
},
- }).json();
+ });
const {
data: { data: houseList },
diff --git a/lib/routes/5music/index.ts b/lib/routes/5music/index.ts
index bcfd1c3af748..92cbbdc02bb7 100644
--- a/lib/routes/5music/index.ts
+++ b/lib/routes/5music/index.ts
@@ -1,6 +1,6 @@
import { load } from 'cheerio';
-import type { Route } from '@/types';
+import type { Language, Route } from '@/types';
import got from '@/utils/got';
import { parseDate } from '@/utils/parse-date';
@@ -84,6 +84,6 @@ async function handler(ctx) {
title: '五大唱片 - 新货上架',
link: url,
item: items,
- language: 'zh-tw',
+ language: 'zh-TW' as const satisfies Language,
};
}
diff --git a/lib/routes/69shu/article.ts b/lib/routes/69shu/article.ts
index bc13b6c30ce7..c3d74ece3783 100644
--- a/lib/routes/69shu/article.ts
+++ b/lib/routes/69shu/article.ts
@@ -45,32 +45,33 @@ export const route: Route = {
item,
image: $('.bookimg2>img').attr('src'),
author: $('.booknav2>p:first-of-type>a').text(),
- language: 'zh-cn',
+ language: 'zh-CN',
};
},
};
const createItem = (url: string) =>
- cache.tryGet(url, async () => {
+ cache.tryGet(url, async (): Promise{detail.label}
- {detail.value?.href && detail.value?.text ? {detail.value.text} : detail.value}
+ {detail.value?.href && detail.value.text ? {detail.value.text} : detail.value}
')
- .flatMap((line, index, array) => (lineMap[index] ? array[lineMap[index]] : line).split('
'))
+ .flatMap((line, index, array) => {
+ const mapped = lineMap[index];
+ return (mapped ? array[mapped] : line).split('
');
+ })
.slice(1, -2)
.join('
');
};
diff --git a/lib/routes/6park/index.ts b/lib/routes/6park/index.ts
index 4e2015f42835..0d10a8feb2ba 100644
--- a/lib/routes/6park/index.ts
+++ b/lib/routes/6park/index.ts
@@ -1,6 +1,6 @@
import { load } from 'cheerio';
-import type { Route } from '@/types';
+import type { DataItem, Route } from '@/types';
import cache from '@/utils/cache';
import got from '@/utils/got';
import { parseDate } from '@/utils/parse-date';
@@ -45,19 +45,20 @@ async function handler(ctx) {
let items = $('#d_list ul li, #thread_list li, .t_l .t_subject')
.toArray()
.slice(0, limit)
- .map((item) => {
- item = $(item);
+ .map((item): DataItem => {
+ const $item = $(item);
- const a = item.find('a').first();
+ const a = $item.find('a').first();
return {
link: `${rootUrl}/${id}/${a.attr('href')}`,
+ title: '',
};
});
items = await Promise.all(
items.map((item) =>
- cache.tryGet(item.link, async () => {
+ cache.tryGet(item.link!, async () => {
const detailResponse = await got({
method: 'get',
url: item.link,
@@ -66,10 +67,10 @@ async function handler(ctx) {
const content = load(detailResponse.data);
item.title = content('title').text().replace(' -6park.com', '');
- item.author = detailResponse.data.match(/送交者: .*>(.*)<.*\[/)[1];
- item.pubDate = timezone(parseDate(detailResponse.data.match(/于 (.*) 已读/)[1], 'YYYY-MM-DD h:m'), +8);
+ item.author = detailResponse.data.match(/送交者:[^>]*>([^<]*)<\/a>/)[1].trim();
+ item.pubDate = timezone(parseDate(detailResponse.data.match(/于 (.*) 已读/)[1], 'YYYY-MM-DD h:m'), 8);
item.description = content('pre')
- .html()
+ .html()!
.replaceAll('', '')
.replaceAll(/6park.com<\/font>/g, '');
diff --git a/lib/routes/6park/news.ts b/lib/routes/6park/news.ts
index 2050185e5d8e..075c49904d1f 100644
--- a/lib/routes/6park/news.ts
+++ b/lib/routes/6park/news.ts
@@ -1,6 +1,6 @@
import { load } from 'cheerio';
-import type { Route } from '@/types';
+import type { DataItem, Route } from '@/types';
import cache from '@/utils/cache';
import got from '@/utils/got';
import { parseDate } from '@/utils/parse-date';
@@ -8,6 +8,8 @@ import timezone from '@/utils/timezone';
export const route: Route = {
path: '/news/:site?/:id?/:keyword?',
+ categories: ['new-media'],
+ example: '/6park/news',
radar: [
{
source: ['club.6parkbbs.com/:id/index.php', 'club.6parkbbs.com/'],
@@ -17,11 +19,16 @@ export const route: Route = {
name: '新闻栏目',
maintainers: ['nczitzk', 'cscnk52'],
parameters: {
- site: '分站,可选newspark、local,默认为 newspark',
- id: '栏目 id,可选,默认为空',
- keyword: '关键词,可选,默认为空',
+ site: '分站,见下表,默认为 newspark',
+ id: '栏目 id',
+ keyword: '关键字',
},
- description: `::: tip 提示
+ description: `分站
+
+| newspark | local |
+| -------- | ----- |
+
+::: tip 提示
若订阅 [时政](https://www.6parknews.com/newspark/index.php?type=1),其网址为
')}`;
+ case 4:
+ return `
${item.comment.user.name}:
`;
+ case 7:
+ return `
${item.comment.comment.body.replaceAll('\n', '
')}${item.talk.name}:
`;
+ case 8:
+ return `
${getContent(item.post)}
+
))}
>
);
diff --git a/lib/routes/98zhibo/namespace.ts b/lib/routes/98zhibo/namespace.ts
new file mode 100644
index 000000000000..161cad308238
--- /dev/null
+++ b/lib/routes/98zhibo/namespace.ts
@@ -0,0 +1,7 @@
+import type { Namespace } from '@/types';
+
+export const namespace: Namespace = {
+ name: '98直播吧',
+ url: 'www.98zhibo.com',
+ lang: 'zh-CN',
+};
diff --git a/lib/routes/98zhibo/zuqiujijin.ts b/lib/routes/98zhibo/zuqiujijin.ts
new file mode 100644
index 000000000000..af14b73467e9
--- /dev/null
+++ b/lib/routes/98zhibo/zuqiujijin.ts
@@ -0,0 +1,102 @@
+import { load } from 'cheerio';
+import iconv from 'iconv-lite';
+
+import type { Data, Route } from '@/types';
+import cache from '@/utils/cache';
+import got from '@/utils/got';
+import { parseDate } from '@/utils/parse-date';
+import timezone from '@/utils/timezone';
+
+const baseUrl = 'https://www.98zhibo.com';
+
+export const route: Route = {
+ path: '/zuqiujijin',
+ categories: ['sport'],
+ example: '/98zhibo/zuqiujijin',
+ name: '足球集锦',
+ maintainers: ['chouj'],
+ radar: [
+ {
+ source: ['www.98zhibo.com/zuqiujijin/'],
+ target: '/zuqiujijin',
+ },
+ ],
+ handler,
+};
+
+// Titles start with the publish date, e.g. 2026年9月9日 欧冠-贝蒂斯客场3-2逆转十人里尔 ...
+const parsePubDateFromTitle = (title: string) => {
+ const match = title.match(/^(\d{4})年(\d{1,2})月(\d{1,2})日/);
+ return match ? timezone(parseDate(`${match[1]}-${match[2]}-${match[3]}`), 8) : undefined;
+};
+
+async function handler(): Promise {
+ const currentUrl = `${baseUrl}/zuqiujijin/`;
+
+ const response = await got({
+ method: 'get',
+ url: currentUrl,
+ responseType: 'buffer',
+ });
+
+ const $ = load(iconv.decode(response.data, 'gbk'));
+
+ const list = $('.list_body_bd li')
+ .toArray()
+ .map((item) => {
+ const $item = $(item);
+ const $link = $item.find('a');
+ const title = $link.text();
+
+ return {
+ title,
+ link: new URL($link.attr('href')!, baseUrl).href,
+ pubDate: parsePubDateFromTitle(title),
+ };
+ });
+
+ const items = await Promise.all(
+ list.map((item) =>
+ cache.tryGet(item.link, async () => {
+ const detailResponse = await got({
+ method: 'get',
+ url: item.link,
+ responseType: 'buffer',
+ });
+ const $detail = load(iconv.decode(detailResponse.data, 'gbk'));
+
+ const $body = $detail('.Content-body');
+ // The hidden block holds the raw match data, the kickoff time is in UTC+8, e.g. 比赛时间:2026-09-09 03:00:00
+ const matchTime = $body
+ .find('div[style*="display:none"]')
+ .text()
+ .match(/比赛时间:(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})/)?.[1];
+
+ // Drop inline scripts, HTML comments and the hidden raw data block, keep only the visible content
+ $body.find('script, div[style*="display:none"]').remove();
+ $body
+ .contents()
+ .filter((_, node) => node.type === 'comment')
+ .remove();
+
+ const $description = $detail('
`).insertBefore(content[0].firstChild);
+ $(`
`).insertBefore(content[0].firstChild!);
}
// remove useless DOMs
@@ -20,11 +20,12 @@ const ProcessFeed = (data) => {
content.find('div.ad-disclaimer-container').remove();
content.find('div').each((i, e) => {
- if ($(e)[0].attribs.class) {
- const classes = $(e)[0].attribs.class;
- if (/\w{10}\s\w{10}/g.test(classes)) {
- $(e).remove();
- }
+ if (!$(e)[0].attribs.class) {
+ return;
+ }
+ const classes = $(e)[0].attribs.class;
+ if (/\w{10}\s\w{10}/.test(classes)) {
+ $(e).remove();
}
});
diff --git a/lib/routes/a9vg/index.ts b/lib/routes/a9vg/index.ts
index 2cbda0659faa..34608ae3957c 100644
--- a/lib/routes/a9vg/index.ts
+++ b/lib/routes/a9vg/index.ts
@@ -1,6 +1,6 @@
import { load } from 'cheerio';
-import type { Route } from '@/types';
+import type { DataItem, Language, Route } from '@/types';
import cache from '@/utils/cache';
import got from '@/utils/got';
import { parseDate } from '@/utils/parse-date';
@@ -10,7 +10,7 @@ import { renderDescription } from './templates/description';
export const handler = async (ctx) => {
const { category = 'news/All' } = ctx.req.param();
- const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 15;
+ const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 15;
const rootUrl = 'http://www.a9vg.com';
const currentUrl = new URL(`list/${category}`, rootUrl).href;
@@ -19,20 +19,20 @@ export const handler = async (ctx) => {
const $ = load(response);
- const language = $('html').prop('lang');
+ const language = $('html').prop('lang') as Language;
let items = $('a.a9-rich-card-list_item')
.slice(0, limit)
.toArray()
- .map((item) => {
- item = $(item);
+ .map((item): DataItem => {
+ const $item = $(item);
- const image = item.find('img.a9-rich-card-list_image');
- const title = item.find('div.a9-rich-card-list_label').text();
+ const image = $item.find('img.a9-rich-card-list_image');
+ const title = $item.find('div.a9-rich-card-list_label').text();
return {
title,
- link: new URL(item.prop('href'), rootUrl).href,
+ link: new URL($item.prop('href')!, rootUrl).href,
description: renderDescription({
images: image
? [
@@ -43,28 +43,28 @@ export const handler = async (ctx) => {
]
: undefined,
}),
- pubDate: timezone(parseDate(item.find('div.a9-rich-card-list_infos').text()), +8),
+ pubDate: timezone(parseDate($item.find('div.a9-rich-card-list_infos').text()), 8),
language,
};
});
items = await Promise.all(
items.map((item) =>
- cache.tryGet(item.link, async () => {
+ cache.tryGet(item.link!, async () => {
const { data: detailResponse } = await got(item.link);
const $$ = load(detailResponse);
$$('ignore_js_op img, p img').each((_, el) => {
- el = $$(el);
+ const $el = $$(el);
- el.parent().replaceWith(
+ $el.parent().replaceWith(
renderDescription({
- images: el.prop('file')
+ images: $el.prop('file')
? [
{
- src: el.prop('file'),
- alt: el.next().find('div.xs0 p').first().text(),
+ src: $el.prop('file'),
+ alt: $el.next().find('div.xs0 p').first().text(),
},
]
: undefined,
@@ -72,9 +72,9 @@ export const handler = async (ctx) => {
);
});
- item.title = $$('h1.ts, div.c-article-main_content-title').first().text();
+ item.title = $$('h1.ts, div.c-article-main_content-title').text();
item.description = renderDescription({
- description: $$('td.t_f, div.c-article-main_contentraw').first().html(),
+ description: $$('td.t_f, div.c-article-main_contentraw').first().html() ?? undefined,
});
item.author =
$$('b a.blue').first().text() ||
@@ -91,11 +91,10 @@ export const handler = async (ctx) => {
$$('div.authi em')
.first()
.text()
- .trim()
.match(/发表于 (\d+-\d+-\d+ \d+:\d+)/)?.[1] ?? $$('span.c-article-main_content-intro-item').first().text(),
['YYYY-M-D HH:mm', 'YYYY-MM-DD HH:mm']
),
- +8
+ 8
);
item.language = language;
diff --git a/lib/routes/aa1/60s.ts b/lib/routes/aa1/60s.ts
index a6569c4b5906..9aa881efcf90 100644
--- a/lib/routes/aa1/60s.ts
+++ b/lib/routes/aa1/60s.ts
@@ -2,14 +2,14 @@ import type { CheerioAPI } from 'cheerio';
import { load } from 'cheerio';
import type { Context } from 'hono';
-import type { Data, DataItem, Route } from '@/types';
+import type { Data, DataItem, Language, Route } from '@/types';
import { ViewType } from '@/types';
import ofetch from '@/utils/ofetch';
import { parseDate } from '@/utils/parse-date';
export const handler = async (ctx: Context): Promise => {
const { category } = ctx.req.param();
- const limit: number = Number.parseInt(ctx.req.query('limit') ?? '100', 10);
+ const limit = Number(ctx.req.query('limit') ?? '100');
const apiSlug = 'wp-json/wp/v2';
const baseUrl = 'https://60s.aa1.cn';
@@ -39,7 +39,7 @@ export const handler = async (ctx: Context): Promise => {
const targetResponse = await ofetch(targetUrl);
const $: CheerioAPI = load(targetResponse);
- const language = $('html').attr('lang') ?? 'zh';
+ const language = ($('html').attr('lang') ?? 'zh') as Language;
const items: DataItem[] = response.slice(0, limit).map((item): DataItem => {
const title: string = item.title?.rendered ?? item.title;
diff --git a/lib/routes/aamacau/index.ts b/lib/routes/aamacau/index.ts
index 86d330dffa4e..daec725567ba 100644
--- a/lib/routes/aamacau/index.ts
+++ b/lib/routes/aamacau/index.ts
@@ -1,6 +1,6 @@
import { load } from 'cheerio';
-import type { Route } from '@/types';
+import type { DataItem, Route } from '@/types';
import cache from '@/utils/cache';
import got from '@/utils/got';
import { parseDate } from '@/utils/parse-date';
@@ -24,7 +24,7 @@ export const route: Route = {
},
],
name: '话题',
- maintainers: [],
+ maintainers: ['nczitzk'],
handler,
url: 'aamacau.com/',
description: `| 即時報道 | 每週專題 | 藝文爛鬼樓 | 論盡紙本 | 新聞事件 | 特別企劃 |
@@ -56,18 +56,18 @@ async function handler(ctx) {
const list = $('post-title a')
.toArray()
- .map((item) => {
- item = $(item);
+ .map((item): DataItem => {
+ const $item = $(item);
return {
- title: item.text(),
- link: item.attr('href'),
+ title: $item.text(),
+ link: $item.attr('href'),
};
});
const items = await Promise.all(
list.map((item) =>
- cache.tryGet(item.link, async () => {
+ cache.tryGet(item.link!, async () => {
const detailResponse = await got({
method: 'get',
url: item.link,
@@ -79,7 +79,7 @@ async function handler(ctx) {
item.description = content('#contentleft').html();
item.author = content('meta[itemprop="author"]').attr('content');
- item.pubDate = parseDate(content('meta[property="article:published_time"]').attr('content'));
+ item.pubDate = parseDate(content('meta[property="article:published_time"]').attr('content')!);
return item;
})
diff --git a/lib/routes/abc-tenpo/detail.ts b/lib/routes/abc-tenpo/detail.ts
new file mode 100644
index 000000000000..d5644be48552
--- /dev/null
+++ b/lib/routes/abc-tenpo/detail.ts
@@ -0,0 +1,177 @@
+import { load } from 'cheerio';
+
+import type { ListingExtra } from '@/routes/temposmart/utils';
+import { clean, normalizeFloor, parseArea, parseCondition, parseHeavyFood, parseJpy, parseWalkMin, parseWard, parseYmd, summarize, tsuboUnit } from '@/routes/temposmart/utils';
+import type { Data, DataItem, Route } from '@/types';
+import cache from '@/utils/cache';
+import ofetch from '@/utils/ofetch';
+import { parseDate } from '@/utils/parse-date';
+import timezone from '@/utils/timezone';
+
+const HOST = 'https://www.abc-tenpo.com';
+
+/**
+ * One listing, from `/property/view/{id}`.
+ *
+ * The visible 所在地 field is truncated and marked 会員限定, but the document title carries the address in
+ * full — '東京都文京区湯島2-31-17・都営大江戸線 本郷三丁目駅・中華料理店|…' — so this is the one place the
+ * site publishes the 丁目 **and the 番地** to a guest. The first `・`-separated segment is that address.
+ */
+const parseDetail = (html: string, id: string): DataItem | null => {
+ const $ = load(html);
+
+ const rows = new Map
+
{intro}
: null}
{description ? raw(description) : null}
diff --git a/lib/routes/acea/namespace.ts b/lib/routes/acea/namespace.ts
new file mode 100644
index 000000000000..2ee1034f0d1b
--- /dev/null
+++ b/lib/routes/acea/namespace.ts
@@ -0,0 +1,3 @@
+import type { Namespace } from '@/types';
+
+export const namespace: Namespace = { name: 'ACEA', url: 'www.acea.auto', lang: 'en' };
diff --git a/lib/routes/acea/publications.ts b/lib/routes/acea/publications.ts
new file mode 100644
index 000000000000..10a49df20bba
--- /dev/null
+++ b/lib/routes/acea/publications.ts
@@ -0,0 +1,71 @@
+import { decodeHTML } from 'entities';
+import type { Context } from 'hono';
+
+import type { Route } from '@/types';
+import ofetch from '@/utils/ofetch';
+import { parseDate } from '@/utils/parse-date';
+
+const baseUrl = 'https://www.acea.auto';
+
+const types = {
+ 'press-releases': 'Press releases',
+ news: 'News',
+ facts: 'Facts',
+ figures: 'Figures',
+ publications: 'Publications',
+};
+
+export const route: Route = {
+ path: '/publications/:type?',
+ example: '/acea/publications/press-releases',
+ name: 'Publications',
+ categories: ['finance'],
+ maintainers: ['DIYgod'],
+ parameters: {
+ type: {
+ description: 'Native content type',
+ options: Object.entries(types).map(([value, label]) => ({ value, label })),
+ default: 'press-releases',
+ },
+ },
+ radar: [{ source: ['www.acea.auto/nav/'], target: '/publications' }],
+ handler,
+};
+
+async function handler(ctx: Context) {
+ const type = ctx.req.param('type') ?? 'press-releases';
+ const response = await ofetch(`${baseUrl}/wp-admin/admin-ajax.php`, {
+ method: 'POST',
+ responseType: 'json',
+ body: new URLSearchParams({ action: 'load_results', 'filters[content][]': type, 'filters[pageNumber]': '1', 'filters[orderby]': 'date' }),
+ });
+ const limit = Number(ctx.req.query('limit')) || 20;
+ const posts = response.posts.slice(0, limit);
+
+ const details = await ofetch(`${baseUrl}/wp-json/wp/v2/allpt`, {
+ query: {
+ include: posts.map((post) => post.ID).join(','),
+ per_page: posts.length,
+ _fields: 'id,date_gmt,content',
+ },
+ });
+
+ const items = posts.map((post) => {
+ const detail = details.find((detail) => detail.id === post.ID);
+ return {
+ title: decodeHTML(post.title),
+ link: post.permalink,
+ description: detail.content.rendered,
+ pubDate: parseDate(`${detail.date_gmt}Z`),
+ category: post.tag.map((tag) => decodeHTML(tag.name)),
+ image: post.thumb?.url,
+ };
+ });
+
+ return {
+ title: `${types[type]} | ACEA - European Automobile Manufacturers' Association`,
+ link: `${baseUrl}/nav/?content=${encodeURIComponent(type)}`,
+ language: 'en' as const,
+ item: items,
+ };
+}
diff --git a/lib/routes/acfun/article.ts b/lib/routes/acfun/article.ts
index fef9499e500a..1cc2de0d342d 100644
--- a/lib/routes/acfun/article.ts
+++ b/lib/routes/acfun/article.ts
@@ -45,7 +45,7 @@ export const route: Route = {
parameters: {
categoryId: {
description: '分区 ID',
- options: Object.keys(categoryMap).map((id) => ({ value: id, label: categoryMap[id].title })),
+ options: Object.entries(categoryMap).map(([id, value]) => ({ value: id, label: value.title })),
},
sortType: {
description: '排序',
@@ -94,7 +94,7 @@ export const route: Route = {
async function handler(ctx) {
const { categoryId, sortType = 'createTime', timeRange = 'all' } = ctx.req.param();
- if (!categoryMap[categoryId]) {
+ if (!Object.hasOwn(categoryMap, categoryId)) {
throw new InvalidParameterError(`Invalid category Id: ${categoryId}`);
}
if (!sortTypeEnum.has(sortType)) {
@@ -133,7 +133,7 @@ async function handler(ctx) {
const $ = load(response.data);
const articleInfo = $('.main script')
.text()
- .match(/window.articleInfo = (.*);\n\s*window.likeDomain/)[1];
+ .match(/window.articleInfo = (.*);\n\s*window.likeDomain/)![1];
const data = JSON.parse(articleInfo);
item.description = data.parts[0].content;
diff --git a/lib/routes/acfun/bangumi.ts b/lib/routes/acfun/bangumi.ts
index 01be818d10df..d29c818e959f 100644
--- a/lib/routes/acfun/bangumi.ts
+++ b/lib/routes/acfun/bangumi.ts
@@ -44,7 +44,7 @@ async function handler(ctx) {
image: bangumiData.belongResource.coverImageV,
item: bangumiList.items.map((item) => ({
title: `${item.episodeName}${item.title ? ` - ${item.title}` : ''}`,
- description: renderDescription({ embed, aid: `ac${item.itemId}`, img: item.imgInfo.thumbnailImage.cdnUrls[0].url.split('?')[0] }),
+ description: renderDescription({ embed, aid: `ac${item.itemId}`, img: item.imgInfo.thumbnailImage.cdnUrls[0].url.split('?', 1)[0] }),
link: `https://www.acfun.cn/bangumi/aa${id}_36188_${item.itemId}`,
pubDate: parseDate(item.updateTime, 'x'),
})),
diff --git a/lib/routes/acfun/user-article.ts b/lib/routes/acfun/user-article.ts
new file mode 100644
index 000000000000..b54258f5d526
--- /dev/null
+++ b/lib/routes/acfun/user-article.ts
@@ -0,0 +1,90 @@
+import { load } from 'cheerio';
+
+import type { Route } from '@/types';
+import { ViewType } from '@/types';
+import cache from '@/utils/cache';
+import ofetch from '@/utils/ofetch';
+import { parseDate } from '@/utils/parse-date';
+
+const host = 'https://www.acfun.cn';
+
+export const route: Route = {
+ path: '/user/article/:uid',
+ radar: [
+ {
+ source: ['www.acfun.cn/u/:id'],
+ target: '/user/article/:id',
+ },
+ ],
+ name: '用户文章',
+ parameters: {
+ uid: '用户 UID',
+ },
+ categories: ['anime'],
+ example: '/acfun/user/article/1384329',
+ view: ViewType.Articles,
+ maintainers: ['tiaod'],
+ handler,
+};
+
+async function handler(ctx) {
+ const uid = ctx.req.param('uid');
+ const link = `${host}/u/${uid}`;
+ const page = await ofetch(link);
+ const $ = load(page);
+
+ const username = $('#ac-space-info .name').first().text().trim();
+ const description = $('.signature .complete').text();
+ const image = $('head style:contains("user-photo")')
+ .text()
+ .match(/.user-photo\{\n\s*background:url\((.*)\) 0% 0% \/ 100% no-repeat;/)?.[1];
+
+ const list = $('#ac-space-article-list .weblog-item')
+ .toArray()
+ .map((item) => {
+ const $item = $(item);
+ const $title = $item.find('a.title');
+ const itemDate = $item
+ .find('.info')
+ .text()
+ .match(/\d{4}\/\d{1,2}\/\d{1,2}/)?.[0];
+
+ return {
+ title: $title.text(),
+ link: `${host}${$title.attr('href')}`,
+ pubDate: itemDate ? parseDate(itemDate, 'YYYY/MM/DD') : undefined,
+ };
+ });
+
+ const items = await Promise.all(
+ list.map((item) =>
+ cache.tryGet(item.link, async () => {
+ const articlePage = await ofetch(item.link, {
+ headers: {
+ referer: link,
+ },
+ });
+ const $article = load(articlePage);
+ const articleInfo = $article('.main script')
+ .text()
+ .match(/window\.articleInfo = (.*);\n\s*window.likeDomain/)![1];
+ const data = JSON.parse(articleInfo);
+
+ return {
+ ...item,
+ description: data.parts[0].content,
+ author: data.user?.name,
+ category: [...(data.channel?.name ? [data.channel.name] : []), ...(data.tagList ?? []).map((tag) => tag.name)],
+ };
+ })
+ )
+ );
+
+ return {
+ title: username ? `${username}的文章` : $('title').text(),
+ link,
+ description,
+ image,
+ item: items,
+ };
+}
diff --git a/lib/routes/acfun/video.ts b/lib/routes/acfun/video.ts
index 39ca0200be73..ec5c50b9302a 100644
--- a/lib/routes/acfun/video.ts
+++ b/lib/routes/acfun/video.ts
@@ -40,7 +40,7 @@ async function handler(ctx) {
const list = $('#ac-space-video-list a').toArray();
const image = $('head style:contains("user-photo")')
.text()
- .match(/.user-photo{\n\s*background:url\((.*)\) 0% 0% \/ 100% no-repeat;/)?.[1];
+ .match(/.user-photo\{\n\s*background:url\((.*)\) 0% 0% \/ 100% no-repeat;/)?.[1];
return {
title,
@@ -54,12 +54,12 @@ async function handler(ctx) {
const itemImg = $item.find('figure img').attr('src');
const itemUrl = $item.attr('href')!;
const itemDate = $item.find('.date').text();
- const wbInfo = JSON.parse(($item.data('wb-info') as string) || '{}');
+ const wbInfo = JSON.parse($item.attr('data-wb-info') || '{}');
const aid = wbInfo.atmid || wbInfo.mediaId || itemUrl.match(/\/v\/(ac\d+)/)?.[1];
return {
title: itemTitle,
- description: renderDescription({ embed, aid, img: itemImg?.split('?')[0] }),
+ description: renderDescription({ embed, aid, img: itemImg?.split('?', 1)[0] }),
link: host + itemUrl,
pubDate: parseDate(itemDate, 'YYYY/MM/DD'),
};
diff --git a/lib/routes/acgvinyl/news.ts b/lib/routes/acgvinyl/news.ts
index 3a8f618f0843..0b5e52622bc7 100644
--- a/lib/routes/acgvinyl/news.ts
+++ b/lib/routes/acgvinyl/news.ts
@@ -8,7 +8,7 @@ import { parseDate } from '@/utils/parse-date';
export const route: Route = {
path: '/news',
categories: ['anime'],
- example: '/news',
+ example: '/acgvinyl/news',
features: {
requireConfig: false,
requirePuppeteer: false,
@@ -40,6 +40,7 @@ async function handler(ctx) {
const newsIndexJsonText = $('script:contains("window.__INITIAL_STATE__")').text().replaceAll('window.__INITIAL_STATE__=', '');
const newsIndexJson = JSON.parse(newsIndexJsonText);
+ const limit = ctx.req.query('limit');
const newsListResponse = await ofetch(`${rootUrl}/rajax/news_h.jsp?cmd=getWafNotCk_getList`, {
method: 'POST',
headers: {
@@ -47,7 +48,7 @@ async function handler(ctx) {
},
body: new URLSearchParams({
page: '1',
- pageSize: String(ctx.req.query('limit') ?? 20),
+ pageSize: String(limit ?? 20),
fromMid: newsIndexJson.modules.module366.id,
idList: `[${newsIndexJson.modules.module366.prop3}]`,
sortKey: newsIndexJson.modules.module366.blob0.sortKey,
diff --git a/lib/routes/acm/amturingaward.ts b/lib/routes/acm/amturingaward.ts
new file mode 100644
index 000000000000..1e61f209d3d1
--- /dev/null
+++ b/lib/routes/acm/amturingaward.ts
@@ -0,0 +1,64 @@
+import { load } from 'cheerio';
+
+import type { Route } from '@/types';
+import ofetch from '@/utils/ofetch';
+import { parseDate } from '@/utils/parse-date';
+
+export const route: Route = {
+ path: '/amturingaward',
+ categories: ['programming'],
+ example: '/acm/amturingaward',
+ name: 'A.M.Turing Award Winners',
+ maintainers: ['nczitzk'],
+ handler,
+};
+
+async function handler() {
+ const rootUrl = 'https://amturing.acm.org';
+ const currentUrl = `${rootUrl}/byyear.cfm`;
+ const response = await ofetch(currentUrl);
+
+ const $ = load(response);
+
+ const items = await Promise.all(
+ $('.award-winners-list li')
+ .slice(0, 5)
+ .toArray()
+ .map(async (item) => {
+ const $item = $(item);
+
+ const year = $item.find('span').text().replaceAll(/[()]/g, '');
+
+ const winnersUrls = $item
+ .find('a')
+ .toArray()
+ .map((a) => `${rootUrl}${$(a).attr('href')}`);
+ const winners = await Promise.all(winnersUrls.map((url) => ofetch(url)));
+
+ let description = '';
+ for (const winner of winners) {
+ const content = load(winner);
+ const image = content('.featured-photo').html() ?? '';
+ const column = content('#tertiary-navigation').parent();
+
+ content('#tertiary-navigation').remove();
+
+ description += image + column.html();
+ }
+
+ return {
+ pubDate: parseDate(`${year}-12-31`),
+ description,
+ title: year,
+ link: currentUrl,
+ guid: `${currentUrl}#${year}`,
+ };
+ })
+ );
+
+ return {
+ title: 'A.M. Turing Award Winners',
+ link: currentUrl,
+ item: items,
+ };
+}
diff --git a/lib/routes/acm/namespace.ts b/lib/routes/acm/namespace.ts
new file mode 100644
index 000000000000..1101bdeab790
--- /dev/null
+++ b/lib/routes/acm/namespace.ts
@@ -0,0 +1,8 @@
+import type { Namespace } from '@/types';
+
+export const namespace: Namespace = {
+ name: 'Association for Computing Machinery (ACM)',
+ url: 'amturing.acm.org',
+ categories: ['programming'],
+ lang: 'en',
+};
diff --git a/lib/routes/acpaa/index.ts b/lib/routes/acpaa/index.ts
index 60707c519458..7c89c37ea6d4 100644
--- a/lib/routes/acpaa/index.ts
+++ b/lib/routes/acpaa/index.ts
@@ -1,6 +1,6 @@
import { load } from 'cheerio';
-import type { Route } from '@/types';
+import type { DataItem, Route } from '@/types';
import cache from '@/utils/cache';
import got from '@/utils/got';
import { parseDate } from '@/utils/parse-date';
@@ -26,7 +26,7 @@ export const route: Route = {
async function handler(ctx) {
const { id = '1', name = '重要通知' } = ctx.req.param();
- const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 30;
+ const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 30;
const rootUrl = 'http://www.acpaa.cn';
const currentUrl = new URL(`article/taglist.jhtml?tagIds=${id}&tagname=${name}`, rootUrl).href;
@@ -38,19 +38,19 @@ async function handler(ctx) {
let items = $('div.text01 ul li a[title]')
.slice(0, limit)
.toArray()
- .map((item) => {
- item = $(item);
+ .map((item): DataItem => {
+ const $item = $(item);
return {
- title: item.prop('title'),
- link: new URL(item.prop('href'), rootUrl).href,
- pubDate: timezone(parseDate(item.find('span[title]').prop('title')), +8),
+ title: $item.prop('title')!,
+ link: new URL($item.prop('href')!, rootUrl).href,
+ pubDate: timezone(parseDate($item.find('span[title]').prop('title')), 8),
};
});
items = await Promise.all(
items.map((item) =>
- cache.tryGet(item.link, async () => {
+ cache.tryGet(item.link!, async () => {
const { data: detailResponse } = await got(item.link);
const content = load(detailResponse);
@@ -71,7 +71,7 @@ async function handler(ctx) {
title: `${author} - ${subtitle}`,
link: currentUrl,
description: $('meta[property="og:description"]').prop('content'),
- language: 'zh',
+ language: 'zh' as const,
subtitle,
author,
};
diff --git a/lib/routes/acs/journal.tsx b/lib/routes/acs/journal.tsx
index 4ad4d5587da1..6160439ac326 100644
--- a/lib/routes/acs/journal.tsx
+++ b/lib/routes/acs/journal.tsx
@@ -10,14 +10,23 @@ import playwright from '@/utils/playwright';
export const route: Route = {
path: '/journal/:id',
+ categories: ['journal'],
+ example: '/acs/journal/jacsat',
+ parameters: { id: 'Journal id, can be found in URL' },
+ features: {
+ supportScihub: true,
+ },
radar: [
{
source: ['pubs.acs.org/journal/:id', 'pubs.acs.org/'],
},
],
- name: 'Unknown',
+ name: 'Journal',
maintainers: ['nczitzk'],
handler,
+ description: `::: tip
+See [Browse Content](https://pubs.acs.org)
+:::`,
};
async function handler(ctx) {
@@ -28,47 +37,47 @@ async function handler(ctx) {
let title = '';
- const browser = await playwright();
+ const context = await playwright();
const items = await cache.tryGet(
currentUrl,
async () => {
- const page = await browser.newPage();
- await page.setRequestInterception(true);
- page.on('request', (request) => {
- request.resourceType() === 'document' || request.resourceType() === 'script' ? request.continue() : request.abort();
+ const page = await context.newPage();
+ await page.route('**/*', (route) => {
+ const request = route.request();
+ request.resourceType() === 'document' || request.resourceType() === 'script' ? route.continue() : route.abort();
});
await page.goto(currentUrl, {
waitUntil: 'domcontentloaded',
});
await page.waitForSelector('.toc');
- const html = await page.evaluate(() => document.documentElement.innerHTML);
+ const html = await page.evaluate(() => document.documentElement.getHTML());
await page.close();
const $ = load(html);
- title = $('meta[property="og:title"]').attr('content');
+ title = $('meta[property="og:title"]').attr('content')!;
return $('.issue-item')
.toArray()
.map((item) => {
- item = $(item);
+ const $item = $(item);
- const a = item.find('.issue-item_title a');
- const doi = item.find('input[name="doi"]').attr('value');
+ const a = $item.find('.issue-item_title a');
+ const doi = $item.find('input[name="doi"]').attr('value');
return {
doi,
guid: doi,
title: a.text(),
link: `${rootUrl}${a.attr('href')}`,
- pubDate: parseDate(item.find('.pub-date-value').text(), 'MMMM D, YYYY'),
- author: item
+ pubDate: parseDate($item.find('.pub-date-value').text(), 'MMMM D, YYYY'),
+ author: $item
.find('.issue-item_loa li')
.toArray()
.map((a) => $(a).text())
.join(', '),
- description: renderDescription(item.find('.issue-item_img').html(), item.find('.hlFld-Abstract').html()),
+ description: renderDescription($item.find('.issue-item_img').html(), $item.find('.hlFld-Abstract').html()),
};
});
},
@@ -76,7 +85,7 @@ async function handler(ctx) {
false
);
- await browser.close();
+ await context.close();
return {
title,
diff --git a/lib/routes/acwifi/index.ts b/lib/routes/acwifi/index.ts
new file mode 100644
index 000000000000..eabef9222f15
--- /dev/null
+++ b/lib/routes/acwifi/index.ts
@@ -0,0 +1,77 @@
+import { load } from 'cheerio';
+
+import type { Route } from '@/types';
+import cache from '@/utils/cache';
+import ofetch from '@/utils/ofetch';
+
+export const route: Route = {
+ path: '/',
+ categories: ['other'],
+ example: '/acwifi',
+ name: '新闻',
+ maintainers: ['cc798461'],
+ features: {
+ antiCrawler: true,
+ },
+ handler,
+};
+
+const toHex = (s: string) => Buffer.from(s).toString('hex');
+
+const getCookie = async (url: string) => {
+ const init = await ofetch.raw(url);
+ const sessionVerify = init.headers
+ .getSetCookie()
+ .map((c) => c.split(';', 1)[0])
+ .find((c) => c.startsWith('security_session_verify='));
+ if (!sessionVerify) {
+ return '';
+ }
+
+ const verify = await ofetch.raw(`${url}?security_verify_data=${toHex('1920,1080')}`, {
+ headers: { Cookie: `${sessionVerify}; srcurl=${toHex(url)}` },
+ });
+ const midVerify = verify.headers
+ .getSetCookie()
+ .map((c) => c.split(';', 1)[0])
+ .find((c) => c.startsWith('security_session_mid_verify='));
+
+ return midVerify ? `${sessionVerify}; ${midVerify}` : sessionVerify;
+};
+
+async function handler() {
+ const baseUrl = 'https://www.acwifi.net/';
+ const cookie = await getCookie(baseUrl);
+ const response = await ofetch(baseUrl, { headers: { Cookie: cookie } });
+ const $ = load(response);
+
+ const list = $('h2')
+ .toArray()
+ .map((item) => {
+ const $a = $(item).find('a');
+ return {
+ title: $a.text(),
+ link: $a.attr('href')!,
+ };
+ });
+
+ const out = await Promise.all(
+ list.map(({ title, link }) =>
+ cache.tryGet(link, async () => {
+ const response = await ofetch(link, {
+ headers: { Cookie: cookie },
+ });
+ const $ = load(response);
+ const content = $('article.article-content');
+ content.find('code-block').remove();
+ return {
+ title,
+ description: content.html(),
+ link,
+ };
+ })
+ )
+ );
+
+ return { title: '路由器交流', link: baseUrl, item: out };
+}
diff --git a/lib/routes/acwifi/namespace.ts b/lib/routes/acwifi/namespace.ts
new file mode 100644
index 000000000000..57837888c449
--- /dev/null
+++ b/lib/routes/acwifi/namespace.ts
@@ -0,0 +1,8 @@
+import type { Namespace } from '@/types';
+
+export const namespace: Namespace = {
+ name: '路由器技术分享',
+ url: 'www.acwifi.net',
+ categories: ['other'],
+ lang: 'zh-CN',
+};
diff --git a/lib/routes/adquan/case-library.ts b/lib/routes/adquan/case-library.ts
index 49bc2804798f..f29554c759c8 100644
--- a/lib/routes/adquan/case-library.ts
+++ b/lib/routes/adquan/case-library.ts
@@ -3,7 +3,7 @@ import { load } from 'cheerio';
import type { Element } from 'domhandler';
import type { Context } from 'hono';
-import type { Data, DataItem, Route } from '@/types';
+import type { Data, DataItem, Language, Route } from '@/types';
import { ViewType } from '@/types';
import cache from '@/utils/cache';
import ofetch from '@/utils/ofetch';
@@ -13,19 +13,19 @@ import timezone from '@/utils/timezone';
import { renderDescription } from './templates/description';
export const handler = async (ctx: Context): Promise => {
- const limit: number = Number.parseInt(ctx.req.query('limit') ?? '24', 10);
+ const limit = Number(ctx.req.query('limit') ?? '24');
const baseUrl = 'https://www.adquan.com';
const targetUrl: string = new URL('case_library/index', baseUrl).href;
const response = await ofetch(targetUrl);
const $: CheerioAPI = load(response);
- const language = $('html').attr('lang') ?? 'zh-CN';
+ const language = ($('html').attr('lang') ?? 'zh-CN') as Language;
let items: DataItem[] = $('div.article_1')
.slice(0, limit)
.toArray()
- .map((el): Element => {
+ .map((el) => {
const $el: Cheerio`, '') // small | middle | orign
+ ? JSON.parse(post.photoLinks)
+ .map((currentValue) => `
`) // small | middle | orign
+ .join('')
: '';
const digest = load(post.digest);
diff --git a/lib/routes/lofter/user.ts b/lib/routes/lofter/user.ts
index ee509e0f1dff..582241cd0840 100644
--- a/lib/routes/lofter/user.ts
+++ b/lib/routes/lofter/user.ts
@@ -40,7 +40,7 @@ async function handler(ctx) {
blogdomain: rootUrl,
checkpwd: '1',
following: '0',
- limit,
+ limit: String(limit),
method: 'getPostLists',
needgetpoststat: '1',
offset: '0',
diff --git a/lib/routes/logclub/columnist.ts b/lib/routes/logclub/columnist.ts
new file mode 100644
index 000000000000..8fa009b18132
--- /dev/null
+++ b/lib/routes/logclub/columnist.ts
@@ -0,0 +1,106 @@
+import type { Route } from '@/types';
+
+import { handler } from './index';
+
+export const route: Route = {
+ path: '/columnist/articleList/:id?',
+ categories: ['new-media'],
+ example: '/logclub/columnist/articleList/27',
+ parameters: { id: '专家 id,见下表,可在对应企业页 URL 中找到' },
+ radar: [
+ {
+ source: ['logclub.com/columnist/articleList/:id'],
+ target: '/columnist/articleList/:id',
+ },
+ ],
+ name: '专家说',
+ maintainers: ['nczitzk'],
+ handler,
+ description: `#### 精选专家
+
+| 潘永刚 | Tracy | 唐隆基 | 褚建新 |
+| ------ | ----- | ------ | ------ |
+| 27 | 157 | 91 | 9749 |
+
+前往 [更多](https://www.logclub.com/columnist/authorMore/experts) 查看更多专家
+
+#### 资深作者
+
+| 物流麻将胡 | 小周伯通 | 郭嘉 | 周艳青 |
+| ---------- | -------- | ---- | ------ |
+| 10 | 19 | 7 | 559 |
+
+前往 [更多](https://www.logclub.com/columnist/authorMore/author) 查看更多专家
+
+#### 综合物流
+
+| 韩雪峰 | 李赛赛 | 陈晓曦 | 李长宏 |
+| ------ | ------ | ------ | ------ |
+| 41 | 12378 | 1495 | 110 |
+
+前往 [更多](https://www.logclub.com/columnist/authorMore/integrated_logistics) 查看更多专家
+
+#### 数字化
+
+| 秦愉 | 冯雷 | 卢立新 | 段琰 |
+| ---- | ---- | ------ | ---- |
+| 160 | 147 | 95 | 284 |
+
+前往 [更多](https://www.logclub.com/columnist/authorMore/digitization) 查看更多专家
+
+#### 智能化
+
+| 曾志宏 | 亦橙 | 马荣 | 陈晓春 |
+| ------ | ---- | ---- | ------ |
+| 34 | 201 | 130 | 123 |
+
+前往 [更多](https://www.logclub.com/columnist/authorMore/intellectualization) 查看更多专家
+
+#### 快运
+
+| 王坚 | 王拥军 | 靖晟 | 廖文明 |
+| ---- | ------ | ---- | ------ |
+| 172 | 252 | 84 | 50 |
+
+前往 [更多](https://www.logclub.com/columnist/authorMore/express_transportation) 查看更多专家
+
+#### 合同物流
+
+| 非红 | 王鹏飞 | 周海 | 王伟 |
+| ---- | ------ | ---- | ---- |
+| 40 | 2274 | 168 | 158 |
+
+前往 [更多](https://www.logclub.com/columnist/authorMore/contract_logistics) 查看更多专家
+
+#### 供应链
+
+| 黄尧笛 | 卓弘毅 | 胡珉 | 雷文军 Jason |
+| ------ | ------ | ---- | ------------ |
+| 26 | 35 | 188 | 303 |
+
+前往 [更多](https://www.logclub.com/columnist/authorMore/supply_chain) 查看更多专家
+
+#### 快递
+
+| 致快递 | 中通之声 | 科技中通 | 明兴 |
+| ------ | -------- | -------- | ---- |
+| 9633 | 618 | 385 | 265 |
+
+前往 [更多](https://www.logclub.com/columnist/authorMore/express) 查看更多专家
+
+#### 城配
+
+| 张春鑫 (荡漾哥) | 梁佳 | 赵波 | 王行广 |
+| --------------- | ---- | ---- | ------ |
+| 1527 | 3374 | 49 | 75 |
+
+前往 [更多](https://www.logclub.com/columnist/authorMore/urban_distribution) 查看更多专家
+
+#### 仓储
+
+| 叶剑 | 木棉 | 陈艺 | 冯银川 |
+| ---- | ---- | ---- | ------ |
+| 1881 | 59 | 1637 | 215 |
+
+前往 [更多](https://www.logclub.com/columnist/authorMore/storage) 查看更多专家`,
+};
diff --git a/lib/routes/logclub/company.ts b/lib/routes/logclub/company.ts
new file mode 100644
index 000000000000..4a618f98e3ec
--- /dev/null
+++ b/lib/routes/logclub/company.ts
@@ -0,0 +1,145 @@
+import type { Route } from '@/types';
+
+import { handler } from './index';
+
+export const route: Route = {
+ path: '/company/:id',
+ categories: ['new-media'],
+ example: '/logclub/company/14',
+ parameters: { id: '企业 id,见下表,可在对应企业页 URL 中找到' },
+ features: {
+ antiCrawler: true,
+ },
+ radar: [
+ {
+ source: ['logclub.com/company/:id'],
+ target: '/company/:id',
+ },
+ ],
+ name: '大企业',
+ maintainers: ['nczitzk'],
+ handler,
+ description: `#### 明星企业
+
+| 顺丰 | 菜鸟 | 京东物流 | 德邦快递 / 德邦股份 |
+| ---- | ---- | -------- | ------------------- |
+| 14 | 56 | 453 | 145 |
+
+| 百世集团 | 中国物流集团 | 极兔速递 | 中通快递 |
+| -------- | ------------ | -------- | -------- |
+| 116 | 6807 | 3246 | 132 |
+
+前往 [更多](https://www.logclub.com/columnist/more/star) 查看更多企业
+
+#### 综合物流 / 供应链企业
+
+| 锐特信息 | 中国物流与采购网 | 则一 | 普路通 |
+| -------- | ---------------- | ---- | ------ |
+| 716 | 525 | 524 | 464 |
+
+| 安得智联 | 集保中国 | 上汽安吉物流 | 苏宁物流 |
+| -------- | -------- | ------------ | -------- |
+| 215 | 147 | 15 | 12 |
+
+| 准时达 | 深国际 | 益邦控股 | 卓志跨境供应链 |
+| ------ | ------ | -------- | -------------- |
+| 158 | 167 | 758 | 130 |
+
+| 日日顺 | 传化智联 | CJ 荣庆物流 | 江苏飞力达 |
+| ------ | -------- | ----------- | ---------- |
+| 179 | 166 | 770 | 548 |
+
+前往 [更多](https://www.logclub.com/columnist/more/integrated_logistics) 查看更多企业
+
+#### 快递 / 快运企业
+
+| 盛丰物流 | 跨越速运 | 顺心捷达 | 中国邮政 |
+| -------- | -------- | -------- | -------- |
+| 819 | 372 | 327 | 134 |
+
+| 韵达 | 申通快递 | 圆通 | 壹米滴答集团 |
+| ---- | -------- | ---- | ------------ |
+| 113 | 137 | 143 | 97 |
+
+| 安能物流 | 联邦快递 FedEx | UPS | DHL |
+| -------- | -------------- | --- | --- |
+| 151 | 104 | 388 | 219 |
+
+| 优速快递 | 中铁快运 | 德坤物流 | 商桥物流 |
+| -------- | -------- | -------- | -------- |
+| 1243 | 1015 | 2254 | 99 |
+
+前往 [更多](https://www.logclub.com/columnist/more/express) 查看更多企业
+
+#### 系统 / 智能平台 / 智能硬件 / 设施企业
+
+| 甲子光年 | 炬星科技 | 斑马智行 | 智行者 |
+| -------- | -------- | -------- | ------ |
+| 700 | 665 | 540 | 510 |
+
+| 纵行科技 | 行深智能 | 地上铁 | 图森未来 |
+| -------- | -------- | ------ | -------- |
+| 509 | 508 | 500 | 445 |
+
+| oTMS 运输管理云平台 | 聚龄供应链 | 博科资讯 | 富勒 FLUX |
+| ------------------- | ---------- | -------- | --------- |
+| 53 | 5806 | 6870 | 122 |
+
+| 科箭软件 | 通天晓软件 | 嬴彻科技 | 货车宝 |
+| -------- | ---------- | -------- | ------ |
+| 180 | 503 | 462 | 129 |
+
+前往 [更多](https://www.logclub.com/columnist/more/intellectualization) 查看更多企业
+
+#### 货运 / 配送平台 / 仓储 / 地产企业
+
+| 卡力互联 | 想乐送 | 宝湾物流 | 卡车之家 |
+| -------- | ------ | -------- | -------- |
+| 1660 | 1558 | 1031 | 365 |
+
+| 罗宾升 | 好多车 | 饿了么 | 闪送 |
+| ------ | ------ | ------ | ---- |
+| 308 | 269 | 172 | 80 |
+
+| 宏昌物流园 | 路歌互联网物流平台 | 福佑卡车 | 普洛斯 |
+| ---------- | ------------------ | -------- | ------ |
+| 6816 | 182 | 18 | 150 |
+
+| 菜鸟速递 | 达达集团 | 满帮集团 | 货拉拉 |
+| -------- | -------- | -------- | ------ |
+| 1972 | 748 | 193 | 79 |
+
+前往 [更多](https://www.logclub.com/columnist/more/freight_transport) 查看更多企业
+
+#### 证券交运 / 咨询机构
+
+| 罗戈网 | 物流沙龙 | 罗戈研究 | 招商证券 |
+| ------ | -------- | -------- | -------- |
+| 17 | 21 | 26 | 51 |
+
+| 兴业证券 | 环球物流咨询规划 | 华创证券 | 艾瑞咨询 |
+| -------- | ---------------- | -------- | -------- |
+| 161 | 29 | 1287 | 58 |
+
+| 安信证券 | 天风证券 | 方正证券 | 中信证券 |
+| -------- | -------- | -------- | -------- |
+| 1295 | 1136 | 1169 | 469 |
+
+| 申万宏源证券 | 国海证券 | 华泰证券 | 东方证券 |
+| ------------ | -------- | -------- | -------- |
+| 1296 | 6381 | 2119 | 1772 |
+
+前往 [更多](https://www.logclub.com/columnist/more/securities_delivery) 查看更多企业
+
+#### 资本
+
+| 源码资本 | 华兴资本 | IDG 资本 | 元赋资本 |
+| -------- | -------- | -------- | -------- |
+| 1037 | 931 | 787 | 393 |
+
+| 钟鼎资本 | 红杉资本 |
+| -------- | -------- |
+| 159 | 5265 |
+
+前往 [更多](https://www.logclub.com/columnist/more/capital) 查看更多企业`,
+};
diff --git a/lib/routes/logclub/index.ts b/lib/routes/logclub/index.ts
index 298882f050c6..6a304cde6652 100644
--- a/lib/routes/logclub/index.ts
+++ b/lib/routes/logclub/index.ts
@@ -1,25 +1,45 @@
import { load } from 'cheerio';
-import type { Route } from '@/types';
+import type { DataItem, Route } from '@/types';
import cache from '@/utils/cache';
+import { getSubPath } from '@/utils/common-utils';
import got from '@/utils/got';
import { parseDate } from '@/utils/parse-date';
import { renderDescription } from './templates/description';
export const route: Route = {
- path: '/:category{.+}?',
- name: 'Unknown',
- maintainers: [],
+ path: '/news/:id?',
+ categories: ['new-media'],
+ example: '/logclub/news',
+ parameters: { id: '资讯 id,见下表,可在对应资讯页 URL 中找到,默认为全部' },
+ radar: [
+ {
+ source: ['logclub.com/news'],
+ target: '/news',
+ },
+ {
+ source: ['logclub.com/news/:id'],
+ target: '/news/:id',
+ },
+ ],
+ name: '资讯',
+ maintainers: ['nczitzk'],
handler,
+ description: `| 供应链 | 快递 | 快运 / 运输 | 仓储 / 地产 | 物流综合 | 国际与跨境物流 | 科技创新 |
+| ------ | ---- | ----------- | ----------- | -------- | -------------- | -------- |
+| 10-16 | 11 | 30 | 9 | 32 | 114 | 107 |
+
+| 绿色供应链 | 低碳物流 | 碳中和碳达峰 |
+| ---------- | -------- | ------------ |
+| 213 | 214 | 215 |`,
};
-async function handler(ctx) {
- const { category = 'news' } = ctx.req.param();
- const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 11;
+export async function handler(ctx) {
+ const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 11;
const rootUrl = 'https://www.logclub.com';
- const currentUrl = new URL(category, rootUrl).href;
+ const currentUrl = new URL(getSubPath(ctx), rootUrl).href;
const { data: response } = await got(currentUrl);
@@ -28,21 +48,21 @@ async function handler(ctx) {
let items = $('li.layui-row, li.layui-timeline-item')
.slice(0, limit)
.toArray()
- .map((item) => {
- item = $(item);
+ .map((item): DataItem => {
+ const $item = $(item);
- const a = item.find('div.newslist-txt h3 a, a.article_title').first();
- const image = item.find('img.img-hover').prop('src')?.split(/\?/)[0] ?? undefined;
+ const a = $item.find('div.newslist-txt h3 a, a.article_title').first();
+ const image = $item.find('img.img-hover').prop('src')?.split(/\?/, 1)[0] ?? undefined;
return {
title: a.text(),
- link: new URL(a.prop('href'), rootUrl).href,
+ link: new URL(a.prop('href')!, rootUrl).href,
description: renderDescription({
image: {
src: image,
alt: a.text(),
},
- intro: item.find('p.newslist-intro, div.newslist-info-intro').text(),
+ intro: $item.find('p.newslist-intro, div.newslist-info-intro').text(),
}),
itunes_item_image: image,
};
@@ -50,22 +70,22 @@ async function handler(ctx) {
items = await Promise.all(
items.map((item) =>
- cache.tryGet(item.link, async () => {
+ cache.tryGet(item.link!, async () => {
const { data: detailResponse } = await got(item.link);
const content = load(detailResponse);
content('a.dl_file').each((_, el) => {
- el = content(el);
- el.parent().remove();
+ const $el = content(el);
+ $el.parent().remove();
});
content('img').each((_, el) => {
- el = content(el);
- el.replaceWith(
+ const $el = content(el);
+ $el.replaceWith(
renderDescription({
image: {
- src: el.prop('src')?.split(/\?/)[0] ?? undefined,
- alt: el.prop('title'),
+ src: $el.prop('src')?.split(/\?/, 1)[0] ?? undefined,
+ alt: $el.prop('title'),
},
})
);
@@ -84,7 +104,7 @@ async function handler(ctx) {
src: item.enclosure_url,
type: item.enclosure_type,
},
- description: content('div.article-cont').html(),
+ description: content('div.article-cont').html() ?? undefined,
});
item.author = content('div.article-info-r a')
.toArray()
@@ -111,7 +131,7 @@ async function handler(ctx) {
)
.text()
.split(/:/)
- .pop()
+ .pop()!
.trim()
)
: parseDate(content('span.aritlceIn-time').text().trim());
@@ -121,17 +141,17 @@ async function handler(ctx) {
)
);
- const icon = new URL($('link[rel="shortcut icon"]').prop('href'), rootUrl).href;
+ const icon = new URL($('link[rel="shortcut icon"]').prop('href')!, rootUrl).href;
const subtitle = $('meta[name="keywords"]').prop('content');
- const author = subtitle.split(/,/)[0];
+ const author = subtitle.split(/,/, 1)[0];
return {
item: items,
- title: $('title').text().split(/-/)[0].trim(),
+ title: $('title').text().split(/-/, 1)[0].trim(),
link: currentUrl,
description: $('meta[name="description"]').prop('content'),
- language: 'zh',
- image: new URL($('div.logo_img img').prop('src'), rootUrl).href,
+ language: 'zh' as const,
+ image: new URL($('div.logo_img img').prop('src')!, rootUrl).href,
icon,
logo: icon,
subtitle: subtitle.replaceAll(',', ''),
diff --git a/lib/routes/logclub/original.ts b/lib/routes/logclub/original.ts
new file mode 100644
index 000000000000..1d5bea157133
--- /dev/null
+++ b/lib/routes/logclub/original.ts
@@ -0,0 +1,18 @@
+import type { Route } from '@/types';
+
+import { handler } from './index';
+
+export const route: Route = {
+ path: '/original',
+ categories: ['new-media'],
+ example: '/logclub/original',
+ radar: [
+ {
+ source: ['logclub.com/original'],
+ target: '/original',
+ },
+ ],
+ name: '原创',
+ maintainers: ['nczitzk'],
+ handler,
+};
diff --git a/lib/routes/logclub/recruit.ts b/lib/routes/logclub/recruit.ts
new file mode 100644
index 000000000000..dcfcc2eac550
--- /dev/null
+++ b/lib/routes/logclub/recruit.ts
@@ -0,0 +1,18 @@
+import type { Route } from '@/types';
+
+import { handler } from './index';
+
+export const route: Route = {
+ path: '/recruit',
+ categories: ['new-media'],
+ example: '/logclub/recruit',
+ radar: [
+ {
+ source: ['logclub.com/recruit'],
+ target: '/recruit',
+ },
+ ],
+ name: '招聘',
+ maintainers: ['nczitzk'],
+ handler,
+};
diff --git a/lib/routes/logclub/report.ts b/lib/routes/logclub/report.ts
index 852fec5f48e0..dd91cd1bea1f 100644
--- a/lib/routes/logclub/report.ts
+++ b/lib/routes/logclub/report.ts
@@ -9,7 +9,7 @@ import timezone from '@/utils/timezone';
import { renderDescription } from './templates/description';
export const route: Route = {
- path: ['/lc_report/:id?', '/report/:id?'],
+ path: '/lc_report/:id?',
categories: ['new-media'],
example: '/logclub/lc_report',
parameters: { id: '报告 id,见下表,默认为罗戈研究出品' },
@@ -21,6 +21,27 @@ export const route: Route = {
supportPodcast: false,
supportScihub: false,
},
+ radar: [
+ {
+ source: ['logclub.com/lc_report'],
+ target: '/lc_report',
+ },
+ {
+ title: '报告 - 罗戈研究出品',
+ source: ['logclub.com/lc_report'],
+ target: '/lc_report/Report',
+ },
+ {
+ title: '报告 - 物流报告',
+ source: ['logclub.com/lc_report'],
+ target: '/lc_report/IndustryReport',
+ },
+ {
+ title: '报告 - 绿色双碳报告',
+ source: ['logclub.com/lc_report'],
+ target: '/lc_report/GreenDualCarbonReport',
+ },
+ ],
name: '报告',
maintainers: ['nczitzk'],
handler,
@@ -31,7 +52,7 @@ export const route: Route = {
async function handler(ctx) {
const { id = 'Report' } = ctx.req.param();
- const limit = ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit'), 10) : 11;
+ const limit = ctx.req.query('limit') ? Number(ctx.req.query('limit')) : 11;
const rootUrl = 'https://www.logclub.com';
const currentUrl = new URL('lc_report', rootUrl).href;
@@ -48,14 +69,14 @@ async function handler(ctx) {
link: new URL(`front/lc_report/get_report_info/${item.id}`, rootUrl).href,
description: renderDescription({
image: {
- src: item.img_url?.split(/\?/)[0] ?? undefined,
+ src: item.img_url?.split(/\?/, 1)[0] ?? undefined,
alt: item.title,
},
}),
author: item.author,
category: [item.channel_name],
guid: `logclub-report-${item.id}`,
- pubDate: timezone(parseDate(item.release_time), +8),
+ pubDate: timezone(parseDate(item.release_time), 8),
}));
items = await Promise.all(
@@ -66,12 +87,12 @@ async function handler(ctx) {
const content = load(detailResponse);
content('img').each((_, el) => {
- el = content(el);
- el.replaceWith(
+ const $el = content(el);
+ $el.replaceWith(
renderDescription({
image: {
- src: el.prop('src')?.split(/\?/)[0] ?? undefined,
- alt: el.prop('title'),
+ src: $el.prop('src')?.split(/\?/, 1)[0] ?? undefined,
+ alt: $el.prop('title'),
},
})
);
@@ -79,7 +100,7 @@ async function handler(ctx) {
item.title = content('h1').first().text();
item.description += renderDescription({
- description: content('div.article-cont').html(),
+ description: content('div.article-cont').html() ?? undefined,
});
item.author = content('div.lc-infos a')
.toArray()
@@ -104,7 +125,7 @@ async function handler(ctx) {
const $ = load(currentResponse);
const title = $('div.this_nav').text().trim();
- const icon = new URL($('link[rel="shortcut icon"]').prop('href'), rootUrl).href;
+ const icon = new URL($('link[rel="shortcut icon"]').prop('href')!, rootUrl).href;
const subtitle = $('meta[name="keywords"]').prop('content');
return {
@@ -112,11 +133,11 @@ async function handler(ctx) {
title: `${$('title').text()}${title}`,
link: currentUrl,
description: $('meta[name="description"]').prop('content'),
- language: 'zh',
- image: new URL($('div.logo_img img').prop('src'), rootUrl).href,
+ language: 'zh' as const,
+ image: new URL($('div.logo_img img').prop('src')!, rootUrl).href,
icon,
logo: icon,
subtitle: subtitle.replaceAll(',', ''),
- author: subtitle.split(/,/)[0],
+ author: subtitle.split(/,/, 1)[0],
};
}
diff --git a/lib/routes/logclub/tender.ts b/lib/routes/logclub/tender.ts
new file mode 100644
index 000000000000..ccc87fbbbae8
--- /dev/null
+++ b/lib/routes/logclub/tender.ts
@@ -0,0 +1,18 @@
+import type { Route } from '@/types';
+
+import { handler } from './index';
+
+export const route: Route = {
+ path: '/tender',
+ categories: ['new-media'],
+ example: '/logclub/tender',
+ radar: [
+ {
+ source: ['logclub.com/tender'],
+ target: '/tender',
+ },
+ ],
+ name: '招投标',
+ maintainers: ['nczitzk'],
+ handler,
+};
diff --git a/lib/routes/logonews/category.ts b/lib/routes/logonews/category.ts
new file mode 100644
index 000000000000..4987da8d0618
--- /dev/null
+++ b/lib/routes/logonews/category.ts
@@ -0,0 +1,22 @@
+import type { Route } from '@/types';
+
+import { handler } from './index';
+
+export const route: Route = {
+ path: '/category/:category/:type',
+ categories: ['design'],
+ example: '/logonews/category/news/newsletter',
+ parameters: { category: '分类,可在对应分类页 URL 中找到', type: '类型,可在对应分类页 URL 中找到' },
+ radar: [
+ {
+ source: ['logonews.cn/category/:category/:type?'],
+ target: '/category/:category/:type?',
+ },
+ ],
+ name: '文章分类',
+ maintainers: ['nczitzk'],
+ handler,
+ url: 'logonews.cn/',
+ description:
+ '如 [简讯 - 标志情报局](https://www.logonews.cn/category/news/newsletter) 的 URL 为 `https://www.logonews.cn/category/news/newsletter`,可得路由为 [`/logonews/category/news/newsletter`](https://rsshub.app/logonews/category/news/newsletter)。',
+};
diff --git a/lib/routes/logonews/index.tsx b/lib/routes/logonews/index.tsx
index 5e228c0d37af..38cbb07b16fc 100644
--- a/lib/routes/logonews/index.tsx
+++ b/lib/routes/logonews/index.tsx
@@ -2,32 +2,34 @@ import { load } from 'cheerio';
import { raw } from 'hono/html';
import { renderToString } from 'hono/jsx/dom/server';
-import type { Route } from '@/types';
+import type { DataItem, Route } from '@/types';
import cache from '@/utils/cache';
import { getSubPath } from '@/utils/common-utils';
import got from '@/utils/got';
import { parseDate } from '@/utils/parse-date';
export const route: Route = {
- path: ['/work/tags/:tag', '/tag/:tag', '*'],
+ path: '/',
+ categories: ['design'],
+ example: '/logonews',
radar: [
{
- source: ['logonews.cn/work/tags/:tag'],
+ source: ['logonews.cn/'],
+ target: '/',
},
],
- name: 'Unknown',
+ name: '首页',
maintainers: ['nczitzk'],
handler,
url: 'logonews.cn/',
- description: '如 [中国 - 标志情报局](https://www.logonews.cn/tag/china) 的 URL 为 `https://www.logonews.cn/tag/china`,可得路由为 [`/logonews/tag/china`](https://rsshub.app/logonews/tag/china)。',
};
-async function handler(ctx) {
- const params = getSubPath(ctx);
- const isWork = params.indexOf('/work') === 0;
+export async function handler(ctx) {
+ const subPath = getSubPath(ctx);
+ const isWork = subPath.startsWith('/work');
const rootUrl = 'https://www.logonews.cn';
- const currentUrl = `${rootUrl}${params === '/' ? '' : params}`;
+ const currentUrl = subPath === '/' ? rootUrl : `${rootUrl}${subPath}`;
const response = await got({
method: 'get',
@@ -39,17 +41,18 @@ async function handler(ctx) {
let items = $(isWork ? 'h2 a' : 'a.article-link')
.slice(0, ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit')) : 25)
.toArray()
- .map((item) => {
- item = $(item);
+ .map((item): DataItem => {
+ const $item = $(item);
return {
- link: item.attr('href'),
+ link: $item.attr('href'),
+ title: '',
};
});
items = await Promise.all(
items.map((item) =>
- cache.tryGet(item.link, async () => {
+ cache.tryGet(item.link!, async () => {
const detailResponse = await got({
method: 'get',
url: item.link,
@@ -63,14 +66,14 @@ async function handler(ctx) {
content(el).attr(
'src',
content(el)
- .attr('data-src')
+ .attr('data-src')!
.replace(/_logonews/, '')
);
});
item.title = content('title').text();
item.author = content('.author-links').text();
- item.pubDate = parseDate(content('meta[property="og:release_date"]').attr('content'));
+ item.pubDate = parseDate(content('meta[property="og:release_date"]').attr('content')!);
item.category = content('a.category_link, a[rel="tag"]')
.toArray()
.map((c) => content(c).text().replaceAll(' · ', ''));
diff --git a/lib/routes/logonews/tag.ts b/lib/routes/logonews/tag.ts
new file mode 100644
index 000000000000..aa8c62d23e96
--- /dev/null
+++ b/lib/routes/logonews/tag.ts
@@ -0,0 +1,21 @@
+import type { Route } from '@/types';
+
+import { handler } from './index';
+
+export const route: Route = {
+ path: '/tag/:tag',
+ categories: ['design'],
+ example: '/logonews/tag/china',
+ parameters: { tag: '标签,可在对应标签页 URL 中找到' },
+ radar: [
+ {
+ source: ['logonews.cn/tag/:tag'],
+ target: '/tag/:tag',
+ },
+ ],
+ name: '文章标签',
+ maintainers: ['nczitzk'],
+ handler,
+ url: 'logonews.cn/',
+ description: '如 [中国 - 标志情报局](https://www.logonews.cn/tag/china) 的 URL 为 `https://www.logonews.cn/tag/china`,可得路由为 [`/logonews/tag/china`](https://rsshub.app/logonews/tag/china)。',
+};
diff --git a/lib/routes/logonews/work-category.ts b/lib/routes/logonews/work-category.ts
new file mode 100644
index 000000000000..6d3b98ac6e0c
--- /dev/null
+++ b/lib/routes/logonews/work-category.ts
@@ -0,0 +1,22 @@
+import type { Route } from '@/types';
+
+import { handler } from './index';
+
+export const route: Route = {
+ path: '/work/categorys/:category',
+ categories: ['design'],
+ example: '/logonews/work/categorys/hotel-catering',
+ parameters: { category: '分类,可在对应分类页 URL 中找到' },
+ radar: [
+ {
+ source: ['logonews.cn/work/categorys/:category'],
+ target: '/work/categorys/:category',
+ },
+ ],
+ name: '作品分类',
+ maintainers: ['nczitzk'],
+ handler,
+ url: 'logonews.cn/',
+ description:
+ '如 [LOGO 作品分类:酒店餐饮 - 标志情报局](https://www.logonews.cn/work/categorys/hotel-catering) 的 URL 为 `https://www.logonews.cn/work/categorys/hotel-catering`,可得路由为 [`/logonews/work/categorys/hotel-catering`](https://rsshub.app/logonews/work/categorys/hotel-catering)。',
+};
diff --git a/lib/routes/logonews/work-tag.ts b/lib/routes/logonews/work-tag.ts
new file mode 100644
index 000000000000..89deb9cea46c
--- /dev/null
+++ b/lib/routes/logonews/work-tag.ts
@@ -0,0 +1,22 @@
+import type { Route } from '@/types';
+
+import { handler } from './index';
+
+export const route: Route = {
+ path: '/work/tags/:tag?',
+ categories: ['design'],
+ example: '/logonews/work/tags/旅游',
+ parameters: { tag: '标签,可在对应标签页 URL 中找到' },
+ radar: [
+ {
+ source: ['logonews.cn/work/tags/:tag'],
+ target: '/work/tags/:tag',
+ },
+ ],
+ name: '作品标签',
+ maintainers: ['nczitzk'],
+ handler,
+ url: 'logonews.cn/',
+ description:
+ '如 [LOGO 标签:旅游 - 标志情报局](https://www.logonews.cn/work/tags/旅游) 的 URL 为 [https://www.logonews.cn/work/tags/ 旅游](https://www.logonews.cn/work/tags/旅游),可得路由为 [`/logonews/work/tags/旅游`](https://rsshub.app/logonews/work/tags/旅游)。',
+};
diff --git a/lib/routes/logonews/work.ts b/lib/routes/logonews/work.ts
new file mode 100644
index 000000000000..7af9fb85e617
--- /dev/null
+++ b/lib/routes/logonews/work.ts
@@ -0,0 +1,19 @@
+import type { Route } from '@/types';
+
+import { handler } from './index';
+
+export const route: Route = {
+ path: '/work',
+ categories: ['design'],
+ example: '/logonews/work',
+ radar: [
+ {
+ source: ['logonews.cn/work'],
+ target: '/work',
+ },
+ ],
+ name: '作品',
+ maintainers: ['nczitzk'],
+ handler,
+ url: 'logonews.cn/',
+};
diff --git a/lib/routes/logrocket/index.ts b/lib/routes/logrocket/index.ts
index de91a6b2a73f..e15601a75fa2 100644
--- a/lib/routes/logrocket/index.ts
+++ b/lib/routes/logrocket/index.ts
@@ -1,6 +1,6 @@
import { load } from 'cheerio'; // 类似 jQuery 的 API HTML 解析器
-import type { Route } from '@/types';
+import type { DataItem, Route } from '@/types';
import cache from '@/utils/cache';
import ofetch from '@/utils/ofetch'; // 统一使用的请求库
import { parseDate } from '@/utils/parse-date';
@@ -33,21 +33,21 @@ async function handler(ctx) {
const $ = load(response);
const list = $('div.post-list .post-card')
.toArray()
- .map((item) => {
- item = $(item);
- const a = item.find('a').first();
- const title = item.find('.post-card-title').first();
+ .map((item): DataItem => {
+ const $item = $(item);
+ const a = $item.find('a').first();
+ const title = $item.find('.post-card-title');
return {
title: title.text(),
link: a.attr('href'),
- pubDate: parseDate(item.find('.post-card-author-name').next().text().split(' ⋅ ')[0], 'MMM D, YYYY'),
- author: item.find('.post-card-author-name').text(),
+ pubDate: parseDate($item.find('.post-card-author-name').next().text().split(' ⋅ ', 1)[0], 'MMM D, YYYY'),
+ author: $item.find('.post-card-author-name').text(),
};
});
const items = await Promise.all(
list.map((item) =>
- cache.tryGet(item.link, async () => {
- const response = await ofetch(item.link);
+ cache.tryGet(item.link!, async () => {
+ const response = await ofetch(item.link!);
const $ = load(response);
//
$('div.content-max-width .sidebar-container div.code-block').remove();
diff --git a/lib/routes/lorientlejour/index.tsx b/lib/routes/lorientlejour/index.tsx
index 0d54c8adfd16..7c63fb78456a 100644
--- a/lib/routes/lorientlejour/index.tsx
+++ b/lib/routes/lorientlejour/index.tsx
@@ -4,7 +4,7 @@ import { renderToString } from 'hono/jsx/dom/server';
import { FetchError } from 'ofetch';
import { config } from '@/config';
-import type { Route } from '@/types';
+import type { Language, Route } from '@/types';
import cache from '@/utils/cache';
import got from '@/utils/got';
import { parseDate } from '@/utils/parse-date';
@@ -86,7 +86,7 @@ async function viewCategory(category: string) {
}
async function handler(ctx) {
- const categoryId = (ctx.req.param('category') ?? '977-Lebanon').split('|').map((item) => item.match(/^(\d+)/i)[0] ?? item);
+ const categoryId = (ctx.req.param('category') ?? '977-Lebanon').split('|').map((item) => item.match(/^(\d+)/)[0] ?? item);
const limit = ctx.req.query('limit') ?? 25;
let token;
@@ -143,14 +143,14 @@ async function handler(ctx) {
let url = `https://www.lorientlejour.com/cmsapi/content.php?text=clean&key=${key}&action=search&category=${encodeURIComponent(JSON.stringify(categoriesParam))}&limit=${limit}&text=false&page=1`;
if (token) {
- url = url + `&token=${token}`;
+ url += `&token=${token}`;
}
const response = await got(url);
const items = response.data.data.map((item) => {
item.link = item.url;
item.author = item.authors.map((author) => author.name).join(', ');
- item.pubDate = timezone(parseDate(item.firstPublished), +3);
- item.updated = timezone(parseDate(item.lastUpdate), +3);
+ item.pubDate = timezone(parseDate(item.firstPublished), 3);
+ item.updated = timezone(parseDate(item.lastUpdate), 3);
item.category = item.categories.map((itemCategory) => itemCategory.name);
const contents = item.contents;
const $ = load(contents);
@@ -161,10 +161,12 @@ async function handler(ctx) {
article.find('.inlineImage').each((_, el) => {
const inlineImageSrc = $(el).attr('src');
const inlineAttachment = item.inline_attachments.find((inlineAttachment) => inlineAttachment.url === inlineImageSrc);
- if (inlineAttachment && inlineAttachment.description) {
- $(el).wrap('
${$item.find('dd a').text()}`,
+ link: new URL(a.attr('href')!, baseUrl).href,
+ };
+ }),
+ };
+}
diff --git a/lib/routes/mafengwo/utils.ts b/lib/routes/mafengwo/utils.ts
new file mode 100644
index 000000000000..fd56f68dc60b
--- /dev/null
+++ b/lib/routes/mafengwo/utils.ts
@@ -0,0 +1,33 @@
+import { randomBytes } from 'node:crypto';
+
+import CryptoJS from 'crypto-js';
+
+import md5 from '@/utils/md5';
+import ofetch from '@/utils/ofetch';
+
+// ?v=vc1jasc
+const key = CryptoJS.enc.Utf8.parse('tg09It3*9h');
+
+/**
+ * `w_tsfp`=`base64(RC4(key, payload))`
+ */
+const generateWTsfp = (url: string) => {
+ const now = Date.now();
+ const fingerprint = randomBytes(16).toString('hex');
+ const salt = randomBytes(16).toString('hex');
+ const payload = JSON.stringify({
+ timestamp: now,
+ basets: now,
+ loadts: now,
+ fingerprint,
+ abnormal: '0'.repeat(32),
+ referer: encodeURIComponent(`${new URL(url).origin}/`),
+ uri: encodeURIComponent(url),
+ checksum: md5(url + fingerprint + salt + now),
+ });
+ const token = CryptoJS.RC4.encrypt(CryptoJS.enc.Utf8.parse(payload), key).ciphertext.toString(CryptoJS.enc.Base64);
+
+ return `x-waf-captcha-referer=; w_tsfp=${token}`;
+};
+
+export const wafFetch =
${summary}
`,
+ category: [$item.find('span.location').text()],
+ };
+ });
+
+ const titleResponse = await wafFetchAttachments (${parsed.attachments.length})
`;
- for (const attachment of parsed.attachments) {
- description += `
') || '';
+ if (parsed.attachments.length) {
+ description += `Attachments (${parsed.attachments.length})
`;
+ for (const attachment of parsed.attachments) {
+ description += `