Example #1
0
        private void writeItem(RssItem item, int channelHashCode)
        {
            if (writer == null)
                throw new InvalidOperationException("RssWriter has been closed, and can not be written to.");
            if (item == null)
                throw new ArgumentNullException("Item must be instanciated with data to be written.");
            if (!wroteChannel)
                throw new InvalidOperationException("Channel must be written first, before writing an item.");

            BeginDocument();

            writer.WriteStartElement("item");
            switch (rssVersion)
            {
                case RssVersion.RSS090:
                case RssVersion.RSS10:
                case RssVersion.RSS091:
                    WriteElement("title", item.Title, true);
                    WriteElement("description", item.Description, false);
                    WriteElement("link", item.Link, true);
                    break;
                case RssVersion.RSS20:
                    if ((item.Title == RssDefault.String) && (item.Description == RssDefault.String))
                        throw new ArgumentException("item title and description cannot be null");
                    goto case RssVersion.RSS092;
                case RssVersion.RSS092:
                    WriteElement("title", item.Title, false);
                    WriteElement("description", item.Description, false);
                    WriteElement("link", item.Link, false);
                    if (item.Source != null)
                    {
                        writer.WriteStartElement("source");
                        WriteAttribute("url", item.Source.Url, true);
                        writer.WriteString(item.Source.Name);
                        writer.WriteEndElement();
                    }
                    if (item.Enclosure != null)
                    {
                        writer.WriteStartElement("enclosure");
                        WriteAttribute("url", item.Enclosure.Url, true);
                        WriteAttribute("length", item.Enclosure.Length, true);
                        WriteAttribute("type", item.Enclosure.Type, true);
                        writer.WriteEndElement();
                    }
                    foreach(RssCategory category in item.Categories)
                        if (category.Name != RssDefault.String)
                        {
                            writer.WriteStartElement("category");
                            WriteAttribute("domain", category.Domain, false);
                            writer.WriteString(category.Name);
                            writer.WriteEndElement();
                        }
                    break;
            }
            if (rssVersion == RssVersion.RSS20)
            {
                WriteElement("author", item.Author, false);
                WriteElement("comments", item.Comments, false);
                if ((item.Guid != null) && (item.Guid.Name != RssDefault.String))
                {
                    writer.WriteStartElement("guid");
                    try {
                    WriteAttribute("isPermaLink", (bool)item.Guid.PermaLink, false);
                    } catch {}
                    writer.WriteString(item.Guid.Name);
                    writer.WriteEndElement();
                }
                WriteElement("pubDate", item.PubDate, false);

                foreach(RssModule rssModule in this._rssModules)
                {
                    if(rssModule.IsBoundTo(channelHashCode))
                    {
                        foreach(RssModuleItemCollection rssModuleItemCollection in rssModule.ItemExtensions)
                        {
                            if(rssModuleItemCollection.IsBoundTo(item.GetHashCode()))
                                writeSubElements(rssModuleItemCollection, rssModule.NamespacePrefix);
                        }
                    }
                }
            }
            writer.WriteEndElement();
            writer.Flush();
        }
        /// <summary>
        /// Inteligent resolution of latest build by real "release date", not only by the date used to publish the feed.
        /// This filters the updates on release page after the release was published.
        /// Obtains the real date from the title.
        /// </summary>
        private static bool IsNewerThanCurrent(RssItem item, DateTime buildDate)
        {
            // rss item published date
            if (item.PubDate < buildDate)
                return false;

            const string DATE_FILTER = @"([^\(]+)\((?<Date>[^\(\)]+)\)"; // Select string iside brackets as "Date" group
            string titleDate = Regex.Match(item.Title, DATE_FILTER).Groups["Date"].Value;
            DateTime releaseDate;
            // there is no culture specification when downloading the feed, so it is always EN
            DateTime.TryParse(titleDate, out releaseDate);
            return releaseDate > buildDate;
        }
Example #3
0
        /// <summary>Reads the next RssElement from the stream.</summary>
        /// <returns>An RSS Element</returns>
        /// <exception cref="InvalidOperationException">RssReader has been closed, and can not be read.</exception>
        /// <exception cref="System.IO.FileNotFoundException">RSS file not found.</exception>
        /// <exception cref="System.Xml.XmlException">Invalid XML syntax in RSS file.</exception>
        /// <exception cref="System.IO.EndOfStreamException">Unable to read an RssElement. Reached the end of the stream.</exception>
        public RssElement Read()
        {
            bool readData = false;
            bool pushElement = true;
            RssElement rssElement = null;
            int lineNumber = -1;
            int linePosition = -1;

            if (reader == null)
                throw new InvalidOperationException("RssReader has been closed, and can not be read.");

            do
            {
                pushElement = true;
                try
                {
                    readData = reader.Read();
                }
                catch (System.IO.EndOfStreamException e)
                {
                    throw new System.IO.EndOfStreamException("Unable to read an RssElement. Reached the end of the stream.", e);
                }
                catch (System.Xml.XmlException e)
                {
                    if (lineNumber != -1 || linePosition != -1)
                        if (reader.LineNumber == lineNumber && reader.LinePosition == linePosition)
                            throw exceptions.LastException;

                    lineNumber = reader.LineNumber;
                    linePosition = reader.LinePosition;

                    exceptions.Add(e); // just add to list of exceptions and continue :)
                }
                if (readData)
                {
                    string readerName = reader.Name.ToLower();
                    switch (reader.NodeType)
                    {
                        case XmlNodeType.Element:
                        {
                            //if (reader.IsEmptyElement)
                            //	break;
                            // doesnt take empty elements into account :/
                            elementText = new StringBuilder();
                            switch (readerName)
                            {
                                case "item":
                                    // is this the end of the channel element? (absence of </channel> before <item>)
                                    if (!wroteChannel)
                                    {
                                        wroteChannel = true;
                                        rssElement = channel; // return RssChannel
                                        readData = false;
                                    }
                                    item = new RssItem(); // create new RssItem
                                    channel.Items.Add(item);
                                    break;
                                case "source":
                                    source = new RssSource();
                                    item.Source = source;
                                    for (int i=0; i < reader.AttributeCount; i++)
                                    {
                                        reader.MoveToAttribute(i);
                                        switch (reader.Name.ToLower())
                                        {
                                            case "url":
                                                try
                                                {
                                                    source.Url = new Uri(reader.Value);
                                                }
                                                catch (Exception e)
                                                {
                                                    exceptions.Add(e);
                                                }
                                                break;
                                        }
                                    }
                                    break;
                                case "enclosure":
                                    enclosure = new RssEnclosure();
                                    item.Enclosure = enclosure;
                                    for (int i=0; i < reader.AttributeCount; i++)
                                    {
                                        reader.MoveToAttribute(i);
                                        switch (reader.Name.ToLower())
                                        {
                                            case "url":
                                                try
                                                {
                                                    enclosure.Url = new Uri(reader.Value);
                                                }
                                                catch (Exception e)
                                                {
                                                    exceptions.Add(e);
                                                }
                                                break;
                                            case "length":
                                                try
                                                {
                                                    enclosure.Length = int.Parse(reader.Value);
                                                }
                                                catch (Exception e)
                                                {
                                                    exceptions.Add(e);
                                                }
                                                break;
                                            case "type":
                                                enclosure.Type = reader.Value;
                                                break;
                                        }
                                    }
                                    break;
                                case "guid":
                                    guid = new RssGuid();
                                    item.Guid = guid;
                                    for (int i=0; i < reader.AttributeCount; i++)
                                    {
                                        reader.MoveToAttribute(i);
                                        switch (reader.Name.ToLower())
                                        {
                                            case "ispermalink":
                                                try
                                                {
                                                    guid.PermaLink = bool.Parse(reader.Value);
                                                }
                                                catch (Exception e)
                                                {
                                                    exceptions.Add(e);
                                                }
                                                break;
                                        }
                                    }
                                    break;
                                case "category":
                                    category = new RssCategory();
                                    if ((string)xmlNodeStack.Peek() == "channel")
                                        channel.Categories.Add(category);
                                    else
                                        item.Categories.Add(category);
                                    for (int i=0; i < reader.AttributeCount; i++)
                                    {
                                        reader.MoveToAttribute(i);
                                        switch (reader.Name.ToLower())
                                        {
                                            case "url":
                                                goto case "domain";
                                            case "domain":
                                                category.Domain = reader.Value;
                                                break;
                                        }
                                    }
                                    break;
                                case "channel":
                                    channel = new RssChannel();
                                    textInput = null;
                                    image = null;
                                    cloud = null;
                                    source = null;
                                    enclosure = null;
                                    category = null;
                                    item = null;
                                    break;
                                case "image":
                                    image = new RssImage();
                                    channel.Image = image;
                                    break;
                                case "textinput":
                                    textInput = new RssTextInput();
                                    channel.TextInput = textInput;
                                    break;
                                case "cloud":
                                    pushElement = false;
                                    cloud = new RssCloud();
                                    channel.Cloud = cloud;
                                    for (int i=0; i < reader.AttributeCount; i++)
                                    {
                                        reader.MoveToAttribute(i);
                                        switch (reader.Name.ToLower())
                                        {
                                            case "domain":
                                                cloud.Domain = reader.Value;
                                                break;
                                            case "port":
                                                try
                                                {
                                                    cloud.Port = ushort.Parse(reader.Value);
                                                }
                                                catch (Exception e)
                                                {
                                                    exceptions.Add(e);
                                                }
                                                break;
                                            case "path":
                                                cloud.Path = reader.Value;
                                                break;
                                            case "registerprocedure":
                                                cloud.RegisterProcedure = reader.Value;
                                                break;
                                            case "protocol":
                                            switch (reader.Value.ToLower())
                                            {
                                                case "xml-rpc":
                                                    cloud.Protocol = RssCloudProtocol.XmlRpc;
                                                    break;
                                                case "soap":
                                                    cloud.Protocol = RssCloudProtocol.Soap;
                                                    break;
                                                case "http-post":
                                                    cloud.Protocol = RssCloudProtocol.HttpPost;
                                                    break;
                                                default:
                                                    cloud.Protocol = RssCloudProtocol.Empty;
                                                    break;
                                            }
                                                break;
                                        }
                                    }
                                    break;
                                case "rss":
                                    for (int i=0; i < reader.AttributeCount; i++)
                                    {
                                        reader.MoveToAttribute(i);
                                        if (reader.Name.ToLower() == "version")
                                            switch (reader.Value)
                                            {
                                                case "0.91":
                                                    rssVersion = RssVersion.RSS091;
                                                    break;
                                                case "0.92":
                                                    rssVersion = RssVersion.RSS092;
                                                    break;
                                                case "2.0":
                                                    rssVersion = RssVersion.RSS20;
                                                    break;
                                                default:
                                                    rssVersion = RssVersion.NotSupported;
                                                    break;
                                            }
                                    }
                                    break;
                                case "rdf":
                                    for (int i=0; i < reader.AttributeCount; i++)
                                    {
                                        reader.MoveToAttribute(i);
                                        if (reader.Name.ToLower() == "version")
                                            switch (reader.Value)
                                            {
                                                case "0.90":
                                                    rssVersion = RssVersion.RSS090;
                                                    break;
                                                case "1.0":
                                                    rssVersion = RssVersion.RSS10;
                                                    break;
                                                default:
                                                    rssVersion = RssVersion.NotSupported;
                                                    break;
                                            }
                                    }
                                    break;

                            }
                            if (pushElement)
                                xmlNodeStack.Push(readerName);
                            break;
                        }
                        case XmlNodeType.EndElement:
                        {
                            if (xmlNodeStack.Count == 1)
                                break;
                            string childElementName = (string)xmlNodeStack.Pop();
                            string parentElementName = (string)xmlNodeStack.Peek();
                            switch (childElementName) // current element
                            {
                                    // item classes
                                case "item":
                                    rssElement = item;
                                    readData = false;
                                    break;
                                case "source":
                                    source.Name = elementText.ToString();
                                    rssElement = source;
                                    readData = false;
                                    break;
                                case "enclosure":
                                    rssElement = enclosure;
                                    readData = false;
                                    break;
                                case "guid":
                                    guid.Name = elementText.ToString();
                                    rssElement = guid;
                                    readData = false;
                                    break;
                                case "category": // parent is either item or channel
                                    category.Name = elementText.ToString();
                                    rssElement = category;
                                    readData = false;
                                    break;
                                    // channel classes
                                case "channel":
                                    if (wroteChannel)
                                        wroteChannel = false;
                                    else
                                    {
                                        wroteChannel = true;
                                        rssElement = channel;
                                        readData = false;
                                    }
                                    break;
                                case "textinput":
                                    rssElement = textInput;
                                    readData = false;
                                    break;
                                case "image":
                                    rssElement = image;
                                    readData = false;
                                    break;
                                case "cloud":
                                    rssElement = cloud;
                                    readData = false;
                                    break;
                            }
                            switch (parentElementName) // parent element
                            {
                                case "item":
                                switch (childElementName)
                                {
                                    case "title":
                                        item.Title = elementText.ToString();
                                        break;
                                    case "link":
                                        item.Link = new Uri(elementText.ToString());
                                        break;
                                    case "description":
                                        item.Description = elementText.ToString();
                                        break;
                                    case "author":
                                        item.Author = elementText.ToString();
                                        break;
                                    case "comments":
                                        item.Comments = elementText.ToString();
                                        break;
                                    case "pubdate":
                                        try
                                        {
                                            item.PubDate = DateTime.Parse(elementText.ToString());
                                        }
                                        catch (Exception e)
                                        {
                                            try {
                                            string tmp = elementText.ToString ();
                                            tmp = tmp.Substring (0, tmp.Length - 5);
                                            tmp += "GMT";
                                            item.PubDate = DateTime.Parse (tmp);
                                            }
                                            catch
                                            {
                                            exceptions.Add(e);
                                            }
                                        }
                                        break;
                                }
                                    break;
                                case "channel":
                                switch (childElementName)
                                {
                                    case "title":
                                        channel.Title = elementText.ToString();
                                        break;
                                    case "link":
                                        try
                                        {
                                            channel.Link = new Uri(elementText.ToString());
                                        }
                                        catch (Exception e)
                                        {
                                            exceptions.Add(e);
                                        }
                                        break;
                                    case "description":
                                        channel.Description = elementText.ToString();
                                        break;
                                    case "language":
                                        channel.Language = elementText.ToString();
                                        break;
                                    case "copyright":
                                        channel.Copyright = elementText.ToString();
                                        break;
                                    case "managingeditor":
                                        channel.ManagingEditor = elementText.ToString();
                                        break;
                                    case "webmaster":
                                        channel.WebMaster = elementText.ToString();
                                        break;
                                    case "rating":
                                        channel.Rating = elementText.ToString();
                                        break;
                                    case "pubdate":
                                        try
                                        {
                                            channel.PubDate = DateTime.Parse(elementText.ToString());
                                        }
                                        catch (Exception e)
                                        {
                                            exceptions.Add(e);
                                        }
                                        break;
                                    case "lastbuilddate":
                                        try
                                        {
                                            channel.LastBuildDate = DateTime.Parse(elementText.ToString());
                                        }
                                        catch (Exception e)
                                        {
                                            exceptions.Add(e);
                                        }
                                        break;
                                    case "generator":
                                        channel.Generator = elementText.ToString();
                                        break;
                                    case "docs":
                                        channel.Docs = elementText.ToString();
                                        break;
                                    case "ttl":
                                        try
                                        {
                                            channel.TimeToLive = int.Parse(elementText.ToString());
                                        }
                                        catch (Exception e)
                                        {
                                            exceptions.Add(e);
                                        }
                                        break;
                                }
                                    break;
                                case "image":
                                switch (childElementName)
                                {
                                    case "url":
                                        try
                                        {
                                            image.Url = new Uri(elementText.ToString());
                                        }
                                        catch (Exception e)
                                        {
                                            exceptions.Add(e);
                                        }
                                        break;
                                    case "title":
                                        image.Title = elementText.ToString();
                                        break;
                                    case "link":
                                        try
                                        {
                                            image.Link = new Uri(elementText.ToString());
                                        }
                                        catch (Exception e)
                                        {
                                            exceptions.Add(e);
                                        }
                                        break;
                                    case "description":
                                        image.Description = elementText.ToString();
                                        break;
                                    case "width":
                                        try
                                        {
                                            image.Width = Byte.Parse(elementText.ToString());
                                        }
                                        catch (Exception e)
                                        {
                                            exceptions.Add(e);
                                        }
                                        break;
                                    case "height":
                                        try
                                        {
                                            image.Height = Byte.Parse(elementText.ToString());
                                        }
                                        catch (Exception e)
                                        {
                                            exceptions.Add(e);
                                        }
                                        break;
                                }
                                    break;
                                case "textinput":
                                switch (childElementName)
                                {
                                    case "title":
                                        textInput.Title = elementText.ToString();
                                        break;
                                    case "description":
                                        textInput.Description = elementText.ToString();
                                        break;
                                    case "name":
                                        textInput.Name = elementText.ToString();
                                        break;
                                    case "link":
                                        try
                                        {
                                            textInput.Link = new Uri(elementText.ToString());
                                        }
                                        catch (Exception e)
                                        {
                                            exceptions.Add(e);
                                        }
                                        break;
                                }
                                    break;
                                case "skipdays":
                                    if (childElementName == "day")
                                        switch (elementText.ToString().ToLower())
                                        {
                                            case "monday":
                                                channel.SkipDays[0] = true;
                                                break;
                                            case "tuesday":
                                                channel.SkipDays[1] = true;
                                                break;
                                            case "wednesday":
                                                channel.SkipDays[2] = true;
                                                break;
                                            case "thursday":
                                                channel.SkipDays[3] = true;
                                                break;
                                            case "friday":
                                                channel.SkipDays[4] = true;
                                                break;
                                            case "saturday":
                                                channel.SkipDays[5] = true;
                                                break;
                                            case "sunday":
                                                channel.SkipDays[6] = true;
                                                break;
                                        }
                                    break;
                                case "skiphours":
                                    if (childElementName == "hour")
                                        channel.SkipHours[Byte.Parse(elementText.ToString().ToLower())] = true;
                                    break;
                            }
                            break;
                        }
                        case XmlNodeType.Text:
                            elementText.Append(reader.Value);
                            break;
                        case XmlNodeType.CDATA:
                            elementText.Append(reader.Value);
                            break;
                    }
                }
            }
            while (readData);
            return rssElement;
        }
Example #4
0
 /// <summary>Writes an RSS item</summary>
 /// <exception cref="InvalidOperationException">Either the RssWriter has already been closed, or the caller is attempting to write an RSS item before an RSS channel.</exception>
 /// <exception cref="ArgumentNullException">Item must be instanciated with data, before calling Write.</exception>
 /// <param name="item">RSS item to write</param>
 public void Write(RssItem item)
 {
     // NOTE: Standalone items cannot adhere to modules, hence -1 is passed. This may not be the case, however, no examples have been seen where this is legal.
     writeItem(item, -1);
 }
 /// <summary>Copies the entire RssItemCollection to a compatible one-dimensional <see cref="Array"/>, starting at the specified index of the target array.</summary>
 /// <param name="array">The one-dimensional RssItem Array that is the destination of the elements copied from RssItemCollection. The Array must have zero-based indexing.</param>
 /// <param name="index">The zero-based index in array at which copying begins.</param>
 /// <exception cref="ArgumentNullException">array is a null reference (Nothing in Visual Basic).</exception>
 /// <exception cref="ArgumentOutOfRangeException">index is less than zero.</exception>
 /// <exception cref="ArgumentException">array is multidimensional. -or- index is equal to or greater than the length of array.-or-The number of elements in the source RssItemCollection is greater than the available space from index to the end of the destination array.</exception>
 public void CopyTo(RssItem[] array, int index)
 {
     List.CopyTo(array, index);
 }
Example #6
0
 /// <summary>Closes connection to file.</summary>
 /// <remarks>This method also releases any resources held while reading.</remarks>
 public void Close()
 {
     textInput = null;
     image = null;
     cloud = null;
     channel = null;
     source = null;
     enclosure = null;
     category = null;
     item = null;
     if (reader!=null)
     {
         reader.Close();
         reader = null;
     }
     elementText = null;
     xmlNodeStack = null;
 }
 /// <summary>Determines whether the RssItemCollection contains a specific element.</summary>
 /// <param name="rssItem">The RssItem to locate in the RssItemCollection.</param>
 /// <returns>true if the RssItemCollection contains the specified value; otherwise, false.</returns>
 public bool Contains(RssItem rssItem)
 {
     return List.Contains(rssItem);
 }
 /// <summary>Adds a specified item to this collection.</summary>
 /// <param name="item">The item to add.</param>
 /// <returns>The zero-based index of the added item.</returns>
 public int Add(RssItem item)
 {
     pubDateChanged = true;
     return List.Add(item);
 }
 /// <summary>Removes a specified item from this collection.</summary>
 /// <param name="item">The item to remove.</param>
 public void Remove(RssItem item)
 {
     pubDateChanged = true;
     List.Remove(item);
 }
 /// <summary>Inserts an item into this collection at a specified index.</summary>
 /// <param name="index">The zero-based index of the collection at which to insert the item.</param>
 /// <param name="item">The item to insert into this collection.</param>
 public void Insert(int index, RssItem item)
 {
     pubDateChanged = true;
     List.Insert(index, item);
 }
 /// <summary>Searches for the specified RssItem and returns the zero-based index of the first occurrence within the entire RssItemCollection.</summary>
 /// <param name="rssItem">The RssItem to locate in the RssItemCollection.</param>
 /// <returns>The zero-based index of the first occurrence of RssItem within the entire RssItemCollection, if found; otherwise, -1.</returns>
 public int IndexOf(RssItem rssItem)
 {
     return List.IndexOf(rssItem);
 }