diff --git a/Aaru.Server.New/Components/Pages/Statistics/Commands.razor b/Aaru.Server.New/Components/Pages/Statistics/Commands.razor new file mode 100644 index 00000000..d8f9154e --- /dev/null +++ b/Aaru.Server.New/Components/Pages/Statistics/Commands.razor @@ -0,0 +1,16 @@ +@using Aaru.Server.Database +@using Aaru.Server.Database.Models +@using Blazorise.Charts +@using Blazorise.DataGrid +@rendermode InteractiveServer + +@inject Microsoft.EntityFrameworkCore.IDbContextFactory DbContextFactory + +

+

All Aaru commands...

+

+ + + + + \ No newline at end of file diff --git a/Aaru.Server.New/Components/Pages/Statistics/Commands.razor.cs b/Aaru.Server.New/Components/Pages/Statistics/Commands.razor.cs new file mode 100644 index 00000000..fc4f1e6a --- /dev/null +++ b/Aaru.Server.New/Components/Pages/Statistics/Commands.razor.cs @@ -0,0 +1,54 @@ +using Aaru.Server.Database.Models; +using Blazorise.Charts; +using Microsoft.EntityFrameworkCore; +using DbContext = Aaru.Server.Database.DbContext; + +namespace Aaru.Server.New.Components.Pages.Statistics; + +public partial class Commands +{ + PieChart? _commandsChart; + List _commandsCounts = []; + string[] _commandsLabels = []; + List CommandsList { get; set; } = []; + + /// + protected override async Task OnInitializedAsync() + { + await base.OnInitializedAsync(); + + await using DbContext ctx = await DbContextFactory.CreateDbContextAsync(); + + CommandsList = await ctx.Commands.OrderBy(static c => c.Name).ToListAsync(); + + _commandsLabels = await ctx.Commands.OrderByDescending(static o => o.Count) + .Take(10) + .Select(static v => v.Name) + .ToArrayAsync(); + + _commandsCounts = await ctx.Commands.OrderByDescending(static o => o.Count) + .Take(10) + .Select(static x => x.Count) + .ToListAsync(); + + if(_commandsLabels.Length >= 10) + { + _commandsLabels[9] = "Other"; + + _commandsCounts[9] = ctx.Commands.Sum(static o => o.Count) - _commandsCounts.Take(9).Sum(); + } + +#pragma warning disable CS8604 // Possible null reference argument. + await Common.HandleRedraw(_commandsChart, _commandsLabels, GetCommandsChartDataset); +#pragma warning restore CS8604 // Possible null reference argument. + } + + PieChartDataset GetCommandsChartDataset() => new() + { + Label = $"Top {_commandsLabels.Length} used commands", + Data = _commandsCounts, + BackgroundColor = Common._backgroundColors, + BorderColor = Common._borderColors, + BorderWidth = 1 + }; +} \ No newline at end of file diff --git a/Aaru.Server.New/Components/Pages/Statistics/Common.cs b/Aaru.Server.New/Components/Pages/Statistics/Common.cs new file mode 100644 index 00000000..2c61ae0b --- /dev/null +++ b/Aaru.Server.New/Components/Pages/Statistics/Common.cs @@ -0,0 +1,26 @@ +using Blazorise.Charts; + +namespace Aaru.Server.New.Components.Pages.Statistics; + +public static class Common +{ + internal static readonly List _backgroundColors = + [ + ChartColor.FromHtmlColorCode("#006412"), ChartColor.FromHtmlColorCode("#0000D3"), + ChartColor.FromHtmlColorCode("#FF6403"), ChartColor.FromHtmlColorCode("#562C05"), + ChartColor.FromHtmlColorCode("#DD0907"), ChartColor.FromHtmlColorCode("#F20884"), + ChartColor.FromHtmlColorCode("#4700A5"), ChartColor.FromHtmlColorCode("#90713A"), + ChartColor.FromHtmlColorCode("#1FB714"), ChartColor.FromHtmlColorCode("#02ABEA"), + ChartColor.FromHtmlColorCode("#FBF305") + ]; + internal static readonly List _borderColors = [ChartColor.FromHtmlColorCode("#8b0000")]; + + internal static async Task HandleRedraw( + BaseChart chart, string[] labels, Func getDataSet) + where TDataSet : ChartDataset where TOptions : ChartOptions where TModel : ChartModel + { + await chart.Clear(); + + await chart.AddLabelsDatasetsAndUpdate(labels, getDataSet()); + } +} \ No newline at end of file diff --git a/Aaru.Server.New/Components/Pages/Statistics/Devices.razor b/Aaru.Server.New/Components/Pages/Statistics/Devices.razor new file mode 100644 index 00000000..6287b9f0 --- /dev/null +++ b/Aaru.Server.New/Components/Pages/Statistics/Devices.razor @@ -0,0 +1,46 @@ +@using Aaru.Server.Database +@using Aaru.Server.Database.Models +@using Blazorise +@using Blazorise.Charts +@using Blazorise.DataGrid +@rendermode InteractiveServer + +@inject Microsoft.EntityFrameworkCore.IDbContextFactory DbContextFactory + +@* + TODO: Group by datagrid +*@ + +

+

All devices found...

+

+ + + + + + + + + + + + + + + + @{ + int? reportId = context?.ReportId; + + if(reportId > 0) + { + Yes + } + else + { + No + } + } + + + \ No newline at end of file diff --git a/Aaru.Server.New/Components/Pages/Statistics/Devices.razor.cs b/Aaru.Server.New/Components/Pages/Statistics/Devices.razor.cs new file mode 100644 index 00000000..af3959c5 --- /dev/null +++ b/Aaru.Server.New/Components/Pages/Statistics/Devices.razor.cs @@ -0,0 +1,116 @@ +using Aaru.Server.Database.Models; +using Blazorise; +using Blazorise.Charts; +using Microsoft.EntityFrameworkCore; +using DbContext = Aaru.Server.Database.DbContext; + +namespace Aaru.Server.New.Components.Pages.Statistics; + +public partial class Devices +{ + PieChart? _devicesByBusChart; + List _devicesByBusCounts = []; + string[] _devicesByBusLabels = []; + PieChart? _devicesByManufacturerChart; + List _devicesByManufacturerCounts = []; + string[] _devicesByManufacturerLabels = []; + Carousel? _devicesCarousel; + List DevicesList { get; set; } = []; + + /// + protected override async Task OnInitializedAsync() + { + await base.OnInitializedAsync(); + + await using DbContext ctx = await DbContextFactory.CreateDbContextAsync(); + + DevicesList = DevicesList.OrderBy(static device => device.Manufacturer) + .ThenBy(static device => device.Model) + .ThenBy(static device => device.Revision) + .ThenBy(static device => device.Bus) + .ToList(); + + var data = await ctx.DeviceStats.Select(static d => d.Bus) + .Distinct() + .Select(deviceBus => new + { + deviceBus, + deviceBusCount = ctx.DeviceStats.LongCount(d => d.Bus == deviceBus) + }) + .Select(static t => new + { + Name = t.deviceBus, + Count = t.deviceBusCount + }) + .ToListAsync(); + + _devicesByBusLabels = data.OrderByDescending(static o => o.Count).Take(10).Select(static v => v.Name).ToArray(); + _devicesByBusCounts = data.OrderByDescending(static o => o.Count).Take(10).Select(static x => x.Count).ToList(); + + if(_devicesByBusLabels.Length >= 10) + { + _devicesByBusLabels[9] = "Other"; + + _devicesByBusCounts[9] = data.Sum(static o => o.Count) - _devicesByBusCounts.Take(9).Sum(); + } + + List devices = await ctx.DeviceStats + .Where(static d => d.Manufacturer != null && d.Manufacturer != "") + .ToListAsync(); + + data = devices.Select(static d => d.Manufacturer!.ToLowerInvariant()) + .Distinct() + .Select(manufacturer => new + { + manufacturer, + manufacturerCount = + devices.LongCount(d => d.Manufacturer?.ToLowerInvariant() == manufacturer) + }) + .Select(static t => new + { + Name = t.manufacturer, + Count = t.manufacturerCount + }) + .ToList(); + + _devicesByManufacturerLabels = + data.OrderByDescending(static o => o.Count).Take(10).Select(static v => v.Name).ToArray(); + + _devicesByManufacturerCounts = + data.OrderByDescending(static o => o.Count).Take(10).Select(static x => x.Count).ToList(); + + if(_devicesByManufacturerLabels.Length < 10) return; + + _devicesByManufacturerLabels[9] = "Other"; + _devicesByManufacturerCounts[9] = data.Sum(static o => o.Count) - _devicesByManufacturerCounts.Take(9).Sum(); + +#pragma warning disable CS8604 // Possible null reference argument. + await Common.HandleRedraw(_devicesByBusChart, _devicesByBusLabels, GetDevicesByBusChartDataset); + + await Common.HandleRedraw(_devicesByManufacturerChart, + _devicesByManufacturerLabels, + GetDevicesByManufacturerChartDataset); +#pragma warning restore CS8604 // Possible null reference argument. + + // Upstream: https://github.com/Megabit/Blazorise/issues/5491 + _devicesCarousel.Interval = 5000; + } + + PieChartDataset GetDevicesByBusChartDataset() => new() + { + Label = $"Top {_devicesByBusLabels.Length} devices by bus", + Data = _devicesByBusCounts, + BackgroundColor = Common._backgroundColors, + BorderColor = Common._borderColors, + BorderWidth = 1 + }; + + PieChartDataset GetDevicesByManufacturerChartDataset() => new() + { + Label = $"Top {_devicesByManufacturerLabels.Length} devices by manufacturers", + Data = _devicesByManufacturerCounts, + BackgroundColor = Common._backgroundColors, + BorderColor = Common._borderColors, + BorderWidth = 1 + }; +} \ No newline at end of file diff --git a/Aaru.Server.New/Components/Pages/Statistics/Filesystems.razor b/Aaru.Server.New/Components/Pages/Statistics/Filesystems.razor new file mode 100644 index 00000000..037385b1 --- /dev/null +++ b/Aaru.Server.New/Components/Pages/Statistics/Filesystems.razor @@ -0,0 +1,16 @@ +@using Aaru.Server.Database +@using Aaru.Server.Database.Models +@using Blazorise.Charts +@using Blazorise.DataGrid +@rendermode InteractiveServer + +@inject Microsoft.EntityFrameworkCore.IDbContextFactory DbContextFactory + +

+

All filesystems found...

+

+ + + + + \ No newline at end of file diff --git a/Aaru.Server.New/Components/Pages/Statistics/Filesystems.razor.cs b/Aaru.Server.New/Components/Pages/Statistics/Filesystems.razor.cs new file mode 100644 index 00000000..50416964 --- /dev/null +++ b/Aaru.Server.New/Components/Pages/Statistics/Filesystems.razor.cs @@ -0,0 +1,54 @@ +using Aaru.Server.Database.Models; +using Blazorise.Charts; +using Microsoft.EntityFrameworkCore; +using DbContext = Aaru.Server.Database.DbContext; + +namespace Aaru.Server.New.Components.Pages.Statistics; + +public partial class Filesystems +{ + PieChart? _filesystemsChart; + List _filesystemsCounts = []; + string[] _filesystemsLabels = []; + List FilesystemsList { get; set; } = []; + + /// + protected override async Task OnInitializedAsync() + { + await base.OnInitializedAsync(); + + await using DbContext ctx = await DbContextFactory.CreateDbContextAsync(); + + FilesystemsList = await ctx.Filesystems.OrderBy(static filesystem => filesystem.Name).ToListAsync(); + + _filesystemsLabels = await ctx.Filesystems.OrderByDescending(static o => o.Count) + .Take(10) + .Select(static v => v.Name) + .ToArrayAsync(); + + _filesystemsCounts = await ctx.Filesystems.OrderByDescending(static o => o.Count) + .Take(10) + .Select(static x => x.Count) + .ToListAsync(); + + if(_filesystemsLabels.Length >= 10) + { + _filesystemsLabels[9] = "Other"; + + _filesystemsCounts[9] = ctx.Filesystems.Sum(static o => o.Count) - _filesystemsCounts.Take(9).Sum(); + } + +#pragma warning disable CS8604 // Possible null reference argument. + await Common.HandleRedraw(_filesystemsChart, _filesystemsLabels, GetFilesystemsChartDataset); +#pragma warning restore CS8604 // Possible null reference argument. + } + + PieChartDataset GetFilesystemsChartDataset() => new() + { + Label = $"Top {_filesystemsLabels.Length} filesystems found", + Data = _filesystemsCounts, + BackgroundColor = Common._backgroundColors, + BorderColor = Common._borderColors, + BorderWidth = 1 + }; +} \ No newline at end of file diff --git a/Aaru.Server.New/Components/Pages/Statistics/Filters.razor b/Aaru.Server.New/Components/Pages/Statistics/Filters.razor new file mode 100644 index 00000000..56fb3096 --- /dev/null +++ b/Aaru.Server.New/Components/Pages/Statistics/Filters.razor @@ -0,0 +1,16 @@ +@using Aaru.Server.Database +@using Aaru.Server.Database.Models +@using Blazorise.Charts +@using Blazorise.DataGrid +@rendermode InteractiveServer + +@inject Microsoft.EntityFrameworkCore.IDbContextFactory DbContextFactory + +

+

All filters found...

+

+ + + + + \ No newline at end of file diff --git a/Aaru.Server.New/Components/Pages/Statistics/Filters.razor.cs b/Aaru.Server.New/Components/Pages/Statistics/Filters.razor.cs new file mode 100644 index 00000000..a56dfbec --- /dev/null +++ b/Aaru.Server.New/Components/Pages/Statistics/Filters.razor.cs @@ -0,0 +1,55 @@ +using Aaru.Server.Database.Models; +using Blazorise.Charts; +using Microsoft.EntityFrameworkCore; +using DbContext = Aaru.Server.Database.DbContext; + +namespace Aaru.Server.New.Components.Pages.Statistics; + +public partial class Filters +{ + PieChart? _filtersChart; + List _filtersCounts = []; + string[] _filtersLabels = []; + List FiltersList { get; set; } = []; + + /// + protected override async Task OnInitializedAsync() + { + await base.OnInitializedAsync(); + + await using DbContext ctx = await DbContextFactory.CreateDbContextAsync(); + + FiltersList = await ctx.Filters.OrderBy(static filter => filter.Name).ToListAsync(); + + _filtersLabels = await ctx.Filters.OrderByDescending(static o => o.Count) + .Take(10) + .Select(static v => v.Name) + .ToArrayAsync(); + + _filtersCounts = await ctx.Filters.OrderByDescending(static o => o.Count) + .Take(10) + .Select(static x => x.Count) + .ToListAsync(); + + if(_filtersLabels.Length >= 10) + { + _filtersLabels[9] = "Other"; + + _filtersCounts[9] = ctx.Filters.Sum(static o => o.Count) - _filtersCounts.Take(9).Sum(); + } + +#pragma warning disable CS8604 // Possible null reference argument. + await Common.HandleRedraw(_filtersChart, _filtersLabels, GetFiltersChartDataset); +#pragma warning restore CS8604 // Possible null reference argument. + } + + + PieChartDataset GetFiltersChartDataset() => new() + { + Label = $"Top {_filtersLabels.Length} filters found", + Data = _filtersCounts, + BackgroundColor = Common._backgroundColors, + BorderColor = Common._borderColors, + BorderWidth = 1 + }; +} \ No newline at end of file diff --git a/Aaru.Server.New/Components/Pages/Statistics/Formats.razor b/Aaru.Server.New/Components/Pages/Statistics/Formats.razor new file mode 100644 index 00000000..dde11c54 --- /dev/null +++ b/Aaru.Server.New/Components/Pages/Statistics/Formats.razor @@ -0,0 +1,22 @@ +@using Aaru.Server.Database +@using Aaru.Server.Database.Models +@using Blazorise.Charts +@using Blazorise.DataGrid +@rendermode InteractiveServer + +@inject Microsoft.EntityFrameworkCore.IDbContextFactory DbContextFactory + +Aaru: Statistics + +@* + TODO: Group by datagrid +*@ + +

+

All media image formats found...

+

+ + + + + \ No newline at end of file diff --git a/Aaru.Server.New/Components/Pages/Statistics/Formats.razor.cs b/Aaru.Server.New/Components/Pages/Statistics/Formats.razor.cs new file mode 100644 index 00000000..f5b4ea96 --- /dev/null +++ b/Aaru.Server.New/Components/Pages/Statistics/Formats.razor.cs @@ -0,0 +1,57 @@ +using Aaru.Server.Database.Models; +using Blazorise.Charts; +using Microsoft.EntityFrameworkCore; +using DbContext = Aaru.Server.Database.DbContext; + +namespace Aaru.Server.New.Components.Pages.Statistics; + +public partial class Formats +{ + PieChart? _formatsChart; + List _formatsCounts = []; + string[] _formatsLabels = []; + List MediaImages { get; set; } = []; + + /// + protected override async Task OnInitializedAsync() + { + await base.OnInitializedAsync(); + + await using DbContext ctx = await DbContextFactory.CreateDbContextAsync(); + + + MediaImages = await ctx.MediaFormats.OrderBy(static format => format.Name).ToListAsync(); + + _formatsLabels = await ctx.MediaFormats.OrderByDescending(static o => o.Count) + .Take(10) + .Select(static v => v.Name) + .ToArrayAsync(); + + _formatsCounts = await ctx.MediaFormats.OrderByDescending(static o => o.Count) + .Take(10) + .Select(static x => x.Count) + .ToListAsync(); + + if(_formatsLabels.Length >= 10) + { + _formatsLabels[9] = "Other"; + + _formatsCounts[9] = ctx.MediaFormats.Sum(static o => o.Count) - _formatsCounts.Take(9).Sum(); + } + + +#pragma warning disable CS8604 // Possible null reference argument. + await Common.HandleRedraw(_formatsChart, _formatsLabels, GetFormatsChartDataset); + +#pragma warning restore CS8604 // Possible null reference argument. + } + + PieChartDataset GetFormatsChartDataset() => new() + { + Label = $"Top {_formatsLabels.Length} media image formats found", + Data = _formatsCounts, + BackgroundColor = Common._backgroundColors, + BorderColor = Common._borderColors, + BorderWidth = 1 + }; +} \ No newline at end of file diff --git a/Aaru.Server.New/Components/Pages/Statistics/OperatingSystems.razor b/Aaru.Server.New/Components/Pages/Statistics/OperatingSystems.razor new file mode 100644 index 00000000..7fbee34a --- /dev/null +++ b/Aaru.Server.New/Components/Pages/Statistics/OperatingSystems.razor @@ -0,0 +1,34 @@ +@using Aaru.CommonTypes.Metadata +@using Aaru.Server.Database +@using Blazorise +@using Blazorise.Charts +@using Blazorise.DataGrid +@rendermode InteractiveServer + +@inject Microsoft.EntityFrameworkCore.IDbContextFactory DbContextFactory + +@* + TODO: Group by datagrid +*@ + +

+

All operating systems Aaru has run on...

+

+ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Aaru.Server.New/Components/Pages/Statistics/OperatingSystems.razor.cs b/Aaru.Server.New/Components/Pages/Statistics/OperatingSystems.razor.cs new file mode 100644 index 00000000..47858b89 --- /dev/null +++ b/Aaru.Server.New/Components/Pages/Statistics/OperatingSystems.razor.cs @@ -0,0 +1,190 @@ +using Aaru.CommonTypes.Interop; +using Aaru.CommonTypes.Metadata; +using Blazorise; +using Blazorise.Charts; +using Microsoft.EntityFrameworkCore; +using DbContext = Aaru.Server.Database.DbContext; +using PlatformID = Aaru.CommonTypes.Interop.PlatformID; + +namespace Aaru.Server.New.Components.Pages.Statistics; + +public partial class OperatingSystems +{ + PieChart? _linuxChart; + List _linuxCounts = []; + string[] _linuxLabels = []; + PieChart? _macosChart; + List _macosCounts = []; + string[] _macosLabels = []; + Carousel? _operatingSystemsCarousel; + PieChart? _operatingSystemsChart; + List _operatingSystemsCounts = []; + string[] _operatingSystemsLabels = []; + PieChart? _windowsChart; + List _windowsCounts = []; + string[] _windowsLabels = []; + List OperatingSystemsList { get; set; } = []; + + /// + protected override async Task OnInitializedAsync() + { + await base.OnInitializedAsync(); + + // TODO: Cache real OS name in database, lookups would be much faster + await using DbContext ctx = await DbContextFactory.CreateDbContextAsync(); + + OperatingSystemsList = (await ctx.OperatingSystems.OrderBy(static os => os.Name) + .ThenBy(static os => os.Version) + .Select(static nvs => new NameValueStats + { + name = + $"{GetPlatformName(nvs.Name, nvs.Version)}{(string.IsNullOrEmpty(nvs.Version) ? "" : " ")}{nvs.Version}", + Value = nvs.Count + }) + .ToListAsync()).OrderBy(static os => os.name) + .ToList(); + + var osQuery = ctx.OperatingSystems.GroupBy(static x => new + { + x.Name + }, + static x => x.Count) + .Select(static g => new + { + g.Key.Name, + Count = g.Sum() + }); + + _operatingSystemsLabels = await osQuery.Select(static x => x.Name).ToArrayAsync(); + _operatingSystemsCounts = await osQuery.Select(static x => x.Count).ToListAsync(); + + for(var i = 0; i < _operatingSystemsLabels.Length; i++) + { + _operatingSystemsLabels[i] = + DetectOS.GetPlatformName((PlatformID)Enum.Parse(typeof(PlatformID), _operatingSystemsLabels[i])); + } + + _linuxLabels = await ctx.OperatingSystems.Where(static o => o.Name == PlatformID.Linux.ToString()) + .OrderByDescending(static o => o.Count) + .Take(10) + .Select(static x => + $"{DetectOS.GetPlatformName(PlatformID.Linux, x.Version)}{(string.IsNullOrEmpty(x.Version) ? "" : " ")}{x.Version}") + .ToArrayAsync(); + + _linuxCounts = await ctx.OperatingSystems.Where(static o => o.Name == PlatformID.Linux.ToString()) + .OrderByDescending(static o => o.Count) + .Take(10) + .Select(static x => x.Count) + .ToListAsync(); + + + if(_linuxLabels.Length >= 10) + { + _linuxLabels[9] = "Other"; + + _linuxCounts[9] = + ctx.OperatingSystems.Where(static o => o.Name == PlatformID.Linux.ToString()).Sum(static o => o.Count) - + _linuxCounts.Take(9).Sum(); + } + + _macosLabels = await ctx.OperatingSystems.Where(static o => o.Name == PlatformID.MacOSX.ToString()) + .OrderByDescending(static o => o.Count) + .Take(10) + .Select(static x => + $"{DetectOS.GetPlatformName(PlatformID.MacOSX, x.Version)}{(string.IsNullOrEmpty(x.Version) ? "" : " ")}{x.Version}") + .ToArrayAsync(); + + _macosCounts = await ctx.OperatingSystems.Where(static o => o.Name == PlatformID.MacOSX.ToString()) + .OrderByDescending(static o => o.Count) + .Take(10) + .Select(static x => x.Count) + .ToListAsync(); + + + if(_macosLabels.Length >= 10) + { + _macosLabels[9] = "Other"; + + _macosCounts[9] = + ctx.OperatingSystems.Where(static o => o.Name == PlatformID.MacOSX.ToString()) + .Sum(static o => o.Count) - + _macosCounts.Take(9).Sum(); + } + + _windowsLabels = await ctx.OperatingSystems.Where(static o => o.Name == PlatformID.Win32NT.ToString()) + .OrderByDescending(static o => o.Count) + .Take(10) + .Select(static x => + $"{DetectOS.GetPlatformName(PlatformID.Win32NT, x.Version)}{(string.IsNullOrEmpty(x.Version) ? "" : " ")}{x.Version}") + .ToArrayAsync(); + + _windowsCounts = await ctx.OperatingSystems.Where(static o => o.Name == PlatformID.Win32NT.ToString()) + .OrderByDescending(static o => o.Count) + .Take(10) + .Select(static x => x.Count) + .ToListAsync(); + + + if(_windowsLabels.Length >= 10) + { + _windowsLabels[9] = "Other"; + + _windowsCounts[9] = + ctx.OperatingSystems.Where(static o => o.Name == PlatformID.Win32NT.ToString()) + .Sum(static o => o.Count) - + _windowsCounts.Take(9).Sum(); + } + +#pragma warning disable CS8604 // Possible null reference argument. + + await Task.WhenAll(Common.HandleRedraw(_operatingSystemsChart, + _operatingSystemsLabels, + GetOperatingSystemsChartDataset), + Common.HandleRedraw(_linuxChart, _linuxLabels, GetLinuxChartDataset), + Common.HandleRedraw(_macosChart, _macosLabels, GetMacosChartDataset), + Common.HandleRedraw(_windowsChart, _windowsLabels, GetWindowsChartDataset)); +#pragma warning restore CS8604 // Possible null reference argument. + + // Upstream: https://github.com/Megabit/Blazorise/issues/5491 + _operatingSystemsCarousel.Interval = 5000; + } + + PieChartDataset GetOperatingSystemsChartDataset() => new() + { + Label = "Operating systems", + Data = _operatingSystemsCounts, + BackgroundColor = Common._backgroundColors, + BorderColor = Common._borderColors, + BorderWidth = 1 + }; + + PieChartDataset GetLinuxChartDataset() => new() + { + Label = $"Top {_linuxLabels.Length} Linux versions", + Data = _linuxCounts, + BackgroundColor = Common._backgroundColors, + BorderColor = Common._borderColors, + BorderWidth = 1 + }; + + PieChartDataset GetMacosChartDataset() => new() + { + Label = $"Top {_macosLabels.Length} macOS versions", + Data = _macosCounts, + BackgroundColor = Common._backgroundColors, + BorderColor = Common._borderColors, + BorderWidth = 1 + }; + + PieChartDataset GetWindowsChartDataset() => new() + { + Label = $"Top {_windowsLabels.Length} Windows versions", + Data = _windowsCounts, + BackgroundColor = Common._backgroundColors, + BorderColor = Common._borderColors, + BorderWidth = 1 + }; + + static string GetPlatformName(string name, string version) => + DetectOS.GetPlatformName((PlatformID)Enum.Parse(typeof(PlatformID), name), version); +} \ No newline at end of file diff --git a/Aaru.Server.New/Components/Pages/Statistics/Partitions.razor b/Aaru.Server.New/Components/Pages/Statistics/Partitions.razor new file mode 100644 index 00000000..6e7f46b6 --- /dev/null +++ b/Aaru.Server.New/Components/Pages/Statistics/Partitions.razor @@ -0,0 +1,16 @@ +@using Aaru.Server.Database +@using Aaru.Server.Database.Models +@using Blazorise.Charts +@using Blazorise.DataGrid +@rendermode InteractiveServer + +@inject Microsoft.EntityFrameworkCore.IDbContextFactory DbContextFactory + +

+

All partitioning schemes found...

+

+ + + + + \ No newline at end of file diff --git a/Aaru.Server.New/Components/Pages/Statistics/Partitions.razor.cs b/Aaru.Server.New/Components/Pages/Statistics/Partitions.razor.cs new file mode 100644 index 00000000..7302d039 --- /dev/null +++ b/Aaru.Server.New/Components/Pages/Statistics/Partitions.razor.cs @@ -0,0 +1,54 @@ +using Aaru.Server.Database.Models; +using Blazorise.Charts; +using Microsoft.EntityFrameworkCore; +using DbContext = Aaru.Server.Database.DbContext; + +namespace Aaru.Server.New.Components.Pages.Statistics; + +public partial class Partitions +{ + PieChart? _partitionsChart; + List _partitionsCounts = []; + string[] _partitionsLabels = []; + List PartitionsList { get; set; } = []; + + /// + protected override async Task OnInitializedAsync() + { + await base.OnInitializedAsync(); + + await using DbContext ctx = await DbContextFactory.CreateDbContextAsync(); + + PartitionsList = await ctx.Partitions.OrderBy(static partition => partition.Name).ToListAsync(); + + _partitionsLabels = await ctx.Partitions.OrderByDescending(static o => o.Count) + .Take(10) + .Select(static v => v.Name) + .ToArrayAsync(); + + _partitionsCounts = await ctx.Partitions.OrderByDescending(static o => o.Count) + .Take(10) + .Select(static x => x.Count) + .ToListAsync(); + + if(_partitionsLabels.Length >= 10) + { + _partitionsLabels[9] = "Other"; + + _partitionsCounts[9] = ctx.Partitions.Sum(static o => o.Count) - _partitionsCounts.Take(9).Sum(); + } + +#pragma warning disable CS8604 // Possible null reference argument. + await Common.HandleRedraw(_partitionsChart, _partitionsLabels, GetPartitionsChartDataset); +#pragma warning restore CS8604 // Possible null reference argument. + } + + PieChartDataset GetPartitionsChartDataset() => new() + { + Label = $"Top {_partitionsLabels.Length} partitioning schemes found", + Data = _partitionsCounts, + BackgroundColor = Common._backgroundColors, + BorderColor = Common._borderColors, + BorderWidth = 1 + }; +} \ No newline at end of file diff --git a/Aaru.Server.New/Components/Pages/Statistics/RealMedias.razor b/Aaru.Server.New/Components/Pages/Statistics/RealMedias.razor new file mode 100644 index 00000000..814c9fec --- /dev/null +++ b/Aaru.Server.New/Components/Pages/Statistics/RealMedias.razor @@ -0,0 +1,21 @@ +@using Aaru.Server.Database +@using Aaru.Server.Database.Models +@using Blazorise.Charts +@using Blazorise.DataGrid +@rendermode InteractiveServer + +@inject Microsoft.EntityFrameworkCore.IDbContextFactory DbContextFactory + +@* + TODO: Group by datagrid +*@ + +

+

All media types found in devices...

+

+ + + + + + \ No newline at end of file diff --git a/Aaru.Server.New/Components/Pages/Statistics/RealMedias.razor.cs b/Aaru.Server.New/Components/Pages/Statistics/RealMedias.razor.cs new file mode 100644 index 00000000..6f87ab16 --- /dev/null +++ b/Aaru.Server.New/Components/Pages/Statistics/RealMedias.razor.cs @@ -0,0 +1,70 @@ +using Aaru.CommonTypes.Metadata; +using Aaru.Server.Database.Models; +using Blazorise.Charts; +using Microsoft.EntityFrameworkCore; +using DbContext = Aaru.Server.Database.DbContext; +using Media = Aaru.Server.Database.Models.Media; + +namespace Aaru.Server.New.Components.Pages.Statistics; + +public partial class RealMedias +{ + PieChart? _realMediaChart; + List _realMediaCounts = []; + string[] _realMediaLabels = []; + List RealMedia { get; set; } = []; + + /// + protected override async Task OnInitializedAsync() + { + await base.OnInitializedAsync(); + + await using DbContext ctx = await DbContextFactory.CreateDbContextAsync(); + + Media[] realMedias = await ctx.Medias.Where(static o => o.Real) + .OrderByDescending(static o => o.Count) + .Take(10) + .ToArrayAsync(); + + foreach(Media media in realMedias) + { + try + { + (string type, string subType) mediaType = + MediaType.MediaTypeToString((CommonTypes.MediaType)Enum.Parse(typeof(CommonTypes.MediaType), + media.Type)); + + media.Type = $"{mediaType.type} ({mediaType.subType})"; + } + catch + { + // Could not get media type/subtype pair from type, so just leave it as is + } + } + + _realMediaLabels = realMedias.Select(static v => v.Type).ToArray(); + _realMediaCounts = realMedias.Select(static x => x.Count).ToList(); + + if(_realMediaLabels.Length >= 10) + { + _realMediaLabels[9] = "Other"; + + _realMediaCounts[9] = ctx.Medias.Where(static o => o.Real).Sum(static o => o.Count) - + _realMediaCounts.Take(9).Sum(); + } + + +#pragma warning disable CS8604 // Possible null reference argument. + await Common.HandleRedraw(_realMediaChart, _realMediaLabels, GetRealMediaChartDataset); +#pragma warning restore CS8604 // Possible null reference argument. + } + + PieChartDataset GetRealMediaChartDataset() => new() + { + Label = $"Top {_realMediaLabels.Length} media types found in devices", + Data = _realMediaCounts, + BackgroundColor = Common._backgroundColors, + BorderColor = Common._borderColors, + BorderWidth = 1 + }; +} \ No newline at end of file diff --git a/Aaru.Server.New/Components/Pages/Statistics/Versions.razor b/Aaru.Server.New/Components/Pages/Statistics/Versions.razor new file mode 100644 index 00000000..8ba28c74 --- /dev/null +++ b/Aaru.Server.New/Components/Pages/Statistics/Versions.razor @@ -0,0 +1,16 @@ +@using Aaru.CommonTypes.Metadata +@using Aaru.Server.Database +@using Blazorise.Charts +@using Blazorise.DataGrid +@rendermode InteractiveServer + +@inject Microsoft.EntityFrameworkCore.IDbContextFactory DbContextFactory + +

+

All Aaru versions...

+

+ + + + + \ No newline at end of file diff --git a/Aaru.Server.New/Components/Pages/Statistics/Versions.razor.cs b/Aaru.Server.New/Components/Pages/Statistics/Versions.razor.cs new file mode 100644 index 00000000..a730f186 --- /dev/null +++ b/Aaru.Server.New/Components/Pages/Statistics/Versions.razor.cs @@ -0,0 +1,60 @@ +using Aaru.CommonTypes.Metadata; +using Blazorise.Charts; +using Microsoft.EntityFrameworkCore; +using DbContext = Aaru.Server.Database.DbContext; + +namespace Aaru.Server.New.Components.Pages.Statistics; + +public partial class Versions +{ + PieChart? _versionsChart; + List _versionsCounts = []; + string[] _versionsLabels = []; + List VersionsList { get; set; } = []; + + /// + protected override async Task OnInitializedAsync() + { + await base.OnInitializedAsync(); + + await using DbContext ctx = await DbContextFactory.CreateDbContextAsync(); + + VersionsList = (await ctx.Versions.Select(static nvs => new NameValueStats + { + name = nvs.Name == "previous" ? "Previous than 3.4.99.0" : nvs.Name, + Value = nvs.Count + }) + .ToListAsync()).OrderBy(static version => version.name) + .ToList(); + + _versionsLabels = await ctx.Versions.OrderByDescending(static o => o.Count) + .Take(10) + .Select(static v => v.Name == "previous" ? "Previous than 3.4.99.0" : v.Name) + .ToArrayAsync(); + + _versionsCounts = await ctx.Versions.OrderByDescending(static o => o.Count) + .Take(10) + .Select(static x => x.Count) + .ToListAsync(); + + if(_versionsLabels.Length >= 10) + { + _versionsLabels[9] = "Other"; + + _versionsCounts[9] = ctx.Versions.Sum(static o => o.Count) - _versionsCounts.Take(9).Sum(); + } + +#pragma warning disable CS8604 // Possible null reference argument. + await Common.HandleRedraw(_versionsChart, _versionsLabels, GetVersionsChartDataset); +#pragma warning restore CS8604 // Possible null reference argument. + } + + PieChartDataset GetVersionsChartDataset() => new() + { + Label = $"Top {_versionsLabels.Length} Aaru versions", + Data = _versionsCounts, + BackgroundColor = Common._backgroundColors, + BorderColor = Common._borderColors, + BorderWidth = 1 + }; +} \ No newline at end of file diff --git a/Aaru.Server.New/Components/Pages/Statistics/VirtualMedias.razor b/Aaru.Server.New/Components/Pages/Statistics/VirtualMedias.razor new file mode 100644 index 00000000..ced0073b --- /dev/null +++ b/Aaru.Server.New/Components/Pages/Statistics/VirtualMedias.razor @@ -0,0 +1,21 @@ +@using Aaru.Server.Database +@using Aaru.Server.Database.Models +@using Blazorise.Charts +@using Blazorise.DataGrid +@rendermode InteractiveServer + +@inject Microsoft.EntityFrameworkCore.IDbContextFactory DbContextFactory + +@* + TODO: Group by datagrid +*@ + +

+

All media types found in images...

+

+ + + + + + \ No newline at end of file diff --git a/Aaru.Server.New/Components/Pages/Statistics/VirtualMedias.razor.cs b/Aaru.Server.New/Components/Pages/Statistics/VirtualMedias.razor.cs new file mode 100644 index 00000000..df06c833 --- /dev/null +++ b/Aaru.Server.New/Components/Pages/Statistics/VirtualMedias.razor.cs @@ -0,0 +1,69 @@ +using Aaru.CommonTypes.Metadata; +using Aaru.Server.Database.Models; +using Blazorise.Charts; +using Microsoft.EntityFrameworkCore; +using DbContext = Aaru.Server.Database.DbContext; +using Media = Aaru.Server.Database.Models.Media; + +namespace Aaru.Server.New.Components.Pages.Statistics; + +public partial class VirtualMedias +{ + PieChart? _virtualMediaChart; + List _virtualMediaCounts = []; + string[] _virtualMediaLabels = []; + List VirtualMedia { get; set; } = []; + + /// + protected override async Task OnInitializedAsync() + { + await base.OnInitializedAsync(); + + await using DbContext ctx = await DbContextFactory.CreateDbContextAsync(); + + Media[] virtualMedias = await ctx.Medias.Where(static o => !o.Real) + .OrderByDescending(static o => o.Count) + .Take(10) + .ToArrayAsync(); + + foreach(Media media in virtualMedias) + { + try + { + (string type, string subType) mediaType = + MediaType.MediaTypeToString((CommonTypes.MediaType)Enum.Parse(typeof(CommonTypes.MediaType), + media.Type)); + + media.Type = $"{mediaType.type} ({mediaType.subType})"; + } + catch + { + // Could not get media type/subtype pair from type, so just leave it as is + } + } + + _virtualMediaLabels = virtualMedias.Select(static v => v.Type).ToArray(); + _virtualMediaCounts = virtualMedias.Select(static x => x.Count).ToList(); + + if(_virtualMediaLabels.Length >= 10) + { + _virtualMediaLabels[9] = "Other"; + + _virtualMediaCounts[9] = ctx.Medias.Where(static o => !o.Real).Sum(static o => o.Count) - + _virtualMediaCounts.Take(9).Sum(); + } + +#pragma warning disable CS8604 // Possible null reference argument. + await Common.HandleRedraw(_virtualMediaChart, _virtualMediaLabels, GetVirtualMediaChartDataset); +#pragma warning restore CS8604 // Possible null reference argument. + } + + PieChartDataset GetVirtualMediaChartDataset() => new() + { + Label = $"Top {_virtualMediaLabels.Length} media types found in images", + Data = _virtualMediaCounts, + BackgroundColor = Common._backgroundColors, + BorderColor = Common._borderColors, + BorderWidth = 1 + }; +} \ No newline at end of file diff --git a/Aaru.Server.New/Components/Pages/Stats.razor b/Aaru.Server.New/Components/Pages/Stats.razor index 731ed797..390ad21f 100644 --- a/Aaru.Server.New/Components/Pages/Stats.razor +++ b/Aaru.Server.New/Components/Pages/Stats.razor @@ -1,167 +1,70 @@ @page "/Stats" -@using Aaru.CommonTypes.Metadata -@using Aaru.Server.Database -@using Aaru.Server.Database.Models +@using Aaru.Server.New.Components.Pages.Statistics @using Blazorise -@using Blazorise.Charts -@using Blazorise.DataGrid @rendermode InteractiveServer -@inject Microsoft.EntityFrameworkCore.IDbContextFactory DbContextFactory - Aaru: Statistics -@* - TODO: Group by datagrid - TODO: Sortable datagrid -*@ -
-

-

All operating systems Aaru has run on...

-

- - - - - - - - - - - - - - - - - - + + + Operating systems + Versions + Commands + Filters + Media image formats + Partitioning schemes + Filesystems + Media types (images) + Media types (devices) + Devices + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
-
-

-

All Aaru versions...

-

- - - - - -
+@code +{ + Tabs _tabs; -
-

-

All Aaru commands...

-

- - - - - -
+ /// + protected override async Task OnAfterRenderAsync(bool firstRender) + { + await base.OnAfterRenderAsync(firstRender); -
-

-

All filters found...

-

- - - - - -
+ if(!firstRender) return; -
-

-

All media image formats found...

-

- - - - - -
- -
-

-

All partitioning schemes found...

-

- - - - - -
- -
-

-

All filesystems found...

-

- - - - - -
- -
-

-

All media types found in images...

-

- - - - - - -
- -
-

-

All media types found in devices...

-

- - - - - - -
- -
-

-

All devices found...

-

- - - - - - - - - - - - - - - - @{ - int? reportId = context?.ReportId; - - if(reportId > 0) - { - Yes - } - else - { - No - } - } - - - -
\ No newline at end of file + await _tabs.SelectTab("oses"); + } +} \ No newline at end of file diff --git a/Aaru.Server.New/Components/Pages/Stats.razor.cs b/Aaru.Server.New/Components/Pages/Stats.razor.cs deleted file mode 100644 index 4075e325..00000000 --- a/Aaru.Server.New/Components/Pages/Stats.razor.cs +++ /dev/null @@ -1,665 +0,0 @@ -using Aaru.CommonTypes.Interop; -using Aaru.CommonTypes.Metadata; -using Aaru.Server.Database.Models; -using Blazorise; -using Blazorise.Charts; -using Microsoft.EntityFrameworkCore; -using DbContext = Aaru.Server.Database.DbContext; -using Media = Aaru.Server.Database.Models.Media; -using PlatformID = Aaru.CommonTypes.Interop.PlatformID; - -namespace Aaru.Server.New.Components.Pages; - -public partial class Stats -{ - readonly List _backgroundColors = - [ - ChartColor.FromHtmlColorCode("#006412"), ChartColor.FromHtmlColorCode("#0000D3"), - ChartColor.FromHtmlColorCode("#FF6403"), ChartColor.FromHtmlColorCode("#562C05"), - ChartColor.FromHtmlColorCode("#DD0907"), ChartColor.FromHtmlColorCode("#F20884"), - ChartColor.FromHtmlColorCode("#4700A5"), ChartColor.FromHtmlColorCode("#90713A"), - ChartColor.FromHtmlColorCode("#1FB714"), ChartColor.FromHtmlColorCode("#02ABEA"), - ChartColor.FromHtmlColorCode("#FBF305") - ]; - readonly List _borderColors = [ChartColor.FromHtmlColorCode("#8b0000")]; - PieChart? _commandsChart; - List _commandsCounts = []; - string[] _commandsLabels = []; - PieChart? _devicesByBusChart; - List _devicesByBusCounts = []; - string[] _devicesByBusLabels = []; - PieChart? _devicesByManufacturerChart; - List _devicesByManufacturerCounts = []; - string[] _devicesByManufacturerLabels = []; - Carousel? _devicesCarousel; - PieChart? _filesystemsChart; - List _filesystemsCounts = []; - string[] _filesystemsLabels = []; - PieChart? _filtersChart; - List _filtersCounts = []; - string[] _filtersLabels = []; - PieChart? _formatsChart; - List _formatsCounts = []; - string[] _formatsLabels = []; - PieChart? _linuxChart; - List _linuxCounts = []; - string[] _linuxLabels = []; - PieChart? _macosChart; - List _macosCounts = []; - string[] _macosLabels = []; - Carousel? _operatingSystemsCarousel; - PieChart? _operatingSystemsChart; - List _operatingSystemsCounts = []; - string[] _operatingSystemsLabels = []; - PieChart? _partitionsChart; - List _partitionsCounts = []; - string[] _partitionsLabels = []; - PieChart? _realMediaChart; - List _realMediaCounts = []; - string[] _realMediaLabels = []; - PieChart? _versionsChart; - List _versionsCounts = []; - string[] _versionsLabels = []; - PieChart? _virtualMediaChart; - List _virtualMediaCounts = []; - string[] _virtualMediaLabels = []; - PieChart? _windowsChart; - List _windowsCounts = []; - string[] _windowsLabels = []; - List OperatingSystems { get; set; } = []; - List Versions { get; set; } = []; - List Commands { get; set; } = []; - List Filters { get; set; } = []; - List MediaImages { get; set; } = []; - List Partitions { get; set; } = []; - List Filesystems { get; set; } = []; - List RealMedia { get; set; } = []; - List VirtualMedia { get; set; } = []; - List Devices { get; set; } = []; - - /// - protected override async Task OnInitializedAsync() - { - await base.OnInitializedAsync(); - - // TOOD: Cache real OS name in database, lookups would be much faster - await using DbContext _ctx = await DbContextFactory.CreateDbContextAsync(); - - OperatingSystems = (await _ctx.OperatingSystems.OrderBy(static os => os.Name) - .ThenBy(static os => os.Version) - .Select(static nvs => new NameValueStats - { - name = - $"{GetPlatformName(nvs.Name, nvs.Version)}{(string.IsNullOrEmpty(nvs.Version) ? "" : " ")}{nvs.Version}", - Value = nvs.Count - }) - .ToListAsync()).OrderBy(static os => os.name) - .ToList(); - - var osQuery = _ctx.OperatingSystems.GroupBy(static x => new - { - x.Name - }, - static x => x.Count) - .Select(static g => new - { - g.Key.Name, - Count = g.Sum() - }); - - _operatingSystemsLabels = await osQuery.Select(static x => x.Name).ToArrayAsync(); - _operatingSystemsCounts = await osQuery.Select(static x => x.Count).ToListAsync(); - - for(var i = 0; i < _operatingSystemsLabels.Length; i++) - { - _operatingSystemsLabels[i] = - DetectOS.GetPlatformName((PlatformID)Enum.Parse(typeof(PlatformID), _operatingSystemsLabels[i])); - } - - _linuxLabels = await _ctx.OperatingSystems.Where(static o => o.Name == PlatformID.Linux.ToString()) - .OrderByDescending(static o => o.Count) - .Take(10) - .Select(static x => - $"{DetectOS.GetPlatformName(PlatformID.Linux, x.Version)}{(string.IsNullOrEmpty(x.Version) ? "" : " ")}{x.Version}") - .ToArrayAsync(); - - _linuxCounts = await _ctx.OperatingSystems.Where(static o => o.Name == PlatformID.Linux.ToString()) - .OrderByDescending(static o => o.Count) - .Take(10) - .Select(static x => x.Count) - .ToListAsync(); - - - if(_linuxLabels.Length >= 10) - { - _linuxLabels[9] = "Other"; - - _linuxCounts[9] = - _ctx.OperatingSystems.Where(static o => o.Name == PlatformID.Linux.ToString()) - .Sum(static o => o.Count) - - _linuxCounts.Take(9).Sum(); - } - - _macosLabels = await _ctx.OperatingSystems.Where(static o => o.Name == PlatformID.MacOSX.ToString()) - .OrderByDescending(static o => o.Count) - .Take(10) - .Select(static x => - $"{DetectOS.GetPlatformName(PlatformID.MacOSX, x.Version)}{(string.IsNullOrEmpty(x.Version) ? "" : " ")}{x.Version}") - .ToArrayAsync(); - - _macosCounts = await _ctx.OperatingSystems.Where(static o => o.Name == PlatformID.MacOSX.ToString()) - .OrderByDescending(static o => o.Count) - .Take(10) - .Select(static x => x.Count) - .ToListAsync(); - - - if(_macosLabels.Length >= 10) - { - _macosLabels[9] = "Other"; - - _macosCounts[9] = - _ctx.OperatingSystems.Where(static o => o.Name == PlatformID.MacOSX.ToString()) - .Sum(static o => o.Count) - - _macosCounts.Take(9).Sum(); - } - - _windowsLabels = await _ctx.OperatingSystems.Where(static o => o.Name == PlatformID.Win32NT.ToString()) - .OrderByDescending(static o => o.Count) - .Take(10) - .Select(static x => - $"{DetectOS.GetPlatformName(PlatformID.Win32NT, x.Version)}{(string.IsNullOrEmpty(x.Version) ? "" : " ")}{x.Version}") - .ToArrayAsync(); - - _windowsCounts = await _ctx.OperatingSystems.Where(static o => o.Name == PlatformID.Win32NT.ToString()) - .OrderByDescending(static o => o.Count) - .Take(10) - .Select(static x => x.Count) - .ToListAsync(); - - - if(_windowsLabels.Length >= 10) - { - _windowsLabels[9] = "Other"; - - _windowsCounts[9] = - _ctx.OperatingSystems.Where(static o => o.Name == PlatformID.Win32NT.ToString()) - .Sum(static o => o.Count) - - _windowsCounts.Take(9).Sum(); - } - - Versions = (await _ctx.Versions.Select(static nvs => new NameValueStats - { - name = nvs.Name == "previous" ? "Previous than 3.4.99.0" : nvs.Name, - Value = nvs.Count - }) - .ToListAsync()).OrderBy(static version => version.name) - .ToList(); - - _versionsLabels = await _ctx.Versions.OrderByDescending(static o => o.Count) - .Take(10) - .Select(static v => v.Name == "previous" ? "Previous than 3.4.99.0" : v.Name) - .ToArrayAsync(); - - _versionsCounts = await _ctx.Versions.OrderByDescending(static o => o.Count) - .Take(10) - .Select(static x => x.Count) - .ToListAsync(); - - if(_versionsLabels.Length >= 10) - { - _versionsLabels[9] = "Other"; - - _versionsCounts[9] = _ctx.Versions.Sum(static o => o.Count) - _versionsCounts.Take(9).Sum(); - } - - Commands = await _ctx.Commands.OrderBy(static c => c.Name).ToListAsync(); - - _commandsLabels = await _ctx.Commands.OrderByDescending(static o => o.Count) - .Take(10) - .Select(static v => v.Name) - .ToArrayAsync(); - - _commandsCounts = await _ctx.Commands.OrderByDescending(static o => o.Count) - .Take(10) - .Select(static x => x.Count) - .ToListAsync(); - - if(_commandsLabels.Length >= 10) - { - _commandsLabels[9] = "Other"; - - _commandsCounts[9] = _ctx.Commands.Sum(static o => o.Count) - _commandsCounts.Take(9).Sum(); - } - - Filters = await _ctx.Filters.OrderBy(static filter => filter.Name).ToListAsync(); - - _filtersLabels = await _ctx.Filters.OrderByDescending(static o => o.Count) - .Take(10) - .Select(static v => v.Name) - .ToArrayAsync(); - - _filtersCounts = await _ctx.Filters.OrderByDescending(static o => o.Count) - .Take(10) - .Select(static x => x.Count) - .ToListAsync(); - - if(_filtersLabels.Length >= 10) - { - _filtersLabels[9] = "Other"; - - _filtersCounts[9] = _ctx.Filters.Sum(static o => o.Count) - _filtersCounts.Take(9).Sum(); - } - - MediaImages = await _ctx.MediaFormats.OrderBy(static format => format.Name).ToListAsync(); - - _formatsLabels = await _ctx.MediaFormats.OrderByDescending(static o => o.Count) - .Take(10) - .Select(static v => v.Name) - .ToArrayAsync(); - - _formatsCounts = await _ctx.MediaFormats.OrderByDescending(static o => o.Count) - .Take(10) - .Select(static x => x.Count) - .ToListAsync(); - - if(_formatsLabels.Length >= 10) - { - _formatsLabels[9] = "Other"; - - _formatsCounts[9] = _ctx.MediaFormats.Sum(static o => o.Count) - _formatsCounts.Take(9).Sum(); - } - - Partitions = await _ctx.Partitions.OrderBy(static partition => partition.Name).ToListAsync(); - - _partitionsLabels = await _ctx.Partitions.OrderByDescending(static o => o.Count) - .Take(10) - .Select(static v => v.Name) - .ToArrayAsync(); - - _partitionsCounts = await _ctx.Partitions.OrderByDescending(static o => o.Count) - .Take(10) - .Select(static x => x.Count) - .ToListAsync(); - - if(_partitionsLabels.Length >= 10) - { - _partitionsLabels[9] = "Other"; - - _partitionsCounts[9] = _ctx.Partitions.Sum(static o => o.Count) - _partitionsCounts.Take(9).Sum(); - } - - Filesystems = await _ctx.Filesystems.OrderBy(static filesystem => filesystem.Name).ToListAsync(); - - _filesystemsLabels = await _ctx.Filesystems.OrderByDescending(static o => o.Count) - .Take(10) - .Select(static v => v.Name) - .ToArrayAsync(); - - _filesystemsCounts = await _ctx.Filesystems.OrderByDescending(static o => o.Count) - .Take(10) - .Select(static x => x.Count) - .ToListAsync(); - - if(_filesystemsLabels.Length >= 10) - { - _filesystemsLabels[9] = "Other"; - - _filesystemsCounts[9] = _ctx.Filesystems.Sum(static o => o.Count) - _filesystemsCounts.Take(9).Sum(); - } - - RealMedia = []; - VirtualMedia = []; - - await foreach(Media nvs in _ctx.Medias.AsAsyncEnumerable()) - { - try - { - (string type, string subType) mediaType = - MediaType.MediaTypeToString((CommonTypes.MediaType)Enum.Parse(typeof(CommonTypes.MediaType), - nvs.Type)); - - if(nvs.Real) - { - RealMedia.Add(new MediaItem - { - Type = mediaType.type, - SubType = mediaType.subType, - Count = nvs.Count - }); - } - else - { - VirtualMedia.Add(new MediaItem - { - Type = mediaType.type, - SubType = mediaType.subType, - Count = nvs.Count - }); - } - } - catch - { - if(nvs.Real) - { - RealMedia.Add(new MediaItem - { - Type = nvs.Type, - SubType = null, - Count = nvs.Count - }); - } - else - { - VirtualMedia.Add(new MediaItem - { - Type = nvs.Type, - SubType = null, - Count = nvs.Count - }); - } - } - } - - RealMedia = RealMedia.OrderBy(static media => media.Type).ThenBy(static media => media.SubType).ToList(); - VirtualMedia = VirtualMedia.OrderBy(static media => media.Type).ThenBy(static media => media.SubType).ToList(); - - Media[] virtualMedias = await _ctx.Medias.Where(static o => !o.Real) - .OrderByDescending(static o => o.Count) - .Take(10) - .ToArrayAsync(); - - foreach(Media media in virtualMedias) - { - try - { - (string type, string subType) mediaType = - MediaType.MediaTypeToString((CommonTypes.MediaType)Enum.Parse(typeof(CommonTypes.MediaType), - media.Type)); - - media.Type = $"{mediaType.type} ({mediaType.subType})"; - } - catch - { - // Could not get media type/subtype pair from type, so just leave it as is - } - } - - _virtualMediaLabels = virtualMedias.Select(static v => v.Type).ToArray(); - _virtualMediaCounts = virtualMedias.Select(static x => x.Count).ToList(); - - if(_virtualMediaLabels.Length >= 10) - { - _virtualMediaLabels[9] = "Other"; - - _virtualMediaCounts[9] = _ctx.Medias.Where(static o => !o.Real).Sum(static o => o.Count) - - _virtualMediaCounts.Take(9).Sum(); - } - - Media[] realMedias = await _ctx.Medias.Where(static o => o.Real) - .OrderByDescending(static o => o.Count) - .Take(10) - .ToArrayAsync(); - - foreach(Media media in realMedias) - { - try - { - (string type, string subType) mediaType = - MediaType.MediaTypeToString((CommonTypes.MediaType)Enum.Parse(typeof(CommonTypes.MediaType), - media.Type)); - - media.Type = $"{mediaType.type} ({mediaType.subType})"; - } - catch - { - // Could not get media type/subtype pair from type, so just leave it as is - } - } - - _realMediaLabels = realMedias.Select(static v => v.Type).ToArray(); - _realMediaCounts = realMedias.Select(static x => x.Count).ToList(); - - if(_realMediaLabels.Length >= 10) - { - _realMediaLabels[9] = "Other"; - - _realMediaCounts[9] = _ctx.Medias.Where(static o => o.Real).Sum(static o => o.Count) - - _realMediaCounts.Take(9).Sum(); - } - - Devices = await _ctx.DeviceStats.Include(static deviceStat => deviceStat.Report) - .Select(static device => new DeviceItem - { - Manufacturer = device.Manufacturer, - Model = device.Model, - Revision = device.Revision, - Bus = device.Bus, - ReportId = device.Report != null && device.Report.Id != 0 ? device.Report.Id : 0 - }) - .ToListAsync(); - - Devices = Devices.OrderBy(static device => device.Manufacturer) - .ThenBy(static device => device.Model) - .ThenBy(static device => device.Revision) - .ThenBy(static device => device.Bus) - .ToList(); - - var data = await _ctx.DeviceStats.Select(static d => d.Bus) - .Distinct() - .Select(deviceBus => new - { - deviceBus, - deviceBusCount = _ctx.DeviceStats.LongCount(d => d.Bus == deviceBus) - }) - .Select(static t => new - { - Name = t.deviceBus, - Count = t.deviceBusCount - }) - .ToListAsync(); - - _devicesByBusLabels = data.OrderByDescending(static o => o.Count).Take(10).Select(static v => v.Name).ToArray(); - _devicesByBusCounts = data.OrderByDescending(static o => o.Count).Take(10).Select(static x => x.Count).ToList(); - - if(_devicesByBusLabels.Length >= 10) - { - _devicesByBusLabels[9] = "Other"; - - _devicesByBusCounts[9] = data.Sum(static o => o.Count) - _devicesByBusCounts.Take(9).Sum(); - } - - List devices = await _ctx.DeviceStats - .Where(static d => d.Manufacturer != null && d.Manufacturer != "") - .ToListAsync(); - - data = devices.Select(static d => d.Manufacturer!.ToLowerInvariant()) - .Distinct() - .Select(manufacturer => new - { - manufacturer, - manufacturerCount = - devices.LongCount(d => d.Manufacturer?.ToLowerInvariant() == manufacturer) - }) - .Select(static t => new - { - Name = t.manufacturer, - Count = t.manufacturerCount - }) - .ToList(); - - _devicesByManufacturerLabels = - data.OrderByDescending(static o => o.Count).Take(10).Select(static v => v.Name).ToArray(); - - _devicesByManufacturerCounts = - data.OrderByDescending(static o => o.Count).Take(10).Select(static x => x.Count).ToList(); - - if(_devicesByManufacturerLabels.Length < 10) return; - - _devicesByManufacturerLabels[9] = "Other"; - _devicesByManufacturerCounts[9] = data.Sum(static o => o.Count) - _devicesByManufacturerCounts.Take(9).Sum(); - -#pragma warning disable CS8604 // Possible null reference argument. - - await - Task.WhenAll(HandleRedraw(_operatingSystemsChart, _operatingSystemsLabels, GetOperatingSystemsChartDataset), - HandleRedraw(_linuxChart, _linuxLabels, GetLinuxChartDataset), - HandleRedraw(_macosChart, _macosLabels, GetMacosChartDataset), - HandleRedraw(_windowsChart, _windowsLabels, GetWindowsChartDataset), - HandleRedraw(_versionsChart, _versionsLabels, GetVersionsChartDataset), - HandleRedraw(_commandsChart, _commandsLabels, GetCommandsChartDataset), - HandleRedraw(_filtersChart, _filtersLabels, GetFiltersChartDataset), - HandleRedraw(_formatsChart, _formatsLabels, GetFormatsChartDataset), - HandleRedraw(_partitionsChart, _partitionsLabels, GetPartitionsChartDataset), - HandleRedraw(_filesystemsChart, _filesystemsLabels, GetFilesystemsChartDataset), - HandleRedraw(_virtualMediaChart, _virtualMediaLabels, GetVirtualMediaChartDataset), - HandleRedraw(_realMediaChart, _realMediaLabels, GetRealMediaChartDataset), - HandleRedraw(_devicesByBusChart, _devicesByBusLabels, GetDevicesByBusChartDataset), - HandleRedraw(_devicesByManufacturerChart, - _devicesByManufacturerLabels, - GetDevicesByManufacturerChartDataset)); -#pragma warning restore CS8604 // Possible null reference argument. - - // Upstream: https://github.com/Megabit/Blazorise/issues/5491 - _operatingSystemsCarousel.Interval = 5000; - _devicesCarousel.Interval = 5000; - } - - static async Task HandleRedraw( - BaseChart chart, string[] labels, Func getDataSet) - where TDataSet : ChartDataset where TOptions : ChartOptions where TModel : ChartModel - { - await chart.Clear(); - - await chart.AddLabelsDatasetsAndUpdate(labels, getDataSet()); - } - - PieChartDataset GetOperatingSystemsChartDataset() => new() - { - Label = "Operating systems", - Data = _operatingSystemsCounts, - BackgroundColor = _backgroundColors, - BorderColor = _borderColors, - BorderWidth = 1 - }; - - PieChartDataset GetLinuxChartDataset() => new() - { - Label = $"Top {_linuxLabels.Length} Linux versions", - Data = _linuxCounts, - BackgroundColor = _backgroundColors, - BorderColor = _borderColors, - BorderWidth = 1 - }; - - PieChartDataset GetMacosChartDataset() => new() - { - Label = $"Top {_macosLabels.Length} macOS versions", - Data = _macosCounts, - BackgroundColor = _backgroundColors, - BorderColor = _borderColors, - BorderWidth = 1 - }; - - PieChartDataset GetWindowsChartDataset() => new() - { - Label = $"Top {_windowsLabels.Length} Windows versions", - Data = _windowsCounts, - BackgroundColor = _backgroundColors, - BorderColor = _borderColors, - BorderWidth = 1 - }; - - PieChartDataset GetVersionsChartDataset() => new() - { - Label = $"Top {_versionsLabels.Length} Aaru versions", - Data = _versionsCounts, - BackgroundColor = _backgroundColors, - BorderColor = _borderColors, - BorderWidth = 1 - }; - - PieChartDataset GetCommandsChartDataset() => new() - { - Label = $"Top {_commandsLabels.Length} used commands", - Data = _commandsCounts, - BackgroundColor = _backgroundColors, - BorderColor = _borderColors, - BorderWidth = 1 - }; - - PieChartDataset GetFiltersChartDataset() => new() - { - Label = $"Top {_filtersLabels.Length} filters found", - Data = _filtersCounts, - BackgroundColor = _backgroundColors, - BorderColor = _borderColors, - BorderWidth = 1 - }; - - PieChartDataset GetFormatsChartDataset() => new() - { - Label = $"Top {_formatsLabels.Length} media image formats found", - Data = _formatsCounts, - BackgroundColor = _backgroundColors, - BorderColor = _borderColors, - BorderWidth = 1 - }; - - PieChartDataset GetPartitionsChartDataset() => new() - { - Label = $"Top {_partitionsLabels.Length} partitioning schemes found", - Data = _partitionsCounts, - BackgroundColor = _backgroundColors, - BorderColor = _borderColors, - BorderWidth = 1 - }; - - PieChartDataset GetFilesystemsChartDataset() => new() - { - Label = $"Top {_filesystemsLabels.Length} filesystems found", - Data = _filesystemsCounts, - BackgroundColor = _backgroundColors, - BorderColor = _borderColors, - BorderWidth = 1 - }; - - PieChartDataset GetVirtualMediaChartDataset() => new() - { - Label = $"Top {_virtualMediaLabels.Length} media types found in images", - Data = _virtualMediaCounts, - BackgroundColor = _backgroundColors, - BorderColor = _borderColors, - BorderWidth = 1 - }; - - PieChartDataset GetRealMediaChartDataset() => new() - { - Label = $"Top {_realMediaLabels.Length} media types found in devices", - Data = _realMediaCounts, - BackgroundColor = _backgroundColors, - BorderColor = _borderColors, - BorderWidth = 1 - }; - - PieChartDataset GetDevicesByBusChartDataset() => new() - { - Label = $"Top {_devicesByBusLabels.Length} devices by bus", - Data = _devicesByBusCounts, - BackgroundColor = _backgroundColors, - BorderColor = _borderColors, - BorderWidth = 1 - }; - - PieChartDataset GetDevicesByManufacturerChartDataset() => new() - { - Label = $"Top {_devicesByManufacturerLabels.Length} devices by manufacturers", - Data = _devicesByManufacturerCounts, - BackgroundColor = _backgroundColors, - BorderColor = _borderColors, - BorderWidth = 1 - }; - - static string GetPlatformName(string name, string version) => - DetectOS.GetPlatformName((PlatformID)Enum.Parse(typeof(PlatformID), name), version); -} \ No newline at end of file