Skip to content

Commit

Permalink
Remove: 移除 Python 3.8 支持 (#108)
Browse files Browse the repository at this point in the history
  • Loading branch information
MeetWq committed May 15, 2024
1 parent 895da62 commit 67912a8
Show file tree
Hide file tree
Showing 215 changed files with 1,250 additions and 949 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ _✨ 表情包生成器,用于制作各种沙雕表情包 ✨_

<p align="center">
<img src="https://img.shields.io/github/license/MeetWq/meme-generator" alt="license">
<img src="https://img.shields.io/badge/python-3.8+-blue.svg" alt="Python">
<img src="https://img.shields.io/badge/python-3.9+-blue.svg" alt="Python">
<a href="https://pypi.org/project/meme-generator">
<img src="https://badgen.net/pypi/v/meme-generator" alt="pypi">
</a>
Expand Down
30 changes: 15 additions & 15 deletions meme_generator/app.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Any, Dict, List, Literal, Optional, Tuple
from typing import Any, Literal, Optional

import filetype
from fastapi import Depends, FastAPI, Form, HTTPException, Response, UploadFile
Expand All @@ -20,22 +20,22 @@ class MemeArgsResponse(BaseModel):
type: str
description: Optional[str] = None
default: Optional[Any] = None
enum: Optional[List[Any]] = None
enum: Optional[list[Any]] = None


class MemeParamsResponse(BaseModel):
min_images: int
max_images: int
min_texts: int
max_texts: int
default_texts: List[str]
args: List[MemeArgsResponse]
default_texts: list[str]
args: list[MemeArgsResponse]


class MemeInfoResponse(BaseModel):
key: str
keywords: List[str]
patterns: List[str]
keywords: list[str]
patterns: list[str]
params: MemeParamsResponse


Expand All @@ -56,11 +56,11 @@ def args_checker(args: Optional[str] = Form(default=str(args_model().json()))):

@app.post(f"/memes/{meme.key}/")
async def _(
images: List[UploadFile] = [],
texts: List[str] = meme.params_type.default_texts,
images: list[UploadFile] = [],
texts: list[str] = meme.params_type.default_texts,
args: args_model = Depends(args_checker), # type: ignore
):
imgs: List[bytes] = []
imgs: list[bytes] = []
for image in images:
imgs.append(await image.read())

Expand Down Expand Up @@ -94,16 +94,16 @@ class MemeKeyWithProperties(BaseModel):


class RenderMemeListRequest(BaseModel):
meme_list: List[MemeKeyWithProperties] = default_meme_list
meme_list: list[MemeKeyWithProperties] = default_meme_list
order_direction: Literal["row", "column"] = "column"
columns: int = 4
column_align: Literal["left", "center", "right"] = "left"
item_padding: Tuple[int, int] = (15, 2)
image_padding: Tuple[int, int] = (50, 50)
item_padding: tuple[int, int] = (15, 2)
image_padding: tuple[int, int] = (50, 50)
bg_color: ColorType = "white"
fontsize: int = 30
fontname: str = ""
fallback_fonts: List[str] = []
fallback_fonts: list[str] = []


def register_routers():
Expand Down Expand Up @@ -158,7 +158,7 @@ def _(key: str):
if meme.params_type.args_type
else MemeArgsModel
)
properties: Dict[str, Dict[str, Any]] = (
properties: dict[str, dict[str, Any]] = (
args_model.schema().get("properties", {}).copy()
)
properties.pop("user_infos")
Expand Down Expand Up @@ -198,7 +198,7 @@ async def _(key: str):
return Response(content=content, media_type=media_type)

@app.post("/memes/{key}/parse_args")
async def _(key: str, args: List[str] = []):
async def _(key: str, args: list[str] = []):
try:
meme = get_meme(key)
return meme.parse_args(args)
Expand Down
12 changes: 6 additions & 6 deletions meme_generator/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import copy
from argparse import ArgumentParser
from pathlib import Path
from typing import Any, Dict, List
from typing import Any

import filetype

Expand Down Expand Up @@ -80,7 +80,7 @@ def meme_info(key: str) -> str:

default_texts = ", ".join([f'"{text}"' for text in meme.params_type.default_texts])

def arg_info(name: str, info: Dict[str, Any]) -> str:
def arg_info(name: str, info: dict[str, Any]) -> str:
text = (
f' "{name}"\n'
f" 描述:{info.get('description', '')}\n"
Expand All @@ -94,7 +94,7 @@ def arg_info(name: str, info: Dict[str, Any]) -> str:

if args := meme.params_type.args_type:
model = args.model
properties: Dict[str, Dict[str, Any]] = model.schema().get("properties", {})
properties: dict[str, dict[str, Any]] = model.schema().get("properties", {})
properties.pop("user_infos")
args_info = "\n" + "\n".join(
[arg_info(name, info) for name, info in properties.items()]
Expand Down Expand Up @@ -134,7 +134,7 @@ def generate_meme_preview(key: str) -> str:


def generate_meme(
key: str, images: List[str], texts: List[str], args: Dict[str, Any]
key: str, images: list[str], texts: list[str], args: dict[str, Any]
) -> str:
try:
meme = get_meme(key)
Expand Down Expand Up @@ -180,8 +180,8 @@ def main():
kwargs = vars(args)
kwargs.pop("handle")
key: str = kwargs.pop("key")
images: List[str] = kwargs.pop("images")
texts: List[str] = kwargs.pop("texts")
images: list[str] = kwargs.pop("images")
texts: list[str] = kwargs.pop("texts")
print(generate_meme(key, images, texts, kwargs)) # noqa: T201

elif handle in ["run", "start"]:
Expand Down
8 changes: 4 additions & 4 deletions meme_generator/config.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import json
from pathlib import Path
from typing import List, Optional, Union
from typing import Optional, Union

import toml
from pydantic import BaseModel, Extra
Expand All @@ -12,13 +12,13 @@

class MemeConfig(BaseModel):
load_builtin_memes: bool = True
meme_dirs: List[Path] = []
meme_disabled_list: List[str] = []
meme_dirs: list[Path] = []
meme_disabled_list: list[str] = []


class ResourceConfig(BaseModel):
resource_url: Optional[str] = None
resource_urls: List[str] = [
resource_urls: list[str] = [
"https://raw.githubusercontent.com/MeetWq/meme-generator/",
"https://ghproxy.com/https://raw.githubusercontent.com/MeetWq/meme-generator/",
"https://fastly.jsdelivr.net/gh/MeetWq/meme-generator@",
Expand Down
5 changes: 2 additions & 3 deletions meme_generator/download.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import json
import time
from pathlib import Path
from typing import List, Tuple

import httpx
from rich.progress import Progress
Expand All @@ -18,7 +17,7 @@ def _resource_url(base_url: str, name: str) -> str:


# https://github.com/mnixry/nonebot-plugin-gocqhttp/blob/main/nonebot_plugin_gocqhttp/process/download.py
async def get_fastest_mirror() -> List[str]:
async def get_fastest_mirror() -> list[str]:
assert meme_config.resource.resource_urls, "No resource url specified."

async def head_mirror(client: httpx.AsyncClient, base_url: str):
Expand Down Expand Up @@ -76,7 +75,7 @@ async def _download(client: httpx.AsyncClient, name: str):
else:
return

download_list: List[Tuple[Path, str]] = []
download_list: list[tuple[Path, str]] = []
for resource in resource_list:
file_name = str(resource["path"])
file_hash = str(resource["hash"])
Expand Down
14 changes: 7 additions & 7 deletions meme_generator/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
import importlib.util
import pkgutil
from pathlib import Path
from typing import Dict, List, Optional, Union
from typing import Optional, Union

from .config import meme_config
from .exception import NoSuchMeme
from .log import logger
from .meme import Meme, MemeArgsType, MemeFunction, MemeParamsType

_memes: Dict[str, Meme] = {}
_memes: dict[str, Meme] = {}


def path_to_module_name(path: Path) -> str:
Expand Down Expand Up @@ -64,10 +64,10 @@ def add_meme(
max_images: int = 0,
min_texts: int = 0,
max_texts: int = 0,
default_texts: List[str] = [],
default_texts: list[str] = [],
args_type: Optional[MemeArgsType] = None,
keywords: List[str] = [],
patterns: List[str] = [],
keywords: list[str] = [],
patterns: list[str] = [],
):
if key in _memes:
logger.warning(f'Meme with key "{key}" already exists!')
Expand Down Expand Up @@ -96,9 +96,9 @@ def get_meme(key: str) -> Meme:
return _memes[key]


def get_memes() -> List[Meme]:
def get_memes() -> list[Meme]:
return list(_memes.values())


def get_meme_keys() -> List[str]:
def get_meme_keys() -> list[str]:
return list(_memes.keys())
35 changes: 16 additions & 19 deletions meme_generator/meme.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
import copy
from argparse import ArgumentError, ArgumentParser
from collections.abc import Awaitable
from contextvars import ContextVar
from dataclasses import dataclass, field
from io import BytesIO
from pathlib import Path
from typing import (
IO,
Any,
Awaitable,
Callable,
Dict,
List,
Literal,
Optional,
Type,
TypeVar,
Union,
cast,
Expand All @@ -40,14 +37,14 @@ class UserInfo(BaseModel):


class MemeArgsModel(BaseModel):
user_infos: List[UserInfo] = []
user_infos: list[UserInfo] = []


ArgsModel = TypeVar("ArgsModel", bound=MemeArgsModel)

MemeFunction = Union[
Callable[[List[BuildImage], List[str], ArgsModel], BytesIO],
Callable[[List[BuildImage], List[str], ArgsModel], Awaitable[BytesIO]],
Callable[[list[BuildImage], list[str], ArgsModel], BytesIO],
Callable[[list[BuildImage], list[str], ArgsModel], Awaitable[BytesIO]],
]


Expand Down Expand Up @@ -77,8 +74,8 @@ def exit(self, status: int = 0, message: Optional[str] = None):
@dataclass
class MemeArgsType:
parser: MemeArgsParser
model: Type[MemeArgsModel]
instances: List[MemeArgsModel] = field(default_factory=list)
model: type[MemeArgsModel]
instances: list[MemeArgsModel] = field(default_factory=list)


@dataclass
Expand All @@ -87,7 +84,7 @@ class MemeParamsType:
max_images: int = 0
min_texts: int = 0
max_texts: int = 0
default_texts: List[str] = field(default_factory=list)
default_texts: list[str] = field(default_factory=list)
args_type: Optional[MemeArgsType] = None


Expand All @@ -96,15 +93,15 @@ class Meme:
key: str
function: MemeFunction
params_type: MemeParamsType
keywords: List[str] = field(default_factory=list)
patterns: List[str] = field(default_factory=list)
keywords: list[str] = field(default_factory=list)
patterns: list[str] = field(default_factory=list)

async def __call__(
self,
*,
images: Union[List[str], List[Path], List[bytes], List[BytesIO]] = [],
texts: List[str] = [],
args: Dict[str, Any] = {},
images: Union[list[str], list[Path], list[bytes], list[BytesIO]] = [],
texts: list[str] = [],
args: dict[str, Any] = {},
) -> BytesIO:
if not (
self.params_type.min_images <= len(images) <= self.params_type.max_images
Expand All @@ -128,7 +125,7 @@ async def __call__(
except ValidationError as e:
raise ArgModelMismatch(self.key, str(e))

imgs: List[BuildImage] = []
imgs: list[BuildImage] = []
try:
for image in images:
if isinstance(image, bytes):
Expand All @@ -146,7 +143,7 @@ async def __call__(
else:
return await run_sync(cast(Callable[..., BytesIO], self.function))(**values)

def parse_args(self, args: List[str] = []) -> Dict[str, Any]:
def parse_args(self, args: list[str] = []) -> dict[str, Any]:
parser = (
copy.deepcopy(self.params_type.args_type.parser)
if self.params_type.args_type
Expand All @@ -163,7 +160,7 @@ def parse_args(self, args: List[str] = []) -> Dict[str, Any]:
finally:
parser_message.reset(t)

async def generate_preview(self, *, args: Dict[str, Any] = {}) -> BytesIO:
async def generate_preview(self, *, args: dict[str, Any] = {}) -> BytesIO:
default_images = [random_image() for _ in range(self.params_type.min_images)]
default_texts = (
self.params_type.default_texts.copy()
Expand All @@ -175,7 +172,7 @@ async def generate_preview(self, *, args: Dict[str, Any] = {}) -> BytesIO:
else [random_text() for _ in range(self.params_type.min_texts)]
)

async def _generate_preview(images: List[BytesIO], texts: List[str]):
async def _generate_preview(images: list[BytesIO], texts: list[str]):
try:
return await self.__call__(images=images, texts=texts, args=args)
except TextOrNameNotEnough:
Expand Down
Loading

0 comments on commit 67912a8

Please sign in to comment.