为 Typora 部署自动图片上传服务

Table of Contents

之前的 posts 几乎都是 plain text. 原因在于,为 Markdown 文章添加配图是很累的事情(倒不如说添加配图本来就很累)。并且由于不信任中国图床,使用外国图床又会导致中国境内加载困难,所以仅有的一篇带配图的 post 城市迷思,其配图走的是 WordPress 添加 media 的方式。

这种方式不仅限制繁多,而且相当麻烦,所以我几乎不为文章加配图。当然也意识到,一篇完全没有配图的文章,有时候可读性是很差的。I get it.

所以准备用之前早就搭好的 nextcloud 部署一个 self-host 的图床。原理和暑期项目部署的图床是一样的。

Step 1

  1. 为 nextcloud 安装 Sharing Path。

  2. 开一个专门的图床账户。

  3. 新建一个用于存放图片的 folder。

  4. 配置 Sharing Path。

总之 Copy prefix 就是https://{Your cloud URL}/apps/sharingpath/{Account name},Sharing folder 如实填写就行。


用 Postman 测试了一下,成了。填好 Basic Auth;

PUT https://{Your cloud URL}/remote.php/dav/files/{Account name}/{Sharing folder}/{pic_filename}

上传成功。直链就是https://{Your cloud url}/apps/sharingpath/{Account name}/{Shared folder}/{pic_filename}

Step 2

现在为 Typora 部署图片自动上传图床的服务

在 Typora 上传图片的文档里写得挺清楚的。以 shell 脚本为例,就是写一个能够以XXX.sh pic1.png pic2.png形式运行的服务即可。要求在标准输出中返回以下内容:

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

于是就写了个 java 程序然后打 jar 包,用 shell 包装下。

Java part

只是一个用了 okhttp 的简单 CLI 程序而已。

准备部分:

final String picSvrUrl = "https://XXX";
final String picDirectURL = "https://YYY";
final String picSvrAuth = "Basic ZZZ";

picSvrUrl就是接下来 PUT 图片的 url,用 nextcloud 的 webdav 即可。

picDirectUrl就是返回图片的直链根地址,这里是上文的https://{Your cloud url}/apps/sharingpath/{Account name}/{Shared folder}/

picSvrAuth放在 cookie 中的用于认证的字符串。这里用的是 Basic Auth。


接下来就是循环把每个参数对应的图片文件上传。

System.out.println("Upload Success:");  // Typora 的要求;事实上偷懒了,没有做 fail 的情况 qwq
for (String filename : args) {  // 遍历参数
    File f = new File(filename);
    FileInputStream fis = null;
    try {
        fis = new FileInputStream(f);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
    byte[] bytes = null;
    try {
        bytes = fis.readAllBytes();
    } catch (IOException e) {
        e.printStackTrace();
    }
    OkHttpClient client = new OkHttpClient().newBuilder()
            .readTimeout(10, TimeUnit.SECONDS)
            .writeTimeout(10, TimeUnit.SECONDS)
            .connectTimeout(10, TimeUnit.SECONDS)
            .build();
    RequestBody requestBody = RequestBody.create(bytes);
    Request request = new Request.Builder().url(picSvrUrl + f.getName())
            .addHeader("Authorization", picSvrAuth)
            .put(requestBody).build();
    try(Response ignored = client.newCall(request).execute()){
    // ignored 是因为并不在乎 response 的内容
    }catch (IOException e){
        e.printStackTrace();
    }
    System.out.println(picDirectURL + f.getName());
    // 输出要的直链
}

Shell part

#!/bin/bash
java -jar XXX.jar $@

说实话日常不用的 shell 早就忘完了,连开头的注释都忘记怎么打(

$@表示全部参数。

还有就是 Typora 调用的时候并不是相对路径,换言之pwd的结果并不是 jar 文件所在的地方,因此脚本中 jar 文件也要写绝对路径。(除非再打包一层 like deb package / 加环境变量)

Step 3

Now you can test the script out in Typora. It has built-in test for your custom command.

Known bugs

图片名称中不能有空格。

Share