Skip to content

Commit 5a39fac

Browse files
committed
完善上传进度
为 sm.ms 和 imgtg 添加上传进度支持。
1 parent 8bc705a commit 5a39fac

10 files changed

Lines changed: 132 additions & 79 deletions

File tree

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ keywords = ["typora", "image bed", "upload"]
1414
dependencies = [
1515
"requests",
1616
"click",
17-
"colorful-logger>=0.2.0b4",
17+
"colorful-logger>=0.2.0b6",
1818
"typing_extensions; python_version<'3.8'",
1919
"tqdm",
2020
"requests-toolbelt",

up2b/__init__.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ def login(username: str, password: str):
103103
"you have chosen `github` as the image bed, please login with `-lg`"
104104
)
105105

106-
logger.info("current image bed", name=ib)
106+
logger.info("current image bed", name=str(ib))
107107

108108
echo("正在验证账号,请耐心等待...")
109109

@@ -177,19 +177,29 @@ def login_git(access_token: str, username: str, repository: str, path: str):
177177
default=False,
178178
help="忽略数据库缓存,强制上传图片",
179179
)
180+
@click.option(
181+
"-q",
182+
"--quiet",
183+
is_flag=True,
184+
show_default=True,
185+
default=False,
186+
help="静默模式。开启后不显示上传进度",
187+
)
180188
@click.option("-t", "--timeout", type=float, help="上传图片的超时时间")
181189
def upload(
182190
image_paths: Tuple[str],
183191
add_watermark: bool,
184192
auto_compress: bool,
185193
ignore_cache: bool,
186194
timeout: float,
195+
quiet: bool,
187196
):
188197
ib = _read_image_bed(
189198
add_watermark=add_watermark,
190199
auto_compress=auto_compress,
191200
ignore_cache=ignore_cache,
192201
timeout=timeout,
202+
quiet=quiet,
193203
)
194204

195205
paths = check_paths(image_paths)
@@ -269,11 +279,12 @@ def _read_image_bed(
269279
add_watermark: bool = False,
270280
ignore_cache: bool = False,
271281
timeout: Optional[float] = None,
282+
quiet: bool = False,
272283
) -> Union[SM, Imgtu, Imgtg, Github]:
273284
conf = read_conf()
274285

275286
selected_code = conf.image_bed
276-
if not selected_code:
287+
if selected_code == None:
277288
logger.fatal("当前图床为空,请先选择要使用的图床")
278289

279290
assert isinstance(selected_code, int)
@@ -286,13 +297,15 @@ def _read_image_bed(
286297
add_watermark=add_watermark,
287298
ignore_cache=ignore_cache,
288299
timeout=timeout,
300+
quiet=quiet,
289301
)
290302
except ValueError:
291303
IMAGE_BEDS[ImageBedCode.SM_MS](
292304
auto_compress=auto_compress,
293305
add_watermark=add_watermark,
294306
ignore_cache=ignore_cache,
295307
timeout=timeout,
308+
quiet=quiet,
296309
)
297310
logger.fatal("未知的图床代码,可能因为清除无效的 gitee 配置,请重试", code=selected_code)
298311

up2b/up2b_lib/file.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import mimetypes
2+
3+
from typing import Optional, Tuple, BinaryIO, Union
4+
from pathlib import Path
5+
from up2b.up2b_lib.custom_types import ImageType
6+
7+
8+
class File:
9+
def __init__(
10+
self, key: str, image: ImageType, filename: Optional[str] = None
11+
) -> None:
12+
self.__key = key
13+
14+
self.mime_type = (
15+
mimetypes.guess_type(image)[0]
16+
if isinstance(image, Path)
17+
else image.mime_type
18+
)
19+
20+
self.filename = (
21+
filename or image.name if isinstance(image, Path) else image.filename
22+
)
23+
self.image = image
24+
25+
@property
26+
def key(self):
27+
return self.__key
28+
29+
def to_tuple(self) -> Tuple[str, Union[BinaryIO, bytes], str]:
30+
return (
31+
self.filename,
32+
self.image.open("rb")
33+
if isinstance(self.image, Path)
34+
else self.image.stream,
35+
self.mime_type, # type: ignore
36+
)
37+
38+
def to_dict(self):
39+
return {self.key: self.to_tuple()}

up2b/up2b_lib/http.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
from typing import Any, Dict, Optional
99
from tqdm import tqdm
10+
from up2b.up2b_lib.file import File
1011

1112

1213
class ProgressBar(tqdm):
@@ -16,17 +17,21 @@ def update_to(self, n: int) -> None:
1617

1718
def upload_with_progress_bar(
1819
url: str,
19-
filename: str,
20-
form: Dict[str, Any],
20+
file: File,
21+
timeout: float,
22+
form: Optional[Dict[str, Any]] = None,
2123
headers: Optional[Dict[str, str]] = None,
2224
):
23-
encoder = requests_toolbelt.MultipartEncoder(form)
25+
data = form or {}
26+
data.update(file.to_dict())
27+
28+
encoder = requests_toolbelt.MultipartEncoder(data)
2429

2530
headers = headers or {}
2631

2732
with ProgressBar(
2833
total=encoder.len,
29-
desc=filename,
34+
desc=file.filename,
3035
unit="B",
3136
unit_scale=True,
3237
unit_divisor=1024,
@@ -39,6 +44,6 @@ def upload_with_progress_bar(
3944

4045
headers.update({"Content-Type": monitor.content_type})
4146

42-
resp = requests.post(url, data=monitor, headers=headers)
47+
resp = requests.post(url, data=monitor, headers=headers, timeout=timeout)
4348

4449
return resp

up2b/up2b_lib/up2b_api/__init__.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,8 +358,12 @@ def __init__(
358358
add_watermark: bool = False,
359359
ignore_cache: bool = False,
360360
conf: Optional[Config] = None,
361+
timeout: Optional[float] = None,
362+
quiet: bool = False,
361363
):
362-
super().__init__(auto_compress, add_watermark, ignore_cache, conf)
364+
super().__init__(
365+
auto_compress, add_watermark, ignore_cache, conf, timeout, quiet
366+
)
363367

364368
if self.auth_info:
365369
self.token = self.auth_info["token"]

up2b/up2b_lib/up2b_api/__init__.pyi

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
from collections.abc import Sequence
21
from pathlib import Path
32
import requests
43

@@ -89,6 +88,7 @@ class Base:
8988
ignore_cache: bool = ...,
9089
conf: Optional[Config] = ...,
9190
timeout: Optional[float] = ...,
91+
quiet: bool = ...,
9292
) -> None: ...
9393
def check_login(self) -> None: ...
9494
def _read_auth_info(self) -> Optional[AuthInfo]: ...
@@ -119,6 +119,7 @@ class GitBase(Base, ImageBedAbstract):
119119
ignore_cache: bool = ...,
120120
conf: Optional[Config] = ...,
121121
timeout: Optional[float] = None,
122+
quiet: bool = ...,
122123
) -> None: ...
123124
def login(
124125
self, token: str, username: str, repo: str, folder: str = ...

up2b/up2b_lib/up2b_api/github.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,5 @@
11
#!/usr/bin/env python3
22
# -*- coding:utf-8 -*-
3-
# @Author: thepoy
4-
# @Email: thepoy@163.com
5-
# @File Name: github.py
6-
# @Created At: 2021-02-13 09:10:14
7-
# @Modified At: 2023-03-04 21:40:12
8-
# @Modified By: thepoy
93

104
import os
115
import requests
@@ -39,8 +33,11 @@ def __init__(
3933
ignore_cache: bool = False,
4034
conf: Optional[Config] = None,
4135
timeout: Optional[float] = None,
36+
quiet: bool = False,
4237
):
43-
super().__init__(auto_compress, add_watermark, ignore_cache, conf, timeout)
38+
super().__init__(
39+
auto_compress, add_watermark, ignore_cache, conf, timeout, quiet
40+
)
4441

4542
if hasattr(self, "token"):
4643
self.headers = {

up2b/up2b_lib/up2b_api/imgtg.py

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import re
66
import time
77
import json
8-
import mimetypes
98
import requests
109

1110
from urllib import parse
@@ -22,6 +21,8 @@
2221
UploadErrorResponse,
2322
)
2423
from up2b.up2b_lib.errors import MissingAuth
24+
from up2b.up2b_lib.file import File
25+
from up2b.up2b_lib.http import upload_with_progress_bar
2526
from up2b.up2b_lib.up2b_api import Base
2627
from up2b.up2b_lib.log import child_logger
2728
from up2b.up2b_lib.constants import IMAGE_BEDS_NAME, ImageBedCode
@@ -46,8 +47,11 @@ def __init__(
4647
ignore_cache: bool = False,
4748
conf: Optional[Config] = None,
4849
timeout: Optional[float] = None,
50+
quiet: bool = False,
4951
):
50-
super().__init__(auto_compress, add_watermark, ignore_cache, conf, timeout)
52+
super().__init__(
53+
auto_compress, add_watermark, ignore_cache, conf, timeout, quiet
54+
)
5155

5256
self.cookie: Optional[str] = None
5357
self.token: Optional[str] = None
@@ -172,20 +176,10 @@ def __upload(
172176
else:
173177
filename = filename_with_suffix + "." + image.mime_type
174178

175-
mime_type = (
176-
mimetypes.guess_type(image)[0]
177-
if isinstance(image, Path)
178-
else image.mime_type
179-
)
179+
file = File("source", image, filename=filename)
180180

181181
timestamp = int(time.time() * 1000)
182182

183-
if isinstance(image, Path):
184-
with open(image, "rb") as fb:
185-
img_buffer = fb.read()
186-
else:
187-
img_buffer = image.stream
188-
189183
data = {
190184
"type": "file",
191185
"action": "upload",
@@ -194,15 +188,24 @@ def __upload(
194188
"nsfw": "0",
195189
}
196190

197-
files = {
198-
"source": (filename, img_buffer, mime_type),
199-
}
200-
201191
logger.debug("请求头", header=self.headers)
202192

203-
resp = requests.post(
204-
url, headers=self.headers, data=data, files=files, timeout=self.timeout # type: ignore
205-
)
193+
try:
194+
if not self.quiet:
195+
resp = upload_with_progress_bar(
196+
url, file, self.timeout, data, self.headers
197+
)
198+
else:
199+
resp = requests.post(
200+
url,
201+
headers=self.headers,
202+
data=data,
203+
files=file.to_dict(),
204+
timeout=self.timeout,
205+
)
206+
except requests.exceptions.ConnectionError as e:
207+
return UploadErrorResponse(400, str(e), str(image))
208+
206209
resp.encoding = "utf-8"
207210

208211
logger.debug("实际请求头", header=resp.request.headers)

up2b/up2b_lib/up2b_api/imgtu.py

Lines changed: 12 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,10 @@
11
#!/usr/bin/env python3
22
# -*- coding:utf-8 -*-
3-
# @Author: thepoy
4-
# @Email: thepoy@163.com
5-
# @File Name: imgtu.py
6-
# @Created At: 2021-02-13 09:04:37
7-
# @Modified At: 2023-04-19 14:48:44
8-
# @Modified By: thepoy
93

104
import os
115
import re
126
import time
137
import json
14-
import mimetypes
158
import requests
169

1710
from urllib import parse
@@ -28,6 +21,7 @@
2821
UploadErrorResponse,
2922
)
3023
from up2b.up2b_lib.errors import MissingAuth
24+
from up2b.up2b_lib.file import File
3125
from up2b.up2b_lib.http import upload_with_progress_bar
3226
from up2b.up2b_lib.up2b_api import Base
3327
from up2b.up2b_lib.constants import IMAGE_BEDS_NAME, ImageBedCode
@@ -53,8 +47,11 @@ def __init__(
5347
ignore_cache: bool = False,
5448
conf: Optional[Config] = None,
5549
timeout: Optional[float] = None,
50+
quiet: bool = False,
5651
):
57-
super().__init__(auto_compress, add_watermark, ignore_cache, conf, timeout)
52+
super().__init__(
53+
auto_compress, add_watermark, ignore_cache, conf, timeout, quiet
54+
)
5855

5956
self.cookie: Optional[str] = None
6057
self.token: Optional[str] = None
@@ -172,20 +169,10 @@ def __upload(
172169
else:
173170
filename = filename_with_suffix + "." + image.mime_type
174171

175-
mime_type = (
176-
mimetypes.guess_type(image)[0]
177-
if isinstance(image, Path)
178-
else image.mime_type
179-
)
172+
file = File("source", image, filename=filename)
180173

181174
timestamp = int(time.time() * 1000)
182175

183-
if isinstance(image, Path):
184-
with open(image, "rb") as fb:
185-
img_buffer = fb.read()
186-
else:
187-
img_buffer = image.stream
188-
189176
data = {
190177
"type": "file",
191178
"action": "upload",
@@ -194,18 +181,18 @@ def __upload(
194181
"nsfw": "0",
195182
}
196183

197-
files = {
198-
"source": (filename, img_buffer, mime_type),
199-
}
200-
201184
try:
202185
if not self.quiet:
203186
resp = upload_with_progress_bar(
204-
url, filename, dict(data, **files), self.headers
187+
url, file, self.timeout, data, self.headers
205188
)
206189
else:
207190
resp = requests.post(
208-
url, headers=self.headers, data=data, files=files, timeout=self.timeout # type: ignore
191+
url,
192+
headers=self.headers,
193+
data=data,
194+
files=file.to_dict(),
195+
timeout=self.timeout,
209196
)
210197
except requests.exceptions.ConnectionError as e:
211198
return UploadErrorResponse(400, str(e), str(image))

0 commit comments

Comments
 (0)