#!/usr/bin/python
# -*# coding: iso-8859-15 -*-

import cgi
import cgitb; cgitb.enable()
import sys
import TextParser
import db as dbapi

# globals
template="LinkList.html"    # the template to be parsed
table="linklist"    # name of the database table
crsr=None           # database cursor
mode=""             # the mode we are in: ""=beginning or end,"gather"=gather the text,"loop"=during looping
parser=TextParser.TextParser() # the TextParser...
looptext=""         # the gathered text


lastcategory=""     # the previous category
row=None
d=None              # hash with column name -> column number

startTag="<%%startloop%%>"
endTag="<%%endloop%%>"
linkTag="<%%(link)%%>"
nameTag="<%%(name)%%>"
descTag="<%%(description)%%>"
idTag="<%%(id)%%>"
categoryTag="<%%category *(\w*)%%>"
includeTag='<%%include *([\w./]*)%%>|<!-- *#include virtual="([\w./]*)" *-->'
addLinkTag="<%%addlink%%>"
editLinkTag="<%%editlink%%>"
ifEditAddTag="<%%ifEditAdd *text=[\"'](.*)[\"']%%>"

def StartLoop(match):
    """handler for the start of the link loop
    16.12.04 jc"""

    global crsr
    
    if mode=="":
        SetMode("gather")
    else:
        print "ooops"
        sys.exit(1)

def EndLoop(match):
    """handler for the end of the loop.
    - in "gather" mode: move to "loop" mode=reparse the gathered text, 'til out of links
    - in "loop" mode: get next link and loop
    - if out of links: quit loop mode and let the rest of the file be parsed
    16.12.04 jc"""

    global crsr,row,mode,looptext

    #print "Endloop Mode:",mode
    if mode=="gather":
        #looptext+=match.group(0)
        #print "LT:",looptext
        mode="loop"
        
    if mode=="loop":
        row=crsr.fetchone()
        while row!=None:
            parser.feed(looptext)
            row=crsr.fetchone()

        SetMode("")
        return

    if mode!="loop" and mode!="gather":
        print match.group(0),



def TagHandler(match, tag=None):
    """'generic' handler for the simple tags like 'link', 'name', 'description'
    'id', and maybe partly for 'category', too
    if mode is 'gather': add the match to (that's the whole tag) to looptext,
    if it is 'loop': print the fitting db-value, and
    otherwise just print the tag (i.e. in ignore it)
    --- this is used as the default tag handler - i.e. the one that's called if nothing else applies
    16.12.04 jc"""
    
    global mode, looptext, row
    
    #print "TagHandler: ",mode
    #print match.group(0),match.group(1)
    if len(match.groups())>0 and tag==None:
        tag=match.group(1)

    if mode=="gather":
        looptext+=match.group(0)
    elif mode=="loop":
        print row[d[tag]],
    else:
        print match.group(0),



def CategoryHandler(match):
    """Handle the category tag
    if it is not in 'loop' mode or
    if it is without parameters (i.e. there is no match group): just like the others
    if it has a 'once' parameter: only print it if it changes
    16.12.04 jc"""

    global lastcategory
    
    #print len(match.groups())==0 or mode!="loop"
    #print len(match.groups())
    if len(match.groups())==0 or mode!="loop":
        TagHandler(match, "category")
    else:
        #print match.group(1).strip()
        if match.group(1).strip()=="once":
            if row[d["category"]]!=lastcategory:
                print row[d["category"]],
                lastcategory=row[d["category"]]



def IncludeHandler(match):
    """Handle an include tag: include a file
    this is of course somewhat dangerous, because
    we don't know, what is in the file. I'll have to
    think about a sanity check for that.
    Maybe if I can get the basedir and the current dir
    from the webserver...
    17.12.04 jc"""
    
    ii=len(match.groups())
    if ii<=0:
        return  # if it's too stupid, just ignore it, it's not a normal
                # tag anyway
    #print len(match.groups()), match.group(2), match.group(0)
    for ij in range(1,ii+1):
        if match.group(ij)!=None:
            filename=match.group(ij)    # take this, empty groups come from the "or" part of the regex
            break
    fin=file(filename)
    if fin!=None:
        print fin.read()



def editLinkTagHandler(match):
    """handle the editlink tag
    25.12.04 jc"""
    global looptext
    
    if mode=="gather":
        looptext+=match.group(0)
    elif mode=="loop":
        print "<a href='/cgi-bin/EditLink.py?id=%s'>Edit link</a> :: <a href='/cgi-bin/AddLink.py?id=%s&mode=delete'>Link loeschen</a>"%(row[d["id"]],row[d["id"]])
    else:
        print match.group(0),



def addLinkTagHandler(match):
    """handle the addlink tag
    25.12.04 jc
    14.03.05 jc: support 'Neuer Link' inside the loop (i.e. adding to looptext)"""
    global looptext
    
    lnk="<a href='/intern/AddLink.html'>Neuer Link</a>"
    if mode=="gather":
        looptext+=match.group(0)
    else:
        print lnk,


def ifEditAddTagHandler(match):
    """handle the ifEditAddTag tag
    14.03.05 jc"""
    global looptext
    
    if mode=="gather":
        looptext+=match.group(0)
    else:
        print match.group(1),


def IgnoreHandler(match):
    """dismiss the matching tag
    26.12.04 jc"""
    pass    # do nothing



def TextHandler(text):
    """Handler for the normal text
    if in 'gather' mode: add to looptext
    else print the text
    16.12.04 jc"""
    
    global looptext
    
    if mode=="gather":
        looptext+=text
    else:
        print text,



def SetMode(str):
    #print "Mode:",str,globals()
    global mode
    mode=str



#######
# main program:
# register the handler, read the file,
# and feed it to the parser
#######


parser.SetTextHandler(TextHandler)
parser.AddHandler(startTag, StartLoop)
parser.AddHandler(endTag, EndLoop)
parser.AddHandler(linkTag, TagHandler)
parser.AddHandler(nameTag, TagHandler)
parser.AddHandler(descTag, TagHandler)
parser.AddHandler(idTag, TagHandler)
parser.AddHandler(categoryTag, CategoryHandler)
parser.AddHandler(includeTag, IncludeHandler)

form=cgi.FieldStorage()
print >> sys.stderr, form
if form.has_key("edit"):
    print >> sys.stderr, "EDIT"
    parser.AddHandler(editLinkTag, editLinkTagHandler)
    parser.AddHandler(addLinkTag, addLinkTagHandler)
    parser.AddHandler(ifEditAddTag, ifEditAddTagHandler)
else:
    parser.AddHandler(editLinkTag, IgnoreHandler)
    parser.AddHandler(addLinkTag, IgnoreHandler)
    parser.AddHandler(ifEditAddTag, IgnoreHandler)


db=dbapi.connect()
crsr=db.cursor()
q="SELECT * FROM %s ORDER BY category;"%(table)
#print q
crsr.execute(q)
# get the column names/numbers
d={}
ii=0
for dsc in crsr.description:
    d[dsc[0]]=ii
    ii+=1
            

# output the http headers
print "Content-type: text/html"
print
            
infile=file(template)
parser.feed(infile.read())

