feat: success console app => api => gemini
This commit is contained in:
@@ -24,7 +24,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<GeneratedCodeDirectory>Generated</GeneratedCodeDirectory>
|
<GeneratedCodeDirectory>Generated</GeneratedCodeDirectory>
|
||||||
<GeneratedConstantsFile>$(GeneratedCodeDirectory)\Constants.cs</GeneratedConstantsFile>
|
<GeneratedConstantsFile>$(GeneratedCodeDirectory)\Constants.cs</GeneratedConstantsFile>
|
||||||
<AltGenApiUri>http://localhost:7297</AltGenApiUri>
|
<AltGenApiUri>https://localhost:7297</AltGenApiUri>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<Target Name="GenerateBuildConstants" BeforeTargets="BeforeBuild;BeforeRebuild">
|
<Target Name="GenerateBuildConstants" BeforeTargets="BeforeBuild;BeforeRebuild">
|
||||||
|
|||||||
@@ -9,6 +9,13 @@ static class HostBuilderExtensions
|
|||||||
|
|
||||||
app.Configure(static c =>
|
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.AddBranch("config", static c =>
|
||||||
{
|
{
|
||||||
c.AddCommand<AddConfigCommand>("add");
|
c.AddCommand<AddConfigCommand>("add");
|
||||||
|
|||||||
@@ -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
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -21,6 +21,16 @@ sealed class AddConfigCommand(
|
|||||||
[CommandOption("-d|--default")]
|
[CommandOption("-d|--default")]
|
||||||
[Description("Set the provider as the default.")]
|
[Description("Set the provider as the default.")]
|
||||||
public bool Default { get; init; }
|
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<int> ExecuteAsync(CommandContext context, Settings settings)
|
public override async Task<int> ExecuteAsync(CommandContext context, Settings settings)
|
||||||
|
|||||||
@@ -44,4 +44,19 @@ record AppSettings
|
|||||||
var updatedProviders = Providers.Where(p => p.Provider != settings.Provider);
|
var updatedProviders = Providers.Where(p => p.Provider != settings.Provider);
|
||||||
return this with { Providers = [.. updatedProviders] };
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -19,7 +19,7 @@ sealed class ListConfigCommand(
|
|||||||
|
|
||||||
var appSettings = await _settingsManager.GetAppSettingsAsync();
|
var appSettings = await _settingsManager.GetAppSettingsAsync();
|
||||||
|
|
||||||
foreach (var provider in appSettings.Providers)
|
foreach (var provider in appSettings.GetProviders())
|
||||||
{
|
{
|
||||||
var providerName = provider.Provider;
|
var providerName = provider.Provider;
|
||||||
var providerKey = provider.Key;
|
var providerKey = provider.Key;
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ sealed class AltGenService(HttpClient client) : IAltGenService
|
|||||||
{
|
{
|
||||||
{ new StringContent(req.Provider), "provider" },
|
{ new StringContent(req.Provider), "provider" },
|
||||||
{ new StringContent(req.ProviderKey), "providerKey" },
|
{ 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)
|
class AltTextException(string message) : Exception(message)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -3,13 +3,15 @@ namespace AltGen.Console.Generate;
|
|||||||
sealed class GenerateCommand(
|
sealed class GenerateCommand(
|
||||||
IAnsiConsole console,
|
IAnsiConsole console,
|
||||||
IFileSystem fileSystem,
|
IFileSystem fileSystem,
|
||||||
IAltGenService altGenService
|
IAltGenService altGenService,
|
||||||
|
IAppSettingsManager settingsManager
|
||||||
) : AsyncCommand<GenerateCommand.Settings>
|
) : AsyncCommand<GenerateCommand.Settings>
|
||||||
{
|
{
|
||||||
|
|
||||||
readonly IAnsiConsole _console = console;
|
readonly IAnsiConsole _console = console;
|
||||||
readonly IFileSystem _fileSystem = fileSystem;
|
readonly IFileSystem _fileSystem = fileSystem;
|
||||||
readonly IAltGenService _altGenService = altGenService;
|
readonly IAltGenService _altGenService = altGenService;
|
||||||
|
readonly IAppSettingsManager _settingsManager = settingsManager;
|
||||||
|
|
||||||
public class Settings(IFileSystem fileSystem) : CommandSettings
|
public class Settings(IFileSystem fileSystem) : CommandSettings
|
||||||
{
|
{
|
||||||
@@ -20,21 +22,17 @@ sealed class GenerateCommand(
|
|||||||
[".png"] = "image/png"
|
[".png"] = "image/png"
|
||||||
};
|
};
|
||||||
|
|
||||||
readonly List<string> _providers = [
|
|
||||||
"gemini",
|
|
||||||
];
|
|
||||||
|
|
||||||
readonly IFileSystem _fileSystem = fileSystem;
|
readonly IFileSystem _fileSystem = fileSystem;
|
||||||
|
|
||||||
[CommandArgument(1, "<provider>")]
|
[CommandOption("-p|--provider")]
|
||||||
[Description("The provider to use for generating alt text.")]
|
[Description("The provider to use for generating alt text.")]
|
||||||
public string Provider { get; init; } = string.Empty;
|
public string Provider { get; init; } = string.Empty;
|
||||||
|
|
||||||
[CommandArgument(2, "<key>")]
|
[CommandOption("-k|--key")]
|
||||||
[Description("The key for the provider.")]
|
[Description("The key for the provider.")]
|
||||||
public string Key { get; init; } = string.Empty;
|
public string Key { get; init; } = string.Empty;
|
||||||
|
|
||||||
[CommandArgument(3, "<path>")]
|
[CommandArgument(1, "<path>")]
|
||||||
[Description("The path to the image to generate alt text for.")]
|
[Description("The path to the image to generate alt text for.")]
|
||||||
public string Path { get; init; } = string.Empty;
|
public string Path { get; init; } = string.Empty;
|
||||||
|
|
||||||
@@ -42,13 +40,6 @@ sealed class GenerateCommand(
|
|||||||
|
|
||||||
public override ValidationResult Validate()
|
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);
|
var pathExists = _fileSystem.File.Exists(Path);
|
||||||
|
|
||||||
@@ -70,12 +61,36 @@ sealed class GenerateCommand(
|
|||||||
|
|
||||||
public override async Task<int> ExecuteAsync(CommandContext context, Settings settings)
|
public override async Task<int> 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 fileName = _fileSystem.Path.GetFileName(settings.Path);
|
||||||
var image = await _fileSystem.File.ReadAllBytesAsync(settings.Path);
|
var image = await _fileSystem.File.ReadAllBytesAsync(settings.Path);
|
||||||
|
|
||||||
var altText = await _altGenService.GenerateAltTextAsync(new(
|
var altText = await _altGenService.GenerateAltTextAsync(new(
|
||||||
settings.Provider,
|
provider,
|
||||||
settings.Key,
|
key,
|
||||||
fileName,
|
fileName,
|
||||||
image,
|
image,
|
||||||
settings.ContentType
|
settings.ContentType
|
||||||
|
|||||||
@@ -2,5 +2,5 @@ namespace AltGen.Console.Generated;
|
|||||||
|
|
||||||
static class Constants
|
static class Constants
|
||||||
{
|
{
|
||||||
public const string AltGenApiUri = "http://localhost:7297";
|
public const string AltGenApiUri = "https://localhost:7297";
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user