Move all localizable strings from Aaru project to resources.

This commit is contained in:
2022-11-18 11:18:45 +00:00
parent a056832c1d
commit 887e58c6e5
42 changed files with 7912 additions and 1284 deletions

View File

@@ -0,0 +1,57 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<OutputType>Library</OutputType>
<RootNamespace>Aaru.Localization</RootNamespace>
<AssemblyName>Aaru.Localization</AssemblyName>
<ReleaseVersion>$(Version)</ReleaseVersion>
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
<Version>6.0.0-alpha8</Version>
<Company>Claunia.com</Company>
<Copyright>Copyright © 2011-2022 Natalia Portillo</Copyright>
<Product>Aaru Data Preservation Suite</Product>
<Title>Aaru.Localization</Title>
<ApplicationVersion>$(Version)</ApplicationVersion>
<LangVersion>11</LangVersion>
<Description>Language resources for the Aaru Data Preservation Suite.</Description>
<PackageProjectUrl>https://github.com/aaru-dps/</PackageProjectUrl>
<PackageLicenseExpression>LGPL-2.1-only</PackageLicenseExpression>
<RepositoryUrl>https://github.com/aaru-dps/Aaru</RepositoryUrl>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<NeutralLanguage>en-US</NeutralLanguage>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<Authors>Natalia Portillo &lt;claunia@claunia.com&gt;</Authors>
<EnableTrimAnalyzer>true</EnableTrimAnalyzer>
<NoWarn>CS1591</NoWarn>
</PropertyGroup>
<ItemGroup>
<EmbeddedResource Update="UI.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
<LastGenOutput>UI.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Update="Core.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
<LastGenOutput>Core.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<Compile Update="UI.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>UI.resx</DependentUpon>
</Compile>
<Compile Update="Core.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Core.resx</DependentUpon>
</Compile>
</ItemGroup>
</Project>

954
Aaru.Localization/Core.Designer.cs generated Normal file
View File

@@ -0,0 +1,954 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Aaru.Localization {
using System;
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
public class Core {
private static System.Resources.ResourceManager resourceMan;
private static System.Globalization.CultureInfo resourceCulture;
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Core() {
}
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
public static System.Resources.ResourceManager ResourceManager {
get {
if (object.Equals(null, resourceMan)) {
System.Resources.ResourceManager temp = new System.Resources.ResourceManager("Aaru.Localization.Core", typeof(Core).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
public static System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
public static string Querying_ATA_IDENTIFY {
get {
return ResourceManager.GetString("Querying_ATA_IDENTIFY", resourceCulture);
}
}
public static string Querying_USB_information {
get {
return ResourceManager.GetString("Querying_USB_information", resourceCulture);
}
}
public static string Querying_PCMCIA_information {
get {
return ResourceManager.GetString("Querying_PCMCIA_information", resourceCulture);
}
}
public static string NVMe_devices_not_yet_supported {
get {
return ResourceManager.GetString("NVMe_devices_not_yet_supported", resourceCulture);
}
}
public static string Querying_ATAPI_IDENTIFY {
get {
return ResourceManager.GetString("Querying_ATAPI_IDENTIFY", resourceCulture);
}
}
public static string Waiting_for_drive_to_become_ready {
get {
return ResourceManager.GetString("Waiting_for_drive_to_become_ready", resourceCulture);
}
}
public static string Device_not_ready_Sense {
get {
return ResourceManager.GetString("Device_not_ready_Sense", resourceCulture);
}
}
public static string Got_sense_status_but_no_sense_buffer {
get {
return ResourceManager.GetString("Got_sense_status_but_no_sense_buffer", resourceCulture);
}
}
public static string Try_to_find_SCSI_READ_LONG_size {
get {
return ResourceManager.GetString("Try_to_find_SCSI_READ_LONG_size", resourceCulture);
}
}
public static string Trying_to_READ_LONG {
get {
return ResourceManager.GetString("Trying_to_READ_LONG", resourceCulture);
}
}
public static string Trying_READ_LONG_with_size_0 {
get {
return ResourceManager.GetString("Trying_READ_LONG_with_size_0", resourceCulture);
}
}
public static string Trying_SCSI_READ_LONG_10 {
get {
return ResourceManager.GetString("Trying_SCSI_READ_LONG_10", resourceCulture);
}
}
public static string Trying_SCSI_READ_LONG_16 {
get {
return ResourceManager.GetString("Trying_SCSI_READ_LONG_16", resourceCulture);
}
}
public static string Please_write_media_manufacturer {
get {
return ResourceManager.GetString("Please_write_media_manufacturer", resourceCulture);
}
}
public static string Media_Type_Name_MMD_140A {
get {
return ResourceManager.GetString("Media_Type_Name_MMD_140A", resourceCulture);
}
}
public static string Media_Type_Name_MDW_60 {
get {
return ResourceManager.GetString("Media_Type_Name_MDW_60", resourceCulture);
}
}
public static string Media_Type_Name_MDW_74 {
get {
return ResourceManager.GetString("Media_Type_Name_MDW_74", resourceCulture);
}
}
public static string Media_Type_Name_MDW_80 {
get {
return ResourceManager.GetString("Media_Type_Name_MDW_80", resourceCulture);
}
}
public static string Media_Type_Name_MiniDisc {
get {
return ResourceManager.GetString("Media_Type_Name_MiniDisc", resourceCulture);
}
}
public static string Unknown_device_type {
get {
return ResourceManager.GetString("Unknown_device_type", resourceCulture);
}
}
public static string Device_supports_MCPT_Command_Set {
get {
return ResourceManager.GetString("Device_supports_MCPT_Command_Set", resourceCulture);
}
}
public static string Device_reports_incorrect_media_card_type {
get {
return ResourceManager.GetString("Device_reports_incorrect_media_card_type", resourceCulture);
}
}
public static string Device_contains_SD_card {
get {
return ResourceManager.GetString("Device_contains_SD_card", resourceCulture);
}
}
public static string Device_contains_MMC {
get {
return ResourceManager.GetString("Device_contains_MMC", resourceCulture);
}
}
public static string Device_contains_SDIO_card {
get {
return ResourceManager.GetString("Device_contains_SDIO_card", resourceCulture);
}
}
public static string Device_contains_SM_card {
get {
return ResourceManager.GetString("Device_contains_SM_card", resourceCulture);
}
}
public static string Device_contains_unknown_media_card_type_0 {
get {
return ResourceManager.GetString("Device_contains_unknown_media_card_type_0", resourceCulture);
}
}
public static string Media_card_is_write_protected {
get {
return ResourceManager.GetString("Media_card_is_write_protected", resourceCulture);
}
}
public static string Card_specific_data_0 {
get {
return ResourceManager.GetString("Card_specific_data_0", resourceCulture);
}
}
public static string Media_identified_as_0 {
get {
return ResourceManager.GetString("Media_identified_as_0", resourceCulture);
}
}
public static string Device_identified_as_0 {
get {
return ResourceManager.GetString("Device_identified_as_0", resourceCulture);
}
}
public static string ASCII_Page_0_1 {
get {
return ResourceManager.GetString("ASCII_Page_0_1", resourceCulture);
}
}
public static string Unit_Serial_Number_0 {
get {
return ResourceManager.GetString("Unit_Serial_Number_0", resourceCulture);
}
}
public static string ASCII_implemented_operating_definitions_0 {
get {
return ResourceManager.GetString("ASCII_implemented_operating_definitions_0", resourceCulture);
}
}
public static string Manufacturer_assigned_Serial_Number_0 {
get {
return ResourceManager.GetString("Manufacturer_assigned_Serial_Number_0", resourceCulture);
}
}
public static string TapeAlert_Supported_Flags_Bitmap_0 {
get {
return ResourceManager.GetString("TapeAlert_Supported_Flags_Bitmap_0", resourceCulture);
}
}
public static string Automation_Device_Serial_Number_0 {
get {
return ResourceManager.GetString("Automation_Device_Serial_Number_0", resourceCulture);
}
}
public static string Data_Transfer_Device_Element_Address_0 {
get {
return ResourceManager.GetString("Data_Transfer_Device_Element_Address_0", resourceCulture);
}
}
public static string Found_undecoded_SCSI_VPD_page_0 {
get {
return ResourceManager.GetString("Found_undecoded_SCSI_VPD_page_0", resourceCulture);
}
}
public static string GET_CONFIGURATION_length_is_0 {
get {
return ResourceManager.GetString("GET_CONFIGURATION_length_is_0", resourceCulture);
}
}
public static string GET_CONFIGURATION_current_profile_is_0 {
get {
return ResourceManager.GetString("GET_CONFIGURATION_current_profile_is_0", resourceCulture);
}
}
public static string Feature_0 {
get {
return ResourceManager.GetString("Feature_0", resourceCulture);
}
}
public static string Found_unknown_feature_code_0 {
get {
return ResourceManager.GetString("Found_unknown_feature_code_0", resourceCulture);
}
}
public static string GET_CONFIGURATION_returned_no_feature_descriptors {
get {
return ResourceManager.GetString("GET_CONFIGURATION_returned_no_feature_descriptors", resourceCulture);
}
}
public static string Drive_has_loaded_a_total_of_0_discs {
get {
return ResourceManager.GetString("Drive_has_loaded_a_total_of_0_discs", resourceCulture);
}
}
public static string Drive_has_spent_0_hours_1_minutes_and_2_seconds_reading_CDs {
get {
return ResourceManager.GetString("Drive_has_spent_0_hours_1_minutes_and_2_seconds_reading_CDs", resourceCulture);
}
}
public static string Drive_has_spent_0_hours_1_minutes_and_2_seconds_writing_CDs {
get {
return ResourceManager.GetString("Drive_has_spent_0_hours_1_minutes_and_2_seconds_writing_CDs", resourceCulture);
}
}
public static string Drive_has_spent_0_hours_1_minutes_and_2_seconds_reading_DVDs {
get {
return ResourceManager.GetString("Drive_has_spent_0_hours_1_minutes_and_2_seconds_reading_DVDs", resourceCulture);
}
}
public static string Drive_has_spent_0_hours_1_minutes_and_2_seconds_writing_DVDs {
get {
return ResourceManager.GetString("Drive_has_spent_0_hours_1_minutes_and_2_seconds_writing_DVDs", resourceCulture);
}
}
public static string Drive_supports_PoweRec_is_enabled_and_recommends_0 {
get {
return ResourceManager.GetString("Drive_supports_PoweRec_is_enabled_and_recommends_0", resourceCulture);
}
}
public static string Drive_supports_PoweRec_and_has_it_enabled {
get {
return ResourceManager.GetString("Drive_supports_PoweRec_and_has_it_enabled", resourceCulture);
}
}
public static string Selected_PoweRec_speed_for_currently_inserted_media_is_0_1 {
get {
return ResourceManager.GetString("Selected_PoweRec_speed_for_currently_inserted_media_is_0_1", resourceCulture);
}
}
public static string Maximum_PoweRec_speed_for_currently_inserted_media_is_0_1 {
get {
return ResourceManager.GetString("Maximum_PoweRec_speed_for_currently_inserted_media_is_0_1", resourceCulture);
}
}
public static string Last_used_PoweRec_was_0_1 {
get {
return ResourceManager.GetString("Last_used_PoweRec_was_0_1", resourceCulture);
}
}
public static string Drive_supports_PoweRec_and_has_it_disabled {
get {
return ResourceManager.GetString("Drive_supports_PoweRec_and_has_it_disabled", resourceCulture);
}
}
public static string Drive_supports_Plextor_SilentMode {
get {
return ResourceManager.GetString("Drive_supports_Plextor_SilentMode", resourceCulture);
}
}
public static string Plextor_SilentMode_is_enabled {
get {
return ResourceManager.GetString("Plextor_SilentMode_is_enabled", resourceCulture);
}
}
public static string Access_time_is_slow {
get {
return ResourceManager.GetString("Access_time_is_slow", resourceCulture);
}
}
public static string Access_time_is_fast {
get {
return ResourceManager.GetString("Access_time_is_fast", resourceCulture);
}
}
public static string CD_read_speed_limited_to_0 {
get {
return ResourceManager.GetString("CD_read_speed_limited_to_0", resourceCulture);
}
}
public static string DVD_read_speed_limited_to_0 {
get {
return ResourceManager.GetString("DVD_read_speed_limited_to_0", resourceCulture);
}
}
public static string CD_write_speed_limited_to_0 {
get {
return ResourceManager.GetString("CD_write_speed_limited_to_0", resourceCulture);
}
}
public static string Drive_supports_Plextor_GigaRec {
get {
return ResourceManager.GetString("Drive_supports_Plextor_GigaRec", resourceCulture);
}
}
public static string Drive_supports_Plextor_SecuRec {
get {
return ResourceManager.GetString("Drive_supports_Plextor_SecuRec", resourceCulture);
}
}
public static string Drive_supports_Plextor_SpeedRead {
get {
return ResourceManager.GetString("Drive_supports_Plextor_SpeedRead", resourceCulture);
}
}
public static string Drive_supports_Plextor_SpeedRead_and_has_it_enabled {
get {
return ResourceManager.GetString("Drive_supports_Plextor_SpeedRead_and_has_it_enabled", resourceCulture);
}
}
public static string Drive_supports_hiding_CDRs_and_forcing_single_session {
get {
return ResourceManager.GetString("Drive_supports_hiding_CDRs_and_forcing_single_session", resourceCulture);
}
}
public static string Drive_currently_hides_CDRs {
get {
return ResourceManager.GetString("Drive_currently_hides_CDRs", resourceCulture);
}
}
public static string Drive_currently_forces_single_session {
get {
return ResourceManager.GetString("Drive_currently_forces_single_session", resourceCulture);
}
}
public static string Drive_supports_Plextor_VariRec {
get {
return ResourceManager.GetString("Drive_supports_Plextor_VariRec", resourceCulture);
}
}
public static string Drive_supports_Plextor_VariRec_for_DVDs {
get {
return ResourceManager.GetString("Drive_supports_Plextor_VariRec_for_DVDs", resourceCulture);
}
}
public static string Drive_supports_bitsetting_DVD_R_book_type {
get {
return ResourceManager.GetString("Drive_supports_bitsetting_DVD_R_book_type", resourceCulture);
}
}
public static string Drive_supports_bitsetting_DVD_R_DL_book_type {
get {
return ResourceManager.GetString("Drive_supports_bitsetting_DVD_R_DL_book_type", resourceCulture);
}
}
public static string Drive_supports_test_writing_DVD_Plus {
get {
return ResourceManager.GetString("Drive_supports_test_writing_DVD_Plus", resourceCulture);
}
}
public static string Can_do_challenge_response_with_Xbox_discs {
get {
return ResourceManager.GetString("Can_do_challenge_response_with_Xbox_discs", resourceCulture);
}
}
public static string Can_read_and_decrypt_SS_from_Xbox_discs {
get {
return ResourceManager.GetString("Can_read_and_decrypt_SS_from_Xbox_discs", resourceCulture);
}
}
public static string Can_set_xtreme_unlock_state_with_Xbox_discs {
get {
return ResourceManager.GetString("Can_set_xtreme_unlock_state_with_Xbox_discs", resourceCulture);
}
}
public static string Can_set_wxripper_unlock_state_with_Xbox_discs {
get {
return ResourceManager.GetString("Can_set_wxripper_unlock_state_with_Xbox_discs", resourceCulture);
}
}
public static string Can_do_challenge_response_with_Xbox_360_discs {
get {
return ResourceManager.GetString("Can_do_challenge_response_with_Xbox_360_discs", resourceCulture);
}
}
public static string Can_read_and_decrypt_SS_from_Xbox_360_discs {
get {
return ResourceManager.GetString("Can_read_and_decrypt_SS_from_Xbox_360_discs", resourceCulture);
}
}
public static string Can_set_xtreme_unlock_state_with_Xbox_360_discs {
get {
return ResourceManager.GetString("Can_set_xtreme_unlock_state_with_Xbox_360_discs", resourceCulture);
}
}
public static string Can_set_wxripper_unlock_state_with_Xbox_360_discs {
get {
return ResourceManager.GetString("Can_set_wxripper_unlock_state_with_Xbox_360_discs", resourceCulture);
}
}
public static string Can_set_Kreon_locked_state {
get {
return ResourceManager.GetString("Can_set_Kreon_locked_state", resourceCulture);
}
}
public static string Kreon_Can_skip_read_errors {
get {
return ResourceManager.GetString("Kreon_Can_skip_read_errors", resourceCulture);
}
}
public static string Block_limits_for_device {
get {
return ResourceManager.GetString("Block_limits_for_device", resourceCulture);
}
}
public static string Generating_subchannels {
get {
return ResourceManager.GetString("Generating_subchannels", resourceCulture);
}
}
public static string Writing_metadata_sidecar {
get {
return ResourceManager.GetString("Writing_metadata_sidecar", resourceCulture);
}
}
public static string Cannot_create_a_sidecar_from_a_directory {
get {
return ResourceManager.GetString("Cannot_create_a_sidecar_from_a_directory", resourceCulture);
}
}
public static string Stack_trace_0 {
get {
return ResourceManager.GetString("Stack_trace_0", resourceCulture);
}
}
public static string Media_has_0_blocks_of_1_bytes_each_for_a_total_of_2_TiB {
get {
return ResourceManager.GetString("Media_has_0_blocks_of_1_bytes_each_for_a_total_of_2_TiB", resourceCulture);
}
}
public static string Media_has_0_blocks_of_1_bytes_each_for_a_total_of_2_GiB {
get {
return ResourceManager.GetString("Media_has_0_blocks_of_1_bytes_each_for_a_total_of_2_GiB", resourceCulture);
}
}
public static string Media_has_0_blocks_of_1_bytes_each_for_a_total_of_2_MiB {
get {
return ResourceManager.GetString("Media_has_0_blocks_of_1_bytes_each_for_a_total_of_2_MiB", resourceCulture);
}
}
public static string Media_has_0_blocks_of_1_bytes_each_for_a_total_of_2_KiB {
get {
return ResourceManager.GetString("Media_has_0_blocks_of_1_bytes_each_for_a_total_of_2_KiB", resourceCulture);
}
}
public static string Media_has_0_blocks_of_1_bytes_each_for_a_total_of_2_bytes {
get {
return ResourceManager.GetString("Media_has_0_blocks_of_1_bytes_each_for_a_total_of_2_bytes", resourceCulture);
}
}
public static string Xbox_DMI {
get {
return ResourceManager.GetString("Xbox_DMI", resourceCulture);
}
}
public static string Xbox_360_DMI {
get {
return ResourceManager.GetString("Xbox_360_DMI", resourceCulture);
}
}
public static string Lead_In_CMI {
get {
return ResourceManager.GetString("Lead_In_CMI", resourceCulture);
}
}
public static string Disc_Definition_Structure {
get {
return ResourceManager.GetString("Disc_Definition_Structure", resourceCulture);
}
}
public static string Medium_Status {
get {
return ResourceManager.GetString("Medium_Status", resourceCulture);
}
}
public static string Spare_Area_Information {
get {
return ResourceManager.GetString("Spare_Area_Information", resourceCulture);
}
}
public static string DVD_RW_Pre_Recorded_Information {
get {
return ResourceManager.GetString("DVD_RW_Pre_Recorded_Information", resourceCulture);
}
}
public static string DVD_RW_PFI {
get {
return ResourceManager.GetString("DVD_RW_PFI", resourceCulture);
}
}
public static string Bluray_Disc_Information {
get {
return ResourceManager.GetString("Bluray_Disc_Information", resourceCulture);
}
}
public static string Bluray_Burst_Cutting_Area {
get {
return ResourceManager.GetString("Bluray_Burst_Cutting_Area", resourceCulture);
}
}
public static string Bluray_Disc_Definition_Structure {
get {
return ResourceManager.GetString("Bluray_Disc_Definition_Structure", resourceCulture);
}
}
public static string Bluray_Cartridge_Status {
get {
return ResourceManager.GetString("Bluray_Cartridge_Status", resourceCulture);
}
}
public static string Bluray_Spare_Area_Information {
get {
return ResourceManager.GetString("Bluray_Spare_Area_Information", resourceCulture);
}
}
public static string Track_Resources_Information {
get {
return ResourceManager.GetString("Track_Resources_Information", resourceCulture);
}
}
public static string POW_Resources_Information {
get {
return ResourceManager.GetString("POW_Resources_Information", resourceCulture);
}
}
public static string TOC {
get {
return ResourceManager.GetString("TOC", resourceCulture);
}
}
public static string ATIP {
get {
return ResourceManager.GetString("ATIP", resourceCulture);
}
}
public static string Standard_Disc_Information {
get {
return ResourceManager.GetString("Standard_Disc_Information", resourceCulture);
}
}
public static string Session_information {
get {
return ResourceManager.GetString("Session_information", resourceCulture);
}
}
public static string Raw_TOC {
get {
return ResourceManager.GetString("Raw_TOC", resourceCulture);
}
}
public static string PMA {
get {
return ResourceManager.GetString("PMA", resourceCulture);
}
}
public static string CD_TEXT_on_Lead_In {
get {
return ResourceManager.GetString("CD_TEXT_on_Lead_In", resourceCulture);
}
}
public static string MCN {
get {
return ResourceManager.GetString("MCN", resourceCulture);
}
}
public static string Tracks_0_ISRC {
get {
return ResourceManager.GetString("Tracks_0_ISRC", resourceCulture);
}
}
public static string Xbox_Security_Sector {
get {
return ResourceManager.GetString("Xbox_Security_Sector", resourceCulture);
}
}
public static string Video_layer_zero_size {
get {
return ResourceManager.GetString("Video_layer_zero_size", resourceCulture);
}
}
public static string Video_layer_one_size {
get {
return ResourceManager.GetString("Video_layer_one_size", resourceCulture);
}
}
public static string Middle_zone_size {
get {
return ResourceManager.GetString("Middle_zone_size", resourceCulture);
}
}
public static string Game_data_size {
get {
return ResourceManager.GetString("Game_data_size", resourceCulture);
}
}
public static string Total_size {
get {
return ResourceManager.GetString("Total_size", resourceCulture);
}
}
public static string Real_layer_break {
get {
return ResourceManager.GetString("Real_layer_break", resourceCulture);
}
}
public static string Media_Serial_Number {
get {
return ResourceManager.GetString("Media_Serial_Number", resourceCulture);
}
}
public static string Media_identified_as {
get {
return ResourceManager.GetString("Media_identified_as", resourceCulture);
}
}
public static string Track_calculations {
get {
return ResourceManager.GetString("Track_calculations", resourceCulture);
}
}
public static string Offsets {
get {
return ResourceManager.GetString("Offsets", resourceCulture);
}
}
public static string Drive_reading_offset_not_found_in_database {
get {
return ResourceManager.GetString("Drive_reading_offset_not_found_in_database", resourceCulture);
}
}
public static string Disc_offset_cannot_be_calculated {
get {
return ResourceManager.GetString("Disc_offset_cannot_be_calculated", resourceCulture);
}
}
public static string Drive_reading_offset_is_0_bytes_1_samples {
get {
return ResourceManager.GetString("Drive_reading_offset_is_0_bytes_1_samples", resourceCulture);
}
}
public static string Disc_write_offset_is_unknown {
get {
return ResourceManager.GetString("Disc_write_offset_is_unknown", resourceCulture);
}
}
public static string Combined_disc_and_drive_offset_are_0_bytes_1_samples {
get {
return ResourceManager.GetString("Combined_disc_and_drive_offset_are_0_bytes_1_samples", resourceCulture);
}
}
public static string Combined_offset_is_0_bytes_1_samples {
get {
return ResourceManager.GetString("Combined_offset_is_0_bytes_1_samples", resourceCulture);
}
}
public static string Disc_offset_is_0_bytes_1_samples {
get {
return ResourceManager.GetString("Disc_offset_is_0_bytes_1_samples", resourceCulture);
}
}
public static string Took_a_total_of_0_seconds_1_processing_commands {
get {
return ResourceManager.GetString("Took_a_total_of_0_seconds_1_processing_commands", resourceCulture);
}
}
public static string Average_speed_0_MiB_sec {
get {
return ResourceManager.GetString("Average_speed_0_MiB_sec", resourceCulture);
}
}
public static string Fastest_speed_burst_0_MiB_sec {
get {
return ResourceManager.GetString("Fastest_speed_burst_0_MiB_sec", resourceCulture);
}
}
public static string Slowest_speed_burst_0_MiB_sec {
get {
return ResourceManager.GetString("Slowest_speed_burst_0_MiB_sec", resourceCulture);
}
}
public static string Summary {
get {
return ResourceManager.GetString("Summary", resourceCulture);
}
}
public static string _0_sectors_took_less_than_3_ms {
get {
return ResourceManager.GetString("_0_sectors_took_less_than_3_ms", resourceCulture);
}
}
public static string _0_sectors_took_less_than_10_ms_but_more_than_3_ms {
get {
return ResourceManager.GetString("_0_sectors_took_less_than_10_ms_but_more_than_3_ms", resourceCulture);
}
}
public static string _0_sectors_took_less_than_50_ms_but_more_than_10_ms {
get {
return ResourceManager.GetString("_0_sectors_took_less_than_50_ms_but_more_than_10_ms", resourceCulture);
}
}
public static string _0_sectors_took_less_than_150_ms_but_more_than_50_ms {
get {
return ResourceManager.GetString("_0_sectors_took_less_than_150_ms_but_more_than_50_ms", resourceCulture);
}
}
public static string _0_sectors_took_less_than_500_ms_but_more_than_150_ms {
get {
return ResourceManager.GetString("_0_sectors_took_less_than_500_ms_but_more_than_150_ms", resourceCulture);
}
}
public static string _0_sectors_took_more_than_500_ms {
get {
return ResourceManager.GetString("_0_sectors_took_more_than_500_ms", resourceCulture);
}
}
public static string _0_sectors_could_not_be_read {
get {
return ResourceManager.GetString("_0_sectors_could_not_be_read", resourceCulture);
}
}
public static string Sector_0_could_not_be_read {
get {
return ResourceManager.GetString("Sector_0_could_not_be_read", resourceCulture);
}
}
public static string Testing_0_seeks_longest_seek_took_1_ms_fastest_one_took_2_ms_3_ms_average {
get {
return ResourceManager.GetString("Testing_0_seeks_longest_seek_took_1_ms_fastest_one_took_2_ms_3_ms_average", resourceCulture);
}
}
public static string Whole_device {
get {
return ResourceManager.GetString("Whole_device", resourceCulture);
}
}
}
}

481
Aaru.Localization/Core.resx Normal file
View File

@@ -0,0 +1,481 @@
<?xml version="1.0" encoding="utf-8" ?>
<root>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" id="root"
xmlns="">
<xsd:element name="root" msdata:IsDataSet="true"></xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089
</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089
</value>
</resheader>
<data name="Querying_ATA_IDENTIFY" xml:space="preserve">
<value>Querying ATA IDENTIFY...</value>
</data>
<data name="Querying_USB_information" xml:space="preserve">
<value>Querying USB information...</value>
</data>
<data name="Querying_PCMCIA_information" xml:space="preserve">
<value>Querying PCMCIA information...</value>
</data>
<data name="NVMe_devices_not_yet_supported" xml:space="preserve">
<value>NVMe devices not yet supported.</value>
</data>
<data name="Querying_ATAPI_IDENTIFY" xml:space="preserve">
<value>Querying ATAPI IDENTIFY...</value>
</data>
<data name="Waiting_for_drive_to_become_ready" xml:space="preserve">
<value>Waiting for drive to become ready</value>
</data>
<data name="Device_not_ready_Sense" xml:space="preserve">
<value>Device not ready. Sense {0} ASC {1:X2}h ASCQ {2:X2}h</value>
</data>
<data name="Got_sense_status_but_no_sense_buffer" xml:space="preserve">
<value>Got sense status but no sense buffer</value>
</data>
<data name="Try_to_find_SCSI_READ_LONG_size" xml:space="preserve">
<value>Drive supports SCSI READ LONG but I cannot find the correct size. Do you want me to try? (This can take hours)</value>
</data>
<data name="Trying_to_READ_LONG" xml:space="preserve">
<value>Trying to READ LONG...</value>
</data>
<data name="Trying_READ_LONG_with_size_0" xml:space="preserve">
<value>Trying to READ LONG with a size of {0} bytes...</value>
</data>
<data name="Trying_SCSI_READ_LONG_10" xml:space="preserve">
<value>Trying SCSI READ LONG (10)...</value>
</data>
<data name="Trying_SCSI_READ_LONG_16" xml:space="preserve">
<value>Trying SCSI READ LONG (16)...</value>
</data>
<data name="Please_write_media_manufacturer" xml:space="preserve">
<value>Please write the media manufacturer and press enter: </value>
</data>
<data name="Media_Type_Name_MMD_140A" xml:space="preserve">
<value>MD DATA (140Mb data MiniDisc)</value>
</data>
<data name="Media_Type_Name_MDW_60" xml:space="preserve">
<value>60 minutes rewritable MiniDisc</value>
</data>
<data name="Media_Type_Name_MDW_74" xml:space="preserve">
<value>74 minutes rewritable MiniDisc</value>
</data>
<data name="Media_Type_Name_MDW_80" xml:space="preserve">
<value>80 minutes rewritable MiniDisc</value>
</data>
<data name="Media_Type_Name_MiniDisc" xml:space="preserve">
<value>Embossed Audio MiniDisc</value>
</data>
<data name="Unknown_device_type" xml:space="preserve">
<value>Unknown device type.</value>
</data>
<data name="Device_supports_MCPT_Command_Set" xml:space="preserve">
<value>Device supports the Media Card Pass Through Command Set</value>
</data>
<data name="Device_reports_incorrect_media_card_type" xml:space="preserve">
<value>Device reports incorrect media card type</value>
</data>
<data name="Device_contains_SD_card" xml:space="preserve">
<value>Device contains a Secure Digital card</value>
</data>
<data name="Device_contains_MMC" xml:space="preserve">
<value>Device contains a MultiMediaCard</value>
</data>
<data name="Device_contains_SDIO_card" xml:space="preserve">
<value>Device contains a Secure Digital I/O card</value>
</data>
<data name="Device_contains_SM_card" xml:space="preserve">
<value>Device contains a Smart Media card</value>
</data>
<data name="Device_contains_unknown_media_card_type_0" xml:space="preserve">
<value>Device contains unknown media card type {0}</value>
</data>
<data name="Media_card_is_write_protected" xml:space="preserve">
<value>Media card is write protected</value>
</data>
<data name="Card_specific_data_0" xml:space="preserve">
<value>Card specific data: 0x{0:X4}</value>
</data>
<data name="Media_identified_as_0" xml:space="preserve">
<value>Media identified as {0}.</value>
</data>
<data name="Device_identified_as_0" xml:space="preserve">
<value>Device identified as {0}</value>
</data>
<data name="ASCII_Page_0_1" xml:space="preserve">
<value>ASCII Page {0:X2}h: {1}</value>
</data>
<data name="Unit_Serial_Number_0" xml:space="preserve">
<value>Unit Serial Number: {0}</value>
</data>
<data name="ASCII_implemented_operating_definitions_0" xml:space="preserve">
<value>ASCII implemented operating definitions: {0}</value>
</data>
<data name="Manufacturer_assigned_Serial_Number_0" xml:space="preserve">
<value>Manufacturer-assigned Serial Number: {0}</value>
</data>
<data name="TapeAlert_Supported_Flags_Bitmap_0" xml:space="preserve">
<value>TapeAlert Supported Flags Bitmap: 0x{0:X16}</value>
</data>
<data name="Automation_Device_Serial_Number_0" xml:space="preserve">
<value>Automation Device Serial Number: {0}</value>
</data>
<data name="Data_Transfer_Device_Element_Address_0" xml:space="preserve">
<value>Data Transfer Device Element Address: 0x{0}</value>
</data>
<data name="Found_undecoded_SCSI_VPD_page_0" xml:space="preserve">
<value>Found undecoded SCSI VPD page 0x{0:X2}</value>
</data>
<data name="GET_CONFIGURATION_length_is_0" xml:space="preserve">
<value>GET CONFIGURATION length is {0} bytes</value>
</data>
<data name="GET_CONFIGURATION_current_profile_is_0" xml:space="preserve">
<value>GET CONFIGURATION current profile is {0:X4}h</value>
</data>
<data name="Feature_0" xml:space="preserve">
<value>Feature {0:X4}h</value>
</data>
<data name="Found_unknown_feature_code_0" xml:space="preserve">
<value>Found unknown feature code {0:X4}h</value>
</data>
<data name="GET_CONFIGURATION_returned_no_feature_descriptors" xml:space="preserve">
<value>GET CONFIGURATION returned no feature descriptors</value>
</data>
<data name="Drive_has_loaded_a_total_of_0_discs" xml:space="preserve">
<value>Drive has loaded a total of {0} discs</value>
</data>
<data name="Drive_has_spent_0_hours_1_minutes_and_2_seconds_reading_CDs" xml:space="preserve">
<value>Drive has spent {0} hours, {1} minutes and {2} seconds reading CDs</value>
</data>
<data name="Drive_has_spent_0_hours_1_minutes_and_2_seconds_writing_CDs" xml:space="preserve">
<value>Drive has spent {0} hours, {1} minutes and {2} seconds writing CDs</value>
</data>
<data name="Drive_has_spent_0_hours_1_minutes_and_2_seconds_reading_DVDs" xml:space="preserve">
<value>Drive has spent {0} hours, {1} minutes and {2} seconds reading DVDs</value>
</data>
<data name="Drive_has_spent_0_hours_1_minutes_and_2_seconds_writing_DVDs" xml:space="preserve">
<value>Drive has spent {0} hours, {1} minutes and {2} seconds writing DVDs</value>
</data>
<data name="Drive_supports_PoweRec_is_enabled_and_recommends_0" xml:space="preserve">
<value>Drive supports PoweRec, is enabled and recommends {0} Kb/sec.</value>
</data>
<data name="Drive_supports_PoweRec_and_has_it_enabled" xml:space="preserve">
<value>Drive supports PoweRec and has it enabled.</value>
</data>
<data name="Selected_PoweRec_speed_for_currently_inserted_media_is_0_1" xml:space="preserve">
<value>Selected PoweRec speed for currently inserted media is {0} Kb/sec ({1}x)</value>
</data>
<data name="Maximum_PoweRec_speed_for_currently_inserted_media_is_0_1" xml:space="preserve">
<value>Maximum PoweRec speed for currently inserted media is {0} Kb/sec ({1}x)</value>
</data>
<data name="Last_used_PoweRec_was_0_1" xml:space="preserve">
<value>Last used PoweRec was {0} Kb/sec ({1}x)</value>
</data>
<data name="Drive_supports_PoweRec_and_has_it_disabled" xml:space="preserve">
<value>Drive supports PoweRec and has it disabled.</value>
</data>
<data name="Drive_supports_Plextor_SilentMode" xml:space="preserve">
<value>Drive supports Plextor SilentMode</value>
</data>
<data name="Plextor_SilentMode_is_enabled" xml:space="preserve">
<value>Plextor SilentMode is enabled:</value>
</data>
<data name="Access_time_is_slow" xml:space="preserve">
<value>Access time is slow</value>
</data>
<data name="Access_time_is_fast" xml:space="preserve">
<value>Access time is fast</value>
</data>
<data name="CD_read_speed_limited_to_0" xml:space="preserve">
<value>CD read speed limited to {0}x</value>
</data>
<data name="DVD_read_speed_limited_to_0" xml:space="preserve">
<value>DVD read speed limited to {0}x</value>
</data>
<data name="CD_write_speed_limited_to_0" xml:space="preserve">
<value>CD write speed limited to {0}x</value>
</data>
<data name="Drive_supports_Plextor_GigaRec" xml:space="preserve">
<value>Drive supports Plextor GigaRec</value>
</data>
<data name="Drive_supports_Plextor_SecuRec" xml:space="preserve">
<value>Drive supports Plextor SecuRec</value>
</data>
<data name="Drive_supports_Plextor_SpeedRead" xml:space="preserve">
<value>Drive supports Plextor SpeedRead</value>
</data>
<data name="Drive_supports_Plextor_SpeedRead_and_has_it_enabled" xml:space="preserve">
<value>Drive supports Plextor SpeedRead and has it enabled</value>
</data>
<data name="Drive_supports_hiding_CDRs_and_forcing_single_session" xml:space="preserve">
<value>Drive supports hiding CD-Rs and forcing single session</value>
</data>
<data name="Drive_currently_hides_CDRs" xml:space="preserve">
<value>Drive currently hides CD-Rs</value>
</data>
<data name="Drive_currently_forces_single_session" xml:space="preserve">
<value>Drive currently forces single session</value>
</data>
<data name="Drive_supports_Plextor_VariRec" xml:space="preserve">
<value>Drive supports Plextor VariRec</value>
</data>
<data name="Drive_supports_Plextor_VariRec_for_DVDs" xml:space="preserve">
<value>Drive supports Plextor VariRec for DVDs</value>
</data>
<data name="Drive_supports_bitsetting_DVD_R_book_type" xml:space="preserve">
<value>Drive supports bitsetting DVD+R book type</value>
</data>
<data name="Drive_supports_bitsetting_DVD_R_DL_book_type" xml:space="preserve">
<value>Drive supports bitsetting DVD+R DL book type</value>
</data>
<data name="Drive_supports_test_writing_DVD_Plus" xml:space="preserve">
<value>Drive supports test writing DVD+</value>
</data>
<data name="Can_do_challenge_response_with_Xbox_discs" xml:space="preserve">
<value>Can do challenge/response with Xbox discs</value>
</data>
<data name="Can_read_and_decrypt_SS_from_Xbox_discs" xml:space="preserve">
<value>Can read and decrypt SS from Xbox discs</value>
</data>
<data name="Can_set_xtreme_unlock_state_with_Xbox_discs" xml:space="preserve">
<value>Can set xtreme unlock state with Xbox discs</value>
</data>
<data name="Can_set_wxripper_unlock_state_with_Xbox_discs" xml:space="preserve">
<value>Can set wxripper unlock state with Xbox discs</value>
</data>
<data name="Can_do_challenge_response_with_Xbox_360_discs" xml:space="preserve">
<value>Can do challenge/response with Xbox 360 discs</value>
</data>
<data name="Can_read_and_decrypt_SS_from_Xbox_360_discs" xml:space="preserve">
<value>Can read and decrypt SS from Xbox 360 discs</value>
</data>
<data name="Can_set_xtreme_unlock_state_with_Xbox_360_discs" xml:space="preserve">
<value>Can set xtreme unlock state with Xbox 360 discs</value>
</data>
<data name="Can_set_wxripper_unlock_state_with_Xbox_360_discs" xml:space="preserve">
<value>Can set wxripper unlock state with Xbox 360 discs</value>
</data>
<data name="Can_set_Kreon_locked_state" xml:space="preserve">
<value>Can set locked state</value>
</data>
<data name="Kreon_Can_skip_read_errors" xml:space="preserve">
<value>Can skip read errors</value>
</data>
<data name="Block_limits_for_device" xml:space="preserve">
<value>Block limits for device:</value>
</data>
<data name="Generating_subchannels" xml:space="preserve">
<value>Generating subchannels...</value>
</data>
<data name="Writing_metadata_sidecar" xml:space="preserve">
<value>Writing metadata sidecar</value>
</data>
<data name="Cannot_create_a_sidecar_from_a_directory" xml:space="preserve">
<value>Cannot create a sidecar from a directory.</value>
</data>
<data name="Stack_trace_0" xml:space="preserve">
<value>Stack trace: {0}</value>
</data>
<data name="Media_has_0_blocks_of_1_bytes_each_for_a_total_of_2_TiB" xml:space="preserve">
<value>Media has {0} blocks of {1} bytes/each. (for a total of {2:F3} TiB)</value>
<comment>TiB = tebibyte</comment>
</data>
<data name="Media_has_0_blocks_of_1_bytes_each_for_a_total_of_2_GiB" xml:space="preserve">
<value>Media has {0} blocks of {1} bytes/each. (for a total of {2:F3} GiB)</value>
<comment>GiB = gibibyte</comment>
</data>
<data name="Media_has_0_blocks_of_1_bytes_each_for_a_total_of_2_MiB" xml:space="preserve">
<value>Media has {0} blocks of {1} bytes/each. (for a total of {2:F3} MiB)</value>
<comment>MiB = mebibyte</comment>
</data>
<data name="Media_has_0_blocks_of_1_bytes_each_for_a_total_of_2_KiB" xml:space="preserve">
<value>Media has {0} blocks of {1} bytes/each. (for a total of {2:F3} KiB)</value>
<comment>KiB = kibibyte</comment>
</data>
<data name="Media_has_0_blocks_of_1_bytes_each_for_a_total_of_2_bytes" xml:space="preserve">
<value>Media has {0} blocks of {1} bytes/each. (for a total of {2} bytes)</value>
</data>
<data name="Xbox_DMI" xml:space="preserve">
<value>Xbox DMI</value>
</data>
<data name="Xbox_360_DMI" xml:space="preserve">
<value>Xbox 360 DMI</value>
</data>
<data name="Lead_In_CMI" xml:space="preserve">
<value>Lead-In CMI</value>
</data>
<data name="Disc_Definition_Structure" xml:space="preserve">
<value>Disc Definition Structure</value>
</data>
<data name="Medium_Status" xml:space="preserve">
<value>Medium Status</value>
</data>
<data name="Spare_Area_Information" xml:space="preserve">
<value>Spare Area Information</value>
</data>
<data name="DVD_RW_Pre_Recorded_Information" xml:space="preserve">
<value>DVD-R(W) Pre-Recorded Information</value>
</data>
<data name="DVD_RW_PFI" xml:space="preserve">
<value>DVD-R(W) PFI</value>
</data>
<data name="Bluray_Disc_Information" xml:space="preserve">
<value>Blu-ray Disc Information</value>
</data>
<data name="Bluray_Burst_Cutting_Area" xml:space="preserve">
<value>Blu-ray Burst Cutting Area</value>
</data>
<data name="Bluray_Disc_Definition_Structure" xml:space="preserve">
<value>Blu-ray Disc Definition Structure</value>
</data>
<data name="Bluray_Cartridge_Status" xml:space="preserve">
<value>Blu-ray Cartridge Status</value>
</data>
<data name="Bluray_Spare_Area_Information" xml:space="preserve">
<value>Blu-ray Spare Area Information</value>
</data>
<data name="Track_Resources_Information" xml:space="preserve">
<value>Track Resources Information</value>
</data>
<data name="POW_Resources_Information" xml:space="preserve">
<value>POW Resources Information</value>
</data>
<data name="TOC" xml:space="preserve">
<value>TOC</value>
</data>
<data name="ATIP" xml:space="preserve">
<value>ATIP</value>
</data>
<data name="Standard_Disc_Information" xml:space="preserve">
<value>Standard Disc Information</value>
</data>
<data name="Session_information" xml:space="preserve">
<value>Session information</value>
</data>
<data name="Raw_TOC" xml:space="preserve">
<value>Raw TOC</value>
</data>
<data name="PMA" xml:space="preserve">
<value>PMA</value>
</data>
<data name="CD_TEXT_on_Lead_In" xml:space="preserve">
<value>CD-TEXT on Lead-In</value>
</data>
<data name="MCN" xml:space="preserve">
<value>MCN</value>
</data>
<data name="Tracks_0_ISRC" xml:space="preserve">
<value>Track's {0} ISRC</value>
</data>
<data name="Xbox_Security_Sector" xml:space="preserve">
<value>Xbox Security Sector</value>
</data>
<data name="Video_layer_zero_size" xml:space="preserve">
<value>Video layer 0 size</value>
</data>
<data name="Video_layer_one_size" xml:space="preserve">
<value>Video layer 1 size</value>
</data>
<data name="Middle_zone_size" xml:space="preserve">
<value>Middle zone size</value>
</data>
<data name="Game_data_size" xml:space="preserve">
<value>Game data size</value>
</data>
<data name="Total_size" xml:space="preserve">
<value>Total size</value>
</data>
<data name="Real_layer_break" xml:space="preserve">
<value>Real layer break</value>
</data>
<data name="Media_Serial_Number" xml:space="preserve">
<value>Media Serial Number</value>
</data>
<data name="Media_identified_as" xml:space="preserve">
<value>Media identified as</value>
</data>
<data name="Track_calculations" xml:space="preserve">
<value>Track calculations</value>
</data>
<data name="Offsets" xml:space="preserve">
<value>Offsets</value>
</data>
<data name="Drive_reading_offset_not_found_in_database" xml:space="preserve">
<value>Drive reading offset not found in database.</value>
</data>
<data name="Disc_offset_cannot_be_calculated" xml:space="preserve">
<value>Disc offset cannot be calculated.</value>
</data>
<data name="Drive_reading_offset_is_0_bytes_1_samples" xml:space="preserve">
<value>Drive reading offset is {0} bytes ({1} samples).</value>
</data>
<data name="Disc_write_offset_is_unknown" xml:space="preserve">
<value>Disc write offset is unknown.</value>
</data>
<data name="Combined_disc_and_drive_offset_are_0_bytes_1_samples" xml:space="preserve">
<value>Combined disc and drive offset are {0} bytes ({1} samples).</value>
</data>
<data name="Combined_offset_is_0_bytes_1_samples" xml:space="preserve">
<value>Combined offset is {0} bytes ({1} samples).</value>
</data>
<data name="Disc_offset_is_0_bytes_1_samples" xml:space="preserve">
<value>Disc offset is {0} bytes ({1} samples).</value>
</data>
<data name="Took_a_total_of_0_seconds_1_processing_commands" xml:space="preserve">
<value>Took a total of {0} seconds ({1} processing commands).</value>
</data>
<data name="Average_speed_0_MiB_sec" xml:space="preserve">
<value>Average speed: {0:F3} MiB/sec.</value>
</data>
<data name="Fastest_speed_burst_0_MiB_sec" xml:space="preserve">
<value>Fastest speed burst: {0:F3} MiB/sec.</value>
</data>
<data name="Slowest_speed_burst_0_MiB_sec" xml:space="preserve">
<value>Slowest speed burst: {0:F3} MiB/sec.</value>
</data>
<data name="Summary" xml:space="preserve">
<value>Summary</value>
</data>
<data name="_0_sectors_took_less_than_3_ms" xml:space="preserve">
<value>{0} sectors took less than 3 ms.</value>
</data>
<data name="_0_sectors_took_less_than_10_ms_but_more_than_3_ms" xml:space="preserve">
<value>{0} sectors took less than 10 ms but more than 3 ms.</value>
</data>
<data name="_0_sectors_took_less_than_50_ms_but_more_than_10_ms" xml:space="preserve">
<value>{0} sectors took less than 50 ms but more than 10 ms.</value>
</data>
<data name="_0_sectors_took_less_than_150_ms_but_more_than_50_ms" xml:space="preserve">
<value>{0} sectors took less than 150 ms but more than 50 ms.</value>
</data>
<data name="_0_sectors_took_less_than_500_ms_but_more_than_150_ms" xml:space="preserve">
<value>{0} sectors took less than 500 ms but more than 150 ms.</value>
</data>
<data name="_0_sectors_took_more_than_500_ms" xml:space="preserve">
<value>{0} sectors took more than 500 ms.</value>
</data>
<data name="_0_sectors_could_not_be_read" xml:space="preserve">
<value>{0} sectors could not be read.</value>
</data>
<data name="Sector_0_could_not_be_read" xml:space="preserve">
<value>Sector {0} could not be read</value>
</data>
<data name="Testing_0_seeks_longest_seek_took_1_ms_fastest_one_took_2_ms_3_ms_average" xml:space="preserve">
<value>Testing {0} seeks, longest seek took {1:F3} ms, fastest one took {2:F3} ms. ({3:F3} ms average)</value>
</data>
<data name="Whole_device" xml:space="preserve">
<value>Whole device</value>
</data>
</root>

3361
Aaru.Localization/UI.Designer.cs generated Normal file

File diff suppressed because it is too large Load Diff

1728
Aaru.Localization/UI.resx Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -44,6 +44,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aaru.Decryption", "Aaru.Dec
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aaru.Archives", "Aaru.Archives\Aaru.Archives.csproj", "{282271D0-CCC2-4ED7-BA38-EC06A84BB974}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Aaru.Archives", "Aaru.Archives\Aaru.Archives.csproj", "{282271D0-CCC2-4ED7-BA38-EC06A84BB974}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aaru.Localization", "Aaru.Localization\Aaru.Localization.csproj", "{90B96C70-F449-4B83-9DC7-F69150806F9B}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@@ -220,6 +222,14 @@ Global
{282271D0-CCC2-4ED7-BA38-EC06A84BB974}.Release|Any CPU.Build.0 = Release|Any CPU {282271D0-CCC2-4ED7-BA38-EC06A84BB974}.Release|Any CPU.Build.0 = Release|Any CPU
{282271D0-CCC2-4ED7-BA38-EC06A84BB974}.Release|x86.ActiveCfg = Release|Any CPU {282271D0-CCC2-4ED7-BA38-EC06A84BB974}.Release|x86.ActiveCfg = Release|Any CPU
{282271D0-CCC2-4ED7-BA38-EC06A84BB974}.Release|x86.Build.0 = Release|Any CPU {282271D0-CCC2-4ED7-BA38-EC06A84BB974}.Release|x86.Build.0 = Release|Any CPU
{90B96C70-F449-4B83-9DC7-F69150806F9B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{90B96C70-F449-4B83-9DC7-F69150806F9B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{90B96C70-F449-4B83-9DC7-F69150806F9B}.Debug|x86.ActiveCfg = Debug|Any CPU
{90B96C70-F449-4B83-9DC7-F69150806F9B}.Debug|x86.Build.0 = Debug|Any CPU
{90B96C70-F449-4B83-9DC7-F69150806F9B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{90B96C70-F449-4B83-9DC7-F69150806F9B}.Release|Any CPU.Build.0 = Release|Any CPU
{90B96C70-F449-4B83-9DC7-F69150806F9B}.Release|x86.ActiveCfg = Release|Any CPU
{90B96C70-F449-4B83-9DC7-F69150806F9B}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View File

@@ -104,6 +104,7 @@
<ProjectReference Include="..\Aaru.Helpers\Aaru.Helpers.csproj"/> <ProjectReference Include="..\Aaru.Helpers\Aaru.Helpers.csproj"/>
<ProjectReference Include="..\Aaru.Images\Aaru.Images.csproj"/> <ProjectReference Include="..\Aaru.Images\Aaru.Images.csproj"/>
<ProjectReference Include="..\Aaru.CommonTypes\Aaru.CommonTypes.csproj"/> <ProjectReference Include="..\Aaru.CommonTypes\Aaru.CommonTypes.csproj"/>
<ProjectReference Include="..\Aaru.Localization\Aaru.Localization.csproj"/>
<ProjectReference Include="..\Aaru.Partitions\Aaru.Partitions.csproj"/> <ProjectReference Include="..\Aaru.Partitions\Aaru.Partitions.csproj"/>
<ProjectReference Include="..\Aaru.Filesystems\Aaru.Filesystems.csproj"/> <ProjectReference Include="..\Aaru.Filesystems\Aaru.Filesystems.csproj"/>
<ProjectReference Include="..\Aaru.Decoders\Aaru.Decoders.csproj"/> <ProjectReference Include="..\Aaru.Decoders\Aaru.Decoders.csproj"/>

View File

@@ -32,12 +32,13 @@
// ****************************************************************************/ // ****************************************************************************/
using System.CommandLine; using System.CommandLine;
using Aaru.Localization;
namespace Aaru.Commands.Archive; namespace Aaru.Commands.Archive;
sealed class ArchiveFamily : Command sealed class ArchiveFamily : Command
{ {
internal ArchiveFamily() : base("archive", "Commands to manage archive files") internal ArchiveFamily() : base("archive", UI.Archive_Command_Family_Description)
{ {
AddAlias("arc"); AddAlias("arc");

View File

@@ -36,13 +36,14 @@ using System.CommandLine.NamingConventionBinder;
using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Enums;
using Aaru.Console; using Aaru.Console;
using Aaru.Core; using Aaru.Core;
using Aaru.Localization;
using Spectre.Console; using Spectre.Console;
namespace Aaru.Commands.Archive; namespace Aaru.Commands.Archive;
sealed class ArchiveInfoCommand : Command sealed class ArchiveInfoCommand : Command
{ {
public ArchiveInfoCommand() : base("info", "Identifies an archive file and shows information about it.") public ArchiveInfoCommand() : base("info", UI.Archive_Info_Command_Description)
{ {
AddArgument(new Argument<string> AddArgument(new Argument<string>
{ {

View File

@@ -35,6 +35,7 @@ using System.CommandLine;
using System.CommandLine.NamingConventionBinder; using System.CommandLine.NamingConventionBinder;
using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Enums;
using Aaru.Console; using Aaru.Console;
using Aaru.Localization;
using Aaru.Settings; using Aaru.Settings;
using Spectre.Console; using Spectre.Console;
@@ -42,7 +43,7 @@ namespace Aaru.Commands;
sealed class ConfigureCommand : Command sealed class ConfigureCommand : Command
{ {
public ConfigureCommand() : base("configure", "Configures user settings and statistics.") => public ConfigureCommand() : base("configure", UI.Configure_Command_Description) =>
Handler = CommandHandler.Create((Func<bool, bool, int>)Invoke); Handler = CommandHandler.Create((Func<bool, bool, int>)Invoke);
int Invoke(bool debug, bool verbose) int Invoke(bool debug, bool verbose)
@@ -81,112 +82,72 @@ sealed class ConfigureCommand : Command
{ {
if(gdprChange) if(gdprChange)
{ {
AaruConsole. AaruConsole.WriteLine(UI.GDPR_Compliance);
WriteLine("In compliance with the [bold]European Union General Data Protection Regulation 2016/679 ([italic]GDPR[/])[/],\n" +
"we must give you the following information about [italic]Aaru[/] and ask if you want to opt-in\n" +
"in some information sharing.");
AaruConsole.WriteLine(); AaruConsole.WriteLine();
AaruConsole. AaruConsole.WriteLine(UI.GDPR_Open_Source_Disclaimer);
WriteLine("Disclaimer: Because [italic]Aaru[/] is an open source software this information, and therefore,\n" +
"compliance with [bold]GDPR[/] only holds true if you obtained a certificated copy from its original\n" +
"authors. In case of doubt, close [italic]Aaru[/] now and ask in our IRC support channel.");
AaruConsole.WriteLine(); AaruConsole.WriteLine();
AaruConsole. AaruConsole.WriteLine(UI.GDPR_Information_sharing);
WriteLine("For any information sharing your IP address may be stored in our server, in a way that is not\n" +
"possible for any person, manual, or automated process, to link with your identity, unless\n" +
"specified otherwise.");
} }
var pressedKey = new ConsoleKeyInfo();
AaruConsole.WriteLine(); AaruConsole.WriteLine();
AaruConsole. AaruConsole.WriteLine(UI.Configure_enable_decryption_disclaimer);
WriteLine("Do you want to enable the decryption of copy protected media (also known as [italic]DRM[/]),\n" +
"like for example [italic]DVD Video CSS[/] encryption.\n" +
"[bold]Consult your local laws before enabling it, as this is illegal in some countries, or\n" +
"only legal under some circumstances[/].");
while(pressedKey.Key != ConsoleKey.Y && Settings.Settings.Current.EnableDecryption =
pressedKey.Key != ConsoleKey.N) AnsiConsole.Confirm($"[italic]{UI.Do_you_want_to_enable_decryption_of_copy_protected_media_Q}[/]");
{
AaruConsole.
Write("[italic]Do you want to enable decryption of copy protected media?[/] [bold]([green]Y[/]/[red]N[/]):[/] ");
Settings.Settings.Current.EnableDecryption = AnsiConsole.Confirm(string.Format("[italic]{0}[/]", "Do you want to enable decryption of copy protected media?"));
#region Device reports #region Device reports
AaruConsole.WriteLine(); AaruConsole.WriteLine();
AaruConsole. AaruConsole.WriteLine(UI.Configure_Device_Report_information_disclaimer);
WriteLine(
"With the 'device-report' command, [italic]Aaru[/] creates a report of a device, that includes its\n" +
"manufacturer, model, firmware revision and/or version, attached bus, size, and supported commands.\n" +
"The serial number of the device is not stored in the report. If used with the debug parameter,\n" +
"extra information about the device will be stored in the report. This information is known to contain\n" +
"the device serial number in non-standard places that prevent the automatic removal of it on a handful\n" +
"of devices. A human-readable copy of the report in XML format is always created in the same directory\n" +
"where [italic]Aaru[/] is being run from.");
while(pressedKey.Key != ConsoleKey.Y && Settings.Settings.Current.SaveReportsGlobally = AnsiConsole.Confirm($"[italic]{UI.
pressedKey.Key != ConsoleKey.N) Configure_Do_you_want_to_save_device_reports_in_shared_folder_of_your_computer_Q}[/]");
{
AaruConsole.
Write("[italic]Do you want to save device reports in shared folder of your computer? [bold]([green]Y[/]/[red]N[/]):[/] ");
Settings.Settings.Current.SaveReportsGlobally = AnsiConsole.Confirm(string.Format("[italic]{0}[/]", "Do you want to save device reports in shared folder of your computer?"));
Settings.Settings.Current.SaveReportsGlobally = pressedKey.Key == ConsoleKey.Y;
pressedKey = new ConsoleKeyInfo();
AaruConsole.WriteLine(); AaruConsole.WriteLine();
AaruConsole. AaruConsole.WriteLine(UI.Configure_share_report_disclaimer);
WriteLine("Sharing a report with us will send it to our server, that's in the european union territory, where it\n" +
"will be manually analyzed by an european union citizen to remove any trace of personal identification\n" +
"from it. Once that is done, it will be shared in our stats website, [italic][blue]https://www.aaru.app[/][/]\n" +
"These report will be used to improve [italic]Aaru[/] support, and in some cases, to provide emulation of the\n" +
"devices to other open-source projects. In any case, no information linking the report to you will be stored.");
Settings.Settings.Current.ShareReports = AnsiConsole.Confirm(string.Format("[italic]{0}[/]", "Do you want to share your device reports with us?")); Settings.Settings.Current.ShareReports =
AnsiConsole.Confirm($"[italic]{UI.Do_you_want_to_share_your_device_reports_with_us_Q}[/]");
#endregion Device reports #endregion Device reports
#region Statistics #region Statistics
AaruConsole.WriteLine(); AaruConsole.WriteLine();
AaruConsole. AaruConsole.WriteLine(UI.Statistics_disclaimer);
WriteLine("[italic]Aaru[/] can store some usage statistics. These statistics are limited to the number of times a\n" +
"command is executed, a filesystem, partition, or device is used, the operating system version, and other.\n" +
"In no case, any information besides pure statistical usage numbers is stored, and they're just joint to the\n" +
"pool with no way of using them to identify you.");
if(AnsiConsole.Confirm(string.Format("[italic]{0}[/]", "Do you want to save stats about your Aaru usage?"))) if(AnsiConsole.Confirm($"[italic]{UI.Do_you_want_to_save_stats_about_your_Aaru_usage_Q}[/]"))
{ {
Settings.Settings.Current.Stats = new StatsSettings(); Settings.Settings.Current.Stats = new StatsSettings
{
Settings.Settings.Current.Stats.ShareStats = AnsiConsole.Confirm(string.Format("[italic]{0}[/]", "Do you want to share your stats (anonymously)?")); ShareStats = AnsiConsole.Confirm($"[italic]{UI.Do_you_want_to_share_your_stats__anonymously_Q}[/]"),
CommandStats =
Settings.Settings.Current.Stats.CommandStats = AnsiConsole.Confirm(string.Format("[italic]{0}[/]", "Do you want to gather statistics about command usage?")); AnsiConsole.Confirm($"[italic]{UI.Do_you_want_to_gather_statistics_about_command_usage_Q}[/]"),
DeviceStats =
Settings.Settings.Current.Stats.DeviceStats = AnsiConsole.Confirm(string.Format("[italic]{0}[/]", "Do you want to gather statistics about found devices?")); AnsiConsole.Confirm($"[italic]{UI.Do_you_want_to_gather_statistics_about_found_devices_Q}[/]"),
FilesystemStats =
Settings.Settings.Current.Stats.FilesystemStats = AnsiConsole.Confirm(string.Format("[italic]{0}[/]", "Do you want to gather statistics about found filesystems?")); AnsiConsole.Confirm($"[italic]{UI.Do_you_want_to_gather_statistics_about_found_filesystems_Q}[/]"),
FilterStats =
Settings.Settings.Current.Stats.FilterStats = AnsiConsole.Confirm(string.Format("[italic]{0}[/]", "Do you want to gather statistics about found file filters?")); AnsiConsole.Confirm($"[italic]{UI.Do_you_want_to_gather_statistics_about_found_file_filters_Q}[/]"),
MediaImageStats =
Settings.Settings.Current.Stats.MediaImageStats = AnsiConsole.Confirm(string.Format("[italic]{0}[/]", "Do you want to gather statistics about found media image formats?")); AnsiConsole.Confirm($"[italic]{UI.Do_you_want_to_gather_statistics_about_found_media_image_formats_Q
}[/]"),
Settings.Settings.Current.Stats.MediaScanStats = AnsiConsole.Confirm(string.Format("[italic]{0}[/]", "Do you want to gather statistics about scanned media?")); MediaScanStats =
AnsiConsole.Confirm($"[italic]{UI.Do_you_want_to_gather_statistics_about_scanned_media_Q}[/]"),
Settings.Settings.Current.Stats.PartitionStats = AnsiConsole.Confirm(string.Format("[italic]{0}[/]", "Do you want to gather statistics about found partitioning schemes?")); PartitionStats =
AnsiConsole.Confirm($"[italic]{UI.
Settings.Settings.Current.Stats.MediaStats = AnsiConsole.Confirm(string.Format("[italic]{0}[/]", "Do you want to gather statistics about media types?")); Do_you_want_to_gather_statistics_about_found_partitioning_schemes_Q}[/]"),
MediaStats =
Settings.Settings.Current.Stats.VerifyStats = AnsiConsole.Confirm(string.Format("[italic]{0}[/]", "Do you want to gather statistics about media image verifications?")); AnsiConsole.Confirm($"[italic]{UI.Do_you_want_to_gather_statistics_about_media_types_Q}[/]"),
VerifyStats =
AnsiConsole.Confirm($"[italic]{UI.Do_you_want_to_gather_statistics_about_media_image_verifications_Q
}[/]")
};
} }
else else
Settings.Settings.Current.Stats = null; Settings.Settings.Current.Stats = null;

View File

@@ -31,13 +31,13 @@
// ****************************************************************************/ // ****************************************************************************/
using System.CommandLine; using System.CommandLine;
using Aaru.Localization;
namespace Aaru.Commands.Database; namespace Aaru.Commands.Database;
sealed class DatabaseFamily : Command sealed class DatabaseFamily : Command
{ {
internal DatabaseFamily(bool mainDbUpdate) : base("database", internal DatabaseFamily(bool mainDbUpdate) : base("database", UI.Database_Command_Family_Description)
"Commands to manage the device and statistics database")
{ {
AddAlias("db"); AddAlias("db");

View File

@@ -36,6 +36,7 @@ using Aaru.CommonTypes.Enums;
using Aaru.Console; using Aaru.Console;
using Aaru.Database; using Aaru.Database;
using Aaru.Database.Models; using Aaru.Database.Models;
using Aaru.Localization;
using Spectre.Console; using Spectre.Console;
using Command = System.CommandLine.Command; using Command = System.CommandLine.Command;
@@ -43,7 +44,7 @@ namespace Aaru.Commands.Database;
sealed class StatisticsCommand : Command sealed class StatisticsCommand : Command
{ {
public StatisticsCommand() : base("stats", "Shows statistics.") => public StatisticsCommand() : base("stats", UI.Database_Stats_Command_Description) =>
Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke))); Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke)));
public static int Invoke(bool debug, bool verbose) public static int Invoke(bool debug, bool verbose)
@@ -85,7 +86,7 @@ sealed class StatisticsCommand : Command
!ctx.Partitions.Any() && !ctx.Partitions.Any() &&
!ctx.SeenDevices.Any()) !ctx.SeenDevices.Any())
{ {
AaruConsole.WriteLine("There are no statistics."); AaruConsole.WriteLine(UI.There_are_no_statistics);
return (int)ErrorNumber.NothingFound; return (int)ErrorNumber.NothingFound;
} }
@@ -97,11 +98,11 @@ sealed class StatisticsCommand : Command
{ {
table = new Table table = new Table
{ {
Title = new TableTitle("Commands statistics") Title = new TableTitle(UI.Commands_statistics)
}; };
table.AddColumn("Command"); table.AddColumn(UI.Title_Command);
table.AddColumn("Times used"); table.AddColumn(UI.Title_Times_used);
table.Columns[1].RightAligned(); table.Columns[1].RightAligned();
if(ctx.Commands.Any(c => c.Name == "analyze")) if(ctx.Commands.Any(c => c.Name == "analyze"))
@@ -154,11 +155,11 @@ sealed class StatisticsCommand : Command
{ {
table = new Table table = new Table
{ {
Title = new TableTitle("Filters statistics") Title = new TableTitle(UI.Filters_statistics)
}; };
table.AddColumn("Filter"); table.AddColumn(UI.Title_Filter);
table.AddColumn("Times found"); table.AddColumn(UI.Title_Times_used);
table.Columns[1].RightAligned(); table.Columns[1].RightAligned();
foreach(string filter in ctx.Filters.Select(c => c.Name).Distinct().OrderBy(c => c)) foreach(string filter in ctx.Filters.Select(c => c.Name).Distinct().OrderBy(c => c))
@@ -183,11 +184,11 @@ sealed class StatisticsCommand : Command
{ {
table = new Table table = new Table
{ {
Title = new TableTitle("Media image format statistics") Title = new TableTitle(UI.Media_image_format_statistics)
}; };
table.AddColumn("Format"); table.AddColumn(UI.Title_Format);
table.AddColumn("Times found"); table.AddColumn(UI.Title_Times_used);
table.Columns[1].RightAligned(); table.Columns[1].RightAligned();
foreach(string format in ctx.MediaFormats.Select(c => c.Name).Distinct().OrderBy(c => c)) foreach(string format in ctx.MediaFormats.Select(c => c.Name).Distinct().OrderBy(c => c))
@@ -212,11 +213,11 @@ sealed class StatisticsCommand : Command
{ {
table = new Table table = new Table
{ {
Title = new TableTitle("Partitioning scheme statistics") Title = new TableTitle(UI.Partitioning_scheme_statistics)
}; };
table.AddColumn("Scheme"); table.AddColumn(UI.Title_Scheme);
table.AddColumn("Times found"); table.AddColumn(UI.Title_Times_used);
table.Columns[1].RightAligned(); table.Columns[1].RightAligned();
foreach(string partition in ctx.Partitions.Select(c => c.Name).Distinct().OrderBy(c => c)) foreach(string partition in ctx.Partitions.Select(c => c.Name).Distinct().OrderBy(c => c))
@@ -241,11 +242,11 @@ sealed class StatisticsCommand : Command
{ {
table = new Table table = new Table
{ {
Title = new TableTitle("Filesystem statistics") Title = new TableTitle(UI.Filesystem_statistics)
}; };
table.AddColumn("Filesystem"); table.AddColumn(UI.Title_Filesystem);
table.AddColumn("Times found"); table.AddColumn(UI.Title_Times_used);
table.Columns[1].RightAligned(); table.Columns[1].RightAligned();
foreach(string filesystem in ctx.Filesystems.Select(c => c.Name).Distinct().OrderBy(c => c)) foreach(string filesystem in ctx.Filesystems.Select(c => c.Name).Distinct().OrderBy(c => c))
@@ -270,13 +271,13 @@ sealed class StatisticsCommand : Command
{ {
table = new Table table = new Table
{ {
Title = new TableTitle("Device statistics") Title = new TableTitle(UI.Device_statistics)
}; };
table.AddColumn("Manufacturer"); table.AddColumn(UI.Title_Manufacturer);
table.AddColumn("Model"); table.AddColumn(UI.Title_Model);
table.AddColumn("Revision"); table.AddColumn(UI.Title_Revision);
table.AddColumn("Bus"); table.AddColumn(UI.Title_Bus);
foreach(DeviceStat ds in ctx.SeenDevices.OrderBy(ds => ds.Manufacturer).ThenBy(ds => ds.Model). foreach(DeviceStat ds in ctx.SeenDevices.OrderBy(ds => ds.Manufacturer).ThenBy(ds => ds.Model).
ThenBy(ds => ds.Revision).ThenBy(ds => ds.Bus)) ThenBy(ds => ds.Revision).ThenBy(ds => ds.Bus))
@@ -292,11 +293,11 @@ sealed class StatisticsCommand : Command
{ {
table = new Table table = new Table
{ {
Title = new TableTitle("Media found in real device statistics") Title = new TableTitle(UI.Media_found_in_real_device_statistics)
}; };
table.AddColumn("Type"); table.AddColumn(UI.Title_Type_for_media);
table.AddColumn("Times found"); table.AddColumn(UI.Title_Times_used);
table.Columns[1].RightAligned(); table.Columns[1].RightAligned();
foreach(string media in ctx.Medias.Where(ms => ms.Real).Select(ms => ms.Type).Distinct().OrderBy(ms => ms)) foreach(string media in ctx.Medias.Where(ms => ms.Real).Select(ms => ms.Type).Distinct().OrderBy(ms => ms))
@@ -322,11 +323,11 @@ sealed class StatisticsCommand : Command
{ {
table = new Table table = new Table
{ {
Title = new TableTitle("Media found in images statistics") Title = new TableTitle(UI.Media_found_in_images_statistics)
}; };
table.AddColumn("Type"); table.AddColumn(UI.Title_Type_for_media);
table.AddColumn("Times found"); table.AddColumn(UI.Title_Times_used);
table.Columns[1].RightAligned(); table.Columns[1].RightAligned();
foreach(string media in ctx.Medias.Where(ms => !ms.Real).Select(ms => ms.Type).Distinct().OrderBy(ms => ms)) foreach(string media in ctx.Medias.Where(ms => !ms.Real).Select(ms => ms.Type).Distinct().OrderBy(ms => ms))
@@ -349,7 +350,7 @@ sealed class StatisticsCommand : Command
} }
if(!thereAreStats) if(!thereAreStats)
AaruConsole.WriteLine("There are no statistics."); AaruConsole.WriteLine(UI.There_are_no_statistics);
return (int)ErrorNumber.NoError; return (int)ErrorNumber.NoError;
} }

View File

@@ -39,6 +39,7 @@ using Aaru.CommonTypes.Enums;
using Aaru.Console; using Aaru.Console;
using Aaru.Core; using Aaru.Core;
using Aaru.Database; using Aaru.Database;
using Aaru.Localization;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Spectre.Console; using Spectre.Console;
@@ -48,12 +49,12 @@ sealed class UpdateCommand : Command
{ {
readonly bool _mainDbUpdate; readonly bool _mainDbUpdate;
public UpdateCommand(bool mainDbUpdate) : base("update", "Updates the database.") public UpdateCommand(bool mainDbUpdate) : base("update", UI.Database_Update_Command_Description)
{ {
_mainDbUpdate = mainDbUpdate; _mainDbUpdate = mainDbUpdate;
Add(new Option<bool>("--clear", () => false, "Clear existing main database.")); Add(new Option<bool>("--clear", () => false, UI.Clear_existing_main_database));
Add(new Option<bool>("--clear-all", () => false, "Clear existing main and local database.")); Add(new Option<bool>("--clear-all", () => false, UI.Clear_existing_main_and_local_database));
Handler = CommandHandler.Create((Func<bool, bool, bool, bool, int>)Invoke); Handler = CommandHandler.Create((Func<bool, bool, bool, bool, int>)Invoke);
} }
@@ -107,7 +108,7 @@ sealed class UpdateCommand : Command
if(Debugger.IsAttached) if(Debugger.IsAttached)
throw; throw;
AaruConsole.ErrorWriteLine("Could not remove local database."); AaruConsole.ErrorWriteLine(UI.Could_not_remove_local_database);
return (int)ErrorNumber.CannotRemoveDatabase; return (int)ErrorNumber.CannotRemoveDatabase;
} }
@@ -122,7 +123,7 @@ sealed class UpdateCommand : Command
if(Debugger.IsAttached) if(Debugger.IsAttached)
throw; throw;
AaruConsole.ErrorWriteLine("Could not remove main database."); AaruConsole.ErrorWriteLine(UI.Could_not_remove_main_database);
return (int)ErrorNumber.CannotRemoveDatabase; return (int)ErrorNumber.CannotRemoveDatabase;
} }

View File

@@ -31,12 +31,13 @@
// ****************************************************************************/ // ****************************************************************************/
using System.CommandLine; using System.CommandLine;
using Aaru.Localization;
namespace Aaru.Commands.Device; namespace Aaru.Commands.Device;
sealed class DeviceFamily : Command sealed class DeviceFamily : Command
{ {
public DeviceFamily() : base("device", "Commands that talks to devices") public DeviceFamily() : base("device", UI.Device_Command_Family_Description)
{ {
AddAlias("dev"); AddAlias("dev");

View File

@@ -49,6 +49,7 @@ using Aaru.Database.Models;
using Aaru.Decoders.SCSI; using Aaru.Decoders.SCSI;
using Aaru.Decoders.SCSI.MMC; using Aaru.Decoders.SCSI.MMC;
using Aaru.Helpers; using Aaru.Helpers;
using Aaru.Localization;
using Newtonsoft.Json; using Newtonsoft.Json;
using Spectre.Console; using Spectre.Console;
using Command = System.CommandLine.Command; using Command = System.CommandLine.Command;
@@ -59,19 +60,19 @@ namespace Aaru.Commands.Device;
sealed class DeviceReportCommand : Command sealed class DeviceReportCommand : Command
{ {
public DeviceReportCommand() : base("report", "Tests the device capabilities and creates an JSON report of them.") public DeviceReportCommand() : base("report", UI.Device_Report_Command_Description)
{ {
AddArgument(new Argument<string> AddArgument(new Argument<string>
{ {
Arity = ArgumentArity.ExactlyOne, Arity = ArgumentArity.ExactlyOne,
Description = "Device path", Description = UI.Device_path,
Name = "device-path" Name = "device-path"
}); });
Add(new Option<bool>(new[] Add(new Option<bool>(new[]
{ {
"--trap-disc", "-t" "--trap-disc", "-t"
}, () => false, "Does a device report using a trap disc.")); }, () => false, UI.Device_report_using_trap_disc));
Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke))); Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke)));
} }
@@ -122,7 +123,7 @@ sealed class DeviceReportCommand : Command
switch(dev) switch(dev)
{ {
case null: case null:
AaruConsole.ErrorWriteLine($"Could not open device, error {devErrno}."); AaruConsole.ErrorWriteLine(string.Format(UI.Could_not_open_device_error_0, devErrno));
return (int)devErrno; return (int)devErrno;
case Devices.Remote.Device remoteDev: case Devices.Remote.Device remoteDev:
@@ -146,10 +147,9 @@ sealed class DeviceReportCommand : Command
if(!isAdmin) if(!isAdmin)
{ {
AaruConsole. AaruConsole.ErrorWriteLine(UI.Device_report_must_be_run_as_admin);
ErrorWriteLine("Because of the commands sent to a device, device report must be run with administrative privileges.");
AaruConsole.ErrorWriteLine("Not continuing."); AaruConsole.ErrorWriteLine(UI.Not_continuing);
return (int)ErrorNumber.NotPermitted; return (int)ErrorNumber.NotPermitted;
} }
@@ -190,7 +190,7 @@ sealed class DeviceReportCommand : Command
if(trapDisc && dev.ScsiType != PeripheralDeviceTypes.MultiMediaDevice) if(trapDisc && dev.ScsiType != PeripheralDeviceTypes.MultiMediaDevice)
{ {
AaruConsole.ErrorWriteLine("This device type does not support doing reports with trap discs."); AaruConsole.ErrorWriteLine(UI.Device_does_not_report_with_trap_discs);
return (int)ErrorNumber.InvalidArgument; return (int)ErrorNumber.InvalidArgument;
} }
@@ -198,22 +198,21 @@ sealed class DeviceReportCommand : Command
var reporter = new DeviceReport(dev); var reporter = new DeviceReport(dev);
if(dev.IsUsb) if(dev.IsUsb)
if(AnsiConsole.Confirm("[italic]Is the device natively USB (in case of doubt, press Y)?[/]")) if(AnsiConsole.Confirm($"[italic]{UI.Is_the_device_natively_USB}[/]"))
{ {
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Querying USB information...").IsIndeterminate(); ctx.AddTask(Localization.Core.Querying_USB_information).IsIndeterminate();
report.USB = reporter.UsbReport(); report.USB = reporter.UsbReport();
}); });
report.USB.RemovableMedia = report.USB.RemovableMedia = AnsiConsole.Confirm($"[italic]{UI.Is_the_media_removable}[/]");
AnsiConsole.Confirm("[italic]Is the media removable from the reading/writing elements?[/]");
removable = report.USB.RemovableMedia; removable = report.USB.RemovableMedia;
} }
if(dev.IsFireWire) if(dev.IsFireWire)
if(AnsiConsole.Confirm("[italic]Is the device natively FireWire (in case of doubt, press Y)?[/]")) if(AnsiConsole.Confirm($"[italic]{UI.Is_the_device_natively_FireWire}[/]"))
{ {
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
@@ -221,8 +220,7 @@ sealed class DeviceReportCommand : Command
report.FireWire = reporter.FireWireReport(); report.FireWire = reporter.FireWireReport();
}); });
report.FireWire.RemovableMedia = report.FireWire.RemovableMedia = AnsiConsole.Confirm($"[italic]{UI.Is_the_media_removable}[/]");
AnsiConsole.Confirm("[italic]Is the media removable from the reading/writing elements?[/]");
removable = report.FireWire.RemovableMedia; removable = report.FireWire.RemovableMedia;
} }
@@ -230,7 +228,7 @@ sealed class DeviceReportCommand : Command
if(dev.IsPcmcia) if(dev.IsPcmcia)
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Querying PCMCIA information...").IsIndeterminate(); ctx.AddTask(Localization.Core.Querying_PCMCIA_information).IsIndeterminate();
report.PCMCIA = reporter.PcmciaReport(); report.PCMCIA = reporter.PcmciaReport();
}); });
@@ -244,7 +242,7 @@ sealed class DeviceReportCommand : Command
{ {
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Querying ATA IDENTIFY...").IsIndeterminate(); ctx.AddTask(Localization.Core.Querying_ATA_IDENTIFY).IsIndeterminate();
dev.AtaIdentify(out buffer, out _, dev.Timeout, out _); dev.AtaIdentify(out buffer, out _, dev.Timeout, out _);
}); });
@@ -267,33 +265,31 @@ sealed class DeviceReportCommand : Command
else if(!removable && else if(!removable &&
report.ATA.IdentifyDevice?.GeneralConfiguration.HasFlag(Identify.GeneralConfigurationBit. report.ATA.IdentifyDevice?.GeneralConfiguration.HasFlag(Identify.GeneralConfigurationBit.
Removable) == true) Removable) == true)
removable = removable = AnsiConsole.Confirm($"[italic]{UI.Is_the_media_removable}[/]");
AnsiConsole.Confirm("[italic]Is the media removable from the reading/writing elements?[/]");
if(removable) if(removable)
{ {
AaruConsole.WriteLine("Please remove any media from the device and press any key when it is out."); AaruConsole.WriteLine(UI.Please_remove_any_media);
System.Console.ReadKey(true); System.Console.ReadKey(true);
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Querying ATA IDENTIFY...").IsIndeterminate(); ctx.AddTask(Localization.Core.Querying_ATA_IDENTIFY).IsIndeterminate();
dev.AtaIdentify(out buffer, out _, dev.Timeout, out _); dev.AtaIdentify(out buffer, out _, dev.Timeout, out _);
}); });
report.ATA.Identify = DeviceReport.ClearIdentify(buffer); report.ATA.Identify = DeviceReport.ClearIdentify(buffer);
List<TestedMedia> mediaTests = new(); List<TestedMedia> mediaTests = new();
while(AnsiConsole.Confirm("[italic]Do you have media that you can insert in the drive?[/]")) while(AnsiConsole.Confirm($"[italic]{UI.Do_you_have_media_you_can_insert}[/]"))
{ {
AaruConsole.WriteLine("Please insert it in the drive and press any key when it is ready."); AaruConsole.WriteLine(UI.Please_insert_it_in_the_drive);
System.Console.ReadKey(true); System.Console.ReadKey(true);
mediumTypeName = mediumTypeName = AnsiConsole.Ask<string>(UI.Please_write_description_of_media_type);
AnsiConsole.Ask<string>("Please write a description of the media type and press enter: ");
mediumModel = AnsiConsole.Ask<string>("Please write the media model and press enter: "); mediumModel = AnsiConsole.Ask<string>(UI.Please_write_media_model);
TestedMedia mediaTest = reporter.ReportAtaMedia(); TestedMedia mediaTest = reporter.ReportAtaMedia();
mediaTest.MediumTypeName = mediumTypeName; mediaTest.MediumTypeName = mediumTypeName;
@@ -318,11 +314,11 @@ sealed class DeviceReportCommand : Command
report.SecureDigital = reporter.MmcSdReport(); report.SecureDigital = reporter.MmcSdReport();
break; break;
case DeviceType.NVMe: throw new NotImplementedException("NVMe devices not yet supported."); case DeviceType.NVMe: throw new NotImplementedException(Localization.Core.NVMe_devices_not_yet_supported);
case DeviceType.ATAPI: case DeviceType.ATAPI:
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Querying ATAPI IDENTIFY...").IsIndeterminate(); ctx.AddTask(Localization.Core.Querying_ATAPI_IDENTIFY).IsIndeterminate();
dev.AtapiIdentify(out buffer, out _, dev.Timeout, out _); dev.AtapiIdentify(out buffer, out _, dev.Timeout, out _);
}); });
@@ -347,7 +343,7 @@ sealed class DeviceReportCommand : Command
case PeripheralDeviceTypes.SCSIZonedBlockDevice: break; case PeripheralDeviceTypes.SCSIZonedBlockDevice: break;
default: default:
{ {
AaruConsole.ErrorWriteLine("Unsupported device type, report cannot be created"); AaruConsole.ErrorWriteLine(UI.Unsupported_device_type_for_report);
throw new IOException(); throw new IOException();
} }
@@ -356,9 +352,7 @@ sealed class DeviceReportCommand : Command
if(!dev.IsUsb && if(!dev.IsUsb &&
!dev.IsFireWire && !dev.IsFireWire &&
dev.IsRemovable) dev.IsRemovable)
removable = removable = AnsiConsole.Confirm($"[italic]{UI.Is_the_media_removable_flash_is_not}[/]");
AnsiConsole.
Confirm("[italic]Is the media removable from the reading/writing elements (flash memories ARE NOT removable)?[/]");
if(removable) if(removable)
{ {
@@ -377,8 +371,7 @@ sealed class DeviceReportCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Asking drive to unload tape (can take a few minutes)..."). ctx.AddTask(UI.Asking_drive_to_unload_tape).IsIndeterminate();
IsIndeterminate();
dev.Unload(out buffer, dev.Timeout, out _); dev.Unload(out buffer, dev.Timeout, out _);
}); });
@@ -386,7 +379,7 @@ sealed class DeviceReportCommand : Command
break; break;
} }
AaruConsole.WriteLine("Please remove any media from the device and press any key when it is out."); AaruConsole.WriteLine(UI.Please_remove_any_media);
System.Console.ReadKey(true); System.Console.ReadKey(true);
} }
@@ -422,26 +415,22 @@ sealed class DeviceReportCommand : Command
{ {
if(iomegaRev) if(iomegaRev)
{ {
AaruConsole. AaruConsole.ErrorWriteLine(UI.Device_does_not_report_with_trap_discs);
ErrorWriteLine("This device type does not support doing reports with trap discs.");
return (int)ErrorNumber.InvalidArgument; return (int)ErrorNumber.InvalidArgument;
} }
if(!AnsiConsole. if(!AnsiConsole.Confirm($"[italic]{UI.Sure_report_trap_disc}[/]"))
Confirm("[italic]Are you sure you want to do a report using a trap disc and the swapping method?\n" +
"This method can damage the drive, or the disc, and requires some ability.\n" +
"In you are unsure, please press N to not continue.[/]"))
return (int)ErrorNumber.NoError; return (int)ErrorNumber.NoError;
if(!AnsiConsole.Confirm("[italic]Do you have an audio trap disc (if unsure press N)?[/]")) if(!AnsiConsole.Confirm($"[italic]{UI.Do_you_have_audio_trap_disc}[/]"))
{ {
AaruConsole.ErrorWriteLine("Please burn an audio trap disc before continuing..."); AaruConsole.ErrorWriteLine(UI.Please_burn_audio_trap_disc);
return (int)ErrorNumber.NoError; return (int)ErrorNumber.NoError;
} }
if(AnsiConsole.Confirm("[italic]Do you have a GD-ROM disc (if unsure press N)?[/]")) if(AnsiConsole.Confirm($"[italic]{UI.Do_you_have_GD_ROM_disc}[/]"))
reporter.ReportGdRomSwapTrick(ref report); reporter.ReportGdRomSwapTrick(ref report);
else else
return (int)ErrorNumber.NoError; return (int)ErrorNumber.NoError;
@@ -702,30 +691,30 @@ sealed class DeviceReportCommand : Command
if(!tryPlextor) if(!tryPlextor)
tryPlextor |= tryPlextor |=
AnsiConsole. AnsiConsole.
Confirm("[italic]Do you have want to try Plextor vendor commands? [red]THIS IS DANGEROUS AND CAN IRREVERSIBLY DESTROY YOUR DRIVE (IF IN DOUBT PRESS 'N')[/][/]", Confirm($"[italic]{UI.Do_you_want_to_try_Plextor_commands} [red]{UI.This_is_dangerous}[/][/]",
false); false);
if(!tryNec) if(!tryNec)
tryNec |= tryNec |=
AnsiConsole. AnsiConsole.
Confirm("[italic]Do you have want to try NEC vendor commands? [red]THIS IS DANGEROUS AND CAN IRREVERSIBLY DESTROY YOUR DRIVE (IF IN DOUBT PRESS 'N')[/][/]", Confirm($"[italic]{UI.Do_you_want_to_try_NEC_commands} [red]{UI.This_is_dangerous}[/][/]",
false); false);
if(!tryPioneer) if(!tryPioneer)
tryPioneer |= tryPioneer |=
AnsiConsole. AnsiConsole.
Confirm("[italic]Do you have want to try Pioneer vendor commands? [red]THIS IS DANGEROUS AND CAN IRREVERSIBLY DESTROY YOUR DRIVE (IF IN DOUBT PRESS 'N')[/][/]", Confirm($"[italic]{UI.Do_you_want_to_try_Pioneer_commands} [red]{UI.This_is_dangerous}[/][/]",
false); false);
if(!tryHldtst) if(!tryHldtst)
tryHldtst |= tryHldtst |=
AnsiConsole. AnsiConsole.
Confirm("[italic]Do you have want to try HL-DT-ST (aka LG) vendor commands? [red]THIS IS DANGEROUS AND CAN IRREVERSIBLY DESTROY YOUR DRIVE (IF IN DOUBT PRESS 'N')[/][/]", Confirm($"[italic]{UI.Do_you_want_to_try_HLDTST_commands} [red]{UI.This_is_dangerous}[/][/]",
false); false);
tryMediaTekF106 = tryMediaTekF106 =
AnsiConsole. AnsiConsole.
Confirm("[italic]Do you have want to try MediaTek vendor command F1h subcommand 06h? [red]THIS IS DANGEROUS AND CAN IRREVERSIBLY DESTROY YOUR DRIVE (IF IN DOUBT PRESS 'N')[/][/]", Confirm($"[italic]{UI.Do_you_want_to_try_MediaTek_commands} [red]{UI.This_is_dangerous}[/][/]",
false); false);
} }
@@ -736,12 +725,11 @@ sealed class DeviceReportCommand : Command
foreach(string mediaType in mediaTypes) foreach(string mediaType in mediaTypes)
{ {
if(!AnsiConsole.Confirm($"[italic]Do you have a {mediaType if(!AnsiConsole.Confirm($"[italic]{string.Format(UI.Do_you_have_a_0_disc, mediaType)
} disc that you can insert in the drive?[/]")) }[/]"))
continue; continue;
AaruConsole. AaruConsole.WriteLine(UI.Please_insert_it_in_the_drive);
WriteLine("Please insert it in the drive and press any key when it is ready.");
System.Console.ReadKey(true); System.Console.ReadKey(true);
@@ -749,7 +737,7 @@ sealed class DeviceReportCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Waiting for drive to become ready").IsIndeterminate(); ctx.AddTask(Localization.Core.Waiting_for_drive_to_become_ready).IsIndeterminate();
sense = dev.ScsiTestUnitReady(out senseBuffer, dev.Timeout, out _); sense = dev.ScsiTestUnitReady(out senseBuffer, dev.Timeout, out _);
if(!sense) if(!sense)
@@ -830,7 +818,7 @@ sealed class DeviceReportCommand : Command
} }
default: default:
AaruConsole.DebugWriteLine("Device-Report command", AaruConsole.DebugWriteLine("Device-Report command",
"Device not ready. Sense {0}h ASC {1:X2}h ASCQ {2:X2}h", Localization.Core.Device_not_ready_Sense,
decSense.Value.SenseKey, decSense.Value.ASC, decSense.Value.SenseKey, decSense.Value.ASC,
decSense.Value.ASCQ); decSense.Value.ASCQ);
@@ -841,7 +829,8 @@ sealed class DeviceReportCommand : Command
else else
{ {
AaruConsole.DebugWriteLine("Device-Report command", AaruConsole.DebugWriteLine("Device-Report command",
"Got sense status but no sense buffer"); Localization.Core.
Got_sense_status_but_no_sense_buffer);
mediaIsRecognized = false; mediaIsRecognized = false;
} }
@@ -859,19 +848,23 @@ sealed class DeviceReportCommand : Command
if((mediaTest.SupportsReadLong == true || mediaTest.SupportsReadLong16 == true) && if((mediaTest.SupportsReadLong == true || mediaTest.SupportsReadLong16 == true) &&
mediaTest.LongBlockSize == mediaTest.BlockSize && mediaTest.LongBlockSize == mediaTest.BlockSize &&
AnsiConsole. AnsiConsole.Confirm($"[italic]{Localization.Core.Try_to_find_SCSI_READ_LONG_size
Confirm("[italic]Drive supports SCSI READ LONG but I cannot find the correct size. Do you want me to try? (This can take hours)[/]")) }[/]"))
AnsiConsole.Progress().AutoClear(true).HideCompleted(true). AnsiConsole.Progress().AutoClear(true).HideCompleted(true).
Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), Columns(new TaskDescriptionColumn(), new ProgressBarColumn(),
new PercentageColumn()).Start(ctx => new PercentageColumn()).Start(ctx =>
{ {
ProgressTask task = ctx.AddTask("Trying to READ LONG..."); ProgressTask task =
ctx.AddTask(Localization.Core.Trying_to_READ_LONG);
task.MaxValue = ushort.MaxValue; task.MaxValue = ushort.MaxValue;
for(ushort i = (ushort)mediaTest.BlockSize;; i++) for(ushort i = (ushort)mediaTest.BlockSize;; i++)
{ {
task.Description = $"Trying to READ LONG with a size of {i task.Description =
} bytes..."; string.
Format(Localization.Core.Trying_READ_LONG_with_size_0,
i);
task.Value = i; task.Value = i;
@@ -899,7 +892,7 @@ sealed class DeviceReportCommand : Command
{ {
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Trying SCSI READ LONG (10)...").IsIndeterminate(); ctx.AddTask(Localization.Core.Trying_SCSI_READ_LONG_10).IsIndeterminate();
sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0,
(ushort)mediaTest.LongBlockSize, dev.Timeout, out _); (ushort)mediaTest.LongBlockSize, dev.Timeout, out _);
@@ -914,7 +907,7 @@ sealed class DeviceReportCommand : Command
{ {
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Trying SCSI READ LONG (16)...").IsIndeterminate(); ctx.AddTask(Localization.Core.Trying_SCSI_READ_LONG_16).IsIndeterminate();
sense = dev.ReadLong16(out buffer, out senseBuffer, false, 0, sense = dev.ReadLong16(out buffer, out senseBuffer, false, 0,
mediaTest.LongBlockSize.Value, dev.Timeout, out _); mediaTest.LongBlockSize.Value, dev.Timeout, out _);
@@ -944,26 +937,24 @@ sealed class DeviceReportCommand : Command
List<TestedSequentialMedia> seqTests = new(); List<TestedSequentialMedia> seqTests = new();
while(AnsiConsole.Confirm("[italic]Do you have media that you can insert in the drive?[/]")) while(AnsiConsole.Confirm($"[italic]{UI.Do_you_have_media_you_can_insert}[/]"))
{ {
AaruConsole.WriteLine("Please insert it in the drive and press any key when it is ready."); AaruConsole.WriteLine(UI.Please_insert_it_in_the_drive);
System.Console.ReadKey(true); System.Console.ReadKey(true);
mediumTypeName = mediumTypeName = AnsiConsole.Ask<string>(UI.Please_write_description_of_media_type);
AnsiConsole.
Ask<string>("Please write a description of the media type and press enter: ");
mediumManufacturer = mediumManufacturer =
AnsiConsole.Ask<string>("Please write the media manufacturer and press enter: "); AnsiConsole.Ask<string>(Localization.Core.Please_write_media_manufacturer);
mediumModel = AnsiConsole.Ask<string>("Please write the media model and press enter: "); mediumModel = AnsiConsole.Ask<string>(UI.Please_write_media_model);
bool mediaIsRecognized = true; bool mediaIsRecognized = true;
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Waiting for drive to become ready").IsIndeterminate(); ctx.AddTask(Localization.Core.Waiting_for_drive_to_become_ready).IsIndeterminate();
sense = dev.ScsiTestUnitReady(out senseBuffer, dev.Timeout, out _); sense = dev.ScsiTestUnitReady(out senseBuffer, dev.Timeout, out _);
AaruConsole.DebugWriteLine("Device reporting", "sense = {0}", sense); AaruConsole.DebugWriteLine("Device reporting", "sense = {0}", sense);
@@ -1046,7 +1037,7 @@ sealed class DeviceReportCommand : Command
} }
default: default:
AaruConsole.DebugWriteLine("Device-Report command", AaruConsole.DebugWriteLine("Device-Report command",
"Device not ready. Sense {0} ASC {1:X2}h ASCQ {2:X2}h", Localization.Core.Device_not_ready_Sense,
decSense.Value.SenseKey, decSense.Value.ASC, decSense.Value.SenseKey, decSense.Value.ASC,
decSense.Value.ASCQ); decSense.Value.ASCQ);
@@ -1057,7 +1048,7 @@ sealed class DeviceReportCommand : Command
else else
{ {
AaruConsole.DebugWriteLine("Device-Report command", AaruConsole.DebugWriteLine("Device-Report command",
"Got sense status but no sense buffer"); Localization.Core.Got_sense_status_but_no_sense_buffer);
mediaIsRecognized = false; mediaIsRecognized = false;
} }
@@ -1077,8 +1068,7 @@ sealed class DeviceReportCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Asking drive to unload tape (can take a few minutes)..."). ctx.AddTask(UI.Asking_drive_to_unload_tape).IsIndeterminate();
IsIndeterminate();
dev.SpcAllowMediumRemoval(out buffer, dev.Timeout, out _); dev.SpcAllowMediumRemoval(out buffer, dev.Timeout, out _);
dev.Unload(out buffer, dev.Timeout, out _); dev.Unload(out buffer, dev.Timeout, out _);
@@ -1095,11 +1085,11 @@ sealed class DeviceReportCommand : Command
{ {
List<string> mediaTypes = new() List<string> mediaTypes = new()
{ {
"MD DATA (140Mb data MiniDisc)", Localization.Core.Media_Type_Name_MMD_140A,
"60 minutes rewritable MiniDisc", Localization.Core.Media_Type_Name_MDW_60,
"74 minutes rewritable MiniDisc", Localization.Core.Media_Type_Name_MDW_74,
"80 minutes rewritable MiniDisc", Localization.Core.Media_Type_Name_MDW_80,
"Embossed Audio MiniDisc" Localization.Core.Media_Type_Name_MiniDisc
}; };
mediaTypes.Sort(); mediaTypes.Sort();
@@ -1108,11 +1098,10 @@ sealed class DeviceReportCommand : Command
foreach(string mediaType in mediaTypes) foreach(string mediaType in mediaTypes)
{ {
if(!AnsiConsole.Confirm($"[italic]Do you have a {mediaType if(!AnsiConsole.Confirm($"[italic]{string.Format(UI.Do_you_have_a_0_disc, mediaType)}[/]"))
} disc that you can insert in the drive?[/]"))
continue; continue;
AaruConsole.WriteLine("Please insert it in the drive and press any key when it is ready."); AaruConsole.WriteLine(UI.Please_insert_it_in_the_drive);
System.Console.ReadKey(true); System.Console.ReadKey(true);
@@ -1120,7 +1109,7 @@ sealed class DeviceReportCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Waiting for drive to become ready").IsIndeterminate(); ctx.AddTask(Localization.Core.Waiting_for_drive_to_become_ready).IsIndeterminate();
sense = dev.ScsiTestUnitReady(out senseBuffer, dev.Timeout, out _); sense = dev.ScsiTestUnitReady(out senseBuffer, dev.Timeout, out _);
@@ -1196,7 +1185,7 @@ sealed class DeviceReportCommand : Command
} }
default: default:
AaruConsole.DebugWriteLine("Device-Report command", AaruConsole.DebugWriteLine("Device-Report command",
"Device not ready. Sense {0}h ASC {1:X2}h ASCQ {2:X2}h", Localization.Core.Device_not_ready_Sense,
decSense.Value.SenseKey, decSense.Value.ASC, decSense.Value.SenseKey, decSense.Value.ASC,
decSense.Value.ASCQ); decSense.Value.ASCQ);
@@ -1207,7 +1196,7 @@ sealed class DeviceReportCommand : Command
else else
{ {
AaruConsole.DebugWriteLine("Device-Report command", AaruConsole.DebugWriteLine("Device-Report command",
"Got sense status but no sense buffer"); Localization.Core.Got_sense_status_but_no_sense_buffer);
mediaIsRecognized = false; mediaIsRecognized = false;
} }
@@ -1224,21 +1213,25 @@ sealed class DeviceReportCommand : Command
if((mediaTest.SupportsReadLong == true || mediaTest.SupportsReadLong16 == true) && if((mediaTest.SupportsReadLong == true || mediaTest.SupportsReadLong16 == true) &&
mediaTest.LongBlockSize == mediaTest.BlockSize && mediaTest.LongBlockSize == mediaTest.BlockSize &&
AnsiConsole. AnsiConsole.Confirm($"[italic]{Localization.Core.Try_to_find_SCSI_READ_LONG_size
Confirm("[italic]Drive supports SCSI READ LONG but I cannot find the correct size. Do you want me to try? (This can take hours)[/]")) }[/]"))
AnsiConsole.Progress().AutoClear(true).HideCompleted(true). AnsiConsole.Progress().AutoClear(true).HideCompleted(true).
Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), Columns(new TaskDescriptionColumn(), new ProgressBarColumn(),
new PercentageColumn()).Start(ctx => new PercentageColumn()).Start(ctx =>
{ {
ProgressTask task = ctx.AddTask("Trying to READ LONG..."); ProgressTask task =
ctx.AddTask(Localization.Core.Trying_to_READ_LONG);
task.MaxValue = ushort.MaxValue; task.MaxValue = ushort.MaxValue;
for(ushort i = (ushort)mediaTest.BlockSize;; i++) for(ushort i = (ushort)mediaTest.BlockSize;; i++)
{ {
task.Value = i; task.Value = i;
task.Description = $"Trying to READ LONG with a size of {i task.Description =
} bytes..."; string.
Format(Localization.Core.Trying_READ_LONG_with_size_0,
i);
sense = mediaTest.SupportsReadLong16 == true sense = mediaTest.SupportsReadLong16 == true
? dev.ReadLong16(out buffer, out senseBuffer, false, ? dev.ReadLong16(out buffer, out senseBuffer, false,
@@ -1265,7 +1258,7 @@ sealed class DeviceReportCommand : Command
{ {
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Trying SCSI READ LONG (10)...").IsIndeterminate(); ctx.AddTask(Localization.Core.Trying_SCSI_READ_LONG_10).IsIndeterminate();
sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0,
(ushort)mediaTest.LongBlockSize, dev.Timeout, out _); (ushort)mediaTest.LongBlockSize, dev.Timeout, out _);
@@ -1280,7 +1273,7 @@ sealed class DeviceReportCommand : Command
{ {
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Trying SCSI READ LONG (16)...").IsIndeterminate(); ctx.AddTask(Localization.Core.Trying_SCSI_READ_LONG_16).IsIndeterminate();
sense = dev.ReadLong16(out buffer, out senseBuffer, false, 0, sense = dev.ReadLong16(out buffer, out senseBuffer, false, 0,
(ushort)mediaTest.LongBlockSize, dev.Timeout, out _); (ushort)mediaTest.LongBlockSize, dev.Timeout, out _);
@@ -1291,15 +1284,16 @@ sealed class DeviceReportCommand : Command
} }
} }
mediaTest.MediumTypeName = mediaType switch if(mediaType == Localization.Core.Media_Type_Name_MMD_140A)
{ mediaTest.MediumTypeName = "MMD-140A";
"MD DATA (140Mb data MiniDisc)" => "MMD-140A", else if(mediaType == Localization.Core.Media_Type_Name_MDW_60)
"60 minutes rewritable MiniDisc" => "MDW-60", mediaTest.MediumTypeName = "MDW-60";
"74 minutes rewritable MiniDisc" => "MDW-74", else if(mediaType == Localization.Core.Media_Type_Name_MDW_74)
"80 minutes rewritable MiniDisc" => "MDW-80", mediaTest.MediumTypeName = "MDW-74";
"Embossed Audio MiniDisc" => "MiniDisc", else if(mediaType == Localization.Core.Media_Type_Name_MDW_80)
_ => mediaTest.MediumTypeName mediaTest.MediumTypeName = "MDW-80";
}; else if(mediaType == Localization.Core.Media_Type_Name_MiniDisc)
mediaTest.MediumTypeName = "MiniDisc";
mediaTest.Manufacturer = "SONY"; mediaTest.Manufacturer = "SONY";
mediaTest.MediaIsRecognized = mediaIsRecognized; mediaTest.MediaIsRecognized = mediaIsRecognized;
@@ -1319,27 +1313,24 @@ sealed class DeviceReportCommand : Command
{ {
List<TestedMedia> mediaTests = new(); List<TestedMedia> mediaTests = new();
while(AnsiConsole.Confirm("[italic]Do you have media that you can insert in the drive?[/]")) while(AnsiConsole.Confirm($"[italic]{UI.Do_you_have_media_you_can_insert}[/]"))
{ {
AaruConsole. AaruConsole.WriteLine(UI.Please_insert_it_in_the_drive);
WriteLine("Please insert it in the drive and press any key when it is ready.");
System.Console.ReadKey(true); System.Console.ReadKey(true);
mediumTypeName = mediumTypeName = AnsiConsole.Ask<string>(UI.Please_write_description_of_media_type);
AnsiConsole.
Ask<string>("Please write a description of the media type and press enter: ");
mediumManufacturer = mediumManufacturer =
AnsiConsole.Ask<string>("Please write the media manufacturer and press enter: "); AnsiConsole.Ask<string>(Localization.Core.Please_write_media_manufacturer);
mediumModel = AnsiConsole.Ask<string>("Please write the media model and press enter: "); mediumModel = AnsiConsole.Ask<string>(UI.Please_write_media_model);
bool mediaIsRecognized = true; bool mediaIsRecognized = true;
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Waiting for drive to become ready").IsIndeterminate(); ctx.AddTask(Localization.Core.Waiting_for_drive_to_become_ready).IsIndeterminate();
sense = dev.ScsiTestUnitReady(out senseBuffer, dev.Timeout, out _); sense = dev.ScsiTestUnitReady(out senseBuffer, dev.Timeout, out _);
if(!sense) if(!sense)
@@ -1407,21 +1398,25 @@ sealed class DeviceReportCommand : Command
if((mediaTest.SupportsReadLong == true || mediaTest.SupportsReadLong16 == true) && if((mediaTest.SupportsReadLong == true || mediaTest.SupportsReadLong16 == true) &&
mediaTest.LongBlockSize == mediaTest.BlockSize && mediaTest.LongBlockSize == mediaTest.BlockSize &&
AnsiConsole. AnsiConsole.Confirm($"[italic]{Localization.Core.Try_to_find_SCSI_READ_LONG_size
Confirm("[italic]Drive supports SCSI READ LONG but I cannot find the correct size. Do you want me to try? (This can take hours)[/]")) }[/]"))
AnsiConsole.Progress().AutoClear(true).HideCompleted(true). AnsiConsole.Progress().AutoClear(true).HideCompleted(true).
Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), Columns(new TaskDescriptionColumn(), new ProgressBarColumn(),
new PercentageColumn()).Start(ctx => new PercentageColumn()).Start(ctx =>
{ {
ProgressTask task = ctx.AddTask("Trying to READ LONG..."); ProgressTask task =
ctx.AddTask(Localization.Core.Trying_to_READ_LONG);
task.MaxValue = ushort.MaxValue; task.MaxValue = ushort.MaxValue;
for(ushort i = (ushort)mediaTest.BlockSize;; i++) for(ushort i = (ushort)mediaTest.BlockSize;; i++)
{ {
task.Value = i; task.Value = i;
task.Description = $"Trying to READ LONG with a size of {i task.Description =
} bytes..."; string.
Format(Localization.Core.Trying_READ_LONG_with_size_0,
i);
sense = mediaTest.SupportsReadLong16 == true sense = mediaTest.SupportsReadLong16 == true
? dev.ReadLong16(out buffer, out senseBuffer, ? dev.ReadLong16(out buffer, out senseBuffer,
@@ -1449,7 +1444,7 @@ sealed class DeviceReportCommand : Command
{ {
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Trying SCSI READ LONG (10)...").IsIndeterminate(); ctx.AddTask(Localization.Core.Trying_SCSI_READ_LONG_10).IsIndeterminate();
sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0,
(ushort)mediaTest.LongBlockSize, dev.Timeout, out _); (ushort)mediaTest.LongBlockSize, dev.Timeout, out _);
@@ -1464,7 +1459,7 @@ sealed class DeviceReportCommand : Command
{ {
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Trying SCSI READ LONG (16)...").IsIndeterminate(); ctx.AddTask(Localization.Core.Trying_SCSI_READ_LONG_16).IsIndeterminate();
sense = dev.ReadLong16(out buffer, out senseBuffer, false, 0, sense = dev.ReadLong16(out buffer, out senseBuffer, false, 0,
(ushort)mediaTest.LongBlockSize, dev.Timeout, out _); (ushort)mediaTest.LongBlockSize, dev.Timeout, out _);
@@ -1495,21 +1490,25 @@ sealed class DeviceReportCommand : Command
if((report.SCSI.ReadCapabilities.SupportsReadLong == true || if((report.SCSI.ReadCapabilities.SupportsReadLong == true ||
report.SCSI.ReadCapabilities.SupportsReadLong16 == true) && report.SCSI.ReadCapabilities.SupportsReadLong16 == true) &&
report.SCSI.ReadCapabilities.LongBlockSize == report.SCSI.ReadCapabilities.BlockSize) report.SCSI.ReadCapabilities.LongBlockSize == report.SCSI.ReadCapabilities.BlockSize)
if(AnsiConsole. if(AnsiConsole.Confirm($"[italic]{Localization.Core.Try_to_find_SCSI_READ_LONG_size
Confirm("[italic]Drive supports SCSI READ LONG but I cannot find the correct size. Do you want me to try? (This can take hours)[/]")) }[/]"))
AnsiConsole.Progress().AutoClear(true).HideCompleted(true). AnsiConsole.Progress().AutoClear(true).HideCompleted(true).
Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), Columns(new TaskDescriptionColumn(), new ProgressBarColumn(),
new PercentageColumn()).Start(ctx => new PercentageColumn()).Start(ctx =>
{ {
ProgressTask task = ctx.AddTask("Trying to READ LONG..."); ProgressTask task =
ctx.AddTask(Localization.Core.Trying_to_READ_LONG);
task.MaxValue = ushort.MaxValue; task.MaxValue = ushort.MaxValue;
for(ushort i = (ushort)report.SCSI.ReadCapabilities.BlockSize;; i++) for(ushort i = (ushort)report.SCSI.ReadCapabilities.BlockSize;; i++)
{ {
task.Value = i; task.Value = i;
task.Description = $"Trying to READ LONG with a size of {i task.Description =
} bytes..."; string.
Format(Localization.Core.Trying_READ_LONG_with_size_0,
i);
sense = report.SCSI.ReadCapabilities.SupportsReadLong16 == true sense = report.SCSI.ReadCapabilities.SupportsReadLong16 == true
? dev.ReadLong16(out buffer, out senseBuffer, false, ? dev.ReadLong16(out buffer, out senseBuffer, false,
@@ -1536,7 +1535,7 @@ sealed class DeviceReportCommand : Command
{ {
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Trying SCSI READ LONG (10)...").IsIndeterminate(); ctx.AddTask(Localization.Core.Trying_SCSI_READ_LONG_10).IsIndeterminate();
sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0, sense = dev.ReadLong10(out buffer, out senseBuffer, false, false, 0,
(ushort)report.SCSI.ReadCapabilities.LongBlockSize, (ushort)report.SCSI.ReadCapabilities.LongBlockSize,
@@ -1552,7 +1551,7 @@ sealed class DeviceReportCommand : Command
{ {
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Trying SCSI READ LONG (16)...").IsIndeterminate(); ctx.AddTask(Localization.Core.Trying_SCSI_READ_LONG_16).IsIndeterminate();
sense = dev.ReadLong16(out buffer, out senseBuffer, false, 0, sense = dev.ReadLong16(out buffer, out senseBuffer, false, 0,
report.SCSI.ReadCapabilities.LongBlockSize.Value, report.SCSI.ReadCapabilities.LongBlockSize.Value,
@@ -1569,7 +1568,7 @@ sealed class DeviceReportCommand : Command
} }
break; break;
default: throw new NotSupportedException("Unknown device type."); default: throw new NotSupportedException(Localization.Core.Unknown_device_type);
} }
var jsonFs = new FileStream(jsonFile, FileMode.Create); var jsonFs = new FileStream(jsonFile, FileMode.Create);

View File

@@ -51,6 +51,7 @@ using Aaru.Decoders.SCSI.MMC;
using Aaru.Decoders.SCSI.SSC; using Aaru.Decoders.SCSI.SSC;
using Aaru.Devices; using Aaru.Devices;
using Aaru.Helpers; using Aaru.Helpers;
using Aaru.Localization;
using Spectre.Console; using Spectre.Console;
using Command = System.CommandLine.Command; using Command = System.CommandLine.Command;
using DeviceInfo = Aaru.Core.Devices.Info.DeviceInfo; using DeviceInfo = Aaru.Core.Devices.Info.DeviceInfo;
@@ -61,17 +62,17 @@ namespace Aaru.Commands.Device;
sealed class DeviceInfoCommand : Command sealed class DeviceInfoCommand : Command
{ {
public DeviceInfoCommand() : base("info", "Gets information about a device.") public DeviceInfoCommand() : base("info", UI.Device_Info_Command_Description)
{ {
Add(new Option<string>(new[] Add(new Option<string>(new[]
{ {
"--output-prefix", "-w" "--output-prefix", "-w"
}, () => null, "Prefix for saving binary information from device.")); }, () => null, UI.Prefix_for_saving_binary_information));
AddArgument(new Argument<string> AddArgument(new Argument<string>
{ {
Arity = ArgumentArity.ExactlyOne, Arity = ArgumentArity.ExactlyOne,
Description = "Device path", Description = UI.Device_path,
Name = "device-path" Name = "device-path"
}); });
@@ -125,7 +126,7 @@ sealed class DeviceInfoCommand : Command
switch(dev) switch(dev)
{ {
case null: case null:
AaruConsole.ErrorWriteLine($"Could not open device, error {devErrno}."); AaruConsole.ErrorWriteLine(string.Format(UI.Could_not_open_device_error_0, devErrno));
return (int)devErrno; return (int)devErrno;
case Devices.Remote.Device remoteDev: case Devices.Remote.Device remoteDev:
@@ -151,7 +152,7 @@ sealed class DeviceInfoCommand : Command
{ {
table = new Table table = new Table
{ {
Title = new TableTitle("[bold]USB device[/]") Title = new TableTitle($"[bold]{UI.Title_USB_device}[/]")
}; };
table.HideHeaders(); table.HideHeaders();
@@ -160,13 +161,13 @@ sealed class DeviceInfoCommand : Command
table.Columns[0].RightAligned(); table.Columns[0].RightAligned();
if(dev.UsbDescriptors != null) if(dev.UsbDescriptors != null)
table.AddRow("Descriptor size", $"{dev.UsbDescriptors.Length}"); table.AddRow(UI.Title_Descriptor_size, $"{dev.UsbDescriptors.Length}");
table.AddRow("Vendor ID", $"{dev.UsbVendorId:X4}"); table.AddRow(UI.Title_Vendor_ID, $"{dev.UsbVendorId:X4}");
table.AddRow("Product ID", $"{dev.UsbProductId:X4}"); table.AddRow(UI.Title_Product_ID, $"{dev.UsbProductId:X4}");
table.AddRow("Manufacturer", $"{Markup.Escape(dev.UsbManufacturerString ?? "")}"); table.AddRow(UI.Title_Manufacturer, Markup.Escape(dev.UsbManufacturerString ?? ""));
table.AddRow("Product", $"{Markup.Escape(dev.UsbProductString ?? "")}"); table.AddRow(UI.Title_Product, Markup.Escape(dev.UsbProductString ?? ""));
table.AddRow("Serial number", $"{Markup.Escape(dev.UsbSerialString ?? "")}"); table.AddRow(UI.Title_Serial_number, Markup.Escape(dev.UsbSerialString ?? ""));
AnsiConsole.Write(table); AnsiConsole.Write(table);
AaruConsole.WriteLine(); AaruConsole.WriteLine();
@@ -176,7 +177,7 @@ sealed class DeviceInfoCommand : Command
{ {
table = new Table table = new Table
{ {
Title = new TableTitle("[bold]FireWire device[/]") Title = new TableTitle($"[bold]{UI.Title_FireWire_device}[/]")
}; };
table.HideHeaders(); table.HideHeaders();
@@ -184,11 +185,11 @@ sealed class DeviceInfoCommand : Command
table.AddColumn(""); table.AddColumn("");
table.Columns[0].RightAligned(); table.Columns[0].RightAligned();
table.AddRow("Vendor ID", $"{dev.FireWireVendor:X6}"); table.AddRow(UI.Title_Vendor_ID, $"{dev.FireWireVendor:X6}");
table.AddRow("Model ID", $"{dev.FireWireModel:X6}"); table.AddRow(UI.Title_Model_ID, $"{dev.FireWireModel:X6}");
table.AddRow("Vendor", $"{Markup.Escape(dev.FireWireVendorName ?? "")}"); table.AddRow(UI.Title_Vendor, $"{Markup.Escape(dev.FireWireVendorName ?? "")}");
table.AddRow("Model", $"{Markup.Escape(dev.FireWireModelName ?? "")}"); table.AddRow(UI.Title_Model, $"{Markup.Escape(dev.FireWireModelName ?? "")}");
table.AddRow("GUID", $"{dev.FireWireGuid:X16}"); table.AddRow(UI.Title_GUID, $"{dev.FireWireGuid:X16}");
AnsiConsole.Write(table); AnsiConsole.Write(table);
AaruConsole.WriteLine(); AaruConsole.WriteLine();
@@ -196,8 +197,8 @@ sealed class DeviceInfoCommand : Command
if(dev.IsPcmcia) if(dev.IsPcmcia)
{ {
AaruConsole.WriteLine("[bold]PCMCIA device[/]"); AaruConsole.WriteLine($"[bold]{UI.Title_PCMCIA_device}[/]");
AaruConsole.WriteLine("PCMCIA CIS is {0} bytes", dev.Cis.Length); AaruConsole.WriteLine(UI.PCMCIA_CIS_is_0_bytes, dev.Cis.Length);
Tuple[] tuples = CIS.GetTuples(dev.Cis); Tuple[] tuples = CIS.GetTuples(dev.Cis);
if(tuples != null) if(tuples != null)
@@ -253,18 +254,18 @@ sealed class DeviceInfoCommand : Command
case TupleCodes.CISTPL_SPCL: case TupleCodes.CISTPL_SPCL:
case TupleCodes.CISTPL_SWIL: case TupleCodes.CISTPL_SWIL:
case TupleCodes.CISTPL_VERS_2: case TupleCodes.CISTPL_VERS_2:
AaruConsole.DebugWriteLine("Device-Info command", "Found undecoded tuple ID {0}", AaruConsole.DebugWriteLine("Device-Info command", UI.Invoke_Found_undecoded_tuple_ID_0,
tuple.Code); tuple.Code);
break; break;
default: default:
AaruConsole.DebugWriteLine("Device-Info command", "Found unknown tuple ID 0x{0:X2}", AaruConsole.DebugWriteLine("Device-Info command", UI.Found_unknown_tuple_ID_0,
(byte)tuple.Code); (byte)tuple.Code);
break; break;
} }
else else
AaruConsole.DebugWriteLine("Device-Info command", "Could not get tuples"); AaruConsole.DebugWriteLine("Device-Info command", UI.Could_not_get_tuples);
} }
var devInfo = new DeviceInfo(dev); var devInfo = new DeviceInfo(dev);
@@ -279,45 +280,45 @@ sealed class DeviceInfoCommand : Command
if(devInfo.AtaMcptError.HasValue) if(devInfo.AtaMcptError.HasValue)
{ {
AaruConsole.WriteLine("Device supports the Media Card Pass Through Command Set"); AaruConsole.WriteLine(Localization.Core.Device_supports_MCPT_Command_Set);
switch(devInfo.AtaMcptError.Value.DeviceHead & 0x7) switch(devInfo.AtaMcptError.Value.DeviceHead & 0x7)
{ {
case 0: case 0:
AaruConsole.WriteLine("Device reports incorrect media card type"); AaruConsole.WriteLine(Localization.Core.Device_reports_incorrect_media_card_type);
break; break;
case 1: case 1:
AaruConsole.WriteLine("Device contains a Secure Digital card"); AaruConsole.WriteLine(Localization.Core.Device_contains_SD_card);
break; break;
case 2: case 2:
AaruConsole.WriteLine("Device contains a MultiMediaCard "); AaruConsole.WriteLine(Localization.Core.Device_contains_MMC);
break; break;
case 3: case 3:
AaruConsole.WriteLine("Device contains a Secure Digital I/O card"); AaruConsole.WriteLine(Localization.Core.Device_contains_SDIO_card);
break; break;
case 4: case 4:
AaruConsole.WriteLine("Device contains a Smart Media card"); AaruConsole.WriteLine(Localization.Core.Device_contains_SM_card);
break; break;
default: default:
AaruConsole.WriteLine("Device contains unknown media card type {0}", AaruConsole.WriteLine(Localization.Core.Device_contains_unknown_media_card_type_0,
devInfo.AtaMcptError.Value.DeviceHead & 0x07); devInfo.AtaMcptError.Value.DeviceHead & 0x07);
break; break;
} }
if((devInfo.AtaMcptError.Value.DeviceHead & 0x08) == 0x08) if((devInfo.AtaMcptError.Value.DeviceHead & 0x08) == 0x08)
AaruConsole.WriteLine("Media card is write protected"); AaruConsole.WriteLine(Localization.Core.Media_card_is_write_protected);
ushort specificData = (ushort)((devInfo.AtaMcptError.Value.CylinderHigh * 0x100) + ushort specificData = (ushort)((devInfo.AtaMcptError.Value.CylinderHigh * 0x100) +
devInfo.AtaMcptError.Value.CylinderLow); devInfo.AtaMcptError.Value.CylinderLow);
if(specificData != 0) if(specificData != 0)
AaruConsole.WriteLine("Card specific data: 0x{0:X4}", specificData); AaruConsole.WriteLine(Localization.Core.Card_specific_data_0, specificData);
} }
if(decodedIdentify.HasValue) if(decodedIdentify.HasValue)
@@ -343,7 +344,9 @@ sealed class DeviceInfoCommand : Command
MediaType mediaType = MediaTypeFromDevice.GetFromAta(dev.Manufacturer, dev.Model, removable, MediaType mediaType = MediaTypeFromDevice.GetFromAta(dev.Manufacturer, dev.Model, removable,
dev.IsCompactFlash, dev.IsPcmcia, blocks); dev.IsCompactFlash, dev.IsPcmcia, blocks);
AaruConsole.WriteLine(removable ? "Media identified as {0}" : "Device identified as {0}", mediaType); AaruConsole.
WriteLine(removable ? Localization.Core.Media_identified_as_0 : Localization.Core.Device_identified_as_0,
mediaType);
Statistics.AddMedia(mediaType, true); Statistics.AddMedia(mediaType, true);
} }
@@ -360,7 +363,7 @@ sealed class DeviceInfoCommand : Command
if(devInfo.ScsiInquiry != null) if(devInfo.ScsiInquiry != null)
{ {
if(dev.Type != DeviceType.ATAPI) if(dev.Type != DeviceType.ATAPI)
AaruConsole.WriteLine("[bold]SCSI device[/]"); AaruConsole.WriteLine($"[bold]{UI.Title_SCSI_device}[/]");
DataFile.WriteTo("Device-Info command", outputPrefix, "_scsi_inquiry.bin", "SCSI INQUIRY", DataFile.WriteTo("Device-Info command", outputPrefix, "_scsi_inquiry.bin", "SCSI INQUIRY",
devInfo.ScsiInquiryData); devInfo.ScsiInquiryData);
@@ -372,14 +375,15 @@ sealed class DeviceInfoCommand : Command
switch(page.Key) switch(page.Key)
{ {
case >= 0x01 and <= 0x7F: case >= 0x01 and <= 0x7F:
AaruConsole.WriteLine("ASCII Page {0:X2}h: {1}", page.Key, AaruConsole.WriteLine(Localization.Core.ASCII_Page_0_1, page.Key,
EVPD.DecodeASCIIPage(page.Value)); EVPD.DecodeASCIIPage(page.Value));
DataFile.WriteTo("Device-Info command", outputPrefix, page.Value); DataFile.WriteTo("Device-Info command", outputPrefix, page.Value);
break; break;
case 0x80: case 0x80:
AaruConsole.WriteLine("Unit Serial Number: {0}", EVPD.DecodePage80(page.Value)); AaruConsole.WriteLine(Localization.Core.Unit_Serial_Number_0,
EVPD.DecodePage80(page.Value));
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin", DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
$"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value); $"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value);
@@ -393,7 +397,7 @@ sealed class DeviceInfoCommand : Command
break; break;
case 0x82: case 0x82:
AaruConsole.WriteLine("ASCII implemented operating definitions: {0}", AaruConsole.WriteLine(Localization.Core.ASCII_implemented_operating_definitions_0,
EVPD.DecodePage82(page.Value)); EVPD.DecodePage82(page.Value));
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin", DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
@@ -443,7 +447,7 @@ sealed class DeviceInfoCommand : Command
break; break;
case 0xB1: case 0xB1:
AaruConsole.WriteLine("Manufacturer-assigned Serial Number: {0}", AaruConsole.WriteLine(Localization.Core.Manufacturer_assigned_Serial_Number_0,
EVPD.DecodePageB1(page.Value)); EVPD.DecodePageB1(page.Value));
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin", DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
@@ -451,7 +455,7 @@ sealed class DeviceInfoCommand : Command
break; break;
case 0xB2: case 0xB2:
AaruConsole.WriteLine("TapeAlert Supported Flags Bitmap: 0x{0:X16}", AaruConsole.WriteLine(Localization.Core.TapeAlert_Supported_Flags_Bitmap_0,
EVPD.DecodePageB2(page.Value)); EVPD.DecodePageB2(page.Value));
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin", DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
@@ -459,7 +463,7 @@ sealed class DeviceInfoCommand : Command
break; break;
case 0xB3: case 0xB3:
AaruConsole.WriteLine("Automation Device Serial Number: {0}", AaruConsole.WriteLine(Localization.Core.Automation_Device_Serial_Number_0,
EVPD.DecodePageB3(page.Value)); EVPD.DecodePageB3(page.Value));
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin", DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
@@ -467,7 +471,7 @@ sealed class DeviceInfoCommand : Command
break; break;
case 0xB4: case 0xB4:
AaruConsole.WriteLine("Data Transfer Device Element Address: 0x{0}", AaruConsole.WriteLine(Localization.Core.Data_Transfer_Device_Element_Address_0,
EVPD.DecodePageB4(page.Value)); EVPD.DecodePageB4(page.Value));
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin", DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
@@ -546,8 +550,8 @@ sealed class DeviceInfoCommand : Command
if(page.Key == 0x00) if(page.Key == 0x00)
continue; continue;
AaruConsole.DebugWriteLine("Device-Info command", "Found undecoded SCSI VPD page 0x{0:X2}", AaruConsole.DebugWriteLine("Device-Info command",
page.Key); Localization.Core.Found_undecoded_SCSI_VPD_page_0, page.Key);
DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin", DataFile.WriteTo("Device-Info command", outputPrefix, $"_scsi_evpd_{page.Key:X2}h.bin",
$"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value); $"SCSI INQUIRY EVPD {page.Key:X2}h", page.Value);
@@ -576,19 +580,20 @@ sealed class DeviceInfoCommand : Command
Features.SeparatedFeatures ftr = Features.Separate(devInfo.MmcConfiguration); Features.SeparatedFeatures ftr = Features.Separate(devInfo.MmcConfiguration);
AaruConsole.DebugWriteLine("Device-Info command", "GET CONFIGURATION length is {0} bytes", AaruConsole.DebugWriteLine("Device-Info command", Localization.Core.GET_CONFIGURATION_length_is_0,
ftr.DataLength); ftr.DataLength);
AaruConsole.DebugWriteLine("Device-Info command", "GET CONFIGURATION current profile is {0:X4}h", AaruConsole.DebugWriteLine("Device-Info command",
Localization.Core.GET_CONFIGURATION_current_profile_is_0,
ftr.CurrentProfile); ftr.CurrentProfile);
if(ftr.Descriptors != null) if(ftr.Descriptors != null)
{ {
AaruConsole.WriteLine("[bold]SCSI MMC GET CONFIGURATION Features:[/]"); AaruConsole.WriteLine($"[bold]{UI.Title_SCSI_MMC_GET_CONFIGURATION_Features}[/]");
foreach(Features.FeatureDescriptor desc in ftr.Descriptors) foreach(Features.FeatureDescriptor desc in ftr.Descriptors)
{ {
AaruConsole.DebugWriteLine("Device-Info command", "Feature {0:X4}h", desc.Code); AaruConsole.DebugWriteLine("Device-Info command", Localization.Core.Feature_0, desc.Code);
switch(desc.Code) switch(desc.Code)
{ {
@@ -825,7 +830,7 @@ sealed class DeviceInfoCommand : Command
break; break;
default: default:
AaruConsole.WriteLine("Found unknown feature code {0:X4}h", desc.Code); AaruConsole.WriteLine(Localization.Core.Found_unknown_feature_code_0, desc.Code);
break; break;
} }
@@ -833,7 +838,7 @@ sealed class DeviceInfoCommand : Command
} }
else else
AaruConsole.DebugWriteLine("Device-Info command", AaruConsole.DebugWriteLine("Device-Info command",
"GET CONFIGURATION returned no feature descriptors"); Localization.Core.GET_CONFIGURATION_returned_no_feature_descriptors);
} }
if(devInfo.RPC != null) if(devInfo.RPC != null)
@@ -844,173 +849,165 @@ sealed class DeviceInfoCommand : Command
DataFile.WriteTo("Device-Info command", outputPrefix, "_plextor_eeprom.bin", "PLEXTOR READ EEPROM", DataFile.WriteTo("Device-Info command", outputPrefix, "_plextor_eeprom.bin", "PLEXTOR READ EEPROM",
devInfo.PlextorFeatures.Eeprom); devInfo.PlextorFeatures.Eeprom);
AaruConsole.WriteLine("Drive has loaded a total of {0} discs", devInfo.PlextorFeatures.Discs); AaruConsole.WriteLine(Localization.Core.Drive_has_loaded_a_total_of_0_discs,
devInfo.PlextorFeatures.Discs);
AaruConsole.WriteLine("Drive has spent {0} hours, {1} minutes and {2} seconds reading CDs", AaruConsole.WriteLine(Localization.Core.Drive_has_spent_0_hours_1_minutes_and_2_seconds_reading_CDs,
devInfo.PlextorFeatures.CdReadTime / 3600, devInfo.PlextorFeatures.CdReadTime / 3600,
devInfo.PlextorFeatures.CdReadTime / 60 % 60, devInfo.PlextorFeatures.CdReadTime / 60 % 60,
devInfo.PlextorFeatures.CdReadTime % 60); devInfo.PlextorFeatures.CdReadTime % 60);
AaruConsole.WriteLine("Drive has spent {0} hours, {1} minutes and {2} seconds writing CDs", AaruConsole.WriteLine(Localization.Core.Drive_has_spent_0_hours_1_minutes_and_2_seconds_writing_CDs,
devInfo.PlextorFeatures.CdWriteTime / 3600, devInfo.PlextorFeatures.CdWriteTime / 3600,
devInfo.PlextorFeatures.CdWriteTime / 60 % 60, devInfo.PlextorFeatures.CdWriteTime / 60 % 60,
devInfo.PlextorFeatures.CdWriteTime % 60); devInfo.PlextorFeatures.CdWriteTime % 60);
if(devInfo.PlextorFeatures.IsDvd) if(devInfo.PlextorFeatures.IsDvd)
{ {
AaruConsole.WriteLine("Drive has spent {0} hours, {1} minutes and {2} seconds reading DVDs", AaruConsole.
devInfo.PlextorFeatures.DvdReadTime / 3600, WriteLine(Localization.Core.Drive_has_spent_0_hours_1_minutes_and_2_seconds_reading_DVDs,
devInfo.PlextorFeatures.DvdReadTime / 60 % 60, devInfo.PlextorFeatures.DvdReadTime / 3600,
devInfo.PlextorFeatures.DvdReadTime % 60); devInfo.PlextorFeatures.DvdReadTime / 60 % 60,
devInfo.PlextorFeatures.DvdReadTime % 60);
AaruConsole.WriteLine("Drive has spent {0} hours, {1} minutes and {2} seconds writing DVDs", AaruConsole.
devInfo.PlextorFeatures.DvdWriteTime / 3600, WriteLine(Localization.Core.Drive_has_spent_0_hours_1_minutes_and_2_seconds_writing_DVDs,
devInfo.PlextorFeatures.DvdWriteTime / 60 % 60, devInfo.PlextorFeatures.DvdWriteTime / 3600,
devInfo.PlextorFeatures.DvdWriteTime % 60); devInfo.PlextorFeatures.DvdWriteTime / 60 % 60,
devInfo.PlextorFeatures.DvdWriteTime % 60);
} }
} }
if(devInfo.PlextorFeatures?.PoweRec == true) if(devInfo.PlextorFeatures?.PoweRec == true)
{ {
AaruConsole.Write("Drive supports PoweRec");
if(devInfo.PlextorFeatures.PoweRecEnabled) if(devInfo.PlextorFeatures.PoweRecEnabled)
{ {
AaruConsole.Write(", has it enabled");
if(devInfo.PlextorFeatures.PoweRecRecommendedSpeed > 0) if(devInfo.PlextorFeatures.PoweRecRecommendedSpeed > 0)
AaruConsole.WriteLine(" and recommends {0} Kb/sec.", AaruConsole.WriteLine(Localization.Core.Drive_supports_PoweRec_is_enabled_and_recommends_0,
devInfo.PlextorFeatures.PoweRecRecommendedSpeed); devInfo.PlextorFeatures.PoweRecRecommendedSpeed);
else else
AaruConsole.WriteLine("."); AaruConsole.WriteLine(Localization.Core.Drive_supports_PoweRec_and_has_it_enabled);
if(devInfo.PlextorFeatures.PoweRecSelected > 0) if(devInfo.PlextorFeatures.PoweRecSelected > 0)
AaruConsole. AaruConsole.
WriteLine("Selected PoweRec speed for currently inserted media is {0} Kb/sec ({1}x)", WriteLine(Localization.Core.Selected_PoweRec_speed_for_currently_inserted_media_is_0_1,
devInfo.PlextorFeatures.PoweRecSelected, devInfo.PlextorFeatures.PoweRecSelected,
devInfo.PlextorFeatures.PoweRecSelected / 177); devInfo.PlextorFeatures.PoweRecSelected / 177);
if(devInfo.PlextorFeatures.PoweRecMax > 0) if(devInfo.PlextorFeatures.PoweRecMax > 0)
AaruConsole.WriteLine("Maximum PoweRec speed for currently inserted media is {0} Kb/sec ({1}x)", AaruConsole.
devInfo.PlextorFeatures.PoweRecMax, WriteLine(Localization.Core.Maximum_PoweRec_speed_for_currently_inserted_media_is_0_1,
devInfo.PlextorFeatures.PoweRecMax / 177); devInfo.PlextorFeatures.PoweRecMax, devInfo.PlextorFeatures.PoweRecMax / 177);
if(devInfo.PlextorFeatures.PoweRecLast > 0) if(devInfo.PlextorFeatures.PoweRecLast > 0)
AaruConsole.WriteLine("Last used PoweRec was {0} Kb/sec ({1}x)", AaruConsole.WriteLine(Localization.Core.Last_used_PoweRec_was_0_1,
devInfo.PlextorFeatures.PoweRecLast, devInfo.PlextorFeatures.PoweRecLast,
devInfo.PlextorFeatures.PoweRecLast / 177); devInfo.PlextorFeatures.PoweRecLast / 177);
} }
else else
{ AaruConsole.WriteLine(Localization.Core.Drive_supports_PoweRec_and_has_it_disabled);
AaruConsole.WriteLine(".");
AaruConsole.WriteLine("PoweRec is disabled");
}
} }
if(devInfo.PlextorFeatures?.SilentMode == true) if(devInfo.PlextorFeatures?.SilentMode == true)
{ {
AaruConsole.WriteLine("Drive supports Plextor SilentMode"); AaruConsole.WriteLine(Localization.Core.Drive_supports_Plextor_SilentMode);
if(devInfo.PlextorFeatures.SilentModeEnabled) if(devInfo.PlextorFeatures.SilentModeEnabled)
{ {
AaruConsole.WriteLine("Plextor SilentMode is enabled:"); AaruConsole.WriteLine(Localization.Core.Plextor_SilentMode_is_enabled);
AaruConsole.WriteLine(devInfo.PlextorFeatures.AccessTimeLimit == 2 ? "\tAccess time is slow" AaruConsole.WriteLine("\t" + (devInfo.PlextorFeatures.AccessTimeLimit == 2
: "\tAccess time is fast"); ? Localization.Core.Access_time_is_slow
: Localization.Core.Access_time_is_fast));
if(devInfo.PlextorFeatures.CdReadSpeedLimit > 0) if(devInfo.PlextorFeatures.CdReadSpeedLimit > 0)
AaruConsole.WriteLine("\tCD read speed limited to {0}x", AaruConsole.WriteLine("\t" + Localization.Core.CD_read_speed_limited_to_0,
devInfo.PlextorFeatures.CdReadSpeedLimit); devInfo.PlextorFeatures.CdReadSpeedLimit);
if(devInfo.PlextorFeatures.DvdReadSpeedLimit > 0 && if(devInfo.PlextorFeatures.DvdReadSpeedLimit > 0 &&
devInfo.PlextorFeatures.IsDvd) devInfo.PlextorFeatures.IsDvd)
AaruConsole.WriteLine("\tDVD read speed limited to {0}x", AaruConsole.WriteLine("\t" + Localization.Core.DVD_read_speed_limited_to_0,
devInfo.PlextorFeatures.DvdReadSpeedLimit); devInfo.PlextorFeatures.DvdReadSpeedLimit);
if(devInfo.PlextorFeatures.CdWriteSpeedLimit > 0) if(devInfo.PlextorFeatures.CdWriteSpeedLimit > 0)
AaruConsole.WriteLine("\tCD write speed limited to {0}x", AaruConsole.WriteLine("\t" + Localization.Core.CD_write_speed_limited_to_0,
devInfo.PlextorFeatures.CdWriteSpeedLimit); devInfo.PlextorFeatures.CdWriteSpeedLimit);
} }
} }
if(devInfo.PlextorFeatures?.GigaRec == true) if(devInfo.PlextorFeatures?.GigaRec == true)
AaruConsole.WriteLine("Drive supports Plextor GigaRec"); AaruConsole.WriteLine(Localization.Core.Drive_supports_Plextor_GigaRec);
if(devInfo.PlextorFeatures?.SecuRec == true) if(devInfo.PlextorFeatures?.SecuRec == true)
AaruConsole.WriteLine("Drive supports Plextor SecuRec"); AaruConsole.WriteLine(Localization.Core.Drive_supports_Plextor_SecuRec);
if(devInfo.PlextorFeatures?.SpeedRead == true) if(devInfo.PlextorFeatures?.SpeedRead == true)
{ AaruConsole.WriteLine(devInfo.PlextorFeatures.SpeedReadEnabled
AaruConsole.Write("Drive supports Plextor SpeedRead"); ? Localization.Core.Drive_supports_Plextor_SpeedRead_and_has_it_enabled
: Localization.Core.Drive_supports_Plextor_SpeedRead);
if(devInfo.PlextorFeatures.SpeedReadEnabled)
AaruConsole.WriteLine("and has it enabled");
else
AaruConsole.WriteLine();
}
if(devInfo.PlextorFeatures?.Hiding == true) if(devInfo.PlextorFeatures?.Hiding == true)
{ {
AaruConsole.WriteLine("Drive supports hiding CD-Rs and forcing single session"); AaruConsole.WriteLine(Localization.Core.Drive_supports_hiding_CDRs_and_forcing_single_session);
if(devInfo.PlextorFeatures.HidesRecordables) if(devInfo.PlextorFeatures.HidesRecordables)
AaruConsole.WriteLine("Drive currently hides CD-Rs"); AaruConsole.WriteLine(Localization.Core.Drive_currently_hides_CDRs);
if(devInfo.PlextorFeatures.HidesSessions) if(devInfo.PlextorFeatures.HidesSessions)
AaruConsole.WriteLine("Drive currently forces single session"); AaruConsole.WriteLine(Localization.Core.Drive_currently_forces_single_session);
} }
if(devInfo.PlextorFeatures?.VariRec == true) if(devInfo.PlextorFeatures?.VariRec == true)
AaruConsole.WriteLine("Drive supports Plextor VariRec"); AaruConsole.WriteLine(Localization.Core.Drive_supports_Plextor_VariRec);
if(devInfo.PlextorFeatures?.IsDvd == true) if(devInfo.PlextorFeatures?.IsDvd == true)
{ {
if(devInfo.PlextorFeatures.VariRecDvd) if(devInfo.PlextorFeatures.VariRecDvd)
AaruConsole.WriteLine("Drive supports Plextor VariRec for DVDs"); AaruConsole.WriteLine(Localization.Core.Drive_supports_Plextor_VariRec_for_DVDs);
if(devInfo.PlextorFeatures.BitSetting) if(devInfo.PlextorFeatures.BitSetting)
AaruConsole.WriteLine("Drive supports bitsetting DVD+R book type"); AaruConsole.WriteLine(Localization.Core.Drive_supports_bitsetting_DVD_R_book_type);
if(devInfo.PlextorFeatures.BitSettingDl) if(devInfo.PlextorFeatures.BitSettingDl)
AaruConsole.WriteLine("Drive supports bitsetting DVD+R DL book type"); AaruConsole.WriteLine(Localization.Core.Drive_supports_bitsetting_DVD_R_DL_book_type);
if(devInfo.PlextorFeatures.DvdPlusWriteTest) if(devInfo.PlextorFeatures.DvdPlusWriteTest)
AaruConsole.WriteLine("Drive supports test writing DVD+"); AaruConsole.WriteLine(Localization.Core.Drive_supports_test_writing_DVD_Plus);
} }
if(devInfo.ScsiInquiry.Value.KreonPresent) if(devInfo.ScsiInquiry.Value.KreonPresent)
{ {
AaruConsole.WriteLine("[bold]Drive has kreon firmware:[/]"); AaruConsole.WriteLine($"[bold]{UI.Title_Drive_has_kreon_firmware}[/]");
if(devInfo.KreonFeatures.HasFlag(KreonFeatures.ChallengeResponse)) if(devInfo.KreonFeatures.HasFlag(KreonFeatures.ChallengeResponse))
AaruConsole.WriteLine("\tCan do challenge/response with Xbox discs"); AaruConsole.WriteLine("\t" + Localization.Core.Can_do_challenge_response_with_Xbox_discs);
if(devInfo.KreonFeatures.HasFlag(KreonFeatures.DecryptSs)) if(devInfo.KreonFeatures.HasFlag(KreonFeatures.DecryptSs))
AaruConsole.WriteLine("\tCan read and decrypt SS from Xbox discs"); AaruConsole.WriteLine("\t" + Localization.Core.Can_read_and_decrypt_SS_from_Xbox_discs);
if(devInfo.KreonFeatures.HasFlag(KreonFeatures.XtremeUnlock)) if(devInfo.KreonFeatures.HasFlag(KreonFeatures.XtremeUnlock))
AaruConsole.WriteLine("\tCan set xtreme unlock state with Xbox discs"); AaruConsole.WriteLine("\t" + Localization.Core.Can_set_xtreme_unlock_state_with_Xbox_discs);
if(devInfo.KreonFeatures.HasFlag(KreonFeatures.WxripperUnlock)) if(devInfo.KreonFeatures.HasFlag(KreonFeatures.WxripperUnlock))
AaruConsole.WriteLine("\tCan set wxripper unlock state with Xbox discs"); AaruConsole.WriteLine("\t" + Localization.Core.Can_set_wxripper_unlock_state_with_Xbox_discs);
if(devInfo.KreonFeatures.HasFlag(KreonFeatures.ChallengeResponse360)) if(devInfo.KreonFeatures.HasFlag(KreonFeatures.ChallengeResponse360))
AaruConsole.WriteLine("\tCan do challenge/response with Xbox 360 discs"); AaruConsole.WriteLine("\t" + Localization.Core.Can_do_challenge_response_with_Xbox_360_discs);
if(devInfo.KreonFeatures.HasFlag(KreonFeatures.DecryptSs360)) if(devInfo.KreonFeatures.HasFlag(KreonFeatures.DecryptSs360))
AaruConsole.WriteLine("\tCan read and decrypt SS from Xbox 360 discs"); AaruConsole.WriteLine("\t" + Localization.Core.Can_read_and_decrypt_SS_from_Xbox_360_discs);
if(devInfo.KreonFeatures.HasFlag(KreonFeatures.XtremeUnlock360)) if(devInfo.KreonFeatures.HasFlag(KreonFeatures.XtremeUnlock360))
AaruConsole.WriteLine("\tCan set xtreme unlock state with Xbox 360 discs"); AaruConsole.WriteLine("\t" + Localization.Core.Can_set_xtreme_unlock_state_with_Xbox_360_discs);
if(devInfo.KreonFeatures.HasFlag(KreonFeatures.WxripperUnlock360)) if(devInfo.KreonFeatures.HasFlag(KreonFeatures.WxripperUnlock360))
AaruConsole.WriteLine("\tCan set wxripper unlock state with Xbox 360 discs"); AaruConsole.WriteLine("\t" + Localization.Core.Can_set_wxripper_unlock_state_with_Xbox_360_discs);
if(devInfo.KreonFeatures.HasFlag(KreonFeatures.Lock)) if(devInfo.KreonFeatures.HasFlag(KreonFeatures.Lock))
AaruConsole.WriteLine("\tCan set locked state"); AaruConsole.WriteLine("\t" + Localization.Core.Can_set_Kreon_locked_state);
if(devInfo.KreonFeatures.HasFlag(KreonFeatures.ErrorSkipping)) if(devInfo.KreonFeatures.HasFlag(KreonFeatures.ErrorSkipping))
AaruConsole.WriteLine("\tCan skip read errors"); AaruConsole.WriteLine("\t" + Localization.Core.Kreon_Can_skip_read_errors);
} }
if(devInfo.BlockLimits != null) if(devInfo.BlockLimits != null)
@@ -1018,7 +1015,7 @@ sealed class DeviceInfoCommand : Command
DataFile.WriteTo("Device-Info command", outputPrefix, "_ssc_readblocklimits.bin", DataFile.WriteTo("Device-Info command", outputPrefix, "_ssc_readblocklimits.bin",
"SSC READ BLOCK LIMITS", devInfo.BlockLimits); "SSC READ BLOCK LIMITS", devInfo.BlockLimits);
AaruConsole.WriteLine("Block limits for device:"); AaruConsole.WriteLine(Localization.Core.Block_limits_for_device);
AaruConsole.WriteLine(BlockLimits.Prettify(devInfo.BlockLimits)); AaruConsole.WriteLine(BlockLimits.Prettify(devInfo.BlockLimits));
} }

View File

@@ -37,6 +37,7 @@ using Aaru.CommonTypes.Enums;
using Aaru.Console; using Aaru.Console;
using Aaru.Core; using Aaru.Core;
using Aaru.Devices; using Aaru.Devices;
using Aaru.Localization;
using JetBrains.Annotations; using JetBrains.Annotations;
using Spectre.Console; using Spectre.Console;
@@ -44,12 +45,12 @@ namespace Aaru.Commands.Device;
sealed class ListDevicesCommand : Command sealed class ListDevicesCommand : Command
{ {
public ListDevicesCommand() : base("list", "Lists all connected devices.") public ListDevicesCommand() : base("list", UI.Device_List_Command_Description)
{ {
AddArgument(new Argument<string> AddArgument(new Argument<string>
{ {
Arity = ArgumentArity.ZeroOrOne, Arity = ArgumentArity.ZeroOrOne,
Description = "aaruremote host", Description = UI.aaruremote_host,
Name = "aaru-remote-host" Name = "aaru-remote-host"
}); });
@@ -101,16 +102,16 @@ sealed class ListDevicesCommand : Command
if(devices == null || if(devices == null ||
devices.Length == 0) devices.Length == 0)
AaruConsole.WriteLine("No known devices attached."); AaruConsole.WriteLine(UI.No_known_devices_attached);
else else
{ {
Table table = new(); Table table = new();
table.AddColumn("Path"); table.AddColumn(UI.Path);
table.AddColumn("Vendor"); table.AddColumn(UI.Title_Vendor);
table.AddColumn("Model"); table.AddColumn(UI.Title_Model);
table.AddColumn("Serial"); table.AddColumn(UI.Serial);
table.AddColumn("Bus"); table.AddColumn(UI.Title_Bus);
table.AddColumn("Supported?"); table.AddColumn(UI.Supported_Question);
foreach(DeviceInfo dev in devices.OrderBy(d => d.Path)) foreach(DeviceInfo dev in devices.OrderBy(d => d.Path))
table.AddRow(Markup.Escape(dev.Path ?? ""), Markup.Escape(dev.Vendor ?? ""), table.AddRow(Markup.Escape(dev.Path ?? ""), Markup.Escape(dev.Vendor ?? ""),

View File

@@ -43,6 +43,7 @@ using Aaru.CommonTypes.Interfaces;
using Aaru.CommonTypes.Structs; using Aaru.CommonTypes.Structs;
using Aaru.Console; using Aaru.Console;
using Aaru.Core; using Aaru.Core;
using Aaru.Localization;
using JetBrains.Annotations; using JetBrains.Annotations;
using Spectre.Console; using Spectre.Console;
using FileAttributes = Aaru.CommonTypes.Structs.FileAttributes; using FileAttributes = Aaru.CommonTypes.Structs.FileAttributes;
@@ -53,39 +54,39 @@ sealed class ExtractFilesCommand : Command
{ {
const long BUFFER_SIZE = 16777216; const long BUFFER_SIZE = 16777216;
public ExtractFilesCommand() : base("extract", "Extracts all files in disc image.") public ExtractFilesCommand() : base("extract", UI.Filesystem_Extract_Command_Description)
{ {
Add(new Option<string>(new[] Add(new Option<string>(new[]
{ {
"--encoding", "-e" "--encoding", "-e"
}, () => null, "Name of character encoding to use.")); }, () => null, UI.Name_of_character_encoding_to_use));
Add(new Option<string>(new[] Add(new Option<string>(new[]
{ {
"--options", "-O" "--options", "-O"
}, () => null, "Comma separated name=value pairs of options to pass to filesystem plugin.")); }, () => null, UI.Comma_separated_name_value_pairs_of_filesystem_options));
Add(new Option<bool>(new[] Add(new Option<bool>(new[]
{ {
"--xattrs", "-x" "--xattrs", "-x"
}, () => false, "Extract extended attributes if present.")); }, () => false, UI.Extract_extended_attributes_if_present));
Add(new Option<string>(new[] Add(new Option<string>(new[]
{ {
"--namespace", "-n" "--namespace", "-n"
}, () => null, "Namespace to use for filenames.")); }, () => null, UI.Namespace_to_use_for_filenames));
AddArgument(new Argument<string> AddArgument(new Argument<string>
{ {
Arity = ArgumentArity.ExactlyOne, Arity = ArgumentArity.ExactlyOne,
Description = "Disc image path", Description = UI.Disc_image_path,
Name = "image-path" Name = "image-path"
}); });
AddArgument(new Argument<string> AddArgument(new Argument<string>
{ {
Arity = ArgumentArity.ExactlyOne, Arity = ArgumentArity.ExactlyOne,
Description = "Directory where extracted files will be created. Will abort if it exists", Description = UI.Directory_where_extracted_files_will_be_created,
Name = "output-dir" Name = "output-dir"
}); });
@@ -137,12 +138,12 @@ sealed class ExtractFilesCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Identifying file filter...").IsIndeterminate(); ctx.AddTask(UI.Identifying_file_filter).IsIndeterminate();
inputFilter = filtersList.GetFilter(imagePath); inputFilter = filtersList.GetFilter(imagePath);
}); });
Dictionary<string, string> parsedOptions = Core.Options.Parse(options); Dictionary<string, string> parsedOptions = Core.Options.Parse(options);
AaruConsole.DebugWriteLine("Extract-Files command", "Parsed options:"); AaruConsole.DebugWriteLine("Extract-Files command", UI.Parsed_options);
foreach(KeyValuePair<string, string> parsedOption in parsedOptions) foreach(KeyValuePair<string, string> parsedOption in parsedOptions)
AaruConsole.DebugWriteLine("Extract-Files command", "{0} = {1}", parsedOption.Key, parsedOption.Value); AaruConsole.DebugWriteLine("Extract-Files command", "{0} = {1}", parsedOption.Key, parsedOption.Value);
@@ -151,7 +152,7 @@ sealed class ExtractFilesCommand : Command
if(inputFilter == null) if(inputFilter == null)
{ {
AaruConsole.ErrorWriteLine("Cannot open specified file."); AaruConsole.ErrorWriteLine(UI.Cannot_open_specified_file);
return (int)ErrorNumber.CannotOpenFile; return (int)ErrorNumber.CannotOpenFile;
} }
@@ -164,11 +165,11 @@ sealed class ExtractFilesCommand : Command
encodingClass = Claunia.Encoding.Encoding.GetEncoding(encoding); encodingClass = Claunia.Encoding.Encoding.GetEncoding(encoding);
if(verbose) if(verbose)
AaruConsole.VerboseWriteLine("Using encoding for {0}.", encodingClass.EncodingName); AaruConsole.VerboseWriteLine(UI.encoding_for_0, encodingClass.EncodingName);
} }
catch(ArgumentException) catch(ArgumentException)
{ {
AaruConsole.ErrorWriteLine("Specified encoding is not supported."); AaruConsole.ErrorWriteLine(UI.Specified_encoding_is_not_supported);
return (int)ErrorNumber.EncodingUnknown; return (int)ErrorNumber.EncodingUnknown;
} }
@@ -182,33 +183,33 @@ sealed class ExtractFilesCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Identifying image format...").IsIndeterminate(); ctx.AddTask(UI.Identifying_image_format).IsIndeterminate();
baseImage = ImageFormat.Detect(inputFilter); baseImage = ImageFormat.Detect(inputFilter);
imageFormat = baseImage as IMediaImage; imageFormat = baseImage as IMediaImage;
}); });
if(baseImage == null) if(baseImage == null)
{ {
AaruConsole.WriteLine("Image format not identified, not proceeding with analysis."); AaruConsole.WriteLine(UI.Image_format_not_identified_not_proceeding_with_file_extraction);
return (int)ErrorNumber.UnrecognizedFormat; return (int)ErrorNumber.UnrecognizedFormat;
} }
if(imageFormat == null) if(imageFormat == null)
{ {
AaruConsole.WriteLine("Command not supported for this image type."); AaruConsole.WriteLine(UI.Command_not_supported_for_this_image_type);
return (int)ErrorNumber.InvalidArgument; return (int)ErrorNumber.InvalidArgument;
} }
if(verbose) if(verbose)
AaruConsole.VerboseWriteLine("Image format identified by {0} ({1}).", imageFormat.Name, imageFormat.Id); AaruConsole.VerboseWriteLine(UI.Image_format_identified_by_0_1, imageFormat.Name, imageFormat.Id);
else else
AaruConsole.WriteLine("Image format identified by {0}.", imageFormat.Name); AaruConsole.WriteLine(UI.Image_format_identified_by_0, imageFormat.Name);
if(outputDir == null) if(outputDir == null)
{ {
AaruConsole.WriteLine("Output directory missing."); AaruConsole.WriteLine(UI.Output_directory_missing);
return (int)ErrorNumber.MissingArgument; return (int)ErrorNumber.MissingArgument;
} }
@@ -216,7 +217,7 @@ sealed class ExtractFilesCommand : Command
if(Directory.Exists(outputDir) || if(Directory.Exists(outputDir) ||
File.Exists(outputDir)) File.Exists(outputDir))
{ {
AaruConsole.ErrorWriteLine("Destination exists, aborting."); AaruConsole.ErrorWriteLine(UI.Destination_exists_aborting);
return (int)ErrorNumber.FileExists; return (int)ErrorNumber.FileExists;
} }
@@ -229,26 +230,26 @@ sealed class ExtractFilesCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Opening image file...").IsIndeterminate(); ctx.AddTask(UI.Invoke_Opening_image_file).IsIndeterminate();
opened = imageFormat.Open(inputFilter); opened = imageFormat.Open(inputFilter);
}); });
if(opened != ErrorNumber.NoError) if(opened != ErrorNumber.NoError)
{ {
AaruConsole.WriteLine("Unable to open image format"); AaruConsole.WriteLine(UI.Unable_to_open_image_format);
AaruConsole.WriteLine("Error {0}", opened); AaruConsole.WriteLine(UI.Error_0, opened);
return (int)opened; return (int)opened;
} }
AaruConsole.DebugWriteLine("Extract-Files command", "Correctly opened image file."); AaruConsole.DebugWriteLine("Extract-Files command", UI.Correctly_opened_image_file);
AaruConsole.DebugWriteLine("Extract-Files command", "Image without headers is {0} bytes.", AaruConsole.DebugWriteLine("Extract-Files command", UI.Image_without_headers_is_0_bytes,
imageFormat.Info.ImageSize); imageFormat.Info.ImageSize);
AaruConsole.DebugWriteLine("Extract-Files command", "Image has {0} sectors.", imageFormat.Info.Sectors); AaruConsole.DebugWriteLine("Extract-Files command", UI.Image_has_0_sectors, imageFormat.Info.Sectors);
AaruConsole.DebugWriteLine("Extract-Files command", "Image identifies disk type as {0}.", AaruConsole.DebugWriteLine("Extract-Files command", UI.Image_identifies_disk_type_as_0,
imageFormat.Info.MediaType); imageFormat.Info.MediaType);
Statistics.AddMediaFormat(imageFormat.Format); Statistics.AddMediaFormat(imageFormat.Format);
@@ -257,8 +258,8 @@ sealed class ExtractFilesCommand : Command
} }
catch(Exception ex) catch(Exception ex)
{ {
AaruConsole.ErrorWriteLine("Unable to open image format"); AaruConsole.ErrorWriteLine(UI.Unable_to_open_image_format);
AaruConsole.ErrorWriteLine("Error: {0}", ex.Message); AaruConsole.ErrorWriteLine(UI.Error_0, ex.Message);
return (int)ErrorNumber.CannotOpenFormat; return (int)ErrorNumber.CannotOpenFormat;
} }
@@ -267,7 +268,7 @@ sealed class ExtractFilesCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Enumerating partitions...").IsIndeterminate(); ctx.AddTask(UI.Enumerating_partitions).IsIndeterminate();
partitions = Core.Partitions.GetAll(imageFormat); partitions = Core.Partitions.GetAll(imageFormat);
}); });
@@ -275,11 +276,11 @@ sealed class ExtractFilesCommand : Command
if(partitions.Count == 0) if(partitions.Count == 0)
{ {
AaruConsole.DebugWriteLine("Ls command", "No partitions found"); AaruConsole.DebugWriteLine("Ls command", UI.No_partitions_found);
partitions.Add(new Partition partitions.Add(new Partition
{ {
Description = "Whole device", Description = Localization.Core.Whole_device,
Length = imageFormat.Info.Sectors, Length = imageFormat.Info.Sectors,
Offset = 0, Offset = 0,
Size = imageFormat.Info.SectorSize * imageFormat.Info.Sectors, Size = imageFormat.Info.SectorSize * imageFormat.Info.Sectors,
@@ -288,23 +289,23 @@ sealed class ExtractFilesCommand : Command
}); });
} }
AaruConsole.WriteLine("{0} partitions found.", partitions.Count); AaruConsole.WriteLine(UI._0_partitions_found, partitions.Count);
for(int i = 0; i < partitions.Count; i++) for(int i = 0; i < partitions.Count; i++)
{ {
AaruConsole.WriteLine(); AaruConsole.WriteLine();
AaruConsole.WriteLine("[bold]Partition {0}:[/]", partitions[i].Sequence); AaruConsole.WriteLine($"[bold]{string.Format(UI.Partition_0, partitions[i].Sequence)}[/]");
List<string> idPlugins = null; List<string> idPlugins = null;
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Identifying filesystems on partition...").IsIndeterminate(); ctx.AddTask(UI.Identifying_filesystems_on_partition).IsIndeterminate();
Core.Filesystems.Identify(imageFormat, out idPlugins, partitions[i]); Core.Filesystems.Identify(imageFormat, out idPlugins, partitions[i]);
}); });
if(idPlugins.Count == 0) if(idPlugins.Count == 0)
AaruConsole.WriteLine("Filesystem not identified"); AaruConsole.WriteLine(UI.Filesystem_not_identified);
else else
{ {
IReadOnlyFilesystem plugin; IReadOnlyFilesystem plugin;
@@ -312,12 +313,13 @@ sealed class ExtractFilesCommand : Command
if(idPlugins.Count > 1) if(idPlugins.Count > 1)
{ {
AaruConsole.WriteLine($"[italic]Identified by {idPlugins.Count} plugins[/]"); AaruConsole.WriteLine($"[italic]{string.Format(UI.Identified_by_0_plugins, idPlugins.Count)
}[/]");
foreach(string pluginName in idPlugins) foreach(string pluginName in idPlugins)
if(plugins.ReadOnlyFilesystems.TryGetValue(pluginName, out plugin)) if(plugins.ReadOnlyFilesystems.TryGetValue(pluginName, out plugin))
{ {
AaruConsole.WriteLine($"[bold]As identified by {plugin.Name}.[/]"); AaruConsole.WriteLine($"[bold]{string.Format(UI.As_identified_by_0, plugin.Name)}[/]");
var fs = (IReadOnlyFilesystem)plugin.GetType().GetConstructor(Type.EmptyTypes)?. var fs = (IReadOnlyFilesystem)plugin.GetType().GetConstructor(Type.EmptyTypes)?.
Invoke(Array.Empty<object>()); Invoke(Array.Empty<object>());
@@ -327,7 +329,7 @@ sealed class ExtractFilesCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Mounting filesystem...").IsIndeterminate(); ctx.AddTask(UI.Mounting_filesystem).IsIndeterminate();
error = fs.Mount(imageFormat, partitions[i], encodingClass, parsedOptions, error = fs.Mount(imageFormat, partitions[i], encodingClass, parsedOptions,
@namespace); @namespace);
@@ -343,7 +345,7 @@ sealed class ExtractFilesCommand : Command
Statistics.AddFilesystem(fs.XmlFsType.Type); Statistics.AddFilesystem(fs.XmlFsType.Type);
} }
else else
AaruConsole.ErrorWriteLine("Unable to mount device, error {0}", error.ToString()); AaruConsole.ErrorWriteLine(UI.Unable_to_mount_volume_error_0, error.ToString());
} }
} }
else else
@@ -353,7 +355,7 @@ sealed class ExtractFilesCommand : Command
if(plugin == null) if(plugin == null)
continue; continue;
AaruConsole.WriteLine($"[bold]Identified by {plugin.Name}.[/]"); AaruConsole.WriteLine($"[bold]{string.Format(UI.Identified_by_0, plugin.Name)}[/]");
var fs = (IReadOnlyFilesystem)plugin.GetType().GetConstructor(Type.EmptyTypes)?. var fs = (IReadOnlyFilesystem)plugin.GetType().GetConstructor(Type.EmptyTypes)?.
Invoke(Array.Empty<object>()); Invoke(Array.Empty<object>());
@@ -363,7 +365,7 @@ sealed class ExtractFilesCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Mounting filesystem...").IsIndeterminate(); ctx.AddTask(UI.Mounting_filesystem).IsIndeterminate();
error = fs.Mount(imageFormat, partitions[i], encodingClass, parsedOptions, @namespace); error = fs.Mount(imageFormat, partitions[i], encodingClass, parsedOptions, @namespace);
}); });
@@ -377,14 +379,14 @@ sealed class ExtractFilesCommand : Command
Statistics.AddFilesystem(fs.XmlFsType.Type); Statistics.AddFilesystem(fs.XmlFsType.Type);
} }
else else
AaruConsole.ErrorWriteLine("Unable to mount device, error {0}", error.ToString()); AaruConsole.ErrorWriteLine(UI.Unable_to_mount_volume_error_0, error.ToString());
} }
} }
} }
} }
catch(Exception ex) catch(Exception ex)
{ {
AaruConsole.ErrorWriteLine($"Error reading file: {ex.Message}"); AaruConsole.ErrorWriteLine(string.Format(UI.Error_reading_file_0, ex.Message));
AaruConsole.DebugWriteLine("Extract-Files command", ex.StackTrace); AaruConsole.DebugWriteLine("Extract-Files command", ex.StackTrace);
return (int)ErrorNumber.UnexpectedException; return (int)ErrorNumber.UnexpectedException;
@@ -403,7 +405,7 @@ sealed class ExtractFilesCommand : Command
if(error != ErrorNumber.NoError) if(error != ErrorNumber.NoError)
{ {
AaruConsole.ErrorWriteLine("Error {0} reading root directory {0}", error.ToString()); AaruConsole.ErrorWriteLine(UI.Error_0_reading_directory_1, error.ToString(), path);
return; return;
} }
@@ -414,7 +416,7 @@ sealed class ExtractFilesCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Retrieving file information...").IsIndeterminate(); ctx.AddTask(UI.Retrieving_file_information).IsIndeterminate();
error = fs.Stat(path + "/" + entry, out stat); error = fs.Stat(path + "/" + entry, out stat);
}); });
@@ -433,7 +435,7 @@ sealed class ExtractFilesCommand : Command
Directory.CreateDirectory(outputPath); Directory.CreateDirectory(outputPath);
AaruConsole.WriteLine("Created subdirectory at {0}", Markup.Escape(outputPath)); AaruConsole.WriteLine(UI.Created_subdirectory_at_0, Markup.Escape(outputPath));
ExtractFilesInDir(path + "/" + entry, fs, volumeName, outputDir, doXattrs); ExtractFilesInDir(path + "/" + entry, fs, volumeName, outputDir, doXattrs);
@@ -482,7 +484,7 @@ sealed class ExtractFilesCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Listing extended attributes...").IsIndeterminate(); ctx.AddTask(UI.Listing_extended_attributes).IsIndeterminate();
error = fs.ListXAttr(path + "/" + entry, out xattrs); error = fs.ListXAttr(path + "/" + entry, out xattrs);
}); });
@@ -493,7 +495,7 @@ sealed class ExtractFilesCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Reading extended attribute...").IsIndeterminate(); ctx.AddTask(UI.Reading_extended_attribute).IsIndeterminate();
error = fs.GetXattr(path + "/" + entry, xattr, ref xattrBuf); error = fs.GetXattr(path + "/" + entry, xattr, ref xattrBuf);
}); });
@@ -525,7 +527,7 @@ sealed class ExtractFilesCommand : Command
{ {
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Writing extended attribute...").IsIndeterminate(); ctx.AddTask(UI.Writing_extended_attribute).IsIndeterminate();
outputFile = new FileStream(outputPath, FileMode.CreateNew, FileAccess.ReadWrite, outputFile = new FileStream(outputPath, FileMode.CreateNew, FileAccess.ReadWrite,
FileShare.None); FileShare.None);
@@ -566,12 +568,11 @@ sealed class ExtractFilesCommand : Command
// ignored // ignored
} }
#pragma warning restore RECS0022 // A catch clause that catches System.Exception and has an empty body #pragma warning restore RECS0022 // A catch clause that catches System.Exception and has an empty body
AaruConsole.WriteLine("Written {0} bytes of xattr {1} from file {2} to {3}", AaruConsole.WriteLine(UI.Written_0_bytes_of_xattr_1_from_file_2_to_3, xattrBuf.Length,
xattrBuf.Length, xattr, entry, outputPath); xattr, entry, outputPath);
} }
else else
AaruConsole.ErrorWriteLine("Cannot write xattr {0} for {1}, output exists", xattr, AaruConsole.ErrorWriteLine(UI.Cannot_write_xattr_0_for_1_output_exists, xattr, entry);
entry);
} }
} }
@@ -603,7 +604,8 @@ sealed class ExtractFilesCommand : Command
Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()). Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()).
Start(ctx => Start(ctx =>
{ {
ProgressTask task = ctx.AddTask($"Reading file {Markup.Escape(entry)}..."); ProgressTask task =
ctx.AddTask(string.Format(UI.Reading_file_0, Markup.Escape(entry)));
task.MaxValue = stat.Length; task.MaxValue = stat.Length;
byte[] outBuf = null; byte[] outBuf = null;
@@ -623,7 +625,7 @@ sealed class ExtractFilesCommand : Command
outputFile.Write(outBuf, 0, (int)bytesToRead); outputFile.Write(outBuf, 0, (int)bytesToRead);
else else
{ {
AaruConsole.ErrorWriteLine("Error {0} reading file {1}", error, entry); AaruConsole.ErrorWriteLine(UI.Error_0_reading_file_1, error, entry);
break; break;
} }
@@ -667,14 +669,14 @@ sealed class ExtractFilesCommand : Command
// ignored // ignored
} }
#pragma warning restore RECS0022 // A catch clause that catches System.Exception and has an empty body #pragma warning restore RECS0022 // A catch clause that catches System.Exception and has an empty body
AaruConsole.WriteLine("Written {0} bytes of file {1} to {2}", position, Markup.Escape(entry), AaruConsole.WriteLine(UI.Written_0_bytes_of_file_1_to_2, position, Markup.Escape(entry),
Markup.Escape(outputPath)); Markup.Escape(outputPath));
} }
else else
AaruConsole.ErrorWriteLine("Cannot write file {0}, output exists", Markup.Escape(entry)); AaruConsole.ErrorWriteLine(UI.Cannot_write_file_0_output_exists, Markup.Escape(entry));
} }
else else
AaruConsole.ErrorWriteLine("Error reading file {0}", Markup.Escape(entry)); AaruConsole.ErrorWriteLine(UI.Error_reading_file_0, Markup.Escape(entry));
} }
} }
} }

View File

@@ -31,12 +31,13 @@
// ****************************************************************************/ // ****************************************************************************/
using System.CommandLine; using System.CommandLine;
using Aaru.Localization;
namespace Aaru.Commands.Filesystem; namespace Aaru.Commands.Filesystem;
sealed class FilesystemFamily : Command sealed class FilesystemFamily : Command
{ {
public FilesystemFamily() : base("filesystem", "Commands to manage filesystems") public FilesystemFamily() : base("filesystem", UI.Filesystem_Command_Family_Description)
{ {
AddAlias("fi"); AddAlias("fi");
AddAlias("fs"); AddAlias("fs");

View File

@@ -40,34 +40,34 @@ using Aaru.CommonTypes.Enums;
using Aaru.CommonTypes.Interfaces; using Aaru.CommonTypes.Interfaces;
using Aaru.Console; using Aaru.Console;
using Aaru.Core; using Aaru.Core;
using Aaru.Localization;
using Spectre.Console; using Spectre.Console;
namespace Aaru.Commands.Filesystem; namespace Aaru.Commands.Filesystem;
sealed class FilesystemInfoCommand : Command sealed class FilesystemInfoCommand : Command
{ {
public FilesystemInfoCommand() : base("info", public FilesystemInfoCommand() : base("info", UI.Filesystem_Info_Command_Description)
"Opens a disc image and prints info on the found partitions and/or filesystems.")
{ {
Add(new Option<string>(new[] Add(new Option<string>(new[]
{ {
"--encoding", "-e" "--encoding", "-e"
}, () => null, "Name of character encoding to use.")); }, () => null, UI.Name_of_character_encoding_to_use));
Add(new Option<bool>(new[] Add(new Option<bool>(new[]
{ {
"--filesystems", "-f" "--filesystems", "-f"
}, () => true, "Searches and prints information about filesystems.")); }, () => true, UI.Searches_and_prints_information_about_filesystems));
Add(new Option<bool>(new[] Add(new Option<bool>(new[]
{ {
"--partitions", "-p" "--partitions", "-p"
}, () => true, "Searches and interprets partitions.")); }, () => true, UI.Searches_and_interprets_partitions));
AddArgument(new Argument<string> AddArgument(new Argument<string>
{ {
Arity = ArgumentArity.ExactlyOne, Arity = ArgumentArity.ExactlyOne,
Description = "Media image path", Description = UI.Media_image_path,
Name = "image-path" Name = "image-path"
}); });
@@ -118,13 +118,13 @@ sealed class FilesystemInfoCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Identifying file filter...").IsIndeterminate(); ctx.AddTask(UI.Identifying_file_filter).IsIndeterminate();
inputFilter = filtersList.GetFilter(imagePath); inputFilter = filtersList.GetFilter(imagePath);
}); });
if(inputFilter == null) if(inputFilter == null)
{ {
AaruConsole.ErrorWriteLine("Cannot open specified file."); AaruConsole.ErrorWriteLine(UI.Cannot_open_specified_file);
return (int)ErrorNumber.CannotOpenFile; return (int)ErrorNumber.CannotOpenFile;
} }
@@ -137,11 +137,11 @@ sealed class FilesystemInfoCommand : Command
encodingClass = Claunia.Encoding.Encoding.GetEncoding(encoding); encodingClass = Claunia.Encoding.Encoding.GetEncoding(encoding);
if(verbose) if(verbose)
AaruConsole.VerboseWriteLine("Using encoding for {0}.", encodingClass.EncodingName); AaruConsole.VerboseWriteLine(UI.encoding_for_0, encodingClass.EncodingName);
} }
catch(ArgumentException) catch(ArgumentException)
{ {
AaruConsole.ErrorWriteLine("Specified encoding is not supported."); AaruConsole.ErrorWriteLine(UI.Specified_encoding_is_not_supported);
return (int)ErrorNumber.EncodingUnknown; return (int)ErrorNumber.EncodingUnknown;
} }
@@ -157,29 +157,29 @@ sealed class FilesystemInfoCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Identifying image format...").IsIndeterminate(); ctx.AddTask(UI.Identifying_image_format).IsIndeterminate();
baseImage = ImageFormat.Detect(inputFilter); baseImage = ImageFormat.Detect(inputFilter);
imageFormat = baseImage as IMediaImage; imageFormat = baseImage as IMediaImage;
}); });
if(baseImage == null) if(baseImage == null)
{ {
AaruConsole.WriteLine("Image format not identified, not proceeding with analysis."); AaruConsole.WriteLine(UI.Image_format_not_identified_not_proceeding_with_analysis);
return (int)ErrorNumber.UnrecognizedFormat; return (int)ErrorNumber.UnrecognizedFormat;
} }
if(imageFormat == null) if(imageFormat == null)
{ {
AaruConsole.WriteLine("Command not supported for this image type."); AaruConsole.WriteLine(UI.Command_not_supported_for_this_image_type);
return (int)ErrorNumber.InvalidArgument; return (int)ErrorNumber.InvalidArgument;
} }
if(verbose) if(verbose)
AaruConsole.VerboseWriteLine("Image format identified by {0} ({1}).", imageFormat.Name, imageFormat.Id); AaruConsole.VerboseWriteLine(UI.Image_format_identified_by_0_1, imageFormat.Name, imageFormat.Id);
else else
AaruConsole.WriteLine("Image format identified by {0}.", imageFormat.Name); AaruConsole.WriteLine(UI.Image_format_identified_by_0, imageFormat.Name);
AaruConsole.WriteLine(); AaruConsole.WriteLine();
@@ -189,14 +189,14 @@ sealed class FilesystemInfoCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Opening image file...").IsIndeterminate(); ctx.AddTask(UI.Invoke_Opening_image_file).IsIndeterminate();
opened = imageFormat.Open(inputFilter); opened = imageFormat.Open(inputFilter);
}); });
if(opened != ErrorNumber.NoError) if(opened != ErrorNumber.NoError)
{ {
AaruConsole.WriteLine("Unable to open image format"); AaruConsole.WriteLine(UI.Unable_to_open_image_format);
AaruConsole.WriteLine("Error {0}", opened); AaruConsole.WriteLine(UI.Error_0, opened);
return (int)opened; return (int)opened;
} }
@@ -213,9 +213,9 @@ sealed class FilesystemInfoCommand : Command
} }
catch(Exception ex) catch(Exception ex)
{ {
AaruConsole.ErrorWriteLine("Unable to open image format"); AaruConsole.ErrorWriteLine(UI.Unable_to_open_image_format);
AaruConsole.ErrorWriteLine("Error: {0}", ex.Message); AaruConsole.ErrorWriteLine(UI.Error_0, ex.Message);
AaruConsole.DebugWriteLine("Fs-info command", "Stack trace: {0}", ex.StackTrace); AaruConsole.DebugWriteLine("Fs-info command", Localization.Core.Stack_trace_0, ex.StackTrace);
return (int)ErrorNumber.CannotOpenFormat; return (int)ErrorNumber.CannotOpenFormat;
} }
@@ -230,7 +230,7 @@ sealed class FilesystemInfoCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Enumerating partitions...").IsIndeterminate(); ctx.AddTask(UI.Enumerating_partitions).IsIndeterminate();
partitionsList = Core.Partitions.GetAll(imageFormat); partitionsList = Core.Partitions.GetAll(imageFormat);
}); });
@@ -238,11 +238,11 @@ sealed class FilesystemInfoCommand : Command
if(partitionsList.Count == 0) if(partitionsList.Count == 0)
{ {
AaruConsole.DebugWriteLine("Fs-info command", "No partitions found"); AaruConsole.DebugWriteLine("Fs-info command", UI.No_partitions_found);
if(!filesystems) if(!filesystems)
{ {
AaruConsole.WriteLine("No partitions founds, not searching for filesystems"); AaruConsole.WriteLine(UI.No_partitions_founds_not_searching_for_filesystems);
return (int)ErrorNumber.NothingFound; return (int)ErrorNumber.NothingFound;
} }
@@ -251,27 +251,32 @@ sealed class FilesystemInfoCommand : Command
} }
else else
{ {
AaruConsole.WriteLine("{0} partitions found.", partitionsList.Count); AaruConsole.WriteLine(UI._0_partitions_found, partitionsList.Count);
for(int i = 0; i < partitionsList.Count; i++) for(int i = 0; i < partitionsList.Count; i++)
{ {
Table table = new() Table table = new()
{ {
Title = new TableTitle($"Partition {partitionsList[i].Sequence}:") Title = new TableTitle(string.Format(UI.Partition_0, partitionsList[i].Sequence))
}; };
table.AddColumn(""); table.AddColumn("");
table.AddColumn(""); table.AddColumn("");
table.HideHeaders(); table.HideHeaders();
table.AddRow("Name", Markup.Escape(partitionsList[i].Name ?? "")); table.AddRow(UI.Title_Name, Markup.Escape(partitionsList[i].Name ?? ""));
table.AddRow("Type", Markup.Escape(partitionsList[i].Type ?? "")); table.AddRow(UI.Title_Type, Markup.Escape(partitionsList[i].Type ?? ""));
table.AddRow("Start", $"sector {partitionsList[i].Start}, byte {partitionsList[i].Offset}");
table.AddRow("Length", $"{partitionsList[i].Length} sectors, {partitionsList[i].Size} bytes"); table.AddRow(UI.Title_Start,
string.Format(UI.sector_0_byte_1, partitionsList[i].Start,
partitionsList[i].Offset));
table.AddRow("Scheme", Markup.Escape(partitionsList[i].Scheme ?? "")); table.AddRow(UI.Title_Length,
table.AddRow("Description", Markup.Escape(partitionsList[i].Description ?? "")); string.Format(UI._0_sectors_1_bytes, partitionsList[i].Length,
partitionsList[i].Size));
table.AddRow(UI.Title_Scheme, Markup.Escape(partitionsList[i].Scheme ?? ""));
table.AddRow(UI.Title_Description, Markup.Escape(partitionsList[i].Description ?? ""));
AnsiConsole.Write(table); AnsiConsole.Write(table);
@@ -280,24 +285,26 @@ sealed class FilesystemInfoCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Identifying filesystems on partition...").IsIndeterminate(); ctx.AddTask(UI.Identifying_filesystems_on_partition).IsIndeterminate();
Core.Filesystems.Identify(imageFormat, out idPlugins, partitionsList[i]); Core.Filesystems.Identify(imageFormat, out idPlugins, partitionsList[i]);
}); });
switch(idPlugins.Count) switch(idPlugins.Count)
{ {
case 0: case 0:
AaruConsole.WriteLine("[bold]Filesystem not identified[/]"); AaruConsole.WriteLine($"[bold]{UI.Filesystem_not_identified}[/]");
break; break;
case > 1: case > 1:
{ {
AaruConsole.WriteLine($"[italic]Identified by {idPlugins.Count} plugins[/]"); AaruConsole.WriteLine($"[italic]{string.Format(UI.Identified_by_0_plugins,
idPlugins.Count)}[/]");
foreach(string pluginName in idPlugins) foreach(string pluginName in idPlugins)
if(plugins.PluginsList.TryGetValue(pluginName, out plugin)) if(plugins.PluginsList.TryGetValue(pluginName, out plugin))
{ {
AaruConsole.WriteLine($"[bold]As identified by {plugin.Name}.[/]"); AaruConsole.WriteLine($"[bold]{string.Format(UI.As_identified_by_0, plugin.Name)
}[/]");
plugin.GetInformation(imageFormat, partitionsList[i], out information, plugin.GetInformation(imageFormat, partitionsList[i], out information,
encodingClass); encodingClass);
@@ -315,7 +322,7 @@ sealed class FilesystemInfoCommand : Command
if(plugin == null) if(plugin == null)
continue; continue;
AaruConsole.WriteLine($"[bold]Identified by {plugin.Name}.[/]"); AaruConsole.WriteLine($"[bold]{string.Format(UI.Identified_by_0, plugin.Name)}[/]");
plugin.GetInformation(imageFormat, partitionsList[i], out information, encodingClass); plugin.GetInformation(imageFormat, partitionsList[i], out information, encodingClass);
AaruConsole.Write("{0}", information); AaruConsole.Write("{0}", information);
Statistics.AddFilesystem(plugin.XmlFsType.Type); Statistics.AddFilesystem(plugin.XmlFsType.Type);
@@ -333,31 +340,32 @@ sealed class FilesystemInfoCommand : Command
{ {
var wholePart = new Partition var wholePart = new Partition
{ {
Name = "Whole device", Name = Localization.Core.Whole_device,
Length = imageFormat.Info.Sectors, Length = imageFormat.Info.Sectors,
Size = imageFormat.Info.Sectors * imageFormat.Info.SectorSize Size = imageFormat.Info.Sectors * imageFormat.Info.SectorSize
}; };
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Identifying filesystems...").IsIndeterminate(); ctx.AddTask(UI.Identifying_filesystems).IsIndeterminate();
Core.Filesystems.Identify(imageFormat, out idPlugins, wholePart); Core.Filesystems.Identify(imageFormat, out idPlugins, wholePart);
}); });
switch(idPlugins.Count) switch(idPlugins.Count)
{ {
case 0: case 0:
AaruConsole.WriteLine("[bold]Filesystem not identified[/]"); AaruConsole.WriteLine($"[bold]{UI.Filesystem_not_identified}[/]");
break; break;
case > 1: case > 1:
{ {
AaruConsole.WriteLine($"[italic]Identified by {idPlugins.Count} plugins[/]"); AaruConsole.WriteLine($"[italic]{string.Format(UI.Identified_by_0_plugins, idPlugins.Count)
}[/]");
foreach(string pluginName in idPlugins) foreach(string pluginName in idPlugins)
if(plugins.PluginsList.TryGetValue(pluginName, out plugin)) if(plugins.PluginsList.TryGetValue(pluginName, out plugin))
{ {
AaruConsole.WriteLine($"[bold]As identified by {plugin.Name}.[/]"); AaruConsole.WriteLine($"[bold]{string.Format(UI.As_identified_by_0, plugin.Name)}[/]");
plugin.GetInformation(imageFormat, wholePart, out information, encodingClass); plugin.GetInformation(imageFormat, wholePart, out information, encodingClass);
AaruConsole.Write(information); AaruConsole.Write(information);
Statistics.AddFilesystem(plugin.XmlFsType.Type); Statistics.AddFilesystem(plugin.XmlFsType.Type);
@@ -371,7 +379,7 @@ sealed class FilesystemInfoCommand : Command
if(plugin != null) if(plugin != null)
{ {
AaruConsole.WriteLine($"[bold]Identified by {plugin.Name}.[/]"); AaruConsole.WriteLine($"[bold]{string.Format(UI.Identified_by_0, plugin.Name)}[/]");
plugin.GetInformation(imageFormat, wholePart, out information, encodingClass); plugin.GetInformation(imageFormat, wholePart, out information, encodingClass);
AaruConsole.Write(information); AaruConsole.Write(information);
Statistics.AddFilesystem(plugin.XmlFsType.Type); Statistics.AddFilesystem(plugin.XmlFsType.Type);
@@ -384,7 +392,7 @@ sealed class FilesystemInfoCommand : Command
} }
catch(Exception ex) catch(Exception ex)
{ {
AaruConsole.ErrorWriteLine($"Error reading file: {ex.Message}"); AaruConsole.ErrorWriteLine(string.Format(UI.Error_reading_file_0, ex.Message));
AaruConsole.DebugWriteLine("Fs-info command", ex.StackTrace); AaruConsole.DebugWriteLine("Fs-info command", ex.StackTrace);
return (int)ErrorNumber.UnexpectedException; return (int)ErrorNumber.UnexpectedException;

View File

@@ -42,6 +42,7 @@ using Aaru.CommonTypes.Interfaces;
using Aaru.CommonTypes.Structs; using Aaru.CommonTypes.Structs;
using Aaru.Console; using Aaru.Console;
using Aaru.Core; using Aaru.Core;
using Aaru.Localization;
using JetBrains.Annotations; using JetBrains.Annotations;
using Spectre.Console; using Spectre.Console;
@@ -49,34 +50,34 @@ namespace Aaru.Commands.Filesystem;
sealed class LsCommand : Command sealed class LsCommand : Command
{ {
public LsCommand() : base("list", "Lists files in disc image.") public LsCommand() : base("list", UI.Filesystem_List_Command_Description)
{ {
AddAlias("ls"); AddAlias("ls");
Add(new Option<string>(new[] Add(new Option<string>(new[]
{ {
"--encoding", "-e" "--encoding", "-e"
}, () => null, "Name of character encoding to use.")); }, () => null, UI.Name_of_character_encoding_to_use));
Add(new Option<bool>(new[] Add(new Option<bool>(new[]
{ {
"--long-format", "-l" "--long-format", "-l"
}, () => true, "Uses long format.")); }, () => true, UI.Use_long_format));
Add(new Option<string>(new[] Add(new Option<string>(new[]
{ {
"--options", "-O" "--options", "-O"
}, () => null, "Comma separated name=value pairs of options to pass to filesystem plugin.")); }, () => null, UI.Comma_separated_name_value_pairs_of_filesystem_options));
Add(new Option<string>(new[] Add(new Option<string>(new[]
{ {
"--namespace", "-n" "--namespace", "-n"
}, () => null, "Namespace to use for filenames.")); }, () => null, UI.Namespace_to_use_for_filenames));
AddArgument(new Argument<string> AddArgument(new Argument<string>
{ {
Arity = ArgumentArity.ExactlyOne, Arity = ArgumentArity.ExactlyOne,
Description = "Media image path", Description = UI.Media_image_path,
Name = "image-path" Name = "image-path"
}); });
@@ -125,12 +126,12 @@ sealed class LsCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Identifying file filter...").IsIndeterminate(); ctx.AddTask(UI.Identifying_file_filter).IsIndeterminate();
inputFilter = filtersList.GetFilter(imagePath); inputFilter = filtersList.GetFilter(imagePath);
}); });
Dictionary<string, string> parsedOptions = Core.Options.Parse(options); Dictionary<string, string> parsedOptions = Core.Options.Parse(options);
AaruConsole.DebugWriteLine("Ls command", "Parsed options:"); AaruConsole.DebugWriteLine("Ls command", UI.Parsed_options);
foreach(KeyValuePair<string, string> parsedOption in parsedOptions) foreach(KeyValuePair<string, string> parsedOption in parsedOptions)
AaruConsole.DebugWriteLine("Ls command", "{0} = {1}", parsedOption.Key, parsedOption.Value); AaruConsole.DebugWriteLine("Ls command", "{0} = {1}", parsedOption.Key, parsedOption.Value);
@@ -139,7 +140,7 @@ sealed class LsCommand : Command
if(inputFilter == null) if(inputFilter == null)
{ {
AaruConsole.ErrorWriteLine("Cannot open specified file."); AaruConsole.ErrorWriteLine(UI.Cannot_open_specified_file);
return (int)ErrorNumber.CannotOpenFile; return (int)ErrorNumber.CannotOpenFile;
} }
@@ -152,11 +153,11 @@ sealed class LsCommand : Command
encodingClass = Claunia.Encoding.Encoding.GetEncoding(encoding); encodingClass = Claunia.Encoding.Encoding.GetEncoding(encoding);
if(verbose) if(verbose)
AaruConsole.VerboseWriteLine("Using encoding for {0}.", encodingClass.EncodingName); AaruConsole.VerboseWriteLine(UI.encoding_for_0, encodingClass.EncodingName);
} }
catch(ArgumentException) catch(ArgumentException)
{ {
AaruConsole.ErrorWriteLine("Specified encoding is not supported."); AaruConsole.ErrorWriteLine(UI.Specified_encoding_is_not_supported);
return (int)ErrorNumber.EncodingUnknown; return (int)ErrorNumber.EncodingUnknown;
} }
@@ -170,29 +171,29 @@ sealed class LsCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Identifying image format...").IsIndeterminate(); ctx.AddTask(UI.Identifying_image_format).IsIndeterminate();
baseImage = ImageFormat.Detect(inputFilter); baseImage = ImageFormat.Detect(inputFilter);
imageFormat = baseImage as IMediaImage; imageFormat = baseImage as IMediaImage;
}); });
if(baseImage == null) if(baseImage == null)
{ {
AaruConsole.WriteLine("Image format not identified, not proceeding with analysis."); AaruConsole.WriteLine(UI.Image_format_not_identified_not_proceeding_with_listing);
return (int)ErrorNumber.UnrecognizedFormat; return (int)ErrorNumber.UnrecognizedFormat;
} }
if(imageFormat == null) if(imageFormat == null)
{ {
AaruConsole.WriteLine("Command not supported for this image type."); AaruConsole.WriteLine(UI.Command_not_supported_for_this_image_type);
return (int)ErrorNumber.InvalidArgument; return (int)ErrorNumber.InvalidArgument;
} }
if(verbose) if(verbose)
AaruConsole.VerboseWriteLine("Image format identified by {0} ({1}).", imageFormat.Name, imageFormat.Id); AaruConsole.VerboseWriteLine(UI.Image_format_identified_by_0_1, imageFormat.Name, imageFormat.Id);
else else
AaruConsole.WriteLine("Image format identified by {0}.", imageFormat.Name); AaruConsole.WriteLine(UI.Image_format_identified_by_0, imageFormat.Name);
try try
{ {
@@ -200,26 +201,26 @@ sealed class LsCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Opening image file...").IsIndeterminate(); ctx.AddTask(UI.Invoke_Opening_image_file).IsIndeterminate();
opened = imageFormat.Open(inputFilter); opened = imageFormat.Open(inputFilter);
}); });
if(opened != ErrorNumber.NoError) if(opened != ErrorNumber.NoError)
{ {
AaruConsole.WriteLine("Unable to open image format"); AaruConsole.WriteLine(UI.Unable_to_open_image_format);
AaruConsole.WriteLine("Error {0}", opened); AaruConsole.WriteLine(UI.Error_0, opened);
return (int)opened; return (int)opened;
} }
AaruConsole.DebugWriteLine("Ls command", "Correctly opened image file."); AaruConsole.DebugWriteLine("Ls command", UI.Correctly_opened_image_file);
AaruConsole.DebugWriteLine("Ls command", "Image without headers is {0} bytes.", AaruConsole.DebugWriteLine("Ls command", UI.Image_without_headers_is_0_bytes,
imageFormat.Info.ImageSize); imageFormat.Info.ImageSize);
AaruConsole.DebugWriteLine("Ls command", "Image has {0} sectors.", imageFormat.Info.Sectors); AaruConsole.DebugWriteLine("Ls command", UI.Image_has_0_sectors, imageFormat.Info.Sectors);
AaruConsole.DebugWriteLine("Ls command", "Image identifies disk type as {0}.", AaruConsole.DebugWriteLine("Ls command", UI.Image_identifies_disk_type_as_0,
imageFormat.Info.MediaType); imageFormat.Info.MediaType);
Statistics.AddMediaFormat(imageFormat.Format); Statistics.AddMediaFormat(imageFormat.Format);
@@ -228,8 +229,8 @@ sealed class LsCommand : Command
} }
catch(Exception ex) catch(Exception ex)
{ {
AaruConsole.ErrorWriteLine("Unable to open image format"); AaruConsole.ErrorWriteLine(UI.Unable_to_open_image_format);
AaruConsole.ErrorWriteLine("Error: {0}", ex.Message); AaruConsole.ErrorWriteLine(UI.Error_0, ex.Message);
return (int)ErrorNumber.CannotOpenFormat; return (int)ErrorNumber.CannotOpenFormat;
} }
@@ -238,7 +239,7 @@ sealed class LsCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Enumerating partitions...").IsIndeterminate(); ctx.AddTask(UI.Enumerating_partitions).IsIndeterminate();
partitions = Core.Partitions.GetAll(imageFormat); partitions = Core.Partitions.GetAll(imageFormat);
}); });
@@ -246,11 +247,11 @@ sealed class LsCommand : Command
if(partitions.Count == 0) if(partitions.Count == 0)
{ {
AaruConsole.DebugWriteLine("Ls command", "No partitions found"); AaruConsole.DebugWriteLine("Ls command", UI.No_partitions_found);
partitions.Add(new Partition partitions.Add(new Partition
{ {
Description = "Whole device", Description = Localization.Core.Whole_device,
Length = imageFormat.Info.Sectors, Length = imageFormat.Info.Sectors,
Offset = 0, Offset = 0,
Size = imageFormat.Info.SectorSize * imageFormat.Info.Sectors, Size = imageFormat.Info.SectorSize * imageFormat.Info.Sectors,
@@ -259,23 +260,23 @@ sealed class LsCommand : Command
}); });
} }
AaruConsole.WriteLine("{0} partitions found.", partitions.Count); AaruConsole.WriteLine(UI._0_partitions_found, partitions.Count);
for(int i = 0; i < partitions.Count; i++) for(int i = 0; i < partitions.Count; i++)
{ {
AaruConsole.WriteLine(); AaruConsole.WriteLine();
AaruConsole.WriteLine("[bold]Partition {0}:[/]", partitions[i].Sequence); AaruConsole.WriteLine($"[bold]{string.Format(UI.Partition_0, partitions[i].Sequence)}[/]");
List<string> idPlugins = null; List<string> idPlugins = null;
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Identifying filesystems on partition...").IsIndeterminate(); ctx.AddTask(UI.Identifying_filesystems_on_partition).IsIndeterminate();
Core.Filesystems.Identify(imageFormat, out idPlugins, partitions[i]); Core.Filesystems.Identify(imageFormat, out idPlugins, partitions[i]);
}); });
if(idPlugins.Count == 0) if(idPlugins.Count == 0)
AaruConsole.WriteLine("Filesystem not identified"); AaruConsole.WriteLine(UI.Filesystem_not_identified);
else else
{ {
IReadOnlyFilesystem plugin; IReadOnlyFilesystem plugin;
@@ -283,12 +284,13 @@ sealed class LsCommand : Command
if(idPlugins.Count > 1) if(idPlugins.Count > 1)
{ {
AaruConsole.WriteLine($"[italic]Identified by {idPlugins.Count} plugins[/]"); AaruConsole.WriteLine($"[italic]{string.Format(UI.Identified_by_0_plugins, idPlugins.Count)
}[/]");
foreach(string pluginName in idPlugins) foreach(string pluginName in idPlugins)
if(plugins.ReadOnlyFilesystems.TryGetValue(pluginName, out plugin)) if(plugins.ReadOnlyFilesystems.TryGetValue(pluginName, out plugin))
{ {
AaruConsole.WriteLine($"[bold]As identified by {plugin.Name}.[/]"); AaruConsole.WriteLine($"[bold]{string.Format(UI.As_identified_by_0, plugin.Name)}[/]");
var fs = (IReadOnlyFilesystem)plugin.GetType().GetConstructor(Type.EmptyTypes)?. var fs = (IReadOnlyFilesystem)plugin.GetType().GetConstructor(Type.EmptyTypes)?.
Invoke(Array.Empty<object>()); Invoke(Array.Empty<object>());
@@ -298,7 +300,7 @@ sealed class LsCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Mounting filesystem...").IsIndeterminate(); ctx.AddTask(UI.Mounting_filesystem).IsIndeterminate();
error = fs.Mount(imageFormat, partitions[i], encodingClass, parsedOptions, error = fs.Mount(imageFormat, partitions[i], encodingClass, parsedOptions,
@namespace); @namespace);
@@ -311,7 +313,7 @@ sealed class LsCommand : Command
Statistics.AddFilesystem(fs.XmlFsType.Type); Statistics.AddFilesystem(fs.XmlFsType.Type);
} }
else else
AaruConsole.ErrorWriteLine("Unable to mount device, error {0}", error.ToString()); AaruConsole.ErrorWriteLine(UI.Unable_to_mount_volume_error_0, error.ToString());
} }
} }
else else
@@ -321,7 +323,7 @@ sealed class LsCommand : Command
if(plugin == null) if(plugin == null)
continue; continue;
AaruConsole.WriteLine($"[bold]Identified by {plugin.Name}.[/]"); AaruConsole.WriteLine($"[bold]{string.Format(UI.Identified_by_0, plugin.Name)}[/]");
var fs = (IReadOnlyFilesystem)plugin.GetType().GetConstructor(Type.EmptyTypes)?. var fs = (IReadOnlyFilesystem)plugin.GetType().GetConstructor(Type.EmptyTypes)?.
Invoke(Array.Empty<object>()); Invoke(Array.Empty<object>());
@@ -331,7 +333,7 @@ sealed class LsCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Mounting filesystem...").IsIndeterminate(); ctx.AddTask(UI.Mounting_filesystem).IsIndeterminate();
error = fs.Mount(imageFormat, partitions[i], encodingClass, parsedOptions, @namespace); error = fs.Mount(imageFormat, partitions[i], encodingClass, parsedOptions, @namespace);
}); });
@@ -342,14 +344,14 @@ sealed class LsCommand : Command
Statistics.AddFilesystem(fs.XmlFsType.Type); Statistics.AddFilesystem(fs.XmlFsType.Type);
} }
else else
AaruConsole.ErrorWriteLine("Unable to mount device, error {0}", error.ToString()); AaruConsole.ErrorWriteLine(UI.Unable_to_mount_volume_error_0, error.ToString());
} }
} }
} }
} }
catch(Exception ex) catch(Exception ex)
{ {
AaruConsole.ErrorWriteLine($"Error reading file: {ex.Message}"); AaruConsole.ErrorWriteLine(string.Format(UI.Error_reading_file_0, ex.Message));
AaruConsole.DebugWriteLine("Ls command", ex.StackTrace); AaruConsole.DebugWriteLine("Ls command", ex.StackTrace);
return (int)ErrorNumber.UnexpectedException; return (int)ErrorNumber.UnexpectedException;
@@ -366,17 +368,18 @@ sealed class LsCommand : Command
if(path.StartsWith('/')) if(path.StartsWith('/'))
path = path[1..]; path = path[1..];
AaruConsole.WriteLine(string.IsNullOrEmpty(path) ? "Root directory" : $"Directory: {Markup.Escape(path)}"); AaruConsole.WriteLine(string.IsNullOrEmpty(path) ? UI.Root_directory
: string.Format(UI.Directory_0, Markup.Escape(path)));
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Reading directory...").IsIndeterminate(); ctx.AddTask(UI.Reading_directory).IsIndeterminate();
error = fs.ReadDir(path, out directory); error = fs.ReadDir(path, out directory);
}); });
if(error != ErrorNumber.NoError) if(error != ErrorNumber.NoError)
{ {
AaruConsole.ErrorWriteLine("Error {0} reading root directory {1}", error.ToString(), path); AaruConsole.ErrorWriteLine(UI.Error_0_reading_directory_1, error.ToString(), path);
return; return;
} }
@@ -386,7 +389,7 @@ sealed class LsCommand : Command
AnsiConsole.Progress().AutoClear(true).HideCompleted(true). AnsiConsole.Progress().AutoClear(true).HideCompleted(true).
Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()).Start(ctx => Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()).Start(ctx =>
{ {
ProgressTask task = ctx.AddTask("Retrieving file information..."); ProgressTask task = ctx.AddTask(UI.Retrieving_file_information);
task.MaxValue = directory.Count; task.MaxValue = directory.Count;
foreach(string entry in directory) foreach(string entry in directory)
@@ -406,7 +409,7 @@ sealed class LsCommand : Command
{ {
if(entry.Value.Attributes.HasFlag(FileAttributes.Directory)) if(entry.Value.Attributes.HasFlag(FileAttributes.Directory))
AaruConsole.WriteLine("{0, 10:d} {0, 12:T} {1, -20} {2}", entry.Value.CreationTimeUtc, AaruConsole.WriteLine("{0, 10:d} {0, 12:T} {1, -20} {2}", entry.Value.CreationTimeUtc,
"<DIR>", Markup.Escape(entry.Key)); UI.Directory_abbreviation, Markup.Escape(entry.Key));
else else
AaruConsole.WriteLine("{0, 10:d} {0, 12:T} {1, 6}{2, 14:N0} {3}", entry.Value.CreationTimeUtc, AaruConsole.WriteLine("{0, 10:d} {0, 12:T} {1, 6}{2, 14:N0} {3}", entry.Value.CreationTimeUtc,
entry.Value.Inode, entry.Value.Length, Markup.Escape(entry.Key)); entry.Value.Inode, entry.Value.Length, Markup.Escape(entry.Key));

View File

@@ -40,6 +40,7 @@ using Aaru.CommonTypes.Enums;
using Aaru.CommonTypes.Interfaces; using Aaru.CommonTypes.Interfaces;
using Aaru.Console; using Aaru.Console;
using Aaru.Core; using Aaru.Core;
using Aaru.Localization;
using JetBrains.Annotations; using JetBrains.Annotations;
using Spectre.Console; using Spectre.Console;
@@ -47,7 +48,7 @@ namespace Aaru.Commands.Filesystem;
sealed class ListOptionsCommand : Command sealed class ListOptionsCommand : Command
{ {
public ListOptionsCommand() : base("options", "Lists all options supported by read-only filesystems.") => public ListOptionsCommand() : base("options", UI.Filesystem_Options_Command_Description) =>
Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke))); Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke)));
public static int Invoke(bool debug, bool verbose) public static int Invoke(bool debug, bool verbose)
@@ -85,7 +86,7 @@ sealed class ListOptionsCommand : Command
PluginBase plugins = GetPluginBase.Instance; PluginBase plugins = GetPluginBase.Instance;
AaruConsole.WriteLine("Read-only filesystems options:"); AaruConsole.WriteLine(UI.Read_only_filesystems_options);
foreach(KeyValuePair<string, IReadOnlyFilesystem> kvp in plugins.ReadOnlyFilesystems) foreach(KeyValuePair<string, IReadOnlyFilesystem> kvp in plugins.ReadOnlyFilesystems)
{ {
@@ -96,12 +97,12 @@ sealed class ListOptionsCommand : Command
var table = new Table var table = new Table
{ {
Title = new TableTitle($"Options for {kvp.Value.Name}:") Title = new TableTitle(string.Format(UI.Options_for_0, kvp.Value.Name))
}; };
table.AddColumn("Name"); table.AddColumn(UI.Title_Name);
table.AddColumn("Type"); table.AddColumn(UI.Title_Type);
table.AddColumn("Description"); table.AddColumn(UI.Title_Description);
foreach((string name, Type type, string description) option in options.OrderBy(t => t.name)) foreach((string name, Type type, string description) option in options.OrderBy(t => t.name))
table.AddRow(Markup.Escape(option.name), $"[italic]{TypeToString(option.type)}[/]", table.AddRow(Markup.Escape(option.name), $"[italic]{TypeToString(option.type)}[/]",
@@ -118,27 +119,27 @@ sealed class ListOptionsCommand : Command
static string TypeToString([NotNull] Type type) static string TypeToString([NotNull] Type type)
{ {
if(type == typeof(bool)) if(type == typeof(bool))
return "boolean"; return UI.TypeToString_boolean;
if(type == typeof(sbyte) || if(type == typeof(sbyte) ||
type == typeof(short) || type == typeof(short) ||
type == typeof(int) || type == typeof(int) ||
type == typeof(long)) type == typeof(long))
return "signed number"; return UI.TypeToString_signed_number;
if(type == typeof(byte) || if(type == typeof(byte) ||
type == typeof(ushort) || type == typeof(ushort) ||
type == typeof(uint) || type == typeof(uint) ||
type == typeof(ulong)) type == typeof(ulong))
return "number"; return UI.TypeToString_number;
if(type == typeof(float) || if(type == typeof(float) ||
type == typeof(double)) type == typeof(double))
return "float number"; return UI.TypeToString_float_number;
if(type == typeof(Guid)) if(type == typeof(Guid))
return "uuid"; return UI.TypeToString_uuid;
return type == typeof(string) ? "string" : type.ToString(); return type == typeof(string) ? UI.TypeToString_string : type.ToString();
} }
} }

View File

@@ -39,13 +39,14 @@ using Aaru.CommonTypes.Enums;
using Aaru.CommonTypes.Interfaces; using Aaru.CommonTypes.Interfaces;
using Aaru.Console; using Aaru.Console;
using Aaru.Core; using Aaru.Core;
using Aaru.Localization;
using Spectre.Console; using Spectre.Console;
namespace Aaru.Commands; namespace Aaru.Commands;
sealed class FormatsCommand : Command sealed class FormatsCommand : Command
{ {
public FormatsCommand() : base("formats", "Lists all supported disc images, partition schemes and file systems.") => public FormatsCommand() : base("formats", UI.List_Formats_Command_Description) =>
Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke))); Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke)));
public static int Invoke(bool verbose, bool debug) public static int Invoke(bool verbose, bool debug)
@@ -87,13 +88,13 @@ sealed class FormatsCommand : Command
Table table = new() Table table = new()
{ {
Title = new TableTitle($"Supported filters ({filtersList.Filters.Count}):") Title = new TableTitle(string.Format(UI.Supported_filters_0, filtersList.Filters.Count))
}; };
if(verbose) if(verbose)
table.AddColumn("GUID"); table.AddColumn(UI.Title_GUID);
table.AddColumn("Filter"); table.AddColumn(UI.Title_Filter);
foreach(KeyValuePair<string, IFilter> kvp in filtersList.Filters) foreach(KeyValuePair<string, IFilter> kvp in filtersList.Filters)
if(verbose) if(verbose)
@@ -107,15 +108,16 @@ sealed class FormatsCommand : Command
table = new Table table = new Table
{ {
Title = new TableTitle($"Read-only media image formats ({ Title = new TableTitle(string.Format(UI.Read_only_media_image_formats_0,
plugins.ImagePluginsList.Count(t => !t.Value.GetType().GetInterfaces().Contains(typeof(IWritableImage))) plugins.ImagePluginsList.Count(t => !t.Value.GetType().GetInterfaces().
}):") Contains(typeof(
IWritableImage)))))
}; };
if(verbose) if(verbose)
table.AddColumn("GUID"); table.AddColumn(UI.Title_GUID);
table.AddColumn("Media image format"); table.AddColumn(UI.Title_Media_image_format);
foreach(KeyValuePair<string, IMediaImage> kvp in plugins.ImagePluginsList.Where(t => !t.Value.GetType(). foreach(KeyValuePair<string, IMediaImage> kvp in plugins.ImagePluginsList.Where(t => !t.Value.GetType().
GetInterfaces().Contains(typeof(IWritableImage)))) GetInterfaces().Contains(typeof(IWritableImage))))
@@ -130,13 +132,13 @@ sealed class FormatsCommand : Command
table = new Table table = new Table
{ {
Title = new TableTitle($"Read/write media image formats ({plugins.WritableImages.Count}):") Title = new TableTitle(string.Format(UI.Read_write_media_image_formats_0, plugins.WritableImages.Count))
}; };
if(verbose) if(verbose)
table.AddColumn("GUID"); table.AddColumn(UI.Title_GUID);
table.AddColumn("Media image format"); table.AddColumn(UI.Title_Media_image_format);
foreach(KeyValuePair<string, IBaseWritableImage> kvp in plugins.WritableImages) foreach(KeyValuePair<string, IBaseWritableImage> kvp in plugins.WritableImages)
if(verbose) if(verbose)
@@ -150,15 +152,16 @@ sealed class FormatsCommand : Command
table = new Table table = new Table
{ {
Title = new TableTitle($"Supported filesystems for identification and information only ({ Title = new TableTitle(string.Format(UI.Supported_filesystems_for_identification_and_information_only_0,
plugins.PluginsList.Count(t => !t.Value.GetType().GetInterfaces().Contains(typeof(IReadOnlyFilesystem))) plugins.PluginsList.Count(t => !t.Value.GetType().GetInterfaces().
}):") Contains(typeof(
IReadOnlyFilesystem)))))
}; };
if(verbose) if(verbose)
table.AddColumn("GUID"); table.AddColumn(UI.Title_GUID);
table.AddColumn("Filesystem"); table.AddColumn(UI.Title_Filesystem);
foreach(KeyValuePair<string, IFilesystem> kvp in plugins.PluginsList.Where(t => !t.Value.GetType(). foreach(KeyValuePair<string, IFilesystem> kvp in plugins.PluginsList.Where(t => !t.Value.GetType().
GetInterfaces().Contains(typeof(IReadOnlyFilesystem)))) GetInterfaces().Contains(typeof(IReadOnlyFilesystem))))
@@ -173,14 +176,14 @@ sealed class FormatsCommand : Command
table = new Table table = new Table
{ {
Title = new TableTitle($"Supported filesystems that can read their contents ({ Title = new TableTitle(string.Format(UI.Supported_filesystems_that_can_read_their_contents_0,
plugins.ReadOnlyFilesystems.Count}):") plugins.ReadOnlyFilesystems.Count))
}; };
if(verbose) if(verbose)
table.AddColumn("GUID"); table.AddColumn(UI.Title_GUID);
table.AddColumn("Filesystem"); table.AddColumn(UI.Title_Filesystem);
foreach(KeyValuePair<string, IReadOnlyFilesystem> kvp in plugins.ReadOnlyFilesystems) foreach(KeyValuePair<string, IReadOnlyFilesystem> kvp in plugins.ReadOnlyFilesystems)
if(verbose) if(verbose)
@@ -194,13 +197,13 @@ sealed class FormatsCommand : Command
table = new Table table = new Table
{ {
Title = new TableTitle($"Supported partitioning schemes ({plugins.PartPluginsList.Count}):") Title = new TableTitle(string.Format(UI.Supported_partitioning_schemes_0, plugins.PartPluginsList.Count))
}; };
if(verbose) if(verbose)
table.AddColumn("GUID"); table.AddColumn(UI.Title_GUID);
table.AddColumn("Scheme"); table.AddColumn(UI.Title_Scheme);
foreach(KeyValuePair<string, IPartition> kvp in plugins.PartPluginsList) foreach(KeyValuePair<string, IPartition> kvp in plugins.PartPluginsList)
if(verbose) if(verbose)
@@ -214,11 +217,11 @@ sealed class FormatsCommand : Command
table = new Table table = new Table
{ {
Title = new TableTitle($"Supported archive formats ({plugins.Archives.Count}):") Title = new TableTitle(string.Format(UI.Supported_archive_formats_0, plugins.Archives.Count))
}; };
if(verbose) if(verbose)
table.AddColumn("GUID"); table.AddColumn(UI.Title_GUID);
table.AddColumn("Archive format"); table.AddColumn("Archive format");

View File

@@ -40,6 +40,7 @@ using Aaru.CommonTypes.Interfaces;
using Aaru.CommonTypes.Structs; using Aaru.CommonTypes.Structs;
using Aaru.Console; using Aaru.Console;
using Aaru.Core; using Aaru.Core;
using Aaru.Localization;
using Schemas; using Schemas;
using Spectre.Console; using Spectre.Console;
@@ -53,59 +54,59 @@ sealed class ChecksumCommand : Command
// How many bytes to read at once // How many bytes to read at once
const int BYTES_TO_READ = 65536; const int BYTES_TO_READ = 65536;
public ChecksumCommand() : base("checksum", "Checksums an image.") public ChecksumCommand() : base("checksum", UI.Image_Checksum_Command_Description)
{ {
AddAlias("chk"); AddAlias("chk");
Add(new Option<bool>(new[] Add(new Option<bool>(new[]
{ {
"--adler32", "-a" "--adler32", "-a"
}, () => false, "Calculates Adler32.")); }, () => false, UI.Calculates_Adler_32));
Add(new Option<bool>("--crc16", () => true, "Calculates CRC16.")); Add(new Option<bool>("--crc16", () => true, UI.Calculates_CRC16));
Add(new Option<bool>(new[] Add(new Option<bool>(new[]
{ {
"--crc32", "-c" "--crc32", "-c"
}, () => true, "Calculates CRC32.")); }, () => true, UI.Calculates_CRC32));
Add(new Option<bool>("--crc64", () => true, "Calculates CRC64.")); Add(new Option<bool>("--crc64", () => true, UI.Calculates_CRC64_ECMA));
Add(new Option<bool>("--fletcher16", () => false, "Calculates Fletcher-16.")); Add(new Option<bool>("--fletcher16", () => false, UI.Calculates_Fletcher_16));
Add(new Option<bool>("--fletcher32", () => false, "Calculates Fletcher-32.")); Add(new Option<bool>("--fletcher32", () => false, UI.Calculates_Fletcher_32));
Add(new Option<bool>(new[] Add(new Option<bool>(new[]
{ {
"--md5", "-m" "--md5", "-m"
}, () => true, "Calculates MD5.")); }, () => true, UI.Calculates_MD5));
Add(new Option<bool>(new[] Add(new Option<bool>(new[]
{ {
"--separated-tracks", "-t" "--separated-tracks", "-t"
}, () => true, "Checksums each track separately.")); }, () => true, UI.Checksums_each_track_separately));
Add(new Option<bool>(new[] Add(new Option<bool>(new[]
{ {
"--sha1", "-s" "--sha1", "-s"
}, () => true, "Calculates SHA1.")); }, () => true, UI.Calculates_SHA1));
Add(new Option<bool>("--sha256", () => false, "Calculates SHA256.")); Add(new Option<bool>("--sha256", () => false, UI.Calculates_SHA256));
Add(new Option<bool>("--sha384", () => false, "Calculates SHA384.")); Add(new Option<bool>("--sha384", () => false, UI.Calculates_SHA384));
Add(new Option<bool>("--sha512", () => true, "Calculates SHA512.")); Add(new Option<bool>("--sha512", () => true, UI.Calculates_SHA512));
Add(new Option<bool>(new[] Add(new Option<bool>(new[]
{ {
"--spamsum", "-f" "--spamsum", "-f"
}, () => true, "Calculates SpamSum fuzzy hash.")); }, () => true, UI.Calculates_SpamSum_fuzzy_hash));
Add(new Option<bool>(new[] Add(new Option<bool>(new[]
{ {
"--whole-disc", "-w" "--whole-disc", "-w"
}, () => true, "Checksums the whole disc.")); }, () => true, UI.Checksums_the_whole_disc));
AddArgument(new Argument<string> AddArgument(new Argument<string>
{ {
Arity = ArgumentArity.ExactlyOne, Arity = ArgumentArity.ExactlyOne,
Description = "Media image path", Description = UI.Media_image_path,
Name = "image-path" Name = "image-path"
}); });
@@ -168,13 +169,13 @@ sealed class ChecksumCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Identifying file filter...").IsIndeterminate(); ctx.AddTask(UI.Identifying_file_filter).IsIndeterminate();
inputFilter = filtersList.GetFilter(imagePath); inputFilter = filtersList.GetFilter(imagePath);
}); });
if(inputFilter == null) if(inputFilter == null)
{ {
AaruConsole.ErrorWriteLine("Cannot open specified file."); AaruConsole.ErrorWriteLine(UI.Cannot_open_specified_file);
return (int)ErrorNumber.CannotOpenFile; return (int)ErrorNumber.CannotOpenFile;
} }
@@ -183,13 +184,13 @@ sealed class ChecksumCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Identifying image format...").IsIndeterminate(); ctx.AddTask(UI.Identifying_image_format).IsIndeterminate();
inputFormat = ImageFormat.Detect(inputFilter); inputFormat = ImageFormat.Detect(inputFilter);
}); });
if(inputFormat == null) if(inputFormat == null)
{ {
AaruConsole.ErrorWriteLine("Unable to recognize image format, not checksumming"); AaruConsole.ErrorWriteLine(UI.Unable_to_recognize_image_format_not_checksumming);
return (int)ErrorNumber.UnrecognizedFormat; return (int)ErrorNumber.UnrecognizedFormat;
} }
@@ -198,13 +199,14 @@ sealed class ChecksumCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Opening image file...").IsIndeterminate(); ctx.AddTask(UI.Invoke_Opening_image_file).IsIndeterminate();
opened = inputFormat.Open(inputFilter); opened = inputFormat.Open(inputFilter);
}); });
if(opened != ErrorNumber.NoError) if(opened != ErrorNumber.NoError)
{ {
AaruConsole.WriteLine("Error {opened} opening image format"); AaruConsole.WriteLine(UI.Unable_to_open_image_format);
AaruConsole.WriteLine(UI.Error_0, opened);
return (int)opened; return (int)opened;
} }
@@ -270,15 +272,16 @@ sealed class ChecksumCommand : Command
Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()). Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()).
Start(ctx => Start(ctx =>
{ {
ProgressTask discTask = ctx.AddTask("Hashing tracks..."); ProgressTask discTask = ctx.AddTask(UI.Hashing_tracks);
discTask.MaxValue = inputTracks.Count; discTask.MaxValue = inputTracks.Count;
foreach(Track currentTrack in inputTracks) foreach(Track currentTrack in inputTracks)
{ {
discTask.Description = discTask.Description =
$"Hashing track {discTask.Value + 1} of {inputTracks.Count}"; string.Format(UI.Hashing_track_0_of_1, discTask.Value + 1,
inputTracks.Count);
ProgressTask trackTask = ctx.AddTask("Hashing sector"); ProgressTask trackTask = ctx.AddTask(UI.Hashing_sector);
/* /*
if(currentTrack.StartSector - previousTrackEnd != 0 && wholeDisc) if(currentTrack.StartSector - previousTrackEnd != 0 && wholeDisc)
@@ -293,7 +296,7 @@ sealed class ChecksumCommand : Command
*/ */
AaruConsole.DebugWriteLine("Checksum command", AaruConsole.DebugWriteLine("Checksum command",
"Track {0} starts at sector {1} and ends at sector {2}", UI.Track_0_starts_at_sector_1_and_ends_at_sector_2,
currentTrack.Sequence, currentTrack.StartSector, currentTrack.Sequence, currentTrack.StartSector,
currentTrack.EndSector); currentTrack.EndSector);
@@ -316,15 +319,16 @@ sealed class ChecksumCommand : Command
currentTrack.Sequence, out sector); currentTrack.Sequence, out sector);
trackTask.Description = trackTask.Description =
string.Format("Hashing sectors {0} to {2} of track {1}", string.Format(UI.Hashing_sectors_0_to_2_of_track_1, doneSectors,
doneSectors, currentTrack.Sequence, currentTrack.Sequence, doneSectors + SECTORS_TO_READ);
doneSectors + SECTORS_TO_READ);
if(errno != ErrorNumber.NoError) if(errno != ErrorNumber.NoError)
{ {
AaruConsole.ErrorWriteLine($"Error {errno} while reading { AaruConsole.
SECTORS_TO_READ} sectors from sector {doneSectors ErrorWriteLine(string.
}, not continuing..."); Format(UI.Error_0_while_reading_1_sectors_from_sector_2,
errno, SECTORS_TO_READ,
doneSectors));
return; return;
} }
@@ -338,15 +342,17 @@ sealed class ChecksumCommand : Command
out sector); out sector);
trackTask.Description = trackTask.Description =
string.Format("Hashing sectors {0} to {2} of track {1}", string.Format(UI.Hashing_sectors_0_to_2_of_track_1, doneSectors,
doneSectors, currentTrack.Sequence, currentTrack.Sequence,
doneSectors + (sectors - doneSectors)); doneSectors + (sectors - doneSectors));
if(errno != ErrorNumber.NoError) if(errno != ErrorNumber.NoError)
{ {
AaruConsole.ErrorWriteLine($"Error {errno} while reading { AaruConsole.
sectors - doneSectors} sectors from sector {doneSectors ErrorWriteLine(string.
}, not continuing..."); Format(UI.Error_0_while_reading_1_sectors_from_sector_2,
errno, sectors - doneSectors,
doneSectors));
return; return;
} }
@@ -373,8 +379,8 @@ sealed class ChecksumCommand : Command
continue; continue;
foreach(ChecksumType chk in trackChecksum.End()) foreach(ChecksumType chk in trackChecksum.End())
AaruConsole.WriteLine("[bold]Track {0}'s {1}:[/] {2}", AaruConsole.WriteLine($"[bold]{string.Format(UI.Checksums_Track_0_has_1,
currentTrack.Sequence, chk.type, chk.Value); currentTrack.Sequence, chk.type)}[/] {chk.Value}");
discTask.Increment(1); discTask.Increment(1);
} }
@@ -399,7 +405,8 @@ sealed class ChecksumCommand : Command
AaruConsole.WriteLine(); AaruConsole.WriteLine();
foreach(ChecksumType chk in mediaChecksum.End()) foreach(ChecksumType chk in mediaChecksum.End())
AaruConsole.WriteLine("[bold]Disc's {0}:[/] {1}", chk.type, chk.Value); AaruConsole.WriteLine($"[bold]{string.Format(UI.Checksums_Disc_has_0, chk.type)
}:[/] {chk.Value}");
}); });
if(errno != ErrorNumber.NoError) if(errno != ErrorNumber.NoError)
@@ -408,7 +415,7 @@ sealed class ChecksumCommand : Command
catch(Exception ex) catch(Exception ex)
{ {
if(debug) if(debug)
AaruConsole.DebugWriteLine("Could not get tracks because {0}", ex.Message); AaruConsole.DebugWriteLine(UI.Could_not_get_tracks_because_0, ex.Message);
else else
AaruConsole.WriteLine("Unable to get separate tracks, not checksumming them"); AaruConsole.WriteLine("Unable to get separate tracks, not checksumming them");
} }
@@ -428,29 +435,30 @@ sealed class ChecksumCommand : Command
Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()). Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()).
Start(ctx => Start(ctx =>
{ {
ProgressTask tapeTask = ctx.AddTask("Hashing files..."); ProgressTask tapeTask = ctx.AddTask(UI.Hashing_files);
tapeTask.MaxValue = tapeImage.Files.Count; tapeTask.MaxValue = tapeImage.Files.Count;
foreach(TapeFile currentFile in tapeImage.Files) foreach(TapeFile currentFile in tapeImage.Files)
{ {
tapeTask.Description = tapeTask.Description =
$"Hashing file {currentFile.File} of {tapeImage.Files.Count}"; string.Format(UI.Hashing_file_0_of_1, currentFile.File, tapeImage.Files.Count);
if(currentFile.FirstBlock - previousFileEnd != 0 && wholeDisc) if(currentFile.FirstBlock - previousFileEnd != 0 && wholeDisc)
{ {
ProgressTask preFileTask = ctx.AddTask("Hashing sector"); ProgressTask preFileTask = ctx.AddTask(UI.Hashing_sector);
preFileTask.MaxValue = currentFile.FirstBlock - previousFileEnd; preFileTask.MaxValue = currentFile.FirstBlock - previousFileEnd;
for(ulong i = previousFileEnd + 1; i < currentFile.FirstBlock; i++) for(ulong i = previousFileEnd + 1; i < currentFile.FirstBlock; i++)
{ {
preFileTask.Description = $"Hashing file-less block {i}"; preFileTask.Description = string.Format(UI.Hashing_file_less_block_0, i);
errno = tapeImage.ReadSector(i, out byte[] hiddenSector); errno = tapeImage.ReadSector(i, out byte[] hiddenSector);
if(errno != ErrorNumber.NoError) if(errno != ErrorNumber.NoError)
{ {
AaruConsole.ErrorWriteLine($"Error {errno} while reading sector {i AaruConsole.
}, not continuing..."); ErrorWriteLine(string.Format(UI.Error_0_while_reading_block_1,
errno, i));
return; return;
} }
@@ -463,7 +471,7 @@ sealed class ChecksumCommand : Command
} }
AaruConsole.DebugWriteLine("Checksum command", AaruConsole.DebugWriteLine("Checksum command",
"File {0} starts at sector {1} and ends at block {2}", UI.File_0_starts_at_block_1_and_ends_at_block_2,
currentFile.File, currentFile.FirstBlock, currentFile.File, currentFile.FirstBlock,
currentFile.LastBlock); currentFile.LastBlock);
@@ -473,7 +481,7 @@ sealed class ChecksumCommand : Command
ulong sectors = currentFile.LastBlock - currentFile.FirstBlock + 1; ulong sectors = currentFile.LastBlock - currentFile.FirstBlock + 1;
ulong doneSectors = 0; ulong doneSectors = 0;
ProgressTask fileTask = ctx.AddTask("Hashing sector"); ProgressTask fileTask = ctx.AddTask(UI.Hashing_sector);
fileTask.MaxValue = sectors; fileTask.MaxValue = sectors;
while(doneSectors < sectors) while(doneSectors < sectors)
@@ -487,15 +495,17 @@ sealed class ChecksumCommand : Command
if(errno != ErrorNumber.NoError) if(errno != ErrorNumber.NoError)
{ {
AaruConsole.ErrorWriteLine($"Error {errno} while reading { AaruConsole.
SECTORS_TO_READ} sectors from sector { ErrorWriteLine(string.
doneSectors + currentFile.FirstBlock}, not continuing..."); Format(UI.Error_0_while_reading_1_sectors_from_sector_2,
errno, SECTORS_TO_READ,
doneSectors + currentFile.FirstBlock));
return; return;
} }
fileTask.Description = fileTask.Description =
string.Format("Hashing blocks {0} to {2} of file {1}", doneSectors, string.Format(UI.Hashing_blocks_0_to_2_of_file_1, doneSectors,
currentFile.File, doneSectors + SECTORS_TO_READ); currentFile.File, doneSectors + SECTORS_TO_READ);
doneSectors += SECTORS_TO_READ; doneSectors += SECTORS_TO_READ;
@@ -507,15 +517,17 @@ sealed class ChecksumCommand : Command
if(errno != ErrorNumber.NoError) if(errno != ErrorNumber.NoError)
{ {
AaruConsole.ErrorWriteLine($"Error {errno} while reading { AaruConsole.
sectors - doneSectors} sectors from sector { ErrorWriteLine(string.
doneSectors + currentFile.FirstBlock}, not continuing..."); Format(UI.Error_0_while_reading_1_sectors_from_sector_2,
errno, sectors - doneSectors,
doneSectors + currentFile.FirstBlock));
return; return;
} }
fileTask.Description = fileTask.Description =
string.Format("Hashing blocks {0} to {2} of file {1}", doneSectors, string.Format(UI.Hashing_blocks_0_to_2_of_file_1, doneSectors,
currentFile.File, doneSectors + (sectors - doneSectors)); currentFile.File, doneSectors + (sectors - doneSectors));
doneSectors += sectors - doneSectors; doneSectors += sectors - doneSectors;
@@ -536,8 +548,8 @@ sealed class ChecksumCommand : Command
if(separatedTracks) if(separatedTracks)
if(trackChecksum != null) if(trackChecksum != null)
foreach(ChecksumType chk in trackChecksum.End()) foreach(ChecksumType chk in trackChecksum.End())
AaruConsole.WriteLine("[bold]File {0}'s {1}[/]: {2}", currentFile.File, AaruConsole.WriteLine($"[bold]{string.Format(UI.Checksums_File_0_has_1,
chk.type, chk.Value); currentFile.File, chk.type)}[/]: {chk.Value}");
previousFileEnd = currentFile.LastBlock; previousFileEnd = currentFile.LastBlock;
@@ -548,19 +560,19 @@ sealed class ChecksumCommand : Command
!wholeDisc) !wholeDisc)
return; return;
ProgressTask postFileTask = ctx.AddTask("Hashing sector"); ProgressTask postFileTask = ctx.AddTask(UI.Hashing_sector);
postFileTask.MaxValue = tapeImage.Info.Sectors - previousFileEnd; postFileTask.MaxValue = tapeImage.Info.Sectors - previousFileEnd;
for(ulong i = previousFileEnd + 1; i < tapeImage.Info.Sectors; i++) for(ulong i = previousFileEnd + 1; i < tapeImage.Info.Sectors; i++)
{ {
postFileTask.Description = $"Hashing file-less block {i}"; postFileTask.Description = string.Format(UI.Hashing_file_less_block_0, i);
errno = tapeImage.ReadSector(i, out byte[] hiddenSector); errno = tapeImage.ReadSector(i, out byte[] hiddenSector);
if(errno != ErrorNumber.NoError) if(errno != ErrorNumber.NoError)
{ {
AaruConsole.ErrorWriteLine($"Error {errno} while reading sector {i AaruConsole.ErrorWriteLine(string.Format(UI.Error_0_while_reading_block_1,
}, not continuing..."); errno, i));
return; return;
} }
@@ -578,7 +590,8 @@ sealed class ChecksumCommand : Command
AaruConsole.WriteLine(); AaruConsole.WriteLine();
foreach(ChecksumType chk in mediaChecksum.End()) foreach(ChecksumType chk in mediaChecksum.End())
AaruConsole.WriteLine("[bold]Tape's {0}:[/] {1}", chk.type, chk.Value); AaruConsole.WriteLine($"[bold]{string.Format(UI.Checksums_Tape_has_0, chk.type)}[/] {chk.Value
}");
} }
break; break;
@@ -592,7 +605,7 @@ sealed class ChecksumCommand : Command
Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()). Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()).
Start(ctx => Start(ctx =>
{ {
ProgressTask imageTask = ctx.AddTask("Hashing image..."); ProgressTask imageTask = ctx.AddTask(UI.Hashing_image);
ulong length = byteAddressableImage.Info.Sectors; ulong length = byteAddressableImage.Info.Sectors;
imageTask.MaxValue = length; imageTask.MaxValue = length;
ulong doneBytes = 0; ulong doneBytes = 0;
@@ -608,14 +621,16 @@ sealed class ChecksumCommand : Command
if(errno != ErrorNumber.NoError) if(errno != ErrorNumber.NoError)
{ {
AaruConsole.ErrorWriteLine($"Error {errno} while reading {BYTES_TO_READ AaruConsole.
} bytes from {doneBytes}, not continuing..."); ErrorWriteLine(string.Format(UI.Error_0_while_reading_1_bytes_from_2,
errno, BYTES_TO_READ, doneBytes));
return; return;
} }
imageTask.Description = imageTask.Description =
$"Hashing bytes {doneBytes} to {doneBytes + BYTES_TO_READ}"; string.Format(UI.Hashing_bytes_0_to_1, doneBytes,
doneBytes + BYTES_TO_READ);
doneBytes += (ulong)bytesRead; doneBytes += (ulong)bytesRead;
@@ -629,14 +644,16 @@ sealed class ChecksumCommand : Command
if(errno != ErrorNumber.NoError) if(errno != ErrorNumber.NoError)
{ {
AaruConsole.ErrorWriteLine($"Error {errno} while reading {length - doneBytes AaruConsole.
} bytes from {doneBytes}, not continuing..."); ErrorWriteLine(string.Format(UI.Error_0_while_reading_1_bytes_from_2,
errno, length - doneBytes, doneBytes));
return; return;
} }
imageTask.Description = $"Hashing bytes {doneBytes} to { imageTask.Description =
doneBytes + (length - doneBytes)}"; string.Format(UI.Hashing_bytes_0_to_1, doneBytes,
doneBytes + (length - doneBytes));
doneBytes += length - doneBytes; doneBytes += length - doneBytes;
} }
@@ -652,7 +669,7 @@ sealed class ChecksumCommand : Command
AaruConsole.WriteLine(); AaruConsole.WriteLine();
foreach(ChecksumType chk in mediaChecksum.End()) foreach(ChecksumType chk in mediaChecksum.End())
AaruConsole.WriteLine("[bold]Media's {0}:[/] {1}", chk.type, chk.Value); AaruConsole.WriteLine($"[bold]{string.Format(UI.Checksums_Media_has_0, chk.type)}[/] {chk.Value}");
break; break;
} }
@@ -666,7 +683,7 @@ sealed class ChecksumCommand : Command
Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()). Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()).
Start(ctx => Start(ctx =>
{ {
ProgressTask diskTask = ctx.AddTask("Hashing sectors..."); ProgressTask diskTask = ctx.AddTask(UI.Hashing_sectors);
ulong sectors = mediaImage.Info.Sectors; ulong sectors = mediaImage.Info.Sectors;
diskTask.MaxValue = sectors; diskTask.MaxValue = sectors;
ulong doneSectors = 0; ulong doneSectors = 0;
@@ -681,14 +698,17 @@ sealed class ChecksumCommand : Command
if(errno != ErrorNumber.NoError) if(errno != ErrorNumber.NoError)
{ {
AaruConsole.ErrorWriteLine($"Error {errno} while reading {SECTORS_TO_READ AaruConsole.
} sectors from sector {doneSectors}, not continuing..."); ErrorWriteLine(string.
Format(UI.Error_0_while_reading_1_sectors_from_sector_2,
errno, SECTORS_TO_READ, doneSectors));
return; return;
} }
diskTask.Description = $"Hashing sectors {doneSectors} to { diskTask.Description =
doneSectors + SECTORS_TO_READ}"; string.Format(UI.Hashing_sectors_0_to_1, doneSectors,
doneSectors + SECTORS_TO_READ);
doneSectors += SECTORS_TO_READ; doneSectors += SECTORS_TO_READ;
} }
@@ -699,15 +719,17 @@ sealed class ChecksumCommand : Command
if(errno != ErrorNumber.NoError) if(errno != ErrorNumber.NoError)
{ {
AaruConsole.ErrorWriteLine($"Error {errno} while reading { AaruConsole.
sectors - doneSectors} sectors from sector {doneSectors ErrorWriteLine(string.
}, not continuing..."); Format(UI.Error_0_while_reading_1_sectors_from_sector_2,
errno, sectors - doneSectors, doneSectors));
return; return;
} }
diskTask.Description = $"Hashing sectors {doneSectors} to { diskTask.Description =
doneSectors + (sectors - doneSectors)}"; string.Format(UI.Hashing_sectors_0_to_1, doneSectors,
doneSectors + (sectors - doneSectors));
doneSectors += sectors - doneSectors; doneSectors += sectors - doneSectors;
} }
@@ -723,7 +745,7 @@ sealed class ChecksumCommand : Command
AaruConsole.WriteLine(); AaruConsole.WriteLine();
foreach(ChecksumType chk in mediaChecksum.End()) foreach(ChecksumType chk in mediaChecksum.End())
AaruConsole.WriteLine("[bold]Disk's {0}:[/] {1}", chk.type, chk.Value); AaruConsole.WriteLine($"[bold]{string.Format(UI.Checksums_Disk_has_0, chk.type)}[/] {chk.Value}");
break; break;
} }

View File

@@ -43,6 +43,7 @@ using Aaru.CommonTypes.Interfaces;
using Aaru.Console; using Aaru.Console;
using Aaru.Core; using Aaru.Core;
using Aaru.Helpers; using Aaru.Helpers;
using Aaru.Localization;
using Spectre.Console; using Spectre.Console;
using ImageInfo = Aaru.CommonTypes.Structs.ImageInfo; using ImageInfo = Aaru.CommonTypes.Structs.ImageInfo;
@@ -50,21 +51,21 @@ namespace Aaru.Commands.Image;
sealed class CompareCommand : Command sealed class CompareCommand : Command
{ {
public CompareCommand() : base("compare", "Compares two disc images.") public CompareCommand() : base("compare", UI.Image_Compare_Command_Description)
{ {
AddAlias("cmp"); AddAlias("cmp");
AddArgument(new Argument<string> AddArgument(new Argument<string>
{ {
Arity = ArgumentArity.ExactlyOne, Arity = ArgumentArity.ExactlyOne,
Description = "First media image path", Description = UI.First_media_image_path,
Name = "image-path1" Name = "image-path1"
}); });
AddArgument(new Argument<string> AddArgument(new Argument<string>
{ {
Arity = ArgumentArity.ExactlyOne, Arity = ArgumentArity.ExactlyOne,
Description = "Second media image path", Description = UI.Second_media_image_path,
Name = "image-path2" Name = "image-path2"
}); });
@@ -113,7 +114,7 @@ sealed class CompareCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Identifying file 1 filter...").IsIndeterminate(); ctx.AddTask(UI.Identifying_first_file_filter).IsIndeterminate();
inputFilter1 = filtersList.GetFilter(imagePath1); inputFilter1 = filtersList.GetFilter(imagePath1);
}); });
@@ -121,20 +122,20 @@ sealed class CompareCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Identifying file 2 filter...").IsIndeterminate(); ctx.AddTask(UI.Identifying_second_file_filter).IsIndeterminate();
inputFilter2 = filtersList.GetFilter(imagePath2); inputFilter2 = filtersList.GetFilter(imagePath2);
}); });
if(inputFilter1 == null) if(inputFilter1 == null)
{ {
AaruConsole.ErrorWriteLine("Cannot open input file 1"); AaruConsole.ErrorWriteLine(UI.Cannot_open_first_input_file);
return (int)ErrorNumber.CannotOpenFile; return (int)ErrorNumber.CannotOpenFile;
} }
if(inputFilter2 == null) if(inputFilter2 == null)
{ {
AaruConsole.ErrorWriteLine("Cannot open input file 2"); AaruConsole.ErrorWriteLine(UI.Cannot_open_second_input_file);
return (int)ErrorNumber.CannotOpenFile; return (int)ErrorNumber.CannotOpenFile;
} }
@@ -144,69 +145,69 @@ sealed class CompareCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Identifying image 1 format...").IsIndeterminate(); ctx.AddTask(UI.Identifying_first_image_format).IsIndeterminate();
input1Format = ImageFormat.Detect(inputFilter1); input1Format = ImageFormat.Detect(inputFilter1);
}); });
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Identifying image 1 format...").IsIndeterminate(); ctx.AddTask(UI.Identifying_second_image_format).IsIndeterminate();
input2Format = ImageFormat.Detect(inputFilter2); input2Format = ImageFormat.Detect(inputFilter2);
}); });
if(input1Format == null) if(input1Format == null)
{ {
AaruConsole.ErrorWriteLine("Input file 1 format not identified, not proceeding with comparison."); AaruConsole.ErrorWriteLine(UI.First_input_file_format_not_identified);
return (int)ErrorNumber.UnrecognizedFormat; return (int)ErrorNumber.UnrecognizedFormat;
} }
if(verbose) if(verbose)
AaruConsole.VerboseWriteLine("Input file 1 format identified by {0} ({1}).", input1Format.Name, AaruConsole.VerboseWriteLine(UI.First_input_file_format_identified_by_0_1, input1Format.Name,
input1Format.Id); input1Format.Id);
else else
AaruConsole.WriteLine("Input file 1 format identified by {0}.", input1Format.Name); AaruConsole.WriteLine(UI.First_input_file_format_identified_by_0, input1Format.Name);
if(input2Format == null) if(input2Format == null)
{ {
AaruConsole.ErrorWriteLine("Input file 2 format not identified, not proceeding with comparison."); AaruConsole.ErrorWriteLine(UI.Second_input_file_format_not_identified);
return (int)ErrorNumber.UnrecognizedFormat; return (int)ErrorNumber.UnrecognizedFormat;
} }
if(verbose) if(verbose)
AaruConsole.VerboseWriteLine("Input file 2 format identified by {0} ({1}).", input2Format.Name, AaruConsole.VerboseWriteLine(UI.Second_input_file_format_identified_by_0_1, input2Format.Name,
input2Format.Id); input2Format.Id);
else else
AaruConsole.WriteLine("Input file 2 format identified by {0}.", input2Format.Name); AaruConsole.WriteLine(UI.Second_input_file_format_identified_by_0, input2Format.Name);
ErrorNumber opened1 = ErrorNumber.NoData; ErrorNumber opened1 = ErrorNumber.NoData;
ErrorNumber opened2 = ErrorNumber.NoData; ErrorNumber opened2 = ErrorNumber.NoData;
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Opening image 1 file...").IsIndeterminate(); ctx.AddTask(UI.Opening_first_image_file).IsIndeterminate();
opened1 = input1Format.Open(inputFilter1); opened1 = input1Format.Open(inputFilter1);
}); });
if(opened1 != ErrorNumber.NoError) if(opened1 != ErrorNumber.NoError)
{ {
AaruConsole.WriteLine("Unable to open image 1 format"); AaruConsole.WriteLine(UI.Unable_to_open_first_image_format);
AaruConsole.WriteLine("Error {0}", opened1); AaruConsole.WriteLine(UI.Error_0, opened1);
return (int)opened1; return (int)opened1;
} }
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Opening image 2 file...").IsIndeterminate(); ctx.AddTask(UI.Opening_second_image_file).IsIndeterminate();
opened2 = input2Format.Open(inputFilter2); opened2 = input2Format.Open(inputFilter2);
}); });
if(opened2 != ErrorNumber.NoError) if(opened2 != ErrorNumber.NoError)
{ {
AaruConsole.WriteLine("Unable to open image 2 format"); AaruConsole.WriteLine(UI.Unable_to_open_second_image_format);
AaruConsole.WriteLine("Error {0}", opened2); AaruConsole.WriteLine(UI.Error_0, opened2);
return (int)opened2; return (int)opened2;
} }
@@ -221,19 +222,19 @@ sealed class CompareCommand : Command
var sb = new StringBuilder(); var sb = new StringBuilder();
Table table = new(); Table table = new();
table.AddColumn(""); table.AddColumn("");
table.AddColumn("Media image 1"); table.AddColumn(UI.Title_First_Media_image);
table.AddColumn("Media image 2"); table.AddColumn(UI.Title_Second_Media_image);
table.Columns[0].RightAligned(); table.Columns[0].RightAligned();
if(verbose) if(verbose)
{ {
table.AddRow("File", Markup.Escape(imagePath1), Markup.Escape(imagePath2)); table.AddRow(UI.Title_File, Markup.Escape(imagePath1), Markup.Escape(imagePath2));
table.AddRow("Media image format", input1Format.Name, input2Format.Name); table.AddRow(UI.Title_Media_image_format, input1Format.Name, input2Format.Name);
} }
else else
{ {
sb.AppendFormat("[bold]Media image 1:[/] {0}", imagePath1).AppendLine(); sb.AppendFormat($"[bold]{UI.Title_First_Media_image}:[/] {imagePath1}").AppendLine();
sb.AppendFormat("[bold]Media image 2:[/] {0}", imagePath2).AppendLine(); sb.AppendFormat($"[bold]{UI.Title_Second_Media_image}:[/] {imagePath2}").AppendLine();
} }
bool imagesDiffer = false; bool imagesDiffer = false;
@@ -266,64 +267,74 @@ sealed class CompareCommand : Command
if(verbose) if(verbose)
{ {
table.AddRow("Has partitions?", image1Info.HasPartitions.ToString(), image2Info.HasPartitions.ToString()); table.AddRow(UI.Has_partitions_Question, image1Info.HasPartitions.ToString(),
image2Info.HasPartitions.ToString());
table.AddRow("Has sessions?", image1Info.HasSessions.ToString(), image2Info.HasSessions.ToString()); table.AddRow(UI.Has_sessions_Question, image1Info.HasSessions.ToString(),
image2Info.HasSessions.ToString());
table.AddRow("Image size", image1Info.ImageSize.ToString(), image2Info.ImageSize.ToString()); table.AddRow(UI.Title_Image_size, image1Info.ImageSize.ToString(), image2Info.ImageSize.ToString());
table.AddRow("Sectors", image1Info.Sectors.ToString(), image2Info.Sectors.ToString()); table.AddRow(UI.Title_Sectors, image1Info.Sectors.ToString(), image2Info.Sectors.ToString());
table.AddRow("Sector size", image1Info.SectorSize.ToString(), image2Info.SectorSize.ToString()); table.AddRow(UI.Title_Sector_size, image1Info.SectorSize.ToString(), image2Info.SectorSize.ToString());
table.AddRow("Creation time", image1Info.CreationTime.ToString(CultureInfo.CurrentCulture), table.AddRow(UI.Title_Creation_time, image1Info.CreationTime.ToString(CultureInfo.CurrentCulture),
image2Info.CreationTime.ToString(CultureInfo.CurrentCulture)); image2Info.CreationTime.ToString(CultureInfo.CurrentCulture));
table.AddRow("Last modification time", image1Info.LastModificationTime.ToString(CultureInfo.CurrentCulture), table.AddRow(UI.Title_Last_modification_time,
image1Info.LastModificationTime.ToString(CultureInfo.CurrentCulture),
image2Info.LastModificationTime.ToString(CultureInfo.CurrentCulture)); image2Info.LastModificationTime.ToString(CultureInfo.CurrentCulture));
table.AddRow("Disk type", image1Info.MediaType.ToString(), image2Info.MediaType.ToString()); table.AddRow(UI.Title_Media_type, image1Info.MediaType.ToString(), image2Info.MediaType.ToString());
table.AddRow("Image version", image1Info.Version ?? "", image2Info.Version ?? ""); table.AddRow(UI.Title_Image_version, image1Info.Version ?? "", image2Info.Version ?? "");
table.AddRow("Image application", image1Info.Application ?? "", image2Info.Application ?? ""); table.AddRow(UI.Title_Image_application, image1Info.Application ?? "", image2Info.Application ?? "");
table.AddRow("Image application version", image1Info.ApplicationVersion ?? "", table.AddRow(UI.Title_Image_application_version, image1Info.ApplicationVersion ?? "",
image2Info.ApplicationVersion ?? ""); image2Info.ApplicationVersion ?? "");
table.AddRow("Image creator", image1Info.Creator ?? "", image2Info.Creator ?? ""); table.AddRow(UI.Title_Image_creator, image1Info.Creator ?? "", image2Info.Creator ?? "");
table.AddRow("Image name", image1Info.MediaTitle ?? "", image2Info.MediaTitle ?? ""); table.AddRow(UI.Title_Image_name, image1Info.MediaTitle ?? "", image2Info.MediaTitle ?? "");
table.AddRow("Image comments", image1Info.Comments ?? "", image2Info.Comments ?? ""); table.AddRow(UI.Title_Image_comments, image1Info.Comments ?? "", image2Info.Comments ?? "");
table.AddRow("Disk manufacturer", image1Info.MediaManufacturer ?? "", image2Info.MediaManufacturer ?? ""); table.AddRow(UI.Title_Media_manufacturer, image1Info.MediaManufacturer ?? "",
image2Info.MediaManufacturer ?? "");
table.AddRow("Disk model", image1Info.MediaModel ?? "", image2Info.MediaModel ?? ""); table.AddRow(UI.Title_Media_model, image1Info.MediaModel ?? "", image2Info.MediaModel ?? "");
table.AddRow("Disk serial number", image1Info.MediaSerialNumber ?? "", image2Info.MediaSerialNumber ?? ""); table.AddRow(UI.Title_Media_serial_number, image1Info.MediaSerialNumber ?? "",
image2Info.MediaSerialNumber ?? "");
table.AddRow("Disk barcode", image1Info.MediaBarcode ?? "", image2Info.MediaBarcode ?? ""); table.AddRow(UI.Title_Media_barcode, image1Info.MediaBarcode ?? "", image2Info.MediaBarcode ?? "");
table.AddRow("Disk part no.", image1Info.MediaPartNumber ?? "", image2Info.MediaPartNumber ?? ""); table.AddRow(UI.Title_Media_part_number, image1Info.MediaPartNumber ?? "",
image2Info.MediaPartNumber ?? "");
table.AddRow("Disk sequence", image1Info.MediaSequence.ToString(), image2Info.MediaSequence.ToString()); table.AddRow(UI.Title_Media_sequence, image1Info.MediaSequence.ToString(),
image2Info.MediaSequence.ToString());
table.AddRow("Last disk on sequence", image1Info.LastMediaSequence.ToString(), table.AddRow(UI.Title_Last_media_on_sequence, image1Info.LastMediaSequence.ToString(),
image2Info.LastMediaSequence.ToString()); image2Info.LastMediaSequence.ToString());
table.AddRow("Drive manufacturer", image1Info.DriveManufacturer ?? "", image2Info.DriveManufacturer ?? ""); table.AddRow(UI.Title_Drive_manufacturer, image1Info.DriveManufacturer ?? "",
image2Info.DriveManufacturer ?? "");
table.AddRow("Drive firmware revision", image1Info.DriveFirmwareRevision ?? "", table.AddRow(UI.Title_Drive_firmware_revision, image1Info.DriveFirmwareRevision ?? "",
image2Info.DriveFirmwareRevision ?? ""); image2Info.DriveFirmwareRevision ?? "");
table.AddRow("Drive model", image1Info.DriveModel ?? "", image2Info.DriveModel ?? ""); table.AddRow(UI.Title_Drive_model, image1Info.DriveModel ?? "", image2Info.DriveModel ?? "");
table.AddRow("Drive serial number", image1Info.DriveSerialNumber ?? "", image2Info.DriveSerialNumber ?? ""); table.AddRow(UI.Title_Drive_serial_number, image1Info.DriveSerialNumber ?? "",
image2Info.DriveSerialNumber ?? "");
foreach(MediaTagType diskTag in foreach(MediaTagType diskTag in
(Enum.GetValues(typeof(MediaTagType)) as MediaTagType[]).OrderBy(e => e.ToString())) (Enum.GetValues(typeof(MediaTagType)) as MediaTagType[]).OrderBy(e => e.ToString()))
table.AddRow($"Has {diskTag}?", image1DiskTags.ContainsKey(diskTag).ToString(), table.AddRow(string.Format(UI.Has_tag_0_Question, diskTag),
image1DiskTags.ContainsKey(diskTag).ToString(),
image2DiskTags.ContainsKey(diskTag).ToString()); image2DiskTags.ContainsKey(diskTag).ToString());
} }
@@ -331,14 +342,14 @@ sealed class CompareCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Comparing disk image characteristics").IsIndeterminate(); ctx.AddTask(UI.Comparing_media_image_characteristics).IsIndeterminate();
if(image1Info.HasPartitions != image2Info.HasPartitions) if(image1Info.HasPartitions != image2Info.HasPartitions)
{ {
imagesDiffer = true; imagesDiffer = true;
if(!verbose) if(!verbose)
sb.AppendLine("Image partitioned status differ"); sb.AppendLine(UI.Image_partitioned_status_differ);
} }
if(image1Info.HasSessions != image2Info.HasSessions) if(image1Info.HasSessions != image2Info.HasSessions)
@@ -346,7 +357,7 @@ sealed class CompareCommand : Command
imagesDiffer = true; imagesDiffer = true;
if(!verbose) if(!verbose)
sb.AppendLine("Image session status differ"); sb.AppendLine(UI.Image_session_status_differ);
} }
if(image1Info.Sectors != image2Info.Sectors) if(image1Info.Sectors != image2Info.Sectors)
@@ -354,7 +365,7 @@ sealed class CompareCommand : Command
imagesDiffer = true; imagesDiffer = true;
if(!verbose) if(!verbose)
sb.AppendLine("Image sectors differ"); sb.AppendLine(UI.Image_sectors_differ);
} }
if(image1Info.SectorSize != image2Info.SectorSize) if(image1Info.SectorSize != image2Info.SectorSize)
@@ -362,7 +373,7 @@ sealed class CompareCommand : Command
imagesDiffer = true; imagesDiffer = true;
if(!verbose) if(!verbose)
sb.AppendLine("Image sector size differ"); sb.AppendLine(UI.Image_sector_size_differ);
} }
if(image1Info.MediaType != image2Info.MediaType) if(image1Info.MediaType != image2Info.MediaType)
@@ -370,7 +381,7 @@ sealed class CompareCommand : Command
imagesDiffer = true; imagesDiffer = true;
if(!verbose) if(!verbose)
sb.AppendLine("Disk type differ"); sb.AppendLine(UI.Media_type_differs);
} }
if(image1Info.Sectors < image2Info.Sectors) if(image1Info.Sectors < image2Info.Sectors)
@@ -379,7 +390,7 @@ sealed class CompareCommand : Command
leastSectors = image1Info.Sectors; leastSectors = image1Info.Sectors;
if(!verbose) if(!verbose)
sb.AppendLine("Image 2 has more sectors"); sb.AppendLine(UI.Second_image_has_more_sectors);
} }
else if(image1Info.Sectors > image2Info.Sectors) else if(image1Info.Sectors > image2Info.Sectors)
{ {
@@ -387,7 +398,7 @@ sealed class CompareCommand : Command
leastSectors = image2Info.Sectors; leastSectors = image2Info.Sectors;
if(!verbose) if(!verbose)
sb.AppendLine("Image 1 has more sectors"); sb.AppendLine(UI.First_image_has_more_sectors);
} }
else else
leastSectors = image1Info.Sectors; leastSectors = image1Info.Sectors;
@@ -418,27 +429,29 @@ sealed class CompareCommand : Command
Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()). Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()).
Start(ctx => Start(ctx =>
{ {
ProgressTask task = ctx.AddTask("Comparing sectors..."); ProgressTask task = ctx.AddTask(UI.Comparing_sectors);
task.MaxValue = leastSectors; task.MaxValue = leastSectors;
for(ulong sector = 0; sector < leastSectors; sector++) for(ulong sector = 0; sector < leastSectors; sector++)
{ {
task.Value = sector; task.Value = sector;
task.Description = $"Comparing sector {sector + 1} of {leastSectors}..."; task.Description = string.Format(UI.Comparing_sector_0_of_1, sector + 1, leastSectors);
try try
{ {
errno = input1MediaImage.ReadSector(sector, out byte[] image1Sector); errno = input1MediaImage.ReadSector(sector, out byte[] image1Sector);
if(errno != ErrorNumber.NoError) if(errno != ErrorNumber.NoError)
AaruConsole.ErrorWriteLine($"Error {errno} reading sector {sector AaruConsole.
} from image 1."); ErrorWriteLine(string.Format(UI.Error_0_reading_sector_1_from_first_image,
errno, sector));
errno = input2MediaImage.ReadSector(sector, out byte[] image2Sector); errno = input2MediaImage.ReadSector(sector, out byte[] image2Sector);
if(errno != ErrorNumber.NoError) if(errno != ErrorNumber.NoError)
AaruConsole.ErrorWriteLine($"Error {errno} reading sector {sector AaruConsole.
} from image 2."); ErrorWriteLine(string.Format(UI.Error_0_reading_sector_1_from_second_image,
errno, sector));
ArrayHelpers.CompareBytes(out bool different, out bool sameSize, image1Sector, ArrayHelpers.CompareBytes(out bool different, out bool sameSize, image1Sector,
image2Sector); image2Sector);
@@ -468,7 +481,7 @@ sealed class CompareCommand : Command
Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()). Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()).
Start(ctx => Start(ctx =>
{ {
ProgressTask task = ctx.AddTask("Comparing images..."); ProgressTask task = ctx.AddTask(UI.Comparing_images);
task.IsIndeterminate = true; task.IsIndeterminate = true;
byte[] data1 = new byte[input1ByteAddressable.Info.Sectors]; byte[] data1 = new byte[input1ByteAddressable.Info.Sectors];
@@ -503,7 +516,7 @@ sealed class CompareCommand : Command
AaruConsole.WriteLine(); AaruConsole.WriteLine();
sb.AppendLine(imagesDiffer ? "Images differ" : "Images do not differ"); sb.AppendLine(imagesDiffer ? UI.Images_differ : UI.Images_do_not_differ);
if(verbose) if(verbose)
AnsiConsole.Write(table); AnsiConsole.Write(table);

View File

@@ -47,6 +47,7 @@ using Aaru.Console;
using Aaru.Core; using Aaru.Core;
using Aaru.Core.Media; using Aaru.Core.Media;
using Aaru.Devices; using Aaru.Devices;
using Aaru.Localization;
using Schemas; using Schemas;
using Spectre.Console; using Spectre.Console;
using ImageInfo = Aaru.CommonTypes.Structs.ImageInfo; using ImageInfo = Aaru.CommonTypes.Structs.ImageInfo;
@@ -57,105 +58,98 @@ namespace Aaru.Commands.Image;
sealed class ConvertImageCommand : Command sealed class ConvertImageCommand : Command
{ {
public ConvertImageCommand() : base("convert", "Converts one image to another format.") public ConvertImageCommand() : base("convert", UI.Image_Convert_Command_Description)
{ {
Add(new Option<string>(new[] Add(new Option<string>(new[]
{ {
"--cicm-xml", "-x" "--cicm-xml", "-x"
}, () => null, "Take metadata from existing CICM XML sidecar.")); }, () => null, UI.Take_metadata_from_existing_CICM_XML_sidecar));
Add(new Option<string>("--comments", () => null, "Image comments.")); Add(new Option<string>("--comments", () => null, UI.Image_comments));
Add(new Option<int>(new[] Add(new Option<int>(new[]
{ {
"--count", "-c" "--count", "-c"
}, () => 64, "How many sectors to convert at once.")); }, () => 64, UI.How_many_sectors_to_convert_at_once));
Add(new Option<string>("--creator", () => null, "Who (person) created the image?.")); Add(new Option<string>("--creator", () => null, UI.Who_person_created_the_image));
Add(new Option<string>("--drive-manufacturer", () => null, Add(new Option<string>("--drive-manufacturer", () => null, UI.Manufacturer_of_drive_read_the_media_by_image));
"Manufacturer of the drive used to read the media represented by the image."));
Add(new Option<string>("--drive-model", () => null, Add(new Option<string>("--drive-model", () => null, UI.Model_of_drive_read_the_media_by_image));
"Model of the drive used to read the media represented by the image."));
Add(new Option<string>("--drive-revision", () => null, Add(new Option<string>("--drive-revision", () => null, UI.Firmware_revision_of_drive_read_the_media_by_image));
"Firmware revision of the drive used to read the media represented by the image."));
Add(new Option<string>("--drive-serial", () => null, Add(new Option<string>("--drive-serial", () => null, UI.Serial_number_of_drive_read_the_media_by_image));
"Serial number of the drive used to read the media represented by the image."));
Add(new Option<bool>(new[] Add(new Option<bool>(new[]
{ {
"--force", "-f" "--force", "-f"
}, "Continue conversion even if sector or media tags will be lost in the process.")); }, UI.Continue_conversion_even_if_data_lost));
Add(new Option<string>(new[] Add(new Option<string>(new[]
{ {
"--format", "-p" "--format", "-p"
}, () => null, }, () => null, UI.Format_of_the_output_image_as_plugin_name_or_plugin_id));
"Format of the output image, as plugin name or plugin id. If not present, will try to detect it from output image extension."));
Add(new Option<string>("--media-barcode", () => null, "Barcode of the media represented by the image.")); Add(new Option<string>("--media-barcode", () => null, UI.Barcode_of_the_media_by_image));
Add(new Option<int>("--media-lastsequence", () => 0, Add(new Option<int>("--media-lastsequence", () => 0, UI.Last_media_of_sequence_by_image));
"Last media of the sequence the media represented by the image corresponds to."));
Add(new Option<string>("--media-manufacturer", () => null, Add(new Option<string>("--media-manufacturer", () => null, UI.Manufacturer_of_media_by_image));
"Manufacturer of the media represented by the image."));
Add(new Option<string>("--media-model", () => null, "Model of the media represented by the image.")); Add(new Option<string>("--media-model", () => null, UI.Model_of_media_by_image));
Add(new Option<string>("--media-partnumber", () => null, "Part number of the media represented by the image.")); Add(new Option<string>("--media-partnumber", () => null, UI.Part_number_of_media_by_image));
Add(new Option<int>("--media-sequence", () => 0, "Number in sequence for the media represented by the image.")); Add(new Option<int>("--media-sequence", () => 0, UI.Number_in_sequence_for_media_by_image));
Add(new Option<string>("--media-serial", () => null, "Serial number of the media represented by the image.")); Add(new Option<string>("--media-serial", () => null, UI.Serial_number_of_media_by_image));
Add(new Option<string>("--media-title", () => null, "Title of the media represented by the image.")); Add(new Option<string>("--media-title", () => null, UI.Title_of_media_represented_by_image));
Add(new Option<string>(new[] Add(new Option<string>(new[]
{ {
"--options", "-O" "--options", "-O"
}, () => null, "Comma separated name=value pairs of options to pass to output image plugin.")); }, () => null, UI.Comma_separated_name_value_pairs_of_image_options));
Add(new Option<string>(new[] Add(new Option<string>(new[]
{ {
"--resume-file", "-r" "--resume-file", "-r"
}, () => null, "Take list of dump hardware from existing resume file.")); }, () => null, UI.Take_dump_hardware_from_existing_resume));
Add(new Option<string>(new[] Add(new Option<string>(new[]
{ {
"--geometry", "-g" "--geometry", "-g"
}, () => null, "Force geometry, only supported in not tape block media. Specify as C/H/S.")); }, () => null, UI.Force_geometry_help));
Add(new Option<bool>(new[] Add(new Option<bool>(new[]
{ {
"--fix-subchannel-position" "--fix-subchannel-position"
}, () => true, "Store subchannel according to the sector they describe.")); }, () => true, UI.Fix_subchannel_position_help));
Add(new Option<bool>(new[] Add(new Option<bool>(new[]
{ {
"--fix-subchannel" "--fix-subchannel"
}, () => false, "Try to fix subchannel. Implies fixing subchannel position.")); }, () => false, UI.Fix_subchannel_help));
Add(new Option<bool>(new[] Add(new Option<bool>(new[]
{ {
"--fix-subchannel-crc" "--fix-subchannel-crc"
}, () => false, "If subchannel looks OK but CRC fails, rewrite it. Implies fixing subchannel.")); }, () => false, UI.Fix_subchannel_crc_help));
Add(new Option<bool>(new[] Add(new Option<bool>(new[]
{ {
"--generate-subchannels" "--generate-subchannels"
}, () => false, "Generates missing subchannels.")); }, () => false, UI.Generates_subchannels_help));
AddArgument(new Argument<string> AddArgument(new Argument<string>
{ {
Arity = ArgumentArity.ExactlyOne, Arity = ArgumentArity.ExactlyOne,
Description = "Input image path", Description = UI.Input_image_path,
Name = "input-path" Name = "input-path"
}); });
AddArgument(new Argument<string> AddArgument(new Argument<string>
{ {
Arity = ArgumentArity.ExactlyOne, Arity = ArgumentArity.ExactlyOne,
Description = "Output image path", Description = UI.Output_image_path,
Name = "output-path" Name = "output-path"
}); });
@@ -237,14 +231,14 @@ sealed class ConvertImageCommand : Command
AaruConsole.DebugWriteLine("Image convert command", "--generate-subchannels={0}", generateSubchannels); AaruConsole.DebugWriteLine("Image convert command", "--generate-subchannels={0}", generateSubchannels);
Dictionary<string, string> parsedOptions = Core.Options.Parse(options); Dictionary<string, string> parsedOptions = Core.Options.Parse(options);
AaruConsole.DebugWriteLine("Image convert command", "Parsed options:"); AaruConsole.DebugWriteLine("Image convert command", UI.Parsed_options);
foreach(KeyValuePair<string, string> parsedOption in parsedOptions) foreach(KeyValuePair<string, string> parsedOption in parsedOptions)
AaruConsole.DebugWriteLine("Image convert command", "{0} = {1}", parsedOption.Key, parsedOption.Value); AaruConsole.DebugWriteLine("Image convert command", "{0} = {1}", parsedOption.Key, parsedOption.Value);
if(count == 0) if(count == 0)
{ {
AaruConsole.ErrorWriteLine("Need to specify more than 0 sectors to copy at once"); AaruConsole.ErrorWriteLine(UI.Need_to_specify_more_than_zero_sectors_to_copy_at_once);
return (int)ErrorNumber.InvalidArgument; return (int)ErrorNumber.InvalidArgument;
} }
@@ -260,7 +254,7 @@ sealed class ConvertImageCommand : Command
if(geometryPieces.Length != 3) if(geometryPieces.Length != 3)
{ {
AaruConsole.ErrorWriteLine("Invalid geometry specified"); AaruConsole.ErrorWriteLine(UI.Invalid_geometry_specified);
return (int)ErrorNumber.InvalidArgument; return (int)ErrorNumber.InvalidArgument;
} }
@@ -268,7 +262,7 @@ sealed class ConvertImageCommand : Command
if(!uint.TryParse(geometryPieces[0], out uint cylinders) || if(!uint.TryParse(geometryPieces[0], out uint cylinders) ||
cylinders == 0) cylinders == 0)
{ {
AaruConsole.ErrorWriteLine("Invalid number of cylinders specified"); AaruConsole.ErrorWriteLine(UI.Invalid_number_of_cylinders_specified);
return (int)ErrorNumber.InvalidArgument; return (int)ErrorNumber.InvalidArgument;
} }
@@ -276,7 +270,7 @@ sealed class ConvertImageCommand : Command
if(!uint.TryParse(geometryPieces[1], out uint heads) || if(!uint.TryParse(geometryPieces[1], out uint heads) ||
heads == 0) heads == 0)
{ {
AaruConsole.ErrorWriteLine("Invalid number of heads specified"); AaruConsole.ErrorWriteLine(UI.Invalid_number_of_heads_specified);
return (int)ErrorNumber.InvalidArgument; return (int)ErrorNumber.InvalidArgument;
} }
@@ -284,7 +278,7 @@ sealed class ConvertImageCommand : Command
if(!uint.TryParse(geometryPieces[2], out uint spt) || if(!uint.TryParse(geometryPieces[2], out uint spt) ||
spt == 0) spt == 0)
{ {
AaruConsole.ErrorWriteLine("Invalid sectors per track specified"); AaruConsole.ErrorWriteLine(UI.Invalid_sectors_per_track_specified);
return (int)ErrorNumber.InvalidArgument; return (int)ErrorNumber.InvalidArgument;
} }
@@ -308,14 +302,14 @@ sealed class ConvertImageCommand : Command
} }
catch(Exception ex) catch(Exception ex)
{ {
AaruConsole.ErrorWriteLine("Incorrect metadata sidecar file, not continuing..."); AaruConsole.ErrorWriteLine(UI.Incorrect_metadata_sidecar_file);
AaruConsole.DebugWriteLine("Image conversion", $"{ex}"); AaruConsole.DebugWriteLine("Image conversion", $"{ex}");
return (int)ErrorNumber.InvalidSidecar; return (int)ErrorNumber.InvalidSidecar;
} }
else else
{ {
AaruConsole.ErrorWriteLine("Could not find metadata sidecar, not continuing..."); AaruConsole.ErrorWriteLine(UI.Could_not_find_metadata_sidecar);
return (int)ErrorNumber.NoSuchFile; return (int)ErrorNumber.NoSuchFile;
} }
@@ -332,14 +326,14 @@ sealed class ConvertImageCommand : Command
} }
catch(Exception ex) catch(Exception ex)
{ {
AaruConsole.ErrorWriteLine("Incorrect resume file, not continuing..."); AaruConsole.ErrorWriteLine(UI.Incorrect_resume_file);
AaruConsole.DebugWriteLine("Image conversion", $"{ex}"); AaruConsole.DebugWriteLine("Image conversion", $"{ex}");
return (int)ErrorNumber.InvalidResume; return (int)ErrorNumber.InvalidResume;
} }
else else
{ {
AaruConsole.ErrorWriteLine("Could not find resume file, not continuing..."); AaruConsole.ErrorWriteLine(UI.Could_not_find_resume_file);
return (int)ErrorNumber.NoSuchFile; return (int)ErrorNumber.NoSuchFile;
} }
@@ -349,20 +343,20 @@ sealed class ConvertImageCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Identifying file filter...").IsIndeterminate(); ctx.AddTask(UI.Identifying_file_filter).IsIndeterminate();
inputFilter = filtersList.GetFilter(inputPath); inputFilter = filtersList.GetFilter(inputPath);
}); });
if(inputFilter == null) if(inputFilter == null)
{ {
AaruConsole.ErrorWriteLine("Cannot open specified file."); AaruConsole.ErrorWriteLine(UI.Cannot_open_specified_file);
return (int)ErrorNumber.CannotOpenFile; return (int)ErrorNumber.CannotOpenFile;
} }
if(File.Exists(outputPath)) if(File.Exists(outputPath))
{ {
AaruConsole.ErrorWriteLine("Output file already exists, not continuing."); AaruConsole.ErrorWriteLine(UI.Output_file_already_exists);
return (int)ErrorNumber.FileExists; return (int)ErrorNumber.FileExists;
} }
@@ -373,14 +367,14 @@ sealed class ConvertImageCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Identifying image format...").IsIndeterminate(); ctx.AddTask(UI.Identifying_image_format).IsIndeterminate();
baseImage = ImageFormat.Detect(inputFilter); baseImage = ImageFormat.Detect(inputFilter);
inputFormat = baseImage as IMediaImage; inputFormat = baseImage as IMediaImage;
}); });
if(inputFormat == null) if(inputFormat == null)
{ {
AaruConsole.WriteLine("Input image format not identified, not proceeding with conversion."); AaruConsole.WriteLine(UI.Input_image_format_not_identified);
return (int)ErrorNumber.UnrecognizedFormat; return (int)ErrorNumber.UnrecognizedFormat;
} }
@@ -388,16 +382,15 @@ sealed class ConvertImageCommand : Command
// TODO: Implement // TODO: Implement
if(inputFormat == null) if(inputFormat == null)
{ {
AaruConsole.WriteLine("Command not yet supported for this image type."); AaruConsole.WriteLine(UI.Command_not_yet_supported_for_this_image_type);
return (int)ErrorNumber.InvalidArgument; return (int)ErrorNumber.InvalidArgument;
} }
if(verbose) if(verbose)
AaruConsole.VerboseWriteLine("Input image format identified by {0} ({1}).", inputFormat.Name, AaruConsole.VerboseWriteLine(UI.Input_image_format_identified_by_0_1, inputFormat.Name, inputFormat.Id);
inputFormat.Id);
else else
AaruConsole.WriteLine("Input image format identified by {0}.", inputFormat.Name); AaruConsole.WriteLine(UI.Input_image_format_identified_by_0, inputFormat.Name);
try try
{ {
@@ -405,14 +398,14 @@ sealed class ConvertImageCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Opening image file...").IsIndeterminate(); ctx.AddTask(UI.Invoke_Opening_image_file).IsIndeterminate();
opened = inputFormat.Open(inputFilter); opened = inputFormat.Open(inputFilter);
}); });
if(opened != ErrorNumber.NoError) if(opened != ErrorNumber.NoError)
{ {
AaruConsole.WriteLine("Unable to open image format"); AaruConsole.WriteLine(UI.Unable_to_open_image_format);
AaruConsole.WriteLine("Error {0}", opened); AaruConsole.WriteLine(UI.Error_0, opened);
return (int)opened; return (int)opened;
} }
@@ -430,14 +423,14 @@ sealed class ConvertImageCommand : Command
}; };
#pragma warning restore 612 #pragma warning restore 612
AaruConsole.DebugWriteLine("Convert-image command", "Correctly opened image file."); AaruConsole.DebugWriteLine("Convert-image command", UI.Correctly_opened_image_file);
AaruConsole.DebugWriteLine("Convert-image command", "Image without headers is {0} bytes.", AaruConsole.DebugWriteLine("Convert-image command", UI.Image_without_headers_is_0_bytes,
inputFormat.Info.ImageSize); inputFormat.Info.ImageSize);
AaruConsole.DebugWriteLine("Convert-image command", "Image has {0} sectors.", inputFormat.Info.Sectors); AaruConsole.DebugWriteLine("Convert-image command", UI.Image_has_0_sectors, inputFormat.Info.Sectors);
AaruConsole.DebugWriteLine("Convert-image command", "Image identifies media type as {0}.", mediaType); AaruConsole.DebugWriteLine("Convert-image command", UI.Image_identifies_media_type_as_0, mediaType);
Statistics.AddMediaFormat(inputFormat.Format); Statistics.AddMediaFormat(inputFormat.Format);
Statistics.AddMedia(mediaType, false); Statistics.AddMedia(mediaType, false);
@@ -445,9 +438,9 @@ sealed class ConvertImageCommand : Command
} }
catch(Exception ex) catch(Exception ex)
{ {
AaruConsole.ErrorWriteLine("Unable to open image format"); AaruConsole.ErrorWriteLine(UI.Unable_to_open_image_format);
AaruConsole.ErrorWriteLine("Error: {0}", ex.Message); AaruConsole.ErrorWriteLine(UI.Error_0, ex.Message);
AaruConsole.DebugWriteLine("Convert-image command", "Stack trace: {0}", ex.StackTrace); AaruConsole.DebugWriteLine("Convert-image command", Localization.Core.Stack_trace_0, ex.StackTrace);
return (int)ErrorNumber.CannotOpenFormat; return (int)ErrorNumber.CannotOpenFormat;
} }
@@ -473,11 +466,11 @@ sealed class ConvertImageCommand : Command
switch(candidates.Count) switch(candidates.Count)
{ {
case 0: case 0:
AaruConsole.WriteLine("No plugin supports requested extension."); AaruConsole.WriteLine(UI.No_plugin_supports_requested_extension);
return (int)ErrorNumber.FormatNotFound; return (int)ErrorNumber.FormatNotFound;
case > 1: case > 1:
AaruConsole.WriteLine("More than one plugin supports requested extension."); AaruConsole.WriteLine(UI.More_than_one_plugin_supports_requested_extension);
return (int)ErrorNumber.TooManyFormats; return (int)ErrorNumber.TooManyFormats;
} }
@@ -485,13 +478,13 @@ sealed class ConvertImageCommand : Command
IBaseWritableImage outputFormat = candidates[0]; IBaseWritableImage outputFormat = candidates[0];
if(verbose) if(verbose)
AaruConsole.VerboseWriteLine("Output image format: {0} ({1}).", outputFormat.Name, outputFormat.Id); AaruConsole.VerboseWriteLine(UI.Output_image_format_0_1, outputFormat.Name, outputFormat.Id);
else else
AaruConsole.WriteLine("Output image format: {0}.", outputFormat.Name); AaruConsole.WriteLine(UI.Output_image_format_0, outputFormat.Name);
if(!outputFormat.SupportedMediaTypes.Contains(mediaType)) if(!outputFormat.SupportedMediaTypes.Contains(mediaType))
{ {
AaruConsole.ErrorWriteLine("Output format does not support media type, cannot continue..."); AaruConsole.ErrorWriteLine(UI.Output_format_does_not_support_media_type);
return (int)ErrorNumber.UnsupportedMedia; return (int)ErrorNumber.UnsupportedMedia;
} }
@@ -499,8 +492,8 @@ sealed class ConvertImageCommand : Command
foreach(MediaTagType mediaTag in inputFormat.Info.ReadableMediaTags.Where(mediaTag => foreach(MediaTagType mediaTag in inputFormat.Info.ReadableMediaTags.Where(mediaTag =>
!outputFormat.SupportedMediaTags.Contains(mediaTag) && !force)) !outputFormat.SupportedMediaTags.Contains(mediaTag) && !force))
{ {
AaruConsole.ErrorWriteLine("Converting image will lose media tag {0}, not continuing...", mediaTag); AaruConsole.ErrorWriteLine(UI.Converting_image_will_lose_media_tag_0, mediaTag);
AaruConsole.ErrorWriteLine("If you don't care, use force option."); AaruConsole.ErrorWriteLine(UI.If_you_dont_care_use_force_option);
return (int)ErrorNumber.DataWillBeLost; return (int)ErrorNumber.DataWillBeLost;
} }
@@ -520,10 +513,10 @@ sealed class ConvertImageCommand : Command
continue; continue;
} }
AaruConsole.ErrorWriteLine("Converting image will lose sector tag {0}, not continuing...", sectorTag); AaruConsole.ErrorWriteLine(UI.Converting_image_will_lose_sector_tag_0, sectorTag);
AaruConsole. AaruConsole.ErrorWriteLine(UI.
ErrorWriteLine("If you don't care, use force option. This will skip all sector tags converting only user data."); If_you_dont_care_use_force_option_This_will_skip_all_sector_tags_converting_only_user_data);
return (int)ErrorNumber.DataWillBeLost; return (int)ErrorNumber.DataWillBeLost;
} }
@@ -534,8 +527,7 @@ sealed class ConvertImageCommand : Command
if(inputTape?.IsTape == true && if(inputTape?.IsTape == true &&
outputTape is null) outputTape is null)
{ {
AaruConsole. AaruConsole.ErrorWriteLine(UI.Input_format_contains_a_tape_image_and_is_not_supported_by_output_format);
ErrorWriteLine("Input format contains a tape image and is not supported by output format, not continuing...");
return (int)ErrorNumber.UnsupportedMedia; return (int)ErrorNumber.UnsupportedMedia;
} }
@@ -550,7 +542,7 @@ sealed class ConvertImageCommand : Command
// Cannot set image to tape mode // Cannot set image to tape mode
if(!ret) if(!ret)
{ {
AaruConsole.ErrorWriteLine("Error setting output image in tape mode, not continuing..."); AaruConsole.ErrorWriteLine(UI.Error_setting_output_image_in_tape_mode);
AaruConsole.ErrorWriteLine(outputFormat.ErrorMessage); AaruConsole.ErrorWriteLine(outputFormat.ErrorMessage);
return (int)ErrorNumber.WriteError; return (int)ErrorNumber.WriteError;
@@ -564,8 +556,7 @@ sealed class ConvertImageCommand : Command
// TODO: Disabled until 6.0 // TODO: Disabled until 6.0
/*if(!_force) /*if(!_force)
{*/ {*/
AaruConsole. AaruConsole.ErrorWriteLine(UI.Output_format_does_not_support_sessions);
ErrorWriteLine("Output format does not support sessions, this will end in a loss of data, not continuing...");
return (int)ErrorNumber.UnsupportedMedia; return (int)ErrorNumber.UnsupportedMedia;
/*} /*}
@@ -577,7 +568,7 @@ sealed class ConvertImageCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Opening image file...").IsIndeterminate(); ctx.AddTask(UI.Invoke_Opening_image_file).IsIndeterminate();
created = outputFormat.Create(outputPath, mediaType, parsedOptions, inputFormat.Info.Sectors, created = outputFormat.Create(outputPath, mediaType, parsedOptions, inputFormat.Info.Sectors,
inputFormat.Info.SectorSize); inputFormat.Info.SectorSize);
@@ -585,7 +576,7 @@ sealed class ConvertImageCommand : Command
if(!created) if(!created)
{ {
AaruConsole.ErrorWriteLine("Error {0} creating output image.", outputFormat.ErrorMessage); AaruConsole.ErrorWriteLine(UI.Error_0_creating_output_image, outputFormat.ErrorMessage);
return (int)ErrorNumber.CannotCreateFormat; return (int)ErrorNumber.CannotCreateFormat;
} }
@@ -612,16 +603,14 @@ sealed class ConvertImageCommand : Command
if(!outputFormat.SetMetadata(metadata)) if(!outputFormat.SetMetadata(metadata))
{ {
AaruConsole.ErrorWrite("Error {0} setting metadata, ", outputFormat.ErrorMessage);
if(!force) if(!force)
{ {
AaruConsole.ErrorWriteLine("not continuing..."); AaruConsole.ErrorWriteLine(UI.Error_0_setting_metadata_not_continuing, outputFormat.ErrorMessage);
return (int)ErrorNumber.WriteError; return (int)ErrorNumber.WriteError;
} }
AaruConsole.ErrorWriteLine("continuing..."); AaruConsole.ErrorWriteLine(UI.Error_0_setting_metadata, outputFormat.ErrorMessage);
} }
CICMMetadataType cicmMetadata = inputFormat.CicmMetadata; CICMMetadataType cicmMetadata = inputFormat.CicmMetadata;
@@ -635,16 +624,16 @@ sealed class ConvertImageCommand : Command
AnsiConsole.Progress().AutoClear(false).HideCompleted(false). AnsiConsole.Progress().AutoClear(false).HideCompleted(false).
Columns(new TaskDescriptionColumn(), new SpinnerColumn()).Start(ctx => Columns(new TaskDescriptionColumn(), new SpinnerColumn()).Start(ctx =>
{ {
ctx.AddTask($"Converting media tag {Markup.Escape(mediaTag.ToString())}"); ctx.AddTask(string.Format(UI.Converting_media_tag_0, Markup.Escape(mediaTag.ToString())));
ErrorNumber errno = inputFormat.ReadMediaTag(mediaTag, out byte[] tag); ErrorNumber errno = inputFormat.ReadMediaTag(mediaTag, out byte[] tag);
if(errno != ErrorNumber.NoError) if(errno != ErrorNumber.NoError)
{ {
if(force) if(force)
AaruConsole.ErrorWriteLine("Error {0} reading media tag, continuing...", errno); AaruConsole.ErrorWriteLine(UI.Error_0_reading_media_tag, errno);
else else
{ {
AaruConsole.ErrorWriteLine("Error {0} writing media tag, not continuing...", errno); AaruConsole.ErrorWriteLine(UI.Error_0_reading_media_tag_not_continuing, errno);
errorNumber = errno; errorNumber = errno;
} }
@@ -656,11 +645,10 @@ sealed class ConvertImageCommand : Command
return; return;
if(force) if(force)
AaruConsole.ErrorWriteLine("Error {0} writing media tag, continuing...", AaruConsole.ErrorWriteLine(UI.Error_0_writing_media_tag, outputFormat.ErrorMessage);
outputFormat.ErrorMessage);
else else
{ {
AaruConsole.ErrorWriteLine("Error {0} writing media tag, not continuing...", AaruConsole.ErrorWriteLine(UI.Error_0_writing_media_tag_not_continuing,
outputFormat.ErrorMessage); outputFormat.ErrorMessage);
errorNumber = ErrorNumber.WriteError; errorNumber = ErrorNumber.WriteError;
@@ -671,7 +659,7 @@ sealed class ConvertImageCommand : Command
return (int)errorNumber; return (int)errorNumber;
} }
AaruConsole.WriteLine("{0} sectors to convert", inputFormat.Info.Sectors); AaruConsole.WriteLine(UI._0_sectors_to_convert, inputFormat.Info.Sectors);
ulong doneSectors = 0; ulong doneSectors = 0;
if(inputFormat is IOpticalMediaImage inputOptical && if(inputFormat is IOpticalMediaImage inputOptical &&
@@ -680,8 +668,7 @@ sealed class ConvertImageCommand : Command
{ {
if(!outputOptical.SetTracks(inputOptical.Tracks)) if(!outputOptical.SetTracks(inputOptical.Tracks))
{ {
AaruConsole.ErrorWriteLine("Error {0} sending tracks list to output image.", AaruConsole.ErrorWriteLine(UI.Error_0_sending_tracks_list_to_output_image, outputOptical.ErrorMessage);
outputOptical.ErrorMessage);
return (int)ErrorNumber.WriteError; return (int)ErrorNumber.WriteError;
} }
@@ -692,18 +679,18 @@ sealed class ConvertImageCommand : Command
Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()). Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()).
Start(ctx => Start(ctx =>
{ {
ProgressTask discTask = ctx.AddTask("Converting disc..."); ProgressTask discTask = ctx.AddTask(UI.Converting_disc);
discTask.MaxValue = inputOptical.Tracks.Count; discTask.MaxValue = inputOptical.Tracks.Count;
foreach(Track track in inputOptical.Tracks) foreach(Track track in inputOptical.Tracks)
{ {
discTask.Description = $"Converting sectors in track {discTask.Value + 1} of { discTask.Description = string.Format(UI.Converting_sectors_in_track_0_of_1,
discTask.MaxValue}"; discTask.Value + 1, discTask.MaxValue);
doneSectors = 0; doneSectors = 0;
ulong trackSectors = track.EndSector - track.StartSector + 1; ulong trackSectors = track.EndSector - track.StartSector + 1;
ProgressTask trackTask = ctx.AddTask("Converting track"); ProgressTask trackTask = ctx.AddTask(UI.Converting_track);
trackTask.MaxValue = trackSectors; trackTask.MaxValue = trackSectors;
while(doneSectors < trackSectors) while(doneSectors < trackSectors)
@@ -717,8 +704,10 @@ sealed class ConvertImageCommand : Command
else else
sectorsToDo = (uint)(trackSectors - doneSectors); sectorsToDo = (uint)(trackSectors - doneSectors);
trackTask.Description = $"Converting sectors {doneSectors + track.StartSector} to { trackTask.Description =
doneSectors + sectorsToDo + track.StartSector} in track {track.Sequence}"; string.Format(UI.Converting_sectors_0_to_1_in_track_2,
doneSectors + track.StartSector,
doneSectors + sectorsToDo + track.StartSector, track.Sequence);
bool useNotLong = false; bool useNotLong = false;
bool result = false; bool result = false;
@@ -742,14 +731,12 @@ sealed class ConvertImageCommand : Command
result = true; result = true;
if(force) if(force)
AaruConsole. AaruConsole.ErrorWriteLine(UI.Error_0_reading_sector_1_continuing,
ErrorWriteLine("Error {0} reading sector {1}, continuing...", errno, errno, doneSectors + track.StartSector);
doneSectors + track.StartSector);
else else
{ {
AaruConsole. AaruConsole.ErrorWriteLine(UI.Error_0_reading_sector_1_not_continuing,
ErrorWriteLine("Error {0} reading sector {1}, not continuing...", errno, doneSectors + track.StartSector);
errno, doneSectors + track.StartSector);
errno = ErrorNumber.WriteError; errno = ErrorNumber.WriteError;
@@ -763,7 +750,8 @@ sealed class ConvertImageCommand : Command
if(!force) if(!force)
{ {
AaruConsole. AaruConsole.
ErrorWriteLine("Input image is not returning raw sectors, use force if you want to continue..."); ErrorWriteLine(UI.
Input_image_is_not_returning_raw_sectors_use_force_if_you_want_to_continue);
errno = ErrorNumber.InOutError; errno = ErrorNumber.InOutError;
@@ -793,14 +781,12 @@ sealed class ConvertImageCommand : Command
result = true; result = true;
if(force) if(force)
AaruConsole. AaruConsole.ErrorWriteLine(UI.Error_0_reading_sector_1_continuing,
ErrorWriteLine("Error {0} reading sector {1}, continuing...", errno, errno, doneSectors + track.StartSector);
doneSectors + track.StartSector);
else else
{ {
AaruConsole. AaruConsole.ErrorWriteLine(UI.Error_0_reading_sector_1_not_continuing,
ErrorWriteLine("Error {0} reading sector {1}, not continuing...", errno, doneSectors + track.StartSector);
errno, doneSectors + track.StartSector);
errno = ErrorNumber.WriteError; errno = ErrorNumber.WriteError;
@@ -811,15 +797,14 @@ sealed class ConvertImageCommand : Command
if(!result) if(!result)
if(force) if(force)
AaruConsole.ErrorWriteLine("Error {0} writing sector {1}, continuing...", AaruConsole.ErrorWriteLine(UI.Error_0_writing_sector_1_continuing,
outputOptical.ErrorMessage, outputOptical.ErrorMessage,
doneSectors + track.StartSector); doneSectors + track.StartSector);
else else
{ {
AaruConsole. AaruConsole.ErrorWriteLine(UI.Error_0_writing_sector_1_not_continuing,
ErrorWriteLine("Error {0} writing sector {1}, not continuing...", outputOptical.ErrorMessage,
outputOptical.ErrorMessage, doneSectors + track.StartSector);
doneSectors + track.StartSector);
errno = ErrorNumber.WriteError; errno = ErrorNumber.WriteError;
@@ -927,13 +912,14 @@ sealed class ConvertImageCommand : Command
Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()). Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()).
Start(ctx => Start(ctx =>
{ {
ProgressTask discTask = ctx.AddTask("Converting disc..."); ProgressTask discTask = ctx.AddTask(UI.Converting_disc);
discTask.MaxValue = inputOptical.Tracks.Count; discTask.MaxValue = inputOptical.Tracks.Count;
foreach(Track track in inputOptical.Tracks) foreach(Track track in inputOptical.Tracks)
{ {
discTask.Description = $"Converting tags in track {discTask.Value + 1} of { discTask.Description =
discTask.MaxValue}"; string.Format(UI.Converting_tags_in_track_0_of_1, discTask.Value + 1,
discTask.MaxValue);
doneSectors = 0; doneSectors = 0;
ulong trackSectors = track.EndSector - track.StartSector + 1; ulong trackSectors = track.EndSector - track.StartSector + 1;
@@ -960,16 +946,14 @@ sealed class ConvertImageCommand : Command
{ {
if(force) if(force)
{ {
AaruConsole. AaruConsole.ErrorWriteLine(UI.Error_0_writing_tag_continuing,
ErrorWriteLine("Error {0} writing tag, continuing...", outputOptical.ErrorMessage);
outputOptical.ErrorMessage);
continue; continue;
} }
AaruConsole. AaruConsole.ErrorWriteLine(UI.Error_0_writing_tag_not_continuing,
ErrorWriteLine("Error {0} writing tag, not continuing...", outputOptical.ErrorMessage);
outputOptical.ErrorMessage);
errno = ErrorNumber.WriteError; errno = ErrorNumber.WriteError;
@@ -979,13 +963,12 @@ sealed class ConvertImageCommand : Command
if(!result) if(!result)
if(force) if(force)
AaruConsole.ErrorWriteLine("Error {0} writing tag, continuing...", AaruConsole.ErrorWriteLine(UI.Error_0_writing_tag_continuing,
outputOptical.ErrorMessage); outputOptical.ErrorMessage);
else else
{ {
AaruConsole. AaruConsole.ErrorWriteLine(UI.Error_0_writing_tag_not_continuing,
ErrorWriteLine("Error {0} writing tag, not continuing...", outputOptical.ErrorMessage);
outputOptical.ErrorMessage);
errno = ErrorNumber.WriteError; errno = ErrorNumber.WriteError;
@@ -995,7 +978,7 @@ sealed class ConvertImageCommand : Command
continue; continue;
} }
ProgressTask trackTask = ctx.AddTask("Converting track"); ProgressTask trackTask = ctx.AddTask(UI.Converting_track);
trackTask.MaxValue = trackSectors; trackTask.MaxValue = trackSectors;
while(doneSectors < trackSectors) while(doneSectors < trackSectors)
@@ -1008,7 +991,7 @@ sealed class ConvertImageCommand : Command
sectorsToDo = (uint)(trackSectors - doneSectors); sectorsToDo = (uint)(trackSectors - doneSectors);
trackTask.Description = trackTask.Description =
string.Format("Converting tag {3} for sectors {0} to {1} in track {2}", string.Format(UI.Converting_tag_3_for_sectors_0_to_1_in_track_2,
doneSectors + track.StartSector, doneSectors + track.StartSector,
doneSectors + sectorsToDo + track.StartSector, track.Sequence, doneSectors + sectorsToDo + track.StartSector, track.Sequence,
tag); tag);
@@ -1047,12 +1030,12 @@ sealed class ConvertImageCommand : Command
if(force) if(force)
AaruConsole. AaruConsole.
ErrorWriteLine("Error {0} reading tag for sector {1}, continuing...", ErrorWriteLine(UI.Error_0_reading_tag_for_sector_1_continuing,
errno, doneSectors + track.StartSector); errno, doneSectors + track.StartSector);
else else
{ {
AaruConsole. AaruConsole.
ErrorWriteLine("Error {0} reading tag for sector {1}, not continuing...", ErrorWriteLine(UI.Error_0_reading_tag_for_sector_1_not_continuing,
errno, doneSectors + track.StartSector); errno, doneSectors + track.StartSector);
return; return;
@@ -1093,12 +1076,12 @@ sealed class ConvertImageCommand : Command
if(force) if(force)
AaruConsole. AaruConsole.
ErrorWriteLine("Error {0} reading tag for sector {1}, continuing...", ErrorWriteLine(UI.Error_0_reading_tag_for_sector_1_continuing,
errno, doneSectors + track.StartSector); errno, doneSectors + track.StartSector);
else else
{ {
AaruConsole. AaruConsole.
ErrorWriteLine("Error {0} reading tag for sector {1}, not continuing...", ErrorWriteLine(UI.Error_0_reading_tag_for_sector_1_not_continuing,
errno, doneSectors + track.StartSector); errno, doneSectors + track.StartSector);
return; return;
@@ -1109,13 +1092,13 @@ sealed class ConvertImageCommand : Command
if(!result) if(!result)
if(force) if(force)
AaruConsole. AaruConsole.
ErrorWriteLine("Error {0} writing tag for sector {1}, continuing...", ErrorWriteLine(UI.Error_0_writing_tag_for_sector_1_continuing,
outputOptical.ErrorMessage, outputOptical.ErrorMessage,
doneSectors + track.StartSector); doneSectors + track.StartSector);
else else
{ {
AaruConsole. AaruConsole.
ErrorWriteLine("Error {0} writing tag for sector {1}, not continuing...", ErrorWriteLine(UI.Error_0_writing_tag_for_sector_1_not_continuing,
outputOptical.ErrorMessage, outputOptical.ErrorMessage,
doneSectors + track.StartSector); doneSectors + track.StartSector);
@@ -1165,7 +1148,7 @@ sealed class ConvertImageCommand : Command
or MediaType.VideoNowXp or MediaType.CVD && generateSubchannels) or MediaType.VideoNowXp or MediaType.CVD && generateSubchannels)
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Generating subchannels...").IsIndeterminate(); ctx.AddTask(Localization.Core.Generating_subchannels).IsIndeterminate();
CompactDisc.GenerateSubchannels(subchannelExtents, tracks, trackFlags, inputOptical.Info.Sectors, CompactDisc.GenerateSubchannels(subchannelExtents, tracks, trackFlags, inputOptical.Info.Sectors,
null, null, null, null, null, outputOptical); null, null, null, null, null, outputOptical);
@@ -1184,11 +1167,11 @@ sealed class ConvertImageCommand : Command
? (geometryValues.Value.cylinders, geometryValues.Value.heads, geometryValues.Value.sectors) ? (geometryValues.Value.cylinders, geometryValues.Value.heads, geometryValues.Value.sectors)
: (inputFormat.Info.Cylinders, inputFormat.Info.Heads, inputFormat.Info.SectorsPerTrack); : (inputFormat.Info.Cylinders, inputFormat.Info.Heads, inputFormat.Info.SectorsPerTrack);
AaruConsole.WriteLine("Setting geometry to {0} cylinders, {1} heads and {2} sectors per track", AaruConsole.WriteLine(UI.Setting_geometry_to_0_cylinders_1_heads_and_2_sectors_per_track, chs.cylinders,
chs.cylinders, chs.heads, chs.sectors); chs.heads, chs.sectors);
if(!outputMedia.SetGeometry(chs.cylinders, chs.heads, chs.sectors)) if(!outputMedia.SetGeometry(chs.cylinders, chs.heads, chs.sectors))
AaruConsole.ErrorWriteLine("Error {0} setting geometry, image may be incorrect, continuing...", AaruConsole.ErrorWriteLine(UI.Error_0_setting_geometry_image_may_be_incorrect_continuing,
outputMedia.ErrorMessage); outputMedia.ErrorMessage);
} }
@@ -1198,7 +1181,7 @@ sealed class ConvertImageCommand : Command
Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()). Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()).
Start(ctx => Start(ctx =>
{ {
ProgressTask mediaTask = ctx.AddTask("Converting media"); ProgressTask mediaTask = ctx.AddTask(UI.Converting_media);
mediaTask.MaxValue = inputFormat.Info.Sectors; mediaTask.MaxValue = inputFormat.Info.Sectors;
while(doneSectors < inputFormat.Info.Sectors) while(doneSectors < inputFormat.Info.Sectors)
@@ -1215,7 +1198,7 @@ sealed class ConvertImageCommand : Command
sectorsToDo = (uint)(inputFormat.Info.Sectors - doneSectors); sectorsToDo = (uint)(inputFormat.Info.Sectors - doneSectors);
mediaTask.Description = mediaTask.Description =
$"Converting sectors {doneSectors} to {doneSectors + sectorsToDo}"; string.Format(UI.Converting_sectors_0_to_1, doneSectors, doneSectors + sectorsToDo);
bool result; bool result;
@@ -1232,13 +1215,12 @@ sealed class ConvertImageCommand : Command
result = true; result = true;
if(force) if(force)
AaruConsole.ErrorWriteLine("Error {0} reading sector {1}, continuing...", AaruConsole.ErrorWriteLine(UI.Error_0_reading_sector_1_continuing, errno,
errno, doneSectors); doneSectors);
else else
{ {
AaruConsole. AaruConsole.ErrorWriteLine(UI.Error_0_reading_sector_1_not_continuing,
ErrorWriteLine("Error {0} reading sector {1}, not continuing...", errno, errno, doneSectors);
doneSectors);
return; return;
} }
@@ -1257,13 +1239,12 @@ sealed class ConvertImageCommand : Command
result = true; result = true;
if(force) if(force)
AaruConsole.ErrorWriteLine("Error {0} reading sector {1}, continuing...", AaruConsole.ErrorWriteLine(UI.Error_0_reading_sector_1_continuing, errno,
errno, doneSectors); doneSectors);
else else
{ {
AaruConsole. AaruConsole.ErrorWriteLine(UI.Error_0_reading_sector_1_not_continuing,
ErrorWriteLine("Error {0} reading sector {1}, not continuing...", errno, errno, doneSectors);
doneSectors);
return; return;
} }
@@ -1272,11 +1253,11 @@ sealed class ConvertImageCommand : Command
if(!result) if(!result)
if(force) if(force)
AaruConsole.ErrorWriteLine("Error {0} writing sector {1}, continuing...", AaruConsole.ErrorWriteLine(UI.Error_0_writing_sector_1_continuing,
outputMedia.ErrorMessage, doneSectors); outputMedia.ErrorMessage, doneSectors);
else else
{ {
AaruConsole.ErrorWriteLine("Error {0} writing sector {1}, not continuing...", AaruConsole.ErrorWriteLine(UI.Error_0_writing_sector_1_not_continuing,
outputMedia.ErrorMessage, doneSectors); outputMedia.ErrorMessage, doneSectors);
errno = ErrorNumber.WriteError; errno = ErrorNumber.WriteError;
@@ -1311,7 +1292,7 @@ sealed class ConvertImageCommand : Command
doneSectors = 0; doneSectors = 0;
ProgressTask tagsTask = ctx.AddTask("Converting tags"); ProgressTask tagsTask = ctx.AddTask(UI.Converting_tags);
tagsTask.MaxValue = inputFormat.Info.Sectors; tagsTask.MaxValue = inputFormat.Info.Sectors;
while(doneSectors < inputFormat.Info.Sectors) while(doneSectors < inputFormat.Info.Sectors)
@@ -1326,7 +1307,7 @@ sealed class ConvertImageCommand : Command
sectorsToDo = (uint)(inputFormat.Info.Sectors - doneSectors); sectorsToDo = (uint)(inputFormat.Info.Sectors - doneSectors);
tagsTask.Description = tagsTask.Description =
string.Format("Converting tag {2} for sectors {0} to {1}", doneSectors, string.Format(UI.Converting_tag_2_for_sectors_0_to_1, doneSectors,
doneSectors + sectorsToDo, tag); doneSectors + sectorsToDo, tag);
bool result; bool result;
@@ -1343,13 +1324,12 @@ sealed class ConvertImageCommand : Command
result = true; result = true;
if(force) if(force)
AaruConsole.ErrorWriteLine("Error {0} reading sector {1}, continuing...", AaruConsole.ErrorWriteLine(UI.Error_0_reading_sector_1_continuing, errno,
errno, doneSectors); doneSectors);
else else
{ {
AaruConsole. AaruConsole.ErrorWriteLine(UI.Error_0_reading_sector_1_not_continuing,
ErrorWriteLine("Error {0} reading sector {1}, not continuing...", errno, errno, doneSectors);
doneSectors);
return; return;
} }
@@ -1357,13 +1337,12 @@ sealed class ConvertImageCommand : Command
if(!result) if(!result)
if(force) if(force)
AaruConsole.ErrorWriteLine("Error {0} writing sector {1}, continuing...", AaruConsole.ErrorWriteLine(UI.Error_0_writing_sector_1_continuing,
outputMedia.ErrorMessage, doneSectors); outputMedia.ErrorMessage, doneSectors);
else else
{ {
AaruConsole. AaruConsole.ErrorWriteLine(UI.Error_0_writing_sector_1_not_continuing,
ErrorWriteLine("Error {0} writing sector {1}, not continuing...", outputMedia.ErrorMessage, doneSectors);
outputMedia.ErrorMessage, doneSectors);
errno = ErrorNumber.WriteError; errno = ErrorNumber.WriteError;
@@ -1382,13 +1361,14 @@ sealed class ConvertImageCommand : Command
!inputTape.IsTape) !inputTape.IsTape)
return; return;
ProgressTask filesTask = ctx.AddTask("Converting files"); ProgressTask filesTask = ctx.AddTask(UI.Converting_files);
filesTask.MaxValue = inputTape.Files.Count; filesTask.MaxValue = inputTape.Files.Count;
foreach(TapeFile tapeFile in inputTape.Files) foreach(TapeFile tapeFile in inputTape.Files)
{ {
filesTask.Description = $"Converting file {tapeFile.File} of partition { filesTask.Description =
tapeFile.Partition}..."; string.Format(UI.Converting_file_0_of_partition_1, tapeFile.File,
tapeFile.Partition);
outputTape.AddFile(tapeFile); outputTape.AddFile(tapeFile);
filesTask.Increment(1); filesTask.Increment(1);
@@ -1396,12 +1376,13 @@ sealed class ConvertImageCommand : Command
filesTask.StopTask(); filesTask.StopTask();
ProgressTask partitionTask = ctx.AddTask("Converting files"); ProgressTask partitionTask = ctx.AddTask(UI.Converting_files);
partitionTask.MaxValue = inputTape.TapePartitions.Count; partitionTask.MaxValue = inputTape.TapePartitions.Count;
foreach(TapePartition tapePartition in inputTape.TapePartitions) foreach(TapePartition tapePartition in inputTape.TapePartitions)
{ {
partitionTask.Description = $"Converting tape partition {tapePartition.Number}..."; partitionTask.Description =
string.Format(UI.Converting_tape_partition_0, tapePartition.Number);
outputTape.AddPartition(tapePartition); outputTape.AddPartition(tapePartition);
} }
@@ -1418,7 +1399,7 @@ sealed class ConvertImageCommand : Command
{ {
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Writing dump hardware list...").IsIndeterminate(); ctx.AddTask(UI.Writing_dump_hardware_list).IsIndeterminate();
if(resume != null) if(resume != null)
ret = outputFormat.SetDumpHardware(resume.Tries); ret = outputFormat.SetDumpHardware(resume.Tries);
@@ -1427,7 +1408,7 @@ sealed class ConvertImageCommand : Command
}); });
if(ret) if(ret)
AaruConsole.WriteLine("Written dump hardware list to output image."); AaruConsole.WriteLine(UI.Written_dump_hardware_list_to_output_image);
} }
ret = false; ret = false;
@@ -1437,7 +1418,7 @@ sealed class ConvertImageCommand : Command
{ {
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Writing metadata...").IsIndeterminate(); ctx.AddTask(UI.Writing_metadata).IsIndeterminate();
if(sidecar != null) if(sidecar != null)
ret = outputFormat.SetCicmMetadata(sidecar); ret = outputFormat.SetCicmMetadata(sidecar);
@@ -1446,26 +1427,26 @@ sealed class ConvertImageCommand : Command
}); });
if(ret) if(ret)
AaruConsole.WriteLine("Written CICM XML metadata to output image."); AaruConsole.WriteLine(UI.Written_CICM_XML_metadata_to_output_image);
} }
bool closed = false; bool closed = false;
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Closing output image...").IsIndeterminate(); ctx.AddTask(UI.Closing_output_image).IsIndeterminate();
closed = outputFormat.Close(); closed = outputFormat.Close();
}); });
if(!closed) if(!closed)
{ {
AaruConsole.ErrorWriteLine("Error {0} closing output image... Contents are not correct.", AaruConsole.ErrorWriteLine(UI.Error_0_closing_output_image_Contents_are_not_correct,
outputFormat.ErrorMessage); outputFormat.ErrorMessage);
return (int)ErrorNumber.WriteError; return (int)ErrorNumber.WriteError;
} }
AaruConsole.WriteLine("Conversion done."); AaruConsole.WriteLine(UI.Conversion_done);
return (int)ErrorNumber.NoError; return (int)ErrorNumber.NoError;
} }

View File

@@ -43,6 +43,7 @@ using Aaru.CommonTypes.Enums;
using Aaru.CommonTypes.Interfaces; using Aaru.CommonTypes.Interfaces;
using Aaru.Console; using Aaru.Console;
using Aaru.Core; using Aaru.Core;
using Aaru.Localization;
using JetBrains.Annotations; using JetBrains.Annotations;
using Schemas; using Schemas;
using Spectre.Console; using Spectre.Console;
@@ -54,29 +55,27 @@ sealed class CreateSidecarCommand : Command
static ProgressTask _progressTask1; static ProgressTask _progressTask1;
static ProgressTask _progressTask2; static ProgressTask _progressTask2;
public CreateSidecarCommand() : base("create-sidecar", "Creates CICM Metadata XML sidecar.") public CreateSidecarCommand() : base("create-sidecar", UI.Image_Create_Sidecar_Command_Description)
{ {
Add(new Option<int>(new[] Add(new Option<int>(new[]
{ {
"--block-size", "-b" "--block-size", "-b"
}, () => 512, }, () => 512, UI.Tape_block_size_argument_help));
"Only used for tapes, indicates block size. Files in the folder whose size is not a multiple of this value will simply be ignored."));
Add(new Option<string>(new[] Add(new Option<string>(new[]
{ {
"--encoding", "-e" "--encoding", "-e"
}, () => null, "Name of character encoding to use.")); }, () => null, UI.Name_of_character_encoding_to_use));
Add(new Option<bool>(new[] Add(new Option<bool>(new[]
{ {
"--tape", "-t" "--tape", "-t"
}, () => false, }, () => false, UI.Tape_argument_input_help));
"When used indicates that input is a folder containing alphabetically sorted files extracted from a linear block-based tape with fixed block size (e.g. a SCSI tape device)."));
AddArgument(new Argument<string> AddArgument(new Argument<string>
{ {
Arity = ArgumentArity.ExactlyOne, Arity = ArgumentArity.ExactlyOne,
Description = "Media image path", Description = UI.Media_image_path,
Name = "image-path" Name = "image-path"
}); });
@@ -130,11 +129,11 @@ sealed class CreateSidecarCommand : Command
encodingClass = Claunia.Encoding.Encoding.GetEncoding(encodingName); encodingClass = Claunia.Encoding.Encoding.GetEncoding(encodingName);
if(verbose) if(verbose)
AaruConsole.VerboseWriteLine("Using encoding for {0}.", encodingClass.EncodingName); AaruConsole.VerboseWriteLine(UI.encoding_for_0, encodingClass.EncodingName);
} }
catch(ArgumentException) catch(ArgumentException)
{ {
AaruConsole.ErrorWriteLine("Specified encoding is not supported."); AaruConsole.ErrorWriteLine(UI.Specified_encoding_is_not_supported);
return (int)ErrorNumber.EncodingUnknown; return (int)ErrorNumber.EncodingUnknown;
} }
@@ -143,7 +142,7 @@ sealed class CreateSidecarCommand : Command
{ {
if(tape) if(tape)
{ {
AaruConsole.ErrorWriteLine("You cannot use --tape option when input is a file."); AaruConsole.ErrorWriteLine(UI.You_cannot_use_tape_option_when_input_is_a_file);
return (int)ErrorNumber.NotDirectory; return (int)ErrorNumber.NotDirectory;
} }
@@ -153,13 +152,13 @@ sealed class CreateSidecarCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Identifying file filter...").IsIndeterminate(); ctx.AddTask(UI.Identifying_file_filter).IsIndeterminate();
inputFilter = filtersList.GetFilter(imagePath); inputFilter = filtersList.GetFilter(imagePath);
}); });
if(inputFilter == null) if(inputFilter == null)
{ {
AaruConsole.ErrorWriteLine("Cannot open specified file."); AaruConsole.ErrorWriteLine(UI.Cannot_open_specified_file);
return (int)ErrorNumber.CannotOpenFile; return (int)ErrorNumber.CannotOpenFile;
} }
@@ -170,22 +169,21 @@ sealed class CreateSidecarCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Identifying image format...").IsIndeterminate(); ctx.AddTask(UI.Identifying_image_format).IsIndeterminate();
imageFormat = ImageFormat.Detect(inputFilter); imageFormat = ImageFormat.Detect(inputFilter);
}); });
if(imageFormat == null) if(imageFormat == null)
{ {
AaruConsole.WriteLine("Image format not identified, not proceeding with analysis."); AaruConsole.WriteLine(UI.Image_format_not_identified_not_proceeding_with_sidecar_creation);
return (int)ErrorNumber.UnrecognizedFormat; return (int)ErrorNumber.UnrecognizedFormat;
} }
if(verbose) if(verbose)
AaruConsole.VerboseWriteLine("Image format identified by {0} ({1}).", imageFormat.Name, AaruConsole.VerboseWriteLine(UI.Image_format_identified_by_0_1, imageFormat.Name, imageFormat.Id);
imageFormat.Id);
else else
AaruConsole.WriteLine("Image format identified by {0}.", imageFormat.Name); AaruConsole.WriteLine(UI.Image_format_identified_by_0, imageFormat.Name);
try try
{ {
@@ -193,23 +191,24 @@ sealed class CreateSidecarCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Opening image file...").IsIndeterminate(); ctx.AddTask(UI.Invoke_Opening_image_file).IsIndeterminate();
opened = imageFormat.Open(inputFilter); opened = imageFormat.Open(inputFilter);
}); });
if(opened != ErrorNumber.NoError) if(opened != ErrorNumber.NoError)
{ {
AaruConsole.WriteLine("Error {opened} opening image format"); AaruConsole.WriteLine(UI.Unable_to_open_image_format);
AaruConsole.WriteLine(UI.Error_0, opened);
return (int)opened; return (int)opened;
} }
AaruConsole.DebugWriteLine("Create sidecar command", "Correctly opened image file."); AaruConsole.DebugWriteLine("Create sidecar command", UI.Correctly_opened_image_file);
} }
catch(Exception ex) catch(Exception ex)
{ {
AaruConsole.ErrorWriteLine("Unable to open image format"); AaruConsole.ErrorWriteLine(UI.Unable_to_open_image_format);
AaruConsole.ErrorWriteLine("Error: {0}", ex.Message); AaruConsole.ErrorWriteLine(UI.Error_0, ex.Message);
return (int)ErrorNumber.CannotOpenFormat; return (int)ErrorNumber.CannotOpenFormat;
} }
@@ -278,7 +277,7 @@ sealed class CreateSidecarCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Writing metadata sidecar").IsIndeterminate(); ctx.AddTask(Localization.Core.Writing_metadata_sidecar).IsIndeterminate();
var xmlFs = var xmlFs =
new new
@@ -292,7 +291,7 @@ sealed class CreateSidecarCommand : Command
} }
catch(Exception ex) catch(Exception ex)
{ {
AaruConsole.ErrorWriteLine($"Error reading file: {ex.Message}"); AaruConsole.ErrorWriteLine(string.Format(UI.Error_reading_file_0, ex.Message));
AaruConsole.DebugWriteLine("Create sidecar command", ex.StackTrace); AaruConsole.DebugWriteLine("Create sidecar command", ex.StackTrace);
return (int)ErrorNumber.UnexpectedException; return (int)ErrorNumber.UnexpectedException;
@@ -302,7 +301,7 @@ sealed class CreateSidecarCommand : Command
{ {
if(!tape) if(!tape)
{ {
AaruConsole.ErrorWriteLine("Cannot create a sidecar from a directory."); AaruConsole.ErrorWriteLine(Localization.Core.Cannot_create_a_sidecar_from_a_directory);
return (int)ErrorNumber.IsDirectory; return (int)ErrorNumber.IsDirectory;
} }
@@ -373,7 +372,7 @@ sealed class CreateSidecarCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Writing metadata sidecar").IsIndeterminate(); ctx.AddTask(Localization.Core.Writing_metadata_sidecar).IsIndeterminate();
var xmlFs = var xmlFs =
new new
@@ -386,7 +385,7 @@ sealed class CreateSidecarCommand : Command
}); });
} }
else else
AaruConsole.ErrorWriteLine("The specified input file cannot be found."); AaruConsole.ErrorWriteLine(UI.The_specified_input_file_cannot_be_found);
return (int)ErrorNumber.NoError; return (int)ErrorNumber.NoError;
} }

View File

@@ -32,6 +32,7 @@
using System.CommandLine; using System.CommandLine;
using System.CommandLine.NamingConventionBinder; using System.CommandLine.NamingConventionBinder;
using System.Globalization;
using Aaru.CommonTypes; using Aaru.CommonTypes;
using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Enums;
using Aaru.CommonTypes.Interfaces; using Aaru.CommonTypes.Interfaces;
@@ -40,38 +41,39 @@ using Aaru.Core;
using Aaru.Decoders.ATA; using Aaru.Decoders.ATA;
using Aaru.Decoders.CD; using Aaru.Decoders.CD;
using Aaru.Decoders.SCSI; using Aaru.Decoders.SCSI;
using Aaru.Localization;
using Spectre.Console; using Spectre.Console;
namespace Aaru.Commands.Image; namespace Aaru.Commands.Image;
sealed class DecodeCommand : Command sealed class DecodeCommand : Command
{ {
public DecodeCommand() : base("decode", "Decodes and pretty prints disk and/or sector tags.") public DecodeCommand() : base("decode", UI.Image_Decode_Command_Description)
{ {
Add(new Option<bool>(new[] Add(new Option<bool>(new[]
{ {
"--disk-tags", "-f" "--disk-tags", "-f"
}, () => true, "Decode disk tags.")); }, () => true, UI.Decode_disk_tags));
Add(new Option<string>(new[] Add(new Option<string>(new[]
{ {
"--length", "-l" "--length", "-l"
}, () => "all", "How many sectors to decode, or \"all\".")); }, () => UI.Parameter_response_all_sectors, UI.How_many_sectors_to_decode_or_all));
Add(new Option<bool>(new[] Add(new Option<bool>(new[]
{ {
"--sector-tags", "-p" "--sector-tags", "-p"
}, () => true, "Decode sector tags.")); }, () => true, UI.Decode_sector_tags));
Add(new Option<ulong>(new[] Add(new Option<ulong>(new[]
{ {
"--start", "-s" "--start", "-s"
}, () => 0, "Sector to start decoding from.")); }, () => 0, UI.Sector_to_start_decoding_from));
AddArgument(new Argument<string> AddArgument(new Argument<string>
{ {
Arity = ArgumentArity.ExactlyOne, Arity = ArgumentArity.ExactlyOne,
Description = "Media image path", Description = UI.Media_image_path,
Name = "image-path" Name = "image-path"
}); });
@@ -123,13 +125,13 @@ sealed class DecodeCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Identifying file filter...").IsIndeterminate(); ctx.AddTask(UI.Identifying_file_filter).IsIndeterminate();
inputFilter = filtersList.GetFilter(imagePath); inputFilter = filtersList.GetFilter(imagePath);
}); });
if(inputFilter == null) if(inputFilter == null)
{ {
AaruConsole.ErrorWriteLine("Cannot open specified file."); AaruConsole.ErrorWriteLine(UI.Cannot_open_specified_file);
return (int)ErrorNumber.CannotOpenFile; return (int)ErrorNumber.CannotOpenFile;
} }
@@ -139,21 +141,21 @@ sealed class DecodeCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Identifying image format...").IsIndeterminate(); ctx.AddTask(UI.Identifying_image_format).IsIndeterminate();
baseImage = ImageFormat.Detect(inputFilter); baseImage = ImageFormat.Detect(inputFilter);
inputFormat = baseImage as IMediaImage; inputFormat = baseImage as IMediaImage;
}); });
if(baseImage == null) if(baseImage == null)
{ {
AaruConsole.ErrorWriteLine("Unable to recognize image format, not decoding"); AaruConsole.ErrorWriteLine(UI.Unable_to_recognize_image_format_not_decoding);
return (int)ErrorNumber.UnrecognizedFormat; return (int)ErrorNumber.UnrecognizedFormat;
} }
if(inputFormat == null) if(inputFormat == null)
{ {
AaruConsole.WriteLine("Command not supported for this image type."); AaruConsole.WriteLine(UI.Command_not_supported_for_this_image_type);
return (int)ErrorNumber.InvalidArgument; return (int)ErrorNumber.InvalidArgument;
} }
@@ -162,13 +164,14 @@ sealed class DecodeCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Opening image file...").IsIndeterminate(); ctx.AddTask(UI.Invoke_Opening_image_file).IsIndeterminate();
opened = inputFormat.Open(inputFilter); opened = inputFormat.Open(inputFilter);
}); });
if(opened != ErrorNumber.NoError) if(opened != ErrorNumber.NoError)
{ {
AaruConsole.WriteLine("Error {opened} opening image format"); AaruConsole.WriteLine(UI.Unable_to_open_image_format);
AaruConsole.WriteLine(UI.Error_0, opened);
return (int)opened; return (int)opened;
} }
@@ -180,7 +183,7 @@ sealed class DecodeCommand : Command
if(diskTags) if(diskTags)
if(inputFormat.Info.ReadableMediaTags.Count == 0) if(inputFormat.Info.ReadableMediaTags.Count == 0)
AaruConsole.WriteLine("There are no disk tags in chosen disc image."); AaruConsole.WriteLine(UI.There_are_no_disk_tags_in_chosen_disc_image);
else else
foreach(MediaTagType tag in inputFormat.Info.ReadableMediaTags) foreach(MediaTagType tag in inputFormat.Info.ReadableMediaTags)
switch(tag) switch(tag)
@@ -190,10 +193,10 @@ sealed class DecodeCommand : Command
errno = inputFormat.ReadMediaTag(MediaTagType.SCSI_INQUIRY, out byte[] inquiry); errno = inputFormat.ReadMediaTag(MediaTagType.SCSI_INQUIRY, out byte[] inquiry);
if(inquiry == null) if(inquiry == null)
AaruConsole.WriteLine("Error {0} reading SCSI INQUIRY response from disc image", errno); AaruConsole.WriteLine(UI.Error_0_reading_SCSI_INQUIRY_response_from_disc_image, errno);
else else
{ {
AaruConsole.WriteLine("[bold]SCSI INQUIRY command response:[/]"); AaruConsole.WriteLine($"[bold]{UI.SCSI_INQUIRY_command_response}[/]");
AaruConsole. AaruConsole.
WriteLine("================================================================================"); WriteLine("================================================================================");
@@ -211,11 +214,11 @@ sealed class DecodeCommand : Command
errno = inputFormat.ReadMediaTag(MediaTagType.ATA_IDENTIFY, out byte[] identify); errno = inputFormat.ReadMediaTag(MediaTagType.ATA_IDENTIFY, out byte[] identify);
if(errno != ErrorNumber.NoError) if(errno != ErrorNumber.NoError)
AaruConsole.WriteLine("Error {0} reading ATA IDENTIFY DEVICE response from disc image", AaruConsole.WriteLine(UI.Error_0_reading_ATA_IDENTIFY_DEVICE_response_from_disc_image,
errno); errno);
else else
{ {
AaruConsole.WriteLine("[bold]ATA IDENTIFY DEVICE command response:[/]"); AaruConsole.WriteLine($"[bold]{UI.ATA_IDENTIFY_DEVICE_command_response}[/]");
AaruConsole. AaruConsole.
WriteLine("================================================================================"); WriteLine("================================================================================");
@@ -234,11 +237,11 @@ sealed class DecodeCommand : Command
if(identify == null) if(identify == null)
AaruConsole. AaruConsole.
WriteLine("Error {0} reading ATA IDENTIFY PACKET DEVICE response from disc image", WriteLine(UI.Error_0_reading_ATA_IDENTIFY_PACKET_DEVICE_response_from_disc_image,
errno); errno);
else else
{ {
AaruConsole.WriteLine("[bold]ATA IDENTIFY PACKET DEVICE command response:[/]"); AaruConsole.WriteLine($"[bold]{UI.ATA_IDENTIFY_PACKET_DEVICE_command_response}[/]");
AaruConsole. AaruConsole.
WriteLine("================================================================================"); WriteLine("================================================================================");
@@ -256,10 +259,10 @@ sealed class DecodeCommand : Command
errno = inputFormat.ReadMediaTag(MediaTagType.CD_ATIP, out byte[] atip); errno = inputFormat.ReadMediaTag(MediaTagType.CD_ATIP, out byte[] atip);
if(errno != ErrorNumber.NoError) if(errno != ErrorNumber.NoError)
AaruConsole.WriteLine("Error {0} reading CD ATIP from disc image", errno); AaruConsole.WriteLine(UI.Error_0_reading_CD_ATIP_from_disc_image, errno);
else else
{ {
AaruConsole.WriteLine("[bold]CD ATIP:[/]"); AaruConsole.WriteLine($"[bold]{UI.CD_ATIP}[/]");
AaruConsole. AaruConsole.
WriteLine("================================================================================"); WriteLine("================================================================================");
@@ -277,10 +280,10 @@ sealed class DecodeCommand : Command
errno = inputFormat.ReadMediaTag(MediaTagType.CD_FullTOC, out byte[] fullToc); errno = inputFormat.ReadMediaTag(MediaTagType.CD_FullTOC, out byte[] fullToc);
if(errno != ErrorNumber.NoError) if(errno != ErrorNumber.NoError)
AaruConsole.WriteLine("Error {0} reading CD full TOC from disc image", errno); AaruConsole.WriteLine(UI.Error_0_reading_CD_full_TOC_from_disc_image, errno);
else else
{ {
AaruConsole.WriteLine("[bold]CD full TOC:[/]"); AaruConsole.WriteLine($"[bold]{UI.CD_full_TOC}[/]");
AaruConsole. AaruConsole.
WriteLine("================================================================================"); WriteLine("================================================================================");
@@ -298,10 +301,10 @@ sealed class DecodeCommand : Command
errno = inputFormat.ReadMediaTag(MediaTagType.CD_PMA, out byte[] pma); errno = inputFormat.ReadMediaTag(MediaTagType.CD_PMA, out byte[] pma);
if(errno != ErrorNumber.NoError) if(errno != ErrorNumber.NoError)
AaruConsole.WriteLine("Error {0} reading CD PMA from disc image", errno); AaruConsole.WriteLine(UI.Error_0_reading_CD_PMA_from_disc_image, errno);
else else
{ {
AaruConsole.WriteLine("[bold]CD PMA:[/]"); AaruConsole.WriteLine($"[bold]{"CD PMA:"}[/]");
AaruConsole. AaruConsole.
WriteLine("================================================================================"); WriteLine("================================================================================");
@@ -319,11 +322,10 @@ sealed class DecodeCommand : Command
errno = inputFormat.ReadMediaTag(MediaTagType.CD_SessionInfo, out byte[] sessionInfo); errno = inputFormat.ReadMediaTag(MediaTagType.CD_SessionInfo, out byte[] sessionInfo);
if(errno != ErrorNumber.NoError) if(errno != ErrorNumber.NoError)
AaruConsole.WriteLine("Error {0} reading CD session information from disc image", AaruConsole.WriteLine(UI.Error_0_reading_CD_session_information_from_disc_image, errno);
errno);
else else
{ {
AaruConsole.WriteLine("[bold]CD session information:[/]"); AaruConsole.WriteLine($"[bold]{UI.CD_session_information}[/]");
AaruConsole. AaruConsole.
WriteLine("================================================================================"); WriteLine("================================================================================");
@@ -341,10 +343,10 @@ sealed class DecodeCommand : Command
errno = inputFormat.ReadMediaTag(MediaTagType.CD_TEXT, out byte[] cdText); errno = inputFormat.ReadMediaTag(MediaTagType.CD_TEXT, out byte[] cdText);
if(errno != ErrorNumber.NoError) if(errno != ErrorNumber.NoError)
AaruConsole.WriteLine("Error reading CD-TEXT from disc image"); AaruConsole.WriteLine(UI.Error_reading_CD_TEXT_from_disc_image);
else else
{ {
AaruConsole.WriteLine("[bold]CD-TEXT:[/]"); AaruConsole.WriteLine($"[bold]{UI.CD_TEXT}[/]");
AaruConsole. AaruConsole.
WriteLine("================================================================================"); WriteLine("================================================================================");
@@ -363,10 +365,10 @@ sealed class DecodeCommand : Command
if(toc == null || if(toc == null ||
errno != ErrorNumber.NoError) errno != ErrorNumber.NoError)
AaruConsole.WriteLine("Error reading CD TOC from disc image"); AaruConsole.WriteLine(UI.Error_reading_CD_TOC_from_disc_image);
else else
{ {
AaruConsole.WriteLine("[bold]CD TOC:[/]"); AaruConsole.WriteLine($"[bold]{UI.CD_TOC}[/]");
AaruConsole. AaruConsole.
WriteLine("================================================================================"); WriteLine("================================================================================");
@@ -380,7 +382,7 @@ sealed class DecodeCommand : Command
break; break;
} }
default: default:
AaruConsole.WriteLine("Decoder for disk tag type \"{0}\" not yet implemented, sorry.", tag); AaruConsole.WriteLine(UI.Decoder_for_disk_tag_type_0_not_yet_implemented_sorry, tag);
break; break;
} }
@@ -388,26 +390,26 @@ sealed class DecodeCommand : Command
if(!sectorTags) if(!sectorTags)
return (int)ErrorNumber.NoError; return (int)ErrorNumber.NoError;
if(length.ToLowerInvariant() == "all") {} if(length.ToLower(CultureInfo.CurrentUICulture) == UI.Parameter_response_all_sectors) {}
else else
{ {
if(!ulong.TryParse(length, out ulong _)) if(!ulong.TryParse(length, out ulong _))
{ {
AaruConsole.WriteLine("Value \"{0}\" is not a valid number for length.", length); AaruConsole.WriteLine(UI.Value_0_is_not_a_valid_number_for_length, length);
AaruConsole.WriteLine("Not decoding sectors tags"); AaruConsole.WriteLine(UI.Not_decoding_sectors_tags);
return 3; return 3;
} }
} }
if(inputFormat.Info.ReadableSectorTags.Count == 0) if(inputFormat.Info.ReadableSectorTags.Count == 0)
AaruConsole.WriteLine("There are no sector tags in chosen disc image."); AaruConsole.WriteLine(UI.There_are_no_sector_tags_in_chosen_disc_image);
else else
foreach(SectorTagType tag in inputFormat.Info.ReadableSectorTags) foreach(SectorTagType tag in inputFormat.Info.ReadableSectorTags)
switch(tag) switch(tag)
{ {
default: default:
AaruConsole.WriteLine("Decoder for disk tag type \"{0}\" not yet implemented, sorry.", tag); AaruConsole.WriteLine(UI.Decoder_for_sector_tag_type_0_not_yet_implemented_sorry, tag);
break; break;
} }

View File

@@ -37,6 +37,7 @@ using Aaru.CommonTypes.Enums;
using Aaru.CommonTypes.Interfaces; using Aaru.CommonTypes.Interfaces;
using Aaru.Console; using Aaru.Console;
using Aaru.Core; using Aaru.Core;
using Aaru.Localization;
using Spectre.Console; using Spectre.Console;
namespace Aaru.Commands.Image; namespace Aaru.Commands.Image;
@@ -46,27 +47,27 @@ sealed class EntropyCommand : Command
static ProgressTask _progressTask1; static ProgressTask _progressTask1;
static ProgressTask _progressTask2; static ProgressTask _progressTask2;
public EntropyCommand() : base("entropy", "Calculates entropy and/or duplicated sectors of an image.") public EntropyCommand() : base("entropy", UI.Image_Entropy_Command_Description)
{ {
Add(new Option<bool>(new[] Add(new Option<bool>(new[]
{ {
"--duplicated-sectors", "-p" "--duplicated-sectors", "-p"
}, () => true, "Calculates how many sectors are duplicated (have same exact data in user area).")); }, () => true, UI.Calculates_how_many_sectors_are_duplicated));
Add(new Option<bool>(new[] Add(new Option<bool>(new[]
{ {
"--separated-tracks", "-t" "--separated-tracks", "-t"
}, () => true, "Calculates entropy for each track separately.")); }, () => true, UI.Calculates_entropy_for_each_track_separately));
Add(new Option<bool>(new[] Add(new Option<bool>(new[]
{ {
"--whole-disc", "-w" "--whole-disc", "-w"
}, () => true, "Calculates entropy for the whole disc.")); }, () => true, UI.Calculates_entropy_for_the_whole_disc));
AddArgument(new Argument<string> AddArgument(new Argument<string>
{ {
Arity = ArgumentArity.ExactlyOne, Arity = ArgumentArity.ExactlyOne,
Description = "Media image path", Description = UI.Media_image_path,
Name = "image-path" Name = "image-path"
}); });
@@ -117,13 +118,13 @@ sealed class EntropyCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Identifying file filter...").IsIndeterminate(); ctx.AddTask(UI.Identifying_file_filter).IsIndeterminate();
inputFilter = filtersList.GetFilter(imagePath); inputFilter = filtersList.GetFilter(imagePath);
}); });
if(inputFilter == null) if(inputFilter == null)
{ {
AaruConsole.ErrorWriteLine("Cannot open specified file."); AaruConsole.ErrorWriteLine(UI.Cannot_open_specified_file);
return (int)ErrorNumber.CannotOpenFile; return (int)ErrorNumber.CannotOpenFile;
} }
@@ -132,13 +133,13 @@ sealed class EntropyCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Identifying image format...").IsIndeterminate(); ctx.AddTask(UI.Identifying_image_format).IsIndeterminate();
inputFormat = ImageFormat.Detect(inputFilter); inputFormat = ImageFormat.Detect(inputFilter);
}); });
if(inputFormat == null) if(inputFormat == null)
{ {
AaruConsole.ErrorWriteLine("Unable to recognize image format, not checksumming"); AaruConsole.ErrorWriteLine(UI.Unable_to_recognize_image_format_not_checksumming);
return (int)ErrorNumber.UnrecognizedFormat; return (int)ErrorNumber.UnrecognizedFormat;
} }
@@ -147,13 +148,14 @@ sealed class EntropyCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Opening image file...").IsIndeterminate(); ctx.AddTask(UI.Invoke_Opening_image_file).IsIndeterminate();
opened = inputFormat.Open(inputFilter); opened = inputFormat.Open(inputFilter);
}); });
if(opened != ErrorNumber.NoError) if(opened != ErrorNumber.NoError)
{ {
AaruConsole.WriteLine("Error {opened} opening image format"); AaruConsole.WriteLine(UI.Unable_to_open_image_format);
AaruConsole.WriteLine(UI.Error_0, opened);
return (int)opened; return (int)opened;
} }
@@ -209,8 +211,8 @@ sealed class EntropyCommand : Command
{ {
if(opticalFormat.Sessions?.Count > 1) if(opticalFormat.Sessions?.Count > 1)
{ {
AaruConsole. AaruConsole.ErrorWriteLine(UI.
ErrorWriteLine("Calculating disc entropy of multisession images is not yet implemented."); Calculating_disc_entropy_of_multisession_images_is_not_yet_implemented);
wholeDisc = false; wholeDisc = false;
} }
@@ -226,12 +228,12 @@ sealed class EntropyCommand : Command
foreach(EntropyResults trackEntropy in tracksEntropy) foreach(EntropyResults trackEntropy in tracksEntropy)
{ {
AaruConsole.WriteLine("Entropy for track {0} is {1:F4}.", trackEntropy.Track, AaruConsole.WriteLine(UI.Entropy_for_track_0_is_1, trackEntropy.Track,
trackEntropy.Entropy); trackEntropy.Entropy);
if(trackEntropy.UniqueSectors != null) if(trackEntropy.UniqueSectors != null)
AaruConsole.WriteLine("Track {0} has {1} unique sectors ({2:P3})", AaruConsole.WriteLine(UI.Track_0_has_1_unique_sectors_2, trackEntropy.Track,
trackEntropy.Track, trackEntropy.UniqueSectors, trackEntropy.UniqueSectors,
(double)trackEntropy.UniqueSectors / trackEntropy.Sectors); (double)trackEntropy.UniqueSectors / trackEntropy.Sectors);
} }
} }
@@ -243,10 +245,10 @@ sealed class EntropyCommand : Command
? entropyCalculator.CalculateLinearMediaEntropy() ? entropyCalculator.CalculateLinearMediaEntropy()
: entropyCalculator.CalculateMediaEntropy(duplicatedSectors); : entropyCalculator.CalculateMediaEntropy(duplicatedSectors);
AaruConsole.WriteLine("Entropy for disk is {0:F4}.", entropy.Entropy); AaruConsole.WriteLine(UI.Entropy_for_disk_is_0, entropy.Entropy);
if(entropy.UniqueSectors != null) if(entropy.UniqueSectors != null)
AaruConsole.WriteLine("Disk has {0} unique sectors ({1:P3})", entropy.UniqueSectors, AaruConsole.WriteLine(UI.Disk_has_0_unique_sectors_1, entropy.UniqueSectors,
(double)entropy.UniqueSectors / entropy.Sectors); (double)entropy.UniqueSectors / entropy.Sectors);
}); });

View File

@@ -31,12 +31,13 @@
// ****************************************************************************/ // ****************************************************************************/
using System.CommandLine; using System.CommandLine;
using Aaru.Localization;
namespace Aaru.Commands.Image; namespace Aaru.Commands.Image;
sealed class ImageFamily : Command sealed class ImageFamily : Command
{ {
public ImageFamily() : base("image", "Commands to manage images") public ImageFamily() : base("image", UI.Image_Command_Family_Description)
{ {
AddAlias("i"); AddAlias("i");

View File

@@ -38,19 +38,19 @@ using Aaru.CommonTypes.Enums;
using Aaru.CommonTypes.Interfaces; using Aaru.CommonTypes.Interfaces;
using Aaru.Console; using Aaru.Console;
using Aaru.Core; using Aaru.Core;
using Aaru.Localization;
using Spectre.Console; using Spectre.Console;
namespace Aaru.Commands.Image; namespace Aaru.Commands.Image;
sealed class ImageInfoCommand : Command sealed class ImageInfoCommand : Command
{ {
public ImageInfoCommand() : base("info", public ImageInfoCommand() : base("info", UI.Image_Info_Command_Description)
"Identifies a media image and shows information about the media it represents and metadata.")
{ {
AddArgument(new Argument<string> AddArgument(new Argument<string>
{ {
Arity = ArgumentArity.ExactlyOne, Arity = ArgumentArity.ExactlyOne,
Description = "Media image path", Description = UI.Media_image_path,
Name = "image-path" Name = "image-path"
}); });
@@ -97,13 +97,13 @@ sealed class ImageInfoCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Identifying file filter...").IsIndeterminate(); ctx.AddTask(UI.Identifying_file_filter).IsIndeterminate();
inputFilter = filtersList.GetFilter(imagePath); inputFilter = filtersList.GetFilter(imagePath);
}); });
if(inputFilter == null) if(inputFilter == null)
{ {
AaruConsole.ErrorWriteLine("Cannot open specified file."); AaruConsole.ErrorWriteLine(UI.Cannot_open_specified_file);
return (int)ErrorNumber.CannotOpenFile; return (int)ErrorNumber.CannotOpenFile;
} }
@@ -114,18 +114,18 @@ sealed class ImageInfoCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Identifying image format...").IsIndeterminate(); ctx.AddTask(UI.Identifying_image_format).IsIndeterminate();
imageFormat = ImageFormat.Detect(inputFilter); imageFormat = ImageFormat.Detect(inputFilter);
}); });
if(imageFormat == null) if(imageFormat == null)
{ {
AaruConsole.WriteLine("Image format not identified."); AaruConsole.WriteLine(UI.Image_format_not_identified);
return (int)ErrorNumber.UnrecognizedFormat; return (int)ErrorNumber.UnrecognizedFormat;
} }
AaruConsole.WriteLine("Image format identified by {0} ({1}).", imageFormat.Name, imageFormat.Id); AaruConsole.WriteLine(UI.Image_format_identified_by_0_1, imageFormat.Name, imageFormat.Id);
AaruConsole.WriteLine(); AaruConsole.WriteLine();
try try
@@ -134,13 +134,14 @@ sealed class ImageInfoCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Opening image file...").IsIndeterminate(); ctx.AddTask(UI.Invoke_Opening_image_file).IsIndeterminate();
opened = imageFormat.Open(inputFilter); opened = imageFormat.Open(inputFilter);
}); });
if(opened != ErrorNumber.NoError) if(opened != ErrorNumber.NoError)
{ {
AaruConsole.WriteLine("Error {opened} opening image format"); AaruConsole.WriteLine(UI.Unable_to_open_image_format);
AaruConsole.WriteLine(UI.Error_0, opened);
return (int)opened; return (int)opened;
} }
@@ -153,16 +154,16 @@ sealed class ImageInfoCommand : Command
} }
catch(Exception ex) catch(Exception ex)
{ {
AaruConsole.ErrorWriteLine("Unable to open image format"); AaruConsole.ErrorWriteLine(UI.Unable_to_open_image_format);
AaruConsole.ErrorWriteLine("Error: {0}", ex.Message); AaruConsole.ErrorWriteLine(UI.Error_0, ex.Message);
AaruConsole.DebugWriteLine("Image-info command", "Stack trace: {0}", ex.StackTrace); AaruConsole.DebugWriteLine("Image-info command", Localization.Core.Stack_trace_0, ex.StackTrace);
return (int)ErrorNumber.CannotOpenFormat; return (int)ErrorNumber.CannotOpenFormat;
} }
} }
catch(Exception ex) catch(Exception ex)
{ {
AaruConsole.ErrorWriteLine($"Error reading file: {ex.Message}"); AaruConsole.ErrorWriteLine(string.Format(UI.Error_reading_file_0, ex.Message));
AaruConsole.DebugWriteLine("Image-info command", ex.StackTrace); AaruConsole.DebugWriteLine("Image-info command", ex.StackTrace);
return (int)ErrorNumber.UnexpectedException; return (int)ErrorNumber.UnexpectedException;

View File

@@ -40,6 +40,7 @@ using Aaru.CommonTypes.Enums;
using Aaru.CommonTypes.Interfaces; using Aaru.CommonTypes.Interfaces;
using Aaru.Console; using Aaru.Console;
using Aaru.Core; using Aaru.Core;
using Aaru.Localization;
using JetBrains.Annotations; using JetBrains.Annotations;
using Spectre.Console; using Spectre.Console;
@@ -47,7 +48,7 @@ namespace Aaru.Commands.Image;
sealed class ListOptionsCommand : Command sealed class ListOptionsCommand : Command
{ {
public ListOptionsCommand() : base("options", "Lists all options supported by writable media images.") => public ListOptionsCommand() : base("options", UI.Image_Options_Command_Description) =>
Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke))); Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke)));
public static int Invoke(bool debug, bool verbose) public static int Invoke(bool debug, bool verbose)
@@ -85,7 +86,7 @@ sealed class ListOptionsCommand : Command
PluginBase plugins = GetPluginBase.Instance; PluginBase plugins = GetPluginBase.Instance;
AaruConsole.WriteLine("Read/Write media images options:"); AaruConsole.WriteLine(UI.Read_Write_media_images_options);
foreach(KeyValuePair<string, IBaseWritableImage> kvp in plugins.WritableImages) foreach(KeyValuePair<string, IBaseWritableImage> kvp in plugins.WritableImages)
{ {
@@ -97,13 +98,13 @@ sealed class ListOptionsCommand : Command
var table = new Table var table = new Table
{ {
Title = new TableTitle($"Options for {kvp.Value.Name}:") Title = new TableTitle(string.Format(UI.Options_for_0, kvp.Value.Name))
}; };
table.AddColumn("Name"); table.AddColumn(UI.Title_Name);
table.AddColumn("Type"); table.AddColumn(UI.Title_Type);
table.AddColumn("Default"); table.AddColumn(UI.Default);
table.AddColumn("Description"); table.AddColumn(UI.Title_Description);
foreach((string name, Type type, string description, object @default) option in foreach((string name, Type type, string description, object @default) option in
options.OrderBy(t => t.name)) options.OrderBy(t => t.name))
@@ -121,27 +122,27 @@ sealed class ListOptionsCommand : Command
static string TypeToString([NotNull] Type type) static string TypeToString([NotNull] Type type)
{ {
if(type == typeof(bool)) if(type == typeof(bool))
return "boolean"; return UI.TypeToString_boolean;
if(type == typeof(sbyte) || if(type == typeof(sbyte) ||
type == typeof(short) || type == typeof(short) ||
type == typeof(int) || type == typeof(int) ||
type == typeof(long)) type == typeof(long))
return "signed number"; return UI.TypeToString_signed_number;
if(type == typeof(byte) || if(type == typeof(byte) ||
type == typeof(ushort) || type == typeof(ushort) ||
type == typeof(uint) || type == typeof(uint) ||
type == typeof(ulong)) type == typeof(ulong))
return "number"; return UI.TypeToString_number;
if(type == typeof(float) || if(type == typeof(float) ||
type == typeof(double)) type == typeof(double))
return "float number"; return UI.TypeToString_float_number;
if(type == typeof(Guid)) if(type == typeof(Guid))
return "uuid"; return UI.TypeToString_uuid;
return type == typeof(string) ? "string" : type.ToString(); return type == typeof(string) ? UI.TypeToString_string : type.ToString();
} }
} }

View File

@@ -39,38 +39,39 @@ using Aaru.CommonTypes.Interfaces;
using Aaru.Console; using Aaru.Console;
using Aaru.Core; using Aaru.Core;
using Aaru.Helpers; using Aaru.Helpers;
using Aaru.Localization;
using Spectre.Console; using Spectre.Console;
namespace Aaru.Commands.Image; namespace Aaru.Commands.Image;
sealed class PrintHexCommand : Command sealed class PrintHexCommand : Command
{ {
public PrintHexCommand() : base("print", "Prints a sector, in hexadecimal values, to the console.") public PrintHexCommand() : base("print", UI.Image_Print_Command_Description)
{ {
Add(new Option<ulong>(new[] Add(new Option<ulong>(new[]
{ {
"--length", "-l" "--length", "-l"
}, () => 1, "How many sectors to print.")); }, () => 1, UI.How_many_sectors_to_print));
Add(new Option<bool>(new[] Add(new Option<bool>(new[]
{ {
"--long-sectors", "-r" "--long-sectors", "-r"
}, () => false, "Print sectors with tags included.")); }, () => false, UI.Print_sectors_with_tags_included));
Add(new Option<ulong>(new[] Add(new Option<ulong>(new[]
{ {
"--start", "-s" "--start", "-s"
}, "Starting sector.")); }, UI.Starting_sector));
Add(new Option<ushort>(new[] Add(new Option<ushort>(new[]
{ {
"--width", "-w" "--width", "-w"
}, () => 32, "How many bytes to print per line.")); }, () => 32, UI.How_many_bytes_to_print_per_line));
AddArgument(new Argument<string> AddArgument(new Argument<string>
{ {
Arity = ArgumentArity.ExactlyOne, Arity = ArgumentArity.ExactlyOne,
Description = "Media image path", Description = UI.Media_image_path,
Name = "image-path" Name = "image-path"
}); });
@@ -122,13 +123,13 @@ sealed class PrintHexCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Identifying file filter...").IsIndeterminate(); ctx.AddTask(UI.Identifying_file_filter).IsIndeterminate();
inputFilter = filtersList.GetFilter(imagePath); inputFilter = filtersList.GetFilter(imagePath);
}); });
if(inputFilter == null) if(inputFilter == null)
{ {
AaruConsole.ErrorWriteLine("Cannot open specified file."); AaruConsole.ErrorWriteLine(UI.Cannot_open_specified_file);
return (int)ErrorNumber.CannotOpenFile; return (int)ErrorNumber.CannotOpenFile;
} }
@@ -137,13 +138,13 @@ sealed class PrintHexCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Identifying image format...").IsIndeterminate(); ctx.AddTask(UI.Identifying_image_format).IsIndeterminate();
inputFormat = ImageFormat.Detect(inputFilter); inputFormat = ImageFormat.Detect(inputFilter);
}); });
if(inputFormat == null) if(inputFormat == null)
{ {
AaruConsole.ErrorWriteLine("Unable to recognize image format, not verifying"); AaruConsole.ErrorWriteLine(UI.Unable_to_recognize_image_format_not_printing);
return (int)ErrorNumber.UnrecognizedFormat; return (int)ErrorNumber.UnrecognizedFormat;
} }
@@ -152,14 +153,14 @@ sealed class PrintHexCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Opening image file...").IsIndeterminate(); ctx.AddTask(UI.Invoke_Opening_image_file).IsIndeterminate();
opened = inputFormat.Open(inputFilter); opened = inputFormat.Open(inputFilter);
}); });
if(opened != ErrorNumber.NoError) if(opened != ErrorNumber.NoError)
{ {
AaruConsole.WriteLine("Unable to open image format"); AaruConsole.WriteLine(UI.Unable_to_open_image_format);
AaruConsole.WriteLine("Error {0}", opened); AaruConsole.WriteLine(UI.Error_0, opened);
return (int)opened; return (int)opened;
} }
@@ -168,7 +169,7 @@ sealed class PrintHexCommand : Command
{ {
var byteAddressableImage = inputFormat as IByteAddressableImage; var byteAddressableImage = inputFormat as IByteAddressableImage;
AaruConsole.WriteLine("[bold][italic]Start {0}[/][/]", start); AaruConsole.WriteLine($"[bold][italic]{string.Format(UI.Start_0_as_in_sector_start, start)}[/][/]");
byte[] data = new byte[length]; byte[] data = new byte[length];
ErrorNumber errno = ErrorNumber.NoError; ErrorNumber errno = ErrorNumber.NoError;
@@ -176,7 +177,7 @@ sealed class PrintHexCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Reading data...").IsIndeterminate(); ctx.AddTask(UI.Reading_data).IsIndeterminate();
errno = byteAddressableImage?.ReadBytesAt((long)start, data, 0, (int)length, out bytesRead) ?? errno = byteAddressableImage?.ReadBytesAt((long)start, data, 0, (int)length, out bytesRead) ??
ErrorNumber.InvalidArgument; ErrorNumber.InvalidArgument;
@@ -193,24 +194,24 @@ sealed class PrintHexCommand : Command
if(errno == ErrorNumber.NoError) if(errno == ErrorNumber.NoError)
AaruConsole.WriteLine(Markup.Escape(PrintHex.ByteArrayToHexArrayString(data, width, true))); AaruConsole.WriteLine(Markup.Escape(PrintHex.ByteArrayToHexArrayString(data, width, true)));
else else
AaruConsole.ErrorWriteLine($"Error {errno} reading data from {start}."); AaruConsole.ErrorWriteLine(string.Format(UI.Error_0_reading_data_from_1, errno, start));
} }
else else
for(ulong i = 0; i < length; i++) for(ulong i = 0; i < length; i++)
{ {
if(inputFormat is not IMediaImage blockImage) if(inputFormat is not IMediaImage blockImage)
{ {
AaruConsole.ErrorWriteLine("Cannot open image file, aborting..."); AaruConsole.ErrorWriteLine(UI.Cannot_open_image_file_aborting);
break; break;
} }
AaruConsole.WriteLine("[bold][italic]Sector {0}[/][/]", start + i); AaruConsole.WriteLine($"[bold][italic]{string.Format(UI.Sector_0_as_in_sector_number, start)}[/][/]" +
i);
if(blockImage.Info.ReadableSectorTags == null) if(blockImage.Info.ReadableSectorTags == null)
{ {
AaruConsole. AaruConsole.WriteLine(UI.Requested_sectors_tags_unsupported_by_image_format_printing_user_data);
WriteLine("Requested sectors with tags, unsupported by underlying image format, printing only user data.");
longSectors = false; longSectors = false;
} }
@@ -218,8 +219,7 @@ sealed class PrintHexCommand : Command
{ {
if(blockImage.Info.ReadableSectorTags.Count == 0) if(blockImage.Info.ReadableSectorTags.Count == 0)
{ {
AaruConsole. AaruConsole.WriteLine(UI.Requested_sectors_tags_unsupported_by_image_format_printing_user_data);
WriteLine("Requested sectors with tags, unsupported by underlying image format, printing only user data.");
longSectors = false; longSectors = false;
} }
@@ -230,7 +230,7 @@ sealed class PrintHexCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Reading sector...").IsIndeterminate(); ctx.AddTask(UI.Reading_sector).IsIndeterminate();
errno = longSectors ? blockImage.ReadSectorLong(start + i, out sector) errno = longSectors ? blockImage.ReadSectorLong(start + i, out sector)
: blockImage.ReadSector(start + i, out sector); : blockImage.ReadSector(start + i, out sector);
@@ -239,7 +239,7 @@ sealed class PrintHexCommand : Command
if(errno == ErrorNumber.NoError) if(errno == ErrorNumber.NoError)
AaruConsole.WriteLine(Markup.Escape(PrintHex.ByteArrayToHexArrayString(sector, width, true))); AaruConsole.WriteLine(Markup.Escape(PrintHex.ByteArrayToHexArrayString(sector, width, true)));
else else
AaruConsole.ErrorWriteLine($"Error {errno} reading sector {start + i}."); AaruConsole.ErrorWriteLine(string.Format(UI.Error_0_reading_sector_1, errno, start + i));
} }
return (int)ErrorNumber.NoError; return (int)ErrorNumber.NoError;

View File

@@ -40,28 +40,29 @@ using Aaru.CommonTypes.Interfaces;
using Aaru.CommonTypes.Structs; using Aaru.CommonTypes.Structs;
using Aaru.Console; using Aaru.Console;
using Aaru.Core; using Aaru.Core;
using Aaru.Localization;
using Spectre.Console; using Spectre.Console;
namespace Aaru.Commands.Image; namespace Aaru.Commands.Image;
sealed class VerifyCommand : Command sealed class VerifyCommand : Command
{ {
public VerifyCommand() : base("verify", "Verifies a disc image integrity, and if supported, sector integrity.") public VerifyCommand() : base("verify", UI.Image_Verify_Command_Description)
{ {
Add(new Option<bool>(new[] Add(new Option<bool>(new[]
{ {
"--verify-disc", "-w" "--verify-disc", "-w"
}, () => true, "Verify disc image if supported.")); }, () => true, UI.Verify_disc_image_if_supported));
Add(new Option<bool>(new[] Add(new Option<bool>(new[]
{ {
"--verify-sectors", "-s" "--verify-sectors", "-s"
}, () => true, "Verify all sectors if supported.")); }, () => true, UI.Verify_all_sectors_if_supported));
AddArgument(new Argument<string> AddArgument(new Argument<string>
{ {
Arity = ArgumentArity.ExactlyOne, Arity = ArgumentArity.ExactlyOne,
Description = "Disc image path", Description = UI.Disc_image_path,
Name = "image-path" Name = "image-path"
}); });
@@ -111,13 +112,13 @@ sealed class VerifyCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Identifying file filter...").IsIndeterminate(); ctx.AddTask(UI.Identifying_file_filter).IsIndeterminate();
inputFilter = filtersList.GetFilter(imagePath); inputFilter = filtersList.GetFilter(imagePath);
}); });
if(inputFilter == null) if(inputFilter == null)
{ {
AaruConsole.ErrorWriteLine("Cannot open specified file."); AaruConsole.ErrorWriteLine(UI.Cannot_open_specified_file);
return (int)ErrorNumber.CannotOpenFile; return (int)ErrorNumber.CannotOpenFile;
} }
@@ -126,13 +127,13 @@ sealed class VerifyCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Identifying image format...").IsIndeterminate(); ctx.AddTask(UI.Identifying_image_format).IsIndeterminate();
inputFormat = ImageFormat.Detect(inputFilter); inputFormat = ImageFormat.Detect(inputFilter);
}); });
if(inputFormat == null) if(inputFormat == null)
{ {
AaruConsole.ErrorWriteLine("Unable to recognize image format, not verifying"); AaruConsole.ErrorWriteLine(UI.Unable_to_recognize_image_format_not_verifying);
return (int)ErrorNumber.FormatNotFound; return (int)ErrorNumber.FormatNotFound;
} }
@@ -141,14 +142,14 @@ sealed class VerifyCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Opening image file...").IsIndeterminate(); ctx.AddTask(UI.Invoke_Opening_image_file).IsIndeterminate();
opened = inputFormat.Open(inputFilter); opened = inputFormat.Open(inputFilter);
}); });
if(opened != ErrorNumber.NoError) if(opened != ErrorNumber.NoError)
{ {
AaruConsole.WriteLine("Unable to open image format"); AaruConsole.WriteLine(UI.Unable_to_open_image_format);
AaruConsole.WriteLine("Error {0}", opened); AaruConsole.WriteLine(UI.Error_0, opened);
return (int)opened; return (int)opened;
} }
@@ -158,9 +159,7 @@ sealed class VerifyCommand : Command
Statistics.AddFilter(inputFilter.Name); Statistics.AddFilter(inputFilter.Name);
bool? correctImage = null; bool? correctImage = null;
long errorSectors = 0;
bool? correctSectors = null; bool? correctSectors = null;
long unknownSectors = 0;
var verifiableImage = inputFormat as IVerifiableImage; var verifiableImage = inputFormat as IVerifiableImage;
var verifiableSectorsImage = inputFormat as IVerifiableSectorsImage; var verifiableSectorsImage = inputFormat as IVerifiableSectorsImage;
@@ -168,7 +167,7 @@ sealed class VerifyCommand : Command
if(verifiableImage is null && if(verifiableImage is null &&
verifiableSectorsImage is null) verifiableSectorsImage is null)
{ {
AaruConsole.ErrorWriteLine("The specified image does not support any kind of verification"); AaruConsole.ErrorWriteLine(UI.The_specified_image_does_not_support_any_kind_of_verification);
return (int)ErrorNumber.NotVerifiable; return (int)ErrorNumber.NotVerifiable;
} }
@@ -182,7 +181,7 @@ sealed class VerifyCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Verifying image checksums...").IsIndeterminate(); ctx.AddTask(UI.Verifying_image_checksums).IsIndeterminate();
DateTime startCheck = DateTime.UtcNow; DateTime startCheck = DateTime.UtcNow;
discCheckStatus = verifiableImage.VerifyMediaImage(); discCheckStatus = verifiableImage.VerifyMediaImage();
@@ -193,21 +192,21 @@ sealed class VerifyCommand : Command
switch(discCheckStatus) switch(discCheckStatus)
{ {
case true: case true:
AaruConsole.WriteLine("Disc image checksums are correct"); AaruConsole.WriteLine(UI.Disc_image_checksums_are_correct);
break; break;
case false: case false:
AaruConsole.WriteLine("Disc image checksums are incorrect"); AaruConsole.WriteLine(UI.Disc_image_checksums_are_incorrect);
break; break;
case null: case null:
AaruConsole.WriteLine("Disc image does not contain checksums"); AaruConsole.WriteLine(UI.Disc_image_does_not_contain_checksums);
break; break;
} }
correctImage = discCheckStatus; correctImage = discCheckStatus;
AaruConsole.VerboseWriteLine("Checking disc image checksums took {0} seconds", checkTime.TotalSeconds); AaruConsole.VerboseWriteLine(UI.Checking_disc_image_checksums_took_0_seconds, checkTime.TotalSeconds);
} }
if(!verifySectors) if(!verifySectors)
@@ -234,24 +233,26 @@ sealed class VerifyCommand : Command
Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()). Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()).
Start(ctx => Start(ctx =>
{ {
ProgressTask discTask = ctx.AddTask("Checking tracks..."); ProgressTask discTask = ctx.AddTask(UI.Checking_tracks);
discTask.MaxValue = inputTracks.Count; discTask.MaxValue = inputTracks.Count;
foreach(Track currentTrack in inputTracks) foreach(Track currentTrack in inputTracks)
{ {
discTask.Description = $"Checking track {discTask.Value + 1} of {inputTracks.Count}"; discTask.Description =
string.Format(UI.Checking_track_0_of_1, discTask.Value + 1, inputTracks.Count);
ulong remainingSectors = currentTrack.EndSector - currentTrack.StartSector + 1; ulong remainingSectors = currentTrack.EndSector - currentTrack.StartSector + 1;
ulong currentSector = 0; ulong currentSector = 0;
ProgressTask trackTask = ctx.AddTask("Checking sector"); ProgressTask trackTask = ctx.AddTask(UI.Checking_sector);
trackTask.MaxValue = remainingSectors; trackTask.MaxValue = remainingSectors;
while(remainingSectors > 0) while(remainingSectors > 0)
{ {
trackTask.Description = $"Checking sector {currentSectorAll} of { trackTask.Description =
inputFormat.Info.Sectors}, on track {currentTrack.Sequence}"; string.Format(UI.Checking_sector_0_of_1_on_track_2, currentSectorAll,
inputFormat.Info.Sectors, currentTrack.Sequence);
List<ulong> tempFailingLbas; List<ulong> tempFailingLbas;
List<ulong> tempUnknownLbas; List<ulong> tempUnknownLbas;
@@ -300,14 +301,15 @@ sealed class VerifyCommand : Command
Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()). Columns(new TaskDescriptionColumn(), new ProgressBarColumn(), new PercentageColumn()).
Start(ctx => Start(ctx =>
{ {
ProgressTask diskTask = ctx.AddTask("Checking sectors..."); ProgressTask diskTask = ctx.AddTask(UI.Checking_sectors);
diskTask.MaxValue = inputFormat.Info.Sectors; diskTask.MaxValue = inputFormat.Info.Sectors;
startCheck = DateTime.UtcNow; startCheck = DateTime.UtcNow;
while(remainingSectors > 0) while(remainingSectors > 0)
{ {
diskTask.Description = $"Checking sector {currentSector} of {inputFormat.Info.Sectors}"; diskTask.Description =
string.Format(UI.Checking_sector_0_of_1, currentSector, inputFormat.Info.Sectors);
List<ulong> tempFailingLbas; List<ulong> tempFailingLbas;
List<ulong> tempUnknownLbas; List<ulong> tempUnknownLbas;
@@ -344,40 +346,41 @@ sealed class VerifyCommand : Command
checkTime = endCheck - startCheck; checkTime = endCheck - startCheck;
if(unknownLbas.Count > 0) if(unknownLbas.Count > 0)
AaruConsole.WriteLine("There is at least one sector that does not contain a checksum"); AaruConsole.WriteLine(UI.There_is_at_least_one_sector_that_does_not_contain_a_checksum);
if(failingLbas.Count > 0) if(failingLbas.Count > 0)
AaruConsole.WriteLine("There is at least one sector with incorrect checksum or errors"); AaruConsole.WriteLine(UI.There_is_at_least_one_sector_with_incorrect_checksum_or_errors);
if(unknownLbas.Count == 0 && if(unknownLbas.Count == 0 &&
failingLbas.Count == 0) failingLbas.Count == 0)
AaruConsole.WriteLine("All sector checksums are correct"); AaruConsole.WriteLine(UI.All_sector_checksums_are_correct);
AaruConsole.VerboseWriteLine("Checking sector checksums took {0} seconds", checkTime.TotalSeconds); AaruConsole.VerboseWriteLine(UI.Checking_sector_checksums_took_0_seconds, checkTime.TotalSeconds);
if(verbose) if(verbose)
{ {
AaruConsole.VerboseWriteLine("[red]LBAs with error:[/]"); AaruConsole.VerboseWriteLine($"[red]{UI.LBAs_with_error}[/]");
if(failingLbas.Count == (int)inputFormat.Info.Sectors) if(failingLbas.Count == (int)inputFormat.Info.Sectors)
AaruConsole.VerboseWriteLine("\t[red]all sectors.[/]"); AaruConsole.VerboseWriteLine($"\t[red]{UI.all_sectors}[/]");
else else
foreach(ulong t in failingLbas) foreach(ulong t in failingLbas)
AaruConsole.VerboseWriteLine("\t{0}", t); AaruConsole.VerboseWriteLine("\t{0}", t);
AaruConsole.WriteLine("[yellow3_1]LBAs without checksum:[/]"); AaruConsole.WriteLine($"[yellow3_1]{UI.LBAs_without_checksum}[/]");
if(unknownLbas.Count == (int)inputFormat.Info.Sectors) if(unknownLbas.Count == (int)inputFormat.Info.Sectors)
AaruConsole.VerboseWriteLine("\t[yellow3_1]all sectors.[/]"); AaruConsole.VerboseWriteLine($"\t[yellow3_1]{UI.all_sectors}[/]");
else else
foreach(ulong t in unknownLbas) foreach(ulong t in unknownLbas)
AaruConsole.VerboseWriteLine("\t{0}", t); AaruConsole.VerboseWriteLine("\t{0}", t);
} }
AaruConsole.WriteLine("[italic]Total sectors...........[/] {0}", inputFormat.Info.Sectors); // TODO: Convert to table
AaruConsole.WriteLine("[italic]Total errors............[/] {0}", failingLbas.Count); AaruConsole.WriteLine($"[italic]{UI.Total_sectors}[/] {inputFormat.Info.Sectors}");
AaruConsole.WriteLine("[italic]Total unknowns..........[/] {0}", unknownLbas.Count); AaruConsole.WriteLine($"[italic]{UI.Total_errors}[/] {failingLbas.Count}");
AaruConsole.WriteLine("[italic]Total errors+unknowns...[/] {0}", failingLbas.Count + unknownLbas.Count); AaruConsole.WriteLine($"[italic]{UI.Total_unknowns}[/] {unknownLbas.Count}");
AaruConsole.WriteLine($"[italic]{UI.Total_errors_plus_unknowns}[/] {failingLbas.Count + unknownLbas.Count}");
if(failingLbas.Count > 0) if(failingLbas.Count > 0)
correctSectors = false; correctSectors = false;

View File

@@ -38,13 +38,14 @@ using System.Text;
using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Enums;
using Aaru.Console; using Aaru.Console;
using Aaru.Core; using Aaru.Core;
using Aaru.Localization;
using Spectre.Console; using Spectre.Console;
namespace Aaru.Commands; namespace Aaru.Commands;
sealed class ListEncodingsCommand : Command sealed class ListEncodingsCommand : Command
{ {
public ListEncodingsCommand() : base("list-encodings", "Lists all supported text encodings and code pages.") => public ListEncodingsCommand() : base("list-encodings", UI.List_Encodings_Command_Description) =>
Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke))); Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke)));
public static int Invoke(bool debug, bool verbose) public static int Invoke(bool debug, bool verbose)
@@ -94,8 +95,8 @@ sealed class ListEncodingsCommand : Command
})); }));
Table table = new(); Table table = new();
table.AddColumn("Name"); table.AddColumn(UI.Title_Name);
table.AddColumn("Description"); table.AddColumn(UI.Title_Description);
foreach(CommonEncodingInfo info in encodings.OrderBy(t => t.DisplayName)) foreach(CommonEncodingInfo info in encodings.OrderBy(t => t.DisplayName))
table.AddRow(info.Name, info.DisplayName); table.AddRow(info.Name, info.DisplayName);

View File

@@ -39,14 +39,14 @@ using Aaru.CommonTypes.Enums;
using Aaru.CommonTypes.Interfaces; using Aaru.CommonTypes.Interfaces;
using Aaru.Console; using Aaru.Console;
using Aaru.Core; using Aaru.Core;
using Aaru.Localization;
using Spectre.Console; using Spectre.Console;
namespace Aaru.Commands; namespace Aaru.Commands;
sealed class ListNamespacesCommand : Command sealed class ListNamespacesCommand : Command
{ {
public ListNamespacesCommand() : public ListNamespacesCommand() : base("list-namespaces", UI.List_Namespaces_Command_Description) =>
base("list-namespaces", "Lists all namespaces supported by read-only filesystems.") =>
Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke))); Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke)));
public static int Invoke(bool debug, bool verbose) public static int Invoke(bool debug, bool verbose)
@@ -89,11 +89,11 @@ sealed class ListNamespacesCommand : Command
{ {
Table table = new() Table table = new()
{ {
Title = new TableTitle($"Namespaces for {kvp.Value.Name}:") Title = new TableTitle(string.Format(UI.Namespaces_for_0, kvp.Value.Name))
}; };
table.AddColumn("Namespace"); table.AddColumn(UI.Title_Namespace);
table.AddColumn("Description"); table.AddColumn(UI.Title_Description);
foreach(KeyValuePair<string, string> @namespace in kvp.Value.Namespaces.OrderBy(t => t.Key)) foreach(KeyValuePair<string, string> @namespace in kvp.Value.Namespaces.OrderBy(t => t.Key))
table.AddRow(@namespace.Key, @namespace.Value); table.AddRow(@namespace.Key, @namespace.Value);

View File

@@ -35,6 +35,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.CommandLine; using System.CommandLine;
using System.CommandLine.NamingConventionBinder; using System.CommandLine.NamingConventionBinder;
using System.Globalization;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
@@ -50,6 +51,7 @@ using Aaru.Console;
using Aaru.Core; using Aaru.Core;
using Aaru.Core.Devices.Dumping; using Aaru.Core.Devices.Dumping;
using Aaru.Core.Logging; using Aaru.Core.Logging;
using Aaru.Localization;
using Schemas; using Schemas;
using Spectre.Console; using Spectre.Console;
@@ -61,149 +63,145 @@ sealed class DumpMediaCommand : Command
static ProgressTask _progressTask1; static ProgressTask _progressTask1;
static ProgressTask _progressTask2; static ProgressTask _progressTask2;
public DumpMediaCommand() : base("dump", "Dumps the media inserted on a device to a media image.") public DumpMediaCommand() : base("dump", UI.Media_Dump_Command_Description)
{ {
Add(new Option<string>(new[] Add(new Option<string>(new[]
{ {
"--cicm-xml", "-x" "--cicm-xml", "-x"
}, () => null, "Take metadata from existing CICM XML sidecar.")); }, () => null, UI.Take_metadata_from_existing_CICM_XML_sidecar));
Add(new Option<string>(new[] Add(new Option<string>(new[]
{ {
"--encoding", "-e" "--encoding", "-e"
}, () => null, "Name of character encoding to use.")); }, () => null, UI.Name_of_character_encoding_to_use));
Add(new Option<bool>("--first-pregap", () => false, Add(new Option<bool>("--first-pregap", () => false, UI.Try_to_read_first_track_pregap));
"Try to read first track pregap. Only applicable to CD/DDCD/GD."));
Add(new Option<bool>("--fix-offset", () => true, "Fix audio tracks offset. Only applicable to CD/GD.")); Add(new Option<bool>("--fix-offset", () => true, UI.Fix_audio_tracks_offset));
Add(new Option<bool>(new[] Add(new Option<bool>(new[]
{ {
"--force", "-f" "--force", "-f"
}, () => false, "Continue dump whatever happens.")); }, () => false, UI.Continue_dump_whatever_happens));
Add(new Option<string>(new[] Add(new Option<string>(new[]
{ {
"--format", "-t" "--format", "-t"
}, () => null, }, () => null, UI.Format_of_the_output_image_as_plugin_name_or_plugin_id));
"Format of the output image, as plugin name or plugin id. If not present, will try to detect it from output image extension."));
Add(new Option<bool>("--metadata", () => true, "Enables creating CICM XML sidecar.")); Add(new Option<bool>("--metadata", () => true, UI.Enables_creating_CICM_XML_sidecar));
Add(new Option<bool>("--trim", () => true, "Enables trimming errored from skipped sectors.")); Add(new Option<bool>("--trim", () => true, UI.Enables_trimming_errored_from_skipped_sectors));
Add(new Option<string>(new[] Add(new Option<string>(new[]
{ {
"--options", "-O" "--options", "-O"
}, () => null, "Comma separated name=value pairs of options to pass to output image plugin.")); }, () => null, UI.Comma_separated_name_value_pairs_of_image_options));
Add(new Option<bool>("--persistent", () => false, "Try to recover partial or incorrect data.")); Add(new Option<bool>("--persistent", () => false, UI.Try_to_recover_partial_or_incorrect_data));
Add(new Option<bool>(new[] Add(new Option<bool>(new[]
{ {
"--resume", "-r" "--resume", "-r"
}, () => true, "Create/use resume mapfile.")); }, () => true, UI.Create_or_use_resume_mapfile));
Add(new Option<ushort>(new[] Add(new Option<ushort>(new[]
{ {
"--retry-passes", "-p" "--retry-passes", "-p"
}, () => 5, "How many retry passes to do.")); }, () => 5, UI.How_many_retry_passes_to_do));
Add(new Option<uint>(new[] Add(new Option<uint>(new[]
{ {
"--skip", "-k" "--skip", "-k"
}, () => 512, "When an unreadable sector is found skip this many sectors.")); }, () => 512, UI.When_an_unreadable_sector_is_found_skip_this_many_sectors));
Add(new Option<bool>(new[] Add(new Option<bool>(new[]
{ {
"--stop-on-error", "-s" "--stop-on-error", "-s"
}, () => false, "Stop media dump on first error.")); }, () => false, UI.Stop_media_dump_on_first_error));
Add(new Option<string>("--subchannel", () => "any", Add(new Option<string>("--subchannel", () => UI.Subchannel_name_any, UI.Subchannel_to_dump_help));
"Subchannel to dump. Only applicable to CD/GD. Values: any, rw, rw-or-pq, pq, none."));
Add(new Option<byte>("--speed", () => 0, "Speed to dump. Only applicable to optical drives, 0 for maximum.")); Add(new Option<byte>("--speed", () => 0, UI.Speed_to_dump));
AddArgument(new Argument<string> AddArgument(new Argument<string>
{ {
Arity = ArgumentArity.ExactlyOne, Arity = ArgumentArity.ExactlyOne,
Description = "Device path", Description = UI.Device_path,
Name = "device-path" Name = "device-path"
}); });
AddArgument(new Argument<string> AddArgument(new Argument<string>
{ {
Arity = ArgumentArity.ExactlyOne, Arity = ArgumentArity.ExactlyOne,
Description = Description = UI.Output_image_path_Dump_help,
"Output image path. If filename starts with # and exists, it will be read as a list of output images, its extension will be used to detect the image output format, each media will be ejected and confirmation for the next one will be asked.", Name = "output-path"
Name = "output-path"
}); });
Add(new Option<bool>(new[] Add(new Option<bool>(new[]
{ {
"--private" "--private"
}, () => false, "Do not store paths and serial numbers in log or metadata.")); }, () => false, UI.Do_not_store_paths_and_serial_numbers_in_log_or_metadata));
Add(new Option<bool>(new[] Add(new Option<bool>(new[]
{ {
"--fix-subchannel-position" "--fix-subchannel-position"
}, () => true, "Store subchannel according to the sector they describe.")); }, () => true, UI.Fix_subchannel_position_help));
Add(new Option<bool>(new[] Add(new Option<bool>(new[]
{ {
"--retry-subchannel" "--retry-subchannel"
}, () => true, "Retry subchannel. Implies fixing subchannel position.")); }, () => true, UI.Retry_subchannel_help));
Add(new Option<bool>(new[] Add(new Option<bool>(new[]
{ {
"--fix-subchannel" "--fix-subchannel"
}, () => false, "Try to fix subchannel. Implies fixing subchannel position.")); }, () => false, UI.Fix_subchannel_help));
Add(new Option<bool>(new[] Add(new Option<bool>(new[]
{ {
"--fix-subchannel-crc" "--fix-subchannel-crc"
}, () => false, "If subchannel looks OK but CRC fails, rewrite it. Implies fixing subchannel.")); }, () => false, UI.Fix_subchannel_crc_help));
Add(new Option<bool>(new[] Add(new Option<bool>(new[]
{ {
"--generate-subchannels" "--generate-subchannels"
}, () => false, "Generates missing subchannels (they don't count as dumped in resume file).")); }, () => false, UI.Generate_subchannels_dump_help));
Add(new Option<bool>(new[] Add(new Option<bool>(new[]
{ {
"--skip-cdiready-hole" "--skip-cdiready-hole"
}, () => true, "Skip the hole between data and audio in a CD-i Ready disc.")); }, () => true, UI.Skip_CDi_Ready_hole_help));
Add(new Option<bool>(new[] Add(new Option<bool>(new[]
{ {
"--eject" "--eject"
}, () => false, "Eject media after dump finishes.")); }, () => false, UI.Eject_media_after_dump_finishes));
Add(new Option<uint>(new[] Add(new Option<uint>(new[]
{ {
"--max-blocks" "--max-blocks"
}, () => 64, "Maximum number of blocks to read at once.")); }, () => 64, UI.Maximum_number_of_blocks_to_read_at_once));
Add(new Option<bool>(new[] Add(new Option<bool>(new[]
{ {
"--use-buffered-reads" "--use-buffered-reads"
}, () => true, "For MMC/SD, use OS buffered reads if CMD23 is not supported.")); }, () => true, UI.OS_buffered_reads_help));
Add(new Option<bool>(new[] Add(new Option<bool>(new[]
{ {
"--store-encrypted" "--store-encrypted"
}, () => true, "Store encrypted data as is.")); }, () => true, UI.Store_encrypted_data_as_is));
Add(new Option<bool>(new[] Add(new Option<bool>(new[]
{ {
"--title-keys" "--title-keys"
}, () => true, "Try to read the title keys from CSS encrypted DVDs (very slow).")); }, () => true, UI.Try_to_read_the_title_keys_from_CSS_DVDs));
Add(new Option<uint>(new[] Add(new Option<uint>(new[]
{ {
"--ignore-cdr-runouts" "--ignore-cdr-runouts"
}, () => 10, "How many CD-R(W) run-out sectors to ignore and regenerate (0 for none).")); }, () => 10, UI.How_many_CDRW_run_out_sectors_to_ignore_and_regenerate));
Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke))); Handler = CommandHandler.Create(GetType().GetMethod(nameof(Invoke)));
} }
@@ -289,7 +287,7 @@ sealed class DumpMediaCommand : Command
//AaruConsole.DebugWriteLine("Dump-Media command", "--raw={0}", raw); //AaruConsole.DebugWriteLine("Dump-Media command", "--raw={0}", raw);
Dictionary<string, string> parsedOptions = Core.Options.Parse(options); Dictionary<string, string> parsedOptions = Core.Options.Parse(options);
AaruConsole.DebugWriteLine("Dump-Media command", "Parsed options:"); AaruConsole.DebugWriteLine("Dump-Media command", UI.Parsed_options);
foreach(KeyValuePair<string, string> parsedOption in parsedOptions) foreach(KeyValuePair<string, string> parsedOption in parsedOptions)
AaruConsole.DebugWriteLine("Dump-Media command", "{0} = {1}", parsedOption.Key, parsedOption.Value); AaruConsole.DebugWriteLine("Dump-Media command", "{0} = {1}", parsedOption.Key, parsedOption.Value);
@@ -302,45 +300,30 @@ sealed class DumpMediaCommand : Command
encodingClass = Claunia.Encoding.Encoding.GetEncoding(encoding); encodingClass = Claunia.Encoding.Encoding.GetEncoding(encoding);
if(verbose) if(verbose)
AaruConsole.VerboseWriteLine("Using encoding for {0}.", encodingClass.EncodingName); AaruConsole.VerboseWriteLine(UI.encoding_for_0, encodingClass.EncodingName);
} }
catch(ArgumentException) catch(ArgumentException)
{ {
AaruConsole.ErrorWriteLine("Specified encoding is not supported."); AaruConsole.ErrorWriteLine(UI.Specified_encoding_is_not_supported);
return (int)ErrorNumber.EncodingUnknown; return (int)ErrorNumber.EncodingUnknown;
} }
DumpSubchannel wantedSubchannel = DumpSubchannel.Any; DumpSubchannel wantedSubchannel = DumpSubchannel.Any;
switch(subchannel?.ToLowerInvariant()) if(subchannel?.ToLower(CultureInfo.CurrentUICulture) == UI.Subchannel_name_any ||
{ subchannel is null)
case "any": wantedSubchannel = DumpSubchannel.Any;
case null: else if(subchannel?.ToLowerInvariant() == UI.Subchannel_name_rw)
wantedSubchannel = DumpSubchannel.Any; wantedSubchannel = DumpSubchannel.Rw;
else if(subchannel?.ToLowerInvariant() == UI.Subchannel_name_rw_or_pq)
break; wantedSubchannel = DumpSubchannel.RwOrPq;
case "rw": else if(subchannel?.ToLowerInvariant() == UI.Subchannel_name_pq)
wantedSubchannel = DumpSubchannel.Rw; wantedSubchannel = DumpSubchannel.Pq;
else if(subchannel?.ToLowerInvariant() == UI.Subchannel_name_none)
break; wantedSubchannel = DumpSubchannel.None;
case "rw-or-pq": else
wantedSubchannel = DumpSubchannel.RwOrPq; AaruConsole.WriteLine(UI.Incorrect_subchannel_type_0_requested, subchannel);
break;
case "pq":
wantedSubchannel = DumpSubchannel.Pq;
break;
case "none":
wantedSubchannel = DumpSubchannel.None;
break;
default:
AaruConsole.WriteLine("Incorrect subchannel type \"{0}\" requested.", subchannel);
break;
}
string filename = Path.GetFileNameWithoutExtension(outputPath); string filename = Path.GetFileNameWithoutExtension(outputPath);
@@ -380,11 +363,11 @@ sealed class DumpMediaCommand : Command
switch(candidates.Count) switch(candidates.Count)
{ {
case 0: case 0:
AaruConsole.WriteLine("No plugin supports requested extension."); AaruConsole.WriteLine(UI.No_plugin_supports_requested_extension);
return (int)ErrorNumber.FormatNotFound; return (int)ErrorNumber.FormatNotFound;
case > 1: case > 1:
AaruConsole.WriteLine("More than one plugin supports requested extension."); AaruConsole.WriteLine(UI.More_than_one_plugin_supports_requested_extension);
return (int)ErrorNumber.TooManyFormats; return (int)ErrorNumber.TooManyFormats;
} }
@@ -398,15 +381,14 @@ sealed class DumpMediaCommand : Command
if(responseLine.Any(c => c < 0x20)) if(responseLine.Any(c => c < 0x20))
{ {
AaruConsole.ErrorWriteLine("Invalid characters found in list of files, exiting..."); AaruConsole.ErrorWriteLine(UI.Invalid_characters_found_in_list_of_files);
return (int)ErrorNumber.InvalidArgument; return (int)ErrorNumber.InvalidArgument;
} }
if(isResponse) if(isResponse)
{ {
AaruConsole.WriteLine("Please insert media with title {0} and press any key to continue...", AaruConsole.WriteLine(UI.Please_insert_media_with_title_0_and_press_any_key_to_continue_, responseLine);
responseLine);
System.Console.ReadKey(); System.Console.ReadKey();
Thread.Sleep(1000); Thread.Sleep(1000);
@@ -431,7 +413,7 @@ sealed class DumpMediaCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Opening device...").IsIndeterminate(); ctx.AddTask(UI.Opening_device).IsIndeterminate();
dev = Devices.Device.Create(devicePath, out devErrno); dev = Devices.Device.Create(devicePath, out devErrno);
}); });
@@ -439,7 +421,7 @@ sealed class DumpMediaCommand : Command
{ {
case null: case null:
{ {
AaruConsole.ErrorWriteLine($"Could not open device, error {devErrno}."); AaruConsole.ErrorWriteLine(string.Format(UI.Could_not_open_device_error_0, devErrno));
if(isResponse) if(isResponse)
continue; continue;
@@ -480,7 +462,7 @@ sealed class DumpMediaCommand : Command
} }
catch catch
{ {
AaruConsole.ErrorWriteLine("Incorrect resume file, not continuing..."); AaruConsole.ErrorWriteLine(UI.Incorrect_resume_file_not_continuing);
if(isResponse) if(isResponse)
continue; continue;
@@ -495,7 +477,7 @@ sealed class DumpMediaCommand : Command
(resumeClass.BadSubchannels is null || resumeClass.BadSubchannels.Count == 0) && (resumeClass.BadSubchannels is null || resumeClass.BadSubchannels.Count == 0) &&
(resumeClass.MissingTitleKeys is null || resumeClass.MissingTitleKeys.Count == 0)) (resumeClass.MissingTitleKeys is null || resumeClass.MissingTitleKeys.Count == 0))
{ {
AaruConsole.WriteLine("Media already dumped correctly, not continuing..."); AaruConsole.WriteLine(UI.Media_already_dumped_correctly_not_continuing);
if(isResponse) if(isResponse)
continue; continue;
@@ -516,7 +498,7 @@ sealed class DumpMediaCommand : Command
} }
catch catch
{ {
AaruConsole.ErrorWriteLine("Incorrect metadata sidecar file, not continuing..."); AaruConsole.ErrorWriteLine(UI.Incorrect_metadata_sidecar_file);
if(isResponse) if(isResponse)
continue; continue;
@@ -525,7 +507,7 @@ sealed class DumpMediaCommand : Command
} }
else else
{ {
AaruConsole.ErrorWriteLine("Could not find metadata sidecar, not continuing..."); AaruConsole.ErrorWriteLine(UI.Could_not_find_metadata_sidecar);
if(isResponse) if(isResponse)
continue; continue;
@@ -558,13 +540,13 @@ sealed class DumpMediaCommand : Command
if(verbose) if(verbose)
{ {
dumpLog.WriteLine("Output image format: {0} ({1}).", outputFormat.Name, outputFormat.Id); dumpLog.WriteLine(UI.Output_image_format_0_1, outputFormat.Name, outputFormat.Id);
AaruConsole.VerboseWriteLine("Output image format: {0} ({1}).", outputFormat.Name, outputFormat.Id); AaruConsole.VerboseWriteLine(UI.Output_image_format_0_1, outputFormat.Name, outputFormat.Id);
} }
else else
{ {
dumpLog.WriteLine("Output image format: {0}.", outputFormat.Name); dumpLog.WriteLine(UI.Output_image_format_0, outputFormat.Name);
AaruConsole.WriteLine("Output image format: {0}.", outputFormat.Name); AaruConsole.WriteLine(UI.Output_image_format_0, outputFormat.Name);
} }
var errorLog = new ErrorLog(outputPrefix + ".error.log"); var errorLog = new ErrorLog(outputPrefix + ".error.log");
@@ -657,7 +639,7 @@ sealed class DumpMediaCommand : Command
if(eject && dev.IsRemovable) if(eject && dev.IsRemovable)
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Ejecting media...").IsIndeterminate(); ctx.AddTask(UI.Ejecting_media).IsIndeterminate();
switch(dev.Type) switch(dev.Type)
{ {

View File

@@ -50,6 +50,7 @@ using Aaru.Decoders.DVD;
using Aaru.Decoders.SCSI.MMC; using Aaru.Decoders.SCSI.MMC;
using Aaru.Decoders.SCSI.SSC; using Aaru.Decoders.SCSI.SSC;
using Aaru.Decoders.Xbox; using Aaru.Decoders.Xbox;
using Aaru.Localization;
using Spectre.Console; using Spectre.Console;
using BCA = Aaru.Decoders.Bluray.BCA; using BCA = Aaru.Decoders.Bluray.BCA;
using Cartridge = Aaru.Decoders.DVD.Cartridge; using Cartridge = Aaru.Decoders.DVD.Cartridge;
@@ -63,17 +64,17 @@ namespace Aaru.Commands.Media;
sealed class MediaInfoCommand : Command sealed class MediaInfoCommand : Command
{ {
public MediaInfoCommand() : base("info", "Gets information about the media inserted on a device.") public MediaInfoCommand() : base("info", UI.Media_Info_Command_Description)
{ {
Add(new Option<string>(new[] Add(new Option<string>(new[]
{ {
"--output-prefix", "-w" "--output-prefix", "-w"
}, () => null, "Write binary responses from device with that prefix.")); }, () => null, UI.Prefix_for_saving_binary_information));
AddArgument(new Argument<string> AddArgument(new Argument<string>
{ {
Arity = ArgumentArity.ExactlyOne, Arity = ArgumentArity.ExactlyOne,
Description = "Device path", Description = UI.Device_path,
Name = "device-path" Name = "device-path"
}); });
@@ -127,14 +128,14 @@ sealed class MediaInfoCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Opening device...").IsIndeterminate(); ctx.AddTask(UI.Opening_device).IsIndeterminate();
dev = Devices.Device.Create(devicePath, out devErrno); dev = Devices.Device.Create(devicePath, out devErrno);
}); });
switch(dev) switch(dev)
{ {
case null: case null:
AaruConsole.ErrorWriteLine($"Could not open device, error {devErrno}."); AaruConsole.ErrorWriteLine(string.Format(UI.Could_not_open_device_error_0, devErrno));
return (int)devErrno; return (int)devErrno;
case Devices.Remote.Device remoteDev: case Devices.Remote.Device remoteDev:
@@ -174,18 +175,18 @@ sealed class MediaInfoCommand : Command
DoScsiMediaInfo(debug, outputPrefix, dev); DoScsiMediaInfo(debug, outputPrefix, dev);
break; break;
default: throw new NotSupportedException("Unknown device type."); default: throw new NotSupportedException(Localization.Core.Unknown_device_type);
} }
return (int)ErrorNumber.NoError; return (int)ErrorNumber.NoError;
} }
static void DoAtaMediaInfo() => AaruConsole.ErrorWriteLine("Please use device-info command for ATA devices."); static void DoAtaMediaInfo() => AaruConsole.ErrorWriteLine(UI.Please_use_device_info_command_for_ATA_devices);
static void DoNvmeMediaInfo(string outputPrefix, Devices.Device dev) => static void DoNvmeMediaInfo(string outputPrefix, Devices.Device dev) =>
throw new NotImplementedException("NVMe devices not yet supported."); throw new NotImplementedException(Localization.Core.NVMe_devices_not_yet_supported);
static void DoSdMediaInfo() => AaruConsole.ErrorWriteLine("Please use device-info command for MMC/SD devices."); static void DoSdMediaInfo() => AaruConsole.ErrorWriteLine(UI.Please_use_device_info_command_for_MMC_SD_devices);
static void DoScsiMediaInfo(bool debug, string outputPrefix, Devices.Device dev) static void DoScsiMediaInfo(bool debug, string outputPrefix, Devices.Device dev)
{ {
@@ -193,7 +194,7 @@ sealed class MediaInfoCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Retrieving SCSI information...").IsIndeterminate(); ctx.AddTask(UI.Retrieving_SCSI_information).IsIndeterminate();
scsiInfo = new ScsiInfo(dev); scsiInfo = new ScsiInfo(dev);
}); });
@@ -234,28 +235,33 @@ sealed class MediaInfoCommand : Command
switch(totalSize) switch(totalSize)
{ {
case > 1099511627776: case > 1099511627776:
AaruConsole.WriteLine("Media has {0} blocks of {1} bytes/each. (for a total of {2:F3} TiB)", AaruConsole.
scsiInfo.Blocks, scsiInfo.BlockSize, totalSize / 1099511627776d); WriteLine(Localization.Core.Media_has_0_blocks_of_1_bytes_each_for_a_total_of_2_TiB,
scsiInfo.Blocks, scsiInfo.BlockSize, totalSize / 1099511627776d);
break; break;
case > 1073741824: case > 1073741824:
AaruConsole.WriteLine("Media has {0} blocks of {1} bytes/each. (for a total of {2:F3} GiB)", AaruConsole.
scsiInfo.Blocks, scsiInfo.BlockSize, totalSize / 1073741824d); WriteLine(Localization.Core.Media_has_0_blocks_of_1_bytes_each_for_a_total_of_2_GiB,
scsiInfo.Blocks, scsiInfo.BlockSize, totalSize / 1073741824d);
break; break;
case > 1048576: case > 1048576:
AaruConsole.WriteLine("Media has {0} blocks of {1} bytes/each. (for a total of {2:F3} MiB)", AaruConsole.
scsiInfo.Blocks, scsiInfo.BlockSize, totalSize / 1048576d); WriteLine(Localization.Core.Media_has_0_blocks_of_1_bytes_each_for_a_total_of_2_MiB,
scsiInfo.Blocks, scsiInfo.BlockSize, totalSize / 1048576d);
break; break;
case > 1024: case > 1024:
AaruConsole.WriteLine("Media has {0} blocks of {1} bytes/each. (for a total of {2:F3} KiB)", AaruConsole.
scsiInfo.Blocks, scsiInfo.BlockSize, totalSize / 1024d); WriteLine(Localization.Core.Media_has_0_blocks_of_1_bytes_each_for_a_total_of_2_KiB,
scsiInfo.Blocks, scsiInfo.BlockSize, totalSize / 1024d);
break; break;
default: default:
AaruConsole.WriteLine("Media has {0} blocks of {1} bytes/each. (for a total of {2} bytes)", AaruConsole.
scsiInfo.Blocks, scsiInfo.BlockSize, totalSize); WriteLine(Localization.Core.Media_has_0_blocks_of_1_bytes_each_for_a_total_of_2_bytes,
scsiInfo.Blocks, scsiInfo.BlockSize, totalSize);
break; break;
} }
@@ -270,7 +276,7 @@ sealed class MediaInfoCommand : Command
if(scsiInfo.DensitySupportHeader.HasValue) if(scsiInfo.DensitySupportHeader.HasValue)
{ {
AaruConsole.WriteLine("[bold]Densities supported by currently inserted media:[/]"); AaruConsole.WriteLine($"[bold]{UI.Densities_supported_by_currently_inserted_media}:[/]");
AaruConsole.WriteLine(DensitySupport.PrettifyDensity(scsiInfo.DensitySupportHeader)); AaruConsole.WriteLine(DensitySupport.PrettifyDensity(scsiInfo.DensitySupportHeader));
} }
} }
@@ -282,7 +288,7 @@ sealed class MediaInfoCommand : Command
if(scsiInfo.MediaTypeSupportHeader.HasValue) if(scsiInfo.MediaTypeSupportHeader.HasValue)
{ {
AaruConsole.WriteLine("[bold]Medium types currently inserted in device:[/]"); AaruConsole.WriteLine($"[bold]{UI.Medium_types_currently_inserted_in_device}:[/]");
AaruConsole.WriteLine(DensitySupport.PrettifyMediumType(scsiInfo.MediaTypeSupportHeader)); AaruConsole.WriteLine(DensitySupport.PrettifyMediumType(scsiInfo.MediaTypeSupportHeader));
} }
@@ -321,10 +327,11 @@ sealed class MediaInfoCommand : Command
"SCSI READ DISC STRUCTURE", scsiInfo.DvdDmi); "SCSI READ DISC STRUCTURE", scsiInfo.DvdDmi);
if(DMI.IsXbox(scsiInfo.DvdDmi)) if(DMI.IsXbox(scsiInfo.DvdDmi))
AaruConsole.WriteLine("[bold]Xbox DMI:[/]\n{0}", Markup.Escape(DMI.PrettifyXbox(scsiInfo.DvdDmi))); AaruConsole.WriteLine($"[bold]{Localization.Core.Xbox_DMI}:[/]",
$"\n{Markup.Escape(DMI.PrettifyXbox(scsiInfo.DvdDmi))}");
else if(DMI.IsXbox360(scsiInfo.DvdDmi)) else if(DMI.IsXbox360(scsiInfo.DvdDmi))
AaruConsole.WriteLine("[bold]Xbox 360 DMI:[/]\n{0}", AaruConsole.WriteLine($"[bold]{Localization.Core.Xbox_360_DMI}:[/]",
Markup.Escape(DMI.PrettifyXbox360(scsiInfo.DvdDmi))); $"\n{Markup.Escape(DMI.PrettifyXbox360(scsiInfo.DvdDmi))}");
} }
if(scsiInfo.DvdCmi != null) if(scsiInfo.DvdCmi != null)
@@ -332,8 +339,8 @@ sealed class MediaInfoCommand : Command
DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_dvd_cmi.bin", DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_dvd_cmi.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.DvdCmi); "SCSI READ DISC STRUCTURE", scsiInfo.DvdCmi);
AaruConsole.WriteLine("[bold]Lead-In CMI:[/]\n{0}", AaruConsole.WriteLine($"[bold]{Localization.Core.Lead_In_CMI}:[/]",
Markup.Escape(CSS_CPRM.PrettifyLeadInCopyright(scsiInfo.DvdCmi))); $"\n{Markup.Escape(CSS_CPRM.PrettifyLeadInCopyright(scsiInfo.DvdCmi))}");
} }
if(scsiInfo.DvdDiscKey != null) if(scsiInfo.DvdDiscKey != null)
@@ -357,8 +364,8 @@ sealed class MediaInfoCommand : Command
DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_dvdram_dds.bin", DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_dvdram_dds.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.DvdRamDds); "SCSI READ DISC STRUCTURE", scsiInfo.DvdRamDds);
AaruConsole.WriteLine("[bold]Disc Definition Structure:[/]\n{0}", AaruConsole.WriteLine($"[bold]{Localization.Core.Disc_Definition_Structure}:[/]",
Markup.Escape(DDS.Prettify(scsiInfo.DvdRamDds))); $"\n{Markup.Escape(DDS.Prettify(scsiInfo.DvdRamDds))}");
} }
if(scsiInfo.DvdRamCartridgeStatus != null) if(scsiInfo.DvdRamCartridgeStatus != null)
@@ -366,8 +373,8 @@ sealed class MediaInfoCommand : Command
DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_dvdram_status.bin", DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_dvdram_status.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.DvdRamCartridgeStatus); "SCSI READ DISC STRUCTURE", scsiInfo.DvdRamCartridgeStatus);
AaruConsole.WriteLine("[bold]Medium Status:[/]\n{0}", AaruConsole.WriteLine($"[bold]{Localization.Core.Medium_Status}:[/]",
Markup.Escape(Cartridge.Prettify(scsiInfo.DvdRamCartridgeStatus))); $"\n{Markup.Escape(Cartridge.Prettify(scsiInfo.DvdRamCartridgeStatus))}");
} }
if(scsiInfo.DvdRamSpareArea != null) if(scsiInfo.DvdRamSpareArea != null)
@@ -375,8 +382,8 @@ sealed class MediaInfoCommand : Command
DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_dvdram_spare.bin", DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_dvdram_spare.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.DvdRamSpareArea); "SCSI READ DISC STRUCTURE", scsiInfo.DvdRamSpareArea);
AaruConsole.WriteLine("[bold]Spare Area Information:[/]\n{0}", AaruConsole.WriteLine($"[bold]{Localization.Core.Spare_Area_Information}:[/]",
Markup.Escape(Spare.Prettify(scsiInfo.DvdRamSpareArea))); $"\n{Markup.Escape(Spare.Prettify(scsiInfo.DvdRamSpareArea))}");
} }
if(scsiInfo.LastBorderOutRmd != null) if(scsiInfo.LastBorderOutRmd != null)
@@ -389,8 +396,8 @@ sealed class MediaInfoCommand : Command
"SCSI READ DISC STRUCTURE", scsiInfo.DvdPreRecordedInfo); "SCSI READ DISC STRUCTURE", scsiInfo.DvdPreRecordedInfo);
if(scsiInfo.DecodedDvdPrePitInformation.HasValue) if(scsiInfo.DecodedDvdPrePitInformation.HasValue)
AaruConsole.WriteLine("[bold]DVD-R(W) Pre-Recorded Information:[/]\n{0}", AaruConsole.WriteLine($"[bold]{Localization.Core.DVD_RW_Pre_Recorded_Information}:[/]",
Markup.Escape(PRI.Prettify(scsiInfo.DecodedDvdPrePitInformation))); $"\n{Markup.Escape(PRI.Prettify(scsiInfo.DecodedDvdPrePitInformation))}");
} }
if(scsiInfo.DvdrMediaIdentifier != null) if(scsiInfo.DvdrMediaIdentifier != null)
@@ -403,8 +410,8 @@ sealed class MediaInfoCommand : Command
"SCSI READ DISC STRUCTURE", scsiInfo.DvdrPhysicalInformation); "SCSI READ DISC STRUCTURE", scsiInfo.DvdrPhysicalInformation);
if(scsiInfo.DecodedDvdrPfi.HasValue) if(scsiInfo.DecodedDvdrPfi.HasValue)
AaruConsole.WriteLine("[bold]DVD-R(W) PFI:[/]\n{0}", AaruConsole.WriteLine($"[bold]{Localization.Core.DVD_RW_PFI}:[/]",
Markup.Escape(PFI.Prettify(scsiInfo.DecodedDvdrPfi))); $"\n{Markup.Escape(PFI.Prettify(scsiInfo.DecodedDvdrPfi))}");
} }
if(scsiInfo.DvdPlusAdip != null) if(scsiInfo.DvdPlusAdip != null)
@@ -452,8 +459,8 @@ sealed class MediaInfoCommand : Command
DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_bd_di.bin", DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_bd_di.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.BlurayDiscInformation); "SCSI READ DISC STRUCTURE", scsiInfo.BlurayDiscInformation);
AaruConsole.WriteLine("[bold]Blu-ray Disc Information:[/]\n{0}", AaruConsole.WriteLine($"[bold]{Localization.Core.Bluray_Disc_Information}:[/]",
Markup.Escape(DI.Prettify(scsiInfo.BlurayDiscInformation))); $"\n{Markup.Escape(DI.Prettify(scsiInfo.BlurayDiscInformation))}");
} }
if(scsiInfo.BlurayPac != null) if(scsiInfo.BlurayPac != null)
@@ -465,8 +472,8 @@ sealed class MediaInfoCommand : Command
DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_bd_bca.bin", DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_bd_bca.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.BlurayBurstCuttingArea); "SCSI READ DISC STRUCTURE", scsiInfo.BlurayBurstCuttingArea);
AaruConsole.WriteLine("[bold]Blu-ray Burst Cutting Area:[/]\n{0}", AaruConsole.WriteLine($"[bold]{Localization.Core.Bluray_Burst_Cutting_Area}:[/]",
Markup.Escape(BCA.Prettify(scsiInfo.BlurayBurstCuttingArea))); $"\n{Markup.Escape(BCA.Prettify(scsiInfo.BlurayBurstCuttingArea))}");
} }
if(scsiInfo.BlurayDds != null) if(scsiInfo.BlurayDds != null)
@@ -474,8 +481,8 @@ sealed class MediaInfoCommand : Command
DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_bd_dds.bin", DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_bd_dds.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.BlurayDds); "SCSI READ DISC STRUCTURE", scsiInfo.BlurayDds);
AaruConsole.WriteLine("[bold]Blu-ray Disc Definition Structure:[/]\n{0}", AaruConsole.WriteLine($"[bold]{Localization.Core.Bluray_Disc_Definition_Structure}:[/]",
Markup.Escape(Decoders.Bluray.DDS.Prettify(scsiInfo.BlurayDds))); $"\n{Markup.Escape(Decoders.Bluray.DDS.Prettify(scsiInfo.BlurayDds))}");
} }
if(scsiInfo.BlurayCartridgeStatus != null) if(scsiInfo.BlurayCartridgeStatus != null)
@@ -483,9 +490,9 @@ sealed class MediaInfoCommand : Command
DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_bd_cartstatus.bin", DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_bd_cartstatus.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.BlurayCartridgeStatus); "SCSI READ DISC STRUCTURE", scsiInfo.BlurayCartridgeStatus);
AaruConsole.WriteLine("[bold]Blu-ray Cartridge Status:[/]\n{0}", AaruConsole.WriteLine($"[bold]{Localization.Core.Bluray_Cartridge_Status}:[/]",
Markup.Escape(Decoders.Bluray.Cartridge. $"\n{Markup.Escape(Decoders.Bluray.Cartridge.Prettify(scsiInfo.
Prettify(scsiInfo.BlurayCartridgeStatus))); BlurayCartridgeStatus))}");
} }
if(scsiInfo.BluraySpareAreaInformation != null) if(scsiInfo.BluraySpareAreaInformation != null)
@@ -493,9 +500,9 @@ sealed class MediaInfoCommand : Command
DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_bd_spare.bin", DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscstructure_bd_spare.bin",
"SCSI READ DISC STRUCTURE", scsiInfo.BluraySpareAreaInformation); "SCSI READ DISC STRUCTURE", scsiInfo.BluraySpareAreaInformation);
AaruConsole.WriteLine("[bold]Blu-ray Spare Area Information:[/]\n{0}", AaruConsole.WriteLine($"[bold]{Localization.Core.Bluray_Spare_Area_Information}:[/]",
Markup.Escape(Decoders.Bluray.Spare. $"\n{Markup.Escape(Decoders.Bluray.Spare.Prettify(scsiInfo.
Prettify(scsiInfo.BluraySpareAreaInformation))); BluraySpareAreaInformation))}");
} }
if(scsiInfo.BlurayRawDfl != null) if(scsiInfo.BlurayRawDfl != null)
@@ -504,8 +511,8 @@ sealed class MediaInfoCommand : Command
if(scsiInfo.BlurayTrackResources != null) if(scsiInfo.BlurayTrackResources != null)
{ {
AaruConsole.WriteLine("[bold]Track Resources Information:[/]\n{0}", AaruConsole.WriteLine($"[bold]{Localization.Core.Track_Resources_Information}:[/]",
Markup.Escape(DiscInformation.Prettify(scsiInfo.BlurayTrackResources))); $"\n{Markup.Escape(DiscInformation.Prettify(scsiInfo.BlurayTrackResources))}");
DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscinformation_001b.bin", DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscinformation_001b.bin",
"SCSI READ DISC INFORMATION", scsiInfo.BlurayTrackResources); "SCSI READ DISC INFORMATION", scsiInfo.BlurayTrackResources);
@@ -513,8 +520,8 @@ sealed class MediaInfoCommand : Command
if(scsiInfo.BlurayPowResources != null) if(scsiInfo.BlurayPowResources != null)
{ {
AaruConsole.WriteLine("[bold]POW Resources Information:[/]\n{0}", AaruConsole.WriteLine($"[bold]{Localization.Core.POW_Resources_Information}:[/]",
Markup.Escape(DiscInformation.Prettify(scsiInfo.BlurayPowResources))); $"\n{Markup.Escape(DiscInformation.Prettify(scsiInfo.BlurayPowResources))}");
DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscinformation_010b.bin", DataFile.WriteTo("Media-Info command", outputPrefix, "_readdiscinformation_010b.bin",
"SCSI READ DISC INFORMATION", scsiInfo.BlurayPowResources); "SCSI READ DISC INFORMATION", scsiInfo.BlurayPowResources);
@@ -526,7 +533,8 @@ sealed class MediaInfoCommand : Command
scsiInfo.Toc); scsiInfo.Toc);
if(scsiInfo.DecodedToc.HasValue) if(scsiInfo.DecodedToc.HasValue)
AaruConsole.WriteLine("[bold]TOC:[/]\n{0}", Markup.Escape(TOC.Prettify(scsiInfo.DecodedToc))); AaruConsole.WriteLine($"[bold]{Localization.Core.TOC}:[/]",
$"\n{Markup.Escape(TOC.Prettify(scsiInfo.DecodedToc))}");
} }
if(scsiInfo.Atip != null) if(scsiInfo.Atip != null)
@@ -535,7 +543,8 @@ sealed class MediaInfoCommand : Command
scsiInfo.Atip); scsiInfo.Atip);
if(scsiInfo.DecodedAtip != null) if(scsiInfo.DecodedAtip != null)
AaruConsole.WriteLine("[bold]ATIP:[/]\n{0}", Markup.Escape(ATIP.Prettify(scsiInfo.DecodedAtip))); AaruConsole.WriteLine($"[bold]{Localization.Core.ATIP}:[/]",
$"\n{Markup.Escape(ATIP.Prettify(scsiInfo.DecodedAtip))}");
} }
if(scsiInfo.DiscInformation != null) if(scsiInfo.DiscInformation != null)
@@ -544,8 +553,9 @@ sealed class MediaInfoCommand : Command
"SCSI READ DISC INFORMATION", scsiInfo.DiscInformation); "SCSI READ DISC INFORMATION", scsiInfo.DiscInformation);
if(scsiInfo.DecodedDiscInformation.HasValue) if(scsiInfo.DecodedDiscInformation.HasValue)
AaruConsole.WriteLine("[bold]Standard Disc Information:[/]\n{0}", AaruConsole.WriteLine($"[bold]{Localization.Core.Standard_Disc_Information}:[/]",
Markup.Escape(DiscInformation.Prettify000b(scsiInfo.DecodedDiscInformation))); $"\n{Markup.Escape(DiscInformation.Prettify000b(scsiInfo.
DecodedDiscInformation))}");
} }
if(scsiInfo.Session != null) if(scsiInfo.Session != null)
@@ -554,8 +564,8 @@ sealed class MediaInfoCommand : Command
scsiInfo.Session); scsiInfo.Session);
if(scsiInfo.DecodedSession.HasValue) if(scsiInfo.DecodedSession.HasValue)
AaruConsole.WriteLine("[bold]Session information:[/]\n{0}", AaruConsole.WriteLine($"[bold]{Localization.Core.Session_information}:[/]",
Markup.Escape(Session.Prettify(scsiInfo.DecodedSession))); $"\n{Markup.Escape(Session.Prettify(scsiInfo.DecodedSession))}");
} }
if(scsiInfo.RawToc != null) if(scsiInfo.RawToc != null)
@@ -564,7 +574,8 @@ sealed class MediaInfoCommand : Command
scsiInfo.RawToc); scsiInfo.RawToc);
if(scsiInfo.FullToc.HasValue) if(scsiInfo.FullToc.HasValue)
AaruConsole.WriteLine("[bold]Raw TOC:[/]\n{0}", Markup.Escape(FullTOC.Prettify(scsiInfo.RawToc))); AaruConsole.WriteLine($"[bold]{Localization.Core.Raw_TOC}:[/]",
$"\n{Markup.Escape(FullTOC.Prettify(scsiInfo.RawToc))}");
} }
if(scsiInfo.Pma != null) if(scsiInfo.Pma != null)
@@ -572,7 +583,8 @@ sealed class MediaInfoCommand : Command
DataFile.WriteTo("Media-Info command", outputPrefix, "_pma.bin", "SCSI READ TOC/PMA/ATIP", DataFile.WriteTo("Media-Info command", outputPrefix, "_pma.bin", "SCSI READ TOC/PMA/ATIP",
scsiInfo.Pma); scsiInfo.Pma);
AaruConsole.WriteLine("[bold]PMA:\n[/]{0}", Markup.Escape(PMA.Prettify(scsiInfo.Pma))); AaruConsole.WriteLine($"[bold]{Localization.Core.PMA}:[/]",
$"\n[/]{Markup.Escape(PMA.Prettify(scsiInfo.Pma))}");
} }
if(scsiInfo.CdTextLeadIn != null) if(scsiInfo.CdTextLeadIn != null)
@@ -581,33 +593,45 @@ sealed class MediaInfoCommand : Command
scsiInfo.CdTextLeadIn); scsiInfo.CdTextLeadIn);
if(scsiInfo.DecodedCdTextLeadIn.HasValue) if(scsiInfo.DecodedCdTextLeadIn.HasValue)
AaruConsole.WriteLine("[bold]CD-TEXT on Lead-In:[/]\n{0}", AaruConsole.WriteLine($"[bold]{Localization.Core.CD_TEXT_on_Lead_In}:[/]",
Markup.Escape(CDTextOnLeadIn.Prettify(scsiInfo.DecodedCdTextLeadIn))); $"\n{Markup.Escape(CDTextOnLeadIn.Prettify(scsiInfo.DecodedCdTextLeadIn))}");
} }
if(!string.IsNullOrEmpty(scsiInfo.Mcn)) if(!string.IsNullOrEmpty(scsiInfo.Mcn))
AaruConsole.WriteLine("[bold]MCN:[/] {0}", Markup.Escape(scsiInfo.Mcn)); AaruConsole.WriteLine($"[bold]{Localization.Core.MCN}:[/]", $" {Markup.Escape(scsiInfo.Mcn)}");
if(scsiInfo.Isrcs != null) if(scsiInfo.Isrcs != null)
foreach(KeyValuePair<byte, string> isrc in scsiInfo.Isrcs) foreach(KeyValuePair<byte, string> isrc in scsiInfo.Isrcs)
AaruConsole.WriteLine("[bold]Track's {0} ISRC:[/] {1}", isrc.Key, Markup.Escape(isrc.Value)); AaruConsole.WriteLine($"[bold]{string.Format(Localization.Core.Tracks_0_ISRC, isrc.Key)}:[/] {
Markup.Escape(isrc.Value)}");
if(scsiInfo.XboxSecuritySector != null) if(scsiInfo.XboxSecuritySector != null)
DataFile.WriteTo("Media-Info command", outputPrefix, "_xbox_ss.bin", "KREON EXTRACT SS", DataFile.WriteTo("Media-Info command", outputPrefix, "_xbox_ss.bin", "KREON EXTRACT SS",
scsiInfo.XboxSecuritySector); scsiInfo.XboxSecuritySector);
if(scsiInfo.DecodedXboxSecuritySector.HasValue) if(scsiInfo.DecodedXboxSecuritySector.HasValue)
AaruConsole.WriteLine("[bold]Xbox Security Sector:[/]\n{0}", AaruConsole.WriteLine($"[bold]{Localization.Core.Xbox_Security_Sector}:[/]",
Markup.Escape(SS.Prettify(scsiInfo.DecodedXboxSecuritySector))); $"\n{Markup.Escape(SS.Prettify(scsiInfo.DecodedXboxSecuritySector))}");
if(scsiInfo.XgdInfo != null) if(scsiInfo.XgdInfo != null)
{ {
AaruConsole.WriteLine("[bold]Video layer 0 size:[/] {0} sectors", scsiInfo.XgdInfo.L0Video); AaruConsole.WriteLine($"[bold]{Localization.Core.Video_layer_zero_size}:[/] {scsiInfo.XgdInfo.L0Video
AaruConsole.WriteLine("[bold]Video layer 1 size:[/] {0} sectors", scsiInfo.XgdInfo.L1Video); } sectors");
AaruConsole.WriteLine("[bold]Middle zone size:[/] {0} sectors", scsiInfo.XgdInfo.MiddleZone);
AaruConsole.WriteLine("[bold]Game data size:[/] {0} sectors", scsiInfo.XgdInfo.GameSize); AaruConsole.WriteLine($"[bold]{Localization.Core.Video_layer_one_size}:[/] {scsiInfo.XgdInfo.L1Video
AaruConsole.WriteLine("[bold]Total size:[/] {0} sectors", scsiInfo.XgdInfo.TotalSize); } sectors");
AaruConsole.WriteLine("[bold]Real layer break:[/] {0}", scsiInfo.XgdInfo.LayerBreak);
AaruConsole.WriteLine($"[bold]{Localization.Core.Middle_zone_size}:[/] {scsiInfo.XgdInfo.MiddleZone
} sectors");
AaruConsole.WriteLine($"[bold]{Localization.Core.Game_data_size}:[/] {scsiInfo.XgdInfo.GameSize
} sectors");
AaruConsole.WriteLine($"[bold]{Localization.Core.Total_size}:[/] {scsiInfo.XgdInfo.TotalSize} sectors");
AaruConsole.WriteLine($"[bold]{Localization.Core.Real_layer_break}:[/] {scsiInfo.XgdInfo.LayerBreak
} sectors");
AaruConsole.WriteLine(); AaruConsole.WriteLine();
} }
} }
@@ -617,7 +641,7 @@ sealed class MediaInfoCommand : Command
DataFile.WriteTo("Media-Info command", outputPrefix, "_mediaserialnumber.bin", DataFile.WriteTo("Media-Info command", outputPrefix, "_mediaserialnumber.bin",
"SCSI READ MEDIA SERIAL NUMBER", scsiInfo.MediaSerialNumber); "SCSI READ MEDIA SERIAL NUMBER", scsiInfo.MediaSerialNumber);
AaruConsole.Write("[bold]Media Serial Number:[/] "); AaruConsole.Write($"[bold]{Localization.Core.Media_Serial_Number}:[/] ");
for(int i = 4; i < scsiInfo.MediaSerialNumber.Length; i++) for(int i = 4; i < scsiInfo.MediaSerialNumber.Length; i++)
AaruConsole.Write("{0:X2}", scsiInfo.MediaSerialNumber[i]); AaruConsole.Write("{0:X2}", scsiInfo.MediaSerialNumber[i]);
@@ -625,7 +649,7 @@ sealed class MediaInfoCommand : Command
AaruConsole.WriteLine(); AaruConsole.WriteLine();
} }
AaruConsole.WriteLine("[bold]Media identified as [italic]{0}[/][/]", scsiInfo.MediaType); AaruConsole.WriteLine($"[bold]{Localization.Core.Media_identified_as} [italic]{scsiInfo.MediaType}[/][/]");
Statistics.AddMedia(scsiInfo.MediaType, true); Statistics.AddMedia(scsiInfo.MediaType, true);
if(scsiInfo.Toc != null || if(scsiInfo.Toc != null ||
@@ -658,22 +682,22 @@ sealed class MediaInfoCommand : Command
tracks[^1].EndSector = (ulong)lastSector; tracks[^1].EndSector = (ulong)lastSector;
AaruConsole.WriteLine(); AaruConsole.WriteLine();
AaruConsole.WriteLine("[bold]Track calculations:[/]"); AaruConsole.WriteLine($"[bold]{Localization.Core.Track_calculations}:[/]");
if(inexactPositioning) if(inexactPositioning)
AaruConsole. AaruConsole.WriteLine($"[yellow]{UI.
WriteLine("[yellow]WARNING: The drive has returned incorrect Q positioning when calculating pregaps. A best effort has been tried but they may be incorrect.[/]"); The_drive_has_returned_incorrect_Q_positioning_calculating_pregaps}[/]");
if(firstLba > 0) if(firstLba > 0)
AaruConsole.WriteLine("Hidden track starts at LBA {0}, ends at LBA {1}", 0, firstLba - 1); AaruConsole.WriteLine(UI.Hidden_track_starts_at_LBA_0_ends_at_LBA_1, 0, firstLba - 1);
foreach(Track track in tracks) foreach(Track track in tracks)
AaruConsole. AaruConsole.
WriteLine("Track {0} starts at LBA {1}, ends at LBA {2}, has a pregap of {3} sectors and is of type {4}", WriteLine(UI.Track_0_starts_at_LBA_1_ends_at_LBA_2_has_a_pregap_of_3_sectors_and_is_of_type_4,
track.Sequence, track.StartSector, track.EndSector, track.Pregap, track.Type); track.Sequence, track.StartSector, track.EndSector, track.Pregap, track.Type);
AaruConsole.WriteLine(); AaruConsole.WriteLine();
AaruConsole.WriteLine("[bold]Offsets:[/]"); AaruConsole.WriteLine($"[bold]{Localization.Core.Offsets}:[/]");
// Search for read offset in main database // Search for read offset in main database
CdOffset cdOffset = CdOffset cdOffset =
@@ -688,15 +712,17 @@ sealed class MediaInfoCommand : Command
{ {
if(driveOffset is null) if(driveOffset is null)
{ {
AaruConsole.WriteLine("[red]Drive reading offset not found in database.[/]"); AaruConsole.WriteLine($"[red]{Localization.Core.Drive_reading_offset_not_found_in_database
AaruConsole.WriteLine("[red]Disc offset cannot be calculated.[/]"); }[/]");
AaruConsole.WriteLine($"[red]{Localization.Core.Disc_offset_cannot_be_calculated}[/]");
} }
else else
{ {
AaruConsole.WriteLine($"Drive reading offset is {driveOffset} bytes ({driveOffset / 4 AaruConsole.WriteLine(string.Format(Localization.Core.Drive_reading_offset_is_0_bytes_1_samples,
} samples)."); driveOffset, driveOffset / 4));
AaruConsole.WriteLine("[red]Disc write offset is unknown.[/]"); AaruConsole.WriteLine($"[red]{Localization.Core.Disc_write_offset_is_unknown}[/]");
} }
} }
else else
@@ -705,21 +731,26 @@ sealed class MediaInfoCommand : Command
if(driveOffset is null) if(driveOffset is null)
{ {
AaruConsole.WriteLine("[red]Drive reading offset not found in database.[/]"); AaruConsole.WriteLine($"[red]{Localization.Core.Drive_reading_offset_not_found_in_database
}[/]");
AaruConsole.WriteLine($"Combined disc and drive offset are {offsetBytes} bytes ({offsetBytes / 4 AaruConsole.
} samples)."); WriteLine(string.
Format(Localization.Core.Combined_disc_and_drive_offset_are_0_bytes_1_samples,
offsetBytes, offsetBytes / 4));
} }
else else
{ {
AaruConsole.WriteLine($"Drive reading offset is {driveOffset} bytes ({driveOffset / 4 AaruConsole.WriteLine(string.Format(Localization.Core.Drive_reading_offset_is_0_bytes_1_samples,
} samples)."); driveOffset, driveOffset / 4));
AaruConsole.WriteLine($"Combined offset is {offsetBytes} bytes ({offsetBytes / 4} samples)."); AaruConsole.WriteLine(string.Format(Localization.Core.Combined_offset_is_0_bytes_1_samples,
offsetBytes, offsetBytes / 4));
int? discOffset = offsetBytes - driveOffset; int? discOffset = offsetBytes - driveOffset;
AaruConsole.WriteLine($"Disc offset is {discOffset} bytes ({discOffset / 4} samples)."); AaruConsole.WriteLine(string.Format(Localization.Core.Disc_offset_is_0_bytes_1_samples,
discOffset, discOffset / 4));
} }
} }
} }

View File

@@ -31,12 +31,13 @@
// ****************************************************************************/ // ****************************************************************************/
using System.CommandLine; using System.CommandLine;
using Aaru.Localization;
namespace Aaru.Commands.Media; namespace Aaru.Commands.Media;
sealed class MediaFamily : Command sealed class MediaFamily : Command
{ {
public MediaFamily() : base("media", "Commands to manage media inserted in devices") public MediaFamily() : base("media", UI.Media_Command_Family_Description)
{ {
AddAlias("m"); AddAlias("m");

View File

@@ -36,6 +36,7 @@ using Aaru.CommonTypes.Enums;
using Aaru.Console; using Aaru.Console;
using Aaru.Core; using Aaru.Core;
using Aaru.Core.Devices.Scanning; using Aaru.Core.Devices.Scanning;
using Aaru.Localization;
using Spectre.Console; using Spectre.Console;
namespace Aaru.Commands.Media; namespace Aaru.Commands.Media;
@@ -44,27 +45,27 @@ sealed class MediaScanCommand : Command
{ {
static ProgressTask _progressTask1; static ProgressTask _progressTask1;
public MediaScanCommand() : base("scan", "Scans the media inserted on a device.") public MediaScanCommand() : base("scan", UI.Media_Scan_Command_Description)
{ {
Add(new Option<string>(new[] Add(new Option<string>(new[]
{ {
"--mhdd-log", "-m" "--mhdd-log", "-m"
}, () => null, "Write a log of the scan in the format used by MHDD.")); }, () => null, UI.Write_a_log_of_the_scan_in_the_format_used_by_MHDD));
Add(new Option<string>(new[] Add(new Option<string>(new[]
{ {
"--ibg-log", "-b" "--ibg-log", "-b"
}, () => null, "Write a log of the scan in the format used by ImgBurn.")); }, () => null, UI.Write_a_log_of_the_scan_in_the_format_used_by_ImgBurn));
Add(new Option<bool>(new[] Add(new Option<bool>(new[]
{ {
"--use-buffered-reads" "--use-buffered-reads"
}, () => true, "For MMC/SD, use OS buffered reads if CMD23 is not supported.")); }, () => true, UI.OS_buffered_reads_help));
AddArgument(new Argument<string> AddArgument(new Argument<string>
{ {
Arity = ArgumentArity.ExactlyOne, Arity = ArgumentArity.ExactlyOne,
Description = "Device path", Description = UI.Device_path,
Name = "device-path" Name = "device-path"
}); });
@@ -121,14 +122,14 @@ sealed class MediaScanCommand : Command
Core.Spectre.ProgressSingleSpinner(ctx => Core.Spectre.ProgressSingleSpinner(ctx =>
{ {
ctx.AddTask("Opening device...").IsIndeterminate(); ctx.AddTask(UI.Opening_device).IsIndeterminate();
dev = Devices.Device.Create(devicePath, out devErrno); dev = Devices.Device.Create(devicePath, out devErrno);
}); });
switch(dev) switch(dev)
{ {
case null: case null:
AaruConsole.ErrorWriteLine($"Could not open device, error {devErrno}."); AaruConsole.ErrorWriteLine(string.Format(UI.Could_not_open_device_error_0, devErrno));
return (int)devErrno; return (int)devErrno;
case Devices.Remote.Device remoteDev: case Devices.Remote.Device remoteDev:
@@ -203,25 +204,37 @@ sealed class MediaScanCommand : Command
results = scanner.Scan(); results = scanner.Scan();
}); });
AaruConsole.WriteLine("Took a total of {0} seconds ({1} processing commands).", results.TotalTime, AaruConsole.WriteLine(Localization.Core.Took_a_total_of_0_seconds_1_processing_commands, results.TotalTime,
results.ProcessingTime); results.ProcessingTime);
AaruConsole.WriteLine("Average speed: {0:F3} MiB/sec.", results.AvgSpeed); AaruConsole.WriteLine(Localization.Core.Average_speed_0_MiB_sec, results.AvgSpeed);
AaruConsole.WriteLine("Fastest speed burst: {0:F3} MiB/sec.", results.MaxSpeed); AaruConsole.WriteLine(Localization.Core.Fastest_speed_burst_0_MiB_sec, results.MaxSpeed);
AaruConsole.WriteLine("Slowest speed burst: {0:F3} MiB/sec.", results.MinSpeed); AaruConsole.WriteLine(Localization.Core.Slowest_speed_burst_0_MiB_sec, results.MinSpeed);
AaruConsole.WriteLine(); AaruConsole.WriteLine();
AaruConsole.WriteLine("[bold]Summary:[/]"); AaruConsole.WriteLine($"[bold]{Localization.Core.Summary}:[/]");
AaruConsole.WriteLine("[lime]{0} sectors took less than 3 ms.[/]", results.A); AaruConsole.WriteLine($"[lime]{string.Format(Localization.Core._0_sectors_took_less_than_3_ms, results.A)}[/]");
AaruConsole.WriteLine("[green]{0} sectors took less than 10 ms but more than 3 ms.[/]", results.B);
AaruConsole.WriteLine("[darkorange]{0} sectors took less than 50 ms but more than 10 ms.[/]", results.C); AaruConsole.WriteLine($"[green]{
AaruConsole.WriteLine("[olive]{0} sectors took less than 150 ms but more than 50 ms.[/]", results.D); string.Format(Localization.Core._0_sectors_took_less_than_10_ms_but_more_than_3_ms, results.B)}[/]");
AaruConsole.WriteLine("[orange3]{0} sectors took less than 500 ms but more than 150 ms.[/]", results.E);
AaruConsole.WriteLine("[red]{0} sectors took more than 500 ms.[/]", results.F); AaruConsole.WriteLine($"[darkorange]{
AaruConsole.WriteLine("[maroon]{0} sectors could not be read.[/]", results.UnreadableSectors.Count); string.Format(Localization.Core._0_sectors_took_less_than_50_ms_but_more_than_10_ms, results.C)}[/]");
AaruConsole.WriteLine($"[olive]{
string.Format(Localization.Core._0_sectors_took_less_than_150_ms_but_more_than_50_ms, results.D)}[/]");
AaruConsole.WriteLine($"[orange3]{
string.Format(Localization.Core._0_sectors_took_less_than_500_ms_but_more_than_150_ms, results.E)}[/]");
AaruConsole.WriteLine($"[red]{string.Format(Localization.Core._0_sectors_took_more_than_500_ms, results.F)
}[/]");
AaruConsole.WriteLine($"[maroon]{string.Format(Localization.Core._0_sectors_could_not_be_read,
results.UnreadableSectors.Count)}[/]");
if(results.UnreadableSectors.Count > 0) if(results.UnreadableSectors.Count > 0)
foreach(ulong bad in results.UnreadableSectors) foreach(ulong bad in results.UnreadableSectors)
AaruConsole.WriteLine("Sector {0} could not be read", bad); AaruConsole.WriteLine(Localization.Core.Sector_0_could_not_be_read, bad);
AaruConsole.WriteLine(); AaruConsole.WriteLine();
@@ -230,7 +243,7 @@ sealed class MediaScanCommand : Command
results.SeekMax > double.MinValue) results.SeekMax > double.MinValue)
AaruConsole. AaruConsole.
WriteLine("Testing {0} seeks, longest seek took {1:F3} ms, fastest one took {2:F3} ms. ({3:F3} ms average)", WriteLine(Localization.Core.Testing_0_seeks_longest_seek_took_1_ms_fastest_one_took_2_ms_3_ms_average,
results.SeekTimes, results.SeekMax, results.SeekMin, results.SeekTotal / 1000); results.SeekTimes, results.SeekMax, results.SeekMin, results.SeekTotal / 1000);
dev.Close(); dev.Close();

View File

@@ -38,6 +38,7 @@ using System.CommandLine.NamingConventionBinder;
using Aaru.CommonTypes.Enums; using Aaru.CommonTypes.Enums;
using Aaru.Console; using Aaru.Console;
using Aaru.Core; using Aaru.Core;
using Aaru.Localization;
using Spectre.Console; using Spectre.Console;
using Remote = Aaru.Devices.Remote.Remote; using Remote = Aaru.Devices.Remote.Remote;
@@ -45,7 +46,7 @@ namespace Aaru.Commands;
sealed class RemoteCommand : Command sealed class RemoteCommand : Command
{ {
public RemoteCommand() : base("remote", "Tests connection to a Aaru Remote Server.") public RemoteCommand() : base("remote", UI.Remote_Command_Description)
{ {
AddArgument(new Argument<string> AddArgument(new Argument<string>
{ {

View File

@@ -48,6 +48,7 @@ using Aaru.CommonTypes.Enums;
using Aaru.Console; using Aaru.Console;
using Aaru.Core; using Aaru.Core;
using Aaru.Database; using Aaru.Database;
using Aaru.Localization;
using Aaru.Settings; using Aaru.Settings;
using JetBrains.Annotations; using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
@@ -171,7 +172,7 @@ class MainClass
if(mainContext.Database.GetPendingMigrations().Any()) if(mainContext.Database.GetPendingMigrations().Any())
{ {
AaruConsole.WriteLine("New database version, updating..."); AaruConsole.WriteLine(UI.New_database_version_updating);
try try
{ {
@@ -179,8 +180,8 @@ class MainClass
} }
catch(Exception) catch(Exception)
{ {
AaruConsole.ErrorWriteLine("Exception trying to remove old database version, cannot continue..."); AaruConsole.ErrorWriteLine(UI.Exception_trying_to_remove_old_database_version);
AaruConsole.ErrorWriteLine("Please manually remove file at {0}", Settings.Settings.MainDbPath); AaruConsole.ErrorWriteLine(UI.Please_manually_remove_file_at_0, Settings.Settings.MainDbPath);
return (int)ErrorNumber.CannotRemoveDatabase; return (int)ErrorNumber.CannotRemoveDatabase;
} }
@@ -205,17 +206,17 @@ class MainClass
rootCommand.AddGlobalOption(new Option<bool>(new[] rootCommand.AddGlobalOption(new Option<bool>(new[]
{ {
"--verbose", "-v" "--verbose", "-v"
}, () => false, "Shows verbose output.")); }, () => false, UI.Shows_verbose_output));
rootCommand.AddGlobalOption(new Option<bool>(new[] rootCommand.AddGlobalOption(new Option<bool>(new[]
{ {
"--debug", "-d" "--debug", "-d"
}, () => false, "Shows debug output from plugins.")); }, () => false, UI.Shows_debug_output_from_plugins));
Option<bool> pauseOption = new(new[] Option<bool> pauseOption = new(new[]
{ {
"--pause" "--pause"
}, () => false, "Pauses before exiting."); }, () => false, UI.Pauses_before_exiting);
rootCommand.AddGlobalOption(pauseOption); rootCommand.AddGlobalOption(pauseOption);
@@ -241,7 +242,7 @@ class MainClass
if(!rootCommand.Parse(args).RootCommandResult.GetValueForOption(pauseOption)) if(!rootCommand.Parse(args).RootCommandResult.GetValueForOption(pauseOption))
return ret; return ret;
AaruConsole.WriteLine("Press any key to exit."); AaruConsole.WriteLine(UI.Press_any_key_to_exit);
System.Console.ReadKey(); System.Console.ReadKey();
return ret; return ret;