Esempio n. 1
0
        /// <summary>
        /// Publish requested mail content to the stream.
        /// </summary>
        /// <param name="cancel"></param>
        /// <param name="uid"></param>
        /// <returns></returns>
        private async Task PublishRequestedByUidMailContent(CancellationToken cancel, string uid)
        {
            try
            {
                using (IMailStorage <MailContentEntity> storage = _mailContentStorageFactory())
                {
                    // 1. Check if content already exists in the database.
                    if (storage.Exists(x => x.Uid == uid))
                    {
                        var mailContentEntity = storage.FindOne(x => x.Uid == uid);

                        if (mailContentEntity == null || !mailContentEntity.IsComplete)
                        {
                            // 2. If content is not yet downloaded of any reason, download it and publish afterwards.
                            await RunDownloadContentAsyncLoop(cancel, new List <string>() { uid });
                        }
                        else
                        {
                            _mailContentStream.OnNext(new MailContent(mailContentEntity));
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Logger.Error(e, "PublishRequestedByUidMailContent");
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Download MailContent for given uids.
        /// </summary>
        /// <param name="cancel"></param>
        /// <param name="uids"></param>
        /// <returns></returns>
        private async Task RunDownloadContentAsyncLoop(CancellationToken cancel, List <string> uids)
        {
            if (uids == null || uids.Count == 0)
            {
                return;
            }

            // Create mail client.
            IMailClient client = (new TrivialMailDllFactory()).Build(_serverType);

            try
            {
                await Task.Factory.StartNew(() =>
                {
                    client.Connect(_serverEncryption, _host);
                    client.Login(_user, _password);

                    // If is not connected or encrypted (if req) then will break and try to reconnect.
                    if (client.IsConnected && (_serverEncryption == MailServerEncryption.Unencrypted || client.IsEncrypted))
                    {
                        using (IMailStorage <MailContentEntity> storage = _mailContentStorageFactory())
                        {
                            foreach (var uid in uids)
                            {
                                if (string.IsNullOrWhiteSpace(uid))
                                {
                                    continue;
                                }

                                if (cancel.IsCancellationRequested)
                                {
                                    break;
                                }

                                var downloadRequired = true;
                                MailContentEntity mailContentEntity = null;
                                if (storage.Exists(x => x.Uid == uid))
                                {
                                    mailContentEntity = storage.FindOne(x => x.Uid == uid);

                                    if (mailContentEntity != null && mailContentEntity.IsComplete)
                                    {
                                        downloadRequired = false;
                                    }
                                }

                                if (downloadRequired)
                                {
                                    // 1. Insert empty MailContent with only uid set to prevent other concurrent method to download same content.
                                    mailContentEntity = new MailContentEntity()
                                    {
                                        Uid        = uid,
                                        IsComplete = false
                                    };
                                    storage.Insert(new List <MailContentEntity>()
                                    {
                                        mailContentEntity
                                    });

                                    // 2. Download complete email.
                                    var message = client.GetMessageByUid(uid);

                                    // Note: MailDll documentation states that message can be null.
                                    if (message != null)
                                    {
                                        IMail email = new MailBuilder().CreateFromEml(message);
                                        if (email != null)
                                        {
                                            // 3. Update database with downloaded email content.
                                            mailContentEntity = new MailContentEntity()
                                            {
                                                Uid          = uid,
                                                Date         = email?.Date == null ? DateTime.MinValue : email.Date.Value,
                                                Html         = email.Html,
                                                MessageId    = email.MessageID,
                                                Text         = email.Text,
                                                CustomHeader = email?.Document.Root.Headers["x-spam"],
                                                IsComplete   = true
                                            };

                                            storage.Update(new List <MailContentEntity>()
                                            {
                                                mailContentEntity
                                            });

                                            // Publish MailContent.
                                            _mailContentStream.OnNext(new MailContent(mailContentEntity));
                                        }
                                    }
                                }
                            }
                        }
                    }
                }, cancel, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
            }
            catch (Exception e)
            {
                Logger.Error(e, $"RunDownloadContentAsync");
            }
            finally
            {
                client?.Close();
            }
        }