mail

package
v0.0.0-...-ee8abc8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 23, 2022 License: MIT Imports: 24 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// LocalLabelMailConf is the name of the local rules which are kept local on
	// disk and do not save in version control.
	LocalLabelMailConf = ".label-mail.local.yml"

	// LabelMailConf is the name of the generic rules which are kept in version
	// control.
	LabelMailConf = ".label-mail.yml"
)
View Source
const (
	// FromName is the name to use when sending mail. This should be
	// configuration.
	FromName = "Andrew Sterling Hanenkamp"

	// ForwardedMessagePrefix is line to put at the top of a forwarded message.
	ForwardedMessagePrefix = "---------- Forwarded message ---------"
)

Variables

View Source
var (

	// DefaultMailDir is the usual maildir
	DefaultMailDir = path.Join(dotfiles.HomeDir, "Mail")

	// SkipFolder lists folders that are never filtered.
	SkipFolder = map[string]skip{
		"gmail.Spam":      skip{},
		"gmail.Draft":     skip{},
		"gmail.Trash":     skip{},
		"gmail.Sent_Mail": skip{},
	}
)
View Source
var (
	// SASLUser contains the username to use to login
	SASLUser = secrets.MustGet(secrets.Secure, "LABEL_MAIL_USERNAME")

	// SASLPass contsint eh password to use to login
	SASLPass = secrets.MustGet(secrets.Secure, "LABEL_MAIL_PASSWORD")
)
View Source
var (
	// FromEmail is the email address to use as the from email address.
	FromEmail = secrets.MustGet(secrets.Secure, "GIT_EMAIL_HOME")

	// FromEmailAddress is the addr.Address created from FromEmail.
	FromEmailAddress addr.AddressList
)
View Source
var (
	// UnwantedFolderSuffix mentions endings we want to strip during vacuuming.
	UnwantedFolderSuffix = []string{","}

	// UnwantedFolderPrefix mentions starts we want to strip during vacuuming.
	UnwantedFolderPrefix = []string{"+", "\\"}

	// UnwantedFolder mentions folders we want to strip during vacuuming.
	UnwantedFolder = []string{"[", "]", "Drafts", "Home_School", "Network", "Pseudo-Junk.Social", "Pseudo-Junk.Social_Network", "Social Network", "OtherJunk"}

	// UnwantedKeyword mentions remaps of folders we want to apply during
	// vacuuming.
	UnwantedKeyword = map[string][]string{
		"JunkSocial":                {"Network", "Pseudo-Junk.Social", "Pseudo-Junk/Social", "Psuedo-Junk/Social_Network", "Pseudo-Junk.Social_Network"},
		"Teamwork":                  {"Discussion"},
		"JunkOther":                 {"OtherJunk"},
		"Pseudo-Junk.ToDo":          {"Do", "Pseudo-Junk.To", "Pseudo-Junk.To_Do"},
		"Pseudo-Junk.Politics.Rush": {"Limbaugh", "Pseudo-Junk.Politics.Rush_Limbaugh"},
		"Jobs.GSG":                  {"Street", "Jobs.Grant_Street", "Jobs.Grant"},
		"Old.NewHope":               {"Hope", "Old.New", "Old.New_Hope"},
		"Old.JiftyBook":             {"Book", "Old.Jifty", "Old.Jifty_Book"},
		"Old.GBCWeb":                {"Web", "Old.GBC", "Old.GBC_Web"},
		"Tech.Perl.Mongers":         {"Mongers", "Tech.Perl.Perl", "Test.Perl.Perl_Mongers"},
		"Money.ForSale":             {"Sale", "Money.For", "Money.For_Sale"},
		"AccountInfo":               {"Account", "Info", "Account_Info"},
	}
)

Functions

func AddressListHTML

func AddressListHTML(addr addr.AddressList) string

AddressListHTML returns an HTML representation of the addr.AddressList.

func AddressListStrings

func AddressListStrings(as addr.AddressList) []string

AddressListStrings a list of strings created by calling CleanString() on each address in the given addr.AddressList.

func CompileAddress

func CompileAddress(name string, a interface{}) (addr.AddressList, error)

CompileAddress handles fields that can either be provided as a list of items or a single string and turns them into an addr.AddressList. Returns an error if there's a problem parsing the email address(es).

func CompileField

func CompileField(name string, field interface{}) []string

CompileField handles fields that can either be provided as a list of items or a single string and turns them into a list of strings.

func CompileLabel

func CompileLabel(name string, label interface{}) []string

CompileLabel provides special handling for label fields. It converts labels to their canonical form.

Types

type ActionsSummary

type ActionsSummary map[string]int

ActionsSummary is the summary of actions taken while filtering to display to the user.

func (ActionsSummary) String

func (actions ActionsSummary) String() string

String returns a nice tabular summary of the actions to the console.

fmt.Print(action)

type ColorPalette

type ColorPalette map[string]*color.Color

ColorPalette gives colors to names.

func (ColorPalette) Fcolor

func (cp ColorPalette) Fcolor(out io.Writer, args ...string)

Fcolor takes an alternating set of string arguments. The even number strings name colors and the odd number strings are strings that will be written to out in the previously named color.

func (ColorPalette) Fprintf

func (cp ColorPalette) Fprintf(color string, out io.Writer, fmt string, args ...interface{})

Fprintf formats the string using the fmt and args, colors it with the color, and writes it out to the given io.Writer.

func (ColorPalette) Join

func (cp ColorPalette) Join(color string, args []string, d string) string

Join returns a string that is the same as would be created by calling

strings.Join(args, d)

but with the separator colored using the given color.

func (ColorPalette) Scolor

func (cp ColorPalette) Scolor(args ...string) string

Scolor takes an alternating set of string arguments. The even number strings name colors and the odd number strings are strings that will be colored by the previously named color. The strings will be concatenated and returned.

func (ColorPalette) Sprintf

func (cp ColorPalette) Sprintf(color string, fmt string, args ...interface{}) string

Sprintf formats the string using the fmt and args, colors it with the color, and returns it as a string.

type CompiledFolderRules

type CompiledFolderRules map[string]CompiledRules

CompiledFolderRules are CompiledRules grouped by folder name.

func (CompiledFolderRules) Add

func (fcrs CompiledFolderRules) Add(folder string, cr *CompiledRule)

Add is a helper message that will cleanly append the rule to the CompiledRules in the named folder.

type CompiledRule

type CompiledRule struct {
	// Match is the original rule taken from the configuration file.
	Match

	// OkayDate is the date calculated from Days. A message does not match this
	// rule unless it has a Date header before the OkayDate.
	OkayDate time.Time

	// Clear lists the labels to clear from the message.
	Clear []string

	// Label lists the lables to add to the message.
	Label []string

	// Move lists the folder to move the message into.
	Move string

	// Forward gives the addresses to send the message to.
	Forward addr.AddressList
}

CompiledRule is the match after it has been processed by teh rule compiler.

func (*CompiledRule) HasOkayDate

func (c *CompiledRule) HasOkayDate() bool

HasOkayDate returns true if the OkayDate is set.

func (*CompiledRule) IsClearing

func (c *CompiledRule) IsClearing() bool

IsClearing returns true if the message lists labels to clear.

func (*CompiledRule) IsForwarding

func (c *CompiledRule) IsForwarding() bool

IsForwarding returns true if the message has forwarding addresses.

func (*CompiledRule) IsLabeling

func (c *CompiledRule) IsLabeling() bool

IsLabeling returns true if the message lists labels to add.

func (*CompiledRule) IsMoving

func (c *CompiledRule) IsMoving() bool

IsMoving returns true if the message has a Move folder.

func (*CompiledRule) NeedsOkayDate

func (c *CompiledRule) NeedsOkayDate() bool

NeedsOkayDate returns true if Days is set on the Match or if the rule adds the Trash label or if the rule moves the message to the Trash.

type CompiledRules

type CompiledRules []*CompiledRule

CompiledRules is a list of compiled rules sectioned by environment name.

func LoadRules

func LoadRules() (CompiledRules, error)

LoadRules will load the rules from the various configuration files, combine, compile, and return them. Returns an error if something goes wrong.

func (CompiledRules) FolderRules

func (crs CompiledRules) FolderRules() CompiledFolderRules

FolderRules takes the compiled rules and groups them by folder. Any rule without a folder match will be added to every folder list. Those with a folder match will only be added to the folder with the same name. This performs some final cleanup on compiled rules as well.

type DirFolder

type DirFolder struct {
	// contains filtered or unexported fields
}

DirFolder represents a single maildir folder in a mail root.

func NewMailDirFolder

func NewMailDirFolder(root, folder string) *DirFolder

NewMailDirFolder constructs a DirFolder from a mail root and folder name.

func (*DirFolder) Basename

func (f *DirFolder) Basename() string

Basename returns the folder name.

func (*DirFolder) Message

func (f *DirFolder) Message(fn string) (*Message, error)

Message returns a single mail message object stored in the given file name.

func (*DirFolder) MessageDirPaths

func (f *DirFolder) MessageDirPaths() []string

MessageDirPaths returns the directory paths that contain message files that can be worked with by these mail tools.

func (*DirFolder) Messages

func (f *DirFolder) Messages() ([]*Message, error)

Messages returns all mail messages stored in the maildir.

func (*DirFolder) Path

func (f *DirFolder) Path() string

Path returns the full path to the maildir folder.

func (*DirFolder) Root

func (f *DirFolder) Root() string

Root returns the path to the mail root.

func (*DirFolder) TempDirPath

func (f *DirFolder) TempDirPath() string

TempDirPath returns the directory path where messages being worked on are stored temporarily.

type DirSlurper

type DirSlurper struct {
	// contains filtered or unexported fields
}

DirSlurper reads an email message in from a maildir folder.

func NewMailDirSlurper

func NewMailDirSlurper(key, flags, rd string, folder *DirFolder) *DirSlurper

NewMailDirSlurper creates and returns a *DirSlurper for the given folder, message key, message flags, and read status. No stat information is provided, so if Stat() is called, it will perform and cache that information later.

func NewMailDirSlurperWithStat

func NewMailDirSlurperWithStat(key, flags, rd string, folder *DirFolder, fi *os.FileInfo) *DirSlurper

NewMailDirSlurperWithStat is the same as NewMailDirSlurper, but it precaches the stat information.

func (*DirSlurper) Filename

func (r *DirSlurper) Filename() string

Filename returns the full path to the maildir message, including the folder path, the read status folder it's in and the key and flag suffix.

func (*DirSlurper) FlagSuffix

func (r *DirSlurper) FlagSuffix() string

FlagSuffix returns the flags associated with this maildir message.

func (*DirSlurper) Folder

func (r *DirSlurper) Folder() string

Folder returns the name of the folder the message is in.

func (*DirSlurper) MoveTo

func (r *DirSlurper) MoveTo(target *DirFolder) error

MoveTo moves the message to the target folder.

func (*DirSlurper) Remove

func (r *DirSlurper) Remove() error

Remove deletes the maildir message file.

func (*DirSlurper) Replace

func (r *DirSlurper) Replace() (*DirWriter, error)

Replace returns another *DirWriter for overwriting the current *DirWriter.

func (*DirSlurper) Slurp

func (r *DirSlurper) Slurp() ([]byte, error)

Slurp slurps up the file data and returns it.

func (*DirSlurper) Stat

func (r *DirSlurper) Stat() (os.FileInfo, error)

Stat returns the cached os.FileInfo or performs an os.Stat() to read it in and return it it. It caches that information for next time.

type DirWriter

type DirWriter struct {
	// contains filtered or unexported fields
}

DirWriter perform message writing for a DirSlurper.

func NewMailDirWriter

func NewMailDirWriter(r *DirSlurper) (*DirWriter, error)

NewMailDirWriter creates a DirWriter from the given DirSlurper. This will immediately open the file referred to by the *DirSlurper for overwriting.

func (*DirWriter) Close

func (w *DirWriter) Close() error

Close closes open file handles.

func (*DirWriter) Write

func (w *DirWriter) Write(bs []byte) (int, error)

Write saves the given bytes to disk.

type EnvRawRules

type EnvRawRules map[string]RawRules

EnvRawRules is a list of rules sectioned by environment name.

type Filter

type Filter struct {
	MailRoot string        // maildir to filter
	Rules    CompiledRules // the compiled filter rules

	LimitRecent time.Duration // if set, only message files newer than this will be filtered

	Debug  int  // set the debug level, higher numbers mean even more verbose logging
	DryRun bool // when set, no changes will be made

	AllowSendingEmail bool // unless set, no email forwarding will be performed
}

Filter represents the tools that parse and understand mail rules and filter folders and messages.

func NewFilter

func NewFilter(root string) (*Filter, error)

NewFilter loads the rules and prepares the system for message filtering.

func (*Filter) AllFolders

func (fi *Filter) AllFolders() ([]string, error)

AllFolders lists all the maildir folders in the mail root.

func (*Filter) ApplyRule

func (fi *Filter) ApplyRule(m *Message, c *CompiledRule) ([]string, error)

ApplyRule applies a single mail filter rule to a single mail message.

func (*Filter) ApplyRules

func (fi *Filter) ApplyRules(msg *Message, rules []*CompiledRule) ([]string, error)

ApplyRules applies all the rules to a single mail message.

func (*Filter) LabelFolderMessages

func (fi *Filter) LabelFolderMessages(
	actions ActionsSummary,
	folder string,
	rules CompiledRules,
) error

LabelFolderMessages performs filtering for a single maildir.

func (*Filter) LabelMessage

func (fi *Filter) LabelMessage(folder, fn string) (ActionsSummary, error)

LabelMessage applies filters to a specific message.

func (*Filter) LabelMessages

func (fi *Filter) LabelMessages(onlyFolders []string) (ActionsSummary, error)

LabelMessages applies filters to all applicable messages in the given list of folders.

func (*Filter) LimitFilterToRecent

func (fi *Filter) LimitFilterToRecent(limit time.Duration)

LimitFilterToRecent sets the LimitRecent time. When set and filtering folders, only messages with a modification time newer than LimitRecent will be filtered.

func (*Filter) LimitSince

func (fi *Filter) LimitSince() time.Time

LimitSince returns the LimitSince setting set by LimitFilterToRecent.

func (*Filter) Message

func (fi *Filter) Message(folder, fn string) (*Message, error)

Message returns a single message in a single folder.

func (*Filter) Messages

func (fi *Filter) Messages(folder string) ([]*Message, error)

Messages returns all the messages that should be filtered in that folder.

func (*Filter) RulesForFolder

func (fi *Filter) RulesForFolder(f string) (CompiledRules, bool)

RulesForFolder returns all the rules that apply to the given folder. The second return value is a boolean indicating whether this folder has any rules at all.

func (*Filter) Vacuum

func (fi *Filter) Vacuum() error

Vacuum performs the vacuum operation which attempts to clean up undesireable folder and keywords from my mail root.

type Match

type Match struct {
	// Folder is used to limit matching to an individual folder. If not given,
	// this rule will be applied to all folders.
	Folder string `yaml:"folder"`

	// From is used to match email addresses in the From header.
	From string `yaml:"from"`

	// FromDomain is used to match email address domains in the From header.
	FromDomain string `yaml:"from_domain"`

	// To is used to match email addresses in the To header.
	To string `yaml:"to"`

	// ToDomain is used to match email address domains in the To header.
	ToDomain string `yaml:"to_domain"`

	// Sender is used to match email addresses in the Sender header.
	Sender string `yaml:"sender"`

	// DeliveredTo is used to match email addresses in the Delivered-To header.
	DeliveredTo string `yaml:"delivered_to"`

	// Subject is used to match entire Subject header exactly.
	Subject string `yaml:"subject"`

	// SubjectFold is used to match entire Subject header exactly but with
	// case-insensitivity.
	SubjectFold string `yaml:"isubject"`

	// SubjectContains is used to match a substring of the Subject header.
	SubjectContains string `yaml:"subject_contains"`

	// SubjectContainsFold is used to match a substring of the Subject header,
	// but with case-insensitivity.
	SubjectContainsFold string `yaml:"subject_icontains"`

	// Contains is used ot match a substring anywhere in the email message.
	Contains string `yaml:"contains"`

	// ContainsFold is used to match a substring anywhere in the email message,
	// but with case-insensitivity.
	ContainsFold string `yaml:"icontains"`

	// Days limits matches to email messages older than the given number
	// of days.
	Days int `yaml:"days"`
}

Match is the input configuration used for each rule.

type Message

type Message struct {
	// contains filtered or unexported fields
}

Message represents a MIME message which may be partially or fully read in.

func NewFileMessage

func NewFileMessage(filename string) *Message

NewFileMessage returns a single message to be read in using a *MessageSlurper with the given filename.

func NewMailDirMessage

func NewMailDirMessage(key, flags, rd string, folder *DirFolder) *Message

NewMailDirMessage returns a single message to be read in using a *DirSlurper from the given key, flags, read status, and folder.

func NewMailDirMessageWithStat

func NewMailDirMessageWithStat(key, flags, rd string, folder *DirFolder, fi *os.FileInfo) *Message

NewMailDirMessageWithStat returns a single message to be read in using a *DirSlurper, but with the given stat info.

func NewMessage

func NewMessage(r Slurper) *Message

NewMessage creates a *Message from a Slurper.

func (*Message) AddKeyword

func (m *Message) AddKeyword(names ...string) error

AddKeyword adds all the given names to the Keywords header. Returns an error if it has a problem reading the email message or writing ot hte Keywords header.

func (*Message) AddressList

func (m *Message) AddressList(key string) (addr.AddressList, error)

AddressList tries the first header matching the given key and parses it as an address list. It returns the parsed list or returns ane error.

func (*Message) AllAddressLists

func (m *Message) AllAddressLists(key string) (addr.AddressList, error)

AllAddressLists tries every header matching the given key and parses it as an address list. Those lists are joined together and returned as a single list. Returns an error if it has trouble reading the message or parsing the address lists.

func (*Message) BestAlternateFolder

func (m *Message) BestAlternateFolder() (string, error)

BestAlternateFolder returns a folder name describing a better folder for the given name. This really ought to be in configuration.

func (*Message) CleanupKeywords

func (m *Message) CleanupKeywords() error

CleanupKeywords removes duplicate keywords from the Keywords header and updates the Keywords header. Returns an error if it has a problem reading or writing the header.

func (*Message) Date

func (m *Message) Date() (time.Time, error)

Date returns the contents of hte Date hread of the message or an error.

func (*Message) EmailMessage

func (m *Message) EmailMessage() (*mime.Message, error)

EmailMessage returns the *mime.Message of the read in message or an error.

func (*Message) Filename

func (m *Message) Filename() string

Filename returns the name of the file containing the message.

func (*Message) Folder

func (m *Message) Folder() (string, error)

Folder returns the name of the folder that contains this email's file.

func (*Message) ForwardMessage

func (m *Message) ForwardMessage(to addr.AddressList) ([]byte, error)

ForwardMessage builds and formats the current message as a message forwarded to the given address.

func (*Message) ForwardTo

func (m *Message) ForwardTo(tos addr.AddressList) error

ForwardTo performs message forwarding. It formats the message itself to prep it for forwarding and contacts the SMTP to create the envelope and send it.

func (*Message) HasKeyword

func (m *Message) HasKeyword(names ...string) (bool, error)

HasKeyword returns true if the Keywords header contains all of the given keyword names. It returns an error if it has a problem reading or parsing the Keywords header. If there's no error reading Keywords and the list of names is empty, this will always return true.

func (*Message) HasNonconformingKeywords

func (m *Message) HasNonconformingKeywords() (bool, error)

HasNonconformingKeywords returns true if the Keywords header is mailformed.

func (*Message) Keywords

func (m *Message) Keywords() ([]string, error)

Keywords returns the contents of the Keywords header of the message as a slice of strings or an error.

func (*Message) KeywordsSet

func (m *Message) KeywordsSet() (km map[string]struct{}, err error)

KeywordsSet returns the contents of the Keywords header as a set or an error.

func (*Message) MissingKeyword

func (m *Message) MissingKeyword(names ...string) (bool, error)

MissingKeyword returns true if the Keywrods header contains none of the given keyword names. It returns an error if it has a problem reading or parsing the Keywords header. If there's no error reading Keywords and the list of names is empty, this will always return true.

func (*Message) MoveTo

func (m *Message) MoveTo(root string, name string) error

MoveTo moves the message to the maildir folder represented by the given root directory and folder name. Returns an error if the move fails.

func (*Message) Raw

func (m *Message) Raw() ([]byte, error)

Raw returns the byte represetnation of the original read in message or an error.

func (*Message) RemoveKeyword

func (m *Message) RemoveKeyword(names ...string) error

RemoveKeyword removes all the a names given from the Keywords header, if those keywords are present. Returns an error if it has a problem reading or parsing the Keywords header or writing to it.

func (*Message) Save

func (m *Message) Save() error

Save saves any modifications made to the message to disk.

func (*Message) Stat

func (m *Message) Stat() (os.FileInfo, error)

Stat returns the file info for the file containing the message or an error.

func (*Message) Subject

func (m *Message) Subject() (string, error)

Subject returns the contents of the Subject header.

type MessageSlurper

type MessageSlurper struct {
	// contains filtered or unexported fields
}

MessageSlurper is able to read a MIME message from any file on disk.

func NewMessageSlurper

func NewMessageSlurper(filename string) *MessageSlurper

NewMessageSlurper returns a *MessageSlurper for the given filename.

func (*MessageSlurper) Filename

func (r *MessageSlurper) Filename() string

Filename returns the name of the message.

func (*MessageSlurper) Folder

func (r *MessageSlurper) Folder() string

Folder attempts to guess what the folder name is and returns that.

func (*MessageSlurper) Slurp

func (r *MessageSlurper) Slurp() ([]byte, error)

Slurp reads in the MIME message.

func (*MessageSlurper) Stat

func (r *MessageSlurper) Stat() (os.FileInfo, error)

Stat uses os.Stat() to stat the file.

type RawRule

type RawRule struct {
	// Match represents the matches to apply.
	Match `yaml:",inline"`

	// Clear is either a string or list containing labels to remove when a
	// message matches.
	Clear interface{} `yaml:"clear"`

	// Label is either a string or list containing labels to edd when a message
	// matches.
	Label interface{} `yaml:"label"`

	// Move is the name of the folder to move matching messages into.
	Move string `yaml:"move"`

	// Forward is the string or list containing email addresses to send the
	// message to if it matches.
	Forward interface{} `yaml:"forward"`
}

RawRule is the rule in the configuration file combining both the Match and the actions to take.

type RawRules

type RawRules []RawRule

RawRules is a list of rules

type Slurper

type Slurper interface {
	// Slurp returns the bytes of the read message or returns an error.
	Slurp() ([]byte, error)

	// Filename gives the file name of the message on disk.
	Filename() string

	// Folder names the folder of the message on disk.
	Folder() string

	// Stat returns the file info for the message on disk or returns an error.
	Stat() (os.FileInfo, error)
}

Slurper describes the interface to implement for anything that can read an email message.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL