use axum::{ extract::{Form, State}, response::IntoResponse, }; use axum_extra::extract::Cached; use axum_htmx::{HxBoosted, HxRequest}; use axum_template::RenderHtml; use http::StatusCode; use minijinja::context as template_context; use serde::Deserialize; use crate::{ contextual_error, http::{ context::WebContext, errors::{ImportError, WebError}, import_utils::import_event_records, middleware_auth::Auth, middleware_i18n::Language, }, select_template, }; pub(crate) async fn handle_import( State(web_context): State, Language(language): Language, Cached(auth): Cached, HxRequest(hx_request): HxRequest, HxBoosted(hx_boosted): HxBoosted, ) -> Result { let current_handle = auth.require("/import")?; let default_context = template_context! { current_handle, language => language.to_string(), canonical_url => format!("https://{}/import", web_context.config.external_base), }; let render_template = select_template!("import", hx_boosted, hx_request, language); Ok(RenderHtml( &render_template, web_context.engine.clone(), default_context, ) .into_response()) } #[derive(Debug, Deserialize)] pub(crate) struct ImportForm { // Empty form just for CSRF protection } pub(crate) async fn handle_import_submit( State(web_context): State, Language(language): Language, Cached(auth): Cached, HxRequest(hx_request): HxRequest, Form(_import_form): Form, ) -> Result { let current_handle = auth.require_flat()?; if !hx_request { return Ok(StatusCode::BAD_REQUEST.into_response()); } let render_template = select_template!("import", false, true, language); let error_template = select_template!(false, hx_request, language); // Import legacy event records let result_map = match import_event_records( &web_context.http_client, &web_context.pool, ¤t_handle.did, ¤t_handle.pds, ) .await { Ok(map) => map, Err(err) => { return contextual_error!( web_context, language, error_template, template_context! {}, ImportError::FailedToListSmokesignalEvents(err.to_string()) ); } }; // Transform the OrderMap into template-friendly data let mut successful_count = 0; let mut failed_records = Vec::new(); for (uri, error_status) in result_map.iter() { match error_status { None => successful_count += 1, Some(error) => { failed_records.push(template_context! { uri => uri, error => error, }); } } } let total_count = result_map.len(); Ok(RenderHtml( &render_template, web_context.engine.clone(), template_context! { current_handle, language => language.to_string(), canonical_url => format!("https://{}/import", web_context.config.external_base), import_complete => true, total_count, successful_count, failed_records, }, ) .into_response()) }