diff options
Diffstat (limited to '')
-rw-r--r-- | src/main/java/de/thedevstack/conversationsplus/utils/MessageParserUtil.java | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/src/main/java/de/thedevstack/conversationsplus/utils/MessageParserUtil.java b/src/main/java/de/thedevstack/conversationsplus/utils/MessageParserUtil.java new file mode 100644 index 00000000..5044d132 --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/utils/MessageParserUtil.java @@ -0,0 +1,164 @@ +package de.thedevstack.conversationsplus.utils; + +import java.net.MalformedURLException; +import java.net.URL; + +import de.thedevstack.conversationsplus.entities.FileParams; +import de.thedevstack.conversationsplus.entities.Message; +import de.thedevstack.conversationsplus.entities.Transferable; +import de.thedevstack.conversationsplus.enums.FileStatus; +import de.thedevstack.conversationsplus.enums.MessageConfirmation; +import de.thedevstack.conversationsplus.xmpp.chatmarkers.ChatMarkers; +import de.thedevstack.conversationsplus.xmpp.receipts.MessageDeliveryReceipts; +import de.thedevstack.conversationsplus.xmpp.stanzas.MessagePacket; + +/** + */ +public class MessageParserUtil { + public static MessageConfirmation extractMessageConfirmation(MessagePacket messagePacket) { + if (messagePacket.hasChild(ChatMarkers.MARKABLE) + && messagePacket.hasChild(MessageDeliveryReceipts.REQUEST)) { + return MessageConfirmation.DELIVERY_RECEIPT_CHAT_MARKERS; + } else if (messagePacket.hasChild(ChatMarkers.MARKABLE)) { + return MessageConfirmation.CHAT_MARKERS; + } else if (messagePacket.hasChild(MessageDeliveryReceipts.REQUEST)) { + return MessageConfirmation.DELIVERY_RECEIPT; + } else { + return MessageConfirmation.NONE; + } + } + + public static void extractFileParamsFromBody(Message message) { + if (null == message) { + return; + } + + // Ensure that for every message the fileParams are set after calling this method + FileParams fileParams = message.getFileParams(); + if (null == fileParams) { + fileParams = new FileParams(); + message.setFileParams(fileParams); + } + + String body = message.getBody(); + /** + * there are a few cases where spaces result in an unwanted behavior, e.g. + * "http://example.com/image.jpg" text that will not be shown /abc.png" + * or more than one image link in one message. + */ + if (null == body || body.isEmpty() || body.contains(" ")) { + return; + } + + URL url = MessageParserUtil.extractValidUrlFromBody(message); + if (null != url) { + String extension = FileUtils.getRelevantExtension(url); + if (message.isHttpUploaded()) { + fileParams.setUrl(url.toString()); + if (null != extension + && (Transferable.WELL_KNOWN_EXTENSIONS.contains(extension.toLowerCase()) || Transferable.VALID_IMAGE_EXTENSIONS.contains(extension.toLowerCase()))) { + message.setTreatAsDownloadable(Message.Decision.MUST); + } else { + MessageParserUtil.setParamsToAvoidDownload(message, fileParams); + } + + extractFilename(message, url.toString()); + return; + } + + if (extension == null) { + MessageParserUtil.setParamsToAvoidDownload(message, fileParams); + return; + } + byte[] ivAndKey = UrlUtil.getIvAndKeyFromURL(url); + + if (null != ivAndKey) { + if (MimeUtils.guessMimeTypeFromExtension(extension) != null) { + message.setTreatAsDownloadable(Message.Decision.MUST); + fileParams.setKeyAndIv(ivAndKey); + } else { + MessageParserUtil.setParamsToAvoidDownload(message, fileParams); + } + } else if (Transferable.VALID_IMAGE_EXTENSIONS.contains(extension) + || Transferable.WELL_KNOWN_EXTENSIONS.contains(extension)) { + message.setTreatAsDownloadable(Message.Decision.SHOULD); + MessageUtil.setFileStatus(message, FileStatus.NEEDS_DOWNLOAD); + } else { + MessageParserUtil.setParamsToAvoidDownload(message, fileParams); + } + + if (message.treatAsDownloadable() == Message.Decision.MUST + || message.treatAsDownloadable() == Message.Decision.SHOULD) { + fileParams.setUrl(url.toString()); + extractFilename(message, url.toString()); + MessageUtil.setFileStatus(message, FileStatus.NEEDS_DOWNLOAD); + } + } else { + MessageParserUtil.setParamsToAvoidDownload(message, fileParams); + } + } + + private static void setParamsToAvoidDownload(Message message, FileParams fileParams) { + message.setTreatAsDownloadable(Message.Decision.NEVER); + MessageUtil.setFileStatus(message, FileStatus.UNDEFINED); + } + + private static void extractFilename(Message message, String url) { + String originalFilename = FileUtils.getFilenameFromPath(url); + final String lowerCaseFilename = originalFilename.toLowerCase(); + final String lastPart = FileUtils.getLastExtension(lowerCaseFilename); + + detectAndSetEncryption(lastPart, message); + + String filenameExtension; + if (!lastPart.isEmpty() && Transferable.VALID_CRYPTO_EXTENSIONS.contains(lastPart)) { + filenameExtension = FileUtils.getSecondToLastExtension(lowerCaseFilename); + originalFilename = originalFilename.replace("." + lastPart, ""); + } else { + filenameExtension = lastPart; + } + message.setRelativeFilePath(message.getUuid() + "." + filenameExtension); + + message.getFileParams().setOriginalFilename(originalFilename); + } + + private static void detectAndSetEncryption(String lastPart, Message message) { + if (!lastPart.isEmpty() && ("pgp".equals(lastPart) || "gpg".equals(lastPart))) { + message.setEncryption(Message.ENCRYPTION_PGP); + } else if (message.getEncryption() != Message.ENCRYPTION_OTR + && message.getEncryption() != Message.ENCRYPTION_AXOLOTL) { + message.setEncryption(Message.ENCRYPTION_NONE); + } else if ((message.getEncryption() == Message.ENCRYPTION_OTR + || message.getEncryption() == Message.ENCRYPTION_AXOLOTL) + && message.getFileParams() != null && message.getFileParams().getKey() == null) { + // If an encryption is set for the message, but no key given -> decryption not possible + message.setEncryption(Message.ENCRYPTION_NONE); + } + } + + private static URL extractValidUrlFromBody(Message message) { + if (null == message) { + return null; + } + String body = message.getBody(); + /** + * there are a few cases where spaces result in an unwanted behavior, e.g. + * "http://example.com/image.jpg" text that will not be shown /abc.png" + * or more than one image link in one message. + */ + if (null == body || body.isEmpty() || body.contains(" ")) { + return null; + } + + try { + URL url = new URL(body); + if (!url.getProtocol().equalsIgnoreCase("http") && !url.getProtocol().equalsIgnoreCase("https")) { + return null; + } + + return url; + } catch (MalformedURLException e) { + return null; + } + } +} |