• deepin上博客发送到为知笔记


    1. 背景

    之前已经做过一个版本的《deepin15和20使用命令行快捷键鼠标右键发布博客之博客园和为知笔记》,其主要思路是已经创建好markdown格式的博客。

    typora是所见即所得的markdown的编辑器,提供了很棒的创作体验。

    如果想把typora的博客,分享到网络平台,那么typora上粘贴的图片(存放在本地),就无法把图片上传。后来typora提供了对图床的支持,还有使用命令方式上传到服务器的支持。

    我基于此,把之前的代码改了该,能够实现使用typora创作的博客,完美发布到博客园《deepin优雅地创作和分享博客》

    但是尝试使用这个方式来实现使用typora创建博客并发送到为知笔记时,发现没法实现。最近改了代码,还是无法实现,主要原因可能是为知笔记提供的接口,其图片链接不是全局的,因为不像博客园那样,像个图床。

    我思来想去 ,如果非要使用typora创作,简直就是自略。更何况现在为知笔记已经有Linux版本了(虽然它的编辑体验和markdown格式太low)

    就这样吧,不折腾了。

    不过,如果要用命令行来写的话,应该没啥问题。后面如果有兴趣了再完善吧,下面贴一下半成品代码

    2. deepin上具体操作

    1. 把代码粘贴复制到一个目录下,比如/home/liwl/.liwl/deepin/scripts/目录
    2. 在/home/liwl/.liw/deepin/scripts/目录创建配置文件,格式看下文
    3. 创建deepin右键发送菜单选项

    大致就是这三步,很简单

    3. 代码

    下面代码,粘贴复制为send_to_wiznote.js,放到一个目录下,在该目录下创建一个wiznote.json,内容如下:

    #!/usr/bin/node
    /*
    1. sudo apt install nodejs,npm
    2. npm install fs,commander,n-readlines,axiso //全局安装使用sudo npm install -g xxx,并且需要添加环境变量,NODE_PATH
    3. update:
        2021-06-24 更新:在deepin20.2.2版本上,通过sudo apt install nodejs npm,npm的版本安装的commander调用是program.opts().file,而非之前的program.file
        2021-12-12 更新: 对相同标题的笔记,进行更新操作(先删除,后更新)
    */
    
    //
    //通过npm安装以下模块
    const fs = require("fs")
    const program = require("commander")
    const linerByLine = require("n-readlines")
    const FormData = require('form-data')
    const path = require('path')
    const axios = require('axios');
    const AS_URL = 'https://as.wiz.cn';
    const CONFIG_JSON = 'wiznote.json'
    
    //通过命令行参数指定文件,便于使用命令行,或者右键
    program
        .option('-f, --file <type>','add filename')
        .option('-i, --image <type>','add image')
        .option('-l, --list','list note')
        .parse(process.argv)
    
    /***********************************************************************************
        execRequest:获取token
    ***********************************************************************************/
    async function execRequest(method, url, body, token,headers) {
      const options = {
        url,
        method,
        data: body,
      };
      if (token) {
        options.headers = {
          'X-Wiz-Token': token,
        };
      }
      if (headers) {
        options.headers = Object.assign({}, options.headers || {}, headers);
      }
    
      const res = await axios(options);
      const data = res.data;
      if (data.returnCode !== 200) {
        console.error(`request error: ${data.returnMessage}`);
        const err = new Error(data.returnMessage);
        err.code = data.returnCode;
        err.externCode = data.externCode;
        throw err;
      }
      return data.result
    }
    
    /***********************************************************************************
    *   login:登陆
    ***********************************************************************************/
    async function login(userId, password) {
      return await execRequest('post', `${AS_URL}/as/user/login`, {userId, password});
    }
    
    /***********************************************************************************
    * createNote: 创建笔记
    ***********************************************************************************/
    
    async function createNote(kbServer, kbGuid, title, folder, html, extOptions, token) {
      const url = `${kbServer}/ks/note/create/${kbGuid}`;
      let note = {
        kbGuid,
        title,
        category: decodeURI(folder), //注意,这里对中文乱码进行解码
        html,
      };
      console.log(note) 
      if (extOptions) {
        note = Object.assign(note, extOptions);
      }
      return await execRequest('post', url, note, token);
    }
    
    /***********************************************************************************
    * deleteNote: 删除笔记
    ***********************************************************************************/
    async function delateNote(kbServer,kbGuid,docGuid,token){
        const deleteUrl = `${kbServer}/ks/note/delete/${kbGuid}/${docGuid}`
        console.log("准备删除")
        return await execRequest('delete',deleteUrl,null,token)
    }
    
    /***********************************************************************************
    * listNote: 查询笔记
    ***********************************************************************************/
    async function listNote(kbServer,kbGuid,folder,token){
        const listUrl = `${kbServer}/ks/note/list/category/${kbGuid}?category=${folder}&withAbstract=false&start=0&count=100&orderBy=created&ascending=desc`
        return await execRequest('get',listUrl,null,token)
    }
    
    /***********************************************************************************
    * uploadImage: 上传图片
    ***********************************************************************************/
    async function uploadImage(kbServer,kbGuid,docGuid,imageFile,token){
        const uploadUrl = `${kbServer}/ks/resource/upload/${kbGuid}/${docGuid}`
        const formData = new FormData();
        formData.append('kbGuid',kbGuid);
        formData.append('docGuid',docGuid);
        formData.append('data',fs.createReadStream(imageFile),{
           filename: path.basename(imageFile) 
        })
        const headers = {
            ...formData.getHeaders(),
        }
        return await execRequest('post',uploadUrl,formData,token,headers)
    }
    
    /******************************脚本主要功能***************************************/
    
    /***********************************************************************************
    * 创建或者更新笔记
    * 逻辑还需要完善一下,删除的笔记,其图片不会其他笔记显示。
    * 没有笔记时,创建空笔记,创建图床地址。新笔记通过更新的方式。
    * 有笔记时,清空笔记内容(相当于创建笔记),然后上传图片
    ***********************************************************************************/
    async function uploadNoteFile(noteFileAbsPath,imageFileAbsPath=null) {
    
        //从配置文件获取用户帐号,密码,默认上传目录
        let data = JSON.parse(fs.readFileSync(CONFIG_JSON,'utf-8'))
        const userId = data.userId
        const password = data.password
        const folder = encodeURI(data.category)
    
        //获取用户登陆信息
        const loginResult = await login(data.userId, data.password);
        const {kbServer, kbGuid, token} = loginResult;
    
        //获取笔记的名称.注意:xxx.md和xxx的笔记的guid不一样
            const noteTitle = noteFileAbsPath.split('/').pop()
    
        /*查询笔记是否已经存在。存在则删除*/
        await listNote(kbServer,kbGuid,folder,token).then(res=>{
    
            //获取目录笔记标题
            let titles = []
            let docGuid = []
            res.forEach(e =>{
                titles.push(e.title)
                docGuid.push(e.docGuid)
            })
    
            //判断要操作的笔记是否已经存在,存在通过docGuid删除笔记
            if (titles.includes(noteTitle)){
                let guid = docGuid[(titles.indexOf(noteTitle))]
                delateNote(kbServer,kbGuid,guid,token)
            }
        })
    
    
        /*创建笔记*/
        console.log("开始创建笔记")
        /**
        * 获取博客内容
        **/ 
        const liner = new linerByLine(noteFileAbsPath)
        let line;
        let noteContent = '';
        while (line = liner.next()){
            noteContent += line + '</br>'; //为markdown每一行添加换行,以便正确解析语法
        }
        //
        //const newNote1 = createNote(kbServer, kbGuid, noteTitle, folder, noteContent, null, token);
        //console.log("创建笔记结束");
        createNote(kbServer, kbGuid, noteTitle, folder, noteContent, null, token).then(res=>{
            //创建笔记结束后,把图片上传,返回图片的url
            guid = res.docGuid
            console.log(guid)
            if(imageFileAbsPath){
                uploadImage(kbServer,kbGuid,guid,imageFileAbsPath,token).then(res=>{
                    console.log("图片url:")
                    url = `https://www.wiz.cn/xapp/ks/note/view/${kbGuid}/${guid}/`+res.url
                    //console.log('https://www.wiz.cn/xapp/ks/note/view/'res.url)
                    console.log(url)
                }) //打印图片的url
            }
        });
    
    }
    
    if (program.opts().file){
            uploadNoteFile(program.opts().file);
        console.log("更新博客")
        if (program.opts().image){
            console.log("上传图片")
            uploadNoteFile(program.opts().file,program.opts().image);
        }
    } 
    

    4. 配置

    创建配置文件名称:wiznote.json,路径跟脚本路径一致,格式如下:

    配置文件可以随便改动,保证脚本代码能加载就行。其引入脚本的代码:const CONFIG_JSON = 'wiznote.json'

    {
        "userId": "为知笔记帐号",
        "password": "为知笔记密码",
        "category": "/要上传的目录/"
    }
    

    5.deepin创建右键发送菜单选项

    deepin操作系统下,终端执行sudo vim /usr/share/deepin/dde-file-manager/oem-menuextensions/deepin-send.desktop

    内容如下,保存退出

    [Desktop Entry]
    Type=Application
    Name=发布文档到
    Actions=SendTocnblogs;SendTonsccwx;SendTowiznote
    X-DFM-MenuTypes=SingleFile
    MimeType=text/markdown
    
    [Desktop Action SendTowiznote]
    Name=为知笔记
    Exec=nodejs /home/liwl/.liwl/deepin/scripts/send_to_wiznote.js --file %U
    Icon=send-to
    

    6. 总结

    这个js脚本,仅仅实现了,不含图片的笔记创作及更新,然后右键发送。

    相比以前的版本,也就是多了一个同一个笔记文件,更新发布的功能。

    算是个半成品吧,以后有空再完善,这次就当练习js编程吧

    【 欢迎交流探讨!邮箱:yunweinote@126.com】
  • 相关阅读:
    Unity 绘制带颜色的流线 streamline
    Tinyply 源码阅读
    题解 [BZOJ2952]长跑
    莫比乌斯反演技巧
    题解 pyh的求和
    Java Web基础
    后端常用数据持久层模板及框架以及一些工具类模板的配置使用集合
    12306火车订票系统(C++)
    C++/Java文件读写并执行相关操作、文件复制、文件格式转换等(举例)
    《Java EE编程技术》综合应用系统开发_作业管理系统_Struts2_设计报告
  • 原文地址:https://www.cnblogs.com/liwanliangblog/p/15682028.html
Copyright © 2020-2023  润新知