From f2a2994fe31fba4f10ed18645cc7ed2975026f40 Mon Sep 17 00:00:00 2001 From: Greg Shuflin Date: Sat, 15 Feb 2025 18:53:17 -0800 Subject: [PATCH] opml parsing works?? --- TODO.md | 6 ++++++ src/import.rs | 34 ++++++++++++++++++++++------------ 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/TODO.md b/TODO.md index b9852b1..36bf2ed 100644 --- a/TODO.md +++ b/TODO.md @@ -18,6 +18,12 @@ Current session management is basic and needs improvement: - Consider using Font Awesome's SVG+JS version for better performance - Update CSS and HTML references to use local assets +## UI Improvements +- Fix sidebar scrollbar styling to match the main content area scrollbar + - Apply consistent scrollbar styling across the application + - Ensure scrollbar is visible but unobtrusive + - Match the color scheme and dimensions of the main content area scrollbar + - [ ] Add a timeout to external RSS feed fetching to prevent hanging on slow feeds - Use reqwest's timeout feature - Consider making the timeout configurable diff --git a/src/import.rs b/src/import.rs index 4d767d2..1a8881b 100644 --- a/src/import.rs +++ b/src/import.rs @@ -1,12 +1,16 @@ // Module for handling OPML feed list imports use std::io::Cursor; +use std::io::Read; use quick_xml::de::from_reader; use rocket::data::ToByteUnit; +use rocket::form::Form; +use rocket::fs::TempFile; use rocket::http::Status; use rocket::serde::json::Json; use rocket::serde::{Deserialize, Serialize}; +use rocket::tokio::io::AsyncReadExt; use rocket::{post, Data}; use rocket_db_pools::Connection; use tracing::{error, info}; @@ -67,30 +71,36 @@ impl OpmlOutline { } } +#[derive(FromForm)] +pub struct UploadForm<'f> { + file: TempFile<'f>, +} + /// Import feeds from an OPML file -#[post("/import/opml", data = "")] +#[post("/import/opml", data = "
")] pub async fn import_opml( mut db: Connection, user: AuthenticatedUser, - file: Data<'_>, + mut form: Form>, ) -> Result, Status> { - // Limit file size to 1MB - let file_data = file.open(1.mebibytes()).into_bytes().await.map_err(|e| { + // Read the file contents + let mut file = form.file.open().await.map_err(|e| { + error!("Failed to open OPML file: {}", e); + Status::BadRequest + })?; + + let mut bytes = Vec::new(); + file.read_to_end(&mut bytes).await.map_err(|e| { error!("Failed to read OPML file: {}", e); Status::BadRequest })?; - if !file_data.is_complete() { - error!("OPML file too large"); - return Err(Status::PayloadTooLarge); - } - - let bytes = file_data.value; - let cursor = Cursor::new(bytes); + let cursor = Cursor::new(bytes.clone()); // Parse OPML let opml: Opml = from_reader(cursor).map_err(|e| { - error!("Failed to parse OPML: {}", e); + let preview = String::from_utf8_lossy(&bytes[..bytes.len().min(100)]); + error!("Failed to parse OPML: {}. File starts with: {}", e, preview); Status::UnprocessableEntity })?;