Skip to content

Instantly share code, notes, and snippets.

@psmay
Last active August 2, 2016 20:26
Show Gist options
  • Save psmay/63d70f99f86ec603b5e96d4c4c96c029 to your computer and use it in GitHub Desktop.
Save psmay/63d70f99f86ec603b5e96d4c4c96c029 to your computer and use it in GitHub Desktop.
Script that unpacks Fritzing part fzpz files and replaces their 128-bit hex nonce with one newly generated by uuidgen. Useful for preventing name collisions when creating a modified copy of an existing part.
FZPZ="$1"
die () {
echo "$1" >&2
exit 2
}
die_if_blank () {
if [ "-$1-" = "--" ]; then
die "$2"
fi
}
log () {
echo "$1" >&2
}
if [ "-$FZPZ-" = "--" ]; then
die "Missing fzpz parameter"
fi
get_module_id() {
part_file="$1"
xmllint --xpath 'string(/module/@moduleId)' "$part_file"
}
generate_nonce() {
uuidgen | perl -pe 's/-//g;'
}
extract_nonce() {
get_module_id "$1" |
perl -nE '
/^.*(?<![[:alnum:]])([0-9A-Fa-f]{32})(?![[:alnum:]]).*?$/
and print $1
'
}
extract_base_name() {
old_nonce="$1"
file="$2"
get_module_id "$2" |
perl -nE '
$old_nonce=q/'"$old_nonce"'/;
if( /^(.*)_$old_nonce/ or /^(.*)$old_nonce/ ) {
print $1;
}
'
}
TMPDIR="`mktemp -d`" &&
PARTDIR="$TMPDIR/part" &&
log "Extracting to '$PARTDIR'" &&
unzip "$FZPZ" -d "$PARTDIR" &&
log "Attempting to guess original nonce" &&
OLD_NONCE="`extract_nonce "$PARTDIR"/part.*.fzp`" &&
die_if_blank "$OLD_NONCE" "Cannot continue: The original nonce could not be guessed" &&
log "Original nonce: $OLD_NONCE" &&
log "Attempting to guess original base name" &&
OLD_BASE_NAME="`extract_base_name "$OLD_NONCE" "$PARTDIR/part."*"$OLD_NONCE"*".fzp"`" &&
die_if_blank "$OLD_BASE_NAME" "Cannot continue: Failed to guess original base name" &&
log "Original base name: '$OLD_BASE_NAME'" &&
log "Generating new nonce" &&
NEW_NONCE="`generate_nonce`" &&
die_if_blank "$NEW_NONCE" "Cannot continue: Failed to generate nonce" &&
log "New nonce: $NEW_NONCE." &&
(
cd "$PARTDIR" &&
log "Renaming files" &&
find . -type f -exec perl -E '
$old_nonce=q/'"$OLD_NONCE"'/;
$new_nonce=q/'"$NEW_NONCE"'/;
$_ = $ARGV[0];
$orig = $_;
s/$old_nonce/$new_nonce/;
if($orig eq $_) {
say qq(Skipping $orig);
}
else {
say qq(Rename $orig -> $_);
rename($orig, $_);
}
' {} \; &&
log "Swapping nonces within files" &&
find . -type f -exec perl -pi -E '
$old_nonce=q/'"$OLD_NONCE"'/;
$new_nonce=q/'"$NEW_NONCE"'/;
s/$old_nonce/$new_nonce/g;
' {} \; &&
log "Done modifying old files" &&
log "Repacking" &&
zip "$TMPDIR/part.zip" *
) &&
DESTFILE="${OLD_BASE_NAME}_$NEW_NONCE.fzpz"
log "Moving to destination '$DESTFILE'" &&
mv "$TMPDIR/part.zip" "$DESTFILE" &&
log "Done"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment