diff --git a/docs/en/journal.md b/docs/en/journal.md index f673cca9f1..9c2d379e7d 100644 --- a/docs/en/journal.md +++ b/docs/en/journal.md @@ -8,10 +8,20 @@ pageClass: routes -| `:category` | Query Type | Route | -| :---------: | :---------------------: | ---------------------------------------- | -| current | Current Issue (default) | [/cell/cell/current](/cell/cell/current) | -| inpress | Articles in press | [/cell/cell/inpress](/cell/cell/inpress) | +| `:category` | Query Type | Route | +| :---------: | :---------------------: | ---------------------------------------------------------- | +| current | Current Issue (default) | [/cell/cell/current](https://rsshub.app/cell/cell/current) | +| inpress | Articles in press | [/cell/cell/inpress](https://rsshub.app/cell/cell/inpress) | + + + +### Cover Story + + + +Subscribe to the cover images of the Cell journals, and get the latest publication updates in time. + +Including 'cell', 'cancer-cell', 'cell-chemical-biology', 'cell-host-microbe', 'cell-metabolism', 'cell-reports', 'cell-reports-physical-science', 'cell-stem-cell', 'cell-systems', 'chem', 'current-biology', 'developmental-cell', 'immunity', 'joule', 'matter', 'molecular-cell', 'neuron', 'one-earth' and 'structure'. @@ -151,7 +161,7 @@ Subscribe to the cover images of the Nature journals, and get the latest publica ### Cover Story - + Subscribe to the cover images of the Science journals, and get the latest publication updates in time. diff --git a/docs/journal.md b/docs/journal.md index 017eea673a..c0cdf5857d 100644 --- a/docs/journal.md +++ b/docs/journal.md @@ -10,10 +10,20 @@ pageClass: routes -| `:category` | 类型说明 | 路由 | -| :---------: | :-----------------: | ---------------------------------------- | -| current | 本期刊物 (默认选项) | [/cell/cell/current](/cell/cell/current) | -| inpress | 在线发表 | [/cell/cell/inpress](/cell/cell/inpress) | +| `:category` | 类型说明 | 路由 | +| :---------: | :-----------------: | ---------------------------------------------------------- | +| current | 本期刊物 (默认选项) | [/cell/cell/current](https://rsshub.app/cell/cell/current) | +| inpress | 在线发表 | [/cell/cell/inpress](https://rsshub.app/cell/cell/inpress) | + + + +### 封面故事 + + + +订阅 Cell 系列杂志的封面图片,并及时获取刊物更新状态。 + +包含了: 'cell'、 'cancer-cell'、 'cell-chemical-biology'、 'cell-host-microbe'、 'cell-metabolism'、 'cell-reports'、 'cell-reports-physical-science'、 'cell-stem-cell'、 'cell-systems'、 'chem'、 'current-biology'、 'developmental-cell'、 'immunity'、 'joule'、 'matter'、 'molecular-cell'、 'neuron'、 'one-earth' 和 'structure'。 @@ -124,7 +134,7 @@ pageClass: routes ### 封面故事 - + 订阅 Science 系列杂志的封面图片,并及时获取刊物更新状态。 @@ -140,9 +150,9 @@ _仅支持 Science 主刊_ -## X-MOL +## X-MOL 平台 -### 平台-期刊 +### 期刊 diff --git a/lib/router.js b/lib/router.js index 2161c6fe4b..a40a2c7320 100644 --- a/lib/router.js +++ b/lib/router.js @@ -1962,8 +1962,8 @@ router.get('/kzfeed/topic/:id', require('./routes/kzfeed/topic')); router.get('/factcheck', require('./routes/tencent/factcheck')); // X-MOL化学资讯平台 -router.get('/x-mol/news/:tag?', require('./routes/journals/x-mol/news.js')); -router.get('/x-mol/paper/:type/:magazine', require('./routes/journals/x-mol/paper')); +router.get('/x-mol/news/:tag?', require('./routes/x-mol/news.js')); +router.get('/x-mol/paper/:type/:magazine', require('./routes/x-mol/paper')); // 知识分子 router.get('/zhishifenzi/news/:type?', require('./routes/zhishifenzi/news')); @@ -1991,19 +1991,20 @@ router.get('/kaggle/discussion/:forumId/:sort?', require('./routes/kaggle/discus router.get('/kaggle/competitions/:category?', require('./routes/kaggle/competitions')); // PubMed Trending -router.get('/pubmed/trending', require('./routes/journals/pubmed/trending')); +router.get('/pubmed/trending', require('./routes/pubmed/trending')); // 领科 (linkresearcher.com) router.get('/linkresearcher/:params', require('./routes/linkresearcher/index')); // eLife [Sci Journal] -router.get('/elife/:tid', require('./routes/journals/elife/index')); +router.get('/elife/:tid', require('./routes/elife/index')); // PNAS [Sci Journal] router.get('/pnas/:topic?', require('./routes/pnas/index')); // cell [Sci Journal] -router.get('/cell/cell/:category', require('./routes/journals/cell/cell/index')); +router.get('/cell/cell/:category', require('./routes/cell/cell/index')); +router.get('/cell/cover', require('./routes/cell/cover')); // nature + nature 子刊 [Sci Journal] router.get('/nature/research/:journal?', require('./routes/nature/research')); diff --git a/lib/routes/cell/cover.js b/lib/routes/cell/cover.js new file mode 100644 index 0000000000..7278843365 --- /dev/null +++ b/lib/routes/cell/cover.js @@ -0,0 +1,109 @@ +// The content is generateed by undocumentated resource of Cell journals + +const got = require('@/utils/got'); +const cheerio = require('cheerio'); +const url = require('url'); + +module.exports = async (ctx) => { + const baseURL = 'https://www.cell.com'; + const journals = [ + 'cell', + 'cancer-cell', + 'cell-chemical-biology', + 'cell-host-microbe', + 'cell-metabolism', + 'cell-reports', + 'cell-reports-physical-science', + 'cell-stem-cell', + 'cell-systems', + 'chem', + 'current-biology', + 'developmental-cell', + 'immunity', + 'joule', + 'matter', + 'molecular-cell', + 'neuron', + 'one-earth', + 'structure', + ]; + const out = await Promise.all( + journals.map(async (journal) => { + // get the lastest volumn and issue id + const pageURL = `${baseURL}/${journal}/current`; + + const pageMeta = await ctx.cache.tryGet( + pageURL, + async () => { + const cookieData = await got + .extend({ + followRedirect: false, + }) + .get(`https://secure.jbs.elsevierhealth.com/action/getSharedSiteSession?redirect=${encodeURI(pageURL)}`) + .then((response) => { + const cookieString = response.headers['set-cookie'].join(' '); + const server = cookieString.match(/SERVER=(\S+);/)[1]; + const jsession = cookieString.match(/JSESSIONID=(\S+);/)[1]; + return `SERVER=${server}; JSESSIONID=${jsession};`; + }); + + const pageResponse = await got.get(pageURL, { + headers: { + cookie: cookieData, + }, + followRedirect: false, + }); + + const $ = cheerio.load(pageResponse.data); + const coverImg = url.resolve('https://', $('#fullCover > img').attr('src')); + const coverDescription = $('#fullCover > img').attr('alt'); + const issueDate = $('h1.toc-header__issue-date').text(); + const issueNum = $('.toc-header__details span') + .contents() + .map(function() { + return this.type === 'text' ? $(this).text() : ''; + }) + .get() + .slice(0, 2) + .join(', '); + const issueName = + $('meta[name="name"]') + .attr('content') + .replace('Issue: ', '') || `Cell ...`; + const m = $('meta[name="pbContext"]') + .attr('content') + .match(/issue:issue:pii\\:(S\d{4})(\d{4})(\d{2})(X\d{4})(\w)/); + const issueID = `${m[1]}-${m[2]}(${m[3]})${m[4]}-${m[5]}`; + return { + coverImg: coverImg, + coverDescription: coverDescription, + issueName: issueName, + issueDate: issueDate, + issueNum: issueNum, + issueID: issueID, + }; + }, + 12 * 60 * 60 // set cache timeout to 12h + ); + const address = `${baseURL}/${journal}/issue?pii=${pageMeta.issueID}`; + const contents = `
${pageMeta.coverDescription}
`; + + const single = { + title: `${pageMeta.issueName} | ${pageMeta.issueNum} (${pageMeta.issueDate})`, + author: '@yech1990', + description: contents, + link: address, + guid: address, + pubDate: new Date(pageMeta.issueDate).toUTCString(), + }; + ctx.cache.set(address, JSON.stringify(single)); + return Promise.resolve(single); + }) + ); + ctx.state.data = { + title: 'Cell Covers Story', + description: 'Find out the cover story of some Cell journals.', + link: baseURL, + item: out, + }; +}; diff --git a/lib/routes/journals/cell/cell/index.js b/lib/routes/journals/cell/cell/index.js deleted file mode 100644 index 4b4c7042ca..0000000000 --- a/lib/routes/journals/cell/cell/index.js +++ /dev/null @@ -1,123 +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(function(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 Promise.resolve(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(function(i, el) { - return $(el).text(); - }) - .get() - .join('; '); - const sectionContents = ` -
- ${section} -
-

[${keywords}]

-
- `; - // graphical content - const brief = $('description').text(); - const graphical = itemCapture('div.abstract.graphical') - .find('img') - .attr('src'); - let graphicalContents = ''; - if (graphical !== '') { - graphicalContents = ` -
-

Graphical Abstract

-
-
- -
-
- ${brief} -
`; - } - // highlight content - const highlight = itemCapture('div.abstract.author-highlights dl').html(); - let highlightContents = ''; - if (highlight !== '') { - highlightContents = ` -
-

Highlights

- ${highlight} -
`; - } - // summary content - const summary = itemCapture('div.abstract.author p').html(); - let summaryContents = ''; - if (summary !== '') { - summaryContents = ` -
-

Summary

- ${summary} -
`; - } - const contents = sectionContents + graphicalContents + highlightContents + summaryContents; - - const single = { - title: title, - author: author, - description: contents, - link: address, - guid: address, - doi: $('dc\\:identifier').text(), - pubDate: pubDate, - }; - ctx.cache.set(address, JSON.stringify(single)); - return Promise.resolve(single); - }) - ); - ctx.state.data = { - title: `Cell | ${categoryTitle}`, - description: `Cell, a research journal`, - link: baseURL, - item: out, - }; -}; diff --git a/lib/routes/journals/elife/index.js b/lib/routes/journals/elife/index.js deleted file mode 100644 index f5b79e6489..0000000000 --- a/lib/routes/journals/elife/index.js +++ /dev/null @@ -1,69 +0,0 @@ -const cheerio = require('cheerio'); -const got = require('@/utils/got'); - -module.exports = async (ctx) => { - const baseUrl = `https://elifesciences.org`; - const tid = ctx.params.tid; - - let url = baseUrl; - if (tid !== 'latest') { - url = `${baseUrl}/subjects/${ctx.params.tid}`; - } - - const res = await got.get(url); - const $ = cheerio.load(res.data); - $('.grid-secondary-column').remove(); - - let topic = 'latest'; - if (tid !== 'latest') { - topic = $('h1.content-header__title.content-header__title--xx-short').text(); - } - - const list = $('li.listing-list__item').get(); - - const out = await Promise.all( - list.map(async (item) => { - const $ = cheerio.load(item); - const title = $('a.teaser__header_text_link').text(); - const partial = $('a.teaser__header_text_link').attr('href'); - const address = `${baseUrl}${partial}`; - const time = $('time').text(); - const description = $('div.teaser__body').text(); - const author = $('div.teaser__secondary_info') - .text() - .trim(); - - const cache = await ctx.cache.get(address); - if (cache) { - return Promise.resolve(JSON.parse(cache)); - } - const res = await got.get(address); - const capture = cheerio.load(res.data); - - const abstract = capture('#abstract .article-section__body').html(); - let contents; - if (description !== '') { - contents = `${description}

Abstract

${abstract}`; - } else { - contents = `
Abstract
${abstract}`; - } - - const single = { - title, - author: author, - description: contents, - link: address, - guid: address, - doi: capture('meta[name="dc.identifier"]')[0].attribs.content, - pubDate: new Date(time).toUTCString(), - }; - ctx.cache.set(address, JSON.stringify(single)); - return Promise.resolve(single); - }) - ); - ctx.state.data = { - title: `eLife | ${topic}`, - link: url, - item: out, - }; -}; diff --git a/lib/routes/journals/nature/highlight.js b/lib/routes/journals/nature/highlight.js deleted file mode 100644 index 35c5335aa3..0000000000 --- a/lib/routes/journals/nature/highlight.js +++ /dev/null @@ -1,60 +0,0 @@ -const cheerio = require('cheerio'); -const got = require('@/utils/got'); - -module.exports = async (ctx) => { - const base = `https://www.nature.com`; - const url = `${base}/nature/articles?type=research-highlight`; - - const res = await got.get(url); - const $ = cheerio.load(res.data); - const list = $('.border-bottom-1.pb20').get(); - - const out = await Promise.all( - list.slice(0, 2).map(async (item) => { - const $ = cheerio.load(item); - const title = $('h3 > a').text(); - const partial = $('h3 > a').attr('href'); - const address = `${base}${partial}`; - const time = $('time').text(); - let author; - if ($('.js-list-authors-3 li').length > 3) { - author = - $('.js-list-authors-3 li') - .slice(0, 1) - .text() + ' et al.'; - } else { - author = $('.js-list-authors-3 li').text(); - } - const cache = await ctx.cache.get(address); - if (cache) { - return Promise.resolve(JSON.parse(cache)); - } - const res = await got.get(address); - const capture = cheerio.load(res.data); - let figure = capture('figure .figure--bleed').html(); - if (figure === null) { - figure = ''; - } - let contents = capture('.article-item--open .article-item__body').html(); - if (contents === null) { - contents = ''; - } - const single = { - title, - author: author, - description: figure + contents, - link: address, - guid: address, - pubDate: new Date(time).toUTCString(), - }; - ctx.cache.set(address, JSON.stringify(single)); - return Promise.resolve(single); - }) - ); - ctx.state.data = { - title: `Nature | Research Highlight`, - description: `Nature, a nature research journal`, - link: url, - item: out, - }; -}; diff --git a/lib/routes/journals/nature/news-and-comment.js b/lib/routes/journals/nature/news-and-comment.js deleted file mode 100644 index e08c1eebd2..0000000000 --- a/lib/routes/journals/nature/news-and-comment.js +++ /dev/null @@ -1,80 +0,0 @@ -// example usage: `/nature/news-and-comment/ng` -// The journals from NPG are run by different group of people, -// and the website of may not be consitent for all the journals -// -// This router has **just** been tested in: -// nbt: Nature Biotechnology -// neuro: Nature Neuroscience -// ng: Nature Genetics -// ni: Nature Immunology -// nmeth: Nature Method -// nchem: Nature Chemistry -// nmat: Nature Materials -// natmachintell: Nature Machine Intelligence - -const cheerio = require('cheerio'); -const got = require('@/utils/got'); - -module.exports = async (ctx) => { - const baseURL = `https://www.nature.com`; - - const journal = ctx.params.journal; - const pageURL = `${baseURL}/${journal}/news-and-comment`; - - const pageResponse = await got.get(pageURL); - const pageCapture = cheerio.load(pageResponse.data); - - const pageDescription = pageCapture('meta[name="description"]').attr('content') || `Nature, a nature research journal`; - const pageTitleName = pageCapture('meta[name="WT.cg_n"]').attr('content') || `Nature (${journal})`; - const pageTitleSub = pageCapture('meta[name="WT.cg_s"]').attr('content') || 'News & Comment'; - - const list = pageCapture('.border-bottom-1.pb20').get(); - - const items = await Promise.all( - list.map(async (el) => { - const $ = cheerio.load(el); - const title = $('h3 > a').text(); - const partial = $('h3 > a').attr('href'); - const address = `${baseURL}${partial}`; - const brief = $('.hide-overflow.inline').text(); - const time = $('time').text(); - const author = $('.js-list-authors-3 li').text(); - const articleType = $('p > span').attr('data-class'); - const headerContents = ` -
-

- ${articleType} - | - ${author} -

-
- `; - let briefContents = ''; - if (brief !== '') { - briefContents = ` -
-

Brief

-

${brief}

-
- `; - } - const contents = headerContents + briefContents; - - const item = { - title, - author: author, - description: contents, - link: address, - guid: address, - pubDate: new Date(time).toUTCString(), - }; - return Promise.resolve(item); - }) - ); - ctx.state.data = { - title: `${pageTitleName} | ${pageTitleSub}`, - description: pageDescription, - link: pageURL, - item: items, - }; -}; diff --git a/lib/routes/journals/nature/news.js b/lib/routes/journals/nature/news.js deleted file mode 100644 index 69ece554f0..0000000000 --- a/lib/routes/journals/nature/news.js +++ /dev/null @@ -1,54 +0,0 @@ -const cheerio = require('cheerio'); -const got = require('@/utils/got'); - -module.exports = async (ctx) => { - const base = `https://www.nature.com`; - const url = `${base}/nature/articles?type=news`; - - const res = await got.get(url); - const $ = cheerio.load(res.data); - const list = $('.border-bottom-1.pb20').get(); - - const out = await Promise.all( - list.map(async (item) => { - const $ = cheerio.load(item); - const title = $('h3 > a').text(); - const partial = $('h3 > a').attr('href'); - const address = `${base}${partial}`; - const time = $('time').text(); - let author; - if ($('.js-list-authors-3 li').length > 3) { - author = - $('.js-list-authors-3 li') - .slice(0, 1) - .text() + ' et al.'; - } else { - author = $('.js-list-authors-3 li').text(); - } - const cache = await ctx.cache.get(address); - if (cache) { - return Promise.resolve(JSON.parse(cache)); - } - const res = await got.get(address); - const capture = cheerio.load(res.data); - const contents = capture('.content .article__body').html(); - - const single = { - title, - author: author, - description: contents, - link: address, - guid: address, - pubDate: new Date(time).toUTCString(), - }; - ctx.cache.set(address, JSON.stringify(single)); - return Promise.resolve(single); - }) - ); - ctx.state.data = { - title: `Nature | Latest News`, - description: `Nature, a nature research journal`, - link: url, - item: out, - }; -}; diff --git a/lib/routes/journals/nature/research.js b/lib/routes/journals/nature/research.js deleted file mode 100644 index e8595e84e8..0000000000 --- a/lib/routes/journals/nature/research.js +++ /dev/null @@ -1,187 +0,0 @@ -// example usage: `/nature/research/ng` -// The journals from NPG are run by different group of people, -// and the website of may not be consitent for all the journals -// -// This router has **just** been tested in: -// nature: Nature -// nbt: Nature Biotechnology -// neuro: Nature Neuroscience -// ng: Nature Genetics -// ni: Nature Immunology -// nmeth: Nature Method -// nchem: Nature Chemistry -// nmat: Nature Materials -// natmachintell: Nature Machine Intelligence - -const cheerio = require('cheerio'); -const got = require('@/utils/got'); - -module.exports = async (ctx) => { - const baseURL = `https://www.nature.com`; - - const journal = ctx.params.journal || 'nature'; - const pageURL = `${baseURL}/${journal}/research`; - - const pageResponse = await got.get(pageURL); - const pageCapture = cheerio.load(pageResponse.data); - - const pageDescription = pageCapture('meta[name="description"]').attr('content') || `Nature, a nature research journal`; - const pageTitleName = pageCapture('meta[name="WT.cg_n"]').attr('content') || `Nature (${journal})`; - const pageTitleSub = pageCapture('meta[name="WT.cg_s"]').attr('content') || 'Latest Research'; - - const list = pageCapture('.border-bottom-1.pb20').get(); - - const items = await Promise.all( - list.map(async (el) => { - const $ = cheerio.load(el); - const title = $('h3 > a').text(); - const partial = $('h3 > a').attr('href'); - const address = `${baseURL}${partial}`; - const brief = $('.hide-overflow.inline').text(); - const time = $('time').text(); - let author; - if ($('.js-list-authors-3 li').length > 3) { - author = - $('.js-list-authors-3 li') - .slice(0, 1) - .text() + ' et al.'; - } else { - author = $('.js-list-authors-3 li').text(); - } - const cache = await ctx.cache.get(address); - if (cache) { - return Promise.resolve(JSON.parse(cache)); - } - const itemResponse = await got.get(address); - const itemCapture = cheerio.load(itemResponse.data); - - // Brief [obtain from entry of each item] - let briefContents = ''; - if (brief !== '') { - briefContents = ` -
-

Brief

-

${brief}

-
- `; - } - // Abstract [obtain form address of each page] - const abs = itemCapture('div#Abs1-content.c-article-section__content > p').html(); - let absContents = ''; - if (abs !== null) { - absContents = ` -
-

Abstract

-

${abs}

-
- `; - } - // Info [obtain form address of each page] - const subject = itemCapture('li.c-article-subject-list__subject > a') - .map(function() { - const link = $(this).attr('href'); - const name = $(this).text(); - if (name !== '') { - return `
  • ${name}
  • `; - } else { - return ''; - } - }) - .get() - .join(''); - const subjectContents = subject !== '' ? `
      ${subject}
    ` : ''; - const citation = itemCapture('p.c-bibliographic-information__download-citation > a').attr('href'); - const citationContents = citation !== undefined ? `Download citation` : ''; - const doi = itemCapture('meta[name="DOI"]').attr('content'); - const doiContents = doi !== undefined ? `DOI: ${doi}` : ''; - const pdf = itemCapture('meta[name="citation_pdf_url"]').attr('content'); - const pdfContents = pdf !== undefined ? `Offical PDF` : ''; - const linkContents = '
      ' + [citationContents, doiContents, pdfContents].filter((x) => x !== '').map((x) => `
    • ${x}
    • `) + '
    '; - const infoContents = ` -
    -

    About this article

    -

    Subjects:

    - ${subjectContents} -
    -

    Links:

    - ${linkContents} -
    - `; - // Add style - const contentStyle = ` - - `; - const contents = briefContents + absContents + infoContents + contentStyle; - - const item = { - title, - author: author, - description: contents, - link: address, - guid: address, - pubDate: new Date(time).toUTCString(), - }; - ctx.cache.set(address, JSON.stringify(item)); - return Promise.resolve(item); - }) - ); - ctx.state.data = { - title: `${pageTitleName} | ${pageTitleSub}`, - description: pageDescription, - link: pageURL, - item: items, - }; -}; diff --git a/lib/routes/journals/pnas/index.js b/lib/routes/journals/pnas/index.js deleted file mode 100644 index cddb3ae781..0000000000 --- a/lib/routes/journals/pnas/index.js +++ /dev/null @@ -1,66 +0,0 @@ -const cheerio = require('cheerio'); -const got = require('@/utils/got'); - -module.exports = async (ctx) => { - const baseUrl = `https://www.pnas.org`; - - const tid = ctx.params.tid; - - let url = `${baseUrl}/content/early/recent`; - if (tid !== 'latest') { - url = `${baseUrl}/content/by/section/${ctx.params.tid}`; - } else { - ctx.params.tid = 'Latest Research'; - } - - const res = await got.get(url); - const $ = cheerio.load(res.data); - const list = $('.highwire-citation-pnas-list-complete').get(); - - const out = await Promise.all( - list.map(async (item) => { - const $ = cheerio.load(item); - const title = $('.highwire-cite-title').text(); - const partial = $('.highwire-cite-linked-title').attr('href'); - const address = `${baseUrl}${partial}`; - let author; - if ($('.highwire-citation-authors span').length > 3) { - author = $('.highwire-citation-author.first').text() + ' et al.'; - } else { - author = $('.highwire-citation-authors span').text(); - } - const cache = await ctx.cache.get(address); - if (cache) { - return Promise.resolve(JSON.parse(cache)); - } - const res = await got.get(address); - const capture = cheerio.load(res.data); - - const significance = capture('.executive-summary').html(); - const abstract = capture('.section.abstract').html(); - let contents; - if (abstract !== null) { - contents = significance + abstract; - } else { - contents = significance; - } - - const single = { - title, - author: author, - description: contents, - link: address, - guid: address, - doi: capture('meta[name="DC.Identifier"]')[0].attribs.content, - pubDate: new Date(capture('meta[name="DC.Date"]')[0].attribs.content).toUTCString(), - }; - ctx.cache.set(address, JSON.stringify(single)); - return Promise.resolve(single); - }) - ); - ctx.state.data = { - title: `PNAS | ${ctx.params.tid}`, - link: url, - item: out, - }; -}; diff --git a/lib/routes/journals/pubmed/trending.js b/lib/routes/journals/pubmed/trending.js deleted file mode 100644 index e777af3165..0000000000 --- a/lib/routes/journals/pubmed/trending.js +++ /dev/null @@ -1,73 +0,0 @@ -const got = require('@/utils/got'); -const cheerio = require('cheerio'); -const url = require('url'); -const date = require('@/utils/date'); - -const base = 'https://www.ncbi.nlm.nih.gov'; - -module.exports = async (ctx) => { - const link = `${base}/pubmed/trending/`; - const response = await got.get(encodeURI(link)); - const pageCapture = cheerio.load(response.data); - - const list = pageCapture('.content div.rprt > div.rslt').get(); - const out = await Promise.all( - list.map(async (elem) => { - const $ = cheerio.load(elem); - const title = $('p > a').text(); - const partial = $('p > a').attr('href'); - const address = url.resolve(base, partial); - const author = $('div.supp > p.desc').text(); - const pubDate = date( - $('div.supp > p.details') - .text() - .split('. ')[1] - ); - - const item = { - title, - author, - pubDate, - link: encodeURI(address), - }; - - const value = await ctx.cache.get(address); - if (value) { - item.description = value; - } else { - const detail = await got.get(item.link); - const detailCapture = cheerio.load(detail.data); - - let authorContents = ''; - if (author !== '') { - authorContents = ` -
    - ${author} -
    - `; - } - const abs = detailCapture('div.abstr > div').html(); - let absContents = ''; - if (abs !== null) { - absContents = ` -
    -

    Abstract

    -

    ${abs}

    -
    - `; - } - item.description = authorContents + absContents; - ctx.cache.set(address, item.description); - } - - return Promise.resolve(item); - }) - ); - - ctx.state.data = { - title: 'PubMed | Trending Articles', - description: 'Trending Articles from PubMed Website', - link: link, - item: out, - }; -}; diff --git a/lib/routes/journals/sciencemag/current.js b/lib/routes/journals/sciencemag/current.js deleted file mode 100644 index b617607544..0000000000 --- a/lib/routes/journals/sciencemag/current.js +++ /dev/null @@ -1,125 +0,0 @@ -// journals form AAAS publishing group -// -// science: Science -// advances: Science Advances -// immunology: Science Immunology -// robotics: Science Robotics -// stke: Science Signaling -// stm: Science Translational Medicine - -const cheerio = require('cheerio'); -const got = require('@/utils/got'); - -module.exports = async (ctx) => { - const journal = ctx.params.journal || 'science'; - const baseURL = `https://${journal}.sciencemag.org`; - - const pageURL = baseURL; - const pageResponse = await got.get(pageURL); - const pageCapture = cheerio.load(pageResponse.data); - - const pageTitleName = pageCapture('head > title').text() || `Science (${journal})`; - - // just select paper relative sections - const sectionList = ['research-articles', 'review', 'reports']; - - const list = [].concat.apply( - [], - sectionList.map((section) => { - const sectionContent = pageCapture(`ul > li.issue-toc-section.issue-toc-section-${section}`).html(); - if (sectionContent !== null) { - const sec = cheerio.load(sectionContent); - const sectionName = sec('h2').text(); - const sectionList = sec('ul > li > div > div > article > div') - .append(`
    ${sectionName}
    `) - .get(); - return sectionList; - } - return []; - }) - ); - - const out = await Promise.all( - list.map(async (item) => { - const $ = cheerio.load(item); - - const title = $('h3').text(); - const partial = $('h3 > a').attr('href'); - const address = `${baseURL}${partial}`; - const section = $('div .toc-section-type').text(); - - let author; - const authorList = $('span.highwire-citation-authors > span.highwire-citation-author') - .map((_, el) => $(el).text()) - .get(); - if (authorList.length > 5) { - author = authorList.slice(0, 5).join(', ') + ' et al.'; - } else { - author = authorList.join(', '); - } - - const time = new Date($('p.highwire-cite-metadata > time').text()).toUTCString(); - - const cache = await ctx.cache.get(address); - if (cache) { - return Promise.resolve(JSON.parse(cache)); - } - - // contents - // section content - let sectionContents = ''; - if (section !== '') { - sectionContents = ` -
    - ${section} -
    - `; - } - // brief content - const brief = $('div.highwire-cite-snippet > div > div > p').text(); - let briefContents = ''; - if (brief !== '') { - briefContents = ` -
    -

    ${brief}

    -
    - `; - } - const itemPage = await got.get(address); - const itemCapture = cheerio.load(itemPage.data); - - const abs = itemCapture('div > div.article > div.section') - .map((_, el) => $(el).html()) - .get() - .join('
    '); - - // abs content - let absContents = ''; - if (abs !== null) { - absContents = ` -
    - ${abs} -
    - `; - } - const contents = sectionContents + briefContents + absContents; - - const single = { - title: title, - author: author, - description: contents, - link: address, - guid: address, - pubDate: time, - }; - ctx.cache.set(address, JSON.stringify(single)); - return Promise.resolve(single); - }) - ); - ctx.state.data = { - title: `${pageTitleName} | Current Issue`, - description: `Current Issue of ${pageTitleName}`, - link: baseURL, - item: out, - }; -}; diff --git a/lib/routes/journals/sciencemag/early.js b/lib/routes/journals/sciencemag/early.js deleted file mode 100644 index 12524a5c28..0000000000 --- a/lib/routes/journals/sciencemag/early.js +++ /dev/null @@ -1,101 +0,0 @@ -// only support Science journal - -const cheerio = require('cheerio'); -const got = require('@/utils/got'); - -module.exports = async (ctx) => { - const base = `https://science.sciencemag.org/content/early/recent`; - - const res = await got.get(base); - const pageCapture = cheerio.load(res.data); - - const list = pageCapture('ul > li > div > article > div').get(); - - const out = await Promise.all( - list.map(async (item) => { - const $ = cheerio.load(item); - - const title = $('h3').text(); - const partial = $('h3 > a').attr('href'); - const address = `${base}${partial}`; - - let author; - const authorList = $('span.highwire-citation-authors > span.highwire-citation-author') - .map(function(i, el) { - return $(el).text(); - }) - .get(); - if (authorList.length > 5) { - author = authorList.slice(0, 5).join(', ') + ' et al.'; - } else { - author = authorList.join(', '); - } - - const time = new Date($('p.highwire-cite-metadata > time').text()).toUTCString(); - - const cache = await ctx.cache.get(address); - if (cache) { - return Promise.resolve(JSON.parse(cache)); - } - - // contents - // brief content - const brief = $('div.highwire-cite-snippet > div > div > p').text(); - let briefContents = ''; - if (brief !== '') { - briefContents = ` -
    -

    ${brief}

    -
    - `; - } - - const itemPage = await got.get(address); - const itemCapture = cheerio.load(itemPage.data); - // section content - const section = itemCapture('header > div.overline').text(); - let sectionContents = ''; - if (section !== '') { - sectionContents = ` -
    - ${section} - [Published Online] -
    - `; - } - // abs content - const abs = itemCapture('div > div.abstract-view > div.section') - .map(function(i, el) { - return $(el).html(); - }) - .get() - .join('
    '); - let absContents = ''; - if (abs !== null) { - absContents = ` -
    - ${abs} -
    - `; - } - const contents = sectionContents + briefContents + absContents; - - const single = { - title: title, - author: author, - description: contents, - link: address, - guid: address, - pubDate: time, - }; - ctx.cache.set(address, JSON.stringify(single)); - return Promise.resolve(single); - }) - ); - ctx.state.data = { - title: `Science | First Release`, - description: `Science, a research journal. For papers that published online.`, - link: base, - item: out, - }; -}; diff --git a/lib/routes/journals/x-mol/news.js b/lib/routes/journals/x-mol/news.js deleted file mode 100644 index 8e3b1799f4..0000000000 --- a/lib/routes/journals/x-mol/news.js +++ /dev/null @@ -1,58 +0,0 @@ -const got = require('@/utils/got'); -const cheerio = require('cheerio'); -const utils = require('./utils'); - -module.exports = async (ctx) => { - const tag = ctx.params.tag; - const path = tag ? `news/tag/${tag}` : 'news/index'; - const response = await got(path, { - method: 'GET', - prefixUrl: utils.host, - }); - const data = response.data; - const $ = cheerio.load(data); - - const title = $('title').text(); - const description = $('meta[name="description"]').attr('content'); - const newsitem = $('.newsitem'); - - const item = newsitem - .map((index, element) => { - const title = $(element) - .find('h3') - .find('a') - .text(); - const a = $(element) - .find('p') - .find('a'); - const link = utils.host + a.attr('href'); - const image = $(element) - .find('img') - .attr('src'); - const description = utils.setDesc(image, a.text()); - const span = $(element).find('.space-right-m30'); - const author = span - .text() - .replace('来源:', '') - .trim(); - const date = utils.getDate(span.next().text()); - const pubDate = utils.transDate(date); - - const single = { - title: title, - link: link, - description: description, - author: author, - pubDate: pubDate, - }; - return single; - }) - .get(); - - ctx.state.data = { - title: title, - link: response.url, - description: description, - item: item, - }; -}; diff --git a/lib/routes/journals/x-mol/paper.js b/lib/routes/journals/x-mol/paper.js deleted file mode 100644 index cf4f25570a..0000000000 --- a/lib/routes/journals/x-mol/paper.js +++ /dev/null @@ -1,79 +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 magazine = ctx.params.magazine; - const path = `paper/${type}/${magazine}`; - const response = await got(path, { - method: 'GET', - prefixUrl: utils.host, - headers: { - Cookie: 'closeFloatWindow=true; journalIndexViewType=list; journalSort=publishDate', - }, - }); - const data = response.data; - const $ = cheerio.load(data); - - const title = $('title').text(); - const description = $('meta[name="description"]').attr('content'); - const newsitem = $('.magazine-text'); - - const item = await Promise.all( - newsitem - .map(async (index, element) => { - const news = $(element); - - const a = news.find('.magazine-text-title').find('a'); - const title = a.text(); - const link = utils.host + a.attr('href'); - - const picId = news.find('.magazine-pic').attr('id'); - const noPic = utils.host + '/css/images/nothesispic.jpg'; - let imageUrl = noPic; - if (picId) { - const imageId = picId.substring(9); - const getLink = utils.host + '/attachment/getImgUrl'; - imageUrl = - (await ctx.cache.tryGet(getLink, async () => { - const result = await got.get(getLink, { - searchParams: queryString.stringify({ - attachmentId: imageId, - }), - }); - return result.data; - })) || noPic; - } - const image = imageUrl; - const text = $(element) - .find('.magazine-description') - .text(); - const description = utils.setDesc(image, text); - - const span = news.find('.magazine-text-atten'); - const arr = span.map((index, element) => $(element).text()).get(); - const author = arr[1]; - const date = utils.getDate(arr[0]); - const pubDate = utils.transDate(date); - - const single = { - title: title, - link: link, - description: description, - author: author, - pubDate: pubDate, - }; - return Promise.resolve(single); - }) - .get() - ); - - ctx.state.data = { - title: title, - link: response.url, - description: description, - item: item, - }; -}; diff --git a/lib/routes/journals/x-mol/utils.js b/lib/routes/journals/x-mol/utils.js deleted file mode 100644 index dbe61a473b..0000000000 --- a/lib/routes/journals/x-mol/utils.js +++ /dev/null @@ -1,16 +0,0 @@ -const XmolUtils = { - host: 'https://www.x-mol.com', - transDate: (date) => new Date(`${date} GMT+0800`).toUTCString(), - getDate: (text) => { - const reg = /[1-9]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])/; - if (typeof text === 'string') { - const arr = text.match(reg); - return arr && text.match(reg)[0]; - } else { - return null; - } - }, - setDesc: (image, text) => `

    ${text}

    `, -}; - -module.exports = XmolUtils;