1452: Implement a GUI for StatMan Algorithms Importer
Task-Url: https://support.d4science.org/issues/1452 Added NotificationRecipients.txt properties file git-svn-id: https://svn.d4science.research-infrastructures.eu/gcube/trunk/portlets/user/statistical-algorithms-importer@122305 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
parent
6e58b9ed3b
commit
7920e8301b
12
pom.xml
12
pom.xml
|
@ -195,8 +195,8 @@
|
||||||
<artifactId>aslsocial</artifactId>
|
<artifactId>aslsocial</artifactId>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Notification -->
|
<!-- Notification -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.gcube.portal</groupId>
|
<groupId>org.gcube.portal</groupId>
|
||||||
<artifactId>notifications-common-library</artifactId>
|
<artifactId>notifications-common-library</artifactId>
|
||||||
|
@ -240,6 +240,14 @@
|
||||||
<version>1.0.3</version>
|
<version>1.0.3</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- JSON -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.json</groupId>
|
||||||
|
<artifactId>json</artifactId>
|
||||||
|
<version>20151123</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
<!-- AceGWT Widget -->
|
<!-- AceGWT Widget -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.gcube.portlets.widgets</groupId>
|
<groupId>org.gcube.portlets.widgets</groupId>
|
||||||
|
|
|
@ -34,6 +34,9 @@ public class CodeParser {
|
||||||
if (parameter.contains("<-")) {
|
if (parameter.contains("<-")) {
|
||||||
String[] varDescription = parameter.split("<-");
|
String[] varDescription = parameter.split("<-");
|
||||||
String defaultValue = varDescription[1].trim();
|
String defaultValue = varDescription[1].trim();
|
||||||
|
if (defaultValue.endsWith(";"))
|
||||||
|
defaultValue = defaultValue.substring(0,
|
||||||
|
defaultValue.length() - 1);
|
||||||
if (defaultValue.startsWith("\""))
|
if (defaultValue.startsWith("\""))
|
||||||
defaultValue = defaultValue.substring(1);
|
defaultValue = defaultValue.substring(1);
|
||||||
if (defaultValue.endsWith("\""))
|
if (defaultValue.endsWith("\""))
|
||||||
|
@ -48,6 +51,9 @@ public class CodeParser {
|
||||||
if (parameter.contains("=")) {
|
if (parameter.contains("=")) {
|
||||||
String[] varDescription = parameter.split("=");
|
String[] varDescription = parameter.split("=");
|
||||||
String defaultValue = varDescription[1].trim();
|
String defaultValue = varDescription[1].trim();
|
||||||
|
if (defaultValue.endsWith(";"))
|
||||||
|
defaultValue = defaultValue.substring(0,
|
||||||
|
defaultValue.length() - 1);
|
||||||
if (defaultValue.startsWith("\""))
|
if (defaultValue.startsWith("\""))
|
||||||
defaultValue = defaultValue.substring(1);
|
defaultValue = defaultValue.substring(1);
|
||||||
if (defaultValue.endsWith("\""))
|
if (defaultValue.endsWith("\""))
|
||||||
|
|
|
@ -29,7 +29,7 @@ public interface CodeEditMessages extends Messages {
|
||||||
@DefaultMessage("Add output variable from code")
|
@DefaultMessage("Add output variable from code")
|
||||||
String btnAddOutputToolTip();
|
String btnAddOutputToolTip();
|
||||||
|
|
||||||
@DefaultMessage("Code:")
|
@DefaultMessage("Main:")
|
||||||
String mainCodeFiledLabel();
|
String mainCodeFiledLabel();
|
||||||
|
|
||||||
@DefaultMessage("Select parameter in the code!")
|
@DefaultMessage("Select parameter in the code!")
|
||||||
|
|
|
@ -8,5 +8,5 @@
|
||||||
|
|
||||||
|
|
||||||
#drop_target_inner {
|
#drop_target_inner {
|
||||||
background-image: url("images/explorer_dragndrop.png") !important;
|
background-image: url("statalgoimporter/images/explorer_dragndrop.png") !important;
|
||||||
}
|
}
|
|
@ -20,7 +20,7 @@ public interface StatAlgoImporterResources extends ClientBundle {
|
||||||
|
|
||||||
@Source("StatAlgoImporter.css")
|
@Source("StatAlgoImporter.css")
|
||||||
StatAlgoImporterCSS srCSS();
|
StatAlgoImporterCSS srCSS();
|
||||||
|
|
||||||
@Source("help_32.png")
|
@Source("help_32.png")
|
||||||
ImageResource help32();
|
ImageResource help32();
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,9 @@
|
||||||
*/
|
*/
|
||||||
package org.gcube.portlets.user.statisticalalgorithmsimporter.server;
|
package org.gcube.portlets.user.statisticalalgorithmsimporter.server;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
import javax.servlet.http.HttpSession;
|
import javax.servlet.http.HttpSession;
|
||||||
|
|
||||||
import org.gcube.application.framework.core.session.ASLSession;
|
import org.gcube.application.framework.core.session.ASLSession;
|
||||||
|
@ -10,6 +13,7 @@ import org.gcube.application.framework.core.session.SessionManager;
|
||||||
import org.gcube.common.scope.api.ScopeProvider;
|
import org.gcube.common.scope.api.ScopeProvider;
|
||||||
import org.gcube.portal.custom.scopemanager.scopehelper.ScopeHelper;
|
import org.gcube.portal.custom.scopemanager.scopehelper.ScopeHelper;
|
||||||
import org.gcube.portlets.user.statisticalalgorithmsimporter.server.file.CodeFileUploadSession;
|
import org.gcube.portlets.user.statisticalalgorithmsimporter.server.file.CodeFileUploadSession;
|
||||||
|
import org.gcube.portlets.user.statisticalalgorithmsimporter.server.social.Recipient;
|
||||||
import org.gcube.portlets.user.statisticalalgorithmsimporter.shared.Constants;
|
import org.gcube.portlets.user.statisticalalgorithmsimporter.shared.Constants;
|
||||||
import org.gcube.portlets.user.statisticalalgorithmsimporter.shared.exception.StatAlgoImporterSessionExpiredException;
|
import org.gcube.portlets.user.statisticalalgorithmsimporter.shared.exception.StatAlgoImporterSessionExpiredException;
|
||||||
import org.gcube.portlets.user.statisticalalgorithmsimporter.shared.file.FileUploadMonitor;
|
import org.gcube.portlets.user.statisticalalgorithmsimporter.shared.file.FileUploadMonitor;
|
||||||
|
@ -61,6 +65,21 @@ public class SessionUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
public static ArrayList<Recipient> getRecipients(ServletContext servletContest) {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
ArrayList<Recipient> recipients=(ArrayList<Recipient>)servletContest.getAttribute(Constants.RECIPIENTS);
|
||||||
|
return recipients;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ArrayList<Recipient> setRecipients(ServletContext servletContest, ArrayList<Recipient> recipients) {
|
||||||
|
servletContest.setAttribute(Constants.RECIPIENTS,recipients);
|
||||||
|
return recipients;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
public static FileUploadMonitor getFileUploadMonitor(HttpSession httpSession) {
|
public static FileUploadMonitor getFileUploadMonitor(HttpSession httpSession) {
|
||||||
FileUploadMonitor fileUploadMonitor = (FileUploadMonitor) httpSession
|
FileUploadMonitor fileUploadMonitor = (FileUploadMonitor) httpSession
|
||||||
|
|
|
@ -1,15 +1,20 @@
|
||||||
package org.gcube.portlets.user.statisticalalgorithmsimporter.server;
|
package org.gcube.portlets.user.statisticalalgorithmsimporter.server;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.http.HttpSession;
|
import javax.servlet.http.HttpSession;
|
||||||
|
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.gcube.application.framework.core.session.ASLSession;
|
import org.gcube.application.framework.core.session.ASLSession;
|
||||||
import org.gcube.portlets.user.statisticalalgorithmsimporter.client.rpc.StatAlgoImporterService;
|
import org.gcube.portlets.user.statisticalalgorithmsimporter.client.rpc.StatAlgoImporterService;
|
||||||
import org.gcube.portlets.user.statisticalalgorithmsimporter.server.file.CodeReader;
|
import org.gcube.portlets.user.statisticalalgorithmsimporter.server.file.CodeReader;
|
||||||
import org.gcube.portlets.user.statisticalalgorithmsimporter.server.generator.ProjectBuilder;
|
import org.gcube.portlets.user.statisticalalgorithmsimporter.server.generator.ProjectBuilder;
|
||||||
import org.gcube.portlets.user.statisticalalgorithmsimporter.server.social.AlgorithmNotification;
|
import org.gcube.portlets.user.statisticalalgorithmsimporter.server.social.AlgorithmNotification;
|
||||||
|
import org.gcube.portlets.user.statisticalalgorithmsimporter.server.social.Recipient;
|
||||||
import org.gcube.portlets.user.statisticalalgorithmsimporter.server.storage.FilesStorage;
|
import org.gcube.portlets.user.statisticalalgorithmsimporter.server.storage.FilesStorage;
|
||||||
import org.gcube.portlets.user.statisticalalgorithmsimporter.server.storage.MainCodeSave;
|
import org.gcube.portlets.user.statisticalalgorithmsimporter.server.storage.MainCodeSave;
|
||||||
import org.gcube.portlets.user.statisticalalgorithmsimporter.server.storage.ProjectArchiver;
|
import org.gcube.portlets.user.statisticalalgorithmsimporter.server.storage.ProjectArchiver;
|
||||||
|
@ -22,6 +27,8 @@ import org.gcube.portlets.user.statisticalalgorithmsimporter.shared.project.Proj
|
||||||
import org.gcube.portlets.user.statisticalalgorithmsimporter.shared.project.ProjectFolder;
|
import org.gcube.portlets.user.statisticalalgorithmsimporter.shared.project.ProjectFolder;
|
||||||
import org.gcube.portlets.user.statisticalalgorithmsimporter.shared.session.UserInfo;
|
import org.gcube.portlets.user.statisticalalgorithmsimporter.shared.session.UserInfo;
|
||||||
import org.gcube.portlets.user.statisticalalgorithmsimporter.shared.workspace.ItemDescription;
|
import org.gcube.portlets.user.statisticalalgorithmsimporter.shared.workspace.ItemDescription;
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONObject;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -49,7 +56,35 @@ public class StatAlgoImporterServiceImpl extends RemoteServiceServlet implements
|
||||||
System.setProperty("jdk.xml.entityExpansionLimit", "0");
|
System.setProperty("jdk.xml.entityExpansionLimit", "0");
|
||||||
|
|
||||||
System.out.println("initializing StatAlgoImporterService");
|
System.out.println("initializing StatAlgoImporterService");
|
||||||
|
String notificationRecipientsFile = "/statalgoimporter/properties/NotificationRecipients.txt";
|
||||||
|
InputStream notificationRecipientsInputStream = this.getServletContext()
|
||||||
|
.getResourceAsStream(notificationRecipientsFile);
|
||||||
|
String text = null;
|
||||||
|
try {
|
||||||
|
text = IOUtils.toString(notificationRecipientsInputStream,
|
||||||
|
StandardCharsets.UTF_8.name());
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.out.println(e.getLocalizedMessage());
|
||||||
|
System.out.println(e.getStackTrace().toString());
|
||||||
|
}
|
||||||
|
ArrayList<Recipient> recipients = new ArrayList<Recipient>();
|
||||||
|
|
||||||
|
JSONObject obj = new JSONObject(text);
|
||||||
|
System.out.println(""+obj);
|
||||||
|
JSONArray arr = obj.getJSONArray("recipients");
|
||||||
|
for (int i = 0; i < arr.length(); i++) {
|
||||||
|
JSONObject dest = arr.getJSONObject(i);
|
||||||
|
System.out.println("" + dest);
|
||||||
|
String user = dest.getString("user");
|
||||||
|
String surname = dest.getString("surname");
|
||||||
|
String name = dest.getString("name");
|
||||||
|
Recipient rec = new Recipient(user, surname, name);
|
||||||
|
recipients.add(rec);
|
||||||
|
|
||||||
|
}
|
||||||
|
System.out.println("Recipients: "+recipients);
|
||||||
|
SessionUtil.setRecipients(this.getServletContext(), recipients);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -422,9 +457,9 @@ public class StatAlgoImporterServiceImpl extends RemoteServiceServlet implements
|
||||||
SessionUtil.setProjectSession(session, project);
|
SessionUtil.setProjectSession(session, project);
|
||||||
ProjectBuilder projectBuilder = new ProjectBuilder(project,
|
ProjectBuilder projectBuilder = new ProjectBuilder(project,
|
||||||
aslSession, session);
|
aslSession, session);
|
||||||
project=projectBuilder.build();
|
project = projectBuilder.build();
|
||||||
SessionUtil.setProjectSession(session, project);
|
SessionUtil.setProjectSession(session, project);
|
||||||
ProjectArchiver.archive(project, aslSession);
|
ProjectArchiver.archive(project, aslSession);
|
||||||
} else {
|
} else {
|
||||||
throw new StatAlgoImporterServiceException("No project open!");
|
throw new StatAlgoImporterServiceException("No project open!");
|
||||||
}
|
}
|
||||||
|
@ -469,6 +504,7 @@ public class StatAlgoImporterServiceImpl extends RemoteServiceServlet implements
|
||||||
HttpSession session = this.getThreadLocalRequest().getSession();
|
HttpSession session = this.getThreadLocalRequest().getSession();
|
||||||
ASLSession aslSession = SessionUtil.getAslSession(session);
|
ASLSession aslSession = SessionUtil.getAslSession(session);
|
||||||
logger.debug("PublishSoftware()");
|
logger.debug("PublishSoftware()");
|
||||||
|
ArrayList<Recipient> recipients=SessionUtil.getRecipients(session.getServletContext());
|
||||||
Project project = SessionUtil.getProjectSession(session);
|
Project project = SessionUtil.getProjectSession(session);
|
||||||
if (project != null && project.getProjectTarget() != null
|
if (project != null && project.getProjectTarget() != null
|
||||||
&& project.getProjectTarget().getTargetFolder() != null
|
&& project.getProjectTarget().getTargetFolder() != null
|
||||||
|
@ -477,10 +513,11 @@ public class StatAlgoImporterServiceImpl extends RemoteServiceServlet implements
|
||||||
&& project.getProjectTarget().getIntegrationInfo() != null
|
&& project.getProjectTarget().getIntegrationInfo() != null
|
||||||
&& project.getProjectTarget().getPackageUrl() != null) {
|
&& project.getProjectTarget().getPackageUrl() != null) {
|
||||||
AlgorithmNotification notify = new AlgorithmNotification(
|
AlgorithmNotification notify = new AlgorithmNotification(
|
||||||
aslSession, project);
|
aslSession, project, recipients);
|
||||||
notify.run();
|
notify.run();
|
||||||
} else {
|
} else {
|
||||||
throw new StatAlgoImporterServiceException("The software was not created correctly try to recreate it!");
|
throw new StatAlgoImporterServiceException(
|
||||||
|
"The software was not created correctly try to recreate it!");
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package org.gcube.portlets.user.statisticalalgorithmsimporter.server.social;
|
package org.gcube.portlets.user.statisticalalgorithmsimporter.server.social;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.gcube.application.framework.core.session.ASLSession;
|
import org.gcube.application.framework.core.session.ASLSession;
|
||||||
|
@ -31,17 +30,20 @@ public class AlgorithmNotification extends Thread {
|
||||||
private ASLSession aslSession;
|
private ASLSession aslSession;
|
||||||
// private NotificationType notificationType;
|
// private NotificationType notificationType;
|
||||||
private Project project;
|
private Project project;
|
||||||
|
private ArrayList<Recipient> recipients;
|
||||||
|
|
||||||
public AlgorithmNotification(ASLSession aslSession, Project project) {
|
public AlgorithmNotification(ASLSession aslSession, Project project,
|
||||||
|
ArrayList<Recipient> recipients) {
|
||||||
this.aslSession = aslSession;
|
this.aslSession = aslSession;
|
||||||
this.project = project;
|
this.project = project;
|
||||||
|
this.recipients = recipients;
|
||||||
// this.notificationType = NotificationType.SAI_ALGORITHM_PUBLICATION;
|
// this.notificationType = NotificationType.SAI_ALGORITHM_PUBLICATION;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void run() {
|
public void run() {
|
||||||
algorithmPublicationEmail();
|
algorithmPublicationEmail();
|
||||||
}
|
}
|
||||||
|
|
||||||
// private void algorithmPublicationNotify() {
|
// private void algorithmPublicationNotify() {
|
||||||
// NotificationsManager nm = new ApplicationNotificationsManager(
|
// NotificationsManager nm = new ApplicationNotificationsManager(
|
||||||
|
@ -100,23 +102,28 @@ public class AlgorithmNotification extends Thread {
|
||||||
logger.error("AlgorithmPublicationEmail(): "
|
logger.error("AlgorithmPublicationEmail(): "
|
||||||
+ e.getLocalizedMessage());
|
+ e.getLocalizedMessage());
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<GenericItemBean> retrieveRecipients() {
|
private List<GenericItemBean> retrieveRecipients() {
|
||||||
List<GenericItemBean> recipients = new ArrayList<GenericItemBean>();
|
List<GenericItemBean> genericItemBeanRecipients = new ArrayList<GenericItemBean>();
|
||||||
recipients.add(new GenericItemBean("gianpaolo.coro", "gianpaolo.coro",
|
for (Recipient recipient : recipients) {
|
||||||
"Gianpaolo" + " " + "Coro", ""));
|
genericItemBeanRecipients.add(new GenericItemBean(recipient
|
||||||
recipients.add(new GenericItemBean("giancarlo.panichi",
|
.getUser(), recipient.getUser(), recipient.getName() + " "
|
||||||
"giancarlo.panichi", "Giancarlo" + " " + "Panichi", ""));
|
+ recipient.getSurname(), ""));
|
||||||
|
}
|
||||||
|
|
||||||
return recipients;
|
return genericItemBeanRecipients;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<String> retrieveListAddressee() {
|
private List<String> retrieveListAddressee() {
|
||||||
return Arrays.asList("gianpaolo.coro", "giancarlo.panichi");
|
ArrayList<String> addressee = new ArrayList<String>();
|
||||||
|
for (Recipient recipient : recipients) {
|
||||||
|
addressee.add(recipient.getUser());
|
||||||
|
}
|
||||||
|
return addressee;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
package org.gcube.portlets.user.statisticalalgorithmsimporter.server.social;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Giancarlo Panichi email: <a
|
||||||
|
* href="mailto:g.panichi@isti.cnr.it">g.panichi@isti.cnr.it</a>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class Recipient implements Serializable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = -3951811134381609022L;
|
||||||
|
private String user;
|
||||||
|
private String surname;
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public Recipient(String user, String surname, String name) {
|
||||||
|
super();
|
||||||
|
this.user = user;
|
||||||
|
this.surname = surname;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUser() {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUser(String user) {
|
||||||
|
this.user = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSurname() {
|
||||||
|
return surname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSurname(String surname) {
|
||||||
|
this.surname = surname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Recipient [user=" + user + ", surname=" + surname + ", name="
|
||||||
|
+ name + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -17,6 +17,7 @@ public class Constants {
|
||||||
public final static String DEFAULT_SCOPE = "/gcube/devsec/devVRE";
|
public final static String DEFAULT_SCOPE = "/gcube/devsec/devVRE";
|
||||||
public static final String FILE_UPLOADED_FIELD = "FileUploadedField";
|
public static final String FILE_UPLOADED_FIELD = "FileUploadedField";
|
||||||
public static final String STATISTICAL_ALGORITHMS_IMPORTER_JAR_PUBLIC_LINK = "JarPublicLink";
|
public static final String STATISTICAL_ALGORITHMS_IMPORTER_JAR_PUBLIC_LINK = "JarPublicLink";
|
||||||
|
public static final String RECIPIENTS = "Recipients";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,5 +7,5 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
#drop_target_inner {
|
#drop_target_inner {
|
||||||
background-image: url("images/explorer_dragndrop.png") !important;
|
background-image: url("statalgoimporter/images/explorer_dragndrop.png") !important;
|
||||||
}
|
}
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
@ -0,0 +1,2 @@
|
||||||
|
{ "recipients": [ { "user":"giancarlo.panichi", "surname":"Panichi", "name":"Giancarlo"},
|
||||||
|
{ "user":"gianpaolo.coro", "surname":"Coro", "name":"Gianpaolo"} ] }
|
Loading…
Reference in New Issue