diff --git a/.gitignore b/.gitignore index 96605804b9..e274d3a3b3 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ config/config.js yarn-error.log tmp newrelic_agent.log +*.swp diff --git a/docs/README.md b/docs/README.md index d0e4e50122..785b5355e7 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1580,7 +1580,7 @@ IATA 国际航空运输协会机场代码, 参见[维基百科 国际航空运 | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | | 0 | 111 | 109 | 110 | 113 | 114 | 115 | 112 | 116 | -## 网络小说 +## 小说·文学 ### 笔趣阁 @@ -1619,6 +1619,14 @@ IATA 国际航空运输协会机场代码, 参见[维基百科 国际航空运 +### 青空文庫 + + + +书籍网站每日一更. 信息更新时间为书籍最初出版时间, 排序可能不符合网络发表时间, 请认准未读消息. + + + ## 中国驻外使领馆 ### 大使馆 diff --git a/router.js b/router.js index 279bbbfb55..f5fae2bc44 100644 --- a/router.js +++ b/router.js @@ -656,6 +656,9 @@ router.get('/laosiji/feed', require('./routes/laosiji/feed')); // 99% Invisible router.get('/99percentinvisible/transcript', require('./routes/99percentinvisible/transcript')); +// 青空文庫 +router.get('/aozora/newbook/:count?', require('./routes/aozora/newbook')); + // Hermes UK router.get('/parcel/hermesuk/:tracking', require('./routes/parcel/hermesuk')); diff --git a/routes/aozora/newbook.js b/routes/aozora/newbook.js new file mode 100644 index 0000000000..039a4ba77d --- /dev/null +++ b/routes/aozora/newbook.js @@ -0,0 +1,103 @@ +// Warning: The author knows nothing about javascript! + +// params: +// count? : count of new-books + +const axios = require('../../utils/axios'); // get web content +const cheerio = require('cheerio'); // html parser +const he = require('he'); + +const base_url = 'https://www.aozora.gr.jp/index_pages/'; +module.exports = async (ctx) => { + // get the update list + const response = await axios({ + method: 'get', + url: base_url + 'whatsnew1.html', + }); + const data = response.data; // content is html format + + const $ = cheerio.load(data); + const list = $('table.list tr'); + + // get how many new-books. amount in this page is 50 + let count = parseInt(ctx.params.count); + if (Number.isNaN(count) || count < 1) { + count = 10; // default count of new-book list + } else if (count > 50) { + count = 50; + } + + // parse book urls + const detail_urls = []; + for (let i = 1; i < count + 1; ++i) { + // i = 1: first tr is table title, ignore + const link = + base_url + + $(list[i]) + .find('a') + .attr('href'); + detail_urls.push(link); + } + + // get book-cards + const responses = await Promise.all(detail_urls.map((url) => axios(url))); + const cards = responses.map(({ data }) => data); + + // get real data to feed + const book_list = []; + for (let i = 0; i < count; ++i) { + const $ = cheerio.load(cards[i]); + const link = $('meta[property="og:url"]').attr('content'); + const link_dir = link.replace(/\/[^/]*$/g, '/'); + const title_info = $('table[summary="タイトルデータ"] > tbody > tr'); + let author = ''; + let title = ''; + let title_sub = ''; + for (let j = 0; j < title_info.length; ++j) { + const tmp = he.decode($(title_info[j]).html()); // should convert from escaped to unicode + if (tmp.includes('作品名:')) { + title = $(title_info[j]) + .find('td:nth-child(2)') + .text(); + } + if (tmp.includes('副題:')) { + title_sub = $(title_info[j]) + .find('td:nth-child(2)') + .text(); + } + if (tmp.includes('著者名:')) { + author = $(title_info[j]) + .find('td:nth-child(2)') + .text(); + } + } + if (title_sub !== '') { + title += ' —— ' + title_sub; + } + const pub_date_raw = $('table[summary="底本データ"] > tbody > tr:nth-child(3) > td:nth-child(2)').text(); + const pub_date_num = pub_date_raw.replace(/(.*)|日/g, '').replace(/[年月]/g, '-'); + const pub_date = new Date(pub_date_num).toUTCString(); + const full_text_relative_link = $('table.download > tbody > tr:nth-child(3) > td:nth-child(3) > a').attr('href'); + const full_text_link = link_dir + full_text_relative_link; + const full_text_link_html = 'いますぐXHTML版で読む
'; + const summury = $('table[summary="作品データ"]') + .html() + .replace(/href="/g, 'href="' + link_dir); + + const item = { + title: title, + author: author, + pubDate: pub_date, + link: link, + description: full_text_link_html + summury, + }; + book_list.push(item); + } + + // feed the data + ctx.state.data = { + title: '青空文庫新着リスト', + link: base_url + 'whatsnew1.html', + item: book_list, + }; +};