feat: added system page to manage background tasks and get basic system information
This commit is contained in:
48
gaseous-server/Controllers/SystemController.cs
Normal file
48
gaseous-server/Controllers/SystemController.cs
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Data;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using gaseous_tools;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace gaseous_server.Controllers
|
||||||
|
{
|
||||||
|
[ApiController]
|
||||||
|
[Route("api/v1/[controller]")]
|
||||||
|
public class SystemController : Controller
|
||||||
|
{
|
||||||
|
[HttpGet]
|
||||||
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
|
public Dictionary<string, object> GetSystemStatus()
|
||||||
|
{
|
||||||
|
Database db = new gaseous_tools.Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
|
|
||||||
|
Dictionary<string, object> ReturnValue = new Dictionary<string, object>();
|
||||||
|
|
||||||
|
// disk size
|
||||||
|
List<Dictionary<string, object>> Disks = new List<Dictionary<string, object>>();
|
||||||
|
//Disks.Add(GetDisk(gaseous_tools.Config.ConfigurationPath));
|
||||||
|
Disks.Add(GetDisk(gaseous_tools.Config.LibraryConfiguration.LibraryRootDirectory));
|
||||||
|
ReturnValue.Add("Paths", Disks);
|
||||||
|
|
||||||
|
// database size
|
||||||
|
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);
|
||||||
|
ReturnValue.Add("DatabaseSize", dbResponse.Rows[0][1]);
|
||||||
|
|
||||||
|
return ReturnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Dictionary<string, object> GetDisk(string Path)
|
||||||
|
{
|
||||||
|
Dictionary<string, object> DiskValues = new Dictionary<string, object>();
|
||||||
|
DiskValues.Add("LibraryPath", Path);
|
||||||
|
DiskValues.Add("SpaceUsed", gaseous_tools.Common.DirSize(new DirectoryInfo(Path)));
|
||||||
|
DiskValues.Add("SpaceAvailable", new DriveInfo(Path).AvailableFreeSpace);
|
||||||
|
DiskValues.Add("TotalSpace", new DriveInfo(Path).TotalSize);
|
||||||
|
|
||||||
|
return DiskValues;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -74,6 +74,11 @@ namespace gaseous_server
|
|||||||
Logging.Log(Logging.LogType.Information, "Timered Event", "Starting Metadata Refresher");
|
Logging.Log(Logging.LogType.Information, "Timered Event", "Starting Metadata Refresher");
|
||||||
Classes.MetadataManagement.RefreshMetadata(true);
|
Classes.MetadataManagement.RefreshMetadata(true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case QueueItemType.OrganiseLibrary:
|
||||||
|
Logging.Log(Logging.LogType.Information, "Timered Event", "Starting Library Organiser");
|
||||||
|
Classes.ImportGame.OrganiseLibrary();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -101,7 +106,8 @@ namespace gaseous_server
|
|||||||
NotConfigured,
|
NotConfigured,
|
||||||
SignatureIngestor,
|
SignatureIngestor,
|
||||||
TitleIngestor,
|
TitleIngestor,
|
||||||
MetadataRefresh
|
MetadataRefresh,
|
||||||
|
OrganiseLibrary
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum QueueItemState
|
public enum QueueItemState
|
||||||
|
@@ -94,6 +94,7 @@ gaseous_server.Classes.Metadata.Platforms.GetPlatform(0);
|
|||||||
ProcessQueue.QueueItems.Add(new ProcessQueue.QueueItem(ProcessQueue.QueueItemType.SignatureIngestor, 60));
|
ProcessQueue.QueueItems.Add(new ProcessQueue.QueueItem(ProcessQueue.QueueItemType.SignatureIngestor, 60));
|
||||||
ProcessQueue.QueueItems.Add(new ProcessQueue.QueueItem(ProcessQueue.QueueItemType.TitleIngestor, 1));
|
ProcessQueue.QueueItems.Add(new ProcessQueue.QueueItem(ProcessQueue.QueueItemType.TitleIngestor, 1));
|
||||||
ProcessQueue.QueueItems.Add(new ProcessQueue.QueueItem(ProcessQueue.QueueItemType.MetadataRefresh, 360));
|
ProcessQueue.QueueItems.Add(new ProcessQueue.QueueItem(ProcessQueue.QueueItemType.MetadataRefresh, 360));
|
||||||
|
ProcessQueue.QueueItems.Add(new ProcessQueue.QueueItem(ProcessQueue.QueueItemType.OrganiseLibrary, 1440));
|
||||||
|
|
||||||
// start the app
|
// start the app
|
||||||
app.Run();
|
app.Run();
|
||||||
|
BIN
gaseous-server/wwwroot/images/cog.jpg
Normal file
BIN
gaseous-server/wwwroot/images/cog.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 88 KiB |
@@ -4,6 +4,7 @@
|
|||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<link type="text/css" rel="stylesheet" href="/styles/style.css" />
|
<link type="text/css" rel="stylesheet" href="/styles/style.css" />
|
||||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||||
|
<script src="https://momentjs.com/downloads/moment.js"></script>
|
||||||
<script src="/scripts/main.js" type="text/javascript"></script>
|
<script src="/scripts/main.js" type="text/javascript"></script>
|
||||||
<script src="/scripts/filterformating.js" type="text/javascript"></script>
|
<script src="/scripts/filterformating.js" type="text/javascript"></script>
|
||||||
<script src="/scripts/gamesformating.js" type="text/javascript"></script>
|
<script src="/scripts/gamesformating.js" type="text/javascript"></script>
|
||||||
@@ -14,12 +15,15 @@
|
|||||||
<title>Gaseous Games</title>
|
<title>Gaseous Games</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="banner_icon">
|
<div id="banner_icon" onclick="window.location.href = '/index.html';">
|
||||||
<img src="/images/logo.png" alt="Gaseous" id="banner_icon_image" />
|
<img src="/images/logo.png" alt="Gaseous" id="banner_icon_image" />
|
||||||
</div>
|
</div>
|
||||||
<div id="banner_header">
|
<div id="banner_header">
|
||||||
<div id="banner_header_label">Gaseous Games</div>
|
<div id="banner_header_label">Gaseous Games</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="banner_cog" onclick="window.location.href = '/index.html?page=system';">
|
||||||
|
<img src="/images/cog.jpg" alt="System" id="banner_system_image" />
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id="content">
|
<div id="content">
|
||||||
|
|
||||||
@@ -37,8 +41,7 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">var modalVariables = null;
|
||||||
var modalVariables = null;
|
|
||||||
|
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
const urlParams = new URLSearchParams(window.location.search);
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
@@ -49,7 +52,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
$('#content').load('/pages/' + myParam + '.html');
|
$('#content').load('/pages/' + myParam + '.html');
|
||||||
});
|
});</script>
|
||||||
</script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@@ -408,24 +408,4 @@
|
|||||||
|
|
||||||
selectScreenshot(selectedScreenshot);
|
selectScreenshot(selectedScreenshot);
|
||||||
}
|
}
|
||||||
|
|
||||||
function createTableRow(isHeader, row, rowClass, cellClass) {
|
|
||||||
var newRow = document.createElement('tr');
|
|
||||||
newRow.className = rowClass;
|
|
||||||
|
|
||||||
for (var i = 0; i < row.length; i++) {
|
|
||||||
var cellType = 'td';
|
|
||||||
if (isHeader == true) {
|
|
||||||
cellType = 'th';
|
|
||||||
}
|
|
||||||
|
|
||||||
var newCell = document.createElement(cellType);
|
|
||||||
newCell.innerHTML = row[i];
|
|
||||||
newCell.className = cellClass;
|
|
||||||
|
|
||||||
newRow.appendChild(newCell);
|
|
||||||
}
|
|
||||||
|
|
||||||
return newRow;
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
198
gaseous-server/wwwroot/pages/system.html
Normal file
198
gaseous-server/wwwroot/pages/system.html
Normal file
@@ -0,0 +1,198 @@
|
|||||||
|
<div id="gamepage">
|
||||||
|
<div id="gametitle">
|
||||||
|
<h1 id="gametitle_label">System</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3>Background Tasks</h3>
|
||||||
|
<div id="system_tasks"></div>
|
||||||
|
|
||||||
|
<h3>Usage</h3>
|
||||||
|
<p><strong>Library</strong></p>
|
||||||
|
<div id="system_disks"></div>
|
||||||
|
<p><strong>Database</strong></p>
|
||||||
|
<div id="system_database"></div>
|
||||||
|
|
||||||
|
<h3>Signatures</h3>
|
||||||
|
<div id="system_signatures"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
function SystemLoadStatus() {
|
||||||
|
ajaxCall('/api/v1/BackgroundTasks', 'GET', function (result) {
|
||||||
|
var newTable = document.createElement('table');
|
||||||
|
newTable.className = 'romtable';
|
||||||
|
newTable.setAttribute('cellspacing', 0);
|
||||||
|
newTable.appendChild(createTableRow(true, ['Task', 'Status', 'Interval', 'Last Run Time', 'Next Run Time', '']));
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
for (var i = 0; i < result.length; i++) {
|
||||||
|
var itemTypeName;
|
||||||
|
switch (result[i].itemType) {
|
||||||
|
case 'SignatureIngestor':
|
||||||
|
itemTypeName = "Signature import";
|
||||||
|
break;
|
||||||
|
case 'TitleIngestor':
|
||||||
|
itemTypeName = "Title import";
|
||||||
|
break;
|
||||||
|
case 'MetadataRefresh':
|
||||||
|
itemTypeName = "Metadata refresh"
|
||||||
|
break;
|
||||||
|
case 'OrganiseLibrary':
|
||||||
|
itemTypeName = "Organise library";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
itemTypeName = result[i].itemType;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
var itemStateName;
|
||||||
|
switch (result[i].itemState) {
|
||||||
|
case 'NeverStarted':
|
||||||
|
itemStateName = "Never started";
|
||||||
|
break;
|
||||||
|
case 'Stopped':
|
||||||
|
itemStateName = "Stopped";
|
||||||
|
break;
|
||||||
|
case 'Running':
|
||||||
|
itemStateName = "Running";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
itemStateName = "Unknown status";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
var startButton = '';
|
||||||
|
if (result[i].itemState != "Running") {
|
||||||
|
startButton = "<span id='startProcess' class='romlink' onclick='StartProcess(\"" + result[i].itemType + "\");'>Start</span>";
|
||||||
|
}
|
||||||
|
|
||||||
|
var newRow = [
|
||||||
|
itemTypeName,
|
||||||
|
itemStateName,
|
||||||
|
result[i].interval,
|
||||||
|
moment(result[i].lastRunTime).fromNow(),
|
||||||
|
moment(result[i].nextRunTime).fromNow(),
|
||||||
|
startButton
|
||||||
|
];
|
||||||
|
newTable.appendChild(createTableRow(false, newRow, 'romrow', 'romcell'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var targetDiv = document.getElementById('system_tasks');
|
||||||
|
targetDiv.innerHTML = '';
|
||||||
|
targetDiv.appendChild(newTable);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function SystemLoadSystemStatus() {
|
||||||
|
ajaxCall('/api/v1/System', 'GET', function (result) {
|
||||||
|
if (result) {
|
||||||
|
// disks
|
||||||
|
var newTable = document.createElement('table');
|
||||||
|
newTable.className = 'romtable';
|
||||||
|
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>']));
|
||||||
|
|
||||||
|
for (var i = 0; i < result.Paths.length; i++) {
|
||||||
|
var spaceUsedByLibrary = result.Paths[i].SpaceUsed;
|
||||||
|
var spaceUsedByOthers = result.Paths[i].TotalSpace - result.Paths[i].SpaceAvailable;
|
||||||
|
|
||||||
|
var newRow = [
|
||||||
|
result.Paths[i].LibraryPath,
|
||||||
|
formatBytes(spaceUsedByLibrary),
|
||||||
|
formatBytes(spaceUsedByOthers),
|
||||||
|
formatBytes(result.Paths[i].TotalSpace)
|
||||||
|
];
|
||||||
|
|
||||||
|
newTable.appendChild(createTableRow(false, newRow, 'romrow', 'romcell'));
|
||||||
|
|
||||||
|
var spaceRow = document.createElement('tr');
|
||||||
|
var spaceCell = document.createElement('td');
|
||||||
|
spaceCell.setAttribute('colspan', 4);
|
||||||
|
spaceCell.appendChild(BuildSpaceBar(spaceUsedByLibrary, spaceUsedByOthers, result.Paths[i].TotalSpace));
|
||||||
|
spaceRow.appendChild(spaceCell);
|
||||||
|
newTable.appendChild(spaceRow);
|
||||||
|
}
|
||||||
|
|
||||||
|
var targetDiv = document.getElementById('system_disks');
|
||||||
|
targetDiv.innerHTML = '';
|
||||||
|
targetDiv.appendChild(newTable);
|
||||||
|
|
||||||
|
// database
|
||||||
|
var newDbTable = document.createElement('table');
|
||||||
|
newDbTable.className = 'romtable';
|
||||||
|
newDbTable.setAttribute('cellspacing', 0);
|
||||||
|
newDbTable.appendChild(createTableRow(false, ['Database Size', formatBytes(result.DatabaseSize)]));
|
||||||
|
|
||||||
|
var targetDbDiv = document.getElementById('system_database');
|
||||||
|
targetDbDiv.innerHTML = '';
|
||||||
|
targetDbDiv.appendChild(newDbTable);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function BuildSpaceBar(LibrarySize, OtherSize, TotalSize) {
|
||||||
|
var newTable = document.createElement('table');
|
||||||
|
newTable.setAttribute('cellspacing', 0);
|
||||||
|
newTable.setAttribute('style', 'width: 100%; height: 10px;');
|
||||||
|
|
||||||
|
var newRow = document.createElement('tr');
|
||||||
|
|
||||||
|
var LibrarySizePercent = Math.floor(LibrarySize / TotalSize * 100);
|
||||||
|
var OtherSizePercent = Math.floor(OtherSize / TotalSize * 100);
|
||||||
|
var FreeSizePercent = Math.floor((LibrarySize + OtherSize) / TotalSize * 100);
|
||||||
|
|
||||||
|
var LibraryCell = document.createElement('td');
|
||||||
|
LibraryCell.setAttribute('style', 'width: ' + LibrarySizePercent + '%; background-color: green;');
|
||||||
|
|
||||||
|
var OtherCell = document.createElement('td');
|
||||||
|
OtherCell.setAttribute('style', 'width: ' + OtherSizePercent + '%; background-color: lightgreen;');
|
||||||
|
|
||||||
|
var FreeCell = document.createElement('td');
|
||||||
|
FreeCell.setAttribute('style', 'width: ' + FreeSizePercent + '%; background-color: lightgray;');
|
||||||
|
|
||||||
|
newRow.appendChild(LibraryCell);
|
||||||
|
newRow.appendChild(OtherCell);
|
||||||
|
newRow.appendChild(FreeCell);
|
||||||
|
|
||||||
|
newTable.appendChild(newRow);
|
||||||
|
|
||||||
|
return newTable;
|
||||||
|
}
|
||||||
|
|
||||||
|
function SystemSignaturesStatus() {
|
||||||
|
ajaxCall('/api/v1/Signatures/Status', 'GET', function (result) {
|
||||||
|
var newTable = document.createElement('table');
|
||||||
|
newTable.className = 'romtable';
|
||||||
|
newTable.setAttribute('cellspacing', 0);
|
||||||
|
newTable.appendChild(createTableRow(true, ['Sources', 'Platforms', 'Games', 'ROMs']));
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
var newRow = [
|
||||||
|
result.sources,
|
||||||
|
result.platforms,
|
||||||
|
result.games,
|
||||||
|
result.roms
|
||||||
|
];
|
||||||
|
newTable.appendChild(createTableRow(false, newRow, 'romrow', 'romcell'));
|
||||||
|
}
|
||||||
|
|
||||||
|
var targetDiv = document.getElementById('system_signatures');
|
||||||
|
targetDiv.innerHTML = '';
|
||||||
|
targetDiv.appendChild(newTable);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function StartProcess(itemType) {
|
||||||
|
ajaxCall('/api/v1/BackgroundTasks/' + itemType + '?ForceRun=true', 'GET', function (result) {
|
||||||
|
SystemLoadStatus();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
SystemLoadStatus();
|
||||||
|
setInterval(SystemLoadStatus, 30000);
|
||||||
|
SystemLoadSystemStatus();
|
||||||
|
setInterval(SystemLoadStatus, 60000);
|
||||||
|
SystemSignaturesStatus();
|
||||||
|
setInterval(SystemSignaturesStatus, 300000);
|
||||||
|
</script>
|
@@ -76,3 +76,27 @@ function randomIntFromInterval(min, max) { // min and max included
|
|||||||
var rand = Math.floor(Math.random() * (max - min + 1) + min);
|
var rand = Math.floor(Math.random() * (max - min + 1) + min);
|
||||||
return rand;
|
return rand;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createTableRow(isHeader, row, rowClass, cellClass) {
|
||||||
|
var newRow = document.createElement('tr');
|
||||||
|
newRow.className = rowClass;
|
||||||
|
|
||||||
|
for (var i = 0; i < row.length; i++) {
|
||||||
|
var cellType = 'td';
|
||||||
|
if (isHeader == true) {
|
||||||
|
cellType = 'th';
|
||||||
|
}
|
||||||
|
|
||||||
|
var newCell = document.createElement(cellType);
|
||||||
|
if (typeof(row[i]) != "object") {
|
||||||
|
newCell.innerHTML = row[i];
|
||||||
|
} else {
|
||||||
|
newCell.appendChild(row[i]);
|
||||||
|
}
|
||||||
|
newCell.className = cellClass;
|
||||||
|
|
||||||
|
newRow.appendChild(newCell);
|
||||||
|
}
|
||||||
|
|
||||||
|
return newRow;
|
||||||
|
}
|
@@ -83,11 +83,38 @@ h3 {
|
|||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#banner_icon:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
#banner_icon_image {
|
#banner_icon_image {
|
||||||
width: 30px;
|
width: 30px;
|
||||||
height: 30px;
|
height: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#banner_cog {
|
||||||
|
background-color: white;
|
||||||
|
position: fixed;
|
||||||
|
top: 0px;
|
||||||
|
right: 0px;
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 0px;
|
||||||
|
margin: 0px;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
#banner_cog:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
#banner_system_image {
|
||||||
|
height: 30px;
|
||||||
|
width: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
#banner_header {
|
#banner_header {
|
||||||
background-color: #001638;
|
background-color: #001638;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
@@ -66,6 +66,24 @@ namespace gaseous_tools
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public static long DirSize(DirectoryInfo d)
|
||||||
|
{
|
||||||
|
long size = 0;
|
||||||
|
// Add file sizes.
|
||||||
|
FileInfo[] fis = d.GetFiles();
|
||||||
|
foreach (FileInfo fi in fis)
|
||||||
|
{
|
||||||
|
size += fi.Length;
|
||||||
|
}
|
||||||
|
// Add subdirectory sizes.
|
||||||
|
DirectoryInfo[] dis = d.GetDirectories();
|
||||||
|
foreach (DirectoryInfo di in dis)
|
||||||
|
{
|
||||||
|
size += DirSize(di);
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user