diff --git a/.env.local.example b/.env.local.example index c561a612..71616d8b 100644 --- a/.env.local.example +++ b/.env.local.example @@ -1,3 +1,23 @@ -SIYUAN_API_URL=... -# some api need to pass token -SIYUAN_AUTH_TOKEN=... \ No newline at end of file +# siyuan +SIYUAN_API_URL= +SIYUAN_AUTH_TOKEN= + +# cnblogs +CNBLOGS_API_URL= +CNBLOGS_USERNAME= +CNBLOGS_PASSWORD= + +# jvue +JVUE_API_URL= +JVUE_USERNAME= +JVUE_PASSWORD= + +# conf +CONF_API_URL= +CONF_USERNAME= +CONF_PASSWORD= + +# conf rest api +CONFLUENCE_REST_API_URL= +CONFLUENCE_REST_USERNAME= +CONFLUENCE_REST_PASSWORD= \ No newline at end of file diff --git a/lib/api.ts b/lib/api.ts index 394283ac..2afeeff2 100644 --- a/lib/api.ts +++ b/lib/api.ts @@ -1,5 +1,9 @@ import {SiYuanApiAdaptor} from "./siyuan/siYuanApiAdaptor"; import {API_TYPE_CONSTANTS} from "./constants"; +import {JvueApiAdaptor} from "./metaweblog/jvueApiAdaptor"; +import {ConfApiAdaptor} from "./metaweblog/confApiAdaptor"; +import {CnblogsApiAdaptor} from "./metaweblog/cnblogsApiAdaptor"; +import {Post} from "./common/post"; export interface IApi { getRecentPosts(numOfPosts: number): Promise> @@ -15,12 +19,21 @@ export class API implements IApi { case API_TYPE_CONSTANTS.API_TYPE_SIYUAN: this.apiAdaptor = new SiYuanApiAdaptor() break; + case API_TYPE_CONSTANTS.API_TYPE_JVUE: + this.apiAdaptor = new JvueApiAdaptor() + break; + case API_TYPE_CONSTANTS.API_TYPE_CONF: + this.apiAdaptor = new ConfApiAdaptor() + break; + case API_TYPE_CONSTANTS.API_TYPE_CNBLOGS: + this.apiAdaptor = new CnblogsApiAdaptor() + break; default: throw new Error("未找到接口适配器,请检查参数") } } - async getRecentPosts(numOfPosts: number): Promise> { + async getRecentPosts(numOfPosts: number): Promise> { return this.apiAdaptor.getRecentPosts(numOfPosts); } } diff --git a/lib/common/post.ts b/lib/common/post.ts new file mode 100644 index 00000000..5bf6ff1e --- /dev/null +++ b/lib/common/post.ts @@ -0,0 +1,9 @@ +export class Post { + postid: string + title: string + + constructor() { + this.postid = "" + this.title = "" + } +} \ No newline at end of file diff --git a/lib/constants.ts b/lib/constants.ts index da6d9043..3b327cbe 100644 --- a/lib/constants.ts +++ b/lib/constants.ts @@ -1,8 +1,26 @@ +/** + * 思源笔记 + */ const API_TYPE_SIYUAN = "siyuan" +/** + * JVue + */ +const API_TYPE_JVUE = "jvue" +/** + * Confluence + */ +const API_TYPE_CONF = "conf" +/** + * Cnblogs + */ +const API_TYPE_CNBLOGS = "cnblogs" /** * API类型常量定义 */ export const API_TYPE_CONSTANTS = { - API_TYPE_SIYUAN + API_TYPE_SIYUAN, + API_TYPE_JVUE, + API_TYPE_CONF, + API_TYPE_CNBLOGS } \ No newline at end of file diff --git a/lib/metaweblog/README.md b/lib/metaweblog/README.md new file mode 100644 index 00000000..806c5feb --- /dev/null +++ b/lib/metaweblog/README.md @@ -0,0 +1,11 @@ +# metaweblog-api + +## 依赖 + +```json +{ + "dependencies": { + "metaweblog-api": "^1.2.0" + } +} +``` \ No newline at end of file diff --git a/lib/metaweblog/cnblogsApiAdaptor.ts b/lib/metaweblog/cnblogsApiAdaptor.ts new file mode 100644 index 00000000..baa2c8f7 --- /dev/null +++ b/lib/metaweblog/cnblogsApiAdaptor.ts @@ -0,0 +1,18 @@ +import {IApi} from "../api"; +import {API_TYPE_CONSTANTS} from "../constants"; +import {MetaWeblogApiAdaptor} from "./metaWeblogApiAdaptor"; +import MetaWeblog from "metaweblog-api"; + +/** + * 博客园的API适配器 + */ +export class CnblogsApiAdaptor extends MetaWeblogApiAdaptor implements IApi { + constructor() { + super(); + + this.metaWeblog = new MetaWeblog(process.env.CNBLOGS_API_URL || ""); + this.username = process.env.CNBLOGS_USERNAME || "" + this.password = process.env.CNBLOGS_PASSWORD || "" + this.appkey = API_TYPE_CONSTANTS.API_TYPE_CNBLOGS + } +} \ No newline at end of file diff --git a/lib/metaweblog/confApiAdaptor.ts b/lib/metaweblog/confApiAdaptor.ts new file mode 100644 index 00000000..1a4a62d1 --- /dev/null +++ b/lib/metaweblog/confApiAdaptor.ts @@ -0,0 +1,19 @@ +import {IApi} from "../api"; +import {MetaWeblogApiAdaptor} from "./metaWeblogApiAdaptor"; +import {API_TYPE_CONSTANTS} from "../constants"; +import MetaWeblog from "metaweblog-api"; + +/** + * Confluence的API适配器 + */ +export class ConfApiAdaptor extends MetaWeblogApiAdaptor implements IApi { + + constructor() { + super(); + + this.metaWeblog = new MetaWeblog(process.env.CONF_API_URL || ""); + this.username = process.env.CONF_USERNAME || "" + this.password = process.env.CONF_PASSWORD || "" + this.appkey = API_TYPE_CONSTANTS.API_TYPE_CONF + } +} \ No newline at end of file diff --git a/lib/metaweblog/jvueApiAdaptor.ts b/lib/metaweblog/jvueApiAdaptor.ts new file mode 100644 index 00000000..374f02c2 --- /dev/null +++ b/lib/metaweblog/jvueApiAdaptor.ts @@ -0,0 +1,18 @@ +import {IApi} from "../api"; +import {MetaWeblogApiAdaptor} from "./metaWeblogApiAdaptor"; +import MetaWeblog from "metaweblog-api"; +import {API_TYPE_CONSTANTS} from "../constants"; + +/** + * JVue的API适配器 + */ +export class JvueApiAdaptor extends MetaWeblogApiAdaptor implements IApi { + constructor() { + super(); + + this.metaWeblog = new MetaWeblog(process.env.JVUE_API_URL || ""); + this.username = process.env.JVUE_USERNAME || "" + this.password = process.env.JVUE_PASSWORD || "" + this.appkey = API_TYPE_CONSTANTS.API_TYPE_JVUE + } +} \ No newline at end of file diff --git a/lib/metaweblog/metaWeblogApiAdaptor.ts b/lib/metaweblog/metaWeblogApiAdaptor.ts new file mode 100644 index 00000000..907ce78a --- /dev/null +++ b/lib/metaweblog/metaWeblogApiAdaptor.ts @@ -0,0 +1,39 @@ +import {IApi} from "../api"; +import {Post} from "../common/post"; + +/** + * 博客园的API适配器 + */ +export class MetaWeblogApiAdaptor implements IApi { + protected metaWeblog: any + protected username: string + protected password: string + protected appkey: string + + constructor() { + this.metaWeblog = null; + this.username = "" + this.password = "" + this.appkey = "" + } + + /** + * getRecentPosts + * https://codex.wordpress.org/XML-RPC_MetaWeblog_API#metaWeblog.getRecentPosts + * @param numOfPosts + */ + public async getRecentPosts(numOfPosts: number): Promise> { + let result: Array = [] + const cnblogsPosts = await this.metaWeblog.getRecentPosts(this.appkey, this.username, this.password, numOfPosts); + for (let i = 0; i < cnblogsPosts.length; i++) { + const cnblogsPost = cnblogsPosts[i] + + // 适配公共属性 + let commonPost = new Post() + commonPost.title = cnblogsPost.title + result.push(commonPost) + } + + return result; + } +} \ No newline at end of file diff --git a/lib/siyuan/siYuanApiAdaptor.ts b/lib/siyuan/siYuanApiAdaptor.ts index 84edb796..1484e9d0 100644 --- a/lib/siyuan/siYuanApiAdaptor.ts +++ b/lib/siyuan/siYuanApiAdaptor.ts @@ -1,6 +1,10 @@ import {IApi} from "../api"; import {getBlockByID} from "./siYuanApi"; +import {Post} from "../common/post"; +/** + * 思源笔记API适配器 + */ export class SiYuanApiAdaptor implements IApi { async getRecentPosts(numOfPosts: number): Promise> { let result = [] @@ -10,7 +14,11 @@ export class SiYuanApiAdaptor implements IApi { let page = await getBlockByID(pageId) if (page) { - result.push(page) + // 适配公共属性 + let commonPost = new Post() + commonPost.postid = page.id + commonPost.title = page.content + result.push(commonPost) } return Promise.resolve(result); } diff --git a/package.json b/package.json index f3868ae1..61af741e 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "lint": "next lint" }, "dependencies": { + "metaweblog-api": "^1.2.0", "next": "12.2.3", "react": "18.2.0", "react-dom": "18.2.0" diff --git a/pages/index.tsx b/pages/index.tsx index da5adeb3..9c70e656 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -4,16 +4,18 @@ import Image from 'next/image' import styles from '../styles/Home.module.css' import {API} from "../lib/api"; import {API_TYPE_CONSTANTS} from "../lib/constants"; +import {Post} from "../lib/common/post"; type Props = { - posts: any[] + type: string, + posts: Post[] } const Home: NextPage = (props, context) => { return (
- Create Next App + {props.type} @@ -23,7 +25,13 @@ const Home: NextPage = (props, context) => { Welcome to Next.js! -

{JSON.stringify(props.posts)}

+ +
+ {props.posts.map((post) => ( +

{post.title}

+ ))} +
+

Get started by editing{' '} @@ -87,7 +95,7 @@ export const getServerSideProps: GetServerSideProps = async (context) => throw new Error("参数类型错误") } - let result = [] + let result: Array = [] const type = query.t || API_TYPE_CONSTANTS.API_TYPE_SIYUAN const api = new API(type) @@ -95,7 +103,8 @@ export const getServerSideProps: GetServerSideProps = async (context) => return { props: { - posts: result + type: type, + posts: JSON.parse(JSON.stringify(result)) } } } \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 58c6c53f..556a16cc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -161,6 +161,11 @@ dependencies: tslib "^2.4.0" +"@types/es6-promise@0.0.28": + version "0.0.28" + resolved "https://registry.npmmirror.com/@types/es6-promise/-/es6-promise-0.0.28.tgz#1af00118ff7b88fe3e46be943add54edeb285b75" + integrity sha512-4GA06MWCWCmuyBf+ptxrVK4BMQBXUSSCmyydk18Fvn9huS5zJdi24mEwxTn5x7sKMmGpJwKS6f1i2oLN7yL4lw== + "@types/json5@^0.0.29": version "0.0.29" resolved "https://registry.npmmirror.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" @@ -171,6 +176,11 @@ resolved "https://registry.npmmirror.com/@types/node/-/node-18.6.3.tgz#4e4a95b6fe44014563ceb514b2598b3e623d1c98" integrity sha512-6qKpDtoaYLM+5+AFChLhHermMQxc3TOEFIDzrZLPRGHPrLEwqFkkT5Kx3ju05g6X7uDPazz3jHbKPX0KzCjntg== +"@types/node@^6.0.31": + version "6.14.13" + resolved "https://registry.npmmirror.com/@types/node/-/node-6.14.13.tgz#b6649578fc0b5dac88c4ef48a46cab33c50a6c72" + integrity sha512-J1F0XJ/9zxlZel5ZlbeSuHW2OpabrUAqpFuC2sm2I3by8sERQ8+KCjNKUcq8QHuzpGMWiJpo9ZxeHrqrP2KzQw== + "@types/prop-types@*": version "15.7.5" resolved "https://registry.npmmirror.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf" @@ -1202,6 +1212,15 @@ merge2@^1.3.0, merge2@^1.4.1: resolved "https://registry.npmmirror.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== +metaweblog-api@^1.2.0: + version "1.2.0" + resolved "https://registry.npmmirror.com/metaweblog-api/-/metaweblog-api-1.2.0.tgz#572981d0f91d28ecfd8f429f6552e283a6d62d6c" + integrity sha512-lbN5Ge/WSM810k26Z2AtO6iLwhni0Q9qIwy2X3tEsjLNN/gP1TIs2MV5VGltVxbTpvs2nO7F86wr7AhW5TXHpQ== + dependencies: + "@types/es6-promise" "0.0.28" + "@types/node" "^6.0.31" + xmlrpc "^1.3.2" + micromatch@^4.0.4: version "4.0.5" resolved "https://registry.npmmirror.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" @@ -1546,6 +1565,11 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" +sax@1.2.x: + version "1.2.4" + resolved "https://registry.npmmirror.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + scheduler@^0.23.0: version "0.23.0" resolved "https://registry.npmmirror.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe" @@ -1773,6 +1797,19 @@ wrappy@1: resolved "https://registry.npmmirror.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== +xmlbuilder@8.2.x: + version "8.2.2" + resolved "https://registry.npmmirror.com/xmlbuilder/-/xmlbuilder-8.2.2.tgz#69248673410b4ba42e1a6136551d2922335aa773" + integrity sha512-eKRAFz04jghooy8muekqzo8uCSVNeyRedbuJrp0fovbLIi7wlsYtdUn3vBAAPq2Y3/0xMz2WMEUQ8yhVVO9Stw== + +xmlrpc@^1.3.2: + version "1.3.2" + resolved "https://registry.npmmirror.com/xmlrpc/-/xmlrpc-1.3.2.tgz#26b2ea347848d028aac7e7514b5351976de3e83d" + integrity sha512-jQf5gbrP6wvzN71fgkcPPkF4bF/Wyovd7Xdff8d6/ihxYmgETQYSuTc+Hl+tsh/jmgPLro/Aro48LMFlIyEKKQ== + dependencies: + sax "1.2.x" + xmlbuilder "8.2.x" + yallist@^4.0.0: version "4.0.0" resolved "https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"