mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-26 10:47:11 -06:00
Merge pull request #3003 from nrq6993-a11y/stream/vc-issue-2996-acb-filename
Fix #2996: color books copy to user folder under book title
This commit is contained in:
@@ -272,7 +272,14 @@ impl<L: LibraryFile> Libraries<L> {
|
||||
.map(|e| (e.path.clone(), e.lib.clone()))
|
||||
.ok_or_else(|| bad(cmd, format!("`{id}` isn't a loaded library")))?;
|
||||
let (file, bytes) = match source.filter(|p| L::EXTS.contains(&extension(p).as_str())) {
|
||||
Some(p) => (file_name(&p), read_file(&p)?),
|
||||
Some(p) => {
|
||||
let ext = extension(&p);
|
||||
let base = file_name(&p);
|
||||
// Color books (.acb) name the tab from the book title inside the file; a sandbox
|
||||
// copy of an import often lands as tmp….tmp.acb (#2996).
|
||||
let file = if ext == "acb" || temporary_library_file_name(&base) { library_file_name(lib.name(), &ext) } else { base };
|
||||
(file, read_file(&p)?)
|
||||
}
|
||||
None => (library_file_name(lib.name(), ext), encode(&lib)?),
|
||||
};
|
||||
self.rescan();
|
||||
@@ -302,6 +309,12 @@ impl<L: LibraryFile> Libraries<L> {
|
||||
}
|
||||
}
|
||||
|
||||
/// A library file name that looks like a host temporary (e.g. macOS `tmp1F2C.tmp.acb`).
|
||||
fn temporary_library_file_name(name: &str) -> bool {
|
||||
let lower = name.to_ascii_lowercase();
|
||||
lower.contains(".tmp.")
|
||||
}
|
||||
|
||||
/// The file name of library `name` with extension `ext`: characters file systems reject become
|
||||
/// `-`, and dots and spaces at either end are dropped. A name with nothing left is `Library`.
|
||||
pub fn library_file_name(name: &str, ext: &str) -> String {
|
||||
|
||||
@@ -392,6 +392,50 @@ fn loaded_libraries_copy_into_the_user_folder_without_replacing_files() {
|
||||
let _ = std::fs::remove_dir_all(dir);
|
||||
}
|
||||
|
||||
/// A color book opened from a host temporary path (macOS sandbox copies) is stored under its title
|
||||
/// when copied into the user library folder (#2996).
|
||||
#[test]
|
||||
fn copying_a_color_book_from_a_temporary_path_uses_its_title() {
|
||||
fn acb_str(out: &mut Vec<u8>, s: &str) {
|
||||
let units: Vec<u16> = s.encode_utf16().collect();
|
||||
out.extend((units.len() as u32).to_be_bytes());
|
||||
units.iter().for_each(|u| out.extend(u.to_be_bytes()));
|
||||
}
|
||||
let mut bytes = b"8BCB".to_vec();
|
||||
bytes.extend(1u16.to_be_bytes());
|
||||
bytes.extend(3000u16.to_be_bytes());
|
||||
for s in ["$$$/colorbook/Test/title=Test Book^R", "TEST ", " C", "a book"] {
|
||||
acb_str(&mut bytes, s);
|
||||
}
|
||||
bytes.extend(1u16.to_be_bytes());
|
||||
bytes.extend(7u16.to_be_bytes());
|
||||
bytes.extend(0u16.to_be_bytes());
|
||||
bytes.extend(0u16.to_be_bytes());
|
||||
acb_str(&mut bytes, "185");
|
||||
bytes.extend(b"TST001");
|
||||
bytes.extend([228, 0, 43]);
|
||||
bytes.extend(b"spflspot");
|
||||
|
||||
let dir = temp_dir("acb-temp");
|
||||
let user = dir.join("user");
|
||||
let elsewhere = dir.join("elsewhere");
|
||||
std::fs::create_dir_all(&user).unwrap();
|
||||
std::fs::create_dir_all(&elsewhere).unwrap();
|
||||
let source = elsewhere.join("tmp1F2C.tmp.acb");
|
||||
std::fs::write(&source, &bytes).unwrap();
|
||||
let source = source.to_string_lossy().to_string();
|
||||
|
||||
let mut s = session();
|
||||
s.swatch_libraries.set_user_dir(Some(user.to_string_lossy().to_string()));
|
||||
let loaded = run(&mut s, "swatch.library.load", json!({ "path": source }))["library"].clone();
|
||||
assert_eq!(run(&mut s, "swatch.library.get", json!({ "library": loaded }))["name"], "Test Book®");
|
||||
let r = run(&mut s, "swatch.library.copyToUser", json!({ "library": loaded }));
|
||||
assert_eq!((r["library"].as_str(), r["name"].as_str(), r["copied"].as_bool()), (Some("user/Test Book®.acb"), Some("Test Book®"), Some(true)));
|
||||
assert_eq!(r["path"], user.join("Test Book®.acb").to_string_lossy().to_string());
|
||||
assert_eq!(std::fs::read(user.join("Test Book®.acb")).unwrap(), bytes);
|
||||
let _ = std::fs::remove_dir_all(dir);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_library_group_stays_one_group_when_a_swatch_has_its_name() {
|
||||
use vectorcraft_testkit::ase::{Block, ase};
|
||||
|
||||
Reference in New Issue
Block a user