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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
use std::path::Path;
use crate::*;
use std::fs;
use smashnet::curl::Curler;
use std::io::Read;
use crate::response::{DirTree, PathEntry, PathList};
fn readDirAll(dir: String, tree: &mut DirTree) {
let paths = fs::read_dir(dir).unwrap();
for pathmaybe in paths {
let path = pathmaybe.unwrap();
let fullpath = path.path();
let file_name = format!("{}", path.file_name().into_string().unwrap());
if path.metadata().unwrap().is_file() {
tree.files.push(file_name);
} else {
let mut subtree = DirTree{name: file_name, files: Vec::new(), dirs: Vec::new()};
readDirAll(fullpath.into_os_string().into_string().unwrap(), &mut subtree);
tree.dirs.push(subtree);
}
}
}
pub fn pong() -> Result<String, String> {
Ok("pong from switch!".to_string())
}
pub fn read_file(context: &mut MessageContext) -> Result<String, String> {
let args = context.arguments.as_ref().unwrap();
let path = args[0].clone();
let exists = Path::new(&path).exists();
if !exists {
return Err("requested file does not exist!".to_string());
} else {
return match fs::read_to_string(path) {
Ok(data) => Ok(data),
Err(e) => Err(format!("While reading file, {}", e))
}
}
}
pub fn download_file(context: &mut MessageContext) -> Result<String, String> {
let args = context.arguments.as_ref().unwrap();
let url = args[0].clone();
let location = args[1].clone();
let progress = |total: f64, current: f64| {
context.send_progress(Progress::new(
"Downloading".to_string(),
"downloading a file".to_string(),
current/total));
};
let result = Curler::new()
.progress_callback(&progress)
.download(url, location);
return match result {
Ok(()) => Ok("File downloaded successfully!".to_string()),
Err(e) => Err(format!("Error during download, error name: {:?}", e))
}
}
pub fn delete_file(context: &mut MessageContext) -> Result<String, String> {
let args = context.arguments.as_ref().unwrap();
let path = args[0].clone();
let exists = Path::new(&path).exists();
if !exists {
return Err("requested file already does not exist.".to_string());
} else {
return match fs::remove_file(path) {
Ok(_) => Ok("The file was removed successfully".to_string()),
Err(e) => Err(format!("{}", e))
}
}
}
pub fn write_file(context: &mut MessageContext) -> Result<String, String> {
let args = context.arguments.as_ref().unwrap();
let path = args[0].clone();
let exists = Path::new(&path).exists();
if exists {
match fs::remove_file(path.clone()) {
Ok(_) => println!("Deleted existing file successfully."),
Err(e) => return Err(format!("Could not delete existing file! Reason: {:?}", e))
}
}
return match fs::write(path, args[1].clone()) {
Ok(_) => Ok("The file was written successfully".to_string()),
Err(e) => Err(format!("Could not write file. Reason: {:?}", e))
}
}
pub fn get_md5(context: &mut MessageContext) -> Result<String, String> {
let args = context.arguments.as_ref().unwrap();
let path = args[0].clone();
let exists = Path::new(&path).exists();
if !exists {
return Err("requested file does not exist!".to_string());
} else {
let data = match fs::read(path) {
Ok(data) => data,
Err(e) => {
return Err(format!("while reading file, {:?}", e));
}
};
let digest = md5::compute(data);
return Ok(format!("{:x}", digest));
}
}
pub fn unzip(context: &mut MessageContext) -> Result<String, String> {
let args = context.arguments.as_ref().unwrap();
let filepath = args[0].clone();
let destination = args[1].clone();
if !Path::new(&filepath).exists() {
return Err(format!("file {} does not exist!", filepath));
}
if !Path::new(&filepath).is_file() {
return Err(format!("path {} is not a file!", filepath));
}
if !Path::new(&destination).exists() {
return Err(format!("path {} does not exist!", destination));
}
if !Path::new(&destination).is_dir() {
return Err(format!("path {} is not a directory!", destination));
}
let mut zip = match unzipper::get_zip_archive(&filepath) {
Ok(zip) => zip,
Err(_) => return Err("Could not parse zip file!".to_string())
};
let count = zip.len();
for file_no in 0..count {
let mut file = zip.by_index(file_no).unwrap();
if !file.is_file() {
continue;
}
context.send_progress(Progress::new(
"Extracting".to_string(),
format!("{}", file.name()),
(file_no as f64)/(count as f64)));
let path = Path::new(&destination).join(file.name());
if let Some(parent) = path.parent() {
std::fs::create_dir_all(parent);
}
let mut file_data = vec![];
file.read_to_end(&mut file_data).unwrap();
std::fs::write(path, file_data).unwrap();
}
Ok("unzip succeeded".to_string())
}
pub fn mkdir(context: &mut MessageContext) -> Result<String, String> {
let dir = &context.arguments.as_ref().unwrap()[0];
return match std::fs::create_dir_all(dir) {
Ok(ok) => Ok(format!("{:?}", ok)),
Err(err) => Ok(format!("{:?}", err)),
};
}
pub fn list_all_files(context: &mut MessageContext) -> Result<String, String> {
let args = context.arguments.as_ref().unwrap();
let path = args[0].clone();
if !Path::new(&path).exists() {
return Err(format!("path {} does not exist!", path));
}
if !Path::new(&path).is_dir() {
return Err(format!("path {} is not a directory!", path));
}
let mut subtree = DirTree{name: path.clone(), files: Vec::new(), dirs: Vec::new()};
readDirAll(path, &mut subtree);
let json = match serde_json::to_string(&subtree) {
Ok(val) => val,
Err(e) => {
return Err(format!("Could not serialize to json DirTree. Error: {}", e));
}
};
Ok(json)
}
pub fn file_exists(context: &mut MessageContext) -> Result<String, String> {
let args = context.arguments.as_ref().unwrap();
let path = args[0].clone();
let exists = Path::new(&path).exists() && Path::new(&path).is_file();
Ok(exists.to_string())
}
pub fn dir_exists(context: &mut MessageContext) -> Result<String, String> {
let args = context.arguments.as_ref().unwrap();
let path = args[0].clone();
let exists = Path::new(&path).exists() && Path::new(&path).is_dir();
Ok(exists.to_string())
}
pub fn list_dir(context: &mut MessageContext) -> Result<String, String> {
let args = context.arguments.as_ref().unwrap();
let path = args[0].clone();
if !Path::new(&path).exists() {
return Err(format!("path {} does not exist!", path));
}
if !Path::new(&path).is_dir() {
return Err(format!("path {} is not a directory!", path));
}
let paths = fs::read_dir(path).unwrap();
let mut vec = Vec::new();
for entry in paths {
let fullpath = entry.unwrap().path().display().to_string();
let md = fs::metadata(fullpath.clone()).unwrap();
let kind = match md.is_file() {
true => 0,
false => 1
};
let path_entry = PathEntry{path: fullpath, kind: kind};
vec.push(path_entry);
}
let path_list = PathList{list: vec};
let json = match serde_json::to_string(&path_list) {
Ok(val) => val,
Err(e) => {
return Err(format!("Could not serialize to json PathList. Error: {}", e));
}
};
Ok(json)
}
pub fn get_request(context: &mut MessageContext) -> Result<String, String> {
let args = context.arguments.as_ref().unwrap();
let url = args[0].clone();
let progress = |total: f64, current: f64| {
context.send_progress(Progress::new(
"Performing GET".to_string(),
"doing GET request".to_string(),
current/total));
};
let result = Curler::new()
.progress_callback(&progress)
.get(url);
return match result {
Ok(body) => Ok(body),
Err(e) => Err(format!("Error during get: {}", e))
}
}
pub(crate) fn register_defaults(engine: &mut RequestEngine) {
engine.register("ping", Some(0), |_|{pong()});
engine.register("read_file", Some(1), |context| {
read_file(context)
});
engine.register("download_file", Some(2), |context| {
download_file(context)
});
engine.register("delete_file", Some(1), |context| {
delete_file(context)
});
engine.register("write_file", Some(2), |context| {
write_file(context)
});
engine.register("get_md5", Some(1), |context| {
get_md5(context)
});
engine.register("unzip", Some(2), |context| {
unzip(context)
});
engine.register("file_exists", Some(1), |context| {
file_exists(context)
});
engine.register("dir_exists", Some(1), |context| {
dir_exists(context)
});
engine.register("list_all_files", Some(1), |context| {
list_all_files(context)
});
engine.register("list_dir", Some(1), |context| {
list_dir(context)
});
engine.register("get_request", Some(1), |context| {
get_request(context)
});
engine.register("exit_session", None, |context| {
context.shutdown();
Ok("session should be closed, so this will never be sent".to_string())
});
engine.register("exit_application", None, |_context| {
unsafe { skyline::nn::oe::ExitApplication();}
});
engine.register("log", None, |context| {
let args = context.arguments.as_ref().unwrap();
println!("Frontend Log: {}", args[0]);
Ok("ok".to_string())
});
engine.register("mkdir", Some(1), |context| {mkdir(context)});
}