WIP
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
|
using gaseous_server.Classes.Metadata;
|
||||||
using HasheousClient.Models.Metadata.IGDB;
|
using HasheousClient.Models.Metadata.IGDB;
|
||||||
|
|
||||||
namespace gaseous_server.Classes
|
namespace gaseous_server.Classes
|
||||||
@@ -12,6 +13,37 @@ namespace gaseous_server.Classes
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void ImportBiosFile(string FilePath, Common.hashObject Hash, ref Dictionary<string, object> BiosFileInfo)
|
||||||
|
{
|
||||||
|
BiosFileInfo.Add("type", "bios");
|
||||||
|
BiosFileInfo.Add("status", "notimported");
|
||||||
|
|
||||||
|
foreach (Classes.Bios.BiosItem biosItem in Classes.Bios.GetBios())
|
||||||
|
{
|
||||||
|
if (biosItem.Available == false)
|
||||||
|
{
|
||||||
|
if (biosItem.hash == Hash.md5hash)
|
||||||
|
{
|
||||||
|
string biosPath = Path.Combine(Config.LibraryConfiguration.LibraryFirmwareDirectory, biosItem.hash + ".bios");
|
||||||
|
Logging.Log(Logging.LogType.Information, "Import BIOS File", " " + FilePath + " is a BIOS file - moving to " + biosPath);
|
||||||
|
|
||||||
|
File.Move(FilePath, biosItem.biosPath, true);
|
||||||
|
|
||||||
|
BiosFileInfo.Add("name", biosItem.filename);
|
||||||
|
BiosFileInfo.Add("platform", Platforms.GetPlatform(biosItem.platformid));
|
||||||
|
BiosFileInfo["status"] = "imported";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (biosItem.hash == Hash.md5hash)
|
||||||
|
{
|
||||||
|
BiosFileInfo["status"] = "duplicate";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void MigrateToNewFolderStructure()
|
public static void MigrateToNewFolderStructure()
|
||||||
{
|
{
|
||||||
// migrate from old BIOS file structure which had each bios file inside a folder named for the platform to the new structure which has each file in a subdirectory named after the MD5 hash
|
// migrate from old BIOS file structure which had each bios file inside a folder named for the platform to the new structure which has each file in a subdirectory named after the MD5 hash
|
||||||
|
@@ -322,7 +322,7 @@ namespace gaseous_server.Classes
|
|||||||
switch (metadataResult.Source)
|
switch (metadataResult.Source)
|
||||||
{
|
{
|
||||||
case HasheousClient.Models.MetadataSources.IGDB:
|
case HasheousClient.Models.MetadataSources.IGDB:
|
||||||
signature.Flags.IGDBPlatformId = (long)Platforms.GetPlatform(metadataResult.Id, false).Id;
|
signature.Flags.IGDBPlatformId = (long)Platforms.GetPlatform(metadataResult.Id).Id;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -18,6 +18,15 @@ namespace gaseous_server.Classes
|
|||||||
{
|
{
|
||||||
public class ImportGame : QueueItemStatus
|
public class ImportGame : QueueItemStatus
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Scan the import directory for games and process them
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ImportPath">
|
||||||
|
/// The path to the directory to scan
|
||||||
|
/// </param>
|
||||||
|
/// <exception cref="DirectoryNotFoundException">
|
||||||
|
/// Thrown when the import directory does not exist
|
||||||
|
/// </exception>
|
||||||
public void ProcessDirectory(string ImportPath)
|
public void ProcessDirectory(string ImportPath)
|
||||||
{
|
{
|
||||||
if (Directory.Exists(ImportPath))
|
if (Directory.Exists(ImportPath))
|
||||||
@@ -47,22 +56,29 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Import a single game file
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="GameFileImportPath">
|
||||||
|
/// The path to the game file to import
|
||||||
|
/// </param>
|
||||||
|
/// <param name="OverridePlatform">
|
||||||
|
/// The platform to use for the game file
|
||||||
|
/// </param>
|
||||||
|
/// <returns>
|
||||||
|
/// A dictionary containing the results of the import
|
||||||
|
/// </returns>
|
||||||
public Dictionary<string, object> ImportGameFile(string GameFileImportPath, Platform? OverridePlatform)
|
public Dictionary<string, object> ImportGameFile(string GameFileImportPath, Platform? OverridePlatform)
|
||||||
{
|
{
|
||||||
Dictionary<string, object> RetVal = new Dictionary<string, object>();
|
Dictionary<string, object> RetVal = new Dictionary<string, object>();
|
||||||
RetVal.Add("path", Path.GetFileName(GameFileImportPath));
|
RetVal.Add("path", Path.GetFileName(GameFileImportPath));
|
||||||
|
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
|
||||||
string sql = "";
|
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
|
||||||
|
|
||||||
if (Common.SkippableFiles.Contains<string>(Path.GetFileName(GameFileImportPath), StringComparer.OrdinalIgnoreCase))
|
if (Common.SkippableFiles.Contains<string>(Path.GetFileName(GameFileImportPath), StringComparer.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
Logging.Log(Logging.LogType.Debug, "Import Game", "Skipping item " + GameFileImportPath);
|
Logging.Log(Logging.LogType.Debug, "Import Game", "Skipping item " + GameFileImportPath);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FileInfo fi = new FileInfo(GameFileImportPath);
|
|
||||||
Common.hashObject hash = new Common.hashObject(GameFileImportPath);
|
Common.hashObject hash = new Common.hashObject(GameFileImportPath);
|
||||||
|
|
||||||
Models.PlatformMapping.PlatformMapItem? IsBios = Classes.Bios.BiosHashSignatureLookup(hash.md5hash);
|
Models.PlatformMapping.PlatformMapItem? IsBios = Classes.Bios.BiosHashSignatureLookup(hash.md5hash);
|
||||||
@@ -70,114 +86,234 @@ namespace gaseous_server.Classes
|
|||||||
if (IsBios == null)
|
if (IsBios == null)
|
||||||
{
|
{
|
||||||
// file is a rom
|
// file is a rom
|
||||||
RetVal.Add("type", "rom");
|
_ImportGameFile(GameFileImportPath, hash, ref RetVal, OverridePlatform);
|
||||||
|
|
||||||
// check to make sure we don't already have this file imported
|
|
||||||
sql = "SELECT COUNT(Id) AS count FROM view_Games_Roms WHERE MD5=@md5 AND SHA1=@sha1";
|
|
||||||
dbDict.Add("md5", hash.md5hash);
|
|
||||||
dbDict.Add("sha1", hash.sha1hash);
|
|
||||||
DataTable importDB = db.ExecuteCMD(sql, dbDict);
|
|
||||||
if ((Int64)importDB.Rows[0]["count"] > 0)
|
|
||||||
{
|
|
||||||
// import source was the import directory
|
|
||||||
if (GameFileImportPath.StartsWith(Config.LibraryConfiguration.LibraryImportDirectory))
|
|
||||||
{
|
|
||||||
Logging.Log(Logging.LogType.Warning, "Import Game", " " + GameFileImportPath + " already in database - moving to " + Config.LibraryConfiguration.LibraryImportDuplicatesDirectory);
|
|
||||||
|
|
||||||
string targetPathWithFileName = GameFileImportPath.Replace(Config.LibraryConfiguration.LibraryImportDirectory, Config.LibraryConfiguration.LibraryImportDuplicatesDirectory);
|
|
||||||
string targetPath = Path.GetDirectoryName(targetPathWithFileName);
|
|
||||||
|
|
||||||
if (!Directory.Exists(targetPath))
|
|
||||||
{
|
|
||||||
Directory.CreateDirectory(targetPath);
|
|
||||||
}
|
|
||||||
File.Move(GameFileImportPath, targetPathWithFileName, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// import source was the upload directory
|
|
||||||
if (GameFileImportPath.StartsWith(Config.LibraryConfiguration.LibraryUploadDirectory))
|
|
||||||
{
|
|
||||||
Logging.Log(Logging.LogType.Warning, "Import Game", " " + GameFileImportPath + " already in database - skipping import");
|
|
||||||
}
|
|
||||||
|
|
||||||
RetVal.Add("status", "duplicate");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Logging.Log(Logging.LogType.Information, "Import Game", " " + GameFileImportPath + " not in database - processing");
|
|
||||||
|
|
||||||
FileSignature fileSignature = new FileSignature();
|
|
||||||
gaseous_server.Models.Signatures_Games discoveredSignature = fileSignature.GetFileSignature(GameLibrary.GetDefaultLibrary, hash, fi, GameFileImportPath);
|
|
||||||
|
|
||||||
// get discovered platform
|
|
||||||
Platform? determinedPlatform = null;
|
|
||||||
if (OverridePlatform == null)
|
|
||||||
{
|
|
||||||
determinedPlatform = Metadata.Platforms.GetPlatform(discoveredSignature.Flags.IGDBPlatformId);
|
|
||||||
if (determinedPlatform == null)
|
|
||||||
{
|
|
||||||
determinedPlatform = new Platform();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
determinedPlatform = OverridePlatform;
|
|
||||||
discoveredSignature.Flags.IGDBPlatformId = (long)determinedPlatform.Id;
|
|
||||||
discoveredSignature.Flags.IGDBPlatformName = determinedPlatform.Name;
|
|
||||||
}
|
|
||||||
|
|
||||||
gaseous_server.Models.Game determinedGame = SearchForGame(discoveredSignature, discoveredSignature.Flags.IGDBPlatformId, true);
|
|
||||||
|
|
||||||
// add to database
|
|
||||||
long RomId = StoreROM(GameLibrary.GetDefaultLibrary, hash, determinedGame, determinedPlatform, discoveredSignature, GameFileImportPath, 0, true);
|
|
||||||
|
|
||||||
// build return value
|
|
||||||
RetVal.Add("romid", RomId);
|
|
||||||
RetVal.Add("platform", determinedPlatform);
|
|
||||||
RetVal.Add("game", determinedGame);
|
|
||||||
RetVal.Add("signature", discoveredSignature);
|
|
||||||
RetVal.Add("status", "imported");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// file is a bios
|
// file is a bios
|
||||||
RetVal.Add("type", "bios");
|
Bios.ImportBiosFile(GameFileImportPath, hash, ref RetVal);
|
||||||
RetVal.Add("status", "notimported");
|
|
||||||
|
|
||||||
foreach (Classes.Bios.BiosItem biosItem in Classes.Bios.GetBios())
|
|
||||||
{
|
|
||||||
if (biosItem.Available == false)
|
|
||||||
{
|
|
||||||
if (biosItem.hash == hash.md5hash)
|
|
||||||
{
|
|
||||||
string biosPath = Path.Combine(Config.LibraryConfiguration.LibraryFirmwareDirectory, biosItem.hash + ".bios");
|
|
||||||
Logging.Log(Logging.LogType.Information, "Import Game", " " + GameFileImportPath + " is a BIOS file - moving to " + biosPath);
|
|
||||||
|
|
||||||
File.Move(GameFileImportPath, biosItem.biosPath, true);
|
|
||||||
|
|
||||||
RetVal.Add("name", biosItem.filename);
|
|
||||||
RetVal.Add("platform", Platforms.GetPlatform(biosItem.platformid));
|
|
||||||
RetVal["status"] = "imported";
|
|
||||||
|
|
||||||
return RetVal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (biosItem.hash == hash.md5hash)
|
|
||||||
{
|
|
||||||
RetVal["status"] = "duplicate";
|
|
||||||
return RetVal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return RetVal;
|
return RetVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Import a single game file
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="FilePath">
|
||||||
|
/// The path to the game file to import
|
||||||
|
/// </param>
|
||||||
|
/// <param name="Hash">
|
||||||
|
/// The hash of the game file
|
||||||
|
/// </param>
|
||||||
|
/// <param name="GameFileInfo">
|
||||||
|
/// A dictionary to store the results of the import
|
||||||
|
/// </param>
|
||||||
|
/// <param name="OverridePlatform">
|
||||||
|
/// The platform to use for the game file
|
||||||
|
/// </param>
|
||||||
|
private static void _ImportGameFile(string FilePath, Common.hashObject Hash, ref Dictionary<string, object> GameFileInfo, Platform? OverridePlatform)
|
||||||
|
{
|
||||||
|
GameFileInfo.Add("type", "rom");
|
||||||
|
|
||||||
|
// check to make sure we don't already have this file imported
|
||||||
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
|
string sql = "";
|
||||||
|
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||||
|
|
||||||
|
sql = "SELECT COUNT(Id) AS count FROM view_Games_Roms WHERE MD5=@md5 AND SHA1=@sha1";
|
||||||
|
dbDict.Add("md5", Hash.md5hash);
|
||||||
|
dbDict.Add("sha1", Hash.sha1hash);
|
||||||
|
DataTable importDB = db.ExecuteCMD(sql, dbDict);
|
||||||
|
if ((Int64)importDB.Rows[0]["count"] > 0)
|
||||||
|
{
|
||||||
|
// import source was the import directory
|
||||||
|
if (FilePath.StartsWith(Config.LibraryConfiguration.LibraryImportDirectory))
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Warning, "Import Game", " " + FilePath + " already in database - moving to " + Config.LibraryConfiguration.LibraryImportDuplicatesDirectory);
|
||||||
|
|
||||||
|
string targetPathWithFileName = FilePath.Replace(Config.LibraryConfiguration.LibraryImportDirectory, Config.LibraryConfiguration.LibraryImportDuplicatesDirectory);
|
||||||
|
string targetPath = Path.GetDirectoryName(targetPathWithFileName);
|
||||||
|
|
||||||
|
if (!Directory.Exists(targetPath))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(targetPath);
|
||||||
|
}
|
||||||
|
File.Move(FilePath, targetPathWithFileName, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// import source was the upload directory
|
||||||
|
if (FilePath.StartsWith(Config.LibraryConfiguration.LibraryUploadDirectory))
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Warning, "Import Game", " " + FilePath + " already in database - skipping import");
|
||||||
|
}
|
||||||
|
|
||||||
|
GameFileInfo.Add("status", "duplicate");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Information, "Import Game", " " + FilePath + " not in database - processing");
|
||||||
|
|
||||||
|
FileInfo fi = new FileInfo(FilePath);
|
||||||
|
FileSignature fileSignature = new FileSignature();
|
||||||
|
gaseous_server.Models.Signatures_Games discoveredSignature = fileSignature.GetFileSignature(GameLibrary.GetDefaultLibrary, Hash, fi, FilePath);
|
||||||
|
|
||||||
|
// get discovered platform
|
||||||
|
Platform? determinedPlatform = null;
|
||||||
|
if (OverridePlatform == null)
|
||||||
|
{
|
||||||
|
determinedPlatform = Metadata.Platforms.GetPlatform(discoveredSignature.Flags.IGDBPlatformId);
|
||||||
|
if (determinedPlatform == null)
|
||||||
|
{
|
||||||
|
determinedPlatform = new Platform();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
determinedPlatform = OverridePlatform;
|
||||||
|
discoveredSignature.Flags.IGDBPlatformId = (long)determinedPlatform.Id;
|
||||||
|
discoveredSignature.Flags.IGDBPlatformName = determinedPlatform.Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
// add to database
|
||||||
|
long RomId = StoreGame(GameLibrary.GetDefaultLibrary, Hash, discoveredSignature, determinedPlatform, FilePath, 0, false);
|
||||||
|
|
||||||
|
// build return value
|
||||||
|
GameFileInfo.Add("romid", RomId);
|
||||||
|
GameFileInfo.Add("platform", determinedPlatform);
|
||||||
|
GameFileInfo.Add("game", discoveredSignature.Game.Name);
|
||||||
|
GameFileInfo.Add("signature", discoveredSignature);
|
||||||
|
GameFileInfo.Add("status", "imported");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Store a game in the database and move the file to the library (if required)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="library">
|
||||||
|
/// The library to store the game in
|
||||||
|
/// </param>
|
||||||
|
/// <param name="hash">
|
||||||
|
/// The hash of the game file
|
||||||
|
/// </param>
|
||||||
|
/// <param name="signature">
|
||||||
|
/// The signature of the game file
|
||||||
|
/// </param>
|
||||||
|
/// <param name="filePath">
|
||||||
|
/// The path to the game file
|
||||||
|
/// </param>
|
||||||
|
/// <param name="romId">
|
||||||
|
/// The ID of the ROM in the database (if it already exists, 0 if it doesn't)
|
||||||
|
/// </param>
|
||||||
|
/// <param name="SourceIsExternal">
|
||||||
|
/// Whether the source of the file is external to the library
|
||||||
|
/// </param>
|
||||||
|
public static long StoreGame(GameLibrary.LibraryItem library, Common.hashObject hash, Signatures_Games signature, Platform platform, string filePath, long romId = 0, bool SourceIsExternal = false)
|
||||||
|
{
|
||||||
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
|
|
||||||
|
string sql = "";
|
||||||
|
|
||||||
|
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||||
|
|
||||||
|
// add the metadata map
|
||||||
|
// check if the map exists already
|
||||||
|
long mapId = 0;
|
||||||
|
sql = "SELECT ParentMapId FROM MetadataMapBridge WHERE SignatureGameName=@gamename AND SignaturePlatformId=@platformid;";
|
||||||
|
dbDict = new Dictionary<string, object>(){
|
||||||
|
{ "gamename", signature.Game.Name },
|
||||||
|
{ "platformid", platform.Id }
|
||||||
|
};
|
||||||
|
DataTable mapDT = db.ExecuteCMD(sql, dbDict);
|
||||||
|
|
||||||
|
if (mapDT.Rows.Count > 0)
|
||||||
|
{
|
||||||
|
mapId = (long)mapDT.Rows[0]["ParentMapId"];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sql = "INSERT INTO MetadataMapBridge (ParentMapId, SignatureGameName, SignaturePlatformId, MetadataSourceType, MetadataSourceId, Preferred, ProcessedAtImport) VALUES (@parentmapid, @gamename, @platformid, @metadatasourcetype, @metadatasourceid, @preferred, @processedatimport); SELECT CAST(LAST_INSERT_ID() AS SIGNED);";
|
||||||
|
dbDict = new Dictionary<string, object>(){
|
||||||
|
{ "parentmapid", 0 },
|
||||||
|
{ "gamename", signature.Game.Name },
|
||||||
|
{ "platformid", platform.Id },
|
||||||
|
{ "metadatasourcetype", MetadataModel.MetadataSources.None },
|
||||||
|
{ "metadatasourceid", 0 }, // set to zero as an initial value - another process will update this later
|
||||||
|
{ "preferred", 1 },
|
||||||
|
{ "processedatimport", 0 }
|
||||||
|
};
|
||||||
|
DataTable mapInsert = db.ExecuteCMD(sql, dbDict);
|
||||||
|
mapId = (long)mapInsert.Rows[0][0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// add or update the rom
|
||||||
|
dbDict = new Dictionary<string, object>();
|
||||||
|
if (romId == 0)
|
||||||
|
{
|
||||||
|
sql = "INSERT INTO Games_Roms (PlatformId, GameId, Name, Size, CRC, MD5, SHA1, DevelopmentStatus, Attributes, RomType, RomTypeMedia, MediaLabel, RelativePath, MetadataSource, MetadataGameName, MetadataVersion, LibraryId, RomDataVersion, MetadataMapId) VALUES (@platformid, @gameid, @name, @size, @crc, @md5, @sha1, @developmentstatus, @Attributes, @romtype, @romtypemedia, @medialabel, @path, @metadatasource, @metadatagamename, @metadataversion, @libraryid, @romdataversion, @metadatamapid); SELECT CAST(LAST_INSERT_ID() AS SIGNED);";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sql = "UPDATE Games_Roms SET PlatformId=@platformid, GameId=@gameid, Name=@name, Size=@size, DevelopmentStatus=@developmentstatus, Attributes=@Attributes, RomType=@romtype, RomTypeMedia=@romtypemedia, MediaLabel=@medialabel, MetadataSource=@metadatasource, MetadataGameName=@metadatagamename, MetadataVersion=@metadataversion, RomDataVersion=@romdataversion, MetadataMapId=@metadatamapid WHERE Id=@id;";
|
||||||
|
dbDict.Add("id", romId);
|
||||||
|
}
|
||||||
|
dbDict.Add("platformid", Common.ReturnValueIfNull(platform.Id, 0));
|
||||||
|
dbDict.Add("gameid", 0); // set to 0 - no longer required as game is mapped using the MetadataMapBridge table
|
||||||
|
dbDict.Add("name", Common.ReturnValueIfNull(signature.Rom.Name, 0));
|
||||||
|
dbDict.Add("size", Common.ReturnValueIfNull(signature.Rom.Size, 0));
|
||||||
|
dbDict.Add("md5", hash.md5hash);
|
||||||
|
dbDict.Add("sha1", hash.sha1hash);
|
||||||
|
dbDict.Add("crc", Common.ReturnValueIfNull(signature.Rom.Crc, ""));
|
||||||
|
dbDict.Add("developmentstatus", Common.ReturnValueIfNull(signature.Rom.DevelopmentStatus, ""));
|
||||||
|
dbDict.Add("metadatasource", signature.Rom.SignatureSource);
|
||||||
|
dbDict.Add("metadatagamename", signature.Game.Name);
|
||||||
|
dbDict.Add("metadataversion", 2);
|
||||||
|
dbDict.Add("libraryid", library.Id);
|
||||||
|
dbDict.Add("romdataversion", 2);
|
||||||
|
dbDict.Add("metadatamapid", mapId);
|
||||||
|
|
||||||
|
if (signature.Rom.Attributes != null)
|
||||||
|
{
|
||||||
|
if (signature.Rom.Attributes.Count > 0)
|
||||||
|
{
|
||||||
|
dbDict.Add("attributes", Newtonsoft.Json.JsonConvert.SerializeObject(signature.Rom.Attributes));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dbDict.Add("attributes", "[ ]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dbDict.Add("attributes", "[ ]");
|
||||||
|
}
|
||||||
|
dbDict.Add("romtype", (int)signature.Rom.RomType);
|
||||||
|
dbDict.Add("romtypemedia", Common.ReturnValueIfNull(signature.Rom.RomTypeMedia, ""));
|
||||||
|
dbDict.Add("medialabel", Common.ReturnValueIfNull(signature.Rom.MediaLabel, ""));
|
||||||
|
|
||||||
|
string libraryRootPath = library.Path;
|
||||||
|
if (libraryRootPath.EndsWith(Path.DirectorySeparatorChar.ToString()) == false)
|
||||||
|
{
|
||||||
|
libraryRootPath += Path.DirectorySeparatorChar;
|
||||||
|
}
|
||||||
|
dbDict.Add("path", filePath.Replace(libraryRootPath, ""));
|
||||||
|
|
||||||
|
DataTable romInsert = db.ExecuteCMD(sql, dbDict);
|
||||||
|
if (romId == 0)
|
||||||
|
{
|
||||||
|
romId = (long)romInsert.Rows[0][0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// move to destination
|
||||||
|
if (library.IsDefaultLibrary == true)
|
||||||
|
{
|
||||||
|
//MoveGameFile(romId, SourceIsExternal);
|
||||||
|
}
|
||||||
|
|
||||||
|
return romId;
|
||||||
|
}
|
||||||
|
|
||||||
public static gaseous_server.Models.Game SearchForGame(gaseous_server.Models.Signatures_Games Signature, long PlatformId, bool FullDownload)
|
public static gaseous_server.Models.Game SearchForGame(gaseous_server.Models.Signatures_Games Signature, long PlatformId, bool FullDownload)
|
||||||
{
|
{
|
||||||
if (Signature.Flags != null)
|
if (Signature.Flags != null)
|
||||||
|
@@ -37,7 +37,10 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
|
|
||||||
public static Game? GetGame(HasheousClient.Models.MetadataModel.MetadataSources SourceType, string? Slug)
|
public static Game? GetGame(HasheousClient.Models.MetadataModel.MetadataSources SourceType, string? Slug)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
Game? RetVal = Metadata.GetMetadata<Game>(SourceType, Slug, false);
|
||||||
|
RetVal.MetadataSource = SourceType;
|
||||||
|
RetVal = MassageResult(RetVal);
|
||||||
|
return RetVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Game GetGame(DataRow dataRow)
|
public static Game GetGame(DataRow dataRow)
|
||||||
|
@@ -17,7 +17,7 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public InvalidMetadataId(string SourceType, string Id) : base("Invalid Metadata id: " + Id + " from source: " + SourceType)
|
public InvalidMetadataId(HasheousClient.Models.MetadataModel.MetadataSources SourceType, string Id) : base("Invalid Metadata id: " + Id + " from source: " + SourceType)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -77,14 +77,30 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
return _GetMetadata<T>(SourceType, Id, ForceRefresh);
|
return _GetMetadata<T>(SourceType, Id, ForceRefresh);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static T? _GetMetadata<T>(HasheousClient.Models.MetadataModel.MetadataSources SourceType, long Id, Boolean ForceRefresh) where T : class
|
public static T? GetMetadata<T>(HasheousClient.Models.MetadataModel.MetadataSources SourceType, string Slug, Boolean ForceRefresh = false) where T : class
|
||||||
|
{
|
||||||
|
return _GetMetadata<T>(SourceType, Slug, ForceRefresh);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static T? _GetMetadata<T>(HasheousClient.Models.MetadataModel.MetadataSources SourceType, object Id, Boolean ForceRefresh) where T : class
|
||||||
{
|
{
|
||||||
// get T type as string
|
// get T type as string
|
||||||
string type = typeof(T).Name;
|
string type = typeof(T).Name;
|
||||||
|
|
||||||
|
// get type of Id as string
|
||||||
|
IdType idType = Id.GetType() == typeof(long) ? IdType.Long : IdType.String;
|
||||||
|
|
||||||
// check cached metadata status
|
// check cached metadata status
|
||||||
// if metadata is not cached or expired, get it from the source. Otherwise, return the cached metadata
|
// if metadata is not cached or expired, get it from the source. Otherwise, return the cached metadata
|
||||||
Storage.CacheStatus? cacheStatus = Storage.GetCacheStatus(SourceType, type, Id);
|
Storage.CacheStatus? cacheStatus;
|
||||||
|
if (idType == IdType.Long)
|
||||||
|
{
|
||||||
|
cacheStatus = Storage.GetCacheStatus(SourceType, type, (long)Id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cacheStatus = Storage.GetCacheStatus(SourceType, type, (string)Id);
|
||||||
|
}
|
||||||
|
|
||||||
// if ForceRefresh is true, set cache status to expired if it is current
|
// if ForceRefresh is true, set cache status to expired if it is current
|
||||||
if (ForceRefresh == true)
|
if (ForceRefresh == true)
|
||||||
@@ -100,16 +116,37 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
switch (cacheStatus)
|
switch (cacheStatus)
|
||||||
{
|
{
|
||||||
case Storage.CacheStatus.Current:
|
case Storage.CacheStatus.Current:
|
||||||
metadata = Storage.GetCacheValue<T>(SourceType, metadata, "Id", Id);
|
if (idType == IdType.Long)
|
||||||
|
{
|
||||||
|
metadata = Storage.GetCacheValue<T>(SourceType, metadata, "Id", (long)Id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
metadata = Storage.GetCacheValue<T>(SourceType, metadata, "Slug", (string)Id);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Storage.CacheStatus.Expired:
|
case Storage.CacheStatus.Expired:
|
||||||
metadata = GetMetadataFromServer<T>(SourceType, Id).Result;
|
if (idType == IdType.Long)
|
||||||
|
{
|
||||||
|
metadata = GetMetadataFromServer<T>(SourceType, (long)Id).Result;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
metadata = GetMetadataFromServer<T>(SourceType, (string)Id).Result;
|
||||||
|
}
|
||||||
Storage.NewCacheValue<T>(SourceType, metadata, true);
|
Storage.NewCacheValue<T>(SourceType, metadata, true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Storage.CacheStatus.NotPresent:
|
case Storage.CacheStatus.NotPresent:
|
||||||
metadata = GetMetadataFromServer<T>(SourceType, Id).Result;
|
if (idType == IdType.Long)
|
||||||
|
{
|
||||||
|
metadata = GetMetadataFromServer<T>(SourceType, (long)Id).Result;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
metadata = GetMetadataFromServer<T>(SourceType, (string)Id).Result;
|
||||||
|
}
|
||||||
Storage.NewCacheValue<T>(SourceType, metadata, false);
|
Storage.NewCacheValue<T>(SourceType, metadata, false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -117,6 +154,12 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
return metadata;
|
return metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private enum IdType
|
||||||
|
{
|
||||||
|
Long,
|
||||||
|
String
|
||||||
|
}
|
||||||
|
|
||||||
private static async Task<T> GetMetadataFromServer<T>(HasheousClient.Models.MetadataModel.MetadataSources SourceType, long Id) where T : class
|
private static async Task<T> GetMetadataFromServer<T>(HasheousClient.Models.MetadataModel.MetadataSources SourceType, long Id) where T : class
|
||||||
{
|
{
|
||||||
// get T type as string
|
// get T type as string
|
||||||
@@ -135,6 +178,24 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
return results.FirstOrDefault<T>();
|
return results.FirstOrDefault<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static async Task<T> GetMetadataFromServer<T>(HasheousClient.Models.MetadataModel.MetadataSources SourceType, string Id) where T : class
|
||||||
|
{
|
||||||
|
// get T type as string
|
||||||
|
string type = typeof(T).Name;
|
||||||
|
|
||||||
|
// get metadata from the server
|
||||||
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<T>(SourceType, (Communications.MetadataEndpoint)Enum.Parse(typeof(Communications.MetadataEndpoint), type, true), Id);
|
||||||
|
|
||||||
|
// check for errors
|
||||||
|
if (results == null)
|
||||||
|
{
|
||||||
|
throw new InvalidMetadataId(SourceType, Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return results.FirstOrDefault<T>();
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -27,9 +27,19 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Platform GetPlatform(string Slug, bool forceRefresh = false, bool GetImages = false)
|
public static Platform GetPlatform(string Slug)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
// get platform id from slug - query Platform table
|
||||||
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
|
string query = "SELECT Id FROM Platform WHERE slug = @slug AND SourceId = @sourceid;";
|
||||||
|
DataTable result = db.ExecuteCMD(query, new Dictionary<string, object> { { "@slug", Slug }, { "@sourceid", Communications.MetadataSource } });
|
||||||
|
if (result.Rows.Count == 0)
|
||||||
|
{
|
||||||
|
throw new Metadata.InvalidMetadataId(Slug);
|
||||||
|
}
|
||||||
|
|
||||||
|
long Id = (long)result.Rows[0]["Id"];
|
||||||
|
return GetPlatform(Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void AddPlatformMapping(Platform platform)
|
private static void AddPlatformMapping(Platform platform)
|
||||||
|
@@ -120,15 +120,26 @@ CREATE TABLE `MetadataMap` (
|
|||||||
|
|
||||||
CREATE TABLE `MetadataMapBridge` (
|
CREATE TABLE `MetadataMapBridge` (
|
||||||
`ParentMapId` bigint(20) NOT NULL,
|
`ParentMapId` bigint(20) NOT NULL,
|
||||||
|
`SignatureGameName` varchar(255) NOT NULL,
|
||||||
|
`SignaturePlatformId` bigint(20) NOT NULL,
|
||||||
`MetadataSourceType` int(11) NOT NULL DEFAULT 0,
|
`MetadataSourceType` int(11) NOT NULL DEFAULT 0,
|
||||||
`MetadataSourceId` bigint(20) NOT NULL `Preferred` BOOLEAN NOT NULL DEFAULT 0,
|
`MetadataSourceId` bigint(20) NOT NULL,
|
||||||
|
`Preferred` BOOLEAN NOT NULL DEFAULT 0,
|
||||||
|
`ProcessedAtImport` BOOLEAN NOT NULL DEFAULT 0,
|
||||||
PRIMARY KEY (
|
PRIMARY KEY (
|
||||||
`ParentMapId`,
|
`ParentMapId`,
|
||||||
`MetadataSourceType`,
|
`MetadataSourceType`,
|
||||||
`MetadataSourceId`
|
`MetadataSourceId`
|
||||||
|
),
|
||||||
|
INDEX `idx_gamename` (
|
||||||
|
`SignatureGameName`,
|
||||||
|
`SignaturePlatformId`
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ALTER TABLE `Games_Roms`
|
||||||
|
ADD CONSTRAINT metadataMapId FOREIGN KEY (`MetadataMapId`) REFERENCES `MetadataMapBridge` (`ParentMapId`) ON DELETE CASCADE;
|
||||||
|
|
||||||
ALTER TABLE `Games_Roms`
|
ALTER TABLE `Games_Roms`
|
||||||
ADD COLUMN `MetadataMapId` BIGINT NOT NULL DEFAULT 0;
|
ADD COLUMN `MetadataMapId` BIGINT NOT NULL DEFAULT 0;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user