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
|
- Consider using Font Awesome's SVG+JS version for better performance
|
||||||
- Update CSS and HTML references to use local assets
|
- 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
|
- [ ] Add a timeout to external RSS feed fetching to prevent hanging on slow feeds
|
||||||
- Use reqwest's timeout feature
|
- Use reqwest's timeout feature
|
||||||
- Consider making the timeout configurable
|
- Consider making the timeout configurable
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
// Module for handling OPML feed list imports
|
// Module for handling OPML feed list imports
|
||||||
|
|
||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
|
use std::io::Read;
|
||||||
|
|
||||||
use quick_xml::de::from_reader;
|
use quick_xml::de::from_reader;
|
||||||
use rocket::data::ToByteUnit;
|
use rocket::data::ToByteUnit;
|
||||||
|
use rocket::form::Form;
|
||||||
|
use rocket::fs::TempFile;
|
||||||
use rocket::http::Status;
|
use rocket::http::Status;
|
||||||
use rocket::serde::json::Json;
|
use rocket::serde::json::Json;
|
||||||
use rocket::serde::{Deserialize, Serialize};
|
use rocket::serde::{Deserialize, Serialize};
|
||||||
|
use rocket::tokio::io::AsyncReadExt;
|
||||||
use rocket::{post, Data};
|
use rocket::{post, Data};
|
||||||
use rocket_db_pools::Connection;
|
use rocket_db_pools::Connection;
|
||||||
use tracing::{error, info};
|
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
|
/// Import feeds from an OPML file
|
||||||
#[post("/import/opml", data = "<file>")]
|
#[post("/import/opml", data = "<form>")]
|
||||||
pub async fn import_opml(
|
pub async fn import_opml(
|
||||||
mut db: Connection<Db>,
|
mut db: Connection<Db>,
|
||||||
user: AuthenticatedUser,
|
user: AuthenticatedUser,
|
||||||
file: Data<'_>,
|
mut form: Form<UploadForm<'_>>,
|
||||||
) -> Result<Json<ImportResponse>, Status> {
|
) -> Result<Json<ImportResponse>, Status> {
|
||||||
// Limit file size to 1MB
|
// Read the file contents
|
||||||
let file_data = file.open(1.mebibytes()).into_bytes().await.map_err(|e| {
|
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);
|
error!("Failed to read OPML file: {}", e);
|
||||||
Status::BadRequest
|
Status::BadRequest
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
if !file_data.is_complete() {
|
let cursor = Cursor::new(bytes.clone());
|
||||||
error!("OPML file too large");
|
|
||||||
return Err(Status::PayloadTooLarge);
|
|
||||||
}
|
|
||||||
|
|
||||||
let bytes = file_data.value;
|
|
||||||
let cursor = Cursor::new(bytes);
|
|
||||||
|
|
||||||
// Parse OPML
|
// Parse OPML
|
||||||
let opml: Opml = from_reader(cursor).map_err(|e| {
|
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
|
Status::UnprocessableEntity
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user