Search in sources :

Example 6 with WordContributionEvent

use of ai.elimu.model.contributor.WordContributionEvent in project webapp by elimu-ai.

the class ContributorController method handleRequest.

@RequestMapping(method = RequestMethod.GET)
public String handleRequest(@PathVariable Long contributorId, Model model) {
    logger.info("handleRequest");
    Contributor contributor = contributorDao.read(contributorId);
    model.addAttribute("contributor2", contributor);
    // For contributor-summarized.jsp
    model.addAttribute("storyBookContributionsCount", storyBookContributionEventDao.readCount(contributor));
    model.addAttribute("storyBookPeerReviewsCount", storyBookPeerReviewEventDao.readCount(contributor));
    model.addAttribute("audioContributionsCount", audioContributionEventDao.readCount(contributor));
    model.addAttribute("audioPeerReviewsCount", audioPeerReviewEventDao.readCount(contributor));
    model.addAttribute("wordContributionsCount", wordContributionEventDao.readCount(contributor));
    model.addAttribute("wordPeerReviewsCount", wordPeerReviewEventDao.readCount(contributor));
    model.addAttribute("numberContributionsCount", numberContributionEventDao.readCount(contributor));
    model.addAttribute("numberPeerReviewsCount", numberPeerReviewEventDao.readCount(contributor));
    // For contributor-storybooks.jsp
    List<StoryBookContributionEvent> storyBookContributionEvents = storyBookContributionEventDao.readAll(contributor);
    model.addAttribute("storyBookContributionEvents", storyBookContributionEvents);
    model.addAttribute("storyBookPeerReviewEvents", storyBookPeerReviewEventDao.readAll(contributor));
    Map<Long, List<StoryBookPeerReviewEvent>> storyBookPeerReviewEventsByContributionMap = new HashMap<>();
    for (StoryBookContributionEvent storyBookContributionEvent : storyBookContributionEvents) {
        storyBookPeerReviewEventsByContributionMap.put(storyBookContributionEvent.getId(), storyBookPeerReviewEventDao.readAll(storyBookContributionEvent));
    }
    model.addAttribute("storyBookPeerReviewEventsByContributionMap", storyBookPeerReviewEventsByContributionMap);
    // For contributor-words.jsp
    List<WordContributionEvent> wordContributionEvents = wordContributionEventDao.readAll(contributor);
    model.addAttribute("wordContributionEvents", wordContributionEvents);
    model.addAttribute("wordPeerReviewEvents", wordPeerReviewEventDao.readAll(contributor));
    Map<Long, List<WordPeerReviewEvent>> wordPeerReviewEventsByContributionMap = new HashMap<>();
    for (WordContributionEvent wordContributionEvent : wordContributionEvents) {
        wordPeerReviewEventsByContributionMap.put(wordContributionEvent.getId(), wordPeerReviewEventDao.readAll(wordContributionEvent));
    }
    model.addAttribute("wordPeerReviewEventsByContributionMap", wordPeerReviewEventsByContributionMap);
    // For contributor-numbers.jsp
    List<NumberContributionEvent> numberContributionEvents = numberContributionEventDao.readAll(contributor);
    model.addAttribute("numberContributionEvents", numberContributionEvents);
    model.addAttribute("numberPeerReviewEvents", numberPeerReviewEventDao.readAll(contributor));
    Map<Long, List<NumberPeerReviewEvent>> numberPeerReviewEventsByContributionMap = new HashMap<>();
    for (NumberContributionEvent numberContributionEvent : numberContributionEvents) {
        numberPeerReviewEventsByContributionMap.put(numberContributionEvent.getId(), numberPeerReviewEventDao.readAll(numberContributionEvent));
    }
    model.addAttribute("numberPeerReviewEventsByContributionMap", numberPeerReviewEventsByContributionMap);
    return "content/contributor/contributor";
}
Also used : HashMap(java.util.HashMap) Contributor(ai.elimu.model.contributor.Contributor) StoryBookContributionEvent(ai.elimu.model.contributor.StoryBookContributionEvent) NumberContributionEvent(ai.elimu.model.contributor.NumberContributionEvent) List(java.util.List) WordContributionEvent(ai.elimu.model.contributor.WordContributionEvent) RequestMapping(org.springframework.web.bind.annotation.RequestMapping)

Example 7 with WordContributionEvent

use of ai.elimu.model.contributor.WordContributionEvent in project webapp by elimu-ai.

the class DbContentImportHelper method performDatabaseContentImport.

/**
 * Extracts educational content from the CSV files in {@code src/main/resources/db/content_TEST/<Language>/} and
 * stores it in the database.
 *
 * @param environment The environment from which to import the database content.
 * @param language The language to use during the import.
 * @param webApplicationContext Context needed to access DAOs.
 */
public synchronized void performDatabaseContentImport(Environment environment, Language language, WebApplicationContext webApplicationContext) {
    logger.info("performDatabaseContentImport");
    logger.info("environment: " + environment + ", language: " + language);
    if (!((environment == Environment.TEST) || (environment == Environment.PROD))) {
        throw new IllegalArgumentException("Database content can only be imported from the TEST environment or from the PROD environment");
    }
    String contentDirectoryPath = "db" + File.separator + "content_" + environment + File.separator + language.toString().toLowerCase();
    logger.info("contentDirectoryPath: \"" + contentDirectoryPath + "\"");
    URL contentDirectoryURL = getClass().getClassLoader().getResource(contentDirectoryPath);
    logger.info("contentDirectoryURL: " + contentDirectoryURL);
    if (contentDirectoryURL == null) {
        logger.warn("The content directory was not found. Aborting content import.");
        return;
    }
    File contentDirectory = new File(contentDirectoryURL.getPath());
    logger.info("contentDirectory: " + contentDirectory);
    contributorDao = (ContributorDao) webApplicationContext.getBean("contributorDao");
    Contributor contributor = new Contributor();
    contributor.setEmail("dev@elimu.ai");
    contributor.setFirstName("Dev");
    contributor.setLastName("Contributor");
    contributor.setRoles(new HashSet<>(Arrays.asList(Role.CONTRIBUTOR, Role.EDITOR, Role.ANALYST, Role.ADMIN)));
    contributor.setRegistrationTime(Calendar.getInstance());
    contributorDao.create(contributor);
    // Extract and import Letters from CSV file in src/main/resources/
    File lettersCsvFile = new File(contentDirectory, "letters.csv");
    List<Letter> letters = CsvContentExtractionHelper.getLettersFromCsvBackup(lettersCsvFile, soundDao);
    logger.info("letters.size(): " + letters.size());
    letterDao = (LetterDao) webApplicationContext.getBean("letterDao");
    letterContributionEventDao = (LetterContributionEventDao) webApplicationContext.getBean("letterContributionEventDao");
    for (Letter letter : letters) {
        letterDao.create(letter);
        LetterContributionEvent letterContributionEvent = new LetterContributionEvent();
        letterContributionEvent.setContributor(contributor);
        letterContributionEvent.setLetter(letter);
        letterContributionEvent.setRevisionNumber(1);
        letterContributionEvent.setTime(Calendar.getInstance());
        letterContributionEvent.setTimeSpentMs((long) (Math.random() * 10) * 60000L);
        letterContributionEvent.setPlatform(Platform.WEBAPP);
        letterContributionEventDao.create(letterContributionEvent);
    }
    // Extract and import Sounds from CSV file in src/main/resources/
    File soundsCsvFile = new File(contentDirectory, "sounds.csv");
    List<Sound> sounds = CsvContentExtractionHelper.getSoundsFromCsvBackup(soundsCsvFile);
    logger.info("sounds.size(): " + sounds.size());
    soundDao = (SoundDao) webApplicationContext.getBean("soundDao");
    for (Sound sound : sounds) {
        soundDao.create(sound);
    }
    // Extract and import letter-sound correspondences in src/main/resources/
    File letterToAllophioneMappingsCsvFile = new File(contentDirectory, "letter-sound-correspondences.csv");
    List<LetterSoundCorrespondence> letterSoundCorrespondences = CsvContentExtractionHelper.getLetterSoundCorrespondencesFromCsvBackup(letterToAllophioneMappingsCsvFile, letterDao, soundDao, letterSoundCorrespondenceDao);
    logger.info("letterSoundCorrespondences.size(): " + letterSoundCorrespondences.size());
    letterSoundCorrespondenceDao = (LetterSoundCorrespondenceDao) webApplicationContext.getBean("letterSoundCorrespondenceDao");
    letterSoundCorrespondenceContributionEventDao = (LetterSoundCorrespondenceContributionEventDao) webApplicationContext.getBean("letterSoundCorrespondenceContributionEventDao");
    for (LetterSoundCorrespondence letterSoundCorrespondence : letterSoundCorrespondences) {
        letterSoundCorrespondenceDao.create(letterSoundCorrespondence);
        LetterSoundCorrespondenceContributionEvent letterSoundCorrespondenceContributionEvent = new LetterSoundCorrespondenceContributionEvent();
        letterSoundCorrespondenceContributionEvent.setContributor(contributor);
        letterSoundCorrespondenceContributionEvent.setLetterSoundCorrespondence(letterSoundCorrespondence);
        letterSoundCorrespondenceContributionEvent.setRevisionNumber(1);
        letterSoundCorrespondenceContributionEvent.setTime(Calendar.getInstance());
        letterSoundCorrespondenceContributionEvent.setTimeSpentMs((long) (Math.random() * 10) * 60000L);
        letterSoundCorrespondenceContributionEvent.setPlatform(Platform.WEBAPP);
        letterSoundCorrespondenceContributionEventDao.create(letterSoundCorrespondenceContributionEvent);
    }
    // Extract and import Words from CSV file in src/main/resources/
    File wordsCsvFile = new File(contentDirectory, "words.csv");
    List<Word> words = CsvContentExtractionHelper.getWordsFromCsvBackup(wordsCsvFile, letterDao, soundDao, letterSoundCorrespondenceDao, wordDao);
    logger.info("words.size(): " + words.size());
    wordDao = (WordDao) webApplicationContext.getBean("wordDao");
    wordContributionEventDao = (WordContributionEventDao) webApplicationContext.getBean("wordContributionEventDao");
    for (Word word : words) {
        wordDao.create(word);
        WordContributionEvent wordContributionEvent = new WordContributionEvent();
        wordContributionEvent.setContributor(contributor);
        wordContributionEvent.setWord(word);
        wordContributionEvent.setRevisionNumber(1);
        wordContributionEvent.setTime(Calendar.getInstance());
        wordContributionEvent.setTimeSpentMs((long) (Math.random() * 10) * 60000L);
        wordContributionEvent.setPlatform(Platform.WEBAPP);
        wordContributionEventDao.create(wordContributionEvent);
    }
    // Extract and import Numbers from CSV file in src/main/resources/
    File numbersCsvFile = new File(contentDirectory, "numbers.csv");
    List<Number> numbers = CsvContentExtractionHelper.getNumbersFromCsvBackup(numbersCsvFile, wordDao);
    logger.info("numbers.size(): " + numbers.size());
    numberDao = (NumberDao) webApplicationContext.getBean("numberDao");
    numberContributionEventDao = (NumberContributionEventDao) webApplicationContext.getBean("numberContributionEventDao");
    for (Number number : numbers) {
        numberDao.create(number);
        NumberContributionEvent numberContributionEvent = new NumberContributionEvent();
        numberContributionEvent.setContributor(contributor);
        numberContributionEvent.setNumber(number);
        numberContributionEvent.setRevisionNumber(1);
        numberContributionEvent.setTime(Calendar.getInstance());
        numberContributionEvent.setTimeSpentMs((long) (Math.random() * 10) * 60000L);
        numberContributionEvent.setPlatform(Platform.WEBAPP);
        numberContributionEventDao.create(numberContributionEvent);
    }
    // Extract and import Syllables from CSV file in src/main/resources/
    // TODO
    // Extract and import Emojis from CSV file in src/main/resources/
    File emojisCsvFile = new File(contentDirectory, "emojis.csv");
    List<Emoji> emojis = CsvContentExtractionHelper.getEmojisFromCsvBackup(emojisCsvFile, wordDao);
    logger.info("emojis.size(): " + emojis.size());
    emojiDao = (EmojiDao) webApplicationContext.getBean("emojiDao");
    for (Emoji emoji : emojis) {
        emojiDao.create(emoji);
    }
    // Extract and import Images from CSV file in src/main/resources/
    // TODO
    // Extract and import Audios from CSV file in src/main/resources/
    // TODO
    // Extract and import StoryBooks from CSV file in src/main/resources/
    File storyBooksCsvFile = new File(contentDirectory, "storybooks.csv");
    List<StoryBookGson> storyBookGsons = CsvContentExtractionHelper.getStoryBooksFromCsvBackup(storyBooksCsvFile);
    logger.info("storyBookGsons.size(): " + storyBookGsons.size());
    storyBookDao = (StoryBookDao) webApplicationContext.getBean("storyBookDao");
    storyBookChapterDao = (StoryBookChapterDao) webApplicationContext.getBean("storyBookChapterDao");
    storyBookParagraphDao = (StoryBookParagraphDao) webApplicationContext.getBean("storyBookParagraphDao");
    storyBookContributionEventDao = (StoryBookContributionEventDao) webApplicationContext.getBean("storyBookContributionEventDao");
    for (StoryBookGson storyBookGson : storyBookGsons) {
        // Convert from GSON to JPA
        StoryBook storyBook = new StoryBook();
        storyBook.setTitle(storyBookGson.getTitle());
        storyBook.setDescription(storyBookGson.getDescription());
        // TODO: storyBook.setContentLicense();
        // TODO: storyBook.setAttributionUrl();
        storyBook.setReadingLevel(storyBookGson.getReadingLevel());
        storyBookDao.create(storyBook);
        for (StoryBookChapterGson storyBookChapterGson : storyBookGson.getStoryBookChapters()) {
            // Convert from GSON to JPA
            StoryBookChapter storyBookChapter = new StoryBookChapter();
            storyBookChapter.setStoryBook(storyBook);
            storyBookChapter.setSortOrder(storyBookChapterGson.getSortOrder());
            // TODO: storyBookChapter.setImage();
            storyBookChapterDao.create(storyBookChapter);
            for (StoryBookParagraphGson storyBookParagraphGson : storyBookChapterGson.getStoryBookParagraphs()) {
                // Convert from GSON to JPA
                StoryBookParagraph storyBookParagraph = new StoryBookParagraph();
                storyBookParagraph.setStoryBookChapter(storyBookChapter);
                storyBookParagraph.setSortOrder(storyBookParagraphGson.getSortOrder());
                storyBookParagraph.setOriginalText(storyBookParagraphGson.getOriginalText());
                List<String> wordsInOriginalText = WordExtractionHelper.getWords(storyBookParagraph.getOriginalText(), language);
                logger.info("wordsInOriginalText.size(): " + wordsInOriginalText.size());
                List<Word> paragraphWords = new ArrayList<>();
                logger.info("paragraphWords.size(): " + paragraphWords.size());
                for (String wordInOriginalText : wordsInOriginalText) {
                    logger.info("wordInOriginalText: \"" + wordInOriginalText + "\"");
                    wordInOriginalText = wordInOriginalText.toLowerCase();
                    logger.info("wordInOriginalText (lower-case): \"" + wordInOriginalText + "\"");
                    Word word = wordDao.readByText(wordInOriginalText);
                    logger.info("word: " + word);
                    paragraphWords.add(word);
                }
                storyBookParagraph.setWords(paragraphWords);
                storyBookParagraphDao.create(storyBookParagraph);
            }
        }
        StoryBookContributionEvent storyBookContributionEvent = new StoryBookContributionEvent();
        storyBookContributionEvent.setContributor(contributor);
        storyBookContributionEvent.setStoryBook(storyBook);
        storyBookContributionEvent.setRevisionNumber(1);
        storyBookContributionEvent.setTime(Calendar.getInstance());
        storyBookContributionEvent.setTimeSpentMs((long) (Math.random() * 10) * 60000L);
        storyBookContributionEvent.setPlatform(Platform.WEBAPP);
        storyBookContributionEventDao.create(storyBookContributionEvent);
    }
    // Extract and import Videos from CSV file in src/main/resources/
    // TODO
    String analyticsDirectoryPath = "db" + File.separator + "analytics_" + environment + File.separator + language.toString().toLowerCase();
    logger.info("analyticsDirectoryPath: \"" + analyticsDirectoryPath + "\"");
    URL analyticsDirectoryURL = getClass().getClassLoader().getResource(analyticsDirectoryPath);
    logger.info("analyticsDirectoryURL: " + analyticsDirectoryURL);
    if (analyticsDirectoryURL == null) {
        logger.warn("The analytics directory was not found. Aborting analytics import.");
        return;
    }
    File analyticsDirectory = new File(analyticsDirectoryURL.getPath());
    logger.info("analyticsDirectory: " + analyticsDirectory);
    // Extract and import LetterLearningEvents from CSV file in src/main/resources/
    // TODO
    // Extract and import WordLearningEvents from CSV file in src/main/resources/
    // TODO
    // Extract and import StoryBookLearningEvents from CSV file in src/main/resources/
    File storyBookLearningEventsCsvFile = new File(analyticsDirectory, "storybook-learning-events.csv");
    applicationDao = (ApplicationDao) webApplicationContext.getBean("applicationDao");
    List<StoryBookLearningEvent> storyBookLearningEvents = CsvAnalyticsExtractionHelper.getStoryBookLearningEventsFromCsvBackup(storyBookLearningEventsCsvFile, applicationDao, storyBookDao);
    logger.info("storyBookLearningEvents.size(): " + storyBookLearningEvents.size());
    storyBookLearningEventDao = (StoryBookLearningEventDao) webApplicationContext.getBean("storyBookLearningEventDao");
    for (StoryBookLearningEvent storyBookLearningEvent : storyBookLearningEvents) {
        storyBookLearningEventDao.create(storyBookLearningEvent);
    }
    logger.info("Content import complete");
}
Also used : StoryBookChapter(ai.elimu.model.content.StoryBookChapter) LetterContributionEvent(ai.elimu.model.contributor.LetterContributionEvent) Word(ai.elimu.model.content.Word) StoryBook(ai.elimu.model.content.StoryBook) StoryBookLearningEvent(ai.elimu.model.analytics.StoryBookLearningEvent) StoryBookGson(ai.elimu.model.v2.gson.content.StoryBookGson) ArrayList(java.util.ArrayList) Contributor(ai.elimu.model.contributor.Contributor) URL(java.net.URL) LetterSoundCorrespondenceContributionEvent(ai.elimu.model.contributor.LetterSoundCorrespondenceContributionEvent) StoryBookContributionEvent(ai.elimu.model.contributor.StoryBookContributionEvent) Number(ai.elimu.model.content.Number) Emoji(ai.elimu.model.content.Emoji) LetterSoundCorrespondence(ai.elimu.model.content.LetterSoundCorrespondence) WordContributionEvent(ai.elimu.model.contributor.WordContributionEvent) StoryBookParagraphGson(ai.elimu.model.v2.gson.content.StoryBookParagraphGson) StoryBookParagraph(ai.elimu.model.content.StoryBookParagraph) Sound(ai.elimu.model.content.Sound) Letter(ai.elimu.model.content.Letter) NumberContributionEvent(ai.elimu.model.contributor.NumberContributionEvent) File(java.io.File) StoryBookChapterGson(ai.elimu.model.v2.gson.content.StoryBookChapterGson)

Example 8 with WordContributionEvent

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

Example 9 with WordContributionEvent

use of ai.elimu.model.contributor.WordContributionEvent in project webapp by elimu-ai.

the class WordEditController method handleSubmit.

@RequestMapping(value = "/{id}", 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) && !existingWord.getId().equals(word.getId())) {
        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("wordContributionEvents", wordContributionEventDao.readAll(word));
        model.addAttribute("wordPeerReviewEvents", wordPeerReviewEventDao.readAll(word));
        model.addAttribute("audios", audioDao.readAll(word));
        // 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);
        return "content/word/edit";
    } else {
        word.setTimeLastUpdate(Calendar.getInstance());
        word.setRevisionNumber(word.getRevisionNumber() + 1);
        wordDao.update(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 edited: " + contentUrl, "\"" + word.getText() + "\"", "Comment: \"" + wordContributionEvent.getComment() + "\"", null, null);
        // Note: updating the list of Words in StoryBookParagraphs is handled by the ParagraphWordScheduler
        // Delete syllables that are actual words
        Syllable syllable = syllableDao.readByText(word.getText());
        if (syllable != null) {
            syllableDao.delete(syllable);
        }
        return "redirect:/content/word/list#" + word.getId();
    }
}
Also used : Word(ai.elimu.model.content.Word) Emoji(ai.elimu.model.content.Emoji) WordContributionEvent(ai.elimu.model.contributor.WordContributionEvent) Image(ai.elimu.model.content.multimedia.Image) Syllable(ai.elimu.model.content.Syllable) RequestMapping(org.springframework.web.bind.annotation.RequestMapping)

Example 10 with WordContributionEvent

use of ai.elimu.model.contributor.WordContributionEvent in project webapp by elimu-ai.

the class WordContributionRestController method postWordContribution.

/**
 * Handles the creation of a new {@link Word} & the corresponding {@link WordContributionEvent}.
 *
 * @param requestBody JSON should contain fields required for the creation of a {@link WordContributionEventGson}
 * object.
 */
@RequestMapping(value = "/word", method = RequestMethod.POST)
public String postWordContribution(HttpServletRequest request, HttpServletResponse response, @RequestBody String requestBody) {
    logger.info("postWordContribution");
    // Validate the Contributor.
    JSONObject jsonObject = new JSONObject();
    String providerIdGoogle = request.getHeader("providerIdGoogle");
    logger.info("providerIdGoogle: " + providerIdGoogle);
    if (StringUtils.isBlank(providerIdGoogle)) {
        jsonObject.put("result", "error");
        jsonObject.put("errorMessage", "Missing providerIdGoogle");
        response.setStatus(HttpStatus.BAD_REQUEST.value());
        String jsonResponse = jsonObject.toString();
        logger.info("jsonResponse: " + jsonResponse);
        return jsonResponse;
    }
    // Lookup the Contributor by ID
    Contributor contributor = contributorDao.readByProviderIdGoogle(providerIdGoogle);
    logger.info("contributor: " + contributor);
    if (contributor == null) {
        jsonObject.put("result", "error");
        jsonObject.put("errorMessage", "The Contributor was not found.");
        response.setStatus(HttpStatus.UNPROCESSABLE_ENTITY.value());
        String jsonResponse = jsonObject.toString();
        logger.info("jsonResponse: " + jsonResponse);
        return jsonResponse;
    }
    logger.info("requestBody: " + requestBody);
    // Convert the request body to a WordContributionEventGson
    WordContributionEventGson wordContributionEventGson = new Gson().fromJson(requestBody, WordContributionEventGson.class);
    logger.info("wordContributionEventGson: " + wordContributionEventGson);
    // Extract the WordGson from the WordContributionEventGson
    WordGson wordGson = wordContributionEventGson.getWord();
    logger.info("wordGson: " + wordGson);
    // Check if the word is already existing.
    Word existingWord = wordDao.readByText(wordGson.getText().toLowerCase());
    if (existingWord != null) {
        jsonObject.put("result", "error");
        jsonObject.put("errorMessage", "NonUnique");
        response.setStatus(HttpStatus.CONFLICT.value());
        String jsonResponse = jsonObject.toString();
        logger.info("jsonResponse: " + jsonResponse);
        return jsonResponse;
    }
    try {
        // Convert the WordGson to Word POJO.
        Word word = new Word();
        word.setWordType(wordGson.getWordType());
        word.setText(wordGson.getText().toLowerCase());
        List<LetterSoundCorrespondenceGson> letterSoundCorrespondencesGsons = wordGson.getLetterSoundCorrespondences();
        List<LetterSoundCorrespondence> letterSoundCorrespondences = new ArrayList<>();
        for (LetterSoundCorrespondenceGson letterSoundCorrespondenceGson : letterSoundCorrespondencesGsons) {
            LetterSoundCorrespondence letterSoundCorrespondence = letterSoundCorrespondenceDao.read(letterSoundCorrespondenceGson.getId());
            letterSoundCorrespondences.add(letterSoundCorrespondence);
        }
        word.setLetterSoundCorrespondences(letterSoundCorrespondences);
        wordDao.create(word);
        WordContributionEvent wordContributionEvent = new WordContributionEvent();
        wordContributionEvent.setContributor(contributor);
        wordContributionEvent.setTime(wordContributionEventGson.getTime());
        wordContributionEvent.setWord(word);
        wordContributionEvent.setRevisionNumber(word.getRevisionNumber());
        wordContributionEvent.setComment(StringUtils.abbreviate(wordContributionEventGson.getComment(), 1000));
        wordContributionEvent.setTimeSpentMs(System.currentTimeMillis() - wordContributionEvent.getTime().getTimeInMillis());
        // TODO: wordContributionEvent.setTimeSpentMs(wordContributionEventGson.getTimeSpentMs());
        // refer to: https://github.com/elimu-ai/webapp/pull/1289#discussion_r642024541
        wordContributionEvent.setPlatform(Platform.CROWDSOURCE_APP);
        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);
        response.setStatus(HttpStatus.CREATED.value());
    } catch (Exception ex) {
        logger.error(ex);
        jsonObject.put("result", "error");
        jsonObject.put("errorMessage", ex.getMessage());
        response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
    }
    String jsonResponse = jsonObject.toString();
    logger.info("jsonResponse: " + jsonResponse);
    return jsonResponse;
}
Also used : Word(ai.elimu.model.content.Word) WordContributionEventGson(ai.elimu.model.v2.gson.crowdsource.WordContributionEventGson) ArrayList(java.util.ArrayList) Contributor(ai.elimu.model.contributor.Contributor) LetterSoundCorrespondenceGson(ai.elimu.model.v2.gson.content.LetterSoundCorrespondenceGson) Gson(com.google.gson.Gson) WordGson(ai.elimu.model.v2.gson.content.WordGson) WordContributionEventGson(ai.elimu.model.v2.gson.crowdsource.WordContributionEventGson) LetterSoundCorrespondenceGson(ai.elimu.model.v2.gson.content.LetterSoundCorrespondenceGson) WordGson(ai.elimu.model.v2.gson.content.WordGson) JSONObject(org.json.JSONObject) LetterSoundCorrespondence(ai.elimu.model.content.LetterSoundCorrespondence) WordContributionEvent(ai.elimu.model.contributor.WordContributionEvent) RequestMapping(org.springframework.web.bind.annotation.RequestMapping)

Aggregations

WordContributionEvent (ai.elimu.model.contributor.WordContributionEvent)10 Contributor (ai.elimu.model.contributor.Contributor)8 Word (ai.elimu.model.content.Word)7 RequestMapping (org.springframework.web.bind.annotation.RequestMapping)7 NumberContributionEvent (ai.elimu.model.contributor.NumberContributionEvent)3 StoryBookContributionEvent (ai.elimu.model.contributor.StoryBookContributionEvent)3 ArrayList (java.util.ArrayList)3 Emoji (ai.elimu.model.content.Emoji)2 LetterSoundCorrespondence (ai.elimu.model.content.LetterSoundCorrespondence)2 Syllable (ai.elimu.model.content.Syllable)2 Image (ai.elimu.model.content.multimedia.Image)2 AudioContributionEvent (ai.elimu.model.contributor.AudioContributionEvent)2 WordPeerReviewEvent (ai.elimu.model.contributor.WordPeerReviewEvent)2 HashMap (java.util.HashMap)2 Test (org.junit.Test)2 StoryBookLearningEvent (ai.elimu.model.analytics.StoryBookLearningEvent)1 Letter (ai.elimu.model.content.Letter)1 Number (ai.elimu.model.content.Number)1 Sound (ai.elimu.model.content.Sound)1 StoryBook (ai.elimu.model.content.StoryBook)1