#!/usr/bin/env python
#Boa:PyApp:main

import re
import urllib
import cgi
import cgitb; cgitb.enable()

modules ={}
class Annotation:
    
    sourceRe = re.compile("""<link rev=[^ ]* href="(http://[^·]*\.xmlschemata\.org/[^"<#]*)""")
    authorRe = re.compile("""<link rel=author rev=made href="mailto:[^"]*" title="([^"]*)">""")
    titleRe = re.compile("""<title>(.*)</title>""")
    dateRe = re.compile("""(\d\d)-(\d\d)-(\d\d) (\d\d:\d\d:\d\d)""")

    def __init__(self, date, url, mail):
    	g = Annotation.dateRe.search(date).groups()
        self.date = "20%s-%02d-%s" % (g[0], int(g[1])+1, g[2])
        self.time = g[3]
        self.mail = mail
        self.url = url
        f = urllib.urlopen(url)
        p = f.read()
        m = Annotation.sourceRe.search(p)
        if m:
            self.source = m.group(1)
        else:
            self.source = "unknown"
        m = Annotation.authorRe.search(p)
        if m:
            self.author = m.group(1)
        else:
            self.author = "unknown"
        m = Annotation.titleRe.search(p)
        if m:
            self.title = m.group(1)
        else:
            self.title = "unknown"
        f.close()
       
    def cmp_time(self, other):
    	return cmp(self.time, other.time)
	
    def cmp_date(self, other):
    	return cmp(self.date, other.date)
	
    def cmp_source(self, other):
    	return cmp(self.source, other.source)
   
    def __str__(self):
        str =  "Annotation: %s\n" % self.url
        str+= "Date: %s\n" % self.date
        str+= "Author: %s\n" % self.author
        str+= "Source: %s\n" % self.source
        return str


class Annotations(dict):

    def __getattr__(self, name):
    	iname = name[:-1]
        if hasattr(self[self.keys()[0]], iname):
	    setattr(self, name, self.getListByAttribute(iname))
	    return getattr(self, name)
	else:
            raise AttributeError

    def getListByAttribute(self, attribute):
        list={}
        for a in self.keys():
	    att = getattr(self[a], attribute)
            if list.has_key(att):
                list[att].append(self[a])
            else:
                list[att] = [self[a]]
        return list

    def toHtmlTree(self, source=None):
        print """<div id="tree">"""
        print """<h1>Annotations by source</h1>"""
	l = self.sources.keys()
	l.sort()
        for s in l:
            if s.find("http://books.xmlschemata.org/relaxng/") == 0 and (source == None or source == s):
                print """<div>"""
                print """<h2>"""
                print """<a href="%s">""" % s
                print s
                print """</a>"""
                print """</h2>"""
                print """<ul>"""
		self.sources[s].sort(Annotation.cmp_date)
                for a in self.sources[s]:
                    self.toHtmlTreeBranch(a)
                print """</ul>"""
                print """</div>"""
        print """</div>"""
        
    def toHtmlTreeBranch(self, annotation):
        print """<li>"""
        print """<a href="%s">""" % annotation.url
        print "%s (%s - %s)" % (annotation.title, annotation.author, annotation.date)
        print """</a>"""
        if self.sources.has_key(annotation.url):
            print """<ul>"""
            for a in self.sources[annotation.url]:
                self.toHtmlTreeBranch(a)
            print """</ul>"""
        print """</li>"""

    def toHtmlByAuthor(self, mail=None):
        print """<div id="author">"""
        print """<h1>Annotations by author</h1>"""
	l = self.authors.keys()
	l.sort()
        for au in l:
	    if mail == None or self[self.authors[au][0].url].mail == mail: 
                print """<div>"""
            	print """<h2>"""
            	print au
            	print """</h2>"""
            	print """<ul>"""
	    	self.authors[au].sort(Annotation.cmp_date)
            	for a in self.authors[au]:
            	    if a.source.find("http://books.xmlschemata.org/relaxng/") == 0:
                        self.toHtmlAuthorBranch(a)
            	print """</ul>"""
            	print """</div>"""
        print """</div>"""
        
    def toHtmlAuthorBranch(self, annotation):
        print """<li>"""
        print """<a href="%s">""" % annotation.url
        print "%s (%s - %s)" % (annotation.title, annotation.source, annotation.date)
        print """</a>"""
        if self.sources.has_key(annotation.url):
            print """<ul>"""
            for a in self.sources[annotation.url]:
                self.toHtmlTreeBranch(a)
            print """</ul>"""
        print """</li>"""

    def toHtmlByDate(self, recent=None):
        print """<div id="date">"""
        print """<h1>Annotations by date</h1>"""
	l = self.dates.keys()
	l.sort()
	if recent != None:
	    l.reverse()
	    count = int(recent)
        for d in l:
	    if recent == None or count > 0:
                print """<div>"""
            	print """<h2>"""
            	print d
            	print """</h2>"""
           	print """<ul>"""
	    	self.dates[d].sort(Annotation.cmp_time)
		if recent != None:
		    self.dates[d].reverse()
            	for a in self.dates[d]:
            	    if a.source.find("http://books.xmlschemata.org/relaxng/") == 0:
                        self.toHtmlDateBranch(a)
            	print """</ul>"""
            	print """</div>"""
		if recent != None:
		    count -= 1
        print """</div>"""
        
    def toHtmlDateBranch(self, annotation):
        print """<li>"""
        print """<a href="%s">""" % annotation.url
        print "%s (%s - %s)" % (annotation.title, annotation.author, annotation.source)
        print """</a>"""
        if self.sources.has_key(annotation.url):
            print """<ul>"""
            for a in self.sources[annotation.url]:
                self.toHtmlTreeBranch(a)
            print """</ul>"""
        print """</li>"""


def readAnnotationsFromLog(file):
    as = Annotations()
    r = re.compile("(\d\d-\d\d-\d\d \d\d:\d\d:\d\d) PUBLIC ([^ ]*) ([^ ]*)")
    f = open(file, "r")
    for l in f.readlines():
        m = r.match(l)
        if m:
            g = m.groups()
            as [g[1]] = Annotation(g[0], g[1], g[2])
    f.close()
    return as


def main():
    annotations = readAnnotationsFromLog("/home/xmlschemata/critdata/public.log")
    print "Content-Type: text/html"
    print 

    print """<html>"""
    print """<body>"""
    form = cgi.FieldStorage()
    if form.has_key("mail"):
    	annotations.toHtmlByAuthor(form["mail"].value)
    elif form.has_key("source"):
    	annotations.toHtmlTree(form["source"].value)
    elif form.has_key("recent"):
    	annotations.toHtmlByDate(form["recent"].value)
    else:
    	annotations.toHtmlTree()
    	annotations.toHtmlByAuthor()
    	annotations.toHtmlByDate()
    print """</body>"""
    print """</html>"""

if __name__ == '__main__':
    main()
