Пример #1
1
func getThreads(c *imap.Client) ([]Thread, error) {
	set, err := imap.NewSeqSet("1:*")
	cmd, err := imap.Wait(c.Fetch(set, "X-GM-THRID", "UID"))
	if err != nil {
		fmt.Println(err)
		return nil, ErrBadConnection
	}
	var result []Thread
	seen := make(map[string]int)
	for _, rsp := range cmd.Data {
		thrid := imap.AsString(rsp.MessageInfo().Attrs["X-GM-THRID"])
		uid := imap.AsNumber(rsp.MessageInfo().Attrs["UID"])
		if i, ok := seen[thrid]; ok {
			result[i] = append(result[i], uid)
		} else {
			result = append(result, Thread{uid})
			seen[thrid] = len(result) - 1
		}
	}
	return result, nil
}
Пример #2
0
func fetch(c *imap.Client, user string, thread Thread) ([]*ParsedMail, error) {
	var set imap.SeqSet
	for _, uid := range thread {
		set.AddNum(uid)
	}
	cmd, err := imap.Wait(c.UIDFetch(&set, "BODY[]", "X-GM-MSGID", "X-GM-THRID"))
	if err != nil {
		return nil, ErrBadConnection
	}
	parsed := make([]*ParsedMail, len(cmd.Data))
	for i, rsp := range cmd.Data {
		p, err := parseMail(imap.AsBytes(rsp.MessageInfo().Attrs["BODY[]"]), user)
		if err != nil {
			return nil, err
		}
		link, err := gmailLink(imap.AsString(rsp.MessageInfo().Attrs["X-GM-MSGID"]))
		if err != nil {
			return nil, err
		}
		p.GmailLink = link
		p.Thrid = imap.AsString(rsp.MessageInfo().Attrs["X-GM-THRID"])
		parsed[i] = p
	}
	return parsed, nil
}
Пример #3
0
func parseContent(mi *imap.MessageInfo, mimeHeader PMIMEHeader) (Content, error) {
	// 1) If no content is given, error and return
	if nil == mi {
		return nil, errors.New("[watney] ERROR: Couldn't parse mail content due to missing content.")
	}
	var (
		content string  = imap.AsString(mi.Attrs["RFC822.TEXT"])
		parts   Content = make(Content, 1)
	)
	// 2) Simple Case: We have no MIME protocol, simply assume the content is plain text
	if 0 == mimeHeader.MimeVersion {
		parts["text/plain"] = ContentPart{
			Encoding: "quoted-printable",
			Charset:  "UTF-8",
			Body:     content,
		}
		return parts, nil
	}
	// 3) Otherwise, we have to check the Content-Type: If its NOT a multipart, just add it as is
	if !strings.Contains(mimeHeader.ContentType, "multipart") {
		parts[mimeHeader.ContentType] = ContentPart{
			Encoding: mimeHeader.Encoding,
			Charset:  "UTF-8",
			Body:     content,
		}
		return parts, nil
	}
	// 4) Otherwise, in case we have a multipart Content-Type, parse all parts
	return parseMultipartContent(content, mimeHeader.MultipartBoundary)
}
Пример #4
0
// newEmailMessage will parse an imap.FieldMap into an map[string]interface{}. This
// will expect the message to container the internaldate and the body with
// all headers included.
func newEmailMessage(msgFields imap.FieldMap) (map[string]interface{}, error) {
	var email map[string]interface{}
	// parse the header
	rawHeader := imap.AsBytes(msgFields["RFC822.HEADER"])
	msg, err := mail.ReadMessage(bytes.NewReader(rawHeader))
	if err != nil {
		return email, err
	}

	email = map[string]interface{}{
		"internal_date": imap.AsDateTime(msgFields["INTERNALDATE"]),
		"body":          imap.AsString(msgFields["BODY[]"]),
		"from":          msg.Header.Get("From"),
		"to":            msg.Header.Get("To"),
		"subject":       msg.Header.Get("Subject"),
	}

	return email, nil
}
Пример #5
0
func parseHeader(mi *imap.MessageInfo) (*Header, error) {
	// 1) If no MessageInfo was passed => return and error
	if nil == mi {
		return nil,
			errors.New("Couldn't parse Mail Header, because the given MessageInfo object is nil")
	}
	// 2) If the given MessageInfo doesn't contain a header string => return and error
	var (
		mailHeader imap.Field
		curHeader  *Header
		err        error
	)
	if mailHeader = mi.Attrs["RFC822.HEADER"]; nil == mailHeader {
		return nil, errors.New("Couldn't parse Mail Header, because no header was provided " +
			"in the given MessageInfo object")
	}
	if curHeader, err = parseHeaderStr(imap.AsString(mailHeader)); err == nil {
		curHeader.Size = mi.Size
	}
	return curHeader, err
}