pso-0.98.D-beta/0040755000175200017510000000000010074410553012573 5ustar thanosuserspso-0.98.D-beta/py/0040755000175200017510000000000010074410552013222 5ustar thanosuserspso-0.98.D-beta/py/pso/0040755000175200017510000000000010074410553014024 5ustar thanosuserspso-0.98.D-beta/py/pso/__init__.py0100666000175200017510000000144007756466403016157 0ustar thanosusers# # __init__.py - Python Service Objects # # Author: Thanos Vassilakis thanos@0x01.com # # Copyright (c) thanos vassilakis 2000,2001, 2002 # # This library 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. # # This library 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 Lesser General Public License for more details. # # See terms of license at gnu.org. # # # $Id: __init__.py,v 1.2 2002/06/19 15:35:42 thanos Exp $ # __version__="$Revision: 1.2 $" pso-0.98.D-beta/py/pso/cgirequest.py0100666000175200017510000000326507756466403016602 0ustar thanosusers# # cgirequest.py - Python Service Objects # # Author: Thanos Vassilakis thanos@0x01.com # # Copyright (c) thanos vassilakis 2000,2001, 2002 # # This library 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. # # This library 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 Lesser General Public License for more details. # # See terms of license at gnu.org. # # $Id: cgirequest.py,v 1.8 2003/01/20 23:20:00 thanos Exp $ # __version__="$Revision: 1.8 $" import sys, operator, os from request import SERVER_RETURN from requestimpl import RequestImpl from copy import copy class CgiRequest(RequestImpl): """ Concrete Implementation class for a CGI Request """ COOKIE_KEY='HTTP_COOKIE' def __init__(self, req=None): #RequestImpl.__init__(self, req) self.ostream= sys.stdout def req(self): return self def getOutStream(self): return self.ostream def getCookieKey(self): return self.COOKIE_KEY def getEnviron(self, handler): env ={} keys = os.environ.keys() values = os.environ.values() map(operator.setitem, [env]*len(keys), keys, values) #import os #env = copy(os.environ) return env def send_http_header(self, handler): handler.write(str(handler.getHeadersOut())) handler.write('\n') def getInputs(self, handler): from cgi import FieldStorage return FieldStorage() def getServerReturn(self): return SERVER_RETURN pso-0.98.D-beta/py/pso/fields.py0100644000175200017510000000501110074406623015641 0ustar thanosusers# # pso.fields.py - Python Service Objects Form Tag lib # # Author: Thanos Vassilakis thanos@0x01.com # # Copyright (c) thanos vassilakis 2000,2001, 2002 # # This library 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. # # This library 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 Lesser General Public License for more details. # # See terms of license at gnu.org. # # $Id: fields.py,v 1.5 2004/07/12 04:03:31 thanos Exp $ # __version__="$Revision: 1.5 $" from string import letters, digits from form import ValidationFailure,FieldMissing, ValidationError, DefaultField, Select, Input from isocodes import USStates from validation import isZipCode class StateSelect(Select): OPTIONS=( ('NN','Non US or Canada'), ) + USStates class ZipInput(Input): def validate(self, handler): value = Input.validate(self, handler) if not value: return '' try: isZipCode(value) except Exception, e: raise ValidationError(self.getName(), '%s' % e) return value class PhoneInput(Input): def validate(self, handler): value = Input.validate(self, handler) if not value: return '' class EmailInput(Input): def validate(self, handler): value = Input.validate(self, handler) if len(value): if value.count('@') != 1: raise ValidationError(self.getName(), 'invalid e-mail') if value.count('.') < 1: raise ValidationError(self.getName(), 'invalid e-mail') return value class UrlInput(Input): def validate(self, handler): value = Input.validate(self, handler) if value: from urllib import urlopen try: urlopen(value) except: raise ValidationError(self.getName(), 'invalide url') return value class UserIdInput(Input): SIZE=5 VALIDCHAR = letters+digits REQUIRED=1 def validate(self, handler): value = Input.validate(self, handler) v = [ch for ch in value if ch not in self.VALIDCHAR] if v: raise ValidationError(value, 'login id must be alphnumerical [a-z, A-Z, 0-9]') size = int(self.getAttrs().get('size', str(self.SIZE))) if len(value) < size: raise ValidationError(value, 'login id must be %d character or longer' % size) return value pso-0.98.D-beta/py/pso/form.py0100644000175200017510000003517610074406573015361 0ustar thanosusers# # pso.form.py - Python Service Objects Form Tag lib # # Author: Thanos Vassilakis thanos@0x01.com # # Copyright (c) thanos vassilakis 2000,2001, 2002 # # This library 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. # # This library 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 Lesser General Public License for more details. # # See terms of license at gnu.org. # # $Id: form.py,v 1.8 2004/07/12 04:03:07 thanos Exp $ # __version__="$Revision: 1.8 $" from types import ListType, TupleType, StringType import md5 from parser import Tag from util import mkDict, log class FormException(Exception):pass class FieldMissing(FormException): def __init__(self, field, message='is mandatory'): self.field=field self.message=message Exception.__init__(self, message) class ValidationError(FormException): def __init__(self, field, message): self.field=field self.message=message Exception.__init__(self, message) class ValidationFailure(FormException): def __init__(self, errors): self.errors=errors Exception.__init__(self, message) class FormPart(Tag): # states FORMsTATEkEY="formState" START = "start" INeRROR = "error" INcONFIRM="confirm" INsUBMIT = "submit" def getState(self, handler): state = handler.scratch().get(self.FORMsTATEkEY, FormPart.START) return state class Form(FormPart): def init(self): Tag.init(self) def validator(self, obj, cdata): if obj is not self: if obj and hasattr(obj, 'validate'): try: self.handler.scratch()[obj] = obj.validate(self.handler) except (ValidationError, FieldMissing), e: self.handler.scratch()[obj] = e self.handler.scratch()['errors'] = e except Exception, e: print child, e def validate(self, handler): handler.scratch()['errors'] = [] self.handler= handler self.travers(self.validator) self.handler= None def preProcess(self, handler): if handler is self: return '' prevState = handler.req().getInput(self.FORMsTATEkEY) if not prevState: # first time currentState = Form.START elif prevState in (Form.START, Form.INeRROR): if handler is not self: self.validate(handler) if handler.scratch()['errors']: currentState = Form.INeRROR else: currentState = Form.INcONFIRM elif prevState == Form.INcONFIRM: currentState = Form.INsUBMIT else: currentState = Form.START handler.scratch()[self.FORMsTATEkEY] = currentState return '' def __call__(self, handler, cdata=''): table = { Form.START: self.renderForm, Form.INeRROR: self.renderForm, Form.INcONFIRM: self.renderConfirm, Form.INsUBMIT: self.doSubmit } method = table[self.getState(handler)] return method(handler, cdata) def renderHidden(self, hidden): if hidden: html='' for k,v in hidden.items(): html += '' % (k,v) return html def getHidden(self, handler): return {} def getAction(self, handler): action = self.attrs.get('action') if not action: url = handler.req().getUrl() url.clear() action = str(url) return action def renderForm(self, handler, fields): action = self.getAction(handler) if action: formattrs = self.buildAttrs( action = action) else: formattrs = self.buildAttrs() hidden = self.getHidden(handler) hidden['action']= handler.req().getInput('action') hidden[self.FORMsTATEkEY] = self.getState(handler) hidden = self.renderHidden(hidden) return "
\n %s %s
" % ( formattrs, hidden, fields) def renderConfirm(self, handler, cdata=''): return self.renderForm(handler, cdata) def onSubmit(self, handler): return handler.req().hasInputs('submit.x', 'submit') def onConfirmed(self, handler): return handler.req().hasInputs('confirm.x','confirm') def goNext(self, handler, cdata): handler.req().log( "GOTO NEXT PAGE") return "GOTO NEXT PAGE" def submit(self, handler, cdata): handler.req().log(handler.req().getInputs()) def doSubmit(self, handler, cdata): self.submit(handler, cdata) self.goNext(handler, cdata) return "form submitted" class Field(FormPart): REQUIRED=0 def getName(self): return self.getAttrs()['name'] def getStartValue(self, handler, name): startvalue = self.getAttrs().get('value','') if hasattr(self, 'record'): record = self.fromDb(self.record(handler)) #if name=='spam': if record: startvalue = record.get(name, startvalue) value = self.getFormValue(handler, name) if not value: return startvalue return value def getFormValue(self, handler, name, default = ''): return handler.req().getInput(name, default) def fromDb(self, value): return value def getValue(self, handler): name = self.getName() if self.getState(handler) is Form.START: value = self.getStartValue(handler, name) else: value = self.getFormValue(handler, name) return value def isGiven(self, handler): name = self.getName() value = self.getFormValue(handler, name) if (self.REQUIRED or self.getAttrs().get('required')) and not value: raise FieldMissing(self.getName()) return value def validate(self, handler): return self.isGiven(handler) def cData(self, handler, cdata): return cdata def __call__(self, handler, cdata=''): if self.getAttrs().get('readonly'): value = self.getValue(handler) return self.renderReadOnly(handler, value, self.cData(handler, cdata)) if self.getState(handler) is Form.START: value = self.getValue(handler) return self.renderEditable(handler, value, self.cData(handler, cdata)) if self.getState(handler) is Form.INeRROR: value = handler.scratch().get(self, '') if isinstance(value, FormException): return self.renderInError(handler, value, self.cData(handler, cdata)) else: return self.renderEditable(handler, value, self.cData(handler, cdata)) if self.getState(handler) is Form.INcONFIRM: value = handler.scratch().get(self, '') #value = self.getValue(handler) return self.renderReadOnly(handler, value, self.cData(handler, cdata)) value = self.getValue(handler) return self.renderEditable(handler, value, self.cData(handler, cdata)) def buildAttrs(self, handler, **kws): return Tag.buildAttrs(self, **kws) def renderInError(self, handler, value, cdata): return '%s <- %s: %s ' % (self.renderEditable(handler, self.getValue(handler), cdata), self.getName(), value) def renderEditable(self, handler, value, cdata): if cdata: return "<%s %s>%s" % (self.getAttrs()['tagname'], self.buildAttrs(handler, value=value) ,cdata, self.getAttrs()['tagname']) else: return "<%s %s />" % (self.getAttrs()['tagname'], self.buildAttrs(handler, value=value) ) def renderReadOnly(self, handler, value, cdata): return """%s""" % (value, self.getName(), self.getValue(handler)) def renderReadOnly(self, handler, values, cdata): html= """%s""" name = self.getName() if type(values) is type([]): fields = map(lambda n,v,h=html: h % (v,n,v), ( name,)*len(values), values) return ','.join(fields) return """%s""" % (values, self.getName(), self.getValue(handler)) class DefaultField(Field): TYPE=None NAME=None EXT="" def init(self): Field.init(self) if self.TYPE: self.getAttrs().setdefault('type',self.TYPE) if not self.getAttrs().has_key('name'): if not self.NAME: name = self.__class__.__name__[:-len(self.EXT)] self.NAME = name[0].lower()+name[1:] self.getAttrs()['name'] = self.NAME class Input(DefaultField): EXT="Input" class Group(DefaultField): EXT="Group" def renderEditable(self, handler, value, cdata): return cdata class ReadOnly(DefaultField): EXT="ReadOnly" def init(self): self.getAttrs()['readonly']=1 DefaultField.init(self) class Hidden(ReadOnly): TYPE="hidden" EXT="Hidden" def renderReadOnly(self, handler, value, cdata): return """""" % (self.getName(), self.getValue(handler)) class Multiple(DefaultField): CHECKED="checked" VALUE = "value" def getFormValue(self, handler, name, default = ''): return handler.req().getInputs(name) def buildAttrs(self, handler, **kws): attrs = self.processAttrs( **kws) givenValues = self.getValue(handler) if type(givenValues) != type([]): givenValues = [givenValues] value = self.getAttrs().get('value') if value: if value in givenValues: attrs[self.CHECKED]=None elif attrs.has_key('checked'): del attrs[self.CHECKED] return DefaultField.buildAttrList(self, attrs) class CheckBox(Multiple): EXT="CheckBox" TYPE="checkbox" def renderEditable(self, handler, value, cdata): value = self.getAttrs().get('value','') #return value, self.buildAttrs(handler, value=value) return DefaultField.renderEditable(self, handler, value, cdata) class Radio(CheckBox): TYPE="radio" EXT="Radio" class Options(Field): def getFormValue(self, handler, name, default = ''): name = self.getName() return handler.req().getInputs(name) def renderEditable(self, handler, value, cdata): return cdata #self.renderReadOnly(handler, values, cdata) def renderReadOnly(self, handler, values, cdata): html= """%s""" name = self.getName() if type(values) is type([]): fields = map(lambda n,v,h=html: h % (v,n,v), ( name,)*len(values), values) return ','.join(fields) return values class Submit(DefaultField): EXT="Submit" TYPE="submit" def buildAttrs(self, handler, **kws): if self.getState(handler)== Form.INcONFIRM: kws['name']="confirm" else: kws['name']="submit" return DefaultField.buildAttrs(self, handler, **kws) def renderReadOnly(self, handler, value, cdata): return self.renderEditable(handler, value , cdata) class Select(DefaultField): EXT="Select" OPTIONS=[] FIRSTSplit="|" SECONDSplit="," def init(self): DefaultField.init(self) self.OPTIONS= self.getOptions() def renderEditable(self, handler, value, cdata): options = self.getOptionList(value) if options: cdata = options return DefaultField.renderEditable(self, handler, value, cdata) def getLabel(self, value): #MING 03-15-2004 some options are list of strings and some are list of tuples. Also, sometimes the first option might be empty string. Therefore can't always index o with 0 for o in self.OPTIONS: if type(o) == StringType: if o == str(value): return o elif str(o[0]) == str(value): return o[1] def renderReadOnly(self, handler, value, cdata): return """%s""" % (self.getLabel(value), self.getName(), self.getValue(handler)) def getOptionList(self, selected): options = self.OPTIONS optionList="" for o in options: if type(o) in (ListType, TupleType): olen = len(o) if olen ==3: value, label, chosen = o else: value, label, chosen = o[0],o[1],'' else: value, label, chosen = o, o, '' if str(value) == str(selected): chosen='selected' optionList = '%s' % ( optionList, value, chosen, label) return optionList def getOptions(self): options = self.getAttrs().get('options') if options is None: return self.OPTIONS options = options.split(self.FIRSTSplit) options = map(lambda x, ch=self.SECONDSplit : x.split(ch), options) if len(options[0]) == 1: options = map(None, options, options) return options class TextArea(DefaultField): EXT="TextArea" def cData(self, handler, cdata): value = self.getValue(handler) if value: cdata = value return DefaultField.cData(self, handler, cdata) class File(DefaultField): EXT="File" TYPE="file" CURRENTLABEL="
current choice: %s " SAVEDAS= "savedAs" SAVED= "saved" READoNLYhTML ="""%(filename)s""" def getStartValue(self, handler, name): filename = DefaultField.getStartValue(self, handler, name+self.SAVED) tempname = DefaultField.getStartValue(self, handler, name+self.SAVEDAS) return filename, tempname def getFormValue(self, handler, name, default = ''): file = handler.req().getFile(name) if file is None or type(file) is type(""): return default #self.getStartValue(handler, name) else: file.keep() return file.filename, file.tempname def renderEditable(self, handler, file, cdata): filename ='' current ='' if not (file is None or type(file) is type("")): filename, tempname = file #if filename and tempname: current = self.getAttrs().get('currentlabel',self.CURRENTLABEL) % self.readOnly(tempname, filename) return DefaultField.renderEditable(self, handler, filename, cdata) + current def renderReadOnly(self, handler, file, cdata): if not (file is None or type(file) is type("")): filename, tempname = file else: filename ='' tempname = '' return self.readOnly(filename, tempname) def readOnly(self, filename, tempname): name = self.getName() attrs = mkDict(saved= name+self.SAVED, savedAs = name+self.SAVEDAS, filename=filename, tempname= tempname) return self.READoNLYhTML % attrs class PasswordEncoder: def encode(self, x): if x[:2] !='x:': return 'x:' + self.crypt(x) return x def crypt(self, x): egg = md5.new(x) return egg.hexdigest() class PasswordGroup(PasswordEncoder, Group): def renderReadOnly(self, handler, value, cdata): value = self.encode(value) return """""" % (self.getName(), value) class PasswordInput(PasswordEncoder, Input): TYPE="password" SIZE=7 REQUIRED=1 def renderReadOnly(self, handler, value, cdata): return """****""" % (self.getName(), value) def validate(self, handler): value = Input.validate(self, handler) size = int(self.getAttrs().get('size', str(self.SIZE))) if len(value) < size: raise ValidationError(self.getName(), 'must be %d characters or longer' % size) return self.encode(value) class PasswordConfirmInput(PasswordInput): def validate(self, handler): value = self.encode(Input.validate(self, handler)) passwd = self.encode(handler.req().getInput('password')) if passwd != value: raise ValidationError(self.getName(), 'must be the same as what you entered for password') return value pso-0.98.D-beta/py/pso/gui.py0100666000175200017510000002074107756466466015222 0ustar thanosusers# # pso.gui.py - Python Service Objects # # Author: Thanos Vassilakis thanos@0x01.com # # Copyright (c) thanos vassilakis 2000,2001, 2002 # # This library 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. # # This library 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 Lesser General Public License for more details. # # See terms of license at gnu.org. # # $Id: gui.py,v 1.2 2003/11/18 19:04:22 thanos Exp $ # # # created: 21/08/2002 Thanos Vassilakis # # # from pso.util import mkDict # application imports from util.cache import EvalCache class Bouncer: def render(self, parser, attr, cdata): if self.shouldBounce(parser, attr): return self.bounce(parser, attr, cdata) return '' def shouldBounce(self, parser, attr): return 0 def bounce(self, parser, attr, cdata): return '' class Link: def render(self, parser, attr, cdata): if self.isEnabled(parser, attr): return self.renderEnabled(parser, attr, cdata) else: return self.renderDisabled(parser, attr, cdata) def isEnabled(self, parser, attr): return 1 def renderEnabled(self, parser, attr, cdata): return parser.handler.url.href(cdata, **attr) def renderDisabled(self, parser, attr, cdata): return '%s' % cdata class Info: def render(self, parser, attr, cdata): if self.isEnabled(parser, attr): return self.renderInfo(parser, attr, cdata) return '' def isEnabled(self, parser, attr): return 1 def renderInfo(self, parser, attr, cdata): return cdata class List: def __init__(self): self.records=None def shouldShow(self, parser, attr) : return 1 def getRecords(self, parser, attr): pass def processRecord(self, parser, attr, record, fields): pass def prepare(self, parser, attr): return {} def render(self, parser, attr, cdata): if not self.shouldShow(parser, attr): return '' if self.records is None: self.records = self.sort(parser, attr) rowlen = len(self.records) fields = self.prepare(parser, attr) rows = map(self.processRow, self.records, rowlen*((parser,attr, cdata, fields),)) del self.records[:] self.records = None return '\n'.join(rows) def sort(self, parser, attr): return self.getRecords(parser, attr) def processRow (self, record, params): parser, attr, cdata, fields = params #MING DEBUG 01-02-03 return cdata % self.processRecord(parser, attr, record, fields) #return str(self.processRecord(parser, attr, record, fields)) def tableMethods(celf): table = celf() return table.render tableMethods = classmethod(tableMethods) class Table(List): PAGESZ='10' paged=0 PAGER_HTML = """
%(legend)s %(prev)s %(next)s  
""" def processPager(self, parser, attr, cdata): if self.records is None: self.records = self.sort(parser, attr) (legend, prev, next, self.records) = self.tabulate(parser, attr, self.records) return mkDict(legend=legend, prev=prev, next=next) def pager(self, parser, attr, cdata): if not self.shouldShow(parser, attr): return '' if not cdata: html = self.PAGER_HTML return html % self.processPager( parser, attr, cdata) def uri(self, parser, attr, label, **vars): tablename = attr.get('name','') url = parser.handler.url.copy() sort = vars.get('sort') if sort is None: sort = parser.handler.getInput(tablename+'sort') if sort is not None: url[tablename+'sort'] = sort line = vars.get('line') if not line: line = parser.handler.getInput(tablename+'line') if line: url[tablename+'line'] = line del url['delta'] return '%s' % (url, label) def tabulate(self, parser, attr, records): numberlines = len(self.records) tablename = attr.get('name','') line = int(parser.handler.getInput(tablename+'line', value='1')) pagesz = int(parser.handler.getInput(tablename+'pageSize', value=self.PAGESZ)) if line > numberlines: line=int(numberlines / pagesz)*pagesz + 1 elif (line < 1): line=1 numberpages = numberlines/ pagesz + (numberlines % pagesz > 0) currentpage = line/ pagesz + (line % pagesz > 0) if (line > (1+(currentpage-1)*pagesz)): prevpage = 1+(currentpage-1)*pagesz nextpage=prevpage+pagesz else: prevpage = line - pagesz nextpage=line + pagesz if prevpage < 0: prevpage = 0 if nextpage > numberlines: nextpage = 0 records = records[int(line-1): int(line+pagesz-1)] if nextpage: nexturi = self.uri(parser, attr, 'next', line= nextpage) else: nexturi = 'next' if prevpage: prevuri = self.uri(parser, attr, 'prev', line= prevpage) + ' |' else: prevuri = 'prev |' if not numberpages: return 'no data', '','', [] return ('%d of %d - ' % ( currentpage, numberpages)), prevuri, nexturi, records def tableMethods(celf): table = celf() return table.pager, table.render tableMethods = classmethod(tableMethods) class SortedTable(Table): def sort(self, parser, attr): records = self.getRecords(parser, attr) records.sort() return records class SortableTable(Table): SORTFIELD = "sort" PAGEFIELD = "line" def __init__(self): List.__init__(self) def toggle(self, parser, attr, current, field): if abs(current)== field: return -current return field def columnHead(self, parser, attr, currentColumn, innerhtml, default, column): label, field = column field +=1 field = self.toggle(parser, attr, currentColumn, field) return self.buildTitle(parser, attr, field, innerhtml %label) def buildTitle(self, parser, attr, field, label): return self.uri(parser, attr, label, sort=field) def getColumns(self, attr): columns = attr.get("columns") if columns: columns = EvalCache.eval(columns, self.GLOBALS) return columns def sortRow(self, parser, attr, html): if not self.shouldShow(parser, attr): return '' tablename = attr.get('name','') columns = self.getColumns(attr) if columns: innerHtml = attr.get("innehtml", "%s") default = EvalCache.eval(attr.get("default","1"), self.GLOBALS) currentField = parser.handler.getInput(tablename+'sort') if not currentField: currentField = default else: currentField = int(currentField) sortrow = [ self.columnHead(parser, attr, currentField, innerHtml, default, column) for column in columns] return html % tuple(sortrow) return html def sort(self, parser, attr): tablename = attr.get('name','') records = self.getRecords(parser, attr) column = parser.handler.getInput(tablename+'sort') if not column: column = self.getDefaultSort(parser.handler, attr) else: column = int(column) if column: records = sortTab(records, column) return records def getDefaultSort(self, handler, attr): value = EvalCache.eval(attr.get("default","0"), self.GLOBALS) if value > 0: value +=1 elif value < 0: value -=1 return value def tableMethods(celf): table = celf() return table.pager, table.sortRow, table.render tableMethods = classmethod(tableMethods) class Tab: def __init__(self, action, label): self.action, self.label = action, label def render(self, parser, attr, cdata=''): if self.isEnabled(parser): return self.renderEnabled(parser, attr, cdata) else: return self.renderDisabled(parser, attr, cdata) def renderEnabled(self, parser, attr, cdata): return parser.handler.url.href(self.getLabel(parser), action=self.action) def renderDisabled(self, parser, attr, cdata): return self.getLabel(parser) def getLabel(self, parser): return self.label def isEnabled(self, parser): return parser.handler.getInput('action') != self.action class TabBar: SPACER= ' | ' HTML="%s" def render(self, parser, attr, cdata=''): if not cdata: cdata = self.HTML try: bar = self.getBar(parser, attr) spacer = attr.setdefault('spacer', self.SPACER) if bar: tabs = [tab.render(parser, attr, cdata) for tab in self.TABS.get(bar, ())] return cdata % spacer.join(tabs) return '' except Exception,e: print "" def getBar(self, parser, attr): pass pso-0.98.D-beta/py/pso/handlers.py0100666000175200017510000000370207756466466016234 0ustar thanosusers# # handlers.py - Python Service Objects # # Author: Thanos Vassilakis thanos@0x01.com # # Copyright (c) thanos vassilakis 2000,2001, 2002 # # This library 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. # # This library 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 Lesser General Public License for more details. # # See terms of license at gnu.org. # # $Id: handlers.py,v 1.6 2003/11/18 19:04:22 thanos Exp $ # __version__="$Revision: 1.6 $" from service import OK from parser import CachedParser class TemplateHandler: TMPL="%s.html" TMPL_PATH='templates/' def renderer(self, object, cdata=''): if object: return object.render(self, cdata) return cdata def parse(self, req): self._req = req self._scratch={} try: template = self.buildTemplate(self.getTemplate(self.req())) tree = CachedParser().parseFile(template) except: import traceback traceback.print_exc() template = self.buildTemplate(self.getDefaultTemplate(req)) tree = CachedParser().parseFile(template) html = tree.render(self.renderer) self._req = None return html def handle(self, req): print self.parse(req) return OK def req(self): return self._req def scratch(self): return self._scratch def buildTemplate(self, template): return self.TMPL_PATH+self.TMPL % template def getTemplate(self, req): return req.pso().getEnviron('PATH_INFO', self.getDefaultTemplate(req)) def getDefaultTemplate(self, req): if not hasattr(self, 'DEFAULT_TEMPLATE'): raise 'please either define attribute DEFAULT_TEMPLATE or override %s' % self.getDefaultTemplate return self.DEFAULT_TEMPLATE pso-0.98.D-beta/py/pso/isocodes.py0100666000175200017510000001624007756466403016234 0ustar thanosusers# # Copyright (c) thanos vassilakis 2000,2001, 2002 # # This library 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. # # This library 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 Lesser General Public License for more details. # # See terms of license at gnu.org. # # $Id: isocodes.py,v 1.1 2003/01/24 17:31:07 thanos Exp $ __version__="$Revision: 1.1 $" USStates = ( ('AL','Alabama'), ('AK','Alaska'), ('AZ','Arizona'), ('AR','Arkansas'), ('CA','California'), ('CO','Colorado'), ('CT','Connecticut'), ('DE','Delaware'), ('FL','Florida'), ('GA','Georgia'), ('HI','Hawaii'), ('ID','Idaho'), ('IL','Illinois'), ('IN','Indiana'), ('IA','Iowa'), ('KS','Kansas'), ('KY','Kentucky'), ('LA','Louisiana'), ('ME','Maine'), ('MD','Maryland'), ('MA','Massachusetts'), ('MI','Michigan'), ('MN','Minnesota'), ('MS','Mississippi'), ('MO','Missouri'), ('MT','Montana'), ('NE','Nebraska'), ('NV','Nevada'), ('NH','New Hampshire'), ('NJ','New Jersey'), ('NM','New Mexico'), ('NY','New York'), ('NC','North Carolina'), ('ND','North Dakota'), ('OH','Ohio'), ('OK','Oklahoma'), ('OR','Oregon'), ('PA','Pennsylvania'), ('RI','Rhode Island'), ('SC','South Carolina'), ('SD','South Dakota'), ('TN','Tennessee'), ('TX','Texas'), ('UT','Utah'), ('VT','Vermont'), ('VA','Virginia'), ('WA','Washington'), ('WV','West Virginia'), ('WI','Wisconsin'), ('WY','Wyoming')) TLDCodes= ( ("ac", "Ascension Island"), ("ad", "Andorra"), ("ae", "United Arab Emirates"), ("af", "Afghanistan"), ("ag", "Antigua and Barbuda"), ("ai", "Anguilla"), ("al", "Albania"), ("am", "Armenia"), ("an", "Netherlands Antilles"), ("ao", "Angola"), ("aq", "Antarctica"), ("ar", "Argentina"), ("as", "American Samoa"), ("at", "Austria"), ("au", "Australia"), ("aw", "Aruba"), ("az", "Azerbaijan"), ("ba", "Bosnia and Herzegovina"), ("bb", "Barbados"), ("bd", "Bangladesh"), ("be", "Belgium"), ("bf", "Burkina Faso"), ("bg", "Bulgaria"), ("bh", "Bahrain"), ("bi", "Burundi"), ("bj", "Benin"), ("bm", "Bermuda"), ("bn", "Brunei Darussalam"), ("bo", "Bolivia"), ("br", "Brazil"), ("bs", "Bahamas"), ("bt", "Bhutan"), ("bv", "Bouvet Island"), ("bw", "Botswana"), ("by", "Belarus"), ("bz", "Belize"), ("ca", "Canada"), ("cc", "Cocos (Keeling) Islands"), ("cd", "Congo, Democratic Republic of the"), ("cf", "Central African Republic"), ("cg", "Congo, Republic of"), ("ch", "Switzerland"), ("ci", "Cote d'Ivoire"), ("ck", "Cook Islands"), ("cl", "Chile"), ("cm", "Cameroon"), ("cn", "China"), ("co", "Colombia"), ("cr", "Costa Rica"), ("cu", "Cuba"), ("cv", "Cap Verde"), ("cx", "Christmas Island"), ("cy", "Cyprus"), ("cz", "Czech Republic"), ("de", "Germany"), ("dj", "Djibouti"), ("dk", "Denmark"), ("dm", "Dominica"), ("do", "Dominican Republic"), ("dz", "Algeria"), ("ec", "Ecuador"), ("ee", "Estonia"), ("eg", "Egypt"), ("eh", "Western Sahara"), ("er", "Eritrea"), ("es", "Spain"), ("et", "Ethiopia"), ("fi", "Finland"), ("fj", "Fiji"), ("fk", "Falkland Islands (Malvina)"), ("fm", "Micronesia, Federal State of"), ("fo", "Faroe Islands"), ("fr", "France"), ("ga", "Gabon"), ("gd", "Grenada"), ("ge", "Georgia"), ("gf", "French Guiana"), ("gg", "Guernsey"), ("gh", "Ghana"), ("gi", "Gibraltar"), ("gl", "Greenland"), ("gm", "Gambia"), ("gn", "Guinea"), ("gp", "Guadeloupe"), ("gq", "Equatorial Guinea"), ("gr", "Greece"), ("gs", "South Georgia and the South Sandwich Islands"), ("gt", "Guatemala"), ("gu", "Guam"), ("gw", "Guinea-Bissau"), ("gy", "Guyana"), ("hk", "Hong Kong"), ("hm", "Heard and McDonald Islands"), ("hn", "Honduras"), ("hr", "Croatia/Hrvatska"), ("ht", "Haiti"), ("hu", "Hungary"), ("id", "Indonesia"), ("ie", "Ireland"), ("il", "Israel"), ("im", "Isle of Man"), ("in", "India"), ("io", "British Indian Ocean Territory"), ("iq", "Iraq"), ("ir", "Iran (Islamic Republic of)"), ("is", "Iceland"), ("it", "Italy"), ("je", "Jersey"), ("jm", "Jamaica"), ("jo", "Jordan"), ("jp", "Japan"), ("ke", "Kenya"), ("kg", "Kyrgyzstan"), ("kh", "Cambodia"), ("ki", "Kiribati"), ("km", "Comoros"), ("kn", "Saint Kitts and Nevis"), ("kp", "Korea, Democratic People's Republic"), ("kr", "Korea, Republic of"), ("kw", "Kuwait"), ("ky", "Cayman Islands"), ("kz", "Kazakhstan"), ("la", "Lao People's Democratic Republic"), ("lb", "Lebanon"), ("lc", "Saint Lucia"), ("li", "Liechtenstein"), ("lk", "Sri Lanka"), ("lr", "Liberia"), ("ls", "Lesotho"), ("lt", "Lithuania"), ("lu", "Luxembourg"), ("lv", "Latvia"), ("ly", "Libyan Arab Jamahiriya"), ("ma", "Morocco"), ("mc", "Monaco"), ("md", "Moldova, Republic of"), ("mg", "Madagascar"), ("mh", "Marshall Islands"), ("mk", "Macedonia, Former Yugoslav Republic"), ("ml", "Mali"), ("mm", "Myanmar"), ("mn", "Mongolia"), ("mo", "Macau"), ("mp", "Northern Mariana Islands"), ("mq", "Martinique"), ("mr", "Mauritania"), ("ms", "Montserrat"), ("mt", "Malta"), ("mu", "Mauritius"), ("mv", "Maldives"), ("mw", "Malawi"), ("mx", "Mexico"), ("my", "Malaysia"), ("mz", "Mozambique"), ("na", "Namibia"), ("nc", "New Caledonia"), ("ne", "Niger"), ("nf", "Norfolk Island"), ("ng", "Nigeria"), ("ni", "Nicaragua"), ("nl", "Netherlands"), ("no", "Norway"), ("np", "Nepal"), ("nr", "Nauru"), ("nu", "Niue"), ("nz", "New Zealand"), ("om", "Oman"), ("pa", "Panama"), ("pe", "Peru"), ("pf", "French Polynesia"), ("pg", "Papua New Guinea"), ("ph", "Philippines"), ("pk", "Pakistan"), ("pl", "Poland"), ("pm", "St. Pierre and Miquelon"), ("pn", "Pitcairn Island"), ("pr", "Puerto Rico"), ("ps", "Palestinian Territories"), ("pt", "Portugal"), ("pw", "Palau"), ("py", "Paraguay"), ("qa", "Qatar"), ("re", "Reunion Island"), ("ro", "Romania"), ("ru", "Russian Federation"), ("rw", "Rwanda"), ("sa", "Saudi Arabia"), ("sb", "Solomon Islands"), ("sc", "Seychelles"), ("sd", "Sudan"), ("se", "Sweden"), ("sg", "Singapore"), ("sh", "St. Helena"), ("si", "Slovenia"), ("sj", "Svalbard and Jan Mayen Islands"), ("sk", "Slovak Republic"), ("sl", "Sierra Leone"), ("sm", "San Marino"), ("sn", "Senegal"), ("so", "Somalia"), ("sr", "Suriname"), ("st", "Sao Tome and Principe"), ("sv", "El Salvador"), ("sy", "Syrian Arab Republic"), ("sz", "Swaziland"), ("tc", "Turks and Caicos Islands"), ("td", "Chad"), ("tf", "French Southern Territories"), ("tg", "Togo"), ("th", "Thailand"), ("tj", "Tajikistan"), ("tk", "Tokelau"), ("tm", "Turkmenistan"), ("tn", "Tunisia"), ("to", "Tonga"), ("tp", "East Timor"), ("tr", "Turkey"), ("tt", "Trinidad and Tobago"), ("tv", "Tuvalu"), ("tw", "Taiwan"), ("tz", "Tanzania"), ("ua", "Ukraine"), ("ug", "Uganda"), ("uk", "United Kingdom"), ("um", "US Minor Outlying Islands"), ("us", "United States"), ("uy", "Uruguay"), ("uz", "Uzbekistan"), ("va", "Holy See (City Vatican State)"), ("vc", "Saint Vincent and the Grenadines"), ("ve", "Venezuela"), ("vg", "Virgin Islands (British)"), ("vi", "Virgin Islands (USA)"), ("vn", "Vietnam"), ("vu", "Vanuatu"), ("wf", "Wallis and Futuna Islands"), ("ws", "Western Samoa"), ("ye", "Yemen"), ("yt", "Mayotte"), ("yu", "Yugoslavia"), ("za", "South Africa"), ("zm", "Zambia"), ("zw", "Zimbabwe")) pso-0.98.D-beta/py/pso/modpython.py0100666000175200017510000000637507756466403016455 0ustar thanosusers# # modpython.py - Python Service Objects # # Author: Thanos Vassilakis thanos@0x01.com # # Copyright (c) thanos vassilakis 2000,2001, 2002 # # This library 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. # # This library 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 Lesser General Public License for more details. # # See terms of license at gnu.org. # # $Id: modpython.py,v 1.10 2002/06/19 15:34:51 thanos Exp $ # __version__="$Revision: 1.10 $" from operator import setitem, getitem from pso import service from cgirequest import CgiRequest from mod_python import apache, util def fixup(req, sessionImpl=None): service.fixup(req, ModPythonRequest, sessionImpl = sessionImpl ) return apache.OK def cleanup(req): service.cleanup(req) return apache.OK class FormInput(util.FieldStorage): def getvalue(key, default=None): reval = default if self.has_key(key): value = self[key] if type(value) is type([]): retval = map(lambda v:v.value, value) else: retval = value.value return retval def getfirst(self, key, default =None): retval = default if self.has_key(key): value = self[key] if type(value) is type([]): retval = value[0].value else: retval = value.value return retval def getlist(self, key): if self.has_key(key): value = self[key] if type(value) is type([]): return value else: return [value] return [] class ModPythonRequest(CgiRequest): """ Concrete Implementation class for a mod_python Request """ #COOKIE_KEY='Cookie' def req(self): return self._req def setup(self, handler, req): #req.pso = handler self._req = req def getOutStream(self): return self.req() def getEnviron(self, handler): self.req().add_common_vars() env = {} subenv = self.req().subprocess_env keys = subenv.keys() values = map(getitem, (subenv,)*len(keys), keys) map(setitem, [env]*len(keys), keys, values) env["GATEWAY_INTERFACE"] = "Python-CGI/1.1" if len(self.req().path_info) > 0: env["SCRIPT_NAME"] = self.req().uri[:-len(self.req().path_info)] else: env["SCRIPT_NAME"] = self.req().uri if self.req().headers_in.has_key("authorization"): env["HTTP_AUTHORIZATION"] = self.req().headers_in["authorization"] options = self.req().get_options() keys = options.keys() values = map(getitem, (options,)*len(keys), keys) map(setitem, [env]*len(keys), keys, values) return env def send_http_header(self, handler, content_type='text/html'): self.req().content_type = content_type self.req().send_http_header() def getInputs(self, handler, key=None, default=None, index=0): from modpython import FormInput return FormInput(self.req()) def getServerReturn(self): return apache.SERVER_RETURN def getHeadersOut(self): return self.req().headers_out def syncHeadersOut(self, headers): pass #self.req().headers_out.add('cookie','MyMi') #for k,v in headers.flatten(): # self.req().headers_out.add(k,v) pso-0.98.D-beta/py/pso/nsapyrequest.py0100666000175200017510000001052707756466403017171 0ustar thanosusers# # nsapy.py - Python Service Objects # # Author: Thanos Vassilakis thanos@0x01.com # # Copyright (c) thanos vassilakis 2000,2001, 2002 # # This library 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. # # This library 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 Lesser General Public License for more details. # # See terms of license at gnu.org. # # $Id: nsapyrequest.py,v 1.4 2002/06/19 15:32:44 thanos Exp $ # __version__="$Revision: 1.4 $" import os from pso.request import ServiceRequest from pso.requestimpl import RequestImpl def buildEnviron( pblock, environ = {}): if pblock: buff = pblock.pblock2str() buff = buff.replace('\\"', 'MinggniM') list = buff.split( '"' ) list = map(lambda var,oldsep='MinggniM',newsep='"':var.replace(oldsep, newsep), list) for n in range( 1, len( list ), 2 ): key = list[n-1][:-1] key = key.strip() environ[key] = list[n] return environ def envReKey(environ): keys = { "content-length": "CONTENT_LENGTH" , "content-type": "CONTENT_TYPE" , "accept": "HTTP_ACCEPT" , "accept-encoding": "HTTP_ACCEPT_ENCODING" , "accept-language": "HTTP_ACCEPT_LANGUAGE" , "authorization": "HTTP_AUTHORIZATION" , "cookie" :"HTTP_COOKIE" , "if-modified-since": "HTTP_IF_MODIFIED_SINCE" , "referer": "HTTP_REFERER" , "user-agent":"HTTP_USER_AGENT" , "auth-type": "AUTH_TYPE" , "path-info": "PATH_INFO" , "auth-user": "REMOTE_USER" , "keysize": "HTTPS_KEYSIZE" , "secret-keysize" :"HTTPS_SECRETSIZE" , "ip": "REMOTE_ADDR" , "security_active": "HTTPS" , "host": "HTTP_HOST" , "server_hostname": "SERVER_NAME" , "query" : "QUERY_STRING", "clf-request" : "REQUEST_LINE", "method" : "REQUEST_METHOD", "uri" : "SCRIPT_NAME", "protocol" : "SERVER_PROTOCOL" } newenv = {} for key, value in [(key, value) for key, value in environ.items() if key in keys]: newenv[key] = value return newenv class NsapyRequest(RequestImpl): """ Concrete Implementation class for a Nsapi Request """ COOKIE_KEY='HTTP_COOKIE' def __init__(self, req=None): self._req= req def req(self): return self._req def getOutStream(self): return self.ostream def getCookieKey(self): return self.COOKIE_KEY def getEnviron(self, handler): env = {} try: env.update( os.environ ) except: pass env = buildEnviron( self.req().pb, env ) env = buildEnviron( self.req().sn.session_dns(), env ) env = buildEnviron( self.req().sn.client(), env ) env = buildEnviron( self.req().rq.reqpb, env ) env = buildEnviron( self.req().rq.headers, env ) env = buildEnviron( self.req().rq.srvhdrs, env ) env = buildEnviron( self.req().rq.vars, env ) env = envReKey(env) env["SERVER_PORT"] = env["SERVER_NAME"] = '' host = env["HTTP_HOST"] if ":" in host: host, port = host.split(":") env["SERVER_PORT"] = port env["SERVER_NAME"] = host if env.has_key('PATH_INFO'): env["SCRIPT_NAME"] = env["SCRIPT_NAME"][:-len( env["PATH-INFO"] )] env['SERVER_URL'] = "http://%(SERVER_NAME)s:%(SERVER_PORT)s" % env return env def send_http_header(self, handler): handler.write(str(self.getHeadersOut())) handler.write('\n') def getInputs(self, handler, key=None, default=None, index=0): from cgi import FieldStorage if handler.getEnviron('REQUEST_METHOD') in ( "POST", "PUT" ): ln = int( self.req().rq.request_header( "content-length", self.sn ) ) data = self.req().sn.form_data( ln ) stdin = StringIO( data ) form = FieldStorage(file = stdin, env = handler.getEnviron()) else: form = FieldStorage(environ = handler.getEnviron()) return form def getServerReturn(self): return SERVER_RETURN def syncHeadersOut(self, headers): for k,v in headers.flatten(): self.req().rq.srvhdrs.nvinsert(k, v) class NSAPYServiceRequest(ServiceRequest): def __init__(self, sessionImpl=None): ServiceRequest.__init__(self, NsapyRequest, sessionImpl) pso-0.98.D-beta/py/pso/parser.py0100644000175200017510000005615610074406733015711 0ustar thanosusers""" # # pso.parser.py - Python Service Objects Parser # # Author: Thanos Vassilakis thanos@0x01.com # # Copyright (c) thanos vassilakis 2000,2001, 2002 # # This library 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. # # This library 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 Lesser General Public License for more details. # # See terms of license at gnu.org. # # $Id: parser.py,v 1.18 2004/07/12 04:04:43 thanos Exp $ # SYNOPSIS Senario One First you make a template - this is just a normal HTML file with a few extra tags: For example, test.tmpl: My Email: thanos@0x01.com

My Name: Now create the mypanel package, mypanel.py from pso.parser import Tag class Email(Tag): "renders email as a uri" def render(self, cdata): return '%s' % ( cdata, cdata) class Name(Tag): "renders name as a uri" def render(self, cdata=''): return '%(name)s' % self.getAttrs() Save it in the python path. Now write the script: from pso.parser import Parser psoParser = Parser() psoTree = psoParser.parseFile("test.tmpl") print psoTree.render() Running this script should generate: My Email: thanos@0x01.com

My Name: Thanos Vassilakis Senario Two Now you might want to just extract the tags and document them... class TagDocumentor: def document(self, object, cdata=''): if object: self.documentation += '\t%s

%s

\n' % (object.__class__, object.__class__.__doc__) def do(self, infile): self.documentation ='' psoParser = Parser() psoTree = psoParser.parseFile(infile, noCache=1) psoTree.render(self.document) print "
%s
" TagDocumentor().do(test.tmpl) And you will get:
mypanel.Email
renders email as a uri
mypanel.Name
renders name as a uri
Senario Three You want to write a robot (this is simplistic - beware): class a(Tag): def getUrl(self, cdata): return self.getAttrs()['href'], cdata class A(a): pass class Robot: def process(self, object, cdata=''): if object: url, linkText = object.getUrl(cdata) if url not in self.links: self.links[url] = linkText self.do(url) def do(self, url): psoParser = Parser() psoTree = psoParser.parseFile(self.getPage(url), allTags=1) psoTree.render(self.process) def run(self, startUrl): self.links = {} self.do(startUrl) for url, linkText in self.link.items(): print '%s' % (url, linkText) """ __version__="$Revision: 1.18 $" __all__ =["Tag", "Parser", "CachedParser"] from types import * from time import time from string import letters, digits, whitespace from os.path import split, join, exists from stat import ST_MTIME from statcache import stat, forget from cPickle import dump, load from copy import copy import traceback import sys from util import log from table import CIMap silent=1 class PSOParts: def __init__(self, parent=None, name ='', className='', start=0, end=0, text='', attribute=None): self.setup(parent, name, className, start, end, text, attribute) self.children=[] self.attribute=attribute def setup(self, parent, name, className, start, end, text, attribute): self.parent = parent self.name = name self.className= className self.text = text self.start = start self.end = end self.attribute = attribute def psoSetup(object, parent, name, className, start, end, text, attribute): if isinstance(object, PSO): object.psoParts.setup(parent, name, className, start, end, text, attribute) else: object.psoParts = PSOParts(parent, name, className, start, end, text, attribute) class PSO: def __init__(self, **kw): """ @param kw: the kew word argumenst match the tags set attributes """ self.attrs= CIMap(kw) self.init() self.psoParts=PSOParts() def init(self): """ Overide to setup the tags values. """ def getAttrs(self): return self.attrs def setup(self, parent, name, start, end, text): """ Sets up a tag with its: @param name: the tags name. has name="A" @param start: character start position of tag in template. @param end: character end position of tag in template. @param text: the actuals tags text n the template before rendering. """ self.psoParts = PSOParts(parent, name, start, end, text) def getChildren(self): """ @return a list of the tags nested within this one.A """ return self.psoParts.children def append(self, child): children = self.psoParts.children if children and type(children[-1]) is StringType and type(child) is StringType: children[-1] += child else: children.append(child) def preProcess(self, renderer=None): """ Called before renderer has visited the nested tags. Overirde this method when you need to do validation before the nested tags are rendered. """ return '' def travers(self, renderer=None): result = self.preProcess(renderer.im_self) try: for child in self.psoParts.children: if type(child) is StringType: retval = renderer(None, child) else: retval = str(child.travers( renderer)) if retval: result +=retval if self.psoParts.parent: result = renderer(self, result) except Exception, e: try: result= ("%s: %s\n\n" % (self.psoParts.name ,e, "\n".join(traceback.format_exception( *sys.exc_info())))) except: result = ("%s\n\n" % (e, "\n".join(traceback.format_exception( *sys.exc_info())))) return result class PSOTree(PSO): def renderer(self, object, cdata=''): if not object: return cdata return object.render(self, cdata) def render(self, renderer = None): if not renderer: renderer = self.renderer return self.travers( renderer) class Token:pass class CData: pass class Comment: pass class StartTag(Token): pass class SingleTag(Token): pass class EndTag(Token): posstart=2 def getName(text, start=1, oldname=''): if oldname: return oldname text = text[start:] ind = text.find(' ') if ind > -1: name=text[:ind] else: if '/' in text: name = text[:-2] else: name=text[:-1] return name firstKeyChar = letters + digits+'_' keyChars = letters + digits+'_.-' def getAttrs(attrs): ind = attrs.find(' ') if ind > -1 and len(attrs) - ind > 2: attrs = attrs[ind:-1] else: return {} dict ={} if not attrs: return dict state='start' while attrs: ch = attrs[0] attrs=attrs[1:] if state == 'start': key=value='' if ch in whitespace: continue if ch in firstKeyChar: state='key' key += ch elif state =='key': if ch in keyChars: state='key' key += ch elif ch in whitespace: state= '=' elif ch == '=': state= 'value' delim='' elif state =='=': if ch in whitespace: continue elif ch == '=': state='value' delim='' elif ch not in whitespace: dict[key]='' state='start' attrs = ch + attrs elif state =='value': if not delim: if ch in '"\'': delim = ch elif ch not in whitespace: delim = whitespace value +=ch else: if ch in delim: dict[key] = value state='start' else: value +=ch else: if key: dict[key] = value return dict class Tag(PSO): def processAttrs(self, **kws): attrs={} for k,v in self.getAttrs().items(): attrs[k] = v for k,v in kws.items(): attrs[k] = v return attrs def buildAttrList(self, attrs): list = "" for k,v in attrs.items(): if k =='tagname': continue if v is None: list = "%s %s" % ( list, k) elif '"' in str(v): list = "%s %s='%s'" % ( list, k, v) else: list = '%s %s="%s"' % ( list, k, v) return list def buildAttrs(self, **kws): return self.buildAttrList( self.processAttrs( **kws )) def render(self, renderer, cdata=''): if self.psoParts.attribute: return getattr(self, self.psoParts.attribute)(renderer, cdata) return self(renderer, cdata) def __call__(self, renderer, cdata=''): """ Override to render tag. Here is where everything happens! """ return cdata class PSOTag(Tag):pass class Tokenizer: TagToFind=0 PsoTagFound=1 TagFound =2 TagStart=3 def __init__(self, text, allTags=0): self.text = text self.allTags= allTags self.textLength= len(self.text) self.reset() def reset(self): self.state=self.TagToFind self.index=0 def getToken2(self, defaultModule, reject={}, accept={}): blockstart = self.index rejectTag = 0 while self.index < self.textLength: try: if self.state is self.TagToFind: self.index = self.text.index('<', self.index) ch1 = self.text[self.index+1] if ch1 == '/': dif = 1 ch1 = self.text[self.index+dif+1] else: dif = 0 if ch1 == 'p'or ch1=='P': ch2=self.text[self.index+dif+2] if ch2 == 's'or ch2=='S': ch3=self.text[self.index+dif+3] if ch3 == 'o'or ch3=='o': self.state = self.PsoTagFound return CData, '', blockstart, self.index, self.text[blockstart:self.index] if self.allTags and ch1 != '!': self.state = self.TagFound return CData, '', blockstart, self.index, self.text[blockstart:self.index] self.index = self.text.index('>', self.index+1)+1 elif self.state in (self.PsoTagFound, self.TagFound): tagstart = self.index self.index = self.text.index('>', tagstart)+1 text = self.text[tagstart:self.index] if text[-2] =='/': tag, startpos = SingleTag, 1 elif text[1] =='/': tag, startpos = EndTag,2 else: tag, startpos = StartTag,1 if self.state == self.PsoTagFound: if tag is not EndTag: attrs = getAttrs(text) else: attrs= {'pso':'pso'} else: name = getName(text, startpos) if name.find(':') < 0: if defaultModule: name = defaultModule+':'+name else: rejectTag = 1 attrs= {'pso':name} if not rejectTag and not reject.has_key(attrs['pso']): return tag, attrs, tagstart, self.index, text self.state = self.TagToFind rejectTag =0 except ValueError: start= blockstart self.state=self.TagToFind self.index = len(self.text) return CData, '', start, self.index, self.text[start:self.index] return None, '', 0, 0, '' def getToken(self, defaultModule, reject={}, accept={}): blockstart = self.index while self.index < self.textLength: try: if self.state is self.TagToFind: self.index = self.text.index('<', self.index) if self.text[self.index+1] !='!': self.state = self.TagFound return CData, '', blockstart, self.index, self.text[blockstart:self.index] self.index = self.text.index('>', self.index+1)+1 elif self.state is self.TagFound: tagstart = self.index self.index = self.text.index('>', tagstart)+1 self.state = self.TagToFind text = self.text[tagstart:self.index] if text[-2] =='/': tag, startpos = SingleTag, 1 elif text[1] =='/': tag, startpos = EndTag,2 else: tag, startpos = StartTag,1 name = getName(text, startpos) attrs={} if name =='pso' or name =='/pso': attrs = {'tagname':'pso', 'pso':name} attrs.update(getAttrs(text)) else: attrs = {'tagname':name, 'pso':name} attrs.update(getAttrs(text)) if not reject.has_key(name): return tag, attrs, tagstart, self.index, text except ValueError: start= blockstart self.state=self.TagToFind self.index = len(self.text) return CData, '', start, self.index, self.text[start:self.index] return None, '', 0, 0, '' def PSOimport(module, object=None, doReload=0): try: if not object: mod = __import__(module) if doReload: reload(mod) comps = name.split('.') for c in comps[1:]: mod = getattr(mod, c) obj = mod else: m = __import__(module, globals(), locals(), [object,]) if doReload: reload(m) obj = getattr(m, object) return obj except: if not silent: import traceback traceback.print_exc() class Parser: """ pso.Parser(defaultModule) - Creates a new parser. The default module is the actual parser module unless its given. When a parser is created with pso.Parser("mytags") tags such as or will be treated as if they were writen or . """ sShared={} def __init__(self, defaultModule=""): self.tokenTree=PSOTree() self.sTagsAccepted={} self.sTagsRejected={} self.defaultModule =defaultModule def clear(self): self.sTagsAccepted={} self.sTagsRejected={} self.__class__.sShared={} def parseFile(self, filePath, oPath='', noCache=1, reload=0, allTags=0): if noCache: f = open(filePath) self.parse(f.read(), reload, allTags) else: ttime = stat(filePath)[ST_MTIME] if oPath: path, file = split(filePath) ofilePath= join(oPath, file) else: idx = filePath.rindex('.') if idx > -1: ofilePath= filePath[:idx] + '.pso' else: ofilePath = filePath+'.pso' try: otime = stat(ofilePath)[ST_MTIME] if otime < ttime: raise 'do parse' tagsAccepted, tagsRejected, self.tokenTree = load(open(ofilePath)) self.sTagsAccepted.update(tagsAccepted) self.sTagsRejected.update(tagsRejected) except: if not silent: import traceback traceback.print_exc() f = open(filePath) self.parse(f.read(), reload, allTags) if not noCache: dump((self.sTagsAccepted, self.sTagsRejected, self.tokenTree), open(ofilePath,'wb')) forget(ofilePath) forget(filePath) return self.tokenTree def parse(self, text, reload=0, allTags=0): self.reload= reload self.tokenizer = Tokenizer(text, allTags) return self.processNode(self.tokenTree) def getPSO(self, parent, args): tag, attrs, start, end, text = args className = attrs['pso'] attribute=None if self.sTagsRejected.has_key(className): return text renderer = None if self.sTagsAccepted.has_key(className): renderer, attribute= self.sTagsAccepted[className] #return renderer else: renderer, attribute = self.findObject(className) if renderer: objectType = type(renderer) if objectType is ClassType: if len(attrs) == 1: attrs.update(getAttrs(text)) whatToSave = renderer, attribute renderer = renderer(**attrs) psoSetup(renderer, parent, attrs['tagname'], className, start, end, text, attribute) self.sTagsAccepted[className] = whatToSave elif objectType is not StringType: renderer = str(renderer) whatToSave= renderer, None self.sTagsAccepted[className] = whatToSave return renderer else: self.sTagsRejected[className]=None tag = None return text def findObject(self, tagName): objName='' moduleName='' if hasattr(self, '%s' % tagName): return getattr(self, 'tag_%s' % tagName), None elif hasattr(self, 'tag_%s' % tagName): return getattr(self, 'tag_%s' % tagName), None elif globals().has_key(tagName): return globals()[tagName], None #elif tagName in dir(__builtins__): # return getattr(__builtins__, tagName) else: indx = tagName.find(':') if indx > -1: moduleName = tagName[:indx] objName = tagName[indx+1:] elif self.defaultModule: moduleName = self.defaultModule objName = tagName tagName = moduleName+':'+objName if objName: indx = objName.find('.') if indx > -1: attribute = objName[indx+1:] objName = objName[:indx] return PSOimport(moduleName, objName, doReload= self.reload), attribute else: return PSOimport(moduleName, objName, doReload= self.reload), None return None, None def processNode(self, currentNode): doAppend = currentNode.append cAppend = currentNode.getChildren().append getToken = self.tokenizer.getToken tagRejected = self.sTagsRejected tagsAccepted = self.sTagsAccepted while 1: token, attrs, start, end, text = getToken( self.defaultModule, self.sTagsRejected, self.sTagsAccepted) if not token: return currentNode if token is CData: doAppend(text) elif token is StartTag: node = self.getPSO(currentNode, (StartTag, attrs, start, end, text)) if type(node) is StringType: doAppend(node) else: cAppend(self.processNode(node)) elif token is SingleTag: node = self.getPSO(currentNode, (SingleTag, attrs, start, end, text)) if type(node) is StringType: doAppend(node) else: cAppend(node) elif token is EndTag: if hasattr(currentNode,'psoParts'): tokenName = currentNode.psoParts.name if currentNode.psoParts.name == attrs['tagname']: break doAppend(text) else: doAppend(text) return currentNode class CachedParser(Parser): trees={} def parseFile(self, filePath, oPath=''): tree = self.trees.get(filePath) if not tree: tree = Parser.parseFile(self, filePath, oPath) self.trees[filePath] = tree return tree class PSOParser(Parser):pass if __name__ =='__main__': file1 = 'templates/contractor_detail1.html' print '-'*25 class TagDocumentor: def render(self, object, cdata=''): if object: self.documentation += ("""%s
%s

\n""" % (object.__class__, object.__class__.__doc__)) def do(self, infile, outfile): self.documentation ='' psoParser = Parser() psoTree = psoParser.parseFile(infile, noCache=1) psoTree.render(self.render) open(outfile, 'w').write("
%s
" % self.documentation) class TagIndexer: index = 0 def render(self, object, cdata=''): if object: self.index +=1 index = self.index if cdata: return ":<%s>%s:" % (index, cdata, index) return ":<%s />:" % index return cdata def do(self, infile, outfile): self.index =0 psoParser = Parser() psoTree = psoParser.parseFile(infile, ) open(outfile, 'w').write(psoTree.render(self.render)) import time class TagTimer: def timer(self, object, cdata=''): if object: t = time.time() r = self.render(object, cdata) self.tagTimes[object.__class__.__name__] = time.time() - t return r return self.render(object, cdata) def do(self, infile): self.tagTimes={} psoParser = Parser() psoTree = psoParser.parseFile(infile) print psoTree.render(self.timer) for k,v in self.tagTimes.items(): print k, v class IndexerTimer(TagTimer, TagIndexer): pass try: import sys infile = file1 #sys.argv[1] outfile = 'r3' #sys.argv[2] TagIndexer().do(infile, 'r2') TagDocumentor().do(infile, 'r3') IndexerTimer().do(infile) except Exception,e: print e print """ usage parser.py template_file output_file """ pso-0.98.D-beta/py/pso/request.py0100644000175200017510000003147410074406326016077 0ustar thanosusers# # Author: Thanos Vassilakis thanos@0x01.com # # Copyright (c) thanos vassilakis 2000,2001, 2002 # # This library 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. # # This library 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 Lesser General Public License for more details. # # See terms of license at gnu.org. # # $Id: request.py,v 1.19 2004/07/12 04:00:22 thanos Exp $ # __version__="$Revision: 1.19 $" from tempfile import mktemp from types import StringType import time import sys from session import Session, CookieFileImpl from resultcodes import HTTP_MOVED_PERMANENTLY, HTTP_MOVED_TEMPORARILY class SERVER_RETURN(Exception):pass from urlparse import urlparse, urlunparse try: from urllib import urlencode except: pass try: from url import Url except: Url = None class RequestIO: """ RequestIO is a proxy ouput stream. Everything writen to it will be buffered until the headers are sent or complete. Then the contents is flused to the real out stream. """ def read(self, n = -1): return "" def readline(self, length = None): return "" def readlines(self): return [] def writelines(self, list): self.write(''.join(list)) def isatty(self): return 0 def seek(self, pos, mode = 0): pass def __init__(self): self.pos = 0 self.headers_sent = 0 self.out = "" self.header_out = None def write(self, s): if not s: return if not self.headers_sent: self.out += s else: self.getOutStream().write(s) self.pos += len(s) def flush(self): self.getOutStream().write(self.out) self.out="" def getHeadersOut(self): if self.header_out is None: self.header_out = self.impl.getHeadersOut() return self.header_out def tell(self): return self.pos def close(self): #if not self.headers_sent: self.send_http_header() self.flush() def headersSent(self): self.headers_sent=1 def __del__(self): self.close() def setHeaderOut(self, key, value): """ set a header entry. If this entry already exits overwrite it. """ if type(value) != StringType: value = str(value) self.getHeadersOut()[key] = value def addHeaderOut(self, key, value): """ add a header entry. """ self.getHeadersOut().add(key, value) def removeHeaderOut(self, key): del self.getHeadersOut()[key] class ServiceRequest(RequestIO): """ Bridge class for a http service Request """ inputs = None inputSeq = None inputDict = None cookies = None environ = None _session = None def __init__(self, implClass, req=None): RequestIO.__init__(self) self.impl = implClass() self.impl.setup(self, req) self.response="" self.status = self.getStatusCode(200) def __call__(self): return self def pso(self): " returns proxy to pso object " return self def getOutStream(self): return self.impl.getOutStream() def getInStream(self): return self.impl.getInStream() def setup(self, serviceHandler, reqHandler): pass def close(self): RequestIO.close(self) if self._session is not None: self._session.save(self) # # basics # def getStatusCode(self, code): self.impl.getStatusCode(code) # # environ # def getEnviron(self, key=None, default = None): """ if key is not given returns a dict of the server environment. Otherwise returns the entry for key. If no entry is found returns None or default if given. """ if self.environ is None: self.environ = self.impl.getEnviron(self) if key is None: return self.environ return self.environ.get(key, default) def setEnviron(self, key, value): self.getEnviron()[key] = value # # # # # # Session handling # def getSession(self, sessionImplClass = CookieFileImpl, **parameters): """ returns the current session. The session implentation class may be passed to sessionImplClass, which if None defaults to CookieFileImpl. The method can be passed keyword arguments which will be treated as HTTP directives """ if sessionImplClass: for k,v in parameters.items(): self.setEnviron(k, v) self._session = Session(self, sessionImplClass()) if self._session.isNew(): self.setSession(self._session) return self._session def setSession(self, session): self.impl.setSession(self, session) session = {} #property(getSession,setSession) # # Cookie handling # def getCookieKey(self): return self.impl.getCookieKey() def getCookies(self): """ req.getCookies()-> dict returns a dictionary of cookies. """ if self.cookies is None: cookies = self.getEnviron(self.impl.getCookieKey(), '') if cookies: from Cookie import SmartCookie self.cookies = SmartCookie() self.cookies.load(cookies) else: self.cookies = {} return self.cookies def getCookie(self, key, default=None): """ returns the cookie requested by key otherwise returns default, if default is not given returns None. """ return self.getCookies().get(key, default) def setCookie(self, key, value, **attrs): """ sets cookie, key, to value. Also will set any attributes given. e.g. request.setCookie("login",name, comment="user id") """ cookiefmt = "%s=%s;" cookie = cookiefmt % (key, value) for k,v in attrs.items(): cookie += cookiefmt % (k, v) self.addHeaderOut('set-cookie', cookie) def send_http_header(self, content_type='text/html'): """ send to stdout the content headers. Each on a seperate line. contenttype has not been set it will default to 'text/html'. Then send an extra newline """ #print if not self.getHeadersOut().has_key('content-type'): if not self.getHeadersOut().has_key('location'): if not self.getHeadersOut().has_key('status'): self.getHeadersOut()['content-type'] = content_type self.impl.syncHeadersOut(self.getHeadersOut()) self.headersSent() self.impl.send_http_header(self) self.flush() # # Control # def redirect(self, url, permanent=0): """ force an imediate redirect to given url. """ self.impl.redirect(self, url, permanent) def setStatus(self, status): """ set the HTTP return status. This normally defaults to 200. """ self.setHeaderOut('status', status) def sendStatus(self, status): """ set the HTTP return status. This normally defaults to 200. """ self.setStatus(status) self.impl.sendStatus(status) # # Input # def hasInput(self, key): """req.hasInput(key) -> 1 | 0 tests if a field in a form was filled. """ return self.getInputs().has_key(key) def hasInputs(self, *keys): return [key for key in keys if key in self.getInputs().keys()] def getInputs(self, key=None): """req.getInput(key) -> FiledStorage| List of Fields if key is given will return a list of fields values for that key. if there are no values an empty list is returned. if no key is given returns the cgi.FieldStorage object. """ if not self.inputs: self.inputs = self.impl.getInputs(self) if not key: return self.inputs if hasattr(self.inputs, 'getlist'): return self.inputs.getlist(key) else: if self.inputs.has_key(key): value = self.inputs.getvalue(key) if value and type(value) is type([]): return value else: return [value] return [] def getInputSeq(self): if not self.inputSeq: self.inputSeq=[] for key in self.getInputs().keys(): values = self.getInputs(key) for value in values: self.inputSeq.append((key, value)) return self.inputSeq def getInputDict(self): if not self.inputDict: self.inputDict={} for key in self.getInputs().keys(): self.inputDict[key] = self.getInputs(key) return self.inputDict def getInput(self, key, default=None, index=None): """req.getInput(key) -> String | default returns the given form field value as a String. If there are multiple values under the same key, it will return the first in the list, unless index is given. If no value is found will return "", unless default is given. """ if not index: index =0 try: return self.getInputs(key)[index] except: # import traceback # traceback.print_exc() return default def getFile(self, key, default=None): """req.getFile(fieldname)-> Field returns an uploaded file. The filed has the usual cgi.Field members plus filename - the given file name file - the actual file uploaded tempname - is None until keep() is called. the methods: keep() - The file object is a temporay file that will be deleted when the cgi terminates. keep asigns the file a a temp file name. save(name) - This method can be used to save the tempfile under the given name. """ if self.hasInput(key): file = self.getInputs()[key] if file.filename: file.__class__.tempname= None file.__class__.keep= keep file.__class__.save= save return file return default # # Utilities # _url = None def getUrl(self): if self._url is None: self._url= Url("http://%(HTTP_HOST)s%(REQUEST_URI)s" % self.getEnviron()) return self._url #url = property(getUrl) def uriParts(self): if not Url: raise 'under mod_python urlparse has problems' url = "http://%(HTTP_HOST)s%(REQUEST_URI)s" % self.getEnviron() parts = list(urlparse(url)) info_path = self.getEnviron('PATH_INFO','') path=parts[2] if info_path: path,dummy = path.split(info_path) indx = path.rfind('/') if indx > -1: script = path[indx:] path = path[:indx] else: script = path path='' parts[2] = path parts.insert(3, script) parts.insert(4, info_path) return parts def buildUri(self, parts, clean, **kws): query={} i = 0 for key in ('scheme', 'netloc', 'path', 'script','pathinfo', 'param', 'fragment'): if kws.has_key(key): parts[i] = kws[key] del kws[key] i += 1 if clean: parts[6] ='' qs = parts[6] if qs: if type((qs)) ==type(''): # now for QS key, values: # querySeq = parts[6].split('&') querySeq= map(lambda x: x.split('='), querySeq) for k,v in querySeq: if query.has_key(k): query[k].append(v) else: query[k] = [v] querySeq=[] query.update(kws) if query: for key,values in query.items(): if type(values) == type([]): for value in values: querySeq.append((key, value)) else: querySeq.append((key, values)) query = urlencode(querySeq, doseq=1) else: query = parts[6] if parts[4]: parts[2]= "%s%s%s" % tuple(parts[2:5]) else: parts[2]= "%s%s" % tuple(parts[2:4]) del parts[3:5] parts[4]= query return urlunparse(parts) def serviceUri(self, clean=1, **kws): parts = list(self.uriParts()) url = self.buildUri(parts, clean, **kws) return url def baseUri(self): parts = list(self.uriParts()) return "%s://%s%s/" % tuple(parts[:3]) def pageUri(self, page): return self.baseUri() + page def log(self, *args): args = map(str, args) post = "\n%s: %s" % ( time.ctime(), ' '.join(args)) try: sys.stderr.write(post) except: import traceback traceback.print_exc(file=self.stderr) def keep(fileField): """ req.getFile(key).keep() -> file This method is added to file form fields. Files that are uploaded are stored as nameless temporary files. This method allows you to store the file, so it can be processed at a later stage. Calling it replaces the nameless temp file with the new named temp file. """ if not fileField.tempname: fileField.tempname = mktemp() fileField.file.seek(0) fp = open(fileField.tempname,'wb') fp.write(fileField.file.read()) fp.close() fileField.file= open(fileField.tempname) def save(fileField, newName): """ req.getFile(key).saveAs(somename) -> None This method is added to file form fields. Files that are uploaded are stored as nameless temporary files. This method alows you to store the file with a given name. """ if not fileField.tempname: fileField.keep() fileField.file.flush() fileField.file.close() import os os.rename(fileField.tempname, newName) def psoTest(req): if not req: req = ServiceRequest() req.pso().send_http_header() try: session['reload'] +=1 except: session['reload'] = 0 req.pso().write("\n try reload ", req.pso().session) def simpleTest(): req = ServiceRequest() import sys sys.stdout = req print 1,"hello world" req.pso().send_http_header() req.pso().write(" 2. hello world") print 3, " third time" def redtest1(): import sys sys.stdout = req = ServiceRequest() print "hello", req.send_http_header() print "world" def redtest2(): req = ServiceRequest() print "hello", req.send_http_header() print "world" if __name__ == '__main__': if 0: import pdb pdb.run("simpleTest()") else: redtest2() pso-0.98.D-beta/py/pso/requestimpl.py0100666000175200017510000000357207756466403017002 0ustar thanosusers# # requestimpl.py - Python Service Objects # # Author: Thanos Vassilakis thanos@0x01.com # # # Copyright (c) thanos vassilakis 2000,2001, 2002 # # This library 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. # # This library 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 Lesser General Public License for more details. # # See terms of license at gnu.org. # $Id: requestimpl.py,v 1.5 2002/06/19 15:32:44 thanos Exp $ # __version__="$Revision: 1.5 $" from resultcodes import HTTP_MOVED_PERMANENTLY, HTTP_MOVED_TEMPORARILY from table import Table class RequestImpl: _req=None def getOutStream(self): pass def getInStream(self): pass def getStatusCode(self, code): pass def getEnviron(self):pass def getCookieKey(self): pass def send_http_header(self): pass def setup(self, handler, req): pass def req(self): return self._req def setSession(self, handler, session): session.setSession() def addHeaderOut(self, handler, key, value): self.getHeadersOut().add(key, value) def redirect(self, handler, url, permanent): handler.setHeaderOut('location', url) if permanent: status = HTTP_MOVED_PERMANENTLY else: status = HTTP_MOVED_TEMPORARILY raise self.getServerReturn(), self.getStatusCode(status) def getStatusCode(self, code): return code def getServerReturn(self,code): return SERVER_RETURN def getHeadersOut(self): return Table() def syncHeadersOut(self, headers): pass def sendStatus(self, status): raise self.getServerReturn(), self.getStatusCode(status) def getInputs(self): pass pso-0.98.D-beta/py/pso/resultcodes.py0100666000175200017510000000524307756466403016761 0ustar thanosusers# # resultcodes.py - Python Service Objects # # Author: Thanos Vassilakis thanos@0x01.com # # Copyright (c) thanos vassilakis 2000,2001, 2002 # # This library 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. # # This library 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 Lesser General Public License for more details. # # See terms of license at gnu.org. # # $Id: resultcodes.py,v 1.2 2002/06/19 15:32:44 thanos Exp $ # __version__="$Revision: 1.2 $" HTTP_CONTINUE = 100 HTTP_SWITCHING_PROTOCOLS = 101 HTTP_PROCESSING = 102 HTTP_OK = 200 HTTP_CREATED = 201 HTTP_ACCEPTED = 202 HTTP_NON_AUTHORITATIVE = 203 HTTP_NO_CONTENT = 204 HTTP_RESET_CONTENT = 205 HTTP_PARTIAL_CONTENT = 206 HTTP_MULTI_STATUS = 207 HTTP_MULTIPLE_CHOICES = 300 HTTP_MOVED_PERMANENTLY = 301 HTTP_MOVED_TEMPORARILY = 302 HTTP_SEE_OTHER = 303 HTTP_NOT_MODIFIED = 304 HTTP_USE_PROXY = 305 HTTP_TEMPORARY_REDIRECT = 307 HTTP_BAD_REQUEST = 400 HTTP_UNAUTHORIZED = 401 HTTP_PAYMENT_REQUIRED = 402 HTTP_FORBIDDEN = 403 HTTP_NOT_FOUND = 404 HTTP_METHOD_NOT_ALLOWED = 405 HTTP_NOT_ACCEPTABLE = 406 HTTP_PROXY_AUTHENTICATION_REQUIRED= 407 HTTP_REQUEST_TIME_OUT = 408 HTTP_CONFLICT = 409 HTTP_GONE = 410 HTTP_LENGTH_REQUIRED = 411 HTTP_PRECONDITION_FAILED = 412 HTTP_REQUEST_ENTITY_TOO_LARGE = 413 HTTP_REQUEST_URI_TOO_LARGE = 414 HTTP_UNSUPPORTED_MEDIA_TYPE = 415 HTTP_RANGE_NOT_SATISFIABLE = 416 HTTP_EXPECTATION_FAILED = 417 HTTP_UNPROCESSABLE_ENTITY = 422 HTTP_LOCKED = 423 HTTP_FAILED_DEPENDENCY = 424 HTTP_INTERNAL_SERVER_ERROR = 500 HTTP_NOT_IMPLEMENTED = 501 HTTP_BAD_GATEWAY = 502 HTTP_SERVICE_UNAVAILABLE = 503 HTTP_GATEWAY_TIME_OUT = 504 HTTP_VERSION_NOT_SUPPORTED = 505 HTTP_VARIANT_ALSO_VARIES = 506 HTTP_INSUFFICIENT_STORAGE = 507 HTTP_NOT_EXTENDED = 510 pso-0.98.D-beta/py/pso/service.py0100644000175200017510000000421010074406326016033 0ustar thanosusers# # Author: Thanos Vassilakis thanos@0x01.com # # # Copyright (c) thanos vassilakis 2000,2001, 2002 # # This library 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. # # This library 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 Lesser General Public License for more details. # # See terms of license at gnu.org. # $Id: service.py,v 1.10 2004/07/12 04:00:22 thanos Exp $ # __version__="$Revision: 1.10 $" import sys from weakref import ref from time import time, strftime, gmtime from util import log from request import ServiceRequest, SERVER_RETURN from session import CookieFileImpl from cgirequest import CgiRequest OK = 0 def fixup(req, requestImpl, sessionImpl=CookieFileImpl): sys.stdout = req.pso = ServiceRequest(requestImpl, req) session = req.pso().getSession( sessionImpl) def cleanup(req): log('cleaing up', req) req.pso().close() class ServiceHandler: PRODUCTION = 0 def run(self, handler, sessionImpl =CookieFileImpl): try: stdout = sys.stdout stderr = sys.stderr sys.stdout = pso = ServiceRequest(CgiRequest) pso.stderr = stderr logfile = pso.getEnviron('PSOLog') if logfile: sys.stderr = open(logfile, 'a', 0) if sessionImpl: pso.session = pso.getSession( sessionImpl ) status = handler(pso) except SERVER_RETURN, status: pass except: sys.stdout = stdout import traceback if not self.PRODUCTION: traceback.print_exc(file = sys.stdout) else: traceback.print_exc() sys.stderr = stderr def test(req): print "hello world" def test1(req): print "hello world" req.send_http_header(content_type= 'text/plain') def test2(req): print "hi there" req.sendStatus(204) def test3(req): print "hi there" req.redirect("http://www.w3c.org/") if __name__ =='__main__': ServiceHandler().run(test3) pso-0.98.D-beta/py/pso/session.py0100644000175200017510000002526010074405346016067 0ustar thanosusers# session.py - Python Service Objects # # Author: Thanos Vassilakis thanos@0x01.com # # Copyright (c) thanos vassilakis 2000,2001, 2002 # # This library 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. # # This library 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 Lesser General Public License for more details. # # See terms of license at gnu.org. # # $Id: session.py,v 1.15 2004/07/12 03:52:06 thanos Exp $ # __version__="$Revision: 1.15 $" from weakref import ref from time import time, strftime, gmtime from cPickle import load, dump from tempfile import mktemp from util import MixIn, log import sys, os try: mapClass = dict except: import UserDict mapClass = UserDict.UserDict class SessionImpl: "abstract implementaion class" DEFAULTServiceIdKey = "PSOServiceId" DEFAULTSessionIdKey = "PSOSessionId" DEFAULTServiceIdValue = "SESSION_ID" def getServiceId(self, reqHandler): """session.getServiceId(requestHandler) -> String ~ The service id, set in the HTTP directive, is returned. This will default to the script's name""" return reqHandler.getEnviron(self.DEFAULTServiceIdKey, self.getDefaultServiceId()) def getDefaultServiceId(self): return self.DEFAULTServiceIdValue def getSessionId(self, reqHandler): """session.getSessionId(requestHandler) -> String | None ~ The current session id returned. If none return None. By default will look for a HTTP directive ServiceId""" return reqHandler.getEnviron(self.DEFAULTSessonIdKey) def load(self, reqHandler, session): "session.load(requestHandler) -> Session" def save(self, reqHandler, session): "session.session(requestHandler, self) -> None" def revert(self, reqHandler): "session.revert(requestHandler, self) -> None ~reverts the session to last saved copy." def expire(self, reqHandler, when): """ session.expire(requestHandler, when) -> None ~ if when is evals to a number will expire the session in when seconds, otherwise will try and parse when as a date. For more on this format see
RFC2068 section 3.3.1 [also RCF822 and RCF1123] """ def newSessionId(self): """ session.newSessionId(self.requestHandler) -> String ~ returns a new sessionId, preferably unique.""" class Session(mapClass): """Session Bridge""" def __init__(self, reqHandler, impl=None): """session = Session(requestHandler, SessionImplmentor()) ~ ctor's a session with the given request handler and session implementation instance""" mapClass.__init__(self) self.init(reqHandler, impl) self.setup() def init(self, reqHandler, impl): """ self.init(reqHandler, impl)-> None ~ template init method called by CTOR""" self.sessionId=None self.serviceId=None self.status='new' self.impl = impl #self.impl.session = ref(self) self.reqHandler= ref(reqHandler) #self.reqHandler= reqHandler self.expiresWhen=None def setup(self): """ self.setup()-> None ~ template method used to define relationship between session and requestHandler""" self.serviceId= self.getServiceId() self.sessionId= self.getSessionId() if not self.isNew(): self.load() def isNew(self): """ session.new()-> 1|0 ~ returns 1 if session was created on this request, otherwise 0 used to define relationship between session and requestHandler""" return self.status=="new" def getServiceId(self, reqHandler=None): """ session.getServiceId()-> String ~ returns serviceId, request passed on to the implementor.""" if reqHandler is None: reqHandler = self.reqHandler() if not self.serviceId: self.serviceId = self.impl.getServiceId(reqHandler) return self.serviceId def getSessionId(self, reqHandler=None): """ session.getSessionId()-> String ~ returns either the current sessionId or a new session id.""" if reqHandler is None: reqHandler = self.reqHandler() if not self.sessionId: self.sessionId = reqHandler.getEnviron(self.getServiceId(reqHandler)) if not self.sessionId: self.sessionId = self.impl.getSessionId(reqHandler) if not self.sessionId: self.status = 'new' self.sessionId = self.impl.newSessionId(reqHandler) self.purge(reqHandler) else: self.status='open' return self.sessionId def purge(self, reqHandler=None): self.impl.purge(reqHandler) def load(self, reqHandler=None): """ session.load()-> None ~ loads a session into its self.""" if reqHandler is None: reqHandler = self.reqHandler() try: session = self.impl.load(reqHandler, self) if session: expires = session.getExpire() if expires is not None and expires < time(): self.status = "new" return self.update(session) else: self.status = "new" except Exception, e: import traceback traceback.print_exc() self.status = "new" return {} def save(self, reqHandler=None): """ session.save()-> None ~ saves self.""" if reqHandler is None: reqHandler = self.reqHandler() self.reqHandler = None self.status = 'open' self.impl.save(reqHandler, self) self.reqHandler= reqHandler def getExpire(self): """ session.getExpire()-> float ~ returns when it will expire in secs since epoche.""" return self.expiresWhen def expire(self, when = None): #def expire(self, when = None): """ session.expire(when)-> None ~ expires session at time.time() + when, if eval(when) evalutes, otherwise tries to parse when and expire session at when. For more on this format see RFC2068 section 3.3.1 [also RCF822 and RCF1123] """ self.expireWhen = when self.impl.expire(self, self.reqHandler(), when) #self.impl.expire(self, self.req(), when) def setSession(self, reqHandler=None): """ session.setSession() -> None ~ adds session to request handler. """ if reqHandler is None: reqHandler = self.reqHandler() self.impl.setSession(self, reqHandler) class FileLoader(MixIn): DIRECTIVEtAG='PSOSessionFileLoader_' DIRECTIVES=('Path',) PATH = os.path.dirname(mktemp()) def getFileName(self, reqHandler, session): """session.getFileName(requestHandler) -> String ~ returns a fully qualified session file name.""" path = self.getPath(reqHandler) file = session.getSessionId(reqHandler) filename = os.path.join(path, file) return filename def getPath(self, reqHandler): """ session.getPath(requestHandler) -> String ~ returns the path where sessions will be stored.""" return self.getDirectives(FileLoader, reqHandler).get('Path', self.PATH) def purge(self, reqHandler=None): pass def newSessionId(self, reqHandler): """session.newSessionId(requestHandler) -> String ~ returns a new sessionId, preferably unique.""" id = os.path.basename(mktemp(self.getServiceId( reqHandler))) return id def load(self, reqHandler, session): """session.load(requestHandler) -> session ~ returns session. All thrown expections passed on.""" return load(open(self.getFileName(reqHandler, session),'r+b')) def save(self, reqHandler, session): """ session.save(requestHandler) -> None ~ saves session. All thrown expections passed on.""" file = self.getFileName(reqHandler, session) f = open(file,'w+b') dump( session, f) class CookieSession(MixIn): DIRECTIVEtAG='PSOCookieSession_' DIRECTIVES=('expires', 'Path','Comment','Domain','Max-Age','secure','Version') def getCookie(self, reqHandler): """ self.getCookie(requestHandler) -> String | None ~ returns the session cookie if found otherwise none""" cookie = reqHandler.getEnviron(reqHandler.getCookieKey()) if cookie: try: start=0 look4 = self.getServiceId(reqHandler)+'=' start = cookie.index(look4) start += len(look4) end = cookie.find(';', start) if end == -1: cookie = cookie[start:] else: cookie = cookie[start:end] return cookie.strip() except Exception, e: import traceback traceback.print_exc() return None def getSessionId(self, reqHandler): """self.getSessionId(requestHandler) -> String | None ~ The current session id returned. If none return None.""" return self.getCookie(reqHandler) def when(self, when): """self.when(when) -> None ~ utility method to build the correct cookie expire attributes.""" if not hasattr(self, 'attrs'): self.attrs = {} if when is not None: try: when = eval(str(when)) when = time() + when #self.attrs['Max-Age']= str(long(when)) self.attrs['expires'] = strftime("%a, %d %b %Y %H:%M:%S GMT", gmtime(when)) except: self.attrs['expires'] = when if self.attrs.has_key('Max-Age'): del self.attrs['Max-Age'] def expire(self, session, reqHandler, when = None): """ self.expire(session, requestHandler, when)-> None ~ expires session at time.time() + when, if eval(when) evalutes, otherwise tries to parse when and expire session at when. For more on this format see RFC2068 section 3.3.1 [also RCF822 and RCF1123] """ self.when(when) reqHandler.setSession(session) def getAttrs(self): """ self.getAttrs() -> Dictionary of cookie attributes ~ utility method for setting up the session cookie""" if hasattr(self, 'attrs'): return self.attrs else: return {} def setSession(self, session, reqHandler): """ self.setSession(session, reqHandler) -> None ~ adds session to request handler. Handles setting the cookie when the session is new. """ self.attrs = self.getAttrs() self.attrs.update(self.getDirectives(CookieSession, reqHandler)) value = reqHandler.getEnviron('PSOSessionExpires') if value: self.when(value) reqHandler.setCookie(session.getServiceId(), session.getSessionId(), **self.getAttrs()) class CookieFileImpl(CookieSession, FileLoader, SessionImpl): """ Default session implementation, using temporary files to store the session, and using a browser cookie to pass the session id accross requests.""" class FileSession(Session ): """ Default session bridge, using CookieFileImpl as the implementaion class""" def init(self, reqHandler,imp): Session.init(self, reqHandler, CookieFileImpl()) pso-0.98.D-beta/py/pso/table.py0100666000175200017510000000323507756466403015513 0ustar thanosusers# table.py - Python Service Objects # # Author: Thanos Vassilakis thanos@@0x01.com # # # Copyright (c) thanos vassilakis 2000,2001, 2002 # # This library 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. # # This library 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 Lesser General Public License for more details. # # See terms of license at gnu.org. # $Id: table.py,v 1.5 2002/06/19 15:23:25 thanos Exp $ # __version__="$Revision: 1.5 $" from types import ListType try: mapClass = dict except: import UserDict mapClass = UserDict.UserDict class Table(mapClass): def add(self, key, value): try: self[key.lower()].append(value) except: self[key.lower()] = [value] def set(self, key, value): self[key.lower()] = [value] def __repr__(self): text="" for k, v in self.flatten(): text += "%s: %s\n" % ( k,v) return text def flatten(self): items=[] for key, values in self.items(): if type(values) is ListType: for value in values: items.append((key,value)) else: items.append((key,values)) return items class CIMap(mapClass): def __setitem__(self, key, item): mapClass.__setitem__(self, key.lower(), item) if __name__ =='__main__': print Table.__bases__ t = Table() t.add("cookie-set","me") t.add("cookie-set","you") t.add("max-set","1") t.set("max-set","2") print t pso-0.98.D-beta/py/pso/tags.py0100666000175200017510000001500010024141047015323 0ustar thanosusers# # tags.py - Python Service Objects # # Author: Thanos Vassilakis thanos@0x01.com # # Copyright (c) thanos vassilakis 2000,2001, 2002 # # This library 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. # # This library 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 Lesser General Public License for more details. # # See terms of license at gnu.org. # # $Id: tags.py,v 1.9 2003/11/18 19:04:23 thanos Exp $ # from parser import Tag from handlers import TemplateHandler import sys from cStringIO import StringIO from util import log class Template(Tag, TemplateHandler): FIELD_NAME='action' def getTemplate(self, req): return req.getInput(self.FIELD_NAME, self.getDefaultTemplate(req)) def __call__(self, handler, cdata=''): # return self.getTemplate( handler) return self.parse(handler.req()) def getDefaultTemplate(self, req): default = self.attrs.get('default') if not default: raise 'please set tag attribute default or override me %s' % self.getDefaultTemplate return default class Exec(Tag): def __call__(self, handler, cdata=''): if not cdata: return '' oldout = sys.stdout try: sys.stdout = StringIO() exec cdata retval = sys.stdout.getvalue() sys.stdout.close() finally: sys.sdtout = oldout return retval class DataMixin: KEY=None def getKey(self, handler): return self.KEY def getRecId(self, handler, key): return handler.req().getInput(key) def getRecord(self, handler, key): pass def record(self, handler): key = self.getRecId(handler, self.getKey(handler)) if key: scratchKey = (self.DATAMODEL, key) record = handler.scratch().get(scratchKey) if not record: record = self.getRecord(handler, key) if record: handler.scratch()[scratchKey] = record return record def getSelect(self, handler): pass def getSelection(self, handler, select): pass def getRecNumber(self, handler): return len(self.selection(handler)) def selection(self, handler): criteria = self.getSelect(handler) scratchKey = (self.DATAMODEL, 'select', tuple(criteria.items())) cursor = handler.scratch().get(scratchKey) if not cursor: cursor = self.getSelection(handler, criteria) if cursor: handler.scratch()[scratchKey] = cursor return cursor class OutLine(Tag): DELIMITER=',' LI='
  • %s
  • ' NAME='' def getValue(self, handler): field = self.attrs.get('name', self.NAME) value = self.record(handler).get(field) return value def getList(self, value): value = value.strip() delimiter = self.attrs.get('delimiter', self.DELIMITER) list = value.split(delimiter) return list def __call__(self, handler, cdata=''): try: return ''.join(map(lambda x: self.LI % x, self.getList(self.getValue(handler)))) except: return '' class Condition(Tag): def toShow(self, handler): return 1 def __call__(self, handler, cdata=''): if self.toShow(handler): return cdata return '' class Label(Tag): def toShow(self, handler): field = self.attrs.get('field') return field and self.record(handler).get(field) class List(Tag): PAGEsIZEkEY="pagesize" LINEkEY="line" PAGEsIZE= 10 HTML = '%s' NA='NA' ROWfIELDS=() def fetch(self, handler, line, pageSize): cursor = self.selection(handler) return cursor.fetch(line=line, pageSize= pageSize) def __call__(self, handler, cdata): records = self.getRows(handler) html = '' for record in records: html += cdata % self.prepareRow(handler, record) return html def getPageSize(self, handler): return int(handler.req().getInput( self.PAGEsIZEkEY, self.getAttrs().get(self.PAGEsIZEkEY, self.PAGEsIZE))) def getLine(self, handler): return int(handler.req().getInput( self.LINEkEY, self.getAttrs().get(self.LINEkEY, '1'))) def getRows(self, handler): return self.fetch(handler, line=self.getLine(handler), pageSize= self.getPageSize(handler)) def prepareRow(self, handler, record): for field in self.ROWfIELDS: if field not in record: record[field] = self.NA " must return an dictionary of fields that will be merged with the cdata" return record def next(self, handler, cdata): line = self.getLine(handler) pageSize = self.getPageSize(handler) if line < self.getRecNumber(handler) - pageSize: url = handler.req().getUrl().copy() url[self.LINEkEY] = line + pageSize return self.HTML % (url, self.getEnabled(cdata)) else: return self.getDisabled(cdata) def prev(self, handler, cdata): line = self.getLine(handler) pageSize = self.getPageSize(handler) if line > pageSize: url = handler.req().getUrl().copy() url[self.LINEkEY] = line - pageSize return self.HTML % (url, self.getEnabled(cdata)) else: return self.getDisabled(cdata) def getEnabled(self, cdata): return cdata def getDisabled(self, cdata): return cdata class TwoColumnList(List): ACTION='' def getRows(self, handler): rows = List.getRows(self, handler) if len(rows) % 2: if type(rows) is type([]): rows = tuple(rows) rows = rows + ('',) return [ i for n,i in zip(xrange(100), zip(rows, rows[1:])) if n % 2==0] def prepareRow(self, handler, record): url = handler.req().getUrl().copy() row={} row['uri0'] = url.uri(action=self.ACTION, category=record[0]) row['uri1'] = url.uri(action=self.ACTION, category=record[1]) row['cat0'] = record[0] row['cat1'] = record[1] return row class DbMixin(DataMixin): DATAMODEL = None TABLE=None TABLENAME = 'table' QS_TABLENAME = TABLENAME KEYNAME= "loginId" QS_KEYNAME= KEYNAME KEY=None def getField(self, handler, qs_key, key, default=None): value = handler.req().getInput(qs_key) if not value: value = self.attrs.get(key, default) return value def getTable(self, handler): tabelname = self.getField(handler, self.QS_TABLENAME, self.TABLENAME, self.TABLE) if tablename: return getattr(self.DATAMODEL, tablename) def getKey(self, handler): return self.getField(handler, self.QS_KEYNAME, self.KEYNAME, self.KEY) def getRecord(self, handler, key): table = self.getTable(handler) return datamodel.get(table, key) def getSelection(self, handler, selectCriteria): cursor = datamodel.select(datamodel.Contractor, selectCriteria) return cursor pso-0.98.D-beta/py/pso/url.py0100644000175200017510000000756410074405155015213 0ustar thanosusers# # pso.url.py - Python Service Objects # # Author: Thanos Vassilakis thanos@0x01.com # # Copyright (c) thanos vassilakis 2000,2001, 2002 # # This library 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. # # This library 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 Lesser General Public License for more details. # # See terms of license at gnu.org. # # $Id: url.py,v 1.5 2004/07/12 03:50:05 thanos Exp $ # # created: thanos vassilakis 1/21/2001 # # LGPL # # __version__="$Revision: 1.5 $" from urlparse import urlsplit, urlunsplit from cgi import parse_qs from urllib import urlencode from xml.sax.saxutils import quoteattr from copy import deepcopy class Url(object): _query=None _script=None def __init__(self, url, scheme="html"): self.scheme, self.netlocation, self.path, query, self.fragment = urlsplit(url, scheme) self.queryTD = self.decryptQuery(query) self.changed=1 self._formFields ="" def decryptQuery(self, query): return query def encryptQuery(self, query): return query def processQuery(self): if self._query is None: self._query = parse_qs(self.queryTD) return self._query query = property(processQuery) def getScript(self): if self.changed or self._script is None: self._script = urlunsplit((self.scheme, self.netlocation, self.path,'','')) return self._script script = property(getScript) def getBase(self): if self.changed or self._script is None: self._script = urlunsplit((self.scheme, self.netlocation, '','','')) return self._script base = property(getBase) def __setitem__(self, key, value): self.changed=1 self.query[key] = value def __delitem__(self, key): try: self.changed=1 del self.query[key] except: pass def __getitem__(self,key): value= self.query.get(key, None) if type(value) is type([]): if len(value) == 1: return value[0] return value def clear(self, *args): if not args: self.query.clear() else: for arg in args: del self[arg] def append(self, key, value): self.changed=1 try: self.query[key].append(value) except: self.query[key]=[value] NDICT={} def __str__(self): if self.changed: self.queryTD= urlencode(self.query, self.query.items()) return urlunsplit((self.scheme, self.netlocation, self.path, self.encryptQuery(self.queryTD), self.fragment)) def getFormFields(self): if self.changed: self._formFields ="" for k, values in self.query.items(): if values: if type(values) is type([]): for v in values: self._formFields = '%s\n' % (self._formFields, k, v) else: self._formFields = '%s\n' % (self._formFields, k, values) return self._formFields formFields = property(getFormFields) def copy(self): return deepcopy(self) def uri(self, **kws): query ={} if not kws.get('_cleanup', True): query.update(self.query) for k,v in kws.items(): if v is None: del kws[k] if k in query: del query[k] else: query[k] = v query = self.encryptQuery(urlencode(query, query.items())) return urlunsplit(('','',self.path, query, '')) def aHref(self, cdata, **kws): query = self.encryptQuery(urlencode(kws, kws.items())) return '%s' %(urlunsplit(('','',self.path, query, '')), cdata) def newA(self, uri, cdata, **attr): attrlist = ["%s=%s" % (k, quoteattr(v)) for k,v in attr.items() if v] attrlist.extend([k for k,v in attr.items() if not v]) attrlist = ' '.join(attrlist) return '%s' %( uri, attrlist, cdata) pso-0.98.D-beta/py/pso/util.py0100644000175200017510000000542410074405047015357 0ustar thanosusers# # $RSCFile$ - Python Service Objects # # Author: Thanos Vassilakis thanos@0x01.com # # # Copyright (c) thanos vassilakis 2000,2001, 2002 # # This library 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. # # This library 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 Lesser General Public License for more details. # # See terms of license at gnu.org. # $Id: util.py,v 1.11 2004/07/12 03:48:55 thanos Exp $ # __version__="$Revision: 1.11 $" import time, gc, sys, weakref class Log: def __init__(self, path=None): self.logfile = path def log(self, *args): args = map(str, args) post = "\n%s: %s" % ( time.ctime(), ' '.join(args)) try: open(self.logfile,'a').write(post) except: import traceback traceback.print_exc() import os, tempfile logger=Log(os.environ.get('PSOLOG',os.path.join(tempfile.gettempdir(), 'pso.log'))) log = logger.log class MixIn: def getDirectives(self, objclass, reqHandler): directives ={} for key in objclass.DIRECTIVES: lkey = objclass.DIRECTIVEtAG + key value = reqHandler.getEnviron( lkey) if value: directives[key] = value return directives def mkDict(**kv): return kv def get(dict,key, default=None): if dict.has_key(key): return dict[key] return default """ class GCDumper: def __init__(self): " set up gc in debug mode" gc.enable() gc.set_debug(gc.DEBUG_LEAK) def dump(self, file=None): " dumps to file, file=stdout by defaut, garbadgeed objects" gc.collect() if file is None: file = sys.stdout for x in gc.garbage: strX = str(x) if len(strX) > 80: tail = '...' else: tail ='' file.write("%s: %s%s\n" % ( type(x), strX[:77], tail)) class meta_ObjTracker: classes = {} def instance(celf, obj): ref = weakref.ref(obj) key = obj.__class__.__name__ try: celf.classes[key].append(ref) except: celf.classes[key] = [ref] instance = classmethod(instance) def report(celf, classes=None): if classes is None: classes = celf.classes.keys() else: classes = classes.split() classes.sort() for name in classes: for ref in celf.classes[name]: obj =ref() if obj is not None: print obj report = classmethod(report) """ if __name__ =='__main__': d = GCDumper() l =[] l.append(l) del l d.dump() class A: def __init__(self): ObjTracker.instance(self) class B: def __init__(self): ObjTracker.instance(self) def test(): a =A() b = B() for i in xrange(10): test() ObjTracker.report() pso-0.98.D-beta/py/pso/validation.py0100666000175200017510000000311010074403033016517 0ustar thanosusers# # Copyright (c) thanos vassilakis 2000,2001, 2002 # # This library 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. # # This library 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 Lesser General Public License for more details. # # See terms of license at gnu.org. # # $Id: validation.py,v 1.1 2003/01/24 17:33:24 thanos Exp $ __version__="$Revision: 1.1 $" import traceback def isZipCode(zipCode): try: sz = len(zipCode) if sz == 10: zipCode.index('-',5) int(zipCode[:5]) int(zipCode[6:]) elif sz in (5, 9): code = int(zipCode) else: raise Exception() except: raise Exception('Invalid zip code, must be 5 or 9 digits') return zipCode def test(funcwhat, res1, res2, show=0): print "trying ", funcwhat, try: exec(funcwhat) except: if show: traceback.print_exc() print res2 else: print res1 if __name__ =='__main__': test( "isZipCode('12345-6789')", "OK", "failed") test( "isZipCode('123456789')", "OK", "failed") test( "isZipCode('12345')", "OK", "failed") test( "isZipCode('12345678')", "OK", "failed") test( "isZipCode('1234256789AB')", "OK", "failed") pso-0.98.D-beta/setup.py0100644000175200017510000000151510074410551014302 0ustar thanosusers#!/usr/bin/env python23 from distutils.core import setup setup(name="pso", version="0.98.D-beta", description="Python Service Objects - An object orientated web development framework.", author="thanos vassilakis", author_email="thanos@scriptfoundry.com", url="http://sourceforge.net/projects/pso", package_dir = {'': 'py'}, packages=['pso'], ) """ classifiers= ['Topic :: Internet :: WWW/HTTP :: Dynamic Content', 'Topic :: Internet :: WWW/HTTP :: Dynamic Content :: CGI Tools/Libraries', 'Topic :: Software Development :: Libraries :: Python Modules', 'Environment :: Web Environment', 'License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)', 'Operating System :: OS Independent', 'Programming Language :: Python', 'Intended Audience :: Developers'] """ pso-0.98.D-beta/PKG-INFO0100644000175200017510000000045710074410553013673 0ustar thanosusersMetadata-Version: 1.0 Name: pso Version: 0.98.D-beta Summary: Python Service Objects - An object orientated web development framework. Home-page: http://sourceforge.net/projects/pso Author: thanos vassilakis Author-email: thanos@scriptfoundry.com License: UNKNOWN Description: UNKNOWN Platform: UNKNOWN