/// <summary>
 /// Alternate Constructor
 /// </summary>
 /// <param name="name"></param>
 /// <param name="parent"></param>
 public IMAPFolder(string name, string parent)
 {
     _subFolders = new IMAPFolderCollection();
     _parentFolder = null;
     _folderName = name;
     _parentFolderName = parent;
     _folderPath = String.Empty;
     _messages = new IMAPMessageCollection();
     _quota = new IMAPFolderQuota();
 }
Example #2
0
        /// <summary>
        /// New method for processing folder list
        /// </summary>
        /// <param name="rootFolder"></param>
        /// <returns></returns>
        public IMAPFolderCollection ProcessFolders(string rootFolder)
        {
            IMAPFolderCollection folders = new IMAPFolderCollection();
            List<IMAPFolder> subFolders = new List<IMAPFolder>();
            _rawFolderList.Clear();
            string cmd = "LIST {0} \"*\"\r\n";
            if (String.IsNullOrEmpty(rootFolder))
                rootFolder = "\"\"";

            ArrayList result = new ArrayList();
            SendAndReceive(String.Format(cmd, rootFolder), ref result);

            foreach (string s in result)
            {
                if (s.StartsWith("*"))
                {
                    int idx = s.IndexOf("\"");
                    char dirDivider = s[idx + 1];
                    int idx2 = s.IndexOf(" ", idx + 2);
                    string folderString = s.Substring(idx2 + 1).Replace("\"","");
                    string[] folderParts = folderString.Split(new char[] { dirDivider });
                    StringBuilder folderPath = new StringBuilder();
                    
                    for (int i = 0; i < folderParts.Length; i++)
                    {
                        if (i > 0 && i < folderParts.Length)
                            folderPath.Append(dirDivider);
                        folderPath.Append(folderParts[i]);
                        

                        IMAPFolder f = new IMAPFolder();
                        f.FolderName = folderParts[i];
                        f.FolderPath = folderPath.ToString();
                        f.Selectable = !s.ToLower().Contains("\\noselect");
                        if (i > 0)
                        {
                            // if this is greater than 0 then we must have already processed its parent folder. find it
                            // in the list
                            foreach (IMAPFolder pf in folders)
                            {
                                if (pf.FolderName.Equals(folderParts[i - 1]))
                                {
                                    f.ParentFolder = pf;

                                    bool subAdded = false;
                                    foreach (IMAPFolder testfolder in pf.SubFolders)
                                    {
                                        if (testfolder.FolderPath.Equals(f.FolderPath))
                                            subAdded = true;
                                    }

                                    if (!subAdded)
                                    {
                                        pf.SubFolders.Add(f);
                                        subFolders.Add(f);
                                    }
                                    //subFolders.Add(f);
                                    break;
                                }

                            }
                        }

                        bool alreadyAdded = false;

                        foreach (IMAPFolder test in folders)
                        {
                            if (test.FolderPath.Equals(f.FolderPath))
                                alreadyAdded = true;
                        }
                        
                        if (!alreadyAdded)
                        {
                            folders.Add(f);
                            _rawFolderList.Add(f);
                        }
                        
                    }                                                            
                }                
            }

            List<IMAPFolder> tmp1 = new List<IMAPFolder>();
            foreach (IMAPFolder f in folders)
                if (f.ParentFolder != null)
                    tmp1.Add(f);

            foreach (IMAPFolder f in tmp1)
                folders.Remove(f);

            return folders;
        }
 /// <summary>
 /// Default constructor. Only used for deserialization purposes.
 /// </summary>
 public IMAPClient()
 {
     _config = null;
     _imap = new IMAP();
     _folders = new IMAPFolderCollection();
 }
 /// <summary>
 /// Helper method for recursively adding all folders from the source folder structure into the flat list
 /// </summary>
 /// <param name="currentFolder"></param>
 /// <param name="master"></param>
 private void FolderRecurser(IMAPFolder currentFolder, ref IMAPFolderCollection master)
 {
     if (currentFolder.SubFolders.Count > 0)
     {
         foreach (IMAPFolder f in currentFolder.SubFolders)
         {
             master.Add(f);
             FolderRecurser(f, ref master);
         }
     }
 }
        /// <summary>
        /// Takes the multi-level folder structure and flattens it into a single list of all folders
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        private IMAPFolderCollection FlattenFolderList(IMAPFolderCollection list)
        {
            IMAPFolderCollection newList = new IMAPFolderCollection();

            foreach (IMAPFolder f in list)
            {
                FolderRecurser(f, ref newList);

                newList.Add(f);
            }

            return newList;
        }
        /// <summary>
        /// Synchronizes the local cache with the server
        /// </summary>
        public void SyncCache()
        {
            if (this.OfflineMode)
                return;

            if (!this.UsingCache)
                return;

            // to synchronize the cache without having to download everything all over again,
            // we first get the folder list from the server. We then look at each folder in the server list
            // and see if it already exists in the client list. if it does not, we add it and pull
            // the message UIDs for it.

            // then we check the client list and see if all of those folders are still on the server
            // if not, the folder on the client side is removed, all with all of its messages

            // keep track of newly added folders so their contents can be downloaded.

            // next we iterate through all the existing folders and check for any new messages.
            // this is accomplished by simply calling the GetMessageIDs method on the folder. this will
            // update the folder with any UIDs that dont already exist.
            // the messages content will be loaded automatically when it is serialized.
            Log(IMAPBase.LogTypeEnum.INFO, "Synching Cache...");
            IMAPFolderCollection serverFolderList = _imap.RawFolderList;
            IMAPFolderCollection clientFolderList = FlattenFolderList(_folders);

            IMAPFolderCollection newFolderList = new IMAPFolderCollection();
            IMAPFolderCollection oldFolderList = new IMAPFolderCollection();

            foreach (IMAPFolder f in serverFolderList)
            {
                bool found = false;

                foreach (IMAPFolder cf in clientFolderList)
                {
                    if (cf.FolderPath.Equals(f.FolderPath))
                        found = true;
                }

                if (!found)
                {
                    newFolderList.Add(f);
                }
            }

            foreach (IMAPFolder f in clientFolderList)
            {
                bool found = false;

                foreach (IMAPFolder sf in serverFolderList)
                {
                    if (sf.FolderPath.Equals(f.FolderPath))
                        found = true;
                }

                if (!found)
                {
                    oldFolderList.Add(f);
                }

            }

            if (oldFolderList.Count > 0)
            {
                Log(IMAPBase.LogTypeEnum.INFO, String.Format("{0} old folders found", newFolderList.Count));
                foreach (IMAPFolder f in oldFolderList)
                {
                    IMAPFolder temp = null;
                    FindFolder(f.FolderPath, ref _folders, ref temp);

                    if (temp != null)
                    {
                        if (temp.ParentFolder == null)
                        {
                            _folders.Remove(temp);
                        }
                        else
                        {
                            temp.ParentFolder.SubFolders.Remove(temp);
                        }
                    }
                }
            }

            if (newFolderList.Count > 0)
            {
                Log(IMAPBase.LogTypeEnum.INFO, String.Format("{0} new folders found", newFolderList.Count));

                // now we need to put these new folders into the proper locations in the tree.
                foreach (IMAPFolder f in newFolderList)
                {
                    f.GetMessageIDs(false);
                    foreach (IMAPFolder sf in serverFolderList)
                    {
                        if (sf.FolderName.Equals(f.ParentFolderName))
                        {
                            f.ParentFolder = sf;
                            break;
                        }
                    }
                    // if the new folder has no parent assigned to it then we just add it to the root folders
                    if (f.ParentFolderName == String.Empty)
                    {
                        _folders.Add(f);
                    }
                    else
                    {

                        // otherwise we just loop through the flat list we created
                        // and find the folder that is the parent of the current new folder
                        // we then add the new folder to the sub folders of its parent
                        foreach (IMAPFolder cf in clientFolderList)
                        {
                            if (cf.FolderPath.Equals(f.ParentFolder.FolderPath))
                            {
                                cf.SubFolders.Add(f);
                                f.ParentFolder = cf;
                                break;
                            }
                        }
                    }
                }
            }

            foreach (IMAPFolder f in clientFolderList)
            {
                // this will get the UIDs of any new messages that have been added to the folder on the server
                f.GetMessageIDs(false);
            }

            UpdateCache(false);
            Log(IMAPBase.LogTypeEnum.INFO, "Cache Synchronization Complete");
        }
        /// <summary>
        /// Login using currently specified connection settings. Called automatically if AutoLogon is true.
        /// </summary>
        public void Logon()
        {
            if (this.LoggedOn || this._config == null)
                return;

            if (!_imap.Login(_config.Host, _config.UserName, _config.Password, _config.UseSSL))
            {
                if (!UsingCache)
                {
                    Log(IMAPBase.LogTypeEnum.ERROR, "Cannot connect to server and no cache is available. System cannot proceed. Quiting...");
                    throw new IMAPException(IMAPException.IMAPErrorEnum.IMAP_ERR_CONNECT);
                }
                OfflineMode = true;
                Log(IMAPBase.LogTypeEnum.WARN, "Login Failed. Switching to Offline Mode");
                return;
            }

            Log(IMAPBase.LogTypeEnum.INFO, "Login Successful");

            if (!UsingCache)
            {
                XmlDocument doc = new XmlDocument();
                _folders.Clear();
                _folders = _imap.ProcessFolders(_config.DefaultFolderName);
                foreach (IMAPFolder f in _folders)
                {
                    f.SetClient(this);
                    if (_config.AutoGetMsgID)
                        f.GetMessageIDs(false);
                }
            }
        }
        /// <summary>
        /// Loads the specified local cache into the object model
        /// </summary>
        public void LoadCache()
        {
            Log(IMAPBase.LogTypeEnum.INFO, "Loading Local Cache...");

            //try
            //{
                Stream s = File.Open(_config.CacheFile, FileMode.Open);
                IMAPClient c = new IMAPClient();
                switch (_config.Format)
                {
                    case CacheFormat.XML:
                        {
                            XmlSerializer xml = new XmlSerializer(typeof(IMAPClient));
                            c = (IMAPClient)xml.Deserialize(s);
                            break;
                        }
                    case CacheFormat.Binary:
                        {
                            BinaryFormatter b = new BinaryFormatter();
                            c = (IMAPClient)b.Deserialize(s);
                            break;
                        }
                }

                this._folders = c.Folders;
                foreach (IMAPFolder f in _folders)
                {
                    f.SetClient(this);
                    f.SetParent(null);
                }

                s.Close();
            //}
            //catch (Exception e)
            //{
            //    throw e;
            //}

            Log(IMAPBase.LogTypeEnum.INFO, String.Format("Cache loaded ({0} messages found, in {1} folders)", this.TotalMessages, this.FolderCount));
        }
        /// <summary>
        /// Searches the entire tree structure of the provided folder collection looking for a folder with
        /// the specified path. if it finds the folder, it is stored in the foundFolder parameter
        /// </summary>
        /// <param name="path"></param>
        /// <param name="sourceList"></param>
        /// <param name="foundFolder"></param>
        public void FindFolder(string path, ref IMAPFolderCollection sourceList, ref IMAPFolder foundFolder)
        {
            if (sourceList.Count == 0)
                return;

            foreach (IMAPFolder f in sourceList)
            {
                if (f.FolderPath.Equals(path))
                {
                    foundFolder = f;
                    return;
                }
                IMAPFolderCollection fc = f.SubFolders;
                FindFolder(path, ref fc, ref foundFolder);
            }
        }
        /// <summary>
        /// Main constructor. 
        /// </summary>
        /// <param name="config">The configuration instance to use for this client</param>
        /// <param name="logger">Custom logger to use with this client. Use null for default logger.</param>
        public IMAPClient(IMAPConfig config, IMAPLogger logger, int maxWorkers)
        {
            _config = config;
            _imap = new IMAP();

            _logger = logger ?? new IMAPLogger(config);
            //_imap.InfoLogged += Log;
            _imap.Logger = _logger;
            _folders = new IMAPFolderCollection();

            Log(IMAPBase.LogTypeEnum.IMAP, "------------------------------------------------------");
            Log(IMAPBase.LogTypeEnum.INFO, "InterIMAP Client Initialized");

            if (config.CacheFile != String.Empty)
            {
                this.UsingCache = true;
                Log(IMAPBase.LogTypeEnum.INFO, String.Format("Using Local Cache File: {0}", config.CacheFile));
            }

            if (config.AutoLogon)
                Logon();

            if (UsingCache)
            {
                FileInfo finfo = new FileInfo(config.CacheFile);
                if (finfo.Exists)
                {
                    // this config has a cache file specified. Load the cache into the object model

                    LoadCache();
                    if (!OfflineMode && config.AutoSyncCache)
                        SyncCache();
                }
                else
                {

                    _folders.Clear();
                    _folders = _imap.ProcessFolders(_config.DefaultFolderName);
                    //IMAPFolderCollection tempFolders = _imap.ProcessFolders(_config.DefaultFolderName);
                    foreach (IMAPFolder f in _folders)
                    {
                        f.SetClient(this);
                        if (_config.AutoGetMsgID)
                            f.GetMessageIDs(false);
                    }

                    BuildNewCache();
                }

            }
        }