private bool downloadArticle() { string server = txtServer.Text; try { // Temporary connection to the server. NewsConnection connection = new NewsConnection(); connection.Connect(server); Newsgroup selectedGroup = (Newsgroup)lstGroups.SelectedItem; Article selectedArticle = (Article)lstArticleHeaders.SelectedItem; connection.GetArticle(selectedGroup, selectedArticle); article = selectedArticle.Body; connection.Disconnect(); if (!articleHistory.ContainsKey(selectedArticle)) { articleHistory.Add(selectedArticle, article); } return(true); } catch (Exception ex) { MessageBox.Show(ex.Message, "Download Article", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return(false); } }
private void downloadArticles() { NewsConnection connection = new NewsConnection(); try { connection.Connect(DEFAULT_HOST); NewsgroupCollection groups = connection.GetNewsgroups(new string[] { DEFAULT_GROUP }, null); if (groups.Count != 1) { MessageBox.Show("Could not find desired group" , "Error" , MessageBoxButtons.OK , MessageBoxIcon.Exclamation); } else { group = groups[0]; group.Articles = connection.GetArticleHeaders(group, DEFAULT_MAX_HEADERS); } } catch (Exception ex) { MessageBox.Show(ex.Message, "Download" , MessageBoxButtons.OK , MessageBoxIcon.Information); } finally { connection.Disconnect(); } }
private void updateArticleListBox(Newsgroup selectedGroup) { clearHeadersList(); if (selectedGroup != null) { listBoxArticleHeaders.DataSource = selectedGroup.Articles; } }
public static void UpdateArticleText(string server, Newsgroup newsgroup, Article article) { NewsConnection connection = new NewsConnection(); connection.Connect(server); string articleText = connection.GetArticle(newsgroup, article); article.Body = articleText; }
private void listBoxArticleHeaders_DoubleClick(object sender, EventArgs e) { Newsgroup selectedGroup = listBoxNewsgroups.SelectedItem as Newsgroup; Article selectedArticle = listBoxArticleHeaders.SelectedItem as Article; if (selectedArticle != null && selectedArticle.Body == null) { Utils.UpdateArticleText(server, selectedGroup, selectedArticle); changeArticleDisplay(selectedArticle); } }
//ugly overload, fragile, too much duplicated code :( public static void UpdateGroupArticles(string server, Newsgroup newsGroup) { if (newsGroup.Articles == null) { NewsConnection connection = new NewsConnection(); connection.Connect(server); ArticleCollection articles = connection.GetArticleHeaders(newsGroup); connection.Disconnect(); newsGroup.Articles = articles; } }
/// <summary> /// Creates a personal catalog /// </summary> /// <param name="identity">The identity of the user making the request</param> /// <param name="catalogName">The name of the personal catalog</param> /// <returns>A value indicating whether the operation was successful</returns> public bool CreatePersonalCatalog(IIdentity identity, string catalogName) { if (string.Compare(catalogName, "INBOX", StringComparison.OrdinalIgnoreCase) == 0) { return(false); } try { using (var session = SessionUtility.OpenSession()) { var owner = session.Query <User>().SingleOrDefault(u => u.Username == identity.Username); if (owner == null) { return(false); } var catalog = session.Query <Newsgroup>().SingleOrDefault(ng => ng.Name == catalogName && ng.Owner.Id == owner.Id); if (catalog != null) { return(false); } catalog = new Newsgroup { CreateDate = DateTime.UtcNow, CreatorEntity = identity.Username, DenyLocalPosting = false, DenyPeerPosting = true, Description = "Personal inbox for " + identity.Username, Moderated = false, Name = catalogName, Owner = owner }; session.Save(catalog); session.Close(); } } catch (MappingException mex) { _Logger.Error("NHibernate Mapping Exception! (Is schema out of date or damaged?)", mex); return(false); } catch (Exception ex) { _Logger.Error("Exception when trying to handle LIST", ex); return(false); } return(true); }
private void lstGroups_SelectedIndexChanged(object sender, EventArgs e) { clearArticleHeaderList(); if (lstGroups.SelectedItem != null) { Newsgroup selectedGroup = (Newsgroup)lstGroups.SelectedItem; if (groupHistory.ContainsKey(selectedGroup)) { lstArticleHeaders.DataSource = groupHistory[selectedGroup]; } } }
private void lstGroups_MouseDoubleClick(object sender, MouseEventArgs e) { Newsgroup selectedGroup = (Newsgroup)lstGroups.SelectedItem; if (!groupHistory.ContainsKey(selectedGroup)) { this.Cursor = Cursors.WaitCursor; clearArticleHeaderList(); downloadArticleHeaders(); populateArticleHeaders(); this.Cursor = Cursors.Default; } }
private void listBoxNewsgroups_DoubleClick(object sender, EventArgs e) { Newsgroup selectedGroup = listBoxNewsgroups.SelectedItem as Newsgroup; if (selectedGroup != null) { selectedGroupIndex = newsGroups.IndexOf(selectedGroup); int maxHeaders = 0; if (Int32.TryParse(textBoxNumArticles.Text, out maxHeaders)) { Utils.UpdateGroupArticles(server, selectedGroup, maxHeaders); } else { Utils.UpdateGroupArticles(server, selectedGroup); } updateArticleListBox(selectedGroup); } }
private bool downloadArticleHeaders() { string server = txtServer.Text; try { // Temporary connection to the server. NewsConnection connection = new NewsConnection(); connection.Connect(server); Newsgroup selectedGroup = (Newsgroup)lstGroups.SelectedItem; if (chkFilterArticles.Checked) { int articleLimit; int.TryParse(txtGetNumber.Text, out articleLimit); articleHeaders = connection.GetArticleHeaders(selectedGroup, articleLimit); } else { articleHeaders = connection.GetArticleHeaders(selectedGroup); } connection.Disconnect(); if (!groupHistory.ContainsKey(selectedGroup)) { groupHistory.Add(selectedGroup, articleHeaders); } return(true); } catch (Exception ex) { MessageBox.Show(ex.Message, "Download Newsgroups", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return(false); } }
/// <summary> /// Ensures a user has any requisite initialization in the store performed prior to their execution of other store methods /// </summary> /// <param name="identity">The identity of the user to ensure is initialized properly in the store</param> public void Ensure(IIdentity identity) { var personalCatalogs = this.GetPersonalCatalogs(identity, null); if (personalCatalogs != null && personalCatalogs.All(c => c.Name != "INBOX")) { using (var session = SessionUtility.OpenSession()) { var ng = new Newsgroup { CreateDate = DateTime.UtcNow, Description = "Personal inbox for " + identity.Username, Name = "INBOX", Owner = (User)identity }; session.Save(ng); session.Flush(); session.Close(); } } }
public void IntervalElapsed(object sender, ElapsedEventArgs e) { if (lockInterval) { return; } lockInterval = true; try { nntp.ConnectServer(NntpSettings.Default.NntpServer, NntpSettings.Default.NntpPort); var newMessages = new SortedDictionary <DateTime, KeyValuePair <Article, string> >(); foreach (Newsgroup ng in nntp.GetGroupList()) { if (!nntpCache.ContainsKey(ng.Group)) { nntpCache.Add(ng.Group, new Dictionary <string, Article>()); } ArrayList list; Newsgroup cng = nntp.ConnectGroup(ng.Group); try { list = nntp.GetArticleList(cng.Low, cng.High); } catch (Exception) { list = new ArrayList(); } // var r = new Random(); Newsgroup newsgroup = ng; foreach (var a in from Article a in list where !nntpCache[newsgroup.Group].ContainsKey(a.MessageId) select a) { // new message nntpCache[ng.Group].Add(a.MessageId, a); if (!newMessages.ContainsKey(a.Header.Date)) { newMessages.Add(a.Header.Date, new KeyValuePair <Article, string>(a, ng.Group)); } } } if (firstTime) { var t = new TimeSpan(0); foreach (var kvp in newMessages) { t = (DateTime.Now - kvp.Key); } foreach (var channel in NntpSettings.Default.NntpChannels.Split(',')) { BotMethods.SendMessage(SendType.Message, channel, "New FMS Posts will be reported: There are " + newMessages.Count + " Messages in the repository"); BotMethods.SendMessage(SendType.Message, channel, "Last Post on FMS was " + Math.Round(t.TotalMinutes) + " minutes ago."); } nntp.Disconnect(); firstTime = false; lockInterval = false; return; } foreach (var m in newMessages) { foreach (var channel in NntpSettings.Default.NntpChannels.Split(',')) { var t = (DateTime.Now - m.Value.Key.Header.Date); if (t >= new TimeSpan(4, 0, 0)) { continue; } if (WordFilter(m.Value.Key)) { BotMethods.SendMessage(SendType.Message, channel, "New Post on FMS: " + IrcConstants.IrcBold + "*** Word Filtered ***" + IrcConstants.IrcBold + " by " + m.Value.Key.Header.From.Split(new[] { '@' })[0] + " in Board " + m.Value.Value + " (" + Math.Round(t.TotalMinutes) + " minutes ago)"); } else if (GroupFilter(m.Value.Value)) { BotMethods.SendMessage(SendType.Message, channel, "New Post on FMS: " + IrcConstants.IrcBold + "*** Group Filtered ***" + IrcConstants.IrcBold + " by " + m.Value.Key.Header.From.Split(new[] { '@' })[0] + " in Board " + m.Value.Value + " (" + Math.Round(t.TotalMinutes) + " minutes ago)"); } else { BotMethods.SendMessage(SendType.Message, channel, "New Post on FMS: " + IrcConstants.IrcBold + m.Value.Key.Header.Subject + IrcConstants.IrcBold + " by " + m.Value.Key.Header.From.Split(new[] { '@' })[0] + " in Board " + m.Value.Value + " (" + Math.Round(t.TotalMinutes) + " minutes ago)"); } } } } catch (Exception exception) { Log.Instance.Log(exception); } finally { lockInterval = false; nntp.Disconnect(); } }
/// <summary> /// Downloads the body text of the given article, storing it into the Body property of article. /// </summary> /// <param name="group">Newsgroup to which article belongs.</param> /// <param name="article">Article for which to download body text.</param> /// <returns>True if successful and the body text is not empty.</returns> public bool GetArticle(Newsgroup group, Article article) { string message; string response; StringBuilder articleStringBuilder = new StringBuilder(); // Gotta get the group before getting an article (the server is stateful // and this sets the group). message = "GROUP " + group.Name + "\r\n"; Write(message); response = Response(); if (response.Substring(0, 3) != "211") { throw new NntpException(response); } message = "ARTICLE " + article.SequenceNumber + "\r\n"; Write(message); response = Response(); if (response.Substring(0, 3) == "423") { // 423 - No such article number in this group. return false; } // 220 means Article retrieved, head and body follow if (response.Substring(0, 3) != "220") { throw new NntpException(response); } // Read past the head. response = Response(); while (response != "\r\n" && response != "\n") { response = Response(); } // Read the body. response = Response(); while (response != ".\r\n" && response != ".\n") { articleStringBuilder.Append(response); response = Response(); } article.Body = articleStringBuilder.ToString(); return article.Body != null && article.Body.Length > 0; }
private void listBoxNewsgroups_SelectedIndexChanged(object sender, EventArgs e) { Newsgroup selectedGroup = listBoxNewsgroups.SelectedItem as Newsgroup; updateArticleListBox(selectedGroup); }
/// <summary> /// Downloads all article headers for the given group. Currently, only some of the header fields are /// downloaded: id, from, date, subject, lines. The body is not downloaded. Use GetArticle to download /// an article's body text. /// </summary> /// <param name="group">Newsgroup whose article headers will be downloaded.</param> /// <returns>A collection of Article objects contained in the given newsgroup. The articles' body /// text is not downloaded. Use GetArticle to download an article's body text.</returns> public ArticleCollection GetArticleHeaders(Newsgroup group) { return GetArticleHeaders(group, -1); }
/// <summary> /// If includeList is not null then this method downloads the newsgroups /// that have any of the words in includeList in any part of the newsgroup name. If excludeList /// is not null then this method downloads the newsgroups that do not have any of the words in /// the excludeList in any part of the newsgroup name. If both parameters are null then all newsgroups /// are downloaded; if both are not null then an assertion is raised. /// </summary> /// <param name="includeList">A collection of strings to search for in the newsgroup names. If any /// of the words are in any part of the newsgroup name then that newsgroup is downloaded. This value /// must be null if excludeList is not null.</param> /// <param name="excludeList">A collection of strings to search for in the newsgroup names. If any /// of the words are in any part of the newsgroup name then that newsgroup is not downloaded. This /// value must be null if includeList is not null.</param> /// <returns>A collection of Newsgroup objects that match the filter criteria given by includeList /// or by excludeList. Each object's Articles property will be null. Use GetArticleHeaders to populate /// these objects with Article objects.</returns> public NewsgroupCollection GetNewsgroups(IList<string> includeList, IList<string> excludeList) { string message; string response; NewsgroupCollection groups = new NewsgroupCollection(); message = "LIST\r\n"; Write(message); response = Response(); if (response.Substring(0, 3) != "215") { throw new NntpException(response); } // Suck next line of data from the socket. response = Response(); while (response != ".\r\n" && response != ".\n") { // The response line should take the format: // group last first p // // groupName - name of the group // last - sequence number of the last message // first - sequence number of the first message // p - boolean value equal to y or n indicating whether or not posting is allowed // (note: this is independent of whether the particular news server allows // posting; some groups are moderated and therefore can only have posting by // the moderator). string[] values = response.Split(' '); // I don't think this would happen, but... if (values.Length != 4) { throw new NntpException("LIST command returned unexpected results."); } string groupName = values[0]; int last = int.Parse(values[1]); int first = int.Parse(values[2]); bool postingAllowed = values[3].Trim().ToLower() == "y"; Newsgroup newGroup; if (includeList != null) { // An include list has been supplied. Add this group only if the group name // contains one of the include list strings. foreach (string includeString in includeList) { if (groupName.Contains(includeString)) { newGroup = new Newsgroup(groupName, postingAllowed, first, last); groups.Add(newGroup); break; } } } else if (excludeList != null) { // An exclude list has been supplied. Add this group only if the group name // contains *none* of the include list strings. bool contains = false; foreach (string excludeString in excludeList) { if (groupName.Contains(excludeString)) { contains = true; break; } } if (!contains) { newGroup = new Newsgroup(groupName, postingAllowed, first, last); groups.Add(newGroup); } } else { // Neither include nor exclude list has been supplied. Add this group. newGroup = new Newsgroup(groupName, postingAllowed, first, last); groups.Add(newGroup); } // Pump the loop. response = Response(); } return groups; }
/// <summary> /// Downloads up to maxHeaders article headers from the given group. The latest ones are chosen. /// Currently, only some of the header fields are downloaded: id, from, date, subject, lines. /// The body is not downloaded. Use GetArticle to download an article's body text. /// </summary> /// <param name="group">Newsgroup whose articles headers will be downloaded.</param> /// <param name="maxHeaders">Maximum number of article headers to download. The latest ones are chosen.</param> /// <returns>A collection of Article objects contained in the given newsgroup. The articles' body /// text is not downloaded. Use GetArticle to download an article's body text.</returns> public ArticleCollection GetArticleHeaders(Newsgroup group, int maxHeaders) { string message; string response; ArticleCollection articles = null; // Get the article numbers of the first and last articles in the group, and an // estimate of the number of articles on file in the group. try { message = "GROUP " + group.Name + "\r\n"; Write(message); response = Response(); if (response.Substring(0, 3) != "211") { throw new NntpException(response); } char[] seps = { ' ' }; string[] values = response.Split(seps); int start = Int32.Parse(values[2]); int end = Int32.Parse(values[3]); int estimatedArticleCount = end - start; if (estimatedArticleCount < 0) estimatedArticleCount = 100; // Was a maximum specified? if (maxHeaders != -1 && start + maxHeaders < end) { start = end - maxHeaders; } articles = new ArticleCollection(estimatedArticleCount); // Create a collection of Article objects, storing just the heading information // into them. DateTime date; string from, subject, id; int numLines; bool allFieldsObtained; int sequenceNum; for (sequenceNum = start; sequenceNum < end; ++sequenceNum) { message = "HEAD " + sequenceNum + "\r\n"; Write(message); response = Response(); if (response.Substring(0, 3) == "423") { // 423 - No such article number in this group. continue; } // 221 means article retrieved, head follows. if (response.Substring(0, 3) != "221") { throw new NntpException(response); } date = DateTime.MinValue; from = subject = id = ""; numLines = -1; allFieldsObtained = false; response = Response(); while (response != ".\r\n" && response != ".\n" && !allFieldsObtained) { // Find the delimiter--usually a colon but seems to be equals sign sometimes. // If neither is found then move on. int delimiterIdx; delimiterIdx = response.IndexOf(':'); if (delimiterIdx == -1) delimiterIdx = response.IndexOf('='); if (delimiterIdx == -1) { response = Response(); continue; } string headerFieldName = response.Substring(0, delimiterIdx).ToLower(); string headerFieldValue = response.Substring(delimiterIdx + 2); headerFieldValue = headerFieldValue.Replace("\r\n", ""); switch (headerFieldName) { case "message-id": id = headerFieldValue; break; case "from": from = headerFieldValue; break; case "date": DateTime.TryParse(headerFieldValue, out date); break; case "subject": subject = headerFieldValue; break; case "lines": int.TryParse(headerFieldValue, out numLines); break; default: break; } allFieldsObtained = (id != "" && from != "" && date != DateTime.MinValue && subject != "" && numLines != -1); if (allFieldsObtained) { // Finish getting rest of header but don't go through the switch. response = Response(); while (response != ".\r\n" && response != ".\n") { response = Response(); } } else { response = Response(); } } Article newArticle; newArticle = new Article(id, sequenceNum, from, date, subject, numLines); articles.Add(newArticle); } } catch { // Ideally, I want to let this exception raise to the UI but we don't covered // exception handling until later, so just swallow it for now. } return articles; }