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

XFEstudio/gpt4free

Update copy_image

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

代码差异

4 个文件 +62 -29
Modified g4f/Provider/needs_auth/Video.py +42 -25
@@ -1,5 +1,6 @@
1 1 from __future__ import annotations
2 2
3 import time
3 4 import asyncio
4 5 import random
5 6 from aiohttp import ClientSession, ClientTimeout
@@ -13,7 +14,7 @@ except:
13 14 pass
14 15
15 16 from ...typing import Messages, AsyncResult
16 from ...providers.response import VideoResponse, Reasoning
17 from ...providers.response import VideoResponse, Reasoning, ContinueResponse
17 18 from ...requests import get_nodriver
18 19 from ...errors import MissingRequirementsError
19 20 from ..base_provider import AsyncGeneratorProvider
@@ -49,24 +50,34 @@ class Video(AsyncGeneratorProvider):
49 50 prompt: str = None,
50 51 **kwargs
51 52 ) -> AsyncResult:
53 started = time.time()
52 54 prompt = format_media_prompt(messages, prompt)
53 55 if not prompt:
54 56 raise ValueError("Prompt cannot be empty.")
57 async with ClientSession() as session:
58 yield Reasoning(label="Lookup")
59 has_video = False
60 for skip in range(0, 9):
61 async with session.get(cls.search_url + quote_plus(prompt) + f"?skip={skip}", timeout=ClientTimeout(total=10)) as response:
62 if response.ok:
63 yield Reasoning(label=f"Found {skip+1}", status="")
64 yield VideoResponse(str(response.url), prompt)
65 has_video = True
66 else:
67 break
68 if has_video:
69 yield Reasoning(label=f"Finished", status="")
70 return
55 71 try:
72 yield Reasoning(label="Open browser")
56 73 browser, stop_browser = await get_nodriver(proxy=proxy, user_data_dir="gemini")
57 74 except Exception as e:
58 75 debug.error(f"Error getting nodriver:", e)
59 76 async with ClientSession() as session:
60 yield Reasoning(label="Lookup")
61 async with session.get(cls.search_url + quote_plus(prompt) + f"&min={prompt.count(' ') + 1}", timeout=ClientTimeout(total=10)) as response:
62 if response.status == 200:
63 yield Reasoning(label="Found", status="")
64 yield VideoResponse(str(response.url), prompt)
65 return
66 77 yield Reasoning(label="Generating")
67 78 async with session.post(cls.api_url + quote(prompt)) as response:
68 79 if not response.ok:
69 debug.error(f"Failed to lookup Video: {response.status}")
80 debug.error(f"Failed to generate Video: {response.status}")
70 81 else:
71 82 yield Reasoning(label="Finished", status="")
72 83 if response.headers.get("content-type", "text/plain").startswith("text/plain"):
@@ -92,20 +103,6 @@ class Video(AsyncGeneratorProvider):
92 103 page = cls.page
93 104 await asyncio.sleep(3)
94 105 await page.select("textarea", 240)
95 def on_request(event: nodriver.cdp.network.RequestWillBeSent, page=None):
96 if "mp4" in event.request.url:
97 RequestConfig.headers = {}
98 for key, value in event.request.headers.items():
99 RequestConfig.headers[key.lower()] = value
100 RequestConfig.urls.append(event.request.url)
101 elif event.request.url.startswith(cls.drive_url):
102 RequestConfig.headers = {}
103 for key, value in event.request.headers.items():
104 RequestConfig.headers[key.lower()] = value
105 RequestConfig.urls.append(event.request.url)
106 await page.send(nodriver.cdp.network.enable())
107 page.add_handler(nodriver.cdp.network.RequestWillBeSent, on_request)
108
109 106 try:
110 107 button = await page.find("Image")
111 108 if button:
@@ -115,6 +112,7 @@ class Video(AsyncGeneratorProvider):
115 112 button = await page.find("Video")
116 113 if button:
117 114 await button.click()
115 yield Reasoning(label=f"Clicked 'Video' button")
118 116 else:
119 117 debug.error("No 'Video' button found.")
120 118 except Exception as e:
@@ -122,6 +120,7 @@ class Video(AsyncGeneratorProvider):
122 120 debug.log(f"Using prompt: {prompt}")
123 121 textarea = await page.select("textarea", 180)
124 122 await textarea.send_keys(prompt)
123 yield Reasoning(label=f"Sending prompt", token=prompt)
125 124 # try:
126 125 # button = await page.select('button[type="submit"]', 5)
127 126 # if button:
@@ -131,12 +130,14 @@ class Video(AsyncGeneratorProvider):
131 130 button = await page.find("Create")
132 131 if button:
133 132 await button.click()
133 yield Reasoning(label=f"Clicked 'Create' button")
134 134 except Exception as e:
135 135 debug.error(f"Error clicking 'Create' button:", e)
136 136 try:
137 137 button = await page.find("Activity")
138 138 if button:
139 139 await button.click()
140 yield Reasoning(label=f"Clicked 'Activity' button")
140 141 except Exception as e:
141 142 debug.error(f"Error clicking 'Activity' button:", e)
142 143 for idx in range(60):
@@ -145,12 +146,27 @@ class Video(AsyncGeneratorProvider):
145 146 button = await page.find("Queued")
146 147 if button:
147 148 await button.click()
148 debug.log(f"Clicked 'Queued' button")
149 yield Reasoning(label=f"Clicked 'Queued' button")
149 150 break
150 except:
151 except Exception as e:
151 152 debug.error(f"Error clicking 'Queued' button:", e)
152 debug.log(f"Waiting for Video URL...")
153 yield Reasoning(label=f"Waiting for Video URL...")
154 def on_request(event: nodriver.cdp.network.RequestWillBeSent, page=None):
155 if "mp4" in event.request.url:
156 RequestConfig.headers = {}
157 for key, value in event.request.headers.items():
158 RequestConfig.headers[key.lower()] = value
159 RequestConfig.urls.append(event.request.url)
160 elif event.request.url.startswith(cls.drive_url):
161 RequestConfig.headers = {}
162 for key, value in event.request.headers.items():
163 RequestConfig.headers[key.lower()] = value
164 RequestConfig.urls.append(event.request.url)
165 await page.send(nodriver.cdp.network.enable())
166 page.add_handler(nodriver.cdp.network.RequestWillBeSent, on_request)
153 167 for idx in range(600):
168 if time.time() - started > 30:
169 yield ContinueResponse("Timeout waiting for Video URL")
154 170 await asyncio.sleep(1)
155 171 if RequestConfig.urls:
156 172 await asyncio.sleep(2)
@@ -159,6 +175,7 @@ class Video(AsyncGeneratorProvider):
159 175 yield VideoResponse(RequestConfig.urls, prompt, {
160 176 "headers": {"authorization": RequestConfig.headers.get("authorization")} if RequestConfig.headers.get("authorization") else {}
161 177 })
178 yield Reasoning(label=f"Finished", status="")
162 179 break
163 180 if idx == 599:
164 181 raise RuntimeError("Failed to get Video URL")
Modified g4f/image/copy_images.py +13 -3
@@ -5,6 +5,7 @@ import time
5 5 import asyncio
6 6 import hashlib
7 7 import base64
8 from datetime import datetime
8 9 from typing import AsyncIterator
9 10 from urllib.parse import quote, unquote
10 11 from aiohttp import ClientSession, ClientError
@@ -135,14 +136,18 @@ async def copy_media(
135 136 if target_path is None:
136 137 # Build safe filename with full Unicode support
137 138 media_extension = get_media_extension(image)
138 filename = get_filename(tags, alt, media_extension, image)
139 path = urlparse(image).path
140 if path.startswith("/media/"):
141 filename = secure_filename(path[len("/media/"):])
142 else:
143 filename = get_filename(tags, alt, media_extension, image)
139 144 target_path = os.path.join(get_media_dir(), filename)
140 145 try:
141 146 # Handle different image types
142 147 if image.startswith("data:"):
143 148 with open(target_path, "wb") as f:
144 149 f.write(extract_data_uri(image))
145 else:
150 elif not os.path.exists(target_path) or os.lstat(target_path).st_size <= 0:
146 151 # Apply BackendApi settings if needed
147 152 if BackendApi.working and image.startswith(BackendApi.url):
148 153 request_headers = BackendApi.headers if headers is None else headers
@@ -151,9 +156,14 @@ async def copy_media(
151 156 request_headers = headers
152 157 request_ssl = ssl
153 158 # Use aiohttp to fetch the image
154 debug.log(f"Copying image: {image} to {target_path}")
155 159 async with session.get(image, ssl=request_ssl, headers=request_headers) as response:
156 160 response.raise_for_status()
161 date = response.headers.get("date")
162 if date and target_path != target:
163 timestamp = datetime.strptime(date, '%a, %d %b %Y %H:%M:%S %Z').timestamp()
164 filename = str(int(timestamp)) + "_" + filename.split("_", maxsplit=1)[-1]
165 target_path = os.path.join(get_media_dir(), filename)
166 debug.log(f"Copying image: {image} to {target_path}")
157 167 media_type = response.headers.get("content-type", "application/octet-stream")
158 168 if media_type not in ("application/octet-stream", "binary/octet-stream"):
159 169 if media_type not in MEDIA_TYPE_MAP:
Modified g4f/providers/response.py +5 -0
@@ -192,6 +192,11 @@ class DebugResponse(HiddenResponse):
192 192 """Initialize with a log message."""
193 193 self.log = log
194 194
195 class ContinueResponse(HiddenResponse):
196 def __init__(self, log: str) -> None:
197 """Initialize with a log message."""
198 self.log = log
199
195 200 class Reasoning(ResponseType):
196 201 def __init__(
197 202 self,
Modified g4f/requests/__init__.py +2 -1
@@ -146,7 +146,7 @@ def set_browser_executable_path(browser_executable_path: str):
146 146 async def get_nodriver(
147 147 proxy: str = None,
148 148 user_data_dir = "nodriver",
149 timeout: int = 120,
149 timeout: int = 300,
150 150 browser_executable_path: str = None,
151 151 **kwargs
152 152 ) -> tuple[Browser, callable]:
@@ -172,6 +172,7 @@ async def get_nodriver(
172 172 time_open = time.time() - opend_at
173 173 if timeout * 2 > time_open:
174 174 debug.log(f"Nodriver: Browser is already in use since {time_open} secs.")
175 debug.log("Lock file:", lock_file)
175 176 for _ in range(timeout):
176 177 if lock_file.exists():
177 178 await asyncio.sleep(1)