diff --git a/src/AltGen.Console/AltGen.Console.csproj b/src/AltGen.Console/AltGen.Console.csproj
index 089a558..f4841cf 100644
--- a/src/AltGen.Console/AltGen.Console.csproj
+++ b/src/AltGen.Console/AltGen.Console.csproj
@@ -24,7 +24,7 @@
Generated
$(GeneratedCodeDirectory)\Constants.cs
- http://localhost:7297
+ https://localhost:7297
diff --git a/src/AltGen.Console/Common/HostBuilderExtensions.cs b/src/AltGen.Console/Common/HostBuilderExtensions.cs
index 8a08ab1..b1077e2 100644
--- a/src/AltGen.Console/Common/HostBuilderExtensions.cs
+++ b/src/AltGen.Console/Common/HostBuilderExtensions.cs
@@ -9,6 +9,13 @@ static class HostBuilderExtensions
app.Configure(static c =>
{
+ c.SetExceptionHandler(static (ex, resolver) =>
+ {
+ var console = resolver?.Resolve(typeof(IAnsiConsole)) as IAnsiConsole;
+ console?.WriteException(ex, ExceptionFormats.ShortenEverything);
+ return -99;
+ });
+
c.AddBranch("config", static c =>
{
c.AddCommand("add");
diff --git a/src/AltGen.Console/Common/Providers.cs b/src/AltGen.Console/Common/Providers.cs
new file mode 100644
index 0000000..a4801de
--- /dev/null
+++ b/src/AltGen.Console/Common/Providers.cs
@@ -0,0 +1,17 @@
+using System.Globalization;
+
+namespace AltGen.Console.Common;
+
+static class Providers
+{
+ const string Gemini = "gemini";
+
+ public static bool IsSupported(string provider)
+ {
+ return provider.ToLower(CultureInfo.InvariantCulture) switch
+ {
+ Gemini => true,
+ _ => false
+ };
+ }
+}
\ No newline at end of file
diff --git a/src/AltGen.Console/Config/AddConfigCommand.cs b/src/AltGen.Console/Config/AddConfigCommand.cs
index 5d69f08..277b947 100644
--- a/src/AltGen.Console/Config/AddConfigCommand.cs
+++ b/src/AltGen.Console/Config/AddConfigCommand.cs
@@ -21,6 +21,16 @@ sealed class AddConfigCommand(
[CommandOption("-d|--default")]
[Description("Set the provider as the default.")]
public bool Default { get; init; }
+
+ public override ValidationResult Validate()
+ {
+ if (Providers.IsSupported(Provider) is false)
+ {
+ return ValidationResult.Error($"The provider '{Provider}' is not supported.");
+ }
+
+ return ValidationResult.Success();
+ }
}
public override async Task ExecuteAsync(CommandContext context, Settings settings)
diff --git a/src/AltGen.Console/Config/AppSettings.cs b/src/AltGen.Console/Config/AppSettings.cs
index a808f97..3863325 100644
--- a/src/AltGen.Console/Config/AppSettings.cs
+++ b/src/AltGen.Console/Config/AppSettings.cs
@@ -44,4 +44,19 @@ record AppSettings
var updatedProviders = Providers.Where(p => p.Provider != settings.Provider);
return this with { Providers = [.. updatedProviders] };
}
+
+ public ProviderSettings[] GetProviders()
+ {
+ return Providers;
+ }
+
+ public ProviderSettings? GetProvider(string provider)
+ {
+ return Providers.FirstOrDefault(p => p.Provider == provider);
+ }
+
+ public ProviderSettings? GetDefaultProvider()
+ {
+ return Providers.FirstOrDefault(static p => p.Default);
+ }
}
\ No newline at end of file
diff --git a/src/AltGen.Console/Config/ListConfigCommand.cs b/src/AltGen.Console/Config/ListConfigCommand.cs
index 8f42182..972c638 100644
--- a/src/AltGen.Console/Config/ListConfigCommand.cs
+++ b/src/AltGen.Console/Config/ListConfigCommand.cs
@@ -19,7 +19,7 @@ sealed class ListConfigCommand(
var appSettings = await _settingsManager.GetAppSettingsAsync();
- foreach (var provider in appSettings.Providers)
+ foreach (var provider in appSettings.GetProviders())
{
var providerName = provider.Provider;
var providerKey = provider.Key;
diff --git a/src/AltGen.Console/Generate/AltGenService.cs b/src/AltGen.Console/Generate/AltGenService.cs
index 9576aee..f782c7c 100644
--- a/src/AltGen.Console/Generate/AltGenService.cs
+++ b/src/AltGen.Console/Generate/AltGenService.cs
@@ -19,7 +19,7 @@ sealed class AltGenService(HttpClient client) : IAltGenService
{
{ new StringContent(req.Provider), "provider" },
{ new StringContent(req.ProviderKey), "providerKey" },
- { new ByteArrayContent(req.Image), "file", req.FileName }
+ { byteContent, "file", req.FileName }
}
};
@@ -41,4 +41,4 @@ record AltTextResponse(string AltText);
class AltTextException(string message) : Exception(message)
{
-}
+}
\ No newline at end of file
diff --git a/src/AltGen.Console/Generate/GenerateCommand.cs b/src/AltGen.Console/Generate/GenerateCommand.cs
index d4b7259..c076088 100644
--- a/src/AltGen.Console/Generate/GenerateCommand.cs
+++ b/src/AltGen.Console/Generate/GenerateCommand.cs
@@ -3,13 +3,15 @@ namespace AltGen.Console.Generate;
sealed class GenerateCommand(
IAnsiConsole console,
IFileSystem fileSystem,
- IAltGenService altGenService
+ IAltGenService altGenService,
+ IAppSettingsManager settingsManager
) : AsyncCommand
{
readonly IAnsiConsole _console = console;
readonly IFileSystem _fileSystem = fileSystem;
readonly IAltGenService _altGenService = altGenService;
+ readonly IAppSettingsManager _settingsManager = settingsManager;
public class Settings(IFileSystem fileSystem) : CommandSettings
{
@@ -20,21 +22,17 @@ sealed class GenerateCommand(
[".png"] = "image/png"
};
- readonly List _providers = [
- "gemini",
- ];
-
readonly IFileSystem _fileSystem = fileSystem;
- [CommandArgument(1, "")]
+ [CommandOption("-p|--provider")]
[Description("The provider to use for generating alt text.")]
public string Provider { get; init; } = string.Empty;
- [CommandArgument(2, "")]
+ [CommandOption("-k|--key")]
[Description("The key for the provider.")]
public string Key { get; init; } = string.Empty;
- [CommandArgument(3, "")]
+ [CommandArgument(1, "")]
[Description("The path to the image to generate alt text for.")]
public string Path { get; init; } = string.Empty;
@@ -42,13 +40,6 @@ sealed class GenerateCommand(
public override ValidationResult Validate()
{
- // TODO: We should allow provider and key to be optional
- // if they are not passed on the command line then
- // we should try to resolve them from configuration
- if (_providers.Contains(Provider) is false)
- {
- return ValidationResult.Error($"The provider '{Provider}' is not supported.");
- }
var pathExists = _fileSystem.File.Exists(Path);
@@ -70,12 +61,36 @@ sealed class GenerateCommand(
public override async Task ExecuteAsync(CommandContext context, Settings settings)
{
+ var appSettings = await _settingsManager.GetAppSettingsAsync();
+ var provider = settings.Provider;
+ var key = settings.Key;
+
+ if (string.IsNullOrWhiteSpace(provider))
+ {
+ var defaultProvider = appSettings.GetDefaultProvider()
+ ?? throw new AltTextException("Please specify a provider or set a default provider.");
+ provider = defaultProvider.Provider;
+ }
+
+ if (Providers.IsSupported(provider) is false)
+ {
+ throw new AltTextException($"The provider '{provider}' is not supported.");
+ }
+
+ if (string.IsNullOrWhiteSpace(key))
+ {
+ var selectedProvider = appSettings.GetProvider(provider)
+ ?? throw new AltTextException("Please specify a key or set a default provider.");
+ key = selectedProvider.Key;
+ }
+
+
var fileName = _fileSystem.Path.GetFileName(settings.Path);
var image = await _fileSystem.File.ReadAllBytesAsync(settings.Path);
var altText = await _altGenService.GenerateAltTextAsync(new(
- settings.Provider,
- settings.Key,
+ provider,
+ key,
fileName,
image,
settings.ContentType
diff --git a/src/AltGen.Console/Generated/Constants.cs b/src/AltGen.Console/Generated/Constants.cs
index c9ed236..6066b7a 100644
--- a/src/AltGen.Console/Generated/Constants.cs
+++ b/src/AltGen.Console/Generated/Constants.cs
@@ -2,5 +2,5 @@ namespace AltGen.Console.Generated;
static class Constants
{
- public const string AltGenApiUri = "http://localhost:7297";
+ public const string AltGenApiUri = "https://localhost:7297";
}