Skip to content

Commit

Permalink
Merge pull request #728 from FEMR/temr-dev
Browse files Browse the repository at this point in the history
PatientEncounter Language automatically set, Refactoring of code for test, TranslationService tests, server changed to POST request & more!
  • Loading branch information
mhayes2772 authored May 24, 2024
2 parents 1c8a7f5 + 2fabac1 commit d267cd2
Show file tree
Hide file tree
Showing 10 changed files with 405 additions and 254 deletions.
13 changes: 10 additions & 3 deletions app/femr/business/services/system/EncounterService.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,15 @@
*/
package femr.business.services.system;

import femr.business.services.core.ISessionService;
import femr.common.dtos.CurrentUser;
import io.ebean.ExpressionList;
import io.ebean.Query;
import com.google.inject.Inject;
import com.google.inject.name.Named;
import femr.business.helpers.QueryProvider;
import femr.business.services.core.IEncounterService;
import femr.business.services.core.ISessionService;
import femr.common.IItemModelMapper;
import femr.common.dtos.ServiceResponse;
import femr.common.models.*;
Expand All @@ -46,6 +49,7 @@ public class EncounterService implements IEncounterService {
private final IRepository<IChiefComplaint> chiefComplaintRepository;
private final IPatientRepository patientRepository;
private final IEncounterRepository patientEncounterRepository;
private final ISessionService sessionService;
private final IRepository<IPatientEncounterTabField> patientEncounterTabFieldRepository;
private final IRepository<ITabField> tabFieldRepository;
private final IUserRepository userRepository;
Expand All @@ -56,6 +60,7 @@ public class EncounterService implements IEncounterService {
public EncounterService(IRepository<IChiefComplaint> chiefComplaintRepository,
IPatientRepository patientRepository,
IEncounterRepository patientEncounterRepository,
ISessionService sessionService,
IRepository<IPatientEncounterTabField> patientEncounterTabFieldRepository,
IRepository<ITabField> tabFieldRepository,
IUserRepository userRepository,
Expand All @@ -65,6 +70,7 @@ public EncounterService(IRepository<IChiefComplaint> chiefComplaintRepository,
this.chiefComplaintRepository = chiefComplaintRepository;
this.patientRepository = patientRepository;
this.patientEncounterRepository = patientEncounterRepository;
this.sessionService = sessionService;
this.patientEncounterTabFieldRepository = patientEncounterTabFieldRepository;
this.tabFieldRepository = tabFieldRepository;
this.userRepository = userRepository;
Expand All @@ -77,7 +83,7 @@ public EncounterService(IRepository<IChiefComplaint> chiefComplaintRepository,
*/
@Override
public ServiceResponse<PatientEncounterItem> createPatientEncounter(int patientId, int userId, Integer tripId, String ageClassification, List<String> chiefComplaints) {

System.out.println("Create Patient Encounter");
ServiceResponse<PatientEncounterItem> response = new ServiceResponse<>();

try {
Expand All @@ -98,8 +104,9 @@ public ServiceResponse<PatientEncounterItem> createPatientEncounter(int patientI
if (patientAgeClassification != null)
patientAgeClassificationId = patientAgeClassification.getId();

IPatientEncounter newPatientEncounter = patientEncounterRepository.createPatientEncounter(patientId, dateUtils.getCurrentDateTime(), nurseUser.getId(), patientAgeClassificationId, tripId);

CurrentUser currentUserSession = sessionService.retrieveCurrentUserSession();
String languageCode = currentUserSession.getLanguageCode();
IPatientEncounter newPatientEncounter = patientEncounterRepository.createPatientEncounter(patientId, dateUtils.getCurrentDateTime(), nurseUser.getId(), patientAgeClassificationId, tripId, languageCode);
List<IChiefComplaint> chiefComplaintBeans = new ArrayList<>();
Integer chiefComplaintSortOrder = 0;
for (String cc : chiefComplaints) {
Expand Down
2 changes: 1 addition & 1 deletion app/femr/data/daos/core/IEncounterRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public interface IEncounterRepository {
* @param tripId id of the trip, may be null
* @return the new patient encounter or null if an error happens
*/
IPatientEncounter createPatientEncounter(int patientID, DateTime date, int userId, Integer patientAgeClassificationId, Integer tripId);
IPatientEncounter createPatientEncounter(int patientID, DateTime date, int userId, Integer patientAgeClassificationId, Integer tripId, String languageCode);

/**
* Deletes a patient's encounter. this is a soft delete
Expand Down
4 changes: 2 additions & 2 deletions app/femr/data/daos/system/EncounterRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public EncounterRepository(Provider<IMissionTrip> missionTripProvider,
* {@inheritDoc}
*/
@Override
public IPatientEncounter createPatientEncounter(int patientID, DateTime date, int userId, Integer patientAgeClassificationId, Integer tripId){
public IPatientEncounter createPatientEncounter(int patientID, DateTime date, int userId, Integer patientAgeClassificationId, Integer tripId, String languageCode){

IPatientEncounter patientEncounter = patientEncounterProvider.get();

Expand All @@ -57,7 +57,7 @@ public IPatientEncounter createPatientEncounter(int patientID, DateTime date, in
patientEncounter.setPatientAgeClassification(Ebean.getReference(patientAgeClassificationProvider.get().getClass(), patientAgeClassificationId));
if (tripId != null)
patientEncounter.setMissionTrip(Ebean.getReference(missionTripProvider.get().getClass(), tripId));

patientEncounter.setLanguageCode(languageCode);
Ebean.save(patientEncounter);
}catch (Exception ex){

Expand Down
30 changes: 0 additions & 30 deletions app/femr/ui/controllers/BackEndControllerHelper.java
Original file line number Diff line number Diff line change
@@ -1,17 +1,8 @@
package femr.ui.controllers;

import femr.util.translation.TranslationServer;
import femr.util.translation.TranslationJson;

import java.io.*;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.net.HttpURLConnection;
import java.net.URL;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.json.JSONArray;
import org.json.JSONObject;


public class BackEndControllerHelper {
Expand Down Expand Up @@ -52,25 +43,4 @@ public static ArrayList<String> executeSpeedTestScript(String absPath) {

return speedInfo;
}

public static String translate(String arg, String from, String to) {
String output = "";
try {
output = TranslationServer.makeServerRequest(arg, from, to);

//parse translation from JSON
ObjectMapper mapper = new ObjectMapper();
TranslationJson api = mapper.readValue(output, TranslationJson.class);
output = api.translatedText;

} catch(MalformedURLException e){
System.out.println("Malformed URL Exception");
System.out.println(e.getMessage());
} catch(IOException e){
System.out.println("IOException for parsing JSON");
System.out.println(e.getMessage());
}
return output;
}

}
36 changes: 26 additions & 10 deletions app/femr/ui/controllers/MedicalController.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package femr.ui.controllers;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.inject.Inject;
import controllers.AssetsFinder;
import femr.business.services.core.*;
Expand All @@ -19,6 +20,8 @@
import femr.util.DataStructure.Mapping.TabFieldMultiMap;
import femr.util.DataStructure.Mapping.VitalMultiMap;
import femr.util.stringhelpers.StringUtils;
import femr.util.translation.TranslationJson;
import femr.util.translation.TranslationServer;
import femr.util.translation.TranslationResponseMap;
import play.data.Form;
import play.data.FormFactory;
Expand Down Expand Up @@ -271,36 +274,49 @@ public Result editGet(int patientId) {
// }

public Result translateGet() {
String text = request().getQueryString("text");
//Harrison Shu
CurrentUser currentUserSession = sessionService.retrieveCurrentUserSession();
String toLanguage = currentUserSession.getLanguageCode();
String jsonText = request().getQueryString("text");
int patientId = Integer.parseInt(request().getQueryString("patientId"));

// retrieve current patient encounter encounter
int patientId = Integer.parseInt(request().getQueryString("patientId"));
ServiceResponse<PatientEncounterItem> currentEncounterByPatientId = searchService.retrieveRecentPatientEncounterItemByPatientId(patientId);
if (currentEncounterByPatientId.hasErrors()) {
throw new RuntimeException();
}
PatientEncounterItem patientEncounter = currentEncounterByPatientId.getResponseObject();
String fromLanguage = patientEncounter.getLanguageCode();
//Harrison Shu
String toLanguage = sessionService.retrieveCurrentUserSession().getLanguageCode();
String fromLanguage = currentEncounterByPatientId.getResponseObject().getLanguageCode();


// Harrison Shu: Handles the creation of the response map and figures out whether or not to translate
TranslationResponseMap responseMapObject = new TranslationResponseMap(fromLanguage, toLanguage, text);
TranslationResponseMap responseMapObject = new TranslationResponseMap(fromLanguage, toLanguage, jsonText);

return ok(responseMapObject.getResponseJson());
}

public String translate(String text, String fromLanguage, String toLanguage) {

// Calls Python Script to translate
public static String translate(String jsonText, String fromLanguage, String toLanguage) {
String data = "";
try {
data = BackEndControllerHelper.translate(text, fromLanguage, toLanguage);
data = TranslationServer.makeServerRequest(jsonText, fromLanguage, toLanguage);
data = parseJsonResponse(data);
} catch (Exception e) {
e.printStackTrace();
}
return data;
}

public static String parseJsonResponse(String jsonResponse){
try{
ObjectMapper mapper = new ObjectMapper();
TranslationJson api = mapper.readValue(jsonResponse, TranslationJson.class);
jsonResponse = api.translatedText;
return jsonResponse;
} catch(Exception e){
System.out.println(e.getMessage());
throw new RuntimeException();
}
}

/**
* Get the populated partial view that represents 1 row of new prescription fields
Expand Down
4 changes: 2 additions & 2 deletions app/femr/util/translation/TranslationResponseMap.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
package femr.util.translation;
import femr.ui.controllers.BackEndControllerHelper;
import femr.ui.controllers.MedicalController;
import java.util.*;
import play.libs.Json;

Expand Down Expand Up @@ -37,7 +37,7 @@ private void populateTranslation() {
} else {
String data = "";
try {
data = BackEndControllerHelper.translate(text, fromLanguage, toLanguage);
data = MedicalController.translate(text, fromLanguage, toLanguage);
} catch (Exception e) {
e.printStackTrace();
}
Expand Down
132 changes: 71 additions & 61 deletions app/femr/util/translation/TranslationServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,69 +4,49 @@
import javax.inject.Singleton;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Scanner;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

@Singleton
public class TranslationServer {
@Inject
public TranslationServer(){
this.start();
start(timeout);
}

private static int portNumber = -1;
private static final String timeout = "600";

//Takes a string, a from code and a to code, and returns the translatedtext
public static String makeServerRequest(String text, String from, String to) throws MalformedURLException {
if(serverNotRunning()){
start();
while(serverNotRunning()); //block
public static int getPortFromLog(String logPath, Boolean wait){
int portNumber = 0;
try{
File log = new File(logPath);
Scanner s = new Scanner(log);
if(wait){
while(log.length() == 0);
}
if (s.hasNext()) {
portNumber = Integer.parseInt(s.nextLine().split(": ")[1]);
}
s.close();
}
//Build GET request argument, replacing spaces and newlines
String response = "";
try {
// Harrison Shu
// Encode the URL String parameter before creating URL to allow arabic and hebrew to be in the URL
String encodedText = URLEncoder.encode(text, StandardCharsets.UTF_8.toString());

//Make GET request
URL url = new URL("http://localhost:" + portNumber +"/?text=" +
encodedText + "&from=" + from + "&to=" + to);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
con.connect();

//read response from server
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
response = in.readLine();
in.close();

con.disconnect();
} catch(IOException e){
return makeServerRequest(text, from, to);
catch(FileNotFoundException e){
return portNumber;
}
return response;
catch(Exception e){
System.out.println("Problem retrieving port number from log");
throw new RuntimeException(e);
}
return portNumber;
}
public static boolean serverNotRunning(){
public static boolean serverNotRunning(String logPath){
//initial value of portNumber
if(portNumber == -1){
File log = new File("translator/server.log");
try {
Scanner s = new Scanner(log);
if(s.hasNext()){
portNumber = Integer.parseInt(s.nextLine().split(": ")[1]);
}
else{
return true;
}
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
portNumber = getPortFromLog(logPath, false);
if(portNumber == 0){
return true;
}
}
try{
Expand All @@ -79,33 +59,63 @@ public static boolean serverNotRunning(){
return true;
}
}
public static void start(){
public static String makeServerRequest(String jsonString, String from, String to) {
String logPath = "translator/server.log";
if(serverNotRunning(logPath)){
start(timeout);
while(serverNotRunning(logPath)); //block
}

String response;
try {
byte[] json = jsonString.getBytes(StandardCharsets.UTF_8);
int length = json.length;

//Make POST request
URL url = new URL("http://localhost:" + portNumber + "/?from=" + from + "&to=" + to);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("POST");
con.setDoOutput(true);
con.setFixedLengthStreamingMode(length);
con.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
con.connect();

try(OutputStream os = con.getOutputStream()) {
os.write(json);
}

//read response from server
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
response = in.readLine();
in.close();

con.disconnect();
} catch(IOException e){
System.out.println(e.getMessage());
return "Translation Unavailable";
}
return response;
}
public static void start(String timeout) {
System.out.println("Starting translation server...");

if(serverNotRunning()){
File log = new File("translator/server.log");
String absPath = "translator/server.py";
String logPath = "translator/server.log";
String absPath = "translator/server.py";
if(serverNotRunning(logPath)){
File log = new File(logPath);
try {
ProcessBuilder pb = new ProcessBuilder("python", absPath);
log.createNewFile();
ProcessBuilder pb = new ProcessBuilder("python", absPath, timeout);
pb.redirectOutput(log);
pb.redirectErrorStream(true);
pb.start();

} catch (IOException e) {
System.out.println("An I/O error has occurred.");
System.out.println(e.getMessage());
}

try {
Scanner s = new Scanner(log);
//Wait for server.log to be written to (port number)
while(log.length() == 0);
portNumber = Integer.parseInt(s.nextLine().split(": ")[1]);
s.close();
} catch (FileNotFoundException e) {
System.out.println("A FileNotFound error has occurred.");
System.out.println(e.getMessage());
}
portNumber = getPortFromLog(logPath, true);

}
System.out.println("Translation server running!");
}
Expand Down
Loading

0 comments on commit d267cd2

Please sign in to comment.