2016-06-03 11:51:11 +02:00
|
|
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
|
|
|
// This file is part of Parity.
|
|
|
|
|
|
|
|
// Parity is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU General Public License as published by
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
// (at your option) any later version.
|
|
|
|
|
|
|
|
// Parity is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU General Public License for more details.
|
|
|
|
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
|
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
use std::io;
|
|
|
|
use std::io::Read;
|
|
|
|
use std::fs;
|
|
|
|
use std::path::PathBuf;
|
|
|
|
use page::LocalPageEndpoint;
|
|
|
|
use endpoint::{Endpoints, EndpointInfo};
|
2016-08-18 12:19:09 +02:00
|
|
|
use apps::manifest::{MANIFEST_FILENAME, deserialize_manifest};
|
2016-06-03 11:51:11 +02:00
|
|
|
|
|
|
|
struct LocalDapp {
|
|
|
|
id: String,
|
|
|
|
path: PathBuf,
|
|
|
|
info: EndpointInfo,
|
|
|
|
}
|
|
|
|
|
|
|
|
fn local_dapps(dapps_path: String) -> Vec<LocalDapp> {
|
|
|
|
let files = fs::read_dir(dapps_path.as_str());
|
|
|
|
if let Err(e) = files {
|
|
|
|
warn!(target: "dapps", "Unable to load local dapps from: {}. Reason: {:?}", dapps_path, e);
|
|
|
|
return vec![];
|
|
|
|
}
|
|
|
|
|
|
|
|
let files = files.expect("Check is done earlier");
|
|
|
|
files.map(|dir| {
|
|
|
|
let entry = try!(dir);
|
|
|
|
let file_type = try!(entry.file_type());
|
|
|
|
|
|
|
|
// skip files
|
|
|
|
if file_type.is_file() {
|
|
|
|
return Err(io::Error::new(io::ErrorKind::NotFound, "Not a file"));
|
|
|
|
}
|
|
|
|
|
|
|
|
// take directory name and path
|
|
|
|
entry.file_name().into_string()
|
|
|
|
.map(|name| (name, entry.path()))
|
|
|
|
.map_err(|e| {
|
|
|
|
info!(target: "dapps", "Unable to load dapp: {:?}. Reason: {:?}", entry.path(), e);
|
|
|
|
io::Error::new(io::ErrorKind::NotFound, "Invalid name")
|
|
|
|
})
|
|
|
|
})
|
|
|
|
.filter_map(|m| {
|
|
|
|
if let Err(ref e) = m {
|
|
|
|
debug!(target: "dapps", "Ignoring local dapp: {:?}", e);
|
|
|
|
}
|
|
|
|
m.ok()
|
|
|
|
})
|
|
|
|
.map(|(name, path)| {
|
|
|
|
// try to get manifest file
|
|
|
|
let info = read_manifest(&name, path.clone());
|
|
|
|
LocalDapp {
|
|
|
|
id: name,
|
|
|
|
path: path,
|
|
|
|
info: info,
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.collect()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn read_manifest(name: &str, mut path: PathBuf) -> EndpointInfo {
|
2016-08-18 12:19:09 +02:00
|
|
|
path.push(MANIFEST_FILENAME);
|
2016-06-03 11:51:11 +02:00
|
|
|
|
|
|
|
fs::File::open(path.clone())
|
|
|
|
.map_err(|e| format!("{:?}", e))
|
|
|
|
.and_then(|mut f| {
|
|
|
|
// Reat file
|
|
|
|
let mut s = String::new();
|
|
|
|
try!(f.read_to_string(&mut s).map_err(|e| format!("{:?}", e)));
|
|
|
|
// Try to deserialize manifest
|
2016-08-18 12:19:09 +02:00
|
|
|
deserialize_manifest(s)
|
2016-06-03 11:51:11 +02:00
|
|
|
})
|
2016-08-18 12:19:09 +02:00
|
|
|
.map(Into::into)
|
2016-06-03 11:51:11 +02:00
|
|
|
.unwrap_or_else(|e| {
|
|
|
|
warn!(target: "dapps", "Cannot read manifest file at: {:?}. Error: {:?}", path, e);
|
|
|
|
|
|
|
|
EndpointInfo {
|
|
|
|
name: name.into(),
|
|
|
|
description: name.into(),
|
|
|
|
version: "0.0.0".into(),
|
|
|
|
author: "?".into(),
|
|
|
|
icon_url: "icon.png".into(),
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn local_endpoints(dapps_path: String) -> Endpoints {
|
|
|
|
let mut pages = Endpoints::new();
|
|
|
|
for dapp in local_dapps(dapps_path) {
|
|
|
|
pages.insert(
|
|
|
|
dapp.id,
|
|
|
|
Box::new(LocalPageEndpoint::new(dapp.path, dapp.info))
|
|
|
|
);
|
|
|
|
}
|
|
|
|
pages
|
|
|
|
}
|