Added a library scan button (#417)

This commit is contained in:
Michael Green
2024-09-06 01:59:59 +10:00
committed by GitHub
parent 68be24d514
commit f0783fcae8
5 changed files with 187 additions and 49 deletions

View File

@@ -175,6 +175,24 @@ namespace gaseous_server
}
}
public static LibraryItem ScanLibrary(int LibraryId)
{
// add the library to scan to the queue
LibraryItem library = GetLibrary(LibraryId);
ImportGame.LibrariesToScan.Add(library);
// start the library scan if it's not already running
foreach (ProcessQueue.QueueItem item in ProcessQueue.QueueItems)
{
if (item.ItemType == ProcessQueue.QueueItemType.LibraryScan && item.ItemState != ProcessQueue.QueueItemState.Running)
{
item.ForceExecute();
}
}
return library;
}
public class LibraryItem
{
public LibraryItem(int Id, string Name, string Path, long DefaultPlatformId, bool IsDefaultLibrary)

View File

@@ -523,61 +523,82 @@ namespace gaseous_server.Classes
}
}
public void LibraryScan(GameLibrary.LibraryItem? singleLibrary = null)
public static List<GameLibrary.LibraryItem> LibrariesToScan = new List<GameLibrary.LibraryItem>();
public void LibraryScan()
{
int maxWorkers = Config.MetadataConfiguration.MaxLibraryScanWorkers;
List<GameLibrary.LibraryItem> libraries = new List<GameLibrary.LibraryItem>();
if (singleLibrary == null)
if (LibrariesToScan.Count == 0)
{
libraries.AddRange(GameLibrary.GetLibraries);
}
else
{
libraries.Add(singleLibrary);
LibrariesToScan.AddRange(GameLibrary.GetLibraries);
}
// setup background tasks for each library
foreach (GameLibrary.LibraryItem library in libraries)
do
{
Logging.Log(Logging.LogType.Information, "Library Scan", "Starting worker process for library " + library.Name);
ProcessQueue.QueueItem queue = new ProcessQueue.QueueItem(
ProcessQueue.QueueItemType.LibraryScanWorker,
1,
new List<ProcessQueue.QueueItemType>
{
ProcessQueue.QueueItemType.OrganiseLibrary,
ProcessQueue.QueueItemType.Rematcher
},
false,
true);
queue.Options = library;
queue.ForceExecute();
Logging.Log(Logging.LogType.Information, "Library Scan", "Library scan queue size: " + LibrariesToScan.Count);
ProcessQueue.QueueItems.Add(queue);
GameLibrary.LibraryItem library = LibrariesToScan[0];
LibrariesToScan.RemoveAt(0);
// check number of running tasks is less than maxWorkers
bool allowContinue;
do
// check if library is already being scanned
bool libraryAlreadyScanning = false;
List<ProcessQueue.QueueItem> ProcessQueueItems = new List<ProcessQueue.QueueItem>();
ProcessQueueItems.AddRange(ProcessQueue.QueueItems);
foreach (ProcessQueue.QueueItem item in ProcessQueueItems)
{
allowContinue = true;
int currentWorkerCount = 0;
List<ProcessQueue.QueueItem> queueItems = new List<ProcessQueue.QueueItem>();
queueItems.AddRange(ProcessQueue.QueueItems);
foreach (ProcessQueue.QueueItem item in queueItems)
if (item.ItemType == ProcessQueue.QueueItemType.LibraryScanWorker)
{
if (item.ItemType == ProcessQueue.QueueItemType.LibraryScanWorker)
if (((GameLibrary.LibraryItem)item.Options).Id == library.Id)
{
currentWorkerCount += 1;
libraryAlreadyScanning = true;
}
}
if (currentWorkerCount >= maxWorkers)
}
if (libraryAlreadyScanning == false)
{
Logging.Log(Logging.LogType.Information, "Library Scan", "Starting worker process for library " + library.Name);
ProcessQueue.QueueItem queue = new ProcessQueue.QueueItem(
ProcessQueue.QueueItemType.LibraryScanWorker,
1,
new List<ProcessQueue.QueueItemType>
{
ProcessQueue.QueueItemType.OrganiseLibrary,
ProcessQueue.QueueItemType.Rematcher
},
false,
true)
{
allowContinue = false;
Thread.Sleep(60000);
}
} while (allowContinue == false);
}
Options = library
};
queue.ForceExecute();
ProcessQueue.QueueItems.Add(queue);
// check number of running tasks is less than maxWorkers
bool allowContinue;
do
{
allowContinue = true;
int currentWorkerCount = 0;
List<ProcessQueue.QueueItem> LibraryScan_QueueItems = new List<ProcessQueue.QueueItem>();
LibraryScan_QueueItems.AddRange(ProcessQueue.QueueItems);
foreach (ProcessQueue.QueueItem item in LibraryScan_QueueItems)
{
if (item.ItemType == ProcessQueue.QueueItemType.LibraryScanWorker)
{
currentWorkerCount += 1;
}
}
if (currentWorkerCount >= maxWorkers)
{
allowContinue = false;
Thread.Sleep(60000);
}
} while (allowContinue == false);
}
} while (LibrariesToScan.Count > 0);
bool WorkersStillWorking;
do
@@ -597,6 +618,12 @@ namespace gaseous_server.Classes
} while (WorkersStillWorking == true);
Logging.Log(Logging.LogType.Information, "Library Scan", "Library scan complete. All workers stopped");
if (LibrariesToScan.Count > 0)
{
Logging.Log(Logging.LogType.Information, "Library Scan", "There are still libraries to scan. Restarting scan process");
LibraryScan();
}
}
public void LibrarySpecificScan(GameLibrary.LibraryItem library)

View File

@@ -86,5 +86,24 @@ namespace gaseous_server.Controllers
return NotFound(exLNF.ToString());
}
}
[MapToApiVersion("1.0")]
[MapToApiVersion("1.1")]
[HttpPost("{LibraryId}/Scan")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public ActionResult ScanLibrary(int LibraryId)
{
try
{
GameLibrary.ScanLibrary(LibraryId);
return Ok();
}
catch (GameLibrary.LibraryNotFound exLNF)
{
return NotFound(exLNF.ToString());
}
}
}
}

View File

@@ -335,7 +335,14 @@
"Extensions": {
"SupportedFileExtensions": [
".CPC",
".DSK"
".DSK",
".SNA",
".TAP",
".CDT",
".VOC",
".M3U",
".CPR",
".ZIP"
],
"UniqueFileExtensions": [
".CPC"
@@ -343,9 +350,25 @@
},
"RetroPieDirectoryName": "amstradcpc",
"WebEmulator": {
"Type": "",
"Core": "",
"AvailableWebEmulators": []
"Type": "EmulatorJS",
"Core": "crocods",
"AvailableWebEmulators": [
{
"EmulatorType": "EmulatorJS",
"AvailableWebEmulatorCores": [
{
"Core": "crocods",
"AlternateCoreName": "",
"Default": true
},
{
"Core": "cap32",
"AlternateCoreName": "",
"Default": false
}
]
}
]
},
"Bios": []
},
@@ -3442,14 +3465,35 @@
"SFC"
],
"Extensions": {
"SupportedFileExtensions": [],
"SupportedFileExtensions": [
".7Z",
".BIN",
".BS",
".FIG",
".MGD",
".SFC",
".SMC",
".SWC",
".ZIP"
],
"UniqueFileExtensions": []
},
"RetroPieDirectoryName": "",
"RetroPieDirectoryName": "snes",
"WebEmulator": {
"Type": "",
"Core": "",
"AvailableWebEmulators": null
"Type": "EmulatorJS",
"Core": "snes",
"AvailableWebEmulators": [
{
"EmulatorType": "EmulatorJS",
"AvailableWebEmulatorCores": [
{
"Core": "snes",
"AlternateCoreName": "snes9x",
"Default": true
}
]
}
]
},
"Bios": []
},

View File

@@ -12,7 +12,7 @@ function drawLibrary() {
function (result) {
let newTable = document.getElementById('settings_libraries');
newTable.innerHTML = '';
newTable.appendChild(createTableRow(true, ['Name', 'Path', 'Default Platform', 'Default Library', '']));
newTable.appendChild(createTableRow(true, ['Name', 'Path', 'Default Platform', 'Default Library', '', '']));
for (let i = 0; i < result.length; i++) {
let platformName = '';
@@ -36,6 +36,35 @@ function drawLibrary() {
let controls = document.createElement('div');
controls.style.textAlign = 'right';
let scanButton = document.createElement('img');
scanButton.id = 'startProcess';
scanButton.className = 'taskstart';
scanButton.src = '/images/start-task.svg';
scanButton.title = 'Start Scan';
scanButton.addEventListener('click', function () {
let scanLibrary = new MessageBox('Scan Library', 'Are you sure you want to scan this library?');
scanLibrary.addButton(new ModalButton('OK', 2, scanLibrary, function (callingObject) {
ajaxCall(
'/api/v1.1/Library/' + result[i].id + '/Scan',
'POST',
function () {
callingObject.msgDialog.close();
drawLibrary();
},
function () {
callingObject.msgDialog.close();
drawLibrary();
}
);
}));
scanLibrary.addButton(new ModalButton('Cancel', 0, scanLibrary, function (callingObject) {
callingObject.msgDialog.close();
}));
scanLibrary.open();
});
let deleteButton = '';
if (result[i].isDefaultLibrary == false) {
deleteButton = document.createElement('a');
@@ -80,6 +109,7 @@ function drawLibrary() {
result[i].path,
platformName,
defaultLibrary,
scanButton,
controls
],
'romrow',