diff --git a/lib/v2/routledge/book-series.js b/lib/v2/routledge/book-series.js new file mode 100644 index 000000000..f876a10d7 --- /dev/null +++ b/lib/v2/routledge/book-series.js @@ -0,0 +1,78 @@ +const got = require('@/utils/got'); +const cheerio = require('cheerio'); +const { parseDate } = require('@/utils/parse-date'); +const { art } = require('@/utils/render'); +const { join } = require('path'); + +module.exports = async (ctx) => { + const { bookName, bookId } = ctx.params; + const baseUrl = 'https://www.routledge.com'; + const pageUrl = `${baseUrl}/${bookName}/book-series/${bookId}`; + const { data: response } = await got(pageUrl, { + headers: { + accept: 'text/html, */*; q=0.01', + }, + searchParams: { + publishedFilter: 'alltitles', + pd: 'published,forthcoming', + pg: 1, + pp: 12, + so: 'pub', + view: 'list', + }, + }); + const $ = cheerio.load(response); + + const list = $('.row.book') + .toArray() + .map((item) => { + item = $(item); + const title = item.find('h3 a'); + const description = item.find('p.description'); + const meta = item.find('p.description').prev().text().split('\n'); + return { + title: title.text(), + link: title.attr('href'), + description: description.text(), + pubDate: parseDate(meta.pop().trim(), 'MMMM DD, YYYY'), + author: meta + .map((i) => i.trim()) + .filter((i) => i) + .join(', '), + }; + }); + + const items = await Promise.all( + list.map((item) => + ctx.cache.tryGet(item.link, async () => { + const { data } = await got(item.link); + const $ = cheerio.load(data); + const isbn = $('meta[property="books:isbn"]').attr('content'); + const { data: image } = await got('https://productimages.routledge.com', { + searchParams: { + isbn, + size: 'amazon', + ext: 'jpg', + }, + }); + + const description = $('.sticky-div'); + description.find('button.accordion-button').contents().unwrap(); + description.find('.fa-shopping-cart').parent().parent().remove(); + + item.description = art(join(__dirname, 'templates/description.art'), { + image, + description: description.html(), + }); + return item; + }) + ) + ); + + ctx.state.data = { + title: $('head title').text(), + description: $('head meta[name="description"]').attr('content'), + link: pageUrl, + item: items, + }; +}; diff --git a/lib/v2/routledge/maintainer.js b/lib/v2/routledge/maintainer.js new file mode 100644 index 000000000..7c3f1201e --- /dev/null +++ b/lib/v2/routledge/maintainer.js @@ -0,0 +1,3 @@ +module.exports = { + '/:bookName/book-series/:bookId': ['TonyRL'], +}; diff --git a/lib/v2/routledge/radar.js b/lib/v2/routledge/radar.js new file mode 100644 index 000000000..2eb39553b --- /dev/null +++ b/lib/v2/routledge/radar.js @@ -0,0 +1,13 @@ +module.exports = { + 'routledge.com': { + _name: 'Routledge', + '.': [ + { + title: 'Book Series', + docs: 'https://docs.rsshub.app/routes/journals#routledge', + source: ['/:bookName/book-series/:bookId'], + target: '/routledge/:bookName/book-series/:bookId', + }, + ], + }, +}; diff --git a/lib/v2/routledge/router.js b/lib/v2/routledge/router.js new file mode 100644 index 000000000..51935b6e9 --- /dev/null +++ b/lib/v2/routledge/router.js @@ -0,0 +1,3 @@ +module.exports = (router) => { + router.get('/:bookName/book-series/:bookId', require('./book-series')); +}; diff --git a/lib/v2/routledge/templates/description.art b/lib/v2/routledge/templates/description.art new file mode 100644 index 000000000..d7f9b4d48 --- /dev/null +++ b/lib/v2/routledge/templates/description.art @@ -0,0 +1,7 @@ +{{ if image }} +
+{{ /if }} + +{{ if description }} +{{@ description }} +{{ /if }} diff --git a/website/docs/routes/journal.mdx b/website/docs/routes/journal.mdx index 8ab97e320..efcec0bdf 100644 --- a/website/docs/routes/journal.mdx +++ b/website/docs/routes/journal.mdx @@ -411,6 +411,12 @@ In `https://pubmed.ncbi.nlm.nih.gov/trending/?filter=simsearch1.fha&filter=pubt. +## Routledge {#routledge} + +### Book Series {#routledge-book-series} + + + ## Royal Society of Chemistry {#royal-society-of-chemistry} ### Journal {#royal-society-of-chemistry-journal}