diff --git a/lib/v2/gocn/jobs.js b/lib/v2/gocn/jobs.js
index 4faeeb68c1f43e..8f9b384b3410fa 100644
--- a/lib/v2/gocn/jobs.js
+++ b/lib/v2/gocn/jobs.js
@@ -1,23 +1,28 @@
const got = require('@/utils/got');
-const util = require('./util');
+const { parseDate } = require('@/utils/parse-date');
+const { renderHTML } = require('./utils');
module.exports = async (ctx) => {
- const base_url = 'https://gocn.vip/topics';
- const api_url = 'https://gocn.vip/apiv3/topic/jobs?currentPage=1&grade=new';
+ const api_url = 'https://gocn.vip/api/files?spaceGuid=Gd7OHl¤tPage=1&sort=1';
+ const base_url = 'https://gocn.vip/c/3lQ6GbD5ny/s/Gd7OHl';
+ const job_url = 'https://gocn.vip/c/3lQ6GbD5ny';
const response = await got({
url: api_url,
- headers: {
- Referer: base_url,
- },
});
- const list = response.data.data.list;
+ const items = response.data.data.list.map((item) => ({
+ title: item.name,
+ link: `${job_url}/s/${item.spaceGuid}/d/${item.guid}`,
+ description: renderHTML(JSON.parse(item.content)),
+ pubDate: parseDate(item.ctime, 'X'),
+ author: item.nickname,
+ }));
ctx.state.data = {
title: `GoCN社区-招聘`,
link: base_url,
- description: `获取GoCN站点最新招聘`,
- item: await Promise.all(list.map((item) => ctx.cache.tryGet(`${base_url}/${item.guid}`, () => util.getFeedItem(item)))),
+ description: `获取GoCN站点招聘`,
+ item: items,
};
};
diff --git a/lib/v2/gocn/maintainer.js b/lib/v2/gocn/maintainer.js
index 37b10046a4a6fb..514f5e5e330bcd 100644
--- a/lib/v2/gocn/maintainer.js
+++ b/lib/v2/gocn/maintainer.js
@@ -1,4 +1,6 @@
module.exports = {
'/': ['AtlanCI', 'CcccFz'],
- '/jobs': ['CcccFz'],
+ '/jobs': ['AtlanCI', 'CcccFz'],
+ '/news': ['AtlanCI'],
+ '/topics': ['AtlanCI', 'CcccFz'],
};
diff --git a/lib/v2/gocn/news.js b/lib/v2/gocn/news.js
new file mode 100644
index 00000000000000..79b0e25ea3a6a3
--- /dev/null
+++ b/lib/v2/gocn/news.js
@@ -0,0 +1,31 @@
+const got = require('@/utils/got');
+const { parseDate } = require('@/utils/parse-date');
+const { renderHTML } = require('./utils');
+
+module.exports = async (ctx) => {
+ const base_url = 'https://gocn.vip/c/3lQ6GbD5ny/home';
+ const article_url = 'https://gocn.vip/c/3lQ6GbD5ny';
+ const api_url = 'https://gocn.vip/api/home/page';
+
+ const response = await got({
+ url: api_url,
+ headers: {
+ Referer: base_url,
+ },
+ });
+
+ const items = response.data.data.articlePageList.list.map((item) => ({
+ title: item.name,
+ link: `${article_url}/s/${item.spaceGuid}/d/${item.guid}`,
+ description: renderHTML(JSON.parse(item.content)),
+ pubDate: parseDate(item.ctime, 'X'),
+ author: item.nickname,
+ }));
+
+ ctx.state.data = {
+ title: `GoCN社区-最新动态`,
+ link: base_url,
+ description: `获取GoCN站点最新动态`,
+ item: items,
+ };
+};
diff --git a/lib/v2/gocn/radar.js b/lib/v2/gocn/radar.js
index b06f033aa48d9a..3c625d107c6ea3 100644
--- a/lib/v2/gocn/radar.js
+++ b/lib/v2/gocn/radar.js
@@ -3,10 +3,16 @@ module.exports = {
_name: 'GoCN',
'.': [
{
- title: '文章',
+ title: '最新动态',
docs: 'https://docs.rsshub.app/routes/programming#GoCN',
source: ['/'],
- target: '/gocn',
+ target: '/gocn/news',
+ },
+ {
+ title: '每日新闻',
+ docs: 'https://docs.rsshub.app/routes/programming#GoCN',
+ source: ['/'],
+ target: '/gocn/topics',
},
{
title: '招聘',
diff --git a/lib/v2/gocn/router.js b/lib/v2/gocn/router.js
index 3574e546ada605..20228ac683bba5 100644
--- a/lib/v2/gocn/router.js
+++ b/lib/v2/gocn/router.js
@@ -1,4 +1,6 @@
module.exports = function (router) {
- router.get('/', require('./topics'));
+ router.get('/', require('./news'));
router.get('/jobs', require('./jobs'));
+ router.get('/news', require('./news'));
+ router.get('/topics', require('./topics'));
};
diff --git a/lib/v2/gocn/topics.js b/lib/v2/gocn/topics.js
index 713e7b2d28e12b..85d9050d634817 100644
--- a/lib/v2/gocn/topics.js
+++ b/lib/v2/gocn/topics.js
@@ -1,9 +1,11 @@
const got = require('@/utils/got');
-const util = require('./util');
+const { parseDate } = require('@/utils/parse-date');
+const { renderHTML } = require('./utils');
module.exports = async (ctx) => {
- const base_url = 'https://gocn.vip/topics';
- const api_url = 'https://gocn.vip/apiv3/topic/list?currentPage=1&cate2Id=0&grade=new';
+ const base_url = 'https://gocn.vip/c/3lQ6GbD5ny/home';
+ const article_url = 'https://gocn.vip/c/3lQ6GbD5ny';
+ const api_url = 'https://gocn.vip/api/files?spaceGuid=Gd7BTB¤tPage=1&sort=1';
const response = await got({
url: api_url,
@@ -12,12 +14,18 @@ module.exports = async (ctx) => {
},
});
- const list = response.data.data.list;
+ const items = response.data.data.list.map((item) => ({
+ title: item.name,
+ link: `${article_url}/s/${item.spaceGuid}/d/${item.guid}`,
+ description: renderHTML(JSON.parse(item.content)),
+ pubDate: parseDate(item.ctime, 'X'),
+ author: item.nickname,
+ }));
ctx.state.data = {
- title: `GoCN社区-文章`,
+ title: `GoCN社区-每日新闻`,
link: base_url,
- description: `获取GoCN站点最新文章`,
- item: await Promise.all(list.map((item) => ctx.cache.tryGet(`${base_url}/${item.guid}`, () => util.getFeedItem(item)))),
+ description: `获取GoCN站点每日新闻`,
+ item: items,
};
};
diff --git a/lib/v2/gocn/util.js b/lib/v2/gocn/util.js
deleted file mode 100644
index 88ed672244d646..00000000000000
--- a/lib/v2/gocn/util.js
+++ /dev/null
@@ -1,17 +0,0 @@
-const got = require('@/utils/got');
-const { parseDate } = require('@/utils/parse-date');
-
-async function getFeedItem(item) {
- const response = await got(`https://gocn.vip/apiv3/topic/${item.guid}/info`);
-
- return {
- link: `https://gocn.vip/topics/${item.guid}`,
- title: item.title,
- description: response.data.data.topic.contentHtml,
- pubDate: parseDate(item.ctime, 'X'),
- };
-}
-
-module.exports = {
- getFeedItem,
-};
diff --git a/lib/v2/gocn/utils.js b/lib/v2/gocn/utils.js
new file mode 100644
index 00000000000000..a42d2f83599a07
--- /dev/null
+++ b/lib/v2/gocn/utils.js
@@ -0,0 +1,38 @@
+const elementMap = {
+ code_block: (element) => `
${element.children[0].text}
`,
+ a: (element) => `${renderHTML(element.children)}`,
+ blockquote: (element) => `${renderHTML(element.children)}
`,
+ br: () => '
',
+ h1: (element) => `${element.children[0].text}
`,
+ h2: (element) => `${element.children[0].text}
`,
+ h3: (element) => `${element.children[0].text}
`,
+ h4: (element) => `${element.children[0].text}
`,
+ h5: (element) => `${element.children[0].text}
`,
+ h6: (element) => `${element.children[0].text}
`,
+ img: (element) => ``,
+ p: (element) => `${renderHTML(element.children)}
`,
+ strong: (element) => `${renderHTML(element.children)}`,
+ ol: (element) => `${renderHTML(element.children)}
`,
+ ul: (element) => `${renderHTML(element.children)}
`,
+ li: (element) => `${renderHTML(element.children)}`,
+ lic: (element) => element.children[0].text,
+};
+
+function renderHTML(json) {
+ return json
+ .map((element) => {
+ const handler = elementMap[element.type];
+ if (handler) {
+ return handler(element);
+ } else if (element.hasOwnProperty('text')) {
+ return element.text;
+ } else {
+ throw new Error(`Unknown handled type: ${element.type}, ${JSON.stringify(element)}`);
+ }
+ })
+ .join('');
+}
+
+module.exports = {
+ renderHTML,
+};
diff --git a/website/docs/routes/programming.md b/website/docs/routes/programming.md
index f9d3bd88663b8c..e974846c2fc401 100644
--- a/website/docs/routes/programming.md
+++ b/website/docs/routes/programming.md
@@ -12,51 +12,51 @@
You have the option to utilize the main heading or use individual categories as topics for the path.
-| **Code** | _code_ |
-|-------------------------|-------------------------|
+| **Code** | _code_ |
+| --------------------------- | ------------------------- |
| **Application Development** | _application-development_ |
-| **Browsers** | _browsers_ |
-| **CSS** | _css_ |
-| **HTML** | _html_ |
-| **JavaScript** | _javascript_ |
-| **The Server Side** | _the-server-side_ |
-
-| **Content** | _content_ |
-|-------------------------|-------------------------|
-| **Community** | _community_ |
-| **Content Strategy** | _content-strategy_ |
-| **Writing** | _writing_ |
-
-| **Design** | _design_ |
-|-------------------------|-------------------------|
-| **Brand Identity** | _brand-identity_ |
-| **Graphic Design** | _graphic-design_ |
-| **Layout & Grids** | _layout-grids_ |
-| **Mobile/Multidevice** | _mobile-multidevice_ |
-| **Responsive Design** | _responsive-design_ |
+| **Browsers** | _browsers_ |
+| **CSS** | _css_ |
+| **HTML** | _html_ |
+| **JavaScript** | _javascript_ |
+| **The Server Side** | _the-server-side_ |
+
+| **Content** | _content_ |
+| -------------------- | ------------------ |
+| **Community** | _community_ |
+| **Content Strategy** | _content-strategy_ |
+| **Writing** | _writing_ |
+
+| **Design** | _design_ |
+| -------------------------- | ---------------------- |
+| **Brand Identity** | _brand-identity_ |
+| **Graphic Design** | _graphic-design_ |
+| **Layout & Grids** | _layout-grids_ |
+| **Mobile/Multidevice** | _mobile-multidevice_ |
+| **Responsive Design** | _responsive-design_ |
| **Typography & Web Fonts** | _typography-web-fonts_ |
-| **Industry & Business** | _industry-business_ |
-|-------------------------|-------------------------|
-| **Business** | _business_ |
-| **Career** | _career_ |
-| **Industry** | _industry_ |
-| **State of the Web** | _state-of-the-web_ |
-
-| **Process** | _process_ |
-|-------------------------|-------------------------|
-| **Creativity** | _creativity_ |
-| **Project Management** | _project-management_ |
-| **Web Strategy** | _web-strategy_ |
-| **Workflow & Tools** | _workflow-tools_ |
-
-| **User Experience** | _user-experience_ |
-|-------------------------|-------------------------|
-| **Accessibility** | _accessibility_ |
+| **Industry & Business** | _industry-business_ |
+| ----------------------- | ------------------- |
+| **Business** | _business_ |
+| **Career** | _career_ |
+| **Industry** | _industry_ |
+| **State of the Web** | _state-of-the-web_ |
+
+| **Process** | _process_ |
+| ---------------------- | -------------------- |
+| **Creativity** | _creativity_ |
+| **Project Management** | _project-management_ |
+| **Web Strategy** | _web-strategy_ |
+| **Workflow & Tools** | _workflow-tools_ |
+
+| **User Experience** | _user-experience_ |
+| ---------------------------- | -------------------------- |
+| **Accessibility** | _accessibility_ |
| **Information Architecture** | _information-architecture_ |
-| **Interaction Design** | _interaction-design_ |
-| **Usability** | _usability_ |
-| **User Research** | _user-research_ |
+| **Interaction Design** | _interaction-design_ |
+| **Usability** | _usability_ |
+| **User Research** | _user-research_ |
@@ -173,7 +173,7 @@ Category
| Blog | News | Announcements | Reports |
-|------|------|---------------|---------|
+| ---- | ---- | ------------- | ------- |
| blog | news | announcements | reports |
@@ -451,13 +451,18 @@ For instance, the `/github/topics/framework/l=php&o=desc&s=stars` route will gen
## GoCN {#gocn}
-### 文章 {#gocn-wen-zhang}
+### 最新动态 {#gocn-zui-xin-dong-tai}
-
+
+
+### 每日新闻 {#gocn-mei-ri-xin-wen}
+
+
### 招聘 {#gocn-zhao-pin}
-
+
+
## Hacker News {#hacker-news}
@@ -845,41 +850,41 @@ Subscribe to the updates (threads and submission) from a paritcular Hacker News
-| **Category** | |
-|----------------------|-----------------------|
-| Accessibility | accessibility |
-| Best practices | best-practices |
-| Business | business |
-| Career | career |
-| Checklists | checklists |
-| CSS | css |
-| Data Visualization | data-visualization |
-| Design | design |
-| Design Patterns | design-patterns |
-| Design Systems | design-systems |
-| E-Commerce | e-commerce |
-| Figma | figma |
-| Freebies | freebies |
-| HTML | html |
-| Illustrator | illustrator |
-| Inspiration | inspiration |
-| JavaScript | javascript |
-| Mobile | mobile |
-| Performance | performance |
-| Privacy | privacy |
-| React | react |
-| Responsive Design | responsive-design |
-| Round-Ups | round-ups |
-| SEO | seo |
-| Typography | typography |
-| Tools | tools |
-| UI | ui |
-| Usability | usability |
-| UX | ux |
-| Vue | vue |
-| Wallpapers | wallpapers |
-| Web Design | web-design |
-| Workflow | workflow |
+| **Category** | |
+| ------------------ | ------------------ |
+| Accessibility | accessibility |
+| Best practices | best-practices |
+| Business | business |
+| Career | career |
+| Checklists | checklists |
+| CSS | css |
+| Data Visualization | data-visualization |
+| Design | design |
+| Design Patterns | design-patterns |
+| Design Systems | design-systems |
+| E-Commerce | e-commerce |
+| Figma | figma |
+| Freebies | freebies |
+| HTML | html |
+| Illustrator | illustrator |
+| Inspiration | inspiration |
+| JavaScript | javascript |
+| Mobile | mobile |
+| Performance | performance |
+| Privacy | privacy |
+| React | react |
+| Responsive Design | responsive-design |
+| Round-Ups | round-ups |
+| SEO | seo |
+| Typography | typography |
+| Tools | tools |
+| UI | ui |
+| Usability | usability |
+| UX | ux |
+| Vue | vue |
+| Wallpapers | wallpapers |
+| Web Design | web-design |
+| Workflow | workflow |
@@ -1246,48 +1251,48 @@ Stay up to date on the latest React news, tutorials, resources, and more. Delive
-| 分类 | id |
-| -------------------- | -- |
-| 全部 | |
-| Stata 入门 | 16 |
-| Stata 教程 | 17 |
-| 计量专题 | 18 |
-| 内生性 - 因果推断 | 19 |
-| 面板数据 | 20 |
-| 交乘项 - 调节 - 中介 | 21 |
-| 结果输出 | 22 |
-| 工具软件 | 23 |
-| Stata 绘图 | 24 |
-| 数据处理 | 25 |
-| Stata 程序 | 26 |
-| Probit-Logit | 27 |
-| 时间序列 | 28 |
-| 空间计量 - 网络分析 | 29 |
-| Markdown-LaTeX | 30 |
-| 论文写作 | 31 |
-| 回归分析 | 32 |
-| 其它 | 33 |
-| 数据分享 | 34 |
-| Stata 资源 | 35 |
-| 文本分析 - 爬虫 | 36 |
-| Python-R-Matlab | 37 |
-| IV-GMM | 38 |
-| 倍分法 DID | 39 |
-| 断点回归 RDD | 40 |
-| PSM-Matching | 41 |
-| 合成控制法 | 42 |
-| Stata 命令 | 43 |
-| 专题课程 | 44 |
-| 风险管理 | 45 |
-| 生存分析 | 46 |
-| 机器学习 | 47 |
-| 分位数回归 | 48 |
-| SFA-DEA - 效率分析 | 49 |
-| 答疑 - 板书 | 50 |
-| 论文重现 | 51 |
-| 最新课程 | 52 |
-| 公开课 | 53 |
-| Stata33 讲 | 54 |
+| 分类 | id |
+| -------------------- | --- |
+| 全部 | |
+| Stata 入门 | 16 |
+| Stata 教程 | 17 |
+| 计量专题 | 18 |
+| 内生性 - 因果推断 | 19 |
+| 面板数据 | 20 |
+| 交乘项 - 调节 - 中介 | 21 |
+| 结果输出 | 22 |
+| 工具软件 | 23 |
+| Stata 绘图 | 24 |
+| 数据处理 | 25 |
+| Stata 程序 | 26 |
+| Probit-Logit | 27 |
+| 时间序列 | 28 |
+| 空间计量 - 网络分析 | 29 |
+| Markdown-LaTeX | 30 |
+| 论文写作 | 31 |
+| 回归分析 | 32 |
+| 其它 | 33 |
+| 数据分享 | 34 |
+| Stata 资源 | 35 |
+| 文本分析 - 爬虫 | 36 |
+| Python-R-Matlab | 37 |
+| IV-GMM | 38 |
+| 倍分法 DID | 39 |
+| 断点回归 RDD | 40 |
+| PSM-Matching | 41 |
+| 合成控制法 | 42 |
+| Stata 命令 | 43 |
+| 专题课程 | 44 |
+| 风险管理 | 45 |
+| 生存分析 | 46 |
+| 机器学习 | 47 |
+| 分位数回归 | 48 |
+| SFA-DEA - 效率分析 | 49 |
+| 答疑 - 板书 | 50 |
+| 论文重现 | 51 |
+| 最新课程 | 52 |
+| 公开课 | 53 |
+| Stata33 讲 | 54 |