Skip to content
Snippets Groups Projects
Commit 550519db authored by Ignacio Fagian's avatar Ignacio Fagian
Browse files

Se agrega i18n en el backend, y se acomoda la parametrizacion desde el frontend

parent d72f8563
No related branches found
No related tags found
No related merge requests found
{ {
"name": "matefun", "name": "matefun",
"version": "2.0.1", "version": "2.0.2",
"license": "MIT", "license": "MIT",
"scripts": { "scripts": {
"ng": "ng", "ng": "ng",
......
...@@ -11,7 +11,15 @@ ...@@ -11,7 +11,15 @@
<div class="form-group"> <div class="form-group">
<input type="password" [(ngModel)]=model.password (keyup.enter)=login() name="password" class="form-control input-underline input-lg" placeholder="Contraseña"> <input type="password" [(ngModel)]=model.password (keyup.enter)=login() name="password" class="form-control input-underline input-lg" placeholder="Contraseña">
</div> </div>
<div class="form-group" style="margin-bottom: 0px;">
<div ngbDropdown class="d-inline-block">
<button class="btn btn-outline-secondary" id="input-lang" ngbDropdownToggle>{{model.language.name}}</button>
<div class="dropdown-menu" aria-labelledby="input-lang">
<button class="dropdown-item" *ngFor="let lang of languages" (click)="model.language = lang" >{{lang.name}}</button>
</div>
</div>
</div>
</div> </div>
<a class="btn rounded-btn" style="background: transparent;color: white;cursor: pointer;width: 159px;margin-right: 3px;" (click)=login()> Iniciar Sesión </a> <a class="btn rounded-btn" style="background: transparent;color: white;cursor: pointer;width: 159px;margin-right: 3px;" (click)=login()> Iniciar Sesión </a>
......
...@@ -12,12 +12,21 @@ import { AuthenticationService } from '../shared/services/authentication.service ...@@ -12,12 +12,21 @@ import { AuthenticationService } from '../shared/services/authentication.service
}) })
export class LoginComponent implements OnInit { export class LoginComponent implements OnInit {
model: any = {}; languages = [
{id: 0, name: "Ingles", code: 'en'},
{id: 1, name: "Español", code: 'es'}
];
model: any = {
language: this.languages[0]
};
loading = false; loading = false;
error = false; error = false;
errorText = ""; errorText = "";
returnUrl: string; returnUrl: string;
constructor( constructor(
private route: ActivatedRoute, private route: ActivatedRoute,
private router: Router, private router: Router,
...@@ -38,7 +47,8 @@ export class LoginComponent implements OnInit { ...@@ -38,7 +47,8 @@ export class LoginComponent implements OnInit {
this.loading = true; this.loading = true;
var that = this; var that = this;
this.authenticationService.login(this.model.cedula, this.model.password)
this.authenticationService.login(this.model.cedula, this.model.password, this.model.language.code)
.subscribe( .subscribe(
data => { data => {
//resetSession = true; //resetSession = true;
...@@ -54,7 +64,8 @@ export class LoginComponent implements OnInit { ...@@ -54,7 +64,8 @@ export class LoginComponent implements OnInit {
invitado(){ invitado(){
this.loading = true; this.loading = true;
this.authenticationService.login("invitado", "invitado")
this.authenticationService.login("invitado", "invitado", this.model.language.code)
.subscribe( .subscribe(
data => { data => {
this.router.navigate([this.returnUrl]); this.router.navigate([this.returnUrl]);
......
...@@ -12,8 +12,10 @@ ...@@ -12,8 +12,10 @@
// export const SERVER = window.location.protocol + '//' + window.location.host;//'http://localhost:9090'; // export const SERVER = window.location.protocol + '//' + window.location.host;//'http://localhost:9090';
// export const GHCI_URL = window.location.protocol == 'http:'? 'ws://'+window.location.host+'/endpoint': 'wss://'+window.location.host+'/endpoint'; // export const GHCI_URL = window.location.protocol == 'http:'? 'ws://'+window.location.host+'/endpoint': 'wss://'+window.location.host+'/endpoint';
// Google cloud platform // Linux Nacho
// export const SERVER = 'http://192.168.129.3:9090';
// export const GHCI_URL = 'ws://192.168.129.3:9090/endpoint';
// Google cloud platform
export const SERVER = 'http://35.199.110.129:9090'; export const SERVER = 'http://35.199.110.129:9090';
export const GHCI_URL = 'ws://35.199.110.129:9090/endpoint'; export const GHCI_URL = 'ws://35.199.110.129:9090/endpoint';
...@@ -10,12 +10,13 @@ import { SERVER } from '../config'; ...@@ -10,12 +10,13 @@ import { SERVER } from '../config';
export class AuthenticationService { export class AuthenticationService {
constructor(private http: Http) { } constructor(private http: Http) { }
login(cedula: string, password: string) { login(cedula: string, password: string, language: string) {
let headers = new Headers({ 'Content-Type': 'application/json' }); let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers }); let options = new RequestOptions({ headers: headers });
return this.http.post(SERVER+'/servicios/login', JSON.stringify({ "cedula": cedula, "password": password }),options) return this.http.post(SERVER+'/servicios/login', JSON.stringify({ "cedula": cedula, "password": password }),options)
.map((response: Response) => { .map((response: Response) => {
let user = response.json(); let user = response.json();
user.language = language;
sessionStorage.setItem('currentUser', JSON.stringify(user)); sessionStorage.setItem('currentUser', JSON.stringify(user));
}); });
} }
...@@ -33,6 +34,11 @@ export class AuthenticationService { ...@@ -33,6 +34,11 @@ export class AuthenticationService {
return currentUser? currentUser.token: undefined; return currentUser? currentUser.token: undefined;
} }
getLanguage() {
var currentUser = JSON.parse(sessionStorage.getItem('currentUser'));
return currentUser? currentUser.language: undefined;
}
setUserConfig(config){ setUserConfig(config){
var user = JSON.parse(sessionStorage.getItem('currentUser')); var user = JSON.parse(sessionStorage.getItem('currentUser'));
user.configuracion = config; user.configuracion = config;
......
...@@ -36,7 +36,7 @@ export class GHCIService { ...@@ -36,7 +36,7 @@ export class GHCIService {
constructor(private authService:AuthenticationService,private router: Router){ constructor(private authService:AuthenticationService,private router: Router){
console.log("contructor ghci"); console.log("contructor ghci");
this.conectarWS(GHCI_URL, authService.getUser().cedula, authService.getToken()); this.conectarWS(GHCI_URL, authService.getUser().cedula, authService.getToken(), authService.getLanguage());
setInterval( this.checkConnection.bind(this), 5000); setInterval( this.checkConnection.bind(this), 5000);
setInterval( this.doPing.bind(this), 30000); setInterval( this.doPing.bind(this), 30000);
} }
...@@ -79,9 +79,9 @@ export class GHCIService { ...@@ -79,9 +79,9 @@ export class GHCIService {
consoleRef:any; consoleRef:any;
conectarWS(wsUrl, cedula, token){ conectarWS(wsUrl, cedula, token, language){
if(cedula && token && (!this.connection || this.connection.readyState == WebSocket.CLOSED)){ if(cedula && token && (!this.connection || this.connection.readyState == WebSocket.CLOSED)){
this.connection = new WebSocket(wsUrl+"/"+cedula+"/"+token); this.connection = new WebSocket(wsUrl+"/"+cedula+"/"+token+"/"+language);
this.connection.onopen = function(){ this.connection.onopen = function(){
console.log('Conexión con web socket exitosa'); console.log('Conexión con web socket exitosa');
...@@ -323,8 +323,9 @@ export class GHCIService { ...@@ -323,8 +323,9 @@ export class GHCIService {
checkConnection(){ checkConnection(){
var usuario = this.authService.getUser(); var usuario = this.authService.getUser();
var token = this.authService.getToken(); var token = this.authService.getToken();
var language = this.authService.getLanguage();
if(usuario && token && (!this.connection || this.connection.readyState == WebSocket.CLOSED)){ if(usuario && token && (!this.connection || this.connection.readyState == WebSocket.CLOSED)){
this.conectarWS(GHCI_URL, usuario.cedula, token); this.conectarWS(GHCI_URL, usuario.cedula, token, language);
} }
} }
......
...@@ -46,6 +46,11 @@ ...@@ -46,6 +46,11 @@
<artifactId>jackson-annotations</artifactId> <artifactId>jackson-annotations</artifactId>
<version>2.9.0</version> <version>2.9.0</version>
</dependency> </dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.0</version>
</dependency>
</dependencies> </dependencies>
......
...@@ -16,6 +16,7 @@ import java.util.regex.Pattern; ...@@ -16,6 +16,7 @@ import java.util.regex.Pattern;
import java.util.Map; import java.util.Map;
import javax.annotation.PreDestroy; import javax.annotation.PreDestroy;
import javax.ejb.Stateful; import javax.ejb.Stateful;
import javax.ejb.EJB;
import javax.inject.Inject; import javax.inject.Inject;
import javax.json.Json; import javax.json.Json;
import javax.json.JsonArray; import javax.json.JsonArray;
...@@ -46,6 +47,9 @@ public class CommandsBean { ...@@ -46,6 +47,9 @@ public class CommandsBean {
@Inject @Inject
LoginEJB loginEJB; LoginEJB loginEJB;
@EJB
I18nEJB i18nEJB;
@Inject @Inject
private ServletContext context; private ServletContext context;
...@@ -58,6 +62,8 @@ public class CommandsBean { ...@@ -58,6 +62,8 @@ public class CommandsBean {
private Process proceso; private Process proceso;
private BufferedWriter p_stdin; private BufferedWriter p_stdin;
private CountDownLatch latch; private CountDownLatch latch;
private Map<String, String> i18n = null;
private String nombrePrompt = ""; private String nombrePrompt = "";
...@@ -91,7 +97,7 @@ public class CommandsBean { ...@@ -91,7 +97,7 @@ public class CommandsBean {
System.out.print("Web socket finalizado"); System.out.print("Web socket finalizado");
return; return;
} }
if (comandoJson.containsKey("ping")) { if (comandoJson.containsKey("ping")) {
// System.out.println(comandoJson.getString("ping")); // System.out.println(comandoJson.getString("ping"));
} else if (comandoJson.containsKey("comando")) { } else if (comandoJson.containsKey("comando")) {
...@@ -155,7 +161,7 @@ public class CommandsBean { ...@@ -155,7 +161,7 @@ public class CommandsBean {
} else { } else {
archivo = archivos.getArchivo(fileId); archivo = archivos.getArchivo(fileId);
} }
this.p_stdin.write("!load " + corregirNombreArchivo(archivo.getNombre())); this.p_stdin.write(String.format("!%s ",this.i18n.get("load")) + corregirNombreArchivo(archivo.getNombre()));
this.p_stdin.newLine(); this.p_stdin.newLine();
this.p_stdin.flush(); this.p_stdin.flush();
...@@ -212,6 +218,16 @@ public class CommandsBean { ...@@ -212,6 +218,16 @@ public class CommandsBean {
p.waitFor(); p.waitFor();
ConfiguracionDTO config = usuarioEJB.getConfiguracion(this.cedula); ConfiguracionDTO config = usuarioEJB.getConfiguracion(this.cedula);
String userLang = "en";
if (session.getUserProperties().containsKey("lang")) {
userLang = (String)session.getUserProperties().get("lang");
}
if (this.i18n == null) {
this.i18n = this.i18nEJB.getLanguage(context.getRealPath("/WEB-INF/classes/edu/proygrado/binarios/i18n"), userLang);
}
if (config != null && config.isArgumentoI() && config.isArgumentoF()) { if (config != null && config.isArgumentoI() && config.isArgumentoF()) {
System.out.println("restart con parametros -i -f"); System.out.println("restart con parametros -i -f");
this.builder = new ProcessBuilder( this.builder = new ProcessBuilder(
...@@ -233,7 +249,8 @@ public class CommandsBean { ...@@ -233,7 +249,8 @@ public class CommandsBean {
this.latch = new CountDownLatch(2); this.latch = new CountDownLatch(2);
Map<String, String> envs = this.builder.environment(); Map<String, String> envs = this.builder.environment();
envs.put("LANGUAGE", "en");
envs.put("LANGUAGE", userLang);
this.proceso = this.builder.start(); this.proceso = this.builder.start();
this.p_stdin = new BufferedWriter(new OutputStreamWriter(proceso.getOutputStream())); this.p_stdin = new BufferedWriter(new OutputStreamWriter(proceso.getOutputStream()));
...@@ -293,6 +310,8 @@ public class CommandsBean { ...@@ -293,6 +310,8 @@ public class CommandsBean {
} }
private Thread outputStandardConsoleThread() { private Thread outputStandardConsoleThread() {
final Map<String, String> _i18n = this.i18n;
Thread inputThread = new Thread(new Runnable() { Thread inputThread = new Thread(new Runnable() {
@Override @Override
public void run() { public void run() {
...@@ -301,13 +320,18 @@ public class CommandsBean { ...@@ -301,13 +320,18 @@ public class CommandsBean {
try { try {
Scanner s = new Scanner(proceso.getInputStream()); Scanner s = new Scanner(proceso.getInputStream());
latch.countDown(); latch.countDown();
Pattern p = Pattern.compile("OUTFigure:(Figure:)*\\[\\]"); Pattern p = Pattern.compile(String.format("OUT%1$s:(%1$s:)*\\[\\]", _i18n.get("Figure")));
Pattern p3d = Pattern.compile("OUT3D Figure:(3D Figure:)*\\[\\]"); Pattern p3d = Pattern.compile(String.format("OUT%1$s:(%1$s:)*\\[\\]",_i18n.get("3D Figure")));
String i18n_OUTFigure = String.format("OUT%s", _i18n.get("Figure"));
String i18n_OUT3D_Figure = String.format("OUT%s", _i18n.get("3D Figure"));
String i18n_OUTGraph = String.format("OUT%s", _i18n.get("Graph"));
ArrayList<String> animacion = new ArrayList<>(); ArrayList<String> animacion = new ArrayList<>();
while (s.hasNextLine()) { while (s.hasNextLine()) {
String result = s.nextLine(); String result = s.nextLine();
//System.out.println(result); // System.out.println(result);
//System.out.println("&&&/////"); // System.out.println("&&&/////");
if (nombrePrompt != "" && result.contains(nombrePrompt + ">")) { if (nombrePrompt != "" && result.contains(nombrePrompt + ">")) {
if (nombrePrompt.length() > 10) { if (nombrePrompt.length() > 10) {
nombrePrompt = nombrePrompt.substring(0, 7) + "..."; nombrePrompt = nombrePrompt.substring(0, 7) + "...";
...@@ -328,12 +352,12 @@ public class CommandsBean { ...@@ -328,12 +352,12 @@ public class CommandsBean {
result = result.substring(index + 6); result = result.substring(index + 6);
animacion.add(result); animacion.add(result);
respuestaJson = null; respuestaJson = null;
} else if (result.equals("OUTFigure")) { } else if (result.equals(i18n_OUTFigure)) {
respuestaJson = Json.createObjectBuilder().add("tipo", "canvas") respuestaJson = Json.createObjectBuilder().add("tipo", "canvas")
.add("resultado", animacion.get(0)).build(); .add("resultado", animacion.get(0)).build();
animacion.clear(); animacion.clear();
} else if (result.equals("OUT3D Figure")) { } else if (result.equals(i18n_OUT3D_Figure)) {
respuestaJson = Json.createObjectBuilder().add("tipo", "canvas3D") respuestaJson = Json.createObjectBuilder().add("tipo", "canvas3D")
.add("resultado", animacion.get(0)).build(); .add("resultado", animacion.get(0)).build();
...@@ -362,7 +386,7 @@ public class CommandsBean { ...@@ -362,7 +386,7 @@ public class CommandsBean {
result = result.substring(index + 6); result = result.substring(index + 6);
respuestaJson = Json.createObjectBuilder().add("tipo", "graph").add("resultado", result) respuestaJson = Json.createObjectBuilder().add("tipo", "graph").add("resultado", result)
.build(); .build();
} else if (result.contains("OUTGraph")) { } else if (result.contains(i18n_OUTGraph)) {
} else { } else {
respuestaJson = Json.createObjectBuilder().add("tipo", "salida") respuestaJson = Json.createObjectBuilder().add("tipo", "salida")
......
package edu.proygrado.ejb;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.io.Reader;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.annotation.PostConstruct;
import javax.ejb.ConcurrencyManagement;
import javax.ejb.ConcurrencyManagementType;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.ejb.LockType;
import javax.ejb.Lock;
import javax.inject.Inject;
import org.apache.commons.text.StringEscapeUtils;
@Singleton
@Startup
@ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
public class I18nEJB {
private Map<String, Map<String, String>> languages;
@PostConstruct
private void Initialize(){
languages = new HashMap<String, Map<String, String>>();
}
@Lock(LockType.READ)
public Map<String, String> getLanguage(String path, String lang) {
if (!this.languages.containsKey(lang)) {
try {
String filePath = String.format("%s/%s.po", path, lang);
this.languages.put(lang, LoadPoFile(filePath));
} catch (FileNotFoundException e) {
System.out.println("File not found exception getLanguage for " + lang + " force loading default: en");
if (!this.languages.containsKey("en")) {
try {
String filePath = String.format("%s/%s.po", path, "en");
this.languages.put("en", LoadPoFile(filePath));
return this.languages.get("en");
} catch (FileNotFoundException e2) {
System.out.println("File not found exception getLanguage for default");
}
}
}
}
return this.languages.get(lang);
}
private Map<String, String> LoadPoFile(String path) throws FileNotFoundException {
Pattern LINE_PATTERN = Pattern.compile("^([\\w_\\[\\]]*)\\s*\\\"(.*)\\\"$");
Map<String, String> resources = new HashMap<String, String>();
File file = new File(path);
LineNumberReader reader = new LineNumberReader(new FileReader(file));
if (reader != null) {
String line = null;
String key = null;
String value = null;
try {
while ((line = reader.readLine()) != null) {
if (line.startsWith("#")) {
// Parsing PO file, comment skipped
} else if (line.trim().length() == 0) {
// Parsing PO file, whitespace line skipped
} else {
Matcher matcher = LINE_PATTERN.matcher(line);
if (matcher.matches()) {
String type = matcher.group(1);
String str = matcher.group(2);
if ("msgid".equals(type)) {
if ( key != null && value != null ) {
// Parsing PO file, key,value pair found [" + key + " => " + value + "]");
resources.put(StringEscapeUtils.unescapeJava(key), StringEscapeUtils.unescapeJava(value));
key = null;
value = null;
}
key = str;
// Parsing PO file, msgid found [" + key + "]");
}
else if ("msgstr".equals(type)) {
value = str;
// Parsing PO file, msgstr found [" + value + "]");
}
else if ( type == null || type.length()==0 ) {
if ( value == null ) {
// Parsing PO file, addition to msgid found
key += str;
}
else {
// Parsing PO file, addition to msgstr found
value += str;
}
}
} else {
// Parsing PO file, invalid syntax
}
}
}
if ( key != null && value != null ) {
// Parsing PO file, key,value pair found [" + key + " => " + value + "]");
resources.put(StringEscapeUtils.unescapeJava(key), StringEscapeUtils.unescapeJava(value));
key = null;
value = null;
}
reader.close();
} catch (IOException e) {
}
}
return resources;
}
}
\ No newline at end of file
...@@ -24,7 +24,7 @@ import edu.proygrado.ejb.CommandsBean; ...@@ -24,7 +24,7 @@ import edu.proygrado.ejb.CommandsBean;
* *
* @author gonzalo * @author gonzalo
*/ */
@ServerEndpoint("/endpoint/{cedula}/{token}") @ServerEndpoint("/endpoint/{cedula}/{token}/{language}")
@Stateful @Stateful
public class WebSocketEndpoint { public class WebSocketEndpoint {
...@@ -40,9 +40,10 @@ public class WebSocketEndpoint { ...@@ -40,9 +40,10 @@ public class WebSocketEndpoint {
} }
@OnOpen @OnOpen
public void onOpen(@PathParam("cedula") String cedula, @PathParam("token") String token, Session session) { public void onOpen(@PathParam("cedula") String cedula, @PathParam("token") String token, @PathParam("language") String language, Session session) {
System.out.println("Nueva conexion cedula:"+cedula+" sessionHashCode:" + session.hashCode()); System.out.println("Nueva conexion cedula:"+cedula+" sessionHashCode:" + session.hashCode());
try { try {
session.getUserProperties().put("lang", language);
commandsBean.restartProcess(cedula, token, session); commandsBean.restartProcess(cedula, token, session);
} catch (InterruptedException e) { } catch (InterruptedException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment