diff --git a/assets/radar-rules.js b/assets/radar-rules.js index e3fe1f192c..4f2695f0b7 100644 --- a/assets/radar-rules.js +++ b/assets/radar-rules.js @@ -1124,6 +1124,14 @@ script: "({id: document.querySelector('html').innerHTML.match(/photos.app.goo.gl\\/(.*?)\"/)[1]})", }, ], + sites: [ + { + title: 'Sites', + docs: 'https://docs.rsshub.app/blog.html#google-sites', + source: ['/site/:id/*', '/site/:id'], + target: '/google/sites/:id', + }, + ], }, 'javlibrary.com': { _name: 'javlibrary', diff --git a/docs/blog.md b/docs/blog.md index 69b916072c..4b8e692169 100644 --- a/docs/blog.md +++ b/docs/blog.md @@ -10,6 +10,12 @@ pageClass: routes +## Google Sites + +### 文章更新 + + + ## Hexo ### Next 主题博客 diff --git a/docs/en/blog.md b/docs/en/blog.md index 3315372171..a7d4ab0446 100644 --- a/docs/en/blog.md +++ b/docs/en/blog.md @@ -10,6 +10,12 @@ pageClass: routes +## Google Sites + +### Articles + + + ## Hexo Blog ### Blog using Next theme diff --git a/lib/router.js b/lib/router.js index 9bf80ec23e..4ae1ffbd58 100644 --- a/lib/router.js +++ b/lib/router.js @@ -476,6 +476,7 @@ router.get('/google/citations/:id', require('./routes/google/citations')); router.get('/google/scholar/:query', require('./routes/google/scholar')); router.get('/google/doodles/:language?', require('./routes/google/doodles')); router.get('/google/album/:id', require('./routes/google/album')); +router.get('/google/sites/:id', require('./routes/google/sites')); // Awesome Pigtals router.get('/pigtails', require('./routes/pigtails')); diff --git a/lib/routes/google/sites.js b/lib/routes/google/sites.js new file mode 100644 index 0000000000..252d8d764e --- /dev/null +++ b/lib/routes/google/sites.js @@ -0,0 +1,75 @@ +const got = require('@/utils/got'); +const cheerio = require('cheerio'); + +const base = 'https://sites.google.com/'; + +module.exports = async (ctx) => { + const id = ctx.params.id; + + const init_url = `https://sites.google.com/site/${id}/system/app/pages/sitemap/list?offset=0`; + const init_response = await got.get(init_url); + + const test_pages_count = init_response.data.match(/'sites-pagination-next-link-top', (\d+),/); + if (!test_pages_count) { + throw 'Site Not Found'; + } + const pages_count = parseInt(test_pages_count[1]); + + const url = pages_count > 20 ? `https://sites.google.com/site/${id}/system/app/pages/sitemap/list?offset=${pages_count - 20}` : init_url; + const response = url === init_url ? init_response : await got.get(url); + + const $ = cheerio.load(response.data); + + const site_name = $('a#sites-chrome-userheader-title').text(); + const list = $('.sites-table > tbody > tr').get(); + + const parseContent = async (htmlString) => { + const $ = cheerio.load(htmlString); + + const content = $('#sites-canvas-main-content'); + + return { + description: content.html(), + }; + }; + + const out = await Promise.all( + list.map(async (item, index) => { + const $ = cheerio.load(item); + + const title = $('a'); + const path = title.attr('href'); + const link = base + path; + const time = new Date(); + time.setMinutes(time.getMinutes() - pages_count + index); + + const cache = await ctx.cache.get(link); + if (cache) { + return Promise.resolve(JSON.parse(cache)); + } + + const rssitem = { + title: title.text().trim(), + link: link, + pubDate: time, + author: site_name, + }; + + try { + const response = await got.get(link); + const result = await parseContent(response.data); + rssitem.description = result.description; + } catch (err) { + return Promise.resolve(''); + } + ctx.cache.set(link, JSON.stringify(rssitem)); + return Promise.resolve(rssitem); + }) + ); + + ctx.state.data = { + title: `${site_name} - Google Sites`, + link: url, + item: out.filter((item) => item !== ''), + }; +};