From c07950ad459f83d212e6e403be3a6a7c660efb88 Mon Sep 17 00:00:00 2001 From: Venkatesh Sangam Date: Wed, 3 Jul 2024 14:10:18 +0530 Subject: [PATCH 1/3] Removed Crowdsource --- .../AudioContributionsRestController.java | 264 ------------------ .../AudioPeerReviewsRestController.java | 242 ---------------- .../ContributorsRestControllerGoogle.java | 120 -------- .../ContributorsRestControllerWeb3.java | 121 -------- .../NumberPeerReviewsRestController.java | 221 --------------- .../WordContributionRestController.java | 192 ------------- .../WordPeerReviewsRestController.java | 225 --------------- .../number/NumberPeerReviewsController.java | 1 - .../AudioPeerReviewEventCreateController.java | 1 - .../word/WordPeerReviewsController.java | 1 - 10 files changed, 1388 deletions(-) delete mode 100644 src/main/java/ai/elimu/rest/v2/crowdsource/AudioContributionsRestController.java delete mode 100644 src/main/java/ai/elimu/rest/v2/crowdsource/AudioPeerReviewsRestController.java delete mode 100644 src/main/java/ai/elimu/rest/v2/crowdsource/ContributorsRestControllerGoogle.java delete mode 100644 src/main/java/ai/elimu/rest/v2/crowdsource/ContributorsRestControllerWeb3.java delete mode 100644 src/main/java/ai/elimu/rest/v2/crowdsource/NumberPeerReviewsRestController.java delete mode 100644 src/main/java/ai/elimu/rest/v2/crowdsource/WordContributionRestController.java delete mode 100644 src/main/java/ai/elimu/rest/v2/crowdsource/WordPeerReviewsRestController.java diff --git a/src/main/java/ai/elimu/rest/v2/crowdsource/AudioContributionsRestController.java b/src/main/java/ai/elimu/rest/v2/crowdsource/AudioContributionsRestController.java deleted file mode 100644 index 5736f2948..000000000 --- a/src/main/java/ai/elimu/rest/v2/crowdsource/AudioContributionsRestController.java +++ /dev/null @@ -1,264 +0,0 @@ -package ai.elimu.rest.v2.crowdsource; - -import ai.elimu.dao.AudioContributionEventDao; -import ai.elimu.dao.AudioDao; -import ai.elimu.dao.ContributorDao; -import ai.elimu.dao.WordDao; -import ai.elimu.model.content.Word; -import ai.elimu.model.content.multimedia.Audio; -import ai.elimu.model.contributor.AudioContributionEvent; -import ai.elimu.model.contributor.Contributor; -import ai.elimu.model.enums.Platform; -import ai.elimu.model.v2.enums.content.AudioFormat; -import ai.elimu.model.v2.gson.content.WordGson; -import ai.elimu.rest.v2.JpaToGsonConverter; -import ai.elimu.util.DiscordHelper; -import ai.elimu.util.audio.AudioMetadataExtractionHelper; -import ai.elimu.util.audio.CrowdsourceHelper; -import ai.elimu.web.context.EnvironmentContextLoaderListener; -import com.google.gson.Gson; -import java.io.File; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.HashMap; -import java.util.List; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import org.apache.commons.lang.StringUtils; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.json.JSONArray; -import org.json.JSONObject; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.multipart.MultipartFile; - -/** - * REST API for the Crowdsource application: https://github.com/elimu-ai/crowdsource - */ -@RestController -@RequestMapping(value = "/rest/v2/crowdsource/audio-contributions", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) -public class AudioContributionsRestController { - - private Logger logger = LogManager.getLogger(); - - @Autowired - private ContributorDao contributorDao; - - @Autowired - private WordDao wordDao; - - @Autowired - private AudioDao audioDao; - - @Autowired - private AudioContributionEventDao audioContributionEventDao; - - /** - * Get {@link Word}s pending {@link Audio} recording for the current {@link Contributor}. - */ - @RequestMapping(value = "/words", method = RequestMethod.GET) - public String getWordsPendingRecording( - HttpServletRequest request, - HttpServletResponse response - ) { - logger.info("getWordsPendingRecording"); - - 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; - } - - // Get the IDs of Words that have already been recorded by the Contributor - List audioContributionEvents = audioContributionEventDao.readAll(contributor); - logger.info("audioContributionEvents.size(): " + audioContributionEvents.size()); - HashMap idsOfRecordedWordsHashMap = new HashMap<>(); - for (AudioContributionEvent audioContributionEvent : audioContributionEvents) { - Audio audio = audioContributionEvent.getAudio(); - Word word = audio.getWord(); - if (word != null) { - idsOfRecordedWordsHashMap.put(word.getId(), null); - } - } - logger.info("idsOfRecordedWordsHashMap.size(): " + idsOfRecordedWordsHashMap.size()); - - // For each Word, check if the Contributor has already contributed a - // corresponding Audio recording. If not, add it to the list of pending recordings. - List wordsPendingAudioRecording = new ArrayList<>(); - for (Word word : wordDao.readAllOrderedByUsage()) { - if (!idsOfRecordedWordsHashMap.containsKey(word.getId())) { - wordsPendingAudioRecording.add(word); - } - } - logger.info("wordsPendingAudioRecording.size(): " + wordsPendingAudioRecording.size()); - - // Convert to JSON - JSONArray wordsJsonArray = new JSONArray(); - for (Word word : wordsPendingAudioRecording) { - WordGson wordGson = JpaToGsonConverter.getWordGson(word); - String json = new Gson().toJson(wordGson); - wordsJsonArray.put(new JSONObject(json)); - } - - String jsonResponse = wordsJsonArray.toString(); - logger.info("jsonResponse: " + jsonResponse); - return jsonResponse; - } - - @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 = "https://" + 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; - } -} diff --git a/src/main/java/ai/elimu/rest/v2/crowdsource/AudioPeerReviewsRestController.java b/src/main/java/ai/elimu/rest/v2/crowdsource/AudioPeerReviewsRestController.java deleted file mode 100644 index 027921fbd..000000000 --- a/src/main/java/ai/elimu/rest/v2/crowdsource/AudioPeerReviewsRestController.java +++ /dev/null @@ -1,242 +0,0 @@ -package ai.elimu.rest.v2.crowdsource; - -import ai.elimu.dao.ContributorDao; -import ai.elimu.dao.AudioContributionEventDao; -import ai.elimu.dao.AudioDao; -import ai.elimu.dao.AudioPeerReviewEventDao; -import ai.elimu.model.content.multimedia.Audio; -import ai.elimu.model.contributor.Contributor; -import ai.elimu.model.contributor.AudioContributionEvent; -import ai.elimu.model.contributor.AudioPeerReviewEvent; -import ai.elimu.model.enums.PeerReviewStatus; -import ai.elimu.model.enums.Platform; -import ai.elimu.model.v2.gson.crowdsource.AudioContributionEventGson; -import ai.elimu.model.v2.gson.crowdsource.AudioPeerReviewEventGson; -import ai.elimu.rest.v2.JpaToGsonConverter; -import ai.elimu.util.DiscordHelper; -import ai.elimu.web.content.peer_review.AudioPeerReviewEventCreateController; -import ai.elimu.web.context.EnvironmentContextLoaderListener; -import com.google.gson.Gson; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import org.apache.commons.lang.StringUtils; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.json.JSONArray; -import org.json.JSONObject; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; - -/** - * REST API for the Crowdsource application: https://github.com/elimu-ai/crowdsource - */ -@RestController -@RequestMapping(value = "/rest/v2/crowdsource/audio-peer-reviews", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) -public class AudioPeerReviewsRestController { - - private Logger logger = LogManager.getLogger(); - - @Autowired - private ContributorDao contributorDao; - - @Autowired - private AudioDao audioDao; - - @Autowired - private AudioContributionEventDao audioContributionEventDao; - - @Autowired - private AudioPeerReviewEventDao audioPeerReviewEventDao; - - /** - * 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 allAudioContributionEvents = audioContributionEventDao.readAll(); - logger.info("allAudioContributionEvents.size(): " + allAudioContributionEvents.size()); - - // Get the most recent AudioContributionEvent for each Audio - List mostRecentAudioContributionEvents = new ArrayList<>(); - HashMap 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 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; - } - - /** - * Note: The logic in this method is similar to the one used at {@link AudioPeerReviewEventCreateController#handleSubmit} - */ - @RequestMapping(value = "/words", method = RequestMethod.POST) - public String uploadAudioPeerReview( - HttpServletRequest request, - HttpServletResponse response, - @RequestBody String requestBody - ) { - logger.info("uploadAudioPeerReview"); - - 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; - } - - try { - // Convert from Gson (POJO) to JPA/Hibernate - logger.info("requestBody: " + requestBody); - AudioPeerReviewEventGson audioPeerReviewEventGson = new Gson().fromJson(requestBody, AudioPeerReviewEventGson.class); - logger.info("audioPeerReviewEventGson: " + audioPeerReviewEventGson); - AudioContributionEventGson audioContributionEventGson = audioPeerReviewEventGson.getAudioContributionEvent(); - logger.info("audioContributionEventGson: " + audioContributionEventGson); - Long audioContributionEventGsonId = audioContributionEventGson.getId(); - logger.info("audioContributionEventGsonId: " + audioContributionEventGsonId); - AudioContributionEvent audioContributionEvent = audioContributionEventDao.read(audioContributionEventGsonId); - logger.info("audioContributionEvent: " + audioContributionEvent); - - AudioPeerReviewEvent audioPeerReviewEvent = new AudioPeerReviewEvent(); - audioPeerReviewEvent.setContributor(contributor); - audioPeerReviewEvent.setAudioContributionEvent(audioContributionEvent); - audioPeerReviewEvent.setApproved(audioPeerReviewEventGson.isApproved()); - audioPeerReviewEvent.setComment(StringUtils.abbreviate(audioPeerReviewEventGson.getComment(), 1000)); - audioPeerReviewEvent.setTime(audioPeerReviewEventGson.getTime()); - audioPeerReviewEvent.setPlatform(Platform.CROWDSOURCE_APP); - audioPeerReviewEventDao.create(audioPeerReviewEvent); - - String contentUrl = "https://" + EnvironmentContextLoaderListener.PROPERTIES.getProperty("content.language").toLowerCase() + ".elimu.ai/content/multimedia/audio/edit/" + audioContributionEvent.getAudio().getId(); - DiscordHelper.sendChannelMessage( - "Audio peer-reviewed: " + contentUrl, - "\"" + audioContributionEvent.getAudio().getTranscription() + "\"", - "Comment: \"" + audioPeerReviewEvent.getComment() + "\"", - audioPeerReviewEvent.isApproved(), - null - ); - - // Update the audio's peer review status - int approvedCount = 0; - int notApprovedCount = 0; - for (AudioPeerReviewEvent peerReviewEvent : audioPeerReviewEventDao.readAll(audioContributionEvent)) { - if (peerReviewEvent.isApproved()) { - approvedCount++; - } else { - notApprovedCount++; - } - } - logger.info("approvedCount: " + approvedCount); - logger.info("notApprovedCount: " + notApprovedCount); - Audio audio = audioContributionEvent.getAudio(); - if (approvedCount >= notApprovedCount) { - audio.setPeerReviewStatus(PeerReviewStatus.APPROVED); - } else { - audio.setPeerReviewStatus(PeerReviewStatus.NOT_APPROVED); - } - audioDao.update(audio); - } 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; - } -} diff --git a/src/main/java/ai/elimu/rest/v2/crowdsource/ContributorsRestControllerGoogle.java b/src/main/java/ai/elimu/rest/v2/crowdsource/ContributorsRestControllerGoogle.java deleted file mode 100644 index efd0ccd8f..000000000 --- a/src/main/java/ai/elimu/rest/v2/crowdsource/ContributorsRestControllerGoogle.java +++ /dev/null @@ -1,120 +0,0 @@ -package ai.elimu.rest.v2.crowdsource; - -import ai.elimu.dao.ContributorDao; -import ai.elimu.model.contributor.Contributor; -import ai.elimu.model.enums.Role; -import ai.elimu.util.DiscordHelper; -import ai.elimu.web.context.EnvironmentContextLoaderListener; -import java.util.Arrays; -import java.util.Calendar; -import java.util.HashSet; -import javax.servlet.http.HttpServletResponse; -import org.apache.commons.lang.StringUtils; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.json.JSONObject; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; - -/** - * REST API for the Crowdsource application: https://github.com/elimu-ai/crowdsource - *

- * - * Stores a {@link Contributor} in the database. - *

- * - * Note that authentication for the same Google accounts are done in the - * {@link SignOnControllerGoogle}. - */ -@RestController -@RequestMapping(value = "/rest/v2/crowdsource/contributors", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) -public class ContributorsRestControllerGoogle { - - private Logger logger = LogManager.getLogger(); - - @Autowired - private ContributorDao contributorDao; - - @RequestMapping(method = RequestMethod.POST) - public String handleGetRequest( - @RequestBody String requestBody, - HttpServletResponse response - ) { - logger.info("handlePostRequest"); - - logger.info("requestBody: " + requestBody); - - JSONObject contributorJSONObject = new JSONObject(requestBody); - logger.info("contributorJSONObject: " + contributorJSONObject); - - String providerIdGoogle = contributorJSONObject.getString("providerIdGoogle"); - String email = contributorJSONObject.getString("email"); - String firstName = contributorJSONObject.getString("firstName"); - String lastName = contributorJSONObject.getString("lastName"); - String imageUrl = contributorJSONObject.getString("imageUrl"); - - JSONObject jsonObject = new JSONObject(); - - // Look for existing Contributor with matching e-mail address - Contributor existingContributor = contributorDao.read(email); - logger.info("existingContributor: " + existingContributor); - if (existingContributor == null) { - // Store the Contributor in the database - Contributor contributor = new Contributor(); - contributor.setRegistrationTime(Calendar.getInstance()); - contributor.setProviderIdGoogle(providerIdGoogle); - contributor.setEmail(email); - contributor.setFirstName(firstName); - contributor.setLastName(lastName); - contributor.setImageUrl(imageUrl); - contributor.setRoles(new HashSet<>(Arrays.asList(Role.CONTRIBUTOR))); - contributorDao.create(contributor); - - String contentUrl = "https://" + EnvironmentContextLoaderListener.PROPERTIES.getProperty("content.language").toLowerCase() + ".elimu.ai/content/contributor/" + contributor.getId(); - String embedThumbnailUrl = null; - if (StringUtils.isNotBlank(contributor.getImageUrl())) { - embedThumbnailUrl = contributor.getImageUrl(); - } - DiscordHelper.sendChannelMessage( - "Contributor joined via the Crowdsource app: " + contentUrl, - contributor.getFirstName() + " " + contributor.getLastName(), - null, - null, - embedThumbnailUrl - ); - - jsonObject.put("result", "success"); - jsonObject.put("successMessage", "The Contributor was stored in the database"); - } else { - // Return error message saying that the Contributor has already been created - logger.warn("The Contributor has already been stored in the database"); - - // Update existing contributor with latest values fetched from provider - if (StringUtils.isNotBlank(providerIdGoogle)) { - existingContributor.setProviderIdGoogle(providerIdGoogle); - } - if (StringUtils.isNotBlank(imageUrl)) { - existingContributor.setImageUrl(imageUrl); - } - if (StringUtils.isNotBlank(firstName)) { - existingContributor.setFirstName(firstName); - } - if (StringUtils.isNotBlank(lastName)) { - existingContributor.setLastName(lastName); - } - contributorDao.update(existingContributor); - - jsonObject.put("result", "error"); - jsonObject.put("errorMessage", "The Contributor has already been stored in the database"); -// response.setStatus(HttpStatus.CONFLICT.value()); - } - - String jsonResponse = jsonObject.toString(); - logger.info("jsonResponse: " + jsonResponse); - return jsonResponse; - } -} diff --git a/src/main/java/ai/elimu/rest/v2/crowdsource/ContributorsRestControllerWeb3.java b/src/main/java/ai/elimu/rest/v2/crowdsource/ContributorsRestControllerWeb3.java deleted file mode 100644 index e4fa61040..000000000 --- a/src/main/java/ai/elimu/rest/v2/crowdsource/ContributorsRestControllerWeb3.java +++ /dev/null @@ -1,121 +0,0 @@ -package ai.elimu.rest.v2.crowdsource; - -import ai.elimu.dao.ContributorDao; -import ai.elimu.model.contributor.Contributor; -import ai.elimu.model.enums.Role; -import ai.elimu.util.Web3Helper; -import java.util.Arrays; -import java.util.Calendar; -import java.util.HashSet; -import javax.servlet.http.HttpServletResponse; -import org.apache.commons.lang.StringUtils; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.json.JSONObject; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; - -/** - * REST API for the Crowdsource application: https://github.com/elimu-ai/crowdsource - *

- * - * Stores a {@link Contributor} in the database. - *

- * - * Note that authentication for the same Web3 accounts are done in the - * {@link SignOnControllerWeb3}. - */ -@RestController -@RequestMapping(value = "/rest/v2/crowdsource/contributors/web3", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) -public class ContributorsRestControllerWeb3 { - - /** - * Must match the signature message used in the Crowdsource application. - */ - private static final String SIGNATURE_MESSAGE = "I verify ownership of this account 👍"; - - private Logger logger = LogManager.getLogger(); - - @Autowired - private ContributorDao contributorDao; - - @RequestMapping(method = RequestMethod.POST) - public String handleGetRequest( - @RequestBody String requestBody, - HttpServletResponse response - ) { - logger.info("handlePostRequest"); - - logger.info("requestBody: " + requestBody); - - JSONObject contributorJSONObject = new JSONObject(requestBody); - logger.info("contributorJSONObject: " + contributorJSONObject); - - JSONObject jsonObject = new JSONObject(); - - String providerIdWeb3 = contributorJSONObject.getString("providerIdWeb3"); - logger.info("providerIdWeb3: " + providerIdWeb3); - if (StringUtils.isBlank(providerIdWeb3)) { - jsonObject.put("result", "error"); - jsonObject.put("errorMessage", "Missing providerIdWeb3"); - response.setStatus(HttpStatus.BAD_REQUEST.value()); - - String jsonResponse = jsonObject.toString(); - logger.info("jsonResponse: " + jsonResponse); - return jsonResponse; - } - providerIdWeb3 = providerIdWeb3.toLowerCase(); - String providerIdWeb3Signature = contributorJSONObject.getString("providerIdWeb3Signature"); - logger.info("providerIdWeb3Signature: " + providerIdWeb3Signature); - if (StringUtils.isBlank(providerIdWeb3Signature)) { - jsonObject.put("result", "error"); - jsonObject.put("errorMessage", "Missing providerIdWeb3Signature"); - response.setStatus(HttpStatus.BAD_REQUEST.value()); - - String jsonResponse = jsonObject.toString(); - logger.info("jsonResponse: " + jsonResponse); - return jsonResponse; - } - - // Check if the signature is valid - if (!Web3Helper.isSignatureValid(providerIdWeb3, providerIdWeb3Signature, SIGNATURE_MESSAGE)) { - jsonObject.put("result", "error"); - jsonObject.put("errorMessage", "Invalid signature"); - response.setStatus(HttpStatus.BAD_REQUEST.value()); - - String jsonResponse = jsonObject.toString(); - logger.info("jsonResponse: " + jsonResponse); - return jsonResponse; - } - logger.info("Valid signature ✍️"); - - // Check if a Contributor with this ETH address already exists in the database - Contributor existingContributor = contributorDao.readByProviderIdWeb3(providerIdWeb3); - logger.info("existingContributor: " + existingContributor); - if (existingContributor == null) { - // Store new Contributor in database - Contributor contributor = new Contributor(); - contributor.setProviderIdWeb3(providerIdWeb3); - contributor.setEmail(providerIdWeb3 + "@ethmail.cc"); - contributor.setRegistrationTime(Calendar.getInstance()); - contributor.setRoles(new HashSet<>(Arrays.asList(Role.CONTRIBUTOR))); - contributorDao.create(contributor); - logger.info("Contributor " + contributor.getProviderIdWeb3() + " was created in the database"); - - jsonObject.put("result", "success"); - jsonObject.put("successMessage", "The Contributor was stored in the database"); - } else { - jsonObject.put("result", "warning"); - jsonObject.put("warningMessage", "The Contributor has already been stored in the database"); - } - - String jsonResponse = jsonObject.toString(); - logger.info("jsonResponse: " + jsonResponse); - return jsonResponse; - } -} diff --git a/src/main/java/ai/elimu/rest/v2/crowdsource/NumberPeerReviewsRestController.java b/src/main/java/ai/elimu/rest/v2/crowdsource/NumberPeerReviewsRestController.java deleted file mode 100644 index 49957fead..000000000 --- a/src/main/java/ai/elimu/rest/v2/crowdsource/NumberPeerReviewsRestController.java +++ /dev/null @@ -1,221 +0,0 @@ -package ai.elimu.rest.v2.crowdsource; - -import ai.elimu.dao.ContributorDao; -import ai.elimu.dao.NumberContributionEventDao; -import ai.elimu.dao.NumberDao; -import ai.elimu.dao.NumberPeerReviewEventDao; -import ai.elimu.model.content.Number; -import ai.elimu.model.contributor.*; -import ai.elimu.model.enums.PeerReviewStatus; -import ai.elimu.model.enums.Platform; -import ai.elimu.model.v2.gson.crowdsource.NumberContributionEventGson; -import ai.elimu.model.v2.gson.crowdsource.NumberPeerReviewEventGson; -import ai.elimu.rest.v2.JpaToGsonConverter; -import ai.elimu.util.DiscordHelper; -import ai.elimu.web.content.number.NumberPeerReviewsController; -import ai.elimu.web.context.EnvironmentContextLoaderListener; -import com.google.gson.Gson; -import org.apache.commons.lang.StringUtils; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.json.JSONArray; -import org.json.JSONObject; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.util.Calendar; -import java.util.List; - -/** - * REST API for the Crowdsource application: https://github.com/elimu-ai/crowdsource - *

- *

- * This controller has similar functionality as the {@link NumberPeerReviewsController}. - */ -@RestController -@RequestMapping(value = "/rest/v2/crowdsource/number-peer-reviews", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) -public class NumberPeerReviewsRestController { - - private Logger logger = LogManager.getLogger(); - - @Autowired - private NumberContributionEventDao numberContributionEventDao; - - @Autowired - private ContributorDao contributorDao; - - @Autowired - private NumberPeerReviewEventDao numberPeerReviewEventDao; - - @Autowired - private NumberDao numberDao; - - /** - * Get {@link NumberContributionEvent}s pending a {@link NumberPeerReviewEvent} for the current {@link Contributor}. - */ - @RequestMapping(method = RequestMethod.GET) - public String handleGetRequest(HttpServletRequest request, - HttpServletResponse response) { - logger.info("handleGetRequest"); - - // 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; - } - - // Get the most recent NumberContributionEvent for each Number, including those made by the current Contributor - List 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. - JSONArray numberContributionEventsPendingPeerReviewJsonArray = new JSONArray(); - 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 numberPeerReviewEvents = numberPeerReviewEventDao. - readAll(mostRecentNumberContributionEvent, contributor); - if (numberPeerReviewEvents.isEmpty()) { - NumberContributionEventGson mostRecentNumberContributionEventGson = JpaToGsonConverter. - getNumberContributionEventGson(mostRecentNumberContributionEvent); - - String json = new Gson().toJson(mostRecentNumberContributionEventGson); - numberContributionEventsPendingPeerReviewJsonArray.put(new JSONObject(json)); - } - } - logger.info("numberContributionEventsPendingPeerReviewJsonArray.size(): " + - numberContributionEventsPendingPeerReviewJsonArray.length()); - - String jsonResponse = numberContributionEventsPendingPeerReviewJsonArray.toString(); - logger.info("jsonResponse: " + jsonResponse); - return jsonResponse; - } - - @RequestMapping(method = RequestMethod.POST) - public String handlePostRequest(HttpServletRequest request, - HttpServletResponse response, - @RequestBody String requestBody) { - logger.info("handlePostRequest"); - - // 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; - } - - try { - // Convert from Gson (POJO) to JPA/Hibernate - logger.info("requestBody: " + requestBody); - NumberPeerReviewEventGson numberPeerReviewEventGson = new Gson().fromJson(requestBody, NumberPeerReviewEventGson.class); - NumberContributionEvent numberContributionEvent = numberContributionEventDao.read(numberPeerReviewEventGson - .getNumberContributionEvent().getId()); - - NumberPeerReviewEvent numberPeerReviewEvent = new NumberPeerReviewEvent(); - numberPeerReviewEvent.setContributor(contributor); - numberPeerReviewEvent.setNumberContributionEvent(numberContributionEvent); - numberPeerReviewEvent.setApproved(numberPeerReviewEventGson.isApproved()); - numberPeerReviewEvent.setComment(numberPeerReviewEventGson.getComment()); - numberPeerReviewEvent.setTime(Calendar.getInstance()); - numberPeerReviewEvent.setPlatform(Platform.CROWDSOURCE_APP); - numberPeerReviewEventDao.create(numberPeerReviewEvent); - - String contentUrl = "https://" + 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); - - } 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); - response.setStatus(HttpStatus.CREATED.value()); - return jsonResponse; - } -} diff --git a/src/main/java/ai/elimu/rest/v2/crowdsource/WordContributionRestController.java b/src/main/java/ai/elimu/rest/v2/crowdsource/WordContributionRestController.java deleted file mode 100644 index bff3013a4..000000000 --- a/src/main/java/ai/elimu/rest/v2/crowdsource/WordContributionRestController.java +++ /dev/null @@ -1,192 +0,0 @@ -package ai.elimu.rest.v2.crowdsource; -import ai.elimu.dao.*; -import ai.elimu.model.content.LetterSoundCorrespondence; -import ai.elimu.model.content.Word; -import ai.elimu.model.contributor.Contributor; -import ai.elimu.model.contributor.WordContributionEvent; -import ai.elimu.model.enums.Platform; -import ai.elimu.model.v2.gson.content.LetterSoundGson; -import ai.elimu.model.v2.gson.content.WordGson; -import ai.elimu.model.v2.gson.crowdsource.WordContributionEventGson; -import ai.elimu.rest.v2.JpaToGsonConverter; -import ai.elimu.util.DiscordHelper; -import ai.elimu.web.context.EnvironmentContextLoaderListener; -import com.google.gson.Gson; -import org.apache.commons.lang.StringUtils; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.json.JSONObject; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.util.ArrayList; -import java.util.List; -import org.json.JSONArray; - -/** - * REST API for the Crowdsource application: https://github.com/elimu-ai/crowdsource - *

- * - * This controller is responsible for handling the creation of words contributed through the Crowdsource app - */ -@RestController -@RequestMapping(value = "/rest/v2/crowdsource/word-contributions", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) -public class WordContributionRestController { - - private final Logger logger = LogManager.getLogger(); - - @Autowired - private WordDao wordDao; - - @Autowired - private WordContributionEventDao wordContributionEventDao; - - @Autowired - private ContributorDao contributorDao; - - @Autowired - private LetterSoundDao letterSoundDao; - - /** - * Returns a list of {@link LetterSoundCorrespondence}s that will be used to construct a {@link Word}. - */ - @RequestMapping(value = "/letter-sound-correspondences", method = RequestMethod.GET) - public String getLetterSoundCorrespondences(HttpServletRequest request, HttpServletResponse response) { - logger.info("getLetterSoundCorrespondences"); - - JSONArray letterSoundCorrespondencesJsonArray = new JSONArray(); - for (LetterSoundCorrespondence letterSoundCorrespondence : letterSoundDao.readAllOrderedByUsage()) { - LetterSoundGson letterSoundGson = - JpaToGsonConverter.getLetterSoundGson(letterSoundCorrespondence); - String json = new Gson().toJson(letterSoundGson); - letterSoundCorrespondencesJsonArray.put(new JSONObject(json)); - } - - String jsonResponse = letterSoundCorrespondencesJsonArray.toString(); - logger.info("jsonResponse: " + jsonResponse); - return jsonResponse; - } - - /** - * 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.readByTextAndType(wordGson.getText().toLowerCase(), wordGson.getWordType()); - 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 letterSoundCorrespondencesGsons = wordGson.getLetterSounds(); - List letterSoundCorrespondences = new ArrayList<>(); - for (LetterSoundGson letterSoundGson : letterSoundCorrespondencesGsons) { - LetterSoundCorrespondence letterSoundCorrespondence = - letterSoundDao.read(letterSoundGson.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 = "https://" + 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; - } -} diff --git a/src/main/java/ai/elimu/rest/v2/crowdsource/WordPeerReviewsRestController.java b/src/main/java/ai/elimu/rest/v2/crowdsource/WordPeerReviewsRestController.java deleted file mode 100644 index c465a36af..000000000 --- a/src/main/java/ai/elimu/rest/v2/crowdsource/WordPeerReviewsRestController.java +++ /dev/null @@ -1,225 +0,0 @@ -package ai.elimu.rest.v2.crowdsource; - -import ai.elimu.dao.ContributorDao; -import ai.elimu.dao.WordContributionEventDao; -import ai.elimu.dao.WordDao; -import ai.elimu.dao.WordPeerReviewEventDao; -import ai.elimu.model.content.Word; -import ai.elimu.model.contributor.*; -import ai.elimu.model.enums.PeerReviewStatus; -import ai.elimu.model.enums.Platform; -import ai.elimu.model.v2.gson.crowdsource.WordContributionEventGson; -import ai.elimu.model.v2.gson.crowdsource.WordPeerReviewEventGson; -import ai.elimu.rest.v2.JpaToGsonConverter; -import ai.elimu.util.DiscordHelper; -import ai.elimu.web.content.word.WordPeerReviewsController; -import ai.elimu.web.context.EnvironmentContextLoaderListener; -import com.google.gson.Gson; -import org.apache.commons.lang.StringUtils; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.json.JSONArray; -import org.json.JSONObject; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RestController; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.util.Calendar; -import java.util.List; - -/** - * REST API for the Crowdsource application: https://github.com/elimu-ai/crowdsource - *

- *

- * This controller has similar functionality as the {@link WordPeerReviewsController}. - */ -@RestController -@RequestMapping(value = "/rest/v2/crowdsource/word-peer-reviews", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) -public class WordPeerReviewsRestController { - - private Logger logger = LogManager.getLogger(); - - @Autowired - private WordContributionEventDao wordContributionEventDao; - - @Autowired - private ContributorDao contributorDao; - - @Autowired - private WordPeerReviewEventDao wordPeerReviewEventDao; - - @Autowired - private WordDao wordDao; - - /** - * Get {@link WordContributionEvent}s pending a {@link WordPeerReviewEvent} for the current {@link Contributor}. - *

- * Note: Currently The list of Emojis are not delivered in this method compared to the handleGetRequest method in - * {@link WordPeerReviewsController} - */ - @RequestMapping(method = RequestMethod.GET) - public String handleGetRequest(HttpServletRequest request, - HttpServletResponse response) { - logger.info("handleGetRequest"); - - - // 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; - } - - // Get the most recent WordContributionEvent for each Word, including those made by the current Contributor - List mostRecentWordContributionEvents = wordContributionEventDao.readMostRecentPerWord(); - logger.info("mostRecentWordContributionEvents.size(): " + mostRecentWordContributionEvents.size()); - - // For each WordContributionEvent, check if the Contributor has already performed a peer-review. - // If not, add it to the list of pending peer reviews. - JSONArray wordContributionEventsPendingPeerReviewJsonArray = new JSONArray(); - for (WordContributionEvent mostRecentWordContributionEvent : mostRecentWordContributionEvents) { - // Ignore WordContributionEvents made by the current Contributor - if (mostRecentWordContributionEvent.getContributor().getId().equals(contributor.getId())) { - continue; - } - - // Check if the current Contributor has already peer-reviewed this Word contribution - List wordPeerReviewEvents = wordPeerReviewEventDao. - readAll(mostRecentWordContributionEvent, contributor); - if (wordPeerReviewEvents.isEmpty()) { - WordContributionEventGson mostRecentWordContributionEventGson = JpaToGsonConverter. - getWordContributionEventGson(mostRecentWordContributionEvent); - - String json = new Gson().toJson(mostRecentWordContributionEventGson); - wordContributionEventsPendingPeerReviewJsonArray.put(new JSONObject(json)); - } - } - logger.info("wordContributionEventsPendingPeerReviewJsonArray.size(): " + - wordContributionEventsPendingPeerReviewJsonArray.length()); - - String jsonResponse = wordContributionEventsPendingPeerReviewJsonArray.toString(); - logger.info("jsonResponse: " + jsonResponse); - return jsonResponse; - } - - @RequestMapping(method = RequestMethod.POST) - public String handlePostRequest(HttpServletRequest request, - HttpServletResponse response, - @RequestBody String requestBody) { - logger.info("handlePostRequest"); - - // 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; - } - - try { - // Convert from Gson (POJO) to JPA/Hibernate - logger.info("requestBody: " + requestBody); - WordPeerReviewEventGson wordPeerReviewEventGson = new Gson().fromJson(requestBody, WordPeerReviewEventGson.class); - WordContributionEvent wordContributionEvent = wordContributionEventDao.read(wordPeerReviewEventGson - .getWordContributionEvent().getId()); - - WordPeerReviewEvent wordPeerReviewEvent = new WordPeerReviewEvent(); - wordPeerReviewEvent.setContributor(contributor); - wordPeerReviewEvent.setWordContributionEvent(wordContributionEvent); - wordPeerReviewEvent.setApproved(wordPeerReviewEventGson.isApproved()); - wordPeerReviewEvent.setComment(wordPeerReviewEventGson.getComment()); - wordPeerReviewEvent.setTime(Calendar.getInstance()); - wordPeerReviewEvent.setPlatform(Platform.CROWDSOURCE_APP); - wordPeerReviewEventDao.create(wordPeerReviewEvent); - - String contentUrl = "https://" + EnvironmentContextLoaderListener.PROPERTIES.getProperty("content.language").toLowerCase() + ".elimu.ai/content/word/edit/" + wordContributionEvent.getWord().getId(); - DiscordHelper.sendChannelMessage( - "Word peer-reviewed: " + contentUrl, - "\"" + wordContributionEvent.getWord().getText() + "\"", - "Comment: \"" + wordPeerReviewEvent.getComment() + "\"", - wordPeerReviewEvent.isApproved(), - null - ); - - // Update the word's peer review status - int approvedCount = 0; - int notApprovedCount = 0; - for (WordPeerReviewEvent peerReviewEvent : wordPeerReviewEventDao.readAll(wordContributionEvent)) { - if (peerReviewEvent.isApproved()) { - approvedCount++; - } else { - notApprovedCount++; - } - } - logger.info("approvedCount: " + approvedCount); - logger.info("notApprovedCount: " + notApprovedCount); - Word word = wordContributionEvent.getWord(); - if (approvedCount >= notApprovedCount) { - word.setPeerReviewStatus(PeerReviewStatus.APPROVED); - } else { - word.setPeerReviewStatus(PeerReviewStatus.NOT_APPROVED); - } - wordDao.update(word); - - } 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); - response.setStatus(HttpStatus.CREATED.value()); - return jsonResponse; - } -} diff --git a/src/main/java/ai/elimu/web/content/number/NumberPeerReviewsController.java b/src/main/java/ai/elimu/web/content/number/NumberPeerReviewsController.java index 2a7772030..eb84eb6d4 100644 --- a/src/main/java/ai/elimu/web/content/number/NumberPeerReviewsController.java +++ b/src/main/java/ai/elimu/web/content/number/NumberPeerReviewsController.java @@ -7,7 +7,6 @@ import ai.elimu.model.contributor.Contributor; import ai.elimu.model.contributor.NumberContributionEvent; import ai.elimu.model.contributor.NumberPeerReviewEvent; -import ai.elimu.rest.v2.crowdsource.NumberPeerReviewsRestController; import java.util.ArrayList; import java.util.List; import javax.servlet.http.HttpSession; diff --git a/src/main/java/ai/elimu/web/content/peer_review/AudioPeerReviewEventCreateController.java b/src/main/java/ai/elimu/web/content/peer_review/AudioPeerReviewEventCreateController.java index aa51e5200..ff2452ce7 100644 --- a/src/main/java/ai/elimu/web/content/peer_review/AudioPeerReviewEventCreateController.java +++ b/src/main/java/ai/elimu/web/content/peer_review/AudioPeerReviewEventCreateController.java @@ -10,7 +10,6 @@ import ai.elimu.model.contributor.AudioPeerReviewEvent; import ai.elimu.model.enums.PeerReviewStatus; import ai.elimu.model.enums.Platform; -import ai.elimu.rest.v2.crowdsource.AudioPeerReviewsRestController; import ai.elimu.util.DiscordHelper; import ai.elimu.web.context.EnvironmentContextLoaderListener; import java.util.Calendar; diff --git a/src/main/java/ai/elimu/web/content/word/WordPeerReviewsController.java b/src/main/java/ai/elimu/web/content/word/WordPeerReviewsController.java index acf6e8527..582dee750 100644 --- a/src/main/java/ai/elimu/web/content/word/WordPeerReviewsController.java +++ b/src/main/java/ai/elimu/web/content/word/WordPeerReviewsController.java @@ -9,7 +9,6 @@ import ai.elimu.model.contributor.Contributor; import ai.elimu.model.contributor.WordContributionEvent; import ai.elimu.model.contributor.WordPeerReviewEvent; -import ai.elimu.rest.v2.crowdsource.WordPeerReviewsRestController; import java.util.ArrayList; import java.util.HashMap; import java.util.List; From 8bafa6778a3e5cae89de5630d0e6dd8dc8c8979f Mon Sep 17 00:00:00 2001 From: Venkatesh Sangam <137500548+venkatesh2k3@users.noreply.github.com> Date: Wed, 10 Jul 2024 23:00:29 +0530 Subject: [PATCH 2/3] Update layout.jsp --- src/main/webapp/WEB-INF/jsp/content/layout.jsp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/webapp/WEB-INF/jsp/content/layout.jsp b/src/main/webapp/WEB-INF/jsp/content/layout.jsp index 6c7c36026..e558fc821 100644 --- a/src/main/webapp/WEB-INF/jsp/content/layout.jsp +++ b/src/main/webapp/WEB-INF/jsp/content/layout.jsp @@ -155,9 +155,6 @@ ${fn:substring(contributor.providerIdWeb3, 0, 6)}...${fn:substring(contributor.providerIdWeb3, 38, 42)} - - <${contributor.email}> -