Files
Aaru.Server/DiscImageChef.Server/Views/Stats/Index.cshtml

604 lines
26 KiB
Plaintext

@using DiscImageChef.CommonTypes.Metadata
@{
// /***************************************************************************
// The Disc Image Chef
// ----------------------------------------------------------------------------
//
// Filename : Index.cshtml
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : DiscImageChef Server.
//
// --[ Description ] ----------------------------------------------------------
//
// Renders statistics.
//
// --[ License ] --------------------------------------------------------------
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2011-2019 Natalia Portillo
// ****************************************************************************/
}
@{
ViewBag.Title = "DiscImageChef Statistics";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<header>
Welcome to
<i>
<a href="http://github.com/claunia/discimagechef" target="_blank">
DiscImageChef
</a>
</i> Server version @ViewBag.Version
</header>
<div class="container-fluid mt-3">
@if (ViewBag.repOperatingSystems != null)
{
<div class="container" id="divOperatingSystems">
<div class="carousel slide" data-ride="carousel" id="carouselOses">
<ol class="carousel-indicators">
<li class="active" data-slide-to="0" data-target="#carouselOses">
</li>
<li data-slide-to="1" data-target="#carouselOses">
</li>
<li data-slide-to="2" data-target="#carouselOses">
</li>
<li data-slide-to="3" data-target="#carouselOses">
</li>
</ol>
<div class="carousel-inner">
<div class="active carousel-item">
<canvas id="osChart"></canvas>
</div>
<div class="carousel-item">
<canvas id="linuxChart"></canvas>
</div>
<div class="carousel-item">
<canvas id="macosChart"></canvas>
</div>
<div class="carousel-item">
<canvas id="windowsChart"></canvas>
</div>
</div>
<a class="carousel-control-prev" data-slide="prev" href="#carouselOses" role="button">
<span aria-hidden="true" class="carousel-control-prev-icon">
</span>
<span class="sr-only">Previous</span>
</a>
<a class="carousel-control-next" data-slide="next" href="#carouselOses" role="button">
<span aria-hidden="true" class="carousel-control-next-icon">
</span>
<span class="sr-only">Next</span>
</a>
</div>
<div class="accordion mt-3" id="osAccordion">
<div class="card">
<div class="card-header" id="osHeading">
<h2 class="mb-0">
<button aria-controls="osCollapse" aria-expanded="true" class="btn btn-link card-button collapsed" data-target="#osCollapse" data-toggle="collapse" type="button">
All operating systems DiscImageChef has run on...
</button>
</h2>
</div>
<div aria-labelledby="osHeading" class="collapse" data-parent="#osAccordion" id="osCollapse">
<div class="card-body">
<table class="table-dark">
@foreach (NameValueStats os in ViewBag.repOperatingSystems)
{
<tr>
<td class="text-left">
DiscImageChef has run on
<i class="table-dark-em">@os.name</i> @os.Value times.
</td>
</tr>
}
</table>
</div>
</div>
</div>
</div>
<br />
</div>
}
@if (ViewBag.repVersions != null)
{
<div class="container mt-3" id="divVersions">
<div class="container">
<canvas id="versionsChart"></canvas>
</div>
<div class="accordion mt-3" id="versionsAccordion">
<div class="card">
<div class="card-header" id="versionsHeading">
<h2 class="mb-0">
<button aria-controls="versionsCollapse" aria-expanded="true" class="btn btn-link card-button collapsed" data-target="#versionsCollapse" data-toggle="collapse" type="button">
All DiscImageChef versions...
</button>
</h2>
</div>
<div aria-labelledby="versionsHeading" class="collapse" data-parent="#versionsAccordion" id="versionsCollapse">
<div class="card-body">
<table class="table-dark">
@foreach (NameValueStats version in ViewBag.repVersions)
{
<tr>
<td class="text-left">
DiscImageChef version
<i class="table-dark-em">@version.name</i> has been used @version.Value times.
</td>
</tr>
}
</table>
</div>
</div>
</div>
</div>
<br />
</div>
}
@if (ViewBag.repCommands != null)
{
<div class="container mt-3" id="divCommands">
<div class="container">
<canvas id="commandsChart"></canvas>
</div>
<div class="accordion mt-3" id="commandsAccordion">
<div class="card">
<div class="card-header" id="commandsHeading">
<h2 class="mb-0">
<button aria-controls="commandsCollapse" aria-expanded="true" class="btn btn-link card-button collapsed" data-target="#commandsCollapse" data-toggle="collapse" type="button">
All DiscImageChef commands...
</button>
</h2>
</div>
<div aria-labelledby="commandsHeading" class="collapse" data-parent="#commandsAccordion" id="commandsCollapse">
<div class="card-body">
<table class="table-dark">
@foreach (Command command in ViewBag.repCommands)
{
<tr>
<td class="text-left">
<i class="table-dark-em">@command.Name</i> has been run @command.Count times.
</td>
</tr>
}
</table>
</div>
</div>
</div>
</div>
<br />
</div>
}
@if (ViewBag.repFilters != null)
{
<div class="container mt-3" id="divFilters">
<div class="container">
<canvas id="filtersChart"></canvas>
</div>
<div class="accordion mt-3" id="filtersAccordion">
<div class="card">
<div class="card-header" id="filtersHeading">
<h2 class="mb-0">
<button aria-controls="filtersCollapse" aria-expanded="true" class="btn btn-link card-button collapsed" data-target="#filtersCollapse" data-toggle="collapse" type="button">
All filters found...
</button>
</h2>
</div>
<div aria-labelledby="filtersHeading" class="collapse" data-parent="#filtersAccordion" id="filtersCollapse">
<div class="card-body">
<table class="table-bordered table-centered table-dark table-striped">
<tr>
<th class="table-dark-header">Filter</th>
<th class="table-dark-header">Times</th>
</tr>
@foreach (Filter filter in ViewBag.repFilters)
{
<tr>
<td class="text-right">
@filter.Name
</td>
<td class="text-left">
@($"{filter.Count}")
</td>
</tr>
}
</table>
</div>
</div>
</div>
</div>
</div>
}
@if (ViewBag.repMediaImages != null)
{
<div class="container mt-3" id="divMediaImages">
<div class="container">
<canvas id="formatsChart"></canvas>
</div>
<div class="accordion mt-3" id="formatsAccordion">
<div class="card">
<div class="card-header" id="formatsHeading">
<h2 class="mb-0">
<button aria-controls="formatsCollapse" aria-expanded="true" class="btn btn-link card-button collapsed" data-target="#formatsCollapse" data-toggle="collapse" type="button">
All media image formats found...
</button>
</h2>
</div>
<div aria-labelledby="formatsHeading" class="collapse" data-parent="#formatsAccordion" id="formatsCollapse">
<div class="card-body">
<table class="table-bordered table-centered table-dark table-striped">
<tr>
<th class="table-dark-header">Media image format</th>
<th class="table-dark-header">Times</th>
</tr>
@foreach (MediaFormat format in ViewBag.repMediaImages)
{
<tr>
<td class="text-left">
@format.Name
</td>
<td class="text-left">
@($"{format.Count}")
</td>
</tr>
}
</table>
</div>
</div>
</div>
</div>
</div>
}
@if (ViewBag.repPartitions != null)
{
<div class="container mt-3" id="divPartitions">
<div class="container">
<canvas id="partitionsChart"></canvas>
</div>
<div class="accordion mt-3" id="partitionsAccordion">
<div class="card">
<div class="card-header" id="partitionsHeading">
<h2 class="mb-0">
<button aria-controls="partitionsCollapse" aria-expanded="true" class="btn btn-link card-button collapsed" data-target="#partitionsCollapse" data-toggle="collapse" type="button">
All partitioning schemes found...
</button>
</h2>
</div>
<div aria-labelledby="partitionsHeading" class="collapse" data-parent="#partitionsAccordion" id="partitionsCollapse">
<div class="card-body">
<table class="table-bordered table-centered table-dark table-striped">
<tr>
<th class="table-dark-header">Partitioning scheme</th>
<th class="table-dark-header">Times</th>
</tr>
@foreach (Partition partition in ViewBag.repPartitions)
{
<tr>
<td class="text-left">
@partition.Name
</td>
<td class="text-left">
@($"{partition.Count}")
</td>
</tr>
}
</table>
</div>
</div>
</div>
</div>
</div>
}
@if (ViewBag.repFilesystems != null)
{
<div class="container mt-3" id="divFilesystems">
<div class="container" id="filesystemsChart">
</div>
<div class="accordion mt-3" id="filesystemsAccordion">
<div class="card">
<div class="card-header" id="filesystemsHeading">
<h2 class="mb-0">
<button aria-controls="filesystemsCollapse" aria-expanded="true" class="btn btn-link card-button collapsed" data-target="#filesystemsCollapse" data-toggle="collapse" type="button">
All filesystems found...
</button>
</h2>
</div>
<div aria-labelledby="filesystemsHeading" class="collapse" data-parent="#filesystemsAccordion" id="filesystemsCollapse">
<div class="card-body">
<table class="table-bordered table-centered table-dark table-striped">
<tr>
<th class="table-dark-header">Filesystem name</th>
<th class="table-dark-header">Times</th>
</tr>
@foreach (Filesystem filesystem in ViewBag.repFilesystems)
{
<tr>
<td class="text-left">
@filesystem.Name
</td>
<td class="text-left">
@($"{filesystem.Count}")
</td>
</tr>
}
</table>
</div>
</div>
</div>
</div>
</div>
}
@if (ViewBag.repVirtualMedia != null)
{
<div class="container mt-3" id="divVirtualMedia">
<div class="container" id="virtualMediaChart">
</div>
<div class="accordion mt-3" id="virtualMediaAccordion">
<div class="card">
<div class="card-header" id="virtualMediaHeading">
<h2 class="mb-0">
<button aria-controls="virtualMediaCollapse" aria-expanded="true" class="btn btn-link card-button collapsed" data-target="#virtualMediaCollapse" data-toggle="collapse" type="button">
All media types found in images...
</button>
</h2>
</div>
<div aria-labelledby="virtualMediaHeading" class="collapse" data-parent="#virtualMediaAccordion" id="virtualMediaCollapse">
<div class="card-body">
<table class="table-bordered table-centered table-dark table-striped">
<tr>
<th class="table-dark-header">Physical type</th>
<th class="table-dark-header">Logical type</th>
<th class="table-dark-header">Times</th>
</tr>
@foreach (MediaItem media in ViewBag.repVirtualMedia)
{
<tr>
<td class="text-left">
@media.Type
</td>
<td class="text-left">
@media.SubType
</td>
<td class="text-left">
@($"{media.Count}")
</td>
</tr>
}
</table>
</div>
</div>
</div>
</div>
</div>
}
@if (ViewBag.repRealMedia != null)
{
<div class="container mt-3" id="divRealMedia">
<div class="container" id="realMediaChart">
</div>
<div class="accordion mt-3" id="realMediaAccordion">
<div class="card">
<div class="card-header" id="realMediaHeading">
<h2 class="mb-0">
<button aria-controls="realMediaCollapse" aria-expanded="true" class="btn btn-link card-button collapsed" data-target="#realMediaCollapse" data-toggle="collapse" type="button">
All media types found in devices...
</button>
</h2>
</div>
<div aria-labelledby="realMediaHeading" class="collapse" data-parent="#realMediaAccordion" id="realMediaCollapse">
<div class="card-body">
<table class="table-bordered table-centered table-dark table-striped">
<tr>
<th class="table-dark-header">Physical type</th>
<th class="table-dark-header">Logical type</th>
<th class="table-dark-header">Times</th>
</tr>
@foreach (MediaItem media in ViewBag.repRealMedia)
{
<tr>
<td class="text-left">
@media.Type
</td>
<td class="text-left">
@media.SubType
</td>
<td class="text-left">
@($"{media.Count}")
</td>
</tr>
}
</table>
</div>
</div>
</div>
</div>
</div>
}
@if (ViewBag.repDevices != null)
{
<div class="container mt-3" id="divDevices">
<div class="carousel slide" data-ride="carousel" id="carouselDevices">
<ol class="carousel-indicators">
<li class="active" data-slide-to="0" data-target="#carouselDevices">
</li>
<li data-slide-to="1" data-target="#carouselDevices">
</li>
<li data-slide-to="2" data-target="#carouselDevices">
</li>
<li data-slide-to="3" data-target="#carouselDevices">
</li>
</ol>
<div class="carousel-inner">
<div class="active carousel-item" id="devicesBusChart">
</div>
<div class="carousel-item" id="devicesManufacturerChart">
</div>
</div>
<a class="carousel-control-prev" data-slide="prev" href="#carouselDevices" role="button">
<span aria-hidden="true" class="carousel-control-prev-icon">
</span>
<span class="sr-only">Previous</span>
</a>
<a class="carousel-control-next" data-slide="next" href="#carouselDevices" role="button">
<span aria-hidden="true" class="carousel-control-next-icon">
</span>
<span class="sr-only">Next</span>
</a>
</div>
<div class="card mt-3">
<div class="card-header">
<h2 class="mb-0">
<h2 class="card-button mb-0">
All devices found...
</h2>
</h2>
</div>
<div class="card-body">
<table class="table-bordered table-centered table-dark table-striped">
<tr>
<th class="table-dark-header">Manufacturer</th>
<th class="table-dark-header">Model</th>
<th class="table-dark-header">Revision</th>
<th class="table-dark-header">Bus</th>
<th class="table-dark-header">Report</th>
</tr>
@foreach (DeviceItem device in ViewBag.repDevices)
{
<tr>
<td>
@device.Manufacturer
</td>
<td>
@device.Model
</td>
<td>
@device.Revision
</td>
<td>
@device.Bus
</td>
<td>
@if (device.ReportId != 0)
{
<text>@Html.ActionLink("Yes", "View", "Report", new
{
id = device.ReportId
}, new
{
target = "_blank"
})</text>
}
else
{
<text>No</text>
}
</td>
</tr>
}
</table>
</div>
</div>
</div>
}
</div>
<script crossorigin="anonymous" integrity="sha256-Uv9BNBucvCPipKQ2NS9wYpJmi8DTOEfTA/nH2aoJALw=" src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.js"></script>
<script>
function DrawPie(elementName, label, dataLabels, data)
{
var ctx = document.getElementById(elementName);
var myChart = new Chart(ctx, {
type: 'pie',
data: {
labels: dataLabels,
datasets: [{
label: label,
data: data,
backgroundColor: themeColors
}]
},
options: {
responsive: true,
title: {
display: true,
text: label,
fontColor: chartTitleColor
},
legend: {
labels: {
fontColor: chartDataLabelColor
}
}}}
);
}
function DrawOsPie(osData)
{
DrawPie("osChart", "Operating systems", osData[0], osData[1])
}
function DrawLinuxPie(linuxData)
{
DrawPie("linuxChart", `Top ${linuxData[0].length} Linux versions`, linuxData[0], linuxData[1])
}
function DrawMacOsPie(macosData)
{
DrawPie("macosChart", `Top ${macosData[0].length} macOS versions`, macosData[0], macosData[1])
}
function DrawWindowsPie(windowsData)
{
DrawPie("windowsChart", `Top ${windowsData[0].length} Windows versions`, windowsData[0], windowsData[1])
}
function DrawVersionsPie(versionsData)
{
DrawPie("versionsChart", `Top ${versionsData[0].length} DiscImageChef versions`, versionsData[0], versionsData[1])
}
function DrawCommandsPie(commandsData)
{
DrawPie("commandsChart", `Top ${commandsData[0].length} used commands`, commandsData[0], commandsData[1])
}
function DrawFiltersPie(filtersData)
{
DrawPie("filtersChart", `Top ${filtersData[0].length} filters found`, filtersData[0], filtersData[1])
}
function DrawFormatsPie(formatsData)
{
DrawPie("formatsChart", `Top ${formatsData[0].length} media image formats found`, formatsData[0], formatsData[1])
}
function DrawPartitionsPie(partitionsData)
{
DrawPie("partitionsChart", `Top ${partitionsData[0].length} partitioning schemes found`, partitionsData[0], partitionsData[1])
}
window.onload = () => {
$.ajax({dataType: "json", url: "/Stats/GetOsData", success: DrawOsPie, cache:false});
$.ajax({dataType: "json", url: "/Stats/GetLinuxData", success: DrawLinuxPie, cache:false});
$.ajax({dataType: "json", url: "/Stats/GetMacOsData", success: DrawMacOsPie, cache:false});
$.ajax({dataType: "json", url: "/Stats/GetWindowsData", success: DrawWindowsPie, cache:false});
$.ajax({dataType: "json", url: "/Stats/GetVersionsData", success: DrawVersionsPie, cache:false});
$.ajax({dataType: "json", url: "/Stats/GetCommandsData", success: DrawCommandsPie, cache:false});
$.ajax({dataType: "json", url: "/Stats/GetFiltersData", success: DrawFiltersPie, cache:false});
$.ajax({dataType: "json", url: "/Stats/GetFormatsData", success: DrawFormatsPie, cache:false});
$.ajax({dataType: "json", url: "/Stats/GetPartitionsData", success: DrawPartitionsPie, cache:false});
}
</script>