作者:hellcoder
项目:streamtool
// getEmails will fetch the full bodies of all emails listed in the given command.
func getEmails(client *imap.Client, cmd *imap.Command) ([]map[string]interface{}, error) {
var emails []map[string]interface{}
seq := new(imap.SeqSet)
for _, rsp := range cmd.Data {
for _, uid := range rsp.SearchResults() {
seq.AddNum(uid)
}
}
if seq.Empty() {
return emails, nil
}
fCmd, err := imap.Wait(client.UIDFetch(seq, "INTERNALDATE", "BODY[]", "UID", "RFC822.HEADER"))
if err != nil {
return emails, err
}
var email map[string]interface{}
for _, msgData := range fCmd.Data {
msgFields := msgData.MessageInfo().Attrs
email, err = newEmailMessage(msgFields)
if err != nil {
return emails, err
}
emails = append(emails, email)
// mark message as read
fSeq := new(imap.SeqSet)
fSeq.AddNum(imap.AsNumber(msgFields["UID"]))
_, err = imap.Wait(client.UIDStore(fSeq, "+FLAGS", "\\SEEN"))
if err != nil {
return emails, err
}
}
return emails, nil
}
作者:pruthvirajsin
项目:go-Sima
func FetchAllUIDs(c *imap.Client) (uids []uint32, err error) {
maxmessages := 150000
uids = make([]uint32, maxmessages)
set, errS := imap.NewSeqSet("1:*")
if errS != nil {
err = errS
return
}
cmd, errF := c.UIDFetch(set, "RFC822.SIZE")
if errF != nil {
err = errF
return
}
messagenum := uint32(0)
for cmd.InProgress() {
errC := c.Recv(-1)
if errC != nil {
continue
}
for _, rsp := range cmd.Data {
uid := imap.AsNumber(rsp.MessageInfo().Attrs["UID"])
uids[messagenum] = uid
}
cmd.Data = nil
messagenum++
}
uids = uids[:messagenum]
return
}
作者:pruthvirajsin
项目:go-Sima
func FetchMessages(c *imap.Client, uidSet *imap.SeqSet) (fetched []MsgData, err error) {
cmd, errF := c.UIDFetch(uidSet, "RFC822")
if errF != nil {
err = errF
return
}
for cmd.InProgress() {
errC := c.Recv(-1)
if errC != nil {
return
}
for _, rsp := range cmd.Data {
uid := imap.AsNumber(rsp.MessageInfo().Attrs["UID"])
mime := imap.AsBytes(rsp.MessageInfo().Attrs["RFC822"])
msg, errR := mail.ReadMessage(bytes.NewReader(mime))
if errR != nil {
continue
}
if msg != nil {
msgdata := GetMessage(msg, uid)
fetched = append(fetched, msgdata)
}
}
cmd.Data = nil
}
return
}
作者:hellcoder
项目:streamtool
// findUnreadEmails will run a find the UIDs of any unread emails in the
// mailbox.
func findUnreadEmails(conn *imap.Client) (*imap.Command, error) {
// get headers and UID for UnSeen message in src inbox...
cmd, err := imap.Wait(conn.UIDSearch("UNSEEN"))
if err != nil {
return &imap.Command{}, err
}
return cmd, nil
}
作者:jprobinso
项目:copycat-ima
// checkAndStoreMessages will wait for WorkRequests to come acorss the pipe. When it receives a request, it will search
// the given destination inbox for the message. If it is not found, this method will attempt to pull the messages data
// from fetchRequests and then append it to the destination.
func CheckAndAppendMessages(dstConn *imap.Client, storeRequests chan WorkRequest, fetchRequests chan fetchRequest, wg *sync.WaitGroup) {
defer wg.Done()
// noop it every few to keep things alive
timeout := time.NewTicker(NoopMinutes * time.Minute)
done := false
for {
select {
case request, ok := <-storeRequests:
if !ok {
done = true
break
}
// search for in dst
cmd, err := imap.Wait(dstConn.UIDSearch([]imap.Field{"HEADER", request.Header, request.Value}))
if err != nil {
log.Printf("Unable to search for message (%s): %s. skippin!", request.Value, err.Error())
continue
}
results := cmd.Data[0].SearchResults()
// if not found, PULL from SRC and STORE in DST
if len(results) == 0 {
// only fetch if we dont have data already
if len(request.Msg.Body) == 0 {
// build and send fetch request
response := make(chan MessageData)
fr := fetchRequest{MessageId: request.Value, UID: request.UID, Response: response}
fetchRequests <- fr
// grab response from fetchers
request.Msg = <-response
}
if len(request.Msg.Body) == 0 {
log.Printf("No data found for from fetch request (%s). giving up", request.Value)
continue
}
err = AppendMessage(dstConn, request.Msg)
if err != nil {
log.Printf("Problems appending message to dst: %s. quitting.", err.Error())
return
}
}
case <-timeout.C:
imap.Wait(dstConn.Noop())
}
if done {
break
}
}
log.Print("storer complete!")
return
}
作者:jprobinso
项目:copycat-ima
// FetchEmails will sit and wait for fetchRequests from the destination workers.
func fetchEmails(conn *imap.Client, requests chan fetchRequest, cache *Cache) {
// noop every few to keep things alive
timeout := time.NewTicker(NoopMinutes * time.Minute)
done := false
for {
select {
case request, ok := <-requests:
if !ok {
done = true
break
}
found := true
// check if the message body is in cache
data, err := cache.Get(request.MessageId)
if err != nil {
found = false
if err != ErrNotFound {
log.Printf("problems pulling message data from cache: %s. Pulling message from src...", err.Error())
}
data = MessageData{}
}
if found {
log.Print("cache success!")
request.Response <- data
continue
}
msgData, err := FetchMessage(conn, request.UID)
if err != nil {
if err == NotFound {
log.Printf("No data found for UID: %d", request.UID)
} else {
log.Printf("Problems fetching message (%s) data: %s. Passing request and quitting.", request.MessageId, err.Error())
requests <- request
return
}
}
request.Response <- msgData
err = cache.Put(request.MessageId, msgData)
if err != nil {
log.Printf("Unable to add message (%s) to cache: %s", request.MessageId, err.Error())
}
case <-timeout.C:
imap.Wait(conn.Noop())
}
if done {
break
}
}
}
作者:jprobinso
项目:copycat-ima
func ResetConnection(conn *imap.Client, readOnly bool) error {
// dont check for error because its possible it's already closed.
conn.Close(!readOnly)
_, err := imap.Wait(conn.Select("INBOX", readOnly))
if err != nil {
return err
}
return nil
}
作者:jprobinso
项目:copycat-ima
func GetAllMessages(conn *imap.Client) (*imap.Command, error) {
// get headers and UID for ALL message in src inbox...
allMsgs, _ := imap.NewSeqSet("")
allMsgs.Add("1:*")
cmd, err := imap.Wait(conn.Fetch(allMsgs, "RFC822.HEADER", "UID"))
if err != nil {
return &imap.Command{}, err
}
return cmd, nil
}
作者:sq
项目:go-sync
func SearchUIDs(c *imap.Client, query string) (uids []uint32, err error) {
cmd, err := c.UIDSearch("X-GM-RAW", fmt.Sprint("\"", query, "\""))
for cmd.InProgress() {
c.Recv(-1)
for _, rsp := range cmd.Data {
uids = rsp.SearchResults()
}
cmd.Data = nil
}
return
}
作者:sq
项目:go-sync
func FetchMessages(c *imap.Client, uidSet *imap.SeqSet) (err error) {
cmd, err := c.UIDFetch(uidSet, "RFC822")
for cmd.InProgress() {
c.Recv(-1)
for _, rsp := range cmd.Data {
uid := imap.AsNumber(rsp.MessageInfo().Attrs["UID"])
mime := imap.AsBytes(rsp.MessageInfo().Attrs["RFC822"])
if msg, _ := mail.ReadMessage(bytes.NewReader(mime)); msg != nil {
PrintMessageAsJSON(msg, uid)
}
}
cmd.Data = nil
}
return
}
作者:jprobinso
项目:copycat-ima
func checkMessagesExist(srcConn *imap.Client, checkRequests chan checkExistsRequest, wg *sync.WaitGroup) {
defer wg.Done()
// get memcache client
cache := memcache.New(MemcacheServer)
timeout := time.NewTicker(NoopMinutes * time.Minute)
done := false
for {
select {
case request, ok := <-checkRequests:
if !ok {
done = true
break
}
// check if it exists in src
// search for in src
cmd, err := imap.Wait(srcConn.UIDSearch([]imap.Field{"HEADER", "Message-Id", request.MessageId}))
if err != nil {
log.Printf("Unable to search source: %s", err.Error())
request.Response <- true
continue
}
results := cmd.Data[0].SearchResults()
// if not found, mark for deletion in DST
found := (len(results) > 0)
// response with found bool
request.Response <- found
// if it doesnt exist, attempt to remove it from memcached
if !found {
cache.Delete(request.MessageId)
}
case <-timeout.C:
imap.Wait(srcConn.Noop())
}
if done {
break
}
}
}
作者:jprobinso
项目:copycat-ima
func FetchMessage(conn *imap.Client, messageUID uint32) (msg MessageData, err error) {
seq, _ := imap.NewSeqSet("")
seq.AddNum(messageUID)
var cmd *imap.Command
cmd, err = imap.Wait(conn.UIDFetch(seq, "INTERNALDATE", "BODY[]", "UID", "RFC822.HEADER"))
if err != nil {
log.Printf("Unable to fetch message (%d): %s", messageUID, err.Error())
return
}
if len(cmd.Data) == 0 {
log.Printf("Unable to fetch message (%d) from src: NO DATA", messageUID)
return msg, NotFound
}
msgFields := cmd.Data[0].MessageInfo().Attrs
msg = MessageData{InternalDate: imap.AsDateTime(msgFields["INTERNALDATE"]), Body: imap.AsBytes(msgFields["BODY[]"])}
return msg, nil
}
作者:jprobinso
项目:copycat-ima
func checkAndPurgeMessages(conn *imap.Client, requests chan WorkRequest, checkRequests chan checkExistsRequest, wg *sync.WaitGroup) {
defer wg.Done()
timeout := time.NewTicker(NoopMinutes * time.Minute)
done := false
for {
select {
case request, ok := <-requests:
if !ok {
done = true
break
}
// check and wait for response
response := make(chan bool)
cr := checkExistsRequest{UID: request.UID, MessageId: request.Value, Response: response}
checkRequests <- cr
// if response is false (does not exist), flag as Deleted
if exists := <-response; !exists {
log.Printf("not found in src. marking for deletion: %s", request.Value)
err := AddDeletedFlag(conn, request.UID)
if err != nil {
log.Printf("Problems removing message from dst: %s", err.Error())
}
}
case <-timeout.C:
imap.Wait(conn.Noop())
}
if done {
break
}
}
log.Printf("expunging...")
// expunge at the end
allMsgs, _ := imap.NewSeqSet("")
allMsgs.Add("1:*")
imap.Wait(conn.Expunge(allMsgs))
log.Printf("expunge complete.")
}
作者:daffodi
项目:go-mailki
func GetUIDs(mbox string, client *imap.Client) ([]uint32, error) {
uids := make([]uint32, 0)
cmd, err := client.Select(mbox, true)
if err != nil {
return uids, err
}
//== Get UIDS of all messages
cmd, err = imap.Wait(client.UIDSearch("", "ALL"))
if err != nil {
return uids, err
}
for idx := range cmd.Data {
for _, uid := range cmd.Data[idx].SearchResults() {
uids = append(uids, uid)
}
}
return uids, nil
}
作者:jprobinso
项目:copycat-ima
// getNextUID will grab the next message UID from the inbox. Client.Mailbox.UIDNext is cached so we can't use it.
func getNextUID(conn *imap.Client) (uint32, error) {
cmd, err := imap.Wait(conn.Status("INBOX", "UIDNEXT"))
if err != nil {
return 0, err
}
if len(cmd.Data) == 0 {
return 0, errors.New("no data returned!")
}
var status *imap.MailboxStatus
for _, resp := range cmd.Data {
switch resp.Type {
case imap.Data:
status = resp.MailboxStatus()
if status != nil {
break
}
}
}
return status.UIDNext, nil
}
作者:pruthvirajsin
项目:go-Sima
func sensitive(c *imap.Client, action string) imap.LogMask {
mask := c.SetLogMask(imap.LogConn)
hide := imap.LogCmd | imap.LogRaw
if mask&hide != 0 {
c.Logln(imap.LogConn, "Raw logging disabled during", action)
}
c.SetLogMask(mask &^ hide)
return mask
}
作者:daffodi
项目:go-mailki
//= Return list of IMAP folders
func GetFolders(client *imap.Client) ([]*Folder, error) {
folders := make([]*Folder, 0)
cmd, err := imap.Wait(client.List("", "*"))
if err != nil {
return folders, err
}
for idx := range cmd.Data {
info := cmd.Data[idx].MailboxInfo()
fol := new(Folder)
fol.Name = info.Name
for flag, boo := range info.Attrs {
fmt.Println(info.Name, boo, flag)
if info.Name == "INBOX" && boo {
fol.Type = "inbox"
} else if flag == "\\Junk" && boo {
fol.Type = "junk"
} else if flag == "\\Trash" && boo {
fol.Type = "trash"
} else if flag == "\\Sent" && boo {
fol.Type = "sent"
} else if flag == "\\Drafts" && boo {
fol.Type = "drafts"
}
}
folders = append(folders, fol)
}
return folders, nil
}
作者:justjak
项目:mai
// use whatever imap connection type is specified by s.UseTLS
func (s *Server) Connect() (*imap.Client, error) {
if s.client != nil {
s.disconnectTimer.Reset(NoUsageDisconnect)
return s.client, nil
}
var c *imap.Client
var err error
// actual dailing happens
if s.UseTLS {
c, err = s.dialTLS()
} else {
c, err = s.dial()
}
if err != nil {
return nil, err
}
// log in
if c.State() == imap.Login {
_, err := c.Login(s.Username, s.Password)
if err != nil {
s.Close()
return nil, err
}
} else {
s.Close()
return nil, fmt.Errorf("expected imap.Login state, instead was %v.", c.State())
}
// auto-disconnect after a certain timeout
s.disconnectTimer = time.AfterFunc(NoUsageDisconnect, func() {
s.Close()
})
return c, nil
}
作者:pruthvirajsin
项目:go-Sima
func login(c *imap.Client, user, pass string) (cmd *imap.Command, err error) {
defer c.SetLogMask(sensitive(c, "LOGIN"))
return c.Login(user, pass)
}
作者:kaihendr
项目:go-ima
func ExampleClient() {
//
// Note: most of error handling code is omitted for brevity
//
var (
c *imap.Client
cmd *imap.Command
rsp *imap.Response
)
// Connect to the server
c, _ = imap.Dial("imap.example.com")
// Remember to log out and close the connection when finished
defer c.Logout(30 * time.Second)
// Print server greeting (first response in the unilateral server data queue)
fmt.Println("Server says hello:", c.Data[0].Info)
c.Data = nil
// Enable encryption, if supported by the server
if c.Caps["STARTTLS"] {
c.StartTLS(nil)
}
// Authenticate
if c.State() == imap.Login {
c.Login("[email protected]", "mysupersecretpassword")
}
// List all top-level mailboxes, wait for the command to finish
cmd, _ = imap.Wait(c.List("", "%"))
// Print mailbox information
fmt.Println("\nTop-level mailboxes:")
for _, rsp = range cmd.Data {
fmt.Println("|--", rsp.MailboxInfo())
}
// Check for new unilateral server data responses
for _, rsp = range c.Data {
fmt.Println("Server data:", rsp)
}
c.Data = nil
// Open a mailbox (synchronous command - no need for imap.Wait)
c.Select("INBOX", true)
fmt.Print("\nMailbox status:\n", c.Mailbox)
// Fetch the headers of the 10 most recent messages
set, _ := imap.NewSeqSet("")
if c.Mailbox.Messages >= 10 {
set.AddRange(c.Mailbox.Messages-9, c.Mailbox.Messages)
} else {
set.Add("1:*")
}
cmd, _ = c.Fetch(set, "RFC822.HEADER")
// Process responses while the command is running
fmt.Println("\nMost recent messages:")
for cmd.InProgress() {
// Wait for the next response (no timeout)
c.Recv(-1)
// Process command data
for _, rsp = range cmd.Data {
header := imap.AsBytes(rsp.MessageInfo().Attrs["RFC822.HEADER"])
if msg, _ := mail.ReadMessage(bytes.NewReader(header)); msg != nil {
fmt.Println("|--", msg.Header.Get("Subject"))
}
}
cmd.Data = nil
// Process unilateral server data
for _, rsp = range c.Data {
fmt.Println("Server data:", rsp)
}
c.Data = nil
}
// Check command completion status
if rsp, err := cmd.Result(imap.OK); err != nil {
if err == imap.ErrAborted {
fmt.Println("Fetch command aborted")
} else {
fmt.Println("Fetch error:", rsp.Info)
}
}
}