use of ai.elimu.model.content.multimedia.Image in project webapp by elimu-ai.
the class StringToImageConverter method convert.
/**
* Convert Image id to Image entity
*/
public Image convert(String id) {
if (StringUtils.isBlank(id)) {
return null;
} else {
Long imageId = Long.parseLong(id);
Image word = imageDao.read(imageId);
return word;
}
}
use of ai.elimu.model.content.multimedia.Image in project webapp by elimu-ai.
the class StoryBookCreateFromEPubController method handleSubmit.
@RequestMapping(method = RequestMethod.POST)
public String handleSubmit(StoryBook storyBook, @RequestParam("bytes") MultipartFile multipartFile, BindingResult result, Model model, HttpServletRequest request, HttpSession session) throws IOException {
logger.info("handleSubmit");
Image storyBookCoverImage = null;
List<StoryBookChapter> storyBookChapters = new ArrayList<>();
List<StoryBookParagraph> storyBookParagraphs = new ArrayList<>();
if (multipartFile.isEmpty()) {
result.rejectValue("bytes", "NotNull");
} else {
String contentType = multipartFile.getContentType();
logger.info("contentType: " + contentType);
String name = multipartFile.getName();
logger.info("name: " + name);
String originalFilename = multipartFile.getOriginalFilename();
logger.info("originalFilename: " + originalFilename);
long size = multipartFile.getSize();
logger.info("size: " + size + " (" + (size / 1024) + "kB)");
byte[] ePubBytes = multipartFile.getBytes();
logger.info("ePubBytes.length: " + (ePubBytes.length / 1024 / 1024) + "MB");
List<File> filesInEPub = unzipFiles(ePubBytes, originalFilename);
logger.info("filesInEPub.size(): " + filesInEPub.size());
// Extract the ePUB's metadata from its OPF file
File opfFile = null;
for (File file : filesInEPub) {
if (file.getName().endsWith(".opf")) {
opfFile = file;
}
}
logger.info("opfFile: \"" + opfFile + "\"");
if (opfFile == null) {
throw new IllegalArgumentException("The OPF file was not found");
} else {
String title = EPubMetadataExtractionHelper.extractTitleFromOpfFile(opfFile);
logger.info("title: \"" + title + "\"");
storyBook.setTitle(title);
String description = EPubMetadataExtractionHelper.extractDescriptionFromOpfFile(opfFile);
logger.info("description: \"" + description + "\"");
if (StringUtils.isNotBlank(description)) {
logger.info("description.length(): " + description.length());
if (description.length() > 1024) {
description = description.substring(0, 1023);
}
storyBook.setDescription(description);
}
storyBookCoverImage = new Image();
String coverImageReference = EPubMetadataExtractionHelper.extractCoverImageReferenceFromOpfFile(opfFile);
logger.info("coverImageReference: " + coverImageReference);
File coverImageFile = new File(opfFile.getParent(), coverImageReference);
logger.info("coverImageFile: " + coverImageFile);
logger.info("coverImageFile.exists(): " + coverImageFile.exists());
URI coverImageUri = coverImageFile.toURI();
logger.info("coverImageUri: " + coverImageUri);
byte[] coverImageBytes = IOUtils.toByteArray(coverImageUri);
storyBookCoverImage.setBytes(coverImageBytes);
byte[] headerBytes = Arrays.copyOfRange(coverImageBytes, 0, 6);
// "GIF87a"
byte[] gifHeader87a = { 71, 73, 70, 56, 55, 97 };
// "GIF89a"
byte[] gifHeader89a = { 71, 73, 70, 56, 57, 97 };
if (Arrays.equals(gifHeader87a, headerBytes) || Arrays.equals(gifHeader89a, headerBytes)) {
storyBookCoverImage.setContentType("image/gif");
storyBookCoverImage.setImageFormat(ImageFormat.GIF);
} else if (coverImageFile.getName().toLowerCase().endsWith(".png")) {
storyBookCoverImage.setContentType("image/png");
storyBookCoverImage.setImageFormat(ImageFormat.PNG);
} else if (coverImageFile.getName().toLowerCase().endsWith(".jpg") || coverImageFile.getName().toLowerCase().endsWith(".jpeg")) {
storyBookCoverImage.setContentType("image/jpg");
storyBookCoverImage.setImageFormat(ImageFormat.JPG);
} else if (coverImageFile.getName().toLowerCase().endsWith(".gif")) {
storyBookCoverImage.setContentType("image/gif");
storyBookCoverImage.setImageFormat(ImageFormat.GIF);
}
try {
int[] dominantColor = ImageColorHelper.getDominantColor(storyBookCoverImage.getBytes());
storyBookCoverImage.setDominantColor("rgb(" + dominantColor[0] + "," + dominantColor[1] + "," + dominantColor[2] + ")");
} catch (NullPointerException ex) {
// javax.imageio.IIOException: Unsupported Image Type
}
if (storyBookCoverImage.getImageFormat() != ImageFormat.GIF) {
// Reduce size if large image
int imageWidth = ImageHelper.getWidth(coverImageBytes);
logger.info("imageWidth: " + imageWidth + "px");
if (imageWidth > ImageHelper.MINIMUM_WIDTH) {
coverImageBytes = ImageHelper.scaleImage(coverImageBytes, ImageHelper.MINIMUM_WIDTH);
storyBookCoverImage.setBytes(coverImageBytes);
}
}
}
// Extract the ePUB's chapters
File tableOfContentsFile = null;
for (File file : filesInEPub) {
if (file.getName().startsWith("toc.")) {
tableOfContentsFile = file;
}
}
logger.info("tableOfContentsFile: \"" + tableOfContentsFile + "\"");
if (tableOfContentsFile == null) {
throw new IllegalArgumentException("The TOC file was not found");
} else {
List<String> chapterReferences = null;
if (tableOfContentsFile.getName().endsWith(".xhtml")) {
// StoryBookProvider#GLOBAL_DIGITAL_LIBRARY or StoryBookProvider#LETS_READ_ASIA
chapterReferences = EPubChapterExtractionHelper.extractChapterReferencesFromTableOfContentsFile(tableOfContentsFile);
} else if (tableOfContentsFile.getName().endsWith(".ncx")) {
// StoryBookProvider#STORYWEAVER
chapterReferences = EPubChapterExtractionHelper.extractChapterReferencesFromTableOfContentsFileNcx(tableOfContentsFile);
}
logger.info("chapterReferences.size(): " + chapterReferences.size());
// Extract each chapter's image (if any) and paragraphs
for (String chapterReference : chapterReferences) {
logger.info("chapterReference: \"" + chapterReference + "\"");
File chapterFile = new File(opfFile.getParent(), chapterReference);
logger.info("chapterFile: \"" + chapterFile + "\"");
StoryBookChapter storyBookChapter = new StoryBookChapter();
storyBookChapter.setSortOrder(storyBookChapters.size());
storyBookChapters.add(storyBookChapter);
String chapterImageReference = EPubImageExtractionHelper.extractImageReferenceFromChapterFile(chapterFile);
logger.info("chapterImageReference: " + chapterImageReference);
if (StringUtils.isNotBlank(chapterImageReference)) {
File chapterImageFile = null;
if (chapterImageReference.startsWith("http://") || chapterImageReference.startsWith("https://")) {
// Download the file
URL sourceUrl = new URL(chapterImageReference);
String tmpDir = System.getProperty("java.io.tmpdir");
logger.info("tmpDir: " + tmpDir);
File tmpDirElimuAi = new File(tmpDir, "elimu-ai");
logger.info("tmpDirElimuAi: " + tmpDirElimuAi);
logger.info("tmpDirElimuAi.mkdir(): " + tmpDirElimuAi.mkdir());
chapterImageFile = new File(tmpDirElimuAi, "chapter-image");
logger.warn("Downloading image from " + sourceUrl + " and storing at " + chapterImageFile);
// 1000 milliseconds x 10
int connectionTimeout = 1000 * 10;
// 1000 milliseconds x 10
int readTimeout = 1000 * 10;
FileUtils.copyURLToFile(sourceUrl, chapterImageFile, connectionTimeout, readTimeout);
} else {
chapterImageFile = new File(chapterFile.getParent(), chapterImageReference);
}
logger.info("chapterImageFile: " + chapterImageFile);
logger.info("chapterImageFile.exists(): " + chapterImageFile.exists());
URI chapterImageUri = chapterImageFile.toURI();
logger.info("chapterImageUri: " + chapterImageUri);
byte[] chapterImageBytes = IOUtils.toByteArray(chapterImageUri);
Image chapterImage = new Image();
chapterImage.setBytes(chapterImageBytes);
byte[] headerBytes = Arrays.copyOfRange(chapterImageBytes, 0, 6);
// "GIF87a"
byte[] gifHeader87a = { 71, 73, 70, 56, 55, 97 };
// "GIF89a"
byte[] gifHeader89a = { 71, 73, 70, 56, 57, 97 };
if (Arrays.equals(gifHeader87a, headerBytes) || Arrays.equals(gifHeader89a, headerBytes)) {
chapterImage.setContentType("image/gif");
chapterImage.setImageFormat(ImageFormat.GIF);
} else if (chapterImageFile.getName().toLowerCase().endsWith(".png")) {
chapterImage.setContentType("image/png");
chapterImage.setImageFormat(ImageFormat.PNG);
} else if (chapterImageFile.getName().toLowerCase().endsWith(".jpg") || chapterImageFile.getName().toLowerCase().endsWith(".jpeg")) {
chapterImage.setContentType("image/jpg");
chapterImage.setImageFormat(ImageFormat.JPG);
} else if (chapterImageFile.getName().toLowerCase().endsWith(".gif")) {
chapterImage.setContentType("image/gif");
chapterImage.setImageFormat(ImageFormat.GIF);
}
try {
int[] dominantColor = ImageColorHelper.getDominantColor(chapterImage.getBytes());
chapterImage.setDominantColor("rgb(" + dominantColor[0] + "," + dominantColor[1] + "," + dominantColor[2] + ")");
} catch (NullPointerException ex) {
// javax.imageio.IIOException: Unsupported Image Type
}
if (chapterImage.getImageFormat() != ImageFormat.GIF) {
// Reduce size if large image
int imageWidth = ImageHelper.getWidth(chapterImageBytes);
logger.info("imageWidth: " + imageWidth + "px");
if (imageWidth > ImageHelper.MINIMUM_WIDTH) {
chapterImageBytes = ImageHelper.scaleImage(chapterImageBytes, ImageHelper.MINIMUM_WIDTH);
chapterImage.setBytes(chapterImageBytes);
}
}
storyBookChapter.setImage(chapterImage);
}
List<String> paragraphs = EPubParagraphExtractionHelper.extractParagraphsFromChapterFile(chapterFile);
logger.info("paragraphs.size(): " + paragraphs.size());
for (int i = 0; i < paragraphs.size(); i++) {
String paragraph = paragraphs.get(i);
logger.info("paragraph: \"" + paragraph + "\"");
logger.info("paragraph.length(): " + paragraph.length());
StoryBookParagraph storyBookParagraph = new StoryBookParagraph();
storyBookParagraph.setStoryBookChapter(storyBookChapter);
storyBookParagraph.setSortOrder(i);
if (paragraph.length() > 1024) {
logger.warn("Reducing the length of the paragraph to its initial 1,024 characters.");
paragraph = paragraph.substring(0, 1023);
}
storyBookParagraph.setOriginalText(paragraph);
// Note: updating the paragraph's list of Words is handled by the ParagraphWordScheduler
storyBookParagraphs.add(storyBookParagraph);
}
}
}
}
if (result.hasErrors()) {
return "content/storybook/create-from-epub";
} else {
// Store the StoryBook in the database
storyBook.setTimeLastUpdate(Calendar.getInstance());
storyBookDao.create(storyBook);
StoryBookContributionEvent storyBookContributionEvent = new StoryBookContributionEvent();
storyBookContributionEvent.setContributor((Contributor) session.getAttribute("contributor"));
storyBookContributionEvent.setTime(Calendar.getInstance());
storyBookContributionEvent.setStoryBook(storyBook);
storyBookContributionEvent.setRevisionNumber(storyBook.getRevisionNumber());
storyBookContributionEvent.setComment("Uploaded ePUB file (🤖 auto-generated comment)");
storyBookContributionEvent.setTimeSpentMs(System.currentTimeMillis() - Long.valueOf(request.getParameter("timeStart")));
storyBookContributionEvent.setPlatform(Platform.WEBAPP);
storyBookContributionEventDao.create(storyBookContributionEvent);
// Store the StoryBook's cover image in the database, and assign it to the StoryBook
storyBookCoverImage.setTitle("storybook-" + storyBook.getId() + "-cover");
imageDao.create(storyBookCoverImage);
storeImageContributionEvent(storyBookCoverImage, session, request);
storyBook.setCoverImage(storyBookCoverImage);
storyBookDao.update(storyBook);
// Store the StoryBookChapters in the database
int chapterSortOrder = 0;
for (StoryBookChapter storyBookChapter : storyBookChapters) {
storyBookChapter.setStoryBook(storyBook);
// Get the paragraphs associated with this chapter
List<StoryBookParagraph> storyBookParagraphsAssociatedWithChapter = new ArrayList<>();
for (StoryBookParagraph storyBookParagraph : storyBookParagraphs) {
if (storyBookParagraph.getStoryBookChapter().getSortOrder().equals(storyBookChapter.getSortOrder())) {
storyBookParagraphsAssociatedWithChapter.add(storyBookParagraph);
}
}
logger.info("storyBookParagraphsAssociatedWithChapter.size(): " + storyBookParagraphsAssociatedWithChapter.size());
// Exclude chapters containing book metadata
boolean isMetadata = false;
for (StoryBookParagraph storyBookParagraph : storyBookParagraphsAssociatedWithChapter) {
String originalTextLowerCase = storyBookParagraph.getOriginalText().toLowerCase();
if (originalTextLowerCase.contains("author: ") || originalTextLowerCase.contains("illustrator: ") || originalTextLowerCase.contains("translator: ") || originalTextLowerCase.contains("creative commons") || originalTextLowerCase.contains("pratham books") || originalTextLowerCase.contains("storyweaver") || originalTextLowerCase.contains("copyright page")) {
isMetadata = true;
break;
}
}
if (isMetadata) {
continue;
}
// Update the chapter's sort order (in case any of the previous chapters were excluded)
storyBookChapter.setSortOrder(chapterSortOrder);
// Store the chapter's image (if any)
Image chapterImage = storyBookChapter.getImage();
if (chapterImage != null) {
chapterImage.setTitle("storybook-" + storyBook.getId() + "-ch-" + (storyBookChapter.getSortOrder() + 1));
imageDao.create(chapterImage);
storeImageContributionEvent(chapterImage, session, request);
}
// Only store the chapter if it has an image or at least one paragraph
if ((chapterImage != null) || (!storyBookParagraphsAssociatedWithChapter.isEmpty())) {
storyBookChapterDao.create(storyBookChapter);
chapterSortOrder++;
}
// Store the chapter's paragraphs in the database
for (StoryBookParagraph storyBookParagraph : storyBookParagraphsAssociatedWithChapter) {
storyBookParagraph.setStoryBookChapter(storyBookChapter);
storyBookParagraphDao.create(storyBookParagraph);
}
}
String contentUrl = "http://" + EnvironmentContextLoaderListener.PROPERTIES.getProperty("content.language").toLowerCase() + ".elimu.ai/content/storybook/edit/" + storyBook.getId();
String embedThumbnailUrl = null;
if (storyBook.getCoverImage() != null) {
embedThumbnailUrl = "http://" + EnvironmentContextLoaderListener.PROPERTIES.getProperty("content.language").toLowerCase() + ".elimu.ai/image/" + storyBook.getCoverImage().getId() + "_r" + storyBook.getCoverImage().getRevisionNumber() + "." + storyBook.getCoverImage().getImageFormat().toString().toLowerCase();
}
DiscordHelper.sendChannelMessage("Storybook created (imported from ePUB): " + contentUrl, "\"" + storyBookContributionEvent.getStoryBook().getTitle() + "\"", "Comment: \"" + storyBookContributionEvent.getComment() + "\"", null, embedThumbnailUrl);
return "redirect:/content/storybook/edit/" + storyBook.getId();
}
}
use of ai.elimu.model.content.multimedia.Image in project webapp by elimu-ai.
the class StoryBookEditController method handleSubmit.
@RequestMapping(value = "/{id}", method = RequestMethod.POST)
public String handleSubmit(@Valid StoryBook storyBook, BindingResult result, Model model, HttpServletRequest request, HttpSession session) {
logger.info("handleSubmit");
StoryBook existingStoryBook = storyBookDao.readByTitle(storyBook.getTitle());
if ((existingStoryBook != null) && !existingStoryBook.getId().equals(storyBook.getId())) {
result.rejectValue("title", "NonUnique");
}
if (result.hasErrors()) {
model.addAttribute("storyBook", storyBook);
model.addAttribute("timeStart", System.currentTimeMillis());
model.addAttribute("contentLicenses", ContentLicense.values());
List<Image> coverImages = imageDao.readAllOrdered();
model.addAttribute("coverImages", coverImages);
model.addAttribute("readingLevels", ReadingLevel.values());
List<StoryBookChapter> storyBookChapters = storyBookChapterDao.readAll(storyBook);
model.addAttribute("storyBookChapters", storyBookChapters);
// Map<StoryBookChapter.id, List<StoryBookParagraph>>
Map<Long, List<StoryBookParagraph>> paragraphsPerStoryBookChapterMap = new HashMap<>();
for (StoryBookChapter storyBookChapter : storyBookChapters) {
paragraphsPerStoryBookChapterMap.put(storyBookChapter.getId(), storyBookParagraphDao.readAll(storyBookChapter));
}
model.addAttribute("paragraphsPerStoryBookChapterMap", paragraphsPerStoryBookChapterMap);
List<String> paragraphs = new ArrayList<>();
for (StoryBookChapter storyBookChapter : storyBookChapters) {
List<StoryBookParagraph> storyBookParagraphs = storyBookParagraphDao.readAll(storyBookChapter);
for (StoryBookParagraph storyBookParagraph : storyBookParagraphs) {
paragraphs.add(storyBookParagraph.getOriginalText());
}
}
model.addAttribute("storyBookContributionEvents", storyBookContributionEventDao.readAll(storyBook));
model.addAttribute("storyBookPeerReviewEvents", storyBookPeerReviewEventDao.readAll(storyBook));
Language language = Language.valueOf(ConfigHelper.getProperty("content.language"));
Map<String, Integer> wordFrequencyMap = WordFrequencyHelper.getWordFrequency(paragraphs, language);
model.addAttribute("wordFrequencyMap", wordFrequencyMap);
Map<String, Word> wordMap = new HashMap<>();
for (Word word : wordDao.readAllOrdered()) {
wordMap.put(word.getText(), word);
}
model.addAttribute("wordMap", wordMap);
model.addAttribute("emojisByWordId", getEmojisByWordId());
Map<String, Integer> letterFrequencyMap = LetterFrequencyHelper.getLetterFrequency(paragraphs, language);
model.addAttribute("letterFrequencyMap", letterFrequencyMap);
Map<String, Letter> letterMap = new HashMap<>();
for (Letter letter : letterDao.readAllOrdered()) {
letterMap.put(letter.getText(), letter);
}
model.addAttribute("letterMap", letterMap);
return "content/storybook/edit";
} else {
storyBook.setTimeLastUpdate(Calendar.getInstance());
storyBook.setRevisionNumber(storyBook.getRevisionNumber() + 1);
storyBookDao.update(storyBook);
StoryBookContributionEvent storyBookContributionEvent = new StoryBookContributionEvent();
storyBookContributionEvent.setContributor((Contributor) session.getAttribute("contributor"));
storyBookContributionEvent.setTime(Calendar.getInstance());
storyBookContributionEvent.setStoryBook(storyBook);
storyBookContributionEvent.setRevisionNumber(storyBook.getRevisionNumber());
storyBookContributionEvent.setComment(StringUtils.abbreviate(request.getParameter("contributionComment"), 1000));
storyBookContributionEvent.setTimeSpentMs(System.currentTimeMillis() - Long.valueOf(request.getParameter("timeStart")));
storyBookContributionEvent.setPlatform(Platform.WEBAPP);
storyBookContributionEventDao.create(storyBookContributionEvent);
String contentUrl = "http://" + EnvironmentContextLoaderListener.PROPERTIES.getProperty("content.language").toLowerCase() + ".elimu.ai/content/storybook/edit/" + storyBook.getId();
String embedThumbnailUrl = null;
if (storyBook.getCoverImage() != null) {
embedThumbnailUrl = "http://" + EnvironmentContextLoaderListener.PROPERTIES.getProperty("content.language").toLowerCase() + ".elimu.ai/image/" + storyBook.getCoverImage().getId() + "_r" + storyBook.getCoverImage().getRevisionNumber() + "." + storyBook.getCoverImage().getImageFormat().toString().toLowerCase();
}
DiscordHelper.sendChannelMessage("Storybook edited: " + contentUrl, "\"" + storyBookContributionEvent.getStoryBook().getTitle() + "\"", "Comment: \"" + storyBookContributionEvent.getComment() + "\"", null, embedThumbnailUrl);
// Refresh REST API cache
storyBooksJsonService.refreshStoryBooksJSONArray();
return "redirect:/content/storybook/list#" + storyBook.getId();
}
}
use of ai.elimu.model.content.multimedia.Image in project webapp by elimu-ai.
the class StoryBookChapterDeleteController method handleRequest.
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public String handleRequest(HttpSession session, @PathVariable Long storyBookId, @PathVariable Long id) {
logger.info("handleRequest");
Contributor contributor = (Contributor) session.getAttribute("contributor");
logger.info("contributor.getRoles(): " + contributor.getRoles());
if (!contributor.getRoles().contains(Role.EDITOR)) {
// TODO: return HttpStatus.FORBIDDEN
throw new IllegalAccessError("Missing role for access");
}
StoryBookChapter storyBookChapterToBeDeleted = storyBookChapterDao.read(id);
logger.info("storyBookChapterToBeDeleted: " + storyBookChapterToBeDeleted);
logger.info("storyBookChapterToBeDeleted.getSortOrder(): " + storyBookChapterToBeDeleted.getSortOrder());
// Delete the chapter's paragraphs
List<StoryBookParagraph> storyBookParagraphs = storyBookParagraphDao.readAll(storyBookChapterToBeDeleted);
logger.info("storyBookParagraphs.size(): " + storyBookParagraphs.size());
for (StoryBookParagraph storyBookParagraphToBeDeleted : storyBookParagraphs) {
// Delete the paragraph's reference from corresponding audios (if any)
List<Audio> paragraphAudios = audioDao.readAll(storyBookParagraphToBeDeleted);
for (Audio paragraphAudio : paragraphAudios) {
paragraphAudio.setStoryBookParagraph(null);
audioDao.update(paragraphAudio);
}
logger.info("Deleting StoryBookParagraph with ID " + storyBookParagraphToBeDeleted.getId());
storyBookParagraphDao.delete(storyBookParagraphToBeDeleted);
}
// Delete the chapter
logger.info("Deleting StoryBookChapter with ID " + storyBookChapterToBeDeleted.getId());
storyBookChapterDao.delete(storyBookChapterToBeDeleted);
// Delete the chapter's image (if any)
Image chapterImage = storyBookChapterToBeDeleted.getImage();
logger.info("chapterImage: " + chapterImage);
if (chapterImage != null) {
// Remove content labels
chapterImage.setLiteracySkills(null);
chapterImage.setNumeracySkills(null);
chapterImage.setLetters(null);
chapterImage.setNumbers(null);
chapterImage.setWords(null);
imageDao.update(chapterImage);
// Remove contribution events
for (ImageContributionEvent imageContributionEvent : imageContributionEventDao.readAll(chapterImage)) {
logger.warn("Deleting ImageContributionEvent from the database");
imageContributionEventDao.delete(imageContributionEvent);
}
logger.warn("Deleting the chapter image from the database");
imageDao.delete(chapterImage);
}
// Update the StoryBook's metadata
StoryBook storyBook = storyBookChapterToBeDeleted.getStoryBook();
storyBook.setTimeLastUpdate(Calendar.getInstance());
storyBook.setRevisionNumber(storyBook.getRevisionNumber() + 1);
storyBook.setPeerReviewStatus(PeerReviewStatus.PENDING);
storyBookDao.update(storyBook);
// Store contribution event
StoryBookContributionEvent storyBookContributionEvent = new StoryBookContributionEvent();
storyBookContributionEvent.setContributor(contributor);
storyBookContributionEvent.setTime(Calendar.getInstance());
storyBookContributionEvent.setStoryBook(storyBook);
storyBookContributionEvent.setRevisionNumber(storyBook.getRevisionNumber());
storyBookContributionEvent.setComment("Deleted storybook chapter " + (storyBookChapterToBeDeleted.getSortOrder() + 1) + " (🤖 auto-generated comment)");
storyBookContributionEvent.setTimeSpentMs(0L);
storyBookContributionEvent.setPlatform(Platform.WEBAPP);
storyBookContributionEventDao.create(storyBookContributionEvent);
String contentUrl = "http://" + EnvironmentContextLoaderListener.PROPERTIES.getProperty("content.language").toLowerCase() + ".elimu.ai/content/storybook/edit/" + storyBook.getId();
String embedThumbnailUrl = null;
if (storyBook.getCoverImage() != null) {
embedThumbnailUrl = "http://" + EnvironmentContextLoaderListener.PROPERTIES.getProperty("content.language").toLowerCase() + ".elimu.ai/image/" + storyBook.getCoverImage().getId() + "_r" + storyBook.getCoverImage().getRevisionNumber() + "." + storyBook.getCoverImage().getImageFormat().toString().toLowerCase();
}
DiscordHelper.sendChannelMessage("Storybook chapter deleted: " + contentUrl, "\"" + storyBookContributionEvent.getStoryBook().getTitle() + "\"", "Comment: \"" + storyBookContributionEvent.getComment() + "\"", null, embedThumbnailUrl);
// Update the sorting order of the remaining chapters
List<StoryBookChapter> storyBookChapters = storyBookChapterDao.readAll(storyBook);
logger.info("storyBookChapters.size(): " + storyBookChapters.size());
for (StoryBookChapter storyBookChapter : storyBookChapters) {
logger.info("storyBookChapter.getId(): " + storyBookChapter.getId() + ", storyBookChapter.getSortOrder(): " + storyBookChapter.getSortOrder());
if (storyBookChapter.getSortOrder() > storyBookChapterToBeDeleted.getSortOrder()) {
// Reduce sort order by 1
storyBookChapter.setSortOrder(storyBookChapter.getSortOrder() - 1);
storyBookChapterDao.update(storyBookChapter);
logger.info("storyBookChapter.getSortOrder() (after update): " + storyBookChapter.getSortOrder());
}
}
// Refresh the REST API cache
storyBooksJsonService.refreshStoryBooksJSONArray();
return "redirect:/content/storybook/edit/" + storyBookId;
}
use of ai.elimu.model.content.multimedia.Image in project webapp by elimu-ai.
the class WordCreateController method handleSubmit.
@RequestMapping(method = RequestMethod.POST)
public String handleSubmit(HttpServletRequest request, HttpSession session, @Valid Word word, BindingResult result, Model model) {
logger.info("handleSubmit");
Word existingWord = wordDao.readByText(word.getText());
if (existingWord != null) {
result.rejectValue("text", "NonUnique");
}
if (StringUtils.containsAny(word.getText(), " ")) {
result.rejectValue("text", "WordSpace");
}
if (result.hasErrors()) {
model.addAttribute("word", word);
model.addAttribute("timeStart", request.getParameter("timeStart"));
// TODO: sort by letter(s) text
model.addAttribute("letterSoundCorrespondences", letterSoundCorrespondenceDao.readAllOrderedByUsage());
model.addAttribute("rootWords", wordDao.readAllOrdered());
model.addAttribute("emojisByWordId", getEmojisByWordId());
model.addAttribute("wordTypes", WordType.values());
model.addAttribute("spellingConsistencies", SpellingConsistency.values());
model.addAttribute("audio", audioDao.readByTranscription(word.getText()));
return "content/word/create";
} else {
word.setTimeLastUpdate(Calendar.getInstance());
wordDao.create(word);
WordContributionEvent wordContributionEvent = new WordContributionEvent();
wordContributionEvent.setContributor((Contributor) session.getAttribute("contributor"));
wordContributionEvent.setTime(Calendar.getInstance());
wordContributionEvent.setWord(word);
wordContributionEvent.setRevisionNumber(word.getRevisionNumber());
wordContributionEvent.setComment(StringUtils.abbreviate(request.getParameter("contributionComment"), 1000));
wordContributionEvent.setTimeSpentMs(System.currentTimeMillis() - Long.valueOf(request.getParameter("timeStart")));
wordContributionEvent.setPlatform(Platform.WEBAPP);
wordContributionEventDao.create(wordContributionEvent);
String contentUrl = "http://" + EnvironmentContextLoaderListener.PROPERTIES.getProperty("content.language").toLowerCase() + ".elimu.ai/content/word/edit/" + word.getId();
DiscordHelper.sendChannelMessage("Word created: " + contentUrl, "\"" + wordContributionEvent.getWord().getText() + "\"", "Comment: \"" + wordContributionEvent.getComment() + "\"", null, null);
// Note: updating the list of Words in StoryBookParagraphs is handled by the ParagraphWordScheduler
// Label Image with Word of matching title
Image matchingImage = imageDao.read(word.getText());
if (matchingImage != null) {
Set<Word> labeledWords = matchingImage.getWords();
if (!labeledWords.contains(word)) {
labeledWords.add(word);
matchingImage.setWords(labeledWords);
imageDao.update(matchingImage);
}
}
// Delete syllables that are actual words
Syllable syllable = syllableDao.readByText(word.getText());
if (syllable != null) {
syllableDao.delete(syllable);
}
// Generate Audio for this Word (if it has not been done already)
List<Audio> audios = audioDao.readAll(word);
if (audios.isEmpty()) {
Calendar timeStart = Calendar.getInstance();
Language language = Language.valueOf(ConfigHelper.getProperty("content.language"));
try {
byte[] audioBytes = GoogleCloudTextToSpeechHelper.synthesizeText(word.getText(), language);
logger.info("audioBytes: " + audioBytes);
if (audioBytes != null) {
Audio audio = new Audio();
audio.setTimeLastUpdate(Calendar.getInstance());
audio.setContentType(AudioFormat.MP3.getContentType());
audio.setWord(word);
audio.setTitle("word-id-" + word.getId());
audio.setTranscription(word.getText());
audio.setBytes(audioBytes);
// TODO: Convert from byte[] to File, and extract audio duration
audio.setDurationMs(null);
audio.setAudioFormat(AudioFormat.MP3);
audioDao.create(audio);
audios.add(audio);
model.addAttribute("audios", audios);
AudioContributionEvent audioContributionEvent = new AudioContributionEvent();
audioContributionEvent.setContributor((Contributor) session.getAttribute("contributor"));
audioContributionEvent.setTime(Calendar.getInstance());
audioContributionEvent.setAudio(audio);
audioContributionEvent.setRevisionNumber(audio.getRevisionNumber());
audioContributionEvent.setComment("Google Cloud Text-to-Speech (🤖 auto-generated comment)️");
audioContributionEvent.setTimeSpentMs(System.currentTimeMillis() - timeStart.getTimeInMillis());
audioContributionEvent.setPlatform(Platform.WEBAPP);
audioContributionEventDao.create(audioContributionEvent);
}
} catch (Exception ex) {
logger.error(ex);
}
}
return "redirect:/content/word/list#" + word.getId();
}
}
Aggregations