diff --git a/Gaseous.sln b/Gaseous.sln index f7adb01..9d1c2ba 100644 --- a/Gaseous.sln +++ b/Gaseous.sln @@ -15,8 +15,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "gaseous-tools", "gaseous-to 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 diff --git a/gaseous-server/Controllers/SignaturesController.cs b/gaseous-server/Controllers/SignaturesController.cs index 7f69893..e1f3e58 100644 --- a/gaseous-server/Controllers/SignaturesController.cs +++ b/gaseous-server/Controllers/SignaturesController.cs @@ -12,7 +12,7 @@ using Microsoft.AspNetCore.Mvc; namespace gaseous_server.Controllers { [ApiController] - [Route("api/[controller]/[action]")] + [Route("api/v1/[controller]/[action]")] public class SignaturesController : ControllerBase { /// diff --git a/gaseous-server/Program.cs b/gaseous-server/Program.cs index 6fd856e..f0ae836 100644 --- a/gaseous-server/Program.cs +++ b/gaseous-server/Program.cs @@ -1,6 +1,12 @@ using System.Text.Json.Serialization; +using gaseous_server; using gaseous_tools; +// set up db +Database db = new gaseous_tools.Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString); +db.InitDB(); + +// set up server var builder = WebApplication.CreateBuilder(args); // Add services to the container. @@ -13,6 +19,7 @@ builder.Services.AddControllers().AddJsonOptions(x => // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); +builder.Services.AddHostedService(); var app = builder.Build(); @@ -29,10 +36,6 @@ 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(); diff --git a/gaseous-server/Timer.cs b/gaseous-server/Timer.cs new file mode 100644 index 0000000..6d3a977 --- /dev/null +++ b/gaseous-server/Timer.cs @@ -0,0 +1,50 @@ +using System; + +namespace gaseous_server +{ + // see: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-5.0&tabs=visual-studio-mac#timed-background-tasks-1 + public class TimedHostedService : IHostedService, IDisposable + { + private int executionCount = 0; + private readonly ILogger _logger; + private Timer _timer; + + public TimedHostedService(ILogger logger) + { + _logger = logger; + } + + public Task StartAsync(CancellationToken stoppingToken) + { + _logger.LogInformation("Timed Hosted Service running."); + + _timer = new Timer(DoWork, null, TimeSpan.Zero, + TimeSpan.FromSeconds(5)); + + return Task.CompletedTask; + } + + private void DoWork(object state) + { + var count = Interlocked.Increment(ref executionCount); + + _logger.LogInformation( + "Timed Hosted Service is working. Count: {Count}", count); + } + + public Task StopAsync(CancellationToken stoppingToken) + { + _logger.LogInformation("Timed Hosted Service is stopping."); + + _timer?.Change(Timeout.Infinite, 0); + + return Task.CompletedTask; + } + + public void Dispose() + { + _timer?.Dispose(); + } + } +} + diff --git a/gaseous-signature-ingestor/Program.cs b/gaseous-signature-ingestor/Program.cs index 6746f5f..5108736 100644 --- a/gaseous-signature-ingestor/Program.cs +++ b/gaseous-signature-ingestor/Program.cs @@ -66,6 +66,7 @@ if (Directory.Exists(tosecXML)) tosecXML = Path.GetFullPath(tosecXML); string[] tosecPathContents = Directory.GetFiles(tosecXML); + Array.Sort(tosecPathContents); int lineFileNameLength = 0; int lineGameNameLength = 0; @@ -172,10 +173,10 @@ if (Directory.Exists(tosecXML)) if (sigDB.Rows.Count == 0) { // entry not present, insert it - sql = "INSERT INTO signatures_platforms (platform) VALUES (@platform); SELECT LAST_INSERT_ID()"; + sql = "INSERT INTO signatures_platforms (platform) VALUES (@platform); SELECT CAST(LAST_INSERT_ID() AS SIGNED);"; sigDB = db.ExecuteCMD(sql, dbDict); - gameSystem = (int)sigDB.Rows[0][0]; + gameSystem = Convert.ToInt32(sigDB.Rows[0][0]); } else { @@ -194,9 +195,9 @@ if (Directory.Exists(tosecXML)) if (sigDB.Rows.Count == 0) { // entry not present, insert it - sql = "INSERT INTO signatures_publishers (publisher) VALUES (@publisher); SELECT LAST_INSERT_ID()"; + sql = "INSERT INTO signatures_publishers (publisher) VALUES (@publisher); SELECT CAST(LAST_INSERT_ID() AS SIGNED);"; sigDB = db.ExecuteCMD(sql, dbDict); - gamePublisher = (int)sigDB.Rows[0][0]; + gamePublisher = Convert.ToInt32(sigDB.Rows[0][0]); } else { @@ -215,10 +216,10 @@ if (Directory.Exists(tosecXML)) // 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 LAST_INSERT_ID()"; + "(@name, @description, @year, @publisherid, @demo, @systemid, @systemvariant, @video, @country, @language, @copyright); SELECT CAST(LAST_INSERT_ID() AS SIGNED);"; sigDB = db.ExecuteCMD(sql, dbDict); - gameId = (int)sigDB.Rows[0][0]; + gameId = Convert.ToInt32(sigDB.Rows[0][0]); } else { @@ -264,11 +265,11 @@ if (Directory.Exists(tosecXML)) if (sigDB.Rows.Count == 0) { // entry not present, insert it - sql = "INSERT INTO signatures_roms (gameid, name, size, crc, md5, sha1, developmentstatus, flags, romtype, romtypemedia, medialabel) VALUES (@gameid, @name, @size, @crc, @md5, @sha1, @developmentstatus, @flags, @romtype, @romtypemedia, @medialabel); SELECT LAST_INSERT_ID()"; + sql = "INSERT INTO signatures_roms (gameid, name, size, crc, md5, sha1, developmentstatus, flags, romtype, romtypemedia, medialabel) VALUES (@gameid, @name, @size, @crc, @md5, @sha1, @developmentstatus, @flags, @romtype, @romtypemedia, @medialabel); SELECT CAST(LAST_INSERT_ID() AS SIGNED);"; sigDB = db.ExecuteCMD(sql, dbDict); - romId = (int)sigDB.Rows[0][0]; + romId = Convert.ToInt32(sigDB.Rows[0][0]); } else { diff --git a/gaseous-tools/Config.cs b/gaseous-tools/Config.cs index c9e8e4e..948b2ac 100644 --- a/gaseous-tools/Config.cs +++ b/gaseous-tools/Config.cs @@ -1,4 +1,5 @@ using System; +using System.Data; using Newtonsoft.Json; namespace gaseous_tools @@ -84,10 +85,44 @@ namespace gaseous_tools File.WriteAllText(ConfigurationFilePath, configRaw); } + private static string ReadSetting(string SettingName, string DefaultValue) + { + Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString); + string sql = "SELECT * FROM settings WHERE setting = @settingname"; + Dictionary dbDict = new Dictionary(); + dbDict.Add("settingname", SettingName); + dbDict.Add("value", DefaultValue); + + DataTable dbResponse = db.ExecuteCMD(sql, dbDict); + if (dbResponse.Rows.Count == 0) + { + // no value with that name stored - respond with the default value + return DefaultValue; + } + else + { + return (string)dbResponse.Rows[0][0]; + } + } + + private static void SetSetting(string SettingName, string Value) + { + Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString); + string sql = "REPLACE INTO settings (setting, value) VALUES (@settingname, @value)"; + Dictionary dbDict = new Dictionary(); + dbDict.Add("settingname", SettingName); + dbDict.Add("value", Value); + + db.ExecuteCMD(sql, dbDict); + } + public class ConfigFile { public Database DatabaseConfiguration = new Database(); + [JsonIgnore] + public Library LibraryConfiguration = new Library(); + public class Database { public string HostName = "localhost"; @@ -106,6 +141,45 @@ namespace gaseous_tools } } } + + public class Library + { + public string LibraryRootDirectory + { + get + { + return ReadSetting("LibraryRootDirectory", Path.Combine(Config.ConfigurationPath, "Data")); + } + set + { + SetSetting("LibraryRootDirectory", value); + } + } + + public string LibraryUploadDirectory + { + get + { + return Path.Combine(LibraryRootDirectory, "Upload"); + } + } + + public string LibraryImportDirectory + { + get + { + return Path.Combine(LibraryRootDirectory, "Import"); + } + } + + public string LibraryDataDirectory + { + get + { + return Path.Combine(LibraryRootDirectory, "Library"); + } + } + } } } } diff --git a/gaseous-tools/Database.cs b/gaseous-tools/Database.cs index 81bc5f7..e11afc0 100644 --- a/gaseous-tools/Database.cs +++ b/gaseous-tools/Database.cs @@ -91,6 +91,7 @@ namespace gaseous_tools // apply script sql = "SELECT schema_version FROM schema_version;"; + dbDict = new Dictionary(); DataTable SchemaVersion = ExecuteCMD(sql, dbDict); if (SchemaVersion.Rows.Count == 0) { @@ -106,6 +107,7 @@ namespace gaseous_tools ExecuteCMD(dbScript, dbDict); sql = "UPDATE schema_version SET schema_version=@schemaver"; + dbDict = new Dictionary(); dbDict.Add("schemaver", i); ExecuteCMD(sql, dbDict); } diff --git a/gaseous-tools/Database/MySQL/gaseous-1000.sql b/gaseous-tools/Database/MySQL/gaseous-1000.sql index 83b73cb..ba3f120 100644 --- a/gaseous-tools/Database/MySQL/gaseous-1000.sql +++ b/gaseous-tools/Database/MySQL/gaseous-1000.sql @@ -42,7 +42,7 @@ CREATE TABLE `signatures_games` ( KEY `ingest_idx` (`name`,`year`,`publisherid`,`systemid`,`country`,`language`) USING BTREE, CONSTRAINT `publisher` FOREIGN KEY (`publisherid`) REFERENCES `signatures_publishers` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `system` FOREIGN KEY (`systemid`) REFERENCES `signatures_platforms` (`id`) ON DELETE CASCADE ON UPDATE CASCADE -) ENGINE=InnoDB AUTO_INCREMENT=1466355 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -58,7 +58,7 @@ CREATE TABLE `signatures_platforms` ( PRIMARY KEY (`id`), UNIQUE KEY `idsignatures_platforms_UNIQUE` (`id`), KEY `platforms_idx` (`platform`,`id`) USING BTREE -) ENGINE=InnoDB AUTO_INCREMENT=1231 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -74,7 +74,7 @@ CREATE TABLE `signatures_publishers` ( PRIMARY KEY (`id`), UNIQUE KEY `id_UNIQUE` (`id`), KEY `publisher_idx` (`publisher`,`id`) -) ENGINE=InnoDB AUTO_INCREMENT=97693 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -104,7 +104,7 @@ CREATE TABLE `signatures_roms` ( KEY `sha1_idx` (`sha1`) USING BTREE, KEY `flags_idx` ((cast(`flags` as char(255) array))), CONSTRAINT `gameid` FOREIGN KEY (`gameid`) REFERENCES `signatures_games` (`id`) ON DELETE CASCADE ON UPDATE CASCADE -) ENGINE=InnoDB AUTO_INCREMENT=3350963 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -131,7 +131,7 @@ CREATE TABLE `signatures_sources` ( UNIQUE KEY `id_UNIQUE` (`id`), KEY `sourcemd5_idx` (`sourcemd5`,`id`) USING BTREE, KEY `sourcesha1_idx` (`sourcesha1`,`id`) USING BTREE -) ENGINE=InnoDB AUTO_INCREMENT=7573 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; diff --git a/gaseous-tools/Database/MySQL/gaseous-1001.sql b/gaseous-tools/Database/MySQL/gaseous-1001.sql index 1b39072..98eb6e0 100644 --- a/gaseous-tools/Database/MySQL/gaseous-1001.sql +++ b/gaseous-tools/Database/MySQL/gaseous-1001.sql @@ -1,8 +1,4 @@ -CREATE - ALGORITHM = UNDEFINED - DEFINER = `root`@`localhost` - SQL SECURITY DEFINER -VIEW `view_signatures_games` AS +CREATE VIEW `view_signatures_games` AS SELECT `signatures_games`.`id` AS `id`, `signatures_games`.`name` AS `name`, diff --git a/gaseous-tools/Database/MySQL/gaseous-1002.sql b/gaseous-tools/Database/MySQL/gaseous-1002.sql new file mode 100644 index 0000000..29ed498 --- /dev/null +++ b/gaseous-tools/Database/MySQL/gaseous-1002.sql @@ -0,0 +1,6 @@ +CREATE TABLE `gaseous`.`settings` ( + `setting` VARCHAR(45) NOT NULL, + `value` LONGTEXT NULL, + UNIQUE INDEX `setting_UNIQUE` (`setting` ASC) VISIBLE, + PRIMARY KEY (`setting`)); + diff --git a/gaseous-tools/gaseous-tools.csproj b/gaseous-tools/gaseous-tools.csproj index 33e2fc7..b63788c 100644 --- a/gaseous-tools/gaseous-tools.csproj +++ b/gaseous-tools/gaseous-tools.csproj @@ -16,6 +16,7 @@ + @@ -24,5 +25,6 @@ +