feat: enhanced title matching, added more metadata types
This commit is contained in:
@@ -3,6 +3,7 @@ using System.Data;
|
||||
using System.Threading.Tasks;
|
||||
using gaseous_tools;
|
||||
using Org.BouncyCastle.Utilities.IO.Pem;
|
||||
using static gaseous_server.Classes.Metadata.Games;
|
||||
|
||||
namespace gaseous_server.Classes
|
||||
{
|
||||
@@ -99,24 +100,48 @@ namespace gaseous_server.Classes
|
||||
}
|
||||
else
|
||||
{
|
||||
// no signature match found - try alternate methods
|
||||
Models.Signatures_Games.GameItem gi = new Models.Signatures_Games.GameItem();
|
||||
Models.Signatures_Games.RomItem ri = new Models.Signatures_Games.RomItem();
|
||||
// no signature match found - try name search
|
||||
signatures = sc.GetByTosecName(fi.Name);
|
||||
|
||||
discoveredSignature.Game = gi;
|
||||
discoveredSignature.Rom = ri;
|
||||
if (signatures.Count == 1)
|
||||
{
|
||||
// only 1 signature found!
|
||||
discoveredSignature = signatures.ElementAt(0);
|
||||
gaseous_server.Models.PlatformMapping.GetIGDBPlatformMapping(ref discoveredSignature, fi, false);
|
||||
}
|
||||
else if (signatures.Count > 1)
|
||||
{
|
||||
// more than one signature found - find one with highest score
|
||||
foreach (Models.Signatures_Games Sig in signatures)
|
||||
{
|
||||
if (Sig.Score > discoveredSignature.Score)
|
||||
{
|
||||
discoveredSignature = Sig;
|
||||
gaseous_server.Models.PlatformMapping.GetIGDBPlatformMapping(ref discoveredSignature, fi, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// still no search - try alternate method
|
||||
Models.Signatures_Games.GameItem gi = new Models.Signatures_Games.GameItem();
|
||||
Models.Signatures_Games.RomItem ri = new Models.Signatures_Games.RomItem();
|
||||
|
||||
// game title is the file name without the extension or path
|
||||
gi.Name = Path.GetFileNameWithoutExtension(GameFileImportPath);
|
||||
discoveredSignature.Game = gi;
|
||||
discoveredSignature.Rom = ri;
|
||||
|
||||
// guess platform
|
||||
gaseous_server.Models.PlatformMapping.GetIGDBPlatformMapping(ref discoveredSignature, fi, true);
|
||||
// game title is the file name without the extension or path
|
||||
gi.Name = Path.GetFileNameWithoutExtension(GameFileImportPath);
|
||||
|
||||
// get rom data
|
||||
ri.Name = Path.GetFileName(GameFileImportPath);
|
||||
ri.Md5 = hash.md5hash;
|
||||
ri.Sha1 = hash.sha1hash;
|
||||
ri.Size = fi.Length;
|
||||
// guess platform
|
||||
gaseous_server.Models.PlatformMapping.GetIGDBPlatformMapping(ref discoveredSignature, fi, true);
|
||||
|
||||
// get rom data
|
||||
ri.Name = Path.GetFileName(GameFileImportPath);
|
||||
ri.Md5 = hash.md5hash;
|
||||
ri.Sha1 = hash.sha1hash;
|
||||
ri.Size = fi.Length;
|
||||
}
|
||||
}
|
||||
|
||||
Logging.Log(Logging.LogType.Information, "Import Game", " Determined import file as: " + discoveredSignature.Game.Name + " (" + discoveredSignature.Game.Year + ") " + discoveredSignature.Game.System);
|
||||
@@ -127,6 +152,13 @@ namespace gaseous_server.Classes
|
||||
determinedPlatform = new IGDB.Models.Platform();
|
||||
}
|
||||
|
||||
// remove string ending ", The" if present
|
||||
if (discoveredSignature.Game.Name.Contains(", The"))
|
||||
{
|
||||
Logging.Log(Logging.LogType.Information, "Import Game", " Removing ', The' from end of game title for search");
|
||||
discoveredSignature.Game.Name.Replace(", The", "");
|
||||
}
|
||||
|
||||
// search discovered game - case insensitive exact match first
|
||||
IGDB.Models.Game determinedGame = new IGDB.Models.Game();
|
||||
|
||||
@@ -137,7 +169,7 @@ namespace gaseous_server.Classes
|
||||
if (games.Length == 1)
|
||||
{
|
||||
// exact match!
|
||||
determinedGame = Metadata.Games.GetGame((long)games[0].Id, false);
|
||||
determinedGame = Metadata.Games.GetGame((long)games[0].Id, false, false);
|
||||
Logging.Log(Logging.LogType.Information, "Import Game", " IGDB game: " + determinedGame.Name);
|
||||
break;
|
||||
}
|
||||
@@ -198,7 +230,7 @@ namespace gaseous_server.Classes
|
||||
|
||||
// get metadata
|
||||
IGDB.Models.Platform platform = gaseous_server.Classes.Metadata.Platforms.GetPlatform(rom.PlatformId);
|
||||
IGDB.Models.Game game = gaseous_server.Classes.Metadata.Games.GetGame(rom.GameId, false);
|
||||
IGDB.Models.Game game = gaseous_server.Classes.Metadata.Games.GetGame(rom.GameId, false, false);
|
||||
|
||||
// build path
|
||||
string platformSlug = "Unknown Platform";
|
||||
|
||||
120
gaseous-server/Classes/Metadata/AgeRating.cs
Normal file
120
gaseous-server/Classes/Metadata/AgeRating.cs
Normal file
@@ -0,0 +1,120 @@
|
||||
using System;
|
||||
using gaseous_tools;
|
||||
using IGDB;
|
||||
using IGDB.Models;
|
||||
using MySqlX.XDevAPI.Common;
|
||||
using static gaseous_tools.Config.ConfigFile;
|
||||
|
||||
namespace gaseous_server.Classes.Metadata
|
||||
{
|
||||
public class AgeRatings
|
||||
{
|
||||
const string fieldList = "fields category,checksum,content_descriptions,rating,rating_cover_url,synopsis;";
|
||||
|
||||
public AgeRatings()
|
||||
{
|
||||
}
|
||||
|
||||
private static IGDBClient igdb = new IGDBClient(
|
||||
// Found in Twitch Developer portal for your app
|
||||
Config.IGDB.ClientId,
|
||||
Config.IGDB.Secret
|
||||
);
|
||||
|
||||
public static AgeRating? GetAgeRatings(long? Id)
|
||||
{
|
||||
if ((Id == 0) || (Id == null))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
Task<AgeRating> RetVal = _GetAgeRatings(SearchUsing.id, Id);
|
||||
return RetVal.Result;
|
||||
}
|
||||
}
|
||||
|
||||
public static AgeRating GetAgeRatings(string Slug)
|
||||
{
|
||||
Task<AgeRating> RetVal = _GetAgeRatings(SearchUsing.slug, Slug);
|
||||
return RetVal.Result;
|
||||
}
|
||||
|
||||
private static async Task<AgeRating> _GetAgeRatings(SearchUsing searchUsing, object searchValue)
|
||||
{
|
||||
// check database first
|
||||
Storage.CacheStatus? cacheStatus = new Storage.CacheStatus();
|
||||
if (searchUsing == SearchUsing.id)
|
||||
{
|
||||
cacheStatus = Storage.GetCacheStatus("AgeRating", (long)searchValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
cacheStatus = Storage.GetCacheStatus("AgeRating", (string)searchValue);
|
||||
}
|
||||
|
||||
// set up where clause
|
||||
string WhereClause = "";
|
||||
switch (searchUsing)
|
||||
{
|
||||
case SearchUsing.id:
|
||||
WhereClause = "where id = " + searchValue;
|
||||
break;
|
||||
case SearchUsing.slug:
|
||||
WhereClause = "where slug = " + searchValue;
|
||||
break;
|
||||
default:
|
||||
throw new Exception("Invalid search type");
|
||||
}
|
||||
|
||||
AgeRating returnValue = new AgeRating();
|
||||
switch (cacheStatus)
|
||||
{
|
||||
case Storage.CacheStatus.NotPresent:
|
||||
returnValue = await GetObjectFromServer(WhereClause);
|
||||
Storage.NewCacheValue(returnValue);
|
||||
UpdateSubClasses(returnValue);
|
||||
break;
|
||||
case Storage.CacheStatus.Expired:
|
||||
returnValue = await GetObjectFromServer(WhereClause);
|
||||
Storage.NewCacheValue(returnValue, true);
|
||||
UpdateSubClasses(returnValue);
|
||||
break;
|
||||
case Storage.CacheStatus.Current:
|
||||
returnValue = Storage.GetCacheValue<AgeRating>(returnValue, "id", (long)searchValue);
|
||||
break;
|
||||
default:
|
||||
throw new Exception("How did you get here?");
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
private static void UpdateSubClasses(AgeRating ageRating)
|
||||
{
|
||||
if (ageRating.ContentDescriptions != null)
|
||||
{
|
||||
foreach (long AgeRatingContentDescriptionId in ageRating.ContentDescriptions.Ids)
|
||||
{
|
||||
AgeRatingContentDescription ageRatingContentDescription = AgeRatingContentDescriptions.GetAgeRatingContentDescriptions(AgeRatingContentDescriptionId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private enum SearchUsing
|
||||
{
|
||||
id,
|
||||
slug
|
||||
}
|
||||
|
||||
private static async Task<AgeRating> GetObjectFromServer(string WhereClause)
|
||||
{
|
||||
// get AgeRatings metadata
|
||||
var results = await igdb.QueryAsync<AgeRating>(IGDBClient.Endpoints.AgeRating, query: fieldList + " " + WhereClause + ";");
|
||||
var result = results.First();
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
107
gaseous-server/Classes/Metadata/AgeRatingContentDescriptions.cs
Normal file
107
gaseous-server/Classes/Metadata/AgeRatingContentDescriptions.cs
Normal file
@@ -0,0 +1,107 @@
|
||||
using System;
|
||||
using gaseous_tools;
|
||||
using IGDB;
|
||||
using IGDB.Models;
|
||||
using MySqlX.XDevAPI.Common;
|
||||
using static gaseous_tools.Config.ConfigFile;
|
||||
|
||||
namespace gaseous_server.Classes.Metadata
|
||||
{
|
||||
public class AgeRatingContentDescriptions
|
||||
{
|
||||
const string fieldList = "fields category,checksum,description;";
|
||||
|
||||
public AgeRatingContentDescriptions()
|
||||
{
|
||||
}
|
||||
|
||||
private static IGDBClient igdb = new IGDBClient(
|
||||
// Found in Twitch Developer portal for your app
|
||||
Config.IGDB.ClientId,
|
||||
Config.IGDB.Secret
|
||||
);
|
||||
|
||||
public static AgeRatingContentDescription? GetAgeRatingContentDescriptions(long? Id)
|
||||
{
|
||||
if ((Id == 0) || (Id == null))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
Task<AgeRatingContentDescription> RetVal = _GetAgeRatingContentDescriptions(SearchUsing.id, Id);
|
||||
return RetVal.Result;
|
||||
}
|
||||
}
|
||||
|
||||
public static AgeRatingContentDescription GetAgeRatingContentDescriptions(string Slug)
|
||||
{
|
||||
Task<AgeRatingContentDescription> RetVal = _GetAgeRatingContentDescriptions(SearchUsing.slug, Slug);
|
||||
return RetVal.Result;
|
||||
}
|
||||
|
||||
private static async Task<AgeRatingContentDescription> _GetAgeRatingContentDescriptions(SearchUsing searchUsing, object searchValue)
|
||||
{
|
||||
// check database first
|
||||
Storage.CacheStatus? cacheStatus = new Storage.CacheStatus();
|
||||
if (searchUsing == SearchUsing.id)
|
||||
{
|
||||
cacheStatus = Storage.GetCacheStatus("AgeRatingContentDescription", (long)searchValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
cacheStatus = Storage.GetCacheStatus("AgeRatingContentDescription", (string)searchValue);
|
||||
}
|
||||
|
||||
// set up where clause
|
||||
string WhereClause = "";
|
||||
switch (searchUsing)
|
||||
{
|
||||
case SearchUsing.id:
|
||||
WhereClause = "where id = " + searchValue;
|
||||
break;
|
||||
case SearchUsing.slug:
|
||||
WhereClause = "where slug = " + searchValue;
|
||||
break;
|
||||
default:
|
||||
throw new Exception("Invalid search type");
|
||||
}
|
||||
|
||||
AgeRatingContentDescription returnValue = new AgeRatingContentDescription();
|
||||
switch (cacheStatus)
|
||||
{
|
||||
case Storage.CacheStatus.NotPresent:
|
||||
returnValue = await GetObjectFromServer(WhereClause);
|
||||
Storage.NewCacheValue(returnValue);
|
||||
break;
|
||||
case Storage.CacheStatus.Expired:
|
||||
returnValue = await GetObjectFromServer(WhereClause);
|
||||
Storage.NewCacheValue(returnValue, true);
|
||||
break;
|
||||
case Storage.CacheStatus.Current:
|
||||
returnValue = Storage.GetCacheValue<AgeRatingContentDescription>(returnValue, "id", (long)searchValue);
|
||||
break;
|
||||
default:
|
||||
throw new Exception("How did you get here?");
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
private enum SearchUsing
|
||||
{
|
||||
id,
|
||||
slug
|
||||
}
|
||||
|
||||
private static async Task<AgeRatingContentDescription> GetObjectFromServer(string WhereClause)
|
||||
{
|
||||
// get AgeRatingContentDescriptionContentDescriptions metadata
|
||||
var results = await igdb.QueryAsync<AgeRatingContentDescription>(IGDBClient.Endpoints.AgeRatingContentDescriptions, query: fieldList + " " + WhereClause + ";");
|
||||
var result = results.First();
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
107
gaseous-server/Classes/Metadata/AlternativeNames.cs
Normal file
107
gaseous-server/Classes/Metadata/AlternativeNames.cs
Normal file
@@ -0,0 +1,107 @@
|
||||
using System;
|
||||
using gaseous_tools;
|
||||
using IGDB;
|
||||
using IGDB.Models;
|
||||
using MySqlX.XDevAPI.Common;
|
||||
using static gaseous_tools.Config.ConfigFile;
|
||||
|
||||
namespace gaseous_server.Classes.Metadata
|
||||
{
|
||||
public class AlternativeNames
|
||||
{
|
||||
const string fieldList = "fields checksum,comment,game,name;";
|
||||
|
||||
public AlternativeNames()
|
||||
{
|
||||
}
|
||||
|
||||
private static IGDBClient igdb = new IGDBClient(
|
||||
// Found in Twitch Developer portal for your app
|
||||
Config.IGDB.ClientId,
|
||||
Config.IGDB.Secret
|
||||
);
|
||||
|
||||
public static AlternativeName? GetAlternativeNames(long? Id)
|
||||
{
|
||||
if ((Id == 0) || (Id == null))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
Task<AlternativeName> RetVal = _GetAlternativeNames(SearchUsing.id, Id);
|
||||
return RetVal.Result;
|
||||
}
|
||||
}
|
||||
|
||||
public static AlternativeName GetAlternativeNames(string Slug)
|
||||
{
|
||||
Task<AlternativeName> RetVal = _GetAlternativeNames(SearchUsing.slug, Slug);
|
||||
return RetVal.Result;
|
||||
}
|
||||
|
||||
private static async Task<AlternativeName> _GetAlternativeNames(SearchUsing searchUsing, object searchValue)
|
||||
{
|
||||
// check database first
|
||||
Storage.CacheStatus? cacheStatus = new Storage.CacheStatus();
|
||||
if (searchUsing == SearchUsing.id)
|
||||
{
|
||||
cacheStatus = Storage.GetCacheStatus("AlternativeName", (long)searchValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
cacheStatus = Storage.GetCacheStatus("AlternativeName", (string)searchValue);
|
||||
}
|
||||
|
||||
// set up where clause
|
||||
string WhereClause = "";
|
||||
switch (searchUsing)
|
||||
{
|
||||
case SearchUsing.id:
|
||||
WhereClause = "where id = " + searchValue;
|
||||
break;
|
||||
case SearchUsing.slug:
|
||||
WhereClause = "where slug = " + searchValue;
|
||||
break;
|
||||
default:
|
||||
throw new Exception("Invalid search type");
|
||||
}
|
||||
|
||||
AlternativeName returnValue = new AlternativeName();
|
||||
switch (cacheStatus)
|
||||
{
|
||||
case Storage.CacheStatus.NotPresent:
|
||||
returnValue = await GetObjectFromServer(WhereClause);
|
||||
Storage.NewCacheValue(returnValue);
|
||||
break;
|
||||
case Storage.CacheStatus.Expired:
|
||||
returnValue = await GetObjectFromServer(WhereClause);
|
||||
Storage.NewCacheValue(returnValue, true);
|
||||
break;
|
||||
case Storage.CacheStatus.Current:
|
||||
returnValue = Storage.GetCacheValue<AlternativeName>(returnValue, "id", (long)searchValue);
|
||||
break;
|
||||
default:
|
||||
throw new Exception("How did you get here?");
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
private enum SearchUsing
|
||||
{
|
||||
id,
|
||||
slug
|
||||
}
|
||||
|
||||
private static async Task<AlternativeName> GetObjectFromServer(string WhereClause)
|
||||
{
|
||||
// get AlternativeNames metadata
|
||||
var results = await igdb.QueryAsync<AlternativeName>(IGDBClient.Endpoints.AlternativeNames, query: fieldList + " " + WhereClause + ";");
|
||||
var result = results.First();
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
107
gaseous-server/Classes/Metadata/Collections.cs
Normal file
107
gaseous-server/Classes/Metadata/Collections.cs
Normal file
@@ -0,0 +1,107 @@
|
||||
using System;
|
||||
using gaseous_tools;
|
||||
using IGDB;
|
||||
using IGDB.Models;
|
||||
using MySqlX.XDevAPI.Common;
|
||||
using static gaseous_tools.Config.ConfigFile;
|
||||
|
||||
namespace gaseous_server.Classes.Metadata
|
||||
{
|
||||
public class Collections
|
||||
{
|
||||
const string fieldList = "fields checksum,created_at,games,name,slug,updated_at,url;";
|
||||
|
||||
public Collections()
|
||||
{
|
||||
}
|
||||
|
||||
private static IGDBClient igdb = new IGDBClient(
|
||||
// Found in Twitch Developer portal for your app
|
||||
Config.IGDB.ClientId,
|
||||
Config.IGDB.Secret
|
||||
);
|
||||
|
||||
public static Collection? GetCollections(long? Id)
|
||||
{
|
||||
if ((Id == 0) || (Id == null))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
Task<Collection> RetVal = _GetCollections(SearchUsing.id, Id);
|
||||
return RetVal.Result;
|
||||
}
|
||||
}
|
||||
|
||||
public static Collection GetCollections(string Slug)
|
||||
{
|
||||
Task<Collection> RetVal = _GetCollections(SearchUsing.slug, Slug);
|
||||
return RetVal.Result;
|
||||
}
|
||||
|
||||
private static async Task<Collection> _GetCollections(SearchUsing searchUsing, object searchValue)
|
||||
{
|
||||
// check database first
|
||||
Storage.CacheStatus? cacheStatus = new Storage.CacheStatus();
|
||||
if (searchUsing == SearchUsing.id)
|
||||
{
|
||||
cacheStatus = Storage.GetCacheStatus("Collection", (long)searchValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
cacheStatus = Storage.GetCacheStatus("Collection", (string)searchValue);
|
||||
}
|
||||
|
||||
// set up where clause
|
||||
string WhereClause = "";
|
||||
switch (searchUsing)
|
||||
{
|
||||
case SearchUsing.id:
|
||||
WhereClause = "where id = " + searchValue;
|
||||
break;
|
||||
case SearchUsing.slug:
|
||||
WhereClause = "where slug = " + searchValue;
|
||||
break;
|
||||
default:
|
||||
throw new Exception("Invalid search type");
|
||||
}
|
||||
|
||||
Collection returnValue = new Collection();
|
||||
switch (cacheStatus)
|
||||
{
|
||||
case Storage.CacheStatus.NotPresent:
|
||||
returnValue = await GetObjectFromServer(WhereClause);
|
||||
Storage.NewCacheValue(returnValue);
|
||||
break;
|
||||
case Storage.CacheStatus.Expired:
|
||||
returnValue = await GetObjectFromServer(WhereClause);
|
||||
Storage.NewCacheValue(returnValue, true);
|
||||
break;
|
||||
case Storage.CacheStatus.Current:
|
||||
returnValue = Storage.GetCacheValue<Collection>(returnValue, "id", (long)searchValue);
|
||||
break;
|
||||
default:
|
||||
throw new Exception("How did you get here?");
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
private enum SearchUsing
|
||||
{
|
||||
id,
|
||||
slug
|
||||
}
|
||||
|
||||
private static async Task<Collection> GetObjectFromServer(string WhereClause)
|
||||
{
|
||||
// get Collections metadata
|
||||
var results = await igdb.QueryAsync<Collection>(IGDBClient.Endpoints.Collections, query: fieldList + " " + WhereClause + ";");
|
||||
var result = results.First();
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
120
gaseous-server/Classes/Metadata/ExternalGames.cs
Normal file
120
gaseous-server/Classes/Metadata/ExternalGames.cs
Normal file
@@ -0,0 +1,120 @@
|
||||
using System;
|
||||
using gaseous_tools;
|
||||
using IGDB;
|
||||
using IGDB.Models;
|
||||
using MySqlX.XDevAPI.Common;
|
||||
using static gaseous_tools.Config.ConfigFile;
|
||||
|
||||
namespace gaseous_server.Classes.Metadata
|
||||
{
|
||||
public class ExternalGames
|
||||
{
|
||||
const string fieldList = "fields category,checksum,countries,created_at,game,media,name,platform,uid,updated_at,url,year;";
|
||||
|
||||
public ExternalGames()
|
||||
{
|
||||
}
|
||||
|
||||
private static IGDBClient igdb = new IGDBClient(
|
||||
// Found in Twitch Developer portal for your app
|
||||
Config.IGDB.ClientId,
|
||||
Config.IGDB.Secret
|
||||
);
|
||||
|
||||
public static ExternalGame? GetExternalGames(long? Id)
|
||||
{
|
||||
if ((Id == 0) || (Id == null))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
Task<ExternalGame> RetVal = _GetExternalGames(SearchUsing.id, Id);
|
||||
return RetVal.Result;
|
||||
}
|
||||
}
|
||||
|
||||
public static ExternalGame GetExternalGames(string Slug)
|
||||
{
|
||||
Task<ExternalGame> RetVal = _GetExternalGames(SearchUsing.slug, Slug);
|
||||
return RetVal.Result;
|
||||
}
|
||||
|
||||
private static async Task<ExternalGame> _GetExternalGames(SearchUsing searchUsing, object searchValue)
|
||||
{
|
||||
// check database first
|
||||
Storage.CacheStatus? cacheStatus = new Storage.CacheStatus();
|
||||
if (searchUsing == SearchUsing.id)
|
||||
{
|
||||
cacheStatus = Storage.GetCacheStatus("ExternalGame", (long)searchValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
cacheStatus = Storage.GetCacheStatus("ExternalGame", (string)searchValue);
|
||||
}
|
||||
|
||||
// set up where clause
|
||||
string WhereClause = "";
|
||||
switch (searchUsing)
|
||||
{
|
||||
case SearchUsing.id:
|
||||
WhereClause = "where id = " + searchValue;
|
||||
break;
|
||||
case SearchUsing.slug:
|
||||
WhereClause = "where slug = " + searchValue;
|
||||
break;
|
||||
default:
|
||||
throw new Exception("Invalid search type");
|
||||
}
|
||||
|
||||
ExternalGame returnValue = new ExternalGame();
|
||||
switch (cacheStatus)
|
||||
{
|
||||
case Storage.CacheStatus.NotPresent:
|
||||
returnValue = await GetObjectFromServer(WhereClause);
|
||||
if (returnValue != null)
|
||||
{
|
||||
Storage.NewCacheValue(returnValue);
|
||||
}
|
||||
break;
|
||||
case Storage.CacheStatus.Expired:
|
||||
returnValue = await GetObjectFromServer(WhereClause);
|
||||
if (returnValue != null)
|
||||
{
|
||||
Storage.NewCacheValue(returnValue, true);
|
||||
}
|
||||
break;
|
||||
case Storage.CacheStatus.Current:
|
||||
returnValue = Storage.GetCacheValue<ExternalGame>(returnValue, "id", (long)searchValue);
|
||||
break;
|
||||
default:
|
||||
throw new Exception("How did you get here?");
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
private enum SearchUsing
|
||||
{
|
||||
id,
|
||||
slug
|
||||
}
|
||||
|
||||
private static async Task<ExternalGame?> GetObjectFromServer(string WhereClause)
|
||||
{
|
||||
// get ExternalGames metadata
|
||||
var results = await igdb.QueryAsync<ExternalGame>(IGDBClient.Endpoints.ExternalGames, query: fieldList + " " + WhereClause + ";");
|
||||
if (results.Length > 0)
|
||||
{
|
||||
var result = results.First();
|
||||
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
107
gaseous-server/Classes/Metadata/Franchises.cs
Normal file
107
gaseous-server/Classes/Metadata/Franchises.cs
Normal file
@@ -0,0 +1,107 @@
|
||||
using System;
|
||||
using gaseous_tools;
|
||||
using IGDB;
|
||||
using IGDB.Models;
|
||||
using MySqlX.XDevAPI.Common;
|
||||
using static gaseous_tools.Config.ConfigFile;
|
||||
|
||||
namespace gaseous_server.Classes.Metadata
|
||||
{
|
||||
public class Franchises
|
||||
{
|
||||
const string fieldList = "fields checksum,created_at,games,name,slug,updated_at,url;";
|
||||
|
||||
public Franchises()
|
||||
{
|
||||
}
|
||||
|
||||
private static IGDBClient igdb = new IGDBClient(
|
||||
// Found in Twitch Developer portal for your app
|
||||
Config.IGDB.ClientId,
|
||||
Config.IGDB.Secret
|
||||
);
|
||||
|
||||
public static Franchise? GetFranchises(long? Id)
|
||||
{
|
||||
if ((Id == 0) || (Id == null))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
Task<Franchise> RetVal = _GetFranchises(SearchUsing.id, Id);
|
||||
return RetVal.Result;
|
||||
}
|
||||
}
|
||||
|
||||
public static Franchise GetFranchises(string Slug)
|
||||
{
|
||||
Task<Franchise> RetVal = _GetFranchises(SearchUsing.slug, Slug);
|
||||
return RetVal.Result;
|
||||
}
|
||||
|
||||
private static async Task<Franchise> _GetFranchises(SearchUsing searchUsing, object searchValue)
|
||||
{
|
||||
// check database first
|
||||
Storage.CacheStatus? cacheStatus = new Storage.CacheStatus();
|
||||
if (searchUsing == SearchUsing.id)
|
||||
{
|
||||
cacheStatus = Storage.GetCacheStatus("Franchise", (long)searchValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
cacheStatus = Storage.GetCacheStatus("Franchise", (string)searchValue);
|
||||
}
|
||||
|
||||
// set up where clause
|
||||
string WhereClause = "";
|
||||
switch (searchUsing)
|
||||
{
|
||||
case SearchUsing.id:
|
||||
WhereClause = "where id = " + searchValue;
|
||||
break;
|
||||
case SearchUsing.slug:
|
||||
WhereClause = "where slug = " + searchValue;
|
||||
break;
|
||||
default:
|
||||
throw new Exception("Invalid search type");
|
||||
}
|
||||
|
||||
Franchise returnValue = new Franchise();
|
||||
switch (cacheStatus)
|
||||
{
|
||||
case Storage.CacheStatus.NotPresent:
|
||||
returnValue = await GetObjectFromServer(WhereClause);
|
||||
Storage.NewCacheValue(returnValue);
|
||||
break;
|
||||
case Storage.CacheStatus.Expired:
|
||||
returnValue = await GetObjectFromServer(WhereClause);
|
||||
Storage.NewCacheValue(returnValue, true);
|
||||
break;
|
||||
case Storage.CacheStatus.Current:
|
||||
returnValue = Storage.GetCacheValue<Franchise>(returnValue, "id", (long)searchValue);
|
||||
break;
|
||||
default:
|
||||
throw new Exception("How did you get here?");
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
private enum SearchUsing
|
||||
{
|
||||
id,
|
||||
slug
|
||||
}
|
||||
|
||||
private static async Task<Franchise> GetObjectFromServer(string WhereClause)
|
||||
{
|
||||
// get FranchiseContentDescriptions metadata
|
||||
var results = await igdb.QueryAsync<Franchise>(IGDBClient.Endpoints.Franchies, query: fieldList + " " + WhereClause + ";");
|
||||
var result = results.First();
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
110
gaseous-server/Classes/Metadata/GameVideos.cs
Normal file
110
gaseous-server/Classes/Metadata/GameVideos.cs
Normal file
@@ -0,0 +1,110 @@
|
||||
using System;
|
||||
using gaseous_tools;
|
||||
using IGDB;
|
||||
using IGDB.Models;
|
||||
using MySqlX.XDevAPI.Common;
|
||||
using static gaseous_tools.Config.ConfigFile;
|
||||
|
||||
namespace gaseous_server.Classes.Metadata
|
||||
{
|
||||
public class GamesVideos
|
||||
{
|
||||
const string fieldList = "fields checksum,game,name,video_id;";
|
||||
|
||||
public GamesVideos()
|
||||
{
|
||||
}
|
||||
|
||||
private static IGDBClient igdb = new IGDBClient(
|
||||
// Found in Twitch Developer portal for your app
|
||||
Config.IGDB.ClientId,
|
||||
Config.IGDB.Secret
|
||||
);
|
||||
|
||||
public static GameVideo? GetGame_Videos(long? Id)
|
||||
{
|
||||
if ((Id == 0) || (Id == null))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
Task<GameVideo> RetVal = _GetGame_Videos(SearchUsing.id, Id);
|
||||
return RetVal.Result;
|
||||
}
|
||||
}
|
||||
|
||||
public static GameVideo GetGame_Videos(string Slug)
|
||||
{
|
||||
Task<GameVideo> RetVal = _GetGame_Videos(SearchUsing.slug, Slug);
|
||||
return RetVal.Result;
|
||||
}
|
||||
|
||||
private static async Task<GameVideo> _GetGame_Videos(SearchUsing searchUsing, object searchValue)
|
||||
{
|
||||
// check database first
|
||||
Storage.CacheStatus? cacheStatus = new Storage.CacheStatus();
|
||||
if (searchUsing == SearchUsing.id)
|
||||
{
|
||||
cacheStatus = Storage.GetCacheStatus("GameVideo", (long)searchValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
cacheStatus = Storage.GetCacheStatus("GameVideo", (string)searchValue);
|
||||
}
|
||||
|
||||
// set up where clause
|
||||
string WhereClause = "";
|
||||
switch (searchUsing)
|
||||
{
|
||||
case SearchUsing.id:
|
||||
WhereClause = "where id = " + searchValue;
|
||||
break;
|
||||
case SearchUsing.slug:
|
||||
WhereClause = "where slug = " + searchValue;
|
||||
break;
|
||||
default:
|
||||
throw new Exception("Invalid search type");
|
||||
}
|
||||
|
||||
GameVideo returnValue = new GameVideo();
|
||||
bool forceImageDownload = false;
|
||||
switch (cacheStatus)
|
||||
{
|
||||
case Storage.CacheStatus.NotPresent:
|
||||
returnValue = await GetObjectFromServer(WhereClause);
|
||||
Storage.NewCacheValue(returnValue);
|
||||
forceImageDownload = true;
|
||||
break;
|
||||
case Storage.CacheStatus.Expired:
|
||||
returnValue = await GetObjectFromServer(WhereClause);
|
||||
Storage.NewCacheValue(returnValue, true);
|
||||
forceImageDownload = true;
|
||||
break;
|
||||
case Storage.CacheStatus.Current:
|
||||
returnValue = Storage.GetCacheValue<GameVideo>(returnValue, "id", (long)searchValue);
|
||||
break;
|
||||
default:
|
||||
throw new Exception("How did you get here?");
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
private enum SearchUsing
|
||||
{
|
||||
id,
|
||||
slug
|
||||
}
|
||||
|
||||
private static async Task<GameVideo> GetObjectFromServer(string WhereClause)
|
||||
{
|
||||
// get Game_Videos metadata
|
||||
var results = await igdb.QueryAsync<GameVideo>(IGDBClient.Endpoints.GameVideos, query: fieldList + " " + WhereClause + ";");
|
||||
var result = results.First();
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace gaseous_server.Classes.Metadata
|
||||
Config.IGDB.Secret
|
||||
);
|
||||
|
||||
public static Game? GetGame(long Id, bool followSubGames)
|
||||
public static Game? GetGame(long Id, bool followSubGames, bool forceRefresh)
|
||||
{
|
||||
if (Id == 0)
|
||||
{
|
||||
@@ -28,18 +28,18 @@ namespace gaseous_server.Classes.Metadata
|
||||
}
|
||||
else
|
||||
{
|
||||
Task<Game> RetVal = _GetGame(SearchUsing.id, Id, followSubGames);
|
||||
Task<Game> RetVal = _GetGame(SearchUsing.id, Id, followSubGames, forceRefresh);
|
||||
return RetVal.Result;
|
||||
}
|
||||
}
|
||||
|
||||
public static Game GetGame(string Slug, bool followSubGames)
|
||||
public static Game GetGame(string Slug, bool followSubGames, bool forceRefresh)
|
||||
{
|
||||
Task<Game> RetVal = _GetGame(SearchUsing.slug, Slug, followSubGames);
|
||||
Task<Game> RetVal = _GetGame(SearchUsing.slug, Slug, followSubGames, forceRefresh);
|
||||
return RetVal.Result;
|
||||
}
|
||||
|
||||
private static async Task<Game> _GetGame(SearchUsing searchUsing, object searchValue, bool followSubGames = false)
|
||||
private static async Task<Game> _GetGame(SearchUsing searchUsing, object searchValue, bool followSubGames = false, bool forceRefresh = false)
|
||||
{
|
||||
// check database first
|
||||
Storage.CacheStatus? cacheStatus = new Storage.CacheStatus();
|
||||
@@ -52,6 +52,11 @@ namespace gaseous_server.Classes.Metadata
|
||||
cacheStatus = Storage.GetCacheStatus("Game", (string)searchValue);
|
||||
}
|
||||
|
||||
if (forceRefresh == true)
|
||||
{
|
||||
if (cacheStatus == Storage.CacheStatus.Current) { cacheStatus = Storage.CacheStatus.Expired; }
|
||||
}
|
||||
|
||||
// set up where clause
|
||||
string WhereClause = "";
|
||||
switch (searchUsing)
|
||||
@@ -88,6 +93,20 @@ namespace gaseous_server.Classes.Metadata
|
||||
|
||||
private static void UpdateSubClasses(Game Game, bool followSubGames)
|
||||
{
|
||||
if (Game.AgeRatings != null)
|
||||
{
|
||||
foreach (long AgeRatingId in Game.AgeRatings.Ids)
|
||||
{
|
||||
AgeRating GameAgeRating = AgeRatings.GetAgeRatings(AgeRatingId);
|
||||
}
|
||||
}
|
||||
if (Game.AlternativeNames != null)
|
||||
{
|
||||
foreach (long AlternativeNameId in Game.AlternativeNames.Ids)
|
||||
{
|
||||
AlternativeName GameAlternativeName = AlternativeNames.GetAlternativeNames(AlternativeNameId);
|
||||
}
|
||||
}
|
||||
if (Game.Artworks != null)
|
||||
{
|
||||
foreach (long ArtworkId in Game.Artworks.Ids)
|
||||
@@ -102,19 +121,48 @@ namespace gaseous_server.Classes.Metadata
|
||||
if (Game.Dlcs != null) { gamesToFetch.AddRange(Game.Dlcs.Ids); }
|
||||
if (Game.Expansions != null) { gamesToFetch.AddRange(Game.Expansions.Ids); }
|
||||
if (Game.ParentGame != null) { gamesToFetch.Add((long)Game.ParentGame.Id); }
|
||||
if (Game.SimilarGames != null) { gamesToFetch.AddRange(Game.SimilarGames.Ids); }
|
||||
//if (Game.SimilarGames != null) { gamesToFetch.AddRange(Game.SimilarGames.Ids); }
|
||||
if (Game.StandaloneExpansions != null) { gamesToFetch.AddRange(Game.StandaloneExpansions.Ids); }
|
||||
if (Game.VersionParent != null) { gamesToFetch.Add((long)Game.VersionParent.Id); }
|
||||
|
||||
foreach (long gameId in gamesToFetch)
|
||||
{
|
||||
Game relatedGame = GetGame(gameId, false);
|
||||
Game relatedGame = GetGame(gameId, false, false);
|
||||
}
|
||||
}
|
||||
if (Game.Collection != null)
|
||||
{
|
||||
Collection GameCollection = Collections.GetCollections(Game.Collection.Id);
|
||||
}
|
||||
if (Game.Cover != null)
|
||||
{
|
||||
Cover GameCover = Covers.GetCover(Game.Cover.Id, Config.LibraryConfiguration.LibraryMetadataDirectory_Game(Game));
|
||||
}
|
||||
if (Game.ExternalGames != null)
|
||||
{
|
||||
foreach (long ExternalGameId in Game.ExternalGames.Ids)
|
||||
{
|
||||
ExternalGame GameExternalGame = ExternalGames.GetExternalGames(ExternalGameId);
|
||||
}
|
||||
}
|
||||
if (Game.Franchise != null)
|
||||
{
|
||||
Franchise GameFranchise = Franchises.GetFranchises(Game.Franchise.Id);
|
||||
}
|
||||
if (Game.Franchises != null)
|
||||
{
|
||||
foreach (long FranchiseId in Game.Franchises.Ids)
|
||||
{
|
||||
Franchise GameFranchise = Franchises.GetFranchises(FranchiseId);
|
||||
}
|
||||
}
|
||||
if (Game.Genres != null)
|
||||
{
|
||||
foreach (long GenreId in Game.Genres.Ids)
|
||||
{
|
||||
Genre GameGenre = Genres.GetGenres(GenreId);
|
||||
}
|
||||
}
|
||||
if (Game.Platforms != null)
|
||||
{
|
||||
foreach (long PlatformId in Game.Platforms.Ids)
|
||||
@@ -129,6 +177,13 @@ namespace gaseous_server.Classes.Metadata
|
||||
Screenshot GameScreenshot = Screenshots.GetScreenshot(ScreenshotId, Config.LibraryConfiguration.LibraryMetadataDirectory_Game(Game));
|
||||
}
|
||||
}
|
||||
if (Game.Videos != null)
|
||||
{
|
||||
foreach (long GameVideoId in Game.Videos.Ids)
|
||||
{
|
||||
GameVideo gameVideo = GamesVideos.GetGame_Videos(GameVideoId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private enum SearchUsing
|
||||
|
||||
110
gaseous-server/Classes/Metadata/Genres.cs
Normal file
110
gaseous-server/Classes/Metadata/Genres.cs
Normal file
@@ -0,0 +1,110 @@
|
||||
using System;
|
||||
using gaseous_tools;
|
||||
using IGDB;
|
||||
using IGDB.Models;
|
||||
using MySqlX.XDevAPI.Common;
|
||||
using static gaseous_tools.Config.ConfigFile;
|
||||
|
||||
namespace gaseous_server.Classes.Metadata
|
||||
{
|
||||
public class Genres
|
||||
{
|
||||
const string fieldList = "fields checksum,created_at,name,slug,updated_at,url;";
|
||||
|
||||
public Genres()
|
||||
{
|
||||
}
|
||||
|
||||
private static IGDBClient igdb = new IGDBClient(
|
||||
// Found in Twitch Developer portal for your app
|
||||
Config.IGDB.ClientId,
|
||||
Config.IGDB.Secret
|
||||
);
|
||||
|
||||
public static Genre? GetGenres(long? Id)
|
||||
{
|
||||
if ((Id == 0) || (Id == null))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
Task<Genre> RetVal = _GetGenres(SearchUsing.id, Id);
|
||||
return RetVal.Result;
|
||||
}
|
||||
}
|
||||
|
||||
public static Genre GetGenres(string Slug)
|
||||
{
|
||||
Task<Genre> RetVal = _GetGenres(SearchUsing.slug, Slug);
|
||||
return RetVal.Result;
|
||||
}
|
||||
|
||||
private static async Task<Genre> _GetGenres(SearchUsing searchUsing, object searchValue)
|
||||
{
|
||||
// check database first
|
||||
Storage.CacheStatus? cacheStatus = new Storage.CacheStatus();
|
||||
if (searchUsing == SearchUsing.id)
|
||||
{
|
||||
cacheStatus = Storage.GetCacheStatus("Genre", (long)searchValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
cacheStatus = Storage.GetCacheStatus("Genre", (string)searchValue);
|
||||
}
|
||||
|
||||
// set up where clause
|
||||
string WhereClause = "";
|
||||
switch (searchUsing)
|
||||
{
|
||||
case SearchUsing.id:
|
||||
WhereClause = "where id = " + searchValue;
|
||||
break;
|
||||
case SearchUsing.slug:
|
||||
WhereClause = "where slug = " + searchValue;
|
||||
break;
|
||||
default:
|
||||
throw new Exception("Invalid search type");
|
||||
}
|
||||
|
||||
Genre returnValue = new Genre();
|
||||
bool forceImageDownload = false;
|
||||
switch (cacheStatus)
|
||||
{
|
||||
case Storage.CacheStatus.NotPresent:
|
||||
returnValue = await GetObjectFromServer(WhereClause);
|
||||
Storage.NewCacheValue(returnValue);
|
||||
forceImageDownload = true;
|
||||
break;
|
||||
case Storage.CacheStatus.Expired:
|
||||
returnValue = await GetObjectFromServer(WhereClause);
|
||||
Storage.NewCacheValue(returnValue, true);
|
||||
forceImageDownload = true;
|
||||
break;
|
||||
case Storage.CacheStatus.Current:
|
||||
returnValue = Storage.GetCacheValue<Genre>(returnValue, "id", (long)searchValue);
|
||||
break;
|
||||
default:
|
||||
throw new Exception("How did you get here?");
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
private enum SearchUsing
|
||||
{
|
||||
id,
|
||||
slug
|
||||
}
|
||||
|
||||
private static async Task<Genre> GetObjectFromServer(string WhereClause)
|
||||
{
|
||||
// get Genres metadata
|
||||
var results = await igdb.QueryAsync<Genre>(IGDBClient.Endpoints.Genres, query: fieldList + " " + WhereClause + ";");
|
||||
var result = results.First();
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -243,6 +243,15 @@ namespace gaseous_server.Classes.Metadata
|
||||
break;
|
||||
case "[igdb.models.gamestatus":
|
||||
property.SetValue(EndpointType, (GameStatus)dataRow[property.Name]);
|
||||
break;
|
||||
case "[igdb.models.ageratingcategory":
|
||||
property.SetValue(EndpointType, (AgeRatingCategory)dataRow[property.Name]);
|
||||
break;
|
||||
case "[igdb.models.ageratingtitle":
|
||||
property.SetValue(EndpointType, (AgeRatingTitle)dataRow[property.Name]);
|
||||
break;
|
||||
case "[igdb.models.externalcategory":
|
||||
property.SetValue(EndpointType, (ExternalCategory)dataRow[property.Name]);
|
||||
break;
|
||||
default:
|
||||
property.SetValue(EndpointType, dataRow[property.Name]);
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace gaseous_server.Classes
|
||||
{
|
||||
public class MetadataManagement
|
||||
{
|
||||
public static void RefreshMetadata()
|
||||
public static void RefreshMetadata(bool forceRefresh = false)
|
||||
{
|
||||
Database db = new gaseous_tools.Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||
string sql = "SELECT id, `name` FROM game;";
|
||||
@@ -15,7 +15,7 @@ namespace gaseous_server.Classes
|
||||
foreach (DataRow dr in dt.Rows)
|
||||
{
|
||||
Logging.Log(Logging.LogType.Information, "Metadata Refresh", "Refreshing metadata for game " + dr["name"] + " (" + dr["id"] + ")");
|
||||
Metadata.Games.GetGame((long)dr["id"], true);
|
||||
Metadata.Games.GetGame((long)dr["id"], true, forceRefresh);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,19 @@ namespace gaseous_server.Controllers
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public List<Models.Signatures_Games> GetByTosecName(string TosecName = "")
|
||||
{
|
||||
if (TosecName.Length > 0)
|
||||
{
|
||||
return _GetSignature("signatures_roms.name = @searchstring", TosecName);
|
||||
} else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private List<Models.Signatures_Games> _GetSignature(string sqlWhere, string searchString)
|
||||
{
|
||||
Database db = new gaseous_tools.Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||
|
||||
@@ -72,7 +72,7 @@ namespace gaseous_server
|
||||
|
||||
case QueueItemType.MetadataRefresh:
|
||||
Logging.Log(Logging.LogType.Information, "Timered Event", "Starting Metadata Refresher");
|
||||
Classes.MetadataManagement.RefreshMetadata();
|
||||
Classes.MetadataManagement.RefreshMetadata(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user