#!/usr/bin/python

"""
    lggrem2rss.py 1.01
    Last updated: Dec 22, 2005
    Copyright (c) 2005 http://www.broobles.com/
    Website: http://www.broobles.com/scripts/lggrem2rss/
    
    Description:
    ===========
    Converts Linkagogo daily reminders into an RSS feed.
    
    Usage:
    =====
    - Modify the following parameters below:
        - username: Your Linkagogo username
        - password: Your Linkagogo password
        - rssFile: The absolute path of the rss file to be generated. This file should
          be accessible via your web server. Example:
          rssFile="/home/your_domain/public_html/reminders.xml"
    - Save the changes and upload the script into a non-public location on your webserver
    - Create a cron job to invoke the script once per day
    
    History:
    =======
    1.01 (Dec 22, 2005): 
        - Using redirect instead of href as the link (feedback from Henry)
        - Fixed behaviour for empty reminders
    1.0  (Dec 21, 2005): 
        - Initial Release
    
    Licence:
    =======
    This script is free software; you can redistribute it and/or modify it under the terms of  
    the GNU Lesser General Public License as published by the Free Software Foundation;         
    either version 2.1 of the License, or (at your option) any later version.                  
    Please visit http://www.gnu.org/copyleft/lesser.html for more information.    

"""

import xml.dom.minidom
import urllib
import urllib2
from time import strftime, gmtime 


""" Configuration """

# Linkagogo username
username="lgg-user"

# Linkagogo password
password="lgg-pass"

# Local file where the fetched file is stored (xbel format)
localRemindersFile="reminders.xbel"

# The resulting rss file (full path)
rssFile="/home/your_domain/public_html/reminders.xml"

# If 1 an rss item will be created for each reminder
oneItemPerReminder=0

# Feed title
feedTitle="LinkaGoGo Reminders"

# Feed description
feedDescription="My Linkagogo Reminders"


class AppURLopener(urllib.FancyURLopener):
    """ Override User-Agent """
    version = "lggrem2rss"

class Bookmark:
    def __init__(self, title, url, lggRedirect):
        self.title = title
        self.url = url
        self.lggRedirect = lggRedirect
    def toLink(self):
        link = "<a href=\"%s\">%s</a>" % (xmlize(self.lggRedirect), xmlize(self.title))
        return link.encode('utf-8')
    def toString(self):
        return "Title: %s\nURL: %s" % (self.title, self.url)
    def getTitle(self):
        return xmlize(self.title).encode('utf-8')
    def getUrl(self):
        return xmlize(self.url)
    def getLGGRedirect(self):
        """ Redirect allows linkaGoGo to update its statistics and therefore 
            update the reminders list upon the next request. This prevents a 
            monthly reminder to keep reappearing every day, even though it has been visited. """
        return self.lggRedirect

def xmlize(text) :
    return text.replace("&", "&amp;").replace("\"", "&quot;").replace("<", "&gt;").replace("<", "&lt;")

def processBookmark(n):
    """ Process the bookmark node, returns a Bookmark object """
    for c in n.childNodes:
        if c.nodeType == c.ELEMENT_NODE and c.localName == "title":
            title = c.firstChild.data
    href = n.attributes["href"]
    redirect = n.attributes["redirect"]
    return Bookmark(title,href.value,redirect.value)
       
def fetchReminders(filename):
    """ Fetch reminders to 'localFile' """
    urllib._urlopener = AppURLopener()
    url = "http://%s:%s@www.linkagogo.com/api/rest/private/reminders/" % (username,password)
    data = urllib.urlopen(url)
    output = open(filename, "wb")
    output.write(data.read())
    output.close()

def createRss(reminders,filename):
    curtime = strftime("%a, %d %b %Y %H:%M:%S +0000", gmtime())
    output = open(filename,"w")
    output.write('<?xml version="1.0" encoding="UTF-8"?>\n')
    output.write('<rss version="2.0">\n<channel>\n')
    output.write('<title>%s</title>\n' % feedTitle)
    output.write('<description>%s</description>\n' % feedDescription)
    output.write('<link>http://www.linkagogo.com/go/Home</link>\n')
    output.write('<language>en-us</language>\n')
    output.write('<lastBuildDate>%s</lastBuildDate>\n' % curtime)
    if oneItemPerReminder:
        # One item per reminder
        i=1
        for reminder in reminders:
            output.write('<item>\n')
            output.write('<title>%s</title>\n' % reminder.getTitle())
            output.write('<link>%s</link>\n' % reminder.getLGGRedirect())
            output.write('<pubDate>%s</pubDate>\n' % curtime)
            # Unique identifier
            output.write('<guid isPermaLink="false">%s%s</guid>\n' % (strftime("%Y%m%d%H%M%S", gmtime()),i))
            i=i+1
            # No need for content (no description)
            output.write('</item>\n')
    else:
        # Group all reminders into a single item
        output.write('<item>\n')    
        output.write('<title>Linkagogo Reminders for %s</title>\n' % strftime("%a, %d %b %Y", gmtime()))
        output.write('<link>http://www.linkagogo.com/go/Home</link>\n')
        output.write('<pubDate>%s</pubDate>\n' % curtime)
        # Unique identifier
        output.write('<guid isPermaLink="false">%s</guid>\n' % strftime("%Y%m%d%H%M%S", gmtime()))
        output.write('<description><![CDATA[')
        if len(reminders)>0:
            for reminder in reminders:
                output.write('<br />'+reminder.toLink())
        else:
            output.write('<br />No reminders')
        output.write(']]></description>\n')
        output.write('</item>\n')
    output.write('</channel>\n</rss>\n')
    output.close()
    
def main():
    fetchReminders(localRemindersFile)
    fh = open(localRemindersFile,"r")
    doc = xml.dom.minidom.parse(fh)   
    xbelNode = doc.firstChild
    reminders = []
    for n in xbelNode.childNodes:
        if n.nodeType == n.ELEMENT_NODE and n.localName == "bookmark":
            reminders.append(processBookmark(n))
    createRss(reminders, rssFile)
    
if __name__ == '__main__': main()