You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2019/04/23 14:54:40 UTC
[sling-org-apache-sling-committer-cli] 31/39: SLING-8368 - Name
comparisons fail when accents are missing
This is an automated email from the ASF dual-hosted git repository.
rombert pushed a commit to branch feature/SLING-8337
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-committer-cli.git
commit f884748ff3aafb3868cc63bf01c53984f0723b5d
Author: Radu Cotescu <ra...@apache.org>
AuthorDate: Fri Apr 19 17:46:25 2019 +0200
SLING-8368 - Name comparisons fail when accents are missing
* made name comparisons ignore accents when looking for a member by name
* if members use their apache email address for emails, then names will
automatically be extracted from Whimsy instead of using the name from
the From/Sender email headers
---
pom.xml | 10 +++
.../java/org/apache/sling/cli/impl/mail/Email.java | 88 +++++++++++++++++++---
.../apache/sling/cli/impl/mail/EmailThread.java | 31 --------
.../sling/cli/impl/mail/VoteThreadFinder.java | 17 ++++-
.../sling/cli/impl/people/MembersFinder.java | 17 ++++-
.../sling/cli/impl/release/TallyVotesCommand.java | 33 ++++----
6 files changed, 135 insertions(+), 61 deletions(-)
diff --git a/pom.xml b/pom.xml
index 0fc0dbd..6cdcf27 100644
--- a/pom.xml
+++ b/pom.xml
@@ -34,6 +34,16 @@
<build>
<plugins>
<plugin>
+ <artifactId>maven-clean-plugin</artifactId>
+ <configuration>
+ <filesets>
+ <fileset>
+ <directory>launcher</directory>
+ </fileset>
+ </filesets>
+ </configuration>
+ </plugin>
+ <plugin>
<groupId>biz.aQute.bnd</groupId>
<artifactId>bnd-maven-plugin</artifactId>
</plugin>
diff --git a/src/main/java/org/apache/sling/cli/impl/mail/Email.java b/src/main/java/org/apache/sling/cli/impl/mail/Email.java
index 54ec66e..e11bfaa 100644
--- a/src/main/java/org/apache/sling/cli/impl/mail/Email.java
+++ b/src/main/java/org/apache/sling/cli/impl/mail/Email.java
@@ -16,33 +16,101 @@
*/
package org.apache.sling.cli.impl.mail;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.util.Properties;
+
+import javax.mail.Address;
+import javax.mail.BodyPart;
+import javax.mail.Message;
+import javax.mail.MessagingException;
+import javax.mail.Session;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.utils.URIBuilder;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+
public class Email {
- private String from;
+
+ private String id;
+ private InternetAddress from;
private String subject;
private String body;
- public String getFrom() {
- return from;
+ public Email(String id) {
+ this.id = id;
+ try (CloseableHttpClient client = HttpClients.createDefault()) {
+ URI uri = new URIBuilder("https://lists.apache.org/api/source.lua/" + URLEncoder.encode(id, StandardCharsets.UTF_8)).build();
+ HttpGet get = new HttpGet(uri);
+ try (CloseableHttpResponse response = client.execute(get)) {
+ try (InputStream content = response.getEntity().getContent()) {
+ if (response.getStatusLine().getStatusCode() != 200) {
+ throw new IOException("Status line : " + response.getStatusLine());
+ }
+ MimeMessage message = new MimeMessage(Session.getDefaultInstance(new Properties()), content);
+ subject = message.getSubject();
+ Address[] who = message.getFrom();
+ if (who.length > 0) {
+ from = (InternetAddress) who[0];
+ }
+ body = getContent(message);
+ }
+ }
+ } catch (URISyntaxException | IOException | MessagingException e) {
+ throw new IllegalArgumentException(e);
+ }
}
- public void setFrom(String from) {
- this.from = from;
+ public String getId() {
+ return id;
+ }
+
+ public InternetAddress getFrom() {
+ return from;
}
public String getSubject() {
return subject;
}
- public void setSubject(String subject) {
- this.subject = subject;
- }
public String getBody() {
return body;
}
- public void setBody(String body) {
- this.body = body;
+ private String getContent(Message message) throws MessagingException, IOException {
+ String result = "";
+ if (message.isMimeType("text/plain")) {
+ result = message.getContent().toString();
+ } else if (message.isMimeType("multipart/*")) {
+ MimeMultipart mimeMultipart = (MimeMultipart) message.getContent();
+ result = getTextFromMimeMultipart(mimeMultipart);
+ }
+ return result;
+ }
+
+ private String getTextFromMimeMultipart(
+ MimeMultipart mimeMultipart) throws MessagingException, IOException {
+ StringBuilder result = new StringBuilder();
+ int count = mimeMultipart.getCount();
+ for (int i = 0; i < count; i++) {
+ BodyPart bodyPart = mimeMultipart.getBodyPart(i);
+ if (bodyPart.isMimeType("text/plain") || bodyPart.isMimeType("text/html")) {
+ result.append("\n").append(bodyPart.getContent());
+ } else if (bodyPart.getContent() instanceof MimeMultipart) {
+ result.append(getTextFromMimeMultipart((MimeMultipart) bodyPart.getContent()));
+ }
+ }
+ return result.toString();
}
}
diff --git a/src/main/java/org/apache/sling/cli/impl/mail/EmailThread.java b/src/main/java/org/apache/sling/cli/impl/mail/EmailThread.java
deleted file mode 100644
index 03ac673..0000000
--- a/src/main/java/org/apache/sling/cli/impl/mail/EmailThread.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.sling.cli.impl.mail;
-
-import java.util.List;
-
-public class EmailThread {
- private List<Email> emails;
-
- public List<Email> getEmails() {
- return emails;
- }
-
- public void setEmails(List<Email> emails) {
- this.emails = emails;
- }
-}
diff --git a/src/main/java/org/apache/sling/cli/impl/mail/VoteThreadFinder.java b/src/main/java/org/apache/sling/cli/impl/mail/VoteThreadFinder.java
index 0d39968..f48baa1 100644
--- a/src/main/java/org/apache/sling/cli/impl/mail/VoteThreadFinder.java
+++ b/src/main/java/org/apache/sling/cli/impl/mail/VoteThreadFinder.java
@@ -21,6 +21,8 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.List;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
@@ -29,12 +31,14 @@ import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.osgi.service.component.annotations.Component;
-import com.google.gson.Gson;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonParser;
@Component(service = VoteThreadFinder.class)
public class VoteThreadFinder {
- public EmailThread findVoteThread(String releaseName) throws IOException {
+ public List<Email> findVoteThread(String releaseName) throws IOException {
try ( CloseableHttpClient client = HttpClients.createDefault() ) {
URI uri = new URIBuilder("https://lists.apache.org/api/stats.lua")
@@ -50,8 +54,13 @@ public class VoteThreadFinder {
InputStreamReader reader = new InputStreamReader(content)) {
if ( response.getStatusLine().getStatusCode() != 200 )
throw new IOException("Status line : " + response.getStatusLine());
- Gson gson = new Gson();
- return gson.fromJson(reader, EmailThread.class);
+ JsonParser parser = new JsonParser();
+ JsonArray emailsArray = parser.parse(reader).getAsJsonObject().get("emails").getAsJsonArray();
+ List<Email> emails = new ArrayList<>();
+ for (JsonElement email : emailsArray) {
+ emails.add(new Email(email.getAsJsonObject().get("id").getAsString()));
+ }
+ return emails;
}
}
} catch (URISyntaxException e) {
diff --git a/src/main/java/org/apache/sling/cli/impl/people/MembersFinder.java b/src/main/java/org/apache/sling/cli/impl/people/MembersFinder.java
index 70b5469..c26ab9a 100644
--- a/src/main/java/org/apache/sling/cli/impl/people/MembersFinder.java
+++ b/src/main/java/org/apache/sling/cli/impl/people/MembersFinder.java
@@ -21,8 +21,10 @@ package org.apache.sling.cli.impl.people;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
+import java.text.Collator;
import java.util.Collections;
import java.util.HashSet;
+import java.util.Locale;
import java.util.Set;
import org.apache.http.client.methods.CloseableHttpResponse;
@@ -103,7 +105,7 @@ public class MembersFinder {
return members;
}
- public Member getMemberById(String id) {
+ public Member findById(String id) {
for (Member member : findMembers()) {
if (id.equals(member.getId())) {
return member;
@@ -112,8 +114,19 @@ public class MembersFinder {
return null;
}
+ public Member findByNameOrEmail(String name, String email) {
+ Collator collator = Collator.getInstance(Locale.US);
+ collator.setDecomposition(Collator.NO_DECOMPOSITION);
+ for (Member member : findMembers()) {
+ if (email.equals(member.getEmail()) || collator.compare(name, member.getName()) == 0) {
+ return member;
+ }
+ }
+ return null;
+ }
+
public Member getCurrentMember() {
- return getMemberById(credentialsService.getCredentials().getUsername());
+ return findById(credentialsService.getCredentials().getUsername());
}
}
diff --git a/src/main/java/org/apache/sling/cli/impl/release/TallyVotesCommand.java b/src/main/java/org/apache/sling/cli/impl/release/TallyVotesCommand.java
index fb3ca95..93dbf0a 100644
--- a/src/main/java/org/apache/sling/cli/impl/release/TallyVotesCommand.java
+++ b/src/main/java/org/apache/sling/cli/impl/release/TallyVotesCommand.java
@@ -17,14 +17,15 @@
package org.apache.sling.cli.impl.release;
import java.io.IOException;
+import java.text.Collator;
import java.util.Arrays;
-import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.Locale;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.sling.cli.impl.Command;
import org.apache.sling.cli.impl.mail.Email;
-import org.apache.sling.cli.impl.mail.EmailThread;
import org.apache.sling.cli.impl.mail.VoteThreadFinder;
import org.apache.sling.cli.impl.nexus.StagingRepository;
import org.apache.sling.cli.impl.nexus.StagingRepositoryFinder;
@@ -84,24 +85,28 @@ public class TallyVotesCommand implements Command {
.stream()
.map(Release::getFullName)
.collect(Collectors.joining(", "));
- EmailThread voteThread = voteThreadFinder.findVoteThread(releaseName);
- Set<String> bindingVoters = new HashSet<>();
- Set<String> nonBindingVoters = new HashSet<>();
- for (Email e : voteThread.getEmails()) {
- if (isPositiveVote(e)) {
- String sender = e.getFrom().replaceAll("<.*>", "").trim();
- for (Member m : membersFinder.findMembers()) {
- if (sender.equals(m.getName())) {
+ Set<String> bindingVoters = new LinkedHashSet<>();
+ Set<String> nonBindingVoters = new LinkedHashSet<>();
+ Collator collator = Collator.getInstance(Locale.US);
+ collator.setDecomposition(Collator.NO_DECOMPOSITION);
+ voteThreadFinder.findVoteThread(releaseName).stream().skip(1).filter(this::isPositiveVote).forEachOrdered(
+ email -> {
+ String from = email.getFrom().getAddress();
+ String name = email.getFrom().getPersonal();
+ Member m = membersFinder.findByNameOrEmail(name, from);
+ if (m != null) {
if (m.isPMCMember()) {
- bindingVoters.add(sender);
+ bindingVoters.add(m.getName());
} else {
- nonBindingVoters.add(sender);
+ nonBindingVoters.add(m.getName());
}
+ } else {
+ nonBindingVoters.add(name);
}
}
- }
- }
+ );
+
String email = EMAIL_TEMPLATE
.replace("##RELEASE_NAME##", releaseFullName)
.replace("##BINDING_VOTERS##", String.join(", ", bindingVoters))