mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-08 13:20:57 +00:00
Merge remote-tracking branch 'server/bug3785' into bug3785
This commit is contained in:
commit
1fa86545a8
8 files changed
+198
-53
No files matched your search
@@ -9,6 +9,7 @@ Bundle-RequiredExecutionEnvironment: JavaSE-1.8
|
||||
Import-Package: com.sap.sailing.server.gateway.deserialization,
|
||||
javax.mail;version="1.4.0",
|
||||
javax.mail.internet;version="1.4.0",
|
||||
javax.mail.util;version="1.4.0",
|
||||
org.json.simple,
|
||||
org.json.simple.parser,
|
||||
org.osgi.framework;version="1.3.0",
|
||||
|
||||
+89
-30
@@ -1,33 +1,92 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>${title}</title>
|
||||
<style type="text/css">
|
||||
.textContainer {
|
||||
margin: 10px;
|
||||
}
|
||||
.buttonContainer {
|
||||
display: inline-block;
|
||||
}
|
||||
.linkButton, .linkButton:active, .linkButton:visited {
|
||||
padding: 15px;
|
||||
margin: 10px;
|
||||
width: 200px;
|
||||
display: inline-block;
|
||||
background-color: #337ab7;
|
||||
border-radius: 4px;
|
||||
color: #ffffff;
|
||||
border: 1px solid #2e6da4;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.linkButton:hover {
|
||||
background-color: #2b618e;
|
||||
border: 1px solid #204d74;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
${body}
|
||||
</body>
|
||||
<head>
|
||||
<title>${title}</title>
|
||||
<style type="text/css">
|
||||
.content {
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.buttonContainer {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.linkButton, .linkButton:active, .linkButton:visited {
|
||||
padding: 15px;
|
||||
margin: 10px 10px 0px 0px;
|
||||
display: inline-block;
|
||||
background-color: #337ab7;
|
||||
border-radius: 4px;
|
||||
color: #ffffff;
|
||||
border: 1px solid #2e6da4;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.linkButton:hover {
|
||||
background-color: #2b618e;
|
||||
border: 1px solid #204d74;
|
||||
}
|
||||
|
||||
.body {
|
||||
background-color: #e3e3e3;
|
||||
color: black;
|
||||
padding: 40px;
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
margin-bottom: 100px;
|
||||
font-family: 'Open Sans', sans-serif;
|
||||
}
|
||||
|
||||
.main {
|
||||
border: 1px solid black;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.header {
|
||||
background-color: black;
|
||||
padding: 10px;
|
||||
font-size: 16px;
|
||||
border-bottom: .2em solid #efaa00;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 20px 30px;
|
||||
min-height: 200px;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin: 30px 10% 200px 10%;
|
||||
text-align: center;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.sapLogo {
|
||||
height: 30px;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.sailingAnalytics {
|
||||
display: inline-block;
|
||||
line-height: 30px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body style="margin: 0px;padding: 0px;">
|
||||
<div class="body">
|
||||
<div class="main">
|
||||
<div class="header">
|
||||
<img src="cid:saplogo" class="sapLogo"/><span class="sailingAnalytics">Sailing Analytics</span>
|
||||
</div>
|
||||
<div class="content">
|
||||
${content}
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
<p>${subscription_information}</p>
|
||||
<p>${site}</p>
|
||||
<p>${footer_links}</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 6.2 KiB |
@@ -26,3 +26,8 @@ competitorScoreCorrectionBody=New results for competitor {0} in {1} are availabl
|
||||
boatClassUpcomingRaceSubject=A race for boat class {0} will start soon
|
||||
# 0: boatClassName, 1: raceDescription, 2: time
|
||||
boatClassUpcomingRaceBody=For boat class {0} {1} will start approximately at {2}.
|
||||
|
||||
subscriptionInformation=You are receiving notifications from SAP Sailing Analytics. To turn off notifications, please visit your profile at the link below.
|
||||
userProfile=User Profile
|
||||
imprint=Imprint
|
||||
privacy=Privacy
|
||||
@@ -3,26 +3,31 @@ raceInFleetInRegattaOfEvent=Wettfahrt {0} ({3}) der Regatta "{1}" bei Veranstalt
|
||||
leaderboardOfEvent=Rangliste "{0}" bei Veranstaltung "{1}"
|
||||
|
||||
leaderboardShowResultsLinkTitle=Ergebnisse anzeigen
|
||||
racesOverviewLinkTitle=Wettfahrtübersicht anzeigen
|
||||
racesOverviewLinkTitle=Wettfahrtübersicht anzeigen
|
||||
raceboardShowRaceLinkTitle=Wettfahrt anzeigen
|
||||
raceboardRaceAnalysisLinkTitle=Wettfahrtanalyse anzeigen
|
||||
|
||||
boatClassRaceFinishedSubject=Wettfahrt für Bootsklasse {0} beendet - Neue Ergebnisse verfügbar
|
||||
boatClassRaceFinishedSubject=Wettfahrt für Bootsklasse {0} beendet - Neue Ergebnisse verfügbar
|
||||
# 0: boatClassName, 1: raceDescription
|
||||
boatClassRaceFinishedBody=Neue Ergebnisse für Bootsklasse {0} in {1} sind verfügbar.
|
||||
boatClassRaceFinishedBody=Neue Ergebnisse für Bootsklasse {0} in {1} sind verfügbar.
|
||||
|
||||
boatClassScoreCorrectionSubject=Neue Ergebnisse für Bootsklasse {0} verfügbar
|
||||
boatClassScoreCorrectionSubject=Neue Ergebnisse für Bootsklasse {0} verfügbar
|
||||
# 0: boatClassName, 1: leaderboardDescription
|
||||
boatClassScoreCorrectionBody=Neue Ergebnisse für Bootsklasse {0} in {1} sind verfügbar.
|
||||
boatClassScoreCorrectionBody=Neue Ergebnisse für Bootsklasse {0} in {1} sind verfügbar.
|
||||
|
||||
competitorPassesFinishSubject=Teilnehmer {0} hat eine Wettfahrt beendet
|
||||
# 0: competitorName, 1: raceDescription
|
||||
competitorPassesFinishBody=Teilnehmer {0} hat bei {1} die Ziellinie überquert.
|
||||
competitorPassesFinishBody=Teilnehmer {0} hat bei {1} die Ziellinie überquert.
|
||||
|
||||
competitorScoreCorrectionSubject=Neue Ergebnisse für Teilnehmer {0}
|
||||
competitorScoreCorrectionSubject=Neue Ergebnisse für Teilnehmer {0}
|
||||
# 0: competitorName, 1: leaderboardDescription
|
||||
competitorScoreCorrectionBody=Für Teilnehmer {0} in {1} sind neue Ergebnisse verfügbar.
|
||||
competitorScoreCorrectionBody=Für Teilnehmer {0} in {1} sind neue Ergebnisse verfügbar.
|
||||
|
||||
boatClassUpcomingRaceSubject=Wettfahrt in Bootsklasse {0} startet bald
|
||||
# 0: boatClassName, 1: raceDescription, 2: time
|
||||
boatClassUpcomingRaceBody=In Bootsklasse {0} startet {1} um etwa {2}.
|
||||
|
||||
subscriptionInformation=Bei dieser Mail handelt es sich um eine automatisierte Benachrichtigung aus der SAP Sailing Analytics. Die Benachrichtigungen können im Benutzerprofil (s.u.) abgeschaltet werden.
|
||||
userProfile=Benutzerprofil
|
||||
imprint=Impressum
|
||||
privacy=Datenschutzerklärung
|
||||
+12
-3
@@ -1,5 +1,6 @@
|
||||
package com.sap.sailing.server.notification.impl;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.Arrays;
|
||||
|
||||
import com.sap.sse.common.Util.Pair;
|
||||
@@ -9,21 +10,29 @@ public class NotificationMailTemplate {
|
||||
private final String subject;
|
||||
private final String title;
|
||||
private final String text;
|
||||
private final String serverBaseUrl;
|
||||
private final Iterable<Pair<String, String>> labelsAndLinkUrls;
|
||||
|
||||
@SafeVarargs
|
||||
public NotificationMailTemplate(String subject, String text, Pair<String, String>... labelsAndLinkUrls) {
|
||||
this(subject, null, text, labelsAndLinkUrls);
|
||||
public NotificationMailTemplate(String subject, String text, URL serverBaseUrl,
|
||||
Pair<String, String>... labelsAndLinkUrls) {
|
||||
this(subject, null, text, serverBaseUrl, labelsAndLinkUrls);
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
public NotificationMailTemplate(String subject, String title, String text, Pair<String, String>... labelsAndLinkUrls) {
|
||||
public NotificationMailTemplate(String subject, String title, String text, URL serverBaseUrl,
|
||||
Pair<String, String>... labelsAndLinkUrls) {
|
||||
this.subject = subject;
|
||||
this.title = title;
|
||||
this.text = text;
|
||||
this.serverBaseUrl = serverBaseUrl.toString();
|
||||
this.labelsAndLinkUrls = Arrays.asList(labelsAndLinkUrls);
|
||||
}
|
||||
|
||||
public String getServerBaseUrl() {
|
||||
return serverBaseUrl;
|
||||
}
|
||||
|
||||
public String getSubject() {
|
||||
return subject;
|
||||
}
|
||||
|
||||
+62
-4
@@ -1,19 +1,25 @@
|
||||
package com.sap.sailing.server.notification.impl;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Locale;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.activation.DataHandler;
|
||||
import javax.activation.DataSource;
|
||||
import javax.mail.BodyPart;
|
||||
import javax.mail.Multipart;
|
||||
import javax.mail.internet.MimeBodyPart;
|
||||
import javax.mail.internet.MimeMultipart;
|
||||
import javax.mail.util.ByteArrayDataSource;
|
||||
|
||||
import com.sap.sse.common.Util.Pair;
|
||||
import com.sap.sse.i18n.impl.ResourceBundleStringMessagesImpl;
|
||||
import com.sap.sse.mail.MailService;
|
||||
import com.sap.sse.mail.queue.MailNotification;
|
||||
import com.sap.sse.security.PreferenceObjectBasedNotificationSet;
|
||||
@@ -22,7 +28,10 @@ public abstract class NotificationSetNotification<T> implements MailNotification
|
||||
private static final Logger logger = Logger.getLogger(NotificationSetNotification.class.getName());
|
||||
|
||||
private static final String TEMPLATE_FILE = "notification-mail-template.html";
|
||||
private static final String LOGO_FILE = "sap_logo_header.png";
|
||||
|
||||
private static final String TEMPLATE = loadTemplateFile();
|
||||
private static final byte[] LOGO_BYTES = loadLogoFile();
|
||||
|
||||
private static String loadTemplateFile() {
|
||||
StringBuilder content = new StringBuilder();
|
||||
@@ -38,13 +47,31 @@ public abstract class NotificationSetNotification<T> implements MailNotification
|
||||
return content.toString();
|
||||
}
|
||||
|
||||
private static byte[] loadLogoFile() {
|
||||
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
InputStream in = NotificationSetNotification.class.getResourceAsStream(LOGO_FILE)) {
|
||||
byte[] buffer = new byte[1024];
|
||||
int bytesRead;
|
||||
while ((bytesRead = in.read(buffer)) >= 0) {
|
||||
baos.write(buffer, 0, bytesRead);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
} catch (IOException exc) {
|
||||
logger.log(Level.SEVERE, "Error while loading notification mail template!", exc);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private final T objectToNotifyAbout;
|
||||
private final PreferenceObjectBasedNotificationSet<?, T> associatedNotificationSet;
|
||||
private static final ResourceBundleStringMessagesImpl messages = new ResourceBundleStringMessagesImpl(
|
||||
SailingNotificationServiceImpl.STRING_MESSAGES_BASE_NAME,
|
||||
NotificationSetNotification.class.getClassLoader());
|
||||
|
||||
public NotificationSetNotification(T objectToNotifyAbout, PreferenceObjectBasedNotificationSet<?, T> associatedNotificationSet) {
|
||||
this.objectToNotifyAbout = objectToNotifyAbout;
|
||||
this.associatedNotificationSet = associatedNotificationSet;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -55,10 +82,19 @@ public abstract class NotificationSetNotification<T> implements MailNotification
|
||||
Locale locale = user.getLocaleOrDefault();
|
||||
Multipart multipart = new MimeMultipart();
|
||||
BodyPart bodyPart = new MimeBodyPart();
|
||||
BodyPart messageImagePart = new MimeBodyPart();
|
||||
try {
|
||||
// TODO: add cid:saplogo
|
||||
NotificationMailTemplate mailTemplate = getMailTemplate(objectToNotifyAbout, locale);
|
||||
bodyPart.setContent(getMailContent(mailTemplate), "text/html");
|
||||
bodyPart.setContent(getMailContent(mailTemplate, locale), "text/html");
|
||||
multipart.addBodyPart(bodyPart);
|
||||
|
||||
DataSource imageDs = new ByteArrayDataSource(LOGO_BYTES, "image/png");
|
||||
messageImagePart.setDataHandler(new DataHandler(imageDs));
|
||||
messageImagePart.setHeader("Content-ID", "saplogo");
|
||||
messageImagePart.setHeader("Content-Disposition", "inline;filename=\"saplogo.png\"");
|
||||
multipart.addBodyPart(messageImagePart);
|
||||
|
||||
mailService.sendMail(user.getEmail(), mailTemplate.getSubject(), multipart);
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE,
|
||||
@@ -67,17 +103,39 @@ public abstract class NotificationSetNotification<T> implements MailNotification
|
||||
});
|
||||
}
|
||||
|
||||
private String getMailContent(NotificationMailTemplate notificationMailTemplate) {
|
||||
private String getMailContent(NotificationMailTemplate notificationMailTemplate, Locale locale) {
|
||||
StringBuilder bodyContent = new StringBuilder();
|
||||
if (notificationMailTemplate.getTitle() != null) {
|
||||
bodyContent.append("<h1>").append(notificationMailTemplate.getTitle()).append("</h1>");
|
||||
}
|
||||
bodyContent.append("<p class=\"textContainer\">").append(notificationMailTemplate.getText()).append("</p>");
|
||||
bodyContent.append("<p>").append(notificationMailTemplate.getText()).append("</p>");
|
||||
for (Pair<String, String> link : notificationMailTemplate.getLabelsAndLinkUrls()) {
|
||||
bodyContent.append("<div class=\"buttonContainer\">").append("<a class=\"linkButton\" href=\"");
|
||||
bodyContent.append(link.getB()).append("\">").append(link.getA()).append("</a>").append("</div>");
|
||||
}
|
||||
return TEMPLATE.replace("${title}", notificationMailTemplate.getSubject()).replace("${body}", bodyContent.toString());
|
||||
String siteLink = "<a href=\"" + notificationMailTemplate.getServerBaseUrl() + "/gwt/Home.html\">"
|
||||
+ notificationMailTemplate.getServerBaseUrl() + "</a>";
|
||||
StringBuilder footerLinks = new StringBuilder();
|
||||
footerLinks //
|
||||
.append("<a href=\"") //
|
||||
.append(notificationMailTemplate.getServerBaseUrl())
|
||||
.append("/gwt/Home.html#/user/profile/:\">").append(messages.get(locale, "userProfile")).append("</a>")
|
||||
.append(" | ");
|
||||
footerLinks.append("<a href=\"http://go.sap.com/about/legal/impressum.html\">")
|
||||
.append(messages.get(locale, "imprint")).append("</a>")
|
||||
.append(" | ");
|
||||
footerLinks.append("<a href=\"http://go.sap.com/about/legal/privacy.html\">")
|
||||
.append(messages.get(locale, "privacy"))
|
||||
.append("</a>");
|
||||
|
||||
String subscriptionInformation = messages.get(locale, "subscriptionInformation");
|
||||
return TEMPLATE //
|
||||
.replace("${title}", notificationMailTemplate.getSubject())
|
||||
.replace("${content}", bodyContent.toString())
|
||||
.replace("${subscription_information}", subscriptionInformation)
|
||||
.replace("${site}", siteLink) //
|
||||
.replace("${footer_links}", footerLinks.toString())
|
||||
;
|
||||
}
|
||||
|
||||
protected abstract NotificationMailTemplate getMailTemplate(T objectToNotifyAbout, Locale locale);
|
||||
|
||||
+16
-8
@@ -37,7 +37,7 @@ import com.sap.sse.mail.queue.MailQueue;
|
||||
import com.sap.sse.security.UserStore;
|
||||
|
||||
public class SailingNotificationServiceImpl implements SailingNotificationService {
|
||||
private static final String STRING_MESSAGES_BASE_NAME = "stringmessages/StringMessages";
|
||||
public static final String STRING_MESSAGES_BASE_NAME = "stringmessages/StringMessages";
|
||||
|
||||
private static final Logger logger = Logger.getLogger(SailingNotificationServiceImpl.class.getName());
|
||||
|
||||
@@ -239,7 +239,9 @@ public class SailingNotificationServiceImpl implements SailingNotificationServic
|
||||
String raceDescription = calculateRaceDescription(locale, event, leaderboard, raceColumn, fleet);
|
||||
return new NotificationMailTemplate(
|
||||
messages.get(locale, "boatClassRaceFinishedSubject", boatClass.getDisplayName()),
|
||||
messages.get(locale, "boatClassRaceFinishedBody", boatClass.getDisplayName(), raceDescription),
|
||||
messages.get(locale, "boatClassRaceFinishedBody", boatClass.getDisplayName(),
|
||||
raceDescription),
|
||||
getBaseURL(event),
|
||||
createRaceBoardShowRaceLink(trackedRace, leaderboard, event, leaderboardGroup, locale),
|
||||
createRaceBoardRaceAnalysisLink(trackedRace, leaderboard, event, leaderboardGroup, locale));
|
||||
}
|
||||
@@ -258,7 +260,9 @@ public class SailingNotificationServiceImpl implements SailingNotificationServic
|
||||
String leaderboardDescription = calculateLeaderboardDescription(locale, event, leaderboard);
|
||||
return new NotificationMailTemplate(
|
||||
messages.get(locale, "boatClassScoreCorrectionSubject", boatClass.getDisplayName()),
|
||||
messages.get(locale, "boatClassScoreCorrectionBody", boatClass.getDisplayName(), leaderboardDescription),
|
||||
messages.get(locale, "boatClassScoreCorrectionBody", boatClass.getDisplayName(),
|
||||
leaderboardDescription),
|
||||
getBaseURL(event),
|
||||
createHomeLeaderboardLink(leaderboard, event, locale));
|
||||
}
|
||||
});
|
||||
@@ -278,7 +282,8 @@ public class SailingNotificationServiceImpl implements SailingNotificationServic
|
||||
return new NotificationMailTemplate(
|
||||
messages.get(locale, "boatClassUpcomingRaceSubject", boatClass.getDisplayName()),
|
||||
messages.get(locale, "boatClassUpcomingRaceBody", boatClass.getDisplayName(),
|
||||
raceDescription, time),
|
||||
raceDescription, time),
|
||||
getBaseURL(event),
|
||||
createHomeRacesListLink(leaderboard, event, locale));
|
||||
}
|
||||
});
|
||||
@@ -295,8 +300,9 @@ public class SailingNotificationServiceImpl implements SailingNotificationServic
|
||||
protected NotificationMailTemplate getMailTemplate(Competitor objectToNotifyAbout, Locale locale) {
|
||||
String raceDescription = calculateRaceDescription(locale, event, leaderboard, raceColumn, fleet);
|
||||
return new NotificationMailTemplate(
|
||||
messages.get(locale, "competitorPassesFinishSubject", competitor.getName()),
|
||||
messages.get(locale, "competitorPassesFinishBody", competitor.getName(), raceDescription),
|
||||
messages.get(locale, "competitorPassesFinishSubject", competitor.getName()),
|
||||
messages.get(locale, "competitorPassesFinishBody", competitor.getName(), raceDescription),
|
||||
getBaseURL(event),
|
||||
createRaceBoardShowRaceLink(trackedRace, leaderboard, event, leaderboardGroup, locale),
|
||||
createRaceBoardRaceAnalysisLink(trackedRace, leaderboard, event, leaderboardGroup, locale));
|
||||
}
|
||||
@@ -313,8 +319,10 @@ public class SailingNotificationServiceImpl implements SailingNotificationServic
|
||||
protected NotificationMailTemplate getMailTemplate(Competitor objectToNotifyAbout, Locale locale) {
|
||||
String leaderboardDescription = calculateLeaderboardDescription(locale, event, leaderboard);
|
||||
return new NotificationMailTemplate(
|
||||
messages.get(locale, "competitorScoreCorrectionSubject", competitor.getName()),
|
||||
messages.get(locale, "competitorScoreCorrectionBody", competitor.getName(), leaderboardDescription),
|
||||
messages.get(locale, "competitorScoreCorrectionSubject", competitor.getName()),
|
||||
messages.get(locale, "competitorScoreCorrectionBody", competitor.getName(),
|
||||
leaderboardDescription),
|
||||
getBaseURL(event),
|
||||
createHomeLeaderboardLink(leaderboard, event, locale));
|
||||
}
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user