~/selfhut

selfhut/src/git/file.rs -rw-r--r-- 3.68 kB
7dbdfabf — arthurmelton I did alot, I should have commited more 2 years ago

            
7dbdfabf arthurmelton
7dbdfabf arthurmelton
00c0a257 Arthur Melton
e22778fe Arthur Melton
7dbdfabf arthurmelton
0016c2cc arthurmelton
7dbdfabf arthurmelton
7dbdfabf arthurmelton
00c0a257 Arthur Melton
7dbdfabf arthurmelton
00c0a257 Arthur Melton
7dbdfabf arthurmelton
00c0a257 Arthur Melton
7dbdfabf arthurmelton
00c0a257 Arthur Melton
7dbdfabf arthurmelton
0016c2cc arthurmelton
7dbdfabf arthurmelton
7dbdfabf arthurmelton
00c0a257 Arthur Melton
7dbdfabf arthurmelton
00c0a257 Arthur Melton
7dbdfabf arthurmelton
00c0a257 Arthur Melton
7dbdfabf arthurmelton
00c0a257 Arthur Melton
19f9b68c arthurmelton
7dbdfabf arthurmelton
7dbdfabf arthurmelton
00c0a257 Arthur Melton
7dbdfabf arthurmelton
0016c2cc arthurmelton
7dbdfabf arthurmelton
00c0a257 Arthur Melton
7dbdfabf arthurmelton





























































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
use serde_derive::{Serialize};
use crate::config::CONFIG;
use std::path::Component;
use humansize::{format_size, DECIMAL};
use git2::ObjectType;
use std::path::PathBuf;

pub fn files(repo: String, branch: String, path: String) -> Option<Vec<File>> {
    if branch.contains(":") {
        return None;
    }
    let mut location = CONFIG.git_location.clone();
    location.push(path.clone());
    if location.components().into_iter().any(|x| x == Component::ParentDir) {
        return None;
    }
    let mut repo_path = CONFIG.git_location.clone();
    repo_path.push(format!("{}.git", repo));
    let repo = git2::Repository::open(repo_path).ok()?;
    let obj = repo.revparse_single(&format!("{}:{}", branch, path)).ok()?;
    let mut returns = Vec::new();
    match obj.kind() {
        Some(ObjectType::Tree) => {
            let tree = obj.as_tree()?;
            for entry in tree.iter() {
                returns.push(File {
                    name: entry.name()?.to_string(),
                    size: match entry.kind() {
                        Some(ObjectType::Blob) => {
                            Some(format_size(entry.to_object(&repo).ok()?.into_blob().ok()?.size(), DECIMAL))
                        },
                        _ => None
                    },
                    file_type: match entry.kind() {
                        Some(ObjectType::Blob) => FileType::blob,
                        _ => FileType::tree
                    },
                    properties: unix_mode::to_string(entry.filemode() as u32),
                    properties_int: entry.filemode()
                })   
            }
        },
        _ => {
            return None;
        }
    }
    Some(returns)
}

pub fn file(repo: String, branch: String, path: String) -> Option<(File, Option<String>, Vec<u8>)> {
    if branch.contains(":") {
        return None;
    }
    let mut location = CONFIG.git_location.clone();
    location.push(path.clone());
    if location.components().into_iter().any(|x| x == Component::ParentDir) {
        return None;
    }
    let mut repo_path = CONFIG.git_location.clone();
    repo_path.push(format!("{}.git", repo));
    let repo = git2::Repository::open(repo_path).ok()?;
    let obj = repo.revparse_single(&format!("{}:{}", branch, path)).ok()?;
    match obj.kind() {
        Some(ObjectType::Blob) => {
            let blob = obj.as_blob()?;
            let mut path_to_folder = PathBuf::from(path);
            path_to_folder.pop();
            let path_to_folder = path_to_folder.into_os_string().to_str()?.to_string();
            let tree = repo.revparse_single(&format!("{}:{}", branch, path_to_folder)).ok()?;
            let tree = tree.as_tree()?;
            let tree_item = tree.get_id(blob.id())?;
            let file = File {
                name: tree_item.name()?.to_string(),
                size: Some(format_size(blob.size(), DECIMAL)),
                file_type: FileType::blob,
                properties: unix_mode::to_string(tree_item.filemode() as u32),
                properties_int: tree_item.filemode()
            };
            let content = match blob.is_binary() {
                false => Some(String::from_utf8_lossy(blob.content()).into_owned()),
                true => None
            };
            return Some((file, content, blob.content().iter().map(|x| *x).collect()));
        },
        _ => {
            return None;
        }
    }
}


#[derive(Serialize)]
pub struct File {
    pub name: String,
    pub size: Option<String>,
    pub file_type: FileType,
    pub properties: String,
    pub properties_int: i32
}

#[derive(Serialize)]
pub enum FileType {
    blob,
    tree
}