opml parsing works??
This commit is contained in:
parent
16ae4fc201
commit
f2a2994fe3
6
TODO.md
6
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
|
||||
|
@ -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 = "<file>")]
|
||||
#[post("/import/opml", data = "<form>")]
|
||||
pub async fn import_opml(
|
||||
mut db: Connection<Db>,
|
||||
user: AuthenticatedUser,
|
||||
file: Data<'_>,
|
||||
mut form: Form<UploadForm<'_>>,
|
||||
) -> Result<Json<ImportResponse>, 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
|
||||
})?;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user