mirror of
https://github.com/yuhkix/wuwa-downloader.git
synced 2025-06-04 08:53:41 +00:00
chore: add package.sh script and apply code formatting
This commit is contained in:
parent
bece26c433
commit
29bd052ef4
11 changed files with 169 additions and 31 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -4,6 +4,9 @@ debug/
|
||||||
target/
|
target/
|
||||||
.idea/
|
.idea/
|
||||||
|
|
||||||
|
# packaging
|
||||||
|
dist/
|
||||||
|
|
||||||
# These are backup files generated by rustfmt
|
# These are backup files generated by rustfmt
|
||||||
**/*.rs.bk
|
**/*.rs.bk
|
||||||
|
|
||||||
|
|
113
package.sh
Normal file
113
package.sh
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
BIN_NAME="wuwa-downloader"
|
||||||
|
DIST_DIR="dist"
|
||||||
|
|
||||||
|
# Colors
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
CYAN='\033[0;36m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
function info() {
|
||||||
|
echo -e "${CYAN}==> $1${NC}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function success() {
|
||||||
|
echo -e "${GREEN}✔ $1${NC}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function warn() {
|
||||||
|
echo -e "${YELLOW}⚠ $1${NC}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function error() {
|
||||||
|
echo -e "${RED}✖ $1${NC}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function build_linux() {
|
||||||
|
local OUT_DIR="target/release"
|
||||||
|
local PACKAGE_NAME="${BIN_NAME}-linux-x86_64"
|
||||||
|
local PACKAGE_DIR="${DIST_DIR}/${PACKAGE_NAME}"
|
||||||
|
local ARCHIVE_NAME="${PACKAGE_NAME}.tar.gz"
|
||||||
|
|
||||||
|
clear
|
||||||
|
|
||||||
|
info "Cleaning binaries to rebuild..."
|
||||||
|
cargo clean
|
||||||
|
|
||||||
|
info "Building release binary for Linux..."
|
||||||
|
cargo build --release
|
||||||
|
clear
|
||||||
|
success "Linux build finished"
|
||||||
|
|
||||||
|
info "Creating package directory..."
|
||||||
|
rm -rf "$PACKAGE_DIR"
|
||||||
|
mkdir -p "$PACKAGE_DIR"
|
||||||
|
success "Package directory ready: $PACKAGE_DIR"
|
||||||
|
|
||||||
|
info "Copying binary..."
|
||||||
|
cp "$OUT_DIR/$BIN_NAME" "$PACKAGE_DIR/"
|
||||||
|
success "Copied binary to package directory"
|
||||||
|
|
||||||
|
info "Creating archive..."
|
||||||
|
cd "$DIST_DIR"
|
||||||
|
tar -czf "$ARCHIVE_NAME" "$PACKAGE_NAME"
|
||||||
|
cd -
|
||||||
|
success "Archive created: ${DIST_DIR}/${ARCHIVE_NAME}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function build_windows() {
|
||||||
|
local TARGET="x86_64-pc-windows-gnu"
|
||||||
|
local OUT_DIR="target/${TARGET}/release"
|
||||||
|
local PACKAGE_NAME="${BIN_NAME}-windows-x86_64"
|
||||||
|
local PACKAGE_DIR="${DIST_DIR}/${PACKAGE_NAME}"
|
||||||
|
local ARCHIVE_NAME="${PACKAGE_NAME}.zip"
|
||||||
|
|
||||||
|
clear
|
||||||
|
|
||||||
|
info "Cleaning binaries to rebuild..."
|
||||||
|
cargo clean
|
||||||
|
|
||||||
|
info "Building release binary for Windows..."
|
||||||
|
cargo build --release --target "$TARGET"
|
||||||
|
clear
|
||||||
|
success "Windows build finished"
|
||||||
|
|
||||||
|
info "Creating package directory..."
|
||||||
|
rm -rf "$PACKAGE_DIR"
|
||||||
|
mkdir -p "$PACKAGE_DIR"
|
||||||
|
success "Package directory ready: $PACKAGE_DIR"
|
||||||
|
|
||||||
|
info "Copying binary..."
|
||||||
|
cp "$OUT_DIR/${BIN_NAME}.exe" "$PACKAGE_DIR/"
|
||||||
|
success "Copied binary to package directory"
|
||||||
|
|
||||||
|
info "Creating archive..."
|
||||||
|
cd "$DIST_DIR"
|
||||||
|
zip -r "$ARCHIVE_NAME" "$PACKAGE_NAME"
|
||||||
|
cd -
|
||||||
|
success "Archive created: ${DIST_DIR}/${ARCHIVE_NAME}"
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ $# -ne 1 ]]; then
|
||||||
|
error "Usage: $0 [linux|windows]"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
linux)
|
||||||
|
build_linux
|
||||||
|
;;
|
||||||
|
windows)
|
||||||
|
build_windows
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
error "Unknown target: $1"
|
||||||
|
error "Usage: $0 [linux|windows]"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
|
@ -2,4 +2,4 @@
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub index_url: String,
|
pub index_url: String,
|
||||||
pub zip_bases: Vec<String>,
|
pub zip_bases: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,11 +4,25 @@ use colored::*;
|
||||||
pub struct Status;
|
pub struct Status;
|
||||||
|
|
||||||
impl Status {
|
impl Status {
|
||||||
pub fn info() -> ColoredString { "[*]".cyan() }
|
pub fn info() -> ColoredString {
|
||||||
pub fn success() -> ColoredString { "[+]".green() }
|
"[*]".cyan()
|
||||||
pub fn warning() -> ColoredString { "[!]".yellow() }
|
}
|
||||||
pub fn error() -> ColoredString { "[-]".red() }
|
pub fn success() -> ColoredString {
|
||||||
pub fn question() -> ColoredString { "[?]".blue() }
|
"[+]".green()
|
||||||
pub fn progress() -> ColoredString { "[→]".purple() }
|
}
|
||||||
pub fn matched() -> ColoredString { "[↓]".bright_purple() }
|
pub fn warning() -> ColoredString {
|
||||||
}
|
"[!]".yellow()
|
||||||
|
}
|
||||||
|
pub fn error() -> ColoredString {
|
||||||
|
"[-]".red()
|
||||||
|
}
|
||||||
|
pub fn question() -> ColoredString {
|
||||||
|
"[?]".blue()
|
||||||
|
}
|
||||||
|
pub fn progress() -> ColoredString {
|
||||||
|
"[→]".purple()
|
||||||
|
}
|
||||||
|
pub fn matched() -> ColoredString {
|
||||||
|
"[↓]".bright_purple()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::{io, path::Path};
|
|
||||||
use colored::Colorize;
|
|
||||||
use crate::config::status::Status;
|
use crate::config::status::Status;
|
||||||
|
use colored::Colorize;
|
||||||
|
use std::{io, path::Path};
|
||||||
|
|
||||||
pub fn print_results(success: usize, total: usize, folder: &Path) {
|
pub fn print_results(success: usize, total: usize, folder: &Path) {
|
||||||
let title = if success == total {
|
let title = if success == total {
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
use std::{fs::{self, OpenOptions}, io::Write, time::SystemTime};
|
use std::{
|
||||||
|
fs::{self, OpenOptions},
|
||||||
|
io::Write,
|
||||||
|
time::SystemTime,
|
||||||
|
};
|
||||||
|
|
||||||
pub fn setup_logging() -> fs::File {
|
pub fn setup_logging() -> fs::File {
|
||||||
OpenOptions::new()
|
OpenOptions::new()
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
pub mod console;
|
pub mod console;
|
||||||
pub mod file;
|
pub mod file;
|
||||||
pub mod logging;
|
pub mod logging;
|
||||||
pub mod util;
|
pub mod util;
|
||||||
|
|
|
@ -2,7 +2,11 @@ use colored::Colorize;
|
||||||
use reqwest::blocking::Client;
|
use reqwest::blocking::Client;
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use std::{
|
use std::{
|
||||||
fs::{self, File}, io::{self, Write}, sync::Arc, thread, time::{Duration, Instant}
|
fs::{self, File},
|
||||||
|
io::{self, Write},
|
||||||
|
sync::Arc,
|
||||||
|
thread,
|
||||||
|
time::{Duration, Instant},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(not(target_os = "windows"))]
|
||||||
|
@ -124,7 +128,7 @@ pub fn calculate_total_size(resources: &[Value], client: &Client, config: &Confi
|
||||||
|
|
||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(not(target_os = "windows"))]
|
||||||
Command::new("clear").status().unwrap();
|
Command::new("clear").status().unwrap();
|
||||||
|
|
||||||
total_size
|
total_size
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,10 +13,11 @@ use wuwa_downloader::{
|
||||||
io::{
|
io::{
|
||||||
console::print_results,
|
console::print_results,
|
||||||
file::get_dir,
|
file::get_dir,
|
||||||
util::{
|
|
||||||
calculate_total_size, download_resources, exit_with_error, setup_ctrlc, track_progress, start_title_thread
|
|
||||||
},
|
|
||||||
logging::setup_logging,
|
logging::setup_logging,
|
||||||
|
util::{
|
||||||
|
calculate_total_size, download_resources, exit_with_error, setup_ctrlc,
|
||||||
|
start_title_thread, track_progress,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
network::client::{fetch_index, get_config},
|
network::client::{fetch_index, get_config},
|
||||||
};
|
};
|
||||||
|
@ -90,7 +91,7 @@ fn main() {
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
clear().unwrap();
|
clear().unwrap();
|
||||||
|
|
||||||
print_results(
|
print_results(
|
||||||
success.load(std::sync::atomic::Ordering::SeqCst),
|
success.load(std::sync::atomic::Ordering::SeqCst),
|
||||||
resources.len(),
|
resources.len(),
|
||||||
|
|
|
@ -2,7 +2,7 @@ use colored::Colorize;
|
||||||
use flate2::read::GzDecoder;
|
use flate2::read::GzDecoder;
|
||||||
use indicatif::{ProgressBar, ProgressStyle};
|
use indicatif::{ProgressBar, ProgressStyle};
|
||||||
use reqwest::blocking::Client;
|
use reqwest::blocking::Client;
|
||||||
use serde_json::{Value, from_reader, from_str};
|
use serde_json::{from_reader, from_str, Value};
|
||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(not(target_os = "windows"))]
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use std::{
|
use std::{
|
||||||
|
@ -322,7 +322,6 @@ pub fn download_file(
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn download_single_file(
|
fn download_single_file(
|
||||||
client: &Client,
|
client: &Client,
|
||||||
url: &str,
|
url: &str,
|
||||||
|
@ -337,10 +336,8 @@ fn download_single_file(
|
||||||
.map_err(|e| format!("Metadata error: {}", e))?
|
.map_err(|e| format!("Metadata error: {}", e))?
|
||||||
.len();
|
.len();
|
||||||
}
|
}
|
||||||
|
|
||||||
let request = client
|
let request = client.get(url).timeout(DOWNLOAD_TIMEOUT);
|
||||||
.get(url)
|
|
||||||
.timeout(DOWNLOAD_TIMEOUT);
|
|
||||||
|
|
||||||
let request = if downloaded > 0 {
|
let request = if downloaded > 0 {
|
||||||
request.header("Range", format!("bytes={}-", downloaded))
|
request.header("Range", format!("bytes={}-", downloaded))
|
||||||
|
@ -356,18 +353,21 @@ fn download_single_file(
|
||||||
return Err("Range not satisfiable. File may already be fully downloaded.".into());
|
return Err("Range not satisfiable. File may already be fully downloaded.".into());
|
||||||
}
|
}
|
||||||
|
|
||||||
if !response.status().is_success() && response.status() != reqwest::StatusCode::PARTIAL_CONTENT {
|
if !response.status().is_success() && response.status() != reqwest::StatusCode::PARTIAL_CONTENT
|
||||||
|
{
|
||||||
return Err(format!("HTTP error: {}", response.status()));
|
return Err(format!("HTTP error: {}", response.status()));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut file = OpenOptions::new()
|
let mut file = OpenOptions::new()
|
||||||
.create(true)
|
.create(true)
|
||||||
.append(true)
|
.append(true)
|
||||||
.open(path)
|
.open(path)
|
||||||
.map_err(|e| format!("File error: {}", e))?;
|
.map_err(|e| format!("File error: {}", e))?;
|
||||||
|
|
||||||
pb.set_position(downloaded);
|
pb.set_position(downloaded);
|
||||||
progress.downloaded_bytes.store(downloaded, std::sync::atomic::Ordering::SeqCst);
|
progress
|
||||||
|
.downloaded_bytes
|
||||||
|
.store(downloaded, std::sync::atomic::Ordering::SeqCst);
|
||||||
|
|
||||||
let mut buffer = [0; BUFFER_SIZE];
|
let mut buffer = [0; BUFFER_SIZE];
|
||||||
loop {
|
loop {
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
pub mod client;
|
pub mod client;
|
||||||
|
|
Loading…
Reference in a new issue