mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
[TUI] Get image information.
This commit is contained in:
@@ -19,6 +19,8 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Aaru.CommonTypes\Aaru.CommonTypes.csproj"/>
|
||||
<ProjectReference Include="..\Aaru.Core\Aaru.Core.csproj"/>
|
||||
<ProjectReference Include="..\Aaru.Helpers\Aaru.Helpers.csproj"/>
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -9,4 +9,5 @@ public class FileModel
|
||||
public IBrush ForegroundBrush { get; set; }
|
||||
public bool IsDirectory { get; set; }
|
||||
public FileInfo? FileInfo { get; set; }
|
||||
public string? Information { get; set; }
|
||||
}
|
||||
@@ -1,18 +1,19 @@
|
||||
using Aaru.Core;
|
||||
using Avalonia;
|
||||
using Consolonia;
|
||||
|
||||
namespace Aaru.Tui
|
||||
{
|
||||
public static class Program
|
||||
{
|
||||
public static int Main(string[] args)
|
||||
{
|
||||
return BuildAvaloniaApp().StartWithConsoleLifetime(args);
|
||||
}
|
||||
namespace Aaru.Tui;
|
||||
|
||||
public static AppBuilder BuildAvaloniaApp()
|
||||
{
|
||||
return AppBuilder.Configure<App>().UseConsolonia().UseAutoDetectedConsole().LogToException();
|
||||
}
|
||||
public static class Program
|
||||
{
|
||||
public static int Main(string[] args)
|
||||
{
|
||||
// There are too many places that depend on this being inited to be sure all are covered, so init it here.
|
||||
PluginBase.Init();
|
||||
|
||||
return BuildAvaloniaApp().StartWithConsoleLifetime(args);
|
||||
}
|
||||
|
||||
public static AppBuilder BuildAvaloniaApp() =>
|
||||
AppBuilder.Configure<App>().UseConsolonia().UseAutoDetectedConsole().LogToException();
|
||||
}
|
||||
@@ -1,6 +1,11 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Windows.Input;
|
||||
using Aaru.CommonTypes;
|
||||
using Aaru.CommonTypes.Enums;
|
||||
using Aaru.CommonTypes.Interfaces;
|
||||
using Aaru.Core;
|
||||
using Aaru.Helpers;
|
||||
using Aaru.Tui.Models;
|
||||
using Avalonia;
|
||||
@@ -8,6 +13,8 @@ using Avalonia.Controls.ApplicationLifetimes;
|
||||
using Avalonia.Media;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using Humanizer;
|
||||
using Humanizer.Bytes;
|
||||
using Color = Avalonia.Media.Color;
|
||||
|
||||
namespace Aaru.Tui.ViewModels.Windows;
|
||||
@@ -51,6 +58,8 @@ public sealed partial class MainWindowViewModel : ViewModelBase
|
||||
OnPropertyChanged(nameof(SelectedFileLastWriteTime));
|
||||
OnPropertyChanged(nameof(SelectedFileAttributes));
|
||||
OnPropertyChanged(nameof(SelectedFileUnixMode));
|
||||
OnPropertyChanged(nameof(SelectedFileHasInformation));
|
||||
OnPropertyChanged(nameof(SelectedFileInformation));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,6 +72,9 @@ public sealed partial class MainWindowViewModel : ViewModelBase
|
||||
public DateTime? SelectedFileLastWriteTime => SelectedFile?.FileInfo?.LastWriteTime;
|
||||
public string? SelectedFileAttributes => SelectedFile?.FileInfo?.Attributes.ToString();
|
||||
public string? SelectedFileUnixMode => SelectedFile?.FileInfo?.UnixFileMode.ToString();
|
||||
public bool SelectedFileHasInformation => SelectedFile?.Information != null;
|
||||
|
||||
public string? SelectedFileInformation => SelectedFile?.Information;
|
||||
|
||||
void Exit()
|
||||
{
|
||||
@@ -129,7 +141,125 @@ public sealed partial class MainWindowViewModel : ViewModelBase
|
||||
|
||||
void Worker()
|
||||
{
|
||||
foreach(FileModel file in Files) file.FileInfo = new FileInfo(file.Path);
|
||||
foreach(FileModel file in Files)
|
||||
{
|
||||
try
|
||||
{
|
||||
file.FileInfo = new FileInfo(file.Path);
|
||||
|
||||
IFilter inputFilter = PluginRegister.Singleton.GetFilter(file.Path);
|
||||
|
||||
if(inputFilter is null) continue;
|
||||
|
||||
IBaseImage imageFormat = ImageFormat.Detect(inputFilter);
|
||||
|
||||
if(imageFormat is null) continue;
|
||||
|
||||
StringBuilder sb = new();
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(imageFormat.Info.Version))
|
||||
sb.AppendLine($"Format: {imageFormat.Format} version {imageFormat.Info.Version}");
|
||||
else
|
||||
sb.AppendLine($"Format: {imageFormat.Format}");
|
||||
|
||||
switch(string.IsNullOrWhiteSpace(imageFormat.Info.Application))
|
||||
{
|
||||
case false when !string.IsNullOrWhiteSpace(imageFormat.Info.ApplicationVersion):
|
||||
sb.AppendLine($"Was created with {imageFormat.Info.Application} version {imageFormat.Info.ApplicationVersion}");
|
||||
|
||||
break;
|
||||
case false:
|
||||
sb.AppendLine($"Was created with {imageFormat.Info.Application}");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
sb.AppendLine($"Image without headers is {imageFormat.Info.ImageSize} bytes long");
|
||||
|
||||
sb.AppendLine($"Contains a media of {imageFormat.Info.Sectors} sectors with a maximum sector size of {imageFormat.Info.SectorSize} bytes (if all sectors are of the same size this would be [aqua]{ByteSize.FromBytes(imageFormat.Info.Sectors * imageFormat.Info.SectorSize).Humanize()})");
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(imageFormat.Info.Creator))
|
||||
sb.AppendLine($"Created by: {imageFormat.Info.Creator}");
|
||||
|
||||
if(imageFormat.Info.CreationTime != DateTime.MinValue)
|
||||
sb.AppendLine($"Created on {imageFormat.Info.CreationTime}");
|
||||
|
||||
if(imageFormat.Info.LastModificationTime != DateTime.MinValue)
|
||||
sb.AppendLine($"Last modified on {imageFormat.Info.LastModificationTime}");
|
||||
|
||||
sb.AppendLine($"Contains a media of type {imageFormat.Info.MediaType} and XML type {imageFormat.Info.MetadataMediaType}");
|
||||
|
||||
sb.AppendLine(imageFormat.Info.HasPartitions ? "Has partitions" : "Doesn\'t have partitions");
|
||||
|
||||
sb.AppendLine(imageFormat.Info.HasSessions ? "Has sessions" : "Doesn\'t have sessions");
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(imageFormat.Info.Comments))
|
||||
sb.AppendLine($"Comments: {imageFormat.Info.Comments}");
|
||||
|
||||
if(imageFormat.Info.MediaSequence != 0 && imageFormat.Info.LastMediaSequence != 0)
|
||||
sb.AppendLine($"Media is number {imageFormat.Info.MediaSequence} on a set of {imageFormat.Info.LastMediaSequence} medias");
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaTitle))
|
||||
sb.AppendLine($"Media title: {imageFormat.Info.MediaTitle}");
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaManufacturer))
|
||||
sb.AppendLine($"Media manufacturer: {imageFormat.Info.MediaManufacturer}");
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaModel))
|
||||
sb.AppendLine($"Media model: {imageFormat.Info.MediaModel}");
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaSerialNumber))
|
||||
sb.AppendLine($"Media serial number: {imageFormat.Info.MediaSerialNumber}");
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaBarcode))
|
||||
sb.AppendLine($"Media barcode: {imageFormat.Info.MediaBarcode}");
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(imageFormat.Info.MediaPartNumber))
|
||||
sb.AppendLine($"Media part number: {imageFormat.Info.MediaPartNumber}");
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(imageFormat.Info.DriveManufacturer))
|
||||
sb.AppendLine($"Drive manufacturer: {imageFormat.Info.DriveManufacturer}");
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(imageFormat.Info.DriveModel))
|
||||
sb.AppendLine($"Drive model: {imageFormat.Info.DriveModel}");
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(imageFormat.Info.DriveSerialNumber))
|
||||
sb.AppendLine($"Drive serial number: {imageFormat.Info.DriveSerialNumber}");
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(imageFormat.Info.DriveFirmwareRevision))
|
||||
sb.AppendLine($"Drive firmware info: {imageFormat.Info.DriveFirmwareRevision}");
|
||||
|
||||
if(imageFormat.Info.Cylinders > 0 &&
|
||||
imageFormat.Info is { Heads: > 0, SectorsPerTrack: > 0 } &&
|
||||
imageFormat.Info.MetadataMediaType != MetadataMediaType.OpticalDisc &&
|
||||
imageFormat is not ITapeImage { IsTape: true })
|
||||
sb.AppendLine($"Media geometry: {imageFormat.Info.Cylinders} cylinders, {imageFormat.Info.Heads} heads, {imageFormat.Info.SectorsPerTrack} sectors per track");
|
||||
|
||||
if(imageFormat.Info.ReadableMediaTags is { Count: > 0 })
|
||||
{
|
||||
sb.AppendLine($"Contains {imageFormat.Info.ReadableMediaTags.Count} readable media tags:");
|
||||
|
||||
foreach(MediaTagType tag in imageFormat.Info.ReadableMediaTags.Order()) sb.Append($"{tag} ");
|
||||
|
||||
sb.AppendLine();
|
||||
}
|
||||
|
||||
if(imageFormat.Info.ReadableSectorTags is { Count: > 0 })
|
||||
{
|
||||
sb.AppendLine($"Contains {imageFormat.Info.ReadableSectorTags.Count} readable sector tags:");
|
||||
|
||||
foreach(SectorTagType tag in imageFormat.Info.ReadableSectorTags.Order()) sb.Append($"{tag} ");
|
||||
|
||||
sb.AppendLine();
|
||||
}
|
||||
|
||||
file.Information = sb.ToString();
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
SentrySdk.CaptureException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OpenSelectedFile()
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
<console:LineBrush LineStyle="DoubleLine"
|
||||
Brush="Blue" />
|
||||
</Border.BorderBrush>
|
||||
<Grid RowDefinitions="*,Auto,Auto"
|
||||
<Grid RowDefinitions="Auto,Auto,Auto,*"
|
||||
VerticalAlignment="Top">
|
||||
<Border Grid.Row="0"
|
||||
BorderThickness="1">
|
||||
@@ -136,6 +136,23 @@
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Border>
|
||||
<Border Grid.Row="3"
|
||||
IsVisible="{Binding SelectedFileHasInformation, Mode=OneWay}"
|
||||
BorderThickness="1">
|
||||
<Border.BorderBrush>
|
||||
<console:LineBrush LineStyle="DoubleLine"
|
||||
Brush="Blue" />
|
||||
</Border.BorderBrush>
|
||||
<ScrollViewer>
|
||||
<StackPanel VerticalAlignment="Top"
|
||||
HorizontalAlignment="Center">
|
||||
<TextBlock Text="Image information"
|
||||
Foreground="SlateBlue"
|
||||
FontWeight="Bold" />
|
||||
<TextBlock Text="{Binding SelectedFileInformation, Mode=OneWay}" />
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Border>
|
||||
</Grid>
|
||||
|
||||
Reference in New Issue
Block a user