Search in sources :

Example 1 with Contributor

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

the class AudioPeerReviewsRestController method listWordRecordingsPendingPeerReview.

/**
 * Get {@link AudioContributionEvent}s pending a {@link AudioPeerReviewEvent} for the current {@link Contributor}.
 */
@RequestMapping(value = "/words", method = RequestMethod.GET)
public String listWordRecordingsPendingPeerReview(HttpServletRequest request, HttpServletResponse response) {
    logger.info("listWordRecordingsPendingPeerReview");
    JSONObject jsonObject = new JSONObject();
    // Lookup the Contributor by ID
    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;
    }
    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;
    }
    List<AudioContributionEvent> allAudioContributionEvents = audioContributionEventDao.readAll();
    logger.info("allAudioContributionEvents.size(): " + allAudioContributionEvents.size());
    // Get the most recent AudioContributionEvent for each Audio
    List<AudioContributionEvent> mostRecentAudioContributionEvents = new ArrayList<>();
    HashMap<Long, Void> idsOfAudiosWithContributionEventHashMap = new HashMap<>();
    for (AudioContributionEvent audioContributionEvent : allAudioContributionEvents) {
        // Ignore AudioContributionEvent if one has already been added for this Audio
        if (idsOfAudiosWithContributionEventHashMap.containsKey(audioContributionEvent.getAudio().getId())) {
            continue;
        }
        // Keep track of the Audio ID
        idsOfAudiosWithContributionEventHashMap.put(audioContributionEvent.getAudio().getId(), null);
        // Ignore AudioContributionEvents made by the current Contributor
        if (audioContributionEvent.getContributor().getId().equals(contributor.getId())) {
            continue;
        }
        mostRecentAudioContributionEvents.add(audioContributionEvent);
    }
    logger.info("mostRecentAudioContributionEvents.size(): " + mostRecentAudioContributionEvents.size());
    // For each AudioContributionEvent, check if the Contributor has already performed a peer review.
    // If not, add it to the list of pending peer reviews.
    List<AudioContributionEvent> audioContributionEventsPendingPeerReview = new ArrayList<>();
    for (AudioContributionEvent mostRecentAudioContributionEvent : mostRecentAudioContributionEvents) {
        AudioPeerReviewEvent audioPeerReviewEvent = audioPeerReviewEventDao.read(mostRecentAudioContributionEvent, contributor);
        if (audioPeerReviewEvent == null) {
            audioContributionEventsPendingPeerReview.add(mostRecentAudioContributionEvent);
        }
    }
    logger.info("audioContributionEventsPendingPeerReview.size(): " + audioContributionEventsPendingPeerReview.size());
    // Convert to JSON
    JSONArray audioContributionEventsJsonArray = new JSONArray();
    for (AudioContributionEvent audioContributionEvent : audioContributionEventsPendingPeerReview) {
        AudioContributionEventGson audioContributionEventGson = JpaToGsonConverter.getAudioContributionEventGson(audioContributionEvent);
        String json = new Gson().toJson(audioContributionEventGson);
        audioContributionEventsJsonArray.put(new JSONObject(json));
    }
    String jsonResponse = audioContributionEventsJsonArray.toString();
    logger.info("jsonResponse: " + jsonResponse);
    return jsonResponse;
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) JSONArray(org.json.JSONArray) Contributor(ai.elimu.model.contributor.Contributor) Gson(com.google.gson.Gson) AudioPeerReviewEventGson(ai.elimu.model.v2.gson.crowdsource.AudioPeerReviewEventGson) AudioContributionEventGson(ai.elimu.model.v2.gson.crowdsource.AudioContributionEventGson) AudioPeerReviewEvent(ai.elimu.model.contributor.AudioPeerReviewEvent) JSONObject(org.json.JSONObject) AudioContributionEventGson(ai.elimu.model.v2.gson.crowdsource.AudioContributionEventGson) AudioContributionEvent(ai.elimu.model.contributor.AudioContributionEvent) RequestMapping(org.springframework.web.bind.annotation.RequestMapping)

Example 2 with Contributor

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

the class AudioContributionsRestController method handleUploadWordRecordingRequest.

@RequestMapping(value = "/words", method = RequestMethod.POST)
public String handleUploadWordRecordingRequest(HttpServletRequest request, HttpServletResponse response, @RequestParam("file") MultipartFile multipartFile) {
    logger.info("handleUploadWordRecordingRequest");
    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;
    }
    String timeSpentMsAsString = request.getHeader("timeSpentMs");
    logger.info("timeSpentMsAsString: " + timeSpentMsAsString);
    if (StringUtils.isBlank(timeSpentMsAsString)) {
        jsonObject.put("result", "error");
        jsonObject.put("errorMessage", "Missing timeSpentMs");
        response.setStatus(HttpStatus.BAD_REQUEST.value());
        String jsonResponse = jsonObject.toString();
        logger.info("jsonResponse: " + jsonResponse);
        return jsonResponse;
    }
    Long timeSpentMs = Long.valueOf(timeSpentMsAsString);
    // 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;
    }
    // Expected format: "word_5.mp3"
    String originalFilename = multipartFile.getOriginalFilename();
    logger.info("originalFilename: " + originalFilename);
    AudioFormat audioFormat = CrowdsourceHelper.extractAudioFormatFromFilename(originalFilename);
    logger.info("audioFormat: " + audioFormat);
    Long wordIdExtractedFromFilename = CrowdsourceHelper.extractWordIdFromFilename(originalFilename);
    logger.info("wordIdExtractedFromFilename: " + wordIdExtractedFromFilename);
    Word word = wordDao.read(wordIdExtractedFromFilename);
    logger.info("word: " + word);
    if (word == null) {
        jsonObject.put("result", "error");
        jsonObject.put("errorMessage", "A Word with ID " + wordIdExtractedFromFilename + " was not found.");
        response.setStatus(HttpStatus.UNPROCESSABLE_ENTITY.value());
        String jsonResponse = jsonObject.toString();
        logger.info("jsonResponse: " + jsonResponse);
        return jsonResponse;
    }
    String contentType = multipartFile.getContentType();
    logger.info("contentType: " + contentType);
    try {
        byte[] bytes = multipartFile.getBytes();
        logger.info("bytes.length: " + bytes.length);
        // Store a backup of the original CSV file on the filesystem (in case it will be needed for debugging)
        // TODO
        // Convert from MultipartFile to File, and extract audio duration
        String tmpDir = System.getProperty("java.io.tmpdir");
        File tmpDirElimuAi = new File(tmpDir, "elimu-ai");
        tmpDirElimuAi.mkdir();
        File file = new File(tmpDirElimuAi, multipartFile.getOriginalFilename());
        logger.info("file: " + file);
        multipartFile.transferTo(file);
        Long durationMs = AudioMetadataExtractionHelper.getDurationInMilliseconds(file);
        logger.info("durationMs: " + durationMs);
        // Store the audio recording in the database
        Audio audio = new Audio();
        audio.setTimeLastUpdate(Calendar.getInstance());
        audio.setContentType(contentType);
        audio.setWord(word);
        audio.setTitle(word.getText().toLowerCase());
        audio.setTranscription(word.getText().toLowerCase());
        audio.setBytes(bytes);
        audio.setDurationMs(durationMs);
        audio.setAudioFormat(audioFormat);
        audioDao.create(audio);
        AudioContributionEvent audioContributionEvent = new AudioContributionEvent();
        audioContributionEvent.setContributor(contributor);
        audioContributionEvent.setTime(Calendar.getInstance());
        audioContributionEvent.setTimeSpentMs(timeSpentMs);
        audioContributionEvent.setPlatform(Platform.CROWDSOURCE_APP);
        audioContributionEvent.setAudio(audio);
        audioContributionEvent.setRevisionNumber(audio.getRevisionNumber());
        audioContributionEventDao.create(audioContributionEvent);
        String contentUrl = "http://" + EnvironmentContextLoaderListener.PROPERTIES.getProperty("content.language").toLowerCase() + ".elimu.ai/content/multimedia/audio/edit/" + audio.getId();
        DiscordHelper.sendChannelMessage("Audio created: " + contentUrl, "\"" + audio.getTranscription() + "\"", "Comment: \"" + audioContributionEvent.getComment() + "\"", null, null);
    } 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) JSONObject(org.json.JSONObject) Contributor(ai.elimu.model.contributor.Contributor) AudioContributionEvent(ai.elimu.model.contributor.AudioContributionEvent) AudioFormat(ai.elimu.model.v2.enums.content.AudioFormat) Audio(ai.elimu.model.content.multimedia.Audio) File(java.io.File) MultipartFile(org.springframework.web.multipart.MultipartFile) RequestMapping(org.springframework.web.bind.annotation.RequestMapping)

Example 3 with Contributor

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

the class StringToContributorConverter method convert.

/**
 * Convert Contributor id to Contributor entity
 */
public Contributor convert(String id) {
    if (StringUtils.isBlank(id)) {
        return null;
    } else {
        Long contributorId = Long.parseLong(id);
        Contributor contributor = contributorDao.read(contributorId);
        return contributor;
    }
}
Also used : Contributor(ai.elimu.model.contributor.Contributor)

Example 4 with Contributor

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

the class StoryBookPeerReviewEventCreateController method handleSubmit.

@RequestMapping(method = RequestMethod.POST)
public String handleSubmit(@RequestParam Long storyBookContributionEventId, @RequestParam Boolean approved, @RequestParam(required = false) String comment, HttpSession session) {
    logger.info("handleSubmit");
    Contributor contributor = (Contributor) session.getAttribute("contributor");
    logger.info("storyBookContributionEventId: " + storyBookContributionEventId);
    StoryBookContributionEvent storyBookContributionEvent = storyBookContributionEventDao.read(storyBookContributionEventId);
    logger.info("storyBookContributionEvent: " + storyBookContributionEvent);
    // Store the peer review event
    StoryBookPeerReviewEvent storyBookPeerReviewEvent = new StoryBookPeerReviewEvent();
    storyBookPeerReviewEvent.setContributor(contributor);
    storyBookPeerReviewEvent.setStoryBookContributionEvent(storyBookContributionEvent);
    storyBookPeerReviewEvent.setApproved(approved);
    storyBookPeerReviewEvent.setComment(StringUtils.abbreviate(comment, 1000));
    storyBookPeerReviewEvent.setTime(Calendar.getInstance());
    storyBookPeerReviewEvent.setPlatform(Platform.WEBAPP);
    storyBookPeerReviewEventDao.create(storyBookPeerReviewEvent);
    String contentUrl = "http://" + EnvironmentContextLoaderListener.PROPERTIES.getProperty("content.language").toLowerCase() + ".elimu.ai/content/storybook/edit/" + storyBookContributionEvent.getStoryBook().getId();
    String embedThumbnailUrl = null;
    if (storyBookContributionEvent.getStoryBook().getCoverImage() != null) {
        embedThumbnailUrl = "http://" + EnvironmentContextLoaderListener.PROPERTIES.getProperty("content.language").toLowerCase() + ".elimu.ai/image/" + storyBookContributionEvent.getStoryBook().getCoverImage().getId() + "_r" + storyBookContributionEvent.getStoryBook().getCoverImage().getRevisionNumber() + "." + storyBookContributionEvent.getStoryBook().getCoverImage().getImageFormat().toString().toLowerCase();
    }
    DiscordHelper.sendChannelMessage("Storybook peer-reviewed: " + contentUrl, "\"" + storyBookContributionEvent.getStoryBook().getTitle() + "\"", "Comment: \"" + storyBookPeerReviewEvent.getComment() + "\"", storyBookPeerReviewEvent.isApproved(), embedThumbnailUrl);
    // Update the storybook's peer review status
    int approvedCount = 0;
    int notApprovedCount = 0;
    for (StoryBookPeerReviewEvent peerReviewEvent : storyBookPeerReviewEventDao.readAll(storyBookContributionEvent)) {
        if (peerReviewEvent.isApproved()) {
            approvedCount++;
        } else {
            notApprovedCount++;
        }
    }
    logger.info("approvedCount: " + approvedCount);
    logger.info("notApprovedCount: " + notApprovedCount);
    StoryBook storyBook = storyBookContributionEvent.getStoryBook();
    if (approvedCount >= notApprovedCount) {
        storyBook.setPeerReviewStatus(PeerReviewStatus.APPROVED);
    } else {
        storyBook.setPeerReviewStatus(PeerReviewStatus.NOT_APPROVED);
    }
    storyBookDao.update(storyBook);
    return "redirect:/content/storybook/edit/" + storyBookContributionEvent.getStoryBook().getId() + "#contribution-events";
}
Also used : StoryBookContributionEvent(ai.elimu.model.contributor.StoryBookContributionEvent) StoryBook(ai.elimu.model.content.StoryBook) Contributor(ai.elimu.model.contributor.Contributor) StoryBookPeerReviewEvent(ai.elimu.model.contributor.StoryBookPeerReviewEvent) RequestMapping(org.springframework.web.bind.annotation.RequestMapping)

Example 5 with Contributor

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

the class CustomAuthenticationManager method authenticate.

@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
    logger.info("authenticate");
    logger.info("authentication.getName(): " + authentication.getName());
    Contributor contributor = (Contributor) authentication.getPrincipal();
    logger.info("contributor: " + contributor);
    logger.info("contributor.getRoles(): " + contributor.getRoles());
    for (Role role : contributor.getRoles()) {
        AUTHORITIES.add(new SimpleGrantedAuthority("ROLE_" + role.toString()));
    }
    return new UsernamePasswordAuthenticationToken(authentication.getName(), authentication.getCredentials(), AUTHORITIES);
}
Also used : Role(ai.elimu.model.enums.Role) SimpleGrantedAuthority(org.springframework.security.core.authority.SimpleGrantedAuthority) Contributor(ai.elimu.model.contributor.Contributor) UsernamePasswordAuthenticationToken(org.springframework.security.authentication.UsernamePasswordAuthenticationToken)

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