返回提交历史
Modified
g4f/gui/server/website.py
+49
-2
XFEstudio/gpt4free
feat: add playground route with caching and GitHub integration for dynamic content serving
8ba8697e
代码差异
1 个文件
+49
-2
@@ -21,7 +21,10 @@ def render(filename = "home", download_url: str = GITHUB_URL):
21
21
html = None
22
22
is_temp = False
23
23
if os.path.exists(DIST_DIR) and not request.args.get("debug"):
24
path = os.path.abspath(os.path.join(os.path.dirname(DIST_DIR), filename))
24
base_dir = os.path.abspath(os.path.dirname(DIST_DIR))
25
path = os.path.abspath(os.path.join(base_dir, filename))
26
if not path.startswith(base_dir + os.sep) and path != base_dir:
27
return redirect('/')
25
28
if os.path.exists(path):
26
29
if download_url == GITHUB_URL:
27
30
with open(path, 'r', encoding='utf-8') as f:
@@ -130,6 +133,14 @@ class Website:
130
133
'function': self._npm,
131
134
'methods': ['GET']
132
135
},
136
'/playground/': {
137
'function': self._playground,
138
'methods': ['GET']
139
},
140
'/playground/<path:filename>': {
141
'function': self._playground,
142
'methods': ['GET']
143
},
133
144
}
134
145
135
146
def _index(self, filename = "home"):
@@ -159,4 +170,40 @@ class Website:
159
170
return render(f"gh/{name}", JSDELIVR_URL)
160
171
161
172
def _npm(self, name):
162
return render(f"npm/{name}", JSDELIVR_URL)
173
return render(f"npm/{name}", JSDELIVR_URL)
174
175
def _playground(self, filename: str = "index.html"):
176
PLAYGROUND_URL = "https://raw.githubusercontent.com/gpt4free/playground/refs/heads/main/"
177
if not filename or filename.endswith("/"):
178
filename = "index.html"
179
# Serve from local ./playground directory if present
180
local_dir = os.path.abspath("./playground")
181
local_path = os.path.normpath(os.path.join(local_dir, filename))
182
if local_path.startswith(local_dir + os.sep) and os.path.isfile(local_path):
183
return send_from_directory(os.path.dirname(local_path), os.path.basename(local_path))
184
# Use cache dir
185
cache_dir = os.path.join(get_cookies_dir(), ".playground_cache")
186
safe_path = os.path.normpath(os.path.join(cache_dir, filename))
187
if not safe_path.startswith(cache_dir + os.sep) and safe_path != cache_dir:
188
return redirect("/playground/")
189
# Serve from cache if present
190
if os.path.isfile(safe_path):
191
return send_from_directory(os.path.dirname(safe_path), os.path.basename(safe_path))
192
# Download and cache from GitHub
193
os.makedirs(os.path.dirname(safe_path), exist_ok=True)
194
try:
195
response = requests.get(f"{PLAYGROUND_URL}{filename}", timeout=10)
196
response.raise_for_status()
197
with open(safe_path, 'wb') as f:
198
f.write(response.content)
199
return send_from_directory(os.path.dirname(safe_path), os.path.basename(safe_path))
200
except requests.RequestException:
201
pass
202
# SPA fallback: serve index.html for unknown sub-paths
203
index_path = os.path.join(cache_dir, "index.html")
204
if os.path.isfile(index_path):
205
return send_from_directory(cache_dir, "index.html")
206
local_index = os.path.join(local_dir, "index.html")
207
if os.path.isfile(local_index):
208
return send_from_directory(local_dir, "index.html")
209
return redirect("https://gpt4free.github.io/playground")