示例#1
0
        public bool Equals(ImapFolderUids p)
        {
            // If parameter is null return false:
            if ((object)p == null)
            {
                return(false);
            }

            // Return true if the fields match:
            return((BeginDateUid == p.BeginDateUid) && (UnhandledUidIntervals.SequenceEqual(p.UnhandledUidIntervals)));
        }
示例#2
0
        public bool Equals(ImapFolderUids p)
        {
            // If parameter is null return false:
            if ((object)p == null)
            {
                return false;
            }

            // Return true if the fields match:
            return (BeginDateUid == p.BeginDateUid) && (UnhandledUidIntervals.SequenceEqual(p.UnhandledUidIntervals));
        }
示例#3
0
        private int LoadMailboxMessage(Mailbox mb,
                                    int folderId,
                                    int maxMessagesPerSession,
                                    string[] tagsNames, out bool quotaErrorFlag)
        {
            UpdateTimeCheckedIfNeeded();

            ImapFolderUids folderUids;
            if (!Account.ImapIntervals.TryGetValue(mb.Name, out folderUids))
                folderUids = new ImapFolderUids(); // by default - mailbox never was processed before

            var imapIntervals = new ImapIntervals(folderUids.UnhandledUidIntervals);
            var beginDateUid = folderUids.BeginDateUid;

            quotaErrorFlag = false;

            int[] tagsIds = null;
            var tagsRetrieved = false;

            var allUids = mb.UidSearch("1:*").OrderBy(i => i).SkipWhile(i => i < beginDateUid).ToList();

            foreach (var uidsInterval in imapIntervals.GetUnhandledIntervalsCopy())
            {
                cancelToken.ThrowIfCancellationRequested();
                
                if (!mb.SourceClient.IsConnected)
                    break;
                
                if (maxMessagesPerSession == 0)
                    break;

                var interval = uidsInterval;
                var uidsCollection =
                    allUids.Select(u => u)
                            .Where(u => u <= interval.To && u >= interval.From)
                            .OrderByDescending(x => x)
                            .ToList();

                if (!uidsCollection.Any())
                {
                    if (!uidsInterval.IsToUidMax())
                        imapIntervals.AddHandledInterval(uidsInterval);
                    continue;
                }

                var toUid = uidsInterval.IsToUidMax()
                                 ? uidsCollection.First()
                                 : Math.Max(uidsInterval.To, uidsCollection.First());

                #region Loading messages

                foreach (var uid in uidsCollection)
                {
                    var hasParseError = false;

                    cancelToken.ThrowIfCancellationRequested();

                    try
                    {
                        if (!mb.SourceClient.IsConnected)
                        {
                            log.Warn("Imap4-server is disconnected. Skip another messages.");
                            break;
                        }

                        log.Debug("Processing new message\tUID: {0}", uid);

                        // flags should be retrieved before message fetch - because mail server
                        // could add seen flag right after message was retrieved by us
                        var flags = mb.Fetch.UidFlags(uid);

                        //Peek method didn't set \Seen flag on mail
                        var message = mb.Fetch.UidMessageObjectPeek(uid);

                        if (message.HasParseError)
                        {
                            log.Error("ActiveUp: message parsed with some errors. MailboxId = {0} Message UID = {1}", Account.MailBoxId, uid);
                            hasParseError = true;
                        }

                        UpdateTimeCheckedIfNeeded();

                        if (message.Date < Account.BeginDate)
                        {
                            log.Debug("Skip message (Date = {0}) on BeginDate = {1}", message.Date, Account.BeginDate);
                            imapIntervals.SetBeginIndex(toUid);
                            beginDateUid = toUid;
                            break;
                        }

                        var uniqueIdentifier = string.Format("{0}|{1}|{2}|{3}",
                                                              message.From.Email,
                                                              message.Subject,
                                                              message.DateString,
                                                              message.MessageId);

                        var headerMd5 = uniqueIdentifier.GetMd5();

                        //Get tags ids for folder before message proccessing only once
                        if (!tagsRetrieved)
                        {
                            tagsIds = tagsNames.Any() ? InvokeOnGetOrCreateTags(tagsNames) : null;
                            tagsRetrieved = true;
                        }

                        var unread = null == flags["seen"];
                        var uidl = string.Format("{0}-{1}", uid, folderId);
                        RetrieveMessage(message, folderId, uidl, headerMd5, hasParseError, unread, tagsIds);
                    }
                    catch (Exception e)
                    {
                        log.Error(
                            "ProcessMessages() Tenant={0} User='******' Account='{2}', MailboxId={3}, UID={4} Exception:\r\n{5}\r\n",
                            Account.TenantId, Account.UserId, Account.EMail.Address, Account.MailBoxId,
                            uid, e);

                        if (e is IOException || e is MailBoxOutException)
                        {
                            maxMessagesPerSession = 0; // stop checking other mailboxes
                        }
                        else if (e is TenantQuotaException)
                        {
                            quotaErrorFlag = true;
                        }

                        if (uid != uidsCollection.First() && uid != toUid)
                        {
                            imapIntervals.AddHandledInterval(new UidInterval(uid + 1, toUid));
                        }
                        toUid = uid - 1;

                        if (maxMessagesPerSession == 0)
                            break;

                        continue;
                    }

                    // after successfully message saving - lets update imap intervals state
                    imapIntervals.AddHandledInterval(
                        new UidInterval(
                            uid == uidsCollection.Last() && uidsInterval.IsFromUidMin() ? uidsInterval.From : uid, toUid));

                    toUid = uid - 1;

                    UpdateTimeCheckedIfNeeded();

                    maxMessagesPerSession--;

                    if (maxMessagesPerSession != 0) continue;

                    log.Info("Limit of max messages per session is exceeded!");
                    break;
                }

                #endregion

            }

            var updatedImapFolderUids = new ImapFolderUids(imapIntervals.ToIndexes(), beginDateUid);

            if (!Account.ImapIntervals.Keys.Contains(mb.Name))
            {
                Account.ImapFolderChanged = true;
                Account.ImapIntervals.Add(mb.Name, updatedImapFolderUids);
            }
            else if (Account.ImapIntervals[mb.Name] != updatedImapFolderUids)
            {
                Account.ImapFolderChanged = true;
                Account.ImapIntervals[mb.Name] = updatedImapFolderUids;
            }

            return maxMessagesPerSession;
        }