0%

python编写typora插件实现传图到chevereto

前言

如何优雅的写博客?

在折腾图床的道路上一去不复返了2333333

为了解决markdown写博客的时候的图片引用问题,我搭建了一个图床,使用的程序是chevereto,图片引用的问题解决了,但是写博客的时候传图还是不够优雅,所以我又折腾了typora的插件,详细请看:

typora-chevereto之博客图片终极解决方法

这篇文章算是上一篇的后续,炒了个冷饭,不过确实找到了一个更优雅的办法。

起因是昨晚写了typora上传插件之后,正好typora又更新了,嘿真巧哈哈哈哈,然后因为window.html被覆盖回去了,要想启用就必须要重新修改,添加对上传插件的引用。

然后我在看更新日志的时候,看到typora其实是支持自定义上传的,只是需要自己写一个接口。

这么做的好处就是不用修改typora的程序文件了,最大化的减少了自定义插件对typora浏览器行为的影响。

写博客中途可以任意修改图片,写完后一键上传全部图片即可。避免了中途频繁修改导致图床中大量垃圾图片的问题。

自定义脚本可以独立维护,也可以使用typora的批量上传功能,更加的方便。

准备工作

首先看官方文档中对于自定义上传的介绍:

您可以使用上述选项中未列出的工具配置自定义命令以上传图像,或者编写自己的工具/脚本。Typora将在您填充自定义命令后附加需要上传的所有图像。

然后,Typora将从您的自定义命令的标准输出的最后N行获取图像url。(N是要上传的图像数)。

例如,如果编写工具upload-image.sh,则可以[some path]/upload-image.sh在命令字段中输入。Typora将调用[some path]/upload-image.sh "image-path-1" "image-path-2"上传位于image-path-1和中的两个图像image-path-2。然后,该命令可能会返回类似以下内容的内容:

1
2
3
Upload Success:
http://remote-image-1.png
http://remote-image-2.png

然后,Typora将从输出中获取两个远程图像URL,并替换Markdown文档中使用的原始本地图像。

您可以单击“测试上传器”按钮来验证您的自定义命令。

大概就是你可以给typora指定一个命令来调用你自己的脚本,然后typora会从脚本的输出结果中读取上传后的url并替换。

typora执行的命令是如下形式:

1
[some path]/upload-image.sh "image-path-1" "image-path-2"...

脚本代码

因为之前在批量将hexo文章中的本地图片转到chevereto图床这篇文章里写过python上传chevereto的代码,所以代码都是现成的,然后我花了十分钟拼了一个:

upload.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#!/usr/bin/env python3
# -*- encoding: utf-8 -*-
# author: guiu
# data: 2020.2.28

import requests
import json
import mimetypes
import argparse
import sys

APP_DESC = """
一个上传图片到chevereto图床的命令行工具
"""

print(APP_DESC)
if len(sys.argv) == 1:
sys.argv.append('--help')

parser = argparse.ArgumentParser()
parser.add_argument('-s', '--source', type=str, nargs='+', help="", required=True)
parser.add_argument('-c', '--config', default="./config.json", help="读取配置文件", required=True)
args = parser.parse_args()

# 从参数中获取要上传的文件列表
img_list = args.source
# print(img_list)

def read_conf(path):
with open(path,"r",encoding="utf-8") as f:
confstr = f.read()
conf = json.loads(confstr)
return conf

def up_to_chevereto(img_list):
# 获得本地图片路径后,上传至图床并记录返回的json字段
for img in img_list:
# 先判断传过来的是本地路径还是远程图片地址
if "http" == img[:4]:
# 非本地图片的话可以考虑下载到本地再上传,但是没这个必要
print(img)
continue
else:
try:
res_json = upload(formatSource(img))
parse_response_url(res_json,img)
except:
print(img+"\t上传失败")

def upload(files):
# 图床api
# APIKey = "THERE PUT YOUR APIKEY"
conf = read_conf(args.config)
url = conf['url'] + "?key=" + conf['APIKEY']
r = requests.post(url, files=files)
return json.loads(r.text)

def formatSource(filename):
imageList = []
mime_type = mimetypes.guess_type(filename)[0]
imageList.append(
('source', (filename, open(filename, 'rb'), mime_type))
)
#print (imageList)
return imageList

def parse_response_url(json, img_path):
# 从返回的json中解析字段
if json['status_code'] != 200:
print("{}\tweb端返回失败,可能是APIKey不对. status_code {} .".format(
img_path, json['status_code'])
)
else:
img_url = json["image"]["url"]
print(img_url)

up_to_chevereto(img_list)

因为后面想写成脱离typora也能使用的上传工具,所以写成了参数从配置文件中读取的形式。

另外需要创建一个config.json

config.json
1
2
3
4
{
"APIKEY": "YOUR API KEY",
"url": "http://your_website/api/1/upload/"
}

然后打开typora -> 文件 -> 偏好设置 -> 图像 -> 上传服务设定

image-20200228191047314

上传服务选Custom Command,自定义命令中填:

1
python3 /your_script_path/upload.js -c /your_config_path/config.json -s

然后点击验证图片上传选项,如果配置正确会出现:

image-20200228191625983

然后就可以优雅的在你的博客中插图了。

然后只需要在要上传的图片上右键点击 -> 上传图片就可以了。

然后写博客的流程就成了:

  1. Hexo new "new_article_title"
  2. 打开typora,编辑new_article_title.md
  3. 该怎么写就怎么写,添加图片就粘贴进去即可
  4. 写完后,点击:格式 -> 图像 -> 上传所有本地图像
  5. 收工

Like this:

image-20200228195145417

优雅~

后记

typora的技术栈是Electron,这是一个用前端技术构建跨平台桌面应用的运行环境。

所以我们看到的功能其实是基于JavaScriptchromium实现的,因此我们也可以像写chrome扩展一样来自定义typora的一些行为。包括之前提到的自定义upload.js插件上传图片,也是基于这个原理的。