diff --git a/docs/en/picture.md b/docs/en/picture.md
index 8b0c343cc6..a76681751a 100644
--- a/docs/en/picture.md
+++ b/docs/en/picture.md
@@ -61,6 +61,12 @@ For example:
+## LoveHeaven
+
+### Manga Updates
+
+
+
## nHentai
### Filter
diff --git a/docs/picture.md b/docs/picture.md
index 2d1d700877..4ebf461428 100644
--- a/docs/picture.md
+++ b/docs/picture.md
@@ -79,6 +79,12 @@ pageClass: routes
+## LoveHeaven
+
+### 漫画更新
+
+
+
## nHentai
### 分类筛选
diff --git a/lib/router.js b/lib/router.js
index cdf39c830f..01bdb67426 100644
--- a/lib/router.js
+++ b/lib/router.js
@@ -2312,4 +2312,7 @@ router.get('/wolley/host/:host', require('./routes/wolley/host'));
// 西安交大
router.get('/xjtu/dean/:subpath+', require('./routes/universities/xjtu/dean'));
+// LoveHeaven
+router.get('/loveheaven/update/:slug', require('./routes/loveheaven/update'));
+
module.exports = router;
diff --git a/lib/routes/loveheaven/update.js b/lib/routes/loveheaven/update.js
new file mode 100644
index 0000000000..ec0c6bacfb
--- /dev/null
+++ b/lib/routes/loveheaven/update.js
@@ -0,0 +1,45 @@
+const got = require('@/utils/got');
+const cheerio = require('cheerio');
+const chrono = require('chrono-node');
+
+const base = 'https://loveheaven.net/';
+
+module.exports = async (ctx) => {
+ const slug = ctx.params.slug;
+
+ const url = `https://loveheaven.net/manga-${slug.replace(/^manga-/, '').replace(/\.html$/, '')}.html`;
+
+ const response = await got.get(url);
+ const $ = cheerio.load(response.data);
+
+ const manga_name = $('.manga-info > h1').text();
+ const manga_other_names = $('.manga-info > li:nth-child(3)').text();
+ const manga_author = $('a.btn-info')
+ .map(function() {
+ return $(this).text();
+ })
+ .get()
+ .join(', ');
+ const manga_cover = $('img.thumbnail').attr('src');
+
+ const list = $('.tab-text .table > tbody > tr').get();
+
+ ctx.state.data = {
+ title: `${manga_name} - LoveHeaven`,
+ description: manga_other_names,
+ link: url,
+ image: manga_cover,
+ item: list.slice(0, 20).map((item) => {
+ item = $(item);
+ const entry = item.find('a');
+ const humanized_date = item.find('time').text();
+ return {
+ title: entry.text(),
+ author: manga_author,
+ description: `
`,
+ link: base + entry.attr('href'),
+ pubDate: humanized_date ? chrono.parseDate(humanized_date) : new Date(),
+ };
+ }),
+ };
+};
diff --git a/package.json b/package.json
index d79da74e45..fb69f81bcc 100644
--- a/package.json
+++ b/package.json
@@ -65,6 +65,7 @@
"aes-js": "3.1.2",
"art-template": "4.13.2",
"cheerio": "1.0.0-rc.3",
+ "chrono-node": "1.4.3",
"cloudscraper": "4.6.0",
"co-redis": "2.1.1",
"currency-symbol-map": "4.0.4",