예제 #1
0
        private async void HandleQueue()
        {
            var active = queue.Join(mailboxes, queue => queue.Owner, mailboxes => mailboxes.Alias,
                                    (q, m) => new { queue = q, mailboxes = m })
                         .Where(q => q.queue.Status == Status.Waiting && !q.mailboxes.Busy)
                         .OrderBy(q => q.queue.Size).ToList();

            //List<Queue> active = queue.Where(q => !q.Owner.Busy && q.Status == Status.Waiting)
            //                          .OrderBy(q => q.Size).ToList();

            if (active.Count == 0 || queuebusy)
            {
                return;
            }
            queuebusy = true;

            List <string> aliases = active.GroupBy(q => q.queue.Owner)
                                    .Select(g => g.First())
                                    .Select(q => q.queue.Owner).ToList();

            foreach (string alias in aliases)
            {
                //List<Queue> batch = active.Where(q => q.Alias == alias)
                //                          .GroupBy(q => q.Owner)
                //                          .Select(g => g.First()).ToList();

                // TODO: combine duplicte messages, so they only download once.

                //while (tocktasks.Count >= config.Settings.MaxQueueThreads)
                while (tocktasks.Count >= 1)
                {
                    await Task.Delay(1000);

                    tocktasks.RemoveAll(t => t.Status == TaskStatus.RanToCompletion);
                }

                Queue   q     = queue.Where(a => a.Owner == alias).First();
                Mailbox owner = mailboxes.Where(m => m.Alias == q.Owner).First();

                tocktasks.Add(Task.Run(() =>
                {
                    ProcessQueuedMessages(owner);
                }));
            }
            queuebusy = false;
        }
예제 #2
0
        private void ProcessQueuedMessages(Mailbox mailbox)
        {
            Server serverout = config.Servers.Find(s => s.Alias == mailbox.Outbound.Alias && s.Type == ServerType.SMTP);

            mailbox.Busy = true;

            WriteLog(string.Format("Precessing Queued Messages: {0}:  {1}:{2}",
                                   serverout.Alias, mailbox.Alias, serverout.Domain, serverout.Port), LogLevel.Informational);

            using (SmtpClient outbound = new SmtpClient(serverout))
            {
                outbound.MessageSent += onMessageSent;
                //TODO: outbound progress

                try
                {
                    outbound.Connect();
                }
                catch (Exception e)
                {
                    WriteLog(String.Format("SMTP: Error connecting to {0} : {1}", mailbox.Outbound.Alias, e.Message), LogLevel.Error);
                    return;
                }

                Server serverin = config.Servers.Find(s => s.Alias == mailbox.Inbound.Alias && s.Type == ServerType.POP3);
                using (var inbound = new Pop3Client(serverin, mailbox))
                {
                    inbound.ProgressChanged += onProgressChanged;
                    try
                    {
                        inbound.Connect();
                    }
                    catch (Exception e)
                    {
                        WriteLog(String.Format("POP3: Error connecting to {0} : {1}", mailbox.Inbound.Alias, e.Message), LogLevel.Error);
                        return;
                    }

                    try
                    {
                        List <Queue> batch = queue.Where(q => q.Owner == mailbox.Alias).OrderBy(q => q.Size).ToList();
                        foreach (Queue q in batch)
                        {
                            TransferMessage(inbound, outbound, q);
                        }
                    }
                    catch (Exception e)
                    {
                        WriteLog(String.Format("Error transfering from {0} : {1}", mailbox.Inbound.Alias, e.Message), LogLevel.Error);
                        return;
                    }
                    if (inbound.IsConnected)
                    {
                        inbound.Disconnect(true);
                    }
                    if (inbound != null)
                    {
                        inbound.Dispose();
                    }
                }
                if (outbound.IsConnected)
                {
                    outbound.Disconnect(true);
                }
                if (outbound != null)
                {
                    outbound.Dispose();
                }
            }
            mailbox.Busy = false;
        }
예제 #3
0
        private void ProcessMailboxAsync(Mailbox mailbox)
        {
            Server server = config.Servers.Find(s => s.Alias == mailbox.Outbound.Alias && s.Type == ServerType.SMTP);

            using (SmtpClient outbound = new SmtpClient(server))
            {
                outbound.MessageSent += onMessageSent;

                try
                {
                    outbound.Connect();
                }
                catch (Exception e)
                {
                    WriteLog(String.Format("SMTP: Error connecting to {0} : {1}", mailbox.Outbound.Alias, e.Message), LogLevel.Error);
                    return;
                }

                using (var inbound = new Pop3Client(config.Servers.Find(s => s.Alias == mailbox.Inbound.Alias && s.Type == ServerType.POP3), mailbox))
                {
                    try
                    {
                        inbound.Connect();
                    }
                    catch (Exception e)
                    {
                        WriteLog(String.Format("POP3: Error connecting to {0} : {1}", mailbox.Inbound.Alias, e.Message), LogLevel.Error);
                        return;
                    }

                    try
                    {
                        if (String.IsNullOrEmpty(mailbox.LastUID))
                        {
                            WriteLog(string.Format("Skipping New Mailbox: {0} : {1} : {2} Mesages", mailbox.Alias, mailbox.Name, inbound.Count), LogLevel.Warning);

                            if (inbound.Count > 0)
                            {
                                // We are going to skip ALL messages, because this is the first run on this mailbox!
                                mailbox.LastUID = inbound.GetMessageUids().Last();
                                return;
                            }
                            else
                            {
                                // Return zero as last UID, because mailbox is empty.
                                mailbox.LastUID = "0";
                                return;
                            }
                        }

                        // Get a list of all new message UIDs
                        IList <string> uids = inbound.GetNewMessageUids(mailbox.LastUID);
                        //uids.Remove(mailbox.LastUID);
                        if (uids.Count > 0)
                        {
                            WriteLog(string.Format("Processing Mailbox: {0} : {1} : {2} Mesages ({3} new)", mailbox.Alias, mailbox.Name, inbound.Count, uids.Count), LogLevel.Informational);
                        }
                        else
                        {
                            WriteLog(string.Format("Processing Mailbox: {0} : {1} : {2} Mesages ({3} new)", mailbox.Alias, mailbox.Name, inbound.Count, uids.Count), LogLevel.Verbose);
                        }
                        if (uids.Count() == 0)
                        {
                            return;
                        }

                        // Set LastUID to the last message in the mailbox.
                        mailbox.LastUID = uids.Last();

                        foreach (string uid in uids)
                        {
                            int size = inbound.GetMessageSize(uid);

                            Queue q = new Queue()
                            {
                                Uid   = uid,
                                Owner = mailbox.Alias,
                                Size  = size
                            };

                            if (size > 2 * 1024 * 1024) // 2Mb
                            {
                                //TODO: Shorten size.
                                // Queue the larger messages, so we can get the smaller ones faster.
                                WriteLog(String.Format("Queued Message {0}:{1} (Size {2:N})", mailbox.Alias, uid, size), LogLevel.Verbose);
                                queue.Add(q);
                            }
                            else
                            {
                                WriteLog(String.Format("Downloading Message {0}:{1} (Size {2:N})", mailbox.Alias, uid, size), LogLevel.Verbose);
                                q.Status = Status.Downloading;
                                queue.Add(q);
                                TransferMessage(inbound, outbound, q);
                            }
                        }

                        //TODO: Keep x days
                        Thread.Sleep(1000);

                        foreach (string uid in uids)
                        {
                            Queue q = queue.Find(c => c.Uid == uid);
                            if (q != null)
                            {
                                if (q.Status == Status.Complete)
                                {
                                    inbound.DeleteMessage(uid);
                                }
                            }
                        }

                        if (inbound.IsConnected)
                        {
                            inbound.Disconnect(true);
                        }
                        if (inbound != null)
                        {
                            inbound.Dispose();
                        }
                    }
                    catch (Exception e)
                    {
                        WriteLog(String.Format("Error downloading from {0} : {1}", mailbox.Inbound.Alias, e.Message), LogLevel.Error);
                        return;
                    }
                }
                if (outbound.IsConnected)
                {
                    outbound.Disconnect(true);
                }
                if (outbound != null)
                {
                    outbound.Dispose();
                }
            }
        }
예제 #4
0
 public Pop3Client(Server server, Mailbox mailbox)
 {
     Server  = server;
     Mailbox = mailbox;
 }