docsify,我觉得这种事情你不要老是让我操心啊

一开始,我在博客上使用了 Halo。我发现有很多问题。时不时会报各种莫名其妙、莫名其妙的主题的错误。有时我不得不升级。

这两天,我抽空来来回回。不小心把镜像给尼玛删了,发的文章都没了。想了想,我需要做出改变!

众所周知,我很懒而且很有名。我想你不要让我担心这种事情。一年内最好不要搬家。和原来的一样。

研究了一阵子,最后还是决定用docsify+github来搞定。最初的想法是把MD文件写在本地,直接push到github,然后触发github的webhook,触发脚本拉取代码到服务器。

在这种情况下,还有想象的空间。以后同步文章的大部分工作都可以省了,可以通过API回调同步。不过,我们还没有调查这些平台是否可以支持它,但这应该不是问题。

是否可以尝试解决方案,我觉得很好。

docsify 构建安装

先安装 docsify-cli 工具

npm i docsify-cli -g

然后进入自己的目录并初始化

docsify init ./

这几乎是一样的。还有几个文件。只需修改index.html,配置名称和代码仓库信息,打开左侧边栏即可。

同时添加一些插件,全部来自互联网。




  
  Document
  
  
  
  


  
window.$docsify = { name: '艾小仙', repo: 'https://github.com/irwinai/JavaInterview.git', loadSidebar: true, autoHeader: true, subMaxLevel: 3, sidebarDisplayLevel: 1, // set sidebar display level count:{ countable:true, fontsize:'0.9em', color:'rgb(90,90,90)', language:'chinese' }, search: { maxAge: 86400000, // Expiration time, the default one day paths: [], // or 'auto' placeholder: '开始搜索', noData: '啥也没有!' }, copyCode: { buttonText : '点击复制', errorText : '错误', successText: '复制成功' }, footer: { copy: '艾小仙 © 2022', auth: '赣ICP备2021008029号-1', pre: '
', style: 'text-align: right;', class: 'className' } }

然后运行,本地会启动:3000,直接看效果

docsify serve

就是这样

目前还没有侧边栏,使用命令生成,它会根据目录自动帮我们创建一个_sidebar.md文件,就是我们的侧边栏。

docsify generate .

然后看看效果。这几乎是一样的。需要注意的是文件名不能有空格,否则生成的侧边栏目录会有问题。您需要修改文件名并将其替换为破折号或下划线。空格(我不明白为什么不能使用空格)。

多级目录生成问题

还有一个问题是不能生成多级目录,即不能超过二级目录。我随意更改了这个。

去docsify-cli的官方git仓库下载源码,然后把这个放进去,执行目录下的node generate.js,把最下面的test目录改成自己的目录。

'use strict'
const fs = require('fs')
const os = require('os')
const {cwd, exists} = require('../util')
const path = require('path')
const logger = require('../util/logger')
const ignoreFiles = ['_navbar', '_coverpage', '_sidebar']
// eslint-disable-next-line
function test (path = '', sidebar) {
  // 获取当前目录
  const cwdPath = cwd(path || '.')
  // console.log('cwdPath', cwdPath, !!exists(cwdPath));
  // console.log('///////', cwdPath, path, cwd(path || '.'))
  if (exists(cwdPath)) {
    if (sidebar) {
      const sidebarPath = cwdPath + '/' + sidebar || '_sidebar.md';
      if (!exists(sidebarPath)) {
        genSidebar(cwdPath, sidebarPath)

图片[1]-docsify,我觉得这种事情你不要老是让我操心啊-唐朝资源网

logger.success(`Successfully generated the sidebar file '${sidebar}'.`) return true } logger.error(`The sidebar file '${sidebar}' already exists.`) process.exitCode = 1 return false } return false; } logger.error(`${cwdPath} directory does not exist.`) } let tree = ''; function genSidebar(cwdPath, sidebarPath) { // let tree = ''; let lastPath = '' let nodeName = '' let blankspace = ''; let test = 0; const files = getFiles(cwdPath); console.log(JSON.stringify(files)); getTree(files); fs.writeFile(sidebarPath, tree, 'utf8', err => { if (err) { logger.error(`Couldn't generate the sidebar file, error: ${err.message}`) } }) return; getDirFiles(cwdPath, function (pathname) { path.relative(pathname, cwdPath) // 找cwdPath的相对路径 pathname = pathname.replace(cwdPath + '/', '') let filename = path.basename(pathname, '.md') // 文件名 let splitPath = pathname.split(path.sep) // 路径分割成数组 let blankspace = ''; if (ignoreFiles.indexOf(filename) !== -1) { return true } nodeName = '- [' + toCamelCase(filename) + '](' + pathname + ')' + os.EOL if (splitPath.length > 1) { if (splitPath[0] !== lastPath) { lastPath = splitPath[0] tree += os.EOL + '- ' + toCamelCase(splitPath[0]) + os.EOL } tree += ' ' + nodeName // console.error('tree=====', tree, splitPath, splitPath.length); } else { if (lastPath !== '') { lastPath = '' tree += os.EOL } tree += nodeName } }) fs.writeFile(sidebarPath, tree, 'utf8', err => { if (err) { logger.error(`Couldn't generate the sidebar file, error: ${err.message}`) } }) } function getFiles (dir) { // let path = require('path'); // let fs = require('fs'); let rootDir = dir; var filesNameArr = [] let cur = 0 // 用个hash队列保存每个目录的深度 var mapDeep = {} mapDeep[dir] = 0 // 先遍历一遍给其建立深度索引 function getMap(dir, curIndex) { var files = fs.readdirSync(dir) //同步拿到文件目录下的所有文件名 files.map(function (file) { //var subPath = path.resolve(dir, file) //拼接为绝对路径 var subPath = path.join(dir, file) //拼接为相对路径 var stats = fs.statSync(subPath) //拿到文件信息对象 // 必须过滤掉node_modules文件夹 if (file != 'node_modules') { mapDeep[file] = curIndex + 1 if (stats.isDirectory()) { //判断是否为文件夹类型 return getMap(subPath, mapDeep[file]) //递归读取文件夹 } } }) } getMap(dir, mapDeep[dir]) function readdirs(dir, folderName, myroot) { var result = { //构造文件夹数据 path: dir, title: path.basename(dir), type: 'directory', deep: mapDeep[folderName] } var files = fs.readdirSync(dir) //同步拿到文件目录下的所有文件名 result.children = files.map(function (file) { //var subPath = path.resolve(dir, file) //拼接为绝对路径 var subPath = path.join(dir, file) //拼接为相对路径 var stats = fs.statSync(subPath) //拿到文件信息对象 if (stats.isDirectory()) { //判断是否为文件夹类型 return readdirs(subPath, file, file) //递归读取文件夹 } if (path.extname(file) === '.md') { const path = subPath.replace(rootDir + '/', ''); // console.log(subPath, rootDir, '========', path); return { //构造文件数据 path: path, name: file, type: 'file',

图片[2]-docsify,我觉得这种事情你不要老是让我操心啊-唐朝资源网

deep: mapDeep[folderName] + 1, } } }) return result //返回数据 } filesNameArr.push(readdirs(dir, dir)) return filesNameArr } function getTree(files) { for (let i=0; i<files.length;i++) { const item = files[i]; if (item) { if (item.deep === 0) { if (item.children) { getTree(item.children) } } else { let blankspace = '' for (let i = 1; i < item.deep; i++) { blankspace += ' ' } // console.log('-' + blankspace + '-', item.deep) if (item.type === 'directory') { tree += os.EOL + blankspace + '- ' + toCamelCase(item.title) + os.EOL } else if (item.type === 'file') { tree += os.EOL + blankspace + '- [' + item.name + '](' + item.path + ')' + os.EOL // console.log('tree', tree); } if (item.children) { getTree(item.children) } } } } } function getDirFiles(dir, callback) { fs.readdirSync(dir).forEach(function (file) { let pathname = path.join(dir, file) if (fs.statSync(pathname).isDirectory()) { getDirFiles(pathname, callback) } else if (path.extname(file) === '.md') { callback(pathname) } }) } function toCamelCase(str) { return str.replace(/b(w)/g, function (match, capture) { return capture.toUpperCase() }).replace(/-|_/g, ' ') } test("/Users/user/Documents/JavaInterview/", "sidebar.md");

图片[3]-docsify,我觉得这种事情你不要老是让我操心啊-唐朝资源网

那岂不是万事大吉?看看最终效果。

nginx 配置

webhook 尚未完成。先手动push,然后上传文件到服务器,再设置nginx。

server {
    listen 80;
    listen [::]:80;
    server_name aixiaoxian.vip;
    client_max_body_size 1024m;
    location / {
        root /你的目录;
        index index.html;
    }
}
server {
    listen       443 ssl;
    server_name  aixiaoxian.vip;
    root         /usr/share/nginx/html;
    ssl_certificate cert/aixiaoxian.pem;
    ssl_certificate_key cert/aixiaoxian.key;
    ssl_session_cache shared:SSL:1m;
    ssl_session_timeout  10m;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
    ssl_prefer_server_ciphers on;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #表示使用的TLS协议的类型。
    include /etc/nginx/default.d/*.conf;
    location / {
        root /你的目录;
        index index.html;
    }
}

这时候你去reload nginx,你会发现网站可能是403。把你的ng文件的第一行改一下,不管后面是什么,改成root就大功告成了。

user root;

就是这样。

内网渗透

然后,你需要创建一个webhook程序,但是在此之前,为了在本地测试webhook的效果,你需要配置一个内网穿透程序,我们使用ngrok。

先安装。

brew install ngrok/ngrok/ngrok

然后你需要注册一个账号,这里没关系,直接用google登录,然后进入个人页面会提示使用步骤。

按照步骤添加令牌,然后映射端口 80。

如果以后发现找不到ngrok命令,可以去官网手动下载一个文件,放到/usr/local/bin目录下。

成功后可以看到ngrok的页面,使用他提供给我们的Forwarding地址,也就是我们的公网地址。

我做了一个随机的80端口,这里可以用自己项目的端口号来映射。我们稍后将其更改为 9000。

网络钩子

配置完成后,到我们的github项目中设置一个webhook,使用上面得到的地址。

设置OK,然后创建一个Java程序,监听9000端口,随便写个Controller。

@PostMapping("/webhook")
public void webhook(@RequestBody JsonNode jsonNode) {
	System.out.println("json===" + jsonNode);
}

© 版权声明
THE END
喜欢就支持一下吧
点赞264 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片