diff options
| author | salmonik <salmonik@tuta.io> | 2026-07-12 21:35:25 +0200 |
|---|---|---|
| committer | salmonik <salmonik@tuta.io> | 2026-07-12 21:35:25 +0200 |
| commit | 9ad52d0151086252e6d8a3e60dc5b8cd4bfd5465 (patch) | |
| tree | 2e638c274e0ab9dc4f3812e8ece6c603d854e1fd /src/routes/backups.rs | |
| parent | first stable (diff) | |
| download | minecraft-ui-9ad52d0151086252e6d8a3e60dc5b8cd4bfd5465.tar.gz minecraft-ui-9ad52d0151086252e6d8a3e60dc5b8cd4bfd5465.zip | |
second stable
Diffstat (limited to 'src/routes/backups.rs')
| -rw-r--r-- | src/routes/backups.rs | 58 |
1 files changed, 0 insertions, 58 deletions
diff --git a/src/routes/backups.rs b/src/routes/backups.rs index 09298d2..6b4dd49 100644 --- a/src/routes/backups.rs +++ b/src/routes/backups.rs | |||
| @@ -37,7 +37,6 @@ pub fn router() -> Router<AppState> { | |||
| 37 | .route("/instances/{id}/backups/create", post(create_backup)) | 37 | .route("/instances/{id}/backups/create", post(create_backup)) |
| 38 | .route("/backups/{id}/restore", post(restore_backup)) | 38 | .route("/backups/{id}/restore", post(restore_backup)) |
| 39 | .route("/backups/{id}/download", get(download_backup)) | 39 | .route("/backups/{id}/download", get(download_backup)) |
| 40 | .route("/instances/{id}/world/export", get(export_world)) | ||
| 41 | } | 40 | } |
| 42 | 41 | ||
| 43 | async fn list_backups( | 42 | async fn list_backups( |
| @@ -197,60 +196,3 @@ async fn download_backup( | |||
| 197 | .body(Body::from(content)) | 196 | .body(Body::from(content)) |
| 198 | .unwrap()) | 197 | .unwrap()) |
| 199 | } | 198 | } |
| 200 | |||
| 201 | async fn export_world( | ||
| 202 | State(state): State<AppState>, | ||
| 203 | Path(instance_id): Path<i64>, | ||
| 204 | CurrentUser(_user): CurrentUser, | ||
| 205 | ) -> Result<Response, (StatusCode, &'static str)> { | ||
| 206 | let conn = state.db.conn(); | ||
| 207 | let instance_name: String = conn | ||
| 208 | .query_row( | ||
| 209 | "SELECT name FROM instances WHERE id = ?1", | ||
| 210 | params![instance_id], | ||
| 211 | |row| row.get(0), | ||
| 212 | ) | ||
| 213 | .map_err(|_| (StatusCode::NOT_FOUND, "Instance not found"))?; | ||
| 214 | drop(conn); | ||
| 215 | |||
| 216 | let world_dir = state | ||
| 217 | .config | ||
| 218 | .server_directory | ||
| 219 | .join("instances") | ||
| 220 | .join(&instance_name) | ||
| 221 | .join("data") | ||
| 222 | .join("world"); | ||
| 223 | |||
| 224 | let mut zip_buf = Vec::new(); | ||
| 225 | { | ||
| 226 | let mut zip = zip::ZipWriter::new(std::io::Cursor::new(&mut zip_buf)); | ||
| 227 | let options: FileOptions<'_, ()> = | ||
| 228 | FileOptions::default().compression_method(zip::CompressionMethod::Deflated); | ||
| 229 | |||
| 230 | if let Ok(entries) = std::fs::read_dir(&world_dir) { | ||
| 231 | for entry in entries.flatten() { | ||
| 232 | let path = entry.path(); | ||
| 233 | if path.is_file() { | ||
| 234 | if let Some(name) = path.file_name() { | ||
| 235 | if let Ok(contents) = std::fs::read(&path) { | ||
| 236 | let _ = zip.start_file(&*name.to_string_lossy(), options); | ||
| 237 | let _ = std::io::Write::write_all(&mut zip, &contents); | ||
| 238 | } | ||
| 239 | } | ||
| 240 | } | ||
| 241 | } | ||
| 242 | } | ||
| 243 | let _ = zip.finish(); | ||
| 244 | } | ||
| 245 | |||
| 246 | let filename = format!("{instance_name}_world.zip"); | ||
| 247 | |||
| 248 | Ok(Response::builder() | ||
| 249 | .header(header::CONTENT_TYPE, "application/zip") | ||
| 250 | .header( | ||
| 251 | header::CONTENT_DISPOSITION, | ||
| 252 | format!("attachment; filename=\"{filename}\""), | ||
| 253 | ) | ||
| 254 | .body(Body::from(zip_buf)) | ||
| 255 | .unwrap()) | ||
| 256 | } | ||
