为什么要开发这款东西?

Typora 是一款 IT 界常用的 Markdown 笔记软件,它有强壮的 Markdown 语法功能。同时它也能够张贴图片、音频、视频等媒体文件。

一般,从剪切板张贴的图片都会默许保存到本地的 assets 同级目录中,文件称号为截图东西生成的称号。保存在本地虽然说能够长期保存,可是假如你要迁移你的文档到其他渠道的时分就很费事,比如说语雀、石墨等渠道。

假如你运用 Typora 提供的上传服务那得要架梯子,文件存储到国外服务器,不会科学上网的小伙伴就费事了。或许你公司或许要求所有文档相关图片要上传到公司的服务器,你也得自己搞一个上传东西。

选择作为图床的渠道

合适作为图床的渠道一般能够是云服务厂商提供的 OSS 存储服务渠道、代码托管渠道、公司自己搭建的 OSS 服务渠道。

下面以 Gitee 为例,调用 Gitee 的开发者 API 上传图片。

Gitee

Gitee 开发者文档

首先我们需要翻开 Gitee 的开发者文档官网:Gitee API 文档。然后找到上传文件的 API:

开发一款Typora自定义图片上传指令行东西,上传到你自己的图床!

而且之前你还需要取得 Gitee API 的授权,就在页面的右上角点击获取授权,笔者这儿已经获取授权了。

在图中,能够看到几个参数:

  • access_token:用户授权码,相当于令牌。
  • owner:是你的注册账号的用户名不是昵称。
  • repo:库房名。
  • path:文件在库房里边存储的路径。
  • content:文件的 base64 编码。
  • message:提交的消息。
  • branch:分支,默许是你的主分支。

接下来,先去获取用户授权码。点击设置,找到用户账号设置,找到私家令牌:

开发一款Typora自定义图片上传指令行东西,上传到你自己的图床!

创立令牌完结了之后,把令牌内容保存下来,由于只显示一次。

Typora 图片上传指令行文档

上述工作完结之后,找到 Typora 图片上传指令行文档:

开发一款Typora自定义图片上传指令行东西,上传到你自己的图床!

开发一款Typora自定义图片上传指令行东西,上传到你自己的图床!

简单来讲,Typora 在你张贴图片的时分会履行像这样的指令:

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

这个指令后边跟着多个参数表明多个图片文件。

最后你需要在控制台打印,如下内容:

Upload Success:


编写代码

在了解如上条件之后,我们接下来就开始编写代码。笔者运用 Go 开发这款东西,由于 Go 代码能够直接编译成二进制文件,正好契合 Typora 的要求。

定义呼应体结构体类型:

package main
type UploadFileResponse struct {  
    Commit Commit `json:"commit"`  
    Content Content `json:"content"`  
}  
type Commit struct {  
    Sha string `json:"sha,omitempty"`  
    Author string `json:"author,omitempty"`  
    Committer string `json:"committer,omitempty"`  
    Message string `json:"message,omitempty"`  
    Tree string `json:"tree,omitempty"`  
    Parents string `json:"parents,omitempty"`  
}  
type Content struct {  
    Name string `json:"name,omitempty"`  
    Path string `json:"path,omitempty"`  
    Size string `json:"size,omitempty"`  
    Sha string `json:"sha,omitempty"`  
    Type string `json:"type,omitempty"`  
    Url string `json:"url,omitempty"`  
    HtmlUrl string `json:"html_url,omitempty"`  
    DownloadUrl string `json:"download_url,omitempty"`  
    Links string `json:"_links,omitempty"`  
}

编写主函数:

package main
import (  
    "bytes"  
    "encoding/base64"  
    "encoding/json"  
    "errors"  
    "fmt"  
    "io"  
    "log"  
    "net/http"  
    "net/url"  
    "os"  
    "text/template"  
    "time"  
)
const (  
    giteeUploadApiTemplate = "https://gitee.com/api/v5/repos/{{.owner}}/{{.repo}}/contents/{{.path}}"  
    owner = "Lob" // 用户名  
    repo = "image-bed" // 图床库房称号  
    accessToken = "1ba4ac9113e5153bd128dc6" // accessToken改成你自己的  
    message = "图床上传图片"  
    branch = "master"  
)  
func uploadPic(path, content string) (string, error) {  
    tmplData := map[string]any{  
        "owner": owner,  
        "repo": repo,  
        "path": path,  
    }  
    formData := url.Values{  
        "access_token": {accessToken},  
        "content": {content},  
        "message": {message},  
        "branch": {branch},  
    }  
    tmpl, err := template.New("tmpl").Parse(giteeUploadApiTemplate)  
    if err != nil {  
        log.Println("Error parsing template:", err)  
        return "", errors.New("error parsing template")  
    }  
    var buf bytes.Buffer  
    err = tmpl.Execute(&buf, tmplData)  
    if err != nil {  
        log.Println("Error parsing template:", err)  
        return "", errors.New("error parsing template")  
    }  
    api := buf.String()  
    req, err := http.NewRequest(http.MethodPost, api, bytes.NewBufferString(formData.Encode()))  
    if err != nil {  
        log.Println("Error creating request:", err)  
        return "", errors.New("error creating request")  
    }  
    req.Header.Set("Content-Type", "application/x-www-form-urlencoded")  
    client := &http.Client{}  
    resp, err := client.Do(req)  
    defer resp.Body.Close()  
    if err != nil {  
        log.Println("Error sending request:", err)  
        return "", errors.New("error creating request")  
    }  
    byteArr, _ := io.ReadAll(resp.Body)  
    u := &UploadFileResponse{}  
    json.Unmarshal(byteArr, u)  
    return u.Content.DownloadUrl, nil  
}  
func main() {  
    parameters := os.Args[1:]  
    var picUrls []string  
    for _, parameter := range parameters {  
        now := time.Now()  
        // 反人类的时刻格式  
        path := fmt.Sprintf("%s.png", now.Format("2006-01-02 15:04:05"))  
        data, err := os.ReadFile(parameter)  
        if err != nil {  
            log.Printf("read file failed: %s", parameter)  
        }  
        content := base64.StdEncoding.EncodeToString(data)  
        picUrl, err := uploadPic(path, content)  
        if err != nil {  
            return  
        }  
        picUrls = append(picUrls, picUrl)  
    }  
    fmt.Println("Upload Success:")  
    for _, picUrl := range picUrls {  
        fmt.Println(picUrl)  
    }  
}

编译测验

go build -o /Users/element/go/bin/gitee-uploader

编译并保存到 GOPATH 下面,然后设置 Typora 的图片上传服务:

开发一款Typora自定义图片上传指令行东西,上传到你自己的图床!

最后测验一下是否成功:

开发一款Typora自定义图片上传指令行东西,上传到你自己的图床!

能够看见成功上传了。图片都在库房里边:

开发一款Typora自定义图片上传指令行东西,上传到你自己的图床!