Click here to Skip to main content
15,885,985 members
Articles / Programming Languages / C#

How to Create a Spam Filter or Automatic Category Sort Algorithm with Your Mail Application

Rate me:
Please Sign up or sign in to vote.
5.00/5 (9 votes)
29 Jul 2012MIT3 min read 40K   1.2K   19  
This article describes automatic category filters in mail applications.
In this article, you will learn how to create a spam filter on your mail application. You will also see how to filter your mail based on whether the mail tells about a particular topic or not.
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
using HigLabo.Net.Mail;

namespace HigLabo.Net.Pop3
{
	/// <summary>
	/// POP3のメッセージを表現するクラスです。
	/// Represent pop3 message with attachment as Pop3Content.
	/// </summary>
    public class Pop3Message : InternetTextMessage
    {
        private Boolean _InvalidFormat = false;
        /// デコード済みの本文の文字列データ
        /// <summary>
        /// Field for decoded body data.
        /// デコード済みの本文の文字列データ
        /// </summary>
        private String _BodyText;
        private Boolean _BodyTextCreated = false;
        private Pop3Content _BodyContent = null;
        private List<Pop3Content> _Contents = new List<Pop3Content>();
        private Int64? _Index = 0;
        private Int32 _Size = 0;
        /// メールボックスにおけるメールのIndexの値を取得します。
        /// <summary>
        /// Get mail index of this mailbox.
        /// メールボックスにおけるメールのIndexの値を取得します。
        /// </summary>
        public Int64? Index
        {
            get { return this._Index; }
        }
        /// Toの値を取得します。
        /// <summary>
        /// Get TO value of this mail.
        /// Toの値を取得します。
        /// </summary>
        public String To
        {
            get { return this["To"]; }
        }
        /// Ccの値を取得します。
        /// <summary>
        /// Get CC value of this mail.
        /// Ccの値を取得します。
        /// </summary>
        public String Cc
        {
            get { return this["Cc"]; }
        }
        /// Bccの値を取得します。
        /// <summary>
        /// Get BCC value of this mail.
        /// Bccの値を取得します。
        /// </summary>
        public String Bcc
        {
            get { return this["Bcc"]; }
        }
        /// Body部のメッセージのテキストを取得します。
        /// <summary>
        /// Get body text message of this mail.
        /// Body部のメッセージのテキストを取得します。
		/// </summary>
        public String BodyText
        {
            get
            {
                this.EnsureBodyText();
                return this._BodyText;
            }
            set { this._BodyText = value; }
        }
		/// Header部分のデータを取得します。
		/// <summary>
		/// Get header text data of this mail.
		/// Header部分のデータを取得します。
		/// </summary>
		public new String HeaderData
		{
			get { return base.HeaderData; }
		}
		/// Body部分のデータを取得します。
		/// <summary>
		/// Get body text data of this mail.
		/// Body部分のデータを取得します。
		/// </summary>
		public new String BodyData
		{
			get { return base.BodyData; }
		}
        /// メールのサイズを取得します。
        /// <summary>
        /// Get mail size of this mail.
        /// メールのサイズを取得します。
        /// </summary>
        public Int32 Size
        {
            get { return this._Size; }
            set { this._Size = value; }
        }
        /// Body部分のPop3Contentを取得します。
        /// <summary>
        /// Get content of this mail message.
        /// Body部分のPop3Contentを取得します。
        /// </summary>
        public Pop3Content BodyContent
        {
            get
            {
                this.EnsureBodyContent(this._Contents);
                return this._BodyContent;
            }
        }
        /// Pop3Contentのコレクションを取得します。
        /// <summary>
        /// Get pop3 content collection of this mail.
        /// Pop3Contentのコレクションを取得します。
        /// </summary>
        public List<Pop3Content> Contents
        {
            get { return this._Contents; }
        }
        /// メッセージのフォーマットが正しいかどうかを示す値を取得します。
        /// <summary>
        /// Get a value that specify this mail format is valid or invalid.
        /// メッセージのフォーマットが正しいかどうかを示す値を取得します。
        /// </summary>
        public Boolean InvalidFormat
        {
            get { return this._InvalidFormat; }
        }
        /// Body部分のテキストが生成済みか同かを示す値を取得します。
        /// <summary>
        /// Get value that indicate body text is created or not.
        /// Body部分のテキストが生成済みか同かを示す値を取得します。
        /// </summary>
        protected Boolean BodyTextCreated
        {
            get { return this._BodyTextCreated; }
            set { this._BodyTextCreated = value; }
        }
		/// <summary>
		/// 
		/// </summary>
		/// <param name="text"></param>
        public Pop3Message(String text) : 
            base(text)
        {
            this.Initialize(text);
        }
		/// <summary>
		/// 
		/// </summary>
		/// <param name="text"></param>
		/// <param name="index"></param>
        public Pop3Message(String text, Int64 index) :
            base(text)
        {
            this._Index = index;
            this.Initialize(text);
        }
        private void Initialize(String text)
        {
            this.Data = text;
            this._Size = text.Length;
            if (this.IsMultiPart == true)
            {
                List<String> l = MimeContent.ParseToContentTextList(this.BodyData, this.MultiPartBoundary);
                for (int i = 0; i < l.Count; i++)
                {
                    this._Contents.Add(new Pop3Content(this, l[i]));
                }
            }
        }
        /// Body部のデータがセットされているか確認し、セットされてない場合はデータをセットします。
        /// <summary>
        /// Ensure that body data is set or not,and set body data if body data is not set.
        /// Body部のデータがセットされているか確認し、セットされてない場合はデータをセットします。
        /// </summary>
        /// <param name="contents"></param>
        /// <returns></returns>
        private Boolean EnsureBodyContent(List<Pop3Content> contents)
        {
            for (int i = 0; i < contents.Count; i++)
            {
                if (contents[i].IsBody == true)
                {
                    this._BodyContent = contents[i];
                    return true;
                }
                if (this.EnsureBodyContent(contents[i].Contents) == true)
                { return true; }
            }
            return false;
        }
        /// 全てのPop3Contentのコレクションを取得します。
        /// <summary>
        /// Get all pop3 content collection.
        /// 全てのPop3Contentのコレクションを取得します。
        /// </summary>
        /// <returns></returns>
        public static List<Pop3Content> GetAllContents(Pop3Message pop3Message)
        {
            if (pop3Message == null)
            { throw new ArgumentNullException("pop3Message"); }
            List<Pop3Content> l = new List<Pop3Content>();
            l = Pop3Message.GetAttachedContents(pop3Message.Contents, delegate(Pop3Content c) { return true; });
            return l;
        }
        /// IsAttachmentがtrueのPop3Contentのコレクションを取得します。
        /// <summary>
        /// Get pop3 content collection that IsAttachment property is true.
        /// IsAttachmentがtrueのPop3Contentのコレクションを取得します。
        /// </summary>
        /// <returns></returns>
        public static List<Pop3Content> GetAttachedContents(Pop3Message pop3Message)
        {
            if (pop3Message == null)
            { throw new ArgumentNullException("pop3Message"); }
            List<Pop3Content> l = new List<Pop3Content>();
            l = Pop3Message.GetAttachedContents(pop3Message.Contents, delegate(Pop3Content c) { return c.IsAttachment; });
            return l;
        }
        /// predicateで与えた条件を満たすPop3Contentのコレクションを取得します。
        /// <summary>
        /// Get pop3 content collection that specify predicate is true.
        /// predicateで与えた条件を満たすPop3Contentのコレクションを取得します。
        /// </summary>
        /// <param name="contents"></param>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public static List<Pop3Content> GetAttachedContents(List<Pop3Content> contents, Predicate<Pop3Content> predicate)
        {
            List<Pop3Content> l = new List<Pop3Content>();
            for (int i = 0; i < contents.Count; i++)
            {
                if (predicate(contents[i]) == true)
                {
                    l.Add(contents[i]);
                }
                l.AddRange(Pop3Message.GetAttachedContents(contents[i].Contents, predicate).ToArray());
            }
            return l;
        }
        /// Body部のテキストがセットされているか確認し、セットされてない場合はBody部の文字列をセットします。
        /// <summary>
        /// Ensure that body text is set or not,and set body text if body text is not set.
        /// Body部のテキストがセットされているか確認し、セットされてない場合はBody部の文字列をセットします。
        /// </summary>
        /// <returns></returns>
        protected virtual void EnsureBodyText()
        {
            if (this.BodyTextCreated == false)
            {
                if (this.ContentType.Value.IndexOf("message/rfc822") > -1)
                {
                    this.BodyText = this.BodyData;
                }
                else if (this.IsMultiPart == true)
                {
                    if (this.BodyContent == null)
                    {
                        this.BodyText = "";
                    }
                    else
                    {
                        this.BodyText = this.BodyContent.BodyText;
                    }
                }
                else if (this.IsText == true)
                {
                    this.BodyText = MailParser.DecodeFromMailBody(this.BodyData, this.ContentTransferEncoding, this.ContentEncoding);
                }
                else
                {
                    this.BodyText = this.BodyData;
                }
            }
            this.BodyTextCreated = true;
        }
        /// このインスタンスの値を元に、SmtpMessageクラスのインスタンスを生成します。
        /// <summary>
        /// Create SmtpMessage instance with this instance value.
        /// このインスタンスの値を元に、SmtpMessageクラスのインスタンスを生成します。
        /// </summary>
        /// <returns></returns>
        public Smtp.SmtpMessage CreateSmtpMessage()
        {
            Smtp.SmtpMessage mg = new HigLabo.Net.Smtp.SmtpMessage();
            Field f = null;

            mg.To.AddRange(MailAddress.CreateMailAddressList(this.To));
			mg.Cc.AddRange(MailAddress.CreateMailAddressList(this.Cc));
            for (int i = 0; i < this.Header.Count; i++)
            {
                f = this.Header[i];
                if (String.IsNullOrEmpty(f.Value) == true)
                { continue; }
                if (f.Key.ToLower() == "to" ||
                    f.Key.ToLower() == "cc")
                { continue; }
                mg[f.Key] = MailParser.DecodeFromMailHeaderLine(f.Value);
            }
            for (int i = 0; i < this.ContentType.Fields.Count; i++)
            {
                f = this.ContentType.Fields[i];
                mg.ContentType.Fields.Add(new Field(f.Key, MailParser.DecodeFromMailHeaderLine(f.Value)));
            }
            for (int i = 0; i < this.ContentDisposition.Fields.Count; i++)
            {
                f = this.ContentDisposition.Fields[i];
                mg.ContentDisposition.Fields.Add(new Field(f.Key, MailParser.DecodeFromMailHeaderLine(f.Value)));
            }
            mg.BodyText = this.BodyText;
            for (int i = 0; i < this.Contents.Count; i++)
            {
                mg.Contents.Add(this.Contents[i].CreateSmtpContent());
            }
            return mg;
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The MIT License


Written By
CEO TinyBetter, Inc
Japan Japan
I'm a CEO of TinyBetter, Inc in Japan.

Comments and Discussions