/// <summary>
        /// Gets the headers to download based on the ones that are allready in the database.
        /// </summary>
        /// <param name="headers">The headers.</param>
        /// <returns>List of headers to download.</returns>
        protected virtual List <ChannelMessageHeader> GetHeadersToDownload(List <ChannelMessageHeader> headers)
        {
            var headersToDownload = new List <ChannelMessageHeader>();

            foreach (var header in headers)
            {
                Message message = null;
                ChannelMessageHeader header1 = header;

                // The sent messages case ensures that we don't retrieve the item that has been sent from Inbox2 but is also
                // in (for example) your GMail sent items. We do this by appending the i2mpMessageid when sending the message.
                if (folder.ToStorageFolder() == Folders.SentItems)
                {
                    if (!String.IsNullOrEmpty(header.Metadata.i2mpMessageId))
                    {
                        message = dataService.SelectBy <Message>(new { MessageKey = header1.Metadata.i2mpMessageId });
                    }
                }

                // Message can still be null (message did not have a match or we are looking at some other folder)
                if (message == null)
                {
                    message = dataService.SelectBy <Message>(
                        String.Format("select * from Messages where (SourceChannelId='{0}' or TargetChannelId='{0}') and MessageNumber='{1}' and Size='{2}'",
                                      config.ChannelId, header1.MessageNumber, header1.Size));
                }

                // Try to find message based on message identifier (not all channels support this)
                if (message == null && !String.IsNullOrEmpty(header1.MessageIdentifier))
                {
                    message = dataService.SelectBy <Message>(
                        String.Format("select * from Messages where (SourceChannelId='{0}' or TargetChannelId='{0}') and MessageIdentifier='{1}' and Size='{2}'",
                                      config.ChannelId, header1.MessageIdentifier, header1.Size));
                }

                if (message == null)
                {
                    headersToDownload.Add(header);
                }
                else
                {
                    if (CheckReadStates(message, header1))
                    {
                        // Check folder of message
                        if (message.MessageFolder != Folders.Archive &&
                            message.MessageFolder != Folders.Trash &&
                            message.MessageFolder != folder.ToStorageFolder())
                        {
                            message.MoveToFolder(folder.ToStorageFolder());
                        }
                    }
                }
            }

            return(headersToDownload);
        }
        protected override void ExecuteChannelCore()
        {
            if (ProgressGroup == null)
            {
                ProgressGroup = new ProgressGroup {
                    SourceChannelId = config.ChannelId
                }
            }
            ;

            ExecuteOnUIThread(() => ProgressManager.Current.Register(ProgressGroup));

            try
            {
                PreProcess();

                channel.SelectFolder(folder);

                SetSelectionRange();

                var headers = channel.GetHeaders().ToList();

                // Channel returned oldest first, turn around and use newest first
                if (Channel is IReversePagableChannel)
                {
                    headers.Reverse();
                }

                var headersToDownload = GetHeadersToDownload(headers);

                if (headersToDownload != null)
                {
                    Logger.Debug("Got {0} headers from {1}", LogSource.Receive, headersToDownload.Count, config.DisplayName);

                    if (headersToDownload.Count > 0)
                    {
                        ProgressGroup.Status = String.Format("Downloading {0}...", LocalizedFolderNames.GetName(folder.ToStorageFolder()));
                        ProgressGroup.SetMaximum(headersToDownload.Count);

                        // Download details for each header
                        headersToDownload.ForEach(DownloadHeader);
                    }
                }

                EventBroker.Publish(AppEvents.ReceiveMessagesFinished);
            }
            finally
            {
                PostProcess();
            }
        }
Example #3
0
        protected override void ExecuteCore()
        {
            try
            {
                Logger.Debug("Retreiving message {0} from {1}", LogSource.Receive, header, config.DisplayName);

                foreach (var channelMessage in channel.GetMessage(header))
                {
                    // Create a duck copy from the mailMessage.
                    var message = new Message
                    {
                        MessageNumber     = header.MessageNumber,
                        MessageIdentifier = channelMessage.MessageIdentifier,
                        From                   = channelMessage.From,
                        ReturnTo               = channelMessage.ReturnTo,
                        To                     = channelMessage.To,
                        CC                     = channelMessage.CC,
                        BCC                    = channelMessage.BCC,
                        InReplyTo              = channelMessage.InReplyTo,
                        Size                   = header.Size,
                        Context                = channelMessage.Context.ToClearSubject(),
                        OriginalContext        = channelMessage.Context,
                        ConversationIdentifier = channelMessage.ConversationId,
                        SourceFolder           = channelMessage.SourceFolder,
                        SourceChannelId        = channelMessage.SourceChannelId,
                        TargetChannelId        = channelMessage.TargetChannelId,
                        Metadata               = channelMessage.Metadata,
                        IsRead                 = channelMessage.IsRead,
                        IsStarred              = channelMessage.IsStarred,
                        DateReceived           = channelMessage.DateReceived,
                        DateSent               = channelMessage.DateSent
                    };

                    message.Context = message.Context != null?message.Context.Trim() : String.Empty;

                    string bodyText = channelMessage.BodyText.ReadString();
                    string bodyHtml = channelMessage.BodyHtml.ReadString();

                    var access = new ClientMessageAccess(message, bodyText, bodyHtml);

                    if (folder.ToStorageFolder() == Folders.SentItems)
                    {
                        // For sent items we sent the TargetChannelId
                        message.TargetChannelId = config.ChannelId;
                    }
                    else
                    {
                        // For all other items we sent the SourceChannelId
                        message.SourceChannelId = config.ChannelId;
                    }

                    // Create BodyPreview field from reader
                    message.BodyPreview        = access.GetBodyPreview();
                    message.BodyHtmlStreamName = access.WriteBodyHtml();
                    message.BodyTextStreamName = access.WriteBodyText();
                    message.MessageFolder      = folder.ToStorageFolder();
                    message.Metadata           = header.Metadata;

                    // Fix for messages which have a timestamp in the futre
                    if (message.DateReceived > DateTime.Now)
                    {
                        message.DateReceived = DateTime.Now;
                    }

                    // Set IsNew state for message
                    if (!message.IsRead)
                    {
                        message.IsNew = true;
                    }

                    // Save message
                    ClientState.Current.DataService.Save(message);


                    // Message received, process attachments
                    foreach (var attachment in channelMessage.Attachments)
                    {
                        var document = new Document
                        {
                            Filename        = attachment.Filename,
                            SourceChannelId = attachment.SourceChannelId,
                            TargetChannelId = attachment.TargetChannelId,
                            DocumentFolder  = folder.ToStorageFolder(),
                            ContentType     = attachment.ContentType,
                            ContentId       = attachment.ContentId,
                            ContentStream   = attachment.ContentStream
                        };

                        document.SourceChannelId = config.ChannelId;
                        document.DateReceived    = message.DateReceived;
                        document.DateSent        = message.DateSent;
                        document.Message         = message;

                        DocumentsHandler.DocumentReceived(document);

                        if (attachment.ContentStream != null)
                        {
                            attachment.ContentStream.Dispose();
                            attachment.ContentStream = null;
                        }
                    }

                    if (channelMessage.BodyText != null)
                    {
                        channelMessage.BodyText.Dispose();
                    }

                    if (channelMessage.BodyHtml != null)
                    {
                        channelMessage.BodyHtml.Dispose();
                    }

                    // Match thread
                    MessageMatcher.Match(message);

                    // Add to search index
                    ClientState.Current.Search.Store(message);

                    new ProfileMatcher(message).Execute();
                }
            }
            catch (Exception ex)
            {
                Logger.Error("An error occured when trying to download header {0}. Exception = {1}", LogSource.BackgroundTask, header, ex);

                throw;
            }
        }