[WIP] A (somewhat barebones) atproto app for creating custom sites without hosting!
at main 1.9 kB view raw
1use ignore::WalkBuilder; 2use jacquard::types::blob::Blob; 3use miette::Diagnostic; 4use mime_guess::mime; 5use std::{collections::HashMap, path::PathBuf}; 6use thiserror::Error; 7 8pub type Sitemap = HashMap<String, SitemapNode>; 9 10#[derive(Debug)] 11pub struct SitemapNode { 12 pub mime_type: String, 13 pub blob: BlobRef, 14} 15 16#[derive(Debug)] 17pub enum BlobRef { 18 Local(PathBuf), 19 Remote(Blob<'static>), 20} 21 22#[derive(Debug, Error, Diagnostic)] 23pub enum SitemapErr { 24 #[error("IO error: {}", .0)] 25 IoErr(#[from] std::io::Error), 26 #[error("Error finding files: {}", .0)] 27 IgnoreErr(#[from] ignore::Error), 28 #[error("Error normalising file paths: {}", .0)] 29 StripPrefixErr(#[from] std::path::StripPrefixError), 30 #[error("Found non UTF-8 path")] 31 NotUTF8Path, 32} 33 34pub fn local_sitemap( 35 dir: PathBuf, 36 include_dotfiles: bool, 37 use_gitignore: bool, 38) -> miette::Result<Sitemap, SitemapErr> { 39 let prefix = dir.canonicalize()?; 40 41 let mut res = HashMap::new(); 42 for file in WalkBuilder::new(dir) 43 .hidden(!include_dotfiles) 44 .git_ignore(use_gitignore) 45 .git_exclude(use_gitignore) 46 .git_global(use_gitignore) 47 .follow_links(true) 48 .build() 49 { 50 let file = file?; 51 52 let metadata = file.metadata()?; 53 54 if !metadata.is_file() { 55 continue; 56 }; 57 58 // find the path of the files relative to the source directory 59 // source dir `./dist`: 60 // ./dist/index.html => index.html 61 // ./dist/assets/cat.jpg => cat.jpg 62 // etc 63 let key = file.path().canonicalize()?; 64 let key = key.strip_prefix(&prefix)?; 65 let key = String::from(key.to_str().ok_or(SitemapErr::NotUTF8Path)?); 66 67 let mime = mime_guess::from_path(&key); 68 let mime = mime.first().unwrap_or(mime::APPLICATION_OCTET_STREAM); 69 let mime = mime.essence_str(); 70 71 res.insert( 72 key, 73 SitemapNode { 74 mime_type: String::from(mime), 75 blob: BlobRef::Local(file.path().to_owned()), 76 }, 77 ); 78 } 79 Ok(res) 80}