返回提交历史
Modified
g4f/gui/server/api.py
+4
-2
Modified
g4f/gui/server/backend_api.py
+2
-2
Modified
g4f/image/__init__.py
+23
-18
Modified
g4f/image/copy_images.py
+3
-3
Modified
g4f/tools/media.py
+8
-0
XFEstudio/gpt4free
Fix load share conversation
74b31371
代码差异
5 个文件
+40
-25
@@ -9,6 +9,7 @@ from inspect import signature
9
9
10
10
from ...errors import VersionNotFoundError, MissingAuthError
11
11
from ...image.copy_images import copy_media, ensure_media_dir, get_media_dir
12
from ...image import get_width_height
12
13
from ...tools.run_tools import iter_run_tools
13
14
from ... import Provider
14
15
from ...providers.base_provider import ProviderModelMixin
@@ -196,8 +197,9 @@ class Api:
196
197
media = chunk
197
198
if download_media or chunk.get("cookies"):
198
199
chunk.alt = format_media_prompt(kwargs.get("messages"), chunk.alt)
199
tags = [model, kwargs.get("aspect_ratio"), kwargs.get("resolution"), kwargs.get("width"), kwargs.get("height")]
200
media = asyncio.run(copy_media(chunk.get_list(), chunk.get("cookies"), chunk.get("headers"), proxy=proxy, alt=chunk.alt, tags=tags))
200
width, height = get_width_height(chunk.get("width"), chunk.get("height"))
201
tags = [model, kwargs.get("aspect_ratio"), kwargs.get("resolution")]
202
media = asyncio.run(copy_media(chunk.get_list(), chunk.get("cookies"), chunk.get("headers"), proxy=proxy, alt=chunk.alt, tags=tags, add_url=f"width={width}&height={height}&"))
201
203
media = ImageResponse(media, chunk.alt) if isinstance(chunk, ImageResponse) else VideoResponse(media, chunk.alt)
202
204
yield self._format_json("content", str(media), urls=media.urls, alt=media.alt)
203
205
elif isinstance(chunk, SynthesizeData):
@@ -442,14 +442,14 @@ class Backend_Api(Api):
442
442
@self.app.route('/backend-api/v2/chat/<share_id>', methods=['GET'])
443
443
def get_chat(share_id: str) -> str:
444
444
share_id = secure_filename(share_id)
445
if self.chat_cache.get(share_id, 0) == int(request.headers.get("if-none-match", 0)):
445
if self.chat_cache.get(share_id, 0) == int(request.headers.get("if-none-match", -1)):
446
446
return jsonify({"error": {"message": "Not modified"}}), 304
447
447
file = get_bucket_dir(share_id, "chat.json")
448
448
if not os.path.isfile(file):
449
449
return jsonify({"error": {"message": "Not found"}}), 404
450
450
with open(file, 'r') as f:
451
451
chat_data = json.load(f)
452
if chat_data.get("updated", 0) == int(request.headers.get("if-none-match", 0)):
452
if chat_data.get("updated", 0) == int(request.headers.get("if-none-match", -1)):
453
453
return jsonify({"error": {"message": "Not modified"}}), 304
454
454
self.chat_cache[share_id] = chat_data.get("updated", 0)
455
455
return jsonify(chat_data), 200
@@ -310,26 +310,31 @@ def to_input_audio(audio: ImageType, filename: str = None) -> str:
310
310
def use_aspect_ratio(extra_body: dict, aspect_ratio: str) -> Image:
311
311
extra_body = {key: value for key, value in extra_body.items() if value is not None}
312
312
if extra_body.get("width") is None or extra_body.get("height") is None:
313
if aspect_ratio == "1:1":
314
extra_body = {
315
"width": extra_body.get("width", 1024),
316
"height": extra_body.get("height", 1024),
317
**extra_body
318
}
319
elif aspect_ratio == "16:9":
320
extra_body = {
321
"width": extra_body.get("width", 832),
322
"height": extra_body.get("height", 480),
323
**extra_body
324
}
325
elif aspect_ratio == "9:16":
326
extra_body = {
327
"width": extra_body.get("width", 480),
328
"height": extra_body.get("height", 832),
329
**extra_body
330
}
313
width, height = get_width_height(
314
aspect_ratio,
315
extra_body.get("width"),
316
extra_body.get("height")
317
)
318
extra_body = {
319
"width": width,
320
"height": height,
321
**extra_body
322
}
331
323
return extra_body
332
324
325
def get_width_height(
326
aspect_ratio: str,
327
width: Optional[int] = None,
328
height: Optional[int] = None
329
) -> tuple[int, int]:
330
if aspect_ratio == "1:1":
331
return width or 1024, height or 1024
332
elif aspect_ratio == "16:9":
333
return width or 832, height or 480
334
elif aspect_ratio == "9:16":
335
return width or 480, height or 832,
336
return width, height
337
333
338
class ImageRequest:
334
339
def __init__(
335
340
self,
@@ -10,7 +10,7 @@ from urllib.parse import quote, unquote
10
10
from aiohttp import ClientSession, ClientError
11
11
from urllib.parse import urlparse
12
12
13
from ..typing import Optional, Cookies
13
from ..typing import Optional, Cookies, Union
14
14
from ..requests.aiohttp import get_connector
15
15
from ..image import MEDIA_TYPE_MAP, EXTENSIONS_MAP
16
16
from ..tools.files import secure_filename
@@ -108,7 +108,7 @@ async def copy_media(
108
108
proxy: Optional[str] = None,
109
109
alt: str = None,
110
110
tags: list[str] = None,
111
add_url: bool = True,
111
add_url: Union[bool, str] = True,
112
112
target: str = None,
113
113
ssl: bool = None
114
114
) -> list[str]:
@@ -178,7 +178,7 @@ async def copy_media(
178
178
pass
179
179
# Build URL with safe encoding
180
180
url_filename = quote(os.path.basename(target_path))
181
return f"/media/{url_filename}" + (('?url=' + quote(image)) if add_url and not image.startswith('data:') else '')
181
return f"/media/{url_filename}" + (('?' + add_url if isinstance(add_url, str) else '' + 'url=' + quote(image)) if add_url and not image.startswith('data:') else '')
182
182
183
183
except (ClientError, IOError, OSError, ValueError) as e:
184
184
debug.error(f"Image copying failed: {type(e).__name__}: {e}")
@@ -70,7 +70,15 @@ def merge_media(media: list, messages: list) -> Iterator:
70
70
yield from media
71
71
72
72
def render_messages(messages: Messages, media: list = None) -> Iterator:
73
last_is_assistant = False
73
74
for idx, message in enumerate(messages):
75
# Remove duplicate assistant messages
76
if message.get("role") == "assistant":
77
if last_is_assistant:
78
continue
79
last_is_assistant = True
80
else:
81
last_is_assistant = False
74
82
if isinstance(message["content"], list):
75
83
parts = [render_part(part) for part in message["content"] if part]
76
84
yield {