跳到主要内容

用Shell脚本做个GitHub图床工具

· 阅读需 5 分钟

前言

因为我的阿里云学生机快到期了,所以思来想去决定还是把博客迁移到静态博客,不折腾Typecho了。不过,使用静态博客有个比较麻烦的事就是图片上传。众所周知,在Markdown里插入图片就需要图片链接,以前折腾了各种对象存储,现在觉得用GitHub做图床就挺不错的,速度其实还是挺快的,还有jsDelivr的CDN加速。

步骤

尽管有很多图床工具可以方便地进行图片上传,例如PicGo、uPic等。不过,我觉得对于这个简单的事情,没必要这么麻烦,用Shell脚本就行。于是乎,就简单用Shell脚本做了个GitHub图床工具。其实图床工具要做的事比较简单,主要流程如下:

图床流程

首先是获取图片文件,我们可以指定本地图片文件的路径,不过我还希望能直接从剪贴板获取图片,因为我在博客里使用的图片大部分时候是截图,如果能从剪贴板获取图片的话会比较方便。在Linux上可以用xclip,在MacOS上我也找到了个能将剪贴板上的图片保存为文件的命令行工具:pngpaste,安装:

$ brew install pngpaste

然后就是图片压缩了,有的图床工具可能没有图片压缩功能,即使有,压缩效果也可能不够理想。我之前找到两个图片压缩命令行工具:pngquantjpegoptim,分别用于压缩png格式和jpg格式。

然后就是重点“图片上传”了。它其实包含两步,一是给图片换个名字以免重复,这一步其实是很个性化的,每个人可能有各自偏爱的图片命名方式。一般情况下,图床工具会提供一些重命名方式,但一般选择很有限,要做到个性化其实很难的。不过,如果是Shell脚本,就完全可以自己修改代码去自定义了。至于上传到GitHub,这个其实很简单,就一个curl命令就行。

最后,就是输出Markdown格式的图片链接了,至于复制链接到剪贴板,MacOS可以用自带的pbcopy,Linux可以依然用xclip

准备

首先,需要到Personal Access Tokens新建一个token:

ScreenShot-2020-12-05T17:29:50

然后,需要新建一个仓库用于存储图片。

代码

#!/usr/bin/env bash
GITHUB_API_TOKEN=your_token
GITHUB_USER_NAME=jlice
GITHUB_USER_EMAIL=i@jlice.top
GITHUB_REPO=blog-assets

function get_file() {
if [[ -z "$1" ]]; then
filename="/tmp/ScreenShot-"$(date '+%Y-%m-%dT%H:%M:%S')".png"
if type pngpaste &> /dev/null; then
pngpaste "$filename"
elif type xclip &> /dev/null; then
xclip -selection clipboard -t image/png -o > "$filename"
fi
else
filename="$1"
fi
echo "$filename"
}

function compress() {
filename="$1"
suffix=${filename##*.}
suffix_lower=$(echo $suffix | tr 'A-Z' 'a-z')
if [[ $suffix_lower == "png" ]]; then
pngquant --skip-if-larger --ext "."$suffix --force --quality=60-90 "$1"
elif [[ $suffix_lower == "jpg" || $suffix_lower == "jpeg" ]]; then
jpegoptim --max=90 --preserve --all-progressive "$1"
fi
}

function new_filename() {
filename=$1
suffix=${filename##*.}
echo $(date '+%Y/%s')"."$suffix
}

function upload() {
curl -siL -w "%{http_code}\n" -o /dev/null -X PUT 'https://api.github.com/repos/'$GITHUB_USER_NAME'/'$GITHUB_REPO'/contents/'"$2" \
-H 'Authorization: token '$GITHUB_API_TOKEN \
-H 'Content-Type: application/json' \
--data-raw '{
"message": "upload",
"committer": {
"name": "'$GITHUB_USER_NAME'",
"email": "'$GITHUB_USER_EMAIL'"
},
"content": "'$(base64 "$1")'"
}'
}

function markdown() {
alt=$(basename "$1")
alt=${alt%%.*}
url="https://cdn.jsdelivr.net/gh/$GITHUB_USER_NAME/$GITHUB_REPO/""$2"
markdown="![$alt]($url)"
echo $markdown
if type pbcopy &> /dev/null; then
echo $markdown | pbcopy
elif type xclip &> /dev/null; then
echo $markdown | xclip -selection clipboard
fi
}

function main() {
filename=$(get_file "$1")
if [[ -f "$filename" ]]; then
compress "$filename"
new_file=$(new_filename "$filename")
upload "$filename" "$new_file"
markdown "$filename" "$new_file"
else
echo "file not found: $filename"
fi
}

main "$1"

使用方法

编辑最上面的GITHUB_API_TOKEN、GITHUB_USER_NAME等参数,换成你自己的。假设保存为uppic,给它添加x权限即可运行。使用非常简单:

# 上传剪贴板图片
$ ./uppic
# 上传本地图片
$ ./uppic "/Users/wjmr/Desktop/test.png"

参考链接