287 lines
7.0 KiB
Bash
Executable File
287 lines
7.0 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
set -euo pipefail
|
|
|
|
usage() {
|
|
echo "Usage: $0 [extension_name|all] [inet-to-intra|intra-to-inet]"
|
|
echo " no arguments: list extension names from the source profile"
|
|
echo " extension_name: copy the first matching extension by name"
|
|
echo " all: copy every extension from source to target"
|
|
echo " direction: which way to copy (default: inet-to-intra)"
|
|
}
|
|
|
|
EXTENSION_NAME=""
|
|
DIRECTION="inet-to-intra"
|
|
|
|
case $# in
|
|
0)
|
|
;;
|
|
1)
|
|
case "$1" in
|
|
inet-to-intra|intra-to-inet)
|
|
usage
|
|
exit 1
|
|
;;
|
|
*)
|
|
EXTENSION_NAME="$1"
|
|
;;
|
|
esac
|
|
;;
|
|
2)
|
|
EXTENSION_NAME="$1"
|
|
DIRECTION="$2"
|
|
;;
|
|
*)
|
|
usage
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
if [[ "$DIRECTION" != "inet-to-intra" && "$DIRECTION" != "intra-to-inet" ]]; then
|
|
usage
|
|
exit 1
|
|
fi
|
|
|
|
MOZILLA_BASE="${HOME}/.mozilla/firefox"
|
|
SNAP_BASE="${HOME}/snap/firefox/common/.mozilla/firefox"
|
|
|
|
find_base_path() {
|
|
if [[ -d "$MOZILLA_BASE" ]] && [[ -f "$MOZILLA_BASE/profiles.ini" ]]; then
|
|
echo "$MOZILLA_BASE"
|
|
return 0
|
|
elif [[ -d "$SNAP_BASE" ]] && [[ -f "$SNAP_BASE/profiles.ini" ]]; then
|
|
echo "$SNAP_BASE"
|
|
return 0
|
|
fi
|
|
return 1
|
|
}
|
|
|
|
find_profile() {
|
|
local base="$1"
|
|
local name="$2"
|
|
|
|
local pattern
|
|
case "$name" in
|
|
internet)
|
|
pattern="*internet*" ;;
|
|
intranet)
|
|
pattern="*intranet*" ;;
|
|
noproxy)
|
|
pattern="*noProxy*" ;;
|
|
*)
|
|
pattern="*${name}*" ;;
|
|
esac
|
|
|
|
for prof in "$base"/$pattern; do
|
|
if [[ -d "$prof" ]]; then
|
|
echo "$prof"
|
|
return 0
|
|
fi
|
|
done
|
|
return 1
|
|
}
|
|
|
|
list_profiles() {
|
|
local base="$1"
|
|
|
|
if [[ ! -d "$base" ]]; then
|
|
return 1
|
|
fi
|
|
|
|
for prof in "$base"/*.default*; do
|
|
if [[ -d "$prof" ]]; then
|
|
echo "$prof"
|
|
fi
|
|
done
|
|
for prof in "$base"/*.*; do
|
|
if [[ -d "$prof" ]]; then
|
|
echo "$prof"
|
|
fi
|
|
done
|
|
}
|
|
|
|
find_extension() {
|
|
local ext_dir="$1"
|
|
local name="$2"
|
|
|
|
if [[ ! -d "$ext_dir" ]]; then
|
|
return 1
|
|
fi
|
|
|
|
for ext in "$ext_dir"/*; do
|
|
if [[ -d "$ext" ]]; then
|
|
if [[ -f "$ext/manifest.json" ]]; then
|
|
if grep -qi "$name" "$ext/manifest.json" 2>/dev/null; then
|
|
echo "$ext"
|
|
return 0
|
|
fi
|
|
fi
|
|
elif [[ -f "$ext" ]] && [[ "$ext" == *.xpi ]]; then
|
|
if unzip -p "$ext" manifest.json 2>/dev/null | grep -qi "$name"; then
|
|
echo "$ext"
|
|
return 0
|
|
fi
|
|
fi
|
|
done
|
|
|
|
return 1
|
|
}
|
|
|
|
list_extensions() {
|
|
local ext_dir="$1"
|
|
|
|
if [[ ! -d "$ext_dir" ]]; then
|
|
return 1
|
|
fi
|
|
|
|
shopt -s nullglob
|
|
for ext in "$ext_dir"/*; do
|
|
if [[ -d "$ext" ]]; then
|
|
if [[ -f "$ext/manifest.json" ]]; then
|
|
local manifest_name
|
|
manifest_name=$(grep -oE '"name"[[:space:]]*:[[:space:]]*"[^"]+"' "$ext/manifest.json" 2>/dev/null | head -n1 | sed -E 's/.*"([^"]+)".*/\1/' || true)
|
|
if [[ -n "$manifest_name" ]]; then
|
|
echo "$manifest_name"
|
|
else
|
|
echo "$(basename "$ext")"
|
|
fi
|
|
fi
|
|
elif [[ -f "$ext" ]] && [[ "$ext" == *.xpi ]]; then
|
|
local manifest_name
|
|
manifest_name=$(unzip -p "$ext" manifest.json 2>/dev/null | grep -oE '"name"[[:space:]]*:[[:space:]]*"[^"]+"' | head -n1 | sed -E 's/.*"([^"]+)".*/\1/' || true)
|
|
if [[ -n "$manifest_name" ]]; then
|
|
echo "$manifest_name"
|
|
else
|
|
echo "$(basename "$ext")"
|
|
fi
|
|
fi
|
|
done
|
|
shopt -u nullglob
|
|
}
|
|
|
|
copy_all_extensions() {
|
|
local source_ext_dir="$1"
|
|
local target_ext_dir="$2"
|
|
|
|
if [[ ! -d "$source_ext_dir" ]]; then
|
|
echo "Error: Source extensions directory not found"
|
|
exit 1
|
|
fi
|
|
|
|
mkdir -p "$target_ext_dir"
|
|
|
|
shopt -s nullglob
|
|
local copied=0
|
|
for ext in "$source_ext_dir"/*; do
|
|
local ext_name
|
|
ext_name=$(basename "$ext")
|
|
local target_ext="$target_ext_dir/$ext_name"
|
|
|
|
if [[ -e "$target_ext" ]]; then
|
|
echo "Removing existing extension from target: $ext_name"
|
|
rm -rf "$target_ext"
|
|
fi
|
|
|
|
cp -r "$ext" "$target_ext"
|
|
echo "Copied: $ext_name"
|
|
copied=1
|
|
done
|
|
shopt -u nullglob
|
|
|
|
if [[ $copied -eq 0 ]]; then
|
|
echo "No extensions found to copy."
|
|
fi
|
|
}
|
|
|
|
main() {
|
|
echo "=== Firefox Extension Sync ($DIRECTION) ==="
|
|
echo ""
|
|
|
|
local base_path
|
|
base_path=$(find_base_path) || {
|
|
echo "Error: Could not find Firefox profile directory"
|
|
exit 1
|
|
}
|
|
|
|
echo "Profile base path: $base_path"
|
|
echo "Available profiles:"
|
|
list_profiles "$base_path" | while read -r p; do
|
|
echo " - $(basename "$p")"
|
|
done
|
|
echo ""
|
|
|
|
local source_profile target_profile
|
|
case "$DIRECTION" in
|
|
inet-to-intra)
|
|
source_profile=$(find_profile "$base_path" "internet")
|
|
target_profile=$(find_profile "$base_path" "intranet")
|
|
;;
|
|
intra-to-inet)
|
|
source_profile=$(find_profile "$base_path" "intranet")
|
|
target_profile=$(find_profile "$base_path" "internet")
|
|
;;
|
|
esac
|
|
|
|
if [[ -z "$source_profile" ]]; then
|
|
echo "Error: Could not find source profile"
|
|
exit 1
|
|
fi
|
|
|
|
if [[ -z "$target_profile" ]]; then
|
|
echo "Error: Could not find target profile"
|
|
exit 1
|
|
fi
|
|
|
|
echo "Source: $(basename "$source_profile")"
|
|
echo "Target: $(basename "$target_profile")"
|
|
echo ""
|
|
|
|
if [[ -z "$EXTENSION_NAME" ]]; then
|
|
echo "Extensions in source profile:"
|
|
local found=0
|
|
while IFS= read -r ext; do
|
|
found=1
|
|
[[ -n "$ext" ]] && echo " - $ext"
|
|
done < <(list_extensions "$source_profile/extensions" || true)
|
|
if [[ $found -eq 0 ]]; then
|
|
echo " - <none>"
|
|
fi
|
|
exit 0
|
|
fi
|
|
|
|
if [[ "$EXTENSION_NAME" == "all" ]]; then
|
|
echo "Copying all extensions..."
|
|
copy_all_extensions "$source_profile/extensions" "$target_profile/extensions"
|
|
echo ""
|
|
echo "Done! Restart Firefox to load the extensions."
|
|
exit 0
|
|
fi
|
|
|
|
local source_ext
|
|
source_ext=$(find_extension "$source_profile/extensions" "$EXTENSION_NAME") || {
|
|
echo "Error: $EXTENSION_NAME extension not found in source profile"
|
|
exit 1
|
|
}
|
|
|
|
local ext_name
|
|
ext_name=$(basename "$source_ext")
|
|
|
|
echo "Found extension: $ext_name"
|
|
echo ""
|
|
|
|
local target_ext="$target_profile/extensions/$ext_name"
|
|
|
|
if [[ -d "$target_ext" ]]; then
|
|
echo "Removing existing extension from target..."
|
|
rm -rf "$target_ext"
|
|
fi
|
|
|
|
cp -r "$source_ext" "$target_ext"
|
|
|
|
echo "Copied successfully!"
|
|
echo ""
|
|
echo "Done! Restart Firefox to load the extension."
|
|
}
|
|
|
|
main "$@"
|