repo

:tada:简介

gopic 是一个图床工具,用来上传到七牛云或者github 等,使用简单,容易开发插件,全并发,充分解耦

:zap:使用

安装

:scroll:从源码安装

1
2
3
4
$ git clone https://github.com/OSTGO/gopic/commits/main
$ cd gopic
$ ninja gopic
$ ls out/

二进制文件生成在 out 目录下。

:package:下载安装

x86-64 linux版本: gopic-linux-amd64

arm-64 linux版本: gopic-linux-arm64

x86-64 mac版本:gopic-mac-amd64

x86-64 windows版本:gopic.exe

下载后可直接运行,注意!请通过命令行运行!

交互

gopic命令 说明
init 初始化配置,配置生成在home/.gopic.json
conf 打印配置信息等
update 从github更新自己
upload 图床主命令,下表有详细参数介绍
convert 图片转换命令
gopic upload 参数 说明 默认值
-a,–all bool类型,若为true,将上传到配置中激活的所有存储插件中 false,若为false,-s内容为空时自动设置为true
-n, –name bool类型,若为true,将不会屏蔽文件名 false
-f, –format string类型,选用哪一个存储插件作为返回值 默认为第一个存储
-s, –storage string列表,选择要上传到哪些存储插件中,用,分割 默认为空,若为空,-a未配置自动配置为true
-p, –path string列表,图片可以是本地地址,也可以是网络地址

例如gopic upload -a -p ./1.gif ./2.png https://cdn.jsdelivr.net/gh/Longtao-W/pics@main/20210916/avatar.71pjc2scvak0.jpg -f qiniu

代表上传./1.gif ./2.png https://baidu.com/img.png三个图片到所有已经激活的插件,并使用qiniu插件的返回值

结果为:

https://cdn.jsdelivr.net/gh/Longtao-W/pics@main/22/8520716594215125117496217642356398137175_1.png https://cdn.jsdelivr.net/gh/Longtao-W/pics@main/22/230182152169544190214107228101001761655235_2.png https://cdn.jsdelivr.net/gh/Longtao-W/pics@main/22/254555454555441902154101556543454354543545_img.png

其中22为年份,文件名为图片内容的md5结果与原本文件名使用_连接,能有效去重

gopic convert 参数 说明 默认值
-c, –covertPath string类型,要操作的文件夹或文件 当前文件夹
-a, –all bool类型,若为true,将上传到配置中激活的所有存储插件中 false,若为false,-s内容为空会报错
-n, –name bool类型,若为true,将不会屏蔽文件名 false
-r, –recurse bool类型,递归替换 默认递归(非递归没实现)
-s, –storage string列表,选择要上传到哪些存储插件中,用,分割 默认为空,若为空,-a未配置会报错
-f, –format string类型,选用哪一个存储插件作为返回值 默认为第一个存储
-d, –dir string类型, 替换后输出的位置 必选

例如,如命令: ./gopic-linux-amd64 convert -c /home/longtao/temp/blog/ -d /home/longtao/temp/blog2 -f samba -s samba

将会把/home/longtao/temp/blog/目录下递归的把所有md文件中的图片转换到samb存储中,并把转换后的md文件存储在 /home/longtao/temp/blog2

对比tree /home/longtao/temp/blog/ tree /home/longtao/temp/blog2 我们发现是一样的,但是每个md文件中的图片都转换到samb存储中路

image-20220805150255551

:seedling:结合Typora使用

1.
进入文件->偏好设置image-20220720161734836
2. 在偏好配置->图像选项卡中选择插入图片时上传图片,并使用Custom Command
自定义上传服务,在命令中填写需要的gopic命令即可image-20220720162157408

  1. 使用验证图片上传成功后,即可开心的任意粘贴图片,文章中图片会自动保存到激活插件的存储中,本说明的图片就使用gopic自动上出处理

:heavy_plus_sign:开发

添加插件

插件需要添加到plugin目录中,需要满足以下条件

  1. 定义这个插件的类,其中要包含基础类*utils.BaseStorage
  2. 实现Upload(im *utils.Image)(string,error)方法,在Upload中实现单个图片的上传,返回值分别为:图片返回地址、错误信息;
  3. 定义初始化函数init()
  4. 将插件名和帮助文档写入utils.StroageHelp
  5. 将插件名和实例写入utils.StroageMap ,注意需要判断是否active

例子:

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
78
package plugin

import (
"bytes"
"encoding/json"
"gopic/conf"
"gopic/utils"
"io/ioutil"
"net/http"
)
//定义插件类
type GithubStorage struct {
*utils.MetaStorage
}
//定义插件名
const (
githubPluginName = "github"
)
//声明插件配置
var githubConfig map[string]interface{}

//实现Upload方法
func (g *GithubStorage) Upload(im *utils.Image) (string, error) {
responseURL := githubConfig["responseurl"].(string)
requestURL := githubConfig["requesturl"].(string)
token := githubConfig["token"].(string)
return responseURL + im.OutSuffix, uploadPictureToGithub(requestURL, token, im.OutBase64, im.OutSuffix)
}

//实现插件实例构造函数
func NewGithubStorage() *GithubStorage {
return &GithubStorage{utils.NewMetaStorage()}
}

//upload具体的实现,用来上传单个图片
func uploadPictureToGithub(requestURL, token, data, suffix string) error {
url := requestURL + suffix
body := make(map[string]interface{})
body["branch"] = "main"
body["message"] = "markdown upload picture"
body["content"] = data
jsonBody, _ := json.Marshal(body)
req, _ := http.NewRequest("PUT", url, bytes.NewBuffer(jsonBody))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "token "+token)
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
_, err = ioutil.ReadAll(resp.Body)
return err
}
//初始化函数
func init() {
//将帮助文档写入
utils.StroageHelp[githubPluginName] = githubHelp()
//读取插件配置
githubConfig = conf.Viper.GetStringMap(githubPluginName)
//判断插件是否在配置文件中存在
if githubConfig == nil {
return
}
//判断配置中的插件是否处于激活状态
active := githubConfig["active"]
if active == nil {
return
}
//如果插件处于激活状态,将插件的实例传入utils.StroageMap
if active == true {
utils.StroageMap[githubPluginName] = NewGithubStorage()
}
}
//帮助文档具体实现
func githubHelp() string {
return "github plugin need this parameters:\nactive: false or true\nresponseURL: like https://gcore.jsdelivr.net/gh/yourUserName/pics@main/\nrequestURL: like https://api.github.com/repos/yourUserName/pics/contents/\ntoke: your github token"
}

:bulb:基本框架

全并行

不同图片之间以及不同插件之间全部并行
单例模式:相同图片只会处理一次,节省内存及时间消耗,对大目录来说能快速转换!

使用一个插件传输一张图片的时间T11与使用m个插件传输n张图片的时间Tmn, 在算力满足的条件下,Tmn远远小于T11*n,更远远小于T11*m*n

充分解耦

插件与框架完全解耦,可自行编写插件


评论
avatar
LongTao
Ewige Wiederkunft
Follow Me
本周code时间
图像1
图像2