-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[AB-xxx] adding amongusText image generation
- Loading branch information
Showing
97 changed files
with
337 additions
and
1 deletion.
There are no files selected for viewing
133 changes: 133 additions & 0 deletions
133
...eration-impl/src/main/java/dev/sheldan/abstracto/imagegeneration/command/AmongusText.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
package dev.sheldan.abstracto.imagegeneration.command; | ||
|
||
import dev.sheldan.abstracto.core.command.UtilityModuleDefinition; | ||
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand; | ||
import dev.sheldan.abstracto.core.command.config.CommandConfiguration; | ||
import dev.sheldan.abstracto.core.command.config.HelpInfo; | ||
import dev.sheldan.abstracto.core.command.config.Parameter; | ||
import dev.sheldan.abstracto.core.command.execution.CommandContext; | ||
import dev.sheldan.abstracto.core.command.execution.CommandResult; | ||
import dev.sheldan.abstracto.core.config.FeatureDefinition; | ||
import dev.sheldan.abstracto.core.interaction.InteractionService; | ||
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig; | ||
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService; | ||
import dev.sheldan.abstracto.core.service.ChannelService; | ||
import dev.sheldan.abstracto.core.templating.model.AttachedFile; | ||
import dev.sheldan.abstracto.core.templating.model.MessageToSend; | ||
import dev.sheldan.abstracto.core.templating.service.TemplateService; | ||
import dev.sheldan.abstracto.core.utils.FileService; | ||
import dev.sheldan.abstracto.core.utils.FutureUtils; | ||
import dev.sheldan.abstracto.imagegeneration.config.ImageGenerationFeatureDefinition; | ||
import dev.sheldan.abstracto.imagegeneration.config.ImageGenerationSlashCommandNames; | ||
import dev.sheldan.abstracto.imagegeneration.service.ImageGenerationService; | ||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.stereotype.Component; | ||
|
||
import java.io.File; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.concurrent.CompletableFuture; | ||
|
||
@Component | ||
public class AmongusText extends AbstractConditionableCommand { | ||
|
||
public static final String TEXT_PARAMETER_KEY = "text"; | ||
|
||
@Autowired | ||
private ImageGenerationService imageGenerationService; | ||
|
||
@Autowired | ||
private TemplateService templateService; | ||
|
||
@Autowired | ||
private ChannelService channelService; | ||
|
||
@Autowired | ||
private FileService fileService; | ||
|
||
@Autowired | ||
private InteractionService interactionService; | ||
|
||
@Autowired | ||
private SlashCommandParameterService slashCommandParameterService; | ||
|
||
private static final String AMONGUS_TEXT_EMBED_TEMPLATE_KEY = "amongusText_response"; | ||
|
||
@Override | ||
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) { | ||
String text = (String) commandContext.getParameters().getParameters().get(0); | ||
File amongusTextImage = imageGenerationService.getAmongusTextImage(text); | ||
MessageToSend messageToSend = templateService.renderEmbedTemplate(AMONGUS_TEXT_EMBED_TEMPLATE_KEY, new Object()); | ||
// template support does not support binary files | ||
AttachedFile file = AttachedFile | ||
.builder() | ||
.file(amongusTextImage) | ||
.fileName("amongus.png") | ||
.build(); | ||
messageToSend.getAttachedFiles().add(file); | ||
return FutureUtils.toSingleFutureGeneric(channelService.sendMessageToSendToChannel(messageToSend, commandContext.getChannel())) | ||
.thenAccept(unused -> fileService.safeDeleteIgnoreException(messageToSend.getAttachedFiles().get(0).getFile())) | ||
.thenApply(unused -> CommandResult.fromIgnored()); | ||
} | ||
|
||
@Override | ||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) { | ||
event.deferReply().queue(); | ||
String text = slashCommandParameterService.getCommandOption(TEXT_PARAMETER_KEY, event, String.class); | ||
File amongusTextImage = imageGenerationService.getAmongusTextImage(text); | ||
MessageToSend messageToSend = templateService.renderEmbedTemplate(AMONGUS_TEXT_EMBED_TEMPLATE_KEY, new Object()); | ||
// template support does not support binary files | ||
AttachedFile file = AttachedFile | ||
.builder() | ||
.file(amongusTextImage) | ||
.fileName("amongus.png") | ||
.build(); | ||
messageToSend.getAttachedFiles().add(file); | ||
return FutureUtils.toSingleFutureGeneric(interactionService.sendMessageToInteraction(messageToSend, event.getHook())) | ||
.thenAccept(unused -> fileService.safeDeleteIgnoreException(messageToSend.getAttachedFiles().get(0).getFile())) | ||
.thenApply(unused -> CommandResult.fromIgnored()); | ||
} | ||
|
||
@Override | ||
public CommandConfiguration getConfiguration() { | ||
List<Parameter> parameters = new ArrayList<>(); | ||
Parameter memberParameter = Parameter | ||
.builder() | ||
.name(TEXT_PARAMETER_KEY) | ||
.type(String.class) | ||
.remainder(true) | ||
.templated(true) | ||
.build(); | ||
parameters.add(memberParameter); | ||
|
||
HelpInfo helpInfo = HelpInfo | ||
.builder() | ||
.templated(true) | ||
.build(); | ||
|
||
SlashCommandConfig slashCommandConfig = SlashCommandConfig | ||
.builder() | ||
.enabled(true) | ||
.rootCommandName(ImageGenerationSlashCommandNames.IMAGE_GENERATION) | ||
.groupName("memes") | ||
.commandName("amongustext") | ||
.build(); | ||
|
||
return CommandConfiguration.builder() | ||
.name("amongusText") | ||
.module(UtilityModuleDefinition.UTILITY) | ||
.templated(true) | ||
.supportsEmbedException(true) | ||
.async(true) | ||
.slashCommandConfig(slashCommandConfig) | ||
.parameters(parameters) | ||
.help(helpInfo) | ||
.build(); | ||
} | ||
|
||
@Override | ||
public FeatureDefinition getFeature() { | ||
return ImageGenerationFeatureDefinition.IMAGE_GENERATION; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
10 changes: 10 additions & 0 deletions
10
...mage-generation/image-generation-impl/src/main/resources/migrations/1.5.22/collection.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
<?xml version="1.1" encoding="UTF-8" standalone="no"?> | ||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" | ||
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" | ||
xmlns:pro="http://www.liquibase.org/xml/ns/pro" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd | ||
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd | ||
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" > | ||
<include file="seedData/data.xml" relativeToChangelogFile="true"/> | ||
</databaseChangeLog> |
20 changes: 20 additions & 0 deletions
20
...eneration/image-generation-impl/src/main/resources/migrations/1.5.22/seedData/command.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<?xml version="1.1" encoding="UTF-8" standalone="no"?> | ||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" | ||
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" | ||
xmlns:pro="http://www.liquibase.org/xml/ns/pro" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd | ||
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd | ||
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" > | ||
<property name="utilityModule" value="(SELECT id FROM module WHERE name = 'utility')"/> | ||
<property name="imageGenerationFeature" value="(SELECT id FROM feature WHERE key = 'imageGeneration')"/> | ||
|
||
<changeSet author="Sheldan" id="amongusText-commands"> | ||
<insert tableName="command"> | ||
<column name="name" value="amongusText"/> | ||
<column name="module_id" valueComputed="${utilityModule}"/> | ||
<column name="feature_id" valueComputed="${imageGenerationFeature}"/> | ||
</insert> | ||
</changeSet> | ||
|
||
</databaseChangeLog> |
10 changes: 10 additions & 0 deletions
10
...e-generation/image-generation-impl/src/main/resources/migrations/1.5.22/seedData/data.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
<?xml version="1.1" encoding="UTF-8" standalone="no"?> | ||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" | ||
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" | ||
xmlns:pro="http://www.liquibase.org/xml/ns/pro" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd | ||
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd | ||
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" > | ||
<include file="command.xml" relativeToChangelogFile="true"/> | ||
</databaseChangeLog> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
26 changes: 26 additions & 0 deletions
26
...ain/java/dev/sheldan/abstracto/imagegeneration/exception/AmongusTextRequestException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package dev.sheldan.abstracto.imagegeneration.exception; | ||
|
||
import dev.sheldan.abstracto.core.exception.AbstractoTemplatableException; | ||
import dev.sheldan.abstracto.imagegeneration.model.exception.AmongusTextRequestExceptionModel; | ||
|
||
public class AmongusTextRequestException extends AbstractoTemplatableException { | ||
private final AmongusTextRequestExceptionModel model; | ||
|
||
public AmongusTextRequestException(String inputText, String errorMessage) { | ||
this.model = AmongusTextRequestExceptionModel | ||
.builder() | ||
.inputText(inputText) | ||
.errorMessage(errorMessage) | ||
.build(); | ||
} | ||
|
||
@Override | ||
public String getTemplateName() { | ||
return "amongusText_exception"; | ||
} | ||
|
||
@Override | ||
public Object getTemplateModel() { | ||
return model; | ||
} | ||
} |
13 changes: 13 additions & 0 deletions
13
...v/sheldan/abstracto/imagegeneration/model/exception/AmongusTextRequestExceptionModel.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package dev.sheldan.abstracto.imagegeneration.model.exception; | ||
|
||
import lombok.Builder; | ||
import lombok.Getter; | ||
|
||
import java.io.Serializable; | ||
|
||
@Getter | ||
@Builder | ||
public class AmongusTextRequestExceptionModel implements Serializable { | ||
private String inputText; | ||
private String errorMessage; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
11 changes: 11 additions & 0 deletions
11
...on/core/core-int/src/main/java/dev/sheldan/abstracto/core/exception/RequestException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package dev.sheldan.abstracto.core.exception; | ||
|
||
import lombok.Builder; | ||
import lombok.Getter; | ||
|
||
@Getter | ||
@Builder | ||
public class RequestException extends RuntimeException { | ||
private String errorMessage; // we just assume the body will be a plain text instead | ||
private Integer httpCode; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
from __main__ import app | ||
|
||
from PIL import Image, ImageOps | ||
from flask import request | ||
import logging | ||
import math | ||
import re | ||
import random | ||
|
||
from utils import flask_utils | ||
|
||
vertical_padding = 5 | ||
horizontal_padding = 5 | ||
|
||
max_chars = 2000 | ||
chars_per_row = 50 | ||
|
||
|
||
space_width = 80 | ||
|
||
character_height = 120 | ||
|
||
|
||
@app.route('/memes/amogus/text') | ||
def generate_amogus_text(): | ||
text = request.args.get('text', type=str) | ||
if text is None: | ||
return 'no text', 400 | ||
if len(text) > max_chars: | ||
return f'too long text, max {max_chars}', 400 | ||
text = text.lower() | ||
text = re.sub(r'[^a-z!\\? ]', "", text) | ||
if len(text) == 0: | ||
return 'No valid characters found.', 400 | ||
logging.info(f'Rendering amogus text.') | ||
image_cache = {} | ||
images_to_use = [] | ||
|
||
try: | ||
for character in text: | ||
if character == ' ': | ||
images_to_use.append(None) | ||
continue | ||
# manual correction for filenames | ||
if character == '?': | ||
character = 'zq' | ||
if character == '!': | ||
character = 'zx' | ||
chosen_sub_image = random.randint(1, 3) | ||
cache_key = f'{character}{chosen_sub_image}' | ||
if cache_key not in image_cache: | ||
character_image = Image.open(f'resources/img/amogus/crewmate-{character}{chosen_sub_image}.png').__enter__() | ||
old_character_width, old_character_height = character_image.size | ||
character_ratio = old_character_height / character_height | ||
desired_width = int(old_character_width * character_ratio) | ||
resized_character_image = ImageOps.contain(character_image, (desired_width, character_height)) | ||
image_cache[cache_key] = resized_character_image | ||
image_to_use = resized_character_image | ||
else: | ||
image_to_use = image_cache[cache_key] | ||
images_to_use.append(image_to_use) | ||
# the line length is defined by the amount of characters, not once a certain width is reached | ||
lines = [images_to_use[i:i + chars_per_row] for i in range(0, len(images_to_use), chars_per_row)] | ||
# calculate the length of each line, and then take the widest one | ||
line_widths = [sum(image_to_use.size[0] + horizontal_padding if image_to_use is not None else space_width for image_to_use in character_line) for character_line in lines] | ||
canvas_width = max(line_widths) | ||
row_count = math.ceil(len(text) / chars_per_row) | ||
canvas_height = row_count * (character_height + vertical_padding) | ||
drawing_board = Image.new('RGBA', (canvas_width, canvas_height), (0, 0, 0, 0)) | ||
start_x = 0 | ||
start_y = 0 | ||
for index, image_to_use in enumerate(images_to_use): | ||
if index > 0 and (index % chars_per_row) == 0: | ||
start_y += character_height + vertical_padding | ||
start_x = 0 | ||
if image_to_use is not None: | ||
drawing_board.paste(image_to_use, (start_x, start_y), image_to_use) | ||
start_x += image_to_use.size[0] + horizontal_padding | ||
else: | ||
start_x += space_width | ||
finally: | ||
for cached_image in image_cache.values(): | ||
cached_image.__exit__(None, None, None) | ||
return flask_utils.serve_pil_image(drawing_board) | ||
|
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.