Skip to content

Commit

Permalink
Start spliting into smalle modules. Starting with downloads
Browse files Browse the repository at this point in the history
  • Loading branch information
LDprg committed May 15, 2024
1 parent 2e77339 commit 9e1a1d9
Show file tree
Hide file tree
Showing 5 changed files with 218 additions and 139 deletions.
2 changes: 1 addition & 1 deletion run.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#!/bin/sh

cargo run -- --input ./test_packages/elfutils/ --output ./out/elfutils/
cargo run -- --input ./test_packages/xz/ --output ./out/xz/
107 changes: 49 additions & 58 deletions src/decompress.rs
Original file line number Diff line number Diff line change
@@ -1,71 +1,62 @@
use std::path::Path;
use std::process::exit;

use log::error;
use tokio::pin;
use tokio_stream::Stream;
use tokio_util::{bytes::Buf, io::StreamReader};

use crate::fatal;
use crate::log::*;

pub async fn decompress(
stream: impl Stream<Item = Result<impl Buf, impl Into<std::io::Error>>>,
output: &Path,
file_name: &str,
) -> String {
let mut file_name = String::from(file_name.trim());

extension: &str,
) {
// TODO: create a more elegant and efficent way to determine compression algo and file name

if file_name.ends_with(".tar.zst") {
let decoder =
async_compression::tokio::bufread::ZstdDecoder::new(StreamReader::new(stream));

pin!(decoder);

tokio_tar::Archive::new(decoder)
.unpack(&output)
.await
.expect("Cannot unpack archive");

file_name.truncate(file_name.len() - ".tar.zst".len())
} else if file_name.ends_with(".tar.xz") {
let decoder = async_compression::tokio::bufread::XzDecoder::new(StreamReader::new(stream));

pin!(decoder);

tokio_tar::Archive::new(decoder)
.unpack(&output)
.await
.expect("Cannot unpack archive");

file_name.truncate(file_name.len() - ".tar.xz".len())
} else if file_name.ends_with(".tar.gz") {
let decoder =
async_compression::tokio::bufread::GzipDecoder::new(StreamReader::new(stream));

pin!(decoder);

tokio_tar::Archive::new(decoder)
.unpack(&output)
.await
.expect("Cannot unpack archive");

file_name.truncate(file_name.len() - ".tar.gz".len())
} else if file_name.ends_with(".tar.bz2") {
let decoder = async_compression::tokio::bufread::BzDecoder::new(StreamReader::new(stream));

pin!(decoder);

tokio_tar::Archive::new(decoder)
.unpack(&output)
.await
.expect("Cannot unpack archive");

file_name.truncate(file_name.len() - ".tar.bz2".len())
} else {
fatal!("Extension of \"{}\" not supported!", file_name);
match extension {
".tar.zst" => {
let decoder =
async_compression::tokio::bufread::ZstdDecoder::new(StreamReader::new(stream));

pin!(decoder);

tokio_tar::Archive::new(decoder)
.unpack(&output)
.await
.expect("Cannot unpack archive");
}
".tar.xz" => {
let decoder =
async_compression::tokio::bufread::XzDecoder::new(StreamReader::new(stream));

pin!(decoder);

tokio_tar::Archive::new(decoder)
.unpack(&output)
.await
.expect("Cannot unpack archive");
}
".tar.gz" => {
let decoder =
async_compression::tokio::bufread::GzipDecoder::new(StreamReader::new(stream));

pin!(decoder);

tokio_tar::Archive::new(decoder)
.unpack(&output)
.await
.expect("Cannot unpack archive");
}
".tar.bz2" => {
let decoder =
async_compression::tokio::bufread::BzDecoder::new(StreamReader::new(stream));

pin!(decoder);

tokio_tar::Archive::new(decoder)
.unpack(&output)
.await
.expect("Cannot unpack archive");
}
_ => fatal!("Extension of \"{}\" not supported!", extension),
}

file_name
}
131 changes: 131 additions & 0 deletions src/downloader.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
use std::cmp::min;
use std::path::Path;

use indicatif::{MultiProgress, ProgressBar};
use tokio_stream::StreamExt;
use url::Url;

use crate::decompress::decompress;
use crate::log::*;
use crate::{bars::ProgressStyle, somebuild_config::Config};

pub struct Download<'a> {
bar: ProgressBar,
config: &'a Config,
output: &'a Path,
#[allow(dead_code)]
pub full_file_name: String,
#[allow(dead_code)]
pub file_name: String,
#[allow(dead_code)]
pub extension: String,
}

impl<'a> Download<'a> {
pub fn new(multibar: &MultiProgress, config: &'a Config, output: &'a Path) -> Self {
let bar = multibar.add(ProgressBar::new(1));
let name = Url::parse(&config.source.url)
.unwrap()
.path_segments()
.unwrap()
.last()
.unwrap()
.trim()
.to_string();

let (full_file_name, file_name, extension) = if name.ends_with(".tar.zst") {
(
name.clone(),
name.split_at(name.len() - ".tar.zst".len()).0.to_string(),
".tar.zst".to_string(),
)
} else if name.ends_with(".tar.xz") {
(
name.clone(),
name.split_at(name.len() - ".tar.xz".len()).0.to_string(),
".tar.xz".to_string(),
)
} else if name.ends_with(".tar.gz") {
(
name.clone(),
name.split_at(name.len() - ".tar.gz".len()).0.to_string(),
".tar.gz".to_string(),
)
} else if name.ends_with(".tar.bz2") {
(
name.clone(),
name.split_at(name.len() - ".tar.bz2".len()).0.to_string(),
".tar.bz2".to_string(),
)
} else {
fatal!("Extension of \"{}\" not supported!", name);
};

Self {
bar,
config,
output,
full_file_name,
file_name,
extension,
}
}

pub async fn download(&self) {
self.bar.set_style(ProgressStyle::Download.value());
self.bar.set_message(format!(
"Starting {}-{}",
self.config.general.name, self.config.source.version
));

self.bar.tick();

let response = reqwest::get(&self.config.source.url).await.unwrap();

let total_size = response.content_length().unwrap_or(0);

self.bar.set_length(total_size);
self.bar.set_message(format!(
"Downloading {}-{}",
self.config.general.name, self.config.source.version
));

let mut hasher = blake3::Hasher::new();
let mut downloaded: u64 = 0;

let stream = response.bytes_stream().map(|result| {
result
.inspect(|result| {
let new = min(downloaded + (result.len() as u64), total_size);
downloaded = new;
self.bar.set_position(new);
})
.inspect(|result| {
hasher.update(result);
})
.map_err(|err| std::io::Error::new(std::io::ErrorKind::Other, err))
});

decompress(stream, self.output, &self.extension).await;

info!("Extract Folder:\t{}", self.file_name);

let hash = hasher.finalize();

if hash.to_string() != self.config.source.hash {
fatal!(
"Hash error for \"{}\" specified \n\t \"{}\" found\n\t \"{}\"",
self.config.source.url,
self.config.source.hash,
hash.to_string()
);
}
}

pub fn finish(&self) {
self.bar.finish_with_message(format!(
"Finished downloading {}-{}",
self.config.general.name, self.config.source.version
));
}
}
25 changes: 25 additions & 0 deletions src/log.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
pub use std::process::exit;

#[allow(unused_imports)]
pub use log::error;

#[allow(unused_imports)]
pub use log::warn;

#[allow(unused_imports)]
pub use log::info;

#[allow(unused_imports)]
pub use log::debug;

#[macro_export]
macro_rules! fatal {
( $($var:tt)* ) => {
{
error!($($var)*);
exit(1);
}
};
}

pub(crate) use fatal;
Loading

0 comments on commit 9e1a1d9

Please sign in to comment.