"""
File: rss.py
Version: 1.0
Author: Andrew Nelis

Very simple rss file generation.

See bottom of file for example usage.
"""
import os
import time

RSS_HEADER = '''<?xml version="1.0" encoding="ISO-8859-1"?>
<rss version="0.91">
 <channel>
  <title>%(title)s</title>
  <link>%(link)s</link>
  <description>%(description)s</description>
'''

RSS_ITEM = '''   <item>
    <title>%(title)s</title>
    <link>%(link)s</link>
    <description>%(description)s</description>
    <pubDate>%(pubdate)s</pubDate>
   </item>
'''

RSS_FOOTER = ''' </channel>
</rss>
'''

RSS_ITEM_COUNT = 30

class SimpleRssFile:
    """Represents a simple RSS file."""
    def __init__(self, filename, title=None, link=None, description=None):
        """Constructor

        filename - String, full path to the resulting rss file.
        Optional: (needed if the rss file doesn't already exist)
        title - Title of the RSS feed or site.
        link - URL pointing to the RSS feed or site.
        description - Description of the RSS feed or site.
        """
        self.filename = filename
        self.srcdetails = {
            'title': title,
            'link': link,
            'description': description,
        }
        self._items = []
        self._parseFile()

    def addItem(self, title, url, description):
        """Add a new entry to the rss file.

        title - The entry title.
        url - URL to the new entry.
        description - Full text description of the update.
        """
        details = {
            'title': title,
            'link': url,
            'description': description,
            'pubdate': time.ctime()}
        items = self._items
        if not items:
            # No existing rss file - must create from scratch.
            items.append(RSS_HEADER % self.srcdetails)
            items.append(RSS_ITEM % details)
            items.append(RSS_FOOTER)
        else:
            # Simply insert a new item.
            items.insert(1, RSS_ITEM % details)
            # Trim if necessary.
            while len(items) > RSS_ITEM_COUNT:
                items.pop(-2)
        # All done.

    def save(self):
        """Actually save the updated file."""
        # The previous version of the rss file is overwritten each time.
        rssfile = file(self.filename, 'w')
        rssfile.write(''.join(self._items))
        rssfile.close()
        
    def _parseFile(self):
        """Split the rss contents into a list of header, items and footer."""
        self._items = []
        if not os.path.exists(self.filename):
            return
        currentitem = ''
        additem = self._items.append
        rssfile = file(self.filename, 'r')
        # Look at each line in the file,
        for line in rssfile:
            # Seperate into a list of strings, seperated by each item.
            if not self._items and '<item>' in line:
                # First item. Push the header
                additem(currentitem)
                currentitem = ''
            currentitem += line
            if '</item>' in line:
                # end of item
                additem(currentitem)
                currentitem = ''
        additem(currentitem)


if __name__ == '__main__':
    filename = 'd:/tmp/test.rss'
    title = 'Our Test RSS Feed'
    description = 'Testing rss.py ...'
    link = 'http://www.example.com/test_item'
    
    rss = SimpleRssFile(filename, title, link, description)
    rss.addItem('New Test Item', 'http://example.com/1', 'Test Item Description')
    rss.save()
    
    # Nothing up my sleeve...
    del rss
    # Just to show different times on the item. ;-)
    time.sleep(5)
    
    # We don't need the feed description this time, it's taken from the existing
    # feed in the file.
    rss = SimpleRssFile(filename)
    rss.addItem('Second Test Item', 'http://example.com/2', 'Another test item. Horray!')
    rss.save()
    # Now if you look in <filename>, you should see the resultant feed.

