Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[pushover] Add support to send an Image URL directly #11027

Merged
merged 2 commits into from
Jul 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion bundles/org.openhab.binding.pushover/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ One has to pass a `null` value if it should be skipped or the default value for

- `sendMonospaceMessage(String message, @Nullable String title)` - This method is used to send a monospace message.

- `sendAttachmentMessage(String message, @Nullable String title, String attachment, @Nullable String contentType)` - This method is used to send a message with an attachment. It takes a (local) path to the attachment (parameter `attachment` **mandatory**) and an optional `contentType` to define the content-type of the attachment (default: `image/jpeg`).
- `sendAttachmentMessage(String message, @Nullable String title, String attachment, @Nullable String contentType)` - This method is used to send a message with an attachment. It takes a local path or URL to the attachment (parameter `attachment` **mandatory**). Additionally you can pass a data URI scheme to this parameter. Optionally pass a `contentType` to define the content-type of the attachment (default: `image/jpeg` or guessed from image data).

- `sendURLMessage(String message, @Nullable String title, String url, @Nullable String urlTitle)` - This method is used to send a message with an URL. A supplementary `url` to show with the message and a `urlTitle` for the URL, otherwise just the URL is shown.

Expand Down Expand Up @@ -76,6 +76,16 @@ val actions = getActions("pushover", "pushover:pushover-account:account")
actions.sendHtmlMessage("Hello <font color='green'>World</font>!", "openHAB")
```

```java
val actions = getActions("pushover", "pushover:pushover-account:account")
// send message with attachment
actions.sendAttachmentMessage("Hello World!", "openHAB", "/path/to/my-local-image.png", "image/png")
actions.sendAttachmentMessage("Hello World!", "openHAB", "https://www.openhab.org/openhab-logo-square.png", null)
actions.sendAttachmentMessage("Hello World!", "openHAB", "data:[<media type>][;base64],<data>", null)
// in case you want to send the content of an Image Item (RawType)
actions.sendAttachmentMessage("Hello World!", "openHAB", myImageItem.state.toFullString, null)
```

```java
val actions = getActions("pushover", "pushover:pushover-account:account")
// send priority message
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
* @author Christoph Weitkamp - Initial contribution
*/
@NonNullByDefault
public class PushoverConfigurationException extends RuntimeException {
public class PushoverConfigurationException extends IllegalArgumentException {

private static final long serialVersionUID = 1L;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.stream.Collectors;

Expand All @@ -24,6 +25,8 @@
import org.eclipse.jetty.client.util.MultiPartContentProvider;
import org.eclipse.jetty.client.util.PathContentProvider;
import org.eclipse.jetty.client.util.StringContentProvider;
import org.openhab.core.io.net.http.HttpUtil;
import org.openhab.core.library.types.RawType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -55,7 +58,7 @@ public class PushoverMessageBuilder {
private static final int MAX_MESSAGE_LENGTH = 1024;
private static final int MAX_TITLE_LENGTH = 250;
private static final int MAX_DEVICE_LENGTH = 25;
private static final List<Integer> VALID_PRIORITY_LIST = Arrays.asList(-2, -1, 0, 1, 2);
private static final List<Integer> VALID_PRIORITY_LIST = List.of(-2, -1, 0, 1, 2);
private static final int DEFAULT_PRIORITY = 0;
public static final int EMERGENCY_PRIORITY = 2;
private static final int MIN_RETRY_SECONDS = 30;
Expand All @@ -76,7 +79,7 @@ public class PushoverMessageBuilder {
private @Nullable String urlTitle;
private @Nullable String sound;
private @Nullable String attachment;
private String contentType = DEFAULT_CONTENT_TYPE;
private @Nullable String contentType;
private boolean html = false;
private boolean monospace = false;

Expand Down Expand Up @@ -239,18 +242,31 @@ public ContentProvider build() throws PushoverCommunicationException {
}

if (attachment != null) {
File file = new File(attachment);
if (!file.exists()) {
throw new IllegalArgumentException(
String.format("Skip sending the message as file '%s' does not exist.", attachment));
}
try {
body.addFilePart(MESSAGE_KEY_ATTACHMENT, file.getName(),
new PathContentProvider(contentType, file.toPath()), null);
} catch (IOException e) {
logger.debug("IOException occurred - skip sending message: {}", e.getLocalizedMessage(), e);
throw new PushoverCommunicationException(
String.format("Skip sending the message: %s", e.getLocalizedMessage()), e);
String localAttachment = attachment;
if (localAttachment.startsWith("http")) { // support data HTTP(S) scheme
RawType rawImage = HttpUtil.downloadImage(attachment, 10000);
if (rawImage == null) {
throw new IllegalArgumentException(
String.format("Skip sending the message as content '%s' does not exist.", attachment));
}
addFilePart(createTempFile(rawImage.getBytes()),
contentType == null ? rawImage.getMimeType() : contentType);
} else if (localAttachment.startsWith("data:")) { // support data URI scheme
try {
RawType rawImage = RawType.valueOf(localAttachment);
addFilePart(createTempFile(rawImage.getBytes()),
contentType == null ? rawImage.getMimeType() : contentType);
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException(String
.format("Skip sending the message because data URI scheme is invalid: %s", e.getMessage()));
}
} else {
File file = new File(attachment);
if (!file.exists()) {
throw new IllegalArgumentException(
String.format("Skip sending the message as file '%s' does not exist.", attachment));
}
addFilePart(file.toPath(), contentType);
}
}

Expand All @@ -262,4 +278,28 @@ public ContentProvider build() throws PushoverCommunicationException {

return body;
}

private Path createTempFile(byte[] data) throws PushoverCommunicationException {
try {
Path tmpFile = Files.createTempFile("pushover-", ".tmp");
return Files.write(tmpFile, data);
} catch (IOException e) {
logger.debug("IOException occurred while creating temp file - skip sending message: {}",
e.getLocalizedMessage(), e);
throw new PushoverCommunicationException(
String.format("Skip sending the message: %s", e.getLocalizedMessage()), e);
}
}

private void addFilePart(Path path, @Nullable String contentType) throws PushoverCommunicationException {
try {
body.addFilePart(MESSAGE_KEY_ATTACHMENT, path.toFile().getName(),
new PathContentProvider(contentType == null ? DEFAULT_CONTENT_TYPE : contentType, path), null);
} catch (IOException e) {
logger.debug("IOException occurred while adding content - skip sending message: {}",
e.getLocalizedMessage(), e);
throw new PushoverCommunicationException(
String.format("Skip sending the message: %s", e.getLocalizedMessage()), e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ sendMonospaceMessageActionDescription = This method is used to send a monospace
sendAttachmentMessageActionLabel = send a plain text message with an attachment
sendAttachmentMessageActionDescription = This method is used to send a message with an attachment.
sendMessageActionInputAttachmentLabel = Attachment
sendMessageActionInputAttachmentDescription = A (local) path to the attachment.
sendMessageActionInputAttachmentDescription = Local path or URL to the attachment.
sendMessageActionInputContentTypeLabel = Content Type
sendMessageActionInputContentTypeDescription = The content type of the attachment. Defaults to "image/jpeg".

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ sendMonospaceMessageActionDescription = Action zum Versenden einer monospace-Nac
sendAttachmentMessageActionLabel = eine Textnachricht mit Anhang senden
sendAttachmentMessageActionDescription = Action zum Versenden einer Textnachricht mit Anhang.
sendMessageActionInputAttachmentLabel = Anhang
sendMessageActionInputAttachmentDescription = Lokaler Pfad zum Anhang.
sendMessageActionInputAttachmentDescription = Lokaler Pfad oder URL zum Anhang.
sendMessageActionInputContentTypeLabel = Content-Type
sendMessageActionInputContentTypeDescription = Der Content-Type f�r den Anhang. Default: "image/jpeg".

Expand Down