Add enhanced schedule management for background tasks (#267)
This commit is contained in:
51
README.MD
51
README.MD
@@ -73,55 +73,8 @@ When Gaseous-Server is started for the first time, it creates a configuration fi
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Docker
|
# Installation
|
||||||
### Deploy with the prebuilt Docker image
|
See https://github.com/gaseous-project/gaseous-server/wiki/Installation for installation instructions.
|
||||||
Dockerfile and docker-compose.yml files have been provided to make deployment of the server as easy as possible.
|
|
||||||
1. Download the docker-compose-{database}.yml file for the database type you would like to use.
|
|
||||||
2. Open the docker-compose.yml file and edit the igdbclientid and igdbclientsecret to the values retrieved from your IGDB account
|
|
||||||
3. Run the command ```docker-compose up -d```
|
|
||||||
4. Connect to the host on port 5198
|
|
||||||
|
|
||||||
### Build and deploy a Docker image from source
|
|
||||||
Dockerfile and docker-compose-build.yml files have been provided to make deployment of the server as easy as possible.
|
|
||||||
1. Clone the repo with ```git clone https://github.com/gaseous-project/gaseous-server.git```
|
|
||||||
2. Change into the gaseous-server directory
|
|
||||||
3. Open the docker-compose-{database}-build.yml file and edit the igdbclientid and igdbclientsecret to the values retrieved from your IGDB account
|
|
||||||
4. Run the command ```docker-compose --file docker-compose-{database}-build.yml up -d```
|
|
||||||
5. Connect to the host on port 5198
|
|
||||||
|
|
||||||
## Source
|
|
||||||
### Build and deploy
|
|
||||||
1. Install and configure a MariaDB or MySQL instance - this is beyond the scope of this document
|
|
||||||
2. Install the dotnet 7.0 packages appropriate for your operating system
|
|
||||||
* See: https://learn.microsoft.com/en-us/dotnet/core/install/linux
|
|
||||||
3. Create a database user with permission to create a databse. Gaseous will create the new database and apply the database schema on it's first startup.
|
|
||||||
4. Clone the repo with ```git clone https://github.com/gaseous-project/gaseous-server.git```
|
|
||||||
5. Change into the gaseous-server directory
|
|
||||||
6. As the main branch is the development branch, you might want to change to a stable version - these are tagged with a version number. For example to change to the 1.5.0 release, use the command ```git checkout v1.5.0```
|
|
||||||
* Check the releases page for the version you would like to run: https://github.com/gaseous-project/gaseous-server/releases
|
|
||||||
7. Download the emulator files from ```https://cdn.emulatorjs.org/releases/4.0.9.zip``` and extract the files to ```gaseous-server/wwwroot/emulators/EmulatorJS```
|
|
||||||
8. Create a directory in the home directory of the user that will run the server. For example, if running as the user ```gaseous```, create the directory ```/home/gaseous/.gaseous-server```
|
|
||||||
9. Change into the ```.gaseous-server``` directory created in the previous step
|
|
||||||
10. Copy the JSON from the config file above into a new file named ```config.json```
|
|
||||||
11. Update the database section with the database server hostname, username, password, and port
|
|
||||||
12. Compile the server by changing back to the repo cloned earlier and executing:
|
|
||||||
* ```dotnet restore "gaseous-server/gaseous-server.csproj"```
|
|
||||||
* ```dotnet publish "gaseous-server/gaseous-server.csproj" --use-current-runtime --self-contained false -c Release -o <output directory>```
|
|
||||||
* replace ```<output directory>``` with the directory of your choosing. The compiled application will be copied there. For this example we'll use ```/opt/gaseous-server```
|
|
||||||
13. The server can then be started by executing ```dotnet /opt/gaseous-server/gaseous-server.dll```
|
|
||||||
* If you would like the server to run on a different ip address and port (for example 0.0.0.0:8080), add the --urls argument: ```dotnet /opt/gaseous-server/gaseous-server.dll --urls http://0.0.0.0:8080```
|
|
||||||
|
|
||||||
**Note**: The above instructions were tested on macOS Ventura, and Ubuntu 22.04.3. There was a report that Debian 11 had an issue with the git submodule commands (see: https://github.com/gaseous-project/gaseous-server/issues/71). This was possibly due to an older git package.
|
|
||||||
|
|
||||||
### Updating from source
|
|
||||||
1. Stop the server
|
|
||||||
2. Switch to the source directory
|
|
||||||
3. Update your repo:
|
|
||||||
* If running from the main branch, run ```git pull``` to update the repo
|
|
||||||
* If running from another branch or tag, run:
|
|
||||||
* ```git fetch```
|
|
||||||
* ```git checkout <branch or tag name>```
|
|
||||||
4. Run steps 12 and 13 from the above Build guide
|
|
||||||
|
|
||||||
# Adding Content
|
# Adding Content
|
||||||
While games can be added to the server without them, it is recommended adding some signature DAT files beforehand to allow for better matching of ROMs to games.
|
While games can be added to the server without them, it is recommended adding some signature DAT files beforehand to allow for better matching of ROMs to games.
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
|
using System.IO.Compression;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
|
|
||||||
@@ -120,6 +121,28 @@ namespace gaseous_server.Classes
|
|||||||
.Single(x => x.GetValue(null).Equals(value)),
|
.Single(x => x.GetValue(null).Equals(value)),
|
||||||
typeof(DescriptionAttribute)))?.Description ?? value.ToString();
|
typeof(DescriptionAttribute)))?.Description ?? value.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// compression
|
||||||
|
public static byte[] Compress(byte[] data)
|
||||||
|
{
|
||||||
|
MemoryStream output = new MemoryStream();
|
||||||
|
using (DeflateStream dstream = new DeflateStream(output, CompressionLevel.Optimal))
|
||||||
|
{
|
||||||
|
dstream.Write(data, 0, data.Length);
|
||||||
|
}
|
||||||
|
return output.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] Decompress(byte[] data)
|
||||||
|
{
|
||||||
|
MemoryStream input = new MemoryStream(data);
|
||||||
|
MemoryStream output = new MemoryStream();
|
||||||
|
using (DeflateStream dstream = new DeflateStream(input, CompressionMode.Decompress))
|
||||||
|
{
|
||||||
|
dstream.CopyTo(output);
|
||||||
|
}
|
||||||
|
return output.ToArray();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@@ -3,6 +3,7 @@ using System.Data;
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using IGDB.Models;
|
using IGDB.Models;
|
||||||
using gaseous_server.Classes.Metadata;
|
using gaseous_server.Classes.Metadata;
|
||||||
|
using NuGet.Common;
|
||||||
|
|
||||||
namespace gaseous_server.Classes
|
namespace gaseous_server.Classes
|
||||||
{
|
{
|
||||||
@@ -161,7 +162,7 @@ namespace gaseous_server.Classes
|
|||||||
File.WriteAllText(ConfigurationFilePath, configRaw);
|
File.WriteAllText(ConfigurationFilePath, configRaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Dictionary<string, string> AppSettings = new Dictionary<string, string>();
|
private static Dictionary<string, object> AppSettings = new Dictionary<string, object>();
|
||||||
|
|
||||||
public static void InitSettings()
|
public static void InitSettings()
|
||||||
{
|
{
|
||||||
@@ -173,43 +174,67 @@ namespace gaseous_server.Classes
|
|||||||
{
|
{
|
||||||
if (AppSettings.ContainsKey((string)dataRow["Setting"]))
|
if (AppSettings.ContainsKey((string)dataRow["Setting"]))
|
||||||
{
|
{
|
||||||
AppSettings[(string)dataRow["Setting"]] = (string)dataRow["Value"];
|
if ((int)dataRow["ValueType"] == 0)
|
||||||
|
{
|
||||||
|
AppSettings[(string)dataRow["Setting"]] = (string)dataRow["Value"];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AppSettings[(string)dataRow["Setting"]] = (DateTime)dataRow["ValueDate"];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AppSettings.Add((string)dataRow["Setting"], (string)dataRow["Value"]);
|
if ((int)dataRow["ValueType"] == 0)
|
||||||
|
{
|
||||||
|
AppSettings.Add((string)dataRow["Setting"], (string)dataRow["Value"]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AppSettings.Add((string)dataRow["Setting"], (DateTime)dataRow["ValueDate"]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string ReadSetting(string SettingName, string DefaultValue)
|
public static T ReadSetting<T>(string SettingName, T DefaultValue)
|
||||||
{
|
{
|
||||||
if (AppSettings.ContainsKey(SettingName))
|
if (AppSettings.ContainsKey(SettingName))
|
||||||
{
|
{
|
||||||
return AppSettings[SettingName];
|
return (T)AppSettings[SettingName];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
string sql = "SELECT Value FROM Settings WHERE Setting = @SettingName";
|
string sql = "SELECT Value, ValueDate FROM Settings WHERE Setting = @SettingName";
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
Dictionary<string, object> dbDict = new Dictionary<string, object>
|
||||||
dbDict.Add("SettingName", SettingName);
|
{
|
||||||
dbDict.Add("Value", DefaultValue);
|
{ "SettingName", SettingName }
|
||||||
|
};
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Logging.Log(Logging.LogType.Debug, "Database", "Reading setting '" + SettingName + "'");
|
Logging.Log(Logging.LogType.Debug, "Database", "Reading setting '" + SettingName + "'");
|
||||||
DataTable dbResponse = db.ExecuteCMD(sql, dbDict);
|
DataTable dbResponse = db.ExecuteCMD(sql, dbDict);
|
||||||
|
Type type = typeof(T);
|
||||||
if (dbResponse.Rows.Count == 0)
|
if (dbResponse.Rows.Count == 0)
|
||||||
{
|
{
|
||||||
// no value with that name stored - respond with the default value
|
// no value with that name stored - respond with the default value
|
||||||
SetSetting(SettingName, DefaultValue);
|
SetSetting<T>(SettingName, DefaultValue);
|
||||||
return DefaultValue;
|
return DefaultValue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AppSettings.Add(SettingName, (string)dbResponse.Rows[0][0]);
|
if (type.ToString() == "System.DateTime")
|
||||||
return (string)dbResponse.Rows[0][0];
|
{
|
||||||
|
AppSettings.Add(SettingName, dbResponse.Rows[0]["ValueDate"]);
|
||||||
|
return (T)dbResponse.Rows[0]["ValueDate"];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AppSettings.Add(SettingName, dbResponse.Rows[0]["Value"]);
|
||||||
|
return (T)dbResponse.Rows[0]["Value"];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -220,13 +245,32 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SetSetting(string SettingName, string Value)
|
public static void SetSetting<T>(string SettingName, T Value)
|
||||||
{
|
{
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
string sql = "REPLACE INTO Settings (Setting, Value) VALUES (@SettingName, @Value)";
|
string sql = "REPLACE INTO Settings (Setting, ValueType, Value, ValueDate) VALUES (@SettingName, @ValueType, @Value, @ValueDate)";
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
Dictionary<string, object> dbDict;
|
||||||
dbDict.Add("SettingName", SettingName);
|
Type type = typeof(T);
|
||||||
dbDict.Add("Value", Value);
|
if (type.ToString() == "System.DateTime")
|
||||||
|
{
|
||||||
|
dbDict = new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
{ "SettingName", SettingName },
|
||||||
|
{ "ValueType", 1 },
|
||||||
|
{ "Value", null },
|
||||||
|
{ "ValueDate", Value }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dbDict = new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
{ "SettingName", SettingName },
|
||||||
|
{ "ValueType", 0 },
|
||||||
|
{ "Value", Value },
|
||||||
|
{ "ValueDate", null }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
Logging.Log(Logging.LogType.Debug, "Database", "Storing setting '" + SettingName + "' to value: '" + Value + "'");
|
Logging.Log(Logging.LogType.Debug, "Database", "Storing setting '" + SettingName + "' to value: '" + Value + "'");
|
||||||
try
|
try
|
||||||
@@ -341,11 +385,11 @@ namespace gaseous_server.Classes
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return ReadSetting("LibraryRootDirectory", Path.Combine(Config.ConfigurationPath, "Data"));
|
return ReadSetting<string>("LibraryRootDirectory", Path.Combine(Config.ConfigurationPath, "Data"));
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
SetSetting("LibraryRootDirectory", value);
|
SetSetting<string>("LibraryRootDirectory", value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -452,13 +452,15 @@ namespace gaseous_server.Classes
|
|||||||
|
|
||||||
if (romDT.Rows.Count > 0)
|
if (romDT.Rows.Count > 0)
|
||||||
{
|
{
|
||||||
foreach (DataRow dr in romDT.Rows)
|
for (int i = 0; i < romDT.Rows.Count; i++)
|
||||||
{
|
{
|
||||||
Logging.Log(Logging.LogType.Information, "Organise Library", "Processing ROM " + dr["name"]);
|
SetStatus(i, romDT.Rows.Count, "Processing file " + romDT.Rows[i]["name"]);
|
||||||
long RomId = (long)dr["id"];
|
Logging.Log(Logging.LogType.Information, "Organise Library", "(" + i + "/" + romDT.Rows.Count + ") Processing ROM " + romDT.Rows[i]["name"]);
|
||||||
|
long RomId = (long)romDT.Rows[i]["id"];
|
||||||
MoveGameFile(RomId);
|
MoveGameFile(RomId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ClearStatus();
|
||||||
|
|
||||||
// clean up empty directories
|
// clean up empty directories
|
||||||
DeleteOrphanedDirectories(GameLibrary.GetDefaultLibrary.Path);
|
DeleteOrphanedDirectories(GameLibrary.GetDefaultLibrary.Path);
|
||||||
|
@@ -9,7 +9,7 @@ namespace gaseous_server.Classes
|
|||||||
{
|
{
|
||||||
const int MaxFileAge = 30;
|
const int MaxFileAge = 30;
|
||||||
|
|
||||||
public void RunMaintenance()
|
public void RunDailyMaintenance()
|
||||||
{
|
{
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
string sql = "";
|
string sql = "";
|
||||||
@@ -33,8 +33,8 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
|
|
||||||
// delete old logs
|
// delete old logs
|
||||||
sql = "DELETE FROM ServerLogs WHERE EventTime < @EventRententionDate;";
|
sql = "DELETE FROM ServerLogs WHERE EventTime < @EventRetentionDate;";
|
||||||
dbDict.Add("EventRententionDate", DateTime.UtcNow.AddDays(Config.LoggingConfiguration.LogRetention * -1));
|
dbDict.Add("EventRetentionDate", DateTime.UtcNow.AddDays(Config.LoggingConfiguration.LogRetention * -1));
|
||||||
db.ExecuteCMD(sql, dbDict);
|
db.ExecuteCMD(sql, dbDict);
|
||||||
|
|
||||||
// delete files and directories older than 7 days in PathsToClean
|
// delete files and directories older than 7 days in PathsToClean
|
||||||
@@ -69,6 +69,13 @@ namespace gaseous_server.Classes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RunWeeklyMaintenance()
|
||||||
|
{
|
||||||
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
|
string sql = "";
|
||||||
|
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||||
|
|
||||||
Logging.Log(Logging.LogType.Information, "Maintenance", "Optimising database tables");
|
Logging.Log(Logging.LogType.Information, "Maintenance", "Optimising database tables");
|
||||||
sql = "SHOW FULL TABLES WHERE Table_Type = 'BASE TABLE';";
|
sql = "SHOW FULL TABLES WHERE Table_Type = 'BASE TABLE';";
|
||||||
|
@@ -12,6 +12,7 @@ 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;
|
using Microsoft.AspNetCore.Razor.Hosting;
|
||||||
|
using RestEase;
|
||||||
|
|
||||||
namespace gaseous_server.Controllers
|
namespace gaseous_server.Controllers
|
||||||
{
|
{
|
||||||
@@ -96,7 +97,7 @@ 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<string>("FirstRunStatus", "0") + ";" + Environment.NewLine +
|
||||||
"var AgeRatingBoardsStrings = " + JsonSerializer.Serialize(ClassificationBoardsStrings, new JsonSerializerOptions{
|
"var AgeRatingBoardsStrings = " + JsonSerializer.Serialize(ClassificationBoardsStrings, new JsonSerializerOptions{
|
||||||
WriteIndented = true
|
WriteIndented = true
|
||||||
}) + ";" + Environment.NewLine +
|
}) + ";" + Environment.NewLine +
|
||||||
@@ -113,19 +114,23 @@ namespace gaseous_server.Controllers
|
|||||||
[MapToApiVersion("1.0")]
|
[MapToApiVersion("1.0")]
|
||||||
[MapToApiVersion("1.1")]
|
[MapToApiVersion("1.1")]
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[Route("Settings/BackgroundTasks/Intervals")]
|
[Route("Settings/BackgroundTasks/Configuration")]
|
||||||
[Authorize(Roles = "Admin")]
|
[Authorize(Roles = "Admin")]
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
public ActionResult GetBackgroundTasks()
|
public ActionResult GetBackgroundTasks()
|
||||||
{
|
{
|
||||||
Dictionary<string, BackgroundTaskItem> Intervals = new Dictionary<string, BackgroundTaskItem>();
|
Dictionary<string, BackgroundTaskItem> Intervals = new Dictionary<string, BackgroundTaskItem>();
|
||||||
Intervals.Add(ProcessQueue.QueueItemType.SignatureIngestor.ToString(), new BackgroundTaskItem(ProcessQueue.QueueItemType.SignatureIngestor));
|
foreach (ProcessQueue.QueueItemType itemType in Enum.GetValues(typeof(ProcessQueue.QueueItemType)))
|
||||||
Intervals.Add(ProcessQueue.QueueItemType.TitleIngestor.ToString(), new BackgroundTaskItem(ProcessQueue.QueueItemType.TitleIngestor));
|
{
|
||||||
Intervals.Add(ProcessQueue.QueueItemType.MetadataRefresh.ToString(), new BackgroundTaskItem(ProcessQueue.QueueItemType.MetadataRefresh));
|
BackgroundTaskItem taskItem = new BackgroundTaskItem(itemType);
|
||||||
Intervals.Add(ProcessQueue.QueueItemType.OrganiseLibrary.ToString(), new BackgroundTaskItem(ProcessQueue.QueueItemType.OrganiseLibrary));
|
if (taskItem.UserManageable == true)
|
||||||
Intervals.Add(ProcessQueue.QueueItemType.LibraryScan.ToString(), new BackgroundTaskItem(ProcessQueue.QueueItemType.LibraryScan));
|
{
|
||||||
Intervals.Add(ProcessQueue.QueueItemType.Rematcher.ToString(), new BackgroundTaskItem(ProcessQueue.QueueItemType.Rematcher));
|
if (!Intervals.ContainsKey(itemType.ToString()))
|
||||||
Intervals.Add(ProcessQueue.QueueItemType.Maintainer.ToString(), new BackgroundTaskItem(ProcessQueue.QueueItemType.Maintainer));
|
{
|
||||||
|
Intervals.Add(itemType.ToString(), taskItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return Ok(Intervals);
|
return Ok(Intervals);
|
||||||
}
|
}
|
||||||
@@ -133,45 +138,102 @@ namespace gaseous_server.Controllers
|
|||||||
[MapToApiVersion("1.0")]
|
[MapToApiVersion("1.0")]
|
||||||
[MapToApiVersion("1.1")]
|
[MapToApiVersion("1.1")]
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[Route("Settings/BackgroundTasks/Intervals")]
|
[Route("Settings/BackgroundTasks/Configuration")]
|
||||||
[Authorize(Roles = "Admin")]
|
[Authorize(Roles = "Admin")]
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
public ActionResult SetBackgroundTasks(Dictionary<string, int> Intervals)
|
public ActionResult SetBackgroundTasks([FromBody] List<BackgroundTaskSettingsItem> model)
|
||||||
{
|
{
|
||||||
foreach (KeyValuePair<string, int> Interval in Intervals)
|
foreach (BackgroundTaskSettingsItem TaskConfiguration in model)
|
||||||
{
|
{
|
||||||
if (Enum.IsDefined(typeof(ProcessQueue.QueueItemType), Interval.Key))
|
if (Enum.IsDefined(typeof(ProcessQueue.QueueItemType), TaskConfiguration.Task))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
BackgroundTaskItem taskItem = new BackgroundTaskItem(
|
BackgroundTaskItem taskItem = new BackgroundTaskItem(
|
||||||
(ProcessQueue.QueueItemType)Enum.Parse(typeof(ProcessQueue.QueueItemType), Interval.Key)
|
(ProcessQueue.QueueItemType)Enum.Parse(typeof(ProcessQueue.QueueItemType), TaskConfiguration.Task)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (Interval.Value >= taskItem.MinimumAllowedValue)
|
if (taskItem.UserManageable == true)
|
||||||
{
|
{
|
||||||
Logging.Log(Logging.LogType.Information, "Update Background Task", "Updating task " + Interval.Key + " with new interval " + Interval.Value);
|
// update task enabled
|
||||||
|
Logging.Log(Logging.LogType.Information, "Update Background Task", "Updating task " + TaskConfiguration.Task + " with enabled value " + TaskConfiguration.Enabled.ToString());
|
||||||
|
|
||||||
Config.SetSetting("Interval_" + Interval.Key, Interval.Value.ToString());
|
Config.SetSetting<string>("Enabled_" + TaskConfiguration.Task, TaskConfiguration.Enabled.ToString());
|
||||||
|
|
||||||
// update existing process
|
// update existing process
|
||||||
foreach (ProcessQueue.QueueItem item in ProcessQueue.QueueItems)
|
foreach (ProcessQueue.QueueItem item in ProcessQueue.QueueItems)
|
||||||
{
|
{
|
||||||
if (item.ItemType.ToString().ToLower() == Interval.Key.ToLower())
|
if (item.ItemType.ToString().ToLower() == TaskConfiguration.Task.ToLower())
|
||||||
{
|
{
|
||||||
item.Interval = Interval.Value;
|
item.Enabled(Boolean.Parse(TaskConfiguration.Enabled.ToString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update task interval
|
||||||
|
if (TaskConfiguration.Interval >= taskItem.MinimumAllowedInterval)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Information, "Update Background Task", "Updating task " + TaskConfiguration.Task + " with new interval " + TaskConfiguration.Interval);
|
||||||
|
|
||||||
|
Config.SetSetting<string>("Interval_" + TaskConfiguration.Task, TaskConfiguration.Interval.ToString());
|
||||||
|
|
||||||
|
// update existing process
|
||||||
|
foreach (ProcessQueue.QueueItem item in ProcessQueue.QueueItems)
|
||||||
|
{
|
||||||
|
if (item.ItemType.ToString().ToLower() == TaskConfiguration.Task.ToLower())
|
||||||
|
{
|
||||||
|
item.Interval = TaskConfiguration.Interval;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Warning, "Update Background Task", "Interval " + TaskConfiguration.Interval.ToString() + " for task " + TaskConfiguration.Task + " is below the minimum allowed value of " + taskItem.MinimumAllowedInterval + ". Skipping.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// update task weekdays
|
||||||
|
Logging.Log(Logging.LogType.Information, "Update Background Task", "Updating task " + TaskConfiguration.Task + " with new weekdays " + String.Join(", ", TaskConfiguration.AllowedDays));
|
||||||
|
|
||||||
|
Config.SetSetting<string>("AllowedDays_" + TaskConfiguration.Task, Newtonsoft.Json.JsonConvert.SerializeObject(TaskConfiguration.AllowedDays));
|
||||||
|
|
||||||
|
// update existing process
|
||||||
|
foreach (ProcessQueue.QueueItem item in ProcessQueue.QueueItems)
|
||||||
|
{
|
||||||
|
if (item.ItemType.ToString().ToLower() == TaskConfiguration.Task.ToLower())
|
||||||
|
{
|
||||||
|
item.AllowedDays = TaskConfiguration.AllowedDays;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// update task hours
|
||||||
|
Logging.Log(Logging.LogType.Information, "Update Background Task", "Updating task " + TaskConfiguration.Task + " with new hours " + TaskConfiguration.AllowedStartHours + ":" + TaskConfiguration.AllowedStartMinutes.ToString("00") + " to " + TaskConfiguration.AllowedEndHours + ":" + TaskConfiguration.AllowedEndMinutes.ToString("00"));
|
||||||
|
|
||||||
|
Config.SetSetting<string>("AllowedStartHours_" + TaskConfiguration.Task, TaskConfiguration.AllowedStartHours.ToString());
|
||||||
|
Config.SetSetting<string>("AllowedStartMinutes_" + TaskConfiguration.Task, TaskConfiguration.AllowedStartMinutes.ToString());
|
||||||
|
Config.SetSetting<string>("AllowedEndHours_" + TaskConfiguration.Task, TaskConfiguration.AllowedEndHours.ToString());
|
||||||
|
Config.SetSetting<string>("AllowedEndMinutes_" + TaskConfiguration.Task, TaskConfiguration.AllowedEndMinutes.ToString());
|
||||||
|
|
||||||
|
// update existing process
|
||||||
|
foreach (ProcessQueue.QueueItem item in ProcessQueue.QueueItems)
|
||||||
|
{
|
||||||
|
if (item.ItemType.ToString().ToLower() == TaskConfiguration.Task.ToLower())
|
||||||
|
{
|
||||||
|
item.AllowedStartHours = TaskConfiguration.AllowedStartHours;
|
||||||
|
item.AllowedStartMinutes = TaskConfiguration.AllowedStartMinutes;
|
||||||
|
item.AllowedEndHours = TaskConfiguration.AllowedEndHours;
|
||||||
|
item.AllowedEndMinutes = TaskConfiguration.AllowedEndMinutes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
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.");
|
Logging.Log(Logging.LogType.Warning, "Update Background Task", "Unable to update non-user manageable task " + TaskConfiguration.Task + ". Skipping.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
// task name not defined
|
// task name not defined
|
||||||
Logging.Log(Logging.LogType.Warning, "Update Background Task", "Task " + Interval.Key + " is not user definable. Skipping.");
|
Logging.Log(Logging.LogType.Warning, "Update Background Task", "Task " + TaskConfiguration.Task + " is not user definable. Skipping.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -256,61 +318,387 @@ namespace gaseous_server.Controllers
|
|||||||
|
|
||||||
public class BackgroundTaskItem
|
public class BackgroundTaskItem
|
||||||
{
|
{
|
||||||
|
public BackgroundTaskItem()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public BackgroundTaskItem(ProcessQueue.QueueItemType TaskName)
|
public BackgroundTaskItem(ProcessQueue.QueueItemType TaskName)
|
||||||
{
|
{
|
||||||
this.Task = TaskName.ToString();
|
this.Task = TaskName.ToString();
|
||||||
|
this.TaskEnum = TaskName;
|
||||||
|
|
||||||
switch (TaskName)
|
switch (TaskName)
|
||||||
{
|
{
|
||||||
case ProcessQueue.QueueItemType.SignatureIngestor:
|
case ProcessQueue.QueueItemType.SignatureIngestor:
|
||||||
|
this._UserManageable = true;
|
||||||
this.DefaultInterval = 60;
|
this.DefaultInterval = 60;
|
||||||
this.MinimumAllowedValue = 20;
|
this.MinimumAllowedInterval = 20;
|
||||||
|
this.DefaultAllowedDays = new List<DayOfWeek>{
|
||||||
|
DayOfWeek.Sunday,
|
||||||
|
DayOfWeek.Monday,
|
||||||
|
DayOfWeek.Tuesday,
|
||||||
|
DayOfWeek.Wednesday,
|
||||||
|
DayOfWeek.Thursday,
|
||||||
|
DayOfWeek.Friday,
|
||||||
|
DayOfWeek.Saturday
|
||||||
|
};
|
||||||
|
this.DefaultAllowedStartHours = 0;
|
||||||
|
this.DefaultAllowedStartMinutes = 0;
|
||||||
|
this.DefaultAllowedEndHours = 23;
|
||||||
|
this.DefaultAllowedEndMinutes = 59;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ProcessQueue.QueueItemType.TitleIngestor:
|
case ProcessQueue.QueueItemType.TitleIngestor:
|
||||||
|
this._UserManageable = true;
|
||||||
this.DefaultInterval = 1;
|
this.DefaultInterval = 1;
|
||||||
this.MinimumAllowedValue = 1;
|
this.MinimumAllowedInterval = 1;
|
||||||
|
this.DefaultAllowedDays = new List<DayOfWeek>{
|
||||||
|
DayOfWeek.Sunday,
|
||||||
|
DayOfWeek.Monday,
|
||||||
|
DayOfWeek.Tuesday,
|
||||||
|
DayOfWeek.Wednesday,
|
||||||
|
DayOfWeek.Thursday,
|
||||||
|
DayOfWeek.Friday,
|
||||||
|
DayOfWeek.Saturday
|
||||||
|
};
|
||||||
|
this.DefaultAllowedStartHours = 0;
|
||||||
|
this.DefaultAllowedStartMinutes = 0;
|
||||||
|
this.DefaultAllowedEndHours = 23;
|
||||||
|
this.DefaultAllowedEndMinutes = 59;
|
||||||
|
this._Blocks = new List<ProcessQueue.QueueItemType>{
|
||||||
|
ProcessQueue.QueueItemType.OrganiseLibrary,
|
||||||
|
ProcessQueue.QueueItemType.LibraryScan,
|
||||||
|
ProcessQueue.QueueItemType.LibraryScanWorker
|
||||||
|
};
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ProcessQueue.QueueItemType.MetadataRefresh:
|
case ProcessQueue.QueueItemType.MetadataRefresh:
|
||||||
|
this._UserManageable = true;
|
||||||
this.DefaultInterval = 360;
|
this.DefaultInterval = 360;
|
||||||
this.MinimumAllowedValue = 360;
|
this.MinimumAllowedInterval = 360;
|
||||||
|
this.DefaultAllowedDays = new List<DayOfWeek>{
|
||||||
|
DayOfWeek.Sunday,
|
||||||
|
DayOfWeek.Monday,
|
||||||
|
DayOfWeek.Tuesday,
|
||||||
|
DayOfWeek.Wednesday,
|
||||||
|
DayOfWeek.Thursday,
|
||||||
|
DayOfWeek.Friday,
|
||||||
|
DayOfWeek.Saturday
|
||||||
|
};
|
||||||
|
this.DefaultAllowedStartHours = 0;
|
||||||
|
this.DefaultAllowedStartMinutes = 0;
|
||||||
|
this.DefaultAllowedEndHours = 23;
|
||||||
|
this.DefaultAllowedEndMinutes = 59;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ProcessQueue.QueueItemType.OrganiseLibrary:
|
case ProcessQueue.QueueItemType.OrganiseLibrary:
|
||||||
|
this._UserManageable = true;
|
||||||
this.DefaultInterval = 1440;
|
this.DefaultInterval = 1440;
|
||||||
this.MinimumAllowedValue = 120;
|
this.MinimumAllowedInterval = 120;
|
||||||
|
this.DefaultAllowedDays = new List<DayOfWeek>{
|
||||||
|
DayOfWeek.Sunday,
|
||||||
|
DayOfWeek.Monday,
|
||||||
|
DayOfWeek.Tuesday,
|
||||||
|
DayOfWeek.Wednesday,
|
||||||
|
DayOfWeek.Thursday,
|
||||||
|
DayOfWeek.Friday,
|
||||||
|
DayOfWeek.Saturday
|
||||||
|
};
|
||||||
|
this.DefaultAllowedStartHours = 0;
|
||||||
|
this.DefaultAllowedStartMinutes = 0;
|
||||||
|
this.DefaultAllowedEndHours = 23;
|
||||||
|
this.DefaultAllowedEndMinutes = 59;
|
||||||
|
this._Blocks = new List<ProcessQueue.QueueItemType>{
|
||||||
|
ProcessQueue.QueueItemType.LibraryScan,
|
||||||
|
ProcessQueue.QueueItemType.LibraryScanWorker,
|
||||||
|
ProcessQueue.QueueItemType.TitleIngestor,
|
||||||
|
ProcessQueue.QueueItemType.Rematcher
|
||||||
|
};
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ProcessQueue.QueueItemType.LibraryScan:
|
case ProcessQueue.QueueItemType.LibraryScan:
|
||||||
|
this._UserManageable = true;
|
||||||
this.DefaultInterval = 1440;
|
this.DefaultInterval = 1440;
|
||||||
this.MinimumAllowedValue = 120;
|
this.MinimumAllowedInterval = 120;
|
||||||
|
this.DefaultAllowedDays = new List<DayOfWeek>{
|
||||||
|
DayOfWeek.Sunday,
|
||||||
|
DayOfWeek.Monday,
|
||||||
|
DayOfWeek.Tuesday,
|
||||||
|
DayOfWeek.Wednesday,
|
||||||
|
DayOfWeek.Thursday,
|
||||||
|
DayOfWeek.Friday,
|
||||||
|
DayOfWeek.Saturday
|
||||||
|
};
|
||||||
|
this.DefaultAllowedStartHours = 0;
|
||||||
|
this.DefaultAllowedStartMinutes = 0;
|
||||||
|
this.DefaultAllowedEndHours = 23;
|
||||||
|
this.DefaultAllowedEndMinutes = 59;
|
||||||
|
this._Blocks = new List<ProcessQueue.QueueItemType>{
|
||||||
|
ProcessQueue.QueueItemType.OrganiseLibrary,
|
||||||
|
ProcessQueue.QueueItemType.Rematcher
|
||||||
|
};
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ProcessQueue.QueueItemType.Rematcher:
|
case ProcessQueue.QueueItemType.Rematcher:
|
||||||
|
this._UserManageable = true;
|
||||||
this.DefaultInterval = 1440;
|
this.DefaultInterval = 1440;
|
||||||
this.MinimumAllowedValue = 360;
|
this.MinimumAllowedInterval = 360;
|
||||||
|
this.DefaultAllowedDays = new List<DayOfWeek>{
|
||||||
|
DayOfWeek.Sunday,
|
||||||
|
DayOfWeek.Monday,
|
||||||
|
DayOfWeek.Tuesday,
|
||||||
|
DayOfWeek.Wednesday,
|
||||||
|
DayOfWeek.Thursday,
|
||||||
|
DayOfWeek.Friday,
|
||||||
|
DayOfWeek.Saturday
|
||||||
|
};
|
||||||
|
this.DefaultAllowedStartHours = 0;
|
||||||
|
this.DefaultAllowedStartMinutes = 0;
|
||||||
|
this.DefaultAllowedEndHours = 23;
|
||||||
|
this.DefaultAllowedEndMinutes = 59;
|
||||||
|
this._Blocks = new List<ProcessQueue.QueueItemType>{
|
||||||
|
ProcessQueue.QueueItemType.OrganiseLibrary,
|
||||||
|
ProcessQueue.QueueItemType.LibraryScan,
|
||||||
|
ProcessQueue.QueueItemType.LibraryScanWorker
|
||||||
|
};
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ProcessQueue.QueueItemType.Maintainer:
|
case ProcessQueue.QueueItemType.DailyMaintainer:
|
||||||
|
this._UserManageable = true;
|
||||||
|
this.DefaultInterval = 1440;
|
||||||
|
this.MinimumAllowedInterval = 1440;
|
||||||
|
this.DefaultAllowedDays = new List<DayOfWeek>{
|
||||||
|
DayOfWeek.Sunday,
|
||||||
|
DayOfWeek.Monday,
|
||||||
|
DayOfWeek.Tuesday,
|
||||||
|
DayOfWeek.Wednesday,
|
||||||
|
DayOfWeek.Thursday,
|
||||||
|
DayOfWeek.Friday,
|
||||||
|
DayOfWeek.Saturday
|
||||||
|
};
|
||||||
|
this.DefaultAllowedStartHours = 1;
|
||||||
|
this.DefaultAllowedStartMinutes = 0;
|
||||||
|
this.DefaultAllowedEndHours = 5;
|
||||||
|
this.DefaultAllowedEndMinutes = 59;
|
||||||
|
this._Blocks = new List<ProcessQueue.QueueItemType>{
|
||||||
|
ProcessQueue.QueueItemType.All
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ProcessQueue.QueueItemType.WeeklyMaintainer:
|
||||||
|
this._UserManageable = true;
|
||||||
this.DefaultInterval = 10080;
|
this.DefaultInterval = 10080;
|
||||||
this.MinimumAllowedValue = 10080;
|
this.MinimumAllowedInterval = 10080;
|
||||||
|
this.DefaultAllowedDays = new List<DayOfWeek>{
|
||||||
|
DayOfWeek.Monday
|
||||||
|
};
|
||||||
|
this.DefaultAllowedStartHours = 1;
|
||||||
|
this.DefaultAllowedStartMinutes = 0;
|
||||||
|
this.DefaultAllowedEndHours = 5;
|
||||||
|
this.DefaultAllowedEndMinutes = 59;
|
||||||
|
this._Blocks = new List<ProcessQueue.QueueItemType>{
|
||||||
|
ProcessQueue.QueueItemType.All
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ProcessQueue.QueueItemType.BackgroundDatabaseUpgrade:
|
||||||
|
this._UserManageable = false;
|
||||||
|
this.DefaultInterval = 1;
|
||||||
|
this.MinimumAllowedInterval = 1;
|
||||||
|
this.DefaultAllowedDays = new List<DayOfWeek>{
|
||||||
|
DayOfWeek.Sunday,
|
||||||
|
DayOfWeek.Monday,
|
||||||
|
DayOfWeek.Tuesday,
|
||||||
|
DayOfWeek.Wednesday,
|
||||||
|
DayOfWeek.Thursday,
|
||||||
|
DayOfWeek.Friday,
|
||||||
|
DayOfWeek.Saturday
|
||||||
|
};
|
||||||
|
this.DefaultAllowedStartHours = 0;
|
||||||
|
this.DefaultAllowedStartMinutes = 0;
|
||||||
|
this.DefaultAllowedEndHours = 23;
|
||||||
|
this.DefaultAllowedEndMinutes = 59;
|
||||||
|
this._Blocks.Add(ProcessQueue.QueueItemType.All);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ProcessQueue.QueueItemType.TempCleanup:
|
||||||
|
this._UserManageable = true;
|
||||||
|
this.DefaultInterval = 1;
|
||||||
|
this.MinimumAllowedInterval = 1;
|
||||||
|
this.DefaultAllowedDays = new List<DayOfWeek>{
|
||||||
|
DayOfWeek.Sunday,
|
||||||
|
DayOfWeek.Monday,
|
||||||
|
DayOfWeek.Tuesday,
|
||||||
|
DayOfWeek.Wednesday,
|
||||||
|
DayOfWeek.Thursday,
|
||||||
|
DayOfWeek.Friday,
|
||||||
|
DayOfWeek.Saturday
|
||||||
|
};
|
||||||
|
this.DefaultAllowedStartHours = 0;
|
||||||
|
this.DefaultAllowedStartMinutes = 0;
|
||||||
|
this.DefaultAllowedEndHours = 23;
|
||||||
|
this.DefaultAllowedEndMinutes = 59;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new Exception("Invalid task");
|
this._UserManageable = false;
|
||||||
|
this.DefaultAllowedDays = new List<DayOfWeek>{
|
||||||
|
DayOfWeek.Sunday,
|
||||||
|
DayOfWeek.Monday,
|
||||||
|
DayOfWeek.Tuesday,
|
||||||
|
DayOfWeek.Wednesday,
|
||||||
|
DayOfWeek.Thursday,
|
||||||
|
DayOfWeek.Friday,
|
||||||
|
DayOfWeek.Saturday
|
||||||
|
};
|
||||||
|
this.DefaultAllowedStartHours = 0;
|
||||||
|
this.DefaultAllowedStartMinutes = 0;
|
||||||
|
this.DefaultAllowedEndHours = 23;
|
||||||
|
this.DefaultAllowedEndMinutes = 59;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Task { get; set; }
|
public string Task { get; set; }
|
||||||
|
public ProcessQueue.QueueItemType TaskEnum { get; set; }
|
||||||
|
public bool Enabled
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_UserManageable == true)
|
||||||
|
{
|
||||||
|
return bool.Parse(Config.ReadSetting<string>("Enabled_" + Task, true.ToString()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_UserManageable == true)
|
||||||
|
{
|
||||||
|
Config.SetSetting<string>("Enabled_" + Task, value.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private bool _UserManageable;
|
||||||
|
public bool UserManageable => _UserManageable;
|
||||||
public int Interval {
|
public int Interval {
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return int.Parse(Config.ReadSetting("Interval_" + Task, DefaultInterval.ToString()));
|
return int.Parse(Config.ReadSetting<string>("Interval_" + Task, DefaultInterval.ToString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public int DefaultInterval { get; set; }
|
public int DefaultInterval { get; set; }
|
||||||
public int MinimumAllowedValue { get; set; }
|
public int MinimumAllowedInterval { get; set; }
|
||||||
|
public List<DayOfWeek> AllowedDays
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
string jsonDefaultAllowedDays = Newtonsoft.Json.JsonConvert.SerializeObject(DefaultAllowedDays);
|
||||||
|
return Newtonsoft.Json.JsonConvert.DeserializeObject<List<DayOfWeek>>(Config.ReadSetting<string>("AllowedDays_" + Task, jsonDefaultAllowedDays));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public int AllowedStartHours
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return int.Parse(Config.ReadSetting<string>("AllowedStartHours_" + Task, DefaultAllowedStartHours.ToString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public int AllowedStartMinutes
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return int.Parse(Config.ReadSetting<string>("AllowedStartMinutes_" + Task, DefaultAllowedStartMinutes.ToString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public int AllowedEndHours
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return int.Parse(Config.ReadSetting<string>("AllowedEndHours_" + Task, DefaultAllowedEndHours.ToString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public int AllowedEndMinutes
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return int.Parse(Config.ReadSetting<string>("AllowedEndMinutes_" + Task, DefaultAllowedEndMinutes.ToString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public List<DayOfWeek> DefaultAllowedDays { get; set; }
|
||||||
|
public int DefaultAllowedStartHours { get; set; }
|
||||||
|
public int DefaultAllowedStartMinutes { get; set; }
|
||||||
|
public int DefaultAllowedEndHours { get; set; }
|
||||||
|
public int DefaultAllowedEndMinutes { get; set; }
|
||||||
|
private List<ProcessQueue.QueueItemType> _Blocks = new List<ProcessQueue.QueueItemType>();
|
||||||
|
public List<ProcessQueue.QueueItemType> Blocks
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_Blocks.Contains(ProcessQueue.QueueItemType.All))
|
||||||
|
{
|
||||||
|
List<ProcessQueue.QueueItemType> blockList = new List<ProcessQueue.QueueItemType>();
|
||||||
|
List<ProcessQueue.QueueItemType> skipBlockItems = new List<ProcessQueue.QueueItemType>{
|
||||||
|
ProcessQueue.QueueItemType.All,
|
||||||
|
ProcessQueue.QueueItemType.NotConfigured,
|
||||||
|
this.TaskEnum
|
||||||
|
};
|
||||||
|
foreach (ProcessQueue.QueueItemType blockType in Enum.GetValues(typeof(ProcessQueue.QueueItemType)))
|
||||||
|
{
|
||||||
|
if (!skipBlockItems.Contains(blockType))
|
||||||
|
{
|
||||||
|
blockList.Add(blockType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return blockList;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return _Blocks;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public List<ProcessQueue.QueueItemType> BlockedBy
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
List<ProcessQueue.QueueItemType> blockedBy = new List<ProcessQueue.QueueItemType>();
|
||||||
|
|
||||||
|
List<BackgroundTaskItem> backgroundTaskItems = new List<BackgroundTaskItem>();
|
||||||
|
foreach (ProcessQueue.QueueItemType blockType in Enum.GetValues(typeof(ProcessQueue.QueueItemType)))
|
||||||
|
{
|
||||||
|
if (blockType != this.TaskEnum)
|
||||||
|
{
|
||||||
|
BackgroundTaskItem taskItem = new BackgroundTaskItem(blockType);
|
||||||
|
if (taskItem.Blocks.Contains(this.TaskEnum))
|
||||||
|
{
|
||||||
|
if (!blockedBy.Contains(blockType))
|
||||||
|
{
|
||||||
|
blockedBy.Add(blockType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return blockedBy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class BackgroundTaskSettingsItem
|
||||||
|
{
|
||||||
|
public string Task { get; set; }
|
||||||
|
public bool Enabled { get; set; }
|
||||||
|
public int Interval { get; set; }
|
||||||
|
public List<DayOfWeek> AllowedDays { get; set; }
|
||||||
|
public int AllowedStartHours { get; set; }
|
||||||
|
public int AllowedStartMinutes { get; set; }
|
||||||
|
public int AllowedEndHours { get; set; }
|
||||||
|
public int AllowedEndMinutes { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SystemSettingsModel
|
public class SystemSettingsModel
|
||||||
|
@@ -40,7 +40,7 @@ namespace gaseous_server.Controllers
|
|||||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
public async Task<ActionResult> CreateAdminAccount(Authentication.RegisterViewModel model)
|
public async Task<ActionResult> CreateAdminAccount(Authentication.RegisterViewModel model)
|
||||||
{
|
{
|
||||||
if (Config.ReadSetting("FirstRunStatus", "0") == "0")
|
if (Config.ReadSetting<string>("FirstRunStatus", "0") == "0")
|
||||||
{
|
{
|
||||||
if (ModelState.IsValid)
|
if (ModelState.IsValid)
|
||||||
{
|
{
|
||||||
@@ -68,7 +68,7 @@ namespace gaseous_server.Controllers
|
|||||||
await _signInManager.SignInAsync(user, isPersistent: true);
|
await _signInManager.SignInAsync(user, isPersistent: true);
|
||||||
|
|
||||||
Logging.Log(Logging.LogType.Information, "First Run", "Setting first run state to 1");
|
Logging.Log(Logging.LogType.Information, "First Run", "Setting first run state to 1");
|
||||||
Config.SetSetting("FirstRunStatus", "1");
|
Config.SetSetting<string>("FirstRunStatus", "1");
|
||||||
|
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
|
@@ -37,8 +37,10 @@ namespace gaseous_server.Controllers.v1_1
|
|||||||
{
|
{
|
||||||
var user = await _userManager.GetUserAsync(User);
|
var user = await _userManager.GetUserAsync(User);
|
||||||
|
|
||||||
|
byte[] CompressedState = Common.Compress(uploadState.StateByteArray);
|
||||||
|
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
string sql = "INSERT INTO GameState (UserId, RomId, IsMediaGroup, StateDateTime, Name, Screenshot, State) VALUES (@userid, @romid, @ismediagroup, @statedatetime, @name, @screenshot, @state); SELECT LAST_INSERT_ID();";
|
string sql = "INSERT INTO GameState (UserId, RomId, IsMediaGroup, StateDateTime, Name, Screenshot, State, Zipped) VALUES (@userid, @romid, @ismediagroup, @statedatetime, @name, @screenshot, @state, @zipped); SELECT LAST_INSERT_ID();";
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>
|
Dictionary<string, object> dbDict = new Dictionary<string, object>
|
||||||
{
|
{
|
||||||
{ "userid", user.Id },
|
{ "userid", user.Id },
|
||||||
@@ -47,10 +49,20 @@ namespace gaseous_server.Controllers.v1_1
|
|||||||
{ "statedatetime", DateTime.UtcNow },
|
{ "statedatetime", DateTime.UtcNow },
|
||||||
{ "name", "" },
|
{ "name", "" },
|
||||||
{ "screenshot", uploadState.ScreenshotByteArray },
|
{ "screenshot", uploadState.ScreenshotByteArray },
|
||||||
{ "state", uploadState.StateByteArray }
|
{ "state", CompressedState },
|
||||||
|
{ "zipped", true }
|
||||||
};
|
};
|
||||||
DataTable data = db.ExecuteCMD(sql, dbDict);
|
DataTable data = db.ExecuteCMD(sql, dbDict);
|
||||||
|
|
||||||
|
if (IsMediaGroup == false)
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Information, "Save State", "Saved state for rom id " + RomId + ". State size: " + uploadState.StateByteArrayBase64.Length + " Compressed size: " + CompressedState.Length);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Logging.Log(Logging.LogType.Information, "Save State", "Saved state for media group id " + RomId + ". State size: " + uploadState.StateByteArrayBase64.Length + " Compressed size: " + CompressedState.Length);
|
||||||
|
}
|
||||||
|
|
||||||
return Ok(await GetStateAsync(RomId, (long)(ulong)data.Rows[0][0], IsMediaGroup));
|
return Ok(await GetStateAsync(RomId, (long)(ulong)data.Rows[0][0], IsMediaGroup));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,7 +236,7 @@ namespace gaseous_server.Controllers.v1_1
|
|||||||
{
|
{
|
||||||
var user = await _userManager.GetUserAsync(User);
|
var user = await _userManager.GetUserAsync(User);
|
||||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||||
string sql = "SELECT State FROM GameState WHERE Id = @id AND RomId = @romid AND IsMediaGroup = @ismediagroup AND UserId = @userid;";
|
string sql = "SELECT Zipped, State FROM GameState WHERE Id = @id AND RomId = @romid AND IsMediaGroup = @ismediagroup AND UserId = @userid;";
|
||||||
Dictionary<string, object> dbDict = new Dictionary<string, object>
|
Dictionary<string, object> dbDict = new Dictionary<string, object>
|
||||||
{
|
{
|
||||||
{ "id", StateId },
|
{ "id", StateId },
|
||||||
@@ -242,7 +254,15 @@ namespace gaseous_server.Controllers.v1_1
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
string filename = "savestate.state";
|
string filename = "savestate.state";
|
||||||
byte[] bytes = (byte[])data.Rows[0][0];
|
byte[] bytes;
|
||||||
|
if ((bool)data.Rows[0]["Zipped"] == false)
|
||||||
|
{
|
||||||
|
bytes = (byte[])data.Rows[0]["State"];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bytes = Common.Decompress((byte[])data.Rows[0]["State"]);
|
||||||
|
}
|
||||||
string contentType = "application/octet-stream";
|
string contentType = "application/octet-stream";
|
||||||
|
|
||||||
var cd = new System.Net.Mime.ContentDisposition
|
var cd = new System.Net.Mime.ContentDisposition
|
||||||
|
@@ -2,6 +2,8 @@
|
|||||||
using System.ComponentModel.Design.Serialization;
|
using System.ComponentModel.Design.Serialization;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using gaseous_server.Classes;
|
using gaseous_server.Classes;
|
||||||
|
using gaseous_server.Controllers;
|
||||||
|
using Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Manage.Internal;
|
||||||
using NuGet.Common;
|
using NuGet.Common;
|
||||||
using NuGet.Packaging;
|
using NuGet.Packaging;
|
||||||
|
|
||||||
@@ -13,25 +15,63 @@ namespace gaseous_server
|
|||||||
|
|
||||||
public class QueueItem
|
public class QueueItem
|
||||||
{
|
{
|
||||||
|
public QueueItem(QueueItemType ItemType, bool AllowManualStart = true, bool RemoveWhenStopped = false)
|
||||||
|
{
|
||||||
|
_ItemType = ItemType;
|
||||||
|
_ItemState = QueueItemState.NeverStarted;
|
||||||
|
_LastRunTime = Config.ReadSetting<DateTime>("LastRun_" + _ItemType.ToString(), DateTime.UtcNow.AddMinutes(-5));
|
||||||
|
_AllowManualStart = AllowManualStart;
|
||||||
|
_RemoveWhenStopped = RemoveWhenStopped;
|
||||||
|
|
||||||
|
// load queueitem configuration
|
||||||
|
BackgroundTaskItem defaultItem = new BackgroundTaskItem(ItemType);
|
||||||
|
Enabled(defaultItem.Enabled);
|
||||||
|
_Interval = defaultItem.Interval;
|
||||||
|
_AllowedDays = defaultItem.AllowedDays;
|
||||||
|
AllowedStartHours = defaultItem.AllowedStartHours;
|
||||||
|
AllowedStartMinutes = defaultItem.AllowedStartMinutes;
|
||||||
|
AllowedEndHours = defaultItem.AllowedEndHours;
|
||||||
|
AllowedEndMinutes = defaultItem.AllowedEndMinutes;
|
||||||
|
_Blocks = defaultItem.Blocks;
|
||||||
|
}
|
||||||
|
|
||||||
public QueueItem(QueueItemType ItemType, int ExecutionInterval, bool AllowManualStart = true, bool RemoveWhenStopped = false)
|
public QueueItem(QueueItemType ItemType, int ExecutionInterval, bool AllowManualStart = true, bool RemoveWhenStopped = false)
|
||||||
{
|
{
|
||||||
_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"))).AddMinutes(-5);
|
_LastRunTime = Config.ReadSetting<DateTime>("LastRun_" + _ItemType.ToString(), DateTime.UtcNow.AddMinutes(-5));
|
||||||
_Interval = ExecutionInterval;
|
_Interval = ExecutionInterval;
|
||||||
_AllowManualStart = AllowManualStart;
|
_AllowManualStart = AllowManualStart;
|
||||||
_RemoveWhenStopped = RemoveWhenStopped;
|
_RemoveWhenStopped = RemoveWhenStopped;
|
||||||
|
|
||||||
|
// load timing defaults
|
||||||
|
BackgroundTaskItem defaultItem = new BackgroundTaskItem(ItemType);
|
||||||
|
Enabled(defaultItem.Enabled);
|
||||||
|
_AllowedDays = defaultItem.AllowedDays;
|
||||||
|
AllowedStartHours = defaultItem.AllowedStartHours;
|
||||||
|
AllowedStartMinutes = defaultItem.AllowedStartMinutes;
|
||||||
|
AllowedEndHours = defaultItem.AllowedEndHours;
|
||||||
|
AllowedEndMinutes = defaultItem.AllowedEndMinutes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public QueueItem(QueueItemType ItemType, int ExecutionInterval, List<QueueItemType> Blocks, bool AllowManualStart = true, bool RemoveWhenStopped = false)
|
public QueueItem(QueueItemType ItemType, int ExecutionInterval, List<QueueItemType> Blocks, bool AllowManualStart = true, bool RemoveWhenStopped = false)
|
||||||
{
|
{
|
||||||
_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"))).AddMinutes(-5);
|
_LastRunTime = Config.ReadSetting<DateTime>("LastRun_" + _ItemType.ToString(), DateTime.UtcNow.AddMinutes(-5));
|
||||||
_Interval = ExecutionInterval;
|
_Interval = ExecutionInterval;
|
||||||
_AllowManualStart = AllowManualStart;
|
_AllowManualStart = AllowManualStart;
|
||||||
_RemoveWhenStopped = RemoveWhenStopped;
|
_RemoveWhenStopped = RemoveWhenStopped;
|
||||||
_Blocks = Blocks;
|
_Blocks = Blocks;
|
||||||
|
|
||||||
|
// load timing defaults
|
||||||
|
BackgroundTaskItem defaultItem = new BackgroundTaskItem(ItemType);
|
||||||
|
Enabled(defaultItem.Enabled);
|
||||||
|
_AllowedDays = defaultItem.AllowedDays;
|
||||||
|
AllowedStartHours = defaultItem.AllowedStartHours;
|
||||||
|
AllowedStartMinutes = defaultItem.AllowedStartMinutes;
|
||||||
|
AllowedEndHours = defaultItem.AllowedEndHours;
|
||||||
|
AllowedEndMinutes = defaultItem.AllowedEndMinutes;
|
||||||
}
|
}
|
||||||
|
|
||||||
private QueueItemType _ItemType = QueueItemType.NotConfigured;
|
private QueueItemType _ItemType = QueueItemType.NotConfigured;
|
||||||
@@ -42,13 +82,15 @@ namespace gaseous_server
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return DateTime.Parse(Config.ReadSetting("LastRun_" + _ItemType.ToString(), DateTime.UtcNow.ToString("yyyy-MM-ddThh:mm:ssZ")));
|
// return DateTime.Parse(Config.ReadSetting("LastRun_" + _ItemType.ToString(), DateTime.UtcNow.ToString("yyyy-MM-ddThh:mm:ssZ")));
|
||||||
|
return Config.ReadSetting<DateTime>("LastRun_" + _ItemType.ToString(), DateTime.UtcNow);
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (_SaveLastRunTime == true)
|
if (_SaveLastRunTime == true)
|
||||||
{
|
{
|
||||||
Config.SetSetting("LastRun_" + _ItemType.ToString(), value.ToString("yyyy-MM-ddThh:mm:ssZ"));
|
//Config.SetSetting("LastRun_" + _ItemType.ToString(), value.ToString("yyyy-MM-ddThh:mm:ssZ"));
|
||||||
|
Config.SetSetting<DateTime>("LastRun_" + _ItemType.ToString(), value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -61,8 +103,33 @@ namespace gaseous_server
|
|||||||
private bool _RemoveWhenStopped = false;
|
private bool _RemoveWhenStopped = false;
|
||||||
private bool _IsBlocked = false;
|
private bool _IsBlocked = false;
|
||||||
private string _CorrelationId = "";
|
private string _CorrelationId = "";
|
||||||
|
private List<DayOfWeek> _AllowedDays = new List<DayOfWeek>
|
||||||
|
{
|
||||||
|
DayOfWeek.Sunday,
|
||||||
|
DayOfWeek.Monday,
|
||||||
|
DayOfWeek.Tuesday,
|
||||||
|
DayOfWeek.Wednesday,
|
||||||
|
DayOfWeek.Thursday,
|
||||||
|
DayOfWeek.Friday,
|
||||||
|
DayOfWeek.Saturday
|
||||||
|
};
|
||||||
private List<QueueItemType> _Blocks = new List<QueueItemType>();
|
private List<QueueItemType> _Blocks = new List<QueueItemType>();
|
||||||
|
|
||||||
|
public List<DayOfWeek> AllowedDays
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _AllowedDays;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_AllowedDays = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public int AllowedStartHours { get; set; } = 0;
|
||||||
|
public int AllowedStartMinutes { get; set; } = 0;
|
||||||
|
public int AllowedEndHours { get; set; } = 23;
|
||||||
|
public int AllowedEndMinutes { get; set; } = 59;
|
||||||
public QueueItemType ItemType => _ItemType;
|
public QueueItemType ItemType => _ItemType;
|
||||||
public QueueItemState ItemState => _ItemState;
|
public QueueItemState ItemState => _ItemState;
|
||||||
public DateTime LastRunTime => _LastRunTime;
|
public DateTime LastRunTime => _LastRunTime;
|
||||||
@@ -72,9 +139,56 @@ namespace gaseous_server
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return LastRunTime.AddMinutes(Interval);
|
// next run time
|
||||||
|
DateTime tempNextRun = LastRunTime.ToLocalTime().AddMinutes(Interval);
|
||||||
|
// if (tempNextRun < DateTime.Now)
|
||||||
|
// {
|
||||||
|
// tempNextRun = DateTime.Now;
|
||||||
|
// }
|
||||||
|
DayOfWeek nextWeekDay = tempNextRun.DayOfWeek;
|
||||||
|
|
||||||
|
// create local start and end times
|
||||||
|
DateTime tempStartTime = new DateTime(tempNextRun.Year, tempNextRun.Month, tempNextRun.Day, AllowedStartHours, AllowedStartMinutes, 0, DateTimeKind.Local);
|
||||||
|
DateTime tempEndTime = new DateTime(tempNextRun.Year, tempNextRun.Month, tempNextRun.Day, AllowedEndHours, AllowedEndMinutes, 0, DateTimeKind.Local);
|
||||||
|
|
||||||
|
// bump the next run time to the next allowed day and hour range
|
||||||
|
if (AllowedDays.Contains(nextWeekDay))
|
||||||
|
{
|
||||||
|
// next run day is allowed, nothing to do
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// keep bumping the day forward until the a weekday is found
|
||||||
|
do
|
||||||
|
{
|
||||||
|
tempNextRun = tempNextRun.AddDays(1);
|
||||||
|
nextWeekDay = tempNextRun.DayOfWeek;
|
||||||
|
}
|
||||||
|
while (!AllowedDays.Contains(nextWeekDay));
|
||||||
|
|
||||||
|
// update windows
|
||||||
|
tempStartTime = new DateTime(tempNextRun.Year, tempNextRun.Month, tempNextRun.Day, AllowedStartHours, AllowedStartMinutes, 0, DateTimeKind.Local);
|
||||||
|
tempEndTime = new DateTime(tempNextRun.Year, tempNextRun.Month, tempNextRun.Day, AllowedEndHours, AllowedEndMinutes, 0, DateTimeKind.Local);
|
||||||
|
}
|
||||||
|
|
||||||
|
// are the hours in the right range
|
||||||
|
TimeSpan spanNextRun = tempNextRun.TimeOfDay;
|
||||||
|
if (LastRunTime.ToLocalTime().AddMinutes(Interval) < tempStartTime)
|
||||||
|
{
|
||||||
|
return tempStartTime.ToUniversalTime();
|
||||||
|
}
|
||||||
|
else if (spanNextRun >= tempStartTime.TimeOfDay && spanNextRun <= tempEndTime.TimeOfDay)
|
||||||
|
{
|
||||||
|
// all good - return nextRun
|
||||||
|
return tempNextRun.ToUniversalTime();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return tempStartTime.ToUniversalTime();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Interval
|
public int Interval
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -233,12 +347,25 @@ namespace gaseous_server
|
|||||||
DatabaseMigration.UpgradeScriptBackgroundTasks();
|
DatabaseMigration.UpgradeScriptBackgroundTasks();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QueueItemType.Maintainer:
|
case QueueItemType.DailyMaintainer:
|
||||||
Logging.Log(Logging.LogType.Debug, "Timered Event", "Starting Maintenance");
|
Logging.Log(Logging.LogType.Debug, "Timered Event", "Starting Daily Maintenance");
|
||||||
Classes.Maintenance maintenance = new Maintenance{
|
Classes.Maintenance maintenance = new Maintenance{
|
||||||
CallingQueueItem = this
|
CallingQueueItem = this
|
||||||
};
|
};
|
||||||
maintenance.RunMaintenance();
|
maintenance.RunDailyMaintenance();
|
||||||
|
|
||||||
|
_SaveLastRunTime = true;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case QueueItemType.WeeklyMaintainer:
|
||||||
|
Logging.Log(Logging.LogType.Debug, "Timered Event", "Starting Weekly Maintenance");
|
||||||
|
Classes.Maintenance weeklyMaintenance = new Maintenance{
|
||||||
|
CallingQueueItem = this
|
||||||
|
};
|
||||||
|
weeklyMaintenance.RunWeeklyMaintenance();
|
||||||
|
|
||||||
|
_SaveLastRunTime = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QueueItemType.TempCleanup:
|
case QueueItemType.TempCleanup:
|
||||||
@@ -277,7 +404,14 @@ namespace gaseous_server
|
|||||||
}
|
}
|
||||||
|
|
||||||
_ForceExecute = false;
|
_ForceExecute = false;
|
||||||
_ItemState = QueueItemState.Stopped;
|
if (_DisableWhenComplete == false)
|
||||||
|
{
|
||||||
|
_ItemState = QueueItemState.Stopped;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_ItemState = QueueItemState.Disabled;
|
||||||
|
}
|
||||||
_LastFinishTime = DateTime.UtcNow;
|
_LastFinishTime = DateTime.UtcNow;
|
||||||
_LastRunDuration = Math.Round((DateTime.UtcNow - _LastRunTime).TotalSeconds, 2);
|
_LastRunDuration = Math.Round((DateTime.UtcNow - _LastRunTime).TotalSeconds, 2);
|
||||||
|
|
||||||
@@ -296,6 +430,26 @@ namespace gaseous_server
|
|||||||
_IsBlocked = BlockState;
|
_IsBlocked = BlockState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool _DisableWhenComplete = false;
|
||||||
|
public void Enabled(bool Enabled)
|
||||||
|
{
|
||||||
|
_DisableWhenComplete = !Enabled;
|
||||||
|
if (Enabled == true)
|
||||||
|
{
|
||||||
|
if (_ItemState == QueueItemState.Disabled)
|
||||||
|
{
|
||||||
|
_ItemState = QueueItemState.Stopped;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (_ItemState == QueueItemState.Stopped || _ItemState == QueueItemState.NeverStarted)
|
||||||
|
{
|
||||||
|
_ItemState = QueueItemState.Disabled;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public HasErrorsItem HasErrors
|
public HasErrorsItem HasErrors
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -420,9 +574,14 @@ namespace gaseous_server
|
|||||||
BackgroundDatabaseUpgrade,
|
BackgroundDatabaseUpgrade,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Performs a clean up of old files, and optimises the database
|
/// Performs a clean up of old files, and purge old logs
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Maintainer,
|
DailyMaintainer,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Performs more intensive cleanups and optimises the database
|
||||||
|
/// </summary>
|
||||||
|
WeeklyMaintainer,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Cleans up marked paths in the temporary directory
|
/// Cleans up marked paths in the temporary directory
|
||||||
|
@@ -55,15 +55,6 @@ Communications.MetadataSource = Config.MetadataConfiguration.MetadataSource;
|
|||||||
// set up hasheous client
|
// set up hasheous client
|
||||||
HasheousClient.WebApp.HttpHelper.BaseUri = Config.MetadataConfiguration.HasheousHost;
|
HasheousClient.WebApp.HttpHelper.BaseUri = Config.MetadataConfiguration.HasheousHost;
|
||||||
|
|
||||||
// set initial values
|
|
||||||
Guid APIKey = Guid.NewGuid();
|
|
||||||
if (Config.ReadSetting("API Key", "Test API Key") == "Test API Key")
|
|
||||||
{
|
|
||||||
// it's a new api key save it
|
|
||||||
Logging.Log(Logging.LogType.Information, "Startup", "Setting initial API key");
|
|
||||||
Config.SetSetting("API Key", APIKey.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
// clean up storage
|
// clean up storage
|
||||||
if (Directory.Exists(Config.LibraryConfiguration.LibraryTempDirectory))
|
if (Directory.Exists(Config.LibraryConfiguration.LibraryTempDirectory))
|
||||||
{
|
{
|
||||||
@@ -421,69 +412,38 @@ 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)
|
||||||
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)
|
||||||
int.Parse(Config.ReadSetting("Interval_TitleIngestor", "1")),
|
|
||||||
new List<ProcessQueue.QueueItemType>
|
|
||||||
{
|
|
||||||
ProcessQueue.QueueItemType.OrganiseLibrary,
|
|
||||||
ProcessQueue.QueueItemType.LibraryScan
|
|
||||||
})
|
|
||||||
);
|
);
|
||||||
ProcessQueue.QueueItems.Add(new ProcessQueue.QueueItem(
|
ProcessQueue.QueueItems.Add(new ProcessQueue.QueueItem(
|
||||||
ProcessQueue.QueueItemType.MetadataRefresh,
|
ProcessQueue.QueueItemType.MetadataRefresh)
|
||||||
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)
|
||||||
int.Parse(Config.ReadSetting("Interval_OrganiseLibrary", "1440")),
|
|
||||||
new List<ProcessQueue.QueueItemType>
|
|
||||||
{
|
|
||||||
ProcessQueue.QueueItemType.LibraryScan,
|
|
||||||
ProcessQueue.QueueItemType.TitleIngestor,
|
|
||||||
ProcessQueue.QueueItemType.Rematcher
|
|
||||||
})
|
|
||||||
);
|
);
|
||||||
ProcessQueue.QueueItems.Add(new ProcessQueue.QueueItem(
|
ProcessQueue.QueueItems.Add(new ProcessQueue.QueueItem(
|
||||||
ProcessQueue.QueueItemType.LibraryScan,
|
ProcessQueue.QueueItemType.LibraryScan)
|
||||||
int.Parse(Config.ReadSetting("Interval_LibraryScan", "1440")),
|
|
||||||
new List<ProcessQueue.QueueItemType>
|
|
||||||
{
|
|
||||||
ProcessQueue.QueueItemType.OrganiseLibrary,
|
|
||||||
ProcessQueue.QueueItemType.Rematcher
|
|
||||||
})
|
|
||||||
);
|
);
|
||||||
ProcessQueue.QueueItems.Add(new ProcessQueue.QueueItem(
|
ProcessQueue.QueueItems.Add(new ProcessQueue.QueueItem(
|
||||||
ProcessQueue.QueueItemType.Rematcher,
|
ProcessQueue.QueueItemType.Rematcher)
|
||||||
int.Parse(Config.ReadSetting("Interval_Rematcher", "1440")),
|
|
||||||
new List<ProcessQueue.QueueItemType>
|
|
||||||
{
|
|
||||||
ProcessQueue.QueueItemType.OrganiseLibrary,
|
|
||||||
ProcessQueue.QueueItemType.LibraryScan
|
|
||||||
})
|
|
||||||
);
|
|
||||||
ProcessQueue.QueueItems.Add(new ProcessQueue.QueueItem(
|
|
||||||
ProcessQueue.QueueItemType.Maintainer,
|
|
||||||
int.Parse(Config.ReadSetting("Interval_Maintainer", "10080")),
|
|
||||||
new List<ProcessQueue.QueueItemType>
|
|
||||||
{
|
|
||||||
ProcessQueue.QueueItemType.All
|
|
||||||
})
|
|
||||||
);
|
);
|
||||||
|
|
||||||
ProcessQueue.QueueItem tempCleanup = new ProcessQueue.QueueItem(
|
// maintenance tasks
|
||||||
ProcessQueue.QueueItemType.TempCleanup,
|
ProcessQueue.QueueItem dailyMaintenance = new ProcessQueue.QueueItem(
|
||||||
1,
|
ProcessQueue.QueueItemType.DailyMaintainer
|
||||||
new List<ProcessQueue.QueueItemType>(),
|
);
|
||||||
false,
|
ProcessQueue.QueueItems.Add(dailyMaintenance);
|
||||||
false
|
|
||||||
|
ProcessQueue.QueueItem weeklyMaintenance = new ProcessQueue.QueueItem(
|
||||||
|
ProcessQueue.QueueItemType.WeeklyMaintainer
|
||||||
|
);
|
||||||
|
ProcessQueue.QueueItems.Add(weeklyMaintenance);
|
||||||
|
|
||||||
|
ProcessQueue.QueueItem tempCleanup = new ProcessQueue.QueueItem(
|
||||||
|
ProcessQueue.QueueItemType.TempCleanup
|
||||||
);
|
);
|
||||||
tempCleanup.ForceExecute();
|
|
||||||
ProcessQueue.QueueItems.Add(tempCleanup);
|
ProcessQueue.QueueItems.Add(tempCleanup);
|
||||||
|
|
||||||
Logging.WriteToDiskOnly = false;
|
Logging.WriteToDiskOnly = false;
|
||||||
|
6
gaseous-server/Support/Database/MySQL/gaseous-1016.sql
Normal file
6
gaseous-server/Support/Database/MySQL/gaseous-1016.sql
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
ALTER TABLE `Settings`
|
||||||
|
ADD COLUMN `ValueType` INT NULL DEFAULT 0 AFTER `Setting`,
|
||||||
|
ADD COLUMN `ValueDate` DATETIME NULL DEFAULT NULL AFTER `Value`;
|
||||||
|
|
||||||
|
ALTER TABLE `GameState`
|
||||||
|
ADD COLUMN `Zipped` BOOLEAN NOT NULL DEFAULT 0;
|
@@ -20,8 +20,8 @@ namespace gaseous_server
|
|||||||
//_logger.LogInformation("Timed Hosted Service running.");
|
//_logger.LogInformation("Timed Hosted Service running.");
|
||||||
Logging.Log(Logging.LogType.Debug, "Background", "Starting background task monitor");
|
Logging.Log(Logging.LogType.Debug, "Background", "Starting background task monitor");
|
||||||
|
|
||||||
_timer = new Timer(DoWork, null, TimeSpan.Zero,
|
_timer = new Timer(DoWork, null, TimeSpan.FromSeconds(30),
|
||||||
TimeSpan.FromSeconds(5));
|
TimeSpan.FromSeconds(30));
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
@@ -36,20 +36,23 @@ namespace gaseous_server
|
|||||||
List<ProcessQueue.QueueItem> ActiveList = new List<ProcessQueue.QueueItem>();
|
List<ProcessQueue.QueueItem> ActiveList = new List<ProcessQueue.QueueItem>();
|
||||||
ActiveList.AddRange(ProcessQueue.QueueItems);
|
ActiveList.AddRange(ProcessQueue.QueueItems);
|
||||||
foreach (ProcessQueue.QueueItem qi in ActiveList) {
|
foreach (ProcessQueue.QueueItem qi in ActiveList) {
|
||||||
if (CheckIfProcessIsBlockedByOthers(qi) == false) {
|
if (qi.ItemState != ProcessQueue.QueueItemState.Disabled)
|
||||||
qi.BlockedState(false);
|
{
|
||||||
if (DateTime.UtcNow > qi.NextRunTime || qi.Force == true)
|
if (CheckIfProcessIsBlockedByOthers(qi) == false) {
|
||||||
{
|
qi.BlockedState(false);
|
||||||
qi.Execute();
|
if (DateTime.UtcNow > qi.NextRunTime || qi.Force == true)
|
||||||
if (qi.RemoveWhenStopped == true && qi.ItemState == ProcessQueue.QueueItemState.Stopped)
|
|
||||||
{
|
{
|
||||||
ProcessQueue.QueueItems.Remove(qi);
|
qi.Execute();
|
||||||
|
if (qi.RemoveWhenStopped == true && qi.ItemState == ProcessQueue.QueueItemState.Stopped)
|
||||||
|
{
|
||||||
|
ProcessQueue.QueueItems.Remove(qi);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
else
|
{
|
||||||
{
|
qi.BlockedState(true);
|
||||||
qi.BlockedState(true);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -60,6 +60,7 @@
|
|||||||
<None Remove="Support\Database\MySQL\gaseous-1013.sql" />
|
<None Remove="Support\Database\MySQL\gaseous-1013.sql" />
|
||||||
<None Remove="Support\Database\MySQL\gaseous-1014.sql" />
|
<None Remove="Support\Database\MySQL\gaseous-1014.sql" />
|
||||||
<None Remove="Support\Database\MySQL\gaseous-1015.sql" />
|
<None Remove="Support\Database\MySQL\gaseous-1015.sql" />
|
||||||
|
<None Remove="Support\Database\MySQL\gaseous-1016.sql" />
|
||||||
<None Remove="Classes\Metadata\" />
|
<None Remove="Classes\Metadata\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -97,5 +98,6 @@
|
|||||||
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1013.sql" />
|
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1013.sql" />
|
||||||
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1014.sql" />
|
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1014.sql" />
|
||||||
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1015.sql" />
|
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1015.sql" />
|
||||||
|
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1016.sql" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
@@ -29,6 +29,7 @@
|
|||||||
EJS_pathtodata = '/emulators/EmulatorJS/data/';
|
EJS_pathtodata = '/emulators/EmulatorJS/data/';
|
||||||
|
|
||||||
EJS_DEBUG_XX = false;
|
EJS_DEBUG_XX = false;
|
||||||
|
console.log("Debug enabled: " + EJS_DEBUG_XX);
|
||||||
|
|
||||||
EJS_backgroundImage = emuBackground;
|
EJS_backgroundImage = emuBackground;
|
||||||
EJS_backgroundBlur = true;
|
EJS_backgroundBlur = true;
|
||||||
|
@@ -268,7 +268,7 @@
|
|||||||
if (newPassword.length > 0) {
|
if (newPassword.length > 0) {
|
||||||
if (newPassword == conPassword) {
|
if (newPassword == conPassword) {
|
||||||
// check if password meets requirements
|
// check if password meets requirements
|
||||||
if (newPassword.length > 10) {
|
if (newPassword.length >= 10) {
|
||||||
errorLabel.innerHTML = "";
|
errorLabel.innerHTML = "";
|
||||||
submitButton.removeAttribute('disabled');
|
submitButton.removeAttribute('disabled');
|
||||||
return true;
|
return true;
|
||||||
|
@@ -49,7 +49,7 @@
|
|||||||
if (userNameVal.includes("@")) {
|
if (userNameVal.includes("@")) {
|
||||||
if (newPassword == conPassword) {
|
if (newPassword == conPassword) {
|
||||||
// check if password meets requirements
|
// check if password meets requirements
|
||||||
if (newPassword.length > 10) {
|
if (newPassword.length >= 10) {
|
||||||
errorLabel.innerHTML = "";
|
errorLabel.innerHTML = "";
|
||||||
submitButton.removeAttribute('disabled');
|
submitButton.removeAttribute('disabled');
|
||||||
} else {
|
} else {
|
||||||
|
@@ -285,7 +285,7 @@
|
|||||||
} else {
|
} else {
|
||||||
if (newPassword == conPassword) {
|
if (newPassword == conPassword) {
|
||||||
// check if password meets requirements
|
// check if password meets requirements
|
||||||
if (newPassword.length > 10) {
|
if (newPassword.length >= 10) {
|
||||||
errorLabel.innerHTML = "";
|
errorLabel.innerHTML = "";
|
||||||
submitButton.removeAttribute('disabled');
|
submitButton.removeAttribute('disabled');
|
||||||
} else {
|
} else {
|
||||||
|
@@ -117,7 +117,7 @@
|
|||||||
} else {
|
} else {
|
||||||
if (newPassword == conPassword) {
|
if (newPassword == conPassword) {
|
||||||
// check if password meets requirements
|
// check if password meets requirements
|
||||||
if (newPassword.length > 10) {
|
if (newPassword.length >= 10) {
|
||||||
errorLabel.innerHTML = " ";
|
errorLabel.innerHTML = " ";
|
||||||
submitButton.removeAttribute('disabled');
|
submitButton.removeAttribute('disabled');
|
||||||
} else {
|
} else {
|
||||||
|
@@ -11,7 +11,6 @@
|
|||||||
<h2>Advanced Settings</h2>
|
<h2>Advanced Settings</h2>
|
||||||
<p><strong>Warning</strong> Do not modify the below settings unless you know what you're doing.</p>
|
<p><strong>Warning</strong> Do not modify the below settings unless you know what you're doing.</p>
|
||||||
<h3>Background Task Timers</h3>
|
<h3>Background Task Timers</h3>
|
||||||
<p>All intervals are in minutes.</p>
|
|
||||||
<table id="settings_tasktimers" class="romtable" style="width: 100%;" cellspacing="0">
|
<table id="settings_tasktimers" class="romtable" style="width: 100%;" cellspacing="0">
|
||||||
|
|
||||||
</table>
|
</table>
|
||||||
@@ -104,44 +103,241 @@
|
|||||||
|
|
||||||
function getBackgroundTaskTimers() {
|
function getBackgroundTaskTimers() {
|
||||||
ajaxCall(
|
ajaxCall(
|
||||||
'/api/v1/System/Settings/BackgroundTasks/Intervals',
|
'/api/v1/System/Settings/BackgroundTasks/Configuration',
|
||||||
'GET',
|
'GET',
|
||||||
function(result) {
|
function(result) {
|
||||||
var targetTable = document.getElementById('settings_tasktimers');
|
var targetTable = document.getElementById('settings_tasktimers');
|
||||||
targetTable.innerHTML = '';
|
targetTable.innerHTML = '';
|
||||||
|
|
||||||
targetTable.appendChild(
|
|
||||||
createTableRow(true, ['Background Task', 'Timer Interval', 'Default Interval', 'Minimum Allowed Interval'])
|
|
||||||
);
|
|
||||||
|
|
||||||
for (const [key, value] of Object.entries(result)) {
|
for (const [key, value] of Object.entries(result)) {
|
||||||
var newTableRow = createTableRow(
|
var newTableRowBody = document.createElement('tbody');
|
||||||
|
newTableRowBody.className = 'romrow';
|
||||||
|
|
||||||
|
var enabledString = "";
|
||||||
|
if (value.enabled == true) {
|
||||||
|
enabledString = 'checked="checked"';
|
||||||
|
}
|
||||||
|
|
||||||
|
var newTableIntervalRow = createTableRow(
|
||||||
false,
|
false,
|
||||||
[
|
[
|
||||||
GetTaskFriendlyName(value.task),
|
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 + '" />',
|
'Enabled',
|
||||||
value.defaultInterval,
|
'<input id="settings_enabled_' + value.task + '" name="settings_tasktimers_enabled" type="checkbox" ' + enabledString + '/>',
|
||||||
value.minimumAllowedValue
|
|
||||||
],
|
],
|
||||||
'romrow',
|
'',
|
||||||
'romcell'
|
'romcell'
|
||||||
);
|
);
|
||||||
targetTable.appendChild(newTableRow);
|
newTableRowBody.appendChild(newTableIntervalRow);
|
||||||
|
|
||||||
|
var newTableRow = createTableRow(
|
||||||
|
false,
|
||||||
|
[
|
||||||
|
'',
|
||||||
|
'Minimum Interval (Minutes):',
|
||||||
|
'<input id="settings_tasktimers_' + value.task + '" name="settings_tasktimers_values" data-name="' + value.task + '" data-default="' + value.defaultInterval + '" type="number" placeholder="' + value.defaultInterval + '" min="' + value.minimumAllowedInterval + '" value="' + value.interval + '" />'
|
||||||
|
],
|
||||||
|
'',
|
||||||
|
'romcell'
|
||||||
|
);
|
||||||
|
newTableRowBody.appendChild(newTableRow);
|
||||||
|
|
||||||
|
// allowed time periods row
|
||||||
|
var newTableRowTime = document.createElement('tr');
|
||||||
|
var rowTimeSpace = document.createElement('td');
|
||||||
|
newTableRowTime.appendChild(rowTimeSpace);
|
||||||
|
|
||||||
|
var rowTimeContentTitle = document.createElement('td');
|
||||||
|
rowTimeContentTitle.className = 'romcell';
|
||||||
|
rowTimeContentTitle.innerHTML = "Allowed Days:";
|
||||||
|
newTableRowTime.appendChild(rowTimeContentTitle);
|
||||||
|
|
||||||
|
var rowTimeContent = document.createElement('td');
|
||||||
|
// rowTimeContent.setAttribute('colspan', 2);
|
||||||
|
rowTimeContent.className = 'romcell';
|
||||||
|
var daySelector = document.createElement('select');
|
||||||
|
daySelector.id = 'settings_alloweddays_' + value.task;
|
||||||
|
daySelector.name = 'settings_alloweddays';
|
||||||
|
daySelector.multiple = 'multiple';
|
||||||
|
daySelector.setAttribute('data-default', value.defaultAllowedDays.join(","));
|
||||||
|
daySelector.style.width = '95%';
|
||||||
|
var days = [ "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" ];
|
||||||
|
for (var d = 0; d < days.length; d++) {
|
||||||
|
var dayOpt = document.createElement('option');
|
||||||
|
dayOpt.value = days[d];
|
||||||
|
dayOpt.innerHTML = days[d];
|
||||||
|
if (value.allowedDays.includes(days[d])) {
|
||||||
|
dayOpt.selected = 'selected';
|
||||||
|
}
|
||||||
|
daySelector.appendChild(dayOpt);
|
||||||
|
}
|
||||||
|
rowTimeContent.appendChild(daySelector);
|
||||||
|
$(daySelector).select2({
|
||||||
|
tags: false
|
||||||
|
});
|
||||||
|
newTableRowTime.appendChild(rowTimeContent);
|
||||||
|
|
||||||
|
newTableRowBody.appendChild(newTableRowTime);
|
||||||
|
|
||||||
|
// add start and end times
|
||||||
|
var newTableRowClock = document.createElement('tr');
|
||||||
|
var rowClockSpace = document.createElement('td');
|
||||||
|
newTableRowClock.appendChild(rowClockSpace);
|
||||||
|
|
||||||
|
var rowClockContentTitle = document.createElement('td');
|
||||||
|
rowClockContentTitle.className = 'romcell';
|
||||||
|
rowClockContentTitle.innerHTML = "Time Range:";
|
||||||
|
newTableRowClock.appendChild(rowClockContentTitle);
|
||||||
|
|
||||||
|
var rowClockContent = document.createElement('td');
|
||||||
|
rowClockContent.className = 'romcell';
|
||||||
|
// rowClockContent.setAttribute('colspan', 2);
|
||||||
|
|
||||||
|
rowClockContent.appendChild(generateTimeDropDowns(value.task, 'Start', value.defaultAllowedStartHours, value.defaultAllowedStartMinutes, value.allowedStartHours, value.allowedStartMinutes));
|
||||||
|
|
||||||
|
rowClockContentSeparator = document.createElement('span');
|
||||||
|
rowClockContentSeparator.innerHTML = ' - ';
|
||||||
|
rowClockContent.appendChild(rowClockContentSeparator);
|
||||||
|
|
||||||
|
rowClockContent.appendChild(generateTimeDropDowns(value.task, 'End', value.defaultAllowedEndHours, value.defaultAllowedEndMinutes, value.allowedEndHours, value.allowedEndMinutes));
|
||||||
|
|
||||||
|
newTableRowClock.appendChild(rowClockContent);
|
||||||
|
|
||||||
|
newTableRowBody.appendChild(newTableRowClock);
|
||||||
|
|
||||||
|
// blocks tasks
|
||||||
|
var newTableRowBlocks = document.createElement('tr');
|
||||||
|
var rowBlocksSpace = document.createElement('td');
|
||||||
|
newTableRowBlocks.appendChild(rowBlocksSpace);
|
||||||
|
|
||||||
|
var rowBlocksContentTitle = document.createElement('td');
|
||||||
|
rowBlocksContentTitle.className = 'romcell';
|
||||||
|
rowBlocksContentTitle.innerHTML = "Blocks:";
|
||||||
|
newTableRowBlocks.appendChild(rowBlocksContentTitle);
|
||||||
|
|
||||||
|
var rowBlocksContent = document.createElement('td');
|
||||||
|
rowBlocksContent.className = 'romcell';
|
||||||
|
// rowBlocksContent.setAttribute('colspan', 2);
|
||||||
|
var blocksString = "";
|
||||||
|
for (var i = 0; i < value.blocks.length; i++) {
|
||||||
|
if (blocksString.length > 0) { blocksString += ", "; }
|
||||||
|
blocksString += GetTaskFriendlyName(value.blocks[i]);
|
||||||
|
}
|
||||||
|
if (blocksString.length == 0) { blocksString = 'None'; }
|
||||||
|
rowBlocksContent.innerHTML = blocksString;
|
||||||
|
newTableRowBlocks.appendChild(rowBlocksContent);
|
||||||
|
|
||||||
|
newTableRowBody.appendChild(newTableRowBlocks);
|
||||||
|
|
||||||
|
// blocked by tasks
|
||||||
|
var newTableRowBlockedBy = document.createElement('tr');
|
||||||
|
var rowBlockedBySpace = document.createElement('td');
|
||||||
|
newTableRowBlockedBy.appendChild(rowBlockedBySpace);
|
||||||
|
|
||||||
|
var rowBlockedByContentTitle = document.createElement('td');
|
||||||
|
rowBlockedByContentTitle.className = 'romcell';
|
||||||
|
rowBlockedByContentTitle.innerHTML = "Blocked By:";
|
||||||
|
newTableRowBlockedBy.appendChild(rowBlockedByContentTitle);
|
||||||
|
|
||||||
|
var rowBlockedByContent = document.createElement('td');
|
||||||
|
rowBlockedByContent.className = 'romcell';
|
||||||
|
// rowBlockedByContent.setAttribute('colspan', 2);
|
||||||
|
var BlockedByString = "";
|
||||||
|
for (var i = 0; i < value.blockedBy.length; i++) {
|
||||||
|
if (BlockedByString.length > 0) { BlockedByString += ", "; }
|
||||||
|
BlockedByString += GetTaskFriendlyName(value.blockedBy[i]);
|
||||||
|
}
|
||||||
|
if (BlockedByString.length == 0) { BlockedByString = 'None'; }
|
||||||
|
rowBlockedByContent.innerHTML = BlockedByString;
|
||||||
|
newTableRowBlockedBy.appendChild(rowBlockedByContent);
|
||||||
|
|
||||||
|
newTableRowBody.appendChild(newTableRowBlockedBy);
|
||||||
|
|
||||||
|
// complete row
|
||||||
|
targetTable.appendChild(newTableRowBody);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function generateTimeDropDowns(taskName, rangeName, defaultHour, defaultMinute, valueHour, valueMinute) {
|
||||||
|
var container = document.createElement('div');
|
||||||
|
container.style.display = 'inline';
|
||||||
|
|
||||||
|
var elementName = 'settings_tasktimers_time';
|
||||||
|
|
||||||
|
var hourSelector = document.createElement('input');
|
||||||
|
hourSelector.id = 'settings_tasktimers_' + taskName + '_' + rangeName + '_Hour';
|
||||||
|
hourSelector.name = elementName;
|
||||||
|
hourSelector.setAttribute('data-name', taskName);
|
||||||
|
hourSelector.setAttribute('type', 'number');
|
||||||
|
hourSelector.setAttribute('min', '0');
|
||||||
|
hourSelector.setAttribute('max', '23');
|
||||||
|
hourSelector.setAttribute('placeholder', defaultHour);
|
||||||
|
hourSelector.value = valueHour;
|
||||||
|
container.appendChild(hourSelector);
|
||||||
|
|
||||||
|
var separator = document.createElement('span');
|
||||||
|
separator.innerHTML = " : ";
|
||||||
|
container.appendChild(separator);
|
||||||
|
|
||||||
|
var minSelector = document.createElement('input');
|
||||||
|
minSelector.id = 'settings_tasktimers_' + taskName + '_' + rangeName + '_Minute';
|
||||||
|
minSelector.name = elementName;
|
||||||
|
minSelector.setAttribute('type', 'number');
|
||||||
|
minSelector.setAttribute('min', '0');
|
||||||
|
minSelector.setAttribute('max', '59');
|
||||||
|
minSelector.setAttribute('placeholder', defaultMinute);
|
||||||
|
minSelector.value = valueMinute;
|
||||||
|
container.appendChild(minSelector);
|
||||||
|
|
||||||
|
return container;
|
||||||
|
}
|
||||||
|
|
||||||
function saveTaskTimers() {
|
function saveTaskTimers() {
|
||||||
var timerValues = document.getElementsByName('settings_tasktimers_values');
|
var timerValues = document.getElementsByName('settings_tasktimers_values');
|
||||||
|
|
||||||
var model = {};
|
var model = [];
|
||||||
for (var i = 0; i < timerValues.length; i++) {
|
for (var i = 0; i < timerValues.length; i++) {
|
||||||
model[timerValues[i].getAttribute('data-name')] = timerValues[i].value;
|
var taskName = timerValues[i].getAttribute('data-name');
|
||||||
|
var taskEnabled = document.getElementById('settings_enabled_' + taskName).checked;
|
||||||
|
var taskIntervalObj = document.getElementById('settings_tasktimers_' + taskName);
|
||||||
|
var taskInterval = function() { if (taskIntervalObj.value) { return taskIntervalObj.value; } else { return taskIntervalObj.getAttribute('placeholder'); } };
|
||||||
|
var taskDaysRaw = $('#settings_alloweddays_' + taskName).select2('data');
|
||||||
|
var taskDays = [];
|
||||||
|
if (taskDaysRaw.length > 0) {
|
||||||
|
for (var d = 0; d < taskDaysRaw.length; d++) {
|
||||||
|
taskDays.push(taskDaysRaw[d].id);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
taskDays.push("Monday");
|
||||||
|
}
|
||||||
|
var taskStartHourObj = document.getElementById('settings_tasktimers_' + taskName + '_Start_Hour');
|
||||||
|
var taskStartMinuteObj = document.getElementById('settings_tasktimers_' + taskName + '_Start_Minute');
|
||||||
|
var taskEndHourObj = document.getElementById('settings_tasktimers_' + taskName + '_End_Hour');
|
||||||
|
var taskEndMinuteObj = document.getElementById('settings_tasktimers_' + taskName + '_End_Minute');
|
||||||
|
|
||||||
|
var taskStartHour = function() { if (taskStartHourObj.value) { return taskStartHourObj.value; } else { return taskStartHourObj.getAttribute('placeholder'); } };
|
||||||
|
var taskStartMinute = function() { if (taskStartMinuteObj.value) { return taskStartMinuteObj.value; } else { return taskStartMinuteObj.getAttribute('placeholder'); } };
|
||||||
|
var taskEndHour = function() { if (taskEndHourObj.value) { return taskEndHourObj.value; } else { return taskEndHourObj.getAttribute('placeholder'); } };
|
||||||
|
var taskEndMinute = function() { if (taskEndMinuteObj.value) { return taskEndMinuteObj.value; } else { return taskEndMinuteObj.getAttribute('placeholder'); } };
|
||||||
|
|
||||||
|
model.push(
|
||||||
|
{
|
||||||
|
"task": taskName,
|
||||||
|
"enabled": taskEnabled,
|
||||||
|
"interval": taskInterval(),
|
||||||
|
"allowedDays": taskDays,
|
||||||
|
"allowedStartHours": taskStartHour(),
|
||||||
|
"allowedStartMinutes": taskStartMinute(),
|
||||||
|
"allowedEndHours": taskEndHour(),
|
||||||
|
"allowedEndMinutes": taskEndMinute()
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
ajaxCall(
|
ajaxCall(
|
||||||
'/api/v1/System/Settings/BackgroundTasks/Intervals',
|
'/api/v1/System/Settings/BackgroundTasks/Configuration',
|
||||||
'POST',
|
'POST',
|
||||||
function(result) {
|
function(result) {
|
||||||
getBackgroundTaskTimers();
|
getBackgroundTaskTimers();
|
||||||
@@ -154,12 +350,32 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function defaultTaskTimers() {
|
function defaultTaskTimers() {
|
||||||
|
var timerValues = document.getElementsByName('settings_tasktimers_enabled');
|
||||||
|
|
||||||
|
for (var i = 0; i < timerValues.length; i++) {
|
||||||
|
timerValues[i].checked = true;
|
||||||
|
}
|
||||||
|
|
||||||
var timerValues = document.getElementsByName('settings_tasktimers_values');
|
var timerValues = document.getElementsByName('settings_tasktimers_values');
|
||||||
|
|
||||||
for (var i = 0; i < timerValues.length; i++) {
|
for (var i = 0; i < timerValues.length; i++) {
|
||||||
timerValues[i].value = timerValues[i].getAttribute('data-default');
|
timerValues[i].value = timerValues[i].getAttribute('data-default');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var timerValues = document.getElementsByName('settings_alloweddays');
|
||||||
|
|
||||||
|
for (var i = 0; i < timerValues.length; i++) {
|
||||||
|
var defaultSelections = timerValues[i].getAttribute('data-default').split(',');
|
||||||
|
$(timerValues[i]).val(defaultSelections);
|
||||||
|
$(timerValues[i]).trigger('change');
|
||||||
|
}
|
||||||
|
|
||||||
|
var timerValues = document.getElementsByName('settings_tasktimers_time');
|
||||||
|
|
||||||
|
for (var i = 0; i < timerValues.length; i++) {
|
||||||
|
timerValues[i].value = timerValues[i].getAttribute('placeholder');
|
||||||
|
}
|
||||||
|
|
||||||
saveTaskTimers();
|
saveTaskTimers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -410,13 +410,25 @@ function GetTaskFriendlyName(TaskName, options) {
|
|||||||
case 'LibraryScan':
|
case 'LibraryScan':
|
||||||
return "Library scan";
|
return "Library scan";
|
||||||
case 'LibraryScanWorker':
|
case 'LibraryScanWorker':
|
||||||
return "Library scan worker: " + options.name;
|
if (options) {
|
||||||
|
return "Library scan worker: " + options.name;
|
||||||
|
} else {
|
||||||
|
return "Library scan worker";
|
||||||
|
}
|
||||||
case 'CollectionCompiler':
|
case 'CollectionCompiler':
|
||||||
return "Compress collection id: " + options;
|
if (options) {
|
||||||
|
return "Compress collection id: " + options;
|
||||||
|
} else {
|
||||||
|
return "Compress collection";
|
||||||
|
}
|
||||||
case 'BackgroundDatabaseUpgrade':
|
case 'BackgroundDatabaseUpgrade':
|
||||||
return "Background database upgrade";
|
return "Background database upgrade";
|
||||||
case 'TempCleanup':
|
case 'TempCleanup':
|
||||||
return "Temporary directory cleanup";
|
return "Temporary directory cleanup";
|
||||||
|
case 'DailyMaintainer':
|
||||||
|
return "Daily maintenance";
|
||||||
|
case 'WeeklyMaintainer':
|
||||||
|
return "Weekly maintenance";
|
||||||
default:
|
default:
|
||||||
return TaskName;
|
return TaskName;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user