XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet
公开
关注 0 Fork 0 Star 1
返回提交历史

XFEstudio/gpt4free

Improve copy_images api Update share target support Improve search enabled hightlight

31a4812d
hlohaus <983577+hlohaus@users.noreply.github.com>
提交于

代码差异

6 个文件 +48 -51
Modified g4f/api/__init__.py +12 -17
@@ -40,7 +40,7 @@ from g4f.client import AsyncClient, ChatCompletion, ImagesResponse, convert_to_p
40 40 from g4f.providers.response import BaseConversation, JsonConversation
41 41 from g4f.client.helper import filter_none
42 42 from g4f.image import is_data_uri_an_image
43 from g4f.image.copy_images import images_dir, copy_images
43 from g4f.image.copy_images import images_dir, copy_images, get_source_url
44 44 from g4f.errors import ProviderNotFoundError, ModelNotFoundError, MissingAuthError, NoValidHarFileError
45 45 from g4f.cookies import read_cookie_files, get_cookies_dir
46 46 from g4f.Provider import ProviderType, ProviderUtils, __providers__
@@ -298,11 +298,9 @@ class Api:
298 298 })
299 299 async def chat_completions(
300 300 config: ChatCompletionsConfig,
301 credentials: Annotated[HTTPAuthorizationCredentials, Depends(Api.security)] = None,
302 provider: str = None
301 credentials: Annotated[HTTPAuthorizationCredentials, Depends(Api.security)] = None
303 302 ):
304 303 try:
305 config.provider = provider if config.provider is None else config.provider
306 304 if config.provider is None:
307 305 config.provider = AppConfig.provider
308 306 if credentials is not None:
@@ -582,19 +580,16 @@ class Api:
582 580 except KeyError:
583 581 pass
584 582 if not os.path.isfile(target):
585 source_url = str(request.query_params).split("url=", 1)
586 if len(source_url) > 1:
587 source_url = source_url[1]
588 source_url = source_url.replace("%2F", "/").replace("%3A", ":").replace("%3F", "?").replace("%3D", "=")
589 if source_url.startswith("https://"):
590 try:
591 await copy_images(
592 [source_url],
593 target=target)
594 debug.log(f"Image copied from {source_url}")
595 except Exception as e:
596 debug.log(f"{type(e).__name__}: Download failed: {source_url}\n{e}")
597 return RedirectResponse(url=source_url)
583 source_url = get_source_url(str(request.query_params))
584 if source_url is not None:
585 try:
586 await copy_images(
587 [source_url],
588 target=target)
589 debug.log(f"Image copied from {source_url}")
590 except Exception as e:
591 debug.log(f"{type(e).__name__}: Download failed: {source_url}\n{e}")
592 return RedirectResponse(url=source_url)
598 593 if not os.path.isfile(target):
599 594 return ErrorResponse.from_message("File not found", HTTP_404_NOT_FOUND)
600 595 async def stream():
Modified g4f/gui/client/index.html +1 -3
@@ -288,9 +288,7 @@
288 288 <div class="buttons">
289 289 <div class="field">
290 290 <button id="search">
291 <a href="" onclick="return false;" title="Enable Web Access">
292 <i class="fa-solid fa-search"></i>
293 </a>
291 <i class="fa-solid fa-search"></i>
294 292 </button>
295 293 </div>
296 294 <div class="field">
Modified g4f/gui/client/static/css/style.css +5 -1
@@ -684,10 +684,14 @@ input-count .text {
684 684 .file-label:has(> input:valid),
685 685 .file-label.selected,
686 686 .micro-label.recognition,
687 #search.active a i {
687 #search.active i {
688 688 color: var(--accent);
689 689 }
690 690
691 #search.active {
692 border-color: var(--accent);
693 }
694
691 695 label[for="image"] {
692 696 top: 32px;
693 697 }
Modified g4f/gui/client/static/img/site.webmanifest +2 -2
@@ -21,9 +21,9 @@
21 21 "method": "GET",
22 22 "enctype": "application/x-www-form-urlencoded",
23 23 "params": {
24 "title": "title",
24 "title": "name",
25 25 "text": "prompt",
26 "url": "url"
26 "url": "link"
27 27 }
28 28 }
29 29 }
Modified g4f/gui/server/website.py +2 -0
@@ -31,6 +31,8 @@ class Website:
31 31 }
32 32
33 33 def _chat(self, conversation_id):
34 if conversation_id == "share":
35 return render_template('index.html', chat_id=str(uuid.uuid4()))
34 36 if '-' not in conversation_id:
35 37 return redirect_home()
36 38 return render_template('index.html', chat_id=conversation_id)
Modified g4f/image/copy_images.py +26 -28
@@ -58,36 +58,34 @@ async def copy_images(
58 58 async def copy_image(image: str, target: str = None, headers: dict = headers, ssl: bool = ssl) -> str:
59 59 if target is None or len(images) > 1:
60 60 hash = hashlib.sha256(image.encode()).hexdigest()
61 target = f"{quote_plus('+'.join(alt.split()[:10])[:100], '')}_{hash}" if alt else str(uuid.uuid4())
61 target = f"{quote_plus('+'.join(alt.split()[:10]), '')[:100]}_{hash[:16]}" if alt else str(uuid.uuid4())
62 62 target = f"{int(time.time())}_{target}{get_image_extension(image)}"
63 63 target = os.path.join(images_dir, target)
64 try:
65 if image.startswith("data:"):
66 with open(target, "wb") as f:
67 f.write(extract_data_uri(image))
68 else:
69 try:
70 if BackendApi.working and image.startswith(BackendApi.url) and headers is None:
71 headers = BackendApi.headers
72 ssl = BackendApi.ssl
73 async with session.get(image, ssl=ssl, headers=headers) as response:
74 response.raise_for_status()
75 with open(target, "wb") as f:
76 async for chunk in response.content.iter_chunked(4096):
77 f.write(chunk)
78 except ClientError as e:
79 debug.log(f"copy_images failed: {e.__class__.__name__}: {e}")
80 return get_source_url(image, image)
81 if "." not in target:
82 with open(target, "rb") as f:
83 extension = is_accepted_format(f.read(12)).split("/")[-1]
84 extension = "jpg" if extension == "jpeg" else extension
85 new_target = f"{target}.{extension}"
86 os.rename(target, new_target)
87 target = new_target
88 finally:
89 if "." not in target and os.path.exists(target):
90 os.unlink(target)
64 if image.startswith("data:"):
65 with open(target, "wb") as f:
66 f.write(extract_data_uri(image))
67 else:
68 try:
69 if BackendApi.working and image.startswith(BackendApi.url) and headers is None:
70 headers = BackendApi.headers
71 ssl = BackendApi.ssl
72 async with session.get(image, ssl=ssl, headers=headers) as response:
73 response.raise_for_status()
74 with open(target, "wb") as f:
75 async for chunk in response.content.iter_chunked(4096):
76 f.write(chunk)
77 except ClientError as e:
78 debug.log(f"copy_images failed: {e.__class__.__name__}: {e}")
79 if os.path.exists(target):
80 os.unlink(target)
81 return get_source_url(image, image)
82 if "." not in target:
83 with open(target, "rb") as f:
84 extension = is_accepted_format(f.read(12)).split("/")[-1]
85 extension = "jpg" if extension == "jpeg" else extension
86 new_target = f"{target}.{extension}"
87 os.rename(target, new_target)
88 target = new_target
91 89 return f"/images/{os.path.basename(target)}{'?url=' + image if add_url and not image.startswith('data:') else ''}"
92 90
93 91 return await asyncio.gather(*[copy_image(image, target) for image in images])