From 3be63e0bd4d4d709f9f96ff38b80148dfecd8166 Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Thu, 26 Mar 2026 10:39:03 +0000 Subject: [PATCH] Add volume selection option for file extraction --- Aaru.Localization/UI.Designer.cs | 12 +++++++ Aaru.Localization/UI.es.resx | 6 ++++ Aaru.Localization/UI.resx | 6 ++++ Aaru/Commands/Filesystem/ExtractFiles.cs | 40 ++++++++++++++++++------ 4 files changed, 54 insertions(+), 10 deletions(-) diff --git a/Aaru.Localization/UI.Designer.cs b/Aaru.Localization/UI.Designer.cs index 3a605ba59..b74abafe5 100644 --- a/Aaru.Localization/UI.Designer.cs +++ b/Aaru.Localization/UI.Designer.cs @@ -741,6 +741,18 @@ namespace Aaru.Localization { } } + public static string Extract_only_from_specified_volume_number { + get { + return ResourceManager.GetString("Extract_only_from_specified_volume_number", resourceCulture); + } + } + + public static string Volume_number_0_not_found_only_1_volumes_found { + get { + return ResourceManager.GetString("Volume_number_0_not_found_only_1_volumes_found", resourceCulture); + } + } + public static string Namespace_to_use_for_filenames { get { return ResourceManager.GetString("Namespace_to_use_for_filenames", resourceCulture); diff --git a/Aaru.Localization/UI.es.resx b/Aaru.Localization/UI.es.resx index fb35feed1..57d6b1668 100644 --- a/Aaru.Localization/UI.es.resx +++ b/Aaru.Localization/UI.es.resx @@ -1116,6 +1116,12 @@ Extraer atributos extendidos si existen. + + + Extraer solo del número de volumen especificado (indexado desde 0). Si no se especifica, extrae de todos los volúmenes. + + + [red]No se encontró el volumen número [orange3]{0}[/]. Solo se encontraron [orange3]{1}[/] volúmenes.[/] El nombre de fichero {0} no está soportado en esta plataforma. ¿Desea renombrarlo a {1}? diff --git a/Aaru.Localization/UI.resx b/Aaru.Localization/UI.resx index 04bc7b904..6ee530635 100644 --- a/Aaru.Localization/UI.resx +++ b/Aaru.Localization/UI.resx @@ -373,6 +373,12 @@ In you are unsure, please press N to not continue. Extract extended attributes if present. + + + Extract only from the specified volume number (0-indexed). If not specified, extracts from all volumes. + + + [red]Volume number [orange3]{0}[/] not found. Only [orange3]{1}[/] volumes were found.[/] Namespace to use for filenames. diff --git a/Aaru/Commands/Filesystem/ExtractFiles.cs b/Aaru/Commands/Filesystem/ExtractFiles.cs index d7397e621..18ecc2839 100644 --- a/Aaru/Commands/Filesystem/ExtractFiles.cs +++ b/Aaru/Commands/Filesystem/ExtractFiles.cs @@ -69,6 +69,7 @@ sealed class ExtractFilesCommand : Command AaruLogging.Debug(MODULE_NAME, "--options={0}", Markup.Escape(settings.Options ?? "")); AaruLogging.Debug(MODULE_NAME, "--output={0}", Markup.Escape(settings.OutputDir ?? "")); AaruLogging.Debug(MODULE_NAME, "--verbose={0}", settings.Verbose); + AaruLogging.Debug(MODULE_NAME, "--volume={0}", settings.Volume?.ToString() ?? "all"); AaruLogging.Debug(MODULE_NAME, "--xattrs={0}", settings.Xattrs); IFilter inputFilter = null; @@ -227,6 +228,8 @@ sealed class ExtractFilesCommand : Command AaruLogging.WriteLine(UI._0_partitions_found, partitions.Count); + var volumeCounter = 0; + for(var i = 0; i < partitions.Count; i++) { AaruLogging.WriteLine(); @@ -274,15 +277,19 @@ sealed class ExtractFilesCommand : Command if(error == ErrorNumber.NoError) { - string volumeName = string.IsNullOrEmpty(fs.Metadata.VolumeName) - ? "NO NAME" - : fs.Metadata.VolumeName; + if(!settings.Volume.HasValue || settings.Volume.Value == volumeCounter) + { + string volumeName = string.IsNullOrEmpty(fs.Metadata.VolumeName) + ? "NO NAME" + : fs.Metadata.VolumeName; - volumeName = volumeName.Replace('/', '_').Replace('\\', '_'); + volumeName = volumeName.Replace('/', '_').Replace('\\', '_'); - ExtractFilesInDir("/", fs, volumeName, settings.OutputDir, settings.Xattrs); + ExtractFilesInDir("/", fs, volumeName, settings.OutputDir, settings.Xattrs); + } Statistics.AddFilesystem(fs.Metadata.Type); + volumeCounter++; } else AaruLogging.Error(UI.Unable_to_mount_volume_error_0, error.ToString()); @@ -309,21 +316,30 @@ sealed class ExtractFilesCommand : Command if(error == ErrorNumber.NoError) { - string volumeName = string.IsNullOrEmpty(fs.Metadata.VolumeName) - ? "NO NAME" - : fs.Metadata.VolumeName; + if(!settings.Volume.HasValue || settings.Volume.Value == volumeCounter) + { + string volumeName = string.IsNullOrEmpty(fs.Metadata.VolumeName) + ? "NO NAME" + : fs.Metadata.VolumeName; - volumeName = volumeName.Replace('/', '_').Replace('\\', '_'); + volumeName = volumeName.Replace('/', '_').Replace('\\', '_'); - ExtractFilesInDir("/", fs, volumeName, settings.OutputDir, settings.Xattrs); + ExtractFilesInDir("/", fs, volumeName, settings.OutputDir, settings.Xattrs); + } Statistics.AddFilesystem(fs.Metadata.Type); + volumeCounter++; } else AaruLogging.Error(UI.Unable_to_mount_volume_error_0, error.ToString()); } } } + + if(settings.Volume.HasValue && settings.Volume.Value >= volumeCounter) + AaruLogging.Error(UI.Volume_number_0_not_found_only_1_volumes_found, + settings.Volume.Value, + volumeCounter); } catch(Exception ex) { @@ -677,6 +693,10 @@ sealed class ExtractFilesCommand : Command [LocalizedDescription(nameof(UI.Extract_extended_attributes_if_present))] [DefaultValue(false)] public bool Xattrs { get; init; } + [CommandOption("--volume")] + [LocalizedDescription(nameof(UI.Extract_only_from_specified_volume_number))] + [DefaultValue(null)] + public int? Volume { get; init; } [CommandOption("-n|--namespace")] [LocalizedDescription(nameof(UI.Namespace_to_use_for_filenames))] [DefaultValue(null)]