Skip to content

Commit

Permalink
feat: provide a files ls command
Browse files Browse the repository at this point in the history
Gives the user to list the files they have uploaded, along with their addresses. We were storing
this data anyway, but it's serialized to binary, so it's not human readable. A little interface on
the client could be useful for users.
  • Loading branch information
jacderida committed Sep 19, 2023
1 parent b8487f4 commit b5666ce
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 5 deletions.
7 changes: 6 additions & 1 deletion sn_cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ mod subcommands;
use crate::{
cli::Opt,
subcommands::{
files::files_cmds,
files::{files_cmds, offline_files_cmds, FilesCmds},
register::register_cmds,
wallet::{wallet_cmds, wallet_cmds_without_client, WalletCmds},
SubCmd,
Expand Down Expand Up @@ -68,6 +68,11 @@ async fn main() -> Result<()> {
wallet_cmds_without_client(cmds, &client_data_dir_path).await?;
return Ok(());
}
} else if let SubCmd::Files(cmd) = &opt.cmd {
if let FilesCmds::Ls {} = cmd {
offline_files_cmds(cmd, &client_data_dir_path).await?;
return Ok(());
}
}
println!("Instantiating a SAFE client...");
let secret_key = get_client_secret_key(&client_data_dir_path)?;
Expand Down
53 changes: 49 additions & 4 deletions sn_cli/src/subcommands/files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@
use super::wallet::{ChunkedFile, BATCH_SIZE};
use bytes::Bytes;
use clap::Parser;
use color_eyre::{
eyre::{bail, Error},
Result,
};
use color_eyre::{eyre::Error, Result};
use libp2p::futures::future::join_all;
use sn_client::{Client, Files};
use sn_protocol::storage::{Chunk, ChunkAddress};
Expand All @@ -28,6 +25,7 @@ use xor_name::XorName;

#[derive(Parser, Debug)]
pub enum FilesCmds {
Ls {},
Upload {
/// The location of the file(s) to upload.
///
Expand Down Expand Up @@ -55,6 +53,18 @@ pub enum FilesCmds {
},
}

pub(crate) async fn offline_files_cmds(cmds: &FilesCmds, root_dir: &Path) -> Result<()> {
match cmds {
FilesCmds::Ls {} => {
list_files(root_dir).await?;
}
cmd => {
return Err(eyre!("{cmd:?} requires a network connection"));
}
}
Ok(())
}

pub(crate) async fn files_cmds(
cmds: FilesCmds,
client: Client,
Expand Down Expand Up @@ -92,10 +102,36 @@ pub(crate) async fn files_cmds(
}
}
}
cmd => {
return Err(eyre!("{cmd:?} is an offline command"));
}
};
Ok(())
}

async fn list_files(root_dir: &Path) -> Result<()> {
let file_names_path = root_dir.join("uploaded_files");
let mut all_files: Vec<Vec<(XorName, String)>> = Vec::new();
let entries = fs::read_dir(file_names_path)?;
for entry in entries {
let entry = entry?;
let path = entry.path();
if path.is_dir() {
continue;
}
let content = fs::read(&path)?;
let deserialized_data: Vec<(XorName, String)> = bincode::deserialize(&content)?;
all_files.push(deserialized_data);
}

for file in all_files.iter() {
for (addr, file_name) in file.iter() {
println!("{addr:64x}: {file_name}");
}
}
Ok(())
}

pub(super) async fn chunk_path(
client: &Client,
root_dir: &Path,
Expand Down Expand Up @@ -236,6 +272,15 @@ async fn upload_files(
// Record the uploaded files locally to be able to fetch them later
let content = bincode::serialize(&uploaded_files)?;
let file_names_path = root_dir.join("uploaded_files");
let all_data_put: Vec<_> = upload_results
.into_iter()
.map(|(addr, filename, _, _)| (addr, filename))
.collect();
for (addr, file_name) in all_data_put.iter() {
println!("Uploaded {file_name} to {addr:64x}");
}
// Write the chunks locally to be able to verify them later
let content = bincode::serialize(&all_data_put)?;
fs::create_dir_all(file_names_path.as_path())?;
let date_time = chrono::Local::now().format("%Y-%m-%d_%H-%M-%S").to_string();
let file_names_path = file_names_path.join(format!("file_names_{date_time}"));
Expand Down

0 comments on commit b5666ce

Please sign in to comment.