deepin上博客发送到为知笔记
1. 背景
之前已经做过一个版本的《deepin15和20使用命令行快捷键鼠标右键发布博客之博客园和为知笔记》,其主要思路是已经创建好markdown格式的博客。
typora是所见即所得的markdown的编辑器,提供了很棒的创作体验。
如果想把typora的博客,分享到网络平台,那么typora上粘贴的图片(存放在本地),就无法把图片上传。后来typora提供了对图床的支持,还有使用命令方式上传到服务器的支持。
我基于此,把之前的代码改了该,能够实现使用typora创作的博客,完美发布到博客园《deepin优雅地创作和分享博客》
但是尝试使用这个方式来实现使用typora创建博客并发送到为知笔记时,发现没法实现。最近改了代码,还是无法实现,主要原因可能是为知笔记提供的接口,其图片链接不是全局的,因为不像博客园那样,像个图床。
我思来想去 ,如果非要使用typora创作,简直就是自略。更何况现在为知笔记已经有Linux版本了(虽然它的编辑体验和markdown格式太low)
就这样吧,不折腾了。
不过,如果要用命令行来写的话,应该没啥问题。后面如果有兴趣了再完善吧,下面贴一下半成品代码
2. deepin上具体操作
- 把代码粘贴复制到一个目录下,比如/home/liwl/.liwl/deepin/scripts/目录
- 在/home/liwl/.liw/deepin/scripts/目录创建配置文件,格式看下文
- 创建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编程吧
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?