Compare commits
8 Commits
bugfix/pla
...
feature/fa
| Author | SHA1 | Date | |
|---|---|---|---|
| 33ff47a133 | |||
| d08138c9e1 | |||
| 4cd1ea3277 | |||
| 1059164b4a | |||
| c1beda1669 | |||
| df39e6a57f | |||
| f438bea4cc | |||
| 53fe79fbbd |
@@ -35,11 +35,12 @@ import org.json.JSONObject;
|
|||||||
|
|
||||||
public class Util {
|
public class Util {
|
||||||
public static final System.Logger LOG = System.getLogger("Util");
|
public static final System.Logger LOG = System.getLogger("Util");
|
||||||
private static final Pattern UML_PATTERN = Pattern.compile("@start(\\w+)(.*)@end(\\1)",Pattern.DOTALL);
|
private static final Pattern UML_PATTERN = Pattern.compile("@start(\\w+)(.*?)@end(\\1)",Pattern.DOTALL);
|
||||||
private static File plantumlJar = null;
|
private static File plantumlJar = null;
|
||||||
private static final JParsedown MARKDOWN = new JParsedown();
|
private static final JParsedown MARKDOWN = new JParsedown();
|
||||||
public static final String SHA1 = "SHA-1";
|
public static final String SHA1 = "SHA-1";
|
||||||
private static final MessageDigest SHA1_DIGEST;
|
private static final MessageDigest SHA1_DIGEST;
|
||||||
|
private static final Map<Integer,String> umlCache = new HashMap<>();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
try {
|
try {
|
||||||
@@ -79,11 +80,22 @@ public class Util {
|
|||||||
try {
|
try {
|
||||||
if (plantumlJar != null && plantumlJar.exists()) {
|
if (plantumlJar != null && plantumlJar.exists()) {
|
||||||
var matcher = UML_PATTERN.matcher(source);
|
var matcher = UML_PATTERN.matcher(source);
|
||||||
if (matcher.find()) {
|
while (matcher.find()) {
|
||||||
var uml = matcher.group(0).trim();
|
var uml = matcher.group(0).trim();
|
||||||
var start = matcher.start(0);
|
var start = matcher.start(0);
|
||||||
var end = matcher.end(0);
|
var end = matcher.end(0);
|
||||||
|
|
||||||
|
var umlHash = uml.hashCode();
|
||||||
|
LOG.log(DEBUG,"Hash of Plantuml code: {0}",umlHash);
|
||||||
|
var svg = umlCache.get(umlHash);
|
||||||
|
if (svg != null){
|
||||||
|
LOG.log(DEBUG,"Serving Plantuml generated SVG from cache…");
|
||||||
|
source = source.substring(0, start) + svg + source.substring(end);
|
||||||
|
matcher = UML_PATTERN.matcher(source);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG.log(DEBUG,"Cache miss. Generating SVG from plantuml code…");
|
||||||
ProcessBuilder processBuilder = new ProcessBuilder("java", "-jar", plantumlJar.getAbsolutePath(), "-tsvg", "-pipe");
|
ProcessBuilder processBuilder = new ProcessBuilder("java", "-jar", plantumlJar.getAbsolutePath(), "-tsvg", "-pipe");
|
||||||
var ignored = processBuilder.redirectErrorStream();
|
var ignored = processBuilder.redirectErrorStream();
|
||||||
var process = processBuilder.start();
|
var process = processBuilder.start();
|
||||||
@@ -94,8 +106,11 @@ public class Util {
|
|||||||
|
|
||||||
try (InputStream is = process.getInputStream()) {
|
try (InputStream is = process.getInputStream()) {
|
||||||
byte[] out = is.readAllBytes();
|
byte[] out = is.readAllBytes();
|
||||||
var svg = new String(out, UTF_8);
|
LOG.log(DEBUG,"Generated SVG. Pushing to cache…");
|
||||||
|
svg = new String(out, UTF_8);
|
||||||
|
umlCache.put(umlHash,svg);
|
||||||
source = source.substring(0, start) + svg + source.substring(end);
|
source = source.substring(0, start) + svg + source.substring(end);
|
||||||
|
matcher = UML_PATTERN.matcher(source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ public class Constants {
|
|||||||
public static final String AUTH = "mail.smtp.auth";
|
public static final String AUTH = "mail.smtp.auth";
|
||||||
|
|
||||||
public static final String CONFIG_DB = "umbrella.modules.message.database";
|
public static final String CONFIG_DB = "umbrella.modules.message.database";
|
||||||
|
public static final String CONFIG_SMTP_FROM = "umbrella.modules.message.smtp.from";
|
||||||
public static final String CONFIG_SMTP_HOST = "umbrella.modules.message.smtp.host";
|
public static final String CONFIG_SMTP_HOST = "umbrella.modules.message.smtp.host";
|
||||||
public static final String CONFIG_SMTP_PASS = "umbrella.modules.message.smtp.pass";
|
public static final String CONFIG_SMTP_PASS = "umbrella.modules.message.smtp.pass";
|
||||||
public static final String CONFIG_SMTP_PORT = "umbrella.modules.message.smtp.port";
|
public static final String CONFIG_SMTP_PORT = "umbrella.modules.message.smtp.port";
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package de.srsoftware.umbrella.message;
|
|||||||
|
|
||||||
import static de.srsoftware.tools.PathHandler.CONTENT_TYPE;
|
import static de.srsoftware.tools.PathHandler.CONTENT_TYPE;
|
||||||
import static de.srsoftware.umbrella.core.ConnectionProvider.connect;
|
import static de.srsoftware.umbrella.core.ConnectionProvider.connect;
|
||||||
|
import static de.srsoftware.umbrella.core.ModuleRegistry.translator;
|
||||||
import static de.srsoftware.umbrella.core.constants.Constants.UTF8;
|
import static de.srsoftware.umbrella.core.constants.Constants.UTF8;
|
||||||
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.missingConfig;
|
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.missingConfig;
|
||||||
import static de.srsoftware.umbrella.message.Constants.*;
|
import static de.srsoftware.umbrella.message.Constants.*;
|
||||||
@@ -12,6 +13,7 @@ import de.srsoftware.configuration.Configuration;
|
|||||||
import de.srsoftware.umbrella.core.ModuleRegistry;
|
import de.srsoftware.umbrella.core.ModuleRegistry;
|
||||||
import de.srsoftware.umbrella.core.api.PostBox;
|
import de.srsoftware.umbrella.core.api.PostBox;
|
||||||
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
||||||
|
import de.srsoftware.umbrella.core.model.EmailAddress;
|
||||||
import de.srsoftware.umbrella.core.model.Envelope;
|
import de.srsoftware.umbrella.core.model.Envelope;
|
||||||
import de.srsoftware.umbrella.core.model.UmbrellaUser;
|
import de.srsoftware.umbrella.core.model.UmbrellaUser;
|
||||||
import de.srsoftware.umbrella.core.model.User;
|
import de.srsoftware.umbrella.core.model.User;
|
||||||
@@ -76,10 +78,10 @@ public class MessageSystem implements PostBox {
|
|||||||
db = new SqliteMessageDb(connect(dbFile));
|
db = new SqliteMessageDb(connect(dbFile));
|
||||||
debugAddress = config.get(DEBUG_ADDREESS).map(Object::toString).orElse(null);
|
debugAddress = config.get(DEBUG_ADDREESS).map(Object::toString).orElse(null);
|
||||||
port = config.get(CONFIG_SMTP_PORT,587);
|
port = config.get(CONFIG_SMTP_PORT,587);
|
||||||
host = config.get(CONFIG_SMTP_HOST).map(Object::toString).orElseThrow(() -> new RuntimeException("umbrella.modules.message.smtp.host not configured!"));
|
host = config.get(CONFIG_SMTP_HOST).map(Object::toString).orElseThrow(() -> missingConfig(CONFIG_SMTP_HOST));
|
||||||
user = config.get(CONFIG_SMTP_USER).map(Object::toString).orElseThrow(() -> new RuntimeException("umbrella.modules.message.smtp.user not configured!"));
|
user = config.get(CONFIG_SMTP_USER).map(Object::toString).orElseThrow(() -> missingConfig(CONFIG_SMTP_USER));
|
||||||
pass = config.get(CONFIG_SMTP_PASS).map(Object::toString).orElseThrow(() -> new RuntimeException("umbrella.modules.message.smtp.pass not configured!"));
|
pass = config.get(CONFIG_SMTP_PASS).map(Object::toString).orElseThrow(() -> missingConfig(CONFIG_SMTP_PASS));
|
||||||
from = user;
|
from = config.get(CONFIG_SMTP_FROM).map(Object::toString).orElseThrow(() -> missingConfig(CONFIG_SMTP_FROM));
|
||||||
ModuleRegistry.add(this);
|
ModuleRegistry.add(this);
|
||||||
new SubmissionTask(8).schedule();
|
new SubmissionTask(8).schedule();
|
||||||
new SubmissionTask(10).schedule();
|
new SubmissionTask(10).schedule();
|
||||||
@@ -116,9 +118,9 @@ public class MessageSystem implements PostBox {
|
|||||||
var date = new Date();
|
var date = new Date();
|
||||||
|
|
||||||
for (var receiver : dueRecipients){
|
for (var receiver : dueRecipients){
|
||||||
BiFunction<String,Map<String,String>,String> translateFunction = (text,fills) -> ModuleRegistry.translator().translate(receiver.language(),text,fills);
|
BiFunction<String,Map<String,String>,String> translateFunction = (text,fills) -> translator().translate(receiver.language(),text,fills);
|
||||||
|
var fallbackSender = new User("Umbrella",new EmailAddress(from),null);
|
||||||
var combined = new CombinedMessage("Collected messages",translateFunction);
|
var combined = new CombinedMessage("Collected messages",translateFunction,fallbackSender);
|
||||||
var envelopes = queue.stream().filter(env -> env.isFor(receiver)).toList();
|
var envelopes = queue.stream().filter(env -> env.isFor(receiver)).toList();
|
||||||
for (var envelope : envelopes) combined.merge(envelope.message());
|
for (var envelope : envelopes) combined.merge(envelope.message());
|
||||||
|
|
||||||
|
|||||||
@@ -5,9 +5,7 @@ import static java.lang.System.Logger.Level.DEBUG;
|
|||||||
import static java.lang.System.Logger.Level.TRACE;
|
import static java.lang.System.Logger.Level.TRACE;
|
||||||
import static java.text.MessageFormat.format;
|
import static java.text.MessageFormat.format;
|
||||||
|
|
||||||
import de.srsoftware.umbrella.core.model.Attachment;
|
import de.srsoftware.umbrella.core.model.*;
|
||||||
import de.srsoftware.umbrella.core.model.Message;
|
|
||||||
import de.srsoftware.umbrella.core.model.UmbrellaUser;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
@@ -16,15 +14,17 @@ public class CombinedMessage {
|
|||||||
|
|
||||||
private final Set<Attachment> attachments = new HashSet<>();
|
private final Set<Attachment> attachments = new HashSet<>();
|
||||||
private final StringBuilder combinedBody = new StringBuilder();
|
private final StringBuilder combinedBody = new StringBuilder();
|
||||||
|
private final User fallbackSender;
|
||||||
private String combinedSubject = null;
|
private String combinedSubject = null;
|
||||||
private final List<Message> mergedMessages = new ArrayList<>();
|
private final List<Message> mergedMessages = new ArrayList<>();
|
||||||
private final String subjectForCombinedMessage;
|
private final String subjectForCombinedMessage;
|
||||||
private final BiFunction<String,Map<String,String>,String> translate;
|
private final BiFunction<String,Map<String,String>,String> translate;
|
||||||
private UmbrellaUser sender = null;
|
private User sender = null;
|
||||||
|
|
||||||
public CombinedMessage(String subjectForCombinedMessage, BiFunction<String, Map<String,String>,String> translateFunction){
|
public CombinedMessage(String subjectForCombinedMessage, BiFunction<String, Map<String,String>,String> translateFunction, User fallbackSender){
|
||||||
LOG.log(DEBUG,"Creating combined message…");
|
LOG.log(DEBUG,"Creating combined message…");
|
||||||
this.subjectForCombinedMessage = subjectForCombinedMessage;
|
this.subjectForCombinedMessage = translateFunction.apply(subjectForCombinedMessage,null);
|
||||||
|
this.fallbackSender = fallbackSender;
|
||||||
translate = translateFunction;
|
translate = translateFunction;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,12 +39,12 @@ public class CombinedMessage {
|
|||||||
combinedSubject = subject;
|
combinedSubject = subject;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
combinedBody.insert(0,format("# {0}:\n# {1}:\n\n",sender,subject)); // insert sender and subject of first message right before the body of the first message
|
if (!sender.equals(message.sender())) sender = fallbackSender;
|
||||||
|
combinedBody.insert(0,format("# {0} / {1}:\n\n",sender,subject)); // insert sender and subject of first message right before the body of the first message
|
||||||
combinedSubject = subjectForCombinedMessage;
|
combinedSubject = subjectForCombinedMessage;
|
||||||
// no break here, we need to append the subject and content
|
// no break here, we need to append the subject and content
|
||||||
default:
|
default:
|
||||||
combinedBody.append("\n\n# ").append(message.sender()).append(":\n");
|
combinedBody.append("\n-----\n# ").append(message.sender()).append(" / ").append(subject).append(":\n\n");
|
||||||
combinedBody.append("# ").append(subject).append(":\n\n");
|
|
||||||
combinedBody.append(body);
|
combinedBody.append(body);
|
||||||
}
|
}
|
||||||
if (message.attachments() != null) attachments.addAll(message.attachments());
|
if (message.attachments() != null) attachments.addAll(message.attachments());
|
||||||
@@ -59,7 +59,7 @@ public class CombinedMessage {
|
|||||||
return combinedBody.toString();
|
return combinedBody.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public UmbrellaUser sender() {
|
public User sender() {
|
||||||
return sender;
|
return sender;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -57,8 +57,9 @@ footer {
|
|||||||
margin: 5px;
|
margin: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
img {
|
img, svg {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
|
height: auto !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
nav {
|
nav {
|
||||||
|
|||||||
@@ -57,8 +57,9 @@ footer {
|
|||||||
margin: 5px;
|
margin: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
img {
|
img, svg {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
|
height: auto !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
nav {
|
nav {
|
||||||
|
|||||||
@@ -57,17 +57,18 @@ footer {
|
|||||||
margin: 5px;
|
margin: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
img {
|
img, svg {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
|
height: auto !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
nav {
|
nav {
|
||||||
position: sticky;
|
position: sticky;
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
top: 0;
|
top: 0;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
margin: 0 0 10px 0;
|
margin: 0 0 10px 0;
|
||||||
border-bottom: 1px solid;
|
border-bottom: 1px solid;
|
||||||
}
|
}
|
||||||
|
|
||||||
td, tr{
|
td, tr{
|
||||||
|
|||||||
Reference in New Issue
Block a user