mirror of
https://gitlab.com/Anson-Projects/projects.git
synced 2025-09-14 09:35:04 +00:00
Add force update functionality for Ghost posts
- Add manual CI trigger 'force-update-ghost' for updating all posts - Support FORCE_UPDATE environment variable in Rust code - Implement post update logic via Ghost API PUT requests - Add get_existing_post_id() function to find existing posts - Update README with usage instructions - Enhanced validation script to test new functionality Usage: - Normal: Only syncs new posts (default behavior) - Force: FORCE_UPDATE=true updates ALL posts including existing ones
This commit is contained in:
@@ -202,6 +202,42 @@ async fn check_if_post_exists(entry: &Entry) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
struct GhostPostsResponse {
|
||||
posts: Vec<GhostPost>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
struct GhostPost {
|
||||
id: String,
|
||||
slug: String,
|
||||
}
|
||||
|
||||
async fn get_existing_post_id(slug: &str, token: &str) -> Option<String> {
|
||||
let client = Client::new();
|
||||
let api_url = format!("https://notes.ansonbiggs.com/ghost/api/v3/admin/posts/slug/{}/", slug);
|
||||
|
||||
match client
|
||||
.get(&api_url)
|
||||
.header("Authorization", format!("Ghost {}", token))
|
||||
.send()
|
||||
.await
|
||||
{
|
||||
Ok(response) => {
|
||||
if response.status().is_success() {
|
||||
if let Ok(ghost_response) = response.json::<GhostPostsResponse>().await {
|
||||
ghost_response.posts.first().map(|post| post.id.clone())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
Err(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
async fn fetch_feed(url: &str) -> Vec<Entry> {
|
||||
let content = reqwest::get(url).await.unwrap().text().await.unwrap();
|
||||
|
||||
@@ -269,6 +305,16 @@ async fn main() {
|
||||
let ghost_api_url = "https://notes.ansonbiggs.com/ghost/api/v3/admin/posts/?source=html";
|
||||
let ghost_admin_api_key = env::var("admin_api_key").unwrap();
|
||||
|
||||
// Check if force update is enabled
|
||||
let force_update = env::var("FORCE_UPDATE").unwrap_or_default() == "true";
|
||||
|
||||
if force_update {
|
||||
println!("🔄 FORCE UPDATE MODE ENABLED");
|
||||
println!(" This will update ALL posts, including existing ones.");
|
||||
} else {
|
||||
println!("📝 NORMAL MODE - Only publishing new posts");
|
||||
}
|
||||
|
||||
let feed = "https://projects.ansonbiggs.com/index.xml";
|
||||
|
||||
// Split the key into ID and SECRET
|
||||
@@ -302,17 +348,25 @@ async fn main() {
|
||||
// Prepare the post data
|
||||
let entries = fetch_feed(feed).await;
|
||||
|
||||
let post_exists_futures = entries.into_iter().map(|entry| {
|
||||
let entry_clone = entry.clone();
|
||||
async move { (entry_clone, check_if_post_exists(&entry).await) }
|
||||
});
|
||||
let filtered_entries: Vec<Entry> = if force_update {
|
||||
println!("🔄 Force update enabled - processing all {} posts", entries.len());
|
||||
entries
|
||||
} else {
|
||||
let post_exists_futures = entries.into_iter().map(|entry| {
|
||||
let entry_clone = entry.clone();
|
||||
async move { (entry_clone, check_if_post_exists(&entry).await) }
|
||||
});
|
||||
|
||||
let post_exists_results = join_all(post_exists_futures).await;
|
||||
let post_exists_results = join_all(post_exists_futures).await;
|
||||
|
||||
let filtered_entries: Vec<Entry> = post_exists_results
|
||||
.into_iter()
|
||||
.filter_map(|(entry, exists)| if !exists { Some(entry) } else { None })
|
||||
.collect();
|
||||
let new_entries: Vec<Entry> = post_exists_results
|
||||
.into_iter()
|
||||
.filter_map(|(entry, exists)| if !exists { Some(entry) } else { None })
|
||||
.collect();
|
||||
|
||||
println!("📝 Found {} new posts to publish", new_entries.len());
|
||||
new_entries
|
||||
};
|
||||
|
||||
if filtered_entries.is_empty() {
|
||||
println!("Nothing to post.");
|
||||
@@ -328,21 +382,46 @@ async fn main() {
|
||||
posts: vec![post.clone()],
|
||||
};
|
||||
|
||||
let response = client
|
||||
.post(ghost_api_url)
|
||||
.header("Authorization", format!("Ghost {}", token))
|
||||
.json(&post_payload)
|
||||
.send()
|
||||
.await
|
||||
.expect("Request failed");
|
||||
// Check if this is an update (for force_update mode)
|
||||
let (method, url) = if force_update {
|
||||
if let Some(existing_id) = get_existing_post_id(&post.slug, &token).await {
|
||||
println!("🔄 Updating existing post: {}", post.title);
|
||||
("PUT", format!("https://notes.ansonbiggs.com/ghost/api/v3/admin/posts/{}/", existing_id))
|
||||
} else {
|
||||
println!("📝 Creating new post: {}", post.title);
|
||||
("POST", ghost_api_url.to_string())
|
||||
}
|
||||
} else {
|
||||
println!("📝 Creating new post: {}", post.title);
|
||||
("POST", ghost_api_url.to_string())
|
||||
};
|
||||
|
||||
let response = match method {
|
||||
"PUT" => client
|
||||
.put(&url)
|
||||
.header("Authorization", format!("Ghost {}", token))
|
||||
.json(&post_payload)
|
||||
.send()
|
||||
.await
|
||||
.expect("Request failed"),
|
||||
_ => client
|
||||
.post(&url)
|
||||
.header("Authorization", format!("Ghost {}", token))
|
||||
.json(&post_payload)
|
||||
.send()
|
||||
.await
|
||||
.expect("Request failed"),
|
||||
};
|
||||
|
||||
// Check the response
|
||||
if response.status().is_success() {
|
||||
println!("Post {} published successfully.", post.title);
|
||||
let action = if method == "PUT" { "updated" } else { "published" };
|
||||
println!("✅ Post '{}' {} successfully.", post.title, action);
|
||||
} else {
|
||||
let action = if method == "PUT" { "update" } else { "publish" };
|
||||
println!(
|
||||
"Failed to publish post {}.\n\tResp: {:?}",
|
||||
&post.title, response
|
||||
"❌ Failed to {} post '{}'.\n\tStatus: {}\n\tResponse: {:?}",
|
||||
action, &post.title, response.status(), response.text().await.unwrap_or_default()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user