예제 #1
0
        public static List <string> GetEmbeddedAttachmentLinks(this MailComposeBase draft)
        {
            var links = new List <string>();

            var fckStorage = StorageManager.GetDataStoreForCkImages(draft.Mailbox.TenantId);
            //todo: replace selector
            var currentMailFckeditorUrl        = fckStorage.GetUri(StorageManager.CKEDITOR_IMAGES_DOMAIN, "").ToString();
            var currentMailAttachmentFolderUrl = MailStoragePathCombiner.GetMessageDirectory(draft.Mailbox.UserId,
                                                                                             draft.StreamId);
            var currentUserStorageUrl = MailStoragePathCombiner.GetUserMailsDirectory(draft.Mailbox.UserId);
            var xpathQuery            = StorageManager.GetXpathQueryForAttachmentsToResaving(currentMailFckeditorUrl,
                                                                                             currentMailAttachmentFolderUrl,
                                                                                             currentUserStorageUrl);

            var doc = new HtmlDocument();

            doc.LoadHtml(draft.HtmlBody);

            var linkNodes = doc.DocumentNode.SelectNodes(xpathQuery);

            if (linkNodes == null)
            {
                return(links);
            }

            links.AddRange(linkNodes.Select(linkNode => linkNode.Attributes["src"].Value));

            return(links);
        }
예제 #2
0
        public static MailMessageData ToMailMessage(this MailComposeBase draft)
        {
            MailboxAddress fromVerified;

            if (string.IsNullOrEmpty(draft.From))
            {
                throw new DraftException(DraftException.ErrorTypes.EmptyField, "Empty email address in {0} field",
                                         DraftFieldTypes.From);
            }

            if (!MailboxAddress.TryParse(ParserOptions.Default, draft.From, out fromVerified))
            {
                throw new DraftException(DraftException.ErrorTypes.IncorrectField, "Incorrect email address",
                                         DraftFieldTypes.From);
            }

            if (string.IsNullOrEmpty(fromVerified.Name))
            {
                fromVerified.Name = draft.Mailbox.Name;
            }

            if (string.IsNullOrEmpty(draft.MimeMessageId))
            {
                throw new ArgumentException("MimeMessageId");
            }

            var messageItem = new MailMessageData
            {
                From                   = fromVerified.ToString(),
                FromEmail              = fromVerified.Address,
                To                     = string.Join(", ", draft.To.ToArray()),
                Cc                     = draft.Cc != null?string.Join(", ", draft.Cc.ToArray()) : "",
                                   Bcc = draft.Bcc != null?string.Join(", ", draft.Bcc.ToArray()) : "",
                                             Subject          = draft.Subject,
                                             Date             = DateTime.UtcNow,
                                             Important        = draft.Important,
                                             HtmlBody         = draft.HtmlBody,
                                             Introduction     = MailUtil.GetIntroduction(draft.HtmlBody),
                                             StreamId         = draft.StreamId,
                                             TagIds           = draft.Labels != null && draft.Labels.Count != 0 ? new List <int>(draft.Labels) : null,
                                             Size             = draft.HtmlBody.Length,
                                             MimeReplyToId    = draft.MimeReplyToId,
                                             MimeMessageId    = draft.MimeMessageId,
                                             IsNew            = false,
                                             Folder           = draft.Folder,
                                             ChainId          = draft.MimeMessageId,
                                             CalendarUid      = draft.CalendarEventUid,
                                             CalendarEventIcs = draft.CalendarIcs,
                                             MailboxId        = draft.Mailbox.MailBoxId
            };

            if (messageItem.Attachments == null)
            {
                messageItem.Attachments = new List <MailAttachmentData>();
            }

            draft.Attachments.ForEach(attachment =>
            {
                attachment.tenant = draft.Mailbox.TenantId;
                attachment.user   = draft.Mailbox.UserId;
            });

            messageItem.Attachments.AddRange(draft.Attachments);

            messageItem.HasAttachments = messageItem.Attachments.Count > 0;

            return(messageItem);
        }
        public MailMessage Save(MailComposeBase compose)
        {
            var embededAttachmentsForSaving = FixHtmlBodyWithEmbeddedAttachments(compose);

            var message = compose.ToMailMessage();

            var engine = new EngineFactory(compose.Mailbox.TenantId, compose.Mailbox.UserId);

            var addIndex = compose.Id == 0;

            var attachmentsToRestore = message.Attachments.Where(att => att.streamId != message.StreamId || att.isTemp).ToList();

            var needRestoreAttachments = attachmentsToRestore.Any();

            if (needRestoreAttachments)
            {
                message.Attachments.ForEach(
                    attachment =>
                    engine.AttachmentEngine.StoreAttachmentCopy(compose.Mailbox.TenantId, compose.Mailbox.UserId,
                                                                attachment, compose.StreamId));
            }

            MessageEngine.StoreMailBody(compose.Mailbox, message, Log);

            long usedQuota;

            using (var daoFactory = new DaoFactory())
            {
                var db = daoFactory.DbManager;

                using (var tx = db.BeginTransaction(IsolationLevel.ReadUncommitted))
                {
                    compose.Id = engine.MessageEngine.MailSave(daoFactory, compose.Mailbox, message, compose.Id, message.Folder, message.Folder, null,
                                                               string.Empty, string.Empty, false, out usedQuota);

                    message.Id = compose.Id;

                    if (compose.AccountChanged)
                    {
                        engine.ChainEngine.UpdateChain(daoFactory, message.ChainId, message.Folder, null, compose.PreviousMailboxId,
                                                       compose.Mailbox.TenantId, compose.Mailbox.UserId);
                    }

                    var daoMailInfo = daoFactory.CreateMailInfoDao(compose.Mailbox.TenantId, compose.Mailbox.UserId);

                    if (compose.Id > 0 && needRestoreAttachments)
                    {
                        var daoAttachment       = daoFactory.CreateAttachmentDao(compose.Mailbox.TenantId, compose.Mailbox.UserId);
                        var existingAttachments = daoAttachment.GetAttachments(
                            new ConcreteMessageAttachmentsExp(compose.Id, compose.Mailbox.TenantId, compose.Mailbox.UserId));

                        foreach (var attachment in message.Attachments)
                        {
                            if (existingAttachments.Any(x => x.Id == attachment.fileId))
                            {
                                continue;
                            }

                            var attach = attachment.ToAttachmnet(compose.Id);
                            attach.Id = 0;

                            var newId = daoAttachment.SaveAttachment(attach);
                            attachment.fileId = newId;
                        }

                        if (message.Attachments.Any())
                        {
                            var count = daoAttachment.GetAttachmentsCount(
                                new ConcreteMessageAttachmentsExp(compose.Id, compose.Mailbox.TenantId, compose.Mailbox.UserId));

                            daoMailInfo.SetFieldValue(
                                SimpleMessagesExp.CreateBuilder(compose.Mailbox.TenantId, compose.Mailbox.UserId)
                                .SetMessageId(compose.Id)
                                .Build(),
                                MailTable.Columns.AttachCount,
                                count);
                        }
                    }

                    if (compose.Id > 0 && embededAttachmentsForSaving.Any())
                    {
                        var daoAttachment = daoFactory.CreateAttachmentDao(compose.Mailbox.TenantId, compose.Mailbox.UserId);

                        foreach (var attachment in embededAttachmentsForSaving)
                        {
                            var newId = daoAttachment.SaveAttachment(attachment.ToAttachmnet(compose.Id));
                            attachment.fileId = newId;
                        }

                        if (message.Attachments.Any())
                        {
                            var count = daoAttachment.GetAttachmentsCount(
                                new ConcreteMessageAttachmentsExp(compose.Id, compose.Mailbox.TenantId, compose.Mailbox.UserId));

                            daoMailInfo.SetFieldValue(
                                SimpleMessagesExp.CreateBuilder(compose.Mailbox.TenantId, compose.Mailbox.UserId)
                                .SetMessageId(compose.Id)
                                .Build(),
                                MailTable.Columns.AttachCount,
                                count);
                        }
                    }

                    engine.ChainEngine.UpdateChain(daoFactory, message.ChainId, message.Folder, null, compose.Mailbox.MailBoxId, compose.Mailbox.TenantId,
                                                   compose.Mailbox.UserId);

                    if (compose.AccountChanged)
                    {
                        var daoCrmLink = daoFactory.CreateCrmLinkDao(compose.Mailbox.TenantId, compose.Mailbox.UserId);

                        daoCrmLink.UpdateCrmLinkedMailboxId(message.ChainId, compose.PreviousMailboxId,
                                                            compose.Mailbox.MailBoxId);
                    }

                    tx.Commit();
                }
            }

            if (usedQuota > 0)
            {
                engine.QuotaEngine.QuotaUsedDelete(usedQuota);
            }

            if (addIndex)
            {
                engine.IndexEngine.Add(message.ToMailWrapper(compose.Mailbox.TenantId, new Guid(compose.Mailbox.UserId)));
            }
            else
            {
                engine.IndexEngine.Update(new List <MailWrapper>
                {
                    message.ToMailWrapper(compose.Mailbox.TenantId,
                                          new Guid(compose.Mailbox.UserId))
                });
            }

            try
            {
                var tempStorage = MailDataStore.GetDataStore(compose.Mailbox.TenantId);

                tempStorage.DeleteDirectory("attachments_temp", compose.Mailbox.UserId + "/" + compose.StreamId + "/");
            }
            catch (Exception ex)
            {
                Log.ErrorFormat("Clearing temp storage failed with exception: {0}", ex.ToString());
            }

            return(message);
        }
        private List <MailAttachmentData> FixHtmlBodyWithEmbeddedAttachments(MailComposeBase compose)
        {
            var embededAttachmentsForSaving = new List <MailAttachmentData>();

            var embeddedLinks = compose.GetEmbeddedAttachmentLinks();

            if (!embeddedLinks.Any())
            {
                return(embededAttachmentsForSaving);
            }

            var fckStorage              = StorageManager.GetDataStoreForCkImages(compose.Mailbox.TenantId);
            var attachmentStorage       = StorageManager.GetDataStoreForAttachments(compose.Mailbox.TenantId);
            var currentMailFckeditorUrl = fckStorage.GetUri(StorageManager.CKEDITOR_IMAGES_DOMAIN, "").ToString();
            var currentUserStorageUrl   = MailStoragePathCombiner.GetUserMailsDirectory(compose.Mailbox.UserId);

            var engine = new EngineFactory(compose.Mailbox.TenantId, compose.Mailbox.UserId);

            StorageManager storage = null;

            foreach (var embeddedLink in embeddedLinks)
            {
                try
                {
                    var isFckImage   = embeddedLink.StartsWith(currentMailFckeditorUrl);
                    var prefixLength = isFckImage
                        ? currentMailFckeditorUrl.Length
                        : embeddedLink.IndexOf(currentUserStorageUrl, StringComparison.Ordinal) +
                                       currentUserStorageUrl.Length + 1;
                    var fileLink = HttpUtility.UrlDecode(embeddedLink.Substring(prefixLength));
                    var fileName = Path.GetFileName(fileLink);
                    var attach   = new MailAttachmentData
                    {
                        fileName      = fileName,
                        storedName    = fileName,
                        contentId     = embeddedLink.GetMd5(),
                        storedFileUrl = fileLink,
                        streamId      = compose.StreamId,
                        user          = compose.Mailbox.UserId,
                        tenant        = compose.Mailbox.TenantId,
                        mailboxId     = compose.Mailbox.MailBoxId
                    };

                    var savedAttachment =
                        engine.AttachmentEngine.GetAttachment(
                            new ConcreteContentAttachmentExp(compose.Id, attach.contentId));

                    var savedAttachmentId = savedAttachment == null ? 0 : savedAttachment.fileId;

                    var attachmentWasSaved = savedAttachmentId != 0;
                    var currentImgStorage  = isFckImage ? fckStorage : attachmentStorage;
                    var domain             = isFckImage ? StorageManager.CKEDITOR_IMAGES_DOMAIN : compose.Mailbox.UserId;

                    if (compose.Id == 0 || !attachmentWasSaved)
                    {
                        attach.data = StorageManager.LoadDataStoreItemData(domain, fileLink, currentImgStorage);

                        if (storage == null)
                        {
                            storage = new StorageManager(compose.Mailbox.TenantId, compose.Mailbox.UserId);
                        }

                        storage.StoreAttachmentWithoutQuota(attach);

                        embededAttachmentsForSaving.Add(attach);
                    }

                    if (attachmentWasSaved)
                    {
                        attach = engine.AttachmentEngine.GetAttachment(
                            new ConcreteUserAttachmentExp(savedAttachmentId, compose.Mailbox.TenantId, compose.Mailbox.UserId));

                        var path = MailStoragePathCombiner.GerStoredFilePath(attach);
                        currentImgStorage    = attachmentStorage;
                        attach.storedFileUrl =
                            MailStoragePathCombiner.GetStoredUrl(currentImgStorage.GetUri(path));
                    }

                    compose.HtmlBody = compose.HtmlBody.Replace(embeddedLink, attach.storedFileUrl);
                }
                catch (Exception ex)
                {
                    Log.ErrorFormat("ChangeEmbededAttachmentLinksForStoring() failed with exception: {0}", ex.ToString());
                }
            }

            return(embededAttachmentsForSaving);
        }
예제 #5
0
        public MailMessage Save(MailComposeBase draft)
        {
            var embededAttachmentsForSaving = FixHtmlBodyWithEmbeddedAttachments(draft);

            var message = draft.ToMailMessage();

            var engine = new EngineFactory(draft.Mailbox.TenantId, draft.Mailbox.UserId);

            var addIndex = draft.Id == 0;

            var needRestoreAttachments = draft.Id == 0 && message.Attachments.Any();

            if (needRestoreAttachments)
            {
                message.Attachments.ForEach(
                    attachment =>
                    engine.AttachmentEngine.StoreAttachmentCopy(draft.Mailbox.TenantId, draft.Mailbox.UserId,
                                                                attachment, draft.StreamId));
            }

            MessageEngine.StoreMailBody(draft.Mailbox, message, Log);

            long usedQuota;

            using (var daoFactory = new DaoFactory())
            {
                var db = daoFactory.DbManager;

                using (var tx = db.BeginTransaction(IsolationLevel.ReadUncommitted))
                {
                    draft.Id = engine.MessageEngine.MailSave(daoFactory, draft.Mailbox, message, draft.Id, message.Folder, message.Folder, null,
                                                             string.Empty, string.Empty, false, out usedQuota);

                    message.Id = draft.Id;

                    if (draft.AccountChanged)
                    {
                        engine.ChainEngine.UpdateChain(daoFactory, message.ChainId, message.Folder, null, draft.PreviousMailboxId,
                                                       draft.Mailbox.TenantId, draft.Mailbox.UserId);
                    }

                    var daoMailInfo = daoFactory.CreateMailInfoDao(draft.Mailbox.TenantId, draft.Mailbox.UserId);

                    if (draft.Id > 0 && needRestoreAttachments)
                    {
                        var daoAttachment = daoFactory.CreateAttachmentDao(draft.Mailbox.TenantId, draft.Mailbox.UserId);

                        foreach (var attachment in message.Attachments)
                        {
                            var attach = attachment.ToAttachmnet(draft.Id);
                            attach.Id = 0;

                            var newId = daoAttachment.SaveAttachment(attach);
                            attachment.fileId = newId;
                        }

                        if (message.Attachments.Any())
                        {
                            var count = daoAttachment.GetAttachmentsCount(
                                new ConcreteMessageAttachmentsExp(draft.Id, draft.Mailbox.TenantId, draft.Mailbox.UserId));

                            daoMailInfo.SetFieldValue(
                                SimpleMessagesExp.CreateBuilder(draft.Mailbox.TenantId, draft.Mailbox.UserId)
                                .SetMessageId(draft.Id)
                                .Build(),
                                MailTable.Columns.AttachCount,
                                count);
                        }
                    }

                    if (draft.Id > 0 && embededAttachmentsForSaving.Any())
                    {
                        var daoAttachment = daoFactory.CreateAttachmentDao(draft.Mailbox.TenantId, draft.Mailbox.UserId);

                        foreach (var attachment in embededAttachmentsForSaving)
                        {
                            var newId = daoAttachment.SaveAttachment(attachment.ToAttachmnet(draft.Id));
                            attachment.fileId = newId;
                        }

                        if (message.Attachments.Any())
                        {
                            var count = daoAttachment.GetAttachmentsCount(
                                new ConcreteMessageAttachmentsExp(draft.Id, draft.Mailbox.TenantId, draft.Mailbox.UserId));

                            daoMailInfo.SetFieldValue(
                                SimpleMessagesExp.CreateBuilder(draft.Mailbox.TenantId, draft.Mailbox.UserId)
                                .SetMessageId(draft.Id)
                                .Build(),
                                MailTable.Columns.AttachCount,
                                count);
                        }
                    }

                    engine.ChainEngine.UpdateChain(daoFactory, message.ChainId, message.Folder, null, draft.Mailbox.MailBoxId, draft.Mailbox.TenantId,
                                                   draft.Mailbox.UserId);

                    if (draft.AccountChanged)
                    {
                        var daoCrmLink = daoFactory.CreateCrmLinkDao(draft.Mailbox.TenantId, draft.Mailbox.UserId);

                        daoCrmLink.UpdateCrmLinkedMailboxId(message.ChainId, draft.PreviousMailboxId,
                                                            draft.Mailbox.MailBoxId);
                    }

                    tx.Commit();
                }
            }

            if (usedQuota > 0)
            {
                engine.QuotaEngine.QuotaUsedDelete(usedQuota);
            }

            if (addIndex)
            {
                engine.IndexEngine.Add(message.ToMailWrapper(draft.Mailbox.TenantId, new Guid(draft.Mailbox.UserId)));
            }
            else
            {
                engine.IndexEngine.Update(new List <MailWrapper>
                {
                    message.ToMailWrapper(draft.Mailbox.TenantId,
                                          new Guid(draft.Mailbox.UserId))
                });
            }

            return(message);
        }