Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add FileManagerThread #11029

Merged
merged 1 commit into from May 11, 2016
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -0,0 +1,137 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
use net_traits::filemanager_thread::{FileManagerThreadMsg, FileManagerResult, FileManagerThreadError};
use std::cell::RefCell;
use std::collections::HashMap;
use std::fs::File;
use std::io::Read;
use std::path::{Path, PathBuf};
use util::thread::spawn_named;
use uuid::Uuid;

pub struct FileManager {
receiver: IpcReceiver<FileManagerThreadMsg>,
idmap: RefCell<HashMap<Uuid, PathBuf>>,
}

impl FileManager {
fn new(recv: IpcReceiver<FileManagerThreadMsg>) -> FileManager {
FileManager {
receiver: recv,
idmap: RefCell::new(HashMap::new()),
}
}

fn new_thread() -> IpcSender<FileManagerThreadMsg> {
let (chan, recv) = ipc::channel().unwrap();

spawn_named("FileManager".to_owned(), move || {
FileManager::new(recv).start();
});

chan
}

/// Start the file manager event loop
pub fn start(&mut self) {
loop {
match self.receiver.recv().unwrap() {
FileManagerThreadMsg::SelectFile(sender) => self.select_file(sender),
FileManagerThreadMsg::SelectFiles(sender) => self.select_files(sender),
FileManagerThreadMsg::ReadFile(sender, id) => self.read_file(sender, id),
FileManagerThreadMsg::DeleteFileID(id) => self.delete_fileid(id),
}
}
}
}

impl FileManager {
fn select_file(&mut self, sender: IpcSender<FileManagerResult<(Uuid, PathBuf, u64)>>) {
// TODO: Pull the dialog UI in and get selected
let selected_path = Path::new("");

match self.create_entry(selected_path) {
Some(triple) => {
let _ = sender.send(Ok(triple));
},
None => {
let _ = sender.send(Err(FileManagerThreadError::InvalidSelection));
}
}
}

fn select_files(&mut self, sender: IpcSender<FileManagerResult<Vec<(Uuid, PathBuf, u64)>>>) {
let selected_paths = vec![Path::new("")];

let mut replies = vec![];

for path in selected_paths {
match self.create_entry(path) {
Some(triple) => replies.push(triple),
None => {
let _ = sender.send(Err(FileManagerThreadError::InvalidSelection));
return;
}
}
}

let _ = sender.send(Ok(replies));
}

fn create_entry(&mut self, file_path: &Path) -> Option<(Uuid, PathBuf, u64)> {
match File::open(file_path) {
Ok(handler) => {
let id = Uuid::new_v4();
self.idmap.borrow_mut().insert(id, file_path.to_path_buf());

// Unix Epoch: https://doc.servo.org/std/time/constant.UNIX_EPOCH.html
let epoch = handler.metadata().and_then(|metadata| metadata.modified()).map_err(|_| ())
.and_then(|systime| systime.elapsed().map_err(|_| ()))
.and_then(|elapsed| {
let secs = elapsed.as_secs();
let nsecs = elapsed.subsec_nanos();
let msecs = secs * 1000 + nsecs as u64 / 1000000;
Ok(msecs)
});

let filename = file_path.file_name();

match (epoch, filename) {
(Ok(epoch), Some(filename)) => Some((id, Path::new(filename).to_path_buf(), epoch)),
_ => None
}
},
Err(_) => None
}
}

fn read_file(&mut self, sender: IpcSender<FileManagerResult<Vec<u8>>>, id: Uuid) {

match self.idmap.borrow().get(&id).and_then(|filepath| {
let mut buffer = vec![];
match File::open(&filepath) {
Ok(mut handler) => {
match handler.read_to_end(&mut buffer) {
Ok(_) => Some(buffer),
Err(_) => None,
}
},
Err(_) => None,
}
}) {
Some(buffer) => {
let _ = sender.send(Ok(buffer));
},
None => {
let _ = sender.send(Err(FileManagerThreadError::ReadFileError));
}
};
}

fn delete_fileid(&mut self, id: Uuid) {

This comment has been minimized.

@Manishearth

Manishearth May 11, 2016

Member

delete_file

This comment has been minimized.

@izgzhen

izgzhen May 11, 2016

Author Contributor

I thought about this name before as well, and I doubt if this name is kind of misleading?

This comment has been minimized.

@Manishearth

Manishearth May 11, 2016

Member

Nah, just consistency. This isn't really important, so feel free to keep it as is if you like this name.

self.idmap.borrow_mut().remove(&id);
}
}
@@ -4,6 +4,7 @@

#![feature(box_syntax)]
#![feature(fnbox)]
#![feature(fs_time)]
#![feature(mpsc_select)]
#![feature(plugin)]
#![feature(plugin)]
@@ -48,6 +49,7 @@ pub mod cookie;
pub mod cookie_storage;
pub mod data_loader;
pub mod file_loader;
pub mod filemanager_thread;
pub mod hsts;
pub mod http_loader;
pub mod image_cache_thread;
@@ -22,3 +22,4 @@ serde = "0.7"
serde_macros = "0.7"
url = {version = "1.0.0", features = ["heap_size"]}
websocket = "0.17"
uuid = { version = "0.2.2", features = ["v4", "serde"] }
@@ -0,0 +1,34 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use ipc_channel::ipc::IpcSender;
use std::path::PathBuf;
use uuid::Uuid;

#[derive(Deserialize, Serialize)]
pub enum FileManagerThreadMsg {
/// Select a single file, return triple (FileID, FileName, lastModified)
SelectFile(IpcSender<FileManagerResult<(Uuid, PathBuf, u64)>>),

/// Select multiple files, return a vector of triples
SelectFiles(IpcSender<FileManagerResult<Vec<(Uuid, PathBuf, u64)>>>),

/// Read file, return the bytes
ReadFile(IpcSender<FileManagerResult<Vec<u8>>>, Uuid),

/// Delete the FileID entry
DeleteFileID(Uuid),
}

pub type FileManagerResult<T> = Result<T, FileManagerThreadError>;

#[derive(Deserialize, Serialize)]
pub enum FileManagerThreadError {
/// The selection action is invalid, nothing is selected
InvalidSelection,
/// Failure to process file information such as file name, modified time etc.
FileInfoProcessingError,
/// Failure to read the file content
ReadFileError,
}
@@ -26,6 +26,7 @@ extern crate msg;
extern crate serde;
extern crate url;
extern crate util;
extern crate uuid;
extern crate websocket;

use hyper::header::{ContentType, Headers};
@@ -42,6 +43,7 @@ use websocket::header;

pub mod bluetooth_scanfilter;
pub mod bluetooth_thread;
pub mod filemanager_thread;
pub mod hosts;
pub mod image_cache_thread;
pub mod net_error_list;

Some generated files are not rendered by default. Learn more.

Some generated files are not rendered by default. Learn more.

Some generated files are not rendered by default. Learn more.

ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.