环境:Python3.11.9 stabled
IDE:Pycharm2023.3.1.1 Typora 1.9.5
成品:upload.exe
项目背景
之前本地博文是用Typora + Picgo + COS,对于上传到Minio,需要安装额外的插件,也不支持对图片的转换。目前所有附件和图片都迁移至自建的Minio中,COS并不承担任何业务数据的存储,只保留备份的数据。为了满足本地博文图片上传的需要,用 Python 编写一个上传图片到 Minio 的脚本,并将其打包成exe文件。这个过程不仅适用于图片上传功能,也可以应用到其他 Python 脚本的打包需求中。
脚本编写
安装库
-
Minio SDK 用于与 Minio 服务进行交互。
-
Pillow 用于处理和转换图片格式。
-
aiohttp 用于处理异步请求,支持从 URL 获取图片。
-
requests 用于 HTTP 请求。
pip install minio pillow aiohttp requests
这些都是必须要安装的,开发过程中其他库可以选用更轻量的库来减小打包后的体积。
查看文档
根据文档,最重要的是Typora会传入${filename}
或者${filepath}
,可以一次性上传多张图片,脚本要返回值要用url
以换行进行切分,且url
必须是干净的,不能有其他输出。
配置约定
-
定义Minio的配置如下:
host = "xxxx.xxxx.com"
port = "xxxx"
access_key = "xxxxxxxxxxxxxxxxxxxx"
secret_key = "xxxxxxxxxxxxxxxxxxxx"
bucket_name = "xxxxxx"
这样拼出来的endpoint
就是endpoint = f"{host}:{port}"
,保留host没有直接用host:port
主要是后面我们要返回url
给typora
-
定义上传路径为
host/bucket/files/${year}/${month}/
-
定义文件名规则是 日期+6位随机UUID 即
currentDate-uuid4[6].webp
给定脚本
这段脚本提供了一些基本的功能:
-
异常处理,且不进行错误重试
-
减小代码冗余,上传不成功就不处理了。
-
-
异步并发上传
-
使用
asyncio
和aiohttp
进行异步操作,通过限制最大并发数(使用Semaphore
)来控制上传任务的数量,避免一次性上传过多图片导致系统资源消耗过大。
-
-
图片格式转换
-
使用
Pillow
将图片转换为 WebP 格式,个人需要,也比较建议将PNG和JPEG的图片进行处理。WebP相较于前两种,压缩率更高,可以减少存储空间。
-
程序打包
-
选用
pyinstaller
打包,本来源码就不大,因此用UPX简单压缩优化下就可以了。pip install pyinstaller
-
UPX下载地址:UPX下载地址
-
执行打包
pyinstaller --onefile --icon=icon.ico --noconsole upload.py
-
执行打包(upx压缩)
pyinstaller --onefile --icon=icon.ico --noconsole --upx-dir="D:\envs\to\upx-4.2.4-win64" upload.py
对比发现优化了9.2%
,体积小于15M问题不大,不需要过分优化了。压缩前的的体积也不是很大,建议用压缩前的,UPX压缩后可能会导致Win报毒。
脚本使用
-
偏好设置上传图片,指定脚本
-
验证图片,可以看到我们打印的结果符合官网自定义的结果
扩展
给定几个以下扩展(利用AI实现起来简单)
-
多存储策略
-
GUI页面开发
-
水印功能
总结
很多配置都是写死了,有需要可以针对源码对原有功能二开,对于已经打包的exe文件就可以扩展到其他项目的打包和分发。