use std::path::Path; use actix_web::web; use actix_web_httpauth::extractors::basic; use actix_web::get; use askama_actix::Template; use serde::Deserialize; use crate::error; use crate::git::GitBrowseEntry; use crate::gitust::Gitust; use crate::gitutils::gitcommit::GitRef; use crate::gitutils::gitdir::GitDir; use crate::gitutils::gitfile::GitFile; use crate::gitutils::gitrepo::GitRepo; use crate::ite::SuperIterator; struct User { name : String, } struct Owner { name : String, } struct Repository { name : String, owner : Owner, } pub enum Entry { Dir(String), File(String), } #[derive(Template)] #[template(path = "git.html")] pub struct GitMainTemplate where for <'a> &'a TS : IntoIterator, for <'a> &'a ROOT : IntoIterator, { repo : Repository, browse : TS, root : ROOT, user_opt : Option, } #[derive(Deserialize)] pub struct GitWebQ { commit: Option, path: Option, branch: Option, } #[get("/git/{owner}/{repo}.git")] pub async fn git_main( web::Path((ownername, reponame)): web::Path<(String, String)>, web::Query(GitWebQ{commit : commitnameopt, path : pathopt, branch : branchopt}) : web::Query, gitust : web::Data, auth : Option, //auth : BasicAuth, ) -> Result, Vec<(String, String)>>, error::Error> { // let authtorization = auth.ok_or(error::Error::Unauthorized("safe repo".to_string()))?; let rootname = match pathopt { None => {"".to_string()} Some(s) => { if s.starts_with("/") { (&s[1..]).to_string() } else { s } } }; let commit = match commitnameopt { None => {match branchopt { None => {GitRef::Head} Some(s) => {GitRef::Branch(s)} }} Some(s) => {GitRef::Commit(s)} }; let owner = Owner { name : ownername}; let repo = Repository {name : reponame, owner}; // let user = User { name : "Hubert".to_string()}; let user = auth.map(|auth| User{name : auth.user_id().to_string()}); // il faut ajouter le commit/branch dans la query let path = rootname.split("/").map_accum("/git/".to_string() + &repo.owner.name + "/" + &repo.name, |str_ref, b| { let href = b + "/" + str_ref; ((str_ref.to_string(), href.clone()), href) }).collect(); let gitrepo = GitRepo::new(format!("{}/{}/{}.git", &gitust.repo_root_path, &repo.owner.name, &repo.name).as_str())?; let root = gitrepo.get_tree(&commit, Path::new(rootname.as_str()))?; let browse = gitrepo.browse(&root).await?; let mut entries : Vec = Vec::new(); for entry in browse { match entry { GitBrowseEntry::EGitFile(GitFile(fullname)) => { let osstr = fullname.file_name().ok_or(git2::Error::from_str("file name not defined"))?; entries.push(Entry::File(format!("{}",osstr.to_string_lossy()))); } GitBrowseEntry::EGitDir(GitDir{fullname, .. }) => { let osstr = fullname.file_name().ok_or(git2::Error::from_str("file name not defined"))?; entries.push(Entry::Dir(format!("{}",osstr.to_string_lossy()))); } } } Ok(GitMainTemplate { repo, browse : entries, root : path, user_opt : user}) }