Feeds + polling work
This commit is contained in:
parent
b4028fa08f
commit
c756e206e4
@ -31,7 +31,7 @@ impl Feed {
|
||||
url,
|
||||
user_id,
|
||||
added_time: now,
|
||||
last_checked_time: now,
|
||||
last_checked_time: chrono::DateTime::UNIX_EPOCH,
|
||||
categorization: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
61
src/poll.rs
61
src/poll.rs
@ -4,8 +4,9 @@ use chrono::{DateTime, Utc};
|
||||
use feed_rs::model::Text;
|
||||
use rocket::http::Status;
|
||||
use rocket::serde::uuid::Uuid;
|
||||
use rocket::serde::{json::Json, Serialize};
|
||||
use rocket::serde::{self, json::Json, Serialize};
|
||||
use rocket_db_pools::Connection;
|
||||
use sqlx::Acquire;
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[serde(crate = "rocket::serde")]
|
||||
@ -57,7 +58,7 @@ pub async fn poll_feed(
|
||||
.unwrap_or(format!("<no {name}>"))
|
||||
}
|
||||
|
||||
let entries = feed_data
|
||||
let entries: Vec<Entry> = feed_data
|
||||
.entries
|
||||
.into_iter()
|
||||
.map(|feed_entry| Entry {
|
||||
@ -71,5 +72,61 @@ pub async fn poll_feed(
|
||||
})
|
||||
.collect();
|
||||
|
||||
// Start a transaction for batch update
|
||||
let mut tx = db.begin().await.map_err(|e| {
|
||||
eprintln!("Failed to start transaction: {}", e);
|
||||
Status::InternalServerError
|
||||
})?;
|
||||
|
||||
let now = Utc::now().to_rfc3339();
|
||||
for entry in &entries {
|
||||
let content_json = if let Some(content) = &entry.content {
|
||||
serde::json::to_string(content).ok()
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let result = sqlx::query(
|
||||
r#"
|
||||
INSERT INTO feed_entries (
|
||||
id, feed_id, title, published, updated, summary, content, link, created_at
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
ON CONFLICT (feed_id, id) DO UPDATE SET
|
||||
title = excluded.title,
|
||||
published = excluded.published,
|
||||
updated = excluded.updated,
|
||||
summary = excluded.summary,
|
||||
content = excluded.content,
|
||||
link = excluded.link
|
||||
"#
|
||||
)
|
||||
.bind(&entry.id)
|
||||
.bind(&feed_id)
|
||||
.bind(&entry.title)
|
||||
.bind(entry.published.map(|dt| dt.to_rfc3339()))
|
||||
.bind(entry.updated.map(|dt| dt.to_rfc3339()))
|
||||
.bind(&entry.summary)
|
||||
.bind(content_json)
|
||||
.bind(&entry.link)
|
||||
.bind(&now)
|
||||
.execute(&mut *tx)
|
||||
.await;
|
||||
|
||||
if let Err(e) = result {
|
||||
eprintln!("Failed to save feed entry: {}", e);
|
||||
tx.rollback().await.map_err(|e| {
|
||||
eprintln!("Failed to rollback transaction: {}", e);
|
||||
Status::InternalServerError
|
||||
})?;
|
||||
return Err(Status::InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
// Commit the transaction
|
||||
tx.commit().await.map_err(|e| {
|
||||
eprintln!("Failed to commit transaction: {}", e);
|
||||
Status::InternalServerError
|
||||
})?;
|
||||
|
||||
Ok(Json(FeedPollResponse { count, entries }))
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user