That one evil commit that means you've actually started development like a real developer. But before that you just wrote things
174 lines
5.9 KiB
C#
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;
|
|
}
|
|
|
|
|
|
}
|