Deepin15和20使用命令行快捷键鼠标右键发布博客至博客园和为知笔记

本博客具备很强的推广性,不限于博主使用的这些操作系统和博客平台

1. 引言

​ 在win10系统上,本人比较喜欢用为知笔记创作markdown博客,并通过其“分享到博客”的功能,发布博客到博客园。最近比较喜欢用Deepin系统作为主力操作系统,平时自己一些学习和实践的内容,很希望通过博客的方法发布出去,并保存在个人笔记中。

​ 但是为知笔记的Linux客户端劝退了我,同时又不希望使用博客园自带编辑器。因此花了点时间,做了一个替代方案,就是这篇博客的主要内容了。

​ 主要的思路分为两步:创作,发布。通过什么方式创作,和怎样发布。

2. 创作

在Linux下创建markdown文档,是非常容易的。比如在deepin系统,你可以通过以下三种方式:

  1. vim编辑器
  2. typora编辑器
  3. vscode编辑器

vim 是自带编辑器,不比多说,适用于习惯vim操作的用户,比如我自己。创建markdown时,只要使用markdown语法就可以了。网上有很多vim支持markdown语法或者markdown(实时预览)的插件,估计配置比较复杂吧,我本人也不推荐配置vim实时预览markdown的方式。比较推荐浏览器插件打开本地.md文件进行预览的方式。推荐一个markdown priview plus的谷歌插件,但是样式不太好,可以自己加载别的样式。

vscode编辑器能够很好地支持vim插件,支持markdown及其预览的插件。也是非常不错的选择。

最后我选择了typora编辑器。它即可预览你所创作的文档,可选多种样式,能够支持侧边栏和大纲,像极了一款本地笔记本。如果配上就坚果云的同步,图库等,更像一款云笔记了。具体的功能这里不多说,有兴趣的同学可以自己去摸索。

本篇就是通过typora编辑创作。让人专注于内容编排。唯一不足的可能就是不支持vim编辑器。

综上,选择创作的方式,目的是创建一篇markdown格式的文档,这很容易实现。

重要的是创作完成之后,该如何发布出去。且看下文。

3. 发布

本篇博客主要想介绍3种发布方式,2种发布对象,涉及deepin系统的两个操作系统版本。

3.1 发布对象

博客园,为知笔记是我比较喜欢的组合。也许网友们有更多的其他选择,比如CSDN,开源中国,51CTO,掘金,简书,个人博客等。比较方面有有道云笔记,印象笔记,onenote,蚂蚁笔记等。

其实看懂了这篇博客,很容易主动学习和动手操作,应用到别的平台。希望大家有所收获。

很多东西我自己有很多都是现学现卖的,面向搜索引擎的编程......

确定了发布对象,就需要了解如何不登录就可以发布了。这要得益于这些平台开放API功能。

3.1.1 博客园的开放API

API在哪里

要使用博客园的API发布自己的博客,需要在自己博客里面设置允许这样的操作。

具体的设置地方,在自己博客后台管理-设置-最后几行,有允许MetaWeblog博客客户端访问的勾选项

同时也可以看到MetaWeblog的访问地址(因人而异),点击这个url,就可以看到提供的api接口了。

如何使用API

Deepin系统调用这些API很方便,因为Deepin自带了Python3。

Python3如果需要使用这些API,需要import一个库,xmlrpc.client库。如果系统没有这个库,可以先安装。

sudo apt-get install python3-pip
sudo pip3 install xmlrpc.client

如果Python3 能够导入这个xmlrpc.client的话,基本上就成功一大半了。

下面的工作,就是编程了,可以先参考这篇CSDN博客

编写发布程序

已经万事具备了 ,只需要创建发布脚步。下面是我的代码,我把它命名为send_to_cnblogs.py

#!/usr/bin/python3
# 本脚本发送博客至www.cnblogs.com

import sys
import xmlrpc.client

class MyCnblogsAPI():

    def __init__(self):
        self.cnblogs_api = xmlrpc.client.ServerProxy("https://rpc.cnblogs.com/metaweblog/你的博客地址")
        self.user = '博客园登录用户名'
        self.password = '博客园登录用户密码'
        self.blogid = self.__get_user_info()[0].get('blogid')

    def __get_user_info(self):
        return self.cnblogs_api.blogger.getUsersBlogs('',self.user,self.password)

    def get_all_blogs(self):
        """
        获取全部文章
        """
        blog_id_title = {}
        allblogs = self.cnblogs_api.metaWeblog.getRecentPosts(self.blogid,self.user,self.password,0)
        for b in allblogs:
            blog_id_title.update({b.get('title'):b.get('postid')})
        return blog_id_title

    def get_post_id(self,post_name):
        """
        通过指定的博客名字获取对应的postid
        """
        return self.get_all_blogs().get(post_name)
    
    def edit_post(self,blog_path):
        """
        重新编辑和发布
        """
        post_name = blog_path.split('/')[-1].split('.')[0]
        post_id = self.get_post_id(post_name)
        with open(blog_path,'r') as blog:
            blog_content = blog.read()

        post_info = {
                'title':post_name,
                'description':blog_content,
                'categories':['[]','[Markdown]'],#默认不发布到博客园首页候选区,默认markdown
        }

        if post_id:
            print("文章已经存在,更新!")
            self.cnblogs_api.metaWeblog.editPost(post_id,self.user,self.password,post_info,True)
        else:
            print("没有这篇文章,新建!")
            self.cnblogs_api.metaWeblog.newPost(self.blogid,self.user,self.password,post_info,True)

if __name__ == "__main__":
    if len(sys.argv) != 2:
        print("未指定文章")
        sys.exit(0)
    markdown_file = str(sys.argv[1:][0])#这部分未做更加详细的解析,请留意
    my_blog = MyCnblogsAPI()
    my_blog.edit_post(markdown_file)

上面的代码主要实现了通过参数指定要发布markdown文件,发布该markdown文件内容到博客园的功能。

这个使用,只要在终端执行python3 send_to_cnblogs.py xxx.md就可把xxx发不到博客园了。

3.1.2 为知笔记的开放API

API在哪里

为知笔记的API地址在这里

官方很贴心地给出了优秀的示例代码,按照他们给的代码,很容易实现对自己为知笔记的操作。

如何使用API

该API是需要用js实现交互的。本人js零基础,只能面向搜索引擎编程了。

首先阅读一下为知笔记API快速入手(实际上我们只是发布文章,也不需要太过复杂的功能),从快速入手的代码,很容易就上手了。

没上手也没关系,我的代码改改就行。要改的很少很少,主要是环境部署.....

编写发布程序

Deepin也很容易使用nodejs,如果没有安装,命令行执行安装就行。

在Deepin 15.11 上,执行sudo apt-get install node npm

在Deepin V20上,执行sudo apt-get install nodejs npm

暂时不需要关注node的版本

下来看看我的代码段,我命名为send_to_wiz.js

//注意:如果下面三个包没有的话,deepin命令行执行npm install xxx即可。有包管理器就是方便。
var fs = require("fs")
var program = require("commander")
var linerByLine = require("n-readlines")

const axios = require('axios');
const AS_URL = 'https://as.wiz.cn';

//这里主要是通过命令行指定文件,因为要集成到deepin的文件管理器右键。它的右键实际就是用文件名做参数,调用你的命令。
program
    .option('-f, --file <type>','add filename')
    .parse(process.argv)

async function execRequest(method, url, body, token) {
  const options = {
    url,
    method,
    data: body,
  };
  if (token) {
    options.headers = {
      'X-Wiz-Token': token,
    };
  }
  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;
}

async function login(userId, password) {
  return await execRequest('post', `${AS_URL}/as/user/login`, {userId, password});
}

async function createNote(kbServer, kbGuid, title, folder, html, extOptions, token) {

  const url = `${kbServer}/ks/note/create/${kbGuid}`;
  let note = {
    kbGuid,
    title,
    category: folder,
    html,
  };
  if (extOptions) {
    note = Object.assign(note, extOptions);
  }
  return await execRequest('post', url, note, token);
}

 async function wiz_api(mdfile,noteHtml) {
  const userId = '为知笔记登录账号';
  const password = '为知笔记登录密码';
  try {
    const loginResult = await login(userId, password);
    const {kbServer, kbGuid, token} = loginResult;
	//js的字符串分割,避免绝对路径的干扰
	const title = mdfile.split('/').pop()
    const newNote1 = await createNote(kbServer, kbGuid, title, '/Deepin/', noteHtml, null, token);//Deepin表示要上传笔记到哪个文件夹
  } catch (err) {
    if (err.externCode === 'WizErrorInvalidPassword') {
      console.error('Invalid password');
    } else {
      console.error(err.message);
    }
  }
}
//这里其实很重要,我摸索了快一天 。
//如果以js读取文件转化为字符串的话,markdown问被分享到为知笔记的时候,不会被正确渲染为markdown
//然后我想到了typora里面有个</br>的标记,索性就按行读取,每行后面添加换行符,果然凑效。
if (program.file){
	const liner = new linerByLine(program.file);
	let line;
	let str = '';
	while (line = liner.next()){
		str += line + '</br>';
	}
	wiz_api(program.file,str);
}

Deepin 15.11,命令行执行node send_to_wiz.js -f xxx.md

Deepin V20,命令行执行nodejs send_to_wiz.js -f xxx.md

即可把xxx.md发布到为知笔记

3.2 发布方式

3.2.1 命令行

如果使用命令行发布,很简单,因为上面的代码均提供了通过参数来指定要发布的markdown博客。

比如要发布"我的博客.md"

发布博客园

终端执行python3 send_to_cnblogs.py 我的博客.md

发布到为知笔记

Deepin 15.11执行node send_to_wiz.js -f 我的博客.md

Deepin V20执行nodejs send_to_wiz.js -f 我的博客.md

3.2.1 快捷键

Deepin设置快捷键很方便,但是快捷键里面的命令是不包含参数的,该如何?

很简单,通过shell脚步调用粘贴板,就可以轻松实现。

比如要发不到博客园的脚本,可以命名为:send_to_cnblogs.sh,内容如下:

#!/bin/bash
# 本脚步用于发送博客到博客园
# python路径
PYTHON="/usr/bin/python3"
# 指定程序所处目录
LOCATION="/home/liwl/.myscripts/cnblogs"
# 指定使用的发送程序
SCRIPT="send_to_cnblogs.py"
# 获取粘贴板的文章
MARKDOWNBLOG=$(xsel --output --clipboard)
# 发送
${PYTHON} ${LOCATION}/${SCRIPT} ${MARKDOWNBLOG}

send_to_cnblogs.sh保存在任何路径都可以,设置快捷键时,指定该脚步的绝对路径即可。

注:Deepin系统下执行sudo apt-get install xsel安装脚步中的xsel工具

要发布到为知笔记的脚本,可以命名为:send_to_wiz.sh,内容如下:

#!/bin/bash
# 本脚本用于发送选中的文件(终端双击选中或者文件管理器ctrl+c复制)到为知笔记
# node路径
NODE="/usr/bin/node"
# 指定程序所处目录
LOCATION="/home/liwl/.myscripts/wiz"
# 指定使用的发送程序
SCRIPT="send_to_wiz.js"
# 获取粘贴板的文章
MARKDOWNBLOG=$(xsel --output --clipboard)
# 发送
${NODE} ${LOCATION}/${SCRIPT} -f ${MARKDOWNBLOG}

send_to_wiz.sh保存在任何路径都可以,设置快捷键时,指定该脚本的绝对路径即可。

注:Deepin设置快捷键。全局快捷键在“控制中心-键盘-快捷键”,命令行快捷键在“终端-右键-自定义命令”

接下来就是发送博客了

如果要发送文档,也有两种方式:

  1. 终端命令行选中文件发送。双击文件名,按下快捷键。
  2. 文件管理器选中文件发送。需要按下crtl+c复制,然后按下快捷键。

3.2.3 鼠标右键

上面两部分实现了命令行和快捷键盘的发送博客到博客园或者为知笔记的功能。

如果此刻你正端着咖啡聊天,或者拿着手机跟女朋友电话,正好空出了无处安放的右手,希望把刚刚写完的博客发送出去,该怎么办?

没错,右键!

Deepin的右键拓展,从15.11到V20,有了质一般的飞跃。两者可能大有不同。

个人感觉还是V20的右键扩展更加友好和强大一些。

Deepin 15.11右键

根据官方提供的方式,用户如果需要扩展文件管理器鼠标右键的功能,需要在自己的

~/.config/deepin/dde-file-manager目录下,

创建一个menuextensions的目录,

然后进入到这个目录,创建任何一个json文件,

比如我的叫做:send_to.json的文件,我在该文件实现了二级目录。

关于Deepin 15.11 右键扩展可以参照简书的这篇博客

其内容如下:

[
	{
		"MenuType":"SingleFile",
		"MimeType":"text/md",
		"Suffix":"md;txt;",
		"Icon":"",
		"Text[zh_CN]":"发送到",
		"SubMenu":[
			{
				"Text[zh_CN]":"博客园",
				"Exec":"/home/liwl/.myscripts/cnblogs/send_to_cnblogs.sh"
			},
			{
				"Text[zh_CN]":"为知笔记",
				"Exec":"/home/liwl/.myscripts/wiz/send_to_wiz.sh"
			}
		]
	}
]

具体含义大概解释一下吧:

MenuType,右键扩展菜单生效的类型:单个文件,单个目录,多个文件,多个目录,空白区域

MimeType,右键扩展菜单生效的文件:text的markdown或者txt类型

Icon,图标

Text,显示的名称

Exec,执行的命令

SubMenu,表示产生二级菜单

特别注意:Deepin 15.11 通过右键发送时,必须按下crtl+c或者右键选择复制,先把博客名字粘贴到剪切板!

Deepin V20的右键扩展

Deepin V20提供了更加友好的右键拓展,这里给深度工程师点赞。

终端执行su - root,切换到root用户

cd /usr/share/deepin/dde-file-manager/oem-menuextensions,进入到该目录

创建一个desktop的后缀文件,touch deepin-liwl-send.desktop,内容如下

[Desktop Entry]
Type=Application
Name=发送到
Actions=SendToCnlogs;SendToWiz
X-DFM-MenuTypes=SingleFile
MimeType=text/markdown

[Desktop Action SendToCnblogs]
Name=博客园
Exec=python3 /home/liwl/.myscripts/cnblogs/send_to_cnblogs.py %U
Icon=text-x-markdown.svg

[Desktop Action SendToWiz]
Name=为知笔记
Exec=nodejs /home/liwl/.myscripts/wiz/send_to_wiz.js -f %U
Icon=text-x-markdown.svg
# %U 就是右键选中的文件,在Deepin V20中,不需要按ctrl+c复制文件了...

注:更加详细的字段说明,请参照这里的官方文档说明

截止到这里,基本完成了全部内容。感觉博客内容已经很详细了,希望对大家有所帮助。

以后就可以愉快地在Linux下进行开发运维工作,以及及时记录与分享所学所得。

原文地址:https://www.cnblogs.com/liwanliangblog/p/12794179.html