Compare commits
18 Commits
v1.7.0-pre
...
v1.7.0-pre
Author | SHA1 | Date | |
---|---|---|---|
![]() |
722c153e40 | ||
![]() |
b691eab0ee | ||
![]() |
907b3e42c4 | ||
![]() |
128bbcc1df | ||
![]() |
789ec7fc17 | ||
![]() |
32051493a8 | ||
![]() |
7b241ee13e | ||
![]() |
84017639eb | ||
![]() |
9e346910f4 | ||
![]() |
e7239c428b | ||
![]() |
9288eb8f12 | ||
![]() |
e32e7ad36f | ||
![]() |
3de551be95 | ||
![]() |
8e3fa4f8d5 | ||
![]() |
b564edb158 | ||
![]() |
0bf2ba5d96 | ||
![]() |
688af162f5 | ||
![]() |
7e4fccb0c1 |
15
.github/release.yml
vendored
Normal file
15
.github/release.yml
vendored
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
changelog:
|
||||||
|
categories:
|
||||||
|
- title: What's New
|
||||||
|
labels:
|
||||||
|
- '*'
|
||||||
|
exclude:
|
||||||
|
labels:
|
||||||
|
- bug
|
||||||
|
- dependencies
|
||||||
|
- title: Bug Fixes
|
||||||
|
labels:
|
||||||
|
- bug
|
||||||
|
- title: Dependencies
|
||||||
|
labels:
|
||||||
|
- dependencies
|
@@ -11,5 +11,6 @@ namespace Authentication
|
|||||||
public class ApplicationUser : IdentityUser
|
public class ApplicationUser : IdentityUser
|
||||||
{
|
{
|
||||||
public SecurityProfileViewModel SecurityProfile { get; set; }
|
public SecurityProfileViewModel SecurityProfile { get; set; }
|
||||||
|
public List<UserPreferenceViewModel> UserPreferences { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -99,6 +99,7 @@ namespace Authentication
|
|||||||
user.AccessFailedCount = string.IsNullOrEmpty((string?)row["AccessFailedCount"]) ? 0 : int.Parse((string?)row["AccessFailedCount"]);
|
user.AccessFailedCount = string.IsNullOrEmpty((string?)row["AccessFailedCount"]) ? 0 : int.Parse((string?)row["AccessFailedCount"]);
|
||||||
user.TwoFactorEnabled = row["TwoFactorEnabled"] == "1" ? true:false;
|
user.TwoFactorEnabled = row["TwoFactorEnabled"] == "1" ? true:false;
|
||||||
user.SecurityProfile = GetSecurityProfile(user);
|
user.SecurityProfile = GetSecurityProfile(user);
|
||||||
|
user.UserPreferences = GetPreferences(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
return user;
|
return user;
|
||||||
@@ -135,6 +136,7 @@ namespace Authentication
|
|||||||
user.AccessFailedCount = string.IsNullOrEmpty((string?)row["AccessFailedCount"]) ? 0 : int.Parse((string?)row["AccessFailedCount"]);
|
user.AccessFailedCount = string.IsNullOrEmpty((string?)row["AccessFailedCount"]) ? 0 : int.Parse((string?)row["AccessFailedCount"]);
|
||||||
user.TwoFactorEnabled = row["TwoFactorEnabled"] == "1" ? true:false;
|
user.TwoFactorEnabled = row["TwoFactorEnabled"] == "1" ? true:false;
|
||||||
user.SecurityProfile = GetSecurityProfile(user);
|
user.SecurityProfile = GetSecurityProfile(user);
|
||||||
|
user.UserPreferences = GetPreferences(user);
|
||||||
users.Add(user);
|
users.Add(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,6 +168,7 @@ namespace Authentication
|
|||||||
user.AccessFailedCount = string.IsNullOrEmpty((string?)row["AccessFailedCount"]) ? 0 : int.Parse((string?)row["AccessFailedCount"]);
|
user.AccessFailedCount = string.IsNullOrEmpty((string?)row["AccessFailedCount"]) ? 0 : int.Parse((string?)row["AccessFailedCount"]);
|
||||||
user.TwoFactorEnabled = row["TwoFactorEnabled"] == "1" ? true:false;
|
user.TwoFactorEnabled = row["TwoFactorEnabled"] == "1" ? true:false;
|
||||||
user.SecurityProfile = GetSecurityProfile(user);
|
user.SecurityProfile = GetSecurityProfile(user);
|
||||||
|
user.UserPreferences = GetPreferences(user);
|
||||||
users.Add(user);
|
users.Add(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -273,6 +276,9 @@ namespace Authentication
|
|||||||
// set default security profile
|
// set default security profile
|
||||||
SetSecurityProfile(user, new SecurityProfileViewModel());
|
SetSecurityProfile(user, new SecurityProfileViewModel());
|
||||||
|
|
||||||
|
// set default preferences
|
||||||
|
SetPreferences(user, new List<UserPreferenceViewModel>());
|
||||||
|
|
||||||
return _database.ExecuteCMD(commandText, parameters).Rows.Count;
|
return _database.ExecuteCMD(commandText, parameters).Rows.Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -283,7 +289,7 @@ namespace Authentication
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private int Delete(string userId)
|
private int Delete(string userId)
|
||||||
{
|
{
|
||||||
string commandText = "Delete from Users where Id = @userId";
|
string commandText = "Delete from Users where Id = @userId; Delete from User_Settings where Id = @userId;";
|
||||||
Dictionary<string, object> parameters = new Dictionary<string, object>();
|
Dictionary<string, object> parameters = new Dictionary<string, object>();
|
||||||
parameters.Add("@userId", userId);
|
parameters.Add("@userId", userId);
|
||||||
|
|
||||||
@@ -328,6 +334,9 @@ namespace Authentication
|
|||||||
// set the security profile
|
// set the security profile
|
||||||
SetSecurityProfile(user, user.SecurityProfile);
|
SetSecurityProfile(user, user.SecurityProfile);
|
||||||
|
|
||||||
|
// set preferences
|
||||||
|
SetPreferences(user, user.UserPreferences);
|
||||||
|
|
||||||
return _database.ExecuteCMD(commandText, parameters).Rows.Count;
|
return _database.ExecuteCMD(commandText, parameters).Rows.Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -367,5 +376,66 @@ namespace Authentication
|
|||||||
|
|
||||||
return _database.ExecuteCMD(commandText, parameters).Rows.Count;
|
return _database.ExecuteCMD(commandText, parameters).Rows.Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<UserPreferenceViewModel> GetPreferences(TUser user)
|
||||||
|
{
|
||||||
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
|
string sql = "SELECT `Setting`, `Value` FROM User_Settings WHERE Id=@id;";
|
||||||
|
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||||
|
dbDict.Add("id", user.Id);
|
||||||
|
|
||||||
|
DataTable data = db.ExecuteCMD(sql, dbDict);
|
||||||
|
|
||||||
|
List<UserPreferenceViewModel> userPrefs = new List<UserPreferenceViewModel>();
|
||||||
|
foreach (DataRow row in data.Rows)
|
||||||
|
{
|
||||||
|
UserPreferenceViewModel userPref = new UserPreferenceViewModel();
|
||||||
|
userPref.Setting = (string)row["Setting"];
|
||||||
|
userPref.Value = (string)row["Value"];
|
||||||
|
userPrefs.Add(userPref);
|
||||||
|
}
|
||||||
|
|
||||||
|
return userPrefs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int SetPreferences(TUser user, List<UserPreferenceViewModel> model)
|
||||||
|
{
|
||||||
|
if (model != null)
|
||||||
|
{
|
||||||
|
List<UserPreferenceViewModel> userPreferences = GetPreferences(user);
|
||||||
|
|
||||||
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
|
|
||||||
|
foreach (UserPreferenceViewModel modelItem in model)
|
||||||
|
{
|
||||||
|
bool prefItemFound = false;
|
||||||
|
foreach (UserPreferenceViewModel existing in userPreferences)
|
||||||
|
{
|
||||||
|
if (existing.Setting.ToLower() == modelItem.Setting.ToLower())
|
||||||
|
{
|
||||||
|
prefItemFound = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string sql = "INSERT INTO User_Settings (`Id`, `Setting`, `Value`) VALUES (@id, @setting, @value);";
|
||||||
|
if (prefItemFound == true)
|
||||||
|
{
|
||||||
|
sql = "UPDATE User_Settings SET `Value`=@value WHERE `Id`=@id AND `Setting`=@setting";
|
||||||
|
}
|
||||||
|
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||||
|
dbDict.Add("id", user.Id);
|
||||||
|
dbDict.Add("setting", modelItem.Setting);
|
||||||
|
dbDict.Add("value", modelItem.Value);
|
||||||
|
db.ExecuteNonQuery(sql, dbDict);
|
||||||
|
}
|
||||||
|
|
||||||
|
return model.Count;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -7,6 +7,7 @@ namespace Authentication
|
|||||||
public string EmailAddress { get; set; }
|
public string EmailAddress { get; set; }
|
||||||
public List<String> Roles { get; set; }
|
public List<String> Roles { get; set; }
|
||||||
public SecurityProfileViewModel SecurityProfile { get; set; }
|
public SecurityProfileViewModel SecurityProfile { get; set; }
|
||||||
|
public List<UserPreferenceViewModel> UserPreferences { get; set; }
|
||||||
public string HighestRole {
|
public string HighestRole {
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@@ -5,13 +5,13 @@ namespace Authentication
|
|||||||
public class SecurityProfileViewModel
|
public class SecurityProfileViewModel
|
||||||
{
|
{
|
||||||
public AgeRestrictionItem AgeRestrictionPolicy { get; set; } = new AgeRestrictionItem{
|
public AgeRestrictionItem AgeRestrictionPolicy { get; set; } = new AgeRestrictionItem{
|
||||||
MaximumAgeRestriction = "Adult",
|
MaximumAgeRestriction = gaseous_server.Classes.Metadata.AgeRatings.AgeGroups.AgeRestrictionGroupings.Adult,
|
||||||
IncludeUnrated = true
|
IncludeUnrated = true
|
||||||
};
|
};
|
||||||
|
|
||||||
public class AgeRestrictionItem
|
public class AgeRestrictionItem
|
||||||
{
|
{
|
||||||
public string MaximumAgeRestriction { get; set; }
|
public gaseous_server.Classes.Metadata.AgeRatings.AgeGroups.AgeRestrictionGroupings MaximumAgeRestriction { get; set; }
|
||||||
public bool IncludeUnrated { get; set; }
|
public bool IncludeUnrated { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,8 @@
|
|||||||
|
namespace Authentication;
|
||||||
|
|
||||||
|
public class UserPreferenceViewModel
|
||||||
|
{
|
||||||
|
public string Setting { get; set; }
|
||||||
|
|
||||||
|
public string Value { get; set; }
|
||||||
|
}
|
@@ -4,20 +4,29 @@ using System.IO.Compression;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
|
using Authentication;
|
||||||
using gaseous_server.Classes.Metadata;
|
using gaseous_server.Classes.Metadata;
|
||||||
using gaseous_server.Controllers;
|
using gaseous_server.Controllers;
|
||||||
using gaseous_server.Models;
|
using gaseous_server.Models;
|
||||||
using IGDB.Models;
|
using IGDB.Models;
|
||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace gaseous_server.Classes
|
namespace gaseous_server.Classes
|
||||||
{
|
{
|
||||||
public class Collections
|
public class Collections
|
||||||
{
|
{
|
||||||
public Collections()
|
private readonly UserManager<ApplicationUser> _userManager;
|
||||||
{
|
private readonly SignInManager<ApplicationUser> _signInManager;
|
||||||
|
|
||||||
}
|
public Collections(
|
||||||
|
UserManager<ApplicationUser> userManager,
|
||||||
|
SignInManager<ApplicationUser> signInManager)
|
||||||
|
{
|
||||||
|
_userManager = userManager;
|
||||||
|
_signInManager = signInManager;
|
||||||
|
}
|
||||||
|
|
||||||
public static List<CollectionItem> GetCollections() {
|
public static List<CollectionItem> GetCollections() {
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
@@ -211,8 +220,11 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// get all platforms to pull from
|
// get all platforms to pull from
|
||||||
FilterController filterController = new FilterController();
|
Dictionary<string, object> FilterDict = Filters.Filter(AgeRatings.AgeGroups.AgeRestrictionGroupings.Adult, true);
|
||||||
platforms.AddRange((List<FilterController.FilterPlatform>)filterController.Filter()["platforms"]);
|
List<Classes.Filters.FilterItem> filteredPlatforms = (List<Classes.Filters.FilterItem>)FilterDict["platforms"];
|
||||||
|
foreach (Filters.FilterItem filterItem in filteredPlatforms) {
|
||||||
|
platforms.Add(Platforms.GetPlatform(filterItem.Id));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// build collection
|
// build collection
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System.Collections.Concurrent;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
|
|
||||||
namespace gaseous_server.Classes
|
namespace gaseous_server.Classes
|
||||||
@@ -111,5 +111,29 @@ namespace gaseous_server.Classes
|
|||||||
.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
|
.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Provides a way to set contextual data that flows with the call and
|
||||||
|
/// async context of a test or invocation.
|
||||||
|
/// </summary>
|
||||||
|
public static class CallContext
|
||||||
|
{
|
||||||
|
static ConcurrentDictionary<string, AsyncLocal<object>> state = new ConcurrentDictionary<string, AsyncLocal<object>>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stores a given object and associates it with the specified name.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">The name with which to associate the new item in the call context.</param>
|
||||||
|
/// <param name="data">The object to store in the call context.</param>
|
||||||
|
public static void SetData(string name, object data) =>
|
||||||
|
state.GetOrAdd(name, _ => new AsyncLocal<object>()).Value = data;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves an object with the specified name from the <see cref="CallContext"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">The name of the item in the call context.</param>
|
||||||
|
/// <returns>The object in the call context associated with the specified name, or <see langword="null"/> if not found.</returns>
|
||||||
|
public static object GetData(string name) =>
|
||||||
|
state.TryGetValue(name, out AsyncLocal<object> data) ? data.Value : null;
|
||||||
|
}
|
||||||
|
}
|
@@ -2,6 +2,7 @@
|
|||||||
using System.Data;
|
using System.Data;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using IGDB.Models;
|
using IGDB.Models;
|
||||||
|
using gaseous_server.Classes.Metadata;
|
||||||
|
|
||||||
namespace gaseous_server.Classes
|
namespace gaseous_server.Classes
|
||||||
{
|
{
|
||||||
@@ -57,6 +58,14 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ConfigFile.MetadataAPI MetadataConfiguration
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _config.MetadataConfiguration;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static ConfigFile.IGDB IGDB
|
public static ConfigFile.IGDB IGDB
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -247,6 +256,8 @@ namespace gaseous_server.Classes
|
|||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public Library LibraryConfiguration = new Library();
|
public Library LibraryConfiguration = new Library();
|
||||||
|
|
||||||
|
public MetadataAPI MetadataConfiguration = new MetadataAPI();
|
||||||
|
|
||||||
public IGDB IGDBConfiguration = new IGDB();
|
public IGDB IGDBConfiguration = new IGDB();
|
||||||
|
|
||||||
public Logging LoggingConfiguration = new Logging();
|
public Logging LoggingConfiguration = new Logging();
|
||||||
@@ -460,6 +471,26 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class MetadataAPI
|
||||||
|
{
|
||||||
|
private static Communications.MetadataSources _Source
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (!String.IsNullOrEmpty(Environment.GetEnvironmentVariable("metadatasource")))
|
||||||
|
{
|
||||||
|
return (Communications.MetadataSources)Enum.Parse(typeof(Communications.MetadataSources), Environment.GetEnvironmentVariable("metadatasource"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return Communications.MetadataSources.IGDB;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Communications.MetadataSources Source = _Source;
|
||||||
|
}
|
||||||
|
|
||||||
public class IGDB
|
public class IGDB
|
||||||
{
|
{
|
||||||
private static string _DefaultIGDBClientId
|
private static string _DefaultIGDBClientId
|
||||||
@@ -503,11 +534,7 @@ namespace gaseous_server.Classes
|
|||||||
// log retention in days
|
// log retention in days
|
||||||
public int LogRetention = 7;
|
public int LogRetention = 7;
|
||||||
|
|
||||||
public enum LoggingFormat
|
public bool AlwaysLogToDisk = false;
|
||||||
{
|
|
||||||
Json,
|
|
||||||
Text
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
151
gaseous-server/Classes/Filters.cs
Normal file
151
gaseous-server/Classes/Filters.cs
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
using System.Data;
|
||||||
|
using System.Reflection.Metadata.Ecma335;
|
||||||
|
using gaseous_server.Classes.Metadata;
|
||||||
|
using IGDB.Models;
|
||||||
|
|
||||||
|
namespace gaseous_server.Classes
|
||||||
|
{
|
||||||
|
public class Filters
|
||||||
|
{
|
||||||
|
public static Dictionary<string, object> Filter(Metadata.AgeRatings.AgeGroups.AgeRestrictionGroupings MaximumAgeRestriction, bool IncludeUnrated)
|
||||||
|
{
|
||||||
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
|
|
||||||
|
Dictionary<string, object> FilterSet = new Dictionary<string, object>();
|
||||||
|
|
||||||
|
// platforms
|
||||||
|
List<FilterItem> platforms = new List<FilterItem>();
|
||||||
|
|
||||||
|
string ageRestriction_Platform = "Game.AgeGroupId <= " + (int)MaximumAgeRestriction;
|
||||||
|
string ageRestriction_Generic = "view_Games.AgeGroupId <= " + (int)MaximumAgeRestriction;
|
||||||
|
if (IncludeUnrated == true)
|
||||||
|
{
|
||||||
|
ageRestriction_Platform += " OR Game.AgeGroupId IS NULL";
|
||||||
|
ageRestriction_Generic += " OR view_Games.AgeGroupId IS NULL";
|
||||||
|
}
|
||||||
|
|
||||||
|
string sql = "SELECT Platform.Id, Platform.`Name`, COUNT(view_Games.Id) AS GameCount FROM view_Games JOIN Relation_Game_Platforms ON Relation_Game_Platforms.GameId = view_Games.Id AND (Relation_Game_Platforms.PlatformsId IN (SELECT DISTINCT PlatformId FROM Games_Roms WHERE Games_Roms.GameId = view_Games.Id)) JOIN Platform ON Platform.Id = Relation_Game_Platforms.PlatformsId WHERE (" + ageRestriction_Generic + ") GROUP BY Platform.`Name` ORDER BY Platform.`Name`;";
|
||||||
|
|
||||||
|
DataTable dbResponse = db.ExecuteCMD(sql);
|
||||||
|
|
||||||
|
foreach (DataRow dr in dbResponse.Rows)
|
||||||
|
{
|
||||||
|
FilterItem platformItem = new FilterItem(dr);
|
||||||
|
platforms.Add(platformItem);
|
||||||
|
|
||||||
|
}
|
||||||
|
FilterSet.Add("platforms", platforms);
|
||||||
|
|
||||||
|
// genres
|
||||||
|
List<FilterItem> genres = new List<FilterItem>();
|
||||||
|
dbResponse = GetGenericFilterItem(db, "Genre", ageRestriction_Generic);
|
||||||
|
|
||||||
|
foreach (DataRow dr in dbResponse.Rows)
|
||||||
|
{
|
||||||
|
FilterItem genreItem = new FilterItem(dr);
|
||||||
|
genres.Add(genreItem);
|
||||||
|
}
|
||||||
|
FilterSet.Add("genres", genres);
|
||||||
|
|
||||||
|
// game modes
|
||||||
|
List<FilterItem> gameModes = new List<FilterItem>();
|
||||||
|
dbResponse = GetGenericFilterItem(db, "GameMode", ageRestriction_Generic);
|
||||||
|
|
||||||
|
foreach (DataRow dr in dbResponse.Rows)
|
||||||
|
{
|
||||||
|
FilterItem gameModeItem = new FilterItem(dr);
|
||||||
|
gameModes.Add(gameModeItem);
|
||||||
|
}
|
||||||
|
FilterSet.Add("gamemodes", gameModes);
|
||||||
|
|
||||||
|
// player perspectives
|
||||||
|
List<FilterItem> playerPerspectives = new List<FilterItem>();
|
||||||
|
dbResponse = GetGenericFilterItem(db, "PlayerPerspective", ageRestriction_Generic);
|
||||||
|
|
||||||
|
foreach (DataRow dr in dbResponse.Rows)
|
||||||
|
{
|
||||||
|
FilterItem playerPerspectiveItem = new FilterItem(dr);
|
||||||
|
playerPerspectives.Add(playerPerspectiveItem);
|
||||||
|
}
|
||||||
|
FilterSet.Add("playerperspectives", playerPerspectives);
|
||||||
|
|
||||||
|
// themes
|
||||||
|
List<FilterItem> themes = new List<FilterItem>();
|
||||||
|
dbResponse = GetGenericFilterItem(db, "Theme", ageRestriction_Generic);
|
||||||
|
|
||||||
|
foreach (DataRow dr in dbResponse.Rows)
|
||||||
|
{
|
||||||
|
FilterItem themeItem = new FilterItem(dr);
|
||||||
|
themes.Add(themeItem);
|
||||||
|
}
|
||||||
|
FilterSet.Add("themes", themes);
|
||||||
|
|
||||||
|
// age groups
|
||||||
|
List<FilterAgeGrouping> agegroupings = new List<FilterAgeGrouping>();
|
||||||
|
sql = "SELECT view_Games.Id, view_Games.AgeGroupId, COUNT(view_Games.Id) AS GameCount FROM view_Games WHERE (" + ageRestriction_Generic + ") GROUP BY view_Games.AgeGroupId ORDER BY view_Games.AgeGroupId DESC;";
|
||||||
|
dbResponse = db.ExecuteCMD(sql);
|
||||||
|
|
||||||
|
foreach (DataRow dr in dbResponse.Rows)
|
||||||
|
{
|
||||||
|
FilterAgeGrouping filterAgeGrouping = new FilterAgeGrouping();
|
||||||
|
if (dr["AgeGroupId"] == DBNull.Value)
|
||||||
|
{
|
||||||
|
filterAgeGrouping.Id = (long)AgeRatings.AgeGroups.AgeRestrictionGroupings.Unclassified;
|
||||||
|
filterAgeGrouping.AgeGroup = AgeRatings.AgeGroups.AgeRestrictionGroupings.Unclassified;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
filterAgeGrouping.Id = (long)(AgeRatings.AgeGroups.AgeRestrictionGroupings)dr["AgeGroupId"];
|
||||||
|
filterAgeGrouping.AgeGroup = (AgeRatings.AgeGroups.AgeRestrictionGroupings)dr["AgeGroupId"];
|
||||||
|
}
|
||||||
|
filterAgeGrouping.GameCount = (int)(long)dr["GameCount"];
|
||||||
|
agegroupings.Add(filterAgeGrouping);
|
||||||
|
}
|
||||||
|
FilterSet.Add("agegroupings", agegroupings);
|
||||||
|
|
||||||
|
return FilterSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static DataTable GetGenericFilterItem(Database db, string Name, string AgeRestriction_Generic)
|
||||||
|
{
|
||||||
|
string sql = "SELECT DISTINCT <ITEMNAME>.Id, <ITEMNAME>.`Name`, COUNT(view_Games.Id) AS GameCount FROM <ITEMNAME> LEFT JOIN Relation_Game_<ITEMNAME>s ON Relation_Game_<ITEMNAME>s.<ITEMNAME>sId = <ITEMNAME>.Id LEFT JOIN view_Games ON view_Games.Id = Relation_Game_<ITEMNAME>s.GameId WHERE (" + AgeRestriction_Generic + ") GROUP BY <ITEMNAME>.Id HAVING GameCount > 0 ORDER BY <ITEMNAME>.`Name`;";
|
||||||
|
sql = sql.Replace("<ITEMNAME>", Name);
|
||||||
|
DataTable dbResponse = db.ExecuteCMD(sql);
|
||||||
|
|
||||||
|
return dbResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class FilterItem
|
||||||
|
{
|
||||||
|
public FilterItem(DataRow dr)
|
||||||
|
{
|
||||||
|
this.Id = (long)dr["Id"];
|
||||||
|
this.Name = (string)dr["Name"];
|
||||||
|
this.GameCount = (int)(long)dr["GameCount"];
|
||||||
|
}
|
||||||
|
|
||||||
|
public long Id { get; set; }
|
||||||
|
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public int GameCount { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class FilterAgeGrouping
|
||||||
|
{
|
||||||
|
public long Id { get; set; }
|
||||||
|
|
||||||
|
public AgeRatings.AgeGroups.AgeRestrictionGroupings AgeGroup { get ; set; }
|
||||||
|
|
||||||
|
public string Name
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return this.AgeGroup.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GameCount { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -45,6 +45,11 @@ namespace gaseous_server
|
|||||||
DataRow row = data.Rows[0];
|
DataRow row = data.Rows[0];
|
||||||
LibraryItem library = new LibraryItem((int)row["Id"], (string)row["Name"], (string)row["Path"], (long)row["DefaultPlatform"], Convert.ToBoolean((int)row["DefaultLibrary"]));
|
LibraryItem library = new LibraryItem((int)row["Id"], (string)row["Name"], (string)row["Path"], (long)row["DefaultPlatform"], Convert.ToBoolean((int)row["DefaultLibrary"]));
|
||||||
|
|
||||||
|
if (!Directory.Exists(library.Path))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(library.Path);
|
||||||
|
}
|
||||||
|
|
||||||
return library;
|
return library;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -61,6 +66,15 @@ namespace gaseous_server
|
|||||||
{
|
{
|
||||||
LibraryItem library = new LibraryItem((int)row["Id"], (string)row["Name"], (string)row["Path"], (long)row["DefaultPlatform"], Convert.ToBoolean((int)row["DefaultLibrary"]));
|
LibraryItem library = new LibraryItem((int)row["Id"], (string)row["Name"], (string)row["Path"], (long)row["DefaultPlatform"], Convert.ToBoolean((int)row["DefaultLibrary"]));
|
||||||
libraryItems.Add(library);
|
libraryItems.Add(library);
|
||||||
|
|
||||||
|
if (library.IsDefaultLibrary == true)
|
||||||
|
{
|
||||||
|
// check directory exists
|
||||||
|
if (!Directory.Exists(library.Path))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(library.Path);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return libraryItems;
|
return libraryItems;
|
||||||
@@ -143,6 +157,11 @@ namespace gaseous_server
|
|||||||
_Path = Path;
|
_Path = Path;
|
||||||
_DefaultPlatformId = DefaultPlatformId;
|
_DefaultPlatformId = DefaultPlatformId;
|
||||||
_IsDefaultLibrary = IsDefaultLibrary;
|
_IsDefaultLibrary = IsDefaultLibrary;
|
||||||
|
|
||||||
|
if (!Directory.Exists(Path))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(Path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int _Id = 0;
|
int _Id = 0;
|
||||||
|
@@ -1,17 +1,19 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.IO.Compression;
|
using System.IO.Compression;
|
||||||
|
using System.Security.Authentication;
|
||||||
using System.Security.Policy;
|
using System.Security.Policy;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using gaseous_server.Classes.Metadata;
|
using gaseous_server.Classes.Metadata;
|
||||||
using IGDB.Models;
|
using IGDB.Models;
|
||||||
using NuGet.Common;
|
using NuGet.Common;
|
||||||
|
using NuGet.LibraryModel;
|
||||||
using static gaseous_server.Classes.Metadata.Games;
|
using static gaseous_server.Classes.Metadata.Games;
|
||||||
|
|
||||||
namespace gaseous_server.Classes
|
namespace gaseous_server.Classes
|
||||||
{
|
{
|
||||||
public class ImportGames
|
public class ImportGames : QueueItemStatus
|
||||||
{
|
{
|
||||||
public ImportGames(string ImportPath)
|
public ImportGames(string ImportPath)
|
||||||
{
|
{
|
||||||
@@ -21,9 +23,15 @@ namespace gaseous_server.Classes
|
|||||||
string[] importContents_Directories = Directory.GetDirectories(ImportPath);
|
string[] importContents_Directories = Directory.GetDirectories(ImportPath);
|
||||||
|
|
||||||
// import files first
|
// import files first
|
||||||
|
int importCount = 1;
|
||||||
foreach (string importContent in importContents_Files) {
|
foreach (string importContent in importContents_Files) {
|
||||||
|
SetStatus(importCount, importContents_Files.Length, "Importing file: " + importContent);
|
||||||
|
|
||||||
ImportGame.ImportGameFile(importContent, null);
|
ImportGame.ImportGameFile(importContent, null);
|
||||||
|
|
||||||
|
importCount += 1;
|
||||||
}
|
}
|
||||||
|
ClearStatus();
|
||||||
|
|
||||||
// import sub directories
|
// import sub directories
|
||||||
foreach (string importDir in importContents_Directories) {
|
foreach (string importDir in importContents_Directories) {
|
||||||
@@ -40,7 +48,7 @@ namespace gaseous_server.Classes
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ImportGame
|
public class ImportGame : QueueItemStatus
|
||||||
{
|
{
|
||||||
public static void ImportGameFile(string GameFileImportPath, IGDB.Models.Platform? OverridePlatform)
|
public static void ImportGameFile(string GameFileImportPath, IGDB.Models.Platform? OverridePlatform)
|
||||||
{
|
{
|
||||||
@@ -600,7 +608,7 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void LibraryScan()
|
public void LibraryScan()
|
||||||
{
|
{
|
||||||
foreach (GameLibrary.LibraryItem library in GameLibrary.GetLibraries)
|
foreach (GameLibrary.LibraryItem library in GameLibrary.GetLibraries)
|
||||||
{
|
{
|
||||||
@@ -645,8 +653,10 @@ namespace gaseous_server.Classes
|
|||||||
// search for files in the library that aren't in the database
|
// search for files in the library that aren't in the database
|
||||||
Logging.Log(Logging.LogType.Information, "Library Scan", "Looking for orphaned library files to add");
|
Logging.Log(Logging.LogType.Information, "Library Scan", "Looking for orphaned library files to add");
|
||||||
string[] LibraryFiles = Directory.GetFiles(library.Path, "*.*", SearchOption.AllDirectories);
|
string[] LibraryFiles = Directory.GetFiles(library.Path, "*.*", SearchOption.AllDirectories);
|
||||||
|
int StatusCount = 0;
|
||||||
foreach (string LibraryFile in LibraryFiles)
|
foreach (string LibraryFile in LibraryFiles)
|
||||||
{
|
{
|
||||||
|
SetStatus(StatusCount, LibraryFiles.Length, "Processing file " + LibraryFile);
|
||||||
if (!Common.SkippableFiles.Contains<string>(Path.GetFileName(LibraryFile), StringComparer.OrdinalIgnoreCase))
|
if (!Common.SkippableFiles.Contains<string>(Path.GetFileName(LibraryFile), StringComparer.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
Common.hashObject LibraryFileHash = new Common.hashObject(LibraryFile);
|
Common.hashObject LibraryFileHash = new Common.hashObject(LibraryFile);
|
||||||
@@ -701,7 +711,9 @@ namespace gaseous_server.Classes
|
|||||||
StoreROM(library, hash, determinedGame, determinedPlatform, sig, LibraryFile);
|
StoreROM(library, hash, determinedGame, determinedPlatform, sig, LibraryFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
StatusCount += 1;
|
||||||
}
|
}
|
||||||
|
ClearStatus();
|
||||||
|
|
||||||
sql = "SELECT * FROM Games_Roms WHERE LibraryId=@libraryid ORDER BY `name`";
|
sql = "SELECT * FROM Games_Roms WHERE LibraryId=@libraryid ORDER BY `name`";
|
||||||
dtRoms = db.ExecuteCMD(sql, dbDict);
|
dtRoms = db.ExecuteCMD(sql, dbDict);
|
||||||
@@ -746,7 +758,7 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Rematcher(bool ForceExecute = false)
|
public void Rematcher(bool ForceExecute = false)
|
||||||
{
|
{
|
||||||
// rescan all titles with an unknown platform or title and see if we can get a match
|
// rescan all titles with an unknown platform or title and see if we can get a match
|
||||||
Logging.Log(Logging.LogType.Information, "Rematch Scan", "Rematch scan starting");
|
Logging.Log(Logging.LogType.Information, "Rematch Scan", "Rematch scan starting");
|
||||||
@@ -755,17 +767,20 @@ namespace gaseous_server.Classes
|
|||||||
string sql = "";
|
string sql = "";
|
||||||
if (ForceExecute == false)
|
if (ForceExecute == false)
|
||||||
{
|
{
|
||||||
sql = "SELECT * FROM Games_Roms WHERE (PlatformId = 0 OR GameId = 0 OR MetadataSource = 0) AND (LastMatchAttemptDate IS NULL OR LastMatchAttemptDate < @lastmatchattemptdate) LIMIT 100;";
|
sql = "SELECT * FROM Games_Roms WHERE ((PlatformId = 0 OR GameId = 0) AND MetadataSource = 0) AND (LastMatchAttemptDate IS NULL OR LastMatchAttemptDate < @lastmatchattemptdate) LIMIT 100;";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sql = "SELECT * FROM Games_Roms WHERE (PlatformId = 0 OR GameId = 0 OR MetadataSource = 0);";
|
sql = "SELECT * FROM Games_Roms WHERE ((PlatformId = 0 OR GameId = 0) AND MetadataSource = 0);";
|
||||||
}
|
}
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||||
dbDict.Add("lastmatchattemptdate", DateTime.UtcNow.AddDays(-7));
|
dbDict.Add("lastmatchattemptdate", DateTime.UtcNow.AddDays(-7));
|
||||||
DataTable data = db.ExecuteCMD(sql, dbDict);
|
DataTable data = db.ExecuteCMD(sql, dbDict);
|
||||||
|
int StatusCount = -0;
|
||||||
foreach (DataRow row in data.Rows)
|
foreach (DataRow row in data.Rows)
|
||||||
{
|
{
|
||||||
|
SetStatus(StatusCount, data.Rows.Count, "Running rematcher");
|
||||||
|
|
||||||
// get library
|
// get library
|
||||||
GameLibrary.LibraryItem library = GameLibrary.GetLibrary((int)row["LibraryId"]);
|
GameLibrary.LibraryItem library = GameLibrary.GetLibrary((int)row["LibraryId"]);
|
||||||
|
|
||||||
@@ -800,9 +815,13 @@ namespace gaseous_server.Classes
|
|||||||
dbLastAttemptDict.Add("id", romId);
|
dbLastAttemptDict.Add("id", romId);
|
||||||
dbLastAttemptDict.Add("lastmatchattemptdate", DateTime.UtcNow);
|
dbLastAttemptDict.Add("lastmatchattemptdate", DateTime.UtcNow);
|
||||||
db.ExecuteCMD(attemptSql, dbLastAttemptDict);
|
db.ExecuteCMD(attemptSql, dbLastAttemptDict);
|
||||||
|
|
||||||
|
StatusCount += 1;
|
||||||
}
|
}
|
||||||
|
ClearStatus();
|
||||||
|
|
||||||
Logging.Log(Logging.LogType.Information, "Rematch Scan", "Rematch scan completed");
|
Logging.Log(Logging.LogType.Information, "Rematch Scan", "Rematch scan completed");
|
||||||
|
ClearStatus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -7,6 +7,7 @@ namespace gaseous_server.Classes
|
|||||||
{
|
{
|
||||||
public class Logging
|
public class Logging
|
||||||
{
|
{
|
||||||
|
private static DateTime lastDiskRetentionSweep = DateTime.UtcNow;
|
||||||
public static bool WriteToDiskOnly { get; set; } = false;
|
public static bool WriteToDiskOnly { get; set; } = false;
|
||||||
|
|
||||||
static public void Log(LogType EventType, string ServerProcess, string Message, Exception? ExceptionValue = null, bool LogToDiskOnly = false)
|
static public void Log(LogType EventType, string ServerProcess, string Message, Exception? ExceptionValue = null, bool LogToDiskOnly = false)
|
||||||
@@ -69,8 +70,47 @@ namespace gaseous_server.Classes
|
|||||||
|
|
||||||
if (LogToDiskOnly == false)
|
if (LogToDiskOnly == false)
|
||||||
{
|
{
|
||||||
|
if (Config.LoggingConfiguration.AlwaysLogToDisk == true)
|
||||||
|
{
|
||||||
|
LogToDisk(logItem, TraceOutput, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
string correlationId;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (CallContext.GetData("CorrelationId").ToString() == null)
|
||||||
|
{
|
||||||
|
correlationId = "";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
correlationId = CallContext.GetData("CorrelationId").ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
correlationId = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
string callingProcess;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (CallContext.GetData("CallingProcess").ToString() == null)
|
||||||
|
{
|
||||||
|
callingProcess = "";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
callingProcess = CallContext.GetData("CallingProcess").ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
callingProcess = "";
|
||||||
|
}
|
||||||
|
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
string sql = "DELETE FROM ServerLogs WHERE EventTime < @EventRententionDate; INSERT INTO ServerLogs (EventTime, EventType, Process, Message, Exception) VALUES (@EventTime, @EventType, @Process, @Message, @Exception);";
|
string sql = "DELETE FROM ServerLogs WHERE EventTime < @EventRententionDate; INSERT INTO ServerLogs (EventTime, EventType, Process, Message, Exception, CorrelationId, CallingProcess) VALUES (@EventTime, @EventType, @Process, @Message, @Exception, @correlationid, @callingprocess);";
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||||
dbDict.Add("EventRententionDate", DateTime.UtcNow.AddDays(Config.LoggingConfiguration.LogRetention * -1));
|
dbDict.Add("EventRententionDate", DateTime.UtcNow.AddDays(Config.LoggingConfiguration.LogRetention * -1));
|
||||||
dbDict.Add("EventTime", logItem.EventTime);
|
dbDict.Add("EventTime", logItem.EventTime);
|
||||||
@@ -78,6 +118,8 @@ namespace gaseous_server.Classes
|
|||||||
dbDict.Add("Process", logItem.Process);
|
dbDict.Add("Process", logItem.Process);
|
||||||
dbDict.Add("Message", logItem.Message);
|
dbDict.Add("Message", logItem.Message);
|
||||||
dbDict.Add("Exception", Common.ReturnValueIfNull(logItem.ExceptionValue, "").ToString());
|
dbDict.Add("Exception", Common.ReturnValueIfNull(logItem.ExceptionValue, "").ToString());
|
||||||
|
dbDict.Add("correlationid", correlationId);
|
||||||
|
dbDict.Add("callingprocess", callingProcess);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -93,6 +135,22 @@ namespace gaseous_server.Classes
|
|||||||
LogToDisk(logItem, TraceOutput, null);
|
LogToDisk(logItem, TraceOutput, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (lastDiskRetentionSweep.AddMinutes(60) < DateTime.UtcNow)
|
||||||
|
{
|
||||||
|
// time to delete any old logs
|
||||||
|
lastDiskRetentionSweep = DateTime.UtcNow;
|
||||||
|
string[] files = Directory.GetFiles(Config.LogPath);
|
||||||
|
|
||||||
|
foreach (string file in files)
|
||||||
|
{
|
||||||
|
FileInfo fi = new FileInfo(file);
|
||||||
|
if (fi.LastAccessTime < DateTime.Now.AddDays(Config.LoggingConfiguration.LogRetention * -1))
|
||||||
|
{
|
||||||
|
fi.Delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void LogToDisk(LogItem logItem, string TraceOutput, Exception? exception)
|
static void LogToDisk(LogItem logItem, string TraceOutput, Exception? exception)
|
||||||
@@ -110,22 +168,100 @@ namespace gaseous_server.Classes
|
|||||||
File.AppendAllText(Config.LogFilePath, TraceOutput);
|
File.AppendAllText(Config.LogFilePath, TraceOutput);
|
||||||
}
|
}
|
||||||
|
|
||||||
static public List<LogItem> GetLogs(long? StartIndex, int PageNumber = 1, int PageSize = 100)
|
static public List<LogItem> GetLogs(LogsViewModel model)
|
||||||
{
|
{
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
|
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||||
|
dbDict.Add("StartIndex", model.StartIndex);
|
||||||
|
dbDict.Add("PageNumber", (model.PageNumber - 1) * model.PageSize);
|
||||||
|
dbDict.Add("PageSize", model.PageSize);
|
||||||
string sql = "";
|
string sql = "";
|
||||||
if (StartIndex == null)
|
|
||||||
|
List<string> whereClauses = new List<string>();
|
||||||
|
|
||||||
|
// handle status criteria
|
||||||
|
if (model.Status != null)
|
||||||
{
|
{
|
||||||
sql = "SELECT * FROM ServerLogs ORDER BY Id DESC LIMIT @PageSize OFFSET @PageNumber;";
|
if (model.Status.Count > 0)
|
||||||
|
{
|
||||||
|
List<string> statusWhere = new List<string>();
|
||||||
|
for (int i = 0; i < model.Status.Count; i++)
|
||||||
|
{
|
||||||
|
string valueName = "@eventtype" + i;
|
||||||
|
statusWhere.Add(valueName);
|
||||||
|
dbDict.Add(valueName, (int)model.Status[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
whereClauses.Add("EventType IN (" + string.Join(",", statusWhere) + ")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle start date criteria
|
||||||
|
if (model.StartDateTime != null)
|
||||||
|
{
|
||||||
|
dbDict.Add("startdate", model.StartDateTime);
|
||||||
|
whereClauses.Add("EventTime >= @startdate");
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle end date criteria
|
||||||
|
if (model.EndDateTime != null)
|
||||||
|
{
|
||||||
|
dbDict.Add("enddate", model.EndDateTime);
|
||||||
|
whereClauses.Add("EventTime <= @enddate");
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle search text criteria
|
||||||
|
if (model.SearchText != null)
|
||||||
|
{
|
||||||
|
if (model.SearchText.Length > 0)
|
||||||
|
{
|
||||||
|
dbDict.Add("messageSearch", model.SearchText);
|
||||||
|
whereClauses.Add("MATCH(Message) AGAINST (@messageSearch)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (model.CorrelationId != null)
|
||||||
|
{
|
||||||
|
if (model.CorrelationId.Length > 0)
|
||||||
|
{
|
||||||
|
dbDict.Add("correlationId", model.CorrelationId);
|
||||||
|
whereClauses.Add("CorrelationId = @correlationId");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (model.CallingProcess != null)
|
||||||
|
{
|
||||||
|
if (model.CallingProcess.Length > 0)
|
||||||
|
{
|
||||||
|
dbDict.Add("callingProcess", model.CallingProcess);
|
||||||
|
whereClauses.Add("CallingProcess = @callingProcess");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// compile WHERE clause
|
||||||
|
string whereClause = "";
|
||||||
|
if (whereClauses.Count > 0)
|
||||||
|
{
|
||||||
|
whereClause = "(" + String.Join(" AND ", whereClauses) + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
// execute query
|
||||||
|
if (model.StartIndex == null)
|
||||||
|
{
|
||||||
|
if (whereClause.Length > 0)
|
||||||
|
{
|
||||||
|
whereClause = "WHERE " + whereClause;
|
||||||
|
}
|
||||||
|
sql = "SELECT * FROM ServerLogs " + whereClause + " ORDER BY Id DESC LIMIT @PageSize OFFSET @PageNumber;";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sql = "SELECT * FROM ServerLogs WHERE Id < @StartIndex ORDER BY Id DESC LIMIT @PageSize OFFSET @PageNumber;";
|
if (whereClause.Length > 0)
|
||||||
|
{
|
||||||
|
whereClause = "AND " + whereClause;
|
||||||
|
}
|
||||||
|
sql = "SELECT * FROM ServerLogs WHERE Id < @StartIndex " + whereClause + " ORDER BY Id DESC LIMIT @PageSize OFFSET @PageNumber;";
|
||||||
}
|
}
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
|
||||||
dbDict.Add("StartIndex", StartIndex);
|
|
||||||
dbDict.Add("PageNumber", (PageNumber - 1) * PageSize);
|
|
||||||
dbDict.Add("PageSize", PageSize);
|
|
||||||
DataTable dataTable = db.ExecuteCMD(sql, dbDict);
|
DataTable dataTable = db.ExecuteCMD(sql, dbDict);
|
||||||
|
|
||||||
List<LogItem> logs = new List<LogItem>();
|
List<LogItem> logs = new List<LogItem>();
|
||||||
@@ -138,7 +274,9 @@ namespace gaseous_server.Classes
|
|||||||
EventType = (LogType)row["EventType"],
|
EventType = (LogType)row["EventType"],
|
||||||
Process = (string)row["Process"],
|
Process = (string)row["Process"],
|
||||||
Message = (string)row["Message"],
|
Message = (string)row["Message"],
|
||||||
ExceptionValue = (string)row["Exception"]
|
ExceptionValue = (string)row["Exception"],
|
||||||
|
CorrelationId = (string)Common.ReturnValueIfNull(row["CorrelationId"], ""),
|
||||||
|
CallingProcess = (string)Common.ReturnValueIfNull(row["CallingProcess"], "")
|
||||||
};
|
};
|
||||||
|
|
||||||
logs.Add(log);
|
logs.Add(log);
|
||||||
@@ -161,6 +299,8 @@ namespace gaseous_server.Classes
|
|||||||
public DateTime EventTime { get; set; }
|
public DateTime EventTime { get; set; }
|
||||||
public LogType? EventType { get; set; }
|
public LogType? EventType { get; set; }
|
||||||
public string Process { get; set; } = "";
|
public string Process { get; set; } = "";
|
||||||
|
public string CorrelationId { get; set; } = "";
|
||||||
|
public string? CallingProcess { get; set; } = "";
|
||||||
private string _Message = "";
|
private string _Message = "";
|
||||||
public string Message
|
public string Message
|
||||||
{
|
{
|
||||||
@@ -175,6 +315,19 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
public string? ExceptionValue { get; set; }
|
public string? ExceptionValue { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class LogsViewModel
|
||||||
|
{
|
||||||
|
public long? StartIndex { get; set; }
|
||||||
|
public int PageNumber { get; set; } = 1;
|
||||||
|
public int PageSize { get; set; } = 100;
|
||||||
|
public List<LogType> Status { get; set; } = new List<LogType>();
|
||||||
|
public DateTime? StartDateTime { get; set; }
|
||||||
|
public DateTime? EndDateTime { get; set; }
|
||||||
|
public string? SearchText { get; set; }
|
||||||
|
public string? CorrelationId { get; set; }
|
||||||
|
public string? CallingProcess { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -5,11 +5,11 @@ using Microsoft.VisualStudio.Web.CodeGeneration;
|
|||||||
|
|
||||||
namespace gaseous_server.Classes
|
namespace gaseous_server.Classes
|
||||||
{
|
{
|
||||||
public class Maintenance
|
public class Maintenance : QueueItemStatus
|
||||||
{
|
{
|
||||||
const int MaxFileAge = 30;
|
const int MaxFileAge = 30;
|
||||||
|
|
||||||
public static void RunMaintenance()
|
public void RunMaintenance()
|
||||||
{
|
{
|
||||||
// delete files and directories older than 7 days in PathsToClean
|
// delete files and directories older than 7 days in PathsToClean
|
||||||
List<string> PathsToClean = new List<string>();
|
List<string> PathsToClean = new List<string>();
|
||||||
@@ -49,8 +49,11 @@ namespace gaseous_server.Classes
|
|||||||
string sql = "SHOW TABLES;";
|
string sql = "SHOW TABLES;";
|
||||||
DataTable tables = db.ExecuteCMD(sql);
|
DataTable tables = db.ExecuteCMD(sql);
|
||||||
|
|
||||||
|
int StatusCounter = 1;
|
||||||
foreach (DataRow row in tables.Rows)
|
foreach (DataRow row in tables.Rows)
|
||||||
{
|
{
|
||||||
|
SetStatus(StatusCounter, tables.Rows.Count, "Optimising table " + row[0].ToString());
|
||||||
|
|
||||||
sql = "OPTIMIZE TABLE " + row[0].ToString();
|
sql = "OPTIMIZE TABLE " + row[0].ToString();
|
||||||
DataTable response = db.ExecuteCMD(sql);
|
DataTable response = db.ExecuteCMD(sql);
|
||||||
foreach (DataRow responseRow in response.Rows)
|
foreach (DataRow responseRow in response.Rows)
|
||||||
@@ -60,9 +63,12 @@ namespace gaseous_server.Classes
|
|||||||
{
|
{
|
||||||
retVal += responseRow.ItemArray[i] + "; ";
|
retVal += responseRow.ItemArray[i] + "; ";
|
||||||
}
|
}
|
||||||
Logging.Log(Logging.LogType.Information, "Maintenance", "Optimizse table " + row[0].ToString() + ": " + retVal);
|
Logging.Log(Logging.LogType.Information, "Maintenance", "(" + StatusCounter + "/" + tables.Rows.Count + "): Optimise table " + row[0].ToString() + ": " + retVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StatusCounter += 1;
|
||||||
}
|
}
|
||||||
|
ClearStatus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -3,6 +3,7 @@ using System.Reflection;
|
|||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using IGDB;
|
using IGDB;
|
||||||
using IGDB.Models;
|
using IGDB.Models;
|
||||||
|
using Microsoft.CodeAnalysis.Classification;
|
||||||
|
|
||||||
namespace gaseous_server.Classes.Metadata
|
namespace gaseous_server.Classes.Metadata
|
||||||
{
|
{
|
||||||
@@ -14,12 +15,6 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
public static AgeRating? GetAgeRatings(long? Id)
|
||||||
{
|
{
|
||||||
if ((Id == 0) || (Id == null))
|
if ((Id == 0) || (Id == null))
|
||||||
@@ -116,7 +111,8 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
private static async Task<AgeRating> GetObjectFromServer(string WhereClause)
|
private static async Task<AgeRating> GetObjectFromServer(string WhereClause)
|
||||||
{
|
{
|
||||||
// get AgeRatings metadata
|
// get AgeRatings metadata
|
||||||
var results = await igdb.QueryAsync<AgeRating>(IGDBClient.Endpoints.AgeRating, query: fieldList + " " + WhereClause + ";");
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<AgeRating>(IGDBClient.Endpoints.AgeRating, fieldList, WhereClause);
|
||||||
var result = results.First();
|
var result = results.First();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -153,6 +149,44 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
public string[] Descriptions { get; set; }
|
public string[] Descriptions { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void PopulateAgeMap()
|
||||||
|
{
|
||||||
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
|
string sql = "DELETE FROM ClassificationMap;";
|
||||||
|
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||||
|
db.ExecuteNonQuery(sql);
|
||||||
|
|
||||||
|
// loop all age groups
|
||||||
|
foreach(KeyValuePair<AgeGroups.AgeRestrictionGroupings, AgeGroups.AgeGroupItem> ageGrouping in AgeGroups.AgeGroupingsFlat)
|
||||||
|
{
|
||||||
|
AgeGroups.AgeGroupItem ageGroupItem = ageGrouping.Value;
|
||||||
|
var properties = ageGroupItem.GetType().GetProperties();
|
||||||
|
foreach (var prop in properties)
|
||||||
|
{
|
||||||
|
if (prop.GetGetMethod() != null)
|
||||||
|
{
|
||||||
|
List<string> AgeRatingCategories = new List<string>(Enum.GetNames(typeof(AgeRatingCategory)));
|
||||||
|
if (AgeRatingCategories.Contains(prop.Name))
|
||||||
|
{
|
||||||
|
AgeRatingCategory ageRatingCategory = (AgeRatingCategory)Enum.Parse(typeof(AgeRatingCategory), prop.Name);
|
||||||
|
List<AgeRatingTitle> ageRatingTitles = (List<AgeRatingTitle>)prop.GetValue(ageGroupItem);
|
||||||
|
|
||||||
|
foreach (AgeRatingTitle ageRatingTitle in ageRatingTitles)
|
||||||
|
{
|
||||||
|
dbDict.Clear();
|
||||||
|
dbDict.Add("AgeGroupId", ageGrouping.Key);
|
||||||
|
dbDict.Add("ClassificationBoardId", ageRatingCategory);
|
||||||
|
dbDict.Add("RatingId", ageRatingTitle);
|
||||||
|
|
||||||
|
sql = "INSERT INTO ClassificationMap (AgeGroupId, ClassificationBoardId, RatingId) VALUES (@AgeGroupId, @ClassificationBoardId, @RatingId);";
|
||||||
|
db.ExecuteCMD(sql, dbDict);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class AgeGroups
|
public class AgeGroups
|
||||||
{
|
{
|
||||||
public AgeGroups()
|
public AgeGroups()
|
||||||
@@ -160,93 +194,55 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Dictionary<string, List<AgeGroupItem>> AgeGroupings
|
public static Dictionary<AgeRestrictionGroupings, List<AgeGroupItem>> AgeGroupings
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return new Dictionary<string, List<AgeGroupItem>>{
|
return new Dictionary<AgeRestrictionGroupings, List<AgeGroupItem>>{
|
||||||
{
|
{
|
||||||
"Adult", new List<AgeGroupItem>{ Adult_Item, Mature_Item, Teen_Item, Child_Item }
|
AgeRestrictionGroupings.Adult, new List<AgeGroupItem>{ Adult_Item, Mature_Item, Teen_Item, Child_Item }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Mature", new List<AgeGroupItem>{ Mature_Item, Teen_Item, Child_Item }
|
AgeRestrictionGroupings.Mature, new List<AgeGroupItem>{ Mature_Item, Teen_Item, Child_Item }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Teen", new List<AgeGroupItem>{ Teen_Item, Child_Item }
|
AgeRestrictionGroupings.Teen, new List<AgeGroupItem>{ Teen_Item, Child_Item }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Child", new List<AgeGroupItem>{ Child_Item }
|
AgeRestrictionGroupings.Child, new List<AgeGroupItem>{ Child_Item }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Dictionary<string, AgeGroupItem> AgeGroupingsFlat
|
public static Dictionary<AgeRestrictionGroupings, AgeGroupItem> AgeGroupingsFlat
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return new Dictionary<string, AgeGroupItem>{
|
return new Dictionary<AgeRestrictionGroupings, AgeGroupItem>{
|
||||||
{
|
{
|
||||||
"Adult", Adult_Item
|
AgeRestrictionGroupings.Adult, Adult_Item
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Mature", Mature_Item
|
AgeRestrictionGroupings.Mature, Mature_Item
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Teen", Teen_Item
|
AgeRestrictionGroupings.Teen, Teen_Item
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Child", Child_Item
|
AgeRestrictionGroupings.Child, Child_Item
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<ClassificationBoardItem> ClassificationBoards
|
public enum AgeRestrictionGroupings
|
||||||
{
|
{
|
||||||
get
|
Adult = 4,
|
||||||
{
|
Mature = 3,
|
||||||
ClassificationBoardItem boardItem = new ClassificationBoardItem{
|
Teen = 2,
|
||||||
Board = AgeRatingCategory.ACB,
|
Child = 1,
|
||||||
Classifications = new List<AgeRatingTitle>{
|
Unclassified = 0
|
||||||
AgeRatingTitle.ACB_G, AgeRatingTitle.ACB_M, AgeRatingTitle.ACB_MA15, AgeRatingTitle.ACB_R18, AgeRatingTitle.ACB_RC
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return new List<ClassificationBoardItem>{
|
|
||||||
new ClassificationBoardItem{
|
|
||||||
Board = AgeRatingCategory.ACB,
|
|
||||||
Classifications = new List<AgeRatingTitle>{
|
|
||||||
AgeRatingTitle.ACB_G,
|
|
||||||
AgeRatingTitle.ACB_M,
|
|
||||||
AgeRatingTitle.ACB_MA15,
|
|
||||||
AgeRatingTitle.ACB_R18,
|
|
||||||
AgeRatingTitle.ACB_RC
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new ClassificationBoardItem{
|
|
||||||
Board = AgeRatingCategory.CERO,
|
|
||||||
Classifications = new List<AgeRatingTitle>{
|
|
||||||
AgeRatingTitle.CERO_A,
|
|
||||||
AgeRatingTitle.CERO_B,
|
|
||||||
AgeRatingTitle.CERO_C,
|
|
||||||
AgeRatingTitle.CERO_D,
|
|
||||||
AgeRatingTitle.CERO_Z
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new ClassificationBoardItem{
|
|
||||||
Board = AgeRatingCategory.CLASS_IND,
|
|
||||||
Classifications = new List<AgeRatingTitle>{
|
|
||||||
AgeRatingTitle.CLASS_IND_L,
|
|
||||||
AgeRatingTitle.CLASS_IND_Ten,
|
|
||||||
AgeRatingTitle.CLASS_IND_Twelve,
|
|
||||||
AgeRatingTitle.CLASS_IND_Fourteen,
|
|
||||||
AgeRatingTitle.CLASS_IND_Sixteen,
|
|
||||||
AgeRatingTitle.CLASS_IND_Eighteen
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
readonly static AgeGroupItem Adult_Item = new AgeGroupItem{
|
readonly static AgeGroupItem Adult_Item = new AgeGroupItem{
|
||||||
@@ -341,12 +337,6 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ClassificationBoardItem
|
|
||||||
{
|
|
||||||
public IGDB.Models.AgeRatingCategory Board { get; set; }
|
|
||||||
public List<IGDB.Models.AgeRatingTitle> Classifications { get; set; }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -13,12 +13,6 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
public static AgeRatingContentDescription? GetAgeRatingContentDescriptions(long? Id)
|
||||||
{
|
{
|
||||||
if ((Id == 0) || (Id == null))
|
if ((Id == 0) || (Id == null))
|
||||||
@@ -103,7 +97,8 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
private static async Task<AgeRatingContentDescription> GetObjectFromServer(string WhereClause)
|
private static async Task<AgeRatingContentDescription> GetObjectFromServer(string WhereClause)
|
||||||
{
|
{
|
||||||
// get AgeRatingContentDescriptionContentDescriptions metadata
|
// get AgeRatingContentDescriptionContentDescriptions metadata
|
||||||
var results = await igdb.QueryAsync<AgeRatingContentDescription>(IGDBClient.Endpoints.AgeRatingContentDescriptions, query: fieldList + " " + WhereClause + ";");
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<AgeRatingContentDescription>(IGDBClient.Endpoints.AgeRatingContentDescriptions, fieldList, WhereClause);
|
||||||
var result = results.First();
|
var result = results.First();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@@ -13,12 +13,6 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
public static AlternativeName? GetAlternativeNames(long? Id)
|
||||||
{
|
{
|
||||||
if ((Id == 0) || (Id == null))
|
if ((Id == 0) || (Id == null))
|
||||||
@@ -103,7 +97,8 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
private static async Task<AlternativeName> GetObjectFromServer(string WhereClause)
|
private static async Task<AlternativeName> GetObjectFromServer(string WhereClause)
|
||||||
{
|
{
|
||||||
// get AlternativeNames metadata
|
// get AlternativeNames metadata
|
||||||
var results = await igdb.QueryAsync<AlternativeName>(IGDBClient.Endpoints.AlternativeNames, query: fieldList + " " + WhereClause + ";");
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<AlternativeName>(IGDBClient.Endpoints.AlternativeNames, fieldList, WhereClause);
|
||||||
var result = results.First();
|
var result = results.First();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@@ -13,12 +13,6 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IGDBClient igdb = new IGDBClient(
|
|
||||||
// Found in Twitch Developer portal for your app
|
|
||||||
Config.IGDB.ClientId,
|
|
||||||
Config.IGDB.Secret
|
|
||||||
);
|
|
||||||
|
|
||||||
public static Artwork? GetArtwork(long? Id, string LogoPath)
|
public static Artwork? GetArtwork(long? Id, string LogoPath)
|
||||||
{
|
{
|
||||||
if ((Id == 0) || (Id == null))
|
if ((Id == 0) || (Id == null))
|
||||||
@@ -113,7 +107,8 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
private static async Task<Artwork> GetObjectFromServer(string WhereClause, string LogoPath)
|
private static async Task<Artwork> GetObjectFromServer(string WhereClause, string LogoPath)
|
||||||
{
|
{
|
||||||
// get Artwork metadata
|
// get Artwork metadata
|
||||||
var results = await igdb.QueryAsync<Artwork>(IGDBClient.Endpoints.Artworks, query: fieldList + " " + WhereClause + ";");
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<Artwork>(IGDBClient.Endpoints.Artworks, fieldList, WhereClause);
|
||||||
var result = results.First();
|
var result = results.First();
|
||||||
|
|
||||||
//GetImageFromServer(result.Url, LogoPath, LogoSize.t_thumb, result.ImageId);
|
//GetImageFromServer(result.Url, LogoPath, LogoSize.t_thumb, result.ImageId);
|
||||||
|
@@ -13,12 +13,6 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
public static Collection? GetCollections(long? Id)
|
||||||
{
|
{
|
||||||
if ((Id == 0) || (Id == null))
|
if ((Id == 0) || (Id == null))
|
||||||
@@ -103,7 +97,8 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
private static async Task<Collection> GetObjectFromServer(string WhereClause)
|
private static async Task<Collection> GetObjectFromServer(string WhereClause)
|
||||||
{
|
{
|
||||||
// get Collections metadata
|
// get Collections metadata
|
||||||
var results = await igdb.QueryAsync<Collection>(IGDBClient.Endpoints.Collections, query: fieldList + " " + WhereClause + ";");
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<Collection>(IGDBClient.Endpoints.Collections, fieldList, WhereClause);
|
||||||
var result = results.First();
|
var result = results.First();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
238
gaseous-server/Classes/Metadata/Communications.cs
Normal file
238
gaseous-server/Classes/Metadata/Communications.cs
Normal file
@@ -0,0 +1,238 @@
|
|||||||
|
using System.Net;
|
||||||
|
using IGDB;
|
||||||
|
using RestEase;
|
||||||
|
|
||||||
|
namespace gaseous_server.Classes.Metadata
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Handles all metadata API communications
|
||||||
|
/// </summary>
|
||||||
|
public class Communications
|
||||||
|
{
|
||||||
|
private static IGDBClient igdb = new IGDBClient(
|
||||||
|
// Found in Twitch Developer portal for your app
|
||||||
|
Config.IGDB.ClientId,
|
||||||
|
Config.IGDB.Secret
|
||||||
|
);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Configure metadata API communications
|
||||||
|
/// </summary>
|
||||||
|
public static MetadataSources MetadataSource
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _MetadataSource;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_MetadataSource = value;
|
||||||
|
|
||||||
|
switch (value)
|
||||||
|
{
|
||||||
|
case MetadataSources.IGDB:
|
||||||
|
// set rate limiter avoidance values
|
||||||
|
RateLimitAvoidanceWait = 1500;
|
||||||
|
RateLimitAvoidanceThreshold = 3;
|
||||||
|
RateLimitAvoidancePeriod = 1;
|
||||||
|
|
||||||
|
// set rate limiter recovery values
|
||||||
|
RateLimitRecoveryWaitTime = 10000;
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// leave all values at default
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static MetadataSources _MetadataSource = MetadataSources.None;
|
||||||
|
|
||||||
|
// rate limit avoidance - what can we do to ensure that rate limiting is avoided?
|
||||||
|
// these values affect all communications
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// How long to wait to avoid hitting an API rate limiter
|
||||||
|
/// </summary>
|
||||||
|
private static int RateLimitAvoidanceWait = 2000;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// How many API calls in the period are allowed before we start introducing a wait
|
||||||
|
/// </summary>
|
||||||
|
private static int RateLimitAvoidanceThreshold = 80;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A counter of API calls since the beginning of the period
|
||||||
|
/// </summary>
|
||||||
|
private static int RateLimitAvoidanceCallCount = 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// How large the period (in seconds) to measure API call counts against
|
||||||
|
/// </summary>
|
||||||
|
private static int RateLimitAvoidancePeriod = 60;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The start of the rate limit avoidance period
|
||||||
|
/// </summary>
|
||||||
|
private static DateTime RateLimitAvoidanceStartTime = DateTime.UtcNow;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Used to determine if we're already in rate limit avoidance mode - always query "InRateLimitAvoidanceMode"
|
||||||
|
/// for up to date mode status.
|
||||||
|
/// This bool is used to track status changes and should not be relied upon for current status.
|
||||||
|
/// </summary>
|
||||||
|
private static bool InRateLimitAvoidanceModeStatus = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determine if we're in rate limit avoidance mode.
|
||||||
|
/// </summary>
|
||||||
|
private static bool InRateLimitAvoidanceMode
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (RateLimitAvoidanceStartTime.AddSeconds(RateLimitAvoidancePeriod) <= DateTime.UtcNow)
|
||||||
|
{
|
||||||
|
// avoidance period has expired - reset
|
||||||
|
RateLimitAvoidanceCallCount = 0;
|
||||||
|
RateLimitAvoidanceStartTime = DateTime.UtcNow;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// we're in the avoidance period
|
||||||
|
if (RateLimitAvoidanceCallCount > RateLimitAvoidanceThreshold)
|
||||||
|
{
|
||||||
|
// the number of call counts indicates we should throttle things a bit
|
||||||
|
if (InRateLimitAvoidanceModeStatus == false)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Information, "API Connection", "Entered rate limit avoidance period, API calls will be throttled by " + RateLimitAvoidanceWait + " milliseconds.");
|
||||||
|
InRateLimitAvoidanceModeStatus = true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// still in full speed mode - no throttle required
|
||||||
|
if (InRateLimitAvoidanceModeStatus == true)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Information, "API Connection", "Exited rate limit avoidance period, API call rate is returned to full speed.");
|
||||||
|
InRateLimitAvoidanceModeStatus = false;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// rate limit handling - how long to wait to allow the server to recover and try again
|
||||||
|
// these values affect ALL communications if a 429 response code is received
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// How long to wait (in milliseconds) if a 429 status code is received before trying again
|
||||||
|
/// </summary>
|
||||||
|
private static int RateLimitRecoveryWaitTime = 10000;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The time when normal communications can attempt to be resumed
|
||||||
|
/// </summary>
|
||||||
|
private static DateTime RateLimitResumeTime = DateTime.UtcNow.AddMinutes(5 * -1);
|
||||||
|
|
||||||
|
// rate limit retry - how many times to retry before aborting
|
||||||
|
private int RetryAttempts = 0;
|
||||||
|
private int RetryAttemptsMax = 3;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Supported metadata sources
|
||||||
|
/// </summary>
|
||||||
|
public enum MetadataSources
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// None - always returns null for metadata requests - should not really be using this source
|
||||||
|
/// </summary>
|
||||||
|
None,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// IGDB - queries the IGDB service for metadata
|
||||||
|
/// </summary>
|
||||||
|
IGDB
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Request data from the metadata API
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">Type of object to return</typeparam>
|
||||||
|
/// <param name="Endpoint">API endpoint segment to use</param>
|
||||||
|
/// <param name="Fields">Fields to request from the API</param>
|
||||||
|
/// <param name="Query">Selection criteria for data to request</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<T[]?> APIComm<T>(string Endpoint, string Fields, string Query)
|
||||||
|
{
|
||||||
|
switch (_MetadataSource)
|
||||||
|
{
|
||||||
|
case MetadataSources.None:
|
||||||
|
return null;
|
||||||
|
case MetadataSources.IGDB:
|
||||||
|
return await IGDBAPI<T>(Endpoint, Fields, Query);
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<T[]> IGDBAPI<T>(string Endpoint, string Fields, string Query)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Debug, "API Connection", "Accessing API for endpoint: " + Endpoint);
|
||||||
|
|
||||||
|
if (RateLimitResumeTime > DateTime.UtcNow)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Information, "API Connection", "IGDB rate limit hit. Pausing API communications until " + RateLimitResumeTime.ToString() + ". Attempt " + RetryAttempts + " of " + RetryAttemptsMax + " retries.");
|
||||||
|
Thread.Sleep(RateLimitRecoveryWaitTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (InRateLimitAvoidanceMode == true)
|
||||||
|
{
|
||||||
|
// sleep for a moment to help avoid hitting the rate limiter
|
||||||
|
Thread.Sleep(RateLimitAvoidanceWait);
|
||||||
|
}
|
||||||
|
|
||||||
|
// perform the actual API call
|
||||||
|
var results = await igdb.QueryAsync<T>(Endpoint, query: Fields + " " + Query + ";");
|
||||||
|
|
||||||
|
// increment rate limiter avoidance call count
|
||||||
|
RateLimitAvoidanceCallCount += 1;
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
catch (ApiException apiEx)
|
||||||
|
{
|
||||||
|
switch (apiEx.StatusCode)
|
||||||
|
{
|
||||||
|
case HttpStatusCode.TooManyRequests:
|
||||||
|
if (RetryAttempts >= RetryAttemptsMax)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Warning, "API Connection", "IGDB rate limiter attempts expired. Aborting.", apiEx);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Information, "API Connection", "IGDB API rate limit hit while accessing endpoint " + Endpoint, apiEx);
|
||||||
|
|
||||||
|
RetryAttempts += 1;
|
||||||
|
|
||||||
|
return await IGDBAPI<T>(Endpoint, Fields, Query);
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
Logging.Log(Logging.LogType.Warning, "API Connection", "Exception when accessing endpoint " + Endpoint, apiEx);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(Exception ex)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Warning, "API Connection", "Exception when accessing endpoint " + Endpoint, ex);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -12,12 +12,6 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IGDBClient igdb = new IGDBClient(
|
|
||||||
// Found in Twitch Developer portal for your app
|
|
||||||
Config.IGDB.ClientId,
|
|
||||||
Config.IGDB.Secret
|
|
||||||
);
|
|
||||||
|
|
||||||
public static Company? GetCompanies(long? Id)
|
public static Company? GetCompanies(long? Id)
|
||||||
{
|
{
|
||||||
if ((Id == 0) || (Id == null))
|
if ((Id == 0) || (Id == null))
|
||||||
@@ -111,7 +105,8 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
private static async Task<Company> GetObjectFromServer(string WhereClause)
|
private static async Task<Company> GetObjectFromServer(string WhereClause)
|
||||||
{
|
{
|
||||||
// get Companies metadata
|
// get Companies metadata
|
||||||
var results = await igdb.QueryAsync<Company>(IGDBClient.Endpoints.Companies, query: fieldList + " " + WhereClause + ";");
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<Company>(IGDBClient.Endpoints.Companies, fieldList, WhereClause);
|
||||||
if (results.Length > 0)
|
if (results.Length > 0)
|
||||||
{
|
{
|
||||||
var result = results.First();
|
var result = results.First();
|
||||||
|
@@ -13,12 +13,6 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IGDBClient igdb = new IGDBClient(
|
|
||||||
// Found in Twitch Developer portal for your app
|
|
||||||
Config.IGDB.ClientId,
|
|
||||||
Config.IGDB.Secret
|
|
||||||
);
|
|
||||||
|
|
||||||
public static CompanyLogo? GetCompanyLogo(long? Id, string LogoPath)
|
public static CompanyLogo? GetCompanyLogo(long? Id, string LogoPath)
|
||||||
{
|
{
|
||||||
if ((Id == 0) || (Id == null))
|
if ((Id == 0) || (Id == null))
|
||||||
@@ -118,7 +112,8 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
private static async Task<CompanyLogo?> GetObjectFromServer(string WhereClause, string LogoPath)
|
private static async Task<CompanyLogo?> GetObjectFromServer(string WhereClause, string LogoPath)
|
||||||
{
|
{
|
||||||
// get CompanyLogo metadata
|
// get CompanyLogo metadata
|
||||||
var results = await igdb.QueryAsync<CompanyLogo>(IGDBClient.Endpoints.CompanyLogos, query: fieldList + " " + WhereClause + ";");
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<CompanyLogo>(IGDBClient.Endpoints.CompanyLogos, fieldList, WhereClause);
|
||||||
if (results.Length > 0)
|
if (results.Length > 0)
|
||||||
{
|
{
|
||||||
var result = results.First();
|
var result = results.First();
|
||||||
|
@@ -13,12 +13,6 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IGDBClient igdb = new IGDBClient(
|
|
||||||
// Found in Twitch Developer portal for your app
|
|
||||||
Config.IGDB.ClientId,
|
|
||||||
Config.IGDB.Secret
|
|
||||||
);
|
|
||||||
|
|
||||||
public static Cover? GetCover(long? Id, string LogoPath)
|
public static Cover? GetCover(long? Id, string LogoPath)
|
||||||
{
|
{
|
||||||
if ((Id == 0) || (Id == null))
|
if ((Id == 0) || (Id == null))
|
||||||
@@ -113,7 +107,8 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
private static async Task<Cover> GetObjectFromServer(string WhereClause, string LogoPath)
|
private static async Task<Cover> GetObjectFromServer(string WhereClause, string LogoPath)
|
||||||
{
|
{
|
||||||
// get Cover metadata
|
// get Cover metadata
|
||||||
var results = await igdb.QueryAsync<Cover>(IGDBClient.Endpoints.Covers, query: fieldList + " " + WhereClause + ";");
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<Cover>(IGDBClient.Endpoints.Covers, fieldList, WhereClause);
|
||||||
var result = results.First();
|
var result = results.First();
|
||||||
|
|
||||||
//GetImageFromServer(result.Url, LogoPath, LogoSize.t_thumb, result.ImageId);
|
//GetImageFromServer(result.Url, LogoPath, LogoSize.t_thumb, result.ImageId);
|
||||||
|
@@ -13,12 +13,6 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
public static ExternalGame? GetExternalGames(long? Id)
|
||||||
{
|
{
|
||||||
if ((Id == 0) || (Id == null))
|
if ((Id == 0) || (Id == null))
|
||||||
@@ -106,7 +100,8 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
private static async Task<ExternalGame?> GetObjectFromServer(string WhereClause)
|
private static async Task<ExternalGame?> GetObjectFromServer(string WhereClause)
|
||||||
{
|
{
|
||||||
// get ExternalGames metadata
|
// get ExternalGames metadata
|
||||||
var results = await igdb.QueryAsync<ExternalGame>(IGDBClient.Endpoints.ExternalGames, query: fieldList + " " + WhereClause + ";");
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<ExternalGame>(IGDBClient.Endpoints.ExternalGames, fieldList, WhereClause);
|
||||||
if (results.Length > 0)
|
if (results.Length > 0)
|
||||||
{
|
{
|
||||||
var result = results.First();
|
var result = results.First();
|
||||||
|
@@ -13,12 +13,6 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
public static Franchise? GetFranchises(long? Id)
|
||||||
{
|
{
|
||||||
if ((Id == 0) || (Id == null))
|
if ((Id == 0) || (Id == null))
|
||||||
@@ -103,7 +97,8 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
private static async Task<Franchise> GetObjectFromServer(string WhereClause)
|
private static async Task<Franchise> GetObjectFromServer(string WhereClause)
|
||||||
{
|
{
|
||||||
// get FranchiseContentDescriptions metadata
|
// get FranchiseContentDescriptions metadata
|
||||||
var results = await igdb.QueryAsync<Franchise>(IGDBClient.Endpoints.Franchies, query: fieldList + " " + WhereClause + ";");
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<Franchise>(IGDBClient.Endpoints.Franchies, fieldList, WhereClause);
|
||||||
var result = results.First();
|
var result = results.First();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@@ -13,12 +13,6 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IGDBClient igdb = new IGDBClient(
|
|
||||||
// Found in Twitch Developer portal for your app
|
|
||||||
Config.IGDB.ClientId,
|
|
||||||
Config.IGDB.Secret
|
|
||||||
);
|
|
||||||
|
|
||||||
public static GameMode? GetGame_Modes(long? Id)
|
public static GameMode? GetGame_Modes(long? Id)
|
||||||
{
|
{
|
||||||
if ((Id == 0) || (Id == null))
|
if ((Id == 0) || (Id == null))
|
||||||
@@ -103,7 +97,8 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
private static async Task<GameMode> GetObjectFromServer(string WhereClause)
|
private static async Task<GameMode> GetObjectFromServer(string WhereClause)
|
||||||
{
|
{
|
||||||
// get Game_Modes metadata
|
// get Game_Modes metadata
|
||||||
var results = await igdb.QueryAsync<GameMode>(IGDBClient.Endpoints.GameModes, query: fieldList + " " + WhereClause + ";");
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<GameMode>(IGDBClient.Endpoints.GameModes, fieldList, WhereClause);
|
||||||
var result = results.First();
|
var result = results.First();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@@ -13,12 +13,6 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
public static GameVideo? GetGame_Videos(long? Id)
|
||||||
{
|
{
|
||||||
if ((Id == 0) || (Id == null))
|
if ((Id == 0) || (Id == null))
|
||||||
@@ -103,7 +97,8 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
private static async Task<GameVideo> GetObjectFromServer(string WhereClause)
|
private static async Task<GameVideo> GetObjectFromServer(string WhereClause)
|
||||||
{
|
{
|
||||||
// get Game_Videos metadata
|
// get Game_Videos metadata
|
||||||
var results = await igdb.QueryAsync<GameVideo>(IGDBClient.Endpoints.GameVideos, query: fieldList + " " + WhereClause + ";");
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<GameVideo>(IGDBClient.Endpoints.GameVideos, fieldList, WhereClause);
|
||||||
var result = results.First();
|
var result = results.First();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@@ -20,12 +20,6 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
{}
|
{}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IGDBClient igdb = new IGDBClient(
|
|
||||||
// Found in Twitch Developer portal for your app
|
|
||||||
Config.IGDB.ClientId,
|
|
||||||
Config.IGDB.Secret
|
|
||||||
);
|
|
||||||
|
|
||||||
public static Game? GetGame(long Id, bool getAllMetadata, bool followSubGames, bool forceRefresh)
|
public static Game? GetGame(long Id, bool getAllMetadata, bool followSubGames, bool forceRefresh)
|
||||||
{
|
{
|
||||||
if (Id == 0)
|
if (Id == 0)
|
||||||
@@ -174,17 +168,25 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Game.AgeRatings != null)
|
||||||
|
{
|
||||||
|
foreach (long AgeRatingId in Game.AgeRatings.Ids)
|
||||||
|
{
|
||||||
|
AgeRating GameAgeRating = AgeRatings.GetAgeRatings(AgeRatingId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Game.ReleaseDates != null)
|
||||||
|
{
|
||||||
|
foreach (long ReleaseDateId in Game.ReleaseDates.Ids)
|
||||||
|
{
|
||||||
|
ReleaseDate GameReleaseDate = ReleaseDates.GetReleaseDates(ReleaseDateId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// optional metadata - usually downloaded as needed
|
// optional metadata - usually downloaded as needed
|
||||||
if (getAllMetadata == true)
|
if (getAllMetadata == true)
|
||||||
{
|
{
|
||||||
if (Game.AgeRatings != null)
|
|
||||||
{
|
|
||||||
foreach (long AgeRatingId in Game.AgeRatings.Ids)
|
|
||||||
{
|
|
||||||
AgeRating GameAgeRating = AgeRatings.GetAgeRatings(AgeRatingId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Game.AlternativeNames != null)
|
if (Game.AlternativeNames != null)
|
||||||
{
|
{
|
||||||
foreach (long AlternativeNameId in Game.AlternativeNames.Ids)
|
foreach (long AlternativeNameId in Game.AlternativeNames.Ids)
|
||||||
@@ -287,11 +289,40 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
private static async Task<Game> GetObjectFromServer(string WhereClause)
|
private static async Task<Game> GetObjectFromServer(string WhereClause)
|
||||||
{
|
{
|
||||||
// get Game metadata
|
// get Game metadata
|
||||||
var results = await igdb.QueryAsync<Game>(IGDBClient.Endpoints.Games, query: fieldList + " " + WhereClause + ";");
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<Game>(IGDBClient.Endpoints.Games, fieldList, WhereClause);
|
||||||
var result = results.First();
|
var result = results.First();
|
||||||
|
|
||||||
|
// add artificial unknown platform mapping
|
||||||
|
List<long> platformIds = new List<long>();
|
||||||
|
platformIds.Add(0);
|
||||||
|
if (result.Platforms != null)
|
||||||
|
{
|
||||||
|
if (result.Platforms.Ids != null)
|
||||||
|
{
|
||||||
|
platformIds.AddRange(result.Platforms.Ids.ToList());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.Platforms = new IdentitiesOrValues<Platform>(
|
||||||
|
ids: platformIds.ToArray<long>()
|
||||||
|
);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void AssignAllGamesToPlatformIdZero()
|
||||||
|
{
|
||||||
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
|
string sql = "SELECT * FROM Game;";
|
||||||
|
DataTable gamesTable = db.ExecuteCMD(sql);
|
||||||
|
foreach (DataRow gameRow in gamesTable.Rows)
|
||||||
|
{
|
||||||
|
sql = "DELETE FROM Relation_Game_Platforms WHERE PlatformsId = 0 AND GameId = @Id; INSERT INTO Relation_Game_Platforms (GameId, PlatformsId) VALUES (@Id, 0);";
|
||||||
|
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||||
|
dbDict.Add("Id", (long)gameRow["Id"]);
|
||||||
|
db.ExecuteCMD(sql, dbDict);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static Game[] SearchForGame(string SearchString, long PlatformId, SearchType searchType)
|
public static Game[] SearchForGame(string SearchString, long PlatformId, SearchType searchType)
|
||||||
{
|
{
|
||||||
@@ -302,7 +333,7 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
private static async Task<Game[]> _SearchForGame(string SearchString, long PlatformId, SearchType searchType)
|
private static async Task<Game[]> _SearchForGame(string SearchString, long PlatformId, SearchType searchType)
|
||||||
{
|
{
|
||||||
string searchBody = "";
|
string searchBody = "";
|
||||||
searchBody += "fields id,name,slug,platforms,summary; ";
|
string searchFields = "fields id,name,slug,platforms,summary; ";
|
||||||
switch (searchType)
|
switch (searchType)
|
||||||
{
|
{
|
||||||
case SearchType.searchNoPlatform:
|
case SearchType.searchNoPlatform:
|
||||||
@@ -322,7 +353,8 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
|
|
||||||
|
|
||||||
// get Game metadata
|
// get Game metadata
|
||||||
var results = await igdb.QueryAsync<Game>(IGDBClient.Endpoints.Games, query: searchBody);
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<Game>(IGDBClient.Endpoints.Games, searchFields, searchBody);
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
@@ -334,5 +366,40 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
search = 2,
|
search = 2,
|
||||||
searchNoPlatform = 3
|
searchNoPlatform = 3
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class MinimalGameItem
|
||||||
|
{
|
||||||
|
public MinimalGameItem(Game gameObject)
|
||||||
|
{
|
||||||
|
this.Id = gameObject.Id;
|
||||||
|
this.Name = gameObject.Name;
|
||||||
|
this.TotalRating = gameObject.TotalRating;
|
||||||
|
this.TotalRatingCount = gameObject.TotalRatingCount;
|
||||||
|
this.Cover = gameObject.Cover;
|
||||||
|
this.Artworks = gameObject.Artworks;
|
||||||
|
|
||||||
|
// compile age ratings
|
||||||
|
this.AgeRatings = new List<AgeRating>();
|
||||||
|
if (gameObject.AgeRatings != null)
|
||||||
|
{
|
||||||
|
foreach (long ageRatingId in gameObject.AgeRatings.Ids)
|
||||||
|
{
|
||||||
|
AgeRating? rating = Classes.Metadata.AgeRatings.GetAgeRatings(ageRatingId);
|
||||||
|
if (rating != null)
|
||||||
|
{
|
||||||
|
this.AgeRatings.Add(rating);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public long? Id { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
public double? TotalRating { get; set; }
|
||||||
|
public int? TotalRatingCount { get; set; }
|
||||||
|
public IGDB.IdentityOrValue<IGDB.Models.Cover> Cover { get; set; }
|
||||||
|
public IGDB.IdentitiesOrValues<IGDB.Models.Artwork> Artworks { get; set; }
|
||||||
|
public List<IGDB.Models.AgeRating> AgeRatings { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -13,12 +13,6 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
public static Genre? GetGenres(long? Id)
|
||||||
{
|
{
|
||||||
if ((Id == 0) || (Id == null))
|
if ((Id == 0) || (Id == null))
|
||||||
@@ -103,7 +97,8 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
private static async Task<Genre> GetObjectFromServer(string WhereClause)
|
private static async Task<Genre> GetObjectFromServer(string WhereClause)
|
||||||
{
|
{
|
||||||
// get Genres metadata
|
// get Genres metadata
|
||||||
var results = await igdb.QueryAsync<Genre>(IGDBClient.Endpoints.Genres, query: fieldList + " " + WhereClause + ";");
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<Genre>(IGDBClient.Endpoints.Genres, fieldList, WhereClause);
|
||||||
var result = results.First();
|
var result = results.First();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@@ -12,12 +12,6 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IGDBClient igdb = new IGDBClient(
|
|
||||||
// Found in Twitch Developer portal for your app
|
|
||||||
Config.IGDB.ClientId,
|
|
||||||
Config.IGDB.Secret
|
|
||||||
);
|
|
||||||
|
|
||||||
public static InvolvedCompany? GetInvolvedCompanies(long? Id)
|
public static InvolvedCompany? GetInvolvedCompanies(long? Id)
|
||||||
{
|
{
|
||||||
if ((Id == 0) || (Id == null))
|
if ((Id == 0) || (Id == null))
|
||||||
@@ -113,7 +107,8 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
// get InvolvedCompanies metadata
|
// get InvolvedCompanies metadata
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var results = await igdb.QueryAsync<InvolvedCompany>(IGDBClient.Endpoints.InvolvedCompanies, query: fieldList + " " + WhereClause + ";");
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<InvolvedCompany>(IGDBClient.Endpoints.InvolvedCompanies, fieldList, WhereClause);
|
||||||
var result = results.First();
|
var result = results.First();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@@ -13,12 +13,6 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IGDBClient igdb = new IGDBClient(
|
|
||||||
// Found in Twitch Developer portal for your app
|
|
||||||
Config.IGDB.ClientId,
|
|
||||||
Config.IGDB.Secret
|
|
||||||
);
|
|
||||||
|
|
||||||
public static MultiplayerMode? GetGame_MultiplayerModes(long? Id)
|
public static MultiplayerMode? GetGame_MultiplayerModes(long? Id)
|
||||||
{
|
{
|
||||||
if ((Id == 0) || (Id == null))
|
if ((Id == 0) || (Id == null))
|
||||||
@@ -103,7 +97,8 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
private static async Task<MultiplayerMode> GetObjectFromServer(string WhereClause)
|
private static async Task<MultiplayerMode> GetObjectFromServer(string WhereClause)
|
||||||
{
|
{
|
||||||
// get Game_MultiplayerModes metadata
|
// get Game_MultiplayerModes metadata
|
||||||
var results = await igdb.QueryAsync<MultiplayerMode>(IGDBClient.Endpoints.MultiplayerModes, query: fieldList + " " + WhereClause + ";");
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<MultiplayerMode>(IGDBClient.Endpoints.MultiplayerModes, fieldList, WhereClause);
|
||||||
var result = results.First();
|
var result = results.First();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@@ -13,12 +13,6 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IGDBClient igdb = new IGDBClient(
|
|
||||||
// Found in Twitch Developer portal for your app
|
|
||||||
Config.IGDB.ClientId,
|
|
||||||
Config.IGDB.Secret
|
|
||||||
);
|
|
||||||
|
|
||||||
public static PlatformLogo? GetPlatformLogo(long? Id, string LogoPath)
|
public static PlatformLogo? GetPlatformLogo(long? Id, string LogoPath)
|
||||||
{
|
{
|
||||||
if ((Id == 0) || (Id == null))
|
if ((Id == 0) || (Id == null))
|
||||||
@@ -118,7 +112,8 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
private static async Task<PlatformLogo?> GetObjectFromServer(string WhereClause, string LogoPath)
|
private static async Task<PlatformLogo?> GetObjectFromServer(string WhereClause, string LogoPath)
|
||||||
{
|
{
|
||||||
// get PlatformLogo metadata
|
// get PlatformLogo metadata
|
||||||
var results = await igdb.QueryAsync<PlatformLogo>(IGDBClient.Endpoints.PlatformLogos, query: fieldList + " " + WhereClause + ";");
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<PlatformLogo>(IGDBClient.Endpoints.PlatformLogos, fieldList, WhereClause);
|
||||||
if (results.Length > 0)
|
if (results.Length > 0)
|
||||||
{
|
{
|
||||||
var result = results.First();
|
var result = results.First();
|
||||||
|
@@ -13,12 +13,6 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IGDBClient igdb = new IGDBClient(
|
|
||||||
// Found in Twitch Developer portal for your app
|
|
||||||
Config.IGDB.ClientId,
|
|
||||||
Config.IGDB.Secret
|
|
||||||
);
|
|
||||||
|
|
||||||
public static PlatformVersion? GetPlatformVersion(long Id, Platform ParentPlatform)
|
public static PlatformVersion? GetPlatformVersion(long Id, Platform ParentPlatform)
|
||||||
{
|
{
|
||||||
if (Id == 0)
|
if (Id == 0)
|
||||||
@@ -113,7 +107,8 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
private static async Task<PlatformVersion?> GetObjectFromServer(string WhereClause)
|
private static async Task<PlatformVersion?> GetObjectFromServer(string WhereClause)
|
||||||
{
|
{
|
||||||
// get PlatformVersion metadata
|
// get PlatformVersion metadata
|
||||||
var results = await igdb.QueryAsync<PlatformVersion>(IGDBClient.Endpoints.PlatformVersions, query: fieldList + " " + WhereClause + ";");
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<PlatformVersion>(IGDBClient.Endpoints.PlatformVersions, fieldList, WhereClause);
|
||||||
if (results.Length > 0)
|
if (results.Length > 0)
|
||||||
{
|
{
|
||||||
var result = results.First();
|
var result = results.First();
|
||||||
|
@@ -15,12 +15,6 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IGDBClient igdb = new IGDBClient(
|
|
||||||
// Found in Twitch Developer portal for your app
|
|
||||||
Config.IGDB.ClientId,
|
|
||||||
Config.IGDB.Secret
|
|
||||||
);
|
|
||||||
|
|
||||||
public static Platform? GetPlatform(long Id, bool forceRefresh = false)
|
public static Platform? GetPlatform(long Id, bool forceRefresh = false)
|
||||||
{
|
{
|
||||||
if (Id == 0)
|
if (Id == 0)
|
||||||
@@ -168,11 +162,26 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
private static async Task<Platform> GetObjectFromServer(string WhereClause)
|
private static async Task<Platform> GetObjectFromServer(string WhereClause)
|
||||||
{
|
{
|
||||||
// get platform metadata
|
// get platform metadata
|
||||||
var results = await igdb.QueryAsync<Platform>(IGDBClient.Endpoints.Platforms, query: fieldList + " " + WhereClause + ";");
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<Platform>(IGDBClient.Endpoints.Platforms, fieldList, WhereClause);
|
||||||
var result = results.First();
|
var result = results.First();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void AssignAllPlatformsToGameIdZero()
|
||||||
|
{
|
||||||
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
|
string sql = "SELECT * FROM Platform;";
|
||||||
|
DataTable platformsTable = db.ExecuteCMD(sql);
|
||||||
|
foreach (DataRow platformRow in platformsTable.Rows)
|
||||||
|
{
|
||||||
|
sql = "DELETE FROM Relation_Game_Platforms WHERE GameId = 0 AND PlatformsId = @Id; INSERT INTO Relation_Game_Platforms (GameId, PlatformsId) VALUES (0, @Id);";
|
||||||
|
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||||
|
dbDict.Add("Id", (long)platformRow["Id"]);
|
||||||
|
db.ExecuteCMD(sql, dbDict);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -13,12 +13,6 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IGDBClient igdb = new IGDBClient(
|
|
||||||
// Found in Twitch Developer portal for your app
|
|
||||||
Config.IGDB.ClientId,
|
|
||||||
Config.IGDB.Secret
|
|
||||||
);
|
|
||||||
|
|
||||||
public static PlayerPerspective? GetGame_PlayerPerspectives(long? Id)
|
public static PlayerPerspective? GetGame_PlayerPerspectives(long? Id)
|
||||||
{
|
{
|
||||||
if ((Id == 0) || (Id == null))
|
if ((Id == 0) || (Id == null))
|
||||||
@@ -105,7 +99,8 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
private static async Task<PlayerPerspective> GetObjectFromServer(string WhereClause)
|
private static async Task<PlayerPerspective> GetObjectFromServer(string WhereClause)
|
||||||
{
|
{
|
||||||
// get Game_PlayerPerspectives metadata
|
// get Game_PlayerPerspectives metadata
|
||||||
var results = await igdb.QueryAsync<PlayerPerspective>(IGDBClient.Endpoints.PlayerPerspectives, query: fieldList + " " + WhereClause + ";");
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<PlayerPerspective>(IGDBClient.Endpoints.PlayerPerspectives, fieldList, WhereClause);
|
||||||
var result = results.First();
|
var result = results.First();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
108
gaseous-server/Classes/Metadata/ReleaseDates.cs
Normal file
108
gaseous-server/Classes/Metadata/ReleaseDates.cs
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
using System;
|
||||||
|
using IGDB;
|
||||||
|
using IGDB.Models;
|
||||||
|
|
||||||
|
|
||||||
|
namespace gaseous_server.Classes.Metadata
|
||||||
|
{
|
||||||
|
public class ReleaseDates
|
||||||
|
{
|
||||||
|
const string fieldList = "fields category,checksum,created_at,date,game,human,m,platform,region,status,updated_at,y;";
|
||||||
|
|
||||||
|
public ReleaseDates()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ReleaseDate? GetReleaseDates(long? Id)
|
||||||
|
{
|
||||||
|
if ((Id == 0) || (Id == null))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Task<ReleaseDate> RetVal = _GetReleaseDates(SearchUsing.id, Id);
|
||||||
|
return RetVal.Result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ReleaseDate GetReleaseDates(string Slug)
|
||||||
|
{
|
||||||
|
Task<ReleaseDate> RetVal = _GetReleaseDates(SearchUsing.slug, Slug);
|
||||||
|
return RetVal.Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<ReleaseDate> _GetReleaseDates(SearchUsing searchUsing, object searchValue)
|
||||||
|
{
|
||||||
|
// check database first
|
||||||
|
Storage.CacheStatus? cacheStatus = new Storage.CacheStatus();
|
||||||
|
if (searchUsing == SearchUsing.id)
|
||||||
|
{
|
||||||
|
cacheStatus = Storage.GetCacheStatus("ReleaseDate", (long)searchValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cacheStatus = Storage.GetCacheStatus("ReleaseDate", (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");
|
||||||
|
}
|
||||||
|
|
||||||
|
ReleaseDate returnValue = new ReleaseDate();
|
||||||
|
switch (cacheStatus)
|
||||||
|
{
|
||||||
|
case Storage.CacheStatus.NotPresent:
|
||||||
|
returnValue = await GetObjectFromServer(WhereClause);
|
||||||
|
Storage.NewCacheValue(returnValue);
|
||||||
|
break;
|
||||||
|
case Storage.CacheStatus.Expired:
|
||||||
|
try
|
||||||
|
{
|
||||||
|
returnValue = await GetObjectFromServer(WhereClause);
|
||||||
|
Storage.NewCacheValue(returnValue, true);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Warning, "Metadata: " + returnValue.GetType().Name, "An error occurred while connecting to IGDB. WhereClause: " + WhereClause, ex);
|
||||||
|
returnValue = Storage.GetCacheValue<ReleaseDate>(returnValue, "id", (long)searchValue);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Storage.CacheStatus.Current:
|
||||||
|
returnValue = Storage.GetCacheValue<ReleaseDate>(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<ReleaseDate> GetObjectFromServer(string WhereClause)
|
||||||
|
{
|
||||||
|
// get ReleaseDates metadata
|
||||||
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<ReleaseDate>(IGDBClient.Endpoints.ReleaseDates, fieldList, WhereClause);
|
||||||
|
var result = results.First();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@@ -13,12 +13,6 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IGDBClient igdb = new IGDBClient(
|
|
||||||
// Found in Twitch Developer portal for your app
|
|
||||||
Config.IGDB.ClientId,
|
|
||||||
Config.IGDB.Secret
|
|
||||||
);
|
|
||||||
|
|
||||||
public static Screenshot? GetScreenshot(long? Id, string LogoPath)
|
public static Screenshot? GetScreenshot(long? Id, string LogoPath)
|
||||||
{
|
{
|
||||||
if ((Id == 0) || (Id == null))
|
if ((Id == 0) || (Id == null))
|
||||||
@@ -114,7 +108,8 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
private static async Task<Screenshot> GetObjectFromServer(string WhereClause, string LogoPath)
|
private static async Task<Screenshot> GetObjectFromServer(string WhereClause, string LogoPath)
|
||||||
{
|
{
|
||||||
// get Screenshot metadata
|
// get Screenshot metadata
|
||||||
var results = await igdb.QueryAsync<Screenshot>(IGDBClient.Endpoints.Screenshots, query: fieldList + " " + WhereClause + ";");
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<Screenshot>(IGDBClient.Endpoints.Screenshots, fieldList, WhereClause);
|
||||||
var result = results.First();
|
var result = results.First();
|
||||||
|
|
||||||
//GetImageFromServer(result.Url, LogoPath, LogoSize.t_thumb, result.ImageId);
|
//GetImageFromServer(result.Url, LogoPath, LogoSize.t_thumb, result.ImageId);
|
||||||
|
@@ -16,32 +16,14 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
Expired
|
Expired
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Dictionary<string, MemoryCacheObject> ObjectCache = new Dictionary<string, MemoryCacheObject>();
|
|
||||||
|
|
||||||
public static CacheStatus GetCacheStatus(string Endpoint, string Slug)
|
public static CacheStatus GetCacheStatus(string Endpoint, string Slug)
|
||||||
{
|
{
|
||||||
CacheClean();
|
return _GetCacheStatus(Endpoint, "slug", Slug);
|
||||||
if (ObjectCache.ContainsKey(Endpoint + Slug))
|
|
||||||
{
|
|
||||||
return CacheStatus.Current;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return _GetCacheStatus(Endpoint, "slug", Slug);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CacheStatus GetCacheStatus(string Endpoint, long Id)
|
public static CacheStatus GetCacheStatus(string Endpoint, long Id)
|
||||||
{
|
{
|
||||||
CacheClean();
|
return _GetCacheStatus(Endpoint, "id", Id);
|
||||||
if (ObjectCache.ContainsKey(Endpoint + Id))
|
|
||||||
{
|
|
||||||
return CacheStatus.Current;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return _GetCacheStatus(Endpoint, "id", Id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CacheStatus GetCacheStatus(DataRow Row)
|
public static CacheStatus GetCacheStatus(DataRow Row)
|
||||||
@@ -185,21 +167,6 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
{
|
{
|
||||||
string Endpoint = EndpointType.GetType().Name;
|
string Endpoint = EndpointType.GetType().Name;
|
||||||
|
|
||||||
if (ObjectCache.ContainsKey(Endpoint + SearchValue))
|
|
||||||
{
|
|
||||||
MemoryCacheObject cacheObject = ObjectCache[Endpoint + SearchValue];
|
|
||||||
if (cacheObject.ExpiryTime < DateTime.UtcNow)
|
|
||||||
{
|
|
||||||
// object has expired, remove it
|
|
||||||
ObjectCache.Remove(Endpoint + SearchValue);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// object is valid, return it
|
|
||||||
return (T)cacheObject.Object;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
|
|
||||||
string sql = "SELECT * FROM " + Endpoint + " WHERE " + SearchField + " = @" + SearchField;
|
string sql = "SELECT * FROM " + Endpoint + " WHERE " + SearchField + " = @" + SearchField;
|
||||||
@@ -218,9 +185,7 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
{
|
{
|
||||||
DataRow dataRow = dt.Rows[0];
|
DataRow dataRow = dt.Rows[0];
|
||||||
object returnObject = BuildCacheObject<T>(EndpointType, dataRow);
|
object returnObject = BuildCacheObject<T>(EndpointType, dataRow);
|
||||||
ObjectCache.Add(Endpoint + SearchValue, new MemoryCacheObject{
|
|
||||||
Object = returnObject
|
|
||||||
});
|
|
||||||
return (T)returnObject;
|
return (T)returnObject;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -404,6 +369,12 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
case "[igdb.models.startdatecategory":
|
case "[igdb.models.startdatecategory":
|
||||||
property.SetValue(EndpointType, (StartDateCategory)dataRow[property.Name]);
|
property.SetValue(EndpointType, (StartDateCategory)dataRow[property.Name]);
|
||||||
break;
|
break;
|
||||||
|
case "[igdb.models.releasedateregion":
|
||||||
|
property.SetValue(EndpointType, (ReleaseDateRegion)dataRow[property.Name]);
|
||||||
|
break;
|
||||||
|
case "[igdb.models.releasedatecategory":
|
||||||
|
property.SetValue(EndpointType, (ReleaseDateCategory)dataRow[property.Name]);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
property.SetValue(EndpointType, dataRow[property.Name]);
|
property.SetValue(EndpointType, dataRow[property.Name]);
|
||||||
break;
|
break;
|
||||||
@@ -454,29 +425,6 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void CacheClean()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (ObjectCache == null)
|
|
||||||
{
|
|
||||||
ObjectCache = new Dictionary<string, MemoryCacheObject>();
|
|
||||||
}
|
|
||||||
Dictionary<string, MemoryCacheObject> workCache = ObjectCache;
|
|
||||||
foreach (KeyValuePair<string, MemoryCacheObject> objectCache in workCache)
|
|
||||||
{
|
|
||||||
if (objectCache.Value.ExpiryTime < DateTime.UtcNow)
|
|
||||||
{
|
|
||||||
ObjectCache.Remove(objectCache.Key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
ObjectCache = new Dictionary<string, MemoryCacheObject>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class MemoryCacheObject
|
private class MemoryCacheObject
|
||||||
{
|
{
|
||||||
public object Object { get; set; }
|
public object Object { get; set; }
|
||||||
|
@@ -13,12 +13,6 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IGDBClient igdb = new IGDBClient(
|
|
||||||
// Found in Twitch Developer portal for your app
|
|
||||||
Config.IGDB.ClientId,
|
|
||||||
Config.IGDB.Secret
|
|
||||||
);
|
|
||||||
|
|
||||||
public static Theme? GetGame_Themes(long? Id)
|
public static Theme? GetGame_Themes(long? Id)
|
||||||
{
|
{
|
||||||
if ((Id == 0) || (Id == null))
|
if ((Id == 0) || (Id == null))
|
||||||
@@ -105,7 +99,8 @@ namespace gaseous_server.Classes.Metadata
|
|||||||
private static async Task<Theme> GetObjectFromServer(string WhereClause)
|
private static async Task<Theme> GetObjectFromServer(string WhereClause)
|
||||||
{
|
{
|
||||||
// get Game_Themes metadata
|
// get Game_Themes metadata
|
||||||
var results = await igdb.QueryAsync<Theme>(IGDBClient.Endpoints.Themes, query: fieldList + " " + WhereClause + ";");
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<Theme>(IGDBClient.Endpoints.Themes, fieldList, WhereClause);
|
||||||
var result = results.First();
|
var result = results.First();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@@ -4,47 +4,71 @@ using gaseous_server.Models;
|
|||||||
|
|
||||||
namespace gaseous_server.Classes
|
namespace gaseous_server.Classes
|
||||||
{
|
{
|
||||||
public class MetadataManagement
|
public class MetadataManagement : QueueItemStatus
|
||||||
{
|
{
|
||||||
public static void RefreshMetadata(bool forceRefresh = false)
|
public void RefreshMetadata(bool forceRefresh = false)
|
||||||
{
|
{
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
string sql = "";
|
string sql = "";
|
||||||
DataTable dt = new DataTable();
|
DataTable dt = new DataTable();
|
||||||
|
|
||||||
|
// disabling forceRefresh
|
||||||
|
forceRefresh = false;
|
||||||
|
|
||||||
// update platforms
|
// update platforms
|
||||||
sql = "SELECT Id, `Name` FROM Platform;";
|
sql = "SELECT Id, `Name` FROM Platform;";
|
||||||
dt = db.ExecuteCMD(sql);
|
dt = db.ExecuteCMD(sql);
|
||||||
|
|
||||||
|
int StatusCounter = 1;
|
||||||
foreach (DataRow dr in dt.Rows)
|
foreach (DataRow dr in dt.Rows)
|
||||||
{
|
{
|
||||||
|
SetStatus(StatusCounter, dt.Rows.Count, "Refreshing metadata for platform " + dr["name"]);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Logging.Log(Logging.LogType.Information, "Metadata Refresh", "Refreshing metadata for platform " + dr["name"] + " (" + dr["id"] + ")");
|
Logging.Log(Logging.LogType.Information, "Metadata Refresh", "(" + StatusCounter + "/" + dt.Rows.Count + "): Refreshing metadata for platform " + dr["name"] + " (" + dr["id"] + ")");
|
||||||
Metadata.Platforms.GetPlatform((long)dr["id"], true);
|
Metadata.Platforms.GetPlatform((long)dr["id"], true);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.Log(Logging.LogType.Critical, "Metadata Refresh", "An error occurred while refreshing metadata for " + dr["name"], ex);
|
Logging.Log(Logging.LogType.Critical, "Metadata Refresh", "An error occurred while refreshing metadata for " + dr["name"], ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StatusCounter += 1;
|
||||||
}
|
}
|
||||||
|
ClearStatus();
|
||||||
|
|
||||||
// update games
|
// update games
|
||||||
sql = "SELECT Id, `Name` FROM Game;";
|
if (forceRefresh == true)
|
||||||
|
{
|
||||||
|
// when forced, only update games with ROMs for
|
||||||
|
sql = "SELECT Id, `Name` FROM view_GamesWithRoms;";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// when run normally, update all games (since this will honour cache timeouts)
|
||||||
|
sql = "SELECT Id, `Name` FROM Game;";
|
||||||
|
}
|
||||||
dt = db.ExecuteCMD(sql);
|
dt = db.ExecuteCMD(sql);
|
||||||
|
|
||||||
|
StatusCounter = 1;
|
||||||
foreach (DataRow dr in dt.Rows)
|
foreach (DataRow dr in dt.Rows)
|
||||||
{
|
{
|
||||||
|
SetStatus(StatusCounter, dt.Rows.Count, "Refreshing metadata for game " + dr["name"]);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Logging.Log(Logging.LogType.Information, "Metadata Refresh", "Refreshing metadata for game " + dr["name"] + " (" + dr["id"] + ")");
|
Logging.Log(Logging.LogType.Information, "Metadata Refresh", "(" + StatusCounter + "/" + dt.Rows.Count + "): Refreshing metadata for game " + dr["name"] + " (" + dr["id"] + ")");
|
||||||
Metadata.Games.GetGame((long)dr["id"], true, true, forceRefresh);
|
Metadata.Games.GetGame((long)dr["id"], true, false, forceRefresh);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.Log(Logging.LogType.Critical, "Metadata Refresh", "An error occurred while refreshing metadata for " + dr["name"], ex);
|
Logging.Log(Logging.LogType.Critical, "Metadata Refresh", "An error occurred while refreshing metadata for " + dr["name"], ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StatusCounter += 1;
|
||||||
}
|
}
|
||||||
|
ClearStatus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
41
gaseous-server/Classes/QueueItemStatus.cs
Normal file
41
gaseous-server/Classes/QueueItemStatus.cs
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
namespace gaseous_server.Classes
|
||||||
|
{
|
||||||
|
public class QueueItemStatus
|
||||||
|
{
|
||||||
|
internal ProcessQueue.QueueItem? CallingQueueItem = null;
|
||||||
|
|
||||||
|
private int _CurrentItemNumber = 0;
|
||||||
|
private int _MaxItemsNumber = 0;
|
||||||
|
private string _StatusText = "";
|
||||||
|
|
||||||
|
public int CurrentItemNumber => _CurrentItemNumber;
|
||||||
|
public int MaxItemsNumber => _MaxItemsNumber;
|
||||||
|
public string StatusText => _StatusText;
|
||||||
|
|
||||||
|
public void SetStatus(int CurrentItemNumber, int MaxItemsNumber, string StatusText)
|
||||||
|
{
|
||||||
|
this._CurrentItemNumber = CurrentItemNumber;
|
||||||
|
this._MaxItemsNumber = MaxItemsNumber;
|
||||||
|
this._StatusText = StatusText;
|
||||||
|
|
||||||
|
if (CallingQueueItem != null)
|
||||||
|
{
|
||||||
|
CallingQueueItem.CurrentState = _CurrentItemNumber + " of " + _MaxItemsNumber + ": " + _StatusText;
|
||||||
|
CallingQueueItem.CurrentStateProgress = _CurrentItemNumber + " of " + _MaxItemsNumber;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ClearStatus()
|
||||||
|
{
|
||||||
|
this._CurrentItemNumber = 0;
|
||||||
|
this._MaxItemsNumber = 0;
|
||||||
|
this._StatusText = "";
|
||||||
|
|
||||||
|
if (CallingQueueItem != null)
|
||||||
|
{
|
||||||
|
CallingQueueItem.CurrentState = "";
|
||||||
|
CallingQueueItem.CurrentStateProgress = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -6,7 +6,7 @@ using System.Data;
|
|||||||
|
|
||||||
namespace gaseous_server.SignatureIngestors.XML
|
namespace gaseous_server.SignatureIngestors.XML
|
||||||
{
|
{
|
||||||
public class XMLIngestor
|
public class XMLIngestor : QueueItemStatus
|
||||||
{
|
{
|
||||||
public void Import(string SearchPath, gaseous_signature_parser.parser.SignatureParser XMLType)
|
public void Import(string SearchPath, gaseous_signature_parser.parser.SignatureParser XMLType)
|
||||||
{
|
{
|
||||||
@@ -31,222 +31,232 @@ namespace gaseous_server.SignatureIngestors.XML
|
|||||||
{
|
{
|
||||||
string XMLFile = PathContents[i];
|
string XMLFile = PathContents[i];
|
||||||
|
|
||||||
// check xml file md5
|
SetStatus(i + 1, PathContents.Length, "Processing signature file: " + XMLFile);
|
||||||
Common.hashObject hashObject = new Common.hashObject(XMLFile);
|
|
||||||
sql = "SELECT * FROM Signatures_Sources WHERE SourceMD5=@sourcemd5";
|
|
||||||
dbDict = new Dictionary<string, object>();
|
|
||||||
dbDict.Add("sourcemd5", hashObject.md5hash);
|
|
||||||
sigDB = db.ExecuteCMD(sql, dbDict);
|
|
||||||
|
|
||||||
if (sigDB.Rows.Count == 0)
|
if (Common.SkippableFiles.Contains(Path.GetFileName(XMLFile), StringComparer.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
try
|
Logging.Log(Logging.LogType.Information, "Signature Ingestor - XML", "Skipping file: " + XMLFile);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// check xml file md5
|
||||||
|
Common.hashObject hashObject = new Common.hashObject(XMLFile);
|
||||||
|
sql = "SELECT * FROM Signatures_Sources WHERE SourceMD5=@sourcemd5";
|
||||||
|
dbDict = new Dictionary<string, object>();
|
||||||
|
dbDict.Add("sourcemd5", hashObject.md5hash);
|
||||||
|
sigDB = db.ExecuteCMD(sql, dbDict);
|
||||||
|
|
||||||
|
if (sigDB.Rows.Count == 0)
|
||||||
{
|
{
|
||||||
Logging.Log(Logging.LogType.Information, "Signature Ingestor - XML", "Importing file: " + XMLFile);
|
try
|
||||||
|
|
||||||
// start parsing file
|
|
||||||
gaseous_signature_parser.parser Parser = new gaseous_signature_parser.parser();
|
|
||||||
RomSignatureObject Object = Parser.ParseSignatureDAT(XMLFile, XMLType);
|
|
||||||
|
|
||||||
// store in database
|
|
||||||
string[] flipNameAndDescription = {
|
|
||||||
"MAMEArcade",
|
|
||||||
"MAMEMess"
|
|
||||||
};
|
|
||||||
|
|
||||||
// store source object
|
|
||||||
bool processGames = false;
|
|
||||||
if (Object.SourceMd5 != null)
|
|
||||||
{
|
{
|
||||||
sql = "SELECT * FROM Signatures_Sources WHERE SourceMD5=@sourcemd5";
|
Logging.Log(Logging.LogType.Information, "Signature Ingestor - XML", "Importing file: " + XMLFile);
|
||||||
dbDict = new Dictionary<string, object>();
|
|
||||||
string sourceUriStr = "";
|
// start parsing file
|
||||||
if (Object.Url != null)
|
gaseous_signature_parser.parser Parser = new gaseous_signature_parser.parser();
|
||||||
|
RomSignatureObject Object = Parser.ParseSignatureDAT(XMLFile, XMLType);
|
||||||
|
|
||||||
|
// store in database
|
||||||
|
string[] flipNameAndDescription = {
|
||||||
|
"MAMEArcade",
|
||||||
|
"MAMEMess"
|
||||||
|
};
|
||||||
|
|
||||||
|
// store source object
|
||||||
|
bool processGames = false;
|
||||||
|
if (Object.SourceMd5 != null)
|
||||||
{
|
{
|
||||||
sourceUriStr = Object.Url.ToString();
|
sql = "SELECT * FROM Signatures_Sources WHERE SourceMD5=@sourcemd5";
|
||||||
}
|
dbDict = new Dictionary<string, object>();
|
||||||
dbDict.Add("name", Common.ReturnValueIfNull(Object.Name, ""));
|
string sourceUriStr = "";
|
||||||
dbDict.Add("description", Common.ReturnValueIfNull(Object.Description, ""));
|
if (Object.Url != null)
|
||||||
dbDict.Add("category", Common.ReturnValueIfNull(Object.Category, ""));
|
|
||||||
dbDict.Add("version", Common.ReturnValueIfNull(Object.Version, ""));
|
|
||||||
dbDict.Add("author", Common.ReturnValueIfNull(Object.Author, ""));
|
|
||||||
dbDict.Add("email", Common.ReturnValueIfNull(Object.Email, ""));
|
|
||||||
dbDict.Add("homepage", Common.ReturnValueIfNull(Object.Homepage, ""));
|
|
||||||
dbDict.Add("uri", sourceUriStr);
|
|
||||||
dbDict.Add("sourcetype", Common.ReturnValueIfNull(Object.SourceType, ""));
|
|
||||||
dbDict.Add("sourcemd5", Object.SourceMd5);
|
|
||||||
dbDict.Add("sourcesha1", Object.SourceSHA1);
|
|
||||||
|
|
||||||
sigDB = db.ExecuteCMD(sql, dbDict);
|
|
||||||
if (sigDB.Rows.Count == 0)
|
|
||||||
{
|
|
||||||
// entry not present, insert it
|
|
||||||
sql = "INSERT INTO Signatures_Sources (Name, Description, Category, Version, Author, Email, Homepage, Url, SourceType, SourceMD5, SourceSHA1) VALUES (@name, @description, @category, @version, @author, @email, @homepage, @uri, @sourcetype, @sourcemd5, @sourcesha1)";
|
|
||||||
|
|
||||||
db.ExecuteCMD(sql, dbDict);
|
|
||||||
|
|
||||||
processGames = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (processGames == true)
|
|
||||||
{
|
|
||||||
for (int x = 0; x < Object.Games.Count; ++x)
|
|
||||||
{
|
{
|
||||||
RomSignatureObject.Game gameObject = Object.Games[x];
|
sourceUriStr = Object.Url.ToString();
|
||||||
|
}
|
||||||
|
dbDict.Add("name", Common.ReturnValueIfNull(Object.Name, ""));
|
||||||
|
dbDict.Add("description", Common.ReturnValueIfNull(Object.Description, ""));
|
||||||
|
dbDict.Add("category", Common.ReturnValueIfNull(Object.Category, ""));
|
||||||
|
dbDict.Add("version", Common.ReturnValueIfNull(Object.Version, ""));
|
||||||
|
dbDict.Add("author", Common.ReturnValueIfNull(Object.Author, ""));
|
||||||
|
dbDict.Add("email", Common.ReturnValueIfNull(Object.Email, ""));
|
||||||
|
dbDict.Add("homepage", Common.ReturnValueIfNull(Object.Homepage, ""));
|
||||||
|
dbDict.Add("uri", sourceUriStr);
|
||||||
|
dbDict.Add("sourcetype", Common.ReturnValueIfNull(Object.SourceType, ""));
|
||||||
|
dbDict.Add("sourcemd5", Object.SourceMd5);
|
||||||
|
dbDict.Add("sourcesha1", Object.SourceSHA1);
|
||||||
|
|
||||||
// set up game dictionary
|
sigDB = db.ExecuteCMD(sql, dbDict);
|
||||||
dbDict = new Dictionary<string, object>();
|
if (sigDB.Rows.Count == 0)
|
||||||
if (flipNameAndDescription.Contains(Object.SourceType))
|
{
|
||||||
{
|
// entry not present, insert it
|
||||||
dbDict.Add("name", Common.ReturnValueIfNull(gameObject.Description, ""));
|
sql = "INSERT INTO Signatures_Sources (Name, Description, Category, Version, Author, Email, Homepage, Url, SourceType, SourceMD5, SourceSHA1) VALUES (@name, @description, @category, @version, @author, @email, @homepage, @uri, @sourcetype, @sourcemd5, @sourcesha1)";
|
||||||
dbDict.Add("description", Common.ReturnValueIfNull(gameObject.Name, ""));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dbDict.Add("name", Common.ReturnValueIfNull(gameObject.Name, ""));
|
|
||||||
dbDict.Add("description", Common.ReturnValueIfNull(gameObject.Description, ""));
|
|
||||||
}
|
|
||||||
dbDict.Add("year", Common.ReturnValueIfNull(gameObject.Year, ""));
|
|
||||||
dbDict.Add("publisher", Common.ReturnValueIfNull(gameObject.Publisher, ""));
|
|
||||||
dbDict.Add("demo", (int)gameObject.Demo);
|
|
||||||
dbDict.Add("system", Common.ReturnValueIfNull(gameObject.System, ""));
|
|
||||||
dbDict.Add("platform", Common.ReturnValueIfNull(gameObject.System, ""));
|
|
||||||
dbDict.Add("systemvariant", Common.ReturnValueIfNull(gameObject.SystemVariant, ""));
|
|
||||||
dbDict.Add("video", Common.ReturnValueIfNull(gameObject.Video, ""));
|
|
||||||
dbDict.Add("country", Common.ReturnValueIfNull(gameObject.Country, ""));
|
|
||||||
dbDict.Add("language", Common.ReturnValueIfNull(gameObject.Language, ""));
|
|
||||||
dbDict.Add("copyright", Common.ReturnValueIfNull(gameObject.Copyright, ""));
|
|
||||||
|
|
||||||
// store platform
|
db.ExecuteCMD(sql, dbDict);
|
||||||
int gameSystem = 0;
|
|
||||||
if (gameObject.System != null)
|
|
||||||
{
|
|
||||||
sql = "SELECT Id FROM Signatures_Platforms WHERE Platform=@platform";
|
|
||||||
|
|
||||||
sigDB = db.ExecuteCMD(sql, dbDict);
|
processGames = true;
|
||||||
if (sigDB.Rows.Count == 0)
|
}
|
||||||
|
|
||||||
|
if (processGames == true)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < Object.Games.Count; ++x)
|
||||||
|
{
|
||||||
|
RomSignatureObject.Game gameObject = Object.Games[x];
|
||||||
|
|
||||||
|
// set up game dictionary
|
||||||
|
dbDict = new Dictionary<string, object>();
|
||||||
|
if (flipNameAndDescription.Contains(Object.SourceType))
|
||||||
{
|
{
|
||||||
// entry not present, insert it
|
dbDict.Add("name", Common.ReturnValueIfNull(gameObject.Description, ""));
|
||||||
sql = "INSERT INTO Signatures_Platforms (Platform) VALUES (@platform); SELECT CAST(LAST_INSERT_ID() AS SIGNED);";
|
dbDict.Add("description", Common.ReturnValueIfNull(gameObject.Name, ""));
|
||||||
sigDB = db.ExecuteCMD(sql, dbDict);
|
|
||||||
|
|
||||||
gameSystem = Convert.ToInt32(sigDB.Rows[0][0]);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gameSystem = (int)sigDB.Rows[0][0];
|
dbDict.Add("name", Common.ReturnValueIfNull(gameObject.Name, ""));
|
||||||
|
dbDict.Add("description", Common.ReturnValueIfNull(gameObject.Description, ""));
|
||||||
}
|
}
|
||||||
}
|
dbDict.Add("year", Common.ReturnValueIfNull(gameObject.Year, ""));
|
||||||
dbDict.Add("systemid", gameSystem);
|
dbDict.Add("publisher", Common.ReturnValueIfNull(gameObject.Publisher, ""));
|
||||||
|
dbDict.Add("demo", (int)gameObject.Demo);
|
||||||
|
dbDict.Add("system", Common.ReturnValueIfNull(gameObject.System, ""));
|
||||||
|
dbDict.Add("platform", Common.ReturnValueIfNull(gameObject.System, ""));
|
||||||
|
dbDict.Add("systemvariant", Common.ReturnValueIfNull(gameObject.SystemVariant, ""));
|
||||||
|
dbDict.Add("video", Common.ReturnValueIfNull(gameObject.Video, ""));
|
||||||
|
dbDict.Add("country", Common.ReturnValueIfNull(gameObject.Country, ""));
|
||||||
|
dbDict.Add("language", Common.ReturnValueIfNull(gameObject.Language, ""));
|
||||||
|
dbDict.Add("copyright", Common.ReturnValueIfNull(gameObject.Copyright, ""));
|
||||||
|
|
||||||
// store publisher
|
// store platform
|
||||||
int gamePublisher = 0;
|
int gameSystem = 0;
|
||||||
if (gameObject.Publisher != null)
|
if (gameObject.System != null)
|
||||||
{
|
|
||||||
sql = "SELECT * FROM Signatures_Publishers WHERE Publisher=@publisher";
|
|
||||||
|
|
||||||
sigDB = db.ExecuteCMD(sql, dbDict);
|
|
||||||
if (sigDB.Rows.Count == 0)
|
|
||||||
{
|
{
|
||||||
// entry not present, insert it
|
sql = "SELECT Id FROM Signatures_Platforms WHERE Platform=@platform";
|
||||||
sql = "INSERT INTO Signatures_Publishers (Publisher) VALUES (@publisher); SELECT CAST(LAST_INSERT_ID() AS SIGNED);";
|
|
||||||
sigDB = db.ExecuteCMD(sql, dbDict);
|
|
||||||
gamePublisher = Convert.ToInt32(sigDB.Rows[0][0]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
gamePublisher = (int)sigDB.Rows[0][0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dbDict.Add("publisherid", gamePublisher);
|
|
||||||
|
|
||||||
// store game
|
|
||||||
int gameId = 0;
|
|
||||||
sql = "SELECT * FROM Signatures_Games WHERE Name=@name AND Year=@year AND Publisherid=@publisher AND Systemid=@systemid AND Country=@country AND Language=@language";
|
|
||||||
|
|
||||||
sigDB = db.ExecuteCMD(sql, dbDict);
|
|
||||||
if (sigDB.Rows.Count == 0)
|
|
||||||
{
|
|
||||||
// entry not present, insert it
|
|
||||||
sql = "INSERT INTO Signatures_Games " +
|
|
||||||
"(Name, Description, Year, PublisherId, Demo, SystemId, SystemVariant, Video, Country, Language, Copyright) VALUES " +
|
|
||||||
"(@name, @description, @year, @publisherid, @demo, @systemid, @systemvariant, @video, @country, @language, @copyright); SELECT CAST(LAST_INSERT_ID() AS SIGNED);";
|
|
||||||
sigDB = db.ExecuteCMD(sql, dbDict);
|
|
||||||
|
|
||||||
gameId = Convert.ToInt32(sigDB.Rows[0][0]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
gameId = (int)sigDB.Rows[0][0];
|
|
||||||
}
|
|
||||||
|
|
||||||
// store rom
|
|
||||||
foreach (RomSignatureObject.Game.Rom romObject in gameObject.Roms)
|
|
||||||
{
|
|
||||||
if (romObject.Md5 != null || romObject.Sha1 != null)
|
|
||||||
{
|
|
||||||
int romId = 0;
|
|
||||||
sql = "SELECT * FROM Signatures_Roms WHERE GameId=@gameid AND MD5=@md5";
|
|
||||||
dbDict = new Dictionary<string, object>();
|
|
||||||
dbDict.Add("gameid", gameId);
|
|
||||||
dbDict.Add("name", Common.ReturnValueIfNull(romObject.Name, ""));
|
|
||||||
dbDict.Add("size", Common.ReturnValueIfNull(romObject.Size, ""));
|
|
||||||
dbDict.Add("crc", Common.ReturnValueIfNull(romObject.Crc, "").ToString().ToLower());
|
|
||||||
dbDict.Add("md5", Common.ReturnValueIfNull(romObject.Md5, "").ToString().ToLower());
|
|
||||||
dbDict.Add("sha1", Common.ReturnValueIfNull(romObject.Sha1, "").ToString().ToLower());
|
|
||||||
dbDict.Add("developmentstatus", Common.ReturnValueIfNull(romObject.DevelopmentStatus, ""));
|
|
||||||
|
|
||||||
if (romObject.Attributes != null)
|
|
||||||
{
|
|
||||||
if (romObject.Attributes.Count > 0)
|
|
||||||
{
|
|
||||||
dbDict.Add("attributes", Newtonsoft.Json.JsonConvert.SerializeObject(romObject.Attributes));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dbDict.Add("attributes", "[ ]");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dbDict.Add("attributes", "[ ]");
|
|
||||||
}
|
|
||||||
dbDict.Add("romtype", (int)romObject.RomType);
|
|
||||||
dbDict.Add("romtypemedia", Common.ReturnValueIfNull(romObject.RomTypeMedia, ""));
|
|
||||||
dbDict.Add("medialabel", Common.ReturnValueIfNull(romObject.MediaLabel, ""));
|
|
||||||
dbDict.Add("metadatasource", romObject.SignatureSource);
|
|
||||||
dbDict.Add("ingestorversion", 2);
|
|
||||||
|
|
||||||
sigDB = db.ExecuteCMD(sql, dbDict);
|
sigDB = db.ExecuteCMD(sql, dbDict);
|
||||||
if (sigDB.Rows.Count == 0)
|
if (sigDB.Rows.Count == 0)
|
||||||
{
|
{
|
||||||
// entry not present, insert it
|
// entry not present, insert it
|
||||||
sql = "INSERT INTO Signatures_Roms (GameId, Name, Size, CRC, MD5, SHA1, DevelopmentStatus, Attributes, RomType, RomTypeMedia, MediaLabel, MetadataSource, IngestorVersion) VALUES (@gameid, @name, @size, @crc, @md5, @sha1, @developmentstatus, @attributes, @romtype, @romtypemedia, @medialabel, @metadatasource, @ingestorversion); SELECT CAST(LAST_INSERT_ID() AS SIGNED);";
|
sql = "INSERT INTO Signatures_Platforms (Platform) VALUES (@platform); SELECT CAST(LAST_INSERT_ID() AS SIGNED);";
|
||||||
sigDB = db.ExecuteCMD(sql, dbDict);
|
sigDB = db.ExecuteCMD(sql, dbDict);
|
||||||
|
|
||||||
|
gameSystem = Convert.ToInt32(sigDB.Rows[0][0]);
|
||||||
romId = Convert.ToInt32(sigDB.Rows[0][0]);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
romId = (int)sigDB.Rows[0][0];
|
gameSystem = (int)sigDB.Rows[0][0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dbDict.Add("systemid", gameSystem);
|
||||||
|
|
||||||
|
// store publisher
|
||||||
|
int gamePublisher = 0;
|
||||||
|
if (gameObject.Publisher != null)
|
||||||
|
{
|
||||||
|
sql = "SELECT * FROM Signatures_Publishers WHERE Publisher=@publisher";
|
||||||
|
|
||||||
|
sigDB = db.ExecuteCMD(sql, dbDict);
|
||||||
|
if (sigDB.Rows.Count == 0)
|
||||||
|
{
|
||||||
|
// entry not present, insert it
|
||||||
|
sql = "INSERT INTO Signatures_Publishers (Publisher) VALUES (@publisher); SELECT CAST(LAST_INSERT_ID() AS SIGNED);";
|
||||||
|
sigDB = db.ExecuteCMD(sql, dbDict);
|
||||||
|
gamePublisher = Convert.ToInt32(sigDB.Rows[0][0]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gamePublisher = (int)sigDB.Rows[0][0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dbDict.Add("publisherid", gamePublisher);
|
||||||
|
|
||||||
|
// store game
|
||||||
|
int gameId = 0;
|
||||||
|
sql = "SELECT * FROM Signatures_Games WHERE Name=@name AND Year=@year AND Publisherid=@publisher AND Systemid=@systemid AND Country=@country AND Language=@language";
|
||||||
|
|
||||||
|
sigDB = db.ExecuteCMD(sql, dbDict);
|
||||||
|
if (sigDB.Rows.Count == 0)
|
||||||
|
{
|
||||||
|
// entry not present, insert it
|
||||||
|
sql = "INSERT INTO Signatures_Games " +
|
||||||
|
"(Name, Description, Year, PublisherId, Demo, SystemId, SystemVariant, Video, Country, Language, Copyright) VALUES " +
|
||||||
|
"(@name, @description, @year, @publisherid, @demo, @systemid, @systemvariant, @video, @country, @language, @copyright); SELECT CAST(LAST_INSERT_ID() AS SIGNED);";
|
||||||
|
sigDB = db.ExecuteCMD(sql, dbDict);
|
||||||
|
|
||||||
|
gameId = Convert.ToInt32(sigDB.Rows[0][0]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gameId = (int)sigDB.Rows[0][0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// store rom
|
||||||
|
foreach (RomSignatureObject.Game.Rom romObject in gameObject.Roms)
|
||||||
|
{
|
||||||
|
if (romObject.Md5 != null || romObject.Sha1 != null)
|
||||||
|
{
|
||||||
|
int romId = 0;
|
||||||
|
sql = "SELECT * FROM Signatures_Roms WHERE GameId=@gameid AND MD5=@md5";
|
||||||
|
dbDict = new Dictionary<string, object>();
|
||||||
|
dbDict.Add("gameid", gameId);
|
||||||
|
dbDict.Add("name", Common.ReturnValueIfNull(romObject.Name, ""));
|
||||||
|
dbDict.Add("size", Common.ReturnValueIfNull(romObject.Size, ""));
|
||||||
|
dbDict.Add("crc", Common.ReturnValueIfNull(romObject.Crc, "").ToString().ToLower());
|
||||||
|
dbDict.Add("md5", Common.ReturnValueIfNull(romObject.Md5, "").ToString().ToLower());
|
||||||
|
dbDict.Add("sha1", Common.ReturnValueIfNull(romObject.Sha1, "").ToString().ToLower());
|
||||||
|
dbDict.Add("developmentstatus", Common.ReturnValueIfNull(romObject.DevelopmentStatus, ""));
|
||||||
|
|
||||||
|
if (romObject.Attributes != null)
|
||||||
|
{
|
||||||
|
if (romObject.Attributes.Count > 0)
|
||||||
|
{
|
||||||
|
dbDict.Add("attributes", Newtonsoft.Json.JsonConvert.SerializeObject(romObject.Attributes));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dbDict.Add("attributes", "[ ]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dbDict.Add("attributes", "[ ]");
|
||||||
|
}
|
||||||
|
dbDict.Add("romtype", (int)romObject.RomType);
|
||||||
|
dbDict.Add("romtypemedia", Common.ReturnValueIfNull(romObject.RomTypeMedia, ""));
|
||||||
|
dbDict.Add("medialabel", Common.ReturnValueIfNull(romObject.MediaLabel, ""));
|
||||||
|
dbDict.Add("metadatasource", romObject.SignatureSource);
|
||||||
|
dbDict.Add("ingestorversion", 2);
|
||||||
|
|
||||||
|
sigDB = db.ExecuteCMD(sql, dbDict);
|
||||||
|
if (sigDB.Rows.Count == 0)
|
||||||
|
{
|
||||||
|
// entry not present, insert it
|
||||||
|
sql = "INSERT INTO Signatures_Roms (GameId, Name, Size, CRC, MD5, SHA1, DevelopmentStatus, Attributes, RomType, RomTypeMedia, MediaLabel, MetadataSource, IngestorVersion) VALUES (@gameid, @name, @size, @crc, @md5, @sha1, @developmentstatus, @attributes, @romtype, @romtypemedia, @medialabel, @metadatasource, @ingestorversion); SELECT CAST(LAST_INSERT_ID() AS SIGNED);";
|
||||||
|
sigDB = db.ExecuteCMD(sql, dbDict);
|
||||||
|
|
||||||
|
|
||||||
|
romId = Convert.ToInt32(sigDB.Rows[0][0]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
romId = (int)sigDB.Rows[0][0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Warning, "Signature Ingestor - XML", "Invalid import file: " + XMLFile, ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
else
|
||||||
{
|
{
|
||||||
Logging.Log(Logging.LogType.Warning, "Signature Ingestor - XML", "Invalid import file: " + XMLFile, ex);
|
Logging.Log(Logging.LogType.Debug, "Signature Ingestor - XML", "Rejecting already imported file: " + XMLFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
Logging.Log(Logging.LogType.Debug, "Signature Ingestor - XML", "Rejecting already imported file: " + XMLFile);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
ClearStatus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -1,3 +1,4 @@
|
|||||||
|
using System.Data;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Authentication;
|
using Authentication;
|
||||||
@@ -95,6 +96,7 @@ namespace gaseous_server.Controllers
|
|||||||
profile.EmailAddress = await _userManager.GetEmailAsync(user);
|
profile.EmailAddress = await _userManager.GetEmailAsync(user);
|
||||||
profile.Roles = new List<string>(await _userManager.GetRolesAsync(user));
|
profile.Roles = new List<string>(await _userManager.GetRolesAsync(user));
|
||||||
profile.SecurityProfile = user.SecurityProfile;
|
profile.SecurityProfile = user.SecurityProfile;
|
||||||
|
profile.UserPreferences = user.UserPreferences;
|
||||||
profile.Roles.Sort();
|
profile.Roles.Sort();
|
||||||
|
|
||||||
return Ok(profile);
|
return Ok(profile);
|
||||||
@@ -115,6 +117,7 @@ namespace gaseous_server.Controllers
|
|||||||
profile.EmailAddress = await _userManager.GetEmailAsync(user);
|
profile.EmailAddress = await _userManager.GetEmailAsync(user);
|
||||||
profile.Roles = new List<string>(await _userManager.GetRolesAsync(user));
|
profile.Roles = new List<string>(await _userManager.GetRolesAsync(user));
|
||||||
profile.SecurityProfile = user.SecurityProfile;
|
profile.SecurityProfile = user.SecurityProfile;
|
||||||
|
profile.UserPreferences = user.UserPreferences;
|
||||||
profile.Roles.Sort();
|
profile.Roles.Sort();
|
||||||
|
|
||||||
string profileString = "var userProfile = " + Newtonsoft.Json.JsonConvert.SerializeObject(profile, Newtonsoft.Json.Formatting.Indented) + ";";
|
string profileString = "var userProfile = " + Newtonsoft.Json.JsonConvert.SerializeObject(profile, Newtonsoft.Json.Formatting.Indented) + ";";
|
||||||
@@ -375,7 +378,7 @@ namespace gaseous_server.Controllers
|
|||||||
IdentityResult passwordChangeResult = await _userManager.ResetPasswordAsync(user, resetToken, model.NewPassword);
|
IdentityResult passwordChangeResult = await _userManager.ResetPasswordAsync(user, resetToken, model.NewPassword);
|
||||||
if (passwordChangeResult.Succeeded == true)
|
if (passwordChangeResult.Succeeded == true)
|
||||||
{
|
{
|
||||||
return Ok();
|
return Ok(passwordChangeResult);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -392,5 +395,23 @@ namespace gaseous_server.Controllers
|
|||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("Preferences")]
|
||||||
|
public async Task<IActionResult> SetPreferences(List<UserPreferenceViewModel> model)
|
||||||
|
{
|
||||||
|
ApplicationUser? user = await _userManager.GetUserAsync(User);
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
return Unauthorized();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
user.UserPreferences = model;
|
||||||
|
await _userManager.UpdateAsync(user);
|
||||||
|
|
||||||
|
return Ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -3,10 +3,12 @@ using System.Collections.Generic;
|
|||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Authentication;
|
||||||
using gaseous_server.Classes;
|
using gaseous_server.Classes;
|
||||||
using IGDB.Models;
|
using IGDB.Models;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
namespace gaseous_server.Controllers
|
namespace gaseous_server.Controllers
|
||||||
@@ -16,98 +18,29 @@ namespace gaseous_server.Controllers
|
|||||||
[ApiVersion("1.1")]
|
[ApiVersion("1.1")]
|
||||||
[Authorize]
|
[Authorize]
|
||||||
[ApiController]
|
[ApiController]
|
||||||
public class FilterController : ControllerBase
|
public class FilterController : Controller
|
||||||
{
|
{
|
||||||
|
private readonly UserManager<ApplicationUser> _userManager;
|
||||||
|
private readonly SignInManager<ApplicationUser> _signInManager;
|
||||||
|
|
||||||
|
public FilterController(
|
||||||
|
UserManager<ApplicationUser> userManager,
|
||||||
|
SignInManager<ApplicationUser> signInManager)
|
||||||
|
{
|
||||||
|
_userManager = userManager;
|
||||||
|
_signInManager = signInManager;
|
||||||
|
}
|
||||||
|
|
||||||
[MapToApiVersion("1.0")]
|
[MapToApiVersion("1.0")]
|
||||||
[MapToApiVersion("1.1")]
|
[MapToApiVersion("1.1")]
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
//[ResponseCache(CacheProfileName = "5Minute")]
|
//[ResponseCache(CacheProfileName = "5Minute")]
|
||||||
public Dictionary<string, object> Filter()
|
public async Task<IActionResult> FilterAsync()
|
||||||
{
|
{
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
var user = await _userManager.GetUserAsync(User);
|
||||||
|
|
||||||
Dictionary<string, object> FilterSet = new Dictionary<string, object>();
|
return Ok(Filters.Filter(user.SecurityProfile.AgeRestrictionPolicy.MaximumAgeRestriction, user.SecurityProfile.AgeRestrictionPolicy.IncludeUnrated));
|
||||||
|
|
||||||
// platforms
|
|
||||||
List<FilterPlatform> platforms = new List<FilterPlatform>();
|
|
||||||
//string sql = "SELECT Platform.Id, Platform.Abbreviation, Platform.AlternativeName, Platform.`Name`, Platform.PlatformLogo, (SELECT COUNT(Games_Roms.Id) AS RomCount FROM Games_Roms WHERE Games_Roms.PlatformId = Platform.Id) AS RomCount FROM Platform HAVING RomCount > 0 ORDER BY `Name`";
|
|
||||||
string sql = "SELECT Platform.Id, Platform.Abbreviation, Platform.AlternativeName, Platform.`Name`, Platform.PlatformLogo, (SELECT COUNT(Games_Roms.Id) AS RomCount FROM Games_Roms WHERE Games_Roms.PlatformId = Platform.Id) AS RomCount, (SELECT COUNT(*) AS GameCount FROM (SELECT DISTINCT Games_Roms.GameId AS ROMGameId, Games_Roms.PlatformId FROM Games_Roms LEFT JOIN Game ON Game.Id = Games_Roms.GameId) Game WHERE Game.PlatformId = Platform.Id) AS GameCount FROM Platform HAVING RomCount > 0 ORDER BY `Name`";
|
|
||||||
DataTable dbResponse = db.ExecuteCMD(sql);
|
|
||||||
|
|
||||||
foreach (DataRow dr in dbResponse.Rows)
|
|
||||||
{
|
|
||||||
FilterPlatform platformItem = new FilterPlatform(Classes.Metadata.Platforms.GetPlatform((long)dr["id"]));
|
|
||||||
platformItem.RomCount = (int)(long)dr["RomCount"];
|
|
||||||
platformItem.GameCount = (int)(long)dr["GameCount"];
|
|
||||||
platforms.Add(platformItem);
|
|
||||||
|
|
||||||
}
|
|
||||||
FilterSet.Add("platforms", platforms);
|
|
||||||
|
|
||||||
// genres
|
|
||||||
List<Genre> genres = new List<Genre>();
|
|
||||||
sql = "SELECT DISTINCT Relation_Game_Genres.GenresId AS id, Genre.`Name` FROM Relation_Game_Genres JOIN Genre ON Relation_Game_Genres.GenresId = Genre.Id WHERE Relation_Game_Genres.GameId IN (SELECT DISTINCT GameId FROM Games_Roms) ORDER BY `Name`;";
|
|
||||||
dbResponse = db.ExecuteCMD(sql);
|
|
||||||
|
|
||||||
foreach (DataRow dr in dbResponse.Rows)
|
|
||||||
{
|
|
||||||
genres.Add(Classes.Metadata.Genres.GetGenres((long)dr["id"]));
|
|
||||||
}
|
|
||||||
FilterSet.Add("genres", genres);
|
|
||||||
|
|
||||||
// game modes
|
|
||||||
List<GameMode> gameModes = new List<GameMode>();
|
|
||||||
sql = "SELECT DISTINCT Relation_Game_GameModes.GameModesId AS id, GameMode.`Name` FROM Relation_Game_GameModes JOIN GameMode ON Relation_Game_GameModes.GameModesId = GameMode.Id WHERE Relation_Game_GameModes.GameId IN (SELECT DISTINCT GameId FROM Games_Roms) ORDER BY `Name`;";
|
|
||||||
dbResponse = db.ExecuteCMD(sql);
|
|
||||||
|
|
||||||
foreach (DataRow dr in dbResponse.Rows)
|
|
||||||
{
|
|
||||||
gameModes.Add(Classes.Metadata.GameModes.GetGame_Modes((long)dr["id"]));
|
|
||||||
}
|
|
||||||
FilterSet.Add("gamemodes", gameModes);
|
|
||||||
|
|
||||||
// player perspectives
|
|
||||||
List<PlayerPerspective> playerPerspectives = new List<PlayerPerspective>();
|
|
||||||
sql = "SELECT DISTINCT Relation_Game_PlayerPerspectives.PlayerPerspectivesId AS id, PlayerPerspective.`Name` FROM Relation_Game_PlayerPerspectives JOIN PlayerPerspective ON Relation_Game_PlayerPerspectives.PlayerPerspectivesId = PlayerPerspective.Id WHERE Relation_Game_PlayerPerspectives.GameId IN (SELECT DISTINCT GameId FROM Games_Roms) ORDER BY `Name`;";
|
|
||||||
dbResponse = db.ExecuteCMD(sql);
|
|
||||||
|
|
||||||
foreach (DataRow dr in dbResponse.Rows)
|
|
||||||
{
|
|
||||||
playerPerspectives.Add(Classes.Metadata.PlayerPerspectives.GetGame_PlayerPerspectives((long)dr["id"]));
|
|
||||||
}
|
|
||||||
FilterSet.Add("playerperspectives", playerPerspectives);
|
|
||||||
|
|
||||||
// themes
|
|
||||||
List<Theme> themes = new List<Theme>();
|
|
||||||
sql = "SELECT DISTINCT Relation_Game_Themes.ThemesId AS id, Theme.`Name` FROM Relation_Game_Themes JOIN Theme ON Relation_Game_Themes.ThemesId = Theme.Id WHERE Relation_Game_Themes.GameId IN (SELECT DISTINCT GameId FROM Games_Roms) ORDER BY `Name`;";
|
|
||||||
dbResponse = db.ExecuteCMD(sql);
|
|
||||||
|
|
||||||
foreach (DataRow dr in dbResponse.Rows)
|
|
||||||
{
|
|
||||||
themes.Add(Classes.Metadata.Themes.GetGame_Themes((long)dr["id"]));
|
|
||||||
}
|
|
||||||
FilterSet.Add("themes", themes);
|
|
||||||
|
|
||||||
return FilterSet;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class FilterPlatform : IGDB.Models.Platform
|
|
||||||
{
|
|
||||||
public FilterPlatform(Platform platform)
|
|
||||||
{
|
|
||||||
var properties = platform.GetType().GetProperties();
|
|
||||||
foreach (var prop in properties)
|
|
||||||
{
|
|
||||||
if (prop.GetGetMethod() != null)
|
|
||||||
{
|
|
||||||
this.GetType().GetProperty(prop.Name).SetValue(this, prop.GetValue(platform));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int RomCount { get; set; }
|
|
||||||
public int GameCount { get; set; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -22,7 +22,7 @@ namespace gaseous_server.Controllers
|
|||||||
[ApiVersion("1.1")]
|
[ApiVersion("1.1")]
|
||||||
[Authorize]
|
[Authorize]
|
||||||
[ApiController]
|
[ApiController]
|
||||||
public class GamesController : ControllerBase
|
public class GamesController : Controller
|
||||||
{
|
{
|
||||||
[MapToApiVersion("1.0")]
|
[MapToApiVersion("1.0")]
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
@@ -181,9 +181,10 @@ namespace gaseous_server.Controllers
|
|||||||
List<long> AgeClassificationsList = new List<long>();
|
List<long> AgeClassificationsList = new List<long>();
|
||||||
foreach (string ratingGroup in ratinggroup.Split(','))
|
foreach (string ratingGroup in ratinggroup.Split(','))
|
||||||
{
|
{
|
||||||
if (AgeGroups.AgeGroupings.ContainsKey(ratingGroup))
|
AgeGroups.AgeRestrictionGroupings ageRestriction = (AgeGroups.AgeRestrictionGroupings)Enum.Parse(typeof(AgeGroups.AgeRestrictionGroupings), ratingGroup);
|
||||||
|
if (AgeGroups.AgeGroupings.ContainsKey(ageRestriction))
|
||||||
{
|
{
|
||||||
List<AgeGroups.AgeGroupItem> ageGroups = AgeGroups.AgeGroupings[ratingGroup];
|
List<AgeGroups.AgeGroupItem> ageGroups = AgeGroups.AgeGroupings[ageRestriction];
|
||||||
foreach (AgeGroups.AgeGroupItem ageGroup in ageGroups)
|
foreach (AgeGroups.AgeGroupItem ageGroup in ageGroups)
|
||||||
{
|
{
|
||||||
AgeClassificationsList.AddRange(ageGroup.AgeGroupItemValues);
|
AgeClassificationsList.AddRange(ageGroup.AgeGroupItemValues);
|
||||||
@@ -824,6 +825,44 @@ namespace gaseous_server.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[MapToApiVersion("1.0")]
|
||||||
|
[MapToApiVersion("1.1")]
|
||||||
|
[HttpGet]
|
||||||
|
[Route("{GameId}/releasedates")]
|
||||||
|
[ProducesResponseType(typeof(List<ReleaseDate>), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
|
[ResponseCache(CacheProfileName = "7Days")]
|
||||||
|
public ActionResult GameReleaseDates(long GameId)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
IGDB.Models.Game gameObject = Classes.Metadata.Games.GetGame(GameId, false, false, false);
|
||||||
|
if (gameObject != null)
|
||||||
|
{
|
||||||
|
List<ReleaseDate> rdObjects = new List<ReleaseDate>();
|
||||||
|
if (gameObject.ReleaseDates != null)
|
||||||
|
{
|
||||||
|
foreach (long icId in gameObject.ReleaseDates.Ids)
|
||||||
|
{
|
||||||
|
ReleaseDate releaseDate = Classes.Metadata.ReleaseDates.GetReleaseDates(icId);
|
||||||
|
|
||||||
|
rdObjects.Add(releaseDate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(rdObjects);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[MapToApiVersion("1.0")]
|
[MapToApiVersion("1.0")]
|
||||||
[MapToApiVersion("1.1")]
|
[MapToApiVersion("1.1")]
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
|
@@ -17,11 +17,11 @@ namespace gaseous_server.Controllers
|
|||||||
{
|
{
|
||||||
[MapToApiVersion("1.0")]
|
[MapToApiVersion("1.0")]
|
||||||
[MapToApiVersion("1.1")]
|
[MapToApiVersion("1.1")]
|
||||||
[HttpGet]
|
[HttpPost]
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
public List<Logging.LogItem> Logs(long? StartIndex, int PageNumber = 1, int PageSize = 100)
|
public List<Logging.LogItem> Logs(Logging.LogsViewModel model)
|
||||||
{
|
{
|
||||||
return Logging.GetLogs(StartIndex, PageNumber, PageSize);
|
return Logging.GetLogs(model);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -22,7 +22,7 @@ namespace gaseous_server.Controllers
|
|||||||
[ApiVersion("1.1")]
|
[ApiVersion("1.1")]
|
||||||
[Authorize]
|
[Authorize]
|
||||||
[ApiController]
|
[ApiController]
|
||||||
public class RomsController : ControllerBase
|
public class RomsController : Controller
|
||||||
{
|
{
|
||||||
[MapToApiVersion("1.0")]
|
[MapToApiVersion("1.0")]
|
||||||
[MapToApiVersion("1.1")]
|
[MapToApiVersion("1.1")]
|
||||||
|
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using gaseous_server.Classes;
|
using gaseous_server.Classes;
|
||||||
|
using gaseous_server.Classes.Metadata;
|
||||||
using IGDB;
|
using IGDB;
|
||||||
using IGDB.Models;
|
using IGDB.Models;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
@@ -19,12 +20,6 @@ namespace gaseous_server.Controllers
|
|||||||
[Authorize]
|
[Authorize]
|
||||||
public class SearchController : Controller
|
public class SearchController : Controller
|
||||||
{
|
{
|
||||||
private static IGDBClient igdb = new IGDBClient(
|
|
||||||
// Found in Twitch Developer portal for your app
|
|
||||||
Config.IGDB.ClientId,
|
|
||||||
Config.IGDB.Secret
|
|
||||||
);
|
|
||||||
|
|
||||||
[MapToApiVersion("1.0")]
|
[MapToApiVersion("1.0")]
|
||||||
[MapToApiVersion("1.1")]
|
[MapToApiVersion("1.1")]
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
@@ -39,11 +34,12 @@ namespace gaseous_server.Controllers
|
|||||||
private static async Task<List<Platform>> _SearchForPlatform(string SearchString)
|
private static async Task<List<Platform>> _SearchForPlatform(string SearchString)
|
||||||
{
|
{
|
||||||
string searchBody = "";
|
string searchBody = "";
|
||||||
searchBody += "fields abbreviation,alternative_name,category,checksum,created_at,generation,name,platform_family,platform_logo,slug,summary,updated_at,url,versions,websites; ";
|
string searchFields = "fields abbreviation,alternative_name,category,checksum,created_at,generation,name,platform_family,platform_logo,slug,summary,updated_at,url,versions,websites; ";
|
||||||
searchBody += "where name ~ *\"" + SearchString + "\"*;";
|
searchBody += "where name ~ *\"" + SearchString + "\"*;";
|
||||||
|
|
||||||
// get Platform metadata
|
// get Platform metadata
|
||||||
var results = await igdb.QueryAsync<Platform>(IGDBClient.Endpoints.Platforms, query: searchBody);
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<Platform>(IGDBClient.Endpoints.Platforms, searchFields, searchBody);
|
||||||
|
|
||||||
return results.ToList();
|
return results.ToList();
|
||||||
}
|
}
|
||||||
@@ -62,12 +58,13 @@ namespace gaseous_server.Controllers
|
|||||||
private static async Task<List<Game>> _SearchForGame(long PlatformId, string SearchString)
|
private static async Task<List<Game>> _SearchForGame(long PlatformId, string SearchString)
|
||||||
{
|
{
|
||||||
string searchBody = "";
|
string searchBody = "";
|
||||||
searchBody += "fields cover.*,first_release_date,name,platforms,slug; ";
|
string searchFields = "fields cover.*,first_release_date,name,platforms,slug; ";
|
||||||
searchBody += "search \"" + SearchString + "\";";
|
searchBody += "search \"" + SearchString + "\";";
|
||||||
searchBody += "where platforms = (" + PlatformId + ");";
|
searchBody += "where platforms = (" + PlatformId + ");";
|
||||||
|
|
||||||
// get Platform metadata
|
// get Platform metadata
|
||||||
var results = await igdb.QueryAsync<Game>(IGDBClient.Endpoints.Games, query: searchBody);
|
Communications comms = new Communications();
|
||||||
|
var results = await comms.APIComm<Game>(IGDBClient.Endpoints.Games, searchFields, searchBody);
|
||||||
|
|
||||||
return results.ToList();
|
return results.ToList();
|
||||||
}
|
}
|
||||||
|
@@ -18,7 +18,7 @@ namespace gaseous_server.Controllers
|
|||||||
[ApiVersion("1.0")]
|
[ApiVersion("1.0")]
|
||||||
[ApiVersion("1.1")]
|
[ApiVersion("1.1")]
|
||||||
[Authorize]
|
[Authorize]
|
||||||
public class SignaturesController : ControllerBase
|
public class SignaturesController : Controller
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get the current signature counts from the database
|
/// Get the current signature counts from the database
|
||||||
|
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Security.Cryptography.X509Certificates;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@@ -10,6 +11,7 @@ using gaseous_server.Classes;
|
|||||||
using gaseous_server.Classes.Metadata;
|
using gaseous_server.Classes.Metadata;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Razor.Hosting;
|
||||||
|
|
||||||
namespace gaseous_server.Controllers
|
namespace gaseous_server.Controllers
|
||||||
{
|
{
|
||||||
@@ -80,6 +82,12 @@ namespace gaseous_server.Controllers
|
|||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
|
|
||||||
// get age ratings dictionary
|
// get age ratings dictionary
|
||||||
|
Dictionary<int, string> ClassificationBoardsStrings = new Dictionary<int, string>();
|
||||||
|
foreach(IGDB.Models.AgeRatingCategory ageRatingCategory in Enum.GetValues(typeof(IGDB.Models.AgeRatingCategory)) )
|
||||||
|
{
|
||||||
|
ClassificationBoardsStrings.Add((int)ageRatingCategory, ageRatingCategory.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
Dictionary<int, string> AgeRatingsStrings = new Dictionary<int, string>();
|
Dictionary<int, string> AgeRatingsStrings = new Dictionary<int, string>();
|
||||||
foreach(IGDB.Models.AgeRatingTitle ageRatingTitle in Enum.GetValues(typeof(IGDB.Models.AgeRatingTitle)) )
|
foreach(IGDB.Models.AgeRatingTitle ageRatingTitle in Enum.GetValues(typeof(IGDB.Models.AgeRatingTitle)) )
|
||||||
{
|
{
|
||||||
@@ -89,6 +97,9 @@ namespace gaseous_server.Controllers
|
|||||||
string ver = "var AppVersion = \"" + Assembly.GetExecutingAssembly().GetName().Version.ToString() + "\";" + Environment.NewLine +
|
string ver = "var AppVersion = \"" + Assembly.GetExecutingAssembly().GetName().Version.ToString() + "\";" + Environment.NewLine +
|
||||||
"var DBSchemaVersion = \"" + db.GetDatabaseSchemaVersion() + "\";" + Environment.NewLine +
|
"var DBSchemaVersion = \"" + db.GetDatabaseSchemaVersion() + "\";" + Environment.NewLine +
|
||||||
"var FirstRunStatus = " + Config.ReadSetting("FirstRunStatus", "0") + ";" + Environment.NewLine +
|
"var FirstRunStatus = " + Config.ReadSetting("FirstRunStatus", "0") + ";" + Environment.NewLine +
|
||||||
|
"var AgeRatingBoardsStrings = " + JsonSerializer.Serialize(ClassificationBoardsStrings, new JsonSerializerOptions{
|
||||||
|
WriteIndented = true
|
||||||
|
}) + ";" + Environment.NewLine +
|
||||||
"var AgeRatingStrings = " + JsonSerializer.Serialize(AgeRatingsStrings, new JsonSerializerOptions{
|
"var AgeRatingStrings = " + JsonSerializer.Serialize(AgeRatingsStrings, new JsonSerializerOptions{
|
||||||
WriteIndented = true
|
WriteIndented = true
|
||||||
}) + ";" + Environment.NewLine +
|
}) + ";" + Environment.NewLine +
|
||||||
@@ -99,6 +110,109 @@ namespace gaseous_server.Controllers
|
|||||||
return File(bytes, "text/javascript");
|
return File(bytes, "text/javascript");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[MapToApiVersion("1.0")]
|
||||||
|
[MapToApiVersion("1.1")]
|
||||||
|
[HttpGet]
|
||||||
|
[Route("Settings/BackgroundTasks/Intervals")]
|
||||||
|
[Authorize(Roles = "Admin")]
|
||||||
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
|
public ActionResult GetBackgroundTasks()
|
||||||
|
{
|
||||||
|
Dictionary<string, BackgroundTaskItem> Intervals = new Dictionary<string, BackgroundTaskItem>();
|
||||||
|
Intervals.Add(ProcessQueue.QueueItemType.SignatureIngestor.ToString(), new BackgroundTaskItem(ProcessQueue.QueueItemType.SignatureIngestor));
|
||||||
|
Intervals.Add(ProcessQueue.QueueItemType.TitleIngestor.ToString(), new BackgroundTaskItem(ProcessQueue.QueueItemType.TitleIngestor));
|
||||||
|
Intervals.Add(ProcessQueue.QueueItemType.MetadataRefresh.ToString(), new BackgroundTaskItem(ProcessQueue.QueueItemType.MetadataRefresh));
|
||||||
|
Intervals.Add(ProcessQueue.QueueItemType.OrganiseLibrary.ToString(), new BackgroundTaskItem(ProcessQueue.QueueItemType.OrganiseLibrary));
|
||||||
|
Intervals.Add(ProcessQueue.QueueItemType.LibraryScan.ToString(), new BackgroundTaskItem(ProcessQueue.QueueItemType.LibraryScan));
|
||||||
|
Intervals.Add(ProcessQueue.QueueItemType.Rematcher.ToString(), new BackgroundTaskItem(ProcessQueue.QueueItemType.Rematcher));
|
||||||
|
Intervals.Add(ProcessQueue.QueueItemType.Maintainer.ToString(), new BackgroundTaskItem(ProcessQueue.QueueItemType.Maintainer));
|
||||||
|
|
||||||
|
return Ok(Intervals);
|
||||||
|
}
|
||||||
|
|
||||||
|
[MapToApiVersion("1.0")]
|
||||||
|
[MapToApiVersion("1.1")]
|
||||||
|
[HttpPost]
|
||||||
|
[Route("Settings/BackgroundTasks/Intervals")]
|
||||||
|
[Authorize(Roles = "Admin")]
|
||||||
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
|
public ActionResult SetBackgroundTasks(Dictionary<string, int> Intervals)
|
||||||
|
{
|
||||||
|
foreach (KeyValuePair<string, int> Interval in Intervals)
|
||||||
|
{
|
||||||
|
if (Enum.IsDefined(typeof(ProcessQueue.QueueItemType), Interval.Key))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
BackgroundTaskItem taskItem = new BackgroundTaskItem(
|
||||||
|
(ProcessQueue.QueueItemType)Enum.Parse(typeof(ProcessQueue.QueueItemType), Interval.Key)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (Interval.Value >= taskItem.MinimumAllowedValue)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Information, "Update Background Task", "Updating task " + Interval.Key + " with new interval " + Interval.Value);
|
||||||
|
|
||||||
|
Config.SetSetting("Interval_" + Interval.Key, Interval.Value.ToString());
|
||||||
|
|
||||||
|
// update existing process
|
||||||
|
foreach (ProcessQueue.QueueItem item in ProcessQueue.QueueItems)
|
||||||
|
{
|
||||||
|
if (item.ItemType.ToString().ToLower() == Interval.Key.ToLower())
|
||||||
|
{
|
||||||
|
item.Interval = Interval.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Warning, "Update Background Task", "Interval " + Interval.Value + " for task " + Interval.Key + " is below the minimum allowed value of " + taskItem.MinimumAllowedValue + ". Skipping.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// task name not defined
|
||||||
|
Logging.Log(Logging.LogType.Warning, "Update Background Task", "Task " + Interval.Key + " is not user definable. Skipping.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
[MapToApiVersion("1.0")]
|
||||||
|
[MapToApiVersion("1.1")]
|
||||||
|
[HttpGet]
|
||||||
|
[Route("Settings/System")]
|
||||||
|
[Authorize(Roles = "Admin")]
|
||||||
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
|
public ActionResult GetSystemSettings()
|
||||||
|
{
|
||||||
|
SystemSettingsModel systemSettingsModel = new SystemSettingsModel{
|
||||||
|
AlwaysLogToDisk = Config.LoggingConfiguration.AlwaysLogToDisk,
|
||||||
|
MinimumLogRetentionPeriod = Config.LoggingConfiguration.LogRetention
|
||||||
|
};
|
||||||
|
|
||||||
|
return Ok(systemSettingsModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
[MapToApiVersion("1.0")]
|
||||||
|
[MapToApiVersion("1.1")]
|
||||||
|
[HttpPost]
|
||||||
|
[Route("Settings/System")]
|
||||||
|
[Authorize(Roles = "Admin")]
|
||||||
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
|
public ActionResult SetSystemSettings(SystemSettingsModel model)
|
||||||
|
{
|
||||||
|
if (ModelState.IsValid)
|
||||||
|
{
|
||||||
|
Config.LoggingConfiguration.AlwaysLogToDisk = model.AlwaysLogToDisk;
|
||||||
|
Config.LoggingConfiguration.LogRetention = model.MinimumLogRetentionPeriod;
|
||||||
|
Config.UpdateConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(model);
|
||||||
|
}
|
||||||
|
|
||||||
private SystemInfo.PathItem GetDisk(string Path)
|
private SystemInfo.PathItem GetDisk(string Path)
|
||||||
{
|
{
|
||||||
SystemInfo.PathItem pathItem = new SystemInfo.PathItem {
|
SystemInfo.PathItem pathItem = new SystemInfo.PathItem {
|
||||||
@@ -139,4 +253,69 @@ namespace gaseous_server.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class BackgroundTaskItem
|
||||||
|
{
|
||||||
|
public BackgroundTaskItem(ProcessQueue.QueueItemType TaskName)
|
||||||
|
{
|
||||||
|
this.Task = TaskName.ToString();
|
||||||
|
|
||||||
|
switch (TaskName)
|
||||||
|
{
|
||||||
|
case ProcessQueue.QueueItemType.SignatureIngestor:
|
||||||
|
this.DefaultInterval = 60;
|
||||||
|
this.MinimumAllowedValue = 20;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ProcessQueue.QueueItemType.TitleIngestor:
|
||||||
|
this.DefaultInterval = 1;
|
||||||
|
this.MinimumAllowedValue = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ProcessQueue.QueueItemType.MetadataRefresh:
|
||||||
|
this.DefaultInterval = 360;
|
||||||
|
this.MinimumAllowedValue = 360;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ProcessQueue.QueueItemType.OrganiseLibrary:
|
||||||
|
this.DefaultInterval = 1440;
|
||||||
|
this.MinimumAllowedValue = 120;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ProcessQueue.QueueItemType.LibraryScan:
|
||||||
|
this.DefaultInterval = 1440;
|
||||||
|
this.MinimumAllowedValue = 120;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ProcessQueue.QueueItemType.Rematcher:
|
||||||
|
this.DefaultInterval = 1440;
|
||||||
|
this.MinimumAllowedValue = 360;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ProcessQueue.QueueItemType.Maintainer:
|
||||||
|
this.DefaultInterval = 10080;
|
||||||
|
this.MinimumAllowedValue = 10080;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new Exception("Invalid task");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Task { get; set; }
|
||||||
|
public int Interval {
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return int.Parse(Config.ReadSetting("Interval_" + Task, DefaultInterval.ToString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public int DefaultInterval { get; set; }
|
||||||
|
public int MinimumAllowedValue { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SystemSettingsModel
|
||||||
|
{
|
||||||
|
public bool AlwaysLogToDisk { get; set; }
|
||||||
|
public int MinimumLogRetentionPeriod { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
@@ -63,7 +63,11 @@ namespace gaseous_server.Controllers
|
|||||||
|
|
||||||
Config.SetSetting("FirstRunStatus", "1");
|
Config.SetSetting("FirstRunStatus", "1");
|
||||||
|
|
||||||
return Ok();
|
return Ok(result);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return Ok(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -39,33 +39,41 @@ namespace gaseous_server.Controllers.v1_1
|
|||||||
|
|
||||||
[MapToApiVersion("1.1")]
|
[MapToApiVersion("1.1")]
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[ProducesResponseType(typeof(List<Game>), StatusCodes.Status200OK)]
|
[ProducesResponseType(typeof(GameReturnPackage), StatusCodes.Status200OK)]
|
||||||
public async Task<IActionResult> Game_v1_1(GameSearchModel model)
|
public async Task<IActionResult> Game_v1_1(GameSearchModel model, int pageNumber = 0, int pageSize = 0)
|
||||||
{
|
{
|
||||||
var user = await _userManager.GetUserAsync(User);
|
var user = await _userManager.GetUserAsync(User);
|
||||||
|
|
||||||
if (user != null)
|
if (user != null)
|
||||||
{
|
{
|
||||||
// apply security profile filtering
|
// apply security profile filtering
|
||||||
List<string> RemoveAgeGroups = new List<string>();
|
if (model.GameAgeRating.AgeGroupings.Count == 0)
|
||||||
switch (user.SecurityProfile.AgeRestrictionPolicy.MaximumAgeRestriction.ToLower())
|
|
||||||
{
|
{
|
||||||
case "adult":
|
model.GameAgeRating.AgeGroupings.Add(AgeGroups.AgeRestrictionGroupings.Adult);
|
||||||
|
model.GameAgeRating.AgeGroupings.Add(AgeGroups.AgeRestrictionGroupings.Mature);
|
||||||
|
model.GameAgeRating.AgeGroupings.Add(AgeGroups.AgeRestrictionGroupings.Teen);
|
||||||
|
model.GameAgeRating.AgeGroupings.Add(AgeGroups.AgeRestrictionGroupings.Child);
|
||||||
|
model.GameAgeRating.IncludeUnrated = true;
|
||||||
|
}
|
||||||
|
List<AgeGroups.AgeRestrictionGroupings> RemoveAgeGroups = new List<AgeGroups.AgeRestrictionGroupings>();
|
||||||
|
switch (user.SecurityProfile.AgeRestrictionPolicy.MaximumAgeRestriction)
|
||||||
|
{
|
||||||
|
case AgeGroups.AgeRestrictionGroupings.Adult:
|
||||||
break;
|
break;
|
||||||
case "mature":
|
case AgeGroups.AgeRestrictionGroupings.Mature:
|
||||||
RemoveAgeGroups.Add("Adult");
|
RemoveAgeGroups.Add(AgeGroups.AgeRestrictionGroupings.Adult);
|
||||||
break;
|
break;
|
||||||
case "teen":
|
case AgeGroups.AgeRestrictionGroupings.Teen:
|
||||||
RemoveAgeGroups.Add("Adult");
|
RemoveAgeGroups.Add(AgeGroups.AgeRestrictionGroupings.Adult);
|
||||||
RemoveAgeGroups.Add("Mature");
|
RemoveAgeGroups.Add(AgeGroups.AgeRestrictionGroupings.Mature);
|
||||||
break;
|
break;
|
||||||
case "child":
|
case AgeGroups.AgeRestrictionGroupings.Child:
|
||||||
RemoveAgeGroups.Add("Adult");
|
RemoveAgeGroups.Add(AgeGroups.AgeRestrictionGroupings.Adult);
|
||||||
RemoveAgeGroups.Add("Mature");
|
RemoveAgeGroups.Add(AgeGroups.AgeRestrictionGroupings.Mature);
|
||||||
RemoveAgeGroups.Add("Teen");
|
RemoveAgeGroups.Add(AgeGroups.AgeRestrictionGroupings.Teen);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
foreach (string RemoveAgeGroup in RemoveAgeGroups)
|
foreach (AgeGroups.AgeRestrictionGroupings RemoveAgeGroup in RemoveAgeGroups)
|
||||||
{
|
{
|
||||||
if (model.GameAgeRating.AgeGroupings.Contains(RemoveAgeGroup))
|
if (model.GameAgeRating.AgeGroupings.Contains(RemoveAgeGroup))
|
||||||
{
|
{
|
||||||
@@ -77,7 +85,47 @@ namespace gaseous_server.Controllers.v1_1
|
|||||||
model.GameAgeRating.IncludeUnrated = false;
|
model.GameAgeRating.IncludeUnrated = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(GetGames(model));
|
return Ok(GetGames(model, pageNumber, pageSize));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return Unauthorized();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[MapToApiVersion("1.1")]
|
||||||
|
[HttpGet]
|
||||||
|
[Route("{GameId}/Related")]
|
||||||
|
[ProducesResponseType(typeof(GameReturnPackage), StatusCodes.Status200OK)]
|
||||||
|
public async Task<IActionResult> GameRelated(long GameId)
|
||||||
|
{
|
||||||
|
var user = await _userManager.GetUserAsync(User);
|
||||||
|
|
||||||
|
if (user != null)
|
||||||
|
{
|
||||||
|
string IncludeUnrated = "";
|
||||||
|
if (user.SecurityProfile.AgeRestrictionPolicy.IncludeUnrated == true) {
|
||||||
|
IncludeUnrated = " OR view_Games.AgeGroupId IS NULL";
|
||||||
|
}
|
||||||
|
|
||||||
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
|
string sql = "SELECT view_Games.Id, view_Games.AgeGroupId, Relation_Game_SimilarGames.SimilarGamesId FROM view_Games JOIN Relation_Game_SimilarGames ON view_Games.Id = Relation_Game_SimilarGames.GameId AND Relation_Game_SimilarGames.SimilarGamesId IN (SELECT Id FROM view_Games) WHERE view_Games.Id = @id AND (view_Games.AgeGroupId <= @agegroupid" + IncludeUnrated + ")";
|
||||||
|
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||||
|
dbDict.Add("id", GameId);
|
||||||
|
dbDict.Add("agegroupid", (int)user.SecurityProfile.AgeRestrictionPolicy.MaximumAgeRestriction);
|
||||||
|
|
||||||
|
List<IGDB.Models.Game> RetVal = new List<IGDB.Models.Game>();
|
||||||
|
|
||||||
|
DataTable dbResponse = db.ExecuteCMD(sql, dbDict);
|
||||||
|
|
||||||
|
foreach (DataRow dr in dbResponse.Rows)
|
||||||
|
{
|
||||||
|
RetVal.Add(Classes.Metadata.Games.GetGame((long)dr["SimilarGamesId"], false, false, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
GameReturnPackage gameReturn = new GameReturnPackage(RetVal.Count, RetVal);
|
||||||
|
|
||||||
|
return Ok(gameReturn);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -109,7 +157,12 @@ namespace gaseous_server.Controllers.v1_1
|
|||||||
|
|
||||||
public class GameAgeRatingItem
|
public class GameAgeRatingItem
|
||||||
{
|
{
|
||||||
public List<string> AgeGroupings { get; set; } = new List<string>{ "Child", "Teen", "Mature", "Adult" };
|
public List<AgeGroups.AgeRestrictionGroupings> AgeGroupings { get; set; } = new List<AgeGroups.AgeRestrictionGroupings>{
|
||||||
|
AgeGroups.AgeRestrictionGroupings.Child,
|
||||||
|
AgeGroups.AgeRestrictionGroupings.Teen,
|
||||||
|
AgeGroups.AgeRestrictionGroupings.Mature,
|
||||||
|
AgeGroups.AgeRestrictionGroupings.Adult
|
||||||
|
};
|
||||||
public bool IncludeUnrated { get; set; } = true;
|
public bool IncludeUnrated { get; set; } = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,7 +181,7 @@ namespace gaseous_server.Controllers.v1_1
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<Game> GetGames(GameSearchModel model)
|
public static GameReturnPackage GetGames(GameSearchModel model, int pageNumber = 0, int pageSize = 0)
|
||||||
{
|
{
|
||||||
string whereClause = "";
|
string whereClause = "";
|
||||||
string havingClause = "";
|
string havingClause = "";
|
||||||
@@ -191,7 +244,7 @@ namespace gaseous_server.Controllers.v1_1
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string unratedClause = "totalRating IS NOT NULL";
|
string unratedClause = "";
|
||||||
if (model.GameRating.IncludeUnrated == true)
|
if (model.GameRating.IncludeUnrated == true)
|
||||||
{
|
{
|
||||||
unratedClause = "totalRating IS NULL";
|
unratedClause = "totalRating IS NULL";
|
||||||
@@ -199,13 +252,20 @@ namespace gaseous_server.Controllers.v1_1
|
|||||||
|
|
||||||
if (ratingClauseValue.Length > 0)
|
if (ratingClauseValue.Length > 0)
|
||||||
{
|
{
|
||||||
havingClauses.Add("((" + ratingClauseValue + ") OR " + unratedClause + ")");
|
if (unratedClause.Length > 0)
|
||||||
|
{
|
||||||
|
havingClauses.Add("((" + ratingClauseValue + ") OR " + unratedClause + ")");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
havingClauses.Add("(" + ratingClauseValue + ")");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (model.Platform.Count > 0)
|
if (model.Platform.Count > 0)
|
||||||
{
|
{
|
||||||
tempVal = "Games_Roms.PlatformId IN (";
|
tempVal = "Relation_Game_Platforms.PlatformsId IN (";
|
||||||
for (int i = 0; i < model.Platform.Count; i++)
|
for (int i = 0; i < model.Platform.Count; i++)
|
||||||
{
|
{
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
@@ -292,43 +352,26 @@ namespace gaseous_server.Controllers.v1_1
|
|||||||
{
|
{
|
||||||
if (model.GameAgeRating.AgeGroupings.Count > 0)
|
if (model.GameAgeRating.AgeGroupings.Count > 0)
|
||||||
{
|
{
|
||||||
List<long> AgeClassificationsList = new List<long>();
|
tempVal = "(AgeGroupId IN (";
|
||||||
foreach (string ratingGroup in model.GameAgeRating.AgeGroupings)
|
for (int i = 0; i < model.GameAgeRating.AgeGroupings.Count; i++)
|
||||||
{
|
{
|
||||||
if (AgeGroups.AgeGroupings.ContainsKey(ratingGroup))
|
if (i > 0)
|
||||||
{
|
{
|
||||||
List<AgeGroups.AgeGroupItem> ageGroups = AgeGroups.AgeGroupings[ratingGroup];
|
tempVal += ", ";
|
||||||
foreach (AgeGroups.AgeGroupItem ageGroup in ageGroups)
|
|
||||||
{
|
|
||||||
AgeClassificationsList.AddRange(ageGroup.AgeGroupItemValues);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
string themeLabel = "@Rating" + i;
|
||||||
|
tempVal += themeLabel;
|
||||||
|
whereParams.Add(themeLabel, model.GameAgeRating.AgeGroupings[i]);
|
||||||
}
|
}
|
||||||
|
tempVal += ")";
|
||||||
|
|
||||||
if (AgeClassificationsList.Count > 0)
|
if (model.GameAgeRating.IncludeUnrated == true)
|
||||||
{
|
{
|
||||||
AgeClassificationsList = new HashSet<long>(AgeClassificationsList).ToList();
|
tempVal += " OR AgeGroupId IS NULL";
|
||||||
tempVal = "(view_AgeRatings.Rating IN (";
|
|
||||||
for (int i = 0; i < AgeClassificationsList.Count; i++)
|
|
||||||
{
|
|
||||||
if (i > 0)
|
|
||||||
{
|
|
||||||
tempVal += ", ";
|
|
||||||
}
|
|
||||||
string themeLabel = "@Rating" + i;
|
|
||||||
tempVal += themeLabel;
|
|
||||||
whereParams.Add(themeLabel, AgeClassificationsList[i]);
|
|
||||||
}
|
|
||||||
tempVal += ")";
|
|
||||||
|
|
||||||
if (model.GameAgeRating.IncludeUnrated == true)
|
|
||||||
{
|
|
||||||
tempVal += " OR view_AgeRatings.Rating IS NULL";
|
|
||||||
}
|
|
||||||
tempVal += ")";
|
|
||||||
|
|
||||||
whereClauses.Add(tempVal);
|
|
||||||
}
|
}
|
||||||
|
tempVal += ")";
|
||||||
|
|
||||||
|
whereClauses.Add(tempVal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -396,18 +439,54 @@ namespace gaseous_server.Controllers.v1_1
|
|||||||
string orderByClause = "ORDER BY `" + orderByField + "` " + orderByOrder;
|
string orderByClause = "ORDER BY `" + orderByField + "` " + orderByOrder;
|
||||||
|
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
string sql = "SELECT DISTINCT Games_Roms.GameId AS ROMGameId, Game.*, case when Game.`Name` like 'The %' then CONCAT(trim(substr(Game.`Name` from 4)), ', The') else Game.`Name` end as NameThe FROM Games_Roms LEFT JOIN Game ON Game.Id = Games_Roms.GameId LEFT JOIN Relation_Game_Genres ON Game.Id = Relation_Game_Genres.GameId LEFT JOIN Relation_Game_GameModes ON Game.Id = Relation_Game_GameModes.GameId LEFT JOIN Relation_Game_PlayerPerspectives ON Game.Id = Relation_Game_PlayerPerspectives.GameId LEFT JOIN Relation_Game_Themes ON Game.Id = Relation_Game_Themes.GameId LEFT JOIN (SELECT Relation_Game_AgeRatings.GameId, AgeRating.* FROM Relation_Game_AgeRatings JOIN AgeRating ON Relation_Game_AgeRatings.AgeRatingsId = AgeRating.Id) view_AgeRatings ON Game.Id = view_AgeRatings.GameId " + whereClause + " " + havingClause + " " + orderByClause;
|
string sql = "SELECT DISTINCT view_Games.* FROM view_Games LEFT JOIN Relation_Game_Platforms ON view_Games.Id = Relation_Game_Platforms.GameId AND (Relation_Game_Platforms.PlatformsId IN (SELECT DISTINCT PlatformId FROM Games_Roms WHERE Games_Roms.GameId = view_Games.Id)) LEFT JOIN Relation_Game_Genres ON view_Games.Id = Relation_Game_Genres.GameId LEFT JOIN Relation_Game_GameModes ON view_Games.Id = Relation_Game_GameModes.GameId LEFT JOIN Relation_Game_PlayerPerspectives ON view_Games.Id = Relation_Game_PlayerPerspectives.GameId LEFT JOIN Relation_Game_Themes ON view_Games.Id = Relation_Game_Themes.GameId " + whereClause + " " + havingClause + " " + orderByClause;
|
||||||
|
|
||||||
List<IGDB.Models.Game> RetVal = new List<IGDB.Models.Game>();
|
List<IGDB.Models.Game> RetVal = new List<IGDB.Models.Game>();
|
||||||
|
|
||||||
DataTable dbResponse = db.ExecuteCMD(sql, whereParams);
|
DataTable dbResponse = db.ExecuteCMD(sql, whereParams);
|
||||||
foreach (DataRow dr in dbResponse.Rows)
|
|
||||||
|
// get count
|
||||||
|
int RecordCount = dbResponse.Rows.Count;
|
||||||
|
|
||||||
|
// compile data for return
|
||||||
|
int pageOffset = pageSize * (pageNumber - 1);
|
||||||
|
for (int i = pageOffset; i < dbResponse.Rows.Count; i++)
|
||||||
{
|
{
|
||||||
//RetVal.Add(Classes.Metadata.Games.GetGame((long)dr["ROMGameId"], false, false));
|
if (i >= (pageOffset + pageSize))
|
||||||
RetVal.Add(Classes.Metadata.Games.GetGame(dr));
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
RetVal.Add(Classes.Metadata.Games.GetGame(dbResponse.Rows[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
return RetVal;
|
GameReturnPackage gameReturn = new GameReturnPackage(RecordCount, RetVal);
|
||||||
|
|
||||||
|
return gameReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GameReturnPackage
|
||||||
|
{
|
||||||
|
public GameReturnPackage()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public GameReturnPackage(int Count, List<Game> Games)
|
||||||
|
{
|
||||||
|
this.Count = Count;
|
||||||
|
|
||||||
|
List<Games.MinimalGameItem> minimalGames = new List<Games.MinimalGameItem>();
|
||||||
|
foreach (Game game in Games)
|
||||||
|
{
|
||||||
|
minimalGames.Add(new Classes.Metadata.Games.MinimalGameItem(game));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.Games = minimalGames;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Count { get; set; }
|
||||||
|
public List<Games.MinimalGameItem> Games { get; set; } = new List<Games.MinimalGameItem>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -157,18 +157,18 @@ namespace gaseous_server.Models
|
|||||||
if (Update == false)
|
if (Update == false)
|
||||||
{
|
{
|
||||||
// insert
|
// insert
|
||||||
sql = "INSERT INTO PlatformMap (Id, RetroPieDirectoryName, WebEmulator_Type, WebEmulator_Core, AvailableWebEmulators) VALUES (@Id, @RetroPieDirectoryName, @WebEmulator_Type, @WebEmulator_Core, @AvailableWebEmulators)";
|
sql = "INSERT INTO PlatformMap (Id, RetroPieDirectoryName, WebEmulator_Type, WebEmulator_Core, AvailableWebEmulators) VALUES (@Id, @RetroPieDirectoryName, @WebEmulator_Type, @WebEmulator_Core, @AvailableWebEmulators);";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// update
|
// update
|
||||||
if (AllowAvailableEmulatorOverwrite == true)
|
if (AllowAvailableEmulatorOverwrite == true)
|
||||||
{
|
{
|
||||||
sql = "UPDATE PlatformMap SET RetroPieDirectoryName=@RetroPieDirectoryName, WebEmulator_Type=@WebEmulator_Type, WebEmulator_Core=@WebEmulator_Core, AvailableWebEmulators=@AvailableWebEmulators WHERE Id = @Id";
|
sql = "UPDATE PlatformMap SET RetroPieDirectoryName=@RetroPieDirectoryName, WebEmulator_Type=@WebEmulator_Type, WebEmulator_Core=@WebEmulator_Core, AvailableWebEmulators=@AvailableWebEmulators WHERE Id = @Id; ";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sql = "UPDATE PlatformMap SET RetroPieDirectoryName=@RetroPieDirectoryName, WebEmulator_Type=@WebEmulator_Type, WebEmulator_Core=@WebEmulator_Core WHERE Id = @Id";
|
sql = "UPDATE PlatformMap SET RetroPieDirectoryName=@RetroPieDirectoryName, WebEmulator_Type=@WebEmulator_Type, WebEmulator_Core=@WebEmulator_Core WHERE Id = @Id;";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dbDict.Add("Id", item.IGDBId);
|
dbDict.Add("Id", item.IGDBId);
|
||||||
|
@@ -1,4 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.ComponentModel.Design.Serialization;
|
||||||
|
using System.Data;
|
||||||
using gaseous_server.Classes;
|
using gaseous_server.Classes;
|
||||||
|
|
||||||
namespace gaseous_server
|
namespace gaseous_server
|
||||||
@@ -13,7 +15,7 @@ namespace gaseous_server
|
|||||||
{
|
{
|
||||||
_ItemType = ItemType;
|
_ItemType = ItemType;
|
||||||
_ItemState = QueueItemState.NeverStarted;
|
_ItemState = QueueItemState.NeverStarted;
|
||||||
_LastRunTime = DateTime.Parse(Config.ReadSetting("LastRun_" + _ItemType.ToString(), DateTime.UtcNow.ToString("yyyy-MM-ddThh:mm:ssZ")));
|
_LastRunTime = DateTime.Parse(Config.ReadSetting("LastRun_" + _ItemType.ToString(), DateTime.UtcNow.ToString("yyyy-MM-ddThh:mm:ssZ"))).AddMinutes(-5);
|
||||||
_Interval = ExecutionInterval;
|
_Interval = ExecutionInterval;
|
||||||
_AllowManualStart = AllowManualStart;
|
_AllowManualStart = AllowManualStart;
|
||||||
_RemoveWhenStopped = RemoveWhenStopped;
|
_RemoveWhenStopped = RemoveWhenStopped;
|
||||||
@@ -23,7 +25,7 @@ namespace gaseous_server
|
|||||||
{
|
{
|
||||||
_ItemType = ItemType;
|
_ItemType = ItemType;
|
||||||
_ItemState = QueueItemState.NeverStarted;
|
_ItemState = QueueItemState.NeverStarted;
|
||||||
_LastRunTime = DateTime.Parse(Config.ReadSetting("LastRun_" + _ItemType.ToString(), DateTime.UtcNow.ToString("yyyy-MM-ddThh:mm:ssZ")));
|
_LastRunTime = DateTime.Parse(Config.ReadSetting("LastRun_" + _ItemType.ToString(), DateTime.UtcNow.ToString("yyyy-MM-ddThh:mm:ssZ"))).AddMinutes(-5);
|
||||||
_Interval = ExecutionInterval;
|
_Interval = ExecutionInterval;
|
||||||
_AllowManualStart = AllowManualStart;
|
_AllowManualStart = AllowManualStart;
|
||||||
_RemoveWhenStopped = RemoveWhenStopped;
|
_RemoveWhenStopped = RemoveWhenStopped;
|
||||||
@@ -33,6 +35,7 @@ namespace gaseous_server
|
|||||||
private QueueItemType _ItemType = QueueItemType.NotConfigured;
|
private QueueItemType _ItemType = QueueItemType.NotConfigured;
|
||||||
private QueueItemState _ItemState = QueueItemState.NeverStarted;
|
private QueueItemState _ItemState = QueueItemState.NeverStarted;
|
||||||
private DateTime _LastRunTime = DateTime.UtcNow;
|
private DateTime _LastRunTime = DateTime.UtcNow;
|
||||||
|
private double _LastRunDuration = 0;
|
||||||
private DateTime _LastFinishTime
|
private DateTime _LastFinishTime
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -55,19 +58,32 @@ namespace gaseous_server
|
|||||||
private bool _AllowManualStart = true;
|
private bool _AllowManualStart = true;
|
||||||
private bool _RemoveWhenStopped = false;
|
private bool _RemoveWhenStopped = false;
|
||||||
private bool _IsBlocked = false;
|
private bool _IsBlocked = false;
|
||||||
|
private string _CorrelationId = "";
|
||||||
private List<QueueItemType> _Blocks = new List<QueueItemType>();
|
private List<QueueItemType> _Blocks = new List<QueueItemType>();
|
||||||
|
|
||||||
public QueueItemType ItemType => _ItemType;
|
public QueueItemType ItemType => _ItemType;
|
||||||
public QueueItemState ItemState => _ItemState;
|
public QueueItemState ItemState => _ItemState;
|
||||||
public DateTime LastRunTime => _LastRunTime;
|
public DateTime LastRunTime => _LastRunTime;
|
||||||
public DateTime LastFinishTime => _LastFinishTime;
|
public DateTime LastFinishTime => _LastFinishTime;
|
||||||
public DateTime NextRunTime {
|
public double LastRunDuration => _LastRunDuration;
|
||||||
|
public DateTime NextRunTime
|
||||||
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return LastRunTime.AddMinutes(Interval);
|
return LastRunTime.AddMinutes(Interval);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public int Interval => _Interval;
|
public int Interval
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _Interval;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_Interval = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
public string LastResult => _LastResult;
|
public string LastResult => _LastResult;
|
||||||
public string? LastError => _LastError;
|
public string? LastError => _LastError;
|
||||||
public bool Force => _ForceExecute;
|
public bool Force => _ForceExecute;
|
||||||
@@ -75,6 +91,9 @@ namespace gaseous_server
|
|||||||
public bool RemoveWhenStopped => _RemoveWhenStopped;
|
public bool RemoveWhenStopped => _RemoveWhenStopped;
|
||||||
public bool IsBlocked => _IsBlocked;
|
public bool IsBlocked => _IsBlocked;
|
||||||
public object? Options { get; set; } = null;
|
public object? Options { get; set; } = null;
|
||||||
|
public string CurrentState { get; set; } = "";
|
||||||
|
public string CurrentStateProgress { get; set; } = "";
|
||||||
|
public string CorrelationId => _CorrelationId;
|
||||||
public List<QueueItemType> Blocks => _Blocks;
|
public List<QueueItemType> Blocks => _Blocks;
|
||||||
|
|
||||||
public void Execute()
|
public void Execute()
|
||||||
@@ -89,7 +108,14 @@ namespace gaseous_server
|
|||||||
_LastResult = "";
|
_LastResult = "";
|
||||||
_LastError = null;
|
_LastError = null;
|
||||||
|
|
||||||
Logging.Log(Logging.LogType.Debug, "Timered Event", "Executing " + _ItemType);
|
// set the correlation id
|
||||||
|
Guid correlationId = Guid.NewGuid();
|
||||||
|
_CorrelationId = correlationId.ToString();
|
||||||
|
CallContext.SetData("CorrelationId", correlationId);
|
||||||
|
CallContext.SetData("CallingProcess", _ItemType.ToString());
|
||||||
|
|
||||||
|
// log the start
|
||||||
|
Logging.Log(Logging.LogType.Debug, "Timered Event", "Executing " + _ItemType + " with correlation id " + _CorrelationId);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -97,8 +123,11 @@ namespace gaseous_server
|
|||||||
{
|
{
|
||||||
case QueueItemType.SignatureIngestor:
|
case QueueItemType.SignatureIngestor:
|
||||||
Logging.Log(Logging.LogType.Debug, "Timered Event", "Starting Signature Ingestor");
|
Logging.Log(Logging.LogType.Debug, "Timered Event", "Starting Signature Ingestor");
|
||||||
SignatureIngestors.XML.XMLIngestor tIngest = new SignatureIngestors.XML.XMLIngestor();
|
SignatureIngestors.XML.XMLIngestor tIngest = new SignatureIngestors.XML.XMLIngestor
|
||||||
|
{
|
||||||
|
CallingQueueItem = this
|
||||||
|
};
|
||||||
|
|
||||||
Logging.Log(Logging.LogType.Debug, "Signature Import", "Processing TOSEC files");
|
Logging.Log(Logging.LogType.Debug, "Signature Import", "Processing TOSEC files");
|
||||||
tIngest.Import(Path.Combine(Config.LibraryConfiguration.LibrarySignatureImportDirectory, "TOSEC"), gaseous_signature_parser.parser.SignatureParser.TOSEC);
|
tIngest.Import(Path.Combine(Config.LibraryConfiguration.LibrarySignatureImportDirectory, "TOSEC"), gaseous_signature_parser.parser.SignatureParser.TOSEC);
|
||||||
|
|
||||||
@@ -114,7 +143,10 @@ namespace gaseous_server
|
|||||||
|
|
||||||
case QueueItemType.TitleIngestor:
|
case QueueItemType.TitleIngestor:
|
||||||
Logging.Log(Logging.LogType.Debug, "Timered Event", "Starting Title Ingestor");
|
Logging.Log(Logging.LogType.Debug, "Timered Event", "Starting Title Ingestor");
|
||||||
Classes.ImportGames importGames = new Classes.ImportGames(Config.LibraryConfiguration.LibraryImportDirectory);
|
Classes.ImportGames importGames = new Classes.ImportGames(Config.LibraryConfiguration.LibraryImportDirectory)
|
||||||
|
{
|
||||||
|
CallingQueueItem = this
|
||||||
|
};
|
||||||
|
|
||||||
Classes.ImportGame.DeleteOrphanedDirectories(Config.LibraryConfiguration.LibraryImportDirectory);
|
Classes.ImportGame.DeleteOrphanedDirectories(Config.LibraryConfiguration.LibraryImportDirectory);
|
||||||
|
|
||||||
@@ -124,7 +156,11 @@ namespace gaseous_server
|
|||||||
|
|
||||||
case QueueItemType.MetadataRefresh:
|
case QueueItemType.MetadataRefresh:
|
||||||
Logging.Log(Logging.LogType.Debug, "Timered Event", "Starting Metadata Refresher");
|
Logging.Log(Logging.LogType.Debug, "Timered Event", "Starting Metadata Refresher");
|
||||||
Classes.MetadataManagement.RefreshMetadata();
|
Classes.MetadataManagement metadataManagement = new MetadataManagement
|
||||||
|
{
|
||||||
|
CallingQueueItem = this
|
||||||
|
};
|
||||||
|
metadataManagement.RefreshMetadata(_ForceExecute);
|
||||||
|
|
||||||
_SaveLastRunTime = true;
|
_SaveLastRunTime = true;
|
||||||
|
|
||||||
@@ -140,7 +176,11 @@ namespace gaseous_server
|
|||||||
|
|
||||||
case QueueItemType.LibraryScan:
|
case QueueItemType.LibraryScan:
|
||||||
Logging.Log(Logging.LogType.Debug, "Timered Event", "Starting Library Scanner");
|
Logging.Log(Logging.LogType.Debug, "Timered Event", "Starting Library Scanner");
|
||||||
Classes.ImportGame.LibraryScan();
|
Classes.ImportGame import = new ImportGame
|
||||||
|
{
|
||||||
|
CallingQueueItem = this
|
||||||
|
};
|
||||||
|
import.LibraryScan();
|
||||||
|
|
||||||
_SaveLastRunTime = true;
|
_SaveLastRunTime = true;
|
||||||
|
|
||||||
@@ -148,7 +188,11 @@ namespace gaseous_server
|
|||||||
|
|
||||||
case QueueItemType.Rematcher:
|
case QueueItemType.Rematcher:
|
||||||
Logging.Log(Logging.LogType.Debug, "Timered Event", "Starting Rematch");
|
Logging.Log(Logging.LogType.Debug, "Timered Event", "Starting Rematch");
|
||||||
Classes.ImportGame.Rematcher(_ForceExecute);
|
Classes.ImportGame importRematch = new ImportGame
|
||||||
|
{
|
||||||
|
CallingQueueItem = this
|
||||||
|
};
|
||||||
|
importRematch.Rematcher(_ForceExecute);
|
||||||
|
|
||||||
_SaveLastRunTime = true;
|
_SaveLastRunTime = true;
|
||||||
|
|
||||||
@@ -171,7 +215,10 @@ namespace gaseous_server
|
|||||||
|
|
||||||
case QueueItemType.Maintainer:
|
case QueueItemType.Maintainer:
|
||||||
Logging.Log(Logging.LogType.Debug, "Timered Event", "Starting Maintenance");
|
Logging.Log(Logging.LogType.Debug, "Timered Event", "Starting Maintenance");
|
||||||
Classes.Maintenance.RunMaintenance();
|
Classes.Maintenance maintenance = new Maintenance{
|
||||||
|
CallingQueueItem = this
|
||||||
|
};
|
||||||
|
maintenance.RunMaintenance();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -186,8 +233,9 @@ namespace gaseous_server
|
|||||||
_ForceExecute = false;
|
_ForceExecute = false;
|
||||||
_ItemState = QueueItemState.Stopped;
|
_ItemState = QueueItemState.Stopped;
|
||||||
_LastFinishTime = DateTime.UtcNow;
|
_LastFinishTime = DateTime.UtcNow;
|
||||||
|
_LastRunDuration = Math.Round((DateTime.UtcNow - _LastRunTime).TotalSeconds, 2);
|
||||||
|
|
||||||
Logging.Log(Logging.LogType.Information, "Timered Event", "Total " + _ItemType + " run time = " + (DateTime.UtcNow - _LastRunTime).TotalSeconds);
|
Logging.Log(Logging.LogType.Information, "Timered Event", "Total " + _ItemType + " run time = " + _LastRunDuration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -201,6 +249,66 @@ namespace gaseous_server
|
|||||||
{
|
{
|
||||||
_IsBlocked = BlockState;
|
_IsBlocked = BlockState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public HasErrorsItem HasErrors
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return new HasErrorsItem(_CorrelationId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class HasErrorsItem
|
||||||
|
{
|
||||||
|
public HasErrorsItem(string? CorrelationId)
|
||||||
|
{
|
||||||
|
if (CorrelationId != null)
|
||||||
|
{
|
||||||
|
if (CorrelationId.Length > 0)
|
||||||
|
{
|
||||||
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
|
string sql = "SELECT EventType, COUNT(EventType) AS EventTypes FROM gaseous.ServerLogs WHERE CorrelationId = @correlationid GROUP BY EventType ORDER BY EventType DESC LIMIT 1;";
|
||||||
|
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||||
|
dbDict.Add("correlationid", CorrelationId);
|
||||||
|
|
||||||
|
DataTable data = db.ExecuteCMD(sql, dbDict);
|
||||||
|
|
||||||
|
if (data.Rows.Count == 0)
|
||||||
|
{
|
||||||
|
ErrorType = null;
|
||||||
|
ErrorCount = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Logging.LogType errorType = (Logging.LogType)data.Rows[0]["EventType"];
|
||||||
|
if (errorType != Logging.LogType.Information)
|
||||||
|
{
|
||||||
|
ErrorType = errorType;
|
||||||
|
ErrorCount = (int)(long)data.Rows[0]["EventTypes"];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ErrorType = null;
|
||||||
|
ErrorCount = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ErrorType = null;
|
||||||
|
ErrorCount = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ErrorType = null;
|
||||||
|
ErrorCount = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Logging.LogType? ErrorType { get; set; }
|
||||||
|
public int ErrorCount { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum QueueItemType
|
public enum QueueItemType
|
||||||
|
@@ -13,6 +13,8 @@ using Microsoft.OpenApi.Models;
|
|||||||
using Authentication;
|
using Authentication;
|
||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
using Microsoft.AspNetCore.Identity.UI.Services;
|
using Microsoft.AspNetCore.Identity.UI.Services;
|
||||||
|
using IGDB.Models;
|
||||||
|
using gaseous_server.Classes.Metadata;
|
||||||
|
|
||||||
Logging.WriteToDiskOnly = true;
|
Logging.WriteToDiskOnly = true;
|
||||||
Logging.Log(Logging.LogType.Information, "Startup", "Starting Gaseous Server " + Assembly.GetExecutingAssembly().GetName().Version);
|
Logging.Log(Logging.LogType.Information, "Startup", "Starting Gaseous Server " + Assembly.GetExecutingAssembly().GetName().Version);
|
||||||
@@ -39,11 +41,17 @@ db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.Conn
|
|||||||
// set up db
|
// set up db
|
||||||
db.InitDB();
|
db.InitDB();
|
||||||
|
|
||||||
|
// populate db with static data for lookups
|
||||||
|
AgeRatings.PopulateAgeMap();
|
||||||
|
|
||||||
// load app settings
|
// load app settings
|
||||||
Config.InitSettings();
|
Config.InitSettings();
|
||||||
// write updated settings back to the config file
|
// write updated settings back to the config file
|
||||||
Config.UpdateConfig();
|
Config.UpdateConfig();
|
||||||
|
|
||||||
|
// set api metadata source from config
|
||||||
|
Communications.MetadataSource = Config.MetadataConfiguration.Source;
|
||||||
|
|
||||||
// set initial values
|
// set initial values
|
||||||
Guid APIKey = Guid.NewGuid();
|
Guid APIKey = Guid.NewGuid();
|
||||||
if (Config.ReadSetting("API Key", "Test API Key") == "Test API Key")
|
if (Config.ReadSetting("API Key", "Test API Key") == "Test API Key")
|
||||||
@@ -287,29 +295,22 @@ using (var scope = app.Services.CreateScope())
|
|||||||
await roleManager.CreateAsync(applicationRole, CancellationToken.None);
|
await roleManager.CreateAsync(applicationRole, CancellationToken.None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// // set up administrator account
|
|
||||||
// var userManager = scope.ServiceProvider.GetRequiredService<UserStore>();
|
|
||||||
// if (await userManager.FindByNameAsync("admin@localhost", CancellationToken.None) == null)
|
|
||||||
// {
|
|
||||||
// ApplicationUser adminUser = new ApplicationUser{
|
|
||||||
// Id = Guid.NewGuid().ToString(),
|
|
||||||
// Email = "admin@localhost",
|
|
||||||
// NormalizedEmail = "ADMIN@LOCALHOST",
|
|
||||||
// EmailConfirmed = true,
|
|
||||||
// UserName = "administrator",
|
|
||||||
// NormalizedUserName = "ADMINISTRATOR"
|
|
||||||
// };
|
|
||||||
|
|
||||||
// //set user password
|
|
||||||
// PasswordHasher<ApplicationUser> ph = new PasswordHasher<ApplicationUser>();
|
|
||||||
// adminUser.PasswordHash = ph.HashPassword(adminUser, "letmein");
|
|
||||||
|
|
||||||
// await userManager.CreateAsync(adminUser, CancellationToken.None);
|
|
||||||
// await userManager.AddToRoleAsync(adminUser, "Admin", CancellationToken.None);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
app.Use(async (context, next) =>
|
||||||
|
{
|
||||||
|
// set the correlation id
|
||||||
|
string correlationId = Guid.NewGuid().ToString();
|
||||||
|
CallContext.SetData("CorrelationId", correlationId);
|
||||||
|
CallContext.SetData("CallingProcess", context.Request.Method + ": " + context.Request.Path);
|
||||||
|
|
||||||
|
context.Response.Headers.Add("x-correlation-id", correlationId.ToString());
|
||||||
|
await next();
|
||||||
|
});
|
||||||
|
|
||||||
app.UseAuthorization();
|
app.UseAuthorization();
|
||||||
|
|
||||||
app.UseDefaultFiles();
|
app.UseDefaultFiles();
|
||||||
@@ -392,20 +393,25 @@ Config.LibraryConfiguration.InitLibrary();
|
|||||||
|
|
||||||
// insert unknown platform and game if not present
|
// insert unknown platform and game if not present
|
||||||
gaseous_server.Classes.Metadata.Games.GetGame(0, false, false, false);
|
gaseous_server.Classes.Metadata.Games.GetGame(0, false, false, false);
|
||||||
|
gaseous_server.Classes.Metadata.Games.AssignAllGamesToPlatformIdZero();
|
||||||
gaseous_server.Classes.Metadata.Platforms.GetPlatform(0);
|
gaseous_server.Classes.Metadata.Platforms.GetPlatform(0);
|
||||||
|
gaseous_server.Classes.Metadata.Platforms.AssignAllPlatformsToGameIdZero();
|
||||||
|
|
||||||
// extract platform map if not present
|
// extract platform map if not present
|
||||||
PlatformMapping.ExtractPlatformMap();
|
PlatformMapping.ExtractPlatformMap();
|
||||||
|
|
||||||
|
// force load platform map into cache
|
||||||
|
var platformMap = PlatformMapping.PlatformMap;
|
||||||
|
|
||||||
// add background tasks
|
// add background tasks
|
||||||
ProcessQueue.QueueItems.Add(new ProcessQueue.QueueItem(
|
ProcessQueue.QueueItems.Add(new ProcessQueue.QueueItem(
|
||||||
ProcessQueue.QueueItemType.SignatureIngestor,
|
ProcessQueue.QueueItemType.SignatureIngestor,
|
||||||
60
|
int.Parse(Config.ReadSetting("Interval_SignatureIngestor", "60"))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
ProcessQueue.QueueItems.Add(new ProcessQueue.QueueItem(
|
ProcessQueue.QueueItems.Add(new ProcessQueue.QueueItem(
|
||||||
ProcessQueue.QueueItemType.TitleIngestor,
|
ProcessQueue.QueueItemType.TitleIngestor,
|
||||||
1,
|
int.Parse(Config.ReadSetting("Interval_TitleIngestor", "1")),
|
||||||
new List<ProcessQueue.QueueItemType>
|
new List<ProcessQueue.QueueItemType>
|
||||||
{
|
{
|
||||||
ProcessQueue.QueueItemType.OrganiseLibrary,
|
ProcessQueue.QueueItemType.OrganiseLibrary,
|
||||||
@@ -414,12 +420,12 @@ ProcessQueue.QueueItems.Add(new ProcessQueue.QueueItem(
|
|||||||
);
|
);
|
||||||
ProcessQueue.QueueItems.Add(new ProcessQueue.QueueItem(
|
ProcessQueue.QueueItems.Add(new ProcessQueue.QueueItem(
|
||||||
ProcessQueue.QueueItemType.MetadataRefresh,
|
ProcessQueue.QueueItemType.MetadataRefresh,
|
||||||
360
|
int.Parse(Config.ReadSetting("Interval_MetadataRefresh", "360"))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
ProcessQueue.QueueItems.Add(new ProcessQueue.QueueItem(
|
ProcessQueue.QueueItems.Add(new ProcessQueue.QueueItem(
|
||||||
ProcessQueue.QueueItemType.OrganiseLibrary,
|
ProcessQueue.QueueItemType.OrganiseLibrary,
|
||||||
1440,
|
int.Parse(Config.ReadSetting("Interval_OrganiseLibrary", "1440")),
|
||||||
new List<ProcessQueue.QueueItemType>
|
new List<ProcessQueue.QueueItemType>
|
||||||
{
|
{
|
||||||
ProcessQueue.QueueItemType.LibraryScan,
|
ProcessQueue.QueueItemType.LibraryScan,
|
||||||
@@ -429,7 +435,7 @@ ProcessQueue.QueueItems.Add(new ProcessQueue.QueueItem(
|
|||||||
);
|
);
|
||||||
ProcessQueue.QueueItems.Add(new ProcessQueue.QueueItem(
|
ProcessQueue.QueueItems.Add(new ProcessQueue.QueueItem(
|
||||||
ProcessQueue.QueueItemType.LibraryScan,
|
ProcessQueue.QueueItemType.LibraryScan,
|
||||||
60,
|
int.Parse(Config.ReadSetting("Interval_LibraryScan", "1440")),
|
||||||
new List<ProcessQueue.QueueItemType>
|
new List<ProcessQueue.QueueItemType>
|
||||||
{
|
{
|
||||||
ProcessQueue.QueueItemType.OrganiseLibrary,
|
ProcessQueue.QueueItemType.OrganiseLibrary,
|
||||||
@@ -438,7 +444,7 @@ ProcessQueue.QueueItems.Add(new ProcessQueue.QueueItem(
|
|||||||
);
|
);
|
||||||
ProcessQueue.QueueItems.Add(new ProcessQueue.QueueItem(
|
ProcessQueue.QueueItems.Add(new ProcessQueue.QueueItem(
|
||||||
ProcessQueue.QueueItemType.Rematcher,
|
ProcessQueue.QueueItemType.Rematcher,
|
||||||
1440,
|
int.Parse(Config.ReadSetting("Interval_Rematcher", "1440")),
|
||||||
new List<ProcessQueue.QueueItemType>
|
new List<ProcessQueue.QueueItemType>
|
||||||
{
|
{
|
||||||
ProcessQueue.QueueItemType.OrganiseLibrary,
|
ProcessQueue.QueueItemType.OrganiseLibrary,
|
||||||
@@ -447,7 +453,7 @@ ProcessQueue.QueueItems.Add(new ProcessQueue.QueueItem(
|
|||||||
);
|
);
|
||||||
ProcessQueue.QueueItems.Add(new ProcessQueue.QueueItem(
|
ProcessQueue.QueueItems.Add(new ProcessQueue.QueueItem(
|
||||||
ProcessQueue.QueueItemType.Maintainer,
|
ProcessQueue.QueueItemType.Maintainer,
|
||||||
10080,
|
int.Parse(Config.ReadSetting("Interval_Maintainer", "10080")),
|
||||||
new List<ProcessQueue.QueueItemType>
|
new List<ProcessQueue.QueueItemType>
|
||||||
{
|
{
|
||||||
ProcessQueue.QueueItemType.All
|
ProcessQueue.QueueItemType.All
|
||||||
|
2
gaseous-server/Support/Database/MySQL/gaseous-1006.sql
Normal file
2
gaseous-server/Support/Database/MySQL/gaseous-1006.sql
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
ALTER TABLE `Signatures_Roms`
|
||||||
|
ADD INDEX `name_Idx` USING BTREE (`Name`) VISIBLE;
|
76
gaseous-server/Support/Database/MySQL/gaseous-1007.sql
Normal file
76
gaseous-server/Support/Database/MySQL/gaseous-1007.sql
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
CREATE TABLE `ClassificationMap` (
|
||||||
|
`AgeGroupId` INT NOT NULL,
|
||||||
|
`ClassificationBoardId` INT NOT NULL,
|
||||||
|
`RatingId` INT NOT NULL,
|
||||||
|
PRIMARY KEY (`AgeGroupId`, `ClassificationBoardId`, `RatingId`));
|
||||||
|
|
||||||
|
CREATE OR REPLACE VIEW `view_GamesWithRoms` AS
|
||||||
|
SELECT DISTINCT
|
||||||
|
Games_Roms.GameId AS ROMGameId,
|
||||||
|
Game.*,
|
||||||
|
CASE
|
||||||
|
WHEN
|
||||||
|
Game.`Name` LIKE 'The %'
|
||||||
|
THEN
|
||||||
|
CONCAT(TRIM(SUBSTR(Game.`Name` FROM 4)),
|
||||||
|
', The')
|
||||||
|
ELSE Game.`Name`
|
||||||
|
END AS NameThe
|
||||||
|
FROM
|
||||||
|
Games_Roms
|
||||||
|
LEFT JOIN
|
||||||
|
Game ON Game.Id = Games_Roms.GameId;
|
||||||
|
|
||||||
|
CREATE OR REPLACE VIEW `view_Games` AS
|
||||||
|
SELECT
|
||||||
|
*
|
||||||
|
FROM
|
||||||
|
(SELECT DISTINCT
|
||||||
|
row_number() over (partition by Id order by AgeGroupId desc) as seqnum, view_GamesWithRoms.*,
|
||||||
|
(SELECT
|
||||||
|
AgeGroupId
|
||||||
|
FROM
|
||||||
|
ClassificationMap
|
||||||
|
WHERE
|
||||||
|
RatingId = AgeRating.Rating
|
||||||
|
ORDER BY AgeGroupId DESC) AgeGroupId
|
||||||
|
FROM
|
||||||
|
view_GamesWithRoms
|
||||||
|
LEFT JOIN Relation_Game_AgeRatings ON view_GamesWithRoms.Id = Relation_Game_AgeRatings.GameId
|
||||||
|
LEFT JOIN AgeRating ON Relation_Game_AgeRatings.AgeRatingsId = AgeRating.Id
|
||||||
|
) g
|
||||||
|
WHERE g.seqnum = 1;
|
||||||
|
|
||||||
|
CREATE TABLE `ReleaseDate` (
|
||||||
|
`Id` BIGINT NOT NULL,
|
||||||
|
`Category` INT(11) NULL DEFAULT NULL,
|
||||||
|
`Checksum` VARCHAR(45) NULL DEFAULT NULL,
|
||||||
|
`CreatedAt` DATETIME NULL DEFAULT NULL,
|
||||||
|
`Date` DATETIME NULL,
|
||||||
|
`Game` BIGINT NULL,
|
||||||
|
`Human` VARCHAR(100) NULL,
|
||||||
|
`m` INT NULL,
|
||||||
|
`Platform` BIGINT NULL,
|
||||||
|
`Region` INT NULL,
|
||||||
|
`Status` BIGINT NULL,
|
||||||
|
`UpdatedAt` DATETIME NULL DEFAULT NULL,
|
||||||
|
`y` INT NULL,
|
||||||
|
`dateAdded` DATETIME NULL DEFAULT NULL,
|
||||||
|
`lastUpdated` DATETIME NULL DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`Id`));
|
||||||
|
|
||||||
|
CREATE TABLE `User_Settings` (
|
||||||
|
`Id` VARCHAR(128) NOT NULL,
|
||||||
|
`Setting` VARCHAR(45) NOT NULL,
|
||||||
|
`Value` LONGTEXT NULL DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`Id`, `Setting`));
|
||||||
|
|
||||||
|
ALTER TABLE `ServerLogs`
|
||||||
|
ADD FULLTEXT INDEX `ft_message` (`Message`) VISIBLE;
|
||||||
|
|
||||||
|
CREATE TABLE `Relation_Game_Platforms` (
|
||||||
|
`GameId` BIGINT NOT NULL,
|
||||||
|
`PlatformsId` BIGINT NOT NULL,
|
||||||
|
PRIMARY KEY (`GameId`, `PlatformsId`),
|
||||||
|
INDEX `idx_PrimaryColumn` (`GameId` ASC) VISIBLE
|
||||||
|
);
|
26
gaseous-server/Support/Database/MySQL/gaseous-1008.sql
Normal file
26
gaseous-server/Support/Database/MySQL/gaseous-1008.sql
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
ALTER TABLE `ClassificationMap`
|
||||||
|
ADD INDEX `idx_RatingId` (`RatingId` ASC) VISIBLE;
|
||||||
|
|
||||||
|
ALTER TABLE `Relation_Game_AgeRatings`
|
||||||
|
ADD INDEX `idx_SecondaryColumn` (`AgeRatingsId` ASC) VISIBLE;
|
||||||
|
|
||||||
|
ALTER TABLE `Relation_Game_GameModes`
|
||||||
|
ADD INDEX `idx_SecondaryColumn` (`GameModesId` ASC) VISIBLE;
|
||||||
|
|
||||||
|
ALTER TABLE `Relation_Game_Genres`
|
||||||
|
ADD INDEX `idx_SecondaryColumn` (`GenresId` ASC) VISIBLE;
|
||||||
|
|
||||||
|
ALTER TABLE `Relation_Game_Platforms`
|
||||||
|
ADD INDEX `idx_SecondaryColumn` (`PlatformsId` ASC) VISIBLE;
|
||||||
|
|
||||||
|
ALTER TABLE `Relation_Game_PlayerPerspectives`
|
||||||
|
ADD INDEX `idx_SecondaryColumn` (`PlayerPerspectivesId` ASC) VISIBLE;
|
||||||
|
|
||||||
|
ALTER TABLE `Relation_Game_Themes`
|
||||||
|
ADD INDEX `idx_SecondaryColumn` (`ThemesId` ASC) VISIBLE;
|
||||||
|
|
||||||
|
ALTER TABLE `ServerLogs`
|
||||||
|
ADD COLUMN `CorrelationId` VARCHAR(45) NULL AFTER `Exception`,
|
||||||
|
ADD COLUMN `CallingProcess` VARCHAR(255) NULL AFTER `CorrelationId`,
|
||||||
|
ADD INDEX `idx_CorrelationId` (`CorrelationId` ASC) VISIBLE,
|
||||||
|
ADD INDEX `idx_CallingProcess` (`CallingProcess` ASC) VISIBLE;
|
4
gaseous-server/Support/Database/MySQL/gaseous-1009.sql
Normal file
4
gaseous-server/Support/Database/MySQL/gaseous-1009.sql
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
ALTER TABLE `Games_Roms`
|
||||||
|
ADD INDEX `id_LibraryId` (`LibraryId` ASC) VISIBLE,
|
||||||
|
ADD INDEX `id_MD5` USING BTREE (`MD5`) VISIBLE;
|
||||||
|
|
@@ -46,6 +46,10 @@
|
|||||||
<None Remove="Support\Database\MySQL\gaseous-1003.sql" />
|
<None Remove="Support\Database\MySQL\gaseous-1003.sql" />
|
||||||
<None Remove="Support\Database\MySQL\gaseous-1004.sql" />
|
<None Remove="Support\Database\MySQL\gaseous-1004.sql" />
|
||||||
<None Remove="Support\Database\MySQL\gaseous-1005.sql" />
|
<None Remove="Support\Database\MySQL\gaseous-1005.sql" />
|
||||||
|
<None Remove="Support\Database\MySQL\gaseous-1006.sql" />
|
||||||
|
<None Remove="Support\Database\MySQL\gaseous-1007.sql" />
|
||||||
|
<None Remove="Support\Database\MySQL\gaseous-1008.sql" />
|
||||||
|
<None Remove="Support\Database\MySQL\gaseous-1009.sql" />
|
||||||
<None Remove="Classes\Metadata\" />
|
<None Remove="Classes\Metadata\" />
|
||||||
<None Remove="Assets\" />
|
<None Remove="Assets\" />
|
||||||
<None Remove="Assets\Ratings\" />
|
<None Remove="Assets\Ratings\" />
|
||||||
@@ -174,5 +178,9 @@
|
|||||||
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1003.sql" />
|
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1003.sql" />
|
||||||
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1004.sql" />
|
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1004.sql" />
|
||||||
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1005.sql" />
|
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1005.sql" />
|
||||||
|
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1006.sql" />
|
||||||
|
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1007.sql" />
|
||||||
|
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1008.sql" />
|
||||||
|
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1009.sql" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
BIN
gaseous-server/wwwroot/.DS_Store
vendored
BIN
gaseous-server/wwwroot/.DS_Store
vendored
Binary file not shown.
@@ -3,9 +3,9 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<script src="/api/v1.1/System/VersionFile"></script>
|
<script src="/api/v1.1/System/VersionFile"></script>
|
||||||
<link type="text/css" rel="stylesheet" dat-href="/styles/style.css" />
|
<link type="text/css" rel="stylesheet" href="/styles/style.css" dat-href="/styles/style.css" />
|
||||||
<script src="/scripts/jquery-3.6.0.min.js"></script>
|
<script src="/scripts/jquery-3.6.0.min.js"></script>
|
||||||
<script src="/scripts/moment.js"></script>
|
<script src="/scripts/moment-with-locales.min.js"></script>
|
||||||
<link href="/styles/select2.min.css" rel="stylesheet" />
|
<link href="/styles/select2.min.css" rel="stylesheet" />
|
||||||
<link href="/styles/dropzone.min.css" rel="stylesheet" type="text/css" />
|
<link href="/styles/dropzone.min.css" rel="stylesheet" type="text/css" />
|
||||||
<script src="/scripts/jquery.lazy.min.js"></script>
|
<script src="/scripts/jquery.lazy.min.js"></script>
|
||||||
|
@@ -27,6 +27,9 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td colspan="2" id="settings_users_edit_label"></td>
|
<td colspan="2" id="settings_users_edit_label"></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2" id="settings_users_edit_errorlabel" style="color: red;"></td>
|
||||||
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -339,6 +342,7 @@
|
|||||||
var newPassword = document.getElementById('settings_users_edit_password').value;
|
var newPassword = document.getElementById('settings_users_edit_password').value;
|
||||||
|
|
||||||
if (newPassword.length > 0) {
|
if (newPassword.length > 0) {
|
||||||
|
console.log("New password value is long enough to commit to database");
|
||||||
var model = {
|
var model = {
|
||||||
"newPassword": newPassword,
|
"newPassword": newPassword,
|
||||||
"confirmPassword": newPassword
|
"confirmPassword": newPassword
|
||||||
@@ -348,12 +352,10 @@
|
|||||||
'/api/v1.1/Account/Users/' + modalVariables + '/Password',
|
'/api/v1.1/Account/Users/' + modalVariables + '/Password',
|
||||||
'POST',
|
'POST',
|
||||||
function(result) {
|
function(result) {
|
||||||
console.log(JSON.stringify(result));
|
savePasswordsCallback(result);
|
||||||
savePropertiesCallback();
|
|
||||||
},
|
},
|
||||||
function(error) {
|
function(error) {
|
||||||
console.log(JSON.stringify(error));
|
savePasswordsCallback(error);
|
||||||
savePropertiesCallback();
|
|
||||||
},
|
},
|
||||||
JSON.stringify(model)
|
JSON.stringify(model)
|
||||||
);
|
);
|
||||||
@@ -366,6 +368,21 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function savePasswordsCallback(result) {
|
||||||
|
console.log(result);
|
||||||
|
if (result.succeeded == true) {
|
||||||
|
savePropertiesCallback();
|
||||||
|
} else {
|
||||||
|
var errorBox = document.getElementById('settings_users_edit_errorlabel');
|
||||||
|
errorBox.innerHTML = '';
|
||||||
|
for (var i = 0; i < result.errors.length; i++) {
|
||||||
|
var errorMessage = document.createElement('p');
|
||||||
|
errorMessage.innerHTML = result.errors[i].description;
|
||||||
|
errorBox.appendChild(errorMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function savePropertiesCallback() {
|
function savePropertiesCallback() {
|
||||||
GetUsers();
|
GetUsers();
|
||||||
closeDialog();
|
closeDialog();
|
||||||
|
@@ -28,6 +28,9 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td colspan="2" id="settings_users_new_label"></td>
|
<td colspan="2" id="settings_users_new_label"></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2" id="settings_users_new_errors" style="color: red;"></td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="2" style="text-align: right; padding-top: 10px;">
|
<td colspan="2" style="text-align: right; padding-top: 10px;">
|
||||||
<button value="OK" id="settings_users_new_okbutton" disabled="disabled" onclick="createUser();">OK</button><button value="Cancel" onclick="closeSubDialog();">Cancel</button>
|
<button value="OK" id="settings_users_new_okbutton" disabled="disabled" onclick="createUser();">OK</button><button value="Cancel" onclick="closeSubDialog();">Cancel</button>
|
||||||
@@ -75,14 +78,27 @@
|
|||||||
'/api/v1.1/Account/Users',
|
'/api/v1.1/Account/Users',
|
||||||
'POST',
|
'POST',
|
||||||
function(result) {
|
function(result) {
|
||||||
GetUsers();
|
createUserCallback(result);
|
||||||
closeSubDialog();
|
|
||||||
},
|
},
|
||||||
function(error) {
|
function(error) {
|
||||||
GetUsers();
|
createUserCallback(result);
|
||||||
closeSubDialog();
|
|
||||||
},
|
},
|
||||||
JSON.stringify(model)
|
JSON.stringify(model)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createUserCallback(result) {
|
||||||
|
if (result.succeeded == true) {
|
||||||
|
GetUsers();
|
||||||
|
closeSubDialog();
|
||||||
|
} else {
|
||||||
|
var errorBox = document.getElementById('settings_users_new_errors');
|
||||||
|
errorBox.innerHTML = '';
|
||||||
|
for (var i = 0; i < result.errors.length; i++) {
|
||||||
|
var errorMessage = document.createElement('p');
|
||||||
|
errorMessage.innerHTML = result.errors[i].description;
|
||||||
|
errorBox.appendChild(errorMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
@@ -1,8 +1,79 @@
|
|||||||
<div id="properties_toc">
|
<div id="properties_toc">
|
||||||
<div id="properties_profile_toc_general" name="properties_profile_toc_item" onclick="ProfileSelectTab('general');">Account</div>
|
<div id="properties_profile_toc_general" name="properties_profile_toc_item" onclick="ProfileSelectTab('general');">Preferences</div>
|
||||||
|
<div id="properties_profile_toc_account" name="properties_profile_toc_item" onclick="ProfileSelectTab('account');">Account</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="properties_bodypanel">
|
<div id="properties_bodypanel">
|
||||||
<div id="properties_bodypanel_general" name="properties_profile_tab" style="display: none;">
|
<div id="properties_bodypanel_general" name="properties_profile_tab" style="display: none;">
|
||||||
|
<h3>Game Library</h3>
|
||||||
|
<table style="width: 100%;">
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
Library
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
Pagination mode:
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<select id="profile_pref-LibraryPagination" data-pref="LibraryPagination" onchange="SavePrefValue_Value(this);">
|
||||||
|
<option value="paged">Paged</option>
|
||||||
|
<option value="infinite">Infinite scrolling</option>
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
Game Icons
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<input type="checkbox" id="profile_pref_LibraryShowGameTitle" data-pref="LibraryShowGameTitle" onchange="SavePrefValue_Checkbox(this);"><label for="profile_pref_LibraryShowGameTitle"> Show title</label>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<input type="checkbox" id="profile_pref_LibraryShowGameRating" data-pref="LibraryShowGameRating" onchange="SavePrefValue_Checkbox(this);"><label for="profile_pref_LibraryShowGameRating"> Show rating</label>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<input type="checkbox" id="profile_pref_LibraryShowGameClassification" data-pref="LibraryShowGameClassification" onchange="SavePrefValue_Checkbox(this);"><label for="profile_pref_LibraryShowGameClassification"> Show age classification badges</label>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<table id="profile_pref_LibraryClassificationBadgeSelect">
|
||||||
|
<tr>
|
||||||
|
<td>Use classification badges from:</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<select id="profile_pref_LibraryPrimaryClassificationBadge" data-primary="primary" onchange="SavePrefValue_ClassBadge(this);">
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Fallback to classification badges from:</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<select id="profile_pref_LibraryFallbackClassificationBadge" onchange="SavePrefValue_ClassBadge(this);">
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div id="properties_bodypanel_account" name="properties_profile_tab" style="display: none;">
|
||||||
<h3>Reset Password</h3>
|
<h3>Reset Password</h3>
|
||||||
<table style="width: 100%;">
|
<table style="width: 100%;">
|
||||||
<tr>
|
<tr>
|
||||||
@@ -20,6 +91,9 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td colspan="2" id="profile_passwordnotice"></td>
|
<td colspan="2" id="profile_passwordnotice"></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2" id="profile_passworderrors" style="color: red;"></td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="2" style="text-align: right;">
|
<td colspan="2" style="text-align: right;">
|
||||||
<button id="profile_resetpassword" value="Reset Password" disabled="disabled" onclick="ResetPassword();">Reset Password</button>
|
<button id="profile_resetpassword" value="Reset Password" disabled="disabled" onclick="ResetPassword();">Reset Password</button>
|
||||||
@@ -52,6 +126,125 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function GetPrefInitialValues() {
|
||||||
|
var paginationMode = document.getElementById('profile_pref-LibraryPagination');
|
||||||
|
paginationMode.value = GetPreference('LibraryPagination', 'paged');
|
||||||
|
|
||||||
|
ConfigurePrefInitialValue_Checkbox("LibraryShowGameTitle", GetPreference("LibraryShowGameTitle", true));
|
||||||
|
ConfigurePrefInitialValue_Checkbox("LibraryShowGameRating", GetPreference("LibraryShowGameRating", true));
|
||||||
|
ConfigurePrefInitialValue_Checkbox("LibraryShowGameClassification", GetPreference("LibraryShowGameClassification", true));
|
||||||
|
|
||||||
|
var primary = document.getElementById('profile_pref_LibraryPrimaryClassificationBadge');
|
||||||
|
var secondary = document.getElementById('profile_pref_LibraryFallbackClassificationBadge');
|
||||||
|
PopulateClassificationMenus(primary);
|
||||||
|
PopulateClassificationMenus(secondary, true);
|
||||||
|
|
||||||
|
var classificationOrder = JSON.parse(GetPreference("LibraryGameClassificationDisplayOrder", JSON.stringify([ "ESRB" ])));
|
||||||
|
primary.value = classificationOrder[0];
|
||||||
|
if (classificationOrder[1]) {
|
||||||
|
secondary.value = classificationOrder[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < secondary.childNodes.length; i++) {
|
||||||
|
if (secondary.childNodes[i].value == primary.value) {
|
||||||
|
secondary.childNodes[i].setAttribute('disabled', 'disabled');
|
||||||
|
} else {
|
||||||
|
secondary.childNodes[i].removeAttribute('disabled');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function PopulateClassificationMenus(targetSelector, IsSecondary) {
|
||||||
|
targetSelector.innerHTML = '';
|
||||||
|
|
||||||
|
if (IsSecondary == true) {
|
||||||
|
var defaultOpt = document.createElement('option');
|
||||||
|
defaultOpt.value = '-';
|
||||||
|
defaultOpt.innerHTML = 'None';
|
||||||
|
targetSelector.appendChild(defaultOpt);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [key, value] of Object.entries(ClassificationBoards)) {
|
||||||
|
var opt = document.createElement('option');
|
||||||
|
opt.value = key;
|
||||||
|
opt.innerHTML = value;
|
||||||
|
targetSelector.appendChild(opt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function ConfigurePrefInitialValue_Checkbox(ValueName, ValueSetting) {
|
||||||
|
var valueCheckbox = document.getElementById("profile_pref_" + ValueName);
|
||||||
|
if (ValueSetting == "true" || ValueSetting == true) {
|
||||||
|
valueCheckbox.checked = true;
|
||||||
|
updateDisplay(ValueName, true);
|
||||||
|
} else {
|
||||||
|
valueCheckbox.checked = false;
|
||||||
|
updateDisplay(ValueName, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function SavePrefValue_Checkbox(e) {
|
||||||
|
var ValueName = e.getAttribute("data-pref");
|
||||||
|
SetPreference(ValueName, e.checked);
|
||||||
|
|
||||||
|
updateDisplay(ValueName, e.checked);
|
||||||
|
|
||||||
|
executeFilter1_1(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
function SavePrefValue_Value(e) {
|
||||||
|
var ValueName = e.getAttribute("data-pref");
|
||||||
|
SetPreference(ValueName, e.value);
|
||||||
|
|
||||||
|
executeFilter1_1(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateDisplay(ValueName, ValueSetting) {
|
||||||
|
switch(ValueName) {
|
||||||
|
case "LibraryShowGameClassification":
|
||||||
|
var badgeSelector = document.getElementById("profile_pref_LibraryClassificationBadgeSelect");
|
||||||
|
if (ValueSetting == true || ValueSetting == "true") {
|
||||||
|
badgeSelector.style.display = '';
|
||||||
|
} else {
|
||||||
|
badgeSelector.style.display = 'none';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function SavePrefValue_ClassBadge(e) {
|
||||||
|
var primary = document.getElementById('profile_pref_LibraryPrimaryClassificationBadge');
|
||||||
|
var secondary = document.getElementById('profile_pref_LibraryFallbackClassificationBadge');
|
||||||
|
|
||||||
|
if (e.getAttribute('data-primary') == 'primary') {
|
||||||
|
// reset secondary to "none" if the same board is selected in both
|
||||||
|
if (primary.value == secondary.value) {
|
||||||
|
secondary.value = '-';
|
||||||
|
}
|
||||||
|
|
||||||
|
// disable in secondary board selected in primary
|
||||||
|
for (var i = 0; i < secondary.childNodes.length; i++) {
|
||||||
|
if (secondary.childNodes[i].value == primary.value) {
|
||||||
|
secondary.childNodes[i].setAttribute('disabled', 'disabled');
|
||||||
|
} else {
|
||||||
|
secondary.childNodes[i].removeAttribute('disabled');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// save values
|
||||||
|
var model = [];
|
||||||
|
if (secondary.value == '-') {
|
||||||
|
model = [ primary.value ];
|
||||||
|
} else {
|
||||||
|
model = [ primary.value, secondary.value ];
|
||||||
|
}
|
||||||
|
|
||||||
|
SetPreference('LibraryGameClassificationDisplayOrder', JSON.stringify(model));
|
||||||
|
|
||||||
|
executeFilter1_1(1);
|
||||||
|
}
|
||||||
|
|
||||||
function checkPasswordsMatch() {
|
function checkPasswordsMatch() {
|
||||||
var oldPassword = document.getElementById('profile_oldpassword').value;
|
var oldPassword = document.getElementById('profile_oldpassword').value;
|
||||||
var newPassword = document.getElementById('profile_newpassword').value;
|
var newPassword = document.getElementById('profile_newpassword').value;
|
||||||
@@ -106,9 +299,16 @@
|
|||||||
|
|
||||||
function ResetPasswordCallback(result) {
|
function ResetPasswordCallback(result) {
|
||||||
var errorLabel = document.getElementById('profile_passwordnotice');
|
var errorLabel = document.getElementById('profile_passwordnotice');
|
||||||
|
var errorBox = document.getElementById('profile_passworderrors');
|
||||||
|
errorBox.innerHTML = '';
|
||||||
|
|
||||||
if (result.succeeded == false) {
|
console.log(result);
|
||||||
errorLabel.innerHTML = result.errors.description;
|
if (result.responseJSON.succeeded == false) {
|
||||||
|
for (var i = 0; i < result.responseJSON.errors.length; i++) {
|
||||||
|
var errorMessage = document.createElement('p');
|
||||||
|
errorMessage.innerHTML = result.responseJSON.errors[i].description;
|
||||||
|
errorBox.appendChild(errorMessage);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
document.getElementById('profile_oldpassword').value = '';
|
document.getElementById('profile_oldpassword').value = '';
|
||||||
document.getElementById('profile_newpassword').value = '';
|
document.getElementById('profile_newpassword').value = '';
|
||||||
@@ -119,4 +319,5 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
ProfileSelectTab('general');
|
ProfileSelectTab('general');
|
||||||
|
GetPrefInitialValues();
|
||||||
</script>
|
</script>
|
||||||
|
@@ -63,7 +63,7 @@
|
|||||||
|
|
||||||
<table style="width: 100%; margin-top: 20px;" cellpadding="5px">
|
<table style="width: 100%; margin-top: 20px;" cellpadding="5px">
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="2" style="font-size: 18px;">Create your account.</td>
|
<td colspan="2" style="font-size: 18px;">Create your administrator account.</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Email</th>
|
<th>Email</th>
|
||||||
@@ -80,6 +80,9 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td colspan="2" id="login_passwordnotice"> </td>
|
<td colspan="2" id="login_passwordnotice"> </td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2" id="login_passworderrors" style="color: red;"></td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="2" style="padding-top: 20px;">
|
<td colspan="2" style="padding-top: 20px;">
|
||||||
<button id="login_createaccount" type="button" value="Create Account" onclick="registerAccount();" disabled="disabled" style="margin-top: 10px; width: 100%; font-size: 16px; border-radius: 10px; padding-top: 10px; padding-bottom: 10px;">Create Account</button>
|
<button id="login_createaccount" type="button" value="Create Account" onclick="registerAccount();" disabled="disabled" style="margin-top: 10px; width: 100%; font-size: 16px; border-radius: 10px; padding-top: 10px; padding-bottom: 10px;">Create Account</button>
|
||||||
@@ -154,13 +157,19 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function loginCallback(result) {
|
function loginCallback(result) {
|
||||||
switch(result.status) {
|
var errorLabel = document.getElementById('login_passwordnotice');
|
||||||
case 200:
|
var errorBox = document.getElementById('login_passworderrors');
|
||||||
window.location.replace('/index.html');
|
errorBox.innerHTML = '';
|
||||||
break;
|
|
||||||
default:
|
console.log(result);
|
||||||
// login failed
|
if (result.succeeded == false) {
|
||||||
break;
|
for (var i = 0; i < result.errors.length; i++) {
|
||||||
|
var errorMessage = document.createElement('p');
|
||||||
|
errorMessage.innerHTML = result.errors[i].description;
|
||||||
|
errorBox.appendChild(errorMessage);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
window.location.replace('/index.html');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@@ -35,6 +35,9 @@
|
|||||||
|
|
||||||
<div id="gamesummary">
|
<div id="gamesummary">
|
||||||
<div id="gamesummary_cover"></div>
|
<div id="gamesummary_cover"></div>
|
||||||
|
<div id="gamesummary_firstrelease">
|
||||||
|
<h3>First Released</h3>
|
||||||
|
</div>
|
||||||
<div id="gamesumarry_genres">
|
<div id="gamesumarry_genres">
|
||||||
<h3>Genres</h3>
|
<h3>Genres</h3>
|
||||||
</div>
|
</div>
|
||||||
@@ -83,6 +86,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="gamesummarysimilar">
|
||||||
|
<h3>Similar Games</h3>
|
||||||
|
<div id="gamesummarysimilarcontent"></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -234,6 +241,16 @@
|
|||||||
}
|
}
|
||||||
gameSummaryCover.appendChild(gameImage);
|
gameSummaryCover.appendChild(gameImage);
|
||||||
|
|
||||||
|
// load release date
|
||||||
|
var gameSummaryRelease = document.getElementById('gamesummary_firstrelease');
|
||||||
|
if (result.firstReleaseDate) {
|
||||||
|
var firstRelease = document.createElement('p');
|
||||||
|
firstRelease.innerHTML = '<p>' + moment(result.firstReleaseDate).format('LL') + ' (' + moment(result.firstReleaseDate).fromNow() + ')</p>';
|
||||||
|
gameSummaryRelease.appendChild(firstRelease);
|
||||||
|
} else {
|
||||||
|
gameSummaryRelease.setAttribute('style', 'display: none;');
|
||||||
|
}
|
||||||
|
|
||||||
// load ratings
|
// load ratings
|
||||||
var gameSummaryRatings = document.getElementById('gamesummary_ratings');
|
var gameSummaryRatings = document.getElementById('gamesummary_ratings');
|
||||||
if (result.ageRatings) {
|
if (result.ageRatings) {
|
||||||
@@ -344,6 +361,26 @@
|
|||||||
gamescreenshots.setAttribute('style', 'display: none;');
|
gamescreenshots.setAttribute('style', 'display: none;');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// load similar
|
||||||
|
var gameSummarySimilar = document.getElementById('gamesummarysimilar');
|
||||||
|
ajaxCall('/api/v1.1/Games/' + gameId + '/Related', 'GET', function (result) {
|
||||||
|
if (result.games.length > 0) {
|
||||||
|
var gameSummarySimilarContent = document.getElementById('gamesummarysimilar');
|
||||||
|
for (var i = 0; i < result.games.length; i++) {
|
||||||
|
var similarObject = renderGameIcon(result.games[i], false, false, false, null, true);
|
||||||
|
gameSummarySimilarContent.appendChild(similarObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
$('.lazy').Lazy({
|
||||||
|
scrollDirection: 'vertical',
|
||||||
|
effect: 'fadeIn',
|
||||||
|
visibleOnly: true
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
gameSummarySimilar.setAttribute('style', 'display: none;');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// load roms
|
// load roms
|
||||||
loadRoms();
|
loadRoms();
|
||||||
});
|
});
|
||||||
|
@@ -2,9 +2,34 @@
|
|||||||
<div id="bgImage_Opacity"></div>
|
<div id="bgImage_Opacity"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="games_home">
|
<div id="games_filter_scroller">
|
||||||
<div id="games_filter"></div>
|
<div id="games_filter"></div>
|
||||||
<div id="games_library"></div>
|
</div>
|
||||||
|
<div id="games_home">
|
||||||
|
<div id="games_home_box">
|
||||||
|
<div id="games_library_controls">
|
||||||
|
<div id="games_library_orderby" class="games_library_controlblock">
|
||||||
|
<span>Order by: </span>
|
||||||
|
<select id="games_library_orderby_select" onchange="executeFilter1_1();">
|
||||||
|
<option selected="selected" value="NameThe">Name, The</option>
|
||||||
|
<option value="Name">Name</option>
|
||||||
|
<option value="Rating">User Rating</option>
|
||||||
|
<option value="RatingCount">User Rating Count</option>
|
||||||
|
</select>
|
||||||
|
<select id="games_library_orderby_direction_select" onchange="executeFilter1_1();">
|
||||||
|
<option selected="selected" value="Ascending">Ascending</option>
|
||||||
|
<option value="Descending">Descending</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div id="games_library_recordcount" class="games_library_controlblock"></div>
|
||||||
|
</div>
|
||||||
|
<div id="games_library"></div>
|
||||||
|
<div id="games_library_pagerstore" style="display: none;">0</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="games_pager" style="display: none;">
|
||||||
|
< 1 2 3 4 5 >
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
@@ -66,6 +66,9 @@
|
|||||||
<input type="checkbox" id="login_rememberme"> <label for="login_rememberme">Remember Me</label>
|
<input type="checkbox" id="login_rememberme"> <label for="login_rememberme">Remember Me</label>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2" id="login_errorlabel" style="color: red;"></td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="2" style="padding-top: 20px;">
|
<td colspan="2" style="padding-top: 20px;">
|
||||||
<button type="button" value="Sign In" onclick="UserLogin();" style="margin-top: 10px; width: 100%; font-size: 16px; border-radius: 10px; padding-top: 10px; padding-bottom: 10px;">Sign In</button>
|
<button type="button" value="Sign In" onclick="UserLogin();" style="margin-top: 10px; width: 100%; font-size: 16px; border-radius: 10px; padding-top: 10px; padding-bottom: 10px;">Sign In</button>
|
||||||
@@ -120,6 +123,7 @@
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// login failed
|
// login failed
|
||||||
|
document.getElementById('login_errorlabel').innerHTML = 'Incorrect password';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -47,6 +47,10 @@
|
|||||||
SelectTab(selectedTab);
|
SelectTab(selectedTab);
|
||||||
|
|
||||||
function SelectTab(TabName) {
|
function SelectTab(TabName) {
|
||||||
|
if (selectedTab != TabName) {
|
||||||
|
window.location.href = '/index.html?page=settings&sub=' + TabName;
|
||||||
|
}
|
||||||
|
|
||||||
var tocs = document.getElementsByName('properties_toc_item');
|
var tocs = document.getElementsByName('properties_toc_item');
|
||||||
for (var i = 0; i < tocs.length; i++) {
|
for (var i = 0; i < tocs.length; i++) {
|
||||||
if ((tocs[i].id) == ("properties_toc_" + TabName)) {
|
if ((tocs[i].id) == ("properties_toc_" + TabName)) {
|
||||||
|
@@ -2,60 +2,121 @@
|
|||||||
<h1 id="gametitle_label">Firmware</h1>
|
<h1 id="gametitle_label">Firmware</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h3>Firmware Availablility</h3>
|
<h3>Firmware Availablility <span id="firmware_totalcount" style="float: right;"></span></h3>
|
||||||
|
<p>
|
||||||
|
Display:
|
||||||
|
<ul style="list-style-type:none;">
|
||||||
|
<li><input type="checkbox" id="firmware_showavailable" checked="checked" onclick="displayFirmwareList();"/><label for="firmware_showavailable"> Available</label></li>
|
||||||
|
<li><input type="checkbox" id="firmware_showunavailable" checked="checked" onclick="displayFirmwareList();"/><label for="firmware_showunavailable"> Unavailable</label></li>
|
||||||
|
</ul>
|
||||||
|
</p>
|
||||||
<table id="table_firmware" class="romtable" cellspacing="0">
|
<table id="table_firmware" class="romtable" cellspacing="0">
|
||||||
|
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
var biosDict = {};
|
||||||
|
|
||||||
ajaxCall('/api/v1.1/Bios', 'GET', function (result) {
|
ajaxCall('/api/v1.1/Bios', 'GET', function (result) {
|
||||||
result.sort((a, b) => a.platformname.charCodeAt(0) - b.platformname.charCodeAt(0));
|
result.sort((a, b) => a.platformname.charCodeAt(0) - b.platformname.charCodeAt(0));
|
||||||
|
|
||||||
|
// sort into a dictionary
|
||||||
|
for (var i = 0; i < result.length; i++) {
|
||||||
|
var tempArray = [];
|
||||||
|
if (biosDict.hasOwnProperty(result[i].platformname)) {
|
||||||
|
tempArray = biosDict[result[i].platformname];
|
||||||
|
tempArray.push(result[i]);
|
||||||
|
} else {
|
||||||
|
tempArray.push(result[i]);
|
||||||
|
biosDict[result[i].platformname] = tempArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
biosDict[result[i].platformname] = tempArray;
|
||||||
|
}
|
||||||
|
console.log(biosDict);
|
||||||
|
|
||||||
|
displayFirmwareList();
|
||||||
|
});
|
||||||
|
|
||||||
|
function displayFirmwareList() {
|
||||||
var lastPlatform = '';
|
var lastPlatform = '';
|
||||||
|
|
||||||
var newTable = document.getElementById('table_firmware');
|
var newTable = document.getElementById('table_firmware');
|
||||||
|
newTable.innerHTML = '';
|
||||||
newTable.appendChild(createTableRow(true, ['Description', 'File name', 'MD5 Hash', 'Available']));
|
newTable.appendChild(createTableRow(true, ['Description', 'File name', 'MD5 Hash', 'Available']));
|
||||||
|
|
||||||
for (var i = 0; i < result.length; i++) {
|
var totalAvailable = 0;
|
||||||
if (result[i].platformname != lastPlatform) {
|
var totalCount = 0;
|
||||||
lastPlatform = result[i].platformname;
|
|
||||||
var platformRow = document.createElement('tr');
|
for (const [key, value] of Object.entries(biosDict)) {
|
||||||
var platformHeader = document.createElement('th');
|
// new platform - show a header
|
||||||
platformHeader.setAttribute('colspan', 4);
|
var platformRow = document.createElement('tr');
|
||||||
platformHeader.innerHTML = result[i].platformname;
|
var platformHeader = document.createElement('th');
|
||||||
platformRow.appendChild(platformHeader);
|
platformHeader.setAttribute('colspan', 4);
|
||||||
newTable.appendChild(platformRow);
|
|
||||||
|
var platformHeaderValue = document.createElement('span');
|
||||||
|
platformHeaderValue.innerHTML = key;
|
||||||
|
platformHeader.appendChild(platformHeaderValue);
|
||||||
|
|
||||||
|
var platformHeaderCounter = document.createElement('span');
|
||||||
|
platformHeaderCounter.style.float = 'right';
|
||||||
|
platformHeader.appendChild(platformHeaderCounter);
|
||||||
|
|
||||||
|
platformRow.appendChild(platformHeader);
|
||||||
|
newTable.appendChild(platformRow);
|
||||||
|
|
||||||
|
var totalPlatformAvailable = 0;
|
||||||
|
|
||||||
|
var showAvailable = document.getElementById('firmware_showavailable').checked;
|
||||||
|
var showUnavailable = document.getElementById('firmware_showunavailable').checked;
|
||||||
|
|
||||||
|
for (var i = 0; i < value.length; i++) {
|
||||||
|
// update counters
|
||||||
|
if (value[i].available == true) {
|
||||||
|
totalAvailable += 1;
|
||||||
|
totalPlatformAvailable += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
(value[i].available == true && showAvailable == true) ||
|
||||||
|
(value[i].available == false && showUnavailable == true)
|
||||||
|
) {
|
||||||
|
var biosFilename = document.createElement('a');
|
||||||
|
biosFilename.href = '/api/v1.1/Bios/' + value[i].platformid + '/' + value[i].filename;
|
||||||
|
biosFilename.innerHTML = value[i].filename;
|
||||||
|
biosFilename.className = 'romlink';
|
||||||
|
|
||||||
|
var availableText = document.createElement('span');
|
||||||
|
if (value[i].available == true) {
|
||||||
|
availableText.innerHTML = 'Available';
|
||||||
|
availableText.className = 'greentext';
|
||||||
|
|
||||||
|
biosFilename = document.createElement('a');
|
||||||
|
biosFilename.href = '/api/v1.1/Bios/' + value[i].platformid + '/' + value[i].filename;
|
||||||
|
biosFilename.innerHTML = value[i].filename;
|
||||||
|
biosFilename.className = 'romlink';
|
||||||
|
} else {
|
||||||
|
availableText.innerHTML = 'Unavailable';
|
||||||
|
availableText.className = 'redtext';
|
||||||
|
|
||||||
|
biosFilename = document.createElement('span');
|
||||||
|
biosFilename.innerHTML = value[i].filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
var newRow = [
|
||||||
|
value[i].description,
|
||||||
|
biosFilename,
|
||||||
|
value[i].hash,
|
||||||
|
availableText
|
||||||
|
];
|
||||||
|
newTable.appendChild(createTableRow(false, newRow, 'romrow', 'romcell'));
|
||||||
|
}
|
||||||
|
totalCount += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
var biosFilename = document.createElement('a');
|
platformHeaderCounter.innerHTML = totalPlatformAvailable + ' / ' + value.length + ' available';
|
||||||
biosFilename.href = '/api/v1.1/Bios/' + result[i].platformid + '/' + result[i].filename;
|
|
||||||
biosFilename.innerHTML = result[i].filename;
|
|
||||||
biosFilename.className = 'romlink';
|
|
||||||
|
|
||||||
var availableText = document.createElement('span');
|
|
||||||
if (result[i].available == true) {
|
|
||||||
availableText.innerHTML = 'Available';
|
|
||||||
availableText.className = 'greentext';
|
|
||||||
|
|
||||||
biosFilename = document.createElement('a');
|
|
||||||
biosFilename.href = '/api/v1.1/Bios/' + result[i].platformid + '/' + result[i].filename;
|
|
||||||
biosFilename.innerHTML = result[i].filename;
|
|
||||||
biosFilename.className = 'romlink';
|
|
||||||
} else {
|
|
||||||
availableText.innerHTML = 'Unavailable';
|
|
||||||
availableText.className = 'redtext';
|
|
||||||
|
|
||||||
biosFilename = document.createElement('span');
|
|
||||||
biosFilename.innerHTML = result[i].filename;
|
|
||||||
}
|
|
||||||
|
|
||||||
var newRow = [
|
|
||||||
result[i].description,
|
|
||||||
biosFilename,
|
|
||||||
result[i].hash,
|
|
||||||
availableText
|
|
||||||
];
|
|
||||||
newTable.appendChild(createTableRow(false, newRow, 'romrow', 'romcell'));
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
document.getElementById('firmware_totalcount').innerHTML = totalAvailable + ' / ' + totalCount + ' available';
|
||||||
|
}
|
||||||
</script>
|
</script>
|
@@ -2,7 +2,38 @@
|
|||||||
<h1 id="gametitle_label">Logs</h1>
|
<h1 id="gametitle_label">Logs</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a href="#" class="romlink" onclick="loadLogs();" style="float: right;"><img src="/images/refresh.svg" alt="Refresh" title="Refresh" class="banner_button_image" /></a>
|
<table style="width: 960px; max-width: 960px;" cellspacing="0">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<input type="datetime-local" id="logs_startdate" style="width: 30%;" /> <input type="datetime-local" id="logs_enddate" style="width: 30%;" />
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input type="checkbox" id="logs_type_info"><label for="logs_type_info">Information</label>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input type="checkbox" id="logs_type_warning"><label for="logs_type_warning">Warning</label>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input type="checkbox" id="logs_type_critical"><label for="logs_type_critical">Critical</label>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="1">
|
||||||
|
<input type="text" id="logs_textsearch" placeholder="Search" style="width: 75%;" />
|
||||||
|
</td>
|
||||||
|
<td colspan="3">
|
||||||
|
<input type="text" id="logs_correlationid" placeholder="Correlation Id" style="width: 75%;" />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="4" style="text-align: right;">
|
||||||
|
<button onclick="loadLogs();">Search</button>
|
||||||
|
<button onclick="resetFilters();">Reset</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<!-- <a href="#" class="romlink" onclick="loadLogs();" style="float: right;"><img src="/images/refresh.svg" alt="Refresh" title="Refresh" class="banner_button_image" /></a> -->
|
||||||
<table id="settings_events_table" style="width: 960px; max-width: 960px;" cellspacing="0">
|
<table id="settings_events_table" style="width: 960px; max-width: 960px;" cellspacing="0">
|
||||||
|
|
||||||
</table>
|
</table>
|
||||||
@@ -14,20 +45,76 @@
|
|||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
var lastStartIndex = 0;
|
var lastStartIndex = 0;
|
||||||
var currentPage = 1;
|
var currentPage = 1;
|
||||||
|
var searchModel = {};
|
||||||
|
|
||||||
|
var correlationIdParam = getQueryString('correlationid', 'string');
|
||||||
|
if (correlationIdParam) {
|
||||||
|
if (correlationIdParam.length > 0) {
|
||||||
|
document.getElementById('logs_correlationid').value = correlationIdParam;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetFilters() {
|
||||||
|
document.getElementById('logs_startdate').value = '';
|
||||||
|
document.getElementById('logs_enddate').value = '';
|
||||||
|
document.getElementById('logs_type_info').checked = false;
|
||||||
|
document.getElementById('logs_type_warning').checked = false;
|
||||||
|
document.getElementById('logs_type_critical').checked = false;
|
||||||
|
document.getElementById('logs_textsearch').value = '';
|
||||||
|
document.getElementById('logs_correlationid').value = '';
|
||||||
|
|
||||||
|
loadLogs();
|
||||||
|
}
|
||||||
|
|
||||||
function loadLogs(StartIndex, PageNumber) {
|
function loadLogs(StartIndex, PageNumber) {
|
||||||
var apiQuery = '';
|
var model = {}
|
||||||
|
|
||||||
if (StartIndex && PageNumber) {
|
if (StartIndex && PageNumber) {
|
||||||
currentPage += 1;
|
currentPage += 1;
|
||||||
apiQuery = '?StartIndex=' + StartIndex + '&PageNumber=' + PageNumber;
|
|
||||||
|
// get saved search model
|
||||||
|
model = searchModel;
|
||||||
|
model.StartIndex = StartIndex;
|
||||||
|
model.PageNumber = PageNumber;
|
||||||
} else {
|
} else {
|
||||||
currentPage = 1;
|
currentPage = 1;
|
||||||
|
|
||||||
|
// create search model
|
||||||
|
var statusList = [];
|
||||||
|
if (document.getElementById('logs_type_info').checked == true) { statusList.push(0); }
|
||||||
|
if (document.getElementById('logs_type_warning').checked == true) { statusList.push(2); }
|
||||||
|
if (document.getElementById('logs_type_critical').checked == true) { statusList.push(3); }
|
||||||
|
var startDate = null;
|
||||||
|
var startDateObj = document.getElementById('logs_startdate');
|
||||||
|
if (startDateObj.value != null) { startDate = new Date(startDateObj.value); }
|
||||||
|
var endDate = null;
|
||||||
|
var endDateObj = document.getElementById('logs_enddate');
|
||||||
|
if (endDateObj.value != null) { endDate = new Date(endDateObj.value); }
|
||||||
|
var searchText = null;
|
||||||
|
var searchTextObj = document.getElementById('logs_textsearch');
|
||||||
|
if (searchTextObj.value != null) { searchText = searchTextObj.value; }
|
||||||
|
var correlationId = null;
|
||||||
|
var correlationIdTextObj = document.getElementById('logs_correlationid');
|
||||||
|
if (correlationIdTextObj.value != null) { correlationId = correlationIdTextObj.value; }
|
||||||
|
|
||||||
|
model = {
|
||||||
|
"StartIndex": StartIndex,
|
||||||
|
"PageNumber": PageNumber,
|
||||||
|
"PageSize": 100,
|
||||||
|
"Status": statusList,
|
||||||
|
"StartDateTime": startDate,
|
||||||
|
"EndDateTime": endDate,
|
||||||
|
"SearchText": searchText,
|
||||||
|
"CorrelationId": correlationId
|
||||||
|
}
|
||||||
|
searchModel = model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log(model);
|
||||||
|
|
||||||
ajaxCall(
|
ajaxCall(
|
||||||
'/api/v1.1/Logs' + apiQuery,
|
'/api/v1.1/Logs',
|
||||||
'GET',
|
'POST',
|
||||||
function (result) {
|
function (result) {
|
||||||
var newTable = document.getElementById('settings_events_table');
|
var newTable = document.getElementById('settings_events_table');
|
||||||
if (currentPage == 1) {
|
if (currentPage == 1) {
|
||||||
@@ -54,13 +141,13 @@
|
|||||||
|
|
||||||
var newRow = [
|
var newRow = [
|
||||||
//result[i].id,
|
//result[i].id,
|
||||||
moment(result[i].eventTime).format("YYYY-MM-DD H:mm:ss"),
|
moment(result[i].eventTime).format("YYYY-MM-DD h:mm:ss a"),
|
||||||
result[i].eventType,
|
result[i].eventType,
|
||||||
result[i].process,
|
result[i].process,
|
||||||
result[i].message
|
result[i].message
|
||||||
];
|
];
|
||||||
|
|
||||||
newTable.appendChild(createTableRow(false, newRow, 'romrow logs_table_row_' + result[i].eventType, 'romcell logs_table_cell'));
|
newTable.appendChild(createTableRow(false, newRow, 'logs_table_row_' + result[i].eventType, 'romcell logs_table_cell'));
|
||||||
|
|
||||||
if (result[i].exceptionValue) {
|
if (result[i].exceptionValue) {
|
||||||
var exceptionString = "<h3>Exception</h3><pre class='logs_table_exception' style='width: 795px; word-wrap: break-word; overflow-wrap: break-word; overflow-y: scroll;'>" + syntaxHighlight(JSON.stringify(result[i].exceptionValue, null, 2)).replace(/\\n/g, "<br /> ") + "</pre>";
|
var exceptionString = "<h3>Exception</h3><pre class='logs_table_exception' style='width: 795px; word-wrap: break-word; overflow-wrap: break-word; overflow-y: scroll;'>" + syntaxHighlight(JSON.stringify(result[i].exceptionValue, null, 2)).replace(/\\n/g, "<br /> ") + "</pre>";
|
||||||
@@ -74,7 +161,11 @@
|
|||||||
newTable.appendChild(exRow);
|
newTable.appendChild(exRow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
function (error) {
|
||||||
|
|
||||||
|
},
|
||||||
|
JSON.stringify(model)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -8,6 +8,49 @@
|
|||||||
</table>
|
</table>
|
||||||
<div style="text-align: right;"><button id="settings_newlibrary" onclick="showSubDialog('librarynew');">New Library</button></div>
|
<div style="text-align: right;"><button id="settings_newlibrary" onclick="showSubDialog('librarynew');">New Library</button></div>
|
||||||
|
|
||||||
|
<h2>Advanced Settings</h2>
|
||||||
|
<p><strong>Warning</strong> Do not modify the below settings unless you know what you're doing.</p>
|
||||||
|
<h3>Background Task Timers</h3>
|
||||||
|
<p>All intervals are in minutes.</p>
|
||||||
|
<table id="settings_tasktimers" class="romtable" style="width: 100%;" cellspacing="0">
|
||||||
|
|
||||||
|
</table>
|
||||||
|
<div style="text-align: right;"><button id="settings_tasktimers_default" onclick="defaultTaskTimers();">Reset to Default</button><button id="settings_tasktimers_new" onclick="saveTaskTimers();">Save</button></div>
|
||||||
|
|
||||||
|
<h3>Logging</h3>
|
||||||
|
<table cellspacing="0" style="width: 100%;">
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
Write logs
|
||||||
|
</th>
|
||||||
|
<td>
|
||||||
|
<input type="radio" name="settings_logs_write" id="settings_logs_write_db" value="false" checked="checked"><label for="settings_logs_write_db"> To database only (default)</label>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td>
|
||||||
|
<input type="radio" name="settings_logs_write" id="settings_logs_write_fs" value="true"><label for="settings_logs_write_fs"> To database and disk</label>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2"> </td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
Minimum log retention (days):
|
||||||
|
</th>
|
||||||
|
<td>
|
||||||
|
<input type="number" min="1" id="settings_logs_retention" />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2" style="text-align: right;">
|
||||||
|
<button id="settings_tasktimers_new" onclick="setLoggingSettings();">Save</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
function drawLibrary() {
|
function drawLibrary() {
|
||||||
ajaxCall(
|
ajaxCall(
|
||||||
@@ -59,5 +102,116 @@
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getBackgroundTaskTimers() {
|
||||||
|
ajaxCall(
|
||||||
|
'/api/v1/System/Settings/BackgroundTasks/Intervals',
|
||||||
|
'GET',
|
||||||
|
function(result) {
|
||||||
|
var targetTable = document.getElementById('settings_tasktimers');
|
||||||
|
targetTable.innerHTML = '';
|
||||||
|
|
||||||
|
targetTable.appendChild(
|
||||||
|
createTableRow(true, ['Background Task', 'Timer Interval', 'Default Interval', 'Minimum Allowed Interval'])
|
||||||
|
);
|
||||||
|
|
||||||
|
for (const [key, value] of Object.entries(result)) {
|
||||||
|
var newTableRow = createTableRow(
|
||||||
|
false,
|
||||||
|
[
|
||||||
|
GetTaskFriendlyName(value.task),
|
||||||
|
'<input id="settings_tasktimers_' + value.task + '" name="settings_tasktimers_values" data-name="' + value.task + '" data-default="' + value.defaultInterval + '" type="number" placeholder="0" min="' + value.minimumAllowedValue + '" value="' + value.interval + '" />',
|
||||||
|
value.defaultInterval,
|
||||||
|
value.minimumAllowedValue
|
||||||
|
],
|
||||||
|
'romrow',
|
||||||
|
'romcell'
|
||||||
|
);
|
||||||
|
targetTable.appendChild(newTableRow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveTaskTimers() {
|
||||||
|
var timerValues = document.getElementsByName('settings_tasktimers_values');
|
||||||
|
|
||||||
|
var model = {};
|
||||||
|
for (var i = 0; i < timerValues.length; i++) {
|
||||||
|
model[timerValues[i].getAttribute('data-name')] = timerValues[i].value;
|
||||||
|
}
|
||||||
|
|
||||||
|
ajaxCall(
|
||||||
|
'/api/v1/System/Settings/BackgroundTasks/Intervals',
|
||||||
|
'POST',
|
||||||
|
function(result) {
|
||||||
|
getBackgroundTaskTimers();
|
||||||
|
},
|
||||||
|
function(error) {
|
||||||
|
getBackgroundTaskTimers();
|
||||||
|
},
|
||||||
|
JSON.stringify(model)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function defaultTaskTimers() {
|
||||||
|
var timerValues = document.getElementsByName('settings_tasktimers_values');
|
||||||
|
|
||||||
|
for (var i = 0; i < timerValues.length; i++) {
|
||||||
|
timerValues[i].value = timerValues[i].getAttribute('data-default');
|
||||||
|
}
|
||||||
|
|
||||||
|
saveTaskTimers();
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLoggingSettings() {
|
||||||
|
ajaxCall(
|
||||||
|
'/api/v1/System/Settings/System',
|
||||||
|
'GET',
|
||||||
|
function(result) {
|
||||||
|
var optionToSelect = 'settings_logs_write_db';
|
||||||
|
if (result.alwaysLogToDisk == true) {
|
||||||
|
optionToSelect = 'settings_logs_write_fs';
|
||||||
|
}
|
||||||
|
document.getElementById(optionToSelect).checked = true;
|
||||||
|
|
||||||
|
document.getElementById('settings_logs_retention').value = result.minimumLogRetentionPeriod;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setLoggingSettings() {
|
||||||
|
var alwaysLogToDisk = false;
|
||||||
|
if ($("input[type='radio'][name='settings_logs_write']:checked").val() == "true") {
|
||||||
|
alwaysLogToDisk = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var retention = document.getElementById('settings_logs_retention');
|
||||||
|
var retentionValue = 0;
|
||||||
|
if (retention.value) {
|
||||||
|
retentionValue = retention.value;
|
||||||
|
} else {
|
||||||
|
retentionValue = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
var model = {
|
||||||
|
"alwaysLogToDisk": alwaysLogToDisk,
|
||||||
|
"minimumLogRetentionPeriod": retentionValue
|
||||||
|
};
|
||||||
|
|
||||||
|
ajaxCall(
|
||||||
|
'/api/v1/System/Settings/System',
|
||||||
|
'POST',
|
||||||
|
function(result) {
|
||||||
|
getLoggingSettings();
|
||||||
|
},
|
||||||
|
function(error) {
|
||||||
|
getLoggingSettings();
|
||||||
|
},
|
||||||
|
JSON.stringify(model)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
drawLibrary();
|
drawLibrary();
|
||||||
|
getBackgroundTaskTimers();
|
||||||
|
getLoggingSettings();
|
||||||
</script>
|
</script>
|
@@ -25,92 +25,90 @@
|
|||||||
<h3>Signatures</h3>
|
<h3>Signatures</h3>
|
||||||
<div id="system_signatures"></div>
|
<div id="system_signatures"></div>
|
||||||
|
|
||||||
<script type="text/javascript">function SystemLoadStatus() {
|
<script type="text/javascript">
|
||||||
|
function SystemLoadStatus() {
|
||||||
ajaxCall('/api/v1.1/BackgroundTasks', 'GET', function (result) {
|
ajaxCall('/api/v1.1/BackgroundTasks', 'GET', function (result) {
|
||||||
var newTable = document.createElement('table');
|
var newTable = document.createElement('table');
|
||||||
newTable.className = 'romtable';
|
newTable.className = 'romtable';
|
||||||
newTable.setAttribute('cellspacing', 0);
|
newTable.setAttribute('cellspacing', 0);
|
||||||
newTable.appendChild(createTableRow(true, ['Task', 'Status', 'Interval', 'Last Run Time', 'Next Run Time', '']));
|
newTable.appendChild(createTableRow(true, ['Task', 'Status', 'Interval<br/>(minutes)', 'Last Run Duration<br />(hh:mm:ss)', '', 'Last Run Start', 'Next Run Start', '']));
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
for (var i = 0; i < result.length; i++) {
|
for (var i = 0; i < result.length; i++) {
|
||||||
var itemTypeName;
|
if (result[i].itemState != "Disabled") {
|
||||||
switch (result[i].itemType) {
|
var itemTypeName = GetTaskFriendlyName(result[i].itemType, result[i].options);
|
||||||
case 'SignatureIngestor':
|
|
||||||
itemTypeName = "Signature import";
|
var itemStateName;
|
||||||
break;
|
var itemLastStart;
|
||||||
case 'TitleIngestor':
|
|
||||||
itemTypeName = "Title import";
|
var hasError = "";
|
||||||
break;
|
if (result[i].hasErrors) {
|
||||||
case 'MetadataRefresh':
|
if (result[i].hasErrors.errorType != null) {
|
||||||
itemTypeName = "Metadata refresh"
|
hasError = " (" + result[i].hasErrors.errorType + ")";
|
||||||
break;
|
}
|
||||||
case 'OrganiseLibrary':
|
|
||||||
itemTypeName = "Organise library";
|
|
||||||
break;
|
|
||||||
case 'LibraryScan':
|
|
||||||
itemTypeName = "Library scan";
|
|
||||||
break;
|
|
||||||
case 'CollectionCompiler':
|
|
||||||
itemTypeName = "Compress collection id: " + result[i].options;
|
|
||||||
break;
|
|
||||||
case 'BackgroundDatabaseUpgrade':
|
|
||||||
itemTypeName = "Background database upgrade";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
itemTypeName = result[i].itemType;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
var itemStateName;
|
|
||||||
var itemLastStart;
|
|
||||||
if (result[i].isBlocked == false) {
|
|
||||||
switch (result[i].itemState) {
|
|
||||||
case 'NeverStarted':
|
|
||||||
itemStateName = "Never started";
|
|
||||||
itemLastStart = '-';
|
|
||||||
break;
|
|
||||||
case 'Stopped':
|
|
||||||
itemStateName = "Stopped";
|
|
||||||
itemLastStart = moment(result[i].lastRunTime).fromNow();
|
|
||||||
break;
|
|
||||||
case 'Running':
|
|
||||||
itemStateName = "Running";
|
|
||||||
itemLastStart = moment(result[i].lastRunTime).fromNow();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
itemStateName = "Unknown status";
|
|
||||||
itemLastStart = moment(result[i].lastRunTime).fromNow();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
itemStateName = "Blocked";
|
|
||||||
itemLastStart = moment(result[i].lastRunTime).fromNow();
|
|
||||||
}
|
|
||||||
|
|
||||||
var itemInterval = result[i].interval;
|
if (result[i].isBlocked == false) {
|
||||||
var nextRunTime = moment(result[i].nextRunTime).fromNow();
|
switch (result[i].itemState) {
|
||||||
var startButton = '';
|
case 'NeverStarted':
|
||||||
if (userProfile.roles.includes("Admin")) {
|
itemStateName = "Never started";
|
||||||
if (result[i].allowManualStart == true && result[i].itemState != "Running") {
|
itemLastStart = '-';
|
||||||
startButton = "<span id='startProcess' class='romstart' onclick='StartProcess(\"" + result[i].itemType + "\");'>Start</span>";
|
break;
|
||||||
|
case 'Stopped':
|
||||||
|
itemStateName = "Stopped";
|
||||||
|
itemLastStart = moment(result[i].lastRunTime).format("YYYY-MM-DD h:mm:ss a");
|
||||||
|
break;
|
||||||
|
case 'Running':
|
||||||
|
var progressPercent = "";
|
||||||
|
if (result[i].currentStateProgress) {
|
||||||
|
progressPercent = " (" + result[i].currentStateProgress + ")";
|
||||||
|
}
|
||||||
|
itemStateName = "Running" + progressPercent;
|
||||||
|
itemLastStart = moment(result[i].lastRunTime).format("YYYY-MM-DD h:mm:ss a");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
itemStateName = "Unknown status";
|
||||||
|
itemLastStart = moment(result[i].lastRunTime).format("YYYY-MM-DD h:mm:ss a");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
itemStateName = "Blocked";
|
||||||
|
itemLastStart = moment(result[i].lastRunTime).format("YYYY-MM-DD h:mm:ss a");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (result[i].allowManualStart == false && result[i].removeWhenStopped == true) {
|
itemStateName += hasError;
|
||||||
itemInterval = '';
|
|
||||||
nextRunTime = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
var newRow = [
|
var itemInterval = result[i].interval;
|
||||||
itemTypeName,
|
var nextRunTime = moment(result[i].nextRunTime).format("YYYY-MM-DD h:mm:ss a");
|
||||||
itemStateName,
|
var startButton = '';
|
||||||
itemInterval,
|
if (userProfile.roles.includes("Admin")) {
|
||||||
itemLastStart,
|
if (result[i].allowManualStart == true && result[i].itemState != "Running") {
|
||||||
nextRunTime,
|
startButton = "<span id='startProcess' class='romstart' onclick='StartProcess(\"" + result[i].itemType + "\");'>Start</span>";
|
||||||
startButton
|
}
|
||||||
];
|
}
|
||||||
newTable.appendChild(createTableRow(false, newRow, 'romrow', 'romcell'));
|
|
||||||
|
if (result[i].allowManualStart == false && result[i].removeWhenStopped == true) {
|
||||||
|
itemInterval = '';
|
||||||
|
nextRunTime = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
var logLink = '';
|
||||||
|
if (result[i].correlationId) {
|
||||||
|
logLink = '<a href="/index.html?page=settings&sub=logs&correlationid=' + result[i].correlationId + '" class="romlink">View Log</a>';
|
||||||
|
}
|
||||||
|
|
||||||
|
var newRow = [
|
||||||
|
itemTypeName,
|
||||||
|
itemStateName,
|
||||||
|
itemInterval,
|
||||||
|
new Date(result[i].lastRunDuration * 1000).toISOString().slice(11, 19),
|
||||||
|
logLink,
|
||||||
|
itemLastStart,
|
||||||
|
nextRunTime,
|
||||||
|
startButton
|
||||||
|
];
|
||||||
|
newTable.appendChild(createTableRow(false, newRow, 'romrow', 'romcell'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,6 +200,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function BuildLibraryStatisticsBar(TargetObject, TargetObjectLegend, LibraryStatistics, LibrarySize) {
|
function BuildLibraryStatisticsBar(TargetObject, TargetObjectLegend, LibraryStatistics, LibrarySize) {
|
||||||
|
TargetObject.innerHTML = '';
|
||||||
|
TargetObjectLegend.innerHTML = '';
|
||||||
|
|
||||||
var newTable = document.createElement('table');
|
var newTable = document.createElement('table');
|
||||||
newTable.setAttribute('cellspacing', 0);
|
newTable.setAttribute('cellspacing', 0);
|
||||||
newTable.setAttribute('style', 'width: 100%; height: 10px;');
|
newTable.setAttribute('style', 'width: 100%; height: 10px;');
|
||||||
@@ -265,8 +266,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
SystemLoadStatus();
|
SystemLoadStatus();
|
||||||
setInterval(SystemLoadStatus, 30000);
|
setInterval(SystemLoadStatus, 3000);
|
||||||
SystemLoadSystemStatus();
|
SystemLoadSystemStatus();
|
||||||
setInterval(SystemLoadStatus, 60000);
|
setInterval(SystemLoadSystemStatus, 60000);
|
||||||
SystemSignaturesStatus();
|
SystemSignaturesStatus();
|
||||||
setInterval(SystemSignaturesStatus, 300000);</script>
|
setInterval(SystemSignaturesStatus, 300000);
|
||||||
|
</script>
|
||||||
|
@@ -19,9 +19,25 @@
|
|||||||
|
|
||||||
panel.appendChild(containerPanelSearch);
|
panel.appendChild(containerPanelSearch);
|
||||||
|
|
||||||
panel.appendChild(buildFilterPanelHeader('userrating', 'User Rating'));
|
panel.appendChild(buildFilterPanelHeader('userrating', 'User Rating', true, false));
|
||||||
var containerPanelUserRating = document.createElement('div');
|
var containerPanelUserRating = document.createElement('div');
|
||||||
|
containerPanelUserRating.id = 'filter_panel_box_userrating';
|
||||||
containerPanelUserRating.className = 'filter_panel_box';
|
containerPanelUserRating.className = 'filter_panel_box';
|
||||||
|
|
||||||
|
var containerPanelUserRatingCheckBox = document.createElement('input');
|
||||||
|
containerPanelUserRatingCheckBox.id = 'filter_panel_userrating_enabled';
|
||||||
|
containerPanelUserRatingCheckBox.type = 'checkbox';
|
||||||
|
containerPanelUserRatingCheckBox.setAttribute('oninput', 'executeFilterDelayed();');
|
||||||
|
var ratingEnabledCookie = getCookie('filter_panel_userrating_enabled');
|
||||||
|
if (ratingEnabledCookie) {
|
||||||
|
if (ratingEnabledCookie == "true") {
|
||||||
|
containerPanelUserRatingCheckBox.checked = true;
|
||||||
|
} else {
|
||||||
|
containerPanelUserRatingCheckBox.checked = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
containerPanelUserRating.appendChild(containerPanelUserRatingCheckBox);
|
||||||
|
|
||||||
var containerPanelUserRatingMinField = document.createElement('input');
|
var containerPanelUserRatingMinField = document.createElement('input');
|
||||||
var minRatingCookie = getCookie('filter_panel_userrating_min');
|
var minRatingCookie = getCookie('filter_panel_userrating_min');
|
||||||
if (minRatingCookie) {
|
if (minRatingCookie) {
|
||||||
@@ -72,7 +88,23 @@
|
|||||||
buildFilterPanel(panel, 'theme', 'Themes', result.themes, true, false);
|
buildFilterPanel(panel, 'theme', 'Themes', result.themes, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (result.agegroupings) {
|
||||||
|
if (result.agegroupings.length > 1) {
|
||||||
|
buildFilterPanel(panel, 'agegroupings', 'Age Groups', result.agegroupings, true, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
targetElement.appendChild(panel);
|
targetElement.appendChild(panel);
|
||||||
|
|
||||||
|
// set order by values
|
||||||
|
var orderByCookie = getCookie('games_library_orderby_select');
|
||||||
|
if (orderByCookie) {
|
||||||
|
document.getElementById('games_library_orderby_select').value = orderByCookie;
|
||||||
|
}
|
||||||
|
var orderByDirectionCookie = getCookie('games_library_orderby_direction_select');
|
||||||
|
if (orderByDirectionCookie) {
|
||||||
|
document.getElementById('games_library_orderby_direction_select').value = orderByDirectionCookie;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildFilterPanel(targetElement, headerString, friendlyHeaderString, valueList, showToggle, initialDisplay) {
|
function buildFilterPanel(targetElement, headerString, friendlyHeaderString, valueList, showToggle, initialDisplay) {
|
||||||
@@ -80,7 +112,6 @@ function buildFilterPanel(targetElement, headerString, friendlyHeaderString, val
|
|||||||
var displayCookie = getCookie('filter_panel_box_' + headerString);
|
var displayCookie = getCookie('filter_panel_box_' + headerString);
|
||||||
if (displayCookie) {
|
if (displayCookie) {
|
||||||
initialDisplay = (displayCookie === 'true');
|
initialDisplay = (displayCookie === 'true');
|
||||||
console.log(displayCookie);
|
|
||||||
}
|
}
|
||||||
targetElement.appendChild(buildFilterPanelHeader(headerString, friendlyHeaderString, showToggle, initialDisplay));
|
targetElement.appendChild(buildFilterPanelHeader(headerString, friendlyHeaderString, showToggle, initialDisplay));
|
||||||
|
|
||||||
@@ -92,14 +123,13 @@ function buildFilterPanel(targetElement, headerString, friendlyHeaderString, val
|
|||||||
}
|
}
|
||||||
for (var i = 0; i < valueList.length; i++) {
|
for (var i = 0; i < valueList.length; i++) {
|
||||||
var tags;
|
var tags;
|
||||||
switch(headerString) {
|
|
||||||
case 'platform':
|
if (valueList[i].gameCount) {
|
||||||
tags = [
|
tags = [
|
||||||
{
|
{
|
||||||
'label': valueList[i].gameCount
|
'label': valueList[i].gameCount
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
containerPanel.appendChild(buildFilterPanelItem(headerString, valueList[i].id, valueList[i].name, tags));
|
containerPanel.appendChild(buildFilterPanelItem(headerString, valueList[i].id, valueList[i].name, tags));
|
||||||
}
|
}
|
||||||
@@ -201,85 +231,6 @@ function executeFilterDelayed() {
|
|||||||
filterExecutor = setTimeout(executeFilter1_1, 1000);
|
filterExecutor = setTimeout(executeFilter1_1, 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
function executeFilter() {
|
|
||||||
// build filter lists
|
|
||||||
var queries = [];
|
|
||||||
|
|
||||||
var platforms = '';
|
|
||||||
var genres = '';
|
|
||||||
|
|
||||||
var searchString = document.getElementById('filter_panel_search');
|
|
||||||
if (searchString.value.length > 0) {
|
|
||||||
queries.push('name=' + searchString.value);
|
|
||||||
}
|
|
||||||
setCookie(searchString.id, searchString.value);
|
|
||||||
|
|
||||||
var minUserRating = 0;
|
|
||||||
var minUserRatingInput = document.getElementById('filter_panel_userrating_min');
|
|
||||||
if (minUserRatingInput.value) {
|
|
||||||
minUserRating = minUserRatingInput.value;
|
|
||||||
queries.push('minrating=' + minUserRating);
|
|
||||||
}
|
|
||||||
setCookie(minUserRatingInput.id, minUserRatingInput.value);
|
|
||||||
|
|
||||||
var maxUserRating = 100;
|
|
||||||
var maxUserRatingInput = document.getElementById('filter_panel_userrating_max');
|
|
||||||
if (maxUserRatingInput.value) {
|
|
||||||
maxUserRating = maxUserRatingInput.value;
|
|
||||||
queries.push('maxrating=' + maxUserRating);
|
|
||||||
}
|
|
||||||
setCookie(maxUserRatingInput.id, maxUserRatingInput.value);
|
|
||||||
|
|
||||||
queries.push(GetFilterQuery('platform'));
|
|
||||||
queries.push(GetFilterQuery('genre'));
|
|
||||||
queries.push(GetFilterQuery('gamemode'));
|
|
||||||
queries.push(GetFilterQuery('playerperspective'));
|
|
||||||
queries.push(GetFilterQuery('theme'));
|
|
||||||
|
|
||||||
var queryString = '';
|
|
||||||
for (var i = 0; i < queries.length; i++) {
|
|
||||||
if (queries[i].length > 0) {
|
|
||||||
if (queryString.length == 0) {
|
|
||||||
queryString = '?';
|
|
||||||
} else {
|
|
||||||
queryString += '&';
|
|
||||||
}
|
|
||||||
|
|
||||||
queryString += queries[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('Query string = ' + queryString);
|
|
||||||
|
|
||||||
ajaxCall('/api/v1.0/Games' + queryString, 'GET', function (result) {
|
|
||||||
var gameElement = document.getElementById('games_library');
|
|
||||||
formatGamesPanel(gameElement, result);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function GetFilterQuery(filterName) {
|
|
||||||
var Filters = document.getElementsByName('filter_' + filterName);
|
|
||||||
var queryString = '';
|
|
||||||
|
|
||||||
for (var i = 0; i < Filters.length; i++) {
|
|
||||||
if (Filters[i].checked) {
|
|
||||||
setCookie(Filters[i].id, true);
|
|
||||||
if (queryString.length > 0) {
|
|
||||||
queryString += ',';
|
|
||||||
}
|
|
||||||
queryString += Filters[i].getAttribute('filter_id');
|
|
||||||
} else {
|
|
||||||
setCookie(Filters[i].id, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (queryString.length > 0) {
|
|
||||||
queryString = filterName + '=' + queryString;
|
|
||||||
}
|
|
||||||
|
|
||||||
return queryString;
|
|
||||||
}
|
|
||||||
|
|
||||||
function buildFilterTag(tags) {
|
function buildFilterTag(tags) {
|
||||||
// accepts an array of numbers + classes for styling (optional)
|
// accepts an array of numbers + classes for styling (optional)
|
||||||
// example [ { label: "G: 13", class: "tag_Green" }, { label: "R: 17", class: "tag_Orange" } ]
|
// example [ { label: "G: 13", class: "tag_Green" }, { label: "R: 17", class: "tag_Orange" } ]
|
||||||
@@ -301,12 +252,23 @@ function buildFilterTag(tags) {
|
|||||||
return boundingDiv;
|
return boundingDiv;
|
||||||
}
|
}
|
||||||
|
|
||||||
function executeFilter1_1() {
|
function executeFilter1_1(pageNumber, pageSize) {
|
||||||
console.log("Execute filter 1.1");
|
if (!pageNumber) {
|
||||||
|
pageNumber = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pageSize) {
|
||||||
|
pageSize = 30;
|
||||||
|
}
|
||||||
|
|
||||||
|
// user ratings
|
||||||
|
var userRatingEnabled = document.getElementById('filter_panel_userrating_enabled');
|
||||||
|
|
||||||
var minUserRating = -1;
|
var minUserRating = -1;
|
||||||
var minUserRatingInput = document.getElementById('filter_panel_userrating_min');
|
var minUserRatingInput = document.getElementById('filter_panel_userrating_min');
|
||||||
if (minUserRatingInput.value) {
|
if (minUserRatingInput.value) {
|
||||||
minUserRating = minUserRatingInput.value;
|
minUserRating = minUserRatingInput.value;
|
||||||
|
userRatingEnabled.checked = true;
|
||||||
}
|
}
|
||||||
setCookie(minUserRatingInput.id, minUserRatingInput.value);
|
setCookie(minUserRatingInput.id, minUserRatingInput.value);
|
||||||
|
|
||||||
@@ -314,15 +276,51 @@ function executeFilter1_1() {
|
|||||||
var maxUserRatingInput = document.getElementById('filter_panel_userrating_max');
|
var maxUserRatingInput = document.getElementById('filter_panel_userrating_max');
|
||||||
if (maxUserRatingInput.value) {
|
if (maxUserRatingInput.value) {
|
||||||
maxUserRating = maxUserRatingInput.value;
|
maxUserRating = maxUserRatingInput.value;
|
||||||
|
userRatingEnabled.checked = true;
|
||||||
}
|
}
|
||||||
setCookie(maxUserRatingInput.id, maxUserRatingInput.value);
|
setCookie(maxUserRatingInput.id, maxUserRatingInput.value);
|
||||||
|
|
||||||
|
if (minUserRating == -1 && maxUserRating == -1) {
|
||||||
|
userRatingEnabled.checked = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (userRatingEnabled.checked == false) {
|
||||||
|
setCookie("filter_panel_userrating_enabled", false);
|
||||||
|
|
||||||
|
minUserRating = -1;
|
||||||
|
minUserRatingInput.value = "";
|
||||||
|
setCookie(minUserRatingInput.id, minUserRatingInput.value);
|
||||||
|
maxUserRating = -1;
|
||||||
|
maxUserRatingInput.value = "";
|
||||||
|
setCookie(maxUserRatingInput.id, maxUserRatingInput.value);
|
||||||
|
} else {
|
||||||
|
setCookie("filter_panel_userrating_enabled", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// get order by
|
||||||
|
var orderBy = document.getElementById('games_library_orderby_select').value;
|
||||||
|
setCookie('games_library_orderby_select', orderBy);
|
||||||
|
var orderByDirection = true;
|
||||||
|
var orderByDirectionSelect = document.getElementById('games_library_orderby_direction_select').value;
|
||||||
|
if (orderByDirectionSelect == "Ascending") {
|
||||||
|
orderByDirection = true;
|
||||||
|
} else {
|
||||||
|
orderByDirection = false;
|
||||||
|
}
|
||||||
|
setCookie('games_library_orderby_direction_select', orderByDirectionSelect);
|
||||||
|
|
||||||
// build filter model
|
// build filter model
|
||||||
|
var ratingAgeGroups = GetFilterQuery1_1('agegroupings');
|
||||||
|
var ratingIncludeUnrated = false;
|
||||||
|
if (ratingAgeGroups.includes("0")) {
|
||||||
|
ratingIncludeUnrated = true;
|
||||||
|
}
|
||||||
|
|
||||||
var model = {
|
var model = {
|
||||||
"Name": document.getElementById('filter_panel_search').value,
|
"Name": document.getElementById('filter_panel_search').value,
|
||||||
"Platform": GetFilterQuery1_1('platform'),
|
"Platform": GetFilterQuery1_1('platform'),
|
||||||
"Genre": GetFilterQuery1_1('genre'),
|
"Genre": GetFilterQuery1_1('genre'),
|
||||||
"GameMode": GetFilterQuery1_1('gamemmode'),
|
"GameMode": GetFilterQuery1_1('gamemode'),
|
||||||
"PlayerPerspective": GetFilterQuery1_1('playerperspective'),
|
"PlayerPerspective": GetFilterQuery1_1('playerperspective'),
|
||||||
"Theme": GetFilterQuery1_1('theme'),
|
"Theme": GetFilterQuery1_1('theme'),
|
||||||
"GameRating": {
|
"GameRating": {
|
||||||
@@ -330,31 +328,24 @@ function executeFilter1_1() {
|
|||||||
"MinimumRatingCount": -1,
|
"MinimumRatingCount": -1,
|
||||||
"MaximumRating": maxUserRating,
|
"MaximumRating": maxUserRating,
|
||||||
"MaximumRatingCount": -1,
|
"MaximumRatingCount": -1,
|
||||||
"IncludeUnrated": true
|
"IncludeUnrated": !userRatingEnabled
|
||||||
},
|
},
|
||||||
"GameAgeRating": {
|
"GameAgeRating": {
|
||||||
"AgeGroupings": [
|
"AgeGroupings": ratingAgeGroups,
|
||||||
"Child",
|
"IncludeUnrated": ratingIncludeUnrated
|
||||||
"Teen",
|
|
||||||
"Mature",
|
|
||||||
"Adult"
|
|
||||||
],
|
|
||||||
"IncludeUnrated": true
|
|
||||||
},
|
},
|
||||||
"Sorting": {
|
"Sorting": {
|
||||||
"SortBy": "NameThe",
|
"SortBy": orderBy,
|
||||||
"SortAscenting": true
|
"SortAscending": orderByDirection
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log('Search model = ' + JSON.stringify(model));
|
|
||||||
|
|
||||||
ajaxCall(
|
ajaxCall(
|
||||||
'/api/v1.1/Games',
|
'/api/v1.1/Games?pageNumber=' + pageNumber + '&pageSize=' + pageSize,
|
||||||
'POST',
|
'POST',
|
||||||
function (result) {
|
function (result) {
|
||||||
var gameElement = document.getElementById('games_library');
|
var gameElement = document.getElementById('games_library');
|
||||||
formatGamesPanel(gameElement, result);
|
formatGamesPanel(gameElement, result, pageNumber, pageSize);
|
||||||
},
|
},
|
||||||
function (error) {
|
function (error) {
|
||||||
console.log('An error occurred: ' + JSON.stringify(error));
|
console.log('An error occurred: ' + JSON.stringify(error));
|
||||||
|
@@ -1,31 +1,249 @@
|
|||||||
function formatGamesPanel(targetElement, result) {
|
var ClassificationBoards = {
|
||||||
targetElement.innerHTML = '';
|
"ESRB": "Entertainment Software Rating Board (ESRB)",
|
||||||
for (var i = 0; i < result.length; i++) {
|
"PEGI": "Pan European Game Information (PEGI)",
|
||||||
var game = renderGameIcon(result[i], true, false);
|
"CERO": "Computer Entertainment Rating Organisation (CERO)",
|
||||||
targetElement.appendChild(game);
|
"USK": "Unterhaltungssoftware Selbstkontrolle (USK)",
|
||||||
|
"GRAC": "Game Rating and Administration Committee (GRAC)",
|
||||||
|
"CLASS_IND": "Brazilian advisory rating system",
|
||||||
|
"ACB": "Australian Classification Board (ACB)"
|
||||||
|
};
|
||||||
|
|
||||||
|
function formatGamesPanel(targetElement, result, pageNumber, pageSize) {
|
||||||
|
console.log("Displaying page: " + pageNumber);
|
||||||
|
console.log("Page size: " + pageSize);
|
||||||
|
|
||||||
|
var pageMode = GetPreference('LibraryPagination', 'paged');
|
||||||
|
|
||||||
|
if (pageNumber == 1 || pageMode == 'paged') {
|
||||||
|
targetElement.innerHTML = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
$('.lazy').Lazy({
|
var pagerCheck = document.getElementById('games_library_pagerstore');
|
||||||
scrollDirection: 'vertical',
|
if (pageNumber == 1) {
|
||||||
effect: 'fadeIn',
|
pagerCheck.innerHTML = "0";
|
||||||
visibleOnly: true
|
}
|
||||||
});
|
|
||||||
|
if (pageNumber > Number(pagerCheck.innerHTML) || pageMode == 'paged') {
|
||||||
|
pagerCheck.innerHTML = pageNumber;
|
||||||
|
|
||||||
|
document.getElementById('games_library_recordcount').innerHTML = result.count + ' games';
|
||||||
|
|
||||||
|
var existingLoadPageButton = document.getElementById('games_library_loadmore');
|
||||||
|
if (existingLoadPageButton) {
|
||||||
|
existingLoadPageButton.parentNode.removeChild(existingLoadPageButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup preferences
|
||||||
|
var showTitle = GetPreference("LibraryShowGameTitle", true);
|
||||||
|
var showRatings = GetPreference("LibraryShowGameRating", true);
|
||||||
|
var showClassification = GetPreference("LibraryShowGameClassification", true);
|
||||||
|
var classificationDisplayOrderString = GetPreference("LibraryGameClassificationDisplayOrder", JSON.stringify([ "ESRB" ]));
|
||||||
|
var classificationDisplayOrder = JSON.parse(classificationDisplayOrderString);
|
||||||
|
if (showTitle == "true") { showTitle = true; } else { showTitle = false; }
|
||||||
|
if (showRatings == "true") { showRatings = true; } else { showRatings = false; }
|
||||||
|
if (showClassification == "true") { showClassification = true; } else { showClassification = false; }
|
||||||
|
|
||||||
|
for (var i = 0; i < result.games.length; i++) {
|
||||||
|
var game = renderGameIcon(result.games[i], showTitle, showRatings, showClassification, classificationDisplayOrder, false);
|
||||||
|
targetElement.appendChild(game);
|
||||||
|
}
|
||||||
|
|
||||||
|
$('.lazy').Lazy({
|
||||||
|
scrollDirection: 'vertical',
|
||||||
|
effect: 'fadeIn',
|
||||||
|
visibleOnly: true
|
||||||
|
});
|
||||||
|
|
||||||
|
var pager = document.getElementById('games_pager');
|
||||||
|
pager.style.display = 'none';
|
||||||
|
|
||||||
|
switch(pageMode) {
|
||||||
|
case 'infinite':
|
||||||
|
if (result.games.length == pageSize) {
|
||||||
|
var loadPageButton = document.createElement("div");
|
||||||
|
loadPageButton.id = 'games_library_loadmore';
|
||||||
|
loadPageButton.innerHTML = 'Load More';
|
||||||
|
loadPageButton.setAttribute('onclick', 'executeFilter1_1(' + (pageNumber + 1) + ', ' + pageSize + ');');
|
||||||
|
loadPageButton.setAttribute('data-pagenumber', Number(pageNumber + 1));
|
||||||
|
loadPageButton.setAttribute('data-pagesize', pageSize);
|
||||||
|
targetElement.appendChild(loadPageButton);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'paged':
|
||||||
|
if (result.count > pageSize) {
|
||||||
|
// add some padding to the bottom of the games list
|
||||||
|
var loadPageButton = document.createElement("div");
|
||||||
|
loadPageButton.id = 'games_library_padding';
|
||||||
|
targetElement.appendChild(loadPageButton);
|
||||||
|
|
||||||
|
var pageCount = Math.ceil(result.count / pageSize);
|
||||||
|
|
||||||
|
// add previous page button
|
||||||
|
var prevPage = document.createElement('span');
|
||||||
|
prevPage.innerHTML = '<';
|
||||||
|
if (pageNumber == 1) {
|
||||||
|
prevPage.className = 'games_pager_number_disabled';
|
||||||
|
} else {
|
||||||
|
prevPage.className = 'games_pager_number';
|
||||||
|
prevPage.setAttribute('onclick', 'executeFilter1_1(' + (pageNumber - 1) + ');');
|
||||||
|
}
|
||||||
|
|
||||||
|
// add page numbers
|
||||||
|
var pageEitherSide = 4;
|
||||||
|
var currentPage = Number(pagerCheck.innerHTML);
|
||||||
|
var pageNumbers = document.createElement('span');
|
||||||
|
for (var i = 1; i <= pageCount; i++) {
|
||||||
|
if (
|
||||||
|
(
|
||||||
|
(i >= currentPage - pageEitherSide) &&
|
||||||
|
(i <= currentPage + pageEitherSide)
|
||||||
|
) ||
|
||||||
|
(
|
||||||
|
(
|
||||||
|
i <= (pageEitherSide * 2 + 1) &&
|
||||||
|
currentPage <= (pageEitherSide)
|
||||||
|
) ||
|
||||||
|
(
|
||||||
|
i >= (pageCount - (pageEitherSide * 2)) &&
|
||||||
|
currentPage >= (pageCount - (pageEitherSide))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
var pageNum = document.createElement('span');
|
||||||
|
if (Number(pagerCheck.innerHTML) == i) {
|
||||||
|
pageNum.className = 'games_pager_number_disabled';
|
||||||
|
} else {
|
||||||
|
pageNum.className = 'games_pager_number';
|
||||||
|
pageNum.setAttribute('onclick', 'executeFilter1_1(' + i + ');');
|
||||||
|
}
|
||||||
|
pageNum.innerHTML = i;
|
||||||
|
pageNumbers.appendChild(pageNum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add next page button
|
||||||
|
var nextPage = document.createElement('span');
|
||||||
|
nextPage.innerHTML = '>';
|
||||||
|
if (pageNumber == pageCount) {
|
||||||
|
nextPage.className = 'games_pager_number_disabled';
|
||||||
|
} else {
|
||||||
|
nextPage.className = 'games_pager_number';
|
||||||
|
nextPage.setAttribute('onclick', 'executeFilter1_1(' + (pageNumber + 1) + ');');
|
||||||
|
}
|
||||||
|
|
||||||
|
pager.innerHTML = '';
|
||||||
|
pager.appendChild(prevPage);
|
||||||
|
pager.appendChild(pageNumbers);
|
||||||
|
pager.appendChild(nextPage);
|
||||||
|
|
||||||
|
pager.style.display = '';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderGameIcon(gameObject, showTitle, showRatings) {
|
function isScrolledIntoView(elem) {
|
||||||
|
if (elem) {
|
||||||
|
var docViewTop = $(window).scrollTop();
|
||||||
|
var docViewBottom = docViewTop + $(window).height();
|
||||||
|
|
||||||
|
var elemTop = $(elem).offset().top;
|
||||||
|
var elemBottom = elemTop + $(elem).height();
|
||||||
|
|
||||||
|
return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function IsInView() {
|
||||||
|
var loadElement = document.getElementById('games_library_loadmore');
|
||||||
|
if (loadElement) {
|
||||||
|
if (isScrolledIntoView(loadElement)) {
|
||||||
|
var pageNumber = Number(document.getElementById('games_library_loadmore').getAttribute('data-pagenumber'));
|
||||||
|
var pageSize = document.getElementById('games_library_loadmore').getAttribute('data-pagesize');
|
||||||
|
executeFilter1_1(pageNumber, pageSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$(window).scroll(IsInView);
|
||||||
|
|
||||||
|
function renderGameIcon(gameObject, showTitle, showRatings, showClassification, classificationDisplayOrder, useSmallCover) {
|
||||||
var gameBox = document.createElement('div');
|
var gameBox = document.createElement('div');
|
||||||
gameBox.className = 'game_tile';
|
gameBox.id = "game_tile_" + gameObject.id;
|
||||||
|
if (useSmallCover == true) {
|
||||||
|
gameBox.className = 'game_tile game_tile_small';
|
||||||
|
} else {
|
||||||
|
gameBox.className = 'game_tile';
|
||||||
|
}
|
||||||
gameBox.setAttribute('onclick', 'window.location.href = "/index.html?page=game&id=' + gameObject.id + '";');
|
gameBox.setAttribute('onclick', 'window.location.href = "/index.html?page=game&id=' + gameObject.id + '";');
|
||||||
|
|
||||||
|
var gameImageBox = document.createElement('div');
|
||||||
|
gameImageBox.className = 'game_tile_box';
|
||||||
|
|
||||||
var gameImage = document.createElement('img');
|
var gameImage = document.createElement('img');
|
||||||
gameImage.className = 'game_tile_image lazy';
|
if (useSmallCover == true) {
|
||||||
|
gameImage.className = 'game_tile_image game_tile_image_small lazy';
|
||||||
|
} else {
|
||||||
|
gameImage.className = 'game_tile_image lazy';
|
||||||
|
}
|
||||||
|
gameImage.src = '/images/unknowngame.png';
|
||||||
if (gameObject.cover) {
|
if (gameObject.cover) {
|
||||||
gameImage.setAttribute('data-src', '/api/v1.1/Games/' + gameObject.id + '/cover/image');
|
gameImage.setAttribute('data-src', '/api/v1.1/Games/' + gameObject.id + '/cover/image');
|
||||||
} else {
|
} else {
|
||||||
gameImage.src = '/images/unknowngame.png';
|
|
||||||
gameImage.className = 'game_tile_image unknown';
|
gameImage.className = 'game_tile_image unknown';
|
||||||
}
|
}
|
||||||
gameBox.appendChild(gameImage);
|
gameImageBox.appendChild(gameImage);
|
||||||
|
|
||||||
|
var classificationPath = '';
|
||||||
|
var displayClassification = false;
|
||||||
|
var shownClassificationBoard = '';
|
||||||
|
if (showClassification == true) {
|
||||||
|
for (var b = 0; b < classificationDisplayOrder.length; b++) {
|
||||||
|
if (shownClassificationBoard == '') {
|
||||||
|
for (var c = 0; c < gameObject.ageRatings.length; c++) {
|
||||||
|
if (gameObject.ageRatings[c].category == classificationDisplayOrder[b]) {
|
||||||
|
shownClassificationBoard = classificationDisplayOrder[b];
|
||||||
|
displayClassification = true;
|
||||||
|
classificationPath = '/api/v1.1/Ratings/Images/' + classificationDisplayOrder[b] + '/' + getKeyByValue(AgeRatingStrings, gameObject.ageRatings[c].rating) + '/image.svg';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gameObject.totalRating || displayClassification == true) {
|
||||||
|
var gameImageRatingBanner = document.createElement('div');
|
||||||
|
gameImageRatingBanner.className = 'game_tile_box_ratingbanner';
|
||||||
|
|
||||||
|
if (showRatings == true || displayClassification == true) {
|
||||||
|
if (showRatings == true) {
|
||||||
|
if (gameObject.totalRating) {
|
||||||
|
var gameImageRatingBannerLogo = document.createElement('img');
|
||||||
|
gameImageRatingBannerLogo.src = '/images/IGDB_logo.svg';
|
||||||
|
gameImageRatingBannerLogo.setAttribute('style', 'filter: invert(100%); height: 10px; margin-right: 5px; padding-top: 4px;');
|
||||||
|
gameImageRatingBanner.appendChild(gameImageRatingBannerLogo);
|
||||||
|
|
||||||
|
var gameImageRatingBannerValue = document.createElement('span');
|
||||||
|
gameImageRatingBannerValue.innerHTML = Math.floor(gameObject.totalRating) + '% / ' + gameObject.totalRatingCount;
|
||||||
|
gameImageRatingBanner.appendChild(gameImageRatingBannerValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gameImageBox.appendChild(gameImageRatingBanner);
|
||||||
|
|
||||||
|
if (displayClassification == true) {
|
||||||
|
var gameImageClassificationLogo = document.createElement('img');
|
||||||
|
gameImageClassificationLogo.src = classificationPath;
|
||||||
|
gameImageClassificationLogo.className = 'rating_image_overlay';
|
||||||
|
gameImageBox.appendChild(gameImageClassificationLogo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gameBox.appendChild(gameImageBox);
|
||||||
|
|
||||||
if (showTitle == true) {
|
if (showTitle == true) {
|
||||||
var gameBoxTitle = document.createElement('div');
|
var gameBoxTitle = document.createElement('div');
|
||||||
@@ -34,19 +252,5 @@ function renderGameIcon(gameObject, showTitle, showRatings) {
|
|||||||
gameBox.appendChild(gameBoxTitle);
|
gameBox.appendChild(gameBoxTitle);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (showRatings == true) {
|
|
||||||
if (gameObject.ageRatings) {
|
|
||||||
var ratingsSection = document.createElement('div');
|
|
||||||
ratingsSection.id = 'ratings_section';
|
|
||||||
for (var i = 0; i < gameObject.ageRatings.ids.length; i++) {
|
|
||||||
var ratingImage = document.createElement('img');
|
|
||||||
ratingImage.src = '/api/v1.1/Games/' + gameObject.id + '/agerating/' + gameObject.ageRatings.ids[i] + '/image';
|
|
||||||
ratingImage.className = 'rating_image_mini';
|
|
||||||
ratingsSection.appendChild(ratingImage);
|
|
||||||
}
|
|
||||||
gameBox.appendChild(ratingsSection);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return gameBox;
|
return gameBox;
|
||||||
}
|
}
|
@@ -1,4 +1,8 @@
|
|||||||
function ajaxCall(endpoint, method, successFunction, errorFunction, body) {
|
var locale = window.navigator.userLanguage || window.navigator.language;
|
||||||
|
console.log(locale);
|
||||||
|
moment.locale(locale);
|
||||||
|
|
||||||
|
function ajaxCall(endpoint, method, successFunction, errorFunction, body) {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
|
|
||||||
// Our sample url to make request
|
// Our sample url to make request
|
||||||
@@ -388,4 +392,81 @@ function CreateBadge(BadgeText, ColourOverride) {
|
|||||||
badgeItem.style.borderColor = ColourOverride;
|
badgeItem.style.borderColor = ColourOverride;
|
||||||
}
|
}
|
||||||
return badgeItem;
|
return badgeItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
function GetTaskFriendlyName(TaskName, options) {
|
||||||
|
switch (TaskName) {
|
||||||
|
case 'SignatureIngestor':
|
||||||
|
return "Signature import";
|
||||||
|
case 'TitleIngestor':
|
||||||
|
return "Title import";
|
||||||
|
case 'MetadataRefresh':
|
||||||
|
return "Metadata refresh";
|
||||||
|
case 'OrganiseLibrary':
|
||||||
|
return "Organise library";
|
||||||
|
case 'LibraryScan':
|
||||||
|
return "Library scan";
|
||||||
|
case 'CollectionCompiler':
|
||||||
|
return "Compress collection id: " + options;
|
||||||
|
case 'BackgroundDatabaseUpgrade':
|
||||||
|
return "Background database upgrade";
|
||||||
|
default:
|
||||||
|
return TaskName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getKeyByValue(object, value) {
|
||||||
|
return Object.keys(object).find(key => object[key] === value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function GetPreference(Setting, DefaultValue) {
|
||||||
|
if (userProfile.userPreferences) {
|
||||||
|
for (var i = 0; i < userProfile.userPreferences.length; i++) {
|
||||||
|
if (userProfile.userPreferences[i].setting == Setting) {
|
||||||
|
return userProfile.userPreferences[i].value.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SetPreference(Setting, DefaultValue);
|
||||||
|
|
||||||
|
return DefaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
function SetPreference(Setting, Value) {
|
||||||
|
var model = [
|
||||||
|
{
|
||||||
|
"setting": Setting,
|
||||||
|
"value": Value.toString()
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
ajaxCall(
|
||||||
|
'/api/v1.1/Account/Preferences',
|
||||||
|
'POST',
|
||||||
|
function(result) {
|
||||||
|
SetPreference_Local(Setting, Value);
|
||||||
|
},
|
||||||
|
function(error) {
|
||||||
|
SetPreference_Local(Setting, Value);
|
||||||
|
},
|
||||||
|
JSON.stringify(model)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function SetPreference_Local(Setting, Value) {
|
||||||
|
if (userProfile.userPreferences) {
|
||||||
|
var prefFound = false;
|
||||||
|
for (var i = 0; i < userProfile.userPreferences.length; i++) {
|
||||||
|
if (userProfile.userPreferences[i].setting == Setting) {
|
||||||
|
userProfile.userPreferences[i].value = Value;
|
||||||
|
prefFound = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prefFound == false) {
|
||||||
|
userProfile.userPreferences.push(model);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
2
gaseous-server/wwwroot/scripts/moment-with-locales.min.js
vendored
Normal file
2
gaseous-server/wwwroot/scripts/moment-with-locales.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -187,12 +187,28 @@ h3 {
|
|||||||
z-index: -100;
|
z-index: -100;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#games_filter_scroller {
|
||||||
|
position: fixed;
|
||||||
|
width: 210px;
|
||||||
|
overflow-y: hidden;
|
||||||
|
overflow-x: hidden;
|
||||||
|
overscroll-behavior: contain;
|
||||||
|
top: 60px;
|
||||||
|
bottom: 20px;
|
||||||
|
/* margin-right: 10px; */
|
||||||
|
}
|
||||||
|
|
||||||
#games_filter {
|
#games_filter {
|
||||||
|
|
||||||
width: 200px;
|
width: 200px;
|
||||||
border-style: solid;
|
/* border-style: solid;
|
||||||
border-width: 1px;
|
border-width: 1px;
|
||||||
border-color: #2b2b2b;
|
border-color: #2b2b2b; */
|
||||||
margin-right: 10px;
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
#games_filter_scroller:hover {
|
||||||
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.filter_header {
|
.filter_header {
|
||||||
@@ -207,7 +223,7 @@ h3 {
|
|||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type='text'], input[type='number'], input[type="email"], input[type="password"] {
|
input[type='text'], input[type='number'], input[type="email"], input[type="password"], input[type="datetime-local"] {
|
||||||
background-color: #2b2b2b;
|
background-color: #2b2b2b;
|
||||||
color: white;
|
color: white;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
@@ -266,8 +282,57 @@ input[id='filter_panel_userrating_max'] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#games_home {
|
#games_home {
|
||||||
display: flex;
|
display: absolute;
|
||||||
|
margin-left: 210px;
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
|
right: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#games_home_box {
|
||||||
|
display: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
#games_pager {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 50px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, 0);
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px;
|
||||||
|
border-radius: 7px;
|
||||||
|
border-color: rgba(0, 22, 56, 0.8);
|
||||||
|
padding-left: 20px;
|
||||||
|
padding-right: 20px;
|
||||||
|
padding-top: 15px;
|
||||||
|
padding-bottom: 15px;
|
||||||
|
font-size: 18px;
|
||||||
|
font-family: Commodore64;
|
||||||
|
background-color: rgba(0, 22, 56, 0.8);
|
||||||
|
backdrop-filter: blur(8px);
|
||||||
|
-webkit-backdrop-filter: blur(8px);
|
||||||
|
box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44);
|
||||||
|
-webkit-box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44);
|
||||||
|
-moz-box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44);
|
||||||
|
}
|
||||||
|
|
||||||
|
.games_pager_number {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 5px;
|
||||||
|
width: 40px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.games_pager_number:hover {
|
||||||
|
background-color: blue;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.games_pager_number_disabled {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 5px;
|
||||||
|
width: 40px;
|
||||||
|
text-align: center;
|
||||||
|
color: grey;
|
||||||
}
|
}
|
||||||
|
|
||||||
.filter_panel_item {
|
.filter_panel_item {
|
||||||
@@ -285,18 +350,52 @@ input[id='filter_panel_userrating_max'] {
|
|||||||
margin-right: 15px;
|
margin-right: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#games_library {
|
#games_library_controls {
|
||||||
width: 90%;
|
display: absolute;
|
||||||
border-style: solid;
|
border-style: solid;
|
||||||
border-width: 1px;
|
border-width: 1px;
|
||||||
border-color: #2b2b2b;
|
border-color: #2b2b2b;
|
||||||
|
border-radius: 5px;
|
||||||
|
margin-bottom: 10px;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.games_library_controlblock {
|
||||||
|
margin-left: 20px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
#games_library {
|
||||||
|
display: block;
|
||||||
|
/* width: 90%; */
|
||||||
|
/* border-style: solid;
|
||||||
|
border-width: 1px;
|
||||||
|
border-color: #2b2b2b; */
|
||||||
|
/* padding: 10px; */
|
||||||
|
}
|
||||||
|
|
||||||
|
#games_library_loadmore {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
padding-top: 10px;
|
||||||
|
height: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#games_library_padding {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
padding-top: 10px;
|
||||||
|
height: 100px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.game_tile {
|
.game_tile {
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 220px;
|
width: 220px;
|
||||||
|
min-height: 200px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@@ -308,6 +407,12 @@ input[id='filter_panel_userrating_max'] {
|
|||||||
border: 1px solid transparent;
|
border: 1px solid transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.game_tile_small {
|
||||||
|
min-height: 50px;
|
||||||
|
min-width: 50px;
|
||||||
|
width: 105px;
|
||||||
|
}
|
||||||
|
|
||||||
.game_tile:hover {
|
.game_tile:hover {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
@@ -318,19 +423,57 @@ input[id='filter_panel_userrating_max'] {
|
|||||||
border: 1px solid #2b2b2b;
|
border: 1px solid #2b2b2b;
|
||||||
}
|
}
|
||||||
|
|
||||||
.game_tile_image {
|
.game_tile_small:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
text-decoration: underline;
|
||||||
|
background-color: #2b2b2b;
|
||||||
|
border-radius: 10px 10px 10px 10px;
|
||||||
|
-webkit-border-radius: 10px 10px 10px 10px;
|
||||||
|
-moz-border-radius: 10px 10px 10px 10px;
|
||||||
|
border: 1px solid #2b2b2b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.game_tile_box {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
max-width: 200px;
|
max-width: 200px;
|
||||||
max-height: 200px;
|
max-height: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.game_tile_box_ratingbanner {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0px;
|
||||||
|
left: 0px;
|
||||||
|
right: 0px;
|
||||||
|
text-align: right;
|
||||||
|
padding-top: 2px;
|
||||||
|
padding-bottom: 2px;
|
||||||
|
padding-left: 5px;
|
||||||
|
padding-right: 5px;
|
||||||
|
height: 19px;
|
||||||
|
background-color: rgba(0, 22, 56, 0.8);
|
||||||
|
backdrop-filter: blur(8px);
|
||||||
|
-webkit-backdrop-filter: blur(8px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.game_tile_image {
|
||||||
|
max-width: 200px;
|
||||||
|
min-width: 150px;
|
||||||
|
max-height: 200px;
|
||||||
|
min-height: 200px;
|
||||||
|
background-color: transparent;
|
||||||
box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44);
|
box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44);
|
||||||
-webkit-box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44);
|
-webkit-box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44);
|
||||||
-moz-box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44);
|
-moz-box-shadow: 5px 5px 19px 0px rgba(0,0,0,0.44);
|
||||||
}
|
}
|
||||||
|
|
||||||
.game_tile_image, .unknown {
|
.game_tile_image, .unknown {
|
||||||
background-color: white;
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.game_tile_image_small {
|
.game_tile_image_small {
|
||||||
|
min-width: 50px;
|
||||||
|
min-height: 50px;
|
||||||
max-width: 100px;
|
max-width: 100px;
|
||||||
max-height: 100px;
|
max-height: 100px;
|
||||||
}
|
}
|
||||||
@@ -408,10 +551,18 @@ input[id='filter_panel_userrating_max'] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.rating_image_mini {
|
.rating_image_mini {
|
||||||
display: inline-block;
|
|
||||||
max-width: 32px;
|
max-width: 32px;
|
||||||
max-height: 32px;
|
max-height: 32px;
|
||||||
margin-right: 10px;
|
margin-right: 5px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rating_image_overlay {
|
||||||
|
position: absolute;
|
||||||
|
max-width: 32px;
|
||||||
|
max-height: 32px;
|
||||||
|
left: 5px;
|
||||||
|
bottom: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#gamescreenshots {
|
#gamescreenshots {
|
||||||
@@ -909,22 +1060,38 @@ button:disabled {
|
|||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
}
|
}
|
||||||
|
|
||||||
.logs_table_row_Information:hover {
|
.logs_table_row_Information:nth-child(even) {
|
||||||
background: rgba(42, 41, 150, 0.3);
|
background: rgba(42, 41, 150, 0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
.logs_table_row_Warning:hover {
|
.logs_table_row_Information:nth-child(odd) {
|
||||||
|
background: rgba(10, 9, 83, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.logs_table_row_Warning:nth-child(even) {
|
||||||
background: rgba(139, 150, 41, 0.3);
|
background: rgba(139, 150, 41, 0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
.logs_table_row_Critical:hover {
|
.logs_table_row_Warning:nth-child(odd) {
|
||||||
|
background: rgba(49, 53, 14, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.logs_table_row_Critical:nth-child(even) {
|
||||||
background: rgba(150, 41, 41, 0.3);
|
background: rgba(150, 41, 41, 0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
.logs_table_row_Debug:hover {
|
.logs_table_row_Critical:nth-child(odd) {
|
||||||
|
background: rgba(58, 16, 16, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.logs_table_row_Debug:nth-child(even) {
|
||||||
background: rgba(150, 41, 135, 0.3);
|
background: rgba(150, 41, 135, 0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.logs_table_row_Debug:nth-child(odd) {
|
||||||
|
background: rgba(68, 18, 61, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
.logs_table_exception {
|
.logs_table_exception {
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
@@ -947,7 +1114,7 @@ button:disabled {
|
|||||||
top: 0px;
|
top: 0px;
|
||||||
right: 0px;
|
right: 0px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 8px;
|
font-size: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tagBoxItem {
|
.tagBoxItem {
|
||||||
|
Reference in New Issue
Block a user