use of ai.elimu.model.content.StoryBookParagraph in project webapp by elimu-ai.
the class StoryBookCsvExportController method handleRequest.
@RequestMapping(value = "/storybooks.csv", method = RequestMethod.GET)
public void handleRequest(HttpServletResponse response, OutputStream outputStream) throws IOException {
logger.info("handleRequest");
List<StoryBook> storyBooks = storyBookDao.readAllOrdered();
logger.info("storyBooks.size(): " + storyBooks.size());
CSVFormat csvFormat = CSVFormat.DEFAULT.withHeader("id", "title", "description", "content_license", "attribution_url", "reading_level", "cover_image_id", "chapters");
StringWriter stringWriter = new StringWriter();
CSVPrinter csvPrinter = new CSVPrinter(stringWriter, csvFormat);
for (StoryBook storyBook : storyBooks) {
logger.info("storyBook.getTitle(): \"" + storyBook.getTitle() + "\"");
Long coverImageId = null;
if (storyBook.getCoverImage() != null) {
coverImageId = storyBook.getCoverImage().getId();
}
// Store chapters as JSON objects
JSONArray chaptersJsonArray = new JSONArray();
List<StoryBookChapter> storyBookChapters = storyBookChapterDao.readAll(storyBook);
logger.info("storyBookChapters.size(): " + storyBookChapters.size());
for (StoryBookChapter storyBookChapter : storyBookChapters) {
logger.info("storyBookChapter.getId(): " + storyBookChapter.getId());
StoryBookChapterGson storyBookChapterGson = JpaToGsonConverter.getStoryBookChapterGson(storyBookChapter);
// TODO: move this code block to JpaToGsonConverter?
if (storyBookChapterGson.getImage() != null) {
ImageGson imageGsonWithIdOnly = new ImageGson();
imageGsonWithIdOnly.setId(storyBookChapterGson.getImage().getId());
storyBookChapterGson.setImage(imageGsonWithIdOnly);
}
// Store paragraphs as JSON objects
List<StoryBookParagraphGson> storyBookParagraphs = new ArrayList<>();
logger.info("storyBookParagraphs.size(): " + storyBookParagraphs.size());
for (StoryBookParagraph storyBookParagraph : storyBookParagraphDao.readAll(storyBookChapter)) {
logger.info("storyBookParagraph.getId(): " + storyBookParagraph.getId());
StoryBookParagraphGson storyBookParagraphGson = JpaToGsonConverter.getStoryBookParagraphGson(storyBookParagraph);
storyBookParagraphGson.setWords(null);
storyBookParagraphs.add(storyBookParagraphGson);
}
storyBookChapterGson.setStoryBookParagraphs(storyBookParagraphs);
String json = new Gson().toJson(storyBookChapterGson);
JSONObject jsonObject = new JSONObject(json);
logger.info("jsonObject: " + jsonObject);
chaptersJsonArray.put(jsonObject);
}
logger.info("chaptersJsonArray: " + chaptersJsonArray);
csvPrinter.printRecord(storyBook.getId(), storyBook.getTitle(), storyBook.getDescription(), storyBook.getContentLicense(), storyBook.getAttributionUrl(), storyBook.getReadingLevel(), coverImageId, chaptersJsonArray);
csvPrinter.flush();
}
String csvFileContent = stringWriter.toString();
response.setContentType("text/csv");
byte[] bytes = csvFileContent.getBytes();
response.setContentLength(bytes.length);
try {
outputStream.write(bytes);
outputStream.flush();
outputStream.close();
} catch (IOException ex) {
logger.error(ex);
}
}
use of ai.elimu.model.content.StoryBookParagraph in project webapp by elimu-ai.
the class WordEditController method handleRequest.
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public String handleRequest(HttpSession session, Model model, @PathVariable Long id) {
logger.info("handleRequest");
Word word = wordDao.read(id);
if (word.getLetterSoundCorrespondences().isEmpty()) {
autoSelectLetterSoundCorrespondences(word);
// TODO: display information message to the Contributor that the letter-sound correspondences were auto-selected, and that they should be verified
}
model.addAttribute("word", word);
model.addAttribute("timeStart", System.currentTimeMillis());
// 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("wordContributionEvents", wordContributionEventDao.readAll(word));
model.addAttribute("wordPeerReviewEvents", wordPeerReviewEventDao.readAll(word));
List<Audio> audios = audioDao.readAll(word);
model.addAttribute("audios", audios);
// Generate Audio for this Word (if it has not been done already)
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_" + word.getText());
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);
}
}
// Look up variants of the same wordByTextMatch
model.addAttribute("wordInflections", wordDao.readInflections(word));
// Look up Multimedia content that has been labeled with this Word
// TODO: labeled Audios
List<Emoji> labeledEmojis = emojiDao.readAllLabeled(word);
model.addAttribute("labeledEmojis", labeledEmojis);
List<Image> labeledImages = imageDao.readAllLabeled(word);
model.addAttribute("labeledImages", labeledImages);
// TODO: labeled Videos
// Look up StoryBook Paragraphs that contain this Word
List<StoryBookParagraph> storyBookParagraphsContainingWord = storyBookParagraphDao.readAllContainingWord(word.getText());
model.addAttribute("storyBookParagraphsContainingWord", storyBookParagraphsContainingWord);
return "content/word/edit";
}
use of ai.elimu.model.content.StoryBookParagraph in project webapp by elimu-ai.
the class StoryBookParagraphCreateController method handleRequest.
@RequestMapping(method = RequestMethod.GET)
public String handleRequest(Model model, @PathVariable Long storyBookChapterId) {
logger.info("handleRequest");
StoryBookParagraph storyBookParagraph = new StoryBookParagraph();
StoryBookChapter storyBookChapter = storyBookChapterDao.read(storyBookChapterId);
storyBookParagraph.setStoryBookChapter(storyBookChapter);
List<StoryBookParagraph> storyBookParagraphs = storyBookParagraphDao.readAll(storyBookChapter);
storyBookParagraph.setSortOrder(storyBookParagraphs.size());
model.addAttribute("storyBookParagraph", storyBookParagraph);
model.addAttribute("audios", audioDao.readAllOrderedByTitle());
model.addAttribute("timeStart", System.currentTimeMillis());
return "content/storybook/paragraph/create";
}
use of ai.elimu.model.content.StoryBookParagraph in project webapp by elimu-ai.
the class StoryBookParagraphEditController method handleSubmit.
@RequestMapping(value = "/{id}", method = RequestMethod.POST)
public String handleSubmit(HttpServletRequest request, HttpSession session, @Valid StoryBookParagraph storyBookParagraph, BindingResult result, Model model) {
logger.info("handleSubmit");
Contributor contributor = (Contributor) session.getAttribute("contributor");
if (result.hasErrors()) {
model.addAttribute("storyBookParagraph", storyBookParagraph);
model.addAttribute("timeStart", System.currentTimeMillis());
return "content/storybook/paragraph/edit";
} else {
// Fetch previously stored paragraph to make it possible to check if the text was modified or not when
// storing the StoryBookContributionEvent below.
StoryBookParagraph storyBookParagraphBeforeEdit = storyBookParagraphDao.read(storyBookParagraph.getId());
storyBookParagraphDao.update(storyBookParagraph);
// Update the storybook's metadata
StoryBook storyBook = storyBookParagraph.getStoryBookChapter().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("Edited storybook paragraph in chapter " + (storyBookParagraph.getStoryBookChapter().getSortOrder() + 1) + " (🤖 auto-generated comment)");
if (!storyBookParagraphBeforeEdit.getOriginalText().equals(storyBookParagraph.getOriginalText())) {
storyBookContributionEvent.setParagraphTextBefore(StringUtils.abbreviate(storyBookParagraphBeforeEdit.getOriginalText(), 1000));
storyBookContributionEvent.setParagraphTextAfter(StringUtils.abbreviate(storyBookParagraph.getOriginalText(), 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 paragraph edited: " + contentUrl, "\"" + storyBookContributionEvent.getStoryBook().getTitle() + "\"", "Comment: \"" + storyBookContributionEvent.getComment() + "\"", null, embedThumbnailUrl);
// Refresh the REST API cache
storyBooksJsonService.refreshStoryBooksJSONArray();
return "redirect:/content/storybook/edit/" + storyBookParagraph.getStoryBookChapter().getStoryBook().getId() + "#ch-id-" + storyBookParagraph.getStoryBookChapter().getId();
}
}
use of ai.elimu.model.content.StoryBookParagraph in project webapp by elimu-ai.
the class StoryBookParagraphEditController method handleRequest.
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public String handleRequest(Model model, @PathVariable Long id, HttpSession session) {
logger.info("handleRequest");
StoryBookParagraph storyBookParagraph = storyBookParagraphDao.read(id);
logger.info("storyBookParagraph: " + storyBookParagraph);
model.addAttribute("storyBookParagraph", storyBookParagraph);
// Generate Audio for this StoryBookParagraph (if it has not been done already)
List<Audio> paragraphAudios = audioDao.readAll(storyBookParagraph);
if (paragraphAudios.isEmpty()) {
Calendar timeStart = Calendar.getInstance();
Language language = Language.valueOf(ConfigHelper.getProperty("content.language"));
try {
byte[] audioBytes = GoogleCloudTextToSpeechHelper.synthesizeText(storyBookParagraph.getOriginalText(), language);
logger.info("audioBytes: " + audioBytes);
if (audioBytes != null) {
Audio audio = new Audio();
audio.setTimeLastUpdate(Calendar.getInstance());
audio.setContentType(AudioFormat.MP3.getContentType());
audio.setStoryBookParagraph(storyBookParagraph);
audio.setTitle("storybook-" + storyBookParagraph.getStoryBookChapter().getStoryBook().getId() + "-ch-" + (storyBookParagraph.getStoryBookChapter().getSortOrder() + 1) + "-par-" + (storyBookParagraph.getSortOrder() + 1));
audio.setTranscription(storyBookParagraph.getOriginalText());
audio.setBytes(audioBytes);
// TODO: Convert from byte[] to File, and extract audio duration
audio.setDurationMs(null);
audio.setAudioFormat(AudioFormat.MP3);
audioDao.create(audio);
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);
paragraphAudios = audioDao.readAll(storyBookParagraph);
}
} catch (Exception ex) {
logger.error(ex);
}
}
model.addAttribute("audios", paragraphAudios);
model.addAttribute("timeStart", System.currentTimeMillis());
return "content/storybook/paragraph/edit";
}
Aggregations