From c5538b4c146cedfbfc5010b9265c29910b52ac93 Mon Sep 17 00:00:00 2001 From: Sergey Palcheh Date: Thu, 12 Jun 2025 21:31:56 +0600 Subject: [PATCH] backup and recovery pfx --- winehelper | 182 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 175 insertions(+), 7 deletions(-) diff --git a/winehelper b/winehelper index 6ee6fbf..573f792 100755 --- a/winehelper +++ b/winehelper @@ -400,14 +400,19 @@ create_desktop () { cp -f "$USER_WORK_PATH/$desktop_filename.desktop" "$WH_MENU_DIR/" - # добавляем информацию о приложении в "$WINEPREFIX/desktop.list" - if [[ -f "$WINEPREFIX/desktop.list" ]] \ - && grep -qe "^${name_desktop}=" "$WINEPREFIX/desktop.list" - then sed -i "/^$name_desktop=/d" "$WINEPREFIX/desktop.list" + if [[ "$RESTORE_FROM_BACKUP" == "1" ]]; then + print_info "Пропускаем обновление desktop.list (режим восстановления из бэкапа)" + else + # добавляем информацию о приложении в "$WINEPREFIX/desktop.list" + if [[ -f "$WINEPREFIX/desktop.list" ]] \ + && grep -qe "^${name_desktop}=" "$WINEPREFIX/desktop.list" + then sed -i "/^$name_desktop=/d" "$WINEPREFIX/desktop.list" + fi + create_new_dir "$WINEPREFIX/icons" + try_copy_file "$icon_file" "$WINEPREFIX/icons/" + echo "$name_desktop=${exe_file//$WINEPREFIX/}=$(basename "$icon_file")" >> "$WINEPREFIX/desktop.list" fi - create_new_dir "$WINEPREFIX/icons" - try_copy_file "$icon_file" "$WINEPREFIX/icons/" - echo "$name_desktop=${exe_file//$WINEPREFIX/}=$(basename "$icon_file")" >> "$WINEPREFIX/desktop.list" + # создаем файл категории для меню create_new_dir "$HOME/.local/share/desktop-directories" @@ -1313,6 +1318,165 @@ remove_winehelper () { fi } +backup_prefix() { + local prefix_name="$1" + local prefix_path="$WH_PREFIXES_DIR/$prefix_name" + local backup_base_dir="$(xdg-user-dir DESKTOP)" + local backup_archive_name="backup_${prefix_name}_$(date +%Y.%m.%d).whpack" + local backup_dest_path="$backup_base_dir/$backup_archive_name" + local temp_backup_dir="$WH_TMP_DIR/backup_${prefix_name}_$(date +%Y.%m.%d)" + + if [[ -z "$prefix_name" ]]; then + print_error "Не указано имя префикса для резервного копирования." + echo "Использование: $SCRIPT_NAME backup-prefix [имя_префикса]" + echo "Доступные префиксы:" + ls -1 "$WH_PREFIXES_DIR" + return 1 + fi + + if [[ ! -d "$prefix_path" ]]; then + print_error "Префикс \"$prefix_name\" не найден по пути $prefix_path." + return 1 + fi + + print_info "Начало резервного копирования префикса: $prefix_name" + create_new_dir "$temp_backup_dir" + create_new_dir "$temp_backup_dir/prefixes/" + create_new_dir "$temp_backup_dir/dist/" + + print_info "Подготовка префикса к упаковке..." + if cp -a "$prefix_path" "$temp_backup_dir/prefixes/$prefix_name"; then + print_ok "Директория префикса подготовлена." + else + print_error "Не удалось подготовить директорию префикса." + try_remove_dir "$temp_backup_dir" + return 1 + fi + + if [[ -f "$prefix_path/last.conf" ]]; then + local wine_version_to_backup + wine_version_to_backup=$( (source "$prefix_path/last.conf" && echo "$WH_WINE_USE") ) + + if [[ -n "$wine_version_to_backup" && "$wine_version_to_backup" != system* && -d "$WH_DIST_DIR/$wine_version_to_backup" ]]; then + print_info "Копирование используемой версии Wine: $wine_version_to_backup..." + + if ! cp -a "$WH_DIST_DIR/$wine_version_to_backup" "$temp_backup_dir/dist/"; then + print_error "Ошибка: не удалось скопировать версию Wine." + exit 1 + fi + print_ok "Версия Wine скопирована." + fi + fi + + print_info "Создание squashfs архива..." + if command -v mksquashfs >/dev/null; then + if mksquashfs "$temp_backup_dir" "$backup_dest_path" -comp zstd; then + print_ok "Архив успешно создан: $backup_dest_path" + else + print_error "Не удалось создать архив." + try_remove_dir "$temp_backup_dir" + return 1 + fi + else + print_error "mksquashfs не установлен. Необходимо установить squashfs-tools." + try_remove_dir "$temp_backup_dir" + return 1 + fi + + try_remove_dir "$temp_backup_dir" + print_info "Резервное копирование завершено." + return 0 +} + +restore_prefix() { + local backup_archive_path="$1" + local temp_extract_dir + + if [[ -z "$backup_archive_path" ]]; then + read -e -p "Укажите путь к архиву резервной копии (/путь/к/архиву.whpack): " backup_archive_path + if [[ -z "$backup_archive_path" ]]; then + print_error "Путь к архиву не указан. Восстановление отменено." + return 1 + fi + fi + + backup_archive_path=$(echo "$backup_archive_path" | sed "s/'//g; s/\"//g") + if [[ ! -f "$backup_archive_path" ]]; then + print_error "Файл архива не найден: $backup_archive_path" + return 1 + fi + + print_info "Восстановление из резервной копии: $backup_archive_path" + + temp_extract_dir="$WH_TMP_DIR/restore_$(basename "$backup_archive_path" .whpack)" + create_new_dir "$temp_extract_dir" + + print_info "Распаковка архива..." + if ! unsquashfs -f -d "$temp_extract_dir" "$backup_archive_path"; then + print_error "Не удалось распаковать архив." + try_remove_dir "$temp_extract_dir" + return 1 + fi + print_ok "Архив успешно распакован." + + if [[ -d "$temp_extract_dir/dist" ]]; then + print_info "Восстановление версий Wine..." + + # TODO: Нужно ли создавать директортю create_new_dir "$WH_DIST_DIR" и перезаписывать/удалять сушествующие файлы в /dist + + if ! mv -n "$temp_extract_dir/dist"/* "$WH_DIST_DIR/"; then + print_warning "Не удалось восстановить версии Wine." + else + print_ok "Версии Wine восстановлены." + fi + fi + + if [[ -d "$temp_extract_dir/prefixes" ]]; then + for prefix_dir in "$temp_extract_dir"/prefixes/*; do + local prefix_name=$(basename "$prefix_dir") + if [[ -d "$prefix_dir" ]]; then + print_info "Восстановление префикса: $prefix_name" + + # TODO: Нужно ли удалять, перезаписывать или создавать новый префикс try_remove_dir "$WH_PREFIXES_DIR/$prefix_name" + + if ! mv "$prefix_dir" "$WH_PREFIXES_DIR/"; then + print_error "Не удалось восстановить префикс $prefix_name." + else + print_ok "Префикс $prefix_name восстановлен." + + print_info "Восстановление ярлыков для префикса $prefix_name..." + export RESTORE_FROM_BACKUP=1 # Устанавливаем флаг восстановления + while IFS='=' read -r line; do + local name_desktop=$(echo "$line" | cut -d'=' -f1) + local exe_path=$(echo "$line" | cut -d'=' -f2) + local icon_name=$(echo "$line" | cut -d'=' -f3) + + local full_exe_path="$WH_PREFIXES_DIR/$prefix_name${exe_path}" + local full_icon_path="$WH_PREFIXES_DIR/$prefix_name/icons/${icon_name}" + + if [[ -f "$full_exe_path" ]]; then + print_info "Создание ярлыка для $name_desktop" + create_desktop "$name_desktop" "$full_exe_path" "${icon_name%.*}" + else + print_warning "Исполняемый файл для ярлыка '$name_desktop' не найден: $full_exe_path" + fi + done < "$WH_PREFIXES_DIR/$prefix_name/desktop.list" + unset RESTORE_FROM_BACKUP # Снимаем флаг после завершения + print_ok "Ярлыки для префикса $prefix_name восстановлены." + fi + fi + done + else + print_error "Директория prefixes не найдена в архиве." + try_remove_dir "$temp_extract_dir" + return 1 + fi + + try_remove_dir "$temp_extract_dir" + print_ok "Полное восстановление завершено." + return 0 +} + wh_info () { echo "Использование: $SCRIPT_NAME [команда] @@ -1325,6 +1489,8 @@ wh_info () { run [программа.exe] запуск программы (отладка) remove-all удалить WineHelper и все связанные данные remove-prefix [имя_префикса] удалить префикс и все связанные данные + backup-prefix [имя_префикса] создать резерную копию префикса + restore-prefix [имя_префикса] восстановить префикс из резервной копии Параметры: --help показать эту справку и выйти @@ -1358,6 +1524,8 @@ case "${1,,}" in install|-i) shift ; run_autoinstall "$@" ;; installed) shift ; check_installed_programs "$1" ;; run|-r) shift ; run_installed_programs "$1" ;; + backup-prefix) shift ; backup_prefix "$@" ;; + restore-prefix) shift ; restore_prefix "$@" ;; remove-all) shift ; remove_winehelper "$@" ;; remove-prefix) shift ; remove_prefix "$@" ;; *)