diff --git a/Cargo.lock b/Cargo.lock index d3502d0..6e7d274 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -101,6 +101,12 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + [[package]] name = "base64" version = "0.21.4" @@ -319,12 +325,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "data-encoding" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" - [[package]] name = "deranged" version = "0.3.9" @@ -345,13 +345,33 @@ dependencies = [ "subtle", ] +[[package]] +name = "dirs" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" +dependencies = [ + "dirs-sys 0.3.7", +] + [[package]] name = "dirs" version = "5.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" dependencies = [ - "dirs-sys", + "dirs-sys 0.4.1", +] + +[[package]] +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +dependencies = [ + "libc", + "redox_users", + "winapi", ] [[package]] @@ -363,7 +383,7 @@ dependencies = [ "libc", "option-ext", "redox_users", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -400,7 +420,7 @@ dependencies = [ "cfg-if", "libc", "redox_syscall 0.3.5", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -993,16 +1013,16 @@ dependencies = [ [[package]] name = "library-loader-core" -version = "0.5.0" +version = "0.4.0" dependencies = [ - "data-encoding", - "dirs", + "base64 0.13.1", + "dirs 4.0.0", "notify", "reqwest", "serde", - "shellexpand", + "shellexpand 2.1.2", "thiserror", - "toml", + "toml 0.5.11", "zip", ] @@ -1014,8 +1034,8 @@ dependencies = [ "library-loader-core", "regex", "serde", - "shellexpand", - "toml", + "shellexpand 3.1.0", + "toml 0.8.2", ] [[package]] @@ -1063,26 +1083,25 @@ dependencies = [ "libc", "log", "wasi", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] name = "notify" -version = "6.1.1" +version = "5.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6205bd8bb1e454ad2e27422015fb5e4f2bcc7e08fa8f27058670d208324a4d2d" +checksum = "729f63e1ca555a43fe3efa4f3efdf4801c479da85b432242a7b726f353c88486" dependencies = [ - "bitflags 2.4.1", + "bitflags 1.3.2", "crossbeam-channel", "filetime", "fsevent-sys", "inotify", "kqueue", "libc", - "log", "mio", "walkdir", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -1316,7 +1335,7 @@ version = "0.11.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" dependencies = [ - "base64", + "base64 0.21.4", "bytes", "encoding_rs", "futures-core", @@ -1398,7 +1417,7 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" dependencies = [ - "base64", + "base64 0.21.4", ] [[package]] @@ -1516,13 +1535,22 @@ dependencies = [ "digest", ] +[[package]] +name = "shellexpand" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ccc8076840c4da029af4f87e4e8daeb0fca6b87bbb02e10cb60b791450e11e4" +dependencies = [ + "dirs 4.0.0", +] + [[package]] name = "shellexpand" version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da03fa3b94cc19e3ebfc88c4229c49d8f08cdbd1228870a45f0ffdf84988e14b" dependencies = [ - "dirs", + "dirs 5.0.1", ] [[package]] @@ -1557,7 +1585,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1629,7 +1657,7 @@ dependencies = [ "cfg-expr", "heck", "pkg-config", - "toml", + "toml 0.8.2", "version-compare", ] @@ -1714,7 +1742,7 @@ dependencies = [ "num_cpus", "pin-project-lite", "socket2 0.5.4", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1741,6 +1769,15 @@ dependencies = [ "tracing", ] +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + [[package]] name = "toml" version = "0.8.2" @@ -2023,13 +2060,37 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + [[package]] name = "windows-sys" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets", + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", ] [[package]] @@ -2038,51 +2099,93 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", ] +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + [[package]] name = "windows_i686_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + [[package]] name = "windows_i686_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" @@ -2105,7 +2208,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ "cfg-if", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] diff --git a/ll-core/Cargo.toml b/ll-core/Cargo.toml index a5b455b..968c726 100644 --- a/ll-core/Cargo.toml +++ b/ll-core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "library-loader-core" -version = "0.5.0" +version = "0.4.0" authors = ["Edwin Svensson "] edition = "2021" publish = false @@ -9,11 +9,11 @@ publish = false [dependencies] serde = { version = "1", features = [ "derive" ] } -toml = "0.8" -notify = "6.0" -dirs = "5.0" +toml = "0.5" +notify = "5.0" +dirs = "4.0" thiserror = "1" reqwest = { version = "0.11", features = [ "blocking", "rustls-tls" ], default-features = false } zip = "0.6" -data-encoding = "2.4" -shellexpand = "3" +base64 = "0.13" +shellexpand = "2" diff --git a/ll-core/src/config/mod.rs b/ll-core/src/config/mod.rs index 8023fc7..ccaed0f 100644 --- a/ll-core/src/config/mod.rs +++ b/ll-core/src/config/mod.rs @@ -50,9 +50,8 @@ impl Config { pub(crate) fn formats(&self) -> Result> { let mut formats_vec = Vec::with_capacity(self.formats.len()); - for (name, f) in &self.formats { + for (_, f) in &self.formats { formats_vec.push(format::Format::from_ecad( - name, f.format.clone(), PathBuf::from(shellexpand::full(&f.output_path)?.as_ref()), )) @@ -62,7 +61,7 @@ impl Config { fn path(path: Option) -> Result { path.or(Self::default_path()) - .ok_or(Error::Other("Could not find config dir")) + .ok_or(Error::Other("Could not find config dir".into())) } pub fn default_path() -> Option { diff --git a/ll-core/src/config/profile.rs b/ll-core/src/config/profile.rs index 15ea14f..799adb6 100644 --- a/ll-core/src/config/profile.rs +++ b/ll-core/src/config/profile.rs @@ -15,7 +15,7 @@ pub struct Profile { impl Profile { pub fn token(&self) -> String { - data_encoding::BASE64.encode(format!("{}:{}", self.username, self.password).as_bytes()) + base64::encode(format!("{}:{}", self.username, self.password)) } pub fn is_empty(&self) -> bool { diff --git a/ll-core/src/cse/mod.rs b/ll-core/src/cse/mod.rs index 071223f..1ec179d 100644 --- a/ll-core/src/cse/mod.rs +++ b/ll-core/src/cse/mod.rs @@ -12,7 +12,6 @@ use { mod result; pub use result::Result; -#[allow(clippy::upper_case_acronyms)] pub struct CSE { auth: String, formats: Arc>, @@ -67,7 +66,7 @@ impl CSE { .replace("attachment;", "") .trim() .replace("filename=", "") - .replace('"', "") + .replace("\"", "") .trim() .to_string() } @@ -97,6 +96,8 @@ impl CSE { } fn unzip(&self, zip_filename: String, data: Vec) -> error::Result> { + let reader = std::io::Cursor::new(&data); + let mut archive = zip::ZipArchive::new(reader)?; let mut vec_results = Vec::with_capacity(self.formats.len()); for format in &*self.formats { @@ -112,10 +113,12 @@ impl CSE { true => zip_filename.as_str()[4..].replace(".zip", ""), false => zip_filename.replace(".zip", ""), }; - let reader = std::io::Cursor::new(&data); - let mut archive = zip::ZipArchive::new(reader)?; - let files = format.extract(&mut archive)?; - + let mut files = Files::new(); + for i in 0..archive.len() { + let mut item = archive.by_index(i)?; + let filename = item.name().to_string(); + format.extract(&mut files, filename, &mut item)?; + } let output_path = match format.create_folder { true => PathBuf::from(&format.output_path).join(lib_name), false => PathBuf::from(&format.output_path), diff --git a/ll-core/src/cse/result.rs b/ll-core/src/cse/result.rs index 8da7de4..f85669d 100644 --- a/ll-core/src/cse/result.rs +++ b/ll-core/src/cse/result.rs @@ -2,11 +2,16 @@ use { crate::error::{self, Error}, std::{ collections::HashMap, - fs, + fs::{self, File}, + io::{BufRead, BufReader, BufWriter, Write}, path::{Path, PathBuf}, + str, }, }; +static FOOTPRINT_FOLDER: &str = "LibraryLoader.pretty"; +static SYM_FILE: &str = "LibraryLoader.kicad_sym"; + pub struct Result { pub output_path: PathBuf, pub files: HashMap>, @@ -15,13 +20,65 @@ pub struct Result { impl Result { pub fn save(&self) -> error::Result { let save_dir = Path::new(&self.output_path); - - if !self.files.is_empty() { + let parent_dir = Path::new(save_dir.parent().unwrap()); + let collected_footprints = parent_dir.join(FOOTPRINT_FOLDER); + let collected_symbol = parent_dir.join(SYM_FILE); + if &self.files.len() > &0 { if !save_dir.exists() { fs::create_dir_all(save_dir)?; } - + if !collected_footprints.exists() { + fs::create_dir_all(collected_footprints.clone())?; + } + if !collected_symbol.exists() { + { + let data = "(kicad_symbol_lib (version ) (generator LibraryLoader)\n)"; + fs::write(parent_dir.join(SYM_FILE), data).expect("Unable to write file"); + } + } for (filename, data) in &self.files { + if filename.contains(".kicad_sym") { + let tmp_file = parent_dir.join(SYM_FILE.to_owned() + ".temp"); + { + let file: File = File::open(collected_symbol.clone()).unwrap(); + let out_file: File = File::create(tmp_file.clone()).unwrap(); + let reader = BufReader::new(&file); + let mut writer = BufWriter::new(&out_file); + let mut it = reader.lines().peekable(); + while let Some(line) = it.next() { + if it.peek().is_none() { + let s = match str::from_utf8(data) { + Ok(v) => v, + Err(e) => panic!("Invalid UTF-8 sequence {}", e), + }; + let mut itt = s.lines().peekable(); + while let Some(mline) = itt.next() { + if !itt.peek().is_none() + && !(mline.contains("kicad_symbol_lib") + || mline.contains("version") + || mline.contains("generator")) + { + writeln!(writer, "{}", mline).unwrap(); + } + } + writeln!(writer, ")").unwrap(); + } else { + writeln!(writer, "{}", line.unwrap()).unwrap(); + } + } + } + fs::rename(tmp_file.clone(), collected_symbol.clone()).unwrap(); + let _ = fs::remove_file(tmp_file); + } else if filename.contains(".kicad_mod") { + Self::write( + collected_footprints.join(format!( + "{}_{}", + save_dir.file_name().unwrap().to_str().unwrap(), + filename + )), + data.clone().to_vec(), + )?; + } let path = save_dir.join(filename); Self::write(path, data.to_vec())?; } @@ -39,7 +96,7 @@ impl Result { return Err(Error::WouldOverwrite); } - fs::write(&path, data)?; + fs::write(&path, &data)?; Ok(path) } } diff --git a/ll-core/src/epw.rs b/ll-core/src/epw.rs index 4ba38bf..c78e747 100644 --- a/ll-core/src/epw.rs +++ b/ll-core/src/epw.rs @@ -1,6 +1,6 @@ use { crate::error::{Error, Result}, - std::{collections::HashMap, ffi::OsStr, fs, io::Read, path::PathBuf}, + std::{collections::HashMap, ffi::OsStr, fs, io::Read, path::PathBuf, thread, time}, }; #[derive(Debug)] @@ -20,6 +20,9 @@ pub struct Epw { impl Epw { pub fn from_file>(path: S) -> Result { let p = path.into(); + while fs::metadata(p.clone())?.len() == 0 { + thread::sleep(time::Duration::from_millis(10)); + } let f_data = fs::read(&p)?; match Some(OsStr::new("zip")) == p.as_path().extension() { @@ -43,7 +46,7 @@ impl Epw { }; for line in lines { - let line_parts: Vec<&str> = line.split('=').collect(); + let line_parts: Vec<&str> = line.split("=").collect(); if line_parts.len() == 2 { map.insert(line_parts[0], line_parts[1]); @@ -51,7 +54,7 @@ impl Epw { } Ok(Self { - id, + id: id, mna: String::from(*map.get("mna").unwrap_or(&"")), mpn: String::from(*map.get("mpn").unwrap_or(&"")), pna: String::from(*map.get("pna").unwrap_or(&"")), @@ -82,7 +85,7 @@ impl Epw { fn from_zip(raw_data: Vec) -> Result { // The zip library crashes if the archive is empty, // lets prevent that. - if raw_data.is_empty() { + if raw_data.len() == 0 { return Err(Error::ZipArchiveEmpty); } diff --git a/ll-core/src/format/extractors/d3.rs b/ll-core/src/format/extractors/d3.rs new file mode 100644 index 0000000..2c486f9 --- /dev/null +++ b/ll-core/src/format/extractors/d3.rs @@ -0,0 +1,10 @@ +use super::*; + +pub fn extract( + format: &Format, + files: &mut Files, + file_path: String, + item: &mut ZipFile, +) -> Result<()> { + generic_extractor(format, files, file_path, item) +} diff --git a/ll-core/src/format/extractors/designspark.rs b/ll-core/src/format/extractors/designspark.rs new file mode 100644 index 0000000..2c486f9 --- /dev/null +++ b/ll-core/src/format/extractors/designspark.rs @@ -0,0 +1,10 @@ +use super::*; + +pub fn extract( + format: &Format, + files: &mut Files, + file_path: String, + item: &mut ZipFile, +) -> Result<()> { + generic_extractor(format, files, file_path, item) +} diff --git a/ll-core/src/format/extractors/eagle.rs b/ll-core/src/format/extractors/eagle.rs new file mode 100644 index 0000000..2c486f9 --- /dev/null +++ b/ll-core/src/format/extractors/eagle.rs @@ -0,0 +1,10 @@ +use super::*; + +pub fn extract( + format: &Format, + files: &mut Files, + file_path: String, + item: &mut ZipFile, +) -> Result<()> { + generic_extractor(format, files, file_path, item) +} diff --git a/ll-core/src/format/extractors/easyeda.rs b/ll-core/src/format/extractors/easyeda.rs new file mode 100644 index 0000000..2c486f9 --- /dev/null +++ b/ll-core/src/format/extractors/easyeda.rs @@ -0,0 +1,10 @@ +use super::*; + +pub fn extract( + format: &Format, + files: &mut Files, + file_path: String, + item: &mut ZipFile, +) -> Result<()> { + generic_extractor(format, files, file_path, item) +} diff --git a/ll-core/src/format/extractors/kicad.rs b/ll-core/src/format/extractors/kicad.rs index 622e452..2c486f9 100644 --- a/ll-core/src/format/extractors/kicad.rs +++ b/ll-core/src/format/extractors/kicad.rs @@ -1,87 +1,10 @@ use super::*; -use std::fs; -use std::fs::File; -use std::io::{BufRead, Cursor, Seek, SeekFrom, Write}; pub fn extract( format: &Format, - archive: &mut zip::ZipArchive>>, -) -> Result>> { - let fp_folder_str = format!("{}.pretty", format.name); - - //ensure we have the footprint library folder - let footprint_folder = PathBuf::from(&format.output_path).join(fp_folder_str.clone()); - if !footprint_folder.exists() { - fs::create_dir_all(footprint_folder.clone())?; - } - - //ensure the symbol library exists - let fn_lib = PathBuf::from(&format.output_path).join(format!("{}.kicad_sym", format.name)); - - if !fn_lib.exists() { - fs::write( - &fn_lib, - "(kicad_symbol_lib (version 20211014) (generator library-loader)\n)\n", - ) - .expect("Unable to create symbol library file"); - } - - let mut symbols: Vec = Vec::new(); - - for i in 0..archive.len() { - let mut item = archive.by_index(i)?; - let name = item.name(); - let path = PathBuf::from(name); - let base_name = path.file_name().unwrap().to_string_lossy().to_string(); - if let Some(ext) = &path.extension() { - match ext.to_str() { - //footprint and 3d files are copied first - Some("kicad_mod") | Some("stl") | Some("stp") | Some("wrl") => { - let mut f_data = Vec::::new(); - item.read_to_end(&mut f_data)?; - let mut f = File::create(footprint_folder.join(base_name))?; - f.write_all(&f_data)?; - } - Some("kicad_sym") => { - //save these to add later, so KiCad will be able to load the footprints right away - symbols.push(name.to_owned()); - } - _ => { - // ignore all other files - } - } - } - } - - let mut f = File::options().read(true).write(true).open(&fn_lib)?; - f.seek(SeekFrom::End(-2))?; - - for symbol_file in symbols { - let mut f_data = Vec::::new(); - let mut item = archive.by_name(&symbol_file)?; - item.read_to_end(&mut f_data)?; - let mut lines: Vec = (&f_data[..]) - .lines() - .map(|l| l.expect("Could not parse line")) - .collect(); - let end = &lines.len() - 1; - for i in 0..end { - //this is necessary to point symbols to correct footprint library - let parts = lines[i].split_whitespace().collect::>(); - if parts.len() >= 2 && parts[0] == "(property" && parts[1] == "\"Footprint\"" { - let footprint_name = &parts[2][1..(parts[2].len() - 1)]; - lines[i] = lines[i].replace( - footprint_name, - &format!("{}:{}", format.name, &footprint_name), - ); - } - } - for line in &lines[1..end] { - f.write_all(line.as_bytes())?; - f.write_all("\n".as_bytes())?; - } - } - f.write_all(")\n".as_bytes())?; - - Ok(Files::new()) + files: &mut Files, + file_path: String, + item: &mut ZipFile, +) -> Result<()> { + generic_extractor(format, files, file_path, item) } diff --git a/ll-core/src/format/extractors/mod.rs b/ll-core/src/format/extractors/mod.rs index 31cbe0a..c6f5f44 100644 --- a/ll-core/src/format/extractors/mod.rs +++ b/ll-core/src/format/extractors/mod.rs @@ -1,9 +1,13 @@ // * Keep these in alphabetical order +pub mod d3; +pub mod designspark; +pub mod eagle; +pub mod easyeda; pub mod kicad; -use std::io::Cursor; pub(super) use { std::{collections::HashMap, io::Read, path::PathBuf}, + zip::read::ZipFile, {super::Format, crate::error::Result}, }; @@ -11,29 +15,26 @@ pub type Files = HashMap>; pub(super) fn generic_extractor( format: &Format, - archive: &mut zip::ZipArchive>>, -) -> Result>> { - let mut files = Files::new(); - 'file_loop: for i in 0..archive.len() { - let mut item = archive.by_index(i)?; - let file_path = item.name().to_string(); - let file_path_lower = file_path.to_lowercase(); + files: &mut Files, + file_path: String, + item: &mut ZipFile, +) -> Result<()> { + let file_path_lower = file_path.to_lowercase(); - // Ignore files - for ignore in &format.ignore { - if file_path_lower.contains(ignore.to_lowercase().as_str()) { - continue 'file_loop; - } + // Ignore files + for ignore in &format.ignore { + if file_path_lower.contains(ignore.to_lowercase().as_str()) { + return Ok(()); } + } - if file_path_lower.contains(&format.match_path.to_lowercase()) { - let path = PathBuf::from(file_path); - let base_name = path.file_name().unwrap().to_string_lossy().to_string(); - let mut f_data = Vec::::new(); - item.read_to_end(&mut f_data)?; - files.insert(base_name, f_data); - } + if file_path_lower.contains(&format.match_path.to_lowercase()) { + let path = PathBuf::from(file_path); + let base_name = path.file_name().unwrap().to_string_lossy().to_string(); + let mut f_data = Vec::::new(); + item.read_to_end(&mut f_data)?; + files.insert(base_name, f_data); } - Ok(files) + Ok(()) } diff --git a/ll-core/src/format/mod.rs b/ll-core/src/format/mod.rs index 0b3535f..403f5e0 100644 --- a/ll-core/src/format/mod.rs +++ b/ll-core/src/format/mod.rs @@ -1,13 +1,11 @@ -use std::collections::HashMap; -use std::io::Cursor; use { crate::error::{Error, Result}, serde::{Deserialize, Serialize}, std::{fmt, path::PathBuf}, + zip::read::ZipFile, }; mod extractors; -use crate::format::extractors::generic_extractor; pub use extractors::Files; macro_rules! ecad { @@ -62,7 +60,7 @@ ecad!([ #[derive(Debug, Clone, PartialEq)] pub struct Format { pub output_path: PathBuf, - pub name: String, + // pub name: String, pub ecad: ECAD, pub create_folder: bool, match_path: &'static str, @@ -70,56 +68,66 @@ pub struct Format { } impl Format { - pub fn from_ecad>(name: &String, ecad: ECAD, output_path: P) -> Self { - //defaults - let mut fmt = Self { - output_path: output_path.into(), - name: (*name).clone(), - ecad, - create_folder: false, - match_path: "", - ignore: vec![], - }; - // specific overrides, keep these in alphabetical order - match fmt.ecad { - ECAD::D3 => { - fmt.create_folder = true; - fmt.match_path = "3D"; - } - ECAD::DesignSpark => { - fmt.match_path = "DesignSpark PCB"; - } - ECAD::Eagle => { - fmt.match_path = "EAGLE"; - fmt.ignore = vec!["Readme.html"]; - } - ECAD::EasyEDA => { - fmt.match_path = "EasyEDA"; - fmt.ignore = vec!["Readme.html"]; - } - ECAD::KiCad => { - fmt.match_path = "KiCad"; - } - ECAD::Zip => { - //no changes - } + pub fn from_ecad>(ecad: ECAD, output_path: P) -> Self { + // * Keep these in alphabetical order + match ecad { + ECAD::D3 => Self { + output_path: output_path.into(), + ecad, + create_folder: true, + match_path: "3D", + ignore: vec![], + }, + ECAD::DesignSpark => Self { + output_path: output_path.into(), + ecad, + create_folder: false, + match_path: "DesignSpark PCB", + ignore: vec![], + }, + ECAD::Eagle => Self { + output_path: output_path.into(), + ecad, + create_folder: false, + match_path: "EAGLE", + ignore: vec!["Readme.html"], + }, + ECAD::EasyEDA => Self { + output_path: output_path.into(), + ecad, + create_folder: false, + match_path: "EasyEDA", + ignore: vec!["Readme.html"], + }, + ECAD::KiCad => Self { + output_path: output_path.into(), + ecad, + create_folder: true, + match_path: "KiCad", + ignore: vec![], + }, + ECAD::Zip => Self { + output_path: output_path.into(), + ecad, + create_folder: false, + match_path: "", + ignore: vec![], + }, } - - fmt } - pub fn extract( - &self, - archive: &mut zip::ZipArchive>>, - ) -> Result>> { - Ok(match &self.ecad { + pub fn extract(&self, files: &mut Files, file_path: String, item: &mut ZipFile) -> Result<()> { + match &self.ecad { // * Keep these in alphabetical order - ECAD::D3 | ECAD::DesignSpark | ECAD::Eagle | ECAD::EasyEDA => { - generic_extractor(self, archive)? - } - ECAD::KiCad => extractors::kicad::extract(self, archive)?, + ECAD::D3 => extractors::d3::extract(&self, files, file_path, item)?, + ECAD::DesignSpark => extractors::designspark::extract(&self, files, file_path, item)?, + ECAD::Eagle => extractors::eagle::extract(&self, files, file_path, item)?, + ECAD::EasyEDA => extractors::easyeda::extract(&self, files, file_path, item)?, + ECAD::KiCad => extractors::kicad::extract(&self, files, file_path, item)?, ECAD::Zip => unreachable!("ZIP not handled!"), // ! NOTE: DO NOT ADD A _ => {} CATCHER HERE! - }) + }; + + Ok(()) } } diff --git a/ll-core/src/updates/mod.rs b/ll-core/src/updates/mod.rs index 7aababf..345ddfd 100644 --- a/ll-core/src/updates/mod.rs +++ b/ll-core/src/updates/mod.rs @@ -1,5 +1,6 @@ use { crate::{consts, error::Result}, + reqwest, serde::Deserialize, }; @@ -23,7 +24,7 @@ pub struct UpdateInfo<'l, 'u> { pub url: &'u str, } -pub fn check(local_version: &str, kind: ClientKind) -> Result> { +pub fn check<'l>(local_version: &'l str, kind: ClientKind) -> Result> { let url = format!( "https://raw.githubusercontent.com/olback/library-loader/master/{kind}/Cargo.toml", kind = kind diff --git a/ll-core/src/watcher/mod.rs b/ll-core/src/watcher/mod.rs index 1e31e42..b014b82 100644 --- a/ll-core/src/watcher/mod.rs +++ b/ll-core/src/watcher/mod.rs @@ -63,46 +63,48 @@ impl Watcher { match rx.recv() { Ok(WatcherEvent::NotifyResult(Ok(event))) => { // log_info!(&*loggers, format!("{:#?}", event)); - - if let NotifyEventKind::Create(NotifyCreateKind::File) = event.kind { - // println!("evt: {:#?}", event); - for file in event.paths { - if file.extension().map(|e| e.to_ascii_lowercase()) - == Some(OsString::from("zip")) - { - log_info!(&*loggers, format!("Detected {:?}", file)); - let token = token.clone(); - let formats = Arc::clone(&formats); - let loggers_clone = Arc::clone(&loggers); - // uuuh - std::thread::sleep(std::time::Duration::from_millis(100)); - match (move || -> Result<()> { - let epw = Epw::from_file(file)?; - for res in CSE::new(token, formats).get(epw)? { - match res.save() { - Ok(save_path) => { - log_info!( - &*loggers_clone, - format!("Saved to {:?}", save_path) - ) - } - Err(e) => { - log_error!(&*loggers_clone, e) + match event.kind { + NotifyEventKind::Create(NotifyCreateKind::File) => { + // println!("evt: {:#?}", event); + for file in event.paths { + if file.extension().map(|e| e.to_ascii_lowercase()) + == Some(OsString::from("zip")) + { + log_info!(&*loggers, format!("Detected {:?}", file)); + let token = token.clone(); + let formats = Arc::clone(&formats); + let loggers_clone = Arc::clone(&loggers); + // uuuh + std::thread::sleep(std::time::Duration::from_millis(100)); + match (move || -> Result<()> { + let epw = Epw::from_file(file)?; + for res in CSE::new(token, formats).get(epw)? { + match res.save() { + Ok(save_path) => { + log_info!( + &*loggers_clone, + format!("Saved to {:?}", save_path) + ) + } + Err(e) => { + log_error!(&*loggers_clone, e) + } } } - } - Ok(()) - })() { - Ok(()) => { - log_info!(&*loggers, "Done"); - } - Err(e) => { - log_error!(&*loggers, format!("{:?}", e)); + Ok(()) + })() { + Ok(()) => { + log_info!(&*loggers, "Done"); + } + Err(e) => { + log_error!(&*loggers, format!("{:?}", e)); + } } } } + // log_info!(&*loggers, format!("{:#?}", event)); } - // log_info!(&*loggers, format!("{:#?}", event)); + _ => {} } } Ok(WatcherEvent::NotifyResult(Err(error))) => { @@ -143,14 +145,17 @@ impl Watcher { } pub fn stop(&mut self) { - if let Some((jh, tx, mut w)) = self.thread.take() { - log_if_error!(&*self.loggers, w.unwatch(self.watch_path.as_path())); - log_if_error!(&*self.loggers, tx.send(WatcherEvent::Stop)); - log_if_error!(&*self.loggers, jh.join()); - log_info!( - &*self.loggers, - format!("Stopped watching {:?}", self.watch_path) - ); + match self.thread.take() { + Some((jh, tx, mut w)) => { + log_if_error!(&*self.loggers, w.unwatch(self.watch_path.as_path())); + log_if_error!(&*self.loggers, tx.send(WatcherEvent::Stop)); + log_if_error!(&*self.loggers, jh.join()); + log_info!( + &*self.loggers, + format!("Stopped watching {:?}", self.watch_path) + ); + } + None => {} } } }