"""RSS 2.0 Generator This library encapsulates the generation of an RSS (2.0) feed You may freely use this code in any way you can think of. """ import xml.sax.saxutils class RSS: """ RSS This class encapsulates the creation of an RSS 2.0 feed The RSS2.0 spec can be found here: http://blogs.law.harvard.edu/tech/rss RSS validator : http://rss.scripting.com The generation of an RSS feed is simple, the following is a sample: from rsslib import RSS, Item, Namespace rss = RSS() rss.channel.link = "http://channel.com" rss.channel.title = "my channel title" rss.channel.description = "my channel description" ns = Namespace( "foobar", "http://foobar.baz" ) rss.channel.namespaces.append( ns ) item = Item() item.link = "http://link.com" item.description = "my link description" item.title ="my item title" item.nsItems[ns.name + ":foo"] = "bar" rss.channel.items.append( item ) item = Item() item.link = "http://link2.com" item.description = "my link2 description" item.title ="my item2 title" item.nsItems[ns.name +":foo"] = "foo bar baz" rss.channel.items.append( item ) print rss.write() output: my channel title http://channel.com my channel description my item title http://link.com my link description bar my item2 title http://link2.com my link2 description foo bar baz author: cmallory /a t/ berserk /dot/ o r g """ def __init__(self): self.channel = Channel() self.version = "2.0" self.contents = None if __name__ == "__main__" : from rsslib import RSS, Item, Namespace rss = RSS() rss.channel.link = "http://channel.com" rss.channel.title = "my channel title" rss.channel.description = "my channel description" ns = Namespace( "foobar", "http://foobar.baz" ) rss.addNamespace( ns ) item = Item() item.link = "http://link.com" item.description = "my link description" item.title ="my item title" item.enclosure.url = "http://enclosure.url.com" item.enclosure.length = 12345 item.enclosure.type = "audio/mpeg" item.nsItems[ns.name + ":foo"] = "bar" rss.addItem( item ) item = Item() item.link = "http://link2.com" item.description = "my link2 description" item.title ="my item2 title" item.nsItems[ns.name +":foo"] = "foo bar baz" rss.addItem( item ) print rss.write() """ Write out the rss document """ def write( self ): self.contents = "\n" #contents += "\n" self.contents += " element """ def generateChannel( self ): contents = "" if ( self.channel.initialized() ): contents += "\n" contents += self.optionalWrite("title", self.channel.title ); contents += self.optionalWrite("link", self.channel.link ); contents += self.optionalWrite("description", self.channel.description ); contents += self.optionalWrite("language", self.channel.language ); contents += self.optionalWrite("copyright", self.channel.copyright ); contents += self.optionalWrite("category", self.channel.category ); contents += self.optionalWrite("managingEditor", self.channel.managingEditor ); contents += self.optionalWrite("webMaster", self.channel.webMaster ); contents += self.optionalWrite("pubDate", self.channel.pubDate ); contents += self.optionalWrite("lastBuildDate", self.channel.lastBuildDate ); contents += self.optionalWrite("docs", self.channel.docs ); contents += self.optionalWrite("cloud", self.channel.cloud ); contents += self.optionalWrite("ttl", self.channel.ttl ); contents += self.optionalWrite("generator", self.channel.generator ); contents += self.optionalWrite("image", self.channel.image ); contents += self.optionalWrite("rating", self.channel.rating ); contents += self.optionalWrite("textInput", self.channel.textInput ); contents += self.optionalWrite("skipHours", self.channel.skipHours ); contents += self.optionalWrite("skipDays", self.channel.skipDays ); contents += "\n" + self.generateItems() + "\n" else : contents = "[Channel not properly initialized. " contents +="A required field is not set.(title/link/description]" return contents """ Generates all items within a channel """ def generateItems( self ): c = "" for i in self.channel.items : c += "" c += self.optionalWrite("title", i.title); c += self.optionalWrite("link", i.link ); c += self.optionalWrite("description", i.description); c += self.optionalWrite("author", i.author ); c += self.optionalWrite("pubDate", str(i.pubDate) ) c += self.optionalWrite("category", i.category ) c += self.optionalWrite("comments", i.comments ) c += self.optionalWrite("guid", i.guid ) c += self.optionalWrite("source", i.source ) if ( i.enclosure.url != "" ): c+= "\n" for k in i.nsItems.keys(): c += self.optionalWrite( k , i.nsItems[ k ] ) c += "\n\n" return c def addNamespace( self, ns ): if ( self.channel.namespaces is not None ): self.channel.namespaces.append( ns ) def addItem( self, item ): if ( self.channel is not None): self.channel.items.append( item ) def optionalWrite( self, key, val ): if ( val is not None and val != "" ): return "<" + key + ">" + xml.sax.saxutils.escape(val) + "\n" else: return "" """ Namespace """ class Namespace: def __init__( self, name, url ): self.url = url self.name = name class Channel: """ Channel (http://blogs.law.harvard.edu/tech/rss) This object represents an RSS channel (as of ver2.0) """ def __init__( self ): # # Required Fields # self.title= None self.link= None self.description= None # # Optional Fields # self.language = "" self.copyright = "" self.managingEditor = "" self.webMaster = "" self.pubDate = "" self.lastBuildDate = "" self.category = "" self.generator = "" self.docs = "" self.cloud = "" self.ttl = "" self.image = "" self.rating = "" self.textInput = "" self.skipHours = "" self.skipDays = "" self.items = [] self.namespaces = [] def initialized( self ): return self.title is not None and self.link is not None and self.description is not None class Item: """ Item http://blogs.law.harvard.edu/tech/rss#hrelementsOfLtitemgt A channel may contain any number of <item>s. An item may represent a "story" -- much like a story in a newspaper or magazine; if so its description is a synopsis of the story, and the link points to the full story. An item may also be complete in itself, if so, the description contains the text (entity-encoded HTML is allowed; see examples), and the link and title may be omitted. All elements of an item are optional, however at least one of title or description must be present. """ def __init__( self ): self.title = "" self.link = "" self.description = "" self.author = "" self.category = "" self.comments = "" self.enclosure = "" self.guid = "" self.pubDate = "" self.source = "" self.enclosure = Enclosure() self.nsItems = {} class Enclosure: """ Enclosure sub-element of is an optional sub-element of . It has three required attributes: url: says where the enclosure is located, length: says how big it is in bytes, and type: says what its type is, a standard MIME type. The url must be an http url. Example: """ def __init__(self): self.url = "" self.length = 0 self.type = ""