Files
pack-util/src/main.rs
T
FantasyPvP 403e6ba087 started project
- packs can now be automatically zipped
- reads from config file but doesn't do anything with it yet
2023-09-01 02:31:27 +01:00

106 lines
4.0 KiB
Rust

use std::{fs, io::{self, Error, ErrorKind}, path::{Path, PathBuf}};
use zip::write::{FileOptions, ZipWriter};
use zip::CompressionMethod;
use walkdir::WalkDir;
use zip_archive::{Archiver, get_dir_list};
use num_cpus;
pub mod utils;
const PACK_REPO: &str = "./";
const RESOURCEPACKS: &str = "./_resourcepacks";
const IGNORE_FOLDERS_PREFIX: &str = "_";
fn main() {
let conf = utils::load_config().unwrap();
let pack_repo = PathBuf::from(PACK_REPO);
clear_resourcepacks().unwrap();
scan_directory(pack_repo).unwrap();
}
fn clear_resourcepacks() -> io::Result<()> {
println!("[removing existing packs]");
fs::remove_dir_all(RESOURCEPACKS)?;
fs::create_dir(RESOURCEPACKS)?;
println!(" => cleared resourcepacks folder");
Ok(())
}
fn scan_directory(path: PathBuf) -> io::Result<()> {
let mut pack_mcmeta = path.clone();
pack_mcmeta.push("pack.mcmeta");
if pack_mcmeta.exists() {
// if pack metadata exists, put the pack into a zip folder.
get_archive(path).map_err(|_| Error::new(ErrorKind::Other, "failed to archive zip"))?;
return Ok(())
} else {
// recursively scans subdirectories for other packs
for entry in fs::read_dir(path)? {
let entry = entry?;
if entry.path()
.file_name()
.unwrap()
.to_os_string()
.into_string()
.map_err(|_| Error::new(ErrorKind::Other, "failed to convert os_str to string"))?
.starts_with("_") {
println!("found _");
continue;
}
if let Some(zip_str) = entry.path().extension() {
if zip_str == "zip" {
fs::copy(entry.path(), format!("{}/{}", RESOURCEPACKS, entry.path().file_name().unwrap().to_os_string().into_string().map_err(|_| Error::new(ErrorKind::Other, "failed to convert os_str to string"))?))?;
}
}
if let Ok(file_type) = entry.file_type() {
if file_type.is_dir() {
scan_directory(entry.path())?;
}
}
}
}
Ok(())
}
fn get_archive(path: PathBuf) -> Result<(), Box<dyn std::error::Error>> {
println!("CREATING ARCHIVE: {}", &path.display());
if let Some(f) = path.file_stem() {
let mut filename = f.to_os_string().into_string().map_err(|_| Error::new(ErrorKind::Other, "failed to convert os_str to string"))?;
filename.push_str("_0");
loop {
if !Path::new(&format!("{}/{}.zip", RESOURCEPACKS, filename.to_string())).exists() { // checks if zip file already exists
let zip_file = fs::File::create(format!("{}/{}.zip", RESOURCEPACKS, filename))?;
let mut zip_writer = ZipWriter::new(zip_file);
let options = FileOptions::default()
.compression_method(CompressionMethod::Deflated)
.unix_permissions(0o755);
for entry in WalkDir::new(path.clone()).into_iter().filter_map(|e| e.ok()) {
let fpath = entry.path();
if fpath.is_file() {
let mut file = fs::File::open(fpath)?;
let relpath = fpath.strip_prefix(path.clone())?;
let mut zip_path = PathBuf::new();
zip_path.push(relpath);
zip_writer.start_file(zip_path.to_string_lossy().into_owned(), options)?;
std::io::copy(&mut file, &mut zip_writer)?;
}
}
zip_writer.finish()?;
break;
} else {
// 10 increments the last digit of the filename by 1
// TODO: add support for more than one digit
let i: u32 = filename.pop().unwrap().to_digit(10).unwrap();
filename.push(char::from_digit(i+1, 10).unwrap());
}
}
}
Ok(())
}