Added a pretty UI for happy path downloads
This commit is contained in:
parent
e97bc5a42e
commit
9a02ab991e
56
src/main.rs
56
src/main.rs
|
@ -188,19 +188,27 @@ fn download(server: &str, args: DownloadArgs) -> Result<(), AviaryDownloadError>
|
||||||
.try_into()
|
.try_into()
|
||||||
.map_err(|_| AviaryDownloadError::MalformedKey(false))?;
|
.map_err(|_| AviaryDownloadError::MalformedKey(false))?;
|
||||||
let download_agent = upload::get_agent();
|
let download_agent = upload::get_agent();
|
||||||
|
|
||||||
|
print!("Downloading index... ");
|
||||||
let encrypted_index = upload::get_data(&download_agent, &index_url, 500_000, &mut download_buffer)
|
let encrypted_index = upload::get_data(&download_agent, &index_url, 500_000, &mut download_buffer)
|
||||||
.map_err(AviaryDownloadError::from_download_error(true))?;
|
.map_err(AviaryDownloadError::from_download_error(true))?;
|
||||||
let serialized_index = crypto::decrypt(&key, &encrypted_index, &mut decrypt_buffer)
|
let serialized_index = crypto::decrypt(&key, &encrypted_index, &mut decrypt_buffer)
|
||||||
.ok_or(AviaryDownloadError::KeyMismatch)?;
|
.ok_or(AviaryDownloadError::KeyMismatch)?;
|
||||||
let index = protobuf::index::Index::parse_from_bytes(&serialized_index)
|
let index = protobuf::index::Index::parse_from_bytes(&serialized_index)
|
||||||
.map_err(|_| AviaryDownloadError::CorruptIndex("Index was not a valid protobuf structure"))?;
|
.map_err(|_| AviaryDownloadError::CorruptIndex("Index was not a valid protobuf structure"))?;
|
||||||
println!("{index:?}");
|
let image_count = index.images.len();
|
||||||
|
println!(
|
||||||
|
"\x1b[32mDone!\x1b[0m\n\nGallery Name: {}\n Image Count: {}\n\n(desc not implemented)\n",
|
||||||
|
index.title.as_ref().map(String::as_str).unwrap_or("<not set>"),
|
||||||
|
image_count
|
||||||
|
);
|
||||||
|
|
||||||
let dest_dir: Cow<Path> = args.output.map(Cow::Owned)
|
let dest_dir: Cow<Path> = args.output.map(Cow::Owned)
|
||||||
.unwrap_or_else(||
|
.unwrap_or_else(||
|
||||||
index.title.map(|title|
|
index.title.map(|title|
|
||||||
Cow::Owned(sanitise_with_options(&title, &SANITIZATION_OPTIONS).into()))
|
Cow::Owned(sanitise_with_options(&title, &SANITIZATION_OPTIONS).into()))
|
||||||
.unwrap_or(Cow::Borrowed("Unnamed-Album".as_ref())));
|
.unwrap_or(Cow::Borrowed("Unnamed-Album".as_ref())));
|
||||||
|
|
||||||
fs::create_dir_all(&dest_dir).map_err(|e| match e.kind() {
|
fs::create_dir_all(&dest_dir).map_err(|e| match e.kind() {
|
||||||
io::ErrorKind::PermissionDenied =>
|
io::ErrorKind::PermissionDenied =>
|
||||||
AviaryDownloadError::PermissionDenied(dest_dir.as_ref().to_owned()),
|
AviaryDownloadError::PermissionDenied(dest_dir.as_ref().to_owned()),
|
||||||
|
@ -208,23 +216,6 @@ fn download(server: &str, args: DownloadArgs) -> Result<(), AviaryDownloadError>
|
||||||
})?;
|
})?;
|
||||||
for (indx, image) in index.images.into_iter().enumerate() {
|
for (indx, image) in index.images.into_iter().enumerate() {
|
||||||
|
|
||||||
// Print a little blurhash
|
|
||||||
const BH_WIDTH: u32 = 12;
|
|
||||||
const BH_HEIGHT: u32 = 5;
|
|
||||||
let blur = blurhash::decode(&image.blurhash, BH_WIDTH, BH_HEIGHT, 1.0);
|
|
||||||
let mut blur = blur.iter();
|
|
||||||
for _ in 0..BH_HEIGHT {
|
|
||||||
for _ in 0..BH_WIDTH {
|
|
||||||
let r = blur.next().unwrap();
|
|
||||||
let g = blur.next().unwrap();
|
|
||||||
let b = blur.next().unwrap();
|
|
||||||
let _ = blur.next().unwrap();
|
|
||||||
print!("\x1b[38;2;{r};{g};{b}m█");
|
|
||||||
}
|
|
||||||
print!("\n");
|
|
||||||
}
|
|
||||||
print!("\x1b[0m");
|
|
||||||
|
|
||||||
let extension = image.format.enum_value().map(|f| match f {
|
let extension = image.format.enum_value().map(|f| match f {
|
||||||
Format::PNG => "png",
|
Format::PNG => "png",
|
||||||
Format::WEBP => "webp",
|
Format::WEBP => "webp",
|
||||||
|
@ -232,6 +223,28 @@ fn download(server: &str, args: DownloadArgs) -> Result<(), AviaryDownloadError>
|
||||||
Format::JPG => "jpg",
|
Format::JPG => "jpg",
|
||||||
Format::GIF => "gif",
|
Format::GIF => "gif",
|
||||||
}).unwrap_or("unk");
|
}).unwrap_or("unk");
|
||||||
|
|
||||||
|
// Print a little blurhash
|
||||||
|
const BH_WIDTH: u32 = 12;
|
||||||
|
const BH_HEIGHT: u32 = 5;
|
||||||
|
let blur = blurhash::decode(&image.blurhash, BH_WIDTH, BH_HEIGHT, 1.0);
|
||||||
|
let mut blur = blur.iter();
|
||||||
|
for y in 0..BH_HEIGHT {
|
||||||
|
for _ in 0..BH_WIDTH {
|
||||||
|
let r = blur.next().unwrap();
|
||||||
|
let g = blur.next().unwrap();
|
||||||
|
let b = blur.next().unwrap();
|
||||||
|
let _ = blur.next().unwrap();
|
||||||
|
print!("\x1b[38;2;{r};{g};{b}m█");
|
||||||
|
}
|
||||||
|
match y {
|
||||||
|
1 => println!("\x1b[0m Image {}/{}", indx + 1, image_count),
|
||||||
|
2 => println!("\x1b[0m Format: {}", extension),
|
||||||
|
_ => println!(""),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
print!("\x1b[37m├─\x1b[0m Reserving file... ");
|
||||||
|
stdout().flush().unwrap();
|
||||||
let path = dest_dir.join(format!("{indx:03}.{extension}"));
|
let path = dest_dir.join(format!("{indx:03}.{extension}"));
|
||||||
let mut dest_file = OpenOptions::new()
|
let mut dest_file = OpenOptions::new()
|
||||||
.write(true)
|
.write(true)
|
||||||
|
@ -251,17 +264,23 @@ fn download(server: &str, args: DownloadArgs) -> Result<(), AviaryDownloadError>
|
||||||
.map_err(|_|
|
.map_err(|_|
|
||||||
AviaryDownloadError::CorruptIndex("Key of invalid length specified in index")
|
AviaryDownloadError::CorruptIndex("Key of invalid length specified in index")
|
||||||
)?;
|
)?;
|
||||||
|
print!("\x1b[32mDone!\n\x1b[37m├─\x1b[0m Dowloading... ");
|
||||||
|
stdout().flush().unwrap();
|
||||||
let encrypted_thumbnail = upload::get_data(
|
let encrypted_thumbnail = upload::get_data(
|
||||||
&download_agent,
|
&download_agent,
|
||||||
&format!("{}/{}.bin", server, image.full_url),
|
&format!("{}/{}.bin", server, image.full_url),
|
||||||
7680_000,
|
7680_000,
|
||||||
&mut download_buffer
|
&mut download_buffer
|
||||||
).map_err(AviaryDownloadError::from_download_error(false))?;
|
).map_err(AviaryDownloadError::from_download_error(false))?;
|
||||||
|
print!("\x1b[32mDone!\n\x1b[37m├─\x1b[0m Decrypting... ");
|
||||||
|
stdout().flush().unwrap();
|
||||||
let decrypted_thumb = crypto::decrypt(
|
let decrypted_thumb = crypto::decrypt(
|
||||||
&key,
|
&key,
|
||||||
encrypted_thumbnail,
|
encrypted_thumbnail,
|
||||||
&mut decrypt_buffer
|
&mut decrypt_buffer
|
||||||
).ok_or(AviaryDownloadError::ExpiredImage)?;
|
).ok_or(AviaryDownloadError::ExpiredImage)?;
|
||||||
|
print!("\x1b[32mDone!\n\x1b[37m└─\x1b[0m Saving... ");
|
||||||
|
stdout().flush().unwrap();
|
||||||
dest_file.write_all(&decrypted_thumb)
|
dest_file.write_all(&decrypted_thumb)
|
||||||
.map_err(|e| match e.kind() {
|
.map_err(|e| match e.kind() {
|
||||||
io::ErrorKind::PermissionDenied =>
|
io::ErrorKind::PermissionDenied =>
|
||||||
|
@ -270,6 +289,7 @@ fn download(server: &str, args: DownloadArgs) -> Result<(), AviaryDownloadError>
|
||||||
AviaryDownloadError::Cancelled,
|
AviaryDownloadError::Cancelled,
|
||||||
_ => AviaryDownloadError::FilesystemError(e, path.clone())
|
_ => AviaryDownloadError::FilesystemError(e, path.clone())
|
||||||
})?;
|
})?;
|
||||||
|
println!("\x1b[32mDone!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -21,12 +21,10 @@ pub fn put_data(agent: &Agent, server: &str, data: &[u8]) -> Result<String, ureq
|
||||||
|
|
||||||
pub fn get_data<'b>(agent: &Agent, location: &str, size_limit: u64, buffer: &'b mut Vec<u8>) -> Result<&'b mut Vec<u8>, ureq::Error> {
|
pub fn get_data<'b>(agent: &Agent, location: &str, size_limit: u64, buffer: &'b mut Vec<u8>) -> Result<&'b mut Vec<u8>, ureq::Error> {
|
||||||
buffer.clear();
|
buffer.clear();
|
||||||
println!("{}", location);
|
agent.get(location)
|
||||||
let read = agent.get(location)
|
|
||||||
.call()?
|
.call()?
|
||||||
.into_reader()
|
.into_reader()
|
||||||
.take(size_limit)
|
.take(size_limit)
|
||||||
.read_to_end(buffer)?;
|
.read_to_end(buffer)?;
|
||||||
println!("{}", read);
|
|
||||||
Ok(buffer)
|
Ok(buffer)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue