Search in sources :

Example 21 with Contributor

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

the class NumberPeerReviewsController method handleGetRequest.

/**
 * Get {@link NumberContributionEvent}s pending a {@link NumberPeerReviewEvent} for the current {@link Contributor}.
 */
@RequestMapping(method = RequestMethod.GET)
public String handleGetRequest(HttpSession session, Model model) {
    logger.info("handleGetRequest");
    Contributor contributor = (Contributor) session.getAttribute("contributor");
    logger.info("contributor: " + contributor);
    // Get the most recent NumberContributionEvent for each Number, including those made by the current Contributor
    List<NumberContributionEvent> mostRecentNumberContributionEvents = numberContributionEventDao.readMostRecentPerNumber();
    logger.info("mostRecentNumberContributionEvents.size(): " + mostRecentNumberContributionEvents.size());
    // For each NumberContributionEvent, check if the Contributor has already performed a peer-review.
    // If not, add it to the list of pending peer reviews.
    List<NumberContributionEvent> numberContributionEventsPendingPeerReview = new ArrayList<>();
    for (NumberContributionEvent mostRecentNumberContributionEvent : mostRecentNumberContributionEvents) {
        // Ignore NumberContributionEvents made by the current Contributor
        if (mostRecentNumberContributionEvent.getContributor().getId().equals(contributor.getId())) {
            continue;
        }
        // Check if the current Contributor has already peer-reviewed this Number contribution
        List<NumberPeerReviewEvent> numberPeerReviewEvents = numberPeerReviewEventDao.readAll(mostRecentNumberContributionEvent, contributor);
        if (numberPeerReviewEvents.isEmpty()) {
            numberContributionEventsPendingPeerReview.add(mostRecentNumberContributionEvent);
        }
    }
    logger.info("numberContributionEventsPendingPeerReview.size(): " + numberContributionEventsPendingPeerReview.size());
    model.addAttribute("numberContributionEventsPendingPeerReview", numberContributionEventsPendingPeerReview);
    return "content/number/peer-reviews/pending";
}
Also used : NumberContributionEvent(ai.elimu.model.contributor.NumberContributionEvent) ArrayList(java.util.ArrayList) Contributor(ai.elimu.model.contributor.Contributor) NumberPeerReviewEvent(ai.elimu.model.contributor.NumberPeerReviewEvent) RequestMapping(org.springframework.web.bind.annotation.RequestMapping)

Example 22 with Contributor

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

the class LetterSoundCorrespondencePeerReviewEventCreateController method handleSubmit.

@RequestMapping(method = RequestMethod.POST)
public String handleSubmit(@RequestParam Long letterSoundCorrespondenceContributionEventId, @RequestParam Boolean approved, @RequestParam(required = false) String comment, HttpSession session) {
    logger.info("handleSubmit");
    Contributor contributor = (Contributor) session.getAttribute("contributor");
    logger.info("letterSoundCorrespondenceContributionEventId: " + letterSoundCorrespondenceContributionEventId);
    LetterSoundCorrespondenceContributionEvent letterSoundCorrespondenceContributionEvent = letterSoundCorrespondenceContributionEventDao.read(letterSoundCorrespondenceContributionEventId);
    logger.info("letterSoundCorrespondenceContributionEvent: " + letterSoundCorrespondenceContributionEvent);
    // Store the peer review event
    LetterSoundCorrespondencePeerReviewEvent letterSoundCorrespondencePeerReviewEvent = new LetterSoundCorrespondencePeerReviewEvent();
    letterSoundCorrespondencePeerReviewEvent.setContributor(contributor);
    letterSoundCorrespondencePeerReviewEvent.setLetterSoundCorrespondenceContributionEvent(letterSoundCorrespondenceContributionEvent);
    letterSoundCorrespondencePeerReviewEvent.setApproved(approved);
    letterSoundCorrespondencePeerReviewEvent.setComment(StringUtils.abbreviate(comment, 1000));
    letterSoundCorrespondencePeerReviewEvent.setTime(Calendar.getInstance());
    letterSoundCorrespondencePeerReviewEvent.setPlatform(Platform.WEBAPP);
    letterSoundCorrespondencePeerReviewEventDao.create(letterSoundCorrespondencePeerReviewEvent);
    String contentUrl = "http://" + EnvironmentContextLoaderListener.PROPERTIES.getProperty("content.language").toLowerCase() + ".elimu.ai/content/letterSoundCorrespondence/edit/" + letterSoundCorrespondenceContributionEvent.getLetterSoundCorrespondence().getId();
    DiscordHelper.sendChannelMessage("LetterSoundCorrespondence peer-reviewed: " + contentUrl, "\"" + letterSoundCorrespondenceContributionEvent.getLetterSoundCorrespondence().getLetters().stream().map(Letter::getText).collect(Collectors.joining()) + "\"", "Comment: \"" + letterSoundCorrespondencePeerReviewEvent.getComment() + "\"", letterSoundCorrespondencePeerReviewEvent.isApproved(), null);
    // Update the letterSoundCorrespondence's peer review status
    int approvedCount = 0;
    int notApprovedCount = 0;
    for (LetterSoundCorrespondencePeerReviewEvent peerReviewEvent : letterSoundCorrespondencePeerReviewEventDao.readAll(letterSoundCorrespondenceContributionEvent)) {
        if (peerReviewEvent.isApproved()) {
            approvedCount++;
        } else {
            notApprovedCount++;
        }
    }
    logger.info("approvedCount: " + approvedCount);
    logger.info("notApprovedCount: " + notApprovedCount);
    LetterSoundCorrespondence letterSoundCorrespondence = letterSoundCorrespondenceContributionEvent.getLetterSoundCorrespondence();
    if (approvedCount >= notApprovedCount) {
        letterSoundCorrespondence.setPeerReviewStatus(PeerReviewStatus.APPROVED);
    } else {
        letterSoundCorrespondence.setPeerReviewStatus(PeerReviewStatus.NOT_APPROVED);
    }
    letterSoundCorrespondenceDao.update(letterSoundCorrespondence);
    return "redirect:/content/letter-sound-correspondence/edit/" + letterSoundCorrespondenceContributionEvent.getLetterSoundCorrespondence().getId() + "#contribution-events";
}
Also used : Letter(ai.elimu.model.content.Letter) LetterSoundCorrespondenceContributionEvent(ai.elimu.model.contributor.LetterSoundCorrespondenceContributionEvent) Contributor(ai.elimu.model.contributor.Contributor) LetterSoundCorrespondence(ai.elimu.model.content.LetterSoundCorrespondence) LetterSoundCorrespondencePeerReviewEvent(ai.elimu.model.contributor.LetterSoundCorrespondencePeerReviewEvent) RequestMapping(org.springframework.web.bind.annotation.RequestMapping)

Example 23 with Contributor

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

Example 24 with Contributor

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

the class NumberPeerReviewEventCreateController method handleSubmit.

@RequestMapping(method = RequestMethod.POST)
public String handleSubmit(@RequestParam Long numberContributionEventId, @RequestParam Boolean approved, @RequestParam(required = false) String comment, HttpSession session) {
    logger.info("handleSubmit");
    Contributor contributor = (Contributor) session.getAttribute("contributor");
    logger.info("numberContributionEventId: " + numberContributionEventId);
    NumberContributionEvent numberContributionEvent = numberContributionEventDao.read(numberContributionEventId);
    logger.info("numberContributionEvent: " + numberContributionEvent);
    // Store the peer review event
    NumberPeerReviewEvent numberPeerReviewEvent = new NumberPeerReviewEvent();
    numberPeerReviewEvent.setContributor(contributor);
    numberPeerReviewEvent.setNumberContributionEvent(numberContributionEvent);
    numberPeerReviewEvent.setApproved(approved);
    numberPeerReviewEvent.setComment(StringUtils.abbreviate(comment, 1000));
    numberPeerReviewEvent.setTime(Calendar.getInstance());
    numberPeerReviewEvent.setPlatform(Platform.WEBAPP);
    numberPeerReviewEventDao.create(numberPeerReviewEvent);
    String contentUrl = "http://" + EnvironmentContextLoaderListener.PROPERTIES.getProperty("content.language").toLowerCase() + ".elimu.ai/content/number/edit/" + numberContributionEvent.getNumber().getId();
    DiscordHelper.sendChannelMessage("Number peer-reviewed: " + contentUrl, "\"" + numberContributionEvent.getNumber().getValue() + "\"", "Comment: \"" + numberPeerReviewEvent.getComment() + "\"", numberPeerReviewEvent.isApproved(), null);
    // Update the number's peer review status
    int approvedCount = 0;
    int notApprovedCount = 0;
    for (NumberPeerReviewEvent peerReviewEvent : numberPeerReviewEventDao.readAll(numberContributionEvent)) {
        if (peerReviewEvent.isApproved()) {
            approvedCount++;
        } else {
            notApprovedCount++;
        }
    }
    logger.info("approvedCount: " + approvedCount);
    logger.info("notApprovedCount: " + notApprovedCount);
    Number number = numberContributionEvent.getNumber();
    if (approvedCount >= notApprovedCount) {
        number.setPeerReviewStatus(PeerReviewStatus.APPROVED);
    } else {
        number.setPeerReviewStatus(PeerReviewStatus.NOT_APPROVED);
    }
    numberDao.update(number);
    return "redirect:/content/number/edit/" + numberContributionEvent.getNumber().getId() + "#contribution-events";
}
Also used : Number(ai.elimu.model.content.Number) NumberContributionEvent(ai.elimu.model.contributor.NumberContributionEvent) Contributor(ai.elimu.model.contributor.Contributor) NumberPeerReviewEvent(ai.elimu.model.contributor.NumberPeerReviewEvent) RequestMapping(org.springframework.web.bind.annotation.RequestMapping)

Example 25 with Contributor

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

the class StoryBookParagraphCreateController method handleSubmit.

@RequestMapping(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("audios", audioDao.readAllOrderedByTitle());
        model.addAttribute("timeStart", request.getParameter("timeStart"));
        return "content/storybook/paragraph/create";
    } else {
        storyBookParagraphDao.create(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("Created storybook paragraph in chapter " + (storyBookParagraph.getStoryBookChapter().getSortOrder() + 1) + " (🤖 auto-generated comment)");
        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 created: " + 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) RequestMapping(org.springframework.web.bind.annotation.RequestMapping)

Aggregations

Contributor (ai.elimu.model.contributor.Contributor)38 RequestMapping (org.springframework.web.bind.annotation.RequestMapping)32 StoryBookContributionEvent (ai.elimu.model.contributor.StoryBookContributionEvent)10 WordContributionEvent (ai.elimu.model.contributor.WordContributionEvent)8 ArrayList (java.util.ArrayList)8 JSONObject (org.json.JSONObject)8 StoryBook (ai.elimu.model.content.StoryBook)7 Word (ai.elimu.model.content.Word)7 Audio (ai.elimu.model.content.multimedia.Audio)6 AudioContributionEvent (ai.elimu.model.contributor.AudioContributionEvent)6 NumberContributionEvent (ai.elimu.model.contributor.NumberContributionEvent)5 HashMap (java.util.HashMap)5 StoryBookParagraph (ai.elimu.model.content.StoryBookParagraph)4 Gson (com.google.gson.Gson)4 LetterSoundCorrespondence (ai.elimu.model.content.LetterSoundCorrespondence)3 AudioPeerReviewEvent (ai.elimu.model.contributor.AudioPeerReviewEvent)3 LetterSoundCorrespondenceContributionEvent (ai.elimu.model.contributor.LetterSoundCorrespondenceContributionEvent)3 IOException (java.io.IOException)3 Test (org.junit.Test)3 Letter (ai.elimu.model.content.Letter)2