#!/usr/bin/python2.4 import os, sys, urllib, libxml2, libxslt, ldap, time # # globals # cscUri = "http://csclub.uwaterloo.ca/xsltproc" cscTerms = ["Winter", "Spring", "Fall"] cscShortTerms = ['w', 's', 'f'] cscLdapUri = "ldap://ldap1.csclub.uwaterloo.ca ldap://ldap2.csclub.uwaterloo.ca" cscLdap = None cscPeopleBase = 'ou=People,dc=csclub,dc=uwaterloo,dc=ca' cscPositions = { # position # name # exec # elected # order 'president' : ( 'President', True, True, 1, ), 'vice-president' : ( 'Vice-president', True, True, 2, ), 'treasurer' : ( 'Treasurer', True, True, 3, ), 'secretary' : ( 'Secretary', True, True, 4, ), 'sysadmin' : ( 'System Administrator', True, False, 5, ), 'librarian' : ( 'Librarian', False, False, 6, ), 'imapd' : ( 'Imapd', False, False, 7, ), 'webmaster' : ( 'Web Master', False, False, 8, ), } cscYesNo = { True : 'yes', False : 'no' } # # cscLdapConnect # def cscLdapConnect(): global cscLdap cscLdap = ldap.initialize(cscLdapUri) cscLdap.simple_bind_s("", "") # # csc:encode-for-uri # def cscEncodeForUri(ctx, arg): if type(arg) == type([]): arg = libxml2.xmlNode(arg[0]).getContent() return urllib.quote(arg) # # csc:term # def cscTerm(ctx, arg): if type(arg) == type([]): arg = libxml2.xmlNode(arg[0]).getContent() try: [year, month, day] = arg.split("-") term = (int(month) - 1) / 4 return cscTerms[term] + " " + year except: print "Invalid term '%s'" % arg raise # # csc:member-list # def cscMemberList(ctx, arg): try: if cscLdap == None: cscLdapConnect() curDate = time.strftime('%d-%m-%Y') year = time.localtime().tm_year term = cscShortTerms[int(time.localtime().tm_mon - 1) / 4] members = cscLdap.search_s(cscPeopleBase, ldap.SCOPE_SUBTREE, '(&(objectClass=member)(term=%s%d))' % (term, year)) doc = libxml2.newDoc("1.0") root = doc.newChild(None, "root", None) for (_, member) in members: node = root.newChild(None, "member", None) node.setProp("userid", member['uid'][0]) node.setProp("name", member['cn'][0]) if not 'program' in member: member['program'] = [''] node.setProp("program", member['program'][0]) return [root] except Exception, e: print e raise # # csc:position-list # def cscPositionList(ctx, arg): try: if cscLdap == None: cscLdapConnect() members = cscLdap.search_s(cscPeopleBase, ldap.SCOPE_SUBTREE, '(&(objectClass=member)(position=*))') doc = libxml2.newDoc("1.0") root = doc.newChild(None, "root", None) positions = {} for (_, member) in members: for position in member['position']: if not position in positions: positions[position] = [] positions[position].append(member) for position in cscPositions.keys(): if not position in positions: positions[position] = [] for (position, members) in positions.iteritems(): node = root.newChild(None, "position", None) node.setProp("position", position) if not position in cscPositions: raise Exception("Position '%s' not known" % position) position = cscPositions[position] node.setProp("name", position[0]) node.setProp("exec", cscYesNo[position[1]]) node.setProp("elected", cscYesNo[position[2]]) node.setProp("order", str(position[3])) for member in members: child = node.newChild(None, "holder", None) child.setProp("userid", member['uid'][0]) child.setProp("name", member['cn'][0]) return [root] except Exception, e: print e raise # # csc:email # def cscEmail(ctx, arg): if type(arg) == type([]): str = libxml2.xmlNode(arg[0]).getContent() return "_EMAIL_TODO_" # # main # # check argv if len(sys.argv) < 4: print "Usage: xsltproc.py input-file style-sheet output-file [params...]" sys.exit(1) inFile = sys.argv[1] xsltFile = sys.argv[2] outFile = sys.argv[3] rawParams = sys.argv[4:] # check params params = {} for p in rawParams: try: [key, val] = p.split("=") params[key] = "'" + val + "'" except: print "Missing value for parameter '%s'" % p sys.exit(1) try: # register extensions libxslt.registerExtModuleFunction("encode-for-uri", cscUri, cscEncodeForUri) libxslt.registerExtModuleFunction("term", cscUri, cscTerm) libxslt.registerExtModuleFunction("member-list", cscUri, cscMemberList) libxslt.registerExtModuleFunction("position-list", cscUri, cscPositionList) libxslt.registerExtModuleFunction("email", cscUri, cscEmail) # parse xml/xslt and apply style-sheet style = libxslt.parseStylesheetFile(xsltFile) doc = libxml2.parseFile(inFile) res = style.applyStylesheet(doc, params) ret = style.saveResultToFilename(outFile, res, 0) except Exception, e: print e sys.exit(1)