Skip to content

Commit 8b6c13f

Browse files
committed
feat: add zenodo dataset commands
1 parent ed966ab commit 8b6c13f

6 files changed

Lines changed: 406 additions & 73 deletions

File tree

Cargo.lock

Lines changed: 81 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ snafu = { version = "0.8.5" }
3131
tokio = { version = "1", features = ["full"] }
3232
tokio-util = { version = "0.7", features = ["codec"] }
3333
walkdir = "2"
34+
tabled = "0.20.0"
35+
chrono = "0.4.43"
3436
futures = { version = "0.3" }
3537
regex = { version = "1.11.0" }
3638
iso8601-timestamp = { version = "0.2.17" }
@@ -47,6 +49,7 @@ openidconnect = { version = "3.5.0", default-features = false, features = [
4749
] }
4850
directories = { version = "5.0" }
4951
comrak = { version = "0.28.0", optional = true }
52+
md5 = "0.8.0"
5053

5154
[features]
5255
default = ["reqwest/default-tls"] # link against system library

src/cli/cmd/dataset.rs

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
pub mod deposit;
22
pub mod zenodo;
3+
mod zenodo_api;
34

4-
use super::Context;
5-
use clap::Parser;
6-
use snafu::Snafu;
5+
use super::Context as ParentContext;
6+
use clap::{Parser, ValueEnum};
7+
use snafu::{ResultExt, Snafu};
8+
9+
#[derive(Debug, Clone, ValueEnum)]
10+
pub enum Provider {
11+
Zenodo,
12+
}
713

814
#[derive(Debug, Snafu)]
915
pub enum Error {
@@ -21,24 +27,54 @@ pub struct Input {
2127
#[derive(Parser, Debug)]
2228
pub enum DatasetCommand {
2329
Deposit {
30+
#[arg(long, default_value = "zenodo")]
31+
provider: Provider,
2432
#[command(subcommand)]
2533
cmd: DepositCommand,
2634
},
2735
}
2836

2937
#[derive(Parser, Debug)]
3038
pub enum DepositCommand {
31-
#[command()]
39+
#[command(name = "cp")]
3240
CopyFiles(deposit::CopyInput),
41+
#[command(name = "ls")]
42+
ListDeposits(deposit::ListInput),
43+
#[command(name = "lsf")]
44+
ListFiles(deposit::ListFiles),
45+
}
46+
47+
pub struct Context {
48+
pub parent: ParentContext,
49+
pub provider: Provider,
50+
}
51+
52+
impl Context {
53+
pub fn new(ctx: ParentContext, provider: Provider) -> Context {
54+
Context {
55+
parent: ctx,
56+
provider,
57+
}
58+
}
3359
}
3460

3561
impl Input {
36-
pub async fn exec(&self, _ctx: Context) -> Result<(), Error> {
37-
match self.subcmd {
38-
DatasetCommand::Deposit { cmd: _ } => {
39-
print!("Hi");
40-
Ok(())
41-
}
62+
pub async fn exec(&self, ctx: ParentContext) -> Result<(), Error> {
63+
match &self.subcmd {
64+
DatasetCommand::Deposit { provider, cmd } => match cmd {
65+
DepositCommand::CopyFiles(input) => input
66+
.exec(Context::new(ctx, provider.clone()))
67+
.await
68+
.context(DepositSnafu),
69+
DepositCommand::ListDeposits(input) => input
70+
.exec(Context::new(ctx, provider.clone()))
71+
.await
72+
.context(DepositSnafu),
73+
DepositCommand::ListFiles(input) => input
74+
.exec(Context::new(ctx, provider.clone()))
75+
.await
76+
.context(DepositSnafu),
77+
},
4278
}
4379
}
4480
}

src/cli/cmd/dataset/deposit.rs

Lines changed: 67 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
11
use super::zenodo;
2-
use super::Context;
3-
use clap::{Parser, ValueEnum};
2+
use super::{Context, Provider};
3+
use clap::Parser;
44
use snafu::{ResultExt, Snafu};
55
use std::env::VarError;
66
use std::path::PathBuf;
7-
8-
#[derive(Debug, Clone, ValueEnum)]
9-
pub enum Provider {
10-
Zenodo,
11-
}
7+
use tabled::builder::Builder;
128

139
#[derive(Debug, Snafu)]
1410
pub enum Error {
@@ -22,29 +18,82 @@ pub enum Error {
2218
/// Copies the data from a location into a data deposit
2319
#[derive(Parser, Debug)]
2420
pub struct CopyInput {
25-
/// The id of the deposit the data should be copied to.
26-
#[arg()]
27-
pub deposit_id: String,
28-
29-
/// The provider for the dataset
30-
#[arg()]
31-
pub provider: Provider,
32-
3321
/// The source directory where the files to be copied can be found.
3422
#[arg()]
3523
pub source_dir: PathBuf,
24+
25+
/// The id of the deposit the data should be copied to.
26+
#[arg()]
27+
pub deposit_id: String,
3628
}
3729

3830
impl CopyInput {
39-
pub async fn exec(&self, _ctx: Context) -> Result<(), Error> {
40-
match self.provider {
31+
pub async fn exec(&self, ctx: Context) -> Result<(), Error> {
32+
match ctx.provider {
4133
Provider::Zenodo => {
4234
let token = std::env::var("ZENODO_API_KEY").context(EnvVarMissingSnafu)?;
43-
let clnt = zenodo::ZenodoClient::new(token);
35+
let clnt = zenodo::ZenodoClient::new(token, ctx.parent.opts.verbose > 1);
4436
clnt.upload_files(&self.deposit_id, &self.source_dir)
4537
.await
4638
.context(ZenodoSnafu)
4739
}
4840
}
4941
}
5042
}
43+
44+
/// List all depositions for the specific provider
45+
#[derive(Parser, Debug)]
46+
pub struct ListInput {}
47+
48+
impl ListInput {
49+
pub async fn exec(&self, ctx: Context) -> Result<(), Error> {
50+
match ctx.provider {
51+
Provider::Zenodo => {
52+
let token = std::env::var("ZENODO_API_KEY").context(EnvVarMissingSnafu)?;
53+
let clnt = zenodo::ZenodoClient::new(token, ctx.parent.opts.verbose > 1);
54+
let deps = clnt.get_depositions().await.context(ZenodoSnafu)?;
55+
let mut table = Builder::default();
56+
table.push_record(["ID", "Title", "State", "Created at"]);
57+
for d in deps {
58+
table.push_record([
59+
d.id.to_string(),
60+
d.title,
61+
d.state,
62+
d.created
63+
.to_rfc3339_opts(chrono::SecondsFormat::Secs, false),
64+
]);
65+
}
66+
println!("{}", table.build());
67+
Ok(())
68+
}
69+
}
70+
}
71+
}
72+
73+
/// List all files in a specific deposit
74+
#[derive(Parser, Debug)]
75+
pub struct ListFiles {
76+
deposit_id: String,
77+
}
78+
79+
impl ListFiles {
80+
pub async fn exec(&self, ctx: Context) -> Result<(), Error> {
81+
match ctx.provider {
82+
Provider::Zenodo => {
83+
let token = std::env::var("ZENODO_API_KEY").context(EnvVarMissingSnafu)?;
84+
let clnt = zenodo::ZenodoClient::new(token, ctx.parent.opts.verbose > 1);
85+
let files = clnt
86+
.list_files(&self.deposit_id)
87+
.await
88+
.context(ZenodoSnafu)?;
89+
let mut table = Builder::default();
90+
table.push_record(["Filename", "Size", "Checksum"]);
91+
for f in files {
92+
table.push_record([f.filename, f.filesize.to_string(), f.checksum]);
93+
}
94+
println!("{}", table.build());
95+
Ok(())
96+
}
97+
}
98+
}
99+
}

0 commit comments

Comments
 (0)