Add a Platform Map editor to the UI (#104)

This commit is contained in:
Michael Green
2023-09-18 01:24:44 +10:00
committed by GitHub
parent 61d9dd16eb
commit 09dece08f3
21 changed files with 1870 additions and 750 deletions

View File

@@ -437,7 +437,7 @@ namespace gaseous_server.Classes
case CollectionItem.FolderStructures.RetroPie: case CollectionItem.FolderStructures.RetroPie:
try try
{ {
PlatformMapping.PlatformMapItem platformMapItem = PlatformMapping.GetPlatformMappingByIGDBid(collectionPlatformItem.Id); PlatformMapping.PlatformMapItem platformMapItem = PlatformMapping.GetPlatformMap(collectionPlatformItem.Id);
ZipPlatformPath = Path.Combine(ZipFileTempPath, "roms", platformMapItem.RetroPieDirectoryName); ZipPlatformPath = Path.Combine(ZipFileTempPath, "roms", platformMapItem.RetroPieDirectoryName);
} }
catch catch

View File

@@ -22,7 +22,7 @@ namespace gaseous_server.Classes.Metadata
Config.IGDB.Secret Config.IGDB.Secret
); );
public static Platform? GetPlatform(long Id) public static Platform? GetPlatform(long Id, bool forceRefresh = false)
{ {
if (Id == 0) if (Id == 0)
{ {
@@ -46,18 +46,18 @@ namespace gaseous_server.Classes.Metadata
} }
else else
{ {
Task<Platform> RetVal = _GetPlatform(SearchUsing.id, Id); Task<Platform> RetVal = _GetPlatform(SearchUsing.id, Id, forceRefresh);
return RetVal.Result; return RetVal.Result;
} }
} }
public static Platform GetPlatform(string Slug) public static Platform GetPlatform(string Slug, bool forceRefresh = false)
{ {
Task<Platform> RetVal = _GetPlatform(SearchUsing.slug, Slug); Task<Platform> RetVal = _GetPlatform(SearchUsing.slug, Slug, forceRefresh);
return RetVal.Result; return RetVal.Result;
} }
private static async Task<Platform> _GetPlatform(SearchUsing searchUsing, object searchValue) private static async Task<Platform> _GetPlatform(SearchUsing searchUsing, object searchValue, bool forceRefresh)
{ {
// check database first // check database first
Storage.CacheStatus? cacheStatus = new Storage.CacheStatus(); Storage.CacheStatus? cacheStatus = new Storage.CacheStatus();
@@ -70,6 +70,11 @@ namespace gaseous_server.Classes.Metadata
cacheStatus = Storage.GetCacheStatus("Platform", (string)searchValue); cacheStatus = Storage.GetCacheStatus("Platform", (string)searchValue);
} }
if (forceRefresh == true)
{
if (cacheStatus == Storage.CacheStatus.Current) { cacheStatus = Storage.CacheStatus.Expired; }
}
// set up where clause // set up where clause
string WhereClause = ""; string WhereClause = "";
switch (searchUsing) switch (searchUsing)
@@ -91,11 +96,13 @@ namespace gaseous_server.Classes.Metadata
returnValue = await GetObjectFromServer(WhereClause); returnValue = await GetObjectFromServer(WhereClause);
Storage.NewCacheValue(returnValue); Storage.NewCacheValue(returnValue);
UpdateSubClasses(returnValue); UpdateSubClasses(returnValue);
AddPlatformMapping(returnValue);
return returnValue; return returnValue;
case Storage.CacheStatus.Expired: case Storage.CacheStatus.Expired:
returnValue = await GetObjectFromServer(WhereClause); returnValue = await GetObjectFromServer(WhereClause);
Storage.NewCacheValue(returnValue, true); Storage.NewCacheValue(returnValue, true);
UpdateSubClasses(returnValue); UpdateSubClasses(returnValue);
AddPlatformMapping(returnValue);
return returnValue; return returnValue;
case Storage.CacheStatus.Current: case Storage.CacheStatus.Current:
return Storage.GetCacheValue<Platform>(returnValue, "id", (long)searchValue); return Storage.GetCacheValue<Platform>(returnValue, "id", (long)searchValue);
@@ -120,6 +127,31 @@ namespace gaseous_server.Classes.Metadata
} }
} }
private static void AddPlatformMapping(Platform platform)
{
// ensure a mapping item exists for this platform
Models.PlatformMapping.PlatformMapItem item = new Models.PlatformMapping.PlatformMapItem();
try
{
Logging.Log(Logging.LogType.Information, "Platform Map", "Checking if " + platform.Name + " is in database.");
item = Models.PlatformMapping.GetPlatformMap((long)platform.Id);
// exists - skip
Logging.Log(Logging.LogType.Information, "Platform Map", "Skipping import of " + platform.Name + " - already in database.");
}
catch
{
Logging.Log(Logging.LogType.Information, "Platform Map", "Importing " + platform.Name + " from predefined data.");
// doesn't exist - add it
item = new Models.PlatformMapping.PlatformMapItem{
IGDBId = (long)platform.Id,
IGDBName = platform.Name,
IGDBSlug = platform.Slug,
AlternateNames = new List<string>{ platform.AlternativeName }
};
Models.PlatformMapping.WritePlatformMap(item, false);
}
}
private enum SearchUsing private enum SearchUsing
{ {
id, id,

View File

@@ -1,5 +1,6 @@
using System; using System;
using System.Data; using System.Data;
using gaseous_server.Models;
using gaseous_tools; using gaseous_tools;
namespace gaseous_server.Classes namespace gaseous_server.Classes
@@ -9,8 +10,29 @@ namespace gaseous_server.Classes
public static void RefreshMetadata(bool forceRefresh = false) public static void RefreshMetadata(bool forceRefresh = false)
{ {
Database db = new gaseous_tools.Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString); Database db = new gaseous_tools.Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
string sql = "SELECT Id, `Name` FROM Game;"; string sql = "";
DataTable dt = db.ExecuteCMD(sql); DataTable dt = new DataTable();
// update platforms
sql = "SELECT Id, `Name` FROM Platform;";
dt = db.ExecuteCMD(sql);
foreach (DataRow dr in dt.Rows)
{
try
{
Logging.Log(Logging.LogType.Information, "Metadata Refresh", "Refreshing metadata for platform " + dr["name"] + " (" + dr["id"] + ")");
Metadata.Platforms.GetPlatform((long)dr["id"], true);
}
catch (Exception ex)
{
Logging.Log(Logging.LogType.Critical, "Metadata Refresh", "An error occurred while refreshing metadata for " + dr["name"], ex);
}
}
// update games
sql = "SELECT Id, `Name` FROM Game;";
dt = db.ExecuteCMD(sql);
foreach (DataRow dr in dt.Rows) foreach (DataRow dr in dt.Rows)
{ {

View File

@@ -0,0 +1,166 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using gaseous_server.Classes.Metadata;
using gaseous_server.Models;
using gaseous_tools;
using IGDB.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.CodeAnalysis.Scripting;
namespace gaseous_server.Controllers
{
[Route("api/v1/[controller]")]
[ApiController]
public class PlatformMapsController : Controller
{
[HttpGet]
[ProducesResponseType(typeof(List<PlatformMapping.PlatformMapItem>), StatusCodes.Status200OK)]
public ActionResult GetPlatformMap(bool ResetToDefault = false)
{
if (ResetToDefault == true)
{
PlatformMapping.ExtractPlatformMap(true);
}
return Ok(PlatformMapping.PlatformMap);
}
[HttpGet]
[Route("{PlatformId}")]
[ProducesResponseType(typeof(PlatformMapping.PlatformMapItem), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public ActionResult PlatformMap(long PlatformId)
{
try
{
PlatformMapping.PlatformMapItem platformMapItem = PlatformMapping.GetPlatformMap(PlatformId);
if (platformMapItem != null)
{
return Ok(platformMapItem);
}
else
{
return NotFound();
}
}
catch
{
return NotFound();
}
}
[HttpPost]
[ProducesResponseType(typeof(List<IFormFile>), StatusCodes.Status200OK)]
[RequestSizeLimit(long.MaxValue)]
[DisableRequestSizeLimit, RequestFormLimits(MultipartBodyLengthLimit = long.MaxValue, ValueLengthLimit = int.MaxValue)]
public async Task<IActionResult> UploadPlatformMap(List<IFormFile> files)
{
Guid sessionid = Guid.NewGuid();
string workPath = Path.Combine(Config.LibraryConfiguration.LibraryUploadDirectory, sessionid.ToString());
long size = files.Sum(f => f.Length);
List<Dictionary<string, object>> UploadedFiles = new List<Dictionary<string, object>>();
foreach (IFormFile formFile in files)
{
if (formFile.Length > 0)
{
Guid FileId = Guid.NewGuid();
string filePath = Path.Combine(workPath, Path.GetFileName(formFile.FileName));
if (!Directory.Exists(workPath))
{
Directory.CreateDirectory(workPath);
}
using (var stream = System.IO.File.Create(filePath))
{
await formFile.CopyToAsync(stream);
Dictionary<string, object> UploadedFile = new Dictionary<string, object>();
UploadedFile.Add("id", FileId.ToString());
UploadedFile.Add("originalname", Path.GetFileName(formFile.FileName));
UploadedFile.Add("fullpath", filePath);
UploadedFiles.Add(UploadedFile);
}
}
}
// Process uploaded files
foreach (Dictionary<string, object> UploadedFile in UploadedFiles)
{
Models.PlatformMapping.ExtractPlatformMap((string)UploadedFile["fullpath"]);
}
if (Directory.Exists(workPath))
{
Directory.Delete(workPath, true);
}
return Ok(new { count = files.Count, size });
}
[HttpPost]
[Route("{PlatformId}")]
[ProducesResponseType(typeof(PlatformMapping.PlatformMapItem), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status409Conflict)]
public ActionResult NewPlatformMap(long PlatformId, PlatformMapping.PlatformMapItem Map)
{
try
{
PlatformMapping.PlatformMapItem platformMapItem = PlatformMapping.GetPlatformMap(PlatformId);
if (platformMapItem != null)
{
return Conflict();
}
else
{
PlatformMapping.WritePlatformMap(Map, false);
return Ok(PlatformMapping.GetPlatformMap(PlatformId));
}
}
catch
{
return NotFound();
}
}
[HttpPatch]
[Route("{PlatformId}")]
[ProducesResponseType(typeof(PlatformMapping.PlatformMapItem), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public ActionResult EditPlatformMap(long PlatformId, PlatformMapping.PlatformMapItem Map)
{
try
{
PlatformMapping.PlatformMapItem platformMapItem = PlatformMapping.GetPlatformMap(PlatformId);
if (platformMapItem != null)
{
PlatformMapping.WritePlatformMap(Map, true);
return Ok(PlatformMapping.GetPlatformMap(PlatformId));
}
else
{
return NotFound();
}
}
catch
{
return NotFound();
}
}
}
}

View File

@@ -6,6 +6,7 @@ using System.Linq;
using System.Reflection; using System.Reflection;
using System.Threading.Tasks; using System.Threading.Tasks;
using gaseous_server.Classes.Metadata; using gaseous_server.Classes.Metadata;
using gaseous_server.Models;
using gaseous_tools; using gaseous_tools;
using IGDB.Models; using IGDB.Models;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
@@ -21,6 +22,11 @@ namespace gaseous_server.Controllers
[HttpGet] [HttpGet]
[ProducesResponseType(typeof(List<Platform>), StatusCodes.Status200OK)] [ProducesResponseType(typeof(List<Platform>), StatusCodes.Status200OK)]
public ActionResult Platform() public ActionResult Platform()
{
return Ok(PlatformsController.GetPlatforms());
}
public static List<Platform> GetPlatforms()
{ {
Database db = new gaseous_tools.Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString); Database db = new gaseous_tools.Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
@@ -34,7 +40,7 @@ namespace gaseous_server.Controllers
RetVal.Add(Classes.Metadata.Platforms.GetPlatform((long)dr["id"])); RetVal.Add(Classes.Metadata.Platforms.GetPlatform((long)dr["id"]));
} }
return Ok(RetVal); return RetVal;
} }
[HttpGet] [HttpGet]

View File

@@ -1,49 +1,309 @@
using System; using System;
using System.Collections;
using System.Data;
using System.Linq;
using System.Reflection; using System.Reflection;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using gaseous_server.Classes; using gaseous_server.Classes;
using gaseous_server.Classes.Metadata;
using gaseous_server.Controllers;
using gaseous_tools;
using IGDB.Models;
using Newtonsoft.Json;
namespace gaseous_server.Models namespace gaseous_server.Models
{ {
public class PlatformMapping public class PlatformMapping
{ {
public PlatformMapping() /// <summary>
/// Updates the platform map from the embedded platform map resource
/// </summary>
public static void ExtractPlatformMap(bool ResetToDefault = false)
{ {
using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("gaseous_server.Support.PlatformMap.json"))
using (StreamReader reader = new StreamReader(stream))
{
string rawJson = reader.ReadToEnd();
List<PlatformMapItem> platforms = new List<PlatformMapItem>();
platforms = Newtonsoft.Json.JsonConvert.DeserializeObject<List<PlatformMapItem>>(rawJson);
foreach (PlatformMapItem mapItem in platforms)
{
// check if it exists first - only add if it doesn't exist
try
{
Logging.Log(Logging.LogType.Information, "Platform Map", "Checking if " + mapItem.IGDBName + " is in database.");
PlatformMapItem item = GetPlatformMap(mapItem.IGDBId);
// exists
if (ResetToDefault == false)
{
Logging.Log(Logging.LogType.Information, "Platform Map", "Skipping import of " + mapItem.IGDBName + " - already in database.");
}
else
{
WritePlatformMap(mapItem, true);
Logging.Log(Logging.LogType.Information, "Platform Map", "Overwriting " + mapItem.IGDBName + " with default values.");
}
}
catch
{
Logging.Log(Logging.LogType.Information, "Platform Map", "Importing " + mapItem.IGDBName + " from predefined data.");
// doesn't exist - add it
WritePlatformMap(mapItem, false);
}
}
}
} }
//private static List<PlatformMapItem> _PlatformMaps = new List<PlatformMapItem>(); /// <summary>
/// Updates the platform map from the provided file - existing items are overwritten
/// </summary>
/// <param name="ImportFile"></param>
public static void ExtractPlatformMap(string ImportFile)
{
string rawJson = File.ReadAllText(ImportFile);
List<PlatformMapItem> platforms = new List<PlatformMapItem>();
platforms = Newtonsoft.Json.JsonConvert.DeserializeObject<List<PlatformMapItem>>(rawJson);
foreach (PlatformMapItem mapItem in platforms)
{
try
{
PlatformMapItem item = GetPlatformMap(mapItem.IGDBId);
// still here? we must have found the item we're looking for! overwrite it
Logging.Log(Logging.LogType.Information, "Platform Map", "Replacing " + mapItem.IGDBName + " from external JSON file.");
WritePlatformMap(mapItem, true);
}
catch
{
// we caught a not found error, insert a new record
Logging.Log(Logging.LogType.Information, "Platform Map", "Importing " + mapItem.IGDBName + " from external JSON file.");
WritePlatformMap(mapItem, false);
}
}
}
public static List<PlatformMapItem> PlatformMap public static List<PlatformMapItem> PlatformMap
{ {
get get
{ {
// load platform maps from: gaseous_server.Support.PlatformMap.json Database db = new gaseous_tools.Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
List<PlatformMapItem> _PlatformMaps = new List<PlatformMapItem>(); string sql = "SELECT * FROM PlatformMap";
var assembly = Assembly.GetExecutingAssembly(); DataTable data = db.ExecuteCMD(sql);
var resourceName = "gaseous_server.Support.PlatformMap.json";
using (Stream stream = assembly.GetManifestResourceStream(resourceName)) List<PlatformMapItem> platformMaps = new List<PlatformMapItem>();
using (StreamReader reader = new StreamReader(stream)) foreach (DataRow row in data.Rows)
{ {
string rawJson = reader.ReadToEnd(); platformMaps.Add(BuildPlatformMapItem(row));
_PlatformMaps.Clear();
_PlatformMaps = Newtonsoft.Json.JsonConvert.DeserializeObject<List<PlatformMapItem>>(rawJson);
} }
return _PlatformMaps; platformMaps.Sort((x, y) => x.IGDBName.CompareTo(y.IGDBName));
return platformMaps;
} }
} }
public static PlatformMapItem GetPlatformMappingByIGDBid(long Id) public static PlatformMapItem GetPlatformMap(long Id)
{ {
foreach (Models.PlatformMapping.PlatformMapItem platformMapping in PlatformMap) Database db = new gaseous_tools.Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
string sql = "SELECT * FROM PlatformMap WHERE Id = @Id";
Dictionary<string, object> dbDict = new Dictionary<string, object>();
dbDict.Add("Id", Id);
DataTable data = db.ExecuteCMD(sql, dbDict);
if (data.Rows.Count > 0)
{ {
if (platformMapping.IGDBId == Id) PlatformMapItem platformMap = BuildPlatformMapItem(data.Rows[0]);
return platformMap;
}
else
{
throw new Exception("");
}
}
public static void WritePlatformMap(PlatformMapItem item, bool Update)
{
Database db = new gaseous_tools.Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
string sql = "";
Dictionary<string, object> dbDict = new Dictionary<string, object>();
if (Update == false)
{
// insert
sql = "INSERT INTO PlatformMap (Id, RetroPieDirectoryName, WebEmulator_Type, WebEmulator_Core) VALUES (@Id, @RetroPieDirectoryName, @WebEmulator_Type, @WebEmulator_Core)";
}
else
{
// update
sql = "UPDATE PlatformMap SET RetroPieDirectoryName=@RetroPieDirectoryName, WebEmulator_Type=@WebEmulator_Type, WebEmulator_Core=@WebEmulator_Core WHERE Id = @Id";
}
dbDict.Add("Id", item.IGDBId);
dbDict.Add("RetroPieDirectoryName", item.RetroPieDirectoryName);
if (item.WebEmulator != null)
{
dbDict.Add("WebEmulator_Type", item.WebEmulator.Type);
dbDict.Add("WebEmulator_Core", item.WebEmulator.Core);
}
else
{
dbDict.Add("WebEmulator_Type", "");
dbDict.Add("WebEmulator_Core", "");
}
db.ExecuteCMD(sql, dbDict);
// remove existing items so they can be re-inserted
sql = "DELETE FROM PlatformMap_AlternateNames WHERE Id = @Id; DELETE FROM PlatformMap_Extensions WHERE Id = @Id; DELETE FROM PlatformMap_UniqueExtensions WHERE Id = @Id; DELETE FROM PlatformMap_Bios WHERE Id = @Id;";
db.ExecuteCMD(sql, dbDict);
// insert alternate names
if (item.AlternateNames != null)
{
foreach (string alternateName in item.AlternateNames)
{ {
return platformMapping; sql = "INSERT INTO PlatformMap_AlternateNames (Id, Name) VALUES (@Id, @Name);";
dbDict.Clear();
dbDict.Add("Id", item.IGDBId);
dbDict.Add("Name", alternateName);
db.ExecuteCMD(sql, dbDict);
} }
} }
throw new Exception("Platform id not found"); // insert extensions
if (item.Extensions != null)
{
foreach (string extension in item.Extensions.SupportedFileExtensions)
{
sql = "INSERT INTO PlatformMap_Extensions (Id, Extension) VALUES (@Id, @Extension);";
dbDict.Clear();
dbDict.Add("Id", item.IGDBId);
dbDict.Add("Extension", extension);
db.ExecuteCMD(sql, dbDict);
}
// delete duplicates
sql = "DELETE FROM PlatformMap_UniqueExtensions; INSERT INTO PlatformMap_UniqueExtensions SELECT * FROM PlatformMap_Extensions WHERE Extension IN (SELECT Extension FROM PlatformMap_Extensions GROUP BY Extension HAVING COUNT(Extension) = 1);";
db.ExecuteCMD(sql);
}
// insert bios
if (item.Bios != null)
{
foreach (PlatformMapItem.EmulatorBiosItem biosItem in item.Bios)
{
sql = "INSERT INTO PlatformMap_Bios (Id, Filename, Description, Hash) VALUES (@Id, @Filename, @Description, @Hash);";
dbDict.Clear();
dbDict.Add("Id", item.IGDBId);
dbDict.Add("Filename", biosItem.filename);
dbDict.Add("Description", biosItem.description);
dbDict.Add("Hash", biosItem.hash);
db.ExecuteCMD(sql, dbDict);
}
}
}
static PlatformMapItem BuildPlatformMapItem(DataRow row)
{
long IGDBId = (long)row["Id"];
Database db = new gaseous_tools.Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
Dictionary<string, object> dbDict = new Dictionary<string, object>();
string sql = "";
// get platform data
IGDB.Models.Platform platform = Platforms.GetPlatform(IGDBId);
// get platform alternate names
sql = "SELECT * FROM PlatformMap_AlternateNames WHERE Id = @Id ORDER BY Name";
dbDict.Clear();
dbDict.Add("Id", IGDBId);
DataTable altTable = db.ExecuteCMD(sql, dbDict);
List<string> alternateNames = new List<string>();
foreach (DataRow altRow in altTable.Rows)
{
string altVal = (string)altRow["Name"];
if (!alternateNames.Contains(altVal, StringComparer.OrdinalIgnoreCase))
{
alternateNames.Add(altVal);
}
}
if (platform.AlternativeName != null)
{
if (!alternateNames.Contains(platform.AlternativeName, StringComparer.OrdinalIgnoreCase))
{
alternateNames.Add(platform.AlternativeName);
}
}
// get platform known extensions
sql = "SELECT * FROM PlatformMap_Extensions WHERE Id = @Id ORDER BY Extension";
dbDict.Clear();
dbDict.Add("Id", IGDBId);
DataTable extTable = db.ExecuteCMD(sql, dbDict);
List<string> knownExtensions = new List<string>();
foreach (DataRow extRow in extTable.Rows)
{
string extVal = (string)extRow["Extension"];
if (!knownExtensions.Contains(extVal, StringComparer.OrdinalIgnoreCase))
{
knownExtensions.Add(extVal);
}
}
// get platform unique extensions
sql = "SELECT * FROM PlatformMap_UniqueExtensions WHERE Id = @Id ORDER BY Extension";
dbDict.Clear();
dbDict.Add("Id", IGDBId);
DataTable uextTable = db.ExecuteCMD(sql, dbDict);
List<string> uniqueExtensions = new List<string>();
foreach (DataRow uextRow in uextTable.Rows)
{
string uextVal = (string)uextRow["Extension"];
if (!uniqueExtensions.Contains(uextVal, StringComparer.OrdinalIgnoreCase))
{
uniqueExtensions.Add(uextVal);
}
}
// get platform bios
sql = "SELECT * FROM PlatformMap_Bios WHERE Id = @Id ORDER BY Filename";
dbDict.Clear();
dbDict.Add("Id", IGDBId);
DataTable biosTable = db.ExecuteCMD(sql, dbDict);
List<PlatformMapItem.EmulatorBiosItem> bioss = new List<PlatformMapItem.EmulatorBiosItem>();
foreach (DataRow biosRow in biosTable.Rows)
{
PlatformMapItem.EmulatorBiosItem bios = new PlatformMapItem.EmulatorBiosItem
{
filename = (string)Common.ReturnValueIfNull(biosRow["Filename"], ""),
description = (string)Common.ReturnValueIfNull(biosRow["Description"], ""),
hash = (string)Common.ReturnValueIfNull(biosRow["Hash"], "")
};
bioss.Add(bios);
}
// build item
PlatformMapItem mapItem = new PlatformMapItem();
mapItem.IGDBId = IGDBId;
mapItem.IGDBName = platform.Name;
mapItem.IGDBSlug = platform.Slug;
mapItem.AlternateNames = alternateNames;
mapItem.Extensions = new PlatformMapItem.FileExtensions{
SupportedFileExtensions = knownExtensions,
UniqueFileExtensions = uniqueExtensions
};
mapItem.RetroPieDirectoryName = (string)Common.ReturnValueIfNull(row["RetroPieDirectoryName"], "");
mapItem.WebEmulator = new PlatformMapItem.WebEmulatorItem{
Type = (string)Common.ReturnValueIfNull(row["WebEmulator_Type"], ""),
Core = (string)Common.ReturnValueIfNull(row["WebEmulator_Core"], "")
};
mapItem.Bios = bioss;
return mapItem;
} }
public static void GetIGDBPlatformMapping(ref Models.Signatures_Games Signature, FileInfo RomFileInfo, bool SetSystemName) public static void GetIGDBPlatformMapping(ref Models.Signatures_Games Signature, FileInfo RomFileInfo, bool SetSystemName)
@@ -51,17 +311,20 @@ namespace gaseous_server.Models
bool PlatformFound = false; bool PlatformFound = false;
foreach (Models.PlatformMapping.PlatformMapItem PlatformMapping in Models.PlatformMapping.PlatformMap) foreach (Models.PlatformMapping.PlatformMapItem PlatformMapping in Models.PlatformMapping.PlatformMap)
{ {
if (PlatformMapping.KnownFileExtensions.Contains(RomFileInfo.Extension, StringComparer.OrdinalIgnoreCase)) if (PlatformMapping.Extensions != null)
{ {
if (SetSystemName == true) if (PlatformMapping.Extensions.UniqueFileExtensions.Contains(RomFileInfo.Extension, StringComparer.OrdinalIgnoreCase))
{ {
if (Signature.Game != null) { Signature.Game.System = PlatformMapping.IGDBName; } if (SetSystemName == true)
} {
Signature.Flags.IGDBPlatformId = PlatformMapping.IGDBId; if (Signature.Game != null) { Signature.Game.System = PlatformMapping.IGDBName; }
Signature.Flags.IGDBPlatformName = PlatformMapping.IGDBName; }
Signature.Flags.IGDBPlatformId = PlatformMapping.IGDBId;
Signature.Flags.IGDBPlatformName = PlatformMapping.IGDBName;
PlatformFound = true; PlatformFound = true;
break; break;
}
} }
} }
@@ -90,10 +353,19 @@ namespace gaseous_server.Models
public class PlatformMapItem public class PlatformMapItem
{ {
public int IGDBId { get; set; } public long IGDBId { get; set; }
public string IGDBName { get; set; } public string IGDBName { get; set; }
public string IGDBSlug { get; set; }
public List<string> AlternateNames { get; set; } = new List<string>(); public List<string> AlternateNames { get; set; } = new List<string>();
public List<string> KnownFileExtensions { get; set; } = new List<string>();
public FileExtensions Extensions { get; set; }
public class FileExtensions
{
public List<string> SupportedFileExtensions { get; set; } = new List<string>();
public List<string> UniqueFileExtensions { get; set; } = new List<string>();
}
public string RetroPieDirectoryName { get; set; } public string RetroPieDirectoryName { get; set; }
public WebEmulatorItem? WebEmulator { get; set; } public WebEmulatorItem? WebEmulator { get; set; }

View File

@@ -1,6 +1,7 @@
using System.Reflection; using System.Reflection;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using gaseous_server; using gaseous_server;
using gaseous_server.Models;
using gaseous_server.SignatureIngestors.XML; using gaseous_server.SignatureIngestors.XML;
using gaseous_tools; using gaseous_tools;
using Microsoft.AspNetCore.Http.Features; using Microsoft.AspNetCore.Http.Features;
@@ -141,8 +142,8 @@ Config.LibraryConfiguration.InitLibrary();
gaseous_server.Classes.Metadata.Games.GetGame(0, false, false, false); gaseous_server.Classes.Metadata.Games.GetGame(0, false, false, false);
gaseous_server.Classes.Metadata.Platforms.GetPlatform(0); gaseous_server.Classes.Metadata.Platforms.GetPlatform(0);
// organise library // extract platform map if not present
//gaseous_server.Classes.ImportGame.OrganiseLibrary(); PlatformMapping.ExtractPlatformMap();
// add background tasks // add background tasks
ProcessQueue.QueueItems.Add(new ProcessQueue.QueueItem(ProcessQueue.QueueItemType.SignatureIngestor, 60)); ProcessQueue.QueueItems.Add(new ProcessQueue.QueueItem(ProcessQueue.QueueItemType.SignatureIngestor, 60));

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M10 7L8.364 1H2.636L1 7zM7.6 2l1.09 4H2.31L3.4 2zm8.036 15l-.818 3H6v-7h8.545L14 15h9l-1.636-6h-5.728l-.818 3H6V9h4l-.273-1H1.273L1 9h4v12h9.545L14 23h9l-1.636-6zm.764-7h4.2l1.09 4h-6.38zm-1.09 12l1.09-4h4.2l1.09 4z"/><path fill="none" d="M0 0h24v24H0z"/></svg>

After

Width:  |  Height:  |  Size: 478 B

View File

@@ -12,6 +12,7 @@
<script src="/scripts/jquery.lazy.plugins.min.js"></script> <script src="/scripts/jquery.lazy.plugins.min.js"></script>
<script src="/scripts/select2.min.js"></script> <script src="/scripts/select2.min.js"></script>
<script src="/scripts/dropzone.min.js"></script> <script src="/scripts/dropzone.min.js"></script>
<script src="/scripts/simpleUpload.min.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>

View File

@@ -0,0 +1,257 @@
<div style="position: absolute; top: 60px; left: 10px; right: 10px; bottom: 40px; overflow-x: scroll;">
<div style="width: 985px;">
<h3>Title Matching</h3>
<table style="width: 100%;">
<tr>
<td style="width: 25%; vertical-align: top;">
<h4>Alternative Names</h4>
</td>
<td>
<select id="mapping_edit_alternativenames" multiple="multiple" style="width: 100%;"></select>
</td>
</tr>
<tr>
<td style="width: 25%; vertical-align: top;">
<h4>Supported File Extensions</h4>
</td>
<td>
<select id="mapping_edit_supportedfileextensions" multiple="multiple" style="width: 100%;"></select>
</td>
</tr>
</table>
<h3>Collections</h3>
<table style="width: 100%;">
<tr>
<td style="width: 25%;">
<h4>Standard Directory Naming</h4>
</td>
<td style="text-align: right;">
<input id="mapping_edit_igdbslug" readonly="readonly" type="text" style="width: 95%;"/>
</td>
</tr>
<tr>
<td colspan="2"><strong>Note</strong>: Standard directory naming uses the IGDB slug for the platform is not editable.</td>
</tr>
<tr>
<td>
<h4>RetroPie Directory Naming</h4>
</td>
<td style="text-align: right;">
<input id="mapping_edit_retropie" type="text" style="width: 95%;"/>
</td>
</tr>
</table>
<h3>Web Emulator</h3>
<table style="width: 100%;">
<tr>
<td style="width: 25%;">
<h4>Web Emulator</h4>
</td>
<td>
<input id="mapping_edit_enablewebemulator" type="checkbox"><label for="mapping_edit_enablewebemulator" style="margin-left: 5px;">Enabled</label>
</td>
</tr>
<tr>
<td style="width: 25%;">
<h4>Engine</h4>
</td>
<td>
<select id="mapping_edit_webemulatorengine" style="width: 100%;">
<option value="">-</option>
<option value="EmulatorJS">EmulatorJS</option>
</select>
</td>
</tr>
<tr>
<td style="width: 25%;">
<h4>Core</h4>
</td>
<td style="text-align: right;">
<input id="mapping_edit_webemulatorcore" type="text" style="width: 95%;"/>
</td>
</tr>
</table>
<h3>BIOS/Firmware</h3>
<div id="mapping_edit_bios"></div>
</div>
</div>
<div style="position: absolute; height: 35px; left: 10px; right: 10px; bottom: 0px; text-align: right;">
<button value="Ok" onclick="SubmitMappingItem();">Ok</button>
</div>
<script type="text/javascript">
var modalContent = document.getElementsByClassName('modal-content');
if (!modalContent[0].classList.contains('collections_modal')) {
modalContent[0].classList.add('collections_modal');
}
ajaxCall(
'/api/v1/PlatformMaps/' + modalVariables,
'GET',
function (result) {
// set heading
document.getElementById('modal-heading').innerHTML = result.igdbName;
// populate page
$('#mapping_edit_alternativenames').select2 ({
tags: true,
tokenSeparators: [',']
});
AddTokensFromList('#mapping_edit_alternativenames', result.alternateNames);
$('#mapping_edit_supportedfileextensions').select2 ({
tags: true,
tokenSeparators: [','],
createTag: function (params) {
if (params.term.indexOf('.') === -1) {
// Return null to disable tag creation
return null;
}
return {
id: params.term.toUpperCase(),
text: params.term.toUpperCase()
}
}
});
AddTokensFromList('#mapping_edit_supportedfileextensions', result.extensions.supportedFileExtensions);
document.getElementById('mapping_edit_igdbslug').value = result.igdbSlug;
document.getElementById('mapping_edit_retropie').value = result.retroPieDirectoryName;
$('#mapping_edit_webemulatorengine').select2();
if (result.webEmulator.type.length > 0) {
document.getElementById('mapping_edit_enablewebemulator').checked = true;
$('#mapping_edit_webemulatorengine').val(result.webEmulator.type);
$('#mapping_edit_webemulatorengine').trigger('change');
document.getElementById('mapping_edit_webemulatorcore').value = result.webEmulator.core;
} else {
document.getElementById('mapping_edit_enablewebemulator').checked = false;
}
var biosTableHeaders = [
{
"name": "filename",
"label": "Filename"
},
{
"name": "description",
"label": "Description"
},
{
"name": "hash",
"label": "MD5 Hash"
}
];
document.getElementById('mapping_edit_bios').appendChild(
CreateEditableTable(
'bios',
biosTableHeaders
)
);
LoadEditableTableData('bios', biosTableHeaders, result.bios);
}
);
function AddTokensFromList(selectObj, tagList) {
for (var i = 0; i < tagList.length; i++) {
var data = {
id: tagList[i],
text: tagList[i]
}
var newOption = new Option(data.text, data.id, true, true);
$(selectObj).append(newOption).trigger('change');
}
}
function SubmitMappingItem() {
var alternateNames = [];
for (var i = 0; i < document.getElementById('mapping_edit_alternativenames').childNodes.length; i++) {
var optionObj = document.getElementById('mapping_edit_alternativenames').childNodes[i];
alternateNames.push(optionObj.innerHTML);
}
var knownExtensions = $('#mapping_edit_supportedfileextensions').val();
var extensions = {
"IGDBId": modalVariables,
"supportedFileExtensions": knownExtensions,
"uniqueFileExtensions": knownExtensions
};
var emulator = null;
if (document.getElementById('mapping_edit_enablewebemulator').checked == true) {
emulator = {
"type": document.getElementById('mapping_edit_webemulatorengine').value,
"core": document.getElementById('mapping_edit_webemulatorcore').value
};
}
var bios = [];
var biosTable = document.getElementById('EditableTable_bios');
// get rows
for (var i = 0; i < biosTable.childNodes.length; i++) {
var rowObj = biosTable.childNodes[i];
var biosObj = {};
var addBiosObj = false;
// get cells
for (var v = 0; v < rowObj.childNodes.length; v++) {
var cell = rowObj.childNodes[v];
if (cell.tagName.toLowerCase() != 'th') {
// get input boxes
for (var c = 0; c < cell.childNodes.length; c++) {
var element = cell.childNodes[c];
if (element) {
if (element.getAttribute('data-cell')) {
var nodeName = element.getAttribute('data-cell');
biosObj[nodeName] = element.value;
addBiosObj = true;
break;
}
}
}
}
}
if (addBiosObj == true) {
bios.push(biosObj);
}
}
var item = {
"igdbId": Number(modalVariables),
"igdbName": document.getElementById('modal-heading').innerHTML,
"igdbSlug": document.getElementById('mapping_edit_igdbslug').value,
"alternateNames": alternateNames,
"extensions": extensions,
"retroPieDirectoryName": document.getElementById('mapping_edit_retropie').value,
"webEmulator": emulator,
"bios": bios
};
console.log(JSON.stringify(item));
ajaxCall(
'/api/v1/PlatformMaps/' + modalVariables,
'PATCH',
function (result) {
loadPlatformMapping();
closeDialog();
},
function (error) {
console.error(JSON.stringify(error));
},
JSON.stringify(item)
);
}
</script>

View File

@@ -368,7 +368,7 @@
var platformRow = document.createElement('tr'); var platformRow = document.createElement('tr');
var platformHeader = document.createElement('th'); var platformHeader = document.createElement('th');
platformHeader.setAttribute('colspan', 6); platformHeader.setAttribute('colspan', 6);
platformHeader.innerHTML = '<a href="#" onclick="ShowCollectionDialog(' + result[i].platform.id + ');" style="float: right; text-decoration: none;" class="romlink"><img src="/images/collections.svg" class="banner_button_image banner_button_image_smaller" alt="Add to collection" title="Add to collection" /></a>' + result[i].platform.name; platformHeader.innerHTML = '<a href="#" onclick="ShowPlatformMappingDialog(' + result[i].platform.id + ');" style="float: right; text-decoration: none;" class="romlink"><img src="/images/map.svg" class="banner_button_image banner_button_image_smaller" alt="Edit platform mapping" title="Edit platform mapping" /></a><a href="#" onclick="ShowCollectionDialog(' + result[i].platform.id + ');" style="float: right; text-decoration: none;" class="romlink"><img src="/images/collections.svg" class="banner_button_image banner_button_image_smaller" alt="Add to collection" title="Add to collection" /></a>' + result[i].platform.name;
platformRow.appendChild(platformHeader); platformRow.appendChild(platformHeader);
newTable.appendChild(platformRow); newTable.appendChild(platformRow);
} }

View File

@@ -6,6 +6,7 @@
<div id="properties_toc" class="settings_toc"> <div id="properties_toc" class="settings_toc">
<div class="filter_header">Settings</div> <div class="filter_header">Settings</div>
<div id="properties_toc_system" name="properties_toc_item" onclick="SelectTab('system');">System</div> <div id="properties_toc_system" name="properties_toc_item" onclick="SelectTab('system');">System</div>
<div id="properties_toc_mapping" name="properties_toc_item" onclick="SelectTab('mapping');">Platform Mapping</div>
<div id="properties_toc_bios" name="properties_toc_item" onclick="SelectTab('bios');">Firmware</div> <div id="properties_toc_bios" name="properties_toc_item" onclick="SelectTab('bios');">Firmware</div>
<div id="properties_toc_logs" name="properties_toc_item" onclick="SelectTab('logs');">Logs</div> <div id="properties_toc_logs" name="properties_toc_item" onclick="SelectTab('logs');">Logs</div>
<div id="properties_toc_about" name="properties_toc_item" onclick="SelectTab('about');">About</div> <div id="properties_toc_about" name="properties_toc_item" onclick="SelectTab('about');">About</div>

View File

@@ -31,7 +31,7 @@
for (var i = 0; i < result.length; i++) { for (var i = 0; i < result.length; i++) {
var exceptionString = ''; var exceptionString = '';
if (result[i].exceptionValue) { if (result[i].exceptionValue) {
exceptionString = "<h3>Exception</h3><pre class='logs_table_exception'>" + syntaxHighlight(JSON.stringify(result[i].exceptionValue, null, 2)) + "</pre>"; exceptionString = "<h3>Exception</h3><pre class='logs_table_exception'>" + syntaxHighlight(JSON.stringify(result[i].exceptionValue, null, 2)).replace(/\\n/g, "<br /> ") + "</pre>";
} }
var newRow = [ var newRow = [

View File

@@ -0,0 +1,87 @@
<div id="gametitle">
<h1 id="gametitle_label">Platform Mapping</h1>
</div>
<p>When determining the platform of a ROM or image (which is later used when determining the game title), only the "Unique File Extensions" are used. All other extensions are ignored as they will limit the ability of Gaseous to determine the game title (see <a href="https://github.com/gaseous-project/gaseous-server#game-image-title-matching" class="romlink">https://github.com/gaseous-project/gaseous-server#game-image-title-matching</a> for more information on how matching works).</p>
<p>This list is pre-populated with some of the more common platforms. New platforms will appear in this list as titles are added.</p>
<p><button value="Export to JSON" onclick="DownloadJSON();">Export to JSON</button><button id="importjson" value="Import JSON">Import JSON</button><button value="Reset to Default" onclick="loadPlatformMapping(true);">Reset to Default</button></p>
<input id='uploadjson' type='file' name='files' hidden/>
<table id="settings_mapping_table" style="width: 100%;" cellspacing="0">
</table>
<script type="text/javascript">
function loadPlatformMapping(Overwrite) {
var queryString = '';
if (Overwrite == true) {
queryString = '?ResetToDefault=true';
}
ajaxCall(
'/api/v1/PlatformMaps' + queryString,
'GET',
function (result) {
var newTable = document.getElementById('settings_mapping_table');
newTable.innerHTML = '';
newTable.appendChild(
createTableRow(
true,
[
'Platform',
'Supported File Extensions',
'Unique File Extensions',
'Has Web Emulator'
],
'',
''
)
);
for (var i = 0; i < result.length; i++) {
var hasWebEmulator = '';
if (result[i].webEmulator.type.length > 0) {
hasWebEmulator = 'Yes';
}
var newRow = [
'<span onclick="ShowPlatformMappingDialog(' + result[i].igdbId + ');" class="romlink">' + result[i].igdbName + '</span>',
result[i].extensions.supportedFileExtensions.join(', '),
result[i].extensions.uniqueFileExtensions.join(', '),
hasWebEmulator
];
newTable.appendChild(createTableRow(false, newRow, 'romrow', 'romcell logs_table_cell'));
}
}
);
}
function DownloadJSON() {
window.open('/api/v1/PlatformMaps', '_blank');
}
document.getElementById('importjson').addEventListener('click', openDialog);
function openDialog() {
document.getElementById('uploadjson').click();
}
$('#uploadjson').change(function () {
$(this).simpleUpload("/api/v1/PlatformMaps", {
start: function (file) {
//upload started
console.log("JSON upload started");
},
success: function(data){
//upload successful
window.location.reload();
}
});
});
loadPlatformMapping();
</script>

View File

@@ -282,4 +282,95 @@ function syntaxHighlight(json) {
} }
return '<span class="' + cls + '">' + match + '</span>'; return '<span class="' + cls + '">' + match + '</span>';
}); });
}
function ShowPlatformMappingDialog(platformId) {
showDialog('platformmapedit', platformId);
}
function CreateEditableTable(TableName, Headers) {
var eDiv = document.createElement('div');
var eTable = document.createElement('table');
eTable.id = 'EditableTable_' + TableName;
eTable.style.width = '100%';
var headRow = document.createElement('tr');
for (var i = 0; i < Headers.length; i++) {
var headCell = document.createElement('th');
headCell.id = 'EditableTable_' + TableName + '_' + Headers[i].name;
headCell.innerHTML = Headers[i].label;
headRow.appendChild(headCell);
}
eTable.appendChild(headRow);
eDiv.appendChild(eTable);
// add more button
var addButton = document.createElement('button');
addButton.value = 'Add Row';
addButton.innerHTML = 'Add Row';
$(addButton).click(function() {
eTable.appendChild(AddEditableTableRow(Headers));
});
eDiv.appendChild(addButton);
return eDiv;
}
function AddEditableTableRow(Headers) {
var uniqueId = Math.floor(Math.random() * Date.now());
var row = document.createElement('tr');
row.setAttribute('id', uniqueId);
for (var i = 0; i < Headers.length; i++) {
var cell = document.createElement('td');
var input = document.createElement('input');
input.type = 'text';
input.setAttribute('data-cell', Headers[i].name);
input.style.width = '95%';
cell.appendChild(input);
row.appendChild(cell);
}
// delete button
var delButtonCell = document.createElement('td');
delButtonCell.style.textAlign = 'right';
var delButton = document.createElement('button');
delButton.value = 'Delete';
delButton.innerHTML = 'Delete';
delButton.setAttribute('onclick', 'document.getElementById("' + uniqueId + '").remove();');
delButtonCell.appendChild(delButton);
row.appendChild(delButtonCell);
return row;
}
function LoadEditableTableData(TableName, Headers, Values) {
var eTable = document.getElementById('EditableTable_' + TableName);
for (var i = 0; i < Values.length; i++) {
// get new row
var row = AddEditableTableRow(Headers);
for (var v = 0; v < row.childNodes.length; v++) {
// looking at the cells here
var cell = row.childNodes[v];
for (var c = 0; c < cell.childNodes.length; c++) {
if (cell.childNodes[c].getAttribute('data-cell')) {
var nodeName = cell.childNodes[c].getAttribute('data-cell');
if (Values[i][nodeName]) {
row.childNodes[v].childNodes[c].value = Values[i][nodeName];
}
break;
}
}
}
eTable.appendChild(row);
}
} }

File diff suppressed because one or more lines are too long

View File

@@ -146,7 +146,7 @@ h3 {
.banner_button_image_smaller { .banner_button_image_smaller {
height: 16px; height: 16px;
width: 16px; width: 16px;
margin: unset; margin-left: 5px;
} }
#banner_header { #banner_header {

View File

@@ -34,6 +34,14 @@ namespace gaseous_tools
} }
} }
public static string PlatformMappingFile
{
get
{
return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".gaseous-server", "platformmap.json");
}
}
public static ConfigFile.Database DatabaseConfiguration public static ConfigFile.Database DatabaseConfiguration
{ {
get get

View File

@@ -14,3 +14,33 @@ ALTER TABLE `RomCollections`
ADD COLUMN `FolderStructure` INT NULL DEFAULT 0 AFTER `MaximumCollectionSizeInBytes`, ADD COLUMN `FolderStructure` INT NULL DEFAULT 0 AFTER `MaximumCollectionSizeInBytes`,
ADD COLUMN `IncludeBIOSFiles` BOOLEAN NULL DEFAULT 0 AFTER `FolderStructure`, ADD COLUMN `IncludeBIOSFiles` BOOLEAN NULL DEFAULT 0 AFTER `FolderStructure`,
ADD COLUMN `AlwaysInclude` JSON NULL AFTER `IncludeBIOSFiles`; ADD COLUMN `AlwaysInclude` JSON NULL AFTER `IncludeBIOSFiles`;
CREATE TABLE `PlatformMap` (
`Id` BIGINT NOT NULL,
`RetroPieDirectoryName` VARCHAR(45) NULL,
`WebEmulator_Type` VARCHAR(45) NULL,
`WebEmulator_Core` VARCHAR(45) NULL,
PRIMARY KEY (`Id`),
UNIQUE INDEX `Id_UNIQUE` (`Id` ASC) VISIBLE);
CREATE TABLE `PlatformMap_AlternateNames` (
`Id` BIGINT NOT NULL,
`Name` VARCHAR(255) NOT NULL,
PRIMARY KEY (`Id`, `Name`));
CREATE TABLE `PlatformMap_Extensions` (
`Id` BIGINT NOT NULL,
`Extension` VARCHAR(45) NOT NULL,
PRIMARY KEY (`Id`, `Extension`));
CREATE TABLE `PlatformMap_UniqueExtensions` (
`Id` BIGINT NOT NULL,
`Extension` VARCHAR(45) NOT NULL,
PRIMARY KEY (`Id`, `Extension`));
CREATE TABLE `PlatformMap_Bios` (
`Id` BIGINT NOT NULL,
`Filename` VARCHAR(45) NOT NULL,
`Description` LONGTEXT NOT NULL,
`Hash` VARCHAR(45) NOT NULL,
PRIMARY KEY (`Id`, `Filename`, `Hash`));

View File

@@ -74,9 +74,7 @@ namespace gaseous_tools
// write log file // write log file
string JsonOutput = Newtonsoft.Json.JsonConvert.SerializeObject(logItem, serializerSettings); string JsonOutput = Newtonsoft.Json.JsonConvert.SerializeObject(logItem, serializerSettings);
StreamWriter jsonLogFile = File.AppendText(Config.LogFilePath); File.AppendAllText(Config.LogFilePath, JsonOutput);
jsonLogFile.WriteLine(JsonOutput);
jsonLogFile.Close();
} }
// quick clean before we go // quick clean before we go
@@ -116,7 +114,14 @@ namespace gaseous_tools
FileInfo fi = new FileInfo(file); FileInfo fi = new FileInfo(file);
if (fi.LastAccessTime.AddDays(Config.LoggingConfiguration.LogRetention) < DateTime.Now) if (fi.LastAccessTime.AddDays(Config.LoggingConfiguration.LogRetention) < DateTime.Now)
{ {
fi.Delete(); try
{
fi.Delete();
}
catch
{
Log(LogType.Warning, "Log Cleanup", "Failed purging log " + fi.FullName);
}
} }
} }
} }