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
|
||||
### Deploy with the prebuilt Docker image
|
||||
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
|
||||
# Installation
|
||||
See https://github.com/gaseous-project/gaseous-server/wiki/Installation for installation instructions.
|
||||
|
||||
# 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.
|
||||
|
@@ -1,5 +1,6 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.ComponentModel;
|
||||
using System.IO.Compression;
|
||||
using System.Reflection;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
@@ -120,6 +121,28 @@ namespace gaseous_server.Classes
|
||||
.Single(x => x.GetValue(null).Equals(value)),
|
||||
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>
|
||||
|
@@ -3,6 +3,7 @@ using System.Data;
|
||||
using Newtonsoft.Json;
|
||||
using IGDB.Models;
|
||||
using gaseous_server.Classes.Metadata;
|
||||
using NuGet.Common;
|
||||
|
||||
namespace gaseous_server.Classes
|
||||
{
|
||||
@@ -161,7 +162,7 @@ namespace gaseous_server.Classes
|
||||
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()
|
||||
{
|
||||
@@ -172,44 +173,68 @@ namespace gaseous_server.Classes
|
||||
foreach (DataRow dataRow in dbResponse.Rows)
|
||||
{
|
||||
if (AppSettings.ContainsKey((string)dataRow["Setting"]))
|
||||
{
|
||||
if ((int)dataRow["ValueType"] == 0)
|
||||
{
|
||||
AppSettings[(string)dataRow["Setting"]] = (string)dataRow["Value"];
|
||||
}
|
||||
else
|
||||
{
|
||||
AppSettings[(string)dataRow["Setting"]] = (DateTime)dataRow["ValueDate"];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
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))
|
||||
{
|
||||
return AppSettings[SettingName];
|
||||
return (T)AppSettings[SettingName];
|
||||
}
|
||||
else
|
||||
{
|
||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||
string sql = "SELECT Value FROM Settings WHERE Setting = @SettingName";
|
||||
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||
dbDict.Add("SettingName", SettingName);
|
||||
dbDict.Add("Value", DefaultValue);
|
||||
string sql = "SELECT Value, ValueDate FROM Settings WHERE Setting = @SettingName";
|
||||
Dictionary<string, object> dbDict = new Dictionary<string, object>
|
||||
{
|
||||
{ "SettingName", SettingName }
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
Logging.Log(Logging.LogType.Debug, "Database", "Reading setting '" + SettingName + "'");
|
||||
DataTable dbResponse = db.ExecuteCMD(sql, dbDict);
|
||||
Type type = typeof(T);
|
||||
if (dbResponse.Rows.Count == 0)
|
||||
{
|
||||
// no value with that name stored - respond with the default value
|
||||
SetSetting(SettingName, DefaultValue);
|
||||
SetSetting<T>(SettingName, DefaultValue);
|
||||
return DefaultValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
AppSettings.Add(SettingName, (string)dbResponse.Rows[0][0]);
|
||||
return (string)dbResponse.Rows[0][0];
|
||||
if (type.ToString() == "System.DateTime")
|
||||
{
|
||||
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)
|
||||
@@ -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);
|
||||
string sql = "REPLACE INTO Settings (Setting, Value) VALUES (@SettingName, @Value)";
|
||||
Dictionary<string, object> dbDict = new Dictionary<string, object>();
|
||||
dbDict.Add("SettingName", SettingName);
|
||||
dbDict.Add("Value", Value);
|
||||
string sql = "REPLACE INTO Settings (Setting, ValueType, Value, ValueDate) VALUES (@SettingName, @ValueType, @Value, @ValueDate)";
|
||||
Dictionary<string, object> dbDict;
|
||||
Type type = typeof(T);
|
||||
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 + "'");
|
||||
try
|
||||
@@ -341,11 +385,11 @@ namespace gaseous_server.Classes
|
||||
{
|
||||
get
|
||||
{
|
||||
return ReadSetting("LibraryRootDirectory", Path.Combine(Config.ConfigurationPath, "Data"));
|
||||
return ReadSetting<string>("LibraryRootDirectory", Path.Combine(Config.ConfigurationPath, "Data"));
|
||||
}
|
||||
set
|
||||
{
|
||||
SetSetting("LibraryRootDirectory", value);
|
||||
SetSetting<string>("LibraryRootDirectory", value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -452,13 +452,15 @@ namespace gaseous_server.Classes
|
||||
|
||||
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"]);
|
||||
long RomId = (long)dr["id"];
|
||||
SetStatus(i, romDT.Rows.Count, "Processing file " + romDT.Rows[i]["name"]);
|
||||
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);
|
||||
}
|
||||
}
|
||||
ClearStatus();
|
||||
|
||||
// clean up empty directories
|
||||
DeleteOrphanedDirectories(GameLibrary.GetDefaultLibrary.Path);
|
||||
|
@@ -9,7 +9,7 @@ namespace gaseous_server.Classes
|
||||
{
|
||||
const int MaxFileAge = 30;
|
||||
|
||||
public void RunMaintenance()
|
||||
public void RunDailyMaintenance()
|
||||
{
|
||||
Database db = new Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
|
||||
string sql = "";
|
||||
@@ -33,8 +33,8 @@ namespace gaseous_server.Classes
|
||||
}
|
||||
|
||||
// delete old logs
|
||||
sql = "DELETE FROM ServerLogs WHERE EventTime < @EventRententionDate;";
|
||||
dbDict.Add("EventRententionDate", DateTime.UtcNow.AddDays(Config.LoggingConfiguration.LogRetention * -1));
|
||||
sql = "DELETE FROM ServerLogs WHERE EventTime < @EventRetentionDate;";
|
||||
dbDict.Add("EventRetentionDate", DateTime.UtcNow.AddDays(Config.LoggingConfiguration.LogRetention * -1));
|
||||
db.ExecuteCMD(sql, dbDict);
|
||||
|
||||
// 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");
|
||||
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.Mvc;
|
||||
using Microsoft.AspNetCore.Razor.Hosting;
|
||||
using RestEase;
|
||||
|
||||
namespace gaseous_server.Controllers
|
||||
{
|
||||
@@ -96,7 +97,7 @@ namespace gaseous_server.Controllers
|
||||
|
||||
string ver = "var AppVersion = \"" + Assembly.GetExecutingAssembly().GetName().Version.ToString() + "\";" + 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{
|
||||
WriteIndented = true
|
||||
}) + ";" + Environment.NewLine +
|
||||
@@ -113,19 +114,23 @@ namespace gaseous_server.Controllers
|
||||
[MapToApiVersion("1.0")]
|
||||
[MapToApiVersion("1.1")]
|
||||
[HttpGet]
|
||||
[Route("Settings/BackgroundTasks/Intervals")]
|
||||
[Route("Settings/BackgroundTasks/Configuration")]
|
||||
[Authorize(Roles = "Admin")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public ActionResult GetBackgroundTasks()
|
||||
{
|
||||
Dictionary<string, BackgroundTaskItem> Intervals = new Dictionary<string, BackgroundTaskItem>();
|
||||
Intervals.Add(ProcessQueue.QueueItemType.SignatureIngestor.ToString(), new BackgroundTaskItem(ProcessQueue.QueueItemType.SignatureIngestor));
|
||||
Intervals.Add(ProcessQueue.QueueItemType.TitleIngestor.ToString(), new BackgroundTaskItem(ProcessQueue.QueueItemType.TitleIngestor));
|
||||
Intervals.Add(ProcessQueue.QueueItemType.MetadataRefresh.ToString(), new BackgroundTaskItem(ProcessQueue.QueueItemType.MetadataRefresh));
|
||||
Intervals.Add(ProcessQueue.QueueItemType.OrganiseLibrary.ToString(), new BackgroundTaskItem(ProcessQueue.QueueItemType.OrganiseLibrary));
|
||||
Intervals.Add(ProcessQueue.QueueItemType.LibraryScan.ToString(), new BackgroundTaskItem(ProcessQueue.QueueItemType.LibraryScan));
|
||||
Intervals.Add(ProcessQueue.QueueItemType.Rematcher.ToString(), new BackgroundTaskItem(ProcessQueue.QueueItemType.Rematcher));
|
||||
Intervals.Add(ProcessQueue.QueueItemType.Maintainer.ToString(), new BackgroundTaskItem(ProcessQueue.QueueItemType.Maintainer));
|
||||
foreach (ProcessQueue.QueueItemType itemType in Enum.GetValues(typeof(ProcessQueue.QueueItemType)))
|
||||
{
|
||||
BackgroundTaskItem taskItem = new BackgroundTaskItem(itemType);
|
||||
if (taskItem.UserManageable == true)
|
||||
{
|
||||
if (!Intervals.ContainsKey(itemType.ToString()))
|
||||
{
|
||||
Intervals.Add(itemType.ToString(), taskItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Ok(Intervals);
|
||||
}
|
||||
@@ -133,45 +138,102 @@ namespace gaseous_server.Controllers
|
||||
[MapToApiVersion("1.0")]
|
||||
[MapToApiVersion("1.1")]
|
||||
[HttpPost]
|
||||
[Route("Settings/BackgroundTasks/Intervals")]
|
||||
[Route("Settings/BackgroundTasks/Configuration")]
|
||||
[Authorize(Roles = "Admin")]
|
||||
[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
|
||||
{
|
||||
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
|
||||
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 " + Interval.Value + " for task " + Interval.Key + " is below the minimum allowed value of " + taskItem.MinimumAllowedValue + ". Skipping.");
|
||||
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
|
||||
{
|
||||
Logging.Log(Logging.LogType.Warning, "Update Background Task", "Unable to update non-user manageable task " + TaskConfiguration.Task + ". Skipping.");
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 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 BackgroundTaskItem()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public BackgroundTaskItem(ProcessQueue.QueueItemType TaskName)
|
||||
{
|
||||
this.Task = TaskName.ToString();
|
||||
this.TaskEnum = TaskName;
|
||||
|
||||
switch (TaskName)
|
||||
{
|
||||
case ProcessQueue.QueueItemType.SignatureIngestor:
|
||||
this._UserManageable = true;
|
||||
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;
|
||||
|
||||
case ProcessQueue.QueueItemType.TitleIngestor:
|
||||
this._UserManageable = true;
|
||||
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;
|
||||
|
||||
case ProcessQueue.QueueItemType.MetadataRefresh:
|
||||
this._UserManageable = true;
|
||||
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;
|
||||
|
||||
case ProcessQueue.QueueItemType.OrganiseLibrary:
|
||||
this._UserManageable = true;
|
||||
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;
|
||||
|
||||
case ProcessQueue.QueueItemType.LibraryScan:
|
||||
this._UserManageable = true;
|
||||
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;
|
||||
|
||||
case ProcessQueue.QueueItemType.Rematcher:
|
||||
this._UserManageable = true;
|
||||
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;
|
||||
|
||||
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.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;
|
||||
|
||||
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 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 {
|
||||
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 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
|
||||
|
@@ -40,7 +40,7 @@ namespace gaseous_server.Controllers
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
public async Task<ActionResult> CreateAdminAccount(Authentication.RegisterViewModel model)
|
||||
{
|
||||
if (Config.ReadSetting("FirstRunStatus", "0") == "0")
|
||||
if (Config.ReadSetting<string>("FirstRunStatus", "0") == "0")
|
||||
{
|
||||
if (ModelState.IsValid)
|
||||
{
|
||||
@@ -68,7 +68,7 @@ namespace gaseous_server.Controllers
|
||||
await _signInManager.SignInAsync(user, isPersistent: true);
|
||||
|
||||
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);
|
||||
}
|
||||
|
@@ -37,8 +37,10 @@ namespace gaseous_server.Controllers.v1_1
|
||||
{
|
||||
var user = await _userManager.GetUserAsync(User);
|
||||
|
||||
byte[] CompressedState = Common.Compress(uploadState.StateByteArray);
|
||||
|
||||
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>
|
||||
{
|
||||
{ "userid", user.Id },
|
||||
@@ -47,10 +49,20 @@ namespace gaseous_server.Controllers.v1_1
|
||||
{ "statedatetime", DateTime.UtcNow },
|
||||
{ "name", "" },
|
||||
{ "screenshot", uploadState.ScreenshotByteArray },
|
||||
{ "state", uploadState.StateByteArray }
|
||||
{ "state", CompressedState },
|
||||
{ "zipped", true }
|
||||
};
|
||||
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));
|
||||
}
|
||||
|
||||
@@ -224,7 +236,7 @@ namespace gaseous_server.Controllers.v1_1
|
||||
{
|
||||
var user = await _userManager.GetUserAsync(User);
|
||||
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>
|
||||
{
|
||||
{ "id", StateId },
|
||||
@@ -242,7 +254,15 @@ namespace gaseous_server.Controllers.v1_1
|
||||
else
|
||||
{
|
||||
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";
|
||||
|
||||
var cd = new System.Net.Mime.ContentDisposition
|
||||
|
@@ -2,6 +2,8 @@
|
||||
using System.ComponentModel.Design.Serialization;
|
||||
using System.Data;
|
||||
using gaseous_server.Classes;
|
||||
using gaseous_server.Controllers;
|
||||
using Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Manage.Internal;
|
||||
using NuGet.Common;
|
||||
using NuGet.Packaging;
|
||||
|
||||
@@ -13,25 +15,63 @@ namespace gaseous_server
|
||||
|
||||
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)
|
||||
{
|
||||
_ItemType = ItemType;
|
||||
_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;
|
||||
_AllowManualStart = AllowManualStart;
|
||||
_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)
|
||||
{
|
||||
_ItemType = ItemType;
|
||||
_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;
|
||||
_AllowManualStart = AllowManualStart;
|
||||
_RemoveWhenStopped = RemoveWhenStopped;
|
||||
_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;
|
||||
@@ -42,13 +82,15 @@ namespace gaseous_server
|
||||
{
|
||||
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
|
||||
{
|
||||
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 _IsBlocked = false;
|
||||
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>();
|
||||
|
||||
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 QueueItemState ItemState => _ItemState;
|
||||
public DateTime LastRunTime => _LastRunTime;
|
||||
@@ -72,9 +139,56 @@ namespace gaseous_server
|
||||
{
|
||||
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
|
||||
{
|
||||
get
|
||||
@@ -233,12 +347,25 @@ namespace gaseous_server
|
||||
DatabaseMigration.UpgradeScriptBackgroundTasks();
|
||||
break;
|
||||
|
||||
case QueueItemType.Maintainer:
|
||||
Logging.Log(Logging.LogType.Debug, "Timered Event", "Starting Maintenance");
|
||||
case QueueItemType.DailyMaintainer:
|
||||
Logging.Log(Logging.LogType.Debug, "Timered Event", "Starting Daily Maintenance");
|
||||
Classes.Maintenance maintenance = new Maintenance{
|
||||
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;
|
||||
|
||||
case QueueItemType.TempCleanup:
|
||||
@@ -277,7 +404,14 @@ namespace gaseous_server
|
||||
}
|
||||
|
||||
_ForceExecute = false;
|
||||
if (_DisableWhenComplete == false)
|
||||
{
|
||||
_ItemState = QueueItemState.Stopped;
|
||||
}
|
||||
else
|
||||
{
|
||||
_ItemState = QueueItemState.Disabled;
|
||||
}
|
||||
_LastFinishTime = DateTime.UtcNow;
|
||||
_LastRunDuration = Math.Round((DateTime.UtcNow - _LastRunTime).TotalSeconds, 2);
|
||||
|
||||
@@ -296,6 +430,26 @@ namespace gaseous_server
|
||||
_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
|
||||
{
|
||||
get
|
||||
@@ -420,9 +574,14 @@ namespace gaseous_server
|
||||
BackgroundDatabaseUpgrade,
|
||||
|
||||
/// <summary>
|
||||
/// Performs a clean up of old files, and optimises the database
|
||||
/// Performs a clean up of old files, and purge old logs
|
||||
/// </summary>
|
||||
Maintainer,
|
||||
DailyMaintainer,
|
||||
|
||||
/// <summary>
|
||||
/// Performs more intensive cleanups and optimises the database
|
||||
/// </summary>
|
||||
WeeklyMaintainer,
|
||||
|
||||
/// <summary>
|
||||
/// Cleans up marked paths in the temporary directory
|
||||
|
@@ -55,15 +55,6 @@ Communications.MetadataSource = Config.MetadataConfiguration.MetadataSource;
|
||||
// set up hasheous client
|
||||
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
|
||||
if (Directory.Exists(Config.LibraryConfiguration.LibraryTempDirectory))
|
||||
{
|
||||
@@ -421,69 +412,38 @@ var platformMap = PlatformMapping.PlatformMap;
|
||||
|
||||
// add background tasks
|
||||
ProcessQueue.QueueItems.Add(new ProcessQueue.QueueItem(
|
||||
ProcessQueue.QueueItemType.SignatureIngestor,
|
||||
int.Parse(Config.ReadSetting("Interval_SignatureIngestor", "60"))
|
||||
)
|
||||
ProcessQueue.QueueItemType.SignatureIngestor)
|
||||
);
|
||||
ProcessQueue.QueueItems.Add(new ProcessQueue.QueueItem(
|
||||
ProcessQueue.QueueItemType.TitleIngestor,
|
||||
int.Parse(Config.ReadSetting("Interval_TitleIngestor", "1")),
|
||||
new List<ProcessQueue.QueueItemType>
|
||||
{
|
||||
ProcessQueue.QueueItemType.OrganiseLibrary,
|
||||
ProcessQueue.QueueItemType.LibraryScan
|
||||
})
|
||||
ProcessQueue.QueueItemType.TitleIngestor)
|
||||
);
|
||||
ProcessQueue.QueueItems.Add(new ProcessQueue.QueueItem(
|
||||
ProcessQueue.QueueItemType.MetadataRefresh,
|
||||
int.Parse(Config.ReadSetting("Interval_MetadataRefresh", "360"))
|
||||
)
|
||||
ProcessQueue.QueueItemType.MetadataRefresh)
|
||||
);
|
||||
ProcessQueue.QueueItems.Add(new ProcessQueue.QueueItem(
|
||||
ProcessQueue.QueueItemType.OrganiseLibrary,
|
||||
int.Parse(Config.ReadSetting("Interval_OrganiseLibrary", "1440")),
|
||||
new List<ProcessQueue.QueueItemType>
|
||||
{
|
||||
ProcessQueue.QueueItemType.LibraryScan,
|
||||
ProcessQueue.QueueItemType.TitleIngestor,
|
||||
ProcessQueue.QueueItemType.Rematcher
|
||||
})
|
||||
ProcessQueue.QueueItemType.OrganiseLibrary)
|
||||
);
|
||||
ProcessQueue.QueueItems.Add(new ProcessQueue.QueueItem(
|
||||
ProcessQueue.QueueItemType.LibraryScan,
|
||||
int.Parse(Config.ReadSetting("Interval_LibraryScan", "1440")),
|
||||
new List<ProcessQueue.QueueItemType>
|
||||
{
|
||||
ProcessQueue.QueueItemType.OrganiseLibrary,
|
||||
ProcessQueue.QueueItemType.Rematcher
|
||||
})
|
||||
ProcessQueue.QueueItemType.LibraryScan)
|
||||
);
|
||||
ProcessQueue.QueueItems.Add(new ProcessQueue.QueueItem(
|
||||
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.QueueItemType.Rematcher)
|
||||
);
|
||||
|
||||
ProcessQueue.QueueItem tempCleanup = new ProcessQueue.QueueItem(
|
||||
ProcessQueue.QueueItemType.TempCleanup,
|
||||
1,
|
||||
new List<ProcessQueue.QueueItemType>(),
|
||||
false,
|
||||
false
|
||||
// maintenance tasks
|
||||
ProcessQueue.QueueItem dailyMaintenance = new ProcessQueue.QueueItem(
|
||||
ProcessQueue.QueueItemType.DailyMaintainer
|
||||
);
|
||||
ProcessQueue.QueueItems.Add(dailyMaintenance);
|
||||
|
||||
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);
|
||||
|
||||
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.");
|
||||
Logging.Log(Logging.LogType.Debug, "Background", "Starting background task monitor");
|
||||
|
||||
_timer = new Timer(DoWork, null, TimeSpan.Zero,
|
||||
TimeSpan.FromSeconds(5));
|
||||
_timer = new Timer(DoWork, null, TimeSpan.FromSeconds(30),
|
||||
TimeSpan.FromSeconds(30));
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
@@ -36,6 +36,8 @@ namespace gaseous_server
|
||||
List<ProcessQueue.QueueItem> ActiveList = new List<ProcessQueue.QueueItem>();
|
||||
ActiveList.AddRange(ProcessQueue.QueueItems);
|
||||
foreach (ProcessQueue.QueueItem qi in ActiveList) {
|
||||
if (qi.ItemState != ProcessQueue.QueueItemState.Disabled)
|
||||
{
|
||||
if (CheckIfProcessIsBlockedByOthers(qi) == false) {
|
||||
qi.BlockedState(false);
|
||||
if (DateTime.UtcNow > qi.NextRunTime || qi.Force == true)
|
||||
@@ -53,6 +55,7 @@ namespace gaseous_server
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Task StopAsync(CancellationToken stoppingToken)
|
||||
{
|
||||
|
@@ -60,6 +60,7 @@
|
||||
<None Remove="Support\Database\MySQL\gaseous-1013.sql" />
|
||||
<None Remove="Support\Database\MySQL\gaseous-1014.sql" />
|
||||
<None Remove="Support\Database\MySQL\gaseous-1015.sql" />
|
||||
<None Remove="Support\Database\MySQL\gaseous-1016.sql" />
|
||||
<None Remove="Classes\Metadata\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@@ -97,5 +98,6 @@
|
||||
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1013.sql" />
|
||||
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1014.sql" />
|
||||
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1015.sql" />
|
||||
<EmbeddedResource Include="Support\Database\MySQL\gaseous-1016.sql" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
@@ -29,6 +29,7 @@
|
||||
EJS_pathtodata = '/emulators/EmulatorJS/data/';
|
||||
|
||||
EJS_DEBUG_XX = false;
|
||||
console.log("Debug enabled: " + EJS_DEBUG_XX);
|
||||
|
||||
EJS_backgroundImage = emuBackground;
|
||||
EJS_backgroundBlur = true;
|
||||
|
@@ -268,7 +268,7 @@
|
||||
if (newPassword.length > 0) {
|
||||
if (newPassword == conPassword) {
|
||||
// check if password meets requirements
|
||||
if (newPassword.length > 10) {
|
||||
if (newPassword.length >= 10) {
|
||||
errorLabel.innerHTML = "";
|
||||
submitButton.removeAttribute('disabled');
|
||||
return true;
|
||||
|
@@ -49,7 +49,7 @@
|
||||
if (userNameVal.includes("@")) {
|
||||
if (newPassword == conPassword) {
|
||||
// check if password meets requirements
|
||||
if (newPassword.length > 10) {
|
||||
if (newPassword.length >= 10) {
|
||||
errorLabel.innerHTML = "";
|
||||
submitButton.removeAttribute('disabled');
|
||||
} else {
|
||||
|
@@ -285,7 +285,7 @@
|
||||
} else {
|
||||
if (newPassword == conPassword) {
|
||||
// check if password meets requirements
|
||||
if (newPassword.length > 10) {
|
||||
if (newPassword.length >= 10) {
|
||||
errorLabel.innerHTML = "";
|
||||
submitButton.removeAttribute('disabled');
|
||||
} else {
|
||||
|
@@ -117,7 +117,7 @@
|
||||
} else {
|
||||
if (newPassword == conPassword) {
|
||||
// check if password meets requirements
|
||||
if (newPassword.length > 10) {
|
||||
if (newPassword.length >= 10) {
|
||||
errorLabel.innerHTML = " ";
|
||||
submitButton.removeAttribute('disabled');
|
||||
} else {
|
||||
|
@@ -11,7 +11,6 @@
|
||||
<h2>Advanced Settings</h2>
|
||||
<p><strong>Warning</strong> Do not modify the below settings unless you know what you're doing.</p>
|
||||
<h3>Background Task Timers</h3>
|
||||
<p>All intervals are in minutes.</p>
|
||||
<table id="settings_tasktimers" class="romtable" style="width: 100%;" cellspacing="0">
|
||||
|
||||
</table>
|
||||
@@ -104,44 +103,241 @@
|
||||
|
||||
function getBackgroundTaskTimers() {
|
||||
ajaxCall(
|
||||
'/api/v1/System/Settings/BackgroundTasks/Intervals',
|
||||
'/api/v1/System/Settings/BackgroundTasks/Configuration',
|
||||
'GET',
|
||||
function(result) {
|
||||
var targetTable = document.getElementById('settings_tasktimers');
|
||||
targetTable.innerHTML = '';
|
||||
|
||||
targetTable.appendChild(
|
||||
createTableRow(true, ['Background Task', 'Timer Interval', 'Default Interval', 'Minimum Allowed Interval'])
|
||||
);
|
||||
|
||||
for (const [key, value] of Object.entries(result)) {
|
||||
var newTableRow = createTableRow(
|
||||
var newTableRowBody = document.createElement('tbody');
|
||||
newTableRowBody.className = 'romrow';
|
||||
|
||||
var enabledString = "";
|
||||
if (value.enabled == true) {
|
||||
enabledString = 'checked="checked"';
|
||||
}
|
||||
|
||||
var newTableIntervalRow = createTableRow(
|
||||
false,
|
||||
[
|
||||
GetTaskFriendlyName(value.task),
|
||||
'<input id="settings_tasktimers_' + value.task + '" name="settings_tasktimers_values" data-name="' + value.task + '" data-default="' + value.defaultInterval + '" type="number" placeholder="0" min="' + value.minimumAllowedValue + '" value="' + value.interval + '" />',
|
||||
value.defaultInterval,
|
||||
value.minimumAllowedValue
|
||||
'Enabled',
|
||||
'<input id="settings_enabled_' + value.task + '" name="settings_tasktimers_enabled" type="checkbox" ' + enabledString + '/>',
|
||||
],
|
||||
'romrow',
|
||||
'',
|
||||
'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() {
|
||||
var timerValues = document.getElementsByName('settings_tasktimers_values');
|
||||
|
||||
var model = {};
|
||||
var model = [];
|
||||
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(
|
||||
'/api/v1/System/Settings/BackgroundTasks/Intervals',
|
||||
'/api/v1/System/Settings/BackgroundTasks/Configuration',
|
||||
'POST',
|
||||
function(result) {
|
||||
getBackgroundTaskTimers();
|
||||
@@ -154,12 +350,32 @@
|
||||
}
|
||||
|
||||
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');
|
||||
|
||||
for (var i = 0; i < timerValues.length; i++) {
|
||||
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();
|
||||
}
|
||||
|
||||
|
@@ -410,13 +410,25 @@ function GetTaskFriendlyName(TaskName, options) {
|
||||
case 'LibraryScan':
|
||||
return "Library scan";
|
||||
case 'LibraryScanWorker':
|
||||
if (options) {
|
||||
return "Library scan worker: " + options.name;
|
||||
} else {
|
||||
return "Library scan worker";
|
||||
}
|
||||
case 'CollectionCompiler':
|
||||
if (options) {
|
||||
return "Compress collection id: " + options;
|
||||
} else {
|
||||
return "Compress collection";
|
||||
}
|
||||
case 'BackgroundDatabaseUpgrade':
|
||||
return "Background database upgrade";
|
||||
case 'TempCleanup':
|
||||
return "Temporary directory cleanup";
|
||||
case 'DailyMaintainer':
|
||||
return "Daily maintenance";
|
||||
case 'WeeklyMaintainer':
|
||||
return "Weekly maintenance";
|
||||
default:
|
||||
return TaskName;
|
||||
}
|
||||
|
Reference in New Issue
Block a user