/* This file is part of jellything (https://codeberg.org/metamuffin/jellything) which is licensed under the GNU Affero General Public License (version 3); see /COPYING. Copyright (C) 2026 metamuffin */ use crate::{request_info::RequestInfo, responders::UiPage, routes::error::MyResult}; use jellycommon::routes::u_admin_import; use jellyimport::{ ImportConfig, import_wrap, is_importing, reporting::{IMPORT_ERRORS, IMPORT_PROGRESS}, }; use jellyui::components::admin::AdminImport; use rocket::{get, post, response::Redirect}; use rocket_ws::{Message, Stream, WebSocket}; use std::time::Duration; use tokio::{spawn, time::sleep}; #[get("/admin/import", rank = 2)] pub async fn r_admin_import(ri: RequestInfo<'_>) -> MyResult { ri.require_admin()?; let last_import_err = IMPORT_ERRORS.read().await.clone(); let last_import_err = last_import_err .iter() .map(|e| e.as_str()) .collect::>(); Ok(ri.respond_ui(&AdminImport { busy: is_importing(), errors: &last_import_err, ri: &ri.render_info(), })) } #[post("/admin/import?")] pub async fn r_admin_import_post(ri: RequestInfo<'_>, incremental: bool) -> MyResult { ri.require_admin()?; spawn(async move { let _ = import_wrap( ImportConfig { config: ri.state.config.import.clone(), cache: ri.state.cache.clone(), db: ri.state.database.clone(), }, incremental, ) .await; }); Ok(Redirect::to(u_admin_import())) } #[get("/admin/import", rank = 1)] pub fn r_admin_import_stream(ri: RequestInfo<'_>, ws: WebSocket) -> MyResult { ri.require_admin()?; Ok({ Stream! { ws => loop { let Some(p) = IMPORT_PROGRESS.read().await.clone() else { break; }; yield Message::Text(serde_json::to_string(&p).unwrap()); sleep(Duration::from_secs_f32(0.05)).await; } yield Message::Text("done".to_string()); let _ = ws; } }) }