github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/builtins/pipes/mail/stdio.go (about)

     1  package mail
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"errors"
     7  	"io"
     8  	"net/smtp"
     9  	"os"
    10  	"sync"
    11  
    12  	"github.com/lmorg/murex/config"
    13  	"github.com/lmorg/murex/lang/stdio"
    14  	"github.com/lmorg/murex/lang/types"
    15  )
    16  
    17  // Since I don't want you to create null pipes, lets not regester it
    18  func init() {
    19  	stdio.RegisterPipe("mail", NewMail)
    20  }
    21  
    22  // Mail is null interface for named pipes
    23  type Mail struct {
    24  	mutex      sync.Mutex
    25  	bWritten   uint64
    26  	dependants int
    27  	client     *smtp.Client
    28  	body       io.WriteCloser
    29  	bodyAuth   *bytes.Buffer
    30  	bAuth      []byte
    31  	useAuth    bool
    32  	smtpAuth   smtp.Auth
    33  	subject    string
    34  	recipients []string
    35  }
    36  
    37  func (m *Mail) File() *os.File {
    38  	return nil
    39  }
    40  
    41  // Read is an empty method because you cannot read a sent email
    42  func (m *Mail) Read(p []byte) (int, error) {
    43  	return 0, nil
    44  }
    45  
    46  // ReadLine is an empty method because you cannot read a sent email
    47  func (m *Mail) ReadLine(func([]byte)) error {
    48  	return errors.New("ReadLine() is not supported by mail pipes")
    49  }
    50  
    51  // ReadArray is an empty method because you cannot read a sent email
    52  func (m *Mail) ReadArray(context.Context, func([]byte)) error {
    53  	return errors.New("ReadArray() is not supported by mail pipes")
    54  }
    55  
    56  // ReadArrayWithType is an empty method because you cannot read a sent email
    57  func (m *Mail) ReadArrayWithType(context.Context, func(interface{}, string)) error {
    58  	return errors.New("ReadArrayWithType() is not supported by mail pipes")
    59  }
    60  
    61  // ReadMap is an empty method because you cannot read a sent email
    62  func (m *Mail) ReadMap(*config.Config, func(*stdio.Map)) error {
    63  	return errors.New("ReadMap() is not supported by mail pipes")
    64  }
    65  
    66  // ReadAll is an empty method because you cannot read a sent email
    67  func (m *Mail) ReadAll() ([]byte, error) {
    68  	return nil, nil
    69  }
    70  
    71  // WriteTo is an empty method because you cannot read a sent email
    72  func (m *Mail) WriteTo(w io.Writer) (int64, error) {
    73  	return 0, nil
    74  }
    75  
    76  // Write - caches the data before send
    77  func (m *Mail) Write(b []byte) (i int, err error) {
    78  	m.mutex.Lock()
    79  	if m.useAuth {
    80  		i, err = m.bodyAuth.Write(b)
    81  	} else {
    82  		i, err = m.body.Write(b)
    83  	}
    84  	m.bWritten += uint64(i)
    85  	m.mutex.Unlock()
    86  	return i, err
    87  }
    88  
    89  // Writeln - caches the data before send
    90  func (m *Mail) Writeln(b []byte) (int, error) {
    91  	return m.Write(append(b, '\n'))
    92  }
    93  
    94  // WriteArray - caches the data before send
    95  func (m *Mail) WriteArray(dataType string) (stdio.ArrayWriter, error) {
    96  	return stdio.WriteArray(m, dataType)
    97  }
    98  
    99  // Stats - return data size
   100  func (m *Mail) Stats() (bytesWritten, bytesRead uint64) {
   101  	m.mutex.Lock()
   102  	bytesWritten = m.bWritten
   103  	//bytesRead = m.bRead
   104  	m.mutex.Unlock()
   105  	return
   106  }
   107  
   108  // GetDataType returns null because you cannot read a sent email
   109  func (m *Mail) GetDataType() string { return types.Null }
   110  
   111  // SetDataType - not required as data is emailed
   112  func (m *Mail) SetDataType(string) {}
   113  
   114  // DefaultDataType - not required as data is emailed
   115  func (m *Mail) DefaultDataType(bool) {}
   116  
   117  // IsTTY - Stdio.Io is an email not a terminal
   118  func (m *Mail) IsTTY() bool { return false }
   119  
   120  // Open email for sending
   121  func (m *Mail) Open() {
   122  	m.mutex.Lock()
   123  	m.dependants++
   124  	m.mutex.Unlock()
   125  }
   126  
   127  // Close email and send
   128  func (m *Mail) Close() {
   129  	m.mutex.Lock()
   130  
   131  	m.dependants--
   132  	if m.dependants == 0 {
   133  		m.send()
   134  	}
   135  
   136  	if m.dependants < 0 {
   137  		panic("more closed dependants than open")
   138  	}
   139  
   140  	m.mutex.Unlock()
   141  }
   142  
   143  // ForceClose is not required on this occasion
   144  func (m *Mail) ForceClose() {}