"""
flixq.py: a program for obtaining and parsing a Netflix queue for display
          on a pyblosxom blog.
Copyright 2005-2006 Michael Cornelius

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    
    A copy of the license can be obtained at the following URL:
    http://www.gnu.org/licenses/gpl.txt

The flixq plugin parses a netflix queue RSS feed and produces 
an html list, which is stored in $flixq, that can be used in head 
or foot templates. Because downloading the queue data from the netflix
server is a potentially costly operation, the data is cached for a user
specifiable time.

REQUIREMENTS
    Python 2.3
    The ElementTree module (http://effbot.org/zone/element-index.htm)

CONFIGURATION SETTINGS

These settings must be included in your config.py file.

    py["flixq_rss_id"] = "Z0000000000000000000000000000000000"
    py["flixq_cache"] = "/home/michael/.netflix_queue"

py["flixq_rss_id"] is the last component of the URL provided by netflix.
py["flixq_cache"] is the file where your cached queue data should be stored.

The following settings are optional, and defaults will be used if they are
not present in config.py. Below the default values are shown.

    py["flixq_ttl"] = 86400  # Number of seconds cache is valid
                             # Note: the netflix feed specifies one hour
                             # but my queue doesn't change that often.

    py["flixq_num"] = 10     # Number items to include in list.

"""

__author__      = "Michael Cornelius - michael at ninthorder dot com"
__version__     = "0.21"
__url__         = "http://cornelii.org/~michael/"
__description__ = "Display your netflix queue."
__depends__     = ["Python 2.2", 
                   "elementtree module (http://effbot.org/zone/element-index.htm)"]

import os, urllib, time
from elementtree import ElementTree

BASE_URL = "http://rss.netflix.com/QueueRSS?id="
FMT = '<li><a href="%s" title="%s">%s</a></li>'

CACHE = "flixq_cache"
RSS_ID = "flixq_rss_id"
NUM = "flixq_num"
TTL = "flixq_ttl"

def verify_installation(request):
    cfg = request.getConfiguration()
    if not cfg.has_key(RSS_ID):
        print "missing config property '%s', which specifies " % RSS_ID
        print "which netflix RSS feed to download."
        return 0
    if not cfg.has_key(CACHE):
        print "missing config property '%s', which specifies " % CACHE
        print "where to store cached queue data."
        return 0
    if not cfg.has_key(TTL):
        print "missing optional config property '%s', which specifies " % TTL
        print "how long cached queue data should be used. Default = 86400"
    if not cfg.has_key(NUM):
        print "missing optional config property '%s', which specifies " % NUM
        print "how many queue entries should be shown in the result list. "
        print "Default = 10"
    return 1

def untrack(link):
    try:
        i = link.index("&trkid=")
    except ValueError:
        return link
    return link[:i]

def get_queue(rss_id, n):
    url = BASE_URL + rss_id
    f = urllib.urlopen(url)
    t = ElementTree.parse(f)
    items = t.findall('channel/item')
    result = ['<ol class="netflix_queue">']
    for i in range(n):
        try:
            title = items[i].findtext("title").split(" ", 1)[1].strip()
        except IndexError:
            break
        description = items[i].findtext("description")
        link = untrack(items[i].findtext("link"));
        result.append(FMT % (link, description, title))
    result.append("</ol>")
    return "\n".join(result)

def cache_is_valid(path, ttl):
    return os.path.exists(path) and time.time() < os.stat(path).st_mtime + ttl

class Flixq:
    def __init__(self, request):
        self.request = request
        self.result = None

    def __str__(self):
        if not self.result: self.gen_result()
        return self.result

    def gen_result(self):
        cfg = self.request.getConfiguration()

        ttl   = cfg.get(TTL, 86400)
        num   = cfg.get(NUM, 10)
        cache = cfg[CACHE]

        if cache_is_valid(cache, ttl):
            self.result = open(cache).read();
        else:
            self.result = get_queue(cfg[RSS_ID], num)
            open(cache, "w").write(self.result)

def cb_prepare(args):
    request = args["request"]
    data = request.getData()
    data["flixq"] = Flixq(request)

# vim: ts=4 sw=4 et
