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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#[macro_use]
extern crate failure;
use failure::{Error, ResultExt};
use std::path::Path;
use std::process::{Command, Stdio};
use std::str::FromStr;
use std::fs::File;
pub struct UpspinPath {
owner: String,
path: String,
}
impl UpspinPath {
pub fn owner(&self) -> &String {
&self.owner
}
pub fn path(&self) -> &String {
&self.path
}
pub fn file_name(&self) -> &str {
&self.path.split("/").last().unwrap()
}
pub fn full_path(&self) -> String {
format!("{}/{}", &self.owner, &self.path)
}
pub fn is_public(&self) -> bool {
match Command::new("upspin")
.args(&["info", &self.full_path()])
.output()
{
Ok(output) => {
output.status.success()
&& std::str::from_utf8(&output.stdout)
.context("Could not parse output")
.unwrap()
.lines()
.any(|line| line.contains("can read") && line.contains("All"))
}
Err(_) => false,
}
}
pub fn get(&self, output_path: &Path) -> Result<(), Error> {
if !self.is_public() {
return Err(format_err!("Path {} is not public", self.full_path()));
}
let output_file = File::create(output_path)
.context("Could not create output file")
.unwrap();
let output = Command::new("upspin")
.args(&["get", &self.full_path()])
.stdout(Stdio::from(output_file))
.output();
match output {
Ok(output) => if output.status.success() {
Ok(())
} else {
Err(format_err!("Could not download"))
},
Err(e) => Err(format_err!("Could not download: {}", e)),
}
}
}
impl FromStr for UpspinPath {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut splitted_s = s.split("/");
let owner = splitted_s.next().unwrap().to_string();
let path = splitted_s.collect::<Vec<_>>().join("/");
Ok(UpspinPath { owner, path })
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
pub fn asdf() {
let path = "augie@upspin.io/Images/Augie/small.jpg";
let upspin_path: UpspinPath = path.parse().unwrap();
assert_eq!(&"augie@upspin.io".to_string(), upspin_path.owner());
assert_eq!(&"Images/Augie/small.jpg".to_string(), upspin_path.path());
assert_eq!(&"small.jpg".to_string(), upspin_path.file_name());
assert_eq!(path, upspin_path.full_path());
}
}