예제 #1
0
        void UpdateFeedStatus(string url, string message)
        {
            int counter = 0;

            foreach (System.Xml.XmlNode outlineNode in this._Library.MyFeedsOPMLDocument.DocumentElement.SelectNodes("body/outline"))
            {
                string href = RSSLibraryClass.GetOutlineUrl(outlineNode);
                if (href == url)
                {
                    // Found it.
                    string listItem = (string)lstFeeds.Items[counter];
                    if (listItem.EndsWith(")") && listItem.Contains("("))
                    {
                        listItem = listItem.Substring(0, listItem.LastIndexOf("(")).Trim();
                    }
                    lstFeeds.Items[counter] = listItem + " (" + _I18N.GetText("Error") + ")";
                    if (counter == lstFeeds.SelectedIndex)
                    {
                        this.lblStatus.Text = message;
                    }
                    break;
                }
                counter++;
            }
            if (url == this._Library.currentFeed.Url)
            {
                MessageBox.Show(this, "Failed to load feed: " + message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
        }
예제 #2
0
        /// <summary>
        /// Parse HTML into text very stupidly.
        /// </summary>
        /// <param name="html">Some HTML mark-up</param>
        /// <returns>Plain text string</returns>
        private string TrivialParse(string html)
        {
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            Char[] htmlChars             = html.ToCharArray();
            int    parseState            = 0;// 0 = output, 1 = don't output, 2 = don't output this character but output next.

            for (int i = 0; i < htmlChars.Length; i++)
            {
                if (htmlChars[i] == '<')
                {
                    parseState = 1;
                }
                else if (htmlChars[i] == '>')
                {
                    parseState = 2;
                }
                else if (parseState == 0)
                {
                    sb.Append(htmlChars[i]);
                }
                if (parseState == 2)
                {
                    sb.Append(" ");
                    parseState = 0;
                }
            }
            string output = sb.ToString();

            while (output.Contains("  "))
            {
                output = output.Replace("  ", " ");
            }
            return(RSSLibraryClass.CleanUpXml(output.Trim()));
        }
예제 #3
0
        /// <summary>
        /// Create a new item using text obtained from an "item" element in a feed.
        /// </summary>
        /// <param name="title">The contents of the "title" element.</param>
        /// <param name="itemUrl">The contents of the "link" element.</param>
        /// <param name="feedUrl">The URL of the feed in which this item sits.</param>
        /// <param name="pubDate">The contents of the "pubDate" element.</param>
        /// <param name="contents">The contents of the "content" or "content:encoded" or "description" node, which can be HTML.</param>
        /// <param name="enclosure">The url of an enclosure - an audio or video file found if this is an item in a podcast.</param>
        public RSSItemClass(string title, string itemUrl, string feedUrl, string pubDate, string contents, string enclosure)
        {
            _title = title;
            // Do character substitutions to catch character escape sequences that have ended up in the data
            // probably because of an error on the website. I'm sure this list could be extended, but
            // quotation marks and dashes are the main offenders.
            _title   = RSSLibraryClass.CleanUpXml(_title);
            _feedUrl = feedUrl;
            _itemUrl = itemUrl.Replace("\t", "").Replace("\n", "").Trim(); // The Daily Mail feed has tabs and newlines
            // in the url, so delete and trim. 3.1.2 4 May 2014.
            DateTime dt;

            if (DateTime.TryParse(pubDate, out dt))
            {
                _pubDate = dt.ToLongDateString();
                if (_pubDate.StartsWith("0"))
                {
                    // Leading zeros look sucky.
                    _pubDate = _pubDate.Substring(1, _pubDate.Length - 1);
                }
            }
            else
            {
                _pubDate = "";
            }
            _contents  = TrivialParse(contents);
            _enclosure = enclosure;
        }
예제 #4
0
        void UpdateItemCount(string url, int count)
        {
            int counter = 0;

            foreach (System.Xml.XmlNode outlineNode in this._Library.MyFeedsOPMLDocument.DocumentElement.SelectNodes("body/outline"))
            {
                string href = RSSLibraryClass.GetOutlineUrl(outlineNode);
                if (href == url)
                {
                    // Found it.
                    string listItem = (string)lstFeeds.Items[counter];
                    if (listItem.EndsWith(")") && listItem.Contains("("))
                    {
                        listItem = listItem.Substring(0, listItem.LastIndexOf("(")).Trim();
                    }
                    lstFeeds.Items[counter] = listItem + " (" + count + ")";
                }
                counter++;
            }
        }
예제 #5
0
        private void addFeedToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string newUrl = Microsoft.VisualBasic.Interaction.InputBox(_I18N.GetText("Enter URL:"), Application.ProductName);

            if (newUrl.Length == 0)
            {
                return;
            }
            this.staMain.Text = "";
            if (!newUrl.ToLowerInvariant().StartsWith("http"))
            {
                // TODO add https?
                newUrl = "http://" + newUrl;
            }
            //The MSDN documentation says it's best to create an XmlTextReader through .Create
            //rather than = new XmlTextReader. However, if you do it through new, you get an
            //XmlTextReader that doesn't choke on malformed XML, and if you do it through
            //.Create you choke on malformed XML. So clearly new is better!
            System.Xml.XmlTextReader xtr;
            try
            {
                xtr = new System.Xml.XmlTextReader(newUrl);
            }
            catch (System.UriFormatException ufe)
            {
                // Not a valid URL. Skip trying to analyse.
                MessageBox.Show(_I18N.GetText("Invalid URL:") + " " + ufe.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            catch (Exception ex)
            {
                // Unknown error - File Not Found, possibly - display and quit.
                MessageBox.Show(ex.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            string newFeedUrl        = "";
            string rootNodeName      = "";
            bool   finishedSearching = false;
            bool   readOK            = true;

            while (!xtr.EOF && !finishedSearching && readOK)
            {
                try
                {
                    readOK = xtr.Read();
                    if (xtr.NodeType == System.Xml.XmlNodeType.Element)
                    {
                        string elementName = xtr.Name.ToLowerInvariant();
                        // If this is the first node then it is the root node.
                        // Remember the name so that we know what type of document
                        // the user has given us - Atom, RSS, or a web page to
                        // search.
                        System.Diagnostics.Debug.Print("Node:" + elementName);
                        if (rootNodeName.Length == 0)
                        {
                            rootNodeName = elementName;
                        }
                        if (rootNodeName == "html")
                        {
                            // This is an HTML file, scan it for RSS feeds.
                            if (elementName == "link")
                            {
                                // Got a link: is it valid?
                                if (xtr.HasAttributes)
                                {
                                    string href = xtr.GetAttribute("href");
                                    string rel  = xtr.GetAttribute("rel");
                                    if (rel.ToLowerInvariant() == "alternate" && href != "")
                                    {
                                        // Got it!
                                        newFeedUrl        = href;
                                        finishedSearching = true;
                                    }
                                }
                            }
                        }
                        else if (rootNodeName == "feed" || rootNodeName == "rss")
                        {
                            // It's an RSS/Atom feed, go ahead and add it
                            // without further checking, and stop reading
                            // this document.
                            newFeedUrl        = newUrl;
                            finishedSearching = true;
                        }
                    }
                }
                catch
                {
                    //Parsing error from the web page or XML = very common, carry on going
                    //until we find something useful.
                }
                System.Windows.Forms.Application.DoEvents();
            }
            xtr.Close();

            // OK, so we've examined the url the user gave us. Found anything?
            if (newFeedUrl == "")
            {
                // Failed to find anything!
                MessageBox.Show(_I18N.GetText("No RSS news feeds found"), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {
                // OK, try getting it.
                System.Xml.XmlTextReader newFeed = new System.Xml.XmlTextReader(newFeedUrl);
                string newTitle             = "";
                string newWebsiteUrl        = "";
                bool   foundTitleAndUrl     = false;
                bool   nextNodeIsTitle      = false;
                bool   nextNodeIsWebsiteUrl = false;
                readOK = true;
                while (!newFeed.EOF && !foundTitleAndUrl && readOK)
                {
                    try
                    {
                        readOK = newFeed.Read();
                        if (newFeed.NodeType == System.Xml.XmlNodeType.Element)
                        {
                            System.Diagnostics.Debug.Print("Node:" + newFeed.Name.ToLowerInvariant());
                            if (newFeed.Name.ToLowerInvariant() == "title")
                            {
                                if (newTitle == "")
                                {
                                    nextNodeIsTitle = true;
                                }
                            }
                            else if (newFeed.Name.ToLowerInvariant() == "link")
                            {
                                if (newWebsiteUrl == "")
                                {
                                    nextNodeIsWebsiteUrl = true;
                                }
                            }
                        }
                        else if (newFeed.NodeType == System.Xml.XmlNodeType.Text)
                        {
                            if (nextNodeIsTitle)
                            {
                                newTitle        = newFeed.Value;
                                nextNodeIsTitle = false;
                            }
                            if (nextNodeIsWebsiteUrl)
                            {
                                newWebsiteUrl        = newFeed.Value;
                                nextNodeIsWebsiteUrl = false;
                            }
                        }
                    }
                    catch
                    {
                        // Error in XML, very common, carry on.
                    }
                    if (newTitle.Length > 0 && newWebsiteUrl.Length > 0)
                    {
                        foundTitleAndUrl = true;
                    }
                    System.Windows.Forms.Application.DoEvents();
                }
                newFeed.Close();
                // OK, add to lists!
                if (foundTitleAndUrl)
                {
                    // Assume this is good.
                    this._Library.AddFeed(newFeedUrl, newTitle, newWebsiteUrl);
                    DisplayFeeds();
                    lblStatus.Text = _I18N.GetText("Added:") + " " + newTitle;
                    // Set focus to the new feed.
                    try
                    {
                        int i = 0;
                        foreach (System.Xml.XmlNode outline in this._Library.MyFeedsOPMLDocument.DocumentElement.SelectNodes("body/outline"))
                        {
                            string url = RSSLibraryClass.GetOutlineUrl(outline);
                            if (url == newFeedUrl)
                            {
                                lstFeeds.SelectedIndex = i;
                                break;
                            }
                            i++;
                        }
                    }
                    catch
                    {
                        // Fine, didn't set focus, carry on.
                    }

                    try
                    {
                        // Submission of RSS feed to database.
                        newTitle = System.Net.WebUtility.HtmlEncode(newTitle);
                        newUrl   = System.Net.WebUtility.HtmlEncode(newUrl);
                        System.Net.HttpWebRequest wr = (System.Net.HttpWebRequest)System.Net.WebRequest.Create("http://data.webbie.org.uk/newRSSFeed.php?title=" + newTitle + "&url=" + newFeedUrl + "&language=" + this._I18N.GetLanguage());
                        wr.KeepAlive         = false;
                        wr.Method            = System.Net.WebRequestMethods.Http.Get;
                        wr.ContentType       = "text/html";
                        wr.AllowAutoRedirect = true;
                        wr.GetResponse();
                    }
                    catch
                    {
                        // Failed to connect and write feed information: record why to error log.
                        System.Diagnostics.EventLog.WriteEntry(Application.ProductName + " " + Application.ProductVersion, "Failed to submit new feed registration to WebbIE (" + newUrl + ")");
                    }
                }
                else
                {
                    // Not found a feed.
                    staMain.Text = this._I18N.GetText("0 feeds found.");
                }
            }
        }
예제 #6
0
        private void frmMain_Load(object sender, EventArgs e)
        {
            //Check for updates. Only do this is WebbIEUpdater.dll is found. This is so that we can do a
            //build without the updater for the Windows 10 Store.
            string exeFolder = System.IO.Path.GetDirectoryName(Application.ExecutablePath);

            if (System.IO.File.Exists(exeFolder + "\\WebbIEUpdater.dll"))
            {
                CheckForUpdates();
            }

            // Normal WebbIE I18N code.
            this._I18N = new I18N();
            this._I18N.DoForm(this);

            // Load the user-subscribed list of feeds.
            this._Library = new RSSLibraryClass(Environment.CurrentDirectory, Application.UserAppDataPath);
            this._Library.ItemCountUpdated += _Library_itemCountUpdated;
            // Handle the events when the user has requested a feed.
            this._Library.LoadProgress += _Library_LoadProgress;
            this._Library.LoadFailed   += _Library_LoadFailed;
            this._Library.LoadFinished += _Library_LoadFinished;

            // Updating previous versions. Check for feeds.xml. This will be located in:
            string existingFeedFile = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\WebbIE\\AccessibleRSS\\1\\feeds.xml";

            if (System.IO.File.Exists(existingFeedFile))
            {
                // We have an existing feed file. Do we need to import it? Have we already?
                System.IO.FileInfo fi = new System.IO.FileInfo(existingFeedFile);
                if (fi.LastWriteTimeUtc > RSSNewsReader.Properties.Settings.Default.ImportedPreviousVersionFeeds)
                {
                    // Need to import.
                    System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
                    doc.Load(existingFeedFile);
                    foreach (System.Xml.XmlNode node in doc.DocumentElement.SelectNodes("feed"))
                    {
                        // I do not get the webpage url, but I've added code so when it is loaded the htmlUrl
                        // is obtained from the feed XML document.
                        this._Library.AddFeed(node.SelectSingleNode("url").InnerText, node.SelectSingleNode("title").InnerText, "");
                    }
                }
                // Ideally I'd now do the Read section, but I've changed how the settings are saved (why? bad move)
                // so it's hard so I'm not going to do it.
            }
            RSSNewsReader.Properties.Settings.Default.ImportedPreviousVersionFeeds = System.DateTime.UtcNow;

            // Open any OPML file that's provided and add it to the existing list.
            if (Environment.GetCommandLineArgs().Length > 1)
            {
                // Been passed an OPML file, presumably.
                string opmlFile = Environment.GetCommandLineArgs()[1];
                string url      = "";
                for (int i = 1; i < Environment.GetCommandLineArgs().Length; i++)
                {
                    url += Environment.GetCommandLineArgs()[i] + " ";
                }
                ImportOPML(url);
            }

            this.deletedItemsToolStripMenuItem.Checked = Properties.Settings.Default.ViewDeletedItems;

            // OK, I have a recurring bug where I end up with duplicates and unsorted feeds, so let's sort it
            // right now.
            this._Library.SortFeeds();
            this._Library.RemoveDuplicateFeeds();

            // Display the current feeds.
            DisplayFeeds();
            if (lstFeeds.Items.Count > 0 && RSSNewsReader.Properties.Settings.Default.SelectedFeedIndex < lstFeeds.Items.Count - 1)
            {
                lstFeeds.SelectedIndex = RSSNewsReader.Properties.Settings.Default.SelectedFeedIndex;
            }
            if (lstFeeds.SelectedIndex == -1 && lstFeeds.Items.Count > 0)
            {
                lstFeeds.SelectedIndex = 0;
            }

            // Add sounds to list boxes.
            ListBoxSounds.AddSounds(this);

            // Set window state
            this.WindowState = RSSNewsReader.Properties.Settings.Default.WindowState;

            // Start the library refreshing the list of read/unread items.
            this._Library.StartUpdatingFeedCacheInTheBackground();
            // Remember that we've done this.
            this._LastChecked = DateTime.Now;
        }