Просмотр исходного кода

Merge branch 'fixed-templates' of UV-APPS/UV_SAIC_DATA into master

Mario Martínez Hernández 1 неделя назад
Родитель
Сommit
f1848c08ab

+ 379 - 0
src/main/java/es/uv/saic/service/TemplateService.java

@@ -0,0 +1,379 @@
+package es.uv.saic.service;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.text.DecimalFormat;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Base64;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.jsoup.select.Elements;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.stereotype.Service;
+
+import es.uv.saic.shared.dto.InstanciaTascaDTO;
+import es.uv.saic.shared.dto.NomProcesOrganDTO;
+import es.uv.saic.shared.dto.OrganDTO;
+import es.uv.saic.shared.feign.IndicadorClient;
+import es.uv.saic.shared.feign.OrganClient;
+import es.uv.saic.shared.feign.TascaClient;
+
+@Service
+public class TemplateService {
+
+    @Autowired
+    private OrganClient oc;
+
+    @Autowired
+	private IndicadorClient ic;
+
+    @Autowired
+	private TascaClient tc;
+
+    private static final DecimalFormat df = new DecimalFormat("0.00");
+
+    public String addTemplateData(Integer idTitulacio, Integer cursAvaluat, Integer idCentre, String opcionsStr, String tlugar, String lugar, BigInteger idInstanciaTasca, String nomVal, String nomvalTitulacio, String template){
+		HashMap<String, String> context = new HashMap<String, String>();
+		HashMap<String, String> header = new HashMap<String, String>();
+		HashMap<String, String> img = new HashMap<String, String>();
+		 
+		String ambit = "G";
+		opcionsStr = opcionsStr.replaceAll("^\\.$", "");
+		String [] opcions = new String[0];
+		if(!opcionsStr.isEmpty()) {
+			opcions = opcionsStr.split(";");
+		}
+		if(tlugar.equals("C")) {
+			if(idTitulacio == 2) {
+				ambit = "M";
+			}
+		}
+		
+		/** Add header information **/
+		addHeaderData(nomVal, Integer.parseInt(lugar), nomvalTitulacio, cursAvaluat, header, img);
+		
+		/** Iterate elements inside {[loop]} ... {[endloop]} **/
+		template = this.iterateLoopTag(template, idCentre, ambit, cursAvaluat, context);
+		
+		/** Iterate elements with data-loop attribute **/
+		Document doc = Jsoup.parse(template);
+		doc = iterateLoopAttr(idCentre, cursAvaluat, doc, context);
+		
+		/** Add template data (non iterated data)**/
+		ic.getTemplateData(idTitulacio, idCentre, cursAvaluat, context);	
+		this.replaceValues(doc, context, header, img);
+		
+		/** Replace sections if specified in options **/
+		this.replaceSection(opcions, tlugar, lugar, idCentre, idTitulacio, doc, idInstanciaTasca);
+		
+		return doc.html();	
+	}
+ 
+    public Document replaceSection(String[] opcions, String tlugar, String lugar, Integer centre, Integer idTitulacio, Document doc, BigInteger idInstanciaTasca) {
+		if(opcions.length > 0) {
+			NomProcesOrganDTO nomProcesOrganDTO = new NomProcesOrganDTO(opcions[0], 
+																		tlugar, 
+																		(Integer) Integer.parseInt(lugar), 
+																		centre, 
+																		idTitulacio);
+			InstanciaTascaDTO itOld = tc.getReportFromNomProcesOrgan(nomProcesOrganDTO);
+			try {
+				Document doc2 = Jsoup.parse(itOld.getText());
+				Elements target = null;
+				Elements source = null;
+				if(opcions.length == 2) {
+					target = this.extractTemplateAnchor(doc2, true, opcions[1]);
+					source = this.extractTemplateAnchor(doc, false, opcions[1]);
+				}
+				else {
+					target = this.extractTemplateAnchor(doc2, true, opcions[1], opcions[2]);
+					source = this.extractTemplateAnchor(doc, false, opcions[1], opcions[2]);
+				}
+				
+				if(target == null || source == null) {
+					return doc;
+				}
+				Element e = source.get(0);
+				e.before(this.clear(target.outerHtml()));
+				source.remove();
+			}
+			catch(NullPointerException e){
+				System.out.println("No previous version found for "+idInstanciaTasca.toString());
+			}
+			
+		}
+		return doc;
+	}
+
+    public String clear(String html){
+		return html.replaceAll("data-mce-style=\"[ ,;:.\\d\\w\\(\\)\\#\\%-]{1,}\"", "")
+				   .replaceAll("font-family:[ \\d\\w-,]{1,};", "")
+				   .replaceAll("font-size:[ \\d\\w,\\.]{1,};", "")
+				   .replaceAll("\\<\\!\\-\\-tinycomments\\|2\\.1\\|data\\:application\\/json\\;base64\\,[A-Za-z0-9\\/\\+\\\\]*\\=*\\-\\-\\>", "")
+				   .replaceAll("data\\-mce\\-annotation\\-uid\\=\"mce\\-conversation\\_[a-zA-Z0-9]+\"", "")
+				   .replaceAll("data\\-mce\\-annotation\\=\"tinycomments\"", "")
+				   .replaceAll("class=\"mce-annotation\"", "");
+	}
+
+    public Elements extractTemplateAnchor(Document doc, Boolean target, String... args) {
+		// <a id="pam"></a>		
+		
+		/* Hardcoded to fix anchor positions in existing templates */
+		try{
+			String anchor_ini = args[0];
+			Element eFirst = doc.select("p:has(a#"+anchor_ini+")").first();
+			Elements elems = eFirst.nextElementSiblings();
+			Elements table = elems.select("table:not(.pdfignore)");
+			return table;
+		}
+		catch(Exception e){
+			return null;
+		}
+		
+		/* Use this code in future */
+		/* 
+		if(args.length == 2){
+			String anchor_end = args[1];
+			Element eLast = doc.select("p:has(a#"+anchor_end+")").first();
+			boolean remove = false;
+			for(Iterator<Element> iter = elems.iterator(); iter.hasNext();){
+				Element x = iter.next();
+				if(remove){
+					iter.remove();
+				}
+				if(x.id().equals(anchor_end) || x.html().contains(anchor_end)){
+					remove = true;
+				}
+			}
+		}
+		*/
+		
+	}
+    
+    public String addTemplateData(Integer idTitulacio, Integer idCentre, Integer curs, String template){
+		
+		HashMap<String, String> context = new HashMap<String, String>();
+		HashMap<String, String> header = new HashMap<String, String>();
+		HashMap<String, String> img = new HashMap<String, String>();
+		 
+		OrganDTO centre = oc.findByID("C", idCentre);
+		OrganDTO titulacio = oc.findByID("T", idTitulacio);
+		
+		/** Add header information **/
+		addHeaderData(centre.getNomVal(), centre.getLugar2(), titulacio.getNomVal(), curs, header, img);
+							
+		/** Iterate elements inside {[loop]} ... {[endloop]} **/
+		template = this.iterateLoopTag(template, idCentre, titulacio.getTambit(), curs, context);
+		
+		/** Iterate elements with data-loop attribute **/
+		Document doc = Jsoup.parse(template);
+		doc = iterateLoopAttr(idCentre, curs, doc, context);
+		
+		/** Add template data (non iterated data)**/
+		ic.getTemplateData(idTitulacio, idCentre, curs, context);	
+		this.replaceValues(doc, context, header, img);
+		
+		return doc.html();	
+	}
+
+    private void addHeaderData(String nomVal, Integer lugar, String nomValTitulacion, Integer curs, HashMap<String, String> header, HashMap<String, String> img) {
+		header.put("centre", nomVal);
+		header.put("titulacio", nomValTitulacion);
+		header.put("curs", "CURSO "+Integer.toString(curs-1)+" - "+Integer.toString(curs));
+		header.put("curs_anterior", Integer.toString(curs-2)+" - "+Integer.toString(curs-1));
+		header.put("conv-ant1", "CONVOCATORIA "+Integer.toString(curs-1)+" - "+Integer.toString(curs));
+		header.put("conv-ant2", "CONVOCATORIA "+Integer.toString(curs-2)+" - "+Integer.toString(curs-1));
+		header.put("periode-ant1", Integer.toString(curs-6)+" - "+Integer.toString(curs-1));
+		header.put("periode-ant2", Integer.toString(curs-7)+" - "+Integer.toString(curs-2));
+		ClassPathResource fuv = new ClassPathResource("/static/logos/UV.png");
+		ClassPathResource fc = new ClassPathResource("/static/logos/C"+Integer.toString(lugar)+".png");
+		String logouv_b64;
+		String logoc_b64;
+		try {
+			logouv_b64 = "data:image/png;base64, "+Base64.getEncoder().encodeToString(fuv.getInputStream().readAllBytes());
+		} catch (IOException e) {
+			logouv_b64 = "https://saic.uv.es/public/logos/UV.png";
+		}
+		try {
+			logoc_b64 = "data:image/png;base64, "+Base64.getEncoder().encodeToString(fc.getInputStream().readAllBytes());
+		} catch (IOException e) {
+			logoc_b64 = "https://saic.uv.es/public/logos/C"+Integer.toString(lugar)+".png";
+		}
+		img.put("logo_centre", logoc_b64);
+		img.put("logo_uv", logouv_b64);
+	}
+	
+	private Document iterateLoopAttr(Integer idCentre, Integer curs, Document doc, HashMap<String, String> context) {
+		Elements loop_elements = doc.select("*[data-loop]");
+		for(Element e : loop_elements) {
+			String tambit = e.attr("data-loop");
+			List<OrganDTO> tits = oc.getTitulacionsByCentreTambit(idCentre, tambit);
+			for(OrganDTO org : tits) {
+				context.clear();
+				Element e_copy = e.clone();
+				ic.getTemplateData(org.getLugar(), org.getLugar2(), curs, context);
+				context.put("titulacio_loop", org.getNomVal());
+				Elements ielements = e_copy.select("*:matchesWholeOwnText(\\{\\{([^\\}]*)\\}\\})");
+				for(Element ielem : ielements) {
+					String t = ielem.html().replace("{", "").replace("}", "");
+					String i = this.formatValue(context.get(t));
+					if(i != null) {
+						if(ielem.tagName().equals("td")) {
+							ielem.attr("class", "mceEditable");
+							ielem.attr("id", "ind_"+t);
+							ielem.html(i);
+						}
+						else {
+							ielem.html(i);
+						}
+					}
+					else {
+						if(ielem.tagName().equals("td")) {
+							ielem.attr("class", "mceEditable");
+							ielem.attr("id", "ind_"+t);
+							ielem.html("");
+						}
+						else {
+							ielem.html("");
+						}
+					}
+				}		
+				e.after(e_copy);
+			}
+			e.remove();
+		}
+		context.clear();
+		return doc;
+	}
+
+    private String iterateLoopTag(String template, Integer idCentre, String Tambit, Integer curs, HashMap<String, String> context) {
+		Pattern pattern = Pattern.compile(".*<p>\\{\\[loop\\]\\}</p>([\\S\\s]*)<p>\\{\\[endloop\\]\\}</p>.*");
+		Matcher matcher = pattern.matcher(template);
+		String replaced = "";
+		
+		while(matcher.find()) {
+			String group = matcher.group(1);
+			Document tab = Jsoup.parse(group);
+			List<OrganDTO> tits = oc.getTitulacionsByCentreTambit(idCentre, Tambit);
+			for(OrganDTO t : tits) {
+				Document tabcopy = Jsoup.parse(tab.html());
+				context.clear();
+				ic.getTemplateData(t.getLugar(), t.getLugar2(), curs, context);
+				context.put("titulacio_loop", t.getNomVal());
+				tabcopy = this.replaceValuesLoop(tabcopy, context);
+				replaced += tabcopy.html()+"<p></p>";
+			}
+			template = template.replace("<p>{[loop]}</p>"+group+"<p>{[endloop]}</p>", replaced);
+		}
+		context.clear();
+		return template;
+	}
+
+    private Document replaceValues(Document doc, HashMap<String, String> context, HashMap<String, String> header, HashMap<String, String> img) {
+		Elements elems = doc.select("*:matchesWholeOwnText(\\{\\{([^\\}]*)\\}\\})");
+		for(Element e : elems) {
+			String t = e.html().replace("{", "").replace("}", "");
+			if(header.containsKey(t)) {
+				e.html(header.get(t));
+			}
+			else if(img.containsKey(t)) {
+				Element x = new Element("img");
+				x.attr("src", img.get(t));
+				x.attr("style", "display:block; margin-left:auto; margin-right:auto; width:100px; max-width:100px;");
+				x.attr("class", "logo");
+				e.html("");
+				e.appendChild(x);	
+			}
+			else {
+				String i = this.formatValue(context.get(t));
+				if(i != null) {
+					if(e.parent().tagName().equals("td")) {
+						e.parent().attr("class", "mceEditable");
+						e.parent().attr("id", "ind_"+t);
+						e.parent().attr("style", e.attr("style"));
+						e.parent().html(i);
+					}
+					else {
+						e.attr("class", "mceEditable");
+						e.attr("ind", "ind_"+t);
+						e.html(i);
+					}
+				}
+				else {
+					if(e.parent().tagName().equals("td")) {
+						e.parent().attr("class", "mceEditable");
+						e.parent().attr("id", "ind_"+t);
+						e.parent().attr("style", e.attr("style"));
+						e.parent().html("");
+					}
+					else {
+						e.attr("class", "mceEditable");
+						e.attr("ind", "ind_"+t);
+						e.html("");
+					}
+				}
+			}
+		}
+		return doc;
+	}
+
+    private Document replaceValuesLoop(Document doc, HashMap<String, String> context) {
+		Elements elems = doc.select("*:matchesWholeOwnText(\\{\\{([^\\}]*)\\}\\})");
+		for(Element e : elems) {
+			String t = e.html().replace("{", "").replace("}", "");
+			String i = this.formatValue(context.get(t));
+			if(i != null) {
+				if(e.parent().tagName().equals("td")) {
+					e.parent().attr("class", "mceEditable");
+					e.parent().attr("id", "ind_"+t);
+					e.parent().attr("style", e.attr("style"));
+					e.parent().html(i);
+				}
+				else {
+					e.attr("class", "mceEditable");
+					e.attr("ind", "ind_"+t);
+					e.html(i);
+				}
+			}
+			else {
+				if(e.parent().tagName().equals("td")) {
+					e.parent().attr("class", "mceEditable");
+					e.parent().attr("id", "ind_"+t);
+					e.parent().attr("style", e.attr("style"));
+					e.parent().html("");
+				}
+				else {
+					e.attr("class", "mceEditable");
+					e.attr("ind", "ind_"+t);
+					e.html("");
+				}
+			}
+		}
+		return doc;
+	}
+	
+	private String formatValue(String v) {	
+		if(v == null) return ""; 
+		if(v.isEmpty() | v.isBlank()) return "";
+		if(v.equals("NP")) return "NP";
+				
+		try {
+		    double d = Double.parseDouble(v);
+		    return (Integer.toString((int)d).equals(v) ? v : df.format(d).replace(",", "."));
+		} 
+		catch (NumberFormatException e) { }
+		
+		if(v.endsWith("%") && v.startsWith(".")) {
+			return "0"+v;
+		}
+		
+		return v;
+		
+	}
+}

+ 29 - 0
src/main/java/es/uv/saic/web/TemplateController.java

@@ -0,0 +1,29 @@
+package es.uv.saic.web;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import es.uv.saic.service.TemplateService;
+import es.uv.saic.shared.dto.TemplateDataDTO;
+
+@RestController
+@RequestMapping("/template")
+public class TemplateController {
+
+    @Autowired
+    private TemplateService ts;
+
+    @PostMapping("/addData")
+    public String addTemplateData(@RequestBody TemplateDataDTO td) {
+        return ts.addTemplateData(td.getIdTitulacio(), td.getCursAvaluat(), (Integer) Integer.parseInt(td.getIdCentre()), td.getOpcionsStr(), td.getTlugar(), td.getLugar(), td.getIdInstaciaTasca(), td.getNomVal(), td.getNomValTitulacio(), td.getTemplate());
+    }
+    
+    @PostMapping("/addData2")
+    public String addTemplateData2(@RequestParam String idTitulacio, @RequestParam String idCentre, @RequestParam String curs, @RequestParam String template) {
+        return ts.addTemplateData(Integer.parseInt(idTitulacio), Integer.parseInt(curs), Integer.parseInt(idCentre), template);        
+    }
+}