rsshub 1.0.0-master.fb6d4f3 → 1.0.0-master.fb7e42c
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/assets/logo.svg +1 -0
- package/lib/config.ts +10 -0
- package/lib/errors/index.test.ts +15 -5
- package/lib/errors/types/captcha.ts +5 -0
- package/lib/middleware/cache.ts +4 -0
- package/lib/middleware/parameter.ts +1 -1
- package/lib/registry.ts +6 -2
- package/lib/routes/10000link/info.ts +1 -1
- package/lib/routes/18comic/album.ts +1 -0
- package/lib/routes/18comic/blogs.ts +1 -0
- package/lib/routes/18comic/search.ts +1 -0
- package/lib/routes/199it/index.ts +1 -1
- package/lib/routes/21caijing/channel.ts +1 -1
- package/lib/routes/51cto/utils.ts +1 -1
- package/lib/routes/6v123/index.ts +487 -0
- package/lib/routes/6v123/namespace.ts +1 -0
- package/lib/routes/8kcos/cat.ts +3 -0
- package/lib/routes/8kcos/latest.ts +1 -0
- package/lib/routes/8kcos/tag.ts +1 -0
- package/lib/routes/91porn/author.ts +1 -0
- package/lib/routes/95mm/category.ts +1 -0
- package/lib/routes/95mm/tag.ts +1 -0
- package/lib/routes/aa1/60s.ts +189 -0
- package/lib/routes/{xinhuanet → aa1}/namespace.ts +3 -3
- package/lib/routes/abc/index.ts +1 -1
- package/lib/routes/abskoop/index.ts +3 -0
- package/lib/routes/abskoop/nsfw.ts +3 -0
- package/lib/routes/acgvinyl/namespace.ts +6 -0
- package/lib/routes/acgvinyl/news.ts +86 -0
- package/lib/routes/ally/rail.ts +1 -1
- package/lib/routes/amazfitwatchfaces/index.ts +1 -2
- package/lib/routes/anthropic/news.ts +13 -11
- package/lib/routes/apnews/mobile-api.ts +1 -1
- package/lib/routes/apnews/sitemap.ts +1 -1
- package/lib/routes/app-sales/index.ts +1 -1
- package/lib/routes/apple/apps.ts +2 -2
- package/lib/routes/apple/podcast.ts +58 -25
- package/lib/routes/apple/security-releases.ts +2 -2
- package/lib/routes/asiafruitchina/categories.ts +1 -1
- package/lib/routes/asiantolick/index.ts +3 -0
- package/lib/routes/asmr-200/index.ts +1 -0
- package/lib/routes/bandisoft/history.ts +2 -2
- package/lib/routes/bangumi.tv/group/reply.ts +1 -1
- package/lib/routes/banshujiang/index.ts +1 -1
- package/lib/routes/banyuetan/index.ts +1 -1
- package/lib/routes/baozimh/index.ts +21 -3
- package/lib/routes/baselang/index.ts +117 -0
- package/lib/routes/baselang/namespace.ts +6 -0
- package/lib/routes/bbc/learningenglish.ts +35 -20
- package/lib/routes/bestofjs/monthly.ts +137 -0
- package/lib/routes/bestofjs/namespace.ts +7 -0
- package/lib/routes/bestofjs/templates/description.art +36 -0
- package/lib/routes/bilibili/cache.ts +17 -1
- package/lib/routes/bilibili/dynamic.ts +34 -8
- package/lib/routes/bilibili/page.ts +1 -1
- package/lib/routes/bilibili/ranking.ts +25 -17
- package/lib/routes/bilibili/wasm-exec.ts +1 -1
- package/lib/routes/bilibili/weekly-recommend.ts +22 -6
- package/lib/routes/bjp/apod.ts +1 -1
- package/lib/routes/bnext/index.ts +58 -0
- package/lib/routes/bnext/namespace.ts +7 -0
- package/lib/routes/bookwalker/namespace.ts +9 -0
- package/lib/routes/bookwalker/search.ts +114 -0
- package/lib/routes/bookwalker/templates/description.art +13 -0
- package/lib/routes/booru/mmda.ts +1 -0
- package/lib/routes/buaa/jiaowu.ts +1 -1
- package/lib/routes/bullionvault/gold-news.ts +4 -4
- package/lib/routes/cast/index.ts +1 -1
- package/lib/routes/cbndata/information.ts +250 -0
- package/lib/routes/cbndata/namespace.ts +9 -0
- package/lib/routes/cbndata/templates/description.art +17 -0
- package/lib/routes/cccmc/index.ts +1 -1
- package/lib/routes/ccg/index.ts +181 -0
- package/lib/routes/ccg/namespace.ts +9 -0
- package/lib/routes/ccg/templates/description.art +21 -0
- package/lib/routes/chikubi/category.ts +1 -0
- package/lib/routes/chikubi/navigation.ts +1 -0
- package/lib/routes/chikubi/nipple-video-category.ts +1 -0
- package/lib/routes/chikubi/nipple-video-maker.ts +1 -0
- package/lib/routes/chikubi/search.ts +1 -0
- package/lib/routes/chinadaily/language.ts +1 -1
- package/lib/routes/chinaratings/credit-research.ts +1 -1
- package/lib/routes/chub/characters.ts +3 -0
- package/lib/routes/civitai/discussions.ts +1 -0
- package/lib/routes/civitai/models.ts +1 -0
- package/lib/routes/civitai/user.ts +3 -0
- package/lib/routes/cline/blog.ts +34 -23
- package/lib/routes/coolapk/utils.ts +5 -4
- package/lib/routes/coolbuy/index.ts +106 -0
- package/lib/routes/coolbuy/namespace.ts +9 -0
- package/lib/routes/coolbuy/templates/description.art +48 -0
- package/lib/routes/coolidge/film-guide.ts +60 -0
- package/lib/routes/coolidge/namespace.ts +7 -0
- package/lib/routes/coolidge/news.ts +65 -0
- package/lib/routes/coolidge/templates/description.art +4 -0
- package/lib/routes/coomer/index.ts +4 -6
- package/lib/routes/copymanga/comic.ts +2 -1
- package/lib/routes/cosplaytele/category.ts +1 -0
- package/lib/routes/cosplaytele/latest.ts +1 -0
- package/lib/routes/cosplaytele/popular.ts +1 -0
- package/lib/routes/cosplaytele/tag.ts +1 -0
- package/lib/routes/cpta/handler.ts +1 -1
- package/lib/routes/creative-comic/book.ts +1 -1
- package/lib/routes/crush/index.ts +77 -0
- package/lib/routes/crush/namespace.ts +7 -0
- package/lib/routes/cursor/blog.ts +84 -0
- package/lib/routes/daum/potplayer.ts +3 -3
- package/lib/routes/dbaplus/new.ts +392 -0
- package/lib/routes/dbaplus/templates/description.art +21 -0
- package/lib/routes/deepl/blog.ts +2 -3
- package/lib/routes/diariofruticola/filtro.ts +1 -1
- package/lib/routes/digitalpolicyalert/activity-tracker.ts +1 -1
- package/lib/routes/dlsite/campaign.ts +1 -0
- package/lib/routes/dlsite/ci-en/article.ts +1 -0
- package/lib/routes/dlsite/new.ts +1 -0
- package/lib/routes/dlsite/z-index/index.ts +3 -0
- package/lib/routes/dockerhub/utils.ts +1 -1
- package/lib/routes/dora-world/article.ts +2 -2
- package/lib/routes/dytt/index.ts +1 -2
- package/lib/routes/eeo/kuaixun.ts +154 -0
- package/lib/routes/eeo/namespace.ts +9 -0
- package/lib/routes/eeo/templates/description.art +7 -0
- package/lib/routes/ehentai/ehapi.ts +3 -3
- package/lib/routes/ehentai/favorites.ts +1 -0
- package/lib/routes/ehentai/search.ts +1 -0
- package/lib/routes/elecfans/article.ts +64 -0
- package/lib/routes/elecfans/namespace.ts +7 -0
- package/lib/routes/elecfans/soft.ts +69 -0
- package/lib/routes/engineering/namespace.ts +8 -0
- package/lib/routes/engineering/tag.ts +55 -0
- package/lib/routes/eventbrite/events.ts +152 -0
- package/lib/routes/eventbrite/namespace.ts +7 -0
- package/lib/routes/eventernote/actors.ts +61 -64
- package/lib/routes/everia/category.ts +1 -0
- package/lib/routes/everia/latest.ts +1 -0
- package/lib/routes/everia/search.ts +1 -0
- package/lib/routes/everia/tag.ts +1 -0
- package/lib/routes/expats/czech-news.ts +1 -1
- package/lib/routes/fangchan/list.ts +1 -1
- package/lib/routes/fansly/post.ts +1 -0
- package/lib/routes/fantia/search.ts +1 -0
- package/lib/routes/fantia/user.ts +1 -0
- package/lib/routes/finology/tag.ts +1 -1
- package/lib/routes/furaffinity/art.ts +1 -0
- package/lib/routes/furaffinity/browse.ts +1 -0
- package/lib/routes/furaffinity/commissions.ts +1 -0
- package/lib/routes/furaffinity/home.ts +1 -0
- package/lib/routes/furaffinity/journal-comments.ts +1 -0
- package/lib/routes/furaffinity/journals.ts +1 -0
- package/lib/routes/furaffinity/search.ts +1 -0
- package/lib/routes/furaffinity/shouts.ts +1 -0
- package/lib/routes/furaffinity/status.ts +1 -0
- package/lib/routes/furaffinity/submission-comments.ts +1 -0
- package/lib/routes/furaffinity/user.ts +1 -0
- package/lib/routes/furaffinity/watchers.ts +1 -0
- package/lib/routes/furaffinity/watching.ts +1 -0
- package/lib/routes/gamebase/news.ts +2 -2
- package/lib/routes/gamer/gnn-index.ts +8 -3
- package/lib/routes/gcores/categories.ts +1 -1
- package/lib/routes/gcores/collections.ts +1 -1
- package/lib/routes/gcores/tags.ts +1 -1
- package/lib/routes/gcores/topics.ts +1 -1
- package/lib/routes/gdufs/xwxy/index.ts +196 -0
- package/lib/routes/gelbooru/post.ts +1 -0
- package/lib/routes/genossenschaften/index.ts +2 -3
- package/lib/routes/github/activity.ts +1 -1
- package/lib/routes/gitstar-ranking/index.ts +1 -1
- package/lib/routes/go/jihs/idwr.ts +3 -4
- package/lib/routes/google/jules.ts +63 -0
- package/lib/routes/gov/mem/namespace.ts +7 -0
- package/lib/routes/gov/mem/zfxxgkpt.ts +96 -0
- package/lib/routes/gov/moa/gjs.ts +1 -1
- package/lib/routes/gov/mot/index.ts +157 -53
- package/lib/routes/grainoil/category.ts +1 -2
- package/lib/routes/gxmzu/lib.ts +2 -2
- package/lib/routes/gxmzu/utils/index.ts +2 -2
- package/lib/routes/hameln/chapter.ts +1 -1
- package/lib/routes/hanime1/previews.ts +1 -0
- package/lib/routes/hanime1/search.ts +1 -0
- package/lib/routes/hex-rays/index.ts +1 -1
- package/lib/routes/hit/hitgs.ts +1 -1
- package/lib/routes/hit/namespace.ts +1 -1
- package/lib/routes/hpoi/banner-item.ts +28 -11
- package/lib/routes/hpoi/info.ts +1 -1
- package/lib/routes/hudsonrivertrading/index.ts +122 -0
- package/lib/routes/hudsonrivertrading/namespace.ts +7 -0
- package/lib/routes/huggingface/daily-papers.ts +45 -9
- package/lib/routes/huijin-inv/namespace.ts +7 -0
- package/lib/routes/huijin-inv/news.ts +83 -0
- package/lib/routes/hupu/index.ts +170 -74
- package/lib/routes/hupu/types.ts +163 -0
- package/lib/routes/hust/gs.ts +1 -1
- package/lib/routes/hust/mse.ts +1 -1
- package/lib/routes/huxiu/util.ts +2 -2
- package/lib/routes/immich/cursed-knowledge.ts +49 -0
- package/lib/routes/immich/namespace.ts +7 -0
- package/lib/routes/infoq/presentations.ts +1 -1
- package/lib/routes/instagram/common-utils.ts +3 -3
- package/lib/routes/investor/index.ts +362 -148
- package/lib/routes/itch/devlog.ts +7 -3
- package/lib/routes/iwara/index.ts +3 -0
- package/lib/routes/iwara/subscriptions.ts +1 -0
- package/lib/routes/javbus/index.ts +1 -1
- package/lib/routes/javdb/actors.ts +1 -0
- package/lib/routes/javdb/index.ts +3 -0
- package/lib/routes/javdb/lists.ts +3 -0
- package/lib/routes/javdb/makers.ts +1 -0
- package/lib/routes/javdb/rankings.ts +1 -0
- package/lib/routes/javdb/search.ts +1 -0
- package/lib/routes/javdb/series.ts +1 -0
- package/lib/routes/javdb/videocodes.ts +1 -0
- package/lib/routes/javlibrary/bestrated.ts +3 -0
- package/lib/routes/javlibrary/bestreviews.ts +1 -0
- package/lib/routes/javlibrary/genre.ts +3 -0
- package/lib/routes/javlibrary/maker.ts +1 -0
- package/lib/routes/javlibrary/mostwanted.ts +3 -0
- package/lib/routes/javlibrary/newentries.ts +3 -0
- package/lib/routes/javlibrary/newrelease.ts +3 -0
- package/lib/routes/javlibrary/update.ts +3 -0
- package/lib/routes/javlibrary/user.ts +3 -0
- package/lib/routes/javlibrary/utils.ts +1 -1
- package/lib/routes/javtrailers/categories.ts +3 -0
- package/lib/routes/javtrailers/studios.ts +3 -0
- package/lib/routes/jbma/namespace.ts +17 -0
- package/lib/routes/jbma/report.ts +471 -0
- package/lib/routes/jetbrains/comments.ts +1 -1
- package/lib/routes/jingzhengu/utils.ts +1 -1
- package/lib/routes/jou/utils/index.ts +2 -2
- package/lib/routes/jpxgmn/search.ts +3 -0
- package/lib/routes/jpxgmn/weekly.ts +3 -0
- package/lib/routes/juejin/aicoding.ts +102 -0
- package/lib/routes/juejin/trending.ts +70 -20
- package/lib/routes/juejin/utils.ts +36 -51
- package/lib/routes/jumeili/home.ts +1 -1
- package/lib/routes/kakuyomu/works.ts +1 -1
- package/lib/routes/kemono/index.ts +11 -3
- package/lib/routes/kemono/templates/discord.art +1 -1
- package/lib/routes/kisskiss/blog.ts +1 -0
- package/lib/routes/komiic/comic.ts +2 -1
- package/lib/routes/koyso/index.ts +339 -0
- package/lib/routes/koyso/namespace.ts +9 -0
- package/lib/routes/koyso/templates/description.art +13 -0
- package/lib/routes/kpopping/kpics.ts +3 -4
- package/lib/routes/kpopping/news.ts +2 -2
- package/lib/routes/laimanhua/index.ts +1 -0
- package/lib/routes/letterboxd/index.ts +65 -0
- package/lib/routes/letterboxd/namespace.ts +8 -0
- package/lib/routes/lhratings/research.ts +1 -1
- package/lib/routes/literotica/category.ts +3 -0
- package/lib/routes/lovelive-anime/topics.ts +5 -6
- package/lib/routes/maccms/index.ts +1 -1
- package/lib/routes/mangadex/index.ts +3 -0
- package/lib/routes/mangadex/mdlist/feed.ts +1 -0
- package/lib/routes/mangadex/user/feed.ts +1 -0
- package/lib/routes/mangadex/user/follows.ts +1 -0
- package/lib/routes/manhuagui/comic.ts +1 -0
- package/lib/routes/manhuagui/subscribe.ts +1 -0
- package/lib/routes/manyvids/video.ts +3 -0
- package/lib/routes/mercari/util.ts +1 -1
- package/lib/routes/mihoyo/sr/news.ts +2 -1
- package/lib/routes/mihoyo/zzz/news.ts +2 -1
- package/lib/routes/mingpao/index.ts +1 -1
- package/lib/routes/musify/index.ts +2 -3
- package/lib/routes/mycard520/news.ts +2 -2
- package/lib/routes/nankai/ai-notice.ts +142 -0
- package/lib/routes/nankai/graduate-notice.ts +162 -0
- package/lib/routes/natgeo/natgeo.ts +3 -2
- package/lib/routes/naturalism/namespace.ts +7 -0
- package/lib/routes/naturalism/new.ts +59 -0
- package/lib/routes/netflav/index.ts +3 -0
- package/lib/routes/nhentai/search.ts +1 -0
- package/lib/routes/nhk/news-web-easy.ts +1 -1
- package/lib/routes/nicovideo/mylist.ts +39 -0
- package/lib/routes/nicovideo/types.ts +27 -0
- package/lib/routes/nicovideo/utils.ts +27 -1
- package/lib/routes/nikkei/cn/index.ts +1 -4
- package/lib/routes/nio/nioradio.ts +1 -1
- package/lib/routes/njxzc/utils/index.ts +2 -2
- package/lib/routes/notion/namespace.ts +2 -2
- package/lib/routes/now/news.ts +1 -1
- package/lib/routes/nytimes/index.ts +1 -1
- package/lib/routes/olevod/vod.ts +3 -0
- package/lib/routes/olevod/vodlist.ts +3 -0
- package/lib/routes/oreno3d/main.ts +1 -0
- package/lib/routes/oschina/column.ts +1 -2
- package/lib/routes/oschina/event.ts +1 -1
- package/lib/routes/osu/beatmaps/latest-ranked.ts +2 -3
- package/lib/routes/papers/category.ts +3 -4
- package/lib/routes/patreon/feed.ts +1 -0
- package/lib/routes/picuki/profile.ts +13 -5
- package/lib/routes/pixiv/bookmarks.ts +1 -0
- package/lib/routes/pixiv/illustfollow.ts +1 -0
- package/lib/routes/pixiv/novel-api/user-novels/sfw.ts +1 -1
- package/lib/routes/pixiv/novel-series.ts +17 -3
- package/lib/routes/pixiv/novels.ts +1 -0
- package/lib/routes/pixiv/ranking.ts +1 -0
- package/lib/routes/pixiv/search.ts +1 -0
- package/lib/routes/pixiv/user.ts +1 -0
- package/lib/routes/pixivision/utils.ts +1 -1
- package/lib/routes/pku/hr.ts +1 -1
- package/lib/routes/pku/scc/recruit.ts +1 -1
- package/lib/routes/pornhub/category-url.ts +1 -0
- package/lib/routes/pornhub/category.ts +1 -0
- package/lib/routes/pornhub/pornstar.ts +1 -0
- package/lib/routes/pornhub/search.ts +1 -0
- package/lib/routes/pornhub/users.ts +1 -0
- package/lib/routes/producthunt/templates/description.art +2 -2
- package/lib/routes/producthunt/today.ts +17 -8
- package/lib/routes/ps/trophy.ts +1 -1
- package/lib/routes/pubscholar/utils.ts +14 -1
- package/lib/routes/qq/lol/news.ts +1 -1
- package/lib/routes/qweather/3days.ts +14 -14
- package/lib/routes/qweather/now.ts +12 -10
- package/lib/routes/qweather/util.tsx +89 -0
- package/lib/routes/qwenlm/blog.ts +75 -0
- package/lib/routes/qwenlm/namespace.ts +6 -0
- package/lib/routes/radio-canada/latest.ts +30 -17
- package/lib/routes/rawkuma/manga.ts +1 -0
- package/lib/routes/ruc/ai.ts +1 -1
- package/lib/routes/ruc/hr.ts +1 -1
- package/lib/routes/samrdprc/index.ts +241 -0
- package/lib/routes/samrdprc/namespace.ts +1 -1
- package/lib/routes/scientificamerican/podcast.ts +2 -2
- package/lib/routes/scitechvista/index.ts +99 -0
- package/lib/routes/scitechvista/namespace.ts +7 -0
- package/lib/routes/scitechvista/templates/description.art +6 -0
- package/lib/routes/scoop/apps.ts +2 -4
- package/lib/routes/sdo/ff14risingstones/api.ts +78 -0
- package/lib/routes/sdo/ff14risingstones/constant.ts +338 -0
- package/lib/routes/sdo/ff14risingstones/posts.ts +80 -0
- package/lib/routes/sdo/ff14risingstones/strats.ts +75 -0
- package/lib/routes/sdo/ff14risingstones/templates/duties-party.art +41 -0
- package/lib/routes/sdo/ff14risingstones/templates/fc-party.art +26 -0
- package/lib/routes/sdo/ff14risingstones/templates/novice-network-party.art +9 -0
- package/lib/routes/sdo/ff14risingstones/templates/rp-party.art +15 -0
- package/lib/routes/sdo/ff14risingstones/timeline.ts +31 -0
- package/lib/routes/sdo/ff14risingstones/types/dynamic.ts +50 -0
- package/lib/routes/sdo/ff14risingstones/types/index.ts +3 -0
- package/lib/routes/sdo/ff14risingstones/types/other.ts +57 -0
- package/lib/routes/sdo/ff14risingstones/types/party.ts +111 -0
- package/lib/routes/sdo/ff14risingstones/user-dynamics.ts +32 -0
- package/lib/routes/sdo/ff14risingstones/user-posts.ts +32 -0
- package/lib/routes/sdo/ff14risingstones/user-resently.ts +38 -0
- package/lib/routes/sdo/ff14risingstones/user-strats.ts +32 -0
- package/lib/routes/sdo/ff14risingstones/utils.ts +215 -0
- package/lib/routes/sdo/namespace.ts +7 -0
- package/lib/routes/secretsanfrancisco/namespace.ts +7 -0
- package/lib/routes/secretsanfrancisco/rss.ts +101 -0
- package/lib/routes/secretsanfrancisco/templates/description.art +9 -0
- package/lib/routes/sehuatang/user.ts +1 -0
- package/lib/routes/showstart/utils.ts +1 -1
- package/lib/routes/shu/global.ts +6 -5
- package/lib/routes/shu/xxgk.ts +107 -0
- package/lib/routes/shuiguopai/index.ts +3 -0
- package/lib/routes/sis001/author.ts +1 -0
- package/lib/routes/sjtu/jwc.ts +1 -1
- package/lib/routes/skeb/following-creators.ts +1 -0
- package/lib/routes/skeb/following-works.ts +1 -0
- package/lib/routes/skeb/friend-works.ts +1 -0
- package/lib/routes/skeb/index.ts +1 -0
- package/lib/routes/skeb/search.ts +1 -0
- package/lib/routes/skeb/works.ts +44 -25
- package/lib/routes/skebetter/illust.ts +1 -0
- package/lib/routes/skebetter/index.ts +1 -0
- package/lib/routes/skebetter/manga.ts +1 -0
- package/lib/routes/sohu/mp.ts +1 -1
- package/lib/routes/sotwe/user.ts +1 -1
- package/lib/routes/sspai/index.ts +5 -1
- package/lib/routes/stcn/index.ts +1 -2
- package/lib/routes/stcn/rank.ts +1 -2
- package/lib/routes/surfshark/blog.ts +273 -77
- package/lib/routes/surfshark/templates/description.art +16 -4
- package/lib/routes/sustainabilitymag/articles.ts +1 -1
- package/lib/routes/syosetu/dev.ts +1 -1
- package/lib/routes/syosetu/ranking-isekai.ts +1 -1
- package/lib/routes/szse/disclosure/listed-notice.ts +44 -6
- package/lib/routes/t66y/post.ts +1 -0
- package/lib/routes/techcrunch/news.ts +1 -0
- package/lib/routes/techpowerup/index.ts +11 -11
- package/lib/routes/techpowerup/namespace.ts +1 -1
- package/lib/routes/techpowerup/review.ts +12 -12
- package/lib/routes/techpowerup/utils.ts +2 -2
- package/lib/routes/telegram/channel-media.ts +249 -0
- package/lib/routes/telegram/channel.ts +5 -4
- package/lib/routes/telegram/stories.ts +130 -0
- package/lib/routes/telegram/tglib/channel.ts +146 -117
- package/lib/routes/telegram/tglib/client.ts +37 -139
- package/lib/routes/tesla/cx.ts +1 -1
- package/lib/routes/test/index.ts +4 -0
- package/lib/routes/thegadgetflow/namespace.ts +7 -0
- package/lib/routes/thegadgetflow/rss.ts +99 -0
- package/lib/routes/thegadgetflow/templates/description.art +9 -0
- package/lib/routes/theverge/index.ts +20 -6
- package/lib/routes/threads/utils.ts +7 -3
- package/lib/routes/tidb/blog.ts +2 -2
- package/lib/routes/tmtpost/column.ts +1 -1
- package/lib/routes/toutiao/user.ts +2 -2
- package/lib/routes/trendforce/namespace.ts +9 -0
- package/lib/routes/trendforce/new.ts +113 -0
- package/lib/routes/tsinghua/news.ts +87 -0
- package/lib/routes/twitter/api/mobile-api/api.ts +1 -1
- package/lib/routes/twitter/api/web-api/api.ts +5 -1
- package/lib/routes/txrjy/fornumtopic.ts +2 -2
- package/lib/routes/typst/universe.ts +1 -1
- package/lib/routes/uber/blog.ts +87 -46
- package/lib/routes/uraaka-joshi/uraaka-joshi-user.ts +1 -0
- package/lib/routes/uraaka-joshi/uraaka-joshi.ts +3 -0
- package/lib/routes/wainao/topics.ts +1 -1
- package/lib/routes/wdfxw/bookfree.ts +1 -1
- package/lib/routes/weibo/utils.ts +17 -9
- package/lib/routes/wikipedia/current-events.ts +411 -0
- package/lib/routes/wikipedia/namespace.ts +7 -0
- package/lib/routes/wnacg/category.ts +3 -0
- package/lib/routes/wnacg/index.ts +3 -0
- package/lib/routes/wnacg/tag.ts +3 -0
- package/lib/routes/wohnnet/index.ts +2 -2
- package/lib/routes/xiaohongshu/user.ts +2 -2
- package/lib/routes/xiaohongshu/util.ts +16 -9
- package/lib/routes/xjtu/ee-jzxx.ts +1 -1
- package/lib/routes/xjtu/zs.ts +1 -1
- package/lib/routes/xsijishe/forum.ts +1 -0
- package/lib/routes/xsijishe/rank.ts +1 -0
- package/lib/routes/xwenming/index.ts +1 -1
- package/lib/routes/yahoo/news/utils.ts +7 -3
- package/lib/routes/ymgal/article.ts +1 -1
- package/lib/routes/yoasobi-music/media.ts +1 -1
- package/lib/routes/youtube/api/google.ts +20 -6
- package/lib/routes/youtube/api/subtitles.ts +86 -0
- package/lib/routes/youtube/api/youtubei.ts +7 -51
- package/lib/routes/youtube/channel.ts +1 -1
- package/lib/routes/youtube/community.ts +4 -4
- package/lib/routes/youtube/user.ts +1 -1
- package/lib/routes/yuanliao/index.ts +1 -1
- package/lib/routes/zaimanhua/comic.ts +1 -0
- package/lib/routes/zaimanhua/update.ts +1 -0
- package/lib/routes/zaker/utils.ts +1 -1
- package/lib/routes/zaobao/interactive.ts +18 -7
- package/lib/routes/zaobao/other.ts +3 -2
- package/lib/routes/zaobao/realtime.ts +3 -2
- package/lib/routes/zaobao/util.tsx +185 -0
- package/lib/routes/zaobao/zaobao.tsx +23 -0
- package/lib/routes/zaobao/znews.ts +3 -2
- package/lib/routes/zhihu/daily-section.ts +19 -24
- package/lib/routes/zhihu/daily.ts +8 -11
- package/lib/routes/zju/cse/index.ts +102 -0
- package/lib/routes/zodgame/forum.ts +1 -0
- package/lib/server.ts +1 -1
- package/lib/types.ts +1 -1
- package/lib/utils/puppeteer-utils.test.ts +5 -5
- package/lib/utils/puppeteer.test.ts +1 -1
- package/lib/views/index.tsx +4 -4
- package/package.json +55 -57
- package/lib/routes/gdufs/xwxy/xwxy-news.ts +0 -90
- package/lib/routes/hit/jwc.ts +0 -86
- package/lib/routes/picuki/utils.ts +0 -19
- package/lib/routes/qweather/templates/3days.art +0 -22
- package/lib/routes/qweather/templates/now.art +0 -16
- package/lib/routes/xinhuanet/app.ts +0 -109
- package/lib/routes/zaobao/templates/zaobao.art +0 -17
- package/lib/routes/zaobao/util.ts +0 -198
|
@@ -36,7 +36,7 @@ const weiboUtils = {
|
|
|
36
36
|
widthOfPics: fallback(params.widthOfPics, queryToInteger(routeParams.widthOfPics), -1),
|
|
37
37
|
heightOfPics: fallback(params.heightOfPics, queryToInteger(routeParams.heightOfPics), -1),
|
|
38
38
|
sizeOfAuthorAvatar: fallback(params.sizeOfAuthorAvatar, queryToInteger(routeParams.sizeOfAuthorAvatar), 48),
|
|
39
|
-
showEmojiInDescription: fallback(params.showEmojiInDescription, queryToInteger(routeParams.showEmojiInDescription),
|
|
39
|
+
showEmojiInDescription: fallback(params.showEmojiInDescription, queryToInteger(routeParams.showEmojiInDescription), false),
|
|
40
40
|
showLinkIconInDescription: fallback(params.showLinkIconInDescription, queryToInteger(routeParams.showLinkIconInDescription), true),
|
|
41
41
|
preferMobileLink: fallback(params.preferMobileLink, queryToBoolean(routeParams.preferMobileLink), false),
|
|
42
42
|
};
|
|
@@ -157,15 +157,23 @@ const weiboUtils = {
|
|
|
157
157
|
let style = '';
|
|
158
158
|
html += '<img ';
|
|
159
159
|
html += readable ? 'vspace="8" hspace="4"' : '';
|
|
160
|
-
if (
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
160
|
+
if (item.large) {
|
|
161
|
+
const { geo, url } = item.large;
|
|
162
|
+
|
|
163
|
+
if (geo?.width || widthOfPics >= 0) {
|
|
164
|
+
const width = geo?.width || widthOfPics;
|
|
165
|
+
html += ` width="${width}"`;
|
|
166
|
+
style += `width: ${width}px;`;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (geo?.height || heightOfPics >= 0) {
|
|
170
|
+
const height = geo?.height || heightOfPics;
|
|
171
|
+
html += ` height="${height}"`;
|
|
172
|
+
style += `height: ${height}px;`;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
html += ` style="${style}" src="${url}">`;
|
|
167
176
|
}
|
|
168
|
-
html += ` style="${style}"` + ' src="' + item.large.url + '">';
|
|
169
177
|
|
|
170
178
|
if (addLinkForPics) {
|
|
171
179
|
html += '</a>';
|
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
import { Route } from '@/types';
|
|
2
|
+
import cache from '@/utils/cache';
|
|
3
|
+
import got from '@/utils/got';
|
|
4
|
+
import { parseDate } from '@/utils/parse-date';
|
|
5
|
+
import { config } from '@/config';
|
|
6
|
+
|
|
7
|
+
/* The different ways to query Wikipedia's Current Events
|
|
8
|
+
|
|
9
|
+
User-facing pages. Can call them with ?action=render to only get the html of the content
|
|
10
|
+
1. portal: `https://en.wikipedia.org/wiki/Portal:Current_events`
|
|
11
|
+
2. single day: `https://en.wikipedia.org/w/index.php?title=Portal:Current_events/2025_September_20`
|
|
12
|
+
3. section that is included in the portal, 7 most recent days: `https://en.wikipedia.org/wiki/Portal:Current_events/Inclusion`
|
|
13
|
+
|
|
14
|
+
API at `https://en.wikipedia.org/w/api.php`. Can target:
|
|
15
|
+
4. multiple pages, result in wikitext, may have continuation with:
|
|
16
|
+
`action=query&format=json&prop=revisions&rvprop=content&rvslots=main&titles=${page1|page2|...}`,
|
|
17
|
+
5. a single page, result in html with:
|
|
18
|
+
`action=parse&format=json&page=${page}` (with page being a page link) or
|
|
19
|
+
`https://en.wikipedia.org/w/api.php?action=parse&format=json&contentmodel=wikitext&text={{wikitext}}` (wikitext is a wikitext expression)
|
|
20
|
+
6. multiple pages, result in html, will have continuation for more than 1 page with (note rvparse is obsolete):
|
|
21
|
+
`action=query&format=json&rvprop=content&rvparse=true${page1|page2|...}`
|
|
22
|
+
|
|
23
|
+
Notes:
|
|
24
|
+
7. combining 5. and 3. as `https://en.wikipedia.org/w/api.php?action=parse&format=json&page=Portal:Current_events/Inclusion`
|
|
25
|
+
seems good but doesn't let exclude the most recent day if too early
|
|
26
|
+
8. combining 5. and 4. as `https://en.wikipedia.org/w/api.php?action=parse&format=json&contentmodel=wikitext&text={{Portal:Current events/Inclusion|2025|09|20}}`
|
|
27
|
+
variant that fix the above
|
|
28
|
+
|
|
29
|
+
- the rendered html still need some processing:
|
|
30
|
+
- for inclusion pages, split in separate days
|
|
31
|
+
- extract the significant div of each day
|
|
32
|
+
- strip css and possibly class/id
|
|
33
|
+
- if the result is in wikitext, it needs to be converted to html
|
|
34
|
+
|
|
35
|
+
4. is the fastest and current implementation. */
|
|
36
|
+
|
|
37
|
+
function getCurrentEventsDatePath(date: Date): string {
|
|
38
|
+
const months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
|
|
39
|
+
|
|
40
|
+
const year = date.getFullYear();
|
|
41
|
+
const month = months[date.getMonth()];
|
|
42
|
+
const day = date.getDate(); // Not zero-padded
|
|
43
|
+
|
|
44
|
+
return `Portal:Current_events/${year}_${month}_${day}`;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Simple MediaWiki template parser for {{Current events}} template
|
|
48
|
+
function parseCurrentEventsTemplate(wikitext: string): string | null {
|
|
49
|
+
if (!wikitext || typeof wikitext !== 'string') {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Look for {{Current events|content=...}} template
|
|
54
|
+
const templateMatch = wikitext.match(/\{\{Current events\s*\|[\s\S]*?content\s*=\s*([\s\S]*?)\}\}/);
|
|
55
|
+
if (!templateMatch) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return templateMatch[1].trim();
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function convertWikiLinks(html: string): string {
|
|
63
|
+
// Convert wiki links [[Link|Text]] or [[Link]]
|
|
64
|
+
html = html.replaceAll(/\[\[([^|\]]+)\|([^\]]+)\]\]/g, '<a href="https://en.wikipedia.org/wiki/$1">$2</a>');
|
|
65
|
+
html = html.replaceAll(/\[\[([^\]]+)\]\]/g, '<a href="https://en.wikipedia.org/wiki/$1">$1</a>');
|
|
66
|
+
return html;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function convertExternalLinks(html: string): string {
|
|
70
|
+
// Convert external links [URL Text] or [URL]
|
|
71
|
+
html = html.replaceAll(/\[([^\s\]]+)\s+([^\]]+)\]/g, '<a href="$1">$2</a>');
|
|
72
|
+
html = html.replaceAll(/\[([^\s\]]+)\]/g, '<a href="$1">$1</a>');
|
|
73
|
+
return html;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function convertTextFormatting(html: string): string {
|
|
77
|
+
// Convert bold '''text'''
|
|
78
|
+
html = html.replaceAll(/'''([^']+)'''/g, '<strong>$1</strong>');
|
|
79
|
+
// Convert italic ''text''
|
|
80
|
+
html = html.replaceAll(/''([^']+)''/g, '<em>$1</em>');
|
|
81
|
+
return html;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function processListsAndLines(html: string): string {
|
|
85
|
+
const lines = html.split('\n');
|
|
86
|
+
const processedLines: string[] = [];
|
|
87
|
+
|
|
88
|
+
for (const line of lines) {
|
|
89
|
+
const trimmedLine = line.trim();
|
|
90
|
+
|
|
91
|
+
if (!trimmedLine) {
|
|
92
|
+
// Empty line - add paragraph break
|
|
93
|
+
processedLines.push('</p><p>');
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Check for bullet points and convert to proper nesting
|
|
98
|
+
const bulletMatch = trimmedLine.match(/^(\*+)\s*(.+)$/);
|
|
99
|
+
if (bulletMatch) {
|
|
100
|
+
const depth = bulletMatch[1].length;
|
|
101
|
+
const content = bulletMatch[2];
|
|
102
|
+
|
|
103
|
+
// Create proper nested list structure
|
|
104
|
+
const indent = ' '.repeat(depth - 1);
|
|
105
|
+
processedLines.push(`${indent}<li>${content}</li>`);
|
|
106
|
+
} else {
|
|
107
|
+
// Regular text line
|
|
108
|
+
processedLines.push(trimmedLine);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
let results = processedLines.join('\n');
|
|
113
|
+
|
|
114
|
+
// Process lists
|
|
115
|
+
results = wrapListItems(results);
|
|
116
|
+
return processNestedLists(results);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function wrapListItems(html: string): string {
|
|
120
|
+
// Convert consecutive <li> elements into proper <ul> structures
|
|
121
|
+
return html.replaceAll(/(<li>.*?<\/li>(?:\s*<li>.*?<\/li>)*)/gs, (match) => `<ul>\n${match}\n</ul>`);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function processNestedLists(html: string): string {
|
|
125
|
+
const finalLines = html.split('\n');
|
|
126
|
+
const result: string[] = [];
|
|
127
|
+
let currentDepth = 0;
|
|
128
|
+
const openTags: string[] = [];
|
|
129
|
+
|
|
130
|
+
for (const line of finalLines) {
|
|
131
|
+
const trimmed = line.trim();
|
|
132
|
+
|
|
133
|
+
if (trimmed.startsWith('<li>')) {
|
|
134
|
+
const indent = line.match(/^(\s*)/)?.[1]?.length || 0;
|
|
135
|
+
const depth = Math.floor(indent / 2) + 1;
|
|
136
|
+
|
|
137
|
+
// Close deeper levels
|
|
138
|
+
while (currentDepth > depth) {
|
|
139
|
+
result.push(' '.repeat(currentDepth - 1) + '</ul>');
|
|
140
|
+
openTags.pop();
|
|
141
|
+
currentDepth--;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Open new level if needed
|
|
145
|
+
if (currentDepth < depth) {
|
|
146
|
+
result.push(' '.repeat(depth - 1) + '<ul>');
|
|
147
|
+
openTags.push('ul');
|
|
148
|
+
currentDepth = depth;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
result.push(' '.repeat(depth) + trimmed);
|
|
152
|
+
} else {
|
|
153
|
+
// Close all open lists
|
|
154
|
+
while (currentDepth > 0) {
|
|
155
|
+
result.push(' '.repeat(currentDepth - 1) + '</ul>');
|
|
156
|
+
openTags.pop();
|
|
157
|
+
currentDepth--;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (trimmed === '</p><p>') {
|
|
161
|
+
result.push('</p>\n<p>');
|
|
162
|
+
} else if (trimmed) {
|
|
163
|
+
result.push(trimmed);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Close any remaining open lists
|
|
169
|
+
while (currentDepth > 0) {
|
|
170
|
+
result.push(' '.repeat(currentDepth - 1) + '</ul>');
|
|
171
|
+
currentDepth--;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return result.join('');
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function stripComments(html: string): string {
|
|
178
|
+
// Remove HTML comments
|
|
179
|
+
return html.replaceAll(/<!--[\s\S]*?-->/g, '');
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function wrapInParagraphsAndCleanup(html: string): string {
|
|
183
|
+
// Clean up multiple paragraph tags and empty paragraphs
|
|
184
|
+
html = html.replaceAll(/<\/p>\s*<p>/g, '</p>\n<p>');
|
|
185
|
+
html = html.replaceAll(/<p>\s*<ul>/g, '<ul>');
|
|
186
|
+
html = html.replaceAll(/<\/ul>\s*<\/p>/g, '</ul>');
|
|
187
|
+
|
|
188
|
+
// Remove any empty paragraphs (be aggressive about it)
|
|
189
|
+
html = html.replaceAll(/<p>[\s\n\r]*<\/p>/g, '');
|
|
190
|
+
html = html.replaceAll(/<p>\s*<\/p>/g, '');
|
|
191
|
+
html = html.replaceAll('<p></p>', '');
|
|
192
|
+
|
|
193
|
+
// Final cleanup - remove trailing empty paragraphs that might have been added
|
|
194
|
+
html = html.replaceAll(/<p>\s*$/g, '').replaceAll(/\s*<\/p>$/g, '');
|
|
195
|
+
|
|
196
|
+
return html;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// Wiki markup to HTML converter with proper list handling
|
|
200
|
+
function wikiToHtml(wikitext: string): string {
|
|
201
|
+
let html = wikitext;
|
|
202
|
+
|
|
203
|
+
// Apply transformations in order
|
|
204
|
+
html = convertWikiLinks(html);
|
|
205
|
+
html = convertExternalLinks(html);
|
|
206
|
+
html = convertTextFormatting(html);
|
|
207
|
+
html = processListsAndLines(html);
|
|
208
|
+
html = wrapInParagraphsAndCleanup(html);
|
|
209
|
+
html = stripComments(html);
|
|
210
|
+
|
|
211
|
+
return html;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
async function fetchMultipleWikiContent(pageNames: string[]): Promise<Record<string, string>> {
|
|
215
|
+
const url = 'https://en.wikipedia.org/w/api.php';
|
|
216
|
+
const titles = pageNames.join('|');
|
|
217
|
+
const results: Record<string, string> = {};
|
|
218
|
+
|
|
219
|
+
let continueParams: Record<string, string> = {};
|
|
220
|
+
|
|
221
|
+
let hasMore = true;
|
|
222
|
+
while (hasMore) {
|
|
223
|
+
const searchParams = {
|
|
224
|
+
action: 'query',
|
|
225
|
+
format: 'json',
|
|
226
|
+
titles,
|
|
227
|
+
prop: 'revisions',
|
|
228
|
+
rvprop: 'content',
|
|
229
|
+
rvslots: 'main',
|
|
230
|
+
...continueParams,
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
// eslint-disable-next-line no-await-in-loop
|
|
234
|
+
const response = await got(url, {
|
|
235
|
+
searchParams,
|
|
236
|
+
headers: {
|
|
237
|
+
'User-Agent': config.trueUA,
|
|
238
|
+
},
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
const data = JSON.parse(response.body);
|
|
242
|
+
|
|
243
|
+
if (data.query && data.query.pages) {
|
|
244
|
+
for (const page of Object.values(data.query.pages)) {
|
|
245
|
+
if (page.revisions && page.revisions[0] && page.revisions[0].slots && page.revisions[0].slots.main) {
|
|
246
|
+
const wikitext = page.revisions[0].slots.main['*'];
|
|
247
|
+
|
|
248
|
+
// Parse the Current events template content
|
|
249
|
+
const content = parseCurrentEventsTemplate(wikitext);
|
|
250
|
+
|
|
251
|
+
if (content) {
|
|
252
|
+
// Convert wiki markup to HTML
|
|
253
|
+
const html = wikiToHtml(content);
|
|
254
|
+
|
|
255
|
+
// Use the page title as the key
|
|
256
|
+
const pageTitle = page.title;
|
|
257
|
+
// Convert back to the format we expect: "Portal:Current_events/2025_September_18"
|
|
258
|
+
const normalizedTitle = pageTitle.replace(/Portal:Current events\/(\d{4}) (\w+) (\d+)/, 'Portal:Current_events/$1_$2_$3');
|
|
259
|
+
results[normalizedTitle] = html;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// Check for continuation
|
|
266
|
+
if (data.continue) {
|
|
267
|
+
continueParams = data.continue;
|
|
268
|
+
} else {
|
|
269
|
+
hasMore = false;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
return results;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
export const route: Route = {
|
|
277
|
+
path: '/current-events/:includeToday?',
|
|
278
|
+
categories: ['new-media'],
|
|
279
|
+
example: '/wikipedia/current-events',
|
|
280
|
+
parameters: {
|
|
281
|
+
includeToday: {
|
|
282
|
+
description: 'Include current day events (may be incomplete early in the day)',
|
|
283
|
+
default: 'auto',
|
|
284
|
+
options: [
|
|
285
|
+
{
|
|
286
|
+
label: 'Auto (include after 18:00 UTC)',
|
|
287
|
+
value: 'auto',
|
|
288
|
+
},
|
|
289
|
+
{
|
|
290
|
+
label: 'Always include current day',
|
|
291
|
+
value: 'always',
|
|
292
|
+
},
|
|
293
|
+
{
|
|
294
|
+
label: 'Never include current day',
|
|
295
|
+
value: 'never',
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
label: 'Include after specific UTC hour (0-23)',
|
|
299
|
+
value: '0-23',
|
|
300
|
+
},
|
|
301
|
+
],
|
|
302
|
+
},
|
|
303
|
+
},
|
|
304
|
+
features: {
|
|
305
|
+
requireConfig: false,
|
|
306
|
+
requirePuppeteer: false,
|
|
307
|
+
antiCrawler: false,
|
|
308
|
+
supportBT: false,
|
|
309
|
+
supportPodcast: false,
|
|
310
|
+
supportScihub: false,
|
|
311
|
+
},
|
|
312
|
+
radar: [
|
|
313
|
+
{
|
|
314
|
+
source: ['en.wikipedia.org/wiki/Portal:Current_events'],
|
|
315
|
+
target: '/wikipedia/current-events',
|
|
316
|
+
},
|
|
317
|
+
],
|
|
318
|
+
name: 'Current Events',
|
|
319
|
+
maintainers: ['aavanian'],
|
|
320
|
+
handler,
|
|
321
|
+
description: 'Wikipedia Portal: Current events - Latest news and events from the past 7 days',
|
|
322
|
+
};
|
|
323
|
+
|
|
324
|
+
async function handler(ctx) {
|
|
325
|
+
const includeToday = ctx.req.param('includeToday') ?? 'auto';
|
|
326
|
+
|
|
327
|
+
// Determine if we should include today's events
|
|
328
|
+
const dates = determineDates(includeToday);
|
|
329
|
+
|
|
330
|
+
// Create array of page names for batch request
|
|
331
|
+
const pageNames = dates.map((date) => getCurrentEventsDatePath(date));
|
|
332
|
+
const cacheKey = 'wikipedia:current-events:batch:' + pageNames.join('|');
|
|
333
|
+
|
|
334
|
+
try {
|
|
335
|
+
// Single batch request for all pages
|
|
336
|
+
const contentMap = await cache.tryGet(cacheKey, async () => await fetchMultipleWikiContent(pageNames), config.cache.contentExpire);
|
|
337
|
+
|
|
338
|
+
// Build RSS items from the fetched content
|
|
339
|
+
const items = dates
|
|
340
|
+
.map((date) => {
|
|
341
|
+
const pageName = getCurrentEventsDatePath(date);
|
|
342
|
+
const html = contentMap[pageName];
|
|
343
|
+
|
|
344
|
+
if (html) {
|
|
345
|
+
const dateStr = date.toISOString().split('T')[0]; // YYYY-MM-DD format
|
|
346
|
+
|
|
347
|
+
return {
|
|
348
|
+
title: `Current events: ${dateStr}`,
|
|
349
|
+
link: `https://en.wikipedia.org/wiki/${pageName}`,
|
|
350
|
+
description: html,
|
|
351
|
+
pubDate: parseDate(date.toISOString()),
|
|
352
|
+
guid: `wikipedia-current-events-${dateStr}`,
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
return null;
|
|
356
|
+
})
|
|
357
|
+
.filter((item) => item !== null);
|
|
358
|
+
|
|
359
|
+
return {
|
|
360
|
+
title: 'Wikipedia: Portal: Current events',
|
|
361
|
+
link: 'https://en.wikipedia.org/wiki/Portal:Current_events',
|
|
362
|
+
description: 'Current events from Wikipedia - Latest news and events',
|
|
363
|
+
item: items,
|
|
364
|
+
};
|
|
365
|
+
} catch (error) {
|
|
366
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
367
|
+
throw new Error(`Failed to fetch Wikipedia current events: ${message}`);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
function determineDates(includeToday: any) {
|
|
371
|
+
const now = new Date();
|
|
372
|
+
const currentHourUTC = now.getUTCHours();
|
|
373
|
+
|
|
374
|
+
let shouldIncludeToday = false;
|
|
375
|
+
|
|
376
|
+
switch (includeToday) {
|
|
377
|
+
case 'always':
|
|
378
|
+
shouldIncludeToday = true;
|
|
379
|
+
|
|
380
|
+
break;
|
|
381
|
+
|
|
382
|
+
case 'never':
|
|
383
|
+
shouldIncludeToday = false;
|
|
384
|
+
|
|
385
|
+
break;
|
|
386
|
+
|
|
387
|
+
case 'auto':
|
|
388
|
+
// Include after 18:00 UTC (6 PM)
|
|
389
|
+
shouldIncludeToday = currentHourUTC >= 18;
|
|
390
|
+
|
|
391
|
+
break;
|
|
392
|
+
|
|
393
|
+
default:
|
|
394
|
+
if (/^\d+$/.test(includeToday)) {
|
|
395
|
+
// Include after specific hour (0-23)
|
|
396
|
+
const targetHour = Number.parseInt(includeToday, 10);
|
|
397
|
+
if (targetHour >= 0 && targetHour <= 23) {
|
|
398
|
+
shouldIncludeToday = currentHourUTC >= targetHour;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
// Create array of dates for the past 7 days, optionally including today
|
|
404
|
+
const startOffset = shouldIncludeToday ? 0 : 1;
|
|
405
|
+
const dates = Array.from({ length: 7 }, (_, i) => {
|
|
406
|
+
const date = new Date();
|
|
407
|
+
date.setDate(date.getDate() - (i + startOffset));
|
|
408
|
+
return date;
|
|
409
|
+
});
|
|
410
|
+
return dates;
|
|
411
|
+
}
|
package/lib/routes/wnacg/tag.ts
CHANGED
|
@@ -18,12 +18,12 @@ Only returns the first page of search results, allowing you to keep track of
|
|
|
18
18
|
newly added apartments. If you're looking for an apartment, make sure to also
|
|
19
19
|
look through the other pages on the website.
|
|
20
20
|
|
|
21
|
-
:::tip
|
|
21
|
+
::: tip
|
|
22
22
|
Note that the parameter \`&sortierung=neueste-zuerst\` for chronological order
|
|
23
23
|
is automatically appended.
|
|
24
24
|
:::
|
|
25
25
|
|
|
26
|
-
:::tip
|
|
26
|
+
::: tip
|
|
27
27
|
To get your query URL, go to https://www.wohnnet.at/immobilien/suche, apply
|
|
28
28
|
all desired filters (but at least a category and a region!) and click the
|
|
29
29
|
"… Treffer anzeigen" link. From the resulting URL, cut off the
|
|
@@ -98,8 +98,8 @@ async function getUserFeeds(url: string, category: string) {
|
|
|
98
98
|
n.map(({ id, noteCard }) => ({
|
|
99
99
|
title: noteCard.displayTitle,
|
|
100
100
|
link: new URL(noteCard.noteId || id, url).toString(),
|
|
101
|
-
guid:
|
|
102
|
-
description: `<img src ="${noteCard.cover.infoList.pop().url}"><br>${noteCard.displayTitle}`,
|
|
101
|
+
guid: noteCard.displayTitle,
|
|
102
|
+
description: `<img src ="${noteCard.cover.infoList.pop().url} width="${noteCard.cover.width}" height="${noteCard.cover.height}"><br>${noteCard.displayTitle}`,
|
|
103
103
|
author: noteCard.user.nickname,
|
|
104
104
|
upvotes: noteCard.interactInfo.likedCount,
|
|
105
105
|
}))
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { config } from '@/config';
|
|
2
2
|
import logger from '@/utils/logger';
|
|
3
3
|
import { parseDate } from '@/utils/parse-date';
|
|
4
|
-
import puppeteer from '@/utils/puppeteer';
|
|
4
|
+
import puppeteer, { getPuppeteerPage } from '@/utils/puppeteer';
|
|
5
5
|
import ofetch from '@/utils/ofetch';
|
|
6
6
|
import { load } from 'cheerio';
|
|
7
7
|
import cache from '@/utils/cache';
|
|
8
|
+
import CaptchaError from '@/errors/types/captcha';
|
|
8
9
|
|
|
9
10
|
// Common headers for requests
|
|
10
11
|
const getHeaders = (cookie?: string) => ({
|
|
@@ -31,19 +32,25 @@ const getUser = (url, cache) =>
|
|
|
31
32
|
cache.tryGet(
|
|
32
33
|
url,
|
|
33
34
|
async () => {
|
|
34
|
-
const
|
|
35
|
+
const { page, destory } = await getPuppeteerPage(url, {
|
|
36
|
+
onBeforeLoad: async (page) => {
|
|
37
|
+
await page.setRequestInterception(true);
|
|
38
|
+
page.on('request', (request) => {
|
|
39
|
+
request.resourceType() === 'document' || request.resourceType() === 'script' || request.resourceType() === 'xhr' || request.resourceType() === 'other' ? request.continue() : request.abort();
|
|
40
|
+
});
|
|
41
|
+
},
|
|
42
|
+
});
|
|
35
43
|
try {
|
|
36
|
-
const page = await browser.newPage();
|
|
37
|
-
await page.setRequestInterception(true);
|
|
38
44
|
let collect = '';
|
|
39
|
-
page.on('request', (request) => {
|
|
40
|
-
request.resourceType() === 'document' || request.resourceType() === 'script' || request.resourceType() === 'xhr' || request.resourceType() === 'other' ? request.continue() : request.abort();
|
|
41
|
-
});
|
|
42
45
|
logger.http(`Requesting ${url}`);
|
|
43
46
|
await page.goto(url, {
|
|
44
47
|
waitUntil: 'domcontentloaded',
|
|
45
48
|
});
|
|
46
|
-
await page.waitForSelector('div.reds-tab-item:nth-child(2)');
|
|
49
|
+
await page.waitForSelector('div.reds-tab-item:nth-child(2), #red-captcha');
|
|
50
|
+
|
|
51
|
+
if (await page.$('#red-captcha')) {
|
|
52
|
+
throw new CaptchaError('小红书风控校验,请稍后再试');
|
|
53
|
+
}
|
|
47
54
|
|
|
48
55
|
const initialState = await page.evaluate(() => (window as any).__INITIAL_STATE__);
|
|
49
56
|
|
|
@@ -69,7 +76,7 @@ const getUser = (url, cache) =>
|
|
|
69
76
|
|
|
70
77
|
return { userPageData, notes, collect };
|
|
71
78
|
} finally {
|
|
72
|
-
await
|
|
79
|
+
await destory();
|
|
73
80
|
}
|
|
74
81
|
},
|
|
75
82
|
config.cache.routeExpire,
|
|
@@ -77,7 +77,7 @@ async function handler(ctx) {
|
|
|
77
77
|
.find('ul li') // 定位到附件列表项
|
|
78
78
|
.each(function () {
|
|
79
79
|
const $li = $(this);
|
|
80
|
-
const newText = $li.html()?.
|
|
80
|
+
const newText = $li.html()?.replaceAll(/已下载[\s\S]*?<\/span>次/g, '') ?? '';
|
|
81
81
|
$li.html(newText.replace(/<\/a>\s*$/, '</a>'));
|
|
82
82
|
})
|
|
83
83
|
.end()
|
package/lib/routes/xjtu/zs.ts
CHANGED
|
@@ -139,7 +139,7 @@ export const route: Route = {
|
|
|
139
139
|
],
|
|
140
140
|
},
|
|
141
141
|
},
|
|
142
|
-
description: `:::tip
|
|
142
|
+
description: `::: tip
|
|
143
143
|
若订阅 [招生快讯](https://zs.xjtu.edu.cn/zsxx1/zskx.htm),网址为 \`https://zs.xjtu.edu.cn/zsxx1/zskx.htm\`,请截取 \`https://zs.xjtu.edu.cn/\` 到末尾 \`.htm\` 的部分 \`zsxx1/zskx\` 作为 \`category\` 参数填入,此时目标路由为 [\`/xjtu/zs/zsxx1/zskx\`](https://rsshub.app/xjtu/zs/zsxx1/zskx)。
|
|
144
144
|
:::
|
|
145
145
|
|
|
@@ -127,7 +127,7 @@ export const route: Route = {
|
|
|
127
127
|
],
|
|
128
128
|
},
|
|
129
129
|
},
|
|
130
|
-
description: `:::tip
|
|
130
|
+
description: `::: tip
|
|
131
131
|
订阅 [科技前沿](https://www.xwenming.com/index.php/category/news),其源网址为 \`https://www.xwenming.com/index.php/category/news\`,请参考该 URL 指定部分构成参数,此时路由为 [\`/xwenming/category/news\`](https://rsshub.app/xwenming/category/news) 或 [\`/xwenming/category/科技前沿\`](https://rsshub.app/xwenming/category/科技前沿)。
|
|
132
132
|
:::
|
|
133
133
|
|
|
@@ -82,11 +82,15 @@ const parseItem = (item, tryGet) =>
|
|
|
82
82
|
const { data: response } = await got(item.link);
|
|
83
83
|
const $ = load(response);
|
|
84
84
|
|
|
85
|
-
const ldJson = JSON.parse(
|
|
86
|
-
|
|
85
|
+
const ldJson = JSON.parse(
|
|
86
|
+
$('script[type="application/ld+json"]')
|
|
87
|
+
.toArray()
|
|
88
|
+
.find((ele) => $(ele).text().includes('"@type":"NewsArticle"'))?.children[0].data
|
|
89
|
+
);
|
|
90
|
+
const author = ldJson.author.name;
|
|
87
91
|
const body = $('.atoms');
|
|
88
92
|
|
|
89
|
-
body.find('noscript').remove();
|
|
93
|
+
body.find('noscript, .text-gandalf, [id^="sda-inbody-"]').remove();
|
|
90
94
|
// remove padding
|
|
91
95
|
body.find('.caas-figure-with-pb, .caas-img-container').each((_, ele) => {
|
|
92
96
|
const $ele = $(ele);
|
|
@@ -45,7 +45,7 @@ async function handler(ctx) {
|
|
|
45
45
|
data.push(...response.data.data);
|
|
46
46
|
})
|
|
47
47
|
);
|
|
48
|
-
data = data.
|
|
48
|
+
data = data.toSorted((a, b) => b.publishTime - a.publishTime).slice(0, 10);
|
|
49
49
|
} else {
|
|
50
50
|
const response = await got(link);
|
|
51
51
|
data = response.data.data;
|
|
@@ -42,7 +42,7 @@ async function handler() {
|
|
|
42
42
|
|
|
43
43
|
const data = Object.values(parseJSONP(response.data).items)
|
|
44
44
|
.flat()
|
|
45
|
-
.
|
|
45
|
+
.toSorted((a, b) => new Date(b.date) - new Date(a.date))
|
|
46
46
|
.map((item) => ({
|
|
47
47
|
date: item.date,
|
|
48
48
|
weekDay: item.youbi,
|