downloadmanager/Config.cs
Robert Morrison 9a1838becc
EVIL COMMIT!
That one evil commit that means you've actually started development like
a real developer.
But before that you just wrote things
2023-05-12 22:58:58 +01:00

174 lines
5.9 KiB
C#

using Serilog;
using Tommy;
namespace DownloadManager;
class configuration
{
private record struct options(bool dryRun,
bool confirm,
string downloadDirectory,
string logDirectory);
/* Default locations for essential things
arrays can be added to later by the user with the last valid entry being used.*/
private static readonly string _home =
Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
private static readonly string _defaultConfigLocation =
_home + "/.config/sherlock5512/downloadmanager";
private string[] _configLocations =
{ $"{_defaultConfigLocation}/config.toml" };
private string[] _ruleDirLocation =
{ $"{_defaultConfigLocation}/rules/" };
private static readonly options _defaultOptions =
new options(
dryRun: false,
confirm: false,
downloadDirectory: _home + "/Downloads",
logDirectory: _home + "/.local/share/sherlock5512");
/* Options are exposed via properties */
private options _options;
public bool dryRun { get => _options.dryRun; }
public bool confirm { get => _options.confirm; }
public string downloadDirectory { get => _options.downloadDirectory; }
public string logDirectory { get => _options.logDirectory; }
public string[] ruleDirectories /* Only returns directories that exist */
{
get => _ruleDirLocation
.Where(x => Directory.Exists(x))
.ToArray();
}
public configuration()
{
_options = new();
Log.Information("new Configuration object created");
_options = loadConfig() ?? _options; /* Attempt to load config */
createDirs();
verifyConfig();
}
/* When arguments are passed we use them and don't load a config*/
public configuration(bool? dryRun, bool? confirm, string? downloadDirectory, string? logDirectory)
{
_options = new( /* labels are used here to allow constructor signature changes */
dryRun: dryRun ?? _defaultOptions.dryRun,
confirm: confirm ?? _defaultOptions.confirm,
downloadDirectory: downloadDirectory ?? _defaultOptions.downloadDirectory,
logDirectory: logDirectory ?? _defaultOptions.logDirectory
);
createDirs();
verifyConfig();
}
/* If the user specifies a config file on the command line */
public configuration(string configLocation)
{
_configLocations.Append(configLocation);
var opt = loadConfig();
if (opt is null)
{
Log.Fatal("Could not load user provided config {loc}", configLocation);
Environment.Exit(78);
}
_options = (options)opt;
createDirs();
verifyConfig();
}
private options? loadConfig()
{
string[] ValidLocations = _configLocations.Where(x => Path.Exists(x)).ToArray();
foreach (var location in ValidLocations)
{
Log.Information("Attempting to load config from {location}", location);
try
{
Log.Debug("In try statement");
using (StreamReader reader = File.OpenText(location))
{
TomlTable table = TOML.Parse(reader);
Log.Debug("Parsed TOML to table: {@table}", table);
// get our config values
bool dryRun = table.HasKey("dryRun") ? table["dryRun"] : _defaultOptions.dryRun;
bool confirm = table.HasKey("confirm") ? table["confirm"] : _defaultOptions.confirm;
string downloadDirectory = table.HasKey("downloadDirectory") ? table["downloadDirectory"] : _defaultOptions.downloadDirectory;
string logDirectory = table.HasKey("logDirectory") ? table["logDirectory"] : _defaultOptions.logDirectory;
// construct the options object
options opts = new(
dryRun: dryRun,
confirm: confirm,
downloadDirectory: downloadDirectory,
logDirectory: logDirectory
);
Log.Debug("Constructed options object: {options}", opts);
return opts;
}
}
catch (TomlParseException e)
{
foreach (var syntaxEx in e.SyntaxErrors)
{
Log.Error("Toml error at l:{line} c:{col}: {message}", syntaxEx.Line, syntaxEx.Column, syntaxEx.Message);
}
}
catch (Exception e)
{
Log.Fatal(e, "Unhandled error decoding toml {location}", location);
Environment.Exit(78);
}
Log.Debug("After try catch block");
}
Log.Error("Attempted to load all valid locations but no config could be loaded successfully");
return null;
}
private bool verifyConfig()
{
if (!Directory.Exists(_options.logDirectory))
{
Log.Fatal("Log directory {dir} does not exist", logDirectory);
Environment.Exit(78);
}
if (!Directory.Exists(_options.downloadDirectory))
{
Log.Fatal("Downloads directory {dir} does not exist", downloadDirectory);
Environment.Exit(78);
}
return true;
}
/* Attempt to create some directories if missing */
private bool createDirs()
{
try
{
Directory.CreateDirectory(_defaultConfigLocation);
Directory.CreateDirectory(_options.logDirectory);
}
catch (UnauthorizedAccessException e)
{
Log.Warning(e, "Failed to create directory, This may cause other errors");
return false;
}
return true;
}
}