Search in sources :

Example 6 with StoryBookParagraph

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);
    }
}
Also used : StoryBookChapter(ai.elimu.model.content.StoryBookChapter) StoryBook(ai.elimu.model.content.StoryBook) StoryBookParagraphGson(ai.elimu.model.v2.gson.content.StoryBookParagraphGson) JSONArray(org.json.JSONArray) ArrayList(java.util.ArrayList) StoryBookParagraph(ai.elimu.model.content.StoryBookParagraph) ImageGson(ai.elimu.model.v2.gson.content.ImageGson) Gson(com.google.gson.Gson) StoryBookParagraphGson(ai.elimu.model.v2.gson.content.StoryBookParagraphGson) StoryBookChapterGson(ai.elimu.model.v2.gson.content.StoryBookChapterGson) IOException(java.io.IOException) CSVPrinter(org.apache.commons.csv.CSVPrinter) ImageGson(ai.elimu.model.v2.gson.content.ImageGson) StringWriter(java.io.StringWriter) JSONObject(org.json.JSONObject) CSVFormat(org.apache.commons.csv.CSVFormat) StoryBookChapterGson(ai.elimu.model.v2.gson.content.StoryBookChapterGson) RequestMapping(org.springframework.web.bind.annotation.RequestMapping)

Example 7 with StoryBookParagraph

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";
}
Also used : Word(ai.elimu.model.content.Word) Calendar(java.util.Calendar) StoryBookParagraph(ai.elimu.model.content.StoryBookParagraph) Image(ai.elimu.model.content.multimedia.Image) Language(ai.elimu.model.v2.enums.Language) Emoji(ai.elimu.model.content.Emoji) AudioContributionEvent(ai.elimu.model.contributor.AudioContributionEvent) Audio(ai.elimu.model.content.multimedia.Audio) RequestMapping(org.springframework.web.bind.annotation.RequestMapping)

Example 8 with StoryBookParagraph

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";
}
Also used : StoryBookChapter(ai.elimu.model.content.StoryBookChapter) StoryBookParagraph(ai.elimu.model.content.StoryBookParagraph) RequestMapping(org.springframework.web.bind.annotation.RequestMapping)

Example 9 with StoryBookParagraph

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();
    }
}
Also used : StoryBookContributionEvent(ai.elimu.model.contributor.StoryBookContributionEvent) StoryBook(ai.elimu.model.content.StoryBook) Contributor(ai.elimu.model.contributor.Contributor) StoryBookParagraph(ai.elimu.model.content.StoryBookParagraph) RequestMapping(org.springframework.web.bind.annotation.RequestMapping)

Example 10 with StoryBookParagraph

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";
}
Also used : Language(ai.elimu.model.v2.enums.Language) Calendar(java.util.Calendar) StoryBookParagraph(ai.elimu.model.content.StoryBookParagraph) AudioContributionEvent(ai.elimu.model.contributor.AudioContributionEvent) Audio(ai.elimu.model.content.multimedia.Audio) RequestMapping(org.springframework.web.bind.annotation.RequestMapping)

Aggregations

StoryBookParagraph (ai.elimu.model.content.StoryBookParagraph)19 RequestMapping (org.springframework.web.bind.annotation.RequestMapping)12 StoryBook (ai.elimu.model.content.StoryBook)11 StoryBookChapter (ai.elimu.model.content.StoryBookChapter)11 ArrayList (java.util.ArrayList)11 Word (ai.elimu.model.content.Word)9 Language (ai.elimu.model.v2.enums.Language)9 StoryBookContributionEvent (ai.elimu.model.contributor.StoryBookContributionEvent)6 Audio (ai.elimu.model.content.multimedia.Audio)5 Image (ai.elimu.model.content.multimedia.Image)5 HashMap (java.util.HashMap)5 Letter (ai.elimu.model.content.Letter)4 Contributor (ai.elimu.model.contributor.Contributor)4 Scheduled (org.springframework.scheduling.annotation.Scheduled)4 StoryBookChapterGson (ai.elimu.model.v2.gson.content.StoryBookChapterGson)3 StoryBookParagraphGson (ai.elimu.model.v2.gson.content.StoryBookParagraphGson)3 Emoji (ai.elimu.model.content.Emoji)2 AudioContributionEvent (ai.elimu.model.contributor.AudioContributionEvent)2 StoryBookGson (ai.elimu.model.v2.gson.content.StoryBookGson)2 Gson (com.google.gson.Gson)2