// 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 }
// 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 }
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 }
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 } } }
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 }