implement download
This commit is contained in:
parent
e112253bf8
commit
a316558140
|
@ -86,6 +86,12 @@ version = "0.3.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
|
checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "byte-unit"
|
||||||
|
version = "3.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "55390dbbf21ce70683f3e926dace00a21da373e35e44a60cafd232e3e9bf2041"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "byteorder"
|
name = "byteorder"
|
||||||
version = "1.3.4"
|
version = "1.3.4"
|
||||||
|
@ -323,6 +329,7 @@ name = "gitea-release"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
"byte-unit",
|
||||||
"cli-table",
|
"cli-table",
|
||||||
"comrak",
|
"comrak",
|
||||||
"git2",
|
"git2",
|
||||||
|
|
|
@ -8,6 +8,7 @@ edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0"
|
anyhow = "1.0"
|
||||||
|
byte-unit = "3"
|
||||||
cli-table = "0.3"
|
cli-table = "0.3"
|
||||||
comrak = "0.7"
|
comrak = "0.7"
|
||||||
git2 = "0.13"
|
git2 = "0.13"
|
||||||
|
@ -18,3 +19,6 @@ serde_json = "1.0"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
structopt = { version = "0.3", default-features = false }
|
structopt = { version = "0.3", default-features = false }
|
||||||
tokio = { version = "0.2", features = ["macros"] }
|
tokio = { version = "0.2", features = ["macros"] }
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
lto = true
|
||||||
|
|
3
TODO.org
3
TODO.org
|
@ -3,7 +3,8 @@
|
||||||
* Commands
|
* Commands
|
||||||
** DONE delete
|
** DONE delete
|
||||||
CLOSED: [2020-05-30 Sat 12:23]
|
CLOSED: [2020-05-30 Sat 12:23]
|
||||||
** TODO download
|
** DONE download
|
||||||
|
CLOSED: [2020-05-30 Sat 14:27]
|
||||||
** TODO edit
|
** TODO edit
|
||||||
** DONE info
|
** DONE info
|
||||||
CLOSED: [2020-05-30 Sat 10:52]
|
CLOSED: [2020-05-30 Sat 10:52]
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
use crate::{gitea::*, *};
|
||||||
|
use anyhow::{anyhow, Result};
|
||||||
|
use cli_table::{Cell, Row, Table};
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::Write;
|
||||||
|
|
||||||
|
pub(crate) async fn run(common: Common, fname: Option<PathBuf>) -> Result<()> {
|
||||||
|
if common.tag.is_none() {
|
||||||
|
return Err(anyhow!("requires --tag"));
|
||||||
|
}
|
||||||
|
let cli = client(&common)?;
|
||||||
|
let release = get_release_by_tag(
|
||||||
|
&cli,
|
||||||
|
&common.server,
|
||||||
|
&common.owner,
|
||||||
|
&common.repo,
|
||||||
|
&common.tag.unwrap(),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
let attachments = get_attachments_for_release(
|
||||||
|
&cli,
|
||||||
|
&common.server,
|
||||||
|
&common.owner,
|
||||||
|
&common.repo,
|
||||||
|
&release.id,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
match fname {
|
||||||
|
None => {
|
||||||
|
let mut rows: Vec<Row> = vec![Row::new(vec![
|
||||||
|
Cell::new(&"name", Default::default()),
|
||||||
|
Cell::new(&"size", Default::default()),
|
||||||
|
Cell::new(&"url", Default::default()),
|
||||||
|
])];
|
||||||
|
for attachment in attachments {
|
||||||
|
rows.push(attachment.row())
|
||||||
|
}
|
||||||
|
|
||||||
|
let table = Table::new(rows, Default::default())?;
|
||||||
|
table.print_stdout()?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(fname) => {
|
||||||
|
let mut url: Option<String> = None;
|
||||||
|
let fname = fname.into_os_string().into_string().unwrap();
|
||||||
|
|
||||||
|
for attachment in attachments {
|
||||||
|
if &fname == &attachment.name {
|
||||||
|
url = Some(attachment.browser_download_url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if url.is_none() {
|
||||||
|
return Err(anyhow!("no attachment named {}", fname));
|
||||||
|
}
|
||||||
|
|
||||||
|
let data = &cli.get(url.unwrap().as_str()).send().await?.bytes().await?;
|
||||||
|
let mut fout = File::create(&fname)?;
|
||||||
|
|
||||||
|
fout.write(data)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,2 +1,3 @@
|
||||||
pub(crate) mod delete;
|
pub(crate) mod delete;
|
||||||
|
pub(crate) mod download;
|
||||||
pub(crate) mod info;
|
pub(crate) mod info;
|
||||||
|
|
50
src/gitea.rs
50
src/gitea.rs
|
@ -85,3 +85,53 @@ pub(crate) async fn get_release_by_tag(
|
||||||
|
|
||||||
Ok(release.unwrap())
|
Ok(release.unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub struct Attachment {
|
||||||
|
pub id: i64,
|
||||||
|
pub name: String,
|
||||||
|
pub size: i64,
|
||||||
|
pub download_count: i64,
|
||||||
|
pub created_at: String,
|
||||||
|
pub uuid: String,
|
||||||
|
pub browser_download_url: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Attachment {
|
||||||
|
pub fn row(&self) -> Row {
|
||||||
|
let size = {
|
||||||
|
let bytes = byte_unit::Byte::from_bytes(self.size as u128);
|
||||||
|
let unit = bytes.get_appropriate_unit(false);
|
||||||
|
unit.to_string()
|
||||||
|
};
|
||||||
|
|
||||||
|
Row::new(vec![
|
||||||
|
Cell::new(&self.name, Default::default()),
|
||||||
|
Cell::new(&size, Default::default()),
|
||||||
|
Cell::new(&self.browser_download_url, Default::default()),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn get_attachments_for_release(
|
||||||
|
cli: &reqwest::Client,
|
||||||
|
server: &String,
|
||||||
|
owner: &String,
|
||||||
|
repo: &String,
|
||||||
|
id: &i64,
|
||||||
|
) -> Result<Vec<Attachment>> {
|
||||||
|
let attachments: Vec<Attachment> = cli
|
||||||
|
.get(
|
||||||
|
format!(
|
||||||
|
"{}/api/v1/repos/{}/{}/releases/{}/assets",
|
||||||
|
server, owner, repo, id
|
||||||
|
)
|
||||||
|
.as_str(),
|
||||||
|
)
|
||||||
|
.send()
|
||||||
|
.await?
|
||||||
|
.json()
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(attachments)
|
||||||
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ pub(crate) struct Common {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Name your user agent after your app?
|
// Name your user agent after your app?
|
||||||
static APP_USER_AGENT: &str = concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION"),);
|
static APP_USER_AGENT: &str = concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION"));
|
||||||
|
|
||||||
pub(crate) fn client(c: &Common) -> Result<Client> {
|
pub(crate) fn client(c: &Common) -> Result<Client> {
|
||||||
let mut headers = header::HeaderMap::new();
|
let mut headers = header::HeaderMap::new();
|
||||||
|
@ -69,7 +69,7 @@ pub(crate) enum Cmd {
|
||||||
common: Common,
|
common: Common,
|
||||||
/// Folder to download release artifacts to
|
/// Folder to download release artifacts to
|
||||||
#[structopt(short, long)]
|
#[structopt(short, long)]
|
||||||
fname: PathBuf,
|
fname: Option<PathBuf>,
|
||||||
},
|
},
|
||||||
/// Edits a release's description, name and other flags
|
/// Edits a release's description, name and other flags
|
||||||
Edit {
|
Edit {
|
||||||
|
@ -124,6 +124,7 @@ async fn main() -> Result<()> {
|
||||||
|
|
||||||
match cmd {
|
match cmd {
|
||||||
Cmd::Delete { common } => cmd::delete::run(common).await,
|
Cmd::Delete { common } => cmd::delete::run(common).await,
|
||||||
|
Cmd::Download { common, fname } => cmd::download::run(common, fname).await,
|
||||||
Cmd::Info { common, json } => cmd::info::run(common, json).await,
|
Cmd::Info { common, json } => cmd::info::run(common, json).await,
|
||||||
|
|
||||||
_ => Err(anyhow!("not implemented yet")),
|
_ => Err(anyhow!("not implemented yet")),
|
||||||
|
|
Loading…
Reference in New Issue