예제 #1
0
        /// <summary>
        /// Saves the mailbox entry.
        /// </summary>
        /// <param name="entry">The entry.</param>
        void SaveMailboxEntry(MailboxEntry entry)
        {
            try
            {
                //load template
                var body = string.Format("<div >Sent by:{1} on: {2}<br/>{0}</div>", entry.Content.Trim(), entry.From, entry.Date);

                if (Config.BodyTemplate.Trim().Length > 0)
                {
                    var data = new Dictionary <string, object> {
                        { "MailboxEntry", entry }
                    };
                    body = NotificationManager.GenerateNotificationContent(Config.BodyTemplate, data);
                }

                var projectId = entry.ProjectMailbox.ProjectId;

                var mailIssue = IssueManager.GetDefaultIssueByProjectId(
                    projectId,
                    entry.Title.Trim(),
                    body.Trim(),
                    entry.ProjectMailbox.AssignToUserName,
                    Config.ReportingUserName);

                if (!IssueManager.SaveOrUpdate(mailIssue))
                {
                    return;
                }

                entry.IssueId      = mailIssue.Id;
                entry.WasProcessed = true;

                var project = ProjectManager.GetById(projectId);

                var projectFolderPath = Path.Combine(Config.UploadsFolderPath, project.UploadPath);

                var doc = new HtmlDocument();
                doc.LoadHtml(mailIssue.Description); // load the issue body to we can process it for inline images (if exist)

                //If there is an attached file present then add it to the database
                //and copy it to the directory specified in the web.config file
                foreach (MIME_Entity mimeEntity in entry.MailAttachments)
                {
                    string fileName;
                    var    isInline    = false;
                    var    contentType = mimeEntity.ContentType.Type.ToLower();

                    var attachment = new IssueAttachment
                    {
                        Id                 = 0,
                        Description        = "File attached by mailbox reader",
                        DateCreated        = DateTime.Now,
                        ContentType        = mimeEntity.ContentType.TypeWithSubtype,
                        CreatorDisplayName = Config.ReportingUserName,
                        CreatorUserName    = Config.ReportingUserName,
                        IssueId            = mailIssue.Id,
                        ProjectFolderPath  = projectFolderPath
                    };

                    switch (contentType)
                    {
                    case "application":
                        attachment.Attachment = ((MIME_b_SinglepartBase)mimeEntity.Body).Data;
                        break;

                    case "attachment":
                    case "image":
                    case "video":
                    case "audio":

                        attachment.Attachment = ((MIME_b_SinglepartBase)mimeEntity.Body).Data;
                        break;

                    case "message":

                        // we need to pull the actual email message out of the entity, and strip the "content type" out so that
                        // email programs will read the file properly
                        var messageBody = mimeEntity.ToString().Replace(mimeEntity.Header.ToString(), "");
                        if (messageBody.StartsWith("\r\n"))
                        {
                            messageBody = messageBody.Substring(2);
                        }

                        attachment.Attachment = Encoding.UTF8.GetBytes(messageBody);

                        break;

                    default:
                        LogWarning(string.Format("MailboxReader: Attachment type could not be processed {0}", mimeEntity.ContentType.Type));
                        break;
                    }

                    if (contentType.Equals("attachment")) // this is an attached email
                    {
                        fileName = mimeEntity.ContentDisposition.Param_FileName;
                    }
                    else if (contentType.Equals("message")) // message has no filename so we create one
                    {
                        fileName = string.Format("Attached_Message_{0}.eml", entry.AttachmentsSavedCount);
                    }
                    else
                    {
                        isInline = true;
                        fileName = string.IsNullOrWhiteSpace(mimeEntity.ContentType.Param_Name) ?
                                   string.Format("untitled.{0}", mimeEntity.ContentType.SubType) :
                                   mimeEntity.ContentType.Param_Name;
                    }

                    attachment.FileName = fileName;

                    var saveFile  = IsAllowedFileExtension(fileName);
                    var fileSaved = false;

                    // can we save the file?
                    if (saveFile)
                    {
                        fileSaved = IssueAttachmentManager.SaveOrUpdate(attachment);

                        if (fileSaved)
                        {
                            entry.AttachmentsSavedCount++;
                        }
                        else
                        {
                            LogWarning("MailboxReader: Attachment could not be saved, please see previous logs");
                        }
                    }

                    if (!entry.IsHtml || !isInline)
                    {
                        continue;
                    }

                    if (string.IsNullOrWhiteSpace(mimeEntity.ContentID))
                    {
                        continue;
                    }

                    var contentId = mimeEntity.ContentID.Replace("<", "").Replace(">", "").Replace("[", "").Replace("]", "");

                    // this is pretty greedy but since people might be sending screenshots I doubt they will send in dozens of images
                    // embedded in the email.  one would hope
                    foreach (var node in doc.DocumentNode.SelectNodes(XpathElementCaseInsensitive("img")).ToList())
                    {
                        var attr = node.Attributes.FirstOrDefault(p => p.Name.ToLowerInvariant() == "src");// get the src attribute

                        if (attr == null)
                        {
                            continue;               // image has no src attribute
                        }
                        if (!attr.Value.Contains(contentId))
                        {
                            continue;                                  // is the attribute value the content id?
                        }
                        // swap out the content of the parent node html will our link to the image
                        var anchor = string.Format("<span class='inline-mail-attachment'>Inline Attachment: <a href='DownloadAttachment.axd?id={0}' target='_blank'>{1}</a></span>", attachment.Id, fileName);

                        // for each image in the body if the file was saved swap out the inline link for a link to the saved attachment
                        // otherwise blank out the content link so we don't get a missing image link
                        node.ParentNode.InnerHtml = fileSaved ? anchor : "";
                    }

                    mailIssue.Description        = doc.DocumentNode.InnerHtml;
                    mailIssue.LastUpdateUserName = mailIssue.OwnerUserName;
                    mailIssue.LastUpdate         = DateTime.Now;

                    IssueManager.SaveOrUpdate(mailIssue);
                }
            }
            catch (Exception ex)
            {
                LogException(ex);
                throw;
            }
        }