notify: added support for attachments
This commit is contained in:
parent
f71f1115fb
commit
6561784b28
|
@ -1,9 +1,13 @@
|
|||
package zoptions
|
||||
|
||||
import "time"
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
type NotifyParameters struct {
|
||||
// AlwaysSend makes sure this message
|
||||
// AlwaysSend makes sure this message when set to true
|
||||
// is always sent no matter the condition.
|
||||
//
|
||||
// It will cause `zen` to ignore every other
|
||||
|
@ -51,12 +55,19 @@ type NotifyParameters struct {
|
|||
// ? max_backoff
|
||||
// : mult_dur_double(initial_backoff, pow(1.5, double(repeat)))
|
||||
BackoffFormula string
|
||||
|
||||
// Attachments is a list of NamedReader (files or buffer) that will be sent as attachments.
|
||||
//
|
||||
// Attachments are guaranteed to be closed wether the notification is sent successfully or not
|
||||
// to avoid resource leaks.
|
||||
Attachments []NamedReader
|
||||
}
|
||||
|
||||
type NotifyOption interface {
|
||||
Apply(parameters *NotifyParameters)
|
||||
}
|
||||
|
||||
// NotifyOptionFunc is a shortcut to create a NotifyOption from a function.
|
||||
type NotifyOptionFunc func(parameters *NotifyParameters)
|
||||
|
||||
func (f NotifyOptionFunc) Apply(parameters *NotifyParameters) {
|
||||
|
@ -71,24 +82,44 @@ func (no NotifiyOptionBuilder) Apply(parameters *NotifyParameters) {
|
|||
}
|
||||
}
|
||||
|
||||
// AlwaysSend makes sure this message when set to true
|
||||
// is always sent no matter the condition.
|
||||
//
|
||||
// It will cause `zen` to ignore every other
|
||||
// parameters and just send the message.
|
||||
func (no NotifiyOptionBuilder) AlwaysSend(alwaysSend bool) NotifiyOptionBuilder {
|
||||
return append(no, NotifyOptionFunc(func(parameters *NotifyParameters) {
|
||||
parameters.AlwaysSend = alwaysSend
|
||||
}))
|
||||
}
|
||||
|
||||
// InitialBackoff is the starting backoff.
|
||||
//
|
||||
// If not specified, the default duration is time.Minute.
|
||||
func (no NotifiyOptionBuilder) InitialBackoff(backoff time.Duration) NotifiyOptionBuilder {
|
||||
return append(no, NotifyOptionFunc(func(parameters *NotifyParameters) {
|
||||
parameters.InitialBackoff = backoff
|
||||
}))
|
||||
}
|
||||
|
||||
// MaxBackoff is the maximum backoff. If unset, the default value
|
||||
// is time.Hour * 24.
|
||||
func (no NotifiyOptionBuilder) MaxBackoff(maxBackoff time.Duration) NotifiyOptionBuilder {
|
||||
return append(no, NotifyOptionFunc(func(parameters *NotifyParameters) {
|
||||
parameters.MaxBackoff = maxBackoff
|
||||
}))
|
||||
}
|
||||
|
||||
// Attachments is a list attachments (files or buffers) that will be sent with the notification.
|
||||
//
|
||||
// Attachments are guaranteed to be closed wether the notification is sent successfully or not
|
||||
// to avoid resource leaks.
|
||||
func (no NotifiyOptionBuilder) Attachments(attachments ...NamedReader) NotifiyOptionBuilder {
|
||||
return append(no, NotifyOptionFunc(func(parameters *NotifyParameters) {
|
||||
parameters.Attachments = append(parameters.Attachments, attachments...)
|
||||
}))
|
||||
}
|
||||
|
||||
// BackoffFormula is a string that represents the formula to calculate the backoff time
|
||||
// when multiple message with the same key is fired off repeatedly.
|
||||
//
|
||||
|
@ -129,3 +160,122 @@ func (no NotifiyOptionBuilder) BackoffFormula(formula string) NotifiyOptionBuild
|
|||
func Notify() NotifiyOptionBuilder {
|
||||
return NotifiyOptionBuilder{}
|
||||
}
|
||||
|
||||
// NamedReader is an interface that extends io.ReadCloser with
|
||||
// Filename and MimeType methods.
|
||||
//
|
||||
// This is used to pass a file with its metadata to the notification
|
||||
// system.
|
||||
type NamedReader interface {
|
||||
io.ReadCloser
|
||||
// Filename returns the name of the file.
|
||||
//
|
||||
// Filename will be sluggified and used as the filename
|
||||
// in the notification.
|
||||
Filename() string
|
||||
// MimeType returns the mime type of the file.
|
||||
//
|
||||
// MimeType is used by Zen to determine the type of the file.
|
||||
//
|
||||
// Use constant values from: https://github.com/ldez/mimetype
|
||||
// for maximum compatibility.
|
||||
//
|
||||
// Attachment like images, videos, etc, using well known mime types
|
||||
// that are supported by browsers can
|
||||
// be displayed by the browser.
|
||||
//
|
||||
// Mimetypes that are supported by browsers:
|
||||
//
|
||||
// - image/png
|
||||
// - image/jpeg
|
||||
// - image/gif
|
||||
// - image/svg+xml
|
||||
// - video/mp4
|
||||
// - video/webm
|
||||
// - video/ogg
|
||||
// - audio/mpeg
|
||||
// - audio/ogg
|
||||
// - audio/wav
|
||||
//
|
||||
// Documents like pdf, docx, xlsx, will be given a download link and proper icons.
|
||||
// How they are handled is up to the browser.
|
||||
//
|
||||
// If the mimetype is not supported, it will be given a download link with a generic icon.
|
||||
MimeType() string
|
||||
}
|
||||
|
||||
// NewNamedReader creates a new NamedReader from the given filename, mimeType and reader.
|
||||
//
|
||||
// If reader implements io.Closer, it will be closed when the NamedReader is closed.
|
||||
//
|
||||
// Otherwise, the reader will be wrapped with io.NopCloser.
|
||||
func NewNamedReader(filename, mimeType string, reader io.Reader) NamedReader {
|
||||
var rc io.ReadCloser
|
||||
if c, ok := reader.(io.ReadCloser); ok {
|
||||
rc = c
|
||||
} else {
|
||||
rc = io.NopCloser(reader)
|
||||
}
|
||||
return &namedReader{
|
||||
filename: filename,
|
||||
mimeType: mimeType,
|
||||
reader: rc,
|
||||
}
|
||||
}
|
||||
|
||||
// NewNamedReaderFromFile same as NewNamedReader but reads the file from the filesystem.
|
||||
//
|
||||
// If the file does not exist or there is an error in permissions on reading the file,
|
||||
// the error will be logged but otherwise ignored.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// NewNamedReaderFromFile("path/to/file.txt", "text/plain")
|
||||
func NewNamedReaderFromFile(path string, mimetype string) NamedReader {
|
||||
var rc io.ReadCloser
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
rc = &errorReader{err}
|
||||
} else {
|
||||
rc = f
|
||||
}
|
||||
return &namedReader{
|
||||
filename: path,
|
||||
mimeType: mimetype,
|
||||
reader: rc,
|
||||
}
|
||||
}
|
||||
|
||||
type namedReader struct {
|
||||
filename string
|
||||
mimeType string
|
||||
reader io.ReadCloser
|
||||
}
|
||||
|
||||
func (na *namedReader) Read(p []byte) (n int, err error) {
|
||||
return na.reader.Read(p)
|
||||
}
|
||||
|
||||
func (na *namedReader) Close() error {
|
||||
return na.reader.Close()
|
||||
}
|
||||
|
||||
func (na *namedReader) Filename() string {
|
||||
return na.filename
|
||||
}
|
||||
|
||||
func (na *namedReader) MimeType() string {
|
||||
return na.mimeType
|
||||
}
|
||||
|
||||
type errorReader struct {
|
||||
err error
|
||||
}
|
||||
|
||||
func (er *errorReader) Read(p []byte) (n int, err error) {
|
||||
return 0, er.err
|
||||
}
|
||||
|
||||
func (er *errorReader) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue