feat: initial signature look up support

This commit is contained in:
Michael Green
2023-03-07 10:53:46 +11:00
parent 959f6f2419
commit 8175b4b6e6
13 changed files with 507 additions and 7 deletions

11
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,11 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: "nuget" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "weekly"

35
.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,35 @@
{
"version": "0.2.0",
"configurations": [
{
// Use IntelliSense to find out which attributes exist for C# debugging
// Use hover for the description of the existing attributes
// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
"name": ".NET Core Launch (web)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/gaseous-server/bin/Debug/net7.0/gaseous-server.dll",
"args": [],
"cwd": "${workspaceFolder}/gaseous-server",
"stopAtEntry": false,
// Enable launching a web browser when ASP.NET Core starts. For more information: https://aka.ms/VSCode-CS-LaunchJson-WebBrowser
"serverReadyAction": {
"action": "openExternally",
"pattern": "\\bNow listening on:\\s+(https?://\\S+)"
},
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"sourceFileMap": {
"/Views": "${workspaceFolder}/Views"
}
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach"
}
]
}

41
.vscode/tasks.json vendored Normal file
View File

@@ -0,0 +1,41 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/gaseous-server/gaseous-server.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "publish",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"${workspaceFolder}/gaseous-server/gaseous-server.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "watch",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"run",
"--project",
"${workspaceFolder}/gaseous-server/gaseous-server.csproj"
],
"problemMatcher": "$msCompile"
}
]
}

View File

@@ -13,6 +13,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "gaseous-signature-ingestor"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "gaseous-tools", "gaseous-tools\gaseous-tools.csproj", "{08FE408A-5EC1-4110-ABD8-D19A1155B8CE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "gaseous-server", "gaseous-server\gaseous-server.csproj", "{A01D2EFF-C82E-473B-84D7-7C25E736F5D2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test", "Test\Test.csproj", "{B07A4655-A003-416B-A790-ADAA5B548E1A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -47,6 +51,14 @@ Global
{08FE408A-5EC1-4110-ABD8-D19A1155B8CE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{08FE408A-5EC1-4110-ABD8-D19A1155B8CE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{08FE408A-5EC1-4110-ABD8-D19A1155B8CE}.Release|Any CPU.Build.0 = Release|Any CPU
{A01D2EFF-C82E-473B-84D7-7C25E736F5D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A01D2EFF-C82E-473B-84D7-7C25E736F5D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A01D2EFF-C82E-473B-84D7-7C25E736F5D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A01D2EFF-C82E-473B-84D7-7C25E736F5D2}.Release|Any CPU.Build.0 = Release|Any CPU
{B07A4655-A003-416B-A790-ADAA5B548E1A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B07A4655-A003-416B-A790-ADAA5B548E1A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B07A4655-A003-416B-A790-ADAA5B548E1A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B07A4655-A003-416B-A790-ADAA5B548E1A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@@ -0,0 +1,92 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Security.Cryptography;
using System.Threading.Tasks;
using gaseous_tools;
using Microsoft.AspNetCore.Mvc;
// For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
namespace gaseous_server.Controllers
{
[ApiController]
[Route("api/[controller]/[action]")]
public class SignaturesController : ControllerBase
{
/// <summary>
/// Get the current signature counts from the database
/// </summary>
/// <returns>Number of sources, publishers, games, and rom signatures in the database</returns>
[HttpGet]
public Models.Signatures_Status Status()
{
return new Models.Signatures_Status();
}
[HttpGet]
[Route("api/[controller]/[action]")]
public List<Models.Signatures_Games> GetSignature(string md5 = "", string sha1 = "")
{
if (md5.Length > 0)
{
return _GetSignature("signatures_roms.md5 = @searchstring", md5);
} else
{
return _GetSignature("signatures_roms.sha1 = @searchstring", sha1);
}
}
private List<Models.Signatures_Games> _GetSignature(string sqlWhere, string searchString)
{
Database db = new gaseous_tools.Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
string sql = "SELECT \n view_signatures_games.*,\n signatures_roms.id AS romid,\n signatures_roms.name AS romname,\n signatures_roms.size,\n signatures_roms.crc,\n signatures_roms.md5,\n signatures_roms.sha1,\n signatures_roms.developmentstatus,\n signatures_roms.flags,\n signatures_roms.romtype,\n signatures_roms.romtypemedia,\n signatures_roms.medialabel\nFROM\n signatures_roms\n INNER JOIN\n view_signatures_games ON signatures_roms.gameid = view_signatures_games.id WHERE " + sqlWhere;
Dictionary<string, object> dbDict = new Dictionary<string, object>();
dbDict.Add("searchString", searchString);
DataTable sigDb = db.ExecuteCMD(sql, dbDict);
List<Models.Signatures_Games> GamesList = new List<Models.Signatures_Games>();
foreach (DataRow sigDbRow in sigDb.Rows)
{
Models.Signatures_Games gameItem = new Models.Signatures_Games
{
Game = new Models.Signatures_Games.GameItem
{
Id = (Int32)sigDbRow["id"],
Name = (string)sigDbRow["name"],
Description = (string)sigDbRow["description"],
Year = (string)sigDbRow["year"],
Publisher = (string)sigDbRow["publisher"],
Demo = (Models.Signatures_Games.GameItem.DemoTypes)(int)sigDbRow["demo"],
System = (string)sigDbRow["platform"],
SystemVariant = (string)sigDbRow["systemvariant"],
Video = (string)sigDbRow["video"],
Country = (string)sigDbRow["country"],
Language = (string)sigDbRow["language"],
Copyright = (string)sigDbRow["copyright"]
},
Rom = new Models.Signatures_Games.RomItem
{
Id = (Int32)sigDbRow["romid"],
Name = (string)sigDbRow["romname"],
Size = (Int64)sigDbRow["size"],
Crc = (string)sigDbRow["crc"],
Md5 = (string)sigDbRow["md5"],
Sha1 = (string)sigDbRow["sha1"],
DevelopmentStatus = (string)sigDbRow["developmentstatus"],
flags = Newtonsoft.Json.JsonConvert.DeserializeObject<List<string>>((string)sigDbRow["flags"]),
RomType = (Models.Signatures_Games.RomItem.RomTypes)(int)sigDbRow["romtype"],
RomTypeMedia = (string)sigDbRow["romtypemedia"],
MediaLabel = (string)sigDbRow["medialabel"]
}
};
GamesList.Add(gameItem);
}
return GamesList;
}
}
}

View File

@@ -0,0 +1,98 @@
using System;
using static gaseous_romsignatureobject.RomSignatureObject.Game;
namespace gaseous_server.Models
{
public class Signatures_Games
{
public Signatures_Games()
{
}
public GameItem? Game { get; set; }
public RomItem? Rom { get; set; }
public class GameItem
{
public Int32? Id { get; set; }
public string? Name { get; set; }
public string? Description { get; set; }
public string? Year { get; set; }
public string? Publisher { get; set; }
public DemoTypes Demo { get; set; }
public string? System { get; set; }
public string? SystemVariant { get; set; }
public string? Video { get; set; }
public string? Country { get; set; }
public string? Language { get; set; }
public string? Copyright { get; set; }
public enum DemoTypes
{
NotDemo = 0,
demo = 1,
demo_kiosk = 2,
demo_playable = 3,
demo_rolling = 4,
demo_slideshow = 5
}
}
public class RomItem
{
public Int32? Id { get; set; }
public string? Name { get; set; }
public Int64? Size { get; set; }
public string? Crc { get; set; }
public string? Md5 { get; set; }
public string? Sha1 { get; set; }
public string? DevelopmentStatus { get; set; }
public List<string> flags { get; set; } = new List<string>();
public RomTypes RomType { get; set; }
public string? RomTypeMedia { get; set; }
public string? MediaLabel { get; set; }
public enum RomTypes
{
/// <summary>
/// Media type is unknown
/// </summary>
Unknown = 0,
/// <summary>
/// Optical media
/// </summary>
Disc = 1,
/// <summary>
/// Magnetic media
/// </summary>
Disk = 2,
/// <summary>
/// Individual files
/// </summary>
File = 3,
/// <summary>
/// Individual pars
/// </summary>
Part = 4,
/// <summary>
/// Tape base media
/// </summary>
Tape = 5,
/// <summary>
/// Side of the media
/// </summary>
Side = 6
}
}
}
}

View File

@@ -0,0 +1,63 @@
using System;
using System.Data;
using gaseous_tools;
namespace gaseous_server.Models
{
public class Signatures_Status
{
private Int64 _SourceCount = 0;
private Int64 _PlatformCount = 0;
private Int64 _GameCount = 0;
private Int64 _RomCount = 0;
public Signatures_Status()
{
Database db = new gaseous_tools.Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
string sql = "select (select count(*) from signatures_sources) as SourceCount, (select count(*) from signatures_platforms) as PlatformCount, (select count(*) from signatures_games) as GameCount, (select count(*) from signatures_roms) as RomCount;";
DataTable sigDb = db.ExecuteCMD(sql);
if (sigDb.Rows.Count > 0)
{
_SourceCount = (Int64)sigDb.Rows[0]["SourceCount"];
_PlatformCount = (Int64)sigDb.Rows[0]["PlatformCount"];
_GameCount = (Int64)sigDb.Rows[0]["GameCount"];
_RomCount = (Int64)sigDb.Rows[0]["RomCount"];
}
}
public Int64 Sources
{
get
{
return _SourceCount;
}
}
public Int64 Platforms
{
get
{
return _PlatformCount;
}
}
public Int64 Games
{
get
{
return _GameCount;
}
}
public Int64 Roms
{
get
{
return _RomCount;
}
}
}
}

38
gaseous-server/Program.cs Normal file
View File

@@ -0,0 +1,38 @@
using System.Text.Json.Serialization;
using gaseous_tools;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers().AddJsonOptions(x =>
{
// serialize enums as strings in api responses (e.g. Role)
x.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
});
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
// set up db
Database db = new gaseous_tools.Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
db.InitDB();
// start the app
app.Run();

View File

@@ -0,0 +1,41 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:38715",
"sslPort": 44314
}
},
"profiles": {
"http": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:5198",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"dotnetRunMessages": true
},
"https": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:7282;http://localhost:5198",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"dotnetRunMessages": true
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

View File

@@ -0,0 +1,10 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}

View File

@@ -0,0 +1,34 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<RootNamespace>gaseous_server</RootNamespace>
</PropertyGroup>
<PropertyGroup Condition=" '$(RunConfiguration)' == 'https' " />
<PropertyGroup Condition=" '$(RunConfiguration)' == 'http' " />
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.3" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\gaseous-tools\gaseous-tools.csproj">
<GlobalPropertiesToRemove></GlobalPropertiesToRemove>
</ProjectReference>
<ProjectReference Include="..\gaseous-romsignatureobject\gaseous-romsignatureobject.csproj">
<GlobalPropertiesToRemove></GlobalPropertiesToRemove>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Remove="Controllers\" />
<None Remove="Models\" />
<None Remove="Models\Signatures.Status" />
</ItemGroup>
<ItemGroup>
<Folder Include="Controllers\" />
<Folder Include="Models\" />
</ItemGroup>
</Project>

View File

@@ -122,17 +122,33 @@ namespace gaseous_tools
}
}
public DataTable ExecuteCMD(string Command)
{
Dictionary<string, object> dbDict = new Dictionary<string, object>();
return _ExecuteCMD(Command, dbDict, 30, "");
}
public DataTable ExecuteCMD(string Command, Dictionary<string, object> Parameters)
{
return _ExecuteCMD(Command, Parameters, 30, "");
}
public DataTable ExecuteCMD(string Command, Dictionary<string, object> Parameters, int Timeout = 30, string ConnectionString = "")
{
if (ConnectionString == "") { ConnectionString = _ConnectionString; }
return _ExecuteCMD(Command, Parameters, Timeout, ConnectionString);
}
private DataTable _ExecuteCMD(string Command, Dictionary<string, object> Parameters, int Timeout = 30, string ConnectionString = "")
{
if (ConnectionString == "") { ConnectionString = _ConnectionString; }
switch (_ConnectorType)
{
case databaseType.MySql:
{
case databaseType.MySql:
MySQLServerConnector conn = new MySQLServerConnector(ConnectionString);
return (DataTable)conn.ExecCMD(Command, Parameters, Timeout);
default:
return new DataTable();
}
return (DataTable)conn.ExecCMD(Command, Parameters, Timeout);
default:
return new DataTable();
}
}
private partial class MySQLServerConnector