An Object Storage can now be configured in the ImGui.

This commit is contained in:
feyris-tan 2025-07-01 18:20:58 +02:00
parent 12c6004578
commit 1faa402dce
7 changed files with 250 additions and 19 deletions

View File

@ -35,6 +35,8 @@ namespace skyscraper5.Data.Minio
.WithCredentials(AccessKey, SecretKey) .WithCredentials(AccessKey, SecretKey)
.WithSSL(Secure).Build(); .WithSSL(Secure).Build();
BucketExistsArgs bucketExistsArgs = new BucketExistsArgs().WithBucket(Bucket); BucketExistsArgs bucketExistsArgs = new BucketExistsArgs().WithBucket(Bucket);
Task<bool> bucketExistsAsync = mc.BucketExistsAsync(bucketExistsArgs);
bucketExistsAsync.Wait();
bool bucketExists = mc.BucketExistsAsync(bucketExistsArgs).Result; bool bucketExists = mc.BucketExistsAsync(bucketExistsArgs).Result;
if (!bucketExists) if (!bucketExists)
{ {

View File

@ -5,7 +5,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Minio" Version="6.0.5" /> <PackageReference Include="Minio" Version="6.0.4" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -30,7 +30,7 @@ namespace skyscraper5.Data.PostgreSql
public DataStorage CreateDataStorage() public DataStorage CreateDataStorage()
{ {
logger.Log(PluginLogLevel.Info, "Connecting to PostgreSQL & MinIO"); logger.Log(PluginLogLevel.Info, "Connecting to postgres://{3}@{0}:{1}/{2}",Host,Port,Database,Username);
NpgsqlConnectionStringBuilder ncsb = new NpgsqlConnectionStringBuilder(); NpgsqlConnectionStringBuilder ncsb = new NpgsqlConnectionStringBuilder();
ncsb.Database = Database; ncsb.Database = Database;
ncsb.ApplicationName = "skyscraper5"; ncsb.ApplicationName = "skyscraper5";

View File

@ -25,7 +25,7 @@ namespace SDL2Demo.Forms
Ini = ini; Ini = ini;
StorageFactories = storageFactories; StorageFactories = storageFactories;
IsOpen = true; IsOpen = true;
storageId = ini.ReadValue("startup", "storage", 0); storageId = ini.ReadValue("startup", "dataStorage", 0);
settings = new List<Setting>(); settings = new List<Setting>();
FactoryNames = new Dictionary<int, string>(); FactoryNames = new Dictionary<int, string>();
connectionManager = StorageConnectionManager.GetInstance(); connectionManager = StorageConnectionManager.GetInstance();

View File

@ -0,0 +1,191 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using ImGuiNET;
using skyscraper5.Skyscraper;
using skyscraper8.Skyscraper.Scraper.Storage;
namespace SDL2Demo.Forms
{
internal class ConfigureObjectStorageWindow : IRenderable
{
public Ini Ini { get; }
public ReadOnlyCollection<KeyValuePair<int, ObjectStorageFactory>> StorageFactories { get; }
private Dictionary<int, string> FactoryNames;
private Dictionary<int, Guid> TempGuids;
private StorageConnectionManager connectionManager;
public ConfigureObjectStorageWindow(Ini ini, ReadOnlyCollection<KeyValuePair<int, ObjectStorageFactory>> storageFactories)
{
Ini = ini;
StorageFactories = storageFactories;
IsOpen = true;
storageId = ini.ReadValue("startup", "objectStorage", 0);
settings = new List<ConfigureDataStorageWindow.Setting>();
FactoryNames = new Dictionary<int, string>();
connectionManager = StorageConnectionManager.GetInstance();
TempGuids = new Dictionary<int, Guid>();
foreach (KeyValuePair<int, ObjectStorageFactory> keyValuePair in storageFactories)
{
FactoryNames.Add(keyValuePair.Key, connectionManager.GetName(keyValuePair.Value));
TempGuids.Add(keyValuePair.Key, Guid.NewGuid());
PropertyInfo[] propertyInfos = keyValuePair.Value.GetType().GetProperties();
foreach (PropertyInfo propertyInfo in propertyInfos)
{
ConfigureDataStorageWindow.Setting s = new ConfigureDataStorageWindow.Setting();
s.IniKey = keyValuePair.Key;
s.SettingName = propertyInfo.Name;
s.SettingControlUuid = Guid.NewGuid().ToString();
switch (propertyInfo.PropertyType.Name)
{
case nameof(String):
s.SettingMode = 1;
s.StringValue = ini.ReadValue(String.Format("objectStorage{0}", s.IniKey), s.SettingName, "");
break;
case nameof(Boolean):
s.SettingMode = 2;
s.BooleanValue = ini.ReadValue(String.Format("objectStorage{0}", s.IniKey), s.SettingName, false);
break;
case nameof(UInt16):
s.SettingMode = 3;
s.UshortValue = (ushort)ini.ReadValue(String.Format("objectStorage{0}", s.IniKey), s.SettingName, ushort.MinValue);
break;
default:
throw new NotImplementedException(propertyInfo.PropertyType.Name);
}
settings.Add(s);
}
}
}
public bool IsOpen;
private bool HasChanges;
private int storageId;
private List<ConfigureDataStorageWindow.Setting> settings;
public bool RequireRestart;
private void Save()
{
Ini.WriteValue("startup", "objectStorage", storageId);
foreach (ConfigureDataStorageWindow.Setting setting in settings)
{
switch (setting.SettingMode)
{
case 1:
Ini.WriteValue(String.Format("objectStorage{0}", setting.IniKey), setting.SettingName, setting.StringValue);
break;
case 2:
Ini.WriteValue(String.Format("objectStorage{0}", setting.IniKey), setting.SettingName, setting.BooleanValue);
break;
case 3:
Ini.WriteValue(String.Format("objectStorage{0}", setting.IniKey), setting.SettingName, setting.UshortValue);
break;
default:
throw new NotImplementedException(String.Format("Setting mode {0}", setting.SettingMode));
}
}
Ini.Export(new FileInfo("skyscraper5.ini"));
if (HasChanges)
RequireRestart = true;
HasChanges = false;
}
private bool CanApply()
{
foreach (ConfigureDataStorageWindow.Setting setting in settings.Where(x => x.IniKey == storageId))
{
if (!setting.Validate())
{
return false;
}
}
return true;
}
public void Render()
{
ImGuiWindowFlags flags = ImGuiWindowFlags.None;
if (HasChanges)
flags |= ImGuiWindowFlags.UnsavedDocument;
ImGui.Begin("Configure ScraperStorage", ref IsOpen, flags);
foreach (KeyValuePair<int, ObjectStorageFactory> keyValuePair in StorageFactories)
{
if (ImGui.RadioButton(FactoryNames[keyValuePair.Key], ref storageId, keyValuePair.Key))
{
HasChanges = true;
}
ImGui.BeginTable(TempGuids[keyValuePair.Key].ToString(), 2);
foreach (ConfigureDataStorageWindow.Setting setting in settings.Where(x => x.IniKey == keyValuePair.Key))
{
ImGui.TableNextRow();
ImGui.TableSetColumnIndex(0);
ImGui.Text(setting.SettingName);
ImGui.TableSetColumnIndex(1);
ImGui.PushID(setting.SettingControlUuid);
switch (setting.SettingMode)
{
case 1:
if (ImGui.InputText("", ref setting.StringValue, 255))
HasChanges = true;
break;
case 2:
if (ImGui.Checkbox("", ref setting.BooleanValue))
HasChanges = true;
break;
case 3:
if (setting.UshortValue < ushort.MinValue)
setting.UshortValue = ushort.MinValue;
if (setting.UshortValue > ushort.MaxValue)
setting.UshortValue = ushort.MaxValue;
if (ImGui.InputInt("", ref setting.UshortValue))
HasChanges = true;
break;
default:
throw new NotImplementedException(String.Format("Setting mode {0}", setting.SettingMode));
}
}
ImGui.PopID();
ImGui.EndTable();
}
bool canApply = CanApply();
ImGui.BeginDisabled(!canApply);
if (ImGui.Button("OK"))
{
Save();
IsOpen = false;
}
ImGui.EndDisabled();
ImGui.SameLine();
if (ImGui.Button("Cancel"))
{
IsOpen = false;
}
ImGui.SameLine();
ImGui.BeginDisabled(!canApply);
if (ImGui.Button("Apply"))
{
Save();
}
ImGui.EndDisabled();
ImGui.End();
}
}
}

View File

@ -167,10 +167,11 @@ namespace SDL2Demo.Forms
} }
ImGui.PopID(); ImGui.PopID();
} }
ImGui.EndTable(); ImGui.EndTable();
} }
ImGui.Separator();
bool canApply = CanApply(); bool canApply = CanApply();
ImGui.BeginDisabled(!canApply); ImGui.BeginDisabled(!canApply);
if (ImGui.Button("OK")) if (ImGui.Button("OK"))

View File

@ -200,7 +200,8 @@ namespace SkyscraperUI
private List<MessageWindow> messageWindows; private List<MessageWindow> messageWindows;
private AboutWindow aboutWindow; private AboutWindow aboutWindow;
private ConfigureDataStorageWindow configureStorageWindow; private ConfigureDataStorageWindow configureDataStorageWindow;
private ConfigureObjectStorageWindow configureObjectStorageWindow;
private SatellitesConfigurationWindow satellitesConfigurationWindow; private SatellitesConfigurationWindow satellitesConfigurationWindow;
private List<SatellitePosition> satellitePositions; private List<SatellitePosition> satellitePositions;
private List<LnbType> lnbTypes; private List<LnbType> lnbTypes;
@ -522,11 +523,6 @@ namespace SkyscraperUI
configureDishTypesWindow = new ConfigureDishTypes(dataStorage, dishTypes); configureDishTypesWindow = new ConfigureDishTypes(dataStorage, dishTypes);
} }
if (ImGui.MenuItem("Configure Data Storage", configureStorageWindow == null))
{
configureStorageWindow = new ConfigureDataStorageWindow(ini, dataStorageFactories);
}
if (ImGui.MenuItem("Configure GPS Receiver", configureGpsWindow == null)) if (ImGui.MenuItem("Configure GPS Receiver", configureGpsWindow == null))
{ {
configureGpsWindow = new ConfigureGpsWindow(ini); configureGpsWindow = new ConfigureGpsWindow(ini);
@ -536,8 +532,18 @@ namespace SkyscraperUI
{ {
satellitesConfigurationWindow = new SatellitesConfigurationWindow(dataStorage); satellitesConfigurationWindow = new SatellitesConfigurationWindow(dataStorage);
} }
ImGui.EndMenu(); if (ImGui.MenuItem("Configure Data Storage", configureDataStorageWindow == null))
{
configureDataStorageWindow = new ConfigureDataStorageWindow(ini, dataStorageFactories);
}
if (ImGui.MenuItem("Configure Object Storage", configureObjectStorageWindow == null))
{
configureObjectStorageWindow = new ConfigureObjectStorageWindow(ini, objectStorageFactories);
}
ImGui.EndMenu();
} }
if (ImGui.BeginMenu("Data")) if (ImGui.BeginMenu("Data"))
@ -620,12 +626,12 @@ namespace SkyscraperUI
if (showDemoWindow) if (showDemoWindow)
ImGui.ShowDemoWindow(); ImGui.ShowDemoWindow();
if (configureStorageWindow != null) if (configureDataStorageWindow != null)
{ {
configureStorageWindow.Render(); configureDataStorageWindow.Render();
if (!configureStorageWindow.IsOpen) if (!configureDataStorageWindow.IsOpen)
{ {
if (configureStorageWindow.RequireRestart) if (configureDataStorageWindow.RequireRestart)
{ {
MessageWindow mw = new MessageWindow( MessageWindow mw = new MessageWindow(
"To apply the storage configuration, skyscraper5 will need to restart. Press the okay button to exit the application."); "To apply the storage configuration, skyscraper5 will need to restart. Press the okay button to exit the application.");
@ -633,11 +639,28 @@ namespace SkyscraperUI
messageWindows.Add(mw); messageWindows.Add(mw);
} }
configureStorageWindow = null; configureDataStorageWindow = null;
} }
} }
if (configureGpsWindow != null) if (configureObjectStorageWindow != null)
{
configureObjectStorageWindow.Render();
if (!configureObjectStorageWindow.IsOpen)
{
if (configureObjectStorageWindow.RequireRestart)
{
MessageWindow mw = new MessageWindow(
"To apply the storage configuration, skyscraper5 will need to restart. Press the okay button to exit the application.");
mw.OnClose = () => quit = true;
messageWindows.Add(mw);
}
configureObjectStorageWindow = null;
}
}
if (configureGpsWindow != null)
{ {
configureGpsWindow.Render(); configureGpsWindow.Render();
if (!configureGpsWindow.IsOpen) if (!configureGpsWindow.IsOpen)
@ -877,7 +900,21 @@ namespace SkyscraperUI
{ {
uiBlockingWindow.Text = "It isn't."; uiBlockingWindow.Text = "It isn't.";
uiBlockingWindow.Line2 = "Creating object storage..."; uiBlockingWindow.Line2 = "Creating object storage...";
objectStorage = objectStorageFactory.CreateObjectStorage(); try
{
objectStorage = objectStorageFactory.CreateObjectStorage();
}
catch (Exception e)
{
string objectStorageName = connectionManager.GetName(objectStorageFactory);
localLogger.Log(PluginLogLevel.Error, "Failed to start the object storage factory: {0}", e.Message);
string rant = String.Format("Could not load {1}.\nThe following went wrong:\n\n{0}\n\n", e.Message, objectStorageName);
messageWindows.Add(new MessageWindow(rant));
blockUi = false;
showMainMenu = true;
return;
}
} }