Skip to content

Commit 6c517fb

Browse files
committed
feat: fix date payload && support uploadFileName payload
1 parent 13040db commit 6c517fb

File tree

3 files changed

+140
-105
lines changed

3 files changed

+140
-105
lines changed

README.md

Lines changed: 122 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -1,129 +1,154 @@
1-
21
## picgo-plugin-s3
32

4-
![github-action](https://github.com/wayjam/picgo-plugin-s3/workflows/publish/badge.svg)
5-
![license](https://img.shields.io/github/license/wayjam/picgo-plugin-s3)
3+
[![github-action](https://github.com/wayjam/picgo-plugin-s3/workflows/publish/badge.svg)](https://github.com/wayjam/picgo-plugin-s3/actions/workflows/publish.yaml)
4+
[![license](https://img.shields.io/github/license/wayjam/picgo-plugin-s3)](https://github.com/wayjam/picgo-plugin-s3/blob/main/LICENSE)
65
[![npm](https://img.shields.io/npm/v/picgo-plugin-s3?style=flat)](https://www.npmjs.com/package/picgo-plugin-s3)
76

87
[PicGo](https://github.com/PicGo/PicGo-Core) Amazon S3 上传插件。
98

10-
- 支持 Amazon S3 与其他如 backblaze b2 等兼容 S3 API 的云存储
11-
- 支持 PicGO GUI
12-
- 支持 MinIO
9+
- 支持 Amazon S3 与其他兼容 S3 API 的云存储 (例如 Backblaze B2)。
10+
- 支持 PicGo GUI。
11+
- 支持 MinIO。
12+
13+
### 安装 (Installation)
1314

14-
### 安装 Installation
15+
GUI 用户可直接在插件市场搜索 `s3` 并下载。
1516

16-
GUI 直接搜索 _S3_ 下载即可,Core 版执行 `picgo add s3` 安装
17+
Core 用户可执行 `picgo add s3` 命令安装
1718

18-
### 配置 Configuration
19+
### 配置 (Configuration)
1920

2021
```sh
21-
picgo set uploader aws-s3
22+
picgo set uploader s3
2223
```
2324

24-
| Key | 说明 | 例子 |
25-
| -------------------------- | -------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
26-
| `accessKeyID` | AWS 凭证 ID | |
27-
| `secretAccessKey` | AWS 凭证密钥 | |
28-
| `bucketName` | S3 桶名称 | `gallery` |
29-
| `uploadPath` | 上传路径,详细配置查看以下说明 | `{year}/{month}/{fullName}` |
30-
| `endpoint` | 指定自定义终端节点 | `s3.us-west-2.amazonaws.com` |
31-
| `proxy` | 代理地址 | 支持 http 代理,例如 `http://127.0.0.1:1080` |
32-
| `region` | 指定执行服务请求的区域 | `us-west-1` |
33-
| `pathStyleAccess` | 是否启用 S3 Path style | 默认为 `false`,使用 minio 请设置为 `true` (e.g., https://s3.amazonaws.com/<bucketName>/<key> instead of https://<bucketName>.s3.amazonaws.com/<key>) |
34-
| `rejectUnauthorized` | 是否拒绝无效 TLS 证书连接 | 默认为 `true`,如上传失败日志显示证书问题可设置为`false` |
35-
| `acl` | 访问控制列表,上传资源的访问策略 | 默认为 `public-read`, AWS 可选 `private" | "public-read" | "public-read-write" | "authenticated-read" | "aws-exec-read" | "bucket-owner-read" | "bucket-owner-full-control` |
36-
| `outputURLPattern` | 自定义输出 URL 模板,详细配置查看以下说明 | `{protocol}://{host}:{port}/{path}` |
37-
| `urlPrefix` | 最终生成图片 URL 的自定义前缀(已废弃,请使用 outputURLPattern) | `https://img.example.com/my-blog/` |
38-
| `urlSuffix` | 最终生成图片 URL 的自定义后缀(已废弃,请使用 outputURLPattern) | `?oxx=xxx` |
39-
| `disableBucketPrefixToURL` | 开启 `pathStyleAccess` 时,是否要禁用最终生成 URL 中添加 bucket 前缀 (已废弃,请使用 outputURLPattern) | 默认为 `false` |
40-
41-
#### 通用占位符 Payload
42-
43-
_上传路径__自定义输出 URL 模板_ 支持的通用占位符,插件将会自行用变量替换到实际使用的路径中。
44-
45-
| payload | 描述 |
46-
| --------------- | ------------------- |
47-
| `{year}` | 当前日期 - 年 |
48-
| `{month}` | 当前日期 - 月 |
49-
| `{day}` | 当前日期 - 日 |
50-
| `{hour}` | 当前日期 - 时 |
51-
| `{minute}` | 当前日期 - 分 |
52-
| `{second}` | 当前日期 - 秒 |
53-
| `{millisecond}` | 当前日期 - 毫秒 |
54-
| `{timestamp}` | Unix 时间戳 |
55-
| `{timestampMS}` | Unix 时间戳(毫秒) |
56-
57-
#### 上传路径(`uploadPath`)
58-
59-
支持占位符方式配置,如 `{year}/{month}/{md5}.{extName}`。除以下列表外,还指出上述通用占位符。
60-
61-
| payload | 描述 |
62-
| ------------ | ---------------------- |
63-
| `{fullName}` | 完整文件名(含扩展名) |
64-
| `{fileName}` | 文件名(不含扩展名) |
65-
| `{extName}` | 扩展名(不含`.`|
66-
| `{md5}` | 图片 MD5 计算值 |
67-
| `{sha1}` | 图片 SHA1 计算值 |
68-
| `{sha256}` | 图片 SHA256 计算值 |
69-
70-
#### 自定义输出 URL 模板(`outputURLPattern`)
71-
72-
支持占位符方式配置,如 `{protocol}://{host}:{port}/{path}`。除以下列表外,还指出上述通用占位符。
73-
74-
| payload | 描述 | 例子 |
75-
| ------------ | ------------------------------------------------------------- | --------------------------------------------------------- |
76-
| `{protocol}` | 原上传 URL 的协议 | `http``https` |
77-
| `{host}` | 原上传 URL 的域名,可不不使用次此变量改为其他自己的反代的域名 | `example.com` |
78-
| `{port}` | 原上传 URL 的端口 | `80` |
79-
| `{dir}` | 原上传 URL 的目录 | `testBucket/2024/12` |
80-
| `{path}` | 原上传 URL 的完整路径 | `testBucket/2024/12/4aa4f41e38817e5fd38ac870f40dbc70.jpg` |
81-
| `{fileName}` | 文件名(含扩展名) | `test.jpg` |
82-
| `{extName}` | 扩展名(不含`.`| `jpg` |
83-
| `{query}` | 上传 URL 的 querystirng 部分(不含 `?`| `height=100&width=200` |
84-
| `{hash}` | 上传 URL 的 hash 部分(不含 `#`| `abc` |
85-
| `{bucket}` | 上传桶名 | `testBucket` |
86-
87-
这个配置将会替代原有的 `urlPrefix``urlSuffix``disableBucketPrefixToURL` 的配置。
88-
89-
另外每个变量都支持**正则替换**
90-
25+
| Key | 说明 | 示例 |
26+
| :--- | :--- | :--- |
27+
| `accessKeyID` | AWS 凭证 ID。 | |
28+
| `secretAccessKey` | AWS 凭证密钥。 | |
29+
| `bucketName` | S3 桶名称。 | `gallery` |
30+
| `uploadPath` | 上传路径,详细配置请查看以下说明。 | `{year}/{month}/{fullName}` |
31+
| `endpoint` | 指定自定义终端节点。 | `s3.us-west-2.amazonaws.com` |
32+
| `proxy` | 代理地址,支持 http 代理。 | `http://127.0.0.1:1080` |
33+
| `region` | 指定执行服务请求的区域。 | `us-west-1` |
34+
| `pathStyleAccess` | 是否启用 S3 Path style 访问模式。<br>例如 `https://s3.amazonaws.com/<bucketName>/<key>`。<br>使用 MinIO 时请设置为 `true`| 默认为 `false` |
35+
| `rejectUnauthorized`| 是否拒绝无效的 TLS 证书连接。<br>如上传失败日志显示证书问题可设置为 `false`| 默认为 `true` |
36+
| `acl` | 访问控制列表 (ACL),用于设置资源的访问策略。<br>可选值: `private`, `public-read`, `public-read-write`, `authenticated-read`, `aws-exec-read`, `bucket-owner-read`, `bucket-owner-full-control`| 默认为 `public-read` |
37+
| `outputURLPattern` | 自定义输出 URL 模板,详细配置请查看以下说明。 | `{protocol}://{host}:{port}/{path}` |
38+
| `urlPrefix` | **[已废弃]** 自定义 URL 前缀。请使用 `outputURLPattern`| `https://img.example.com/my-blog/` |
39+
| `urlSuffix` | **[已废弃]** 自定义 URL 后缀。请使用 `outputURLPattern`| `?oxx=xxx` |
40+
| `disableBucketPrefixToURL` | **[已废弃]** 禁用 URL 中的 bucket 前缀。请使用 `outputURLPattern`| 默认为 `false` |
41+
42+
---
43+
44+
#### 通用占位符
45+
46+
`uploadPath``outputURLPattern` 均支持通用占位符,插件会将其替换为实际变量。
47+
48+
| 占位符 | 描述 |
49+
| :--- | :--- |
50+
| `{year}` ||
51+
| `{month}` ||
52+
| `{day}` ||
53+
| `{hour}` ||
54+
| `{minute}` ||
55+
| `{second}` ||
56+
| `{millisecond}` | 毫秒 |
57+
| `{timestamp}` | Unix 时间戳 (秒) |
58+
| `{timestampMS}` | Unix 时间戳 (毫秒) |
59+
60+
#### 上传路径 (`uploadPath`)
61+
62+
除了通用占位符外,还支持以下变量:
63+
64+
| 占位符 | 描述 |
65+
| :--- | :--- |
66+
| `{fullName}` | 完整文件名 (含扩展名) |
67+
| `{fileName}` | 文件名 (不含扩展名) |
68+
| `{extName}` | 扩展名 (不含 `.`) |
69+
| `{md5}` | 图片 MD5 |
70+
| `{sha1}` | 图片 SHA1 |
71+
| `{sha256}` | 图片 SHA256 |
72+
73+
---
74+
75+
#### 自定义输出 URL 模板 (`outputURLPattern`)
76+
77+
此配置将替代已废弃的 `urlPrefix``urlSuffix``disableBucketPrefixToURL`
78+
79+
除了通用占位符外,还支持以下变量:
80+
81+
| 占位符 | 描述 | 示例 |
82+
| :--- | :--- | :--- |
83+
| `{protocol}` | URL 协议 | `http``https` |
84+
| `{host}` | URL 域名 | `s3.amazonaws.com` |
85+
| `{port}` | URL 端口 | `80` |
86+
| `{dir}` | 上传目录 | `my-bucket/2024/12` |
87+
| `{file}` | 上传后的文件名 (含扩展名) | `4aa4f41e38817e5fd38ac870f40dbc70.jpg` |
88+
| `{path}` | 完整路径 (`{dir}/{file}`) | `my-bucket/2024/12/4aa4f41e38817e5fd38ac870f40dbc70.jpg` |
89+
| `{fileName}` | ****文件名 (含扩展名) | `test.jpg` |
90+
| `{extName}` | ****文件扩展名 (不含 `.`) | `jpg` |
91+
| `{query}` | URL 查询参数 (不含 `?`) | `height=100&width=200` |
92+
| `{hash}` | URL hash (不含 `#`) | `abc` |
93+
| `{bucket}` | S3 桶名 | `my-bucket` |
94+
95+
##### 正则替换
96+
97+
每个变量都支持通过正则表达式进行替换。
98+
99+
**语法:**
91100
```
92-
语法:
93-
{payload:/pattern/reFlag,'replacement'}
101+
{payload:/pattern/flags,'replacement'}
94102
```
95103

96-
比如配置为 `{protocol}://example.imgbed/{path:/testBucket/i,'myimage'}`,如果原URL为 `https://cluster-test-1.s3.us-east-001.example.com/testBucket/image.jpg` 则会生成 `https://example.imgbed/myimage/image.jpg`
104+
**示例:**
105+
假设配置为 `{protocol}://example.com/{path:/testBucket/i,'myimage'}`
106+
并且原始 URL 为 `https://cluster.s3.example.com/testBucket/image.jpg`
107+
则最终生成的 URL 为 `https://example.com/myimage/image.jpg`
97108

98-
#### 示例 Example
109+
---
110+
111+
#### 完整示例 (Example)
99112

100113
```json
101-
"aws-s3": {
102-
"accessKeyID": "xxx",
103-
"secretAccessKey": "xxxxx",
104-
"bucketName": "my-bucket",
105-
"uploadPath": "{year}/{md5}.{extName}",
106-
"endpoint": "s3.us-west-000.backblazeb2.com",
107-
"outputURLPattern": "{protocol}://{host}/{path}"
108-
}
114+
{
115+
"picgo-plugin-s3": {
116+
"accessKeyID": "xxx",
117+
"secretAccessKey": "xxxxx",
118+
"bucketName": "my-bucket",
119+
"uploadPath": "{year}/{md5}.{extName}",
120+
"endpoint": "s3.us-west-000.backblazeb2.com",
121+
"outputURLPattern": "https://img.example.com/{bucket}/{path}"
122+
}
123+
}
109124
```
125+
如果 PicGo 按以上配置,上传 `sample.png`,最终得到的图片地址可能为:`https://img.example.com/my-bucket/2021/4aa4f41e38817e5fd38ac870f40dbc70.png`
110126

111-
如果 PicGo 像以上配置,执行上传:`picgo upload sample.png`,则最终得到图片地址为:`https://img.example.com/2021/4aa4f41e38817e5fd38ac870f40dbc70.jpg`
112-
113-
## 发布 Publish
127+
## 发布 (Publish)
114128

115-
With the following command, a versioned commit which modifies the `version` of `package.json` would be genereated and pushed to the origin. Github Action will automatically compile this pacakage and publish it to NPM.
129+
执行以下任一命令,会自动更新 `package.json` 的版本号并生成一个 commit 推送到远程仓库。GitHub Action 将会自动编译、打包并发布到 NPM
116130

117131
```sh
132+
# 更新补丁版本 (patch)
118133
npm run patch
134+
135+
# 更新次要版本 (minor)
119136
npm run minor
137+
138+
# 更新主要版本 (major)
120139
npm run major
121140
```
122141

123-
## 贡献 Contributing
142+
## 开发 (Development)
143+
144+
1. Clone this repo
145+
2. `npm i && npm run dev`
146+
3. `cd ~/.picgo && npm install ${path_to_the_repo}`
147+
148+
## 贡献 (Contributing)
124149

125-
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
150+
欢迎提交 Pull Request。对于重大更改,请先开一个 Issue 进行讨论。
126151

127-
## 许可证 License
152+
## 许可证 (License)
128153

129-
Released under the [MIT License](https://github.com/wayjam/picgo-plugin-s3/blob/master/LICENSE).
154+
Released under the [MIT License](https://github.com/wayjam/picgo-plugin-s3/blob/main/LICENSE).

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ const upload = async (ctx: IPicGo) => {
1111
const output = ctx.output
1212

1313
const tasks = output.map((item, idx) => {
14+
item.uploadDate = new Date()
1415
const fileNameGenerator = new FileNameGenerator(item)
1516
return uploader.createUploadTask({
1617
client,

src/utils.ts

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,12 @@ import { IS3UserConfig } from "./config"
99
class Generateor {
1010
readonly date: Date
1111

12-
constructor() {
13-
this.date = new Date()
12+
constructor(date?: Date) {
13+
if (date) {
14+
this.date = date
15+
} else {
16+
this.date = new Date()
17+
}
1418
}
1519

1620
protected year(): string {
@@ -78,7 +82,7 @@ export class FileNameGenerator extends Generateor {
7882
readonly info: IImgInfo
7983

8084
constructor(info: IImgInfo) {
81-
super()
85+
super(info.date)
8286
this.info = info
8387
}
8488

@@ -154,7 +158,7 @@ export class FileNameGenerator extends Generateor {
154158
(result, [key, formatter]) => {
155159
const simplePattern = new RegExp(`{${key}}`, 'g')
156160
const truncatePattern = new RegExp(`{${key}:(\\d+)}`, 'g')
157-
161+
158162
if (truncatePattern.test(result)) {
159163
result = result.replace(truncatePattern, (match, length) => {
160164
const value = formatter()
@@ -183,7 +187,7 @@ export class OutputURLGenerator extends Generateor {
183187
readonly _info: IImgInfo
184188

185189
constructor(config: IS3UserConfig, info: IImgInfo) {
186-
super()
190+
super(info.date)
187191
this._config = config
188192
this._info = info
189193

@@ -226,20 +230,24 @@ export class OutputURLGenerator extends Generateor {
226230
if (this._info.fileName) {
227231
return this._info.fileName
228232
}
229-
return path.basename(this.path())
233+
return path.basename(this.path()) // will fallback to the uploaded filename.
230234
}
231235

232236
public extName(): string {
233237
if (this._info.extname) {
234-
return this._info.extname.replace(/^./,'')
238+
return this._info.extname.replace(/^./, '')
235239
}
236-
return path.extname(this.path()).replace(/^./,'')
240+
return path.extname(this.path()).replace(/^./, '') // will fallback to the uploaded file extname.
237241
}
238242

239243
public dir(): string {
240244
return path.dirname(this.path())
241245
}
242246

247+
public uploadedFileName(): string {
248+
return path.basename(this.path())
249+
}
250+
243251
public originalURL(): string {
244252
let url = this._info.url
245253
if (!url) {
@@ -290,6 +298,7 @@ export class OutputURLGenerator extends Generateor {
290298
dir: () => this.dir(),
291299
fileName: () => this.fileName(),
292300
path: () => this.path(),
301+
uploadedFileName: () => this.uploadedFileName(),
293302
extName: () => this.extName(),
294303
query: () => this.query(),
295304
hash: () => this.hash(),

0 commit comments

Comments
 (0)