diff --git a/docs/en/new-media.md b/docs/en/new-media.md
index 5efa25634..a4177072b 100644
--- a/docs/en/new-media.md
+++ b/docs/en/new-media.md
@@ -305,6 +305,16 @@ Country
+## Global Disinformation Index
+
+### Research
+
+
+
+### Blog
+
+
+
## Google News
### News
diff --git a/docs/new-media.md b/docs/new-media.md
index ab5e0184e..5ac0adbd7 100644
--- a/docs/new-media.md
+++ b/docs/new-media.md
@@ -425,6 +425,16 @@ Country
+## Global Disinformation Index
+
+### Research
+
+
+
+### Blog
+
+
+
## GQ
### GQ 台湾
diff --git a/lib/router.js b/lib/router.js
index 16d34f373..e10febfed 100644
--- a/lib/router.js
+++ b/lib/router.js
@@ -4172,9 +4172,9 @@ router.get('/fashionnetwork/headline/:country?', lazyloadRouteHandler('./routes/
// mirror.xyz
router.get('/mirror/:id', lazyloadRouteHandler('./routes/mirror/entries'));
-// Deprecated: DO NOT ADD ROUTE HERE
-
// KBS
router.get('/kbs/today/:language?', lazyloadRouteHandler('./routes/kbs/today'));
+// Deprecated: DO NOT ADD ROUTE HERE
+
module.exports = router;
diff --git a/lib/v2/disinformationindex/blog.js b/lib/v2/disinformationindex/blog.js
new file mode 100644
index 000000000..e62568efb
--- /dev/null
+++ b/lib/v2/disinformationindex/blog.js
@@ -0,0 +1,49 @@
+const got = require('@/utils/got');
+const cheerio = require('cheerio');
+const { parseDate } = require('@/utils/parse-date');
+
+module.exports = async (ctx) => {
+ const rootUrl = 'https://disinformationindex.org';
+ const currentUrl = `${rootUrl}/blog`;
+ const response = await got({
+ method: 'get',
+ url: currentUrl,
+ });
+
+ const $ = cheerio.load(response.data);
+
+ const list = $('.blog-entry-title a')
+ .map((_, item) => {
+ item = $(item);
+ return {
+ title: item.text(),
+ link: `${rootUrl}${item.attr('href')}`,
+ };
+ })
+ .get();
+
+ const items = await Promise.all(
+ list.map(
+ async (item) =>
+ await ctx.cache.tryGet(item.link, async () => {
+ const detailResponse = await got({
+ method: 'get',
+ url: item.link,
+ });
+ const content = cheerio.load(detailResponse.data);
+
+ item.author = content('.meta-author').text();
+ item.description = content('.entry-content').html();
+ item.pubDate = parseDate(content('.meta-date').text(), 'MMMM D, YYYY');
+
+ return item;
+ })
+ )
+ );
+
+ ctx.state.data = {
+ title: $('title').text(),
+ link: currentUrl,
+ item: items,
+ };
+};
diff --git a/lib/v2/disinformationindex/maintainer.js b/lib/v2/disinformationindex/maintainer.js
new file mode 100644
index 000000000..b678eb73f
--- /dev/null
+++ b/lib/v2/disinformationindex/maintainer.js
@@ -0,0 +1,4 @@
+module.export = {
+ '/blog': ['nczitzk'],
+ '/research': ['nczitzk'],
+};
diff --git a/lib/v2/disinformationindex/radar.js b/lib/v2/disinformationindex/radar.js
new file mode 100644
index 000000000..5710743e5
--- /dev/null
+++ b/lib/v2/disinformationindex/radar.js
@@ -0,0 +1,19 @@
+module.export = {
+ 'disinformationindex.org': {
+ _name: 'Global Disinformation Index',
+ '.': [
+ {
+ title: 'Blog',
+ docs: 'https://docs.rsshub.app/new-media.html#global-disinformation-index',
+ source: ['/'],
+ target: '/disinformationindex/blog',
+ },
+ {
+ title: 'Research',
+ docs: 'https://docs.rsshub.app/new-media.html#global-disinformation-index',
+ source: ['/'],
+ target: '/disinformationindex/research',
+ },
+ ],
+ },
+};
diff --git a/lib/v2/disinformationindex/research.js b/lib/v2/disinformationindex/research.js
new file mode 100644
index 000000000..6b81f7da5
--- /dev/null
+++ b/lib/v2/disinformationindex/research.js
@@ -0,0 +1,45 @@
+const got = require('@/utils/got');
+const cheerio = require('cheerio');
+const { art } = require('@/utils/render');
+const path = require('path');
+
+module.exports = async (ctx) => {
+ const rootUrl = 'https://disinformationindex.org';
+ const currentUrl = `${rootUrl}/research`;
+ const response = await got({
+ method: 'get',
+ url: currentUrl,
+ });
+
+ const $ = cheerio.load(response.data);
+
+ const items = $('.elementor-widget-container .elementor-text-editor')
+ .map((_, item) => {
+ item = $(item);
+ const title = item.find('h3, h4').eq(0);
+ const image = item.parentsUntil('.elementor-container').find('.elementor-image img');
+ const firstLink = item.find('a.button').eq(0);
+
+ let links = '';
+ item.find('a.button').each(function () {
+ links += `
${$(this).text()}`;
+ });
+
+ return {
+ link: firstLink.attr('href'),
+ title: title.text() || firstLink.text(),
+ description: art(path.resolve(__dirname, 'templates/description.art'), {
+ image: image ? image.attr('src') : undefined,
+ title: title.next().html(),
+ links,
+ }),
+ };
+ })
+ .get();
+
+ ctx.state.data = {
+ title: $('title').text(),
+ link: currentUrl,
+ item: items,
+ };
+};
diff --git a/lib/v2/disinformationindex/router.js b/lib/v2/disinformationindex/router.js
new file mode 100644
index 000000000..d01b16339
--- /dev/null
+++ b/lib/v2/disinformationindex/router.js
@@ -0,0 +1,4 @@
+module.exports = (router) => {
+ router.get('/blog', require('./blog'));
+ router.get('/research', require('./research'));
+};
diff --git a/lib/v2/disinformationindex/templates/description.art b/lib/v2/disinformationindex/templates/description.art
new file mode 100644
index 000000000..d72c080d1
--- /dev/null
+++ b/lib/v2/disinformationindex/templates/description.art
@@ -0,0 +1,7 @@
+{{ if image }}
+ 
+{{ /if }}
+{{ if title }}
+ {{@ title }}
+{{ /if }}
+{{@ links }}