diff --git a/README.md b/README.md index 1b6fc09..79efc81 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ The application now provides a rich CLI with Picocli. For detailed CLI documenta mvn quarkus:dev -Dquarkus.args="--help" # Generate image with custom prompt -mvn quarkus:dev -Dquarkus.args="--prompt 'Create a vibrant conference banner' -o output.png" +quarkus dev -Dquarkus.args='image --template-name=generate-image-blog-post --title=DuckDB --name=zMember -o=outpu.png --z-photo=images/people/my-z-member.png' # Generate video mvn quarkus:dev -Dquarkus.args="-t video --prompt 'Conference intro' --vertex" diff --git a/src/main/java/zenika/marketing/cli/GenerateImageCommand.java b/src/main/java/zenika/marketing/cli/GenerateImageCommand.java index 9ee2975..5d0fc55 100644 --- a/src/main/java/zenika/marketing/cli/GenerateImageCommand.java +++ b/src/main/java/zenika/marketing/cli/GenerateImageCommand.java @@ -1,13 +1,23 @@ package zenika.marketing.cli; +import com.google.genai.types.Content; +import com.google.genai.types.Part; import io.quarkus.logging.Log; import jakarta.inject.Inject; import picocli.CommandLine.Command; import picocli.CommandLine.Option; import zenika.marketing.config.ConfigProperties; import zenika.marketing.config.MODE_FEATURE; -import zenika.marketing.services.GeminiServices; +import zenika.marketing.domain.Template; +import zenika.marketing.services.GeminiImagesServices; import zenika.marketing.services.TemplateService; +import zenika.marketing.utils.Utils; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Map; +import java.util.function.Consumer; @Command( name = "image", @@ -17,7 +27,7 @@ public class GenerateImageCommand implements Runnable { @Inject - GeminiServices geminiServices; + GeminiImagesServices geminiServices; @Inject ConfigProperties config; @@ -27,7 +37,7 @@ public class GenerateImageCommand implements Runnable { @Option( names = {"-o", "--output"}, - description = "Output filename (default: ${DEFAULT-VALUE})" + description = "Output filename" ) String output; @@ -38,16 +48,16 @@ public class GenerateImageCommand implements Runnable { String templatePath; @Option( - names = {"--file1"}, - description = "Path to first additional image" + names = {"--name"}, + description = "Speaker or writer Name" ) - String file1Path; + String name; @Option( - names = {"--file2"}, - description = "Path to second additional image" + names = {"--title"}, + description = "Blog post or talk title" ) - String file2Path; + String title; @Option( names = {"-m", "--model"}, @@ -55,6 +65,18 @@ public class GenerateImageCommand implements Runnable { ) String model; + @Option( + names = {"--photo1"}, + description = "First photo" + ) + String photo1; + + @Option( + names = {"--photo2"}, + description = "Second photo" + ) + String photo2; + @Option( names = {"--template-name"}, description = "Name of the template to use", @@ -62,37 +84,100 @@ public class GenerateImageCommand implements Runnable { ) String templateName; + private final Map> templateHandlers = Map.of( + "generate-image-blog-post", this::generateImageBlogPost, + "generate-image-speaker-event", this::generateImageSpeakerEvent, + "generate-image-2-speaker-event", this::generateImage2SpeakerEvent + ); + @Override public void run() { try { var template = templateService.waitAValidTemplateByUser(templateName); - // Check that the template is of type IMAGE - if (template.type() != MODE_FEATURE.IMAGE) { - Log.error("❌ Error: Template '" + templateName + "' is not an IMAGE template"); + if (!template.type().equals(MODE_FEATURE.IMAGE.toString())) { + Log.error("❌ Error: Template '" + templateName + "' is not an IMAGE template (" + template.type() + ")"); System.exit(1); - return; } - String templatePrompt = template.prompt(); - String finalOutput = output != null ? output : config.getDefaultResultFilename(); - String finalTemplatePath = templatePath != null ? templatePath : config.getDefaultTemplatePath(); - String finalFile1Path = file1Path != null ? file1Path : config.getDefaultFile1Path(); - String finalFile2Path = file2Path != null ? file2Path : config.getDefaultFile2Path(); - String finalModel = model != null ? model : config.getDefaultGeminiModelImage(); - - geminiServices.generateImage( - finalModel, - templatePrompt, - finalOutput, - finalTemplatePath, - finalFile1Path, - finalFile2Path - ); + Consumer