Sets the storage path for document files, validating that the path is usable. This method configures where document files (like PDFs) will be stored when downloaded through the system. It performs extensive validation to ensure the path is usable and accessible: - Verifies the path exists or can be created - Confirms the filesystem is writable - Validates sufficient permissions exist - Ensures t
(&self, path: impl AsRef<Path>)
| 236 | /// # } |
| 237 | /// ``` |
| 238 | pub async fn set_storage_path(&self, path: impl AsRef<Path>) -> Result<()> { |
| 239 | let original_path_result = self.get_storage_path().await; |
| 240 | let path = path.as_ref(); |
| 241 | |
| 242 | // Convert relative paths to absolute using current working directory |
| 243 | let absolute_path = |
| 244 | if !path.is_absolute() { std::env::current_dir()?.join(path) } else { path.to_path_buf() }; |
| 245 | |
| 246 | // Create a test file to verify write permissions |
| 247 | let test_file = absolute_path.join(".learner_write_test"); |
| 248 | |
| 249 | // First try to create the directory structure |
| 250 | match std::fs::create_dir_all(&absolute_path) { |
| 251 | Ok(_) => { |
| 252 | // Rest of the code remains the same, but use absolute_path instead of path |
| 253 | match std::fs::write(&test_file, b"test") { |
| 254 | Ok(_) => { |
| 255 | // Clean up test file |
| 256 | let _ = std::fs::remove_file(&test_file); |
| 257 | }, |
| 258 | Err(e) => { |
| 259 | return Err(match e.kind() { |
| 260 | std::io::ErrorKind::PermissionDenied => LearnerError::Path(std::io::Error::new( |
| 261 | std::io::ErrorKind::PermissionDenied, |
| 262 | "Insufficient permissions to write to storage directory", |
| 263 | )), |
| 264 | std::io::ErrorKind::ReadOnlyFilesystem => LearnerError::Path(std::io::Error::new( |
| 265 | std::io::ErrorKind::ReadOnlyFilesystem, |
| 266 | "Storage location is on a read-only filesystem", |
| 267 | )), |
| 268 | _ => LearnerError::Path(e), |
| 269 | }); |
| 270 | }, |
| 271 | } |
| 272 | }, |
| 273 | Err(e) => { |
| 274 | return Err(LearnerError::Path(std::io::Error::new( |
| 275 | e.kind(), |
| 276 | format!("Failed to create storage directory: {}", e), |
| 277 | ))); |
| 278 | }, |
| 279 | } |
| 280 | |
| 281 | // If we get here, the path is valid and writable |
| 282 | let path_str = absolute_path.to_string_lossy().to_string(); |
| 283 | |
| 284 | self |
| 285 | .conn |
| 286 | .call(move |conn| { |
| 287 | Ok( |
| 288 | conn |
| 289 | .execute("INSERT OR REPLACE INTO config (key, value) VALUES ('storage_path', ?1)", [ |
| 290 | path_str, |
| 291 | ])?, |
| 292 | ) |
| 293 | }) |
| 294 | .await?; |
| 295 |