From fc423272e3531ca345130a1e13dce9b686a4a449 Mon Sep 17 00:00:00 2001 From: Massimiliano Assante Date: Wed, 8 Jul 2015 16:47:36 +0000 Subject: [PATCH] most of the part is complete, missing the notification part and bug on newlines not reported. git-svn-id: http://svn.research-infrastructures.eu/public/d4science/gcube/trunk/portal/social-mail-servlet@117104 82a268e6-3cf1-43bd-a215-b396298e98cf --- .classpath | 32 +++ .project | 42 ++++ .settings/.jsdtscope | 13 + .settings/org.eclipse.core.resources.prefs | 3 + .settings/org.eclipse.jdt.core.prefs | 8 + .settings/org.eclipse.m2e.core.prefs | 4 + .settings/org.eclipse.wst.common.component | 11 + ....eclipse.wst.common.project.facet.core.xml | 7 + ...rg.eclipse.wst.jsdt.ui.superType.container | 1 + .../org.eclipse.wst.jsdt.ui.superType.name | 1 + .settings/org.eclipse.wst.validation.prefs | 2 + distro/INSTALL | 2 + distro/LICENSE | 7 + distro/MAINTAINERS | 6 + distro/README | 35 +++ distro/changelog.xml | 5 + distro/descriptor.xml | 48 ++++ distro/profile.xml | 25 ++ distro/svnpath.txt | 1 + pom.xml | 200 +++++++++++++++ .../gcube/portal/socialmail/MailReader.java | 102 ++++++++ .../gcube/portal/socialmail/PeriodicTask.java | 233 ++++++++++++++++++ .../org/gcube/portal/socialmail/Utils.java | 83 +++++++ src/main/resources/clientlog4j.properties | 13 + src/main/webapp/WEB-INF/web.xml | 17 ++ src/main/webapp/index.jsp | 5 + 26 files changed, 906 insertions(+) create mode 100644 .classpath create mode 100644 .project create mode 100644 .settings/.jsdtscope create mode 100644 .settings/org.eclipse.core.resources.prefs create mode 100644 .settings/org.eclipse.jdt.core.prefs create mode 100644 .settings/org.eclipse.m2e.core.prefs create mode 100644 .settings/org.eclipse.wst.common.component create mode 100644 .settings/org.eclipse.wst.common.project.facet.core.xml create mode 100644 .settings/org.eclipse.wst.jsdt.ui.superType.container create mode 100644 .settings/org.eclipse.wst.jsdt.ui.superType.name create mode 100644 .settings/org.eclipse.wst.validation.prefs create mode 100644 distro/INSTALL create mode 100644 distro/LICENSE create mode 100644 distro/MAINTAINERS create mode 100644 distro/README create mode 100644 distro/changelog.xml create mode 100644 distro/descriptor.xml create mode 100644 distro/profile.xml create mode 100644 distro/svnpath.txt create mode 100644 pom.xml create mode 100644 src/main/java/org/gcube/portal/socialmail/MailReader.java create mode 100644 src/main/java/org/gcube/portal/socialmail/PeriodicTask.java create mode 100644 src/main/java/org/gcube/portal/socialmail/Utils.java create mode 100644 src/main/resources/clientlog4j.properties create mode 100644 src/main/webapp/WEB-INF/web.xml create mode 100644 src/main/webapp/index.jsp diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..1151b0d --- /dev/null +++ b/.classpath @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.project b/.project new file mode 100644 index 0000000..cc814fd --- /dev/null +++ b/.project @@ -0,0 +1,42 @@ + + + social-mail-servlet + + + + + + org.eclipse.wst.jsdt.core.javascriptValidator + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.wst.common.project.facet.core.builder + + + + + org.eclipse.wst.validation.validationbuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jem.workbench.JavaEMFNature + org.eclipse.wst.common.modulecore.ModuleCoreNature + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + org.eclipse.wst.common.project.facet.core.nature + org.eclipse.wst.jsdt.core.jsNature + + diff --git a/.settings/.jsdtscope b/.settings/.jsdtscope new file mode 100644 index 0000000..b72a6a4 --- /dev/null +++ b/.settings/.jsdtscope @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..db32697 --- /dev/null +++ b/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,3 @@ +eclipse.preferences.version=1 +encoding//src/main/resources=UTF-8 +encoding/=UTF-8 diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..443e085 --- /dev/null +++ b/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,8 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.source=1.7 diff --git a/.settings/org.eclipse.m2e.core.prefs b/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/.settings/org.eclipse.wst.common.component b/.settings/org.eclipse.wst.common.component new file mode 100644 index 0000000..7bedda1 --- /dev/null +++ b/.settings/org.eclipse.wst.common.component @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/.settings/org.eclipse.wst.common.project.facet.core.xml b/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 0000000..4045d87 --- /dev/null +++ b/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/.settings/org.eclipse.wst.jsdt.ui.superType.container b/.settings/org.eclipse.wst.jsdt.ui.superType.container new file mode 100644 index 0000000..3bd5d0a --- /dev/null +++ b/.settings/org.eclipse.wst.jsdt.ui.superType.container @@ -0,0 +1 @@ +org.eclipse.wst.jsdt.launching.baseBrowserLibrary \ No newline at end of file diff --git a/.settings/org.eclipse.wst.jsdt.ui.superType.name b/.settings/org.eclipse.wst.jsdt.ui.superType.name new file mode 100644 index 0000000..05bd71b --- /dev/null +++ b/.settings/org.eclipse.wst.jsdt.ui.superType.name @@ -0,0 +1 @@ +Window \ No newline at end of file diff --git a/.settings/org.eclipse.wst.validation.prefs b/.settings/org.eclipse.wst.validation.prefs new file mode 100644 index 0000000..04cad8c --- /dev/null +++ b/.settings/org.eclipse.wst.validation.prefs @@ -0,0 +1,2 @@ +disabled=06target +eclipse.preferences.version=1 diff --git a/distro/INSTALL b/distro/INSTALL new file mode 100644 index 0000000..139597f --- /dev/null +++ b/distro/INSTALL @@ -0,0 +1,2 @@ + + diff --git a/distro/LICENSE b/distro/LICENSE new file mode 100644 index 0000000..cdb5851 --- /dev/null +++ b/distro/LICENSE @@ -0,0 +1,7 @@ +gCube System - License +------------------------------------------------------------ + +The gCube/gCore software is licensed as Free Open Source software conveying to the EUPL (http://ec.europa.eu/idabc/eupl). +The software and documentation is provided by its authors/distributors "as is" and no expressed or +implied warranty is given for its use, quality or fitness for a particular case. + diff --git a/distro/MAINTAINERS b/distro/MAINTAINERS new file mode 100644 index 0000000..680cebb --- /dev/null +++ b/distro/MAINTAINERS @@ -0,0 +1,6 @@ +Mantainers +------- + +* Massimiliano Assante (massimiliano.assante@isti.cnr.it), CNR Pisa, + Istituto di Scienza e Tecnologie dell'Informazione "A. Faedo". + diff --git a/distro/README b/distro/README new file mode 100644 index 0000000..3b378a6 --- /dev/null +++ b/distro/README @@ -0,0 +1,35 @@ +The gCube System - Social Library +------------------------------------------------------------ + +This work is partially funded by the European Commission in the +context of the iMarine project (www.i-marine.eu), under the 1st call of FP7 IST priority. + +Authors +------- +Massimiliano Assante +* +Version and Release Date +------------------------ + + + +Description +----------- +Social Mail Servlet + +Download information +-------------------- +Source code is available from SVN: +https://svn.d4science.research-infrastructures.eu/gcube/trunk/portal/social-mail-servlet + +Binaries can be downloaded from: +http://www.gcube-system.org/ + +Documentation +------------- +Documentation is available on-line from the Projects Documentation Wiki: + +Licensing +--------- + +This software is licensed under the terms you may find in the file named "LICENSE" in this directory. diff --git a/distro/changelog.xml b/distro/changelog.xml new file mode 100644 index 0000000..48a2030 --- /dev/null +++ b/distro/changelog.xml @@ -0,0 +1,5 @@ + + + First Release + + diff --git a/distro/descriptor.xml b/distro/descriptor.xml new file mode 100644 index 0000000..4efc827 --- /dev/null +++ b/distro/descriptor.xml @@ -0,0 +1,48 @@ + + servicearchive + + tar.gz + + / + + + ${distroDirectory} + / + true + + README + LICENSE + INSTALL + MAINTAINERS + changelog.xml + + 755 + true + + + target/apidocs + /${artifactId}/doc/api + true + 755 + + + + + ${distroDirectory}/profile.xml + ./ + true + + + target/${build.finalName}.war + /${artifactId} + + + ${distroDirectory}/svnpath.txt + /${artifactId} + true + + + \ No newline at end of file diff --git a/distro/profile.xml b/distro/profile.xml new file mode 100644 index 0000000..4dda0b9 --- /dev/null +++ b/distro/profile.xml @@ -0,0 +1,25 @@ + + + + Library + + ${description} + Portal + ${artifactId} + 1.0.0 + + + ${artifactId} + ${version} + + ${groupId} + ${artifactId} + ${version} + + + ${build.finalName}.war + + + + + diff --git a/distro/svnpath.txt b/distro/svnpath.txt new file mode 100644 index 0000000..edacb04 --- /dev/null +++ b/distro/svnpath.txt @@ -0,0 +1 @@ +${scm.url} \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..756fde0 --- /dev/null +++ b/pom.xml @@ -0,0 +1,200 @@ + + + maven-parent + org.gcube.tools + 1.0.0 + + + + 4.0.0 + org.gcube.portal + social-mail-servlet + war + 1.0.0-SNAPSHOT + social-mail-servlet Maven Webapp + This component read periodically email replies from user wanting to reply to a post via email + + 1.7 + 6.0.6 + ${project.basedir}/distro + ${project.build.directory}/${project.build.finalName} + distro + + UTF-8 + UTF-8 + + + + + http://svn.d4science.research-infrastructures.eu/gcube/trunk/portal/${project.artifactId} + + + + + org.gcube.distribution + maven-portal-bom + LATEST + pom + import + + + + + + org.gcube.common.portal + portal-manager + + + org.gcube.portal + custom-portal-handler + provided + + + org.gcube.applicationsupportlayer + aslcore + provided + + + org.gcube.applicationsupportlayer + aslsocial + provided + + + org.gcube.portal + social-networking-library + provided + + + com.google + gwt-jsonmaker + + + org.gcube.dvos + usermanagement-core + + + org.gcube.resources.discovery + ic-client + + + org.gcube.core + common-encryption + provided + + + com.sun.mail + javax.mail + provided + + + com.liferay.portal + portal-service + provided + + + javax.portlet + portlet-api + provided + + + javax.servlet + servlet-api + 2.3 + provided + + + javax.servlet.jsp + jsp-api + 2.0 + provided + + + org.slf4j + slf4j-api + provided + + + junit + junit + 3.8.1 + test + + + + social-mail-servlet + + + org.apache.maven.plugins + maven-war-plugin + 2.1.1 + + + compile + + exploded + + + + + ${webappDirectory} + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.3.2 + + 1.7 + 1.7 + + + + + org.apache.maven.plugins + maven-assembly-plugin + 2.2 + + + ${distroDirectory}/descriptor.xml + + + + + servicearchive + install + + single + + + + + + org.apache.maven.plugins + maven-resources-plugin + 2.5 + + + copy-profile + install + + copy-resources + + + target + + + ${distroDirectory} + true + + profile.xml + + + + + + + + + + diff --git a/src/main/java/org/gcube/portal/socialmail/MailReader.java b/src/main/java/org/gcube/portal/socialmail/MailReader.java new file mode 100644 index 0000000..6d27a5f --- /dev/null +++ b/src/main/java/org/gcube/portal/socialmail/MailReader.java @@ -0,0 +1,102 @@ +package org.gcube.portal.socialmail; + +import static org.gcube.resources.discovery.icclient.ICFactory.clientFor; +import static org.gcube.resources.discovery.icclient.ICFactory.queryFor; + +import java.io.IOException; +import java.util.List; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.gcube.common.encryption.StringEncrypter; +import org.gcube.common.portal.PortalContext; +import org.gcube.common.resources.gcore.ServiceEndpoint; +import org.gcube.common.resources.gcore.ServiceEndpoint.AccessPoint; +import org.gcube.common.scope.api.ScopeProvider; +import org.gcube.portal.databook.server.DBCassandraAstyanaxImpl; +import org.gcube.portal.databook.server.DatabookStore; +import org.gcube.resources.discovery.client.api.DiscoveryClient; +import org.gcube.resources.discovery.client.queries.api.SimpleQuery; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +@SuppressWarnings("serial") +public class MailReader extends HttpServlet { + + private static final Logger _log = LoggerFactory.getLogger(MailReader.class); + private static final int MINUTES_DELAY = 1; + + private final static ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); + + private static DatabookStore store; + + private static String portalName; + private static String host; + private static String user; + private static String password; + + public void init() { + store = new DBCassandraAstyanaxImpl(); + portalName = PortalContext.getPortalInstanceName(); + + PortalContext context = PortalContext.getConfiguration(); + String scope = "/" + context.getInfrastructureName(); + ScopeProvider.instance.set(scope); + + SimpleQuery query = queryFor(ServiceEndpoint.class); + query.addCondition("$resource/Profile/Category/text() eq 'Portal'"); + query.addCondition("$resource/Profile/Name/text() eq '" + portalName + "'"); + + DiscoveryClient client = clientFor(ServiceEndpoint.class); + + List list = client.submit(query); + if (list == null || list.isEmpty()) { + _log.error("Could not find any Service endpoint registred in the infrastructure for this portal: " + portalName); + } + else if (list.size() > 1) { + _log.warn("Found more than one Service endpoint registred in the infrastructure for this portal: " + portalName); + } + else { + for (ServiceEndpoint res : list) { + AccessPoint found = res.profile().accessPoints().iterator().next(); + host = found.address(); + user = found.username(); + String encrPassword = found.password(); + + try { + password = StringEncrypter.getEncrypter().decrypt( encrPassword); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + + + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + + scheduler.scheduleAtFixedRate(new PeriodicTask(store, portalName, host, user, password), 0, MINUTES_DELAY, TimeUnit.MINUTES); + + String toReturn = "Check Notification Email Started ... "; + response.setContentType("text/html"); + response.getWriter().write(toReturn); + } + + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {} + + public static void main(String[] args) { + new MailReader().init(); + System.out.println("Scheduling periodic task ... "); + //System.out.println(host + user + password); + scheduler.scheduleAtFixedRate(new PeriodicTask(store, portalName, host, user, password), 0, MINUTES_DELAY, TimeUnit.MINUTES); + } + + +} \ No newline at end of file diff --git a/src/main/java/org/gcube/portal/socialmail/PeriodicTask.java b/src/main/java/org/gcube/portal/socialmail/PeriodicTask.java new file mode 100644 index 0000000..b044a22 --- /dev/null +++ b/src/main/java/org/gcube/portal/socialmail/PeriodicTask.java @@ -0,0 +1,233 @@ +package org.gcube.portal.socialmail; + +import java.security.GeneralSecurityException; +import java.util.Date; +import java.util.Properties; +import java.util.UUID; + +import javax.mail.Address; +import javax.mail.BodyPart; +import javax.mail.Flags; +import javax.mail.Folder; +import javax.mail.Message; +import javax.mail.MessagingException; +import javax.mail.Multipart; +import javax.mail.NoSuchProviderException; +import javax.mail.Session; +import javax.mail.Store; +import javax.mail.internet.InternetAddress; +import javax.mail.internet.MimeMessage.RecipientType; + +import org.gcube.application.framework.core.session.ASLSession; +import org.gcube.application.framework.core.session.SessionManager; +import org.gcube.application.framework.core.util.GenderType; +import org.gcube.applicationsupportlayer.social.mailing.EmailPlugin; +import org.gcube.common.portal.PortalContext; +import org.gcube.portal.custom.communitymanager.OrganizationsUtil; +import org.gcube.portal.databook.server.DatabookStore; +import org.gcube.portal.databook.shared.Comment; +import org.gcube.portal.databook.shared.ex.FeedIDNotFoundException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.liferay.portal.kernel.exception.PortalException; +import com.liferay.portal.kernel.exception.SystemException; +import com.liferay.portal.model.User; +import com.liferay.portal.service.UserLocalServiceUtil; +import com.sun.mail.util.MailSSLSocketFactory; + +/** + * + * @author Massimiliano Assante, CNR-ISTI + * + */ +public class PeriodicTask implements Runnable { + private static final Logger _log = LoggerFactory.getLogger(PeriodicTask.class); + + private DatabookStore socialStore; + private String host; + private String mailserver_username; + private String password; + private String portalName; + + public PeriodicTask(DatabookStore store, String portalName, String host, String mailserver_username, String password) { + super(); + this.socialStore = store; + this.portalName = portalName; + this.host = host; + this.mailserver_username = mailserver_username; + this.password = password; + } + + + @Override + public void run() { + //check("pop.isti.cnr.it", "social.post", "kof9044+"); + check(portalName, host, mailserver_username, password); + + } + /** + * @return a fake session usuful for Notifications + */ + private ASLSession getFakeASLSession(String emailAddress) { + String sessionID = UUID.randomUUID().toString(); + PortalContext context = PortalContext.getConfiguration(); + String scope = "/" + context.getInfrastructureName(); + + String username = ""; + long companyId; + try { + companyId = OrganizationsUtil.getCompany().getCompanyId(); + User user = UserLocalServiceUtil.getUserByEmailAddress(companyId, emailAddress); + username = user.getScreenName(); + SessionManager.getInstance().getASLSession(sessionID, username).setScope(scope); + + //add the social information needed by apps + String fullName = user.getFirstName() + " " + user.getLastName(); + String email = user.getEmailAddress(); + String thumbnailURL = "/image/user_male_portrait?img_id="+user.getPortraitId(); + boolean isMale = user.isMale(); + + SessionManager.getInstance().getASLSession(sessionID, username).setUserFullName(fullName); + SessionManager.getInstance().getASLSession(sessionID, username).setUserEmailAddress(email); + SessionManager.getInstance().getASLSession(sessionID, username).setUserAvatarId(thumbnailURL); + SessionManager.getInstance().getASLSession(sessionID, username).setUserGender(isMale? GenderType.MALE : GenderType.FEMALE); + + } catch (PortalException | SystemException e) { + e.printStackTrace(); + } + + + return SessionManager.getInstance().getASLSession(sessionID, username); + } + + public void check(String portalName, String host, String user, String password) { + try { + MailSSLSocketFactory sf = null; + try { + sf = new MailSSLSocketFactory(); + } + catch (GeneralSecurityException e) { + e.printStackTrace(); + } + sf.setTrustAllHosts(true); + + Properties pop3Props = new Properties(); + pop3Props.setProperty("mail.pop3.ssl.enable", "true"); + pop3Props.setProperty("mail.protocol.ssl.trust", host); + pop3Props.put("mail.pop3s.ssl.socketFactory", sf); + pop3Props.setProperty("mail.pop3s.port", "995"); + + + Session emailSession = Session.getDefaultInstance(pop3Props); + //emailSession.setDebug(true); + + //create the POP3 socialStore object and connect with the pop server + Store store = emailSession.getStore("pop3s"); + + store.connect(host, user, password); + + //create the folder object and open it + Folder emailFolder = store.getFolder("INBOX"); + emailFolder.open(Folder.READ_WRITE); + + // retrieve the messages from the folder in an array and print it + Message[] messages = emailFolder.getMessages(); + _log.debug("Found " + messages.length + " new messages ..."); + + for (int i = 0, n = messages.length; i < n; i++) { + Message message = messages[i]; + _log.debug("--------------- FOUND EMAIL ------------------"); + String subject = message.getSubject(); + _log.debug("Parsing email of " + message.getFrom()[0] + " with subject: " + subject); + + String feedId = extractFeedId(message); + String commentText = extractText(portalName, feedId, message); + + String escapedCommentText = Utils.escapeHtmlAndTransformUrl(commentText); + + + Address[] froms = message.getFrom(); + String emailAddress = froms == null ? null : ((InternetAddress) froms[0]).getAddress(); + + ASLSession fakeSession = getFakeASLSession(emailAddress); + + Comment comment = new Comment(UUID.randomUUID().toString(), fakeSession.getUsername(), + new Date(), feedId, escapedCommentText, fakeSession.getUserFullName(), fakeSession.getUserAvatarId()); + + _log.debug("Parsed and escapedCommentText =>" + escapedCommentText); + boolean commentCommitResult = false; + try { + if (socialStore.addComment(comment)) + commentCommitResult = true; + } catch (FeedIDNotFoundException e) { + _log.error("Related post not found for this comment " + e.getMessage()); + e.printStackTrace(); + } + if (commentCommitResult) { //the notify + _log.info("Now the NOTIFICATION SHOULD START!!!!!"); + } + + + message.setFlag(Flags.Flag.DELETED, true); + System.out.println("Marked DELETE for message: " + subject); + } + + //close the socialStore and folder objects + emailFolder.close(true); + store.close(); + + } catch (NoSuchProviderException e) { + e.printStackTrace(); + } catch (MessagingException e) { + e.printStackTrace(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private String extractFeedId(Message message) throws MessagingException { + Address[] emails = message.getRecipients(RecipientType.TO); + String toParse = emails[0].toString(); + int plus = toParse.indexOf('+'); + int at = toParse.indexOf('@'); + if (plus == -1) + return null; + return toParse.substring(plus+1, at); + } + + private String extractText(String portalName, String subjectId, Message message) throws Exception { + Address[] emails = message.getRecipients(RecipientType.TO); + Object messageContent = message.getContent(); + String toParse = null; + // Check if content is pure text/html or in parts + if (messageContent instanceof Multipart) { + _log.debug("Found Multipart Message, getting text part"); + Multipart multipart = (Multipart) messageContent; + BodyPart part = multipart.getBodyPart(0); + part.toString(); + toParse = part.getContent().toString(); + } + else { + _log.debug("Found g text/plain Message, getting text"); + toParse = messageContent.toString(); + } + + String[] lines = toParse.split(System.getProperty("line.separator")); + int until = -1; + for (int i = 0; i < lines.length; i++) { + if (lines[i].contains(EmailPlugin.WRITE_ABOVE_TO_REPLY)) { + until = i; + break; + } + } + String toReturn = ""; + for (int i = 0; i < until; i++) { + if (! ( lines[i].contains(portalName) || lines[i].contains(subjectId) || (lines[i].startsWith("> ") && lines[i].trim().length() < 2)) ) { + toReturn += lines[i]; + } + } + return toReturn; + + } +} diff --git a/src/main/java/org/gcube/portal/socialmail/Utils.java b/src/main/java/org/gcube/portal/socialmail/Utils.java new file mode 100644 index 0000000..36dee71 --- /dev/null +++ b/src/main/java/org/gcube/portal/socialmail/Utils.java @@ -0,0 +1,83 @@ +package org.gcube.portal.socialmail; + +import java.net.MalformedURLException; +import java.net.URL; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class Utils { + private static final Logger _log = LoggerFactory.getLogger(Utils.class); + /** + * Escape an html string. Escaping data received from the client helps to + * prevent cross-site script vulnerabilities. + * + * @param html the html string to escape + * @return the escaped string + */ + protected static String escapeHtmlAndTransformUrl(String html) { + if (html == null) { + return null; + } + String toReturn = html.replaceAll("&", "&").replaceAll("<", "<") + .replaceAll(">", ">"); + + // replace all the line breaks by
+ toReturn = toReturn.replaceAll("(\r\n|\n)","
"); + //transfrom the URL in a clickable URL + toReturn = transformUrls(toReturn); + // then replace all the double spaces by the html version   + toReturn = toReturn.replaceAll("\\s\\s","  "); + return toReturn; + } + /** + * utility method that convert a url ina text in a clickable url by the browser + * and if the user has just pasted a link, converts the link in: shared a link + * @param feedText + * @return the text with the clickable url in it + */ + protected static String transformUrls(String feedText) { + StringBuilder sb = new StringBuilder(); + // separate input by spaces ( URLs have no spaces ) + String [] parts = feedText.split("\\s"); + // Attempt to convert each item into an URL. + for (int i = 0; i < parts.length; i++) { + String toCheck = getHttpToken(parts[i]); + if (toCheck != null) { + try { + URL url = new URL(toCheck); + if (i == 0 && parts.length == 1) //then he shared just a link + return sb.append("shared ").append("a link.").append(" ").toString(); + // If possible then replace with anchor... + sb.append("").append(url).append(" "); + } catch (MalformedURLException e) { + // If there was an URL then it's not valid + _log.error("MalformedURLException returning... "); + return feedText; + } + } else { + sb.append(parts[i]); + sb.append(" "); + } + } + return sb.toString(); + } + /** + * check the tokens of a pasted text and see if there's any http link in it + * @param item a text token + * @return the actual http link + */ + private static String getHttpToken(String item) { + if (item.startsWith("http") || item.startsWith("www") || item.startsWith("(www") || item.startsWith("(http")) { + if (item.startsWith("(")) + item = item.substring(1, item.length()); + if (item.endsWith(".") || item.endsWith(")")) { //sometimes people write the url and close the phrase with a . + item = item.substring(0, item.length()-1); + } + item = item.startsWith("www") ? "http://"+item : item; + //System.out.println("getHttpToken returns -> " + item); + return item; + } + return null; + } +} diff --git a/src/main/resources/clientlog4j.properties b/src/main/resources/clientlog4j.properties new file mode 100644 index 0000000..574c7b1 --- /dev/null +++ b/src/main/resources/clientlog4j.properties @@ -0,0 +1,13 @@ +log4j.rootLogger=DEBUG, A1 +log4j.appender.A1=org.apache.log4j.ConsoleAppender +log4j.appender.A1.layout=org.apache.log4j.PatternLayout + +# Print the date in ISO 8601 format +log4j.appender.A1.layout.ConversionPattern=%d [%t] %-5p %c - %m%n + +# Print only messages of level TRACE or above in the package org.gcube +log4j.logger.org.gcube=TRACE +log4j.logger.org.gcube.application.framework.core.session=INFO +log4j.logger.com.netflix.astyanax.connectionpool=ERROR +log4j.logger.org.gcube.portal.databook.server.DBCassandraAstyanaxImpl=TRACE +log4j.logger.org.gcube.common=ERROR \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000..0dbac63 --- /dev/null +++ b/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,17 @@ + + + + Email Comments Reader Webapp + + + read-mail + org.gcube.portal.socialmail.MailReader + + + read-mail + /read-mail + + + diff --git a/src/main/webapp/index.jsp b/src/main/webapp/index.jsp new file mode 100644 index 0000000..04fa808 --- /dev/null +++ b/src/main/webapp/index.jsp @@ -0,0 +1,5 @@ + + +

Hello From Mail Reader Scheduler service!

+ +