package de.thedevstack.conversationsplus.utils; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import java.net.MalformedURLException; import java.net.URL; import java.util.regex.Matcher; import java.util.regex.Pattern; import de.thedevstack.conversationsplus.ConversationsPlusApplication; import de.thedevstack.conversationsplus.entities.FileParams; import de.thedevstack.conversationsplus.enums.FileStatus; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.DownloadableFile; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.entities.Transferable; import eu.siacs.conversations.persistance.DatabaseBackend; import eu.siacs.conversations.persistance.FileBackend; import eu.siacs.conversations.utils.FileUtils; import eu.siacs.conversations.utils.MimeUtils; /** * Utility class to work with messages. */ public final class MessageUtil { public static void extractFileParamsFromBody(Message message) { if (null == message) { return; } 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; } FileParams fileParams = message.getFileParams(); if (null == fileParams) { fileParams = new FileParams(); message.setFileParams(fileParams); } try { URL url = new URL(body); if (!url.getProtocol().equalsIgnoreCase("http") && !url.getProtocol().equalsIgnoreCase("https")) { message.setTreatAsDownloadable(Message.Decision.NEVER); return; } if (message.isHttpUploaded()) { fileParams.setUrl(url.toString()); message.setTreatAsDownloadable(Message.Decision.MUST); return; } String extension = FileUtils.getRelevantExtension(url); if (extension == null) { message.setTreatAsDownloadable(Message.Decision.NEVER); return; } byte[] ivAndKey = UrlUtil.getIvAndKeyFromURL(url); if (null != ivAndKey) { if (MimeUtils.guessMimeTypeFromExtension(extension) != null) { message.setTreatAsDownloadable(Message.Decision.MUST); fileParams.setKeyAndIv(ivAndKey); fileParams.setUrl(url.toString()); } else { message.setTreatAsDownloadable(Message.Decision.NEVER); } } else if (Transferable.VALID_IMAGE_EXTENSIONS.contains(extension) || Transferable.WELL_KNOWN_EXTENSIONS.contains(extension)) { message.setTreatAsDownloadable(Message.Decision.SHOULD); fileParams.setUrl(url.toString()); } else { message.setTreatAsDownloadable(Message.Decision.NEVER); } } catch (MalformedURLException e) { message.setTreatAsDownloadable(Message.Decision.NEVER); } } public static boolean needsDownload(Message message) { FileStatus fileStatus = (null != message.getFileParams()) ? message.getFileParams().getFileStatus() : null; return (null == fileStatus || (null != fileStatus && (fileStatus == FileStatus.NEEDS_DOWNLOAD || fileStatus == FileStatus.UNDEFINED))) && message.treatAsDownloadable() != Message.Decision.NEVER; } public static boolean isMessageSent(Message message) { switch (message.getStatus()) { case Message.STATUS_SEND: case Message.STATUS_SEND_DISPLAYED: case Message.STATUS_SEND_RECEIVED: return true; default: return false; } } public static void setAndSaveFileStatus(Message message, FileStatus fileStatus) { message.getFileParams().setFileStatus(fileStatus); DatabaseBackend.getInstance().updateMessage(message); UiUpdateHelper.updateConversationUi(); } public static boolean markMessage(Conversation conversation, String uuid, int status) { if (uuid == null) { return false; } else { Message message = conversation.findSentMessageWithUuid(uuid); if (message != null) { markMessage(message, status); return true; } else { return false; } } } public static void markMessage(Message message, int status) { if (status == Message.STATUS_SEND_FAILED && (message.getStatus() == Message.STATUS_SEND_RECEIVED || message .getStatus() == Message.STATUS_SEND_DISPLAYED)) { return; } message.setStatus(status); DatabaseBackend.getInstance(ConversationsPlusApplication.getAppContext()).updateMessage(message); UiUpdateHelper.updateConversationUi(); } public static boolean wasHighlightedOrPrivate(final Message message) { final String nick = message.getConversation().getMucOptions().getActualNick(); final Pattern highlight = generateNickHighlightPattern(nick); if (message.getBody() == null || nick == null) { return false; } final Matcher m = highlight.matcher(message.getBody()); return (m.find() || message.getType() == Message.TYPE_PRIVATE); } private static Pattern generateNickHighlightPattern(final String nick) { // We expect a word boundary, i.e. space or start of string, followed by // the // nick (matched in case-insensitive manner), followed by optional // punctuation (for example "bob: i disagree" or "how are you alice?"), // followed by another word boundary. return Pattern.compile("\\b" + Pattern.quote(nick) + "\\p{Punct}?\\b", Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE); } public static void updateMessageWithImageDetails(Message message, String filePath, long size, int imageWidth, int imageHeight) { message.setRelativeFilePath(filePath); MessageUtil.updateMessageWithFileParams(message, null, size, imageWidth, imageHeight); } public static void updateFileParams(Message message) { updateFileParams(message, null); } public static void updateFileParams(Message message, URL url) { DownloadableFile file = FileBackend.getFile(message); int imageWidth = -1; int imageHeight = -1; if (message.getType() == Message.TYPE_IMAGE || file.getMimeType().startsWith("image/")) { BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; Bitmap bmp = BitmapFactory.decodeFile(file.getAbsolutePath(), options); imageHeight = options.outHeight; imageWidth = options.outWidth; if (null != bmp) { bmp.recycle(); } } MessageUtil.updateMessageWithFileParams(message, url, file.getSize(), imageWidth, imageHeight); } private static void updateMessageWithFileParams(Message message, URL url, long size, int imageWidth, int imageHeight) { FileParams fileParams = message.getFileParams(); if (null == fileParams) { fileParams = new FileParams(); message.setFileParams(fileParams); } fileParams.setSize(size); if (null != url) { fileParams.setUrl(url.toString()); } if (-1 < imageWidth) { fileParams.setWidth(imageWidth); } if (-1 < imageHeight) { fileParams.setHeight(imageHeight); } String relativeFilePathFromMessage = message.getRelativeFilePath(); if (null != relativeFilePathFromMessage && relativeFilePathFromMessage.startsWith("/")) { fileParams.setPath(relativeFilePathFromMessage); } } private MessageUtil() { // Static helper class } }