...
Tawesoft Logo

Source file src/tawesoft.co.uk/go/legacy/email/attachment.go

Documentation: src/tawesoft.co.uk/go/legacy/email/attachment.go

     1  package email
     2  
     3  import (
     4      "encoding/base64"
     5      "fmt"
     6      "io"
     7      "io/ioutil"
     8      "mime"
     9      "os"
    10      "path"
    11  )
    12  
    13  // Attachment defines an e-mail attachment. They are read lazily.
    14  type Attachment struct {
    15      // Filename is the name to give the attachment in the email
    16      Filename string
    17      
    18      // Mimetype e.g. "application/pdf".
    19      // If an empty string, then attempts to automatically detect based on filename extension.
    20      Mimetype string
    21      
    22      // Reader is a lazy reader. e.g. return the result of os.Open.
    23      Reader func() (io.Reader, error)
    24  }
    25  
    26  // FileAttachment returns an Attachment from a file path. The file at that path is lazily opened at the time the
    27  // attachment is sent.
    28  func FileAttachment(src string) *Attachment {
    29      
    30      var mimetype string
    31      var base = path.Base(src)
    32      
    33      var reader = func() (io.Reader, error) {
    34          return os.Open(src)
    35      }
    36      
    37      mimetype =  mime.TypeByExtension(path.Ext(src))
    38      if mimetype == "" {
    39          mimetype = "application/octet-stream"
    40      }
    41      
    42      return &Attachment{
    43          Filename: base,
    44          Mimetype: mimetype,
    45          Reader: reader,
    46      }
    47  }
    48  
    49  // write encodes an attachment as part of a RFC 2045 MIME Email
    50  func (a *Attachment) write(w io.Writer) error {
    51      fmt.Fprintf(w, "Content-Disposition: attachment; filename=\"%[1]s\"; filename*=\"%[1]s\"\r\n",
    52          optionalQEncode(a.Filename))
    53      fmt.Fprintf(w, "Content-Type: %s\r\n", a.Mimetype)
    54      fmt.Fprintf(w, "Content-Transfer-Encoding: base64\r\n")
    55      fmt.Fprintf(w, "\r\n")
    56      
    57      var reader, err = a.Reader()
    58      if err != nil {
    59          return fmt.Errorf("attachment open error: %v", err)
    60      }
    61      
    62      var encoder = base64.NewEncoder(base64.StdEncoding, lineBreaker{writer: w})
    63      
    64      var xs []byte
    65      xs, err = ioutil.ReadAll(reader)
    66      if err != nil {
    67          encoder.Close()
    68          return fmt.Errorf("attachment read error: %v", err)
    69      }
    70      encoder.Write(xs)
    71      encoder.Close()
    72      
    73      fmt.Fprintf(w, "\r\n")
    74      return nil
    75  }
    76  

View as plain text