feat: added platform disk usage breakdown on the settings page (#37)
This commit is contained in:
@@ -14,35 +14,73 @@ namespace gaseous_server.Controllers
|
|||||||
{
|
{
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
public Dictionary<string, object> GetSystemStatus()
|
public SystemInfo GetSystemStatus()
|
||||||
{
|
{
|
||||||
Database db = new gaseous_tools.Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
Database db = new gaseous_tools.Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
|
|
||||||
Dictionary<string, object> ReturnValue = new Dictionary<string, object>();
|
SystemInfo ReturnValue = new SystemInfo();
|
||||||
|
|
||||||
// disk size
|
// disk size
|
||||||
List<Dictionary<string, object>> Disks = new List<Dictionary<string, object>>();
|
List<SystemInfo.PathItem> Disks = new List<SystemInfo.PathItem>();
|
||||||
//Disks.Add(GetDisk(gaseous_tools.Config.ConfigurationPath));
|
//Disks.Add(GetDisk(gaseous_tools.Config.ConfigurationPath));
|
||||||
Disks.Add(GetDisk(gaseous_tools.Config.LibraryConfiguration.LibraryRootDirectory));
|
Disks.Add(GetDisk(gaseous_tools.Config.LibraryConfiguration.LibraryRootDirectory));
|
||||||
ReturnValue.Add("Paths", Disks);
|
ReturnValue.Paths = Disks;
|
||||||
|
|
||||||
// database size
|
// database size
|
||||||
string sql = "SELECT table_schema, SUM(data_length + index_length) FROM information_schema.tables WHERE table_schema = '" + Config.DatabaseConfiguration.DatabaseName + "'";
|
string sql = "SELECT table_schema, SUM(data_length + index_length) FROM information_schema.tables WHERE table_schema = '" + Config.DatabaseConfiguration.DatabaseName + "'";
|
||||||
DataTable dbResponse = db.ExecuteCMD(sql);
|
DataTable dbResponse = db.ExecuteCMD(sql);
|
||||||
ReturnValue.Add("DatabaseSize", dbResponse.Rows[0][1]);
|
ReturnValue.DatabaseSize = (long)(System.Decimal)dbResponse.Rows[0][1];
|
||||||
|
|
||||||
|
// platform statistics
|
||||||
|
sql = "SELECT Platform.`name`, grc.Count, grs.Size FROM Platform INNER JOIN (SELECT Platform.`name` AS `Name`, SUM(grs.Size) AS Size FROM Platform JOIN Games_Roms AS grs ON (grs.PlatformId = Platform.Id) GROUP BY Platform.`name`) grs ON (grs.`Name` = Platform.`name`) INNER JOIN (SELECT Platform.`name` AS `Name`, COUNT(grc.Size) AS Count FROM Platform JOIN Games_Roms AS grc ON (grc.PlatformId = Platform.Id) GROUP BY Platform.`name`) grc ON (grc.`Name` = Platform.`name`) ORDER BY Platform.`name`;";
|
||||||
|
dbResponse = db.ExecuteCMD(sql);
|
||||||
|
ReturnValue.PlatformStatistics = new List<SystemInfo.PlatformStatisticsItem>();
|
||||||
|
foreach (DataRow dr in dbResponse.Rows)
|
||||||
|
{
|
||||||
|
SystemInfo.PlatformStatisticsItem platformStatisticsItem = new SystemInfo.PlatformStatisticsItem
|
||||||
|
{
|
||||||
|
Platform = (string)dr["name"],
|
||||||
|
RomCount = (long)dr["Count"],
|
||||||
|
TotalSize = (long)(System.Decimal)dr["Size"]
|
||||||
|
};
|
||||||
|
ReturnValue.PlatformStatistics.Add(platformStatisticsItem);
|
||||||
|
}
|
||||||
|
|
||||||
return ReturnValue;
|
return ReturnValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Dictionary<string, object> GetDisk(string Path)
|
private SystemInfo.PathItem GetDisk(string Path)
|
||||||
{
|
{
|
||||||
Dictionary<string, object> DiskValues = new Dictionary<string, object>();
|
SystemInfo.PathItem pathItem = new SystemInfo.PathItem {
|
||||||
DiskValues.Add("LibraryPath", Path);
|
LibraryPath = Path,
|
||||||
DiskValues.Add("SpaceUsed", gaseous_tools.Common.DirSize(new DirectoryInfo(Path)));
|
SpaceUsed = gaseous_tools.Common.DirSize(new DirectoryInfo(Path)),
|
||||||
DiskValues.Add("SpaceAvailable", new DriveInfo(Path).AvailableFreeSpace);
|
SpaceAvailable = new DriveInfo(Path).AvailableFreeSpace,
|
||||||
DiskValues.Add("TotalSpace", new DriveInfo(Path).TotalSize);
|
TotalSpace = new DriveInfo(Path).TotalSize
|
||||||
|
};
|
||||||
|
|
||||||
return DiskValues;
|
return pathItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SystemInfo
|
||||||
|
{
|
||||||
|
public List<PathItem>? Paths { get; set; }
|
||||||
|
public long DatabaseSize { get; set; }
|
||||||
|
public List<PlatformStatisticsItem>? PlatformStatistics { get; set; }
|
||||||
|
|
||||||
|
public class PathItem
|
||||||
|
{
|
||||||
|
public string LibraryPath { get; set; }
|
||||||
|
public long SpaceUsed { get; set; }
|
||||||
|
public long SpaceAvailable { get; set; }
|
||||||
|
public long TotalSpace { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class PlatformStatisticsItem
|
||||||
|
{
|
||||||
|
public string Platform { get; set; }
|
||||||
|
public long RomCount { get; set; }
|
||||||
|
public long TotalSize { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -6,8 +6,19 @@
|
|||||||
<div id="system_tasks"></div>
|
<div id="system_tasks"></div>
|
||||||
|
|
||||||
<h3>Usage</h3>
|
<h3>Usage</h3>
|
||||||
<p><strong>Library</strong></p>
|
<p><strong>Disk</strong></p>
|
||||||
<div id="system_disks"></div>
|
<div id="system_disks"></div>
|
||||||
|
<p><strong>Library</strong></p>
|
||||||
|
<div>
|
||||||
|
<table cellspacing="0" style="width: 100%;">
|
||||||
|
<tr>
|
||||||
|
<td id="system_platforms"></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td id="system_platforms_legend"></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
<p><strong>Database</strong></p>
|
<p><strong>Database</strong></p>
|
||||||
<div id="system_database"></div>
|
<div id="system_database"></div>
|
||||||
|
|
||||||
@@ -92,21 +103,24 @@
|
|||||||
function SystemLoadSystemStatus() {
|
function SystemLoadSystemStatus() {
|
||||||
ajaxCall('/api/v1/System', 'GET', function (result) {
|
ajaxCall('/api/v1/System', 'GET', function (result) {
|
||||||
if (result) {
|
if (result) {
|
||||||
|
var totalLibrarySpace = 0;
|
||||||
|
|
||||||
// disks
|
// disks
|
||||||
var newTable = document.createElement('table');
|
var newTable = document.createElement('table');
|
||||||
newTable.className = 'romtable';
|
newTable.className = 'romtable';
|
||||||
newTable.setAttribute('cellspacing', 0);
|
newTable.setAttribute('cellspacing', 0);
|
||||||
newTable.appendChild(createTableRow(true, ['Path', 'Library Size <div id="disk_LibSize" style="width: 10px; height: 10px; background-color: green;"></div>', 'Other <div id="disk_OtherSize" style="width: 10px; height: 10px; background-color: lightgreen;"></div>', 'Total Size <div id="disk_FreeSize" style="width: 10px; height: 10px; background-color: lightgray;"></div>']));
|
newTable.appendChild(createTableRow(true, ['Path', 'Library Size <div id="disk_LibSize" style="width: 10px; height: 10px; background-color: green;"></div>', 'Other <div id="disk_OtherSize" style="width: 10px; height: 10px; background-color: lightgreen;"></div>', 'Total Size <div id="disk_FreeSize" style="width: 10px; height: 10px; background-color: lightgray;"></div>']));
|
||||||
|
|
||||||
for (var i = 0; i < result.Paths.length; i++) {
|
for (var i = 0; i < result.paths.length; i++) {
|
||||||
var spaceUsedByLibrary = result.Paths[i].SpaceUsed;
|
var spaceUsedByLibrary = result.paths[i].spaceUsed;
|
||||||
var spaceUsedByOthers = result.Paths[i].TotalSpace - result.Paths[i].SpaceAvailable;
|
totalLibrarySpace += spaceUsedByLibrary;
|
||||||
|
var spaceUsedByOthers = result.paths[i].totalSpace - result.paths[i].spaceAvailable;
|
||||||
|
|
||||||
var newRow = [
|
var newRow = [
|
||||||
result.Paths[i].LibraryPath,
|
result.paths[i].libraryPath,
|
||||||
formatBytes(spaceUsedByLibrary),
|
formatBytes(spaceUsedByLibrary),
|
||||||
formatBytes(spaceUsedByOthers),
|
formatBytes(spaceUsedByOthers),
|
||||||
formatBytes(result.Paths[i].TotalSpace)
|
formatBytes(result.paths[i].totalSpace)
|
||||||
];
|
];
|
||||||
|
|
||||||
newTable.appendChild(createTableRow(false, newRow, 'romrow', 'romcell'));
|
newTable.appendChild(createTableRow(false, newRow, 'romrow', 'romcell'));
|
||||||
@@ -114,7 +128,7 @@
|
|||||||
var spaceRow = document.createElement('tr');
|
var spaceRow = document.createElement('tr');
|
||||||
var spaceCell = document.createElement('td');
|
var spaceCell = document.createElement('td');
|
||||||
spaceCell.setAttribute('colspan', 4);
|
spaceCell.setAttribute('colspan', 4);
|
||||||
spaceCell.appendChild(BuildSpaceBar(spaceUsedByLibrary, spaceUsedByOthers, result.Paths[i].TotalSpace));
|
spaceCell.appendChild(BuildSpaceBar(spaceUsedByLibrary, spaceUsedByOthers, result.paths[i].totalSpace));
|
||||||
spaceRow.appendChild(spaceCell);
|
spaceRow.appendChild(spaceCell);
|
||||||
newTable.appendChild(spaceRow);
|
newTable.appendChild(spaceRow);
|
||||||
}
|
}
|
||||||
@@ -123,11 +137,13 @@
|
|||||||
targetDiv.innerHTML = '';
|
targetDiv.innerHTML = '';
|
||||||
targetDiv.appendChild(newTable);
|
targetDiv.appendChild(newTable);
|
||||||
|
|
||||||
|
BuildLibraryStatisticsBar(document.getElementById('system_platforms'), document.getElementById('system_platforms_legend'), result.platformStatistics, totalLibrarySpace);
|
||||||
|
|
||||||
// database
|
// database
|
||||||
var newDbTable = document.createElement('table');
|
var newDbTable = document.createElement('table');
|
||||||
newDbTable.className = 'romtable';
|
newDbTable.className = 'romtable';
|
||||||
newDbTable.setAttribute('cellspacing', 0);
|
newDbTable.setAttribute('cellspacing', 0);
|
||||||
newDbTable.appendChild(createTableRow(false, ['Database Size', formatBytes(result.DatabaseSize)]));
|
newDbTable.appendChild(createTableRow(false, ['Database Size', formatBytes(result.databaseSize)]));
|
||||||
|
|
||||||
var targetDbDiv = document.getElementById('system_database');
|
var targetDbDiv = document.getElementById('system_database');
|
||||||
targetDbDiv.innerHTML = '';
|
targetDbDiv.innerHTML = '';
|
||||||
@@ -165,6 +181,40 @@
|
|||||||
return newTable;
|
return newTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function BuildLibraryStatisticsBar(TargetObject, TargetObjectLegend, LibraryStatistics, LibrarySize) {
|
||||||
|
var newTable = document.createElement('table');
|
||||||
|
newTable.setAttribute('cellspacing', 0);
|
||||||
|
newTable.setAttribute('style', 'width: 100%; height: 10px;');
|
||||||
|
|
||||||
|
var newRow = document.createElement('tr');
|
||||||
|
|
||||||
|
for (var i = 0; i < LibraryStatistics.length; i++) {
|
||||||
|
var platformSizePercent = LibraryStatistics[i].totalSize / LibrarySize * 100;
|
||||||
|
var platformSizeColour = intToRGB(hashCode(LibraryStatistics[i].platform));
|
||||||
|
var newCell = document.createElement('td');
|
||||||
|
newCell.setAttribute('style', 'min-width: 2px; width: ' + platformSizePercent + '%; background-color: #' + platformSizeColour);
|
||||||
|
newRow.appendChild(newCell);
|
||||||
|
|
||||||
|
var legend = document.createElement('div');
|
||||||
|
legend.className = 'legend_box';
|
||||||
|
|
||||||
|
var legendColour = document.createElement('div');
|
||||||
|
legendColour.className = 'legend_colour';
|
||||||
|
legendColour.setAttribute('style', 'background-color: #' + platformSizeColour + ';');
|
||||||
|
|
||||||
|
var legendLabel = document.createElement('div');
|
||||||
|
legendLabel.className = 'legend_label';
|
||||||
|
legendLabel.innerHTML = LibraryStatistics[i].platform + '<br />' + formatBytes(LibraryStatistics[i].totalSize);
|
||||||
|
|
||||||
|
legend.appendChild(legendColour);
|
||||||
|
legend.appendChild(legendLabel);
|
||||||
|
TargetObjectLegend.appendChild(legend);
|
||||||
|
}
|
||||||
|
|
||||||
|
newTable.appendChild(newRow);
|
||||||
|
TargetObject.appendChild(newTable);
|
||||||
|
}
|
||||||
|
|
||||||
function SystemSignaturesStatus() {
|
function SystemSignaturesStatus() {
|
||||||
ajaxCall('/api/v1/Signatures/Status', 'GET', function (result) {
|
ajaxCall('/api/v1/Signatures/Status', 'GET', function (result) {
|
||||||
var newTable = document.createElement('table');
|
var newTable = document.createElement('table');
|
||||||
|
@@ -99,4 +99,21 @@ function createTableRow(isHeader, row, rowClass, cellClass) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return newRow;
|
return newRow;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hashCode(str) {
|
||||||
|
var hash = 0;
|
||||||
|
for (var i = 0; i < str.length; i++) {
|
||||||
|
hash = str.charCodeAt(i) + ((hash << 5) - hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
function intToRGB(i) {
|
||||||
|
var c = (i & 0x00FFFFFF)
|
||||||
|
.toString(16)
|
||||||
|
.toUpperCase();
|
||||||
|
|
||||||
|
return "00000".substring(0, 6 - c.length) + c;
|
||||||
}
|
}
|
@@ -705,4 +705,26 @@ button:disabled {
|
|||||||
height: 310px;
|
height: 310px;
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend_box {
|
||||||
|
display: inline-block;
|
||||||
|
width: 145px;
|
||||||
|
height: 50px;
|
||||||
|
vertical-align: top;
|
||||||
|
margin-right: 5px;
|
||||||
|
padding-right: 5px;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend_colour {
|
||||||
|
float: left;
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
margin-top: 3px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend_label {
|
||||||
|
margin-left: 15px;
|
||||||
}
|
}
|
Reference in New Issue
Block a user