示例#1
0
 public override void Initialise(List <MailFolder> folderList)
 {
     Status          = MessageProcessorStatus.Initialising;
     _mainFolderList = folderList;
     service         = ExchangeHelper.ExchangeConnect(_hostname, _username, _password);
     //service.TraceEnabled = true;
     //service.TraceFlags = TraceFlags.All;
     folders = new List <ExchangeFolder>();
     ExchangeHelper.GetAllSubFolders(service, new ExchangeFolder {
         Folder = Folder.Bind(service, WellKnownFolderName.MsgFolderRoot)
     }, folders, false);
     if (_createAllFolders)
     {
         // we need to create all folders which don't exist
         foreach (var mailFolder in _mainFolderList)
         {
             GetCreateFolder(mailFolder.DestinationFolder);
         }
     }
     _lastState = new ImportState();
     _queue     = new PCQueue <RawMessageDescriptor, ImportState>(Name + "-exchangeTarget")
     {
         ProduceMethod      = ProcessMessage,
         InitialiseProducer = () => _lastState,
         ShutdownProducer   = ShutdownQueue
     };
     _queue.Start();
     Status = MessageProcessorStatus.Initialised;
 }
示例#2
0
        public override void Initialise(List <MailFolder> folderList)
        {
            Status  = MessageProcessorStatus.Initialising;
            service = ExchangeHelper.ExchangeConnect(_hostname, _username, _password);
            folders = new List <ExchangeFolder>();
            // Use Exchange Helper to get all the folders for this account
            ExchangeHelper.GetAllSubFolders(service,
                                            new ExchangeFolder()
            {
                Folder = Folder.Bind(service, WellKnownFolderName.MsgFolderRoot)
            }, folders,
                                            false);
            if (IncludePublicFolders)
            {
                Logger.Debug("Including Public Folders");
                ExchangeHelper.GetAllSubFolders(service,
                                                new ExchangeFolder()
                {
                    Folder = Folder.Bind(service, WellKnownFolderName.PublicFoldersRoot), IsPublicFolder = true
                }, folders,
                                                false);
            }

            // Are we limited folders to a specific list?
            if (_limitFolderList != null)
            {
                var newFolders = new List <ExchangeFolder>();
                foreach (var mailbox in _limitFolderList)
                {
                    var mailboxMatch = mailbox.ToLower().Replace('/', '\\');;
                    newFolders.AddRange(folders.Where(folder => folder.FolderPath.ToLower().Equals(mailboxMatch)));
                }
                folders = newFolders;
            }

            // Scan the folders to get message counts
            ExchangeHelper.GetFolderSummary(service, folders, _startDate, _endDate);
            folders.ForEach(folder => TotalMessages += !TestOnly ? folder.MessageCount : (folder.MessageCount > 20 ? 20 : folder.MessageCount));
            Logger.Debug("Found " + folders.Count + " folders and " + TotalMessages + " messages.");

            // Now build the folder list that we pass on to the next folders.
            foreach (var exchangeFolder in folders)
            {
                var folder = new MailFolder()
                {
                    SourceFolder      = exchangeFolder.FolderPath,
                    DestinationFolder = exchangeFolder.MappedDestination,
                    MessageCount      = exchangeFolder.MessageCount,
                };
                _mainFolderList.Add(folder);
            }
            // Now initialise the next read, I am not going to start reading unless I know the pipeline is groovy
            NextReader.Initialise(_mainFolderList);
            Status = MessageProcessorStatus.Initialised;
            Logger.Info("ExchangeExporter Initialised");
        }
示例#3
0
 private void Run()
 {
     try
     {
         Status = MessageProcessorStatus.Started;
         var fullPropertySet = new PropertySet(PropertySet.FirstClassProperties)
         {
             EmailMessageSchema.IsRead,
             EmailMessageSchema.IsReadReceiptRequested,
             EmailMessageSchema.IsDeliveryReceiptRequested,
             ItemSchema.DateTimeSent,
             ItemSchema.DateTimeReceived,
             ItemSchema.DateTimeCreated,
             ItemSchema.ItemClass,
             ItemSchema.MimeContent,
             ItemSchema.Categories,
             ItemSchema.Importance,
             ItemSchema.InReplyTo,
             ItemSchema.IsFromMe,
             ItemSchema.IsReminderSet,
             ItemSchema.IsResend,
             ItemSchema.IsDraft,
             ItemSchema.ReminderDueBy,
             ItemSchema.Sensitivity,
             ItemSchema.Subject,
             ItemSchema.Id,
             ExchangeHelper.MsgPropertyContentType,
             ExchangeHelper.PidTagFollowupIcon,
         };
         if (service.RequestedServerVersion != ExchangeVersion.Exchange2007_SP1)
         {
             fullPropertySet.Add(ItemSchema.ConversationId);
             fullPropertySet.Add(ItemSchema.IsAssociated);
         }
         if (service.RequestedServerVersion == ExchangeVersion.Exchange2013)
         {
             fullPropertySet.Add(ItemSchema.ArchiveTag);
             fullPropertySet.Add(ItemSchema.Flag);
             fullPropertySet.Add(ItemSchema.IconIndex);
         }
         SearchFilter.SearchFilterCollection filter = new SearchFilter.SearchFilterCollection();
         filter.LogicalOperator = LogicalOperator.And;
         if (_startDate != null)
         {
             Logger.Debug("Getting mails from " + _startDate);
             filter.Add(new SearchFilter.IsGreaterThanOrEqualTo(ItemSchema.DateTimeReceived, _startDate));
         }
         if (_endDate != null)
         {
             Logger.Debug("Getting mails up until " + _endDate);
             filter.Add(new SearchFilter.IsLessThanOrEqualTo(ItemSchema.DateTimeReceived, _endDate));
         }
         foreach (var exchangeFolder in folders)
         {
             ItemView view = new ItemView(_pageSize, 0, OffsetBasePoint.Beginning);
             view.PropertySet = PropertySet.IdOnly;
             List <EmailMessage> emails = new List <EmailMessage>();
             Boolean             more   = true;
             while (more)
             {
                 try
                 {
                     more = FindExchangeMessages(exchangeFolder, filter, view, emails, fullPropertySet);
                     if (emails.Count > 0)
                     {
                         try
                         {
                             foreach (var emailMessage in emails)
                             {
                                 try
                                 {
                                     String subject;
                                     if (!emailMessage.TryGetProperty(ItemSchema.Subject, out subject) ||
                                         subject == null)
                                     {
                                         Logger.Warn("Item " + emailMessage.Id.UniqueId + " has no subject assigned, unable to determine subject.");
                                     }
                                     Logger.Debug("Exporting " + emailMessage.Id.UniqueId + " from " + exchangeFolder.FolderPath + " : " + subject);
                                     var     flags = new Collection <MessageFlags>();
                                     Boolean flag;
                                     if (emailMessage.TryGetProperty(EmailMessageSchema.IsRead, out flag) &&
                                         !flag)
                                     {
                                         flags.Add(MessageFlags.Unread);
                                     }
                                     if (emailMessage.TryGetProperty(ItemSchema.IsDraft, out flag) && flag)
                                     {
                                         flags.Add(MessageFlags.Draft);
                                     }
                                     if (
                                         emailMessage.TryGetProperty(EmailMessageSchema.IsReadReceiptRequested,
                                                                     out flag) && flag)
                                     {
                                         flags.Add(MessageFlags.ReadReceiptRequested);
                                     }
                                     if (
                                         emailMessage.TryGetProperty(
                                             EmailMessageSchema.IsDeliveryReceiptRequested, out flag) && flag)
                                     {
                                         flags.Add(MessageFlags.DeliveryReceiptRequested);
                                     }
                                     if (emailMessage.TryGetProperty(ItemSchema.IsReminderSet, out flag) && flag)
                                     {
                                         flags.Add(MessageFlags.ReminderSet);
                                     }
                                     if (emailMessage.TryGetProperty(ItemSchema.IsAssociated, out flag) && flag)
                                     {
                                         flags.Add(MessageFlags.Associated);
                                     }
                                     if (emailMessage.TryGetProperty(ItemSchema.IsFromMe, out flag) && flag)
                                     {
                                         flags.Add(MessageFlags.FromMe);
                                     }
                                     if (emailMessage.TryGetProperty(ItemSchema.IsResend, out flag) && flag)
                                     {
                                         flags.Add(MessageFlags.Resend);
                                     }
                                     var message = new RawMessageDescriptor
                                     {
                                         SourceId          = emailMessage.Id.UniqueId,
                                         Subject           = subject,
                                         Flags             = flags,
                                         RawMessage        = "",
                                         SourceFolder      = exchangeFolder.FolderPath,
                                         DestinationFolder = exchangeFolder.MappedDestination,
                                         IsPublicFolder    = exchangeFolder.IsPublicFolder,
                                     };
                                     Object result;
                                     if (emailMessage.TryGetProperty(ItemSchema.MimeContent, out result) &&
                                         result != null)
                                     {
                                         message.RawMessage = Encoding.UTF8.GetString(emailMessage.MimeContent.Content);
                                     }
                                     if (emailMessage.TryGetProperty(ItemSchema.ItemClass, out result) &&
                                         result != null)
                                     {
                                         message.ItemClass = emailMessage.ItemClass;
                                     }
                                     if (emailMessage.TryGetProperty(ItemSchema.IconIndex, out result) &&
                                         result != null)
                                     {
                                         message.IconIndex = (int)emailMessage.IconIndex;
                                     }
                                     if (emailMessage.TryGetProperty(ItemSchema.Importance, out result) &&
                                         result != null)
                                     {
                                         message.Importance = (int)emailMessage.Importance;
                                     }
                                     if (emailMessage.TryGetProperty(ItemSchema.Sensitivity, out result) &&
                                         result != null)
                                     {
                                         message.Sensitivity = (int)emailMessage.Sensitivity;
                                     }
                                     if (emailMessage.TryGetProperty(ItemSchema.InReplyTo, out result) &&
                                         result != null)
                                     {
                                         message.InReplyTo = emailMessage.InReplyTo;
                                     }
                                     if (emailMessage.TryGetProperty(ItemSchema.ConversationId, out result) &&
                                         result != null)
                                     {
                                         message.ConversationId = emailMessage.ConversationId.ChangeKey;
                                     }
                                     if (emailMessage.TryGetProperty(ItemSchema.ReminderDueBy, out result) &&
                                         result != null)
                                     {
                                         message.ReminderDueBy = emailMessage.ReminderDueBy;
                                     }
                                     if (
                                         emailMessage.TryGetProperty(ExchangeHelper.PidTagFollowupIcon,
                                                                     out result) && result != null)
                                     {
                                         message.FlagIcon = ExchangeHelper.ConvertFlagIcon((int)result);
                                     }
                                     if (emailMessage.TryGetProperty(ItemSchema.DateTimeReceived, out result) &&
                                         result != null)
                                     {
                                         message.ReceivedDateTime = emailMessage.DateTimeReceived;
                                     }
                                     if (emailMessage.TryGetProperty(ItemSchema.DateTimeSent, out result) &&
                                         result != null)
                                     {
                                         message.SentDateTime = emailMessage.DateTimeSent;
                                     }
                                     if (emailMessage.TryGetProperty(ItemSchema.Flag, out result) &&
                                         result != null)
                                     {
                                         message.FollowUpFlag = new FollowUpFlag()
                                         {
                                             StartDateTime    = ((Flag)result).StartDate,
                                             DueDateTime      = ((Flag)result).DueDate,
                                             CompleteDateTime = ((Flag)result).CompleteDate,
                                             Status           =
                                                 ExchangeHelper.ConvertFlagStatus(((Flag)result).FlagStatus),
                                         }
                                     }
                                     ;
                                     if (emailMessage.TryGetProperty(ItemSchema.Categories, out result) &&
                                         result != null && emailMessage.Categories.Count > 0)
                                     {
                                         foreach (var category in emailMessage.Categories)
                                         {
                                             message.Categories.Add(category);
                                         }
                                     }
                                     if (emailMessage.ExtendedProperties != null)
                                     {
                                         foreach (var extendedProperty in emailMessage.ExtendedProperties)
                                         {
                                             if (
                                                 extendedProperty.PropertyDefinition.Equals(
                                                     ExchangeHelper.MsgPropertyContentType))
                                             {
                                                 if (extendedProperty.Value.ToString().Contains("signed-data"))
                                                 {
                                                     message.IsEncrypted = true;
                                                 }
                                             }
                                         }
                                     }
                                     NextReader.Process(message);
                                     SucceededMessageCount++;
                                 }
                                 catch (Exception e)
                                 {
                                     Logger.Error("Failed to load properties for message " + emailMessage.Id.UniqueId, e);
                                     FailedMessageCount++;
                                 }
                             }
                         }
                         catch (Exception e)
                         {
                             Logger.Error("Failed to load properties for messages in " + exchangeFolder.FolderPath, e);
                             FailedMessageCount += emails.Count;
                         }
                         ProcessedMessageCount += emails.Count;
                     }
                     if (more)
                     {
                         view.Offset += _pageSize;
                     }
                 }
                 catch (Exception e)
                 {
                     Logger.Error("Failed to find results against folder " + exchangeFolder.FolderPath, e);
                     more = false;
                 }
             }
         }
     }
     catch (Exception e)
     {
         Logger.Error("Failed to run exporter", e);
     }
     finally
     {
         Close();
     }
 }
示例#4
0
 private FolderId GetCreateFolder(string destinationFolder, bool secondAttempt = false)
 {
     lock (_folderCreationLock)
     {
         if (!folders.Any(folder => folder.FolderPath.Equals(destinationFolder)))
         {
             // folder doesn't exist
             // getCreate its parent
             var      parentPath     = Regex.Replace(destinationFolder, @"\\[^\\]+$", "");
             FolderId parentFolderId = null;
             if (parentPath.Equals(destinationFolder))
             {
                 // we are at the root
                 parentPath     = "";
                 parentFolderId = WellKnownFolderName.MsgFolderRoot;
             }
             else
             {
                 parentFolderId = GetCreateFolder(parentPath);
             }
             Logger.Debug("Folder " + destinationFolder + " doesn't exist, creating.");
             var    destinationFolderName = Regex.Replace(destinationFolder, @"^.*\\", "");
             Folder folder = new Folder(service)
             {
                 DisplayName = destinationFolderName
             };
             try
             {
                 folder.Save(parentFolderId);
             }
             catch (Exception e)
             {
                 // If the folder exists, we need to refresh and have another crack
                 if (e.Message.Equals("A folder with the specified name already exists.") && !secondAttempt)
                 {
                     Logger.Warn("Looks like the folder " + destinationFolder + " was created under our feet, refreshing the folder list. We will only attempt this once per folder.");
                     // Oops, the folders have been updated on the server, we need a refresh
                     var newFolders = new List <ExchangeFolder>();
                     ExchangeHelper.GetAllSubFolders(service, new ExchangeFolder {
                         Folder = Folder.Bind(service, WellKnownFolderName.MsgFolderRoot)
                     }, newFolders, false);
                     folders = newFolders;
                     // lets try again
                     return(GetCreateFolder(destinationFolder, true));
                 }
                 throw e;
             }
             folders.Add(new ExchangeFolder()
             {
                 Folder     = folder,
                 FolderId   = folder.Id,
                 FolderPath =
                     String.IsNullOrEmpty(parentPath)
                         ? destinationFolderName
                         : parentPath + @"\" + destinationFolderName,
             });
             return(folder.Id);
         }
         else
         {
             return(folders.First(folder => folder.FolderPath.Equals(destinationFolder)).FolderId);
         }
     }
 }
示例#5
0
        private EmailMessage PrepareEWSItem(RawMessageDescriptor msg)
        {
            var headersString = msg.RawMessage;
            var headerLimit   = msg.RawMessage.IndexOf("\n\n");

            if (headerLimit < 0)
            {
                headerLimit = msg.RawMessage.IndexOf("\r\n\r\n");
            }
            if (headerLimit > 0)
            {
                headersString = msg.RawMessage.Substring(0, headerLimit);
            }
            // sometimes there is no received header, we will have to modify this so Outlook sorts this correctly
            if (!headersString.Contains("Received: ") && !msg.DestinationFolder.Equals("Sent Items"))
            {
                var match = Regex.Match(headersString, @"Date: (.*)");
                if (match.Success)
                {
                    Logger.Debug("Missing Received header, adding dummy header");
                    msg.RawMessage = "Received: from zinkuba.export (127.0.0.1) by\r\n" +
                                     " zinkuba.import (127.0.0.1) with Zinkuba id 0.0.0.0;\r\n" +
                                     " " + match.Groups[1] +
                                     "\r\n" +
                                     msg.RawMessage;
                }
            }

            EmailMessage item = new EmailMessage(service)
            {
                MimeContent = new MimeContent("UTF-8", Encoding.UTF8.GetBytes(msg.RawMessage))
            };

            if (msg.DestinationFolder.Equals("Sent Items"))
            {
                // we need to set a sent date property otherwise dates don't show up properly in exchange
                DateTime?sentDate = msg.SentDateTime;
                if (sentDate == null)
                {
                    var match = Regex.Match(headersString, @"Date: (.*)");
                    if (match.Success)
                    {
                        try
                        {
                            sentDate = DateTime.Parse(match.Groups[1].Value);
                        }
                        catch (Exception e)
                        {
                            Logger.Error("Failed to parse header date " + match.Groups[1] + " to a date for sending.");
                        }
                    }
                }
                if (sentDate == null)
                {
                    Logger.Error("Failed to set sent date on " + msg.Subject);
                }
                else
                {
                    try
                    {
                        item.SetExtendedProperty(ExchangeHelper.MsgPropertyDateTimeSent,
                                                 sentDate.Value.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ"));
                        item.SetExtendedProperty(ExchangeHelper.MsgPropertyDateTimeReceived,
                                                 sentDate.Value.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ"));
                    }
                    catch (Exception e)
                    {
                        Logger.Error("Failed to set sent item date on " + msg.Subject + " to " + sentDate, e);
                    }
                }
            }

            String folder = msg.DestinationFolder;

            // This is required to be set one way or another, otherwise the message is marked as new (not delivered)
            item.IsRead = !msg.Flags.Contains(MessageFlags.Unread);
            // Set the defaults to no receipts, to be corrected later by flags.
            item.IsReadReceiptRequested     = false;
            item.IsDeliveryReceiptRequested = false;
            if (!String.IsNullOrEmpty(msg.ItemClass))
            {
                item.ItemClass = msg.ItemClass;
            }
            else
            {
                // default Item.Class
                item.ItemClass = "IPM.Note";
                // we need to detect the item class
                if (headersString.Contains("Return-Path: <>"))
                {
                    // Looks like it may be a bounce
                    if (headersString.Contains("X-MS-Exchange-Message-Is-Ndr:") ||
                        headersString.Contains("Content-Type: multipart/report; report-type=delivery-status;") ||
                        headersString.Contains("X-Failed-Recipients:")
                        )
                    {
                        item.ItemClass = "REPORT.IPM.NOTE.NDR";
                    }
                }
            }

            foreach (var messageFlag in msg.Flags)
            {
                try
                {
                    switch (messageFlag)
                    {
                    case MessageFlags.Associated:
                    {
                        item.IsAssociated = true;
                        break;
                    }

                    case MessageFlags.FollowUp:
                    {
                        item.Flag = new Flag()
                        {
                            FlagStatus = ItemFlagStatus.Flagged
                        };
                        break;
                    }

                    case MessageFlags.ReminderSet:
                    {
                        item.IsReminderSet = true;
                        break;
                    }

                    case MessageFlags.ReadReceiptRequested:
                    {
                        // If the item is read already, we don't set a read receipt request as it will send one on save.
                        if (!item.IsRead)
                        {
                            item.IsReadReceiptRequested = true;
                        }
                        break;
                    }

                    case MessageFlags.DeliveryReceiptRequested:
                    {
                        // this causes spam
                        //item.IsDeliveryReceiptRequested = true;
                        break;
                    }
                    }
                }
                catch (Exception e)
                {
                    Logger.Warn("Failed to set flag on " + folder + @"\" + msg.Subject + ", ignoring flag.", e);
                }
            }

            if (msg.FlagIcon != FlagIcon.None)
            {
                item.SetExtendedProperty(ExchangeHelper.PidTagFlagStatus, 2);
                item.SetExtendedProperty(ExchangeHelper.PidTagFollowupIcon, ExchangeHelper.ConvertFlagIcon(msg.FlagIcon));
            }

            if (service.RequestedServerVersion == ExchangeVersion.Exchange2013 && msg.FollowUpFlag != null)
            {
                item.Flag = new Flag()
                {
                    DueDate      = msg.FollowUpFlag.DueDateTime,
                    StartDate    = msg.FollowUpFlag.StartDateTime,
                    CompleteDate = msg.FollowUpFlag.CompleteDateTime,
                    FlagStatus   = ExchangeHelper.ConvertFlagStatus(msg.FollowUpFlag.Status),
                };
            }

            try
            {
                if (!msg.Flags.Contains(MessageFlags.Draft))
                {
                    item.SetExtendedProperty(ExchangeHelper.MsgFlagRead, 1);
                }
                if (msg.Importance != null)
                {
                    item.Importance = (Importance)msg.Importance;
                }
                if (msg.Sensitivity != null)
                {
                    item.Sensitivity = (Sensitivity)msg.Sensitivity;
                }
                if (msg.ReminderDueBy != null)
                {
                    item.ReminderDueBy = (DateTime)msg.ReminderDueBy;
                }
                item.Categories = new StringList(msg.Categories);
            }
            catch (Exception e)
            {
                Logger.Warn(
                    "Failed to set metadata on " + folder + @"\" + msg.Subject + ", ignoring metadata.", e);
            }

            return(item);
        }