コード例 #1
0
 public void CreateIntervalsFromZeroItemsList()
 {
     var imapIntervals = new ImapIntervals(new List<int> {1, int.MaxValue});
     var uidIntervals = imapIntervals.GetUnhandledIntervalsCopy();
     Assert.IsTrue(uidIntervals.Contains(new UidInterval(1, int.MaxValue)));
     Assert.IsTrue(uidIntervals.Count == 1);
 }
コード例 #2
0
 public void CreateIntervalsFromEvenList1()
 {
     var imapIntervals = new ImapIntervals(new List<int> { 1, 10, 20, int.MaxValue });
     var uidIntervals = imapIntervals.GetUnhandledIntervalsCopy();
     Assert.IsTrue(uidIntervals.Contains(new UidInterval(1, 10)));
     Assert.IsTrue(uidIntervals.Contains(new UidInterval(20, int.MaxValue)));
 }
コード例 #3
0
        public bool SaveMailBox(MailBox mailbox)
        {
            if (mailbox == null) throw new ArgumentNullException("mailbox");

            var idMailbox = MailBoxExists(GetAddress(mailbox.EMail), mailbox.UserId, mailbox.TenantId);

            using (var db = GetDb())
            {
                int result;

                var loginDelayTime = GetLoginDelayTime(mailbox);

                if (idMailbox == 0)
                {
                    var utcNow = DateTime.UtcNow;
                    
                    result = db.ExecuteScalar<int>(
                        new SqlInsert(MailboxTable.name)
                            .InColumnValue(MailboxTable.Columns.id, 0)
                            .InColumnValue(MailboxTable.Columns.id_tenant, mailbox.TenantId)
                            .InColumnValue(MailboxTable.Columns.id_user, mailbox.UserId)
                            .InColumnValue(MailboxTable.Columns.address, GetAddress(mailbox.EMail))
                            .InColumnValue(MailboxTable.Columns.name, mailbox.Name)
                            .InColumnValue(MailboxTable.Columns.password, EncryptPassword(mailbox.Password))
                            .InColumnValue(MailboxTable.Columns.msg_count_last, mailbox.MessagesCount)
                            .InColumnValue(MailboxTable.Columns.smtp_password,
                                           string.IsNullOrEmpty(mailbox.SmtpPassword)
                                               ? EncryptPassword(mailbox.Password)
                                               : EncryptPassword(mailbox.SmtpPassword))
                            .InColumnValue(MailboxTable.Columns.size_last, mailbox.Size)
                            .InColumnValue(MailboxTable.Columns.login_delay, loginDelayTime)
                            .InColumnValue(MailboxTable.Columns.enabled, true)
                            .InColumnValue(MailboxTable.Columns.imap, mailbox.Imap)
                            .InColumnValue(MailboxTable.Columns.begin_date, mailbox.BeginDate)
                            .InColumnValue(MailboxTable.Columns.service_type, mailbox.ServiceType)
                            .InColumnValue(MailboxTable.Columns.refresh_token, mailbox.RefreshToken)
                            .InColumnValue(MailboxTable.Columns.id_smtp_server, mailbox.SmtpServerId)
                            .InColumnValue(MailboxTable.Columns.id_in_server, mailbox.InServerId)
                            .InColumnValue(MailboxTable.Columns.date_created, utcNow)
                            .Identity(0, 0, true));

                    mailbox.MailBoxId = result;
                    mailbox.Enabled = true;
                }
                else
                {
                    mailbox.MailBoxId = idMailbox;

                    var queryUpdate = new SqlUpdate(MailboxTable.name)
                        .Where(MailboxTable.Columns.id, idMailbox)
                        .Set(MailboxTable.Columns.id_tenant, mailbox.TenantId)
                        .Set(MailboxTable.Columns.id_user, mailbox.UserId)
                        .Set(MailboxTable.Columns.address, GetAddress(mailbox.EMail))
                        .Set(MailboxTable.Columns.name, mailbox.Name)
                        .Set(MailboxTable.Columns.password, EncryptPassword(mailbox.Password))
                        .Set(MailboxTable.Columns.msg_count_last, mailbox.MessagesCount)
                        .Set(MailboxTable.Columns.smtp_password,
                             string.IsNullOrEmpty(mailbox.SmtpPassword)
                                 ? EncryptPassword(mailbox.Password)
                                 : EncryptPassword(mailbox.SmtpPassword))
                        .Set(MailboxTable.Columns.size_last, mailbox.Size)
                        .Set(MailboxTable.Columns.login_delay, loginDelayTime)
                        .Set(MailboxTable.Columns.is_removed, false)
                        .Set(MailboxTable.Columns.imap, mailbox.Imap)
                        .Set(MailboxTable.Columns.begin_date, mailbox.BeginDate)
                        .Set(MailboxTable.Columns.service_type, mailbox.ServiceType)
                        .Set(MailboxTable.Columns.refresh_token, mailbox.RefreshToken)
                        .Set(MailboxTable.Columns.id_smtp_server, mailbox.SmtpServerId)
                        .Set(MailboxTable.Columns.id_in_server, mailbox.InServerId);

                    if (mailbox.BeginDate == MinBeginDate)
                    {
                        var currentMailbox = GetMailBox(idMailbox);

                        if (currentMailbox == null)
                            throw new ItemNotFoundException("Mailbox was removed");

                        if (mailbox.BeginDate != currentMailbox.BeginDate)
                        {
                            foreach (var folderName in currentMailbox.ImapIntervals.Keys)
                            {
                                var imapIntervals =
                                    new ImapIntervals(currentMailbox.ImapIntervals[folderName].UnhandledUidIntervals);

                                if (currentMailbox.ImapIntervals[folderName].BeginDateUid != 1)
                                    imapIntervals.AddUnhandledInterval(new UidInterval(1,
                                                                                       currentMailbox.ImapIntervals[
                                                                                           folderName].BeginDateUid));
                                
                                currentMailbox.ImapIntervals[folderName].UnhandledUidIntervals =
                                    new List<int>(imapIntervals.ToIndexes());

                                currentMailbox.ImapIntervals[folderName].BeginDateUid = 1;
                            }

                            queryUpdate.Set(MailboxTable.Columns.imap_intervals, currentMailbox.ImapIntervalsJson);
                        }

                    }

                    result = db.ExecuteNonQuery(queryUpdate);
                }

                return result > 0;
            }
        }
コード例 #4
0
ファイル: Imap4Worker.cs プロジェクト: vipwan/CommunityServer
        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;
        }
コード例 #5
0
 public void ToIndexesWithoutModificationTestBase(int[] indexesArr)
 {
     var indexesList = new List<int>(indexesArr);
     var imapIntervals = new ImapIntervals(indexesList);
     Assert.IsTrue(indexesList.SequenceEqual(imapIntervals.ToIndexes()));
 }
コード例 #6
0
 public void CreateIntervalsFromUnevenList()
 {
     var intervals = new ImapIntervals(new List<int> { 10, 20, 30 });
     Assert.IsNotNull(intervals);
 }
コード例 #7
0
 public void CreateIntervalsFromSingleItemList()
 {
     var intervals = new ImapIntervals(new List<int> { 1 });
     Assert.IsNotNull(intervals);
 }
コード例 #8
0
 public void CreateIntervalsFromEmptyIndexesList()
 {
     var intervals = new ImapIntervals(new List<int>());
     Assert.IsNotNull(intervals);
 }
コード例 #9
0
        public void AddUnhandledIntervalBaseTest(int[] indexes, UidInterval newInterval, int[] indexesMody, UidInterval[] intervals)
        {
            var imapIntervals = new ImapIntervals(new List<int>(indexes));
            imapIntervals.AddUnhandledInterval(newInterval);
            var uidIntervals = imapIntervals.GetUnhandledIntervalsCopy();
            Assert.IsTrue(uidIntervals.Count == intervals.Count());
            foreach (var interval in intervals)
            {
                Assert.IsTrue(uidIntervals.Contains(interval));
            }

            var indexesListMody = new List<int>(indexesMody);
            Assert.IsTrue(indexesListMody.SequenceEqual(imapIntervals.ToIndexes()));
        }
コード例 #10
0
        public void SetBeginIndexForSeveralIntervalsBase(int[] indexes, int beginIndex, int[] indexesMody, UidInterval[] intervals)
        {
            var imapIntervals = new ImapIntervals(new List<int>(indexes));
            imapIntervals.SetBeginIndex(beginIndex);
            var uidIntervals = imapIntervals.GetUnhandledIntervalsCopy();
            foreach (var interval in intervals)
            {
                Assert.IsTrue(uidIntervals.Contains(interval));
            }

            var indexesListMody = new List<int>(indexesMody);
            Assert.IsTrue(indexesListMody.SequenceEqual(imapIntervals.ToIndexes()));
        }