package qa.qcri.aidr.trainer.api.service.impl; import java.io.InputStream; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.SortedMap; import org.apache.log4j.Logger; import org.hibernate.criterion.Restrictions; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import qa.qcri.aidr.dbmanager.dto.CustomUiTemplateDTO; import qa.qcri.aidr.dbmanager.dto.ModelFamilyDTO; import qa.qcri.aidr.dbmanager.dto.NominalAttributeDTO; import qa.qcri.aidr.dbmanager.dto.NominalLabelDTO; import qa.qcri.aidr.dbmanager.ejb.remote.facade.CustomUiTemplateResourceFacade; import qa.qcri.aidr.dbmanager.entities.misc.CustomUiTemplate; import qa.qcri.aidr.dbmanager.entities.model.NominalLabel; import qa.qcri.aidr.trainer.api.entity.ClientApp; import qa.qcri.aidr.trainer.api.service.ClientAppService; import qa.qcri.aidr.trainer.api.service.CrisisService; import qa.qcri.aidr.trainer.api.service.CustomUITemplateService; import qa.qcri.aidr.trainer.api.store.CodeLookUp; import qa.qcri.aidr.trainer.api.store.StatusCodeType; import qa.qcri.aidr.trainer.api.template.CrisisJsonModel; import qa.qcri.aidr.trainer.api.template.NominalAttributeJsonModel; import qa.qcri.aidr.trainer.api.template.NominalLabelJsonModel; import qa.qcri.aidr.trainer.api.util.Communicator; import qa.qcri.aidr.trainer.api.util.DataSorterUtil; import qa.qcri.aidr.trainer.api.util.StreamConverter; /** * Created with IntelliJ IDEA. * User: jlucas * Date: 4/2/14 * Time: 5:02 PM * To change this template use File | Settings | File Templates. */ @Service("customUITemplateService") @Transactional(readOnly = true) public class CustomUITemplateServiceImpl implements CustomUITemplateService { protected static Logger logger = Logger.getLogger(CustomUITemplateServiceImpl.class); @Autowired CustomUiTemplateResourceFacade remoteCustomUiTemplateResourceEJB; @Autowired CrisisService crisisService; @Autowired ClientAppService clientAppService; @Override public List<CustomUiTemplateDTO> getCustomTemplateSkinType(Long crisisID){ return getCustomUiTemplateByCrisisWithType(crisisID, CodeLookUp.CLASSIFIER_SKIN); } @Override public List<CustomUiTemplate> getCustomTemplateByCrisis(Long crisisID){ return remoteCustomUiTemplateResourceEJB.getAllByCriteria(Restrictions.eq("crisisID", crisisID)); } @Override public List<CustomUiTemplateDTO> getCustomUiTemplateByCrisisWithType(Long crisisID, Integer templateType){ return remoteCustomUiTemplateResourceEJB.getCustomUITemplateBasedOnTypeByCrisisID(crisisID,templateType ); } @Override public List<CustomUiTemplate> getCustomTemplateForLandingPage(Long crisisID){ List<CustomUiTemplate> templates = getCustomTemplateByCrisis(crisisID) ; List<CustomUiTemplate> tempList = new ArrayList<CustomUiTemplate>(); for(CustomUiTemplate template : templates){ Integer tempType = template.getTemplateType(); if(tempType.equals(CodeLookUp.PUBLIC_LANDING_PAGE_TOP) || tempType.equals(CodeLookUp.PUBLIC_LANDING_PAGE_BOTTOM) || tempType.equals(CodeLookUp.CURATOR_NAME)) { tempList.add(template) ; } } return tempList ; } @Override public void updateCustomTemplateByCrisis(Long crisisID, int customUIType) { List<CustomUiTemplate> customUITemplateList = getCustomTemplateByCrisis(crisisID); if(customUITemplateList.size() > 0){ List<ClientApp> clientApps = clientAppService.getAllClientAppByCrisisID(crisisID); for(ClientApp app :clientApps){ long attributeID = app.getNominalAttributeID(); } } //To change body of implemented methods use File | Settings | File Templates. } @Override public void updateCustomTemplateByAttribute(Long crisisID, Long attributeID, int customUIType, int skinType) throws Exception { /** logger.debug("updateCustomTemplateByAttribute"); logger.debug("crisisID : " + crisisID); logger.debug("attributeID" + attributeID); logger.debug("customUIType" + customUIType); logger.debug("skinType" + skinType); **/ List<CustomUiTemplateDTO> cList ; if(customUIType== CodeLookUp.CLASSIFIER_WELCOME_PAGE){ logger.debug("CLASSIFIER_WELCOME_PAGE"); cList = getTemplateByAttributeAndType(crisisID,attributeID, StatusCodeType.CUSTOM_UI_UPDATE_REQUEST, customUIType); if(cList.size() > 0){ ClientApp clientApp = clientAppService.getClientAppByCrisisAndAttribute(crisisID, attributeID); CustomUiTemplateDTO c = cList.get(0); String longDescString = buildWelcomePage(c.getTemplateValue()); //ClientApp clientApp, int customUIType, String updateTemplateValue String jsonData = this.assembleTPybossaJson(clientApp, CodeLookUp.WELCOMPAGE_UPDATE, longDescString); this.sendToPybossa(jsonData, clientApp ); } } if(customUIType== CodeLookUp.CLASSIFIER_TUTORIAL_ONE || customUIType== CodeLookUp.CLASSIFIER_TUTORIAL_TWO){ //logger.debug("CLASSIFIER_TUTORIAL"); cList = getTemplateByAttribute( crisisID, attributeID); ClientApp clientApp = clientAppService.getClientAppByCrisisAndAttribute(crisisID, attributeID); if(cList.size() > 0){ String tutorialOne = null ; String tutorialTwo = null; for(CustomUiTemplateDTO c : cList){ if(c.getTemplateType().equals(CodeLookUp.CLASSIFIER_TUTORIAL_ONE) ){ tutorialOne = c.getTemplateValue(); } if(c.getTemplateType().equals(CodeLookUp.CLASSIFIER_TUTORIAL_TWO) ){ tutorialTwo = c.getTemplateValue(); } } String tutorialPage; if(tutorialOne == null ){ tutorialOne = this.buildDefaultTutorialPartOne(clientApp); } if(tutorialTwo == null ){ tutorialTwo = this.buildDefaultTutorialPartTwo(clientApp); } tutorialPage = buildTutorialTemplate(clientApp, tutorialOne, tutorialTwo); //logger.debug("CLASSIFIER_TUTORIAL - Context : " + tutorialPage); String jsonData = this.assembleTPybossaJson(clientApp,CodeLookUp.TUTORIAL, tutorialPage); this.sendToPybossa(jsonData, clientApp ); } else{ String defaultTutorialPage = this.buildDefaultTutorialTemplate(clientApp); // logger.debug("CLASSIFIER_TUTORIAL - Context : " + defaultTutorialPage); String jsonData = this.assembleTPybossaJson(clientApp,CodeLookUp.TUTORIAL, defaultTutorialPage); this.sendToPybossa(jsonData, clientApp ); } } if(customUIType== CodeLookUp.CLASSIFIER_SKIN){ //logger.debug("CLASSIFIER_SKIN"); List<ClientApp> apps = clientAppService.getAllClientAppByCrisisID(crisisID); //logger.debug("skim. app count: " + apps.size()); for(ClientApp clientApp : apps){ // logger.debug("skim. clientApp: " + clientApp.getClientAppID()); //ClientApp clientApp = clientAppService.getClientAppByCrisisAndAttribute(crisisID, attributeID); List<ModelFamilyDTO> families = crisisService.findByCrisisID(crisisID).getModelFamiliesDTO(); // logger.debug("skim. families: " + families.size()); for(ModelFamilyDTO family : families){ // logger.debug("skim. families: " + family.getNominalAttributeID()); // logger.debug("skim. clientApp: " + clientApp.getNominalAttributeID()); if(family.getNominalAttributeDTO().getNominalAttributeId().equals(clientApp.getNominalAttributeID())){ NominalAttributeDTO nom = family.getNominalAttributeDTO(); String skinUpdate = buildAppSkin(clientApp, nom, skinType); String jsonData = this.assembleTPybossaJson(clientApp,CodeLookUp.TASK_PRESENTER, skinUpdate); this.sendToPybossa(jsonData, clientApp ); } } } } } @Override public List<CustomUiTemplateDTO> getTemplateByAttributeAndType(Long crisisID, Long attributeID, Integer status, Integer type){ if(status == null){ return remoteCustomUiTemplateResourceEJB.getCustomUITemplateBasedOnTypeByCrisisIDAndAttributeID(crisisID, attributeID, type); } else{ return remoteCustomUiTemplateResourceEJB.getCustomUITemplateBasedOnTypeByCrisisIDAttributeIDAndStatus(crisisID, attributeID, type, status); } } @Override public List<CustomUiTemplateDTO> getTemplateByAttribute(Long crisisID, Long attributeID) { return remoteCustomUiTemplateResourceEJB.getCustomUITemplateByCrisisIDAndAttributeID(crisisID, attributeID); } @Override public String assembleTPybossaJson(ClientApp clientApp, String key, String value) throws Exception{ String getInfo = this.getAppInfo(clientApp); JSONParser parser = new JSONParser(); JSONObject data = (JSONObject) parser.parse(getInfo); String created = (String)data.get("created"); JSONObject info = (JSONObject)data.get("info"); String long_description = (String)data.get("long_description"); String tutorial = (String)info.get("tutorial"); String task_presenter = (String)info.get("task_presenter"); if(key.equalsIgnoreCase(CodeLookUp.WELCOMPAGE_UPDATE)){ long_description = value; } if(key.equalsIgnoreCase(CodeLookUp.TUTORIAL)){ tutorial = value; } if(key.equalsIgnoreCase(CodeLookUp.TASK_PRESENTER)){ task_presenter = value; } JSONObject app = new JSONObject(); app.put("task_presenter", task_presenter); app.put("tutorial", tutorial); app.put("thumbnail", "http://i.imgur.com/lgZAWIc.png"); JSONObject app2 = new JSONObject(); app2.put("info", app ); app2.put("long_description", long_description); app2.put("name", clientApp.getName()); app2.put("short_name", clientApp.getShortName()); app2.put("description", clientApp.getShortName()); app2.put("id", clientApp.getPlatformAppID()); app2.put("time_limit", 0); app2.put("long_tasks", 0); app2.put("created", created); app2.put("calibration_frac", 0); app2.put("bolt_course_id", 0); app2.put("link", "<link rel='self' title='app' href='http://localhost:5000/api/app/2'/>"); app2.put("allow_anonymous_contributors", true); app2.put("time_estimate", 0); app2.put("hidden", 0); if(data.get("category_id")!=null){ long category_id = (Long)data.get("category_id"); app2.put("category_id", category_id); } //app2.put("owner_id", 1); return app2.toJSONString(); } public String buildTutorialTemplate(ClientApp clientApp, String partOne, String partTwo) throws Exception{ InputStream tutorialIS = Thread.currentThread().getContextClassLoader().getResourceAsStream("html/tutorial.html"); String tutorialString = StreamConverter.convertStreamToString(tutorialIS) ; tutorialString = tutorialString.replace("TEMPLATE:SHORTNAME", clientApp.getShortName()); tutorialString = tutorialString.replace("TEMPLATE:NAME", clientApp.getName()); tutorialString = tutorialString.replace("TEMPLATE:PARTONE", partOne); tutorialString = tutorialString.replace("TEMPLATE:PARTTWO", partTwo); return tutorialString; } public String buildWelcomePage(String templateValue) throws Exception{ InputStream longDescIS = Thread.currentThread().getContextClassLoader().getResourceAsStream("html/long_description.html"); String longDescString = StreamConverter.convertStreamToString(longDescIS) ; longDescString = longDescString.replace("TEMPLATE:DESCRIPTION", templateValue); return longDescString; } public String buildAppSkin(ClientApp clientApp, NominalAttributeDTO attribute, int skinType) throws Exception { InputStream templateIS = null; if(skinType == CodeLookUp.DEFAULT_SKIN){ templateIS = Thread.currentThread().getContextClassLoader().getResourceAsStream("html/template.html"); } else{ templateIS = Thread.currentThread().getContextClassLoader().getResourceAsStream("html/iPhoneTemplate.html"); } String templateString = StreamConverter.convertStreamToString(templateIS) ; templateString = templateString.replace("TEMPLATE:SHORTNAME", clientApp.getShortName()); String attributeDisplay = attribute.getName(); attributeDisplay = attributeDisplay +" " + attribute.getDescription(); templateString = templateString.replace("TEMPLATE:FORATTRIBUTEAIDR", attributeDisplay); List<NominalLabelDTO> nominalLabels = attribute.getNominalLabelsDTO(); SortedMap nominalLabelMap = DataSorterUtil.sortNominalLabelByCode(nominalLabels); String labelString = buildLabelList(nominalLabelMap, skinType); templateString = templateString.replace("TEMPLATE:FORLABELSFROMAIDR", labelString); return templateString; } public String buildLabelList(SortedMap mapData, int skinType){ StringBuffer displayLabel = new StringBuffer(); Iterator itr= mapData.entrySet().iterator(); Set<String> numbers = mapData.keySet(); for (String number : numbers) { //System.out.println(mapData.get(number)); NominalLabel featureJsonObj =(NominalLabel) mapData.get(number); String labelName = featureJsonObj.getName() ; String lableCode = featureJsonObj.getNominalLabelCode() ; String description = featureJsonObj.getDescription(); Long norminalLabelID = featureJsonObj.getNominalLabelId().longValue(); if(skinType == CodeLookUp.IPHONE_SKIN) { displayLabel.append("<li id='") ; displayLabel.append(lableCode) ; displayLabel.append("'>") ; displayLabel.append(labelName) ; displayLabel.append("</li>") ; } else{ displayLabel.append("<label class='radio' name='nominalLabel'><strong>") ; displayLabel.append("<input name='nominalLabel' type='radio' value='"); displayLabel.append(lableCode) ; displayLabel.append("'>") ; displayLabel.append(labelName) ; displayLabel.append("</strong>") ; if(!description.isEmpty()){ displayLabel.append("  ") ; displayLabel.append("<font color='#999999' size=-1>") ; displayLabel.append(description) ; displayLabel.append("</font>") ; } displayLabel.append("</label>") ; } } return displayLabel.toString(); } public String buildDefaultTutorialPartOne(ClientApp clientApp) throws Exception{ long crisisID = clientApp.getCrisisID(); CrisisJsonModel crisisJsonModel = crisisService.findByOptimizedCrisisID(crisisID); StringBuffer partOne = new StringBuffer(); partOne.append("<b>Hi!</b> Many thanks for volunteering your time as a Digital Humanitarian, in order to learn more about "); partOne.append(crisisJsonModel.getName()); partOne.append("."); partOne.append(" Critical information is often shared on Twitter in real time, which is where you come in."); return partOne.toString(); } public String buildDefaultTutorialPartTwo(ClientApp clientApp) throws Exception{ long crisisID = clientApp.getCrisisID(); long attributeID = clientApp.getNominalAttributeID(); CrisisJsonModel crisisJsonModel = crisisService.findByOptimizedCrisisID(crisisID); Set<NominalAttributeJsonModel> nominalAttributes = crisisJsonModel.getNominalAttributeJsonModelSet(); Set<NominalLabelJsonModel> labelJsonModelSet = null; for(NominalAttributeJsonModel a : nominalAttributes){ if(a.getNominalAttributeID().equals(attributeID)) { labelJsonModelSet = a.getNominalLabelJsonModelSet(); } } StringBuffer partTwo = new StringBuffer(); partTwo.append("Being a Digital Humanitarian is as easy and fast as a click of the mouse. "); partTwo.append("If you want to keep track of your progress and points, make sure to login! "); partTwo.append("This Clicker will simply load a tweet and ask you to click on the category that best describes the tweet.<br/>"); if(labelJsonModelSet != null ){ partTwo.append("<table>"); for(NominalLabelJsonModel labelJsonModel : labelJsonModelSet) { partTwo.append("<tr><td>"); partTwo.append("<b>" + labelJsonModel.getName() + "</b></td>") ; if(!labelJsonModel.getDescription().isEmpty()){ partTwo.append("<td>: " + labelJsonModel.getDescription() + "</td>") ; } partTwo.append("</tr>"); } partTwo.append("</table>"); } partTwo.append("<br/><br/>"); partTwo.append("Note that these tweets come directly from twitter and may on rare occasions include disturbing content. Only start clicking if you understand this and still wish to volunteer."); partTwo.append("<br/><br/>"); partTwo.append("Thank you!"); return partTwo.toString(); } private String buildDefaultTutorialTemplate(ClientApp clientApp) throws Exception{ long crisisID = clientApp.getCrisisID(); long attributeID = clientApp.getNominalAttributeID(); CrisisJsonModel crisisJsonModel = crisisService.findByOptimizedCrisisID(crisisID); Set<NominalAttributeJsonModel> nominalAttributes = crisisJsonModel.getNominalAttributeJsonModelSet(); Set<NominalLabelJsonModel> labelJsonModelSet = null; for(NominalAttributeJsonModel a : nominalAttributes){ if(a.getNominalAttributeID().equals(attributeID)) { labelJsonModelSet = a.getNominalLabelJsonModelSet(); } } StringBuffer partOne = new StringBuffer(); partOne.append("<b>Hi!</b> Many thanks for volunteering your time as a Digital Humanitarian, in order to learn more about "); partOne.append(crisisJsonModel.getName()); partOne.append("."); partOne.append(" Critical information is often shared on Twitter in real time, which is where you come in."); StringBuffer partTwo = new StringBuffer(); partTwo.append("Being a Digital Humanitarian is as easy and fast as a click of the mouse. "); partTwo.append("If you want to keep track of your progress and points, make sure to login! "); partTwo.append("This Clicker will simply load a tweet and ask you to click on the category that best describes the tweet.<br/>"); if(labelJsonModelSet != null ){ partTwo.append("<table>"); for(NominalLabelJsonModel labelJsonModel : labelJsonModelSet) { partTwo.append("<tr><td>"); partTwo.append("<b>" + labelJsonModel.getName() + "</b></td>") ; if(!labelJsonModel.getDescription().isEmpty()){ partTwo.append("<td>: " + labelJsonModel.getDescription() + "</td>") ; } partTwo.append("</tr>"); } partTwo.append("</table>"); } partTwo.append("<br/><br/>"); partTwo.append("Note that these tweets come directly from twitter and may on rare occasions include disturbing content. Only start clicking if you understand this and still wish to volunteer."); partTwo.append("<br/><br/>"); partTwo.append("Thank you!"); return buildTutorialTemplate(clientApp, partOne.toString(), partTwo.toString()); } private String getAppInfo(ClientApp clientApp){ Communicator pybossaCommunicator = new Communicator(); String url = clientApp.getClient().getHostURL() + "/project/" + clientApp.getPlatformAppID(); String response = pybossaCommunicator.sendGet(url); return response; } private void sendToPybossa(String jsonData,ClientApp clientApp){ // logger.info("sendToPybossa jsonData : " + jsonData); Communicator pybossaCommunicator = new Communicator(); String url = clientApp.getClient().getHostURL() + "/project/" + clientApp.getPlatformAppID() + "?api_key=" + clientApp.getClient().getHostAPIKey(); // logger.info("sendToPybossa url:" + url); int responseCode = pybossaCommunicator.sendPut(jsonData, url); // logger.info("sendToPybossa response:" + responseCode); } }