<commit_before>// Use of this source code is governed by a BSD-style licence.
// Copyright 2011 The Go Authors. All rights reserved.
// Author: <NAME> <<EMAIL>>

// Package mail implements composing and parsing of mail messages.
//
// Creating a message with multiple parts and attachments ends up being a
// surprisingly painful task in Go. That's because the mail package in the
// standard library only offers tools to parse mail messages and addresses.
//
// This package can replace the net/mail package of the standard library without
// breaking your existing code.
//
// Features
//
// - multipart support
//
// - attachments
//
// - quoted-printable encoding of body text
//
// - quoted-printable decoding of headers
//
// - getters and setters common headers
//
// Known issues
//
// - Quoted-printable encoding does not respect the 76 characters per line
// limitation imposed by RFC 2045 (https://github.com/golang/go/issues/4943).
//
// Installation
//
// <NAME>'s quotedprintable package (https://godoc.org/gopkg.in/alexcesaro/quotedprintable.v1)
// is the only external dependency. It's likely to be included in Go 1.5 in a new
// mime/quotedprintable package (https://codereview.appspot.com/132680044).
// 	go get godoc.org/gopkg.in/alexcesaro/quotedprintable.v1
// 	go get github.com/mohamedattahri/mail
package mail

import (
	"bufio"
	"bytes"
	"crypto/rand"
	"encoding/base64"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"math"
	"mime"
	"mime/multipart"
	"net/textproto"
	"path/filepath"
	"strconv"
	"strings"
	"time"
	"unicode"

	qp "gopkg.in/alexcesaro/quotedprintable.v1"
)

var debug = debugT(false)

type debugT bool

func (d debugT) Printf(format string, args ...interface{}) {
	if d {
		log.Printf(format, args...)
	}
}

const (
	crlf            = "\r\n"
	boundaryLength  = 30
	messageIDLength = 12
	maxLineLen      = 76 // RFC 2045
)

// AttachmentType indicates to the mail user agent how an attachment should be
// treated.
type AttachmentType string

const (
	// Attachment indicates that the attachment should be offered as an optional
	// download.
	Attachment AttachmentType = "attachment"
	// Inline indicates that the attachment should be rendered in the body of
	// the message.
	Inline AttachmentType = "inline"
)

// A Message represents a mail message.
type Message struct {
	Header Header
	Body   io.ReadWriter
	root   *Multipart
}

func (m *Message) mimeVersion() string {
	return m.GetHeader("Mime-Version")
}

// GetHeader returns the undecoded value of header if found. To access the
// raw (potentially encoded) value of header, use the Message.Header.
func (m *Message) GetHeader(header string) string {
	encoded := textproto.MIMEHeader(m.Header).Get(header)
	if encoded == "" {
		return ""
	}
	decoded, _, err := qp.DecodeHeader(encoded)
	if err != nil {
		return ""
	}

	return decoded
}

// SetHeader adds header to the list of headers and sets it to quoted-printable
// encoded value.
func (m *Message) SetHeader(header, value string) {
	textproto.MIMEHeader(m.Header).Set(header, value)
}

// Subject line of the message.
func (m *Message) Subject() string {
	return m.GetHeader("Subject")
}

// SetSubject sets the subject line of the message.
func (m *Message) SetSubject(subject string) {
	m.SetHeader("Subject", subject)
}

// From returns the address of the author.
func (m *Message) From() *Address {
	address, err := ParseAddress(m.GetHeader("From"))
	if err != nil {
		return &Address{}
	}
	return address
}

// SetFrom sets the address of the message's author.
func (m *Message) SetFrom(address *Address) {
	m.SetHeader("From", address.String())
}

// Date returns the time and date when the message was written.
func (m *Message) Date() time.Time {
	date, _ := m.Header.Date()
	return date
}<commit_msg>Missing From was returning an empty Address struct<commit_after>// Use of this source code is governed by a BSD-style licence.
// Copyright 2011 The Go Authors. All rights reserved.
// Author: <NAME> <<EMAIL>>

// Package mail implements composing and parsing of mail messages.
//
// Creating a message with multiple parts and attachments ends up being a
// surprisingly painful task in Go. That's because the mail package in the
// standard library only offers tools to parse mail messages and addresses.
//
// This package can replace the net/mail package of the standard library without
// breaking your existing code.
//
// Features
//
// - multipart support
//
// - attachments
//
// - quoted-printable encoding of body text
//
// - quoted-printable decoding of headers
//
// - getters and setters common headers
//
// Known issues
//
// - Quoted-printable encoding does not respect the 76 characters per line
// limitation imposed by RFC 2045 (https://github.com/golang/go/issues/4943).
//
// Installation
//
// <NAME>'s quotedprintable package (https://godoc.org/gopkg.in/alexcesaro/quotedprintable.v1)
// is the only external dependency. It's likely to be included in Go 1.5 in a new
// mime/quotedprintable package (https://codereview.appspot.com/132680044).
// 	go get godoc.org/gopkg.in/alexcesaro/quotedprintable.v1
// 	go get github.com/mohamedattahri/mail
package mail

import (
	"bufio"
	"bytes"
	"crypto/rand"
	"encoding/base64"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"math"
	"mime"
	"mime/multipart"
	"net/textproto"
	"path/filepath"
	"strconv"
	"strings"
	"time"
	"unicode"

	qp "gopkg.in/alexcesaro/quotedprintable.v1"
)

var debug = debugT(false)

type debugT bool

func (d debugT) Printf(format string, args ...interface{}) {
	if d {
		log.Printf(format, args...)
	}
}

const (
	crlf            = "\r\n"
	boundaryLength  = 30
	messageIDLength = 12
	maxLineLen      = 76 // RFC 2045
)

// AttachmentType indicates to the mail user agent how an attachment should be
// treated.
type AttachmentType string

const (
	// Attachment indicates that the attachment should be offered as an optional
	// download.
	Attachment AttachmentType = "attachment"
	// Inline indicates that the attachment should be rendered in the body of
	// the message.
	Inline AttachmentType = "inline"
)

// A Message represents a mail message.
type Message struct {
	Header Header
	Body   io.ReadWriter
	root   *Multipart
}

func (m *Message) mimeVersion() string {
	return m.GetHeader("Mime-Version")
}

// GetHeader returns the undecoded value of header if found. To access the
// raw (potentially encoded) value of header, use the Message.Header.
func (m *Message) GetHeader(header string) string {
	encoded := textproto.MIMEHeader(m.Header).Get(header)
	if encoded == "" {
		return ""
	}
	decoded, _, err := qp.DecodeHeader(encoded)
	if err != nil {
		return ""
	}

	return decoded
}

// SetHeader adds header to the list of headers and sets it to quoted-printable
// encoded value.
func (m *Message) SetHeader(header, value string) {
	textproto.MIMEHeader(m.Header).Set(header, value)
}

// Subject line of the message.
func (m *Message) Subject() string {
	return m.GetHeader("Subject")
}

// SetSubject sets the subject line of the message.
func (m *Message) SetSubject(subject string) {
	m.SetHeader("Subject", subject)
}

// From returns the address of the author.
func (m *Message) From() *Address {
	address, err := ParseAddress(m.GetHeader("From"))
	if err != nil {
		return nil
	}
	return address
}

// SetFrom sets the address of the message's author.
func (m *Message) SetFrom(address *Address) {
	m.SetHeader("From", address.String())
}

// Date returns the time and date when the message was written.
func (m *Message) Date() time.Time {
	date, _ := m.Header.Date()
	return date
}
{'fraction_non_alphanumeric': 0.11709446943635883, 'fraction_numerical': 0.010584810796507013, 'mean_word_length': 3.478080568720379, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 6, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7263389', 'n_tokens_mistral': 2480, 'n_tokens_neox': 2366, 'n_words': 845}