/// <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(); }
/// <summary> /// Copies all messages in this folder to the specified folder /// </summary> /// <param name="destFolder">The destination folder all the messages should be copied to</param> public void CopyAllMessagesToFolder(IMAPFolder destFolder) { if (_client.OfflineMode) { _client.Log(IMAPBase.LogTypeEnum.WARN, "Cannot copy messages in offline mode."); return; } if (!this.IsCurrentlySelected) { this.Select(); } string cmd = "UID COPY {0}:{1} \"{2}\"\r\n"; ArrayList result = new ArrayList(); int firstMsg = _messages[0].Uid; int lastMsg = _messages[_messages.Count - 1].Uid; cmd = String.Format(cmd, firstMsg, lastMsg, destFolder.FolderPath); _client._imap.SendAndReceive(cmd, ref result); // TODO: Need to find a way to determine what the UIDs of the copies are and instead of having // to pull the same messages from the server again, just copy the IMAPMessage objects and update // the UID to the new value. This is possible if copying one message at a time, but is not as // easy when copying messages in bulk. foreach (string s in result) { if (s.Contains("OK")) { destFolder.GetMessageIDs(false); _client.UpdateCache(true); _client.Log(IMAPBase.LogTypeEnum.INFO, String.Format("All Messages from {0} successfully copied to {1}.", this.FolderName, destFolder.FolderName)); break; } } }
/// <summary> /// Recursive helper method to count the total number of folders /// </summary> /// <param name="currentFolder"></param> /// <param name="count"></param> private void CountFolders(IMAPFolder currentFolder, ref int count) { count++; foreach (IMAPFolder f in currentFolder.SubFolders) CountFolders(f, ref count); }
/// <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> /// Creates a new sub-folder under this folder /// </summary> /// <param name="name"></param> public void CreateFolder(string name) { if (OfflineMode) { Log(IMAPBase.LogTypeEnum.WARN, "Cannot create folders in offline mode."); return; } string cmd = "CREATE \"{0}\"\r\n"; ArrayList result = new ArrayList(); string newFolder = String.Format("{0}", name); _imap.SendAndReceive(String.Format(cmd, newFolder), ref result); if (result[0].ToString().Contains("OK")) { IMAPFolder oNewFolder = new IMAPFolder(); oNewFolder.FolderName = name; oNewFolder.FolderPath = newFolder; oNewFolder.ParentFolder = null; oNewFolder.ParentFolderName = String.Empty; _folders.Add(oNewFolder); UpdateCache(true); Log(IMAPBase.LogTypeEnum.INFO, String.Format("Folder {0} created successfully.", name)); } else { _imap.Log(IMAPBase.LogTypeEnum.ERROR, "Folder could not be created (" + result[0].ToString()+")"); } }
/// <summary> /// Creates a new sub-folder under this folder /// </summary> /// <param name="name">Name of folder to create</param> /// <param name="autoSelect">Automatically select this folder upon successful creation</param> public void CreateFolder(string name, bool autoSelect) { if (_client.OfflineMode) { _client.Log(IMAPBase.LogTypeEnum.WARN, "Cannot create folders in offline mode."); return; } string cmd = "CREATE \"{0}\"\r\n"; ArrayList result = new ArrayList(); string newFolder = String.Format("{0}/{1}", this.FolderPath, name); _client._imap.SendAndReceive(String.Format(cmd, newFolder), ref result); if (result[0].ToString().Contains("OK")) { IMAPFolder oNewFolder = new IMAPFolder(); oNewFolder.FolderName = name; oNewFolder.FolderPath = newFolder; oNewFolder.ParentFolder = this; oNewFolder.ParentFolderName = this.FolderName; _subFolders.Add(oNewFolder); if (autoSelect) oNewFolder.Select(); _client.UpdateCache(true); } else { _client.Log(IMAPBase.LogTypeEnum.ERROR, "Folder could not be created." + result[0].ToString()); } }
/// <summary> /// Moves the specified message to the specified folder /// </summary> /// <param name="msg">The message to move</param> /// <param name="destFolder">The folder to move the message to</param> public void MoveMessageToFolder(IMAPMessage msg, IMAPFolder destFolder) { if (_client.OfflineMode) { _client.Log(IMAPBase.LogTypeEnum.WARN, "Cannot move messages in offline mode."); return; } CopyMessageToFolder(msg, destFolder); DeleteMessage(msg); }
/// <summary> /// Copies the specified message to the specified folder /// </summary> /// <param name="msg">The message to copy</param> /// <param name="destFolder">The folder to copy the message to</param> public void CopyMessageToFolder(IMAPMessage msg, IMAPFolder destFolder) { if (_client.OfflineMode) { _client.Log(IMAPBase.LogTypeEnum.WARN, "Cannot copy messages in offline mode."); return; } string cmd = "UID COPY {0} \"{1}\"\r\n"; ArrayList result = new ArrayList(); _client._imap.SendAndReceive(String.Format(cmd, msg.Uid, destFolder.FolderPath), ref result); foreach (string s in result) { if (s.Contains("OK")) { // if the copy was successful, tell the destination folder to refresh its message UID list. destFolder.GetMessageIDs(false); int msgCount = destFolder.Messages.Count; // the copy function puts the new message at the end of the folder so lets automatically // load the data for the copy. If for some reason during the folder refresh another new message // was found and added making the copied message not the last one in the folder, thats ok // because as soon as the content is accessed the data will be loaded automatically if (msgCount > 0) destFolder.Messages[msgCount - 1].RefreshData(msg.ContentLoaded, true); _client.UpdateCache(true); _client.Log(IMAPBase.LogTypeEnum.INFO, String.Format("Message with UID {0} successfully copied to folder \"{1}\"", msg.Uid, destFolder.FolderName)); break; } } }
/// <summary> /// Default Constructor /// </summary> public IMAPSearchResult() { _query = null; _folder = null; _messages = new IMAPMessageCollection(); }
/// <summary> /// Sets the ParentFolder field for this folder /// </summary> /// <param name="parent"></param> internal void SetParent(IMAPFolder parent) { this._parentFolder = parent; foreach (IMAPFolder f in _subFolders) { f.SetParent(this); } }
/// <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("*")) continue; 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> /// Overload to take an IMAPFolder object instead of the folder name /// </summary> /// <param name="folder"></param> public void ExamineFolder(IMAPFolder folder) { if (!folder.Selectable) { Log(LogTypeEnum.WARN, String.Format("Folder {0} is not selectable", folder.FolderPath)); return; } ExamineFolder(String.Format("\"{0}\"",folder.FolderPath)); _examinedFolder = folder; _selectedFolder = null; }
/// <summary> /// Recursive helper method to count the total number of messages in all folders /// </summary> /// <param name="currentFolder"></param> /// <param name="count"></param> private void CountMessages(IMAPFolder currentFolder, ref int count) { count += currentFolder._messages.Count; foreach (IMAPFolder f in currentFolder.SubFolders) { CountMessages(f, ref count); } }
/// <summary> /// Copies all messages in this folder to the specified folder /// </summary> /// <param name="destFolder">The destination folder all the messages should be copied to</param> public void CopyAllMessagesToFolder(IMAPFolder destFolder) { if (_client.OfflineMode) { _client.Log(IMAPBase.LogTypeEnum.WARN, "Cannot copy messages in offline mode."); return; } if (!this.IsCurrentlySelected) this.Select(); string cmd = "UID COPY {0}:{1} \"{2}\"\r\n"; ArrayList result = new ArrayList(); int firstMsg = _messages[0].Uid; int lastMsg = _messages[_messages.Count-1].Uid; cmd = String.Format(cmd, firstMsg, lastMsg, destFolder.FolderPath); _client._imap.SendAndReceive(cmd, ref result); // TODO: Need to find a way to determine what the UIDs of the copies are and instead of having // to pull the same messages from the server again, just copy the IMAPMessage objects and update // the UID to the new value. This is possible if copying one message at a time, but is not as // easy when copying messages in bulk. foreach (string s in result) { if (s.Contains("OK")) { destFolder.GetMessageIDs(false); _client.UpdateCache(true); _client.Log(IMAPBase.LogTypeEnum.INFO, String.Format("All Messages from {0} successfully copied to {1}.", this.FolderName, destFolder.FolderName)); break; } } }
/// <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> /// 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"); }