Feeds + polling work
This commit is contained in:
parent
b4028fa08f
commit
c756e206e4
@ -31,7 +31,7 @@ impl Feed {
|
|||||||
url,
|
url,
|
||||||
user_id,
|
user_id,
|
||||||
added_time: now,
|
added_time: now,
|
||||||
last_checked_time: now,
|
last_checked_time: chrono::DateTime::UNIX_EPOCH,
|
||||||
categorization: Vec::new(),
|
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 feed_rs::model::Text;
|
||||||
use rocket::http::Status;
|
use rocket::http::Status;
|
||||||
use rocket::serde::uuid::Uuid;
|
use rocket::serde::uuid::Uuid;
|
||||||
use rocket::serde::{json::Json, Serialize};
|
use rocket::serde::{self, json::Json, Serialize};
|
||||||
use rocket_db_pools::Connection;
|
use rocket_db_pools::Connection;
|
||||||
|
use sqlx::Acquire;
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
#[serde(crate = "rocket::serde")]
|
#[serde(crate = "rocket::serde")]
|
||||||
@ -57,7 +58,7 @@ pub async fn poll_feed(
|
|||||||
.unwrap_or(format!("<no {name}>"))
|
.unwrap_or(format!("<no {name}>"))
|
||||||
}
|
}
|
||||||
|
|
||||||
let entries = feed_data
|
let entries: Vec<Entry> = feed_data
|
||||||
.entries
|
.entries
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|feed_entry| Entry {
|
.map(|feed_entry| Entry {
|
||||||
@ -71,5 +72,61 @@ pub async fn poll_feed(
|
|||||||
})
|
})
|
||||||
.collect();
|
.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 }))
|
Ok(Json(FeedPollResponse { count, entries }))
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user