diff --git a/differential/plugins/base.py b/differential/plugins/base.py index 09e2eba..eeba257 100644 --- a/differential/plugins/base.py +++ b/differential/plugins/base.py @@ -22,7 +22,7 @@ from differential.utils.binary import ffprobe, execute from differential.utils.mediainfo import get_track_attr from differential.utils.mediainfo import get_full_mediainfo -from differential.utils.image import ptpimg_upload, smms_upload, imgurl_upload, chevereto_api_upload, chevereto_cookie_upload +from differential.utils.image import ptpimg_upload, smms_upload, imgurl_upload, chevereto_api_upload, chevereto_username_upload PARSER = argparse.ArgumentParser(description="Differential - 差速器 PT快速上传工具") @@ -84,8 +84,8 @@ def add_parser(cls, parser: argparse.ArgumentParser) -> argparse.ArgumentParser: parser.add_argument('--chevereto-hosting-url', type=str, help="自建chevereto图床的地址", default=argparse.SUPPRESS) parser.add_argument('--ptpimg-api-key', type=str, help="PTPIMG的API Key", default=argparse.SUPPRESS) parser.add_argument('--chevereto-api-key', type=str, help="自建Chevereto的API Key,详情见https://v3-docs.chevereto.com/api/#api-call", default=argparse.SUPPRESS) - parser.add_argument('--chevereto-cookie', type=str, help="如果自建Chevereto的API未开放,请设置auth token和cookie", default=argparse.SUPPRESS) - parser.add_argument('--chevereto-auth-token', type=str, help="如果自建Chevereto的API未开放,请设置auth token和cookie", default=argparse.SUPPRESS) + parser.add_argument('--chevereto-username', type=str, help="如果自建Chevereto的API未开放,请设置username和password", default=argparse.SUPPRESS) + parser.add_argument('--chevereto-password', type=str, help="如果自建Chevereto的API未开放,请设置username和password", default=argparse.SUPPRESS) parser.add_argument('--imgurl-api-key', type=str, help="Imgurl的API Key", default=argparse.SUPPRESS) parser.add_argument('--smms-api-key', type=str, help="SM.MS的API Key", default=argparse.SUPPRESS) parser.add_argument('--ptgen-url', type=str, help="自定义PTGEN的地址", default=argparse.SUPPRESS) @@ -104,8 +104,8 @@ def __init__( imgurl_hosting_url: str = '', ptpimg_api_key: str = None, chevereto_api_key: str = None, - chevereto_cookie: str = None, - chevereto_auth_token: str = None, + chevereto_username: str = None, + chevereto_password: str = None, imgurl_api_key: str = None, smms_api_key: str = None, ptgen_url: str = "https://ptgen.lgto.workers.dev", @@ -123,8 +123,8 @@ def __init__( self.chevereto_hosting_url = chevereto_hosting_url self.imgurl_hosting_url = imgurl_hosting_url self.ptpimg_api_key = ptpimg_api_key - self.chevereto_cookie = chevereto_cookie - self.chevereto_auth_token = chevereto_auth_token + self.chevereto_username = chevereto_username + self.chevereto_password = chevereto_password self.chevereto_api_key = chevereto_api_key self.imgurl_api_key = imgurl_api_key self.smms_api_key = smms_api_key @@ -144,7 +144,7 @@ def __init__( def upload_screenshots(self, img_dir: str) -> list: img_urls = [] for count, img in enumerate(sorted(Path(img_dir).glob("*.png"))): - if img.is_file() and img.name.lower().endswith('png'): + if img.is_file(): img_url = None img_url_file = img.resolve().parent.joinpath(".{}.{}".format(self.image_hosting.value, img.stem)) if img_url_file.is_file(): @@ -160,10 +160,10 @@ def upload_screenshots(self, img_dir: str) -> list: sys.exit(1) if self.chevereto_api_key: img_url = chevereto_api_upload(img, self.chevereto_hosting_url, self.chevereto_api_key) - elif self.chevereto_cookie and self.chevereto_auth_token: - img_url = chevereto_cookie_upload(img, self.chevereto_hosting_url, self.chevereto_cookie, self.chevereto_auth_token) + elif self.chevereto_username and self.chevereto_password: + img_url = chevereto_username_upload(img, self.chevereto_hosting_url, self.chevereto_username, self.chevereto_password) else: - logger.error("Chevereto的API Key/Cookie均未设置,请检查chevereto-api-key/chevereto-cookie+chevereto-auth-token设置") + logger.error("Chevereto的API或用户名或密码未设置,请检查chevereto-username/chevereto-password设置") elif self.image_hosting == ImageHosting.IMGURL: img_url = imgurl_upload(img, self.imgurl_hosting_url, self.imgurl_api_key) elif self.image_hosting == ImageHosting.SMMS: diff --git a/differential/utils/image/__init__.py b/differential/utils/image/__init__.py index 4b97290..ee1f0f6 100644 --- a/differential/utils/image/__init__.py +++ b/differential/utils/image/__init__.py @@ -1,4 +1,4 @@ from differential.utils.image.smms import smms_upload from differential.utils.image.ptpimg import ptpimg_upload from differential.utils.image.imgurl import imgurl_upload -from differential.utils.image.chevereto import chevereto_api_upload, chevereto_cookie_upload \ No newline at end of file +from differential.utils.image.chevereto import chevereto_api_upload, chevereto_cookie_upload, chevereto_username_upload \ No newline at end of file diff --git a/differential/utils/image/chevereto.py b/differential/utils/image/chevereto.py index 59e27e8..71aaabe 100644 --- a/differential/utils/image/chevereto.py +++ b/differential/utils/image/chevereto.py @@ -1,3 +1,4 @@ +import re import json from pathlib import Path from typing import Optional @@ -5,6 +6,7 @@ import requests from loguru import logger +sessions = {} def chevereto_api_upload(img: Path, url: str, api_key: str) -> Optional[str]: data = {'key': api_key} @@ -37,6 +39,58 @@ def chevereto_cookie_upload(img: Path, url: str, cookie: str, auth_token: str) - files = {'source': open(img, 'rb')} req = requests.post(f'{url}/json', data=data, files=files, headers=headers) + try: + res = req.json() + logger.trace(res) + except json.decoder.JSONDecodeError: + res = {} + if not req.ok: + logger.trace(req.content) + logger.warning( + f"上传图片失败: HTTP {req.status_code}, reason: {req.reason} " + f"{res['error'].get('message') if 'error' in res else ''}") + return None + if 'error' in res: + logger.warning(f"上传图片失败: [{res['error'].get('code')}] {res['error'].get('context')} {res['error'].get('message')}") + return None + if 'status_code' in res and res.get('status_code') != 200: + logger.warning(f"上传图片失败: [{res['status_code']}] {res.get('status_txt')}") + return None + if 'image' not in res or 'url' not in res['image']: + logger.warning(f"图片直链获取失败") + return None + return res['image']['url'] + + +def with_session(func): + def wrapper(img: Path, url: str, username: str, password: str): + if (username, password) not in sessions: + session = requests.Session() + req = session.get(url) + m = re.search(r'auth_token.*?\"(\w+)\"', req.text) + if not m: + logger.warning("未找到auth_token,请重试") + return + auth_token = m.groups()[0] + data = {'auth_token': auth_token, 'login-subject': username, 'password': password, 'keep-login': 1} + logger.info("正在登录Chevereto...") + req = session.post(f"{url}/login", data=data) + if not req.ok: + logger.warning("Chevereto登录失败,请重试") + return + sessions[(username, password)] = (session, auth_token) + else: + session, auth_token = sessions.get((username, password)) + return func(session, img, url, auth_token) + return wrapper + + +@with_session +def chevereto_username_upload(session: requests.Session, img: Path, url: str, auth_token: str) -> Optional[str]: + data = {'type': 'file', 'action': 'upload', 'nsfw': 0, 'auth_token': auth_token} + files = {'source': open(img, 'rb')} + req = session.post(f'{url}/json', data=data, files=files) + try: res = req.json() logger.trace(res)