From b1107a79738af21a64bce9d97a89d25220ea1868 Mon Sep 17 00:00:00 2001
From: FantasyPvP <80643031+FantasyPvP@users.noreply.github.com>
Date: Tue, 19 Mar 2024 00:31:11 +0000
Subject: [PATCH] .
.
---
Cargo.lock | 11 ++
Cargo.toml | 1 +
_v2/.idea/workspace.xml | 118 ++++++++++++++
src/cli.rs | 351 ++++++++++++++++++++--------------------
4 files changed, 303 insertions(+), 178 deletions(-)
create mode 100644 _v2/.idea/workspace.xml
diff --git a/Cargo.lock b/Cargo.lock
index 813159e..30ef881 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -102,6 +102,16 @@ dependencies = [
"inout",
]
+[[package]]
+name = "colored"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8"
+dependencies = [
+ "lazy_static",
+ "windows-sys",
+]
+
[[package]]
name = "constant_time_eq"
version = "0.1.5"
@@ -392,6 +402,7 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
name = "pack_sync"
version = "0.1.0"
dependencies = [
+ "colored",
"dirs",
"num_cpus",
"serde",
diff --git a/Cargo.toml b/Cargo.toml
index 9422898..e021b97 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -14,6 +14,7 @@ path = "src/server.rs"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
+colored = "2.1.0"
dirs = "5.0.1"
num_cpus = "1.16.0"
serde = { version = "1.0.188", features = ["derive"] }
diff --git a/_v2/.idea/workspace.xml b/_v2/.idea/workspace.xml
new file mode 100644
index 0000000..6968fad
--- /dev/null
+++ b/_v2/.idea/workspace.xml
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {
+ "associatedIndex": 5
+}
+
+
+
+
+
+ {
+ "keyToString": {
+ "ASKED_SHARE_PROJECT_CONFIGURATION_FILES": "true",
+ "Cargo.Run Cli.executor": "Run",
+ "Cargo.Run.executor": "Run",
+ "RunOnceActivity.OpenProjectViewOnStart": "true",
+ "RunOnceActivity.ShowReadmeOnStart": "true",
+ "RunOnceActivity.rust.reset.selective.auto.import": "true",
+ "SHARE_PROJECT_CONFIGURATION_FILES": "true",
+ "git-widget-placeholder": "master",
+ "last_opened_file_path": "/home/fantasypvp/Everything else/packs/_pack_sync/_v2",
+ "node.js.detected.package.eslint": "true",
+ "node.js.detected.package.tslint": "true",
+ "node.js.selected.package.eslint": "(autodetect)",
+ "node.js.selected.package.tslint": "(autodetect)",
+ "nodejs_package_manager_path": "npm",
+ "org.rust.cargo.project.model.PROJECT_DISCOVERY": "true",
+ "org.rust.cargo.project.model.impl.CargoExternalSystemProjectAware.subscribe.first.balloon": "",
+ "settings.editor.selected.configurable": "preferences.lookFeel",
+ "vue.rearranger.settings.migration": "true"
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1710716737984
+
+
+ 1710716737984
+
+
+
+
+
+
+
+
+
+
+ 1710759220133
+
+
+
+ 1710759220133
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/cli.rs b/src/cli.rs
index 92a23ff..ee0c18a 100644
--- a/src/cli.rs
+++ b/src/cli.rs
@@ -1,13 +1,13 @@
-
-
use num_cpus;
use std::{
fs::{self, OpenOptions},
- io::{self, Error, ErrorKind, Write},
+ io::{self, Error, ErrorKind, Write, Read},
path::{Path, PathBuf},
+ collections::HashMap,
+ slice::SliceIndex
};
-use std::collections::HashMap;
-use std::slice::SliceIndex;
+use colored::Colorize;
+
use tracing::{event, info, span, Level, warn, error};
use tracing_subscriber::{
filter::{EnvFilter, LevelFilter},
@@ -16,10 +16,11 @@ use tracing_subscriber::{
};
use toml;
-
use walkdir::WalkDir;
-use zip::write::{FileOptions, ZipWriter};
-use zip::CompressionMethod;
+use zip::{
+ CompressionMethod, ZipArchive,
+ write::{FileOptions, ZipWriter}
+};
use zip_archive::{get_dir_list, Archiver};
@@ -36,7 +37,7 @@ fn main() {
)
.with(
EnvFilter::builder()
- .with_default_directive(LevelFilter::DEBUG.into())
+ .with_default_directive(LevelFilter::WARN.into())
.from_env_lossy(),
)
.init();
@@ -54,11 +55,27 @@ fn clear_resourcepacks(conf: &Config) -> io::Result<()> {
let span = span!(Level::INFO, "clear_packs");
let _guard = span.enter();
- info!("Clearing existing resourcepacks folder");
+ conf.versions.iter().for_each(|(k, v)| {
+ if let Some(folder) = v.resourcepacks.clone() {
+ match fs::remove_dir_all(&folder) {
+ Ok(_) => {}
+ Err(e) => warn!("No existing packs folder detected for version. Creating new folder."),
+ }
+ match fs::create_dir(&folder) {
+ Ok(_) => {}
+ Err(e) => {
+ error!("{}", e);
+ return;
+ }
+ };
+ }
+ });
+
match fs::remove_dir_all(&conf.resourcepacks) {
Ok(_) => {}
- Err(e) => warn!("No existing packs folder detected. Creating new folder."),
+ Err(e) => warn!("No existing global packs folder detected. Creating new folder."),
};
+
match fs::create_dir(&conf.resourcepacks) {
Ok(_) => {}
Err(e) => {
@@ -66,35 +83,62 @@ fn clear_resourcepacks(conf: &Config) -> io::Result<()> {
return Err(e);
}
};
- info!("Successfully reset resourcepacks folder");
Ok(())
}
fn search_dir(path: &PathBuf, config: &Config) -> io::Result<()> {
- let span = span!(Level::INFO, "Searching for packs");
+ let span = span!(Level::INFO, "Searching");
let _guard = span.enter();
// info!("Searching for packs in {}", path.display());
// check if file is a valid pack
- if path.clone().join("pack.toml").exists() {
- println!("Found pack {}", path.display());
- Pack::load(&path).unwrap().archive(&path, config).unwrap();
- return Ok(());
- } else {
- println!("1c| {}", path.display());
-
- for entry in WalkDir::new(path.clone())
- .into_iter()
- .filter_map(|e| e.ok())
- .filter(|e| e.file_type().is_dir() && e.file_name() != path)
- .filter(|e| !e.file_name().to_str().unwrap().to_string().contains("/_"))
- {
- println!("PATH {}", entry.path().join(entry.file_name()).to_str().unwrap());
- // search_dir(&entry.path().join(entry.file_name()).to_path_buf(), config).unwrap();
- }
- }
+ println!("{}", "\nArchiving Packs...".blue().underline());
+ WalkDir::new(path.clone())
+ .into_iter()
+ .filter_map(|e| e.ok())
+ .filter(|e| !e.path().to_str().unwrap().contains("/_"))
+ .filter(|e| e.file_name().to_str().unwrap() == "pack.toml")
+ .for_each(|entry| {
+ if let Ok(pack) = Pack::from_path(&entry.path().to_path_buf()) {
+ println!(" {} {} {} : {}", "̯".blue(), "Found".green(), entry.path().to_str().unwrap(), pack.name);
+ pack.archive( &mut entry.path().to_path_buf(), config).unwrap();
+ }
+ });
+ println!("{}", " ȯ Done!".blue());
+ println!("{}", "\nChecking for existing zip files...".blue().underline());
+ WalkDir::new(path.clone())
+ .into_iter()
+ .filter_map(|e| e.ok())
+ .filter(|e| !e.path().to_str().unwrap().contains("/_"))
+ .filter(|e| e.file_name().to_str().unwrap().ends_with(".zip"))
+ .for_each(|entry| {
+ if let Ok(file) = std::fs::File::open(&entry.path().to_path_buf()) {
+ if let Ok(mut archive) = ZipArchive::new(file) {
+ if let Ok(mut pack_config) = archive.by_name("pack.toml") {
+ if let Ok(pack) = Pack::from_string({
+ let mut buff = String::new();
+ pack_config.read_to_string(&mut buff).unwrap();
+ buff
+ }) {
+ println!(" {} {} {} : {}", "̯".blue(), "Found".green(), entry.path().display(), pack.name);
+ if pack.release {
+ pack.move_archive(&mut entry.path().to_path_buf(), config).unwrap()
+ }
+ }
+ } else {
+ println!(" {} {} {}", "̯".blue(), "Found".green(), entry.path().display());
+ if !fs::read_dir(&config.resourcepacks).unwrap().any(|f| f.unwrap().file_name().to_str().unwrap() == format!("{}.zip", entry.file_name().to_str().unwrap()).as_str()) {
+ fs::copy(entry.path(), format!("{}/{}", &config.resourcepacks, entry.file_name().to_str().unwrap())).unwrap();
+ } else {
+ println!(" {} {}", "║".blue(), " File Already Exists: Ignoring".yellow());
+ }
+ }
+ }
+ }
+ });
+ println!("{}", " ȯ Done!".blue());
Ok(())
}
@@ -107,56 +151,117 @@ struct Pack {
name: String,
version: String,
description: String,
- packs: HashMap,
+ packs: Option>,
}
impl Pack {
- fn load(path: &PathBuf) -> io::Result {
+ fn from_path(path: &PathBuf) -> io::Result {
+ let pack_config = fs::read_to_string(path).unwrap();
+ Pack::from_string(pack_config)
+ }
+
+ fn from_string(pack_config: String) -> io::Result {
let span = span!(Level::INFO, "Loading Pack Config file");
let _guard = span.enter();
- let contents = fs::read_to_string(path.join("pack.toml"))?;
- let pack = toml::from_str::(&contents).map_err(|e| Error::new(ErrorKind::Other, e))?;
-
- Ok(pack)
+ toml::from_str::(&pack_config).map_err(|e| Error::new(ErrorKind::Other, e))
}
- fn archive(&self, path: &PathBuf, config: &Config) -> Result<(), Box> {
- let span = span!(Level::INFO, "Archiving Pack");
+ fn archive(
+ &self, // pack config
+ path: &mut PathBuf, // the path to the pack in the filesystem
+ config: &Config // global config for pack sync
+ ) -> Result<(), Box> {
+ let span = span!(Level::INFO, "Archiving Pack ");
let _guard = span.enter();
- let resourcepacks = if config.versions.contains_key(&self.version) {
+ path.pop();
+
+ if self.packs.is_none() {
+ return Ok(())
+ }
+ for (k, v) in self.packs.clone().unwrap().iter() {
+ if v.release {
+ println!(" {} {} : {}", "╠════»".blue(), "Archiving Version".green(), k);
+ let zip_file = fs::File::create(format!("{}/{}-{}.zip", self.output_folder(config), self.name, k))?;
+ 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())
+ .filter(|e| {
+ if v.prefix == "" { // for the "global" instance of the pack / base pack
+ // ignoring all files that contain a . in the file stem as these are not global textures
+ !e.path().file_stem().expect("unable to get file stem").to_str().unwrap().contains(".")
+ } else {
+ e.path().file_stem().expect("unable to get file stem").to_str().unwrap().starts_with(format!("{}.", v.prefix).as_str())
+ }
+ })
+ .filter(|e| e.file_name().to_str().unwrap() != "pack.toml")
+ {
+ let file_path = entry.path();
+
+ if file_path.is_file() {
+ let mut file = fs::File::open(file_path)?;
+ let relpath = file_path.strip_prefix(path.clone())?;
+ let mut zip_path = PathBuf::new();
+
+ if v.prefix == "" {
+ zip_path.push(relpath);
+ } else {
+ let dir = relpath.parent().unwrap();
+ let filename = relpath
+ .file_name()
+ .unwrap()
+ .to_str()
+ .unwrap()
+ .to_string()
+ .strip_prefix(format!("{}.", v.prefix).as_str())
+ .unwrap()
+ .to_string();
+ let final_path = dir.join(filename);
+ zip_path.push(final_path);
+ }
+
+ zip_writer.start_file(zip_path.to_string_lossy().into_owned(), options)?;
+ std::io::copy(&mut file, &mut zip_writer)?;
+ }
+ }
+
+ zip_writer.finish()?;
+ } else {
+ println!(" {} {} : {}", "╠════»".blue(), "Ignoring Version ".yellow(), k);
+ }
+ };
+
+
+ Ok(())
+ }
+
+ fn output_folder(&self, config: &Config) -> String {
+ if config.versions.contains_key(&self.version) {
match config.versions.get(&self.version).unwrap().resourcepacks.clone() {
Some(folder) => folder,
None => config.resourcepacks.clone()
}
} else {
config.resourcepacks.clone()
- };
- let zip_file = fs::File::create(format!("{}/{}.zip", resourcepacks, self.name))?;
- 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 file_path = entry.path();
- if file_path.is_file() {
- let mut file = fs::File::open(file_path)?;
- let relpath = file_path.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()?;
+ }
+ fn move_archive(&self, path: &PathBuf, config: &Config) -> io::Result<()> {
+ let span = span!(Level::INFO, "Moving Pack");
+ let _guard = span.enter();
+
+ if !fs::read_dir(self.output_folder(config)).unwrap().any(|f| f.unwrap().file_name().to_str().unwrap() == format!("{}.zip",self.name).as_str()) {
+ fs::copy(path, format!("{}/{}.zip", self.output_folder(config), self.name))?;
+ } else {
+ println!(" {} {}", "║".blue(), " File Already Exists: Ignoring".yellow());
+ }
Ok(())
}
}
@@ -168,110 +273,6 @@ struct PackComponent {
release: bool,
}
-//
-// fn scan_directory(path: PathBuf, config: &Config) -> 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, config).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!(
-// "{}/{}",
-// config.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(), &config)?;
-// }
-// }
-// }
-// }
-// Ok(())
-// }
-//
-// fn get_archive(path: PathBuf, config: &Config) -> Result<(), Box> {
-// 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", config.resourcepacks, filename.to_string())).exists() {
-// // checks if zip file already exists
-// let zip_file = fs::File::create(format!("{}/{}.zip", config.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 file_path = entry.path();
-// if file_path.is_file() {
-// let mut file = fs::File::open(file_path)?;
-// let relpath = file_path.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(())
-// }
-
-
#[derive(Debug, Deserialize, Serialize)]
pub struct VersionConfig {
pub pack_repo: Option,
@@ -308,16 +309,10 @@ impl Config {
if conf_path.exists() {
let config: Config = toml::from_str(fs::read_to_string(&conf_path)?.as_str())
.map_err(|_| Error::new(ErrorKind::Other, "failed to deserialise"))?;
- info!(
- "Loaded Config File: \n\trepo: {}\n\tpacks folder: {}\n\tignore with prefix: {}",
- config.repository, config.resourcepacks, config.ignore_folder_prefix
- );
+ info!("Loaded Config File: \n\trepo: {}\n\tpacks folder: {}\n\tignore with prefix: {}", config.repository, config.resourcepacks, config.ignore_folder_prefix);
Ok(config)
} else {
- warn!(
- "No config file detected. Creating config file with default values at:\n\t{}",
- conf_path.display()
- );
+ warn!("No config file detected. Creating config file with default values at:\n\t{}", conf_path.display());
create_config_file(&conf_path)?;
Ok(Config::default())
}
@@ -326,21 +321,21 @@ impl Config {
fn path() -> Option {
Some(PathBuf::from(".").join("config.toml"))
}
+
#[cfg(not(debug_assertions))]
fn path() -> Option {
- dirs::config_dir()?.join("pack_sync").join("config.toml")
+ Some(dirs::config_dir()?.join("pack_sync").join("config.toml"))
}
}
-
fn create_config_file(path: &PathBuf) -> Result<(), Error> {
println!("{}", path.display());
fs::create_dir_all(path.parent().unwrap())?;
fs::File::create(path)?;
- let yaml = serde_yaml::to_string(&Config::default())
+ let output = toml::to_string(&Config::default())
.map_err(|_| Error::new(ErrorKind::Other, "failed to serialise"))?;
let mut file = OpenOptions::new()
@@ -348,7 +343,7 @@ fn create_config_file(path: &PathBuf) -> Result<(), Error> {
.create(true)
.truncate(true)
.open(path)?
- .write_all(yaml.as_bytes())?;
+ .write_all(output.as_bytes())?;
Ok(())
}
\ No newline at end of file