Follow Picture Agent gallery data URL
This commit is contained in:
@@ -14,12 +14,15 @@ use axum::{
|
|||||||
routing::{get, post},
|
routing::{get, post},
|
||||||
};
|
};
|
||||||
use reqwest::Client;
|
use reqwest::Client;
|
||||||
|
use reqwest::Url;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use serde_json::{Value, json};
|
use serde_json::{Value, json};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
const TEMPLATE_GALLERY_URL: &str =
|
const TEMPLATE_GALLERY_PAGE_URL: &str =
|
||||||
"https://weiyyin.github.io/linux-do-gpt-image/linux_do_2036927_prompts_images.filtered.json";
|
"https://weiyyin.github.io/linux-do-gpt-image/prompt_gallery.html";
|
||||||
|
const TEMPLATE_GALLERY_FALLBACK_DATA_URL: &str =
|
||||||
|
"https://weiyyin.github.io/linux-do-gpt-image/linux_do_2036927_prompts_images.with_tags.json";
|
||||||
const TASK_TYPE_PICTURE_GENERATION: &str = "picture-agent-generation";
|
const TASK_TYPE_PICTURE_GENERATION: &str = "picture-agent-generation";
|
||||||
const TEMPLATE_GALLERY_TIMEOUT_SECS: u64 = 30;
|
const TEMPLATE_GALLERY_TIMEOUT_SECS: u64 = 30;
|
||||||
const PICTURE_GENERATION_TIMEOUT_SECS: u64 = 300;
|
const PICTURE_GENERATION_TIMEOUT_SECS: u64 = 300;
|
||||||
@@ -285,6 +288,23 @@ mod tests {
|
|||||||
assert!(!is_picture_model_pattern("deepseek-chat"));
|
assert!(!is_picture_model_pattern("deepseek-chat"));
|
||||||
assert!(!is_picture_model_pattern("qwen-plus"));
|
assert!(!is_picture_model_pattern("qwen-plus"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn extracts_gallery_data_url_from_page_script() {
|
||||||
|
let html = r#"
|
||||||
|
<script>
|
||||||
|
const DATA_URL = "./linux_do_2036927_prompts_images.with_tags.json";
|
||||||
|
</script>
|
||||||
|
"#;
|
||||||
|
assert_eq!(
|
||||||
|
extract_gallery_data_url(html).as_deref(),
|
||||||
|
Some("./linux_do_2036927_prompts_images.with_tags.json")
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
absolute_gallery_url("./linux_do_2036927_prompts_images.with_tags.json").unwrap(),
|
||||||
|
"https://weiyyin.github.io/linux-do-gpt-image/linux_do_2036927_prompts_images.with_tags.json"
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prompt_title(prompt: &str, post_number: Option<i64>) -> String {
|
fn prompt_title(prompt: &str, post_number: Option<i64>) -> String {
|
||||||
@@ -364,7 +384,7 @@ async fn templates_handler(
|
|||||||
|
|
||||||
Ok(Json(json!({
|
Ok(Json(json!({
|
||||||
"success": true,
|
"success": true,
|
||||||
"sourceUrl": "https://weiyyin.github.io/linux-do-gpt-image/prompt_gallery.html",
|
"sourceUrl": TEMPLATE_GALLERY_PAGE_URL,
|
||||||
"fallback": remote_status.get("ok").and_then(Value::as_bool) != Some(true),
|
"fallback": remote_status.get("ok").and_then(Value::as_bool) != Some(true),
|
||||||
"remote": remote_status,
|
"remote": remote_status,
|
||||||
"templates": templates,
|
"templates": templates,
|
||||||
@@ -378,13 +398,15 @@ async fn fetch_remote_gallery_templates(
|
|||||||
if limit == 0 {
|
if limit == 0 {
|
||||||
return Ok(Vec::new());
|
return Ok(Vec::new());
|
||||||
}
|
}
|
||||||
let items = crate::template_http::client(config, TEMPLATE_GALLERY_TIMEOUT_SECS)
|
let client = crate::template_http::client(config, TEMPLATE_GALLERY_TIMEOUT_SECS);
|
||||||
.get(TEMPLATE_GALLERY_URL)
|
let data_url = resolve_gallery_data_url(&client).await?;
|
||||||
|
let items = client
|
||||||
|
.get(&data_url)
|
||||||
.send()
|
.send()
|
||||||
.await
|
.await
|
||||||
.map_err(|err| format!("failed to fetch templates: {err}"))?
|
.map_err(|err| format!("failed to fetch templates from {data_url}: {err}"))?
|
||||||
.error_for_status()
|
.error_for_status()
|
||||||
.map_err(|err| format!("template gallery returned {err}"))?
|
.map_err(|err| format!("template gallery data returned {err}"))?
|
||||||
.json::<Vec<GalleryItem>>()
|
.json::<Vec<GalleryItem>>()
|
||||||
.await
|
.await
|
||||||
.map_err(|err| format!("failed to parse templates: {err}"))?;
|
.map_err(|err| format!("failed to parse templates: {err}"))?;
|
||||||
@@ -427,6 +449,45 @@ async fn fetch_remote_gallery_templates(
|
|||||||
.collect())
|
.collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn resolve_gallery_data_url(client: &Client) -> Result<String, String> {
|
||||||
|
let html = client
|
||||||
|
.get(TEMPLATE_GALLERY_PAGE_URL)
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
.map_err(|err| format!("failed to fetch template gallery page: {err}"))?
|
||||||
|
.error_for_status()
|
||||||
|
.map_err(|err| format!("template gallery page returned {err}"))?
|
||||||
|
.text()
|
||||||
|
.await
|
||||||
|
.map_err(|err| format!("failed to read template gallery page: {err}"))?;
|
||||||
|
|
||||||
|
let data_url = extract_gallery_data_url(&html)
|
||||||
|
.ok_or_else(|| "template gallery page did not expose DATA_URL".to_string())?;
|
||||||
|
absolute_gallery_url(&data_url)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn extract_gallery_data_url(html: &str) -> Option<String> {
|
||||||
|
let regex = regex::Regex::new(r#"(?m)\bDATA_URL\s*=\s*["']([^"']+)["']"#).ok()?;
|
||||||
|
regex
|
||||||
|
.captures(html)
|
||||||
|
.and_then(|captures| captures.get(1))
|
||||||
|
.map(|match_| match_.as_str().trim().to_string())
|
||||||
|
.filter(|value| !value.is_empty())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn absolute_gallery_url(value: &str) -> Result<String, String> {
|
||||||
|
if value.starts_with("http://") || value.starts_with("https://") {
|
||||||
|
return Ok(value.to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
let base = Url::parse(TEMPLATE_GALLERY_PAGE_URL)
|
||||||
|
.map_err(|err| format!("invalid template gallery page URL: {err}"))?;
|
||||||
|
base.join(value)
|
||||||
|
.map(|url| url.to_string())
|
||||||
|
.or_else(|_| Url::parse(TEMPLATE_GALLERY_FALLBACK_DATA_URL).map(|url| url.to_string()))
|
||||||
|
.map_err(|err| format!("invalid template gallery data URL: {err}"))
|
||||||
|
}
|
||||||
|
|
||||||
fn builtin_picture_templates(limit: usize) -> Vec<Value> {
|
fn builtin_picture_templates(limit: usize) -> Vec<Value> {
|
||||||
[
|
[
|
||||||
(
|
(
|
||||||
|
|||||||
Reference in New Issue
Block a user