from OFS.Folder import Folder
from Acquisition import Implicit
from Globals import DTMLFile,package_home,Persistent
import urllib
import re
import string
#from pyPgSQL import libpq
from AccessControl import getSecurityManager,Unauthorized
from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate
from Products.PageTemplates.PageTemplateFile import PageTemplateFile
from Products.ZSQLMethods.SQL import SQLConnectionIDs
from xml.sax.saxutils import escape
from types import *
import Shared.DC.ZRDB.DA
import logging
import os.path
import os
import copy
import unicodedata
import tempfile
import sys
#ersetzt logging
def logger(txt,method,txt2):
"""logging"""
logging.info(txt+ txt2)
from OFS.SimpleItem import SimpleItem
def getTextFromNode(nodename):
"""get the cdata content of a node"""
if nodename is None:
return ""
nodelist=nodename.childNodes
rc = ""
for node in nodelist:
if node.nodeType == node.TEXT_NODE:
rc = rc + node.data
return rc
def analyseIntSearch(word):
#analyse integer searches
splitted=word.split("-")
if len(splitted)==1:
return "="+splitted[0]
if splitted[0]=="":
return "< "+splitted[1]
if splitted[1]=='':
return "> "+splitted[0]
else:
return "BETWEEN "+splitted[0]+" AND "+splitted[1]
def unicodify(str):
"""decode str (utf-8 or latin-1 representation) into unicode object"""
if not str:
return u""
if type(str) is StringType:
try:
return str.decode('utf-8')
except:
return str.decode('latin-1')
else:
return str
def utf8ify(str):
"""encode unicode object or string into byte string in utf-8 representation"""
if not str:
return ""
if type(str) is StringType:
return str
else:
return str.encode('utf-8')
def setPsycopg2UseUnicode():
"""force Psycopg2DA to return unicode objects"""
try:
import psycopg2
import psycopg2.extensions
psycopg2.extensions.register_type(psycopg2.extensions.UNICODE)
except:
logging.error("Unable to force psycopg2 to use unicode")
def sql_quote(v):
# quote dictionary
quote_dict = {"\'": "''", "\\": "\\\\"}
for dkey in quote_dict.keys():
if string.find(v, dkey) >= 0:
v=string.join(string.split(v,dkey),quote_dict[dkey])
return "'%s'" % v
def showSQLConnectionIDs(self):
return SQLConnectionIDs(self)
class Options:
"""options class"""
class ZSQLIndex(SimpleItem):
"""index"""
meta_type="ZSQLIndex"
def __init__(self,index,id,table=''):
self.index=[x for x in index]
self.id=id
self.table=table
def setIndex(self,index):
self.index=[x for x in index]
def getIndex(self):
return self.index
class ZSQLExtendFolder(Folder,Persistent, Implicit):
"""Klasse die Methoden fuer die Abfrage einer SQL-Datenbank zur Verfuegung stellt.
"""
meta_type="ZSQLExtendFolder"
def ZSQLQuote(self,str):
"""quote str for sql"""
return sql_quote(str)
def normalizeField(self,table,fieldname, newFieldName=None,mode="alter", RESPONSE=None):
"""normalize a field, d.h. entfernt alle diakritischen Zeichen und ersetzt diese
durch den Grundbuchstaben in einer Spalte einer Tabelle
@param table: Tabellename
@param fieldname: Name der Spalte
@param newFieldName: (optional) default ist fieldname+"_normal"
@param mode: (optional) default ist "alter". Mode "alter" aendert ein bestehendes Feld newFieldName, mode "create" erzeugt diese zuerst.
"""
import unicodedata
if not newFieldName:
newFieldName=fieldname+"_normal"
#normalisierungs routine
def normal(str):
if str:
return unicodedata.normalize('NFKD', str.decode('utf-8')).encode('ASCII', 'ignore')
else:
return ""
if mode=="create": # create the field
qstr="""alter table %s add %s %s"""
self.ZSQLSimpleSearch(qstr%(table,newFieldName,'text'))
qstr="select oid,%s from %s"%(fieldname,table)
for result in self.ZSQLSimpleSearch(qstr):
qstr="update %s set %s = %s where oid = %s"
self.ZSQLSimpleSearch(qstr%(table,newFieldName,self.ZSQLQuote(normal(getattr(result,fieldname))),result.oid))
def importAccessModell(self,configFileName,RESPONSE=None):
"""import tables from access
@param configFileName: xml-configfile
"""
from Ft.Xml import Parse
fh=file(configFileName)
doc=Parse(fh)
x=doc.xpath("//pathToFolder/@path")
if not (len(x)==1): # tag ist nich eineindeutig
return False
pathToFolder=x[0].value
for db in doc.xpath("//db"):
containers=db.xpath("./@container")
identifiers=db.xpath("./@identify")
if not (len(containers)==1):
return False
else:
container=containers[0].value
if not (len(identifiers)==1):
identifier=None
else:
identifier=identifiers[0].value
self.xsdToTable(container.lower(),container,modus="drop",filename=os.path.join(pathToFolder,container.lower()+".xsd"))
self.importXMLFileAccess(container.lower(),container,filename=os.path.join(pathToFolder,container.lower()+".xml"),identify=identifier)
return "<html><body>DONE</body></html>"
def xsdToTable(self,table,elementNameForTable,modus="update", filename=None,data=None,RESPONSE=None):
"""reads an xsd file an creates the columns of a table out of its structure
@param table: name of the table the xml shall be imported into
@param elementNameForTable: must be a element of type complex type. the element of the sequence in the complex type
define the columns of the table >table<
@param data (optional): data to be imported
@param filename (optional) or filename
@param identify: (optional) field res. tag which identifies a entry uniquely for updating purposes.
@param RESPONSE: (optional)
"""
#from xml.dom.minidom import parseString,parse
from Ft.Xml import Parse
logger("import xsd",logging.INFO,"called")
#fh=file("/tmp/fmpxml.xml")
import bz2
import base64
ret=""
if data:
data=bz2.decompress(base64.decodestring(data))
#logger("import xsd",logging.INFO,"received file")
doc=Parse(data)
#logger("import xsd",logging.INFO,"parsed file")
elif filename:
fh=file(filename)
txt=fh.read()
doc=Parse(txt)
#logger("import xsd",logging.INFO,"parsed file")
Nss={'xsd':'http://www.w3.org/2001/XMLSchema'}
definingSequence=doc.xpath("""//xsd:element[@name='%s']/xsd:complexType/xsd:sequence/xsd:element/@name"""%elementNameForTable,explicitNss=Nss)
fieldNames=[x.value for x in definingSequence]
#check if table exists
qstr="""select relname from pg_class where relname = '%s'"""%table
if not(self.ZSQLSimpleSearch(qstr)) or (len (self.ZSQLSimpleSearch(qstr))<1): # if not the create the table
columns=[]
create=True
else:
create=False
logger("update xsd: fieldnames",logging.INFO,repr(fieldNames))
qstr="""select attname from pg_attribute, pg_class where attrelid = pg_class.oid and relname = '%s' """
columns=[x.attname for x in self.ZSQLSimpleSearch(qstr%table)]
if (modus=="drop") and (not create): #table shall be deleted, therefore it should exist (not create)
print "drop"
qstr="""DROP TABLE %s """
self.ZSQLSimpleSearch(qstr%table)
columns=[]
create=True
for fieldName in fieldNames:
if type(fieldName) is UnicodeType:
fieldName=fieldName.encode('utf-8')
logging.info("update xml: fieldname",logging.INFO,repr(fieldName))
if fieldName.lower() not in columns:
if create:# table does not exist therefore create with one column
qstr="""create table %s (%s %s)"""
create=False
else:# otherwise add the field
qstr="""alter table %s add %s %s"""
self.ZSQLSimpleSearch(qstr%(table,fieldName,'text'))
logger("update xsd: fieldname add",logging.INFO,qstr%(table,fieldName,'text'))
def importXMLFileAccess(self,table,container,data=None,identify=None,filename=None,RESPONSE=None):
'''
Import XML file in access format into the table
@param table: name of the table the xml shall be imported into
@param containerTagName: XML-Tag which describes a dataset
@param data: data to be imported
@param identify: (optional) field res. tag which identifies a entry uniquely for updating purposes.
@param RESPONSE: (optional)
'''
from xml.dom.pulldom import parseString,parse
logger("import xml",logging.INFO,"called")
#fh=file("/tmp/fmpxml.xml")
import bz2
import base64
ret=""
if data:
data=bz2.decompress(base64.decodestring(data))
logger("import xml",logging.INFO,"received file")
doc=parseString(data)
logger("import xml",logging.INFO,"parsed file")
elif filename:
fh=file(filename)
doc=parse(fh)
logger("import xml",logging.INFO,"parsed file")
while 1:
node=doc.getEvent()
if node is None:
break;
else:
if node[1].nodeName.lower()==container.lower(): # make everything case insensitive
doc.expandNode(node[1])
dataSet={}
for col in node[1].childNodes:
if col.nodeType is col.ELEMENT_NODE:
data=col.nodeName
dataSet[data]=getTextFromNode(col)
update=False
if identify:
field=dataSet[identify]
searchStr="""select %s from %s where %s = '%s'"""%(identify,table,identify,field)
logger("import xml",logging.INFO,searchStr)
search=self.ZSQLSimpleSearch(searchStr)
if search:
update=True
if update:
tmp=[]
for fieldName in dataSet.keys():
tmp.append("""%s = %s"""%(fieldName,self.ZSQLQuote(dataSet[fieldName])))
setStr=",".join(tmp)
field=dataSet[identify]
queryStr="""UPDATE %s SET %s WHERE %s = '%s' """%(table,setStr,identify,field)
logger("update xml",logging.INFO,queryStr)
self.ZSQLSimpleSearch(queryStr)
ret+="ud: %s \n"%field
else:
fields=",".join(dataSet.keys())
values=",".join([""" %s """%self.ZSQLQuote(dataSet[x]) for x in dataSet.keys()])
queryStr="""INSERT INTO %s (%s) VALUES (%s)"""%(table,fields,values)
self.ZSQLSimpleSearch(queryStr)
logger("update xml",logging.INFO,queryStr)
return ret
def importXMLFileFMP(self,tables,dsn=None,uploadfile=None,update_fields=None,id_field=None,sync_mode=False,
lc_names=True,keep_fields=False,ascii_db=False,replace=False,backup=False,
debug=False,log_to_response=False,
redirect_url=None,RESPONSE=None):
'''
Import FileMaker XML file (FMPXMLRESULT format) into the table.
@param dsn: database connection string
@param table: name of the table the xml shall be imported into
@param uploadfile: xmlfile file
@param update_fields: (optional) list of fields to update; default is to create all fields
@param id_field: (optional) field which uniquely identifies an entry for updating purposes.
@param sync_mode: (optional) really synchronise, i.e. delete entries not in XML file
@param lc_names: (optional) lower case and clean up field names from XML
@param keep_fields: (optional) don't add fields to SQL database
@param ascii_db: (optional) assume ascii encoding in db
@param replace: (optional) delete and re-insert data
@param backup: (optional) create backup of old table (breaks indices)
@param RESPONSE: (optional)
@param redirect_url: (optional) url for redirecting after the upload is done
'''
tfilehd,filename=tempfile.mkstemp()
tfile=os.fdopen(tfilehd,'w')
logging.info("import %s"%uploadfile)
for c in uploadfile.read():
tfile.write(c)
tfile.close()
from importFMPXML import importFMPXML
if not dsn:
dsn=self.getConnectionObj().connection_string
tablelist=tables.split(',')
logging.debug("tablelist: %s" %tablelist)
#table=tables
for table in tablelist :
logging.debug("table: %s" %table)
options=Options()
options.dsn=dsn
options.table=table
options.filename=filename
options.update_fields=update_fields
options.id_field=id_field
options.sync_mode=sync_mode
options.lc_names=lc_names
options.replace_table=replace
options.keep_fields=keep_fields
options.ascii_db=ascii_db
options.replace_table=replace
options.backup_table=backup
options.debug=debug
if RESPONSE and log_to_response:
# set up logging to response as plain text
RESPONSE.setHeader("Content-Type","text/plain; charset=utf-8")
RESPONSE.write("Import FMPXML file...\n\n")
loghandler = logging.StreamHandler(RESPONSE)
if debug:
loghandler.setLevel(logging.DEBUG)
else:
loghandler.setLevel(logging.INFO)
logger = logging.getLogger('db.import.fmpxml')
logger.addHandler(loghandler)
options.use_logger_instance = logger
importFMPXML(options)
if RESPONSE and log_to_response:
loghandler.flush()
RESPONSE.write("\n\n DONE!")
elif RESPONSE and redirect_url:
RESPONSE.redirect(redirect_url)
os.remove(filename)
def generateIndex(self,field,index_name,table,RESPONSE=None):
"""erzeuge ein Index Objekt einem Feld (experimental)
@param field: Feldname zu dem ein Index erzeugt werden soll
@param index_name: Name des Index
@param table: Tabellen name"""
index={}
founds=self.ZSQLSimpleSearch("""SELECT %s,oid FROM %s """%(field,table))
for found in founds:
tmp=getattr(found,field,None)
if tmp:
strings=tmp.split(" ")
for string in strings:
if index.get(string):
index[string].append(found.oid)
else:
index[string]=[found.oid]
RESPONSE.write(string+"\n")
if not hasattr(self,index_name):
obj=ZSQLIndex(index,index_name,table)
self._setObject(index_name,obj)
self._getOb(index_name).setIndex(index)
def getIndex(self,index_name):
"""getIndex from index_name
return an indexObject with index_name
"""
founds=self.ZopeFind(self,obj_ids=[index_name])
return founds[0][1].getIndex()
def URLquote(self,txt):
"""urlquote"
@param txt: text der urlgequoted werden soll.
"""
return urllib.quote(txt)
def createIdSet(self, resultset, idField=None):
"""returns a (frozen)set of IDs from a SQL-resultset (using idField) or a list (if idField=None)"""
logging.debug("createidset for idfield %s"%idField)
if idField is None:
return frozenset(resultset)
else:
idlist = [r[idField] for r in resultset]
return frozenset(idlist)
def opIdSet(self, a, b, op):
"""operate on sets a and b"""
logging.debug("opidset with op %s"%op)
if (op == 'intersect'):
return a.intersection(b)
elif (op == 'union'):
return a.union(b)
elif (op == 'diff'):
return a.difference(b)
def searchRel(self,relStatement,statement,wherePart,classes):
"""suche relative haufigkeiten (experimental)"""
ret={}
allRecords=len(self.ZSQLSimpleSearch(statement + " where "+wherePart))
for oneclass in classes:
ret[oneclass]=len(self.ZSQLSimpleSearch(statement + " where ("+wherePart+") and "+ relStatement%oneclass))
return (ret,allRecords)
def content_html(self):
"""template fuer content_html Aufruf, notwendig fuer Kompatibiliaet bei gemeinsamem Einsatz mich ECHO-Produkt"""
try:
obj=getattr(self,"ZSQLBibliography_template")
return obj()
except:
pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','ZSQLBibliography_template_standard.zpt'),content_type='text/html').__of__(self)
pt.content_type="text/html"
return pt()
def getWeight(self):
"""getWeight, gewicht notwendig fuer Kompatibiliaet bei gemeinsamem Einsatz mich ECHO-Produkt"""
try:
return self.weight
except:
return ""
def getLabel(self):
"""getLabel notwendig fuer Kompatibiliaet bei gemeinsamem Einsatz mich ECHO-Produkt"""
try:
return self.label
except:
return ""
def getDescription(self):
"""getDEscription: notwendig fuer Kompatibiliaet bei gemeinsamem Einsatz mich ECHO-Produkt"""
try:
return self.description
except:
return ""
manage_options=Folder.manage_options+(
{'label':'Main Config','action':'changeZSQLExtendForm'},
)
def changeZSQLExtendForm(self):
"""change folder config"""
pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','changeZSQLExtendForm.zpt')).__of__(self)
return pt()
def changeZSQLExtend(self,label,description,weight=0,connection_id=None,REQUEST=None,):
"""change the Konfiguration"""
self.connection_id=connection_id
self.weight=weight
self.label=label
self.description=description
if REQUEST is not None:
return self.manage_main(self, REQUEST)
def formatAscii(self,str,url=None):
"""ersetze ascii umbrueche durch <br>
@param str: string der Formatiert werden soll.
@param url: (optional) default ist "None", sonderfall erzeugt einen Link aus String mit unterliegender url
"""
#logging.debug("formatascii str=%s url=%s"%(repr(str),repr(url)))
if not str:
return ""
str=str.rstrip().lstrip()
if url and str:
retStr=""
words=str.split("\n")
for word in words:
strUrl=url%word
#print "str",strUrl
retStr+="""<a href="%s">%s</a><br/>"""%(strUrl,word)
str=retStr
if str:
retStr = re.sub(r"[\n]","<br/>",str)
#logging.debug("formatascii out=%s"%(repr(retStr)))
return retStr
else:
return ""
def getSAttribute(self,obj,atribute,pref=''):
"""get Attribute or emptystring"""
#print "obj",obj
try:
return pref+getattr(obj,atribute)
except:
return ""
def getS(self,str):
"""make none to empty string"""
if str:
return str
else:
return ""
def actualPath(self,url=None):
"""path"""
if self.REQUEST['HTTP_X_FORWARDED_SERVER']=='':
host=self.REQUEST['HTTP_HOST']
else:
host=self.REQUEST['HTTP_X_FORWARDED_SERVER']
if not url:
return "http://"+host+self.REQUEST['PATH_TRANSLATED']
else:
temp=self.REQUEST[url].split("/")
temp[2]=host
return string.join(temp,"/")
def getRequest(self):
"""request"""
return self.REQUEST
def lowerEnd(self,path):
"""oinly for demo"""
return os.path.splitext(path)[0]+".jpg"
def ZSQLisEmpty(self,str):
"""Teste ob String leer bzw. none ist.
"""
#print "field",field
if not str:
return 1
if str.strip()=="":
return 1
return 0
def ZSQLMultiSearch(self,_table,_searchField,_value,_idField,_additionalStatement="",_select=None,_subselectAddition="",_storename=None):
"""
Durchsucht in einer Tabelle "table" die Spalte "searchfield" nach dem allen Vorkommnissen
von Worten in value und gibt alle Werte mit gleichem id field zurŸck, d.h. es wird die "und" suche Ÿber mehrere Eintrsege in einer
Tabelle mit gleichem idField werd realisiert,
z.B. fŸr simplesearch ueber mehrere Felder
@param _table: Tabelle, die durchsucht werden soll.
@param _searchField: Feld, das durchsucht wird
@param _value: String der gesucht werden soll, gesucht wird nach allen Worten des Strings, die durch " "-getrennt sind.
@param _idField: Feld mit id fŸr die identifikation gleicher EintrŠge
@param _additionalStatement: (optional) Zusaetzliches SQL Statement, dass zwischen dem ersten "select from" und dem ersten "where" eingegefŸgt wird.
@param _select: (optional) Alternativer Wert fŸr den ersten SELECT Aufruf.
@param _storename: (optional) Name fuer die Zwischenspeicherung von Werten in der Session
"""
if _storename:
"""store"""
else:
_storename="foundCount"
queries=[]
#baue jede einzelne abfrage
splitted=_value.split(" ")
if not _select:
_select=_idField
query="select %s from %s %s where lower(%s) like '%%%s%%'"%(_select,_table,_additionalStatement,_searchField,splitted[0].lower())
if len(splitted)>1: # mehr als ein Wort
query+=" and %s in"%_idField # dann einschraenken
for v in splitted[1:]:
queries.append("select %s from %s %s where lower(%s) like '%%%s%%'"%(_idField,_table,_subselectAddition,_searchField,v.lower()))
intersect=" intersect ".join(queries) # nun baue sie zusammen
query+="(%s)"%intersect
logging.info("ZSQLSimple: %s"%query)
retT=self.ZSQLSimpleSearch(query)
logging.info("ZSQLSimple: %s"%retT)
#das Ergebis enthaelt unter u.U. eine id mehrfach, dieses wir jetzt vereinheitlicht.
retFinalT={}
for x in retT:
split=_idField.split(".")
if len(split)>1:
f=split[1]
else:
f=_idField
retFinalT[getattr(x,f)]=x
ret=list(retFinalT.values())
#aus Kompatibilaetsgruenen mit ZSQLSearch / ZSQLInlineSeach noch einzelne Felder in der SESSION belegen.
if not self.REQUEST.SESSION.has_key(_storename):
self.REQUEST.SESSION[_storename]={}
self.REQUEST.SESSION[_storename]['searchFieldsOnly']={}
self.REQUEST.SESSION[_storename]['qs']=query
return ret
def ZSQLsearchOptions(self,fieldname=""):
"""return HTML Fragment with search options"""
ret="""<select name="-op_%s">
<option value="bw">begins with</option> <!-- begins with / beginnt mit, "Wort*" -->
<option value="ew">ends with</option>
<option value="ct" selected>contains</option> <!-- contains / enthaellt, "Wort" -->
<option value="eq">equals</option> <!-- equals / ist, =Wort -->
</select>"""%fieldname
return ret
def ZSQLSelectionFromCRList(self,fieldname,listField,boxType="checkbox",checked=None):
"""generate selection HTML Fragemnt from a cr seperated list
@param fieldname: Wert fuer das "name"-Attribute der erzeugten input-Tags
@param listField: "cr" (\n) getrennte Liste der Werte
@param boxType: (optional) default ist "checkbox", moegliche Werte "checkbox" und "radio"
@param checked: "cr" getrennt Liste von Werten aus listField, die als ausgewahlt markiert werden sollen.
"""
fields=listField.split("\n")
ret=""
for field in fields:
if checked and (field in checked.split("\n")):
ret+="""<input name="%s" type="%s" value="%s" checked>%s"""%(fieldname,boxType,field.encode('utf-8'),field.encode('utf-8'))
else:
ret+="""<input name="%s" type="%s" value="%s">%s"""%(fieldname,boxType,field.encode('utf-8'),field.encode('utf-8'))
return ret
def ZSQLSelectionFromSearchList(self,fieldname,results,fieldnameResult,boxType="checkbox",checked=None):
"""generate select options from research-results Objekt
generate selection HTML Fragemnt from a cr seperated list
@param fieldname: Wert fuer das "name"-Attribute der erzeugten input-Tags
@param results: result Object einer SQL-suche
@param fieldNameResult: Feldname des Resultobjekts, das angezeigt werden soll.
@param boxType: (optional) default ist "checkbox", moegliche Werte "checkbox" und "radio"
@param checked: "cr" getrennt Liste von Werten aus results.fieldNameResult, die als ausgewahlt markiert werden sollen.
"""
ret=""
if not results: return ""
for result in results:
field=getattr(result,fieldnameResult)
if field:
if checked and (getattr(result,fieldnameResult) in checked.split("\n")):
ret+="""<input name="%s" type="%s" value="%s" checked>%s"""%(fieldname,boxType,field.encode('utf-8'),field.encode('utf-8'))
else:
ret+="""<input name="%s" type="%s" value="%s">%s"""%(fieldname,boxType,field.encode('utf-8'),field.encode('utf-8'))
return ret
def ZSQLOptionsFromCRList(self,fieldname,listField, multiple='',start=None,startValue=None,size=None,selected=None):
"""generate select oprions form a cr seperated list"""
fields=listField.split("\n")
if size:
ret="""<select name="%s" %s size="%s" >
"""%(fieldname,multiple,size)
else:
ret="""<select name="%s" %s >
"""%(fieldname,multiple)
if start:
if start==' ':
start=''
if not startValue:
startValue=start
ret+="""<option value="%s" >%s</option>"""%(startValue,start)
for field in fields:
if selected and (field in selected.split("\n")):
ret+="""<option selected value="%s">%s</option>"""%(field.encode('utf-8'),field.encode('utf-8'))
else:
ret+="""<option value="%s">%s</option>"""%(field.encode('utf-8'),field.encode('utf-8'))
ret+="""</select>"""
return ret
def ZSQLOptionsFromSearchList(self,fieldname,
results,fieldName,
valueName=None,start=None,
multiple='',startValue=None,
additionalSelect="",size=None,
linelen=None,selected=None,
clear=False):
"""generate select options form a search list
es wird
<select name=fieldname mutiple>
<option value=startValue>start</option>
<option value=result.fieldName>result.fieldValue</option>
erzeugt.
@param fieldname: Name fuer name-wert im select-tag
@param results: Resultobject einer SQL-suche
@param fieldName: Name des Feldes, das als value in den option-tag geschrieben werden soll.
@param valueName: (optional) Name des Feldes, dass als im option-tag ausgegeben wird, default wert ist valueName=fieldName
@param start: (optional) falls zusaetzliches option tag erzeugt werden soll, gibt start an was im option tag steht
@param startValue (optional): gibt den entsprechenden Wert an.
@param selected (optional): Wert der ausgewaehlt sein soll.
@param linelen: (optional) maximale laenge eines Eintrages
der im Klappmenue noch angezeigt wird, laengeres wird abgeschnitten.
@param addionalSaelect (optional): zusaetzlicher text fuer den select tag
@param clear (optional): setze auf den startwert.
"""
if not valueName:
valueName=fieldName
if size:
ret="""<select name="%s" %s size="%s" %s>
"""%(fieldname,multiple,size,additionalSelect)
else:
ret="""<select name="%s" %s %s>
"""%(fieldname,multiple,additionalSelect)
if start:
if start==' ':
start=''
if not startValue:
startValue=start
if clear:
ret+="""<option selected value="%s" >%s</option>"""%(startValue,start)
else:
ret+="""<option value="%s" >%s</option>"""%(startValue,start)
for result in results:
field=getattr(result,fieldName)
fieldValue=getattr(result,valueName)
if linelen and fieldValue and (len(fieldValue) > string.atoi(linelen)):
displayValue = fieldValue[:string.atoi(linelen)]
else:
displayValue = fieldValue
if displayValue: #show only if value not none
if field == selected:
ret+="""<option value="%s" selected>%s</option>"""%(field,displayValue)
else:
ret+="""<option value="%s">%s</option>"""%(field,displayValue)
ret+="""</select>"""
return ret
def ZSQLInlineSearchU(self,storename=None,args=None,**argv):
"""one element if exists"""
qs=[]
if storename:
"""store"""
storename=storename
else:
storename="foundCount"
if args:
argTmp=args
else:
argTmp=argv
#print "INLINE:",argv
for a in argTmp.keys():
aFiltered=re.sub(r"^-","_",a) # beginning of a command should always be "_"
qs.append(aFiltered+"="+urllib.quote(str(argTmp[a])))
#return []
ret = self.parseQueryString(string.join(qs,","),"_",storename=storename)
try:
return ret[0]
except:
return None
def ZSQLSequentialSearch(self,_fieldlist,_searchTerm,storename=None,args=None,**argv):
"""get a list of tuples (fields,searchoptions,table) to search the searchTerm in, returns dictionary. """
#print "do search with:",_fieldlist,_searchTerm,storename,args,argv
ret={}
if args:
argTmp=args
else:
argTmp=argv
for field in _fieldlist:
argTmp2=copy.deepcopy(argTmp)
argTmp2[field[0]]=_searchTerm
argTmp2['_op_'+field[0]]=field[1]
argTmp2['_table']=field[2]
ret[field[0]]=(self.ZSQLInlineSearch(storename=storename,args=argTmp2),field[3],field[4],field[5],field[6])
return ret
def ZSQLInlineSearch(self,storename=None,args=None,**argv):
"""inlinesearch"""
qs=[]
if storename:
"""store"""
else:
storename="foundCount"
if args:
argTmp=args
else:
argTmp=argv
#print "INLINE:",argv
for a in argTmp.keys():
aFiltered=re.sub(r"^-","_",a) # beginning of a command should always be "_"
if type(argTmp[a]) is ListType: # ein parameter zweimal
value=""
#TODO find a better solution, currently only the last non empty entry is used.
for x in argTmp[a]:
if x:
value=x
else:
value=str(argTmp[a])
qs.append(aFiltered+"="+urllib.quote(value))
#return []
return self.parseQueryString(string.join(qs,","),"_",storename=storename)
def ZSQLInlineSearch2(self,query):
"""inlinesearch"""
qs=[]
#print "INLINE:",query
return self.ZSQLSimpleSearch(query)
def ZSQLResetConnection(self):
"""reset the connectione"""
try:
self.getConnectionObj().manage_close_connection()
except:
logger("ZSQLResetConnection",logging.ERROR, '%s %s'%sys.exc_info()[:2])
try:
self.getConnectionObj().manage_open_connection()
except:
logger("ZSQLResetConnection",logging.ERROR, '%s %s'%sys.exc_info()[:2])
def ZSQLSimpleSearch(self,query=None,max_rows=1000000):
"""simple search"""
logging.error("ZSQLSimpleSearch X %s"%query)
#print query
if not query:
query=self.query
if (hasattr(self,"_v_searchSQL") and (self._v_searchSQL == None)) or (not hasattr(self,"_v_searchSQL")):
self._v_searchSQL=Shared.DC.ZRDB.DA.DA("_v_searchSQL","_v_searchSQL",self.getConnectionObj().getId(),"var","<dtml-var var>")
#self._v_searchSQL=self.getConnectionObj()()
self._v_searchSQL.max_rows_=max_rows
#self._v_searchSQL.set_client_encoding('UNICODE')
try:
logging.error("I am here")
t=self._v_searchSQL.__call__(var=query)
#t=self._v_searchSQL.query(query)
logging.error("I am here %s"%t)
return t
except :
logger("ZSQLSimpleSearch ERROR1",logging.ERROR, '%s %s'%sys.exc_info()[:2])
if sys.exc_info()[0]=="Database Error":
try:
self.getConnectionObj().manage_open_connection()
except:
logger("ZSQLSimpleSearch ERROR2",logging.ERROR, '%s %s'%sys.exc_info()[:2])
else:
try:
self._v_searchSQL.max_rows_=max_rows
#self._v_searchSQL.set_client_encoding('UNICODE')
return self._v_searchSQL.__call__(var=query)
#return self._v_searchSQL.query(query)
except :
logger("ZSQLSimpleSearch ERROR2",logging.ERROR, '%s %s'%sys.exc_info()[:2])
if sys.exc_info()[0]=="Database Error":
try:
self.getConnectionObj().manage_open_connection()
except:
logger("ZSQLSimpleSearch",logging.ERROR, '%s %s'%sys.exc_info()[:2])
def getConnectionObj(self):
if hasattr(self,'connection_id'):
return getattr(self,self.connection_id)
def ZSQLSimpleSearch2(self,query=None):
""" returrn SQLSearch"""
if not query:
query=self.query
if getattr(self,'_v_search',None):
return self._v_search(var=query)
if hasattr(self,'search') and (self.search.meta_type=="Z SQL Method"):
self._v_search=self.search
return self.search(var=query)
else:
if hasattr(self.aq_parent.aq_parent,'search') and (self.aq_parent.aq_parent.search.meta_type=="Z SQL Method"):
self._v_search=self.aq_parent.aq_parent.search
return self.aq_parent.aq_parent.search(var=query)
else:
search=self.ZopeFind(self,obj_metatypes=["Z SQL Method"],search_sub=1)
if search:
self._v_search=search[0][1]
return search[0][1](var=query)
else:
return []
def ZSQLAdd(self,format=None,RESPONSE=None,args=None,**argv):
"""Neuer Eintrag"""
if args:
argTmp=args
else:
argTmp=argv
qs_temp=[]
for a in self.REQUEST.form.keys():
qs_temp.append(a+"="+urllib.quote(str(self.REQUEST.form[a])))
qs=string.join(qs_temp,",")
for field in argTmp.keys():
if field[0]=="_":
fieldTmp="-"+field[1:]
else:
fieldTmp=field
qs+=",%s=%s"%(fieldTmp,argTmp[field])
addList={}
for q in qs.split(","):
name=re.sub("r'+'"," ",q.split("=")[0].lower())
value=q.split("=")[1]
value=re.sub(r'\+'," ",value)
value=urllib.unquote(value)
if name=="-table":
table=urllib.unquote(value)
elif name=="-format":
format=urllib.unquote(value)
elif (not (name[0]=="-" or name[0]=="_")) and (not len(value)==0):
addList[urllib.unquote(name)]=urllib.unquote(value)
keyList=[]
valueList=[]
for x in addList.keys():
keyList.append("\""+x+"\"")
valueList.append(sql_quote(addList[x]))
keyString=string.join(keyList,",")
valueString=string.join(valueList,",")
queryString="INSERT INTO %s (%s) VALUES (%s)"%(table,keyString,valueString)
self.ZSQLSimpleSearch(queryString)
if RESPONSE and format:
return RESPONSE.redirect(format)
else:
return True
def ZSQLChange(self,format=None,RESPONSE=None,USE_FORM=None,args=None,**argv):
"""change entries"""
#qs=self.REQUEST['QUERY_STRING']
# very bad hack
qs_temp=[]
if USE_FORM or RESPONSE:
for a in self.REQUEST.form.keys():
qs_temp.append(a+"="+urllib.quote(str(self.REQUEST.form[a])))
if args:
arg_tmp=args
else:
arg_tmp=argv
for field in arg_tmp.keys():
if field[0]=="_":
fieldTmp="-"+field[1:]
else:
fieldTmp=field
qs_temp.append("%s=%s"%(fieldTmp,arg_tmp[field]))
changeList=[]
logging.info("ZSQLChange qs_temp: %s"%repr(qs_temp))
for q in qs_temp:
name=urllib.unquote(re.sub("r'+'"," ",q.split("=")[0].lower()))
value="=".join(q.split("=")[1:])
value=re.sub(r'\+'," ",value)
value=urllib.unquote(value)
if name=="-table":
table=urllib.unquote(value)
elif name=="-identify":
identify=urllib.unquote(value)
identify="lower("+identify.split("=")[0]+")="+sql_quote(identify.split("=")[1].lower())
elif name=="-format":
format=urllib.unquote(value)
#elif (not (name[0]=="-" or name[0]=="_")) and (not len(value)==0):
elif (not (name[0]=="-" or name[0]=="_")):
if value=="":
changeList.append("\""+name+"\"=null")
else:
changeList.append("\""+name+"\"="+sql_quote(urllib.unquote(value)))
changeString=string.join(changeList,",")
queryString="UPDATE %s SET %s WHERE %s"%(table,changeString,identify)
logger("ZSQLExtend",logging.INFO,"CHANGE: "+queryString)
self.ZSQLSimpleSearch(queryString)
if RESPONSE and format:
return RESPONSE.redirect(format)
else:
return True
def ZSQLFindIndexed(self,tableList=[],qs="",select="oid,*",storename=None,indexedFields=['data_line'],restrictField='id_text',**argv):
"""find2"""
for index in self.ZopeFind(self,obj_ids=indexedFields):
txt=argv.get(index[0],None)
if txt:
oids=index[1].getIndex()[txt]
search1= self.ZSQLFind(qs=qs,select=select,storename=storename,tableExt=tableList[1],restrictField=restrictField,NoQuery='yes',NoLimit='yes',**argv)
search2 = self.ZSQLFind(tableExt=tableList[0],qs=qs,select=select,storename=storename,restrictConnect=(tableList[0]+"."+restrictField,search1),**argv)
return search2
def ZSQLFind2(self,qs="",select="oid,*",storename=None,tableList=['cdli_translit','cdli_cat'],restrictField='id_text',**argv):
"""find2"""
search1= self.ZSQLFind(qs=qs,select=select,storename=storename,tableExt=tableList[1],restrictField=restrictField,NoQuery='yes',NoLimit='yes',**argv)
search2 = self.ZSQLFind(tableExt=tableList[0],qs=qs,select=select,storename=storename,restrictConnect=(tableList[0]+"."+restrictField,search1),**argv)
return search2
def ZSQLFind(self,qs="",select="oid,*",storename="foundCount",tableExt=None,NoQuery=None,NoLimit=None,restrictField=None,restrictConnect=None,filter=None,**argv):
"""search in database"""
def delEmpty(list):
""""loesche leere elemente aus der liste"""
ret=[]
for x in list:
splitted=x.split("=")
if (len(splitted)>1) and not (splitted[1]==' '):
ret.append(x)
return ret
if qs=="":
#kein querystring ubergeben
if self.REQUEST['QUERY_STRING']:
qs=self.REQUEST['QUERY_STRING']
qs=string.join(qs.split("&"),",")
for field in argv.keys():
if field[0]=="_":
fieldTmp="-"+field[1:]
else:
fieldTmp=field
qs+=",%s=%s"%(fieldTmp,argv[field])
else:
qs=self.REQUEST.SESSION.get('query','')
for field in argv.keys():
if field[0]=="_":
fieldTmp="-"+field[1:]
else:
fieldTmp=field
qs+=",%s=%s"%(fieldTmp,argv[field])
else:
self.REQUEST['QUERY_STRING']=qs
qs=string.join(qs.split("&"),",")
qs=re.sub("\\+"," ",qs)#TODO: Austauschen da Leerzeichen bei http-get durch + ersetzt wird, generell sollte alles auf post umgeschrieben werden. vom search formular.
qs=string.join(delEmpty(qs.split(",")),",")
#store query for further usage
#TODO: erste der beiden ist ueberfluessig
self.REQUEST.SESSION['query']=qs
if not self.REQUEST.SESSION.has_key(storename):
self.REQUEST.SESSION[storename]={}
self.REQUEST.SESSION[storename]['qs']=qs
#print "calling Query with",repr(NoQuery)
ret=self.parseQueryString(qs,"-",select=select,storemax="yes",storename=storename,tableExt=tableExt,NoQuery=NoQuery,NoLimit=NoLimit,restrictField=restrictField,restrictConnect=restrictConnect,filter=filter)
#print self.REQUEST.SESSION["foundCount"]
return ret
def ZSQLFoundCountLen(self,var):
return len(var)
def ZSQLFoundCount(self,qs="",select="*",storename="foundCount"):
return self.REQUEST.SESSION[storename]['count']
def ZSQLRangeStart(self,storename="foundCount"):
return int(self.REQUEST.SESSION[storename]['rangeStart'])+1
def ZSQLRangeSize(self,storename="foundCount"):
return self.REQUEST.SESSION[storename]['rangeSize']
def ZSQLRangeEnd(self,storename="foundCount"):
return str(min(int(self.REQUEST.SESSION[storename]['rangeEnd']),int(self.REQUEST.SESSION[storename]['count'])))
def ZSQLNewQuery(self,linkText,storename="foundCount",**argv):
"""suche neu"""
return self.ZSQLNewSearch(linkText,storename,url=self.REQUEST['URL'],args=argv)
def ZSQLNewSearch(self,linkText,storename="foundCount",url=None,args=None,**argv):
"""suche mit alten parametern bis auf die in argv getauschten"""
str = self.ZSQLNewSearchURL(storename, url, args, **argv)
return """<a href="%s"> %s</a>"""%(str,linkText)
def ZSQLNewSearchURL(self, storename="foundCount",url=None,args=None,**argv):
"""suche mit alten parametern bis auf die in argv getauschten"""
if args:
argv=args
#get the old queries
qs=self.REQUEST.SESSION[storename]['qs']
querys=qs.split(",")
#which arguments are in the old query string
queryList={}
for query in querys:
arg=query.split("=")[0]
if arg[0]=="_": arg="-"+arg[1:] # sicherstellen, dass an Anfang stets "_"
try:
queryList[arg]=urllib.unquote_plus(query.split("=")[1])
except:
queryList[arg]=''
argList=[]
arg=""
#gehe durch die zu aendernden Argumente
for argTmp in argv.keys():
arg=argTmp[0:]# sicherstellen, dass der string auh kopiert wird
if arg[0]=="_": arg="-"+arg[1:] # sicherstellen, dass an Anfang stets "_"
queryList[arg]=argv[argTmp]
if url:
str=url+"?"+urllib.urlencode(queryList)
else:
str="ZSQLSearch?"+urllib.urlencode(queryList)
return str
def parseQueryString(self,qs,iCT,storemax="no",select=None,nostore=None,storename="foundCount",tableExt=None,NoQuery=None,NoLimit=None,restrictField=None,restrictConnect=None,filter=None):
"""analysieren den QueryString"""
#setzte generische werte
lop="AND" # standardsuche mit and
max="ALL" #standard alle auswaehlen
maxstr=""
whereList=[]
sort=""
op="bw"
opfields={}
lopfields={} #Verknuepfung bei mehrfachauswahl von einem feld
sortfields={} #order of sortfields
diacritics={} #diacritische zeichen, falls "no", dann werden diese fuer das feld gefiltert.
sortAllFields=None
skip=""
rangeStart=0
limit=0
searchFields={}
searchFieldsOnly={}
queryTemplate=[]
outerjoin=""
debug=None
if not select:
select="oid,*"
#check for op
splitted=qs.split(",")
if tableExt:
table=tableExt
if restrictField:
select=restrictField
#erster durchgang suche operatoren
for q in splitted:
name=re.sub("r'+'"," ",q.split("=")[0].lower())
if name=="_debug":
debug=True
try:
value=urllib.unquote(q.split("=",1)[1])
except:
value=""
#print "Hi",name[0:3],q
if name[0:3]==iCT+"op":
op=value
field=name[4:]
opfields[field]=op
if name[0:4]==iCT+"lop":
lop=value
field=name[5:]
lopfields[field]=lop
if name[0:11]==iCT+"diacritics":
field=name[12:]
diacritics[field]=value
if name[0:10]==iCT+"sortorder":
#sort=value
field=name[11:]
sortAllFields=None
#no field selected
if field=="":
sortAllFields=value
else:
sortfields[field]=value
#zweiter durchgang analysiere felder
for q in qs.split(","):
name=re.sub("r'+'"," ",q.split("=")[0].lower())
try:
value=urllib.unquote(q.split("=",1)[1])
except:
value=""
punktsplit=name.split(".") #sonderfall feld mit punkten(tabelle.suchFeld.ausgewaehltesFeld,feldinoriginal), d.h. suche in anderer tabelle:
#analysiere alle anderen faelle
if diacritics.get(name,'yes')=='no':
"""filter diacritische zeichen"""
value=unicodedata.normalize('NFKD', value.decode('utf-8')).encode('ASCII', 'ignore')
if name==iCT+"lop":
lop=value
elif name==iCT+"table":
if not tableExt:
table=value
elif name==iCT+"select":
if not restrictField:
select=value
elif name==iCT+"max":
if not NoLimit:
maxstr="LIMIT "+str(value)
limit=str(value)
elif name==iCT+"skip":
skip="OFFSET "+str(value)
rangeStart=str(value)
elif name==iCT+"join":
whereList.append(value)
elif name==iCT+"outerjoin":
outerjoin=value
elif name==iCT+"sort":
sortstrs=[]
for word in value.split(','):
wordstr=word.lstrip().rstrip()
if sortAllFields:
order=sortAllFields
else:
order=sortfields.get(wordstr,'ASC')
if not (wordstr == ""):
sortstrs.append(wordstr+" "+order)
if len(sortstrs)>0:
sort="ORDER BY "+string.join(sortstrs,',')
elif name==iCT+"token":
if not nostore=="yes":
self.REQUEST.SESSION['token']=value
elif name==iCT+"op":
op=value
#sonderfall Name hat das Format:
#TABELLE.SUCHFELD_IN_DIESER_TABELLE.SELECT_FIELD.IDENTIFIER_IN_TABELLE_-table
#i.e. erzeugt wird
#das Statement
#WHERE IDENTIFIER_IN_TABELLE in (select * from SELECT_FIELD
#where LOWER(SUCHFELD_IN_DIESER_TABELLE) something value)
#something is defined by _op_TABELLE.SUCHFELD_IN_DIESER_TABELLE.SELECT_FIELD.IDENTIFIER_IN_TABELLE
elif (not name[0]==iCT) and len(punktsplit)==4:
if opfields.has_key(name):
op=opfields[name]
else:
op="ct"
namealt=name
name="LOWER("+punktsplit[1]+")"
value=value.lower()
if op=="ct":
tmp=(name+" LIKE "+sql_quote("%"+value+"%"))
elif op=="gt":
tmp=(name+">"+sql_quote(value))
elif op=="lt":
tmp=(name+"<"+sql_quote(value))
elif op=="eq":
tmp=(name+"="+sql_quote(value))
elif op=="bw":
tmp=(name+" LIKE "+sql_quote(value+"%"))
elif op=="ew":
tmp=(name+" LIKE "+sql_quote("%"+value))
elif op=="all":
tmps=[]
for word in value.split(" "):
tmps.append(name+" LIKE "+sql_quote("%"+word+"%"))
tmp=string.join(tmps,' AND ')
elif op=="numerical":
term=analyseIntSearch(value)
tmp=(name+" "+term)
elif op=="grep":
tmp=(name+" ~* "+sql_quote(value))
elif op=="one":
tmps=[]
for word in value.split(" "):
tmps.append(name+" LIKE "+sql_quote("%"+word+"%"))
tmp=string.join(tmps,' OR ')
op="all"
if value!='': #lehre Werte werde nicht hinzugefuegt
searchTmp="""%s in (select %s from %s where %s)"""%(punktsplit[3],punktsplit[2],punktsplit[0],tmp)
queryTemplate.append(searchTmp)
elif (not name[0]==iCT) and (not len(value)==0):
#print "OP",op,name
value=value.lower()
tmp=""
if opfields.has_key(name):
op=opfields[name]
else:
op="ct"
namealt=name
name="LOWER("+name+")"
if op=="ct":
tmp=(name+" LIKE "+sql_quote("%"+value+"%"))
elif op=="gt":
tmp=(name+">"+sql_quote(value))
elif op=="lt":
tmp=(name+"<"+sql_quote(value))
elif op=="eq":
tmp=(name+"="+sql_quote(value))
elif op=="bw":
tmp=(name+" LIKE "+sql_quote(value+"%"))
elif op=="ew":
tmp=(name+" LIKE "+sql_quote("%"+value))
elif op=="all":
tmps=[]
for word in value.split(" "):
tmps.append(name+" LIKE "+sql_quote("%"+word+"%"))
tmp=string.join(tmps,' AND ')
elif op=="numerical":
term=analyseIntSearch(value)
tmp=(name+" "+term)
elif op=="grep":
tmp=(name+" ~* "+sql_quote(value))
elif op=="one":
tmps=[]
for word in value.split(" "):
tmps.append(name+" LIKE "+sql_quote("%"+word+"%"))
tmp=string.join(tmps,' OR ')
op="all"
if (value!='') and ((not tableExt) or (namealt.split('.')[0]==tableExt)): #keine leeren werde und keine auschluss
if searchFields.has_key(namealt):
searchFields[namealt]+=lopfields.get(name,'OR')+" "+tmp
searchFieldsOnly[namealt]+=lopfields.get(name,'OR')+" "+value
else:
searchFields[namealt]=tmp
searchFieldsOnly[namealt]=value
whereList=["("+searchFields[x]+")" for x in searchFields.keys()]
whereList+=queryTemplate
if len(whereList)>0:
if filter:
whereStr="("+string.join(whereList," "+lop+" ")+") AND "+filter
else:
whereStr=string.join(whereList," "+lop+" ")
where="WHERE "+whereStr
else:
if filter:
where="WHERE "+filter
else:
where=""
if restrictConnect:
if len(where)==0:
where="WHERE "+restrictConnect[0]+" in ("+restrictConnect[1]+")"
else:
where+="and "+restrictConnect[0]+" in ("+restrictConnect[1]+")"
#print "QE",table
#print (select,table,where,sort,maxstr,skip)
query="SELECT %s FROM %s %s %s %s %s %s"%(select,table,outerjoin,where,sort,maxstr,skip)
if not nostore=="yes":
self.REQUEST.SESSION['qs']=opfields
#print "IAMHERE again:", query
if not NoQuery:
query2="SELECT count(*) FROM %s %s"%(table,where)
#print "QUERYSTRING:",self.REQUEST.SESSION[storename]['queryString2']
if not self.REQUEST.SESSION.has_key(storename):
self.REQUEST.SESSION[storename]={}
self.REQUEST.SESSION[storename]['qs']=qs #sichere Querystring
if self.REQUEST.SESSION[storename].has_key('queryString2'):
if not self.REQUEST.SESSION[storename]['queryString2']==query2:
#print "HOOOOO",storename
self.REQUEST.SESSION[storename]['queryString2']=query2
try:
self.REQUEST.SESSION[storename]['count']=self.ZSQLSimpleSearch(query2)[0].count
except:
self.REQUEST.SESSION[storename]['count']=0
#print "QUERY",query2,"::::",self.REQUEST.SESSION[storename]['queryString2']
else:
self.REQUEST.SESSION[storename]['queryString2']=query2
if self.ZSQLSimpleSearch(query2):
self.REQUEST.SESSION[storename]['count']=self.ZSQLSimpleSearch(query2)[0].count
else:
self.REQUEST.SESSION[storename]['count']=0
#print "QUERYNEW",self.REQUEST.SESSION[storename]['queryString2']
self.REQUEST.SESSION[storename]['rangeStart']=rangeStart
self.REQUEST.SESSION[storename]['rangeEnd']=self.REQUEST.SESSION[storename]['count']
if (limit=="all") or (limit==int(limit)):
self.REQUEST.SESSION[storename]['rangeEnd']=self.REQUEST.SESSION[storename]['count']
else:
self.REQUEST.SESSION[storename]['rangeEnd']=int(rangeStart)+int(limit)
self.REQUEST.SESSION[storename]['rangeSize']=limit
self.REQUEST.SESSION[storename]['searchFields']=searchFields
self.REQUEST.SESSION[storename]['searchFieldsOnly']=searchFieldsOnly
if debug:
logging.error("ZSQLSimpleSearch %s"%query)
if not NoQuery:
return self.ZSQLQuery(query)
else:
return query
def ZSQLUniqueQuery(self,value,returns):
"""unique relation"""
if returns:
statement="""select %s from %s where %s = '%s' """%(returns[1],returns[0],returns[2],value)
founds=self.ZSQLSimpleSearch(statement)
if founds:
return getattr(founds[0],returns[1])
else:
return value
else:
return value
def ZSQLQuery(self,query,debug=None):
"""query"""
if debug:
logger("ZSQLQuery", logging.INFO, query)
return self.ZSQLSimpleSearch(query)
def ZSQLSearch(self):
"""To be done"""
formatfile=self.REQUEST['URL1'] #generisch redirect zur gleichen url
#zerlege querystring in key value paare
#TODO: check if this is really necessary, use argv**
rq=self.REQUEST['QUERY_STRING']
querys=rq.split("&")
for querytemp in querys: #zerg
query=querytemp.split("=")
try:
if query[0].lower()=="-format":
formatfile=query[1]
except:
pass
#sichern
self.REQUEST.SESSION['query']=string.join(self.REQUEST['QUERY_STRING'].split("&"),",")
self.REQUEST.SESSION['come_from_search']="yes"
return self.REQUEST.RESPONSE.redirect(urllib.unquote(formatfile)+"?"+rq)
def ZSQLint(self,string):
try:
return(int(string))
except:
return 0
def getZSQLSearchFieldsList(self,storename="foundCount"):
"""get searchfieldList"""
#print self.REQUEST.SESSION[storename]['searchFields'].keys()
return self.REQUEST.SESSION[storename]['searchFieldsOnly'].keys()
def getZSQLSearchFields(self,field,storename="foundCount"):
"""get searchfield"""
#print "SF",self.REQUEST.SESSION[storename]['searchFields']
return self.REQUEST.SESSION[storename]['searchFieldsOnly'][field]
def nextLink(self,html,storename="foundCount"):
"""nextLink"""
try:
limit=self.REQUEST.SESSION[storename]['rangeSize']
if int(limit)==0 :
limit="1"
newRangeStart=int(self.REQUEST.SESSION[storename]['rangeStart'])+int(limit)
except:
limit=1
newRangeStart=0
if (newRangeStart>=self.REQUEST.SESSION[storename]['count']) or (self.REQUEST.SESSION[storename]['count']==self.REQUEST.SESSION[storename]['rangeEnd']):
#newRangeStart=self.REQUEST.SESSION[storename]['count']-1
return ""
#create new query string
if self.REQUEST['QUERY_STRING']=="":
qs=self.REQUEST.SESSION['query']
queries=string.split(qs,",")[0:]
else:
qs=self.REQUEST['QUERY_STRING']
queries=string.split(qs,"&")[0:]
newquery=[]
skipFound=0
for query in queries:
if query[0]=="_" : query="-"+query[1:]
if query.split("=")[0].lower()=="-skip":
skipFound=1
query="-skip=%i"%newRangeStart
newquery.append(query)
if skipFound==0 :
query="-skip=%i"%newRangeStart
newquery.append(query)
newquerystring=string.join(newquery,"&")
return "<a href='%s'>%s</a>"%(self.REQUEST['URL']+"?"+newquerystring,html)
def prevLink(self,html,storename="foundCount"):
"""prev link"""
try:
limit=self.REQUEST.SESSION[storename]['rangeSize']
if int(limit)==0 :
limit="1"
newRangeStart=int(self.REQUEST.SESSION[storename]['rangeStart'])-int(limit)
except:
limit=1
newRangeStart=0
if newRangeStart <0:
return ""
#print "limit",limit,newRangeStart,int(self.REQUEST.SESSION[storename]['rangeStart'])
if newRangeStart<0:
newRangeStart=0
#create new query string
if self.REQUEST['QUERY_STRING']=="":
qs=self.REQUEST.SESSION['query']
#qs=re.sub(r'_','-',qs) #aendern fuer query
queries=string.split(qs,",")
else:
qs=self.REQUEST['QUERY_STRING']
queries=string.split(qs,"&")
newquery=[]
skipFound=0
for query in queries:
#print query.split("=")[0]
if query[0]=="_" : query[0]="-"
if query.split("=")[0].lower()=="-skip":
#print"HI"
query="-skip=%i"%newRangeStart
skipFound=1
newquery.append(query)
if skipFound==0 :
query="-skip=%i"%newRangeStart
newquery.append(query)
newquerystring=string.join(newquery,"&")
return "<a href='%s'>%s</a>"%(self.REQUEST['URL']+"?"+newquerystring,html)
manage_addZSQLExtendFolderForm=DTMLFile('ZSQLExtendFolderAdd', globals())
def manage_addZSQLExtendFolder(self, id, title='', label='', description='',
createPublic=0,
createUserF=0,
connection_id=None,
REQUEST=None):
"""Add a new Folder object with id *id*.
If the 'createPublic' and 'createUserF' parameters are set to any true
value, an 'index_html' and a 'UserFolder' objects are created respectively
in the new folder.
"""
ob=ZSQLExtendFolder()
ob.id=str(id)
ob.title=title
self._setObject(id, ob)
ob=self._getOb(id)
setattr(ob,'label',label)
setattr(ob,'description',description)
setattr(ob,'connection_id',connection_id)
checkPermission=getSecurityManager().checkPermission
if createUserF:
if not checkPermission('Add User Folders', ob):
raise Unauthorized, (
'You are not authorized to add User Folders.'
)
ob.manage_addUserFolder()
if createPublic:
if not checkPermission('Add Page Templates', ob):
raise Unauthorized, (
'You are not authorized to add Page Templates.'
)
ob.manage_addProduct['PageTemplates'].manage_addPageTemplate(
id='index_html', title='')
if REQUEST is not None:
return self.manage_main(self, REQUEST, update_menu=1)
class ZSQLBibliography(Folder,ZSQLExtendFolder):
"""Bibliography"""
meta_type="ZSQLBibliography"
def getLabel(self):
try:
return self.label
except:
return ""
def getDescription(self):
try:
return self.description
except:
return ""
def changeZSQLBibliographyForm(self):
"""change folder config"""
pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','changeZSQLBibliographyForm.zpt')).__of__(self)
return pt()
def content_html(self):
"""template fuer content"""
try:
obj=getattr(self,"ZSQLBibliography_template")
return obj()
except:
pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','ZSQLBibliography_template_standard.zpt')).__of__(self)
pt.content_type="text/html"
return pt()
def changeZSQLBibliography(self,tableName,label,description,connection_id=None,REQUEST=None):
"""change it"""
self.connection_id=connection_id
self.tableName=tableName
self.label=label
self.description=description
if REQUEST is not None:
return self.manage_main(self, REQUEST)
manage_options=Folder.manage_options+(
{'label':'Main Config','action':'changeZSQLBibliographyForm'},
{'label':'Generate RDF Template','action':'generateRDFTemplate'},
{'label':'Generate XML Template','action':'generateXMLTemplate'},
)
def getFieldLabel(self,fields,field):
"""get labels"""
try:
ret =fields[0][field]
if ret == "":
return field
else:
return ret
except:
return field
def getFieldValue(self,found,field):
"""get value"""
try:
ret=getattr(found,field)
if ret == "":
return None
else:
return ret
except:
return None
def findTagsFromMapping(self,referenceType):
"""gib hash mit label -> generic zurueck"""
self.referencetypes=self.ZopeFind(self.standardMD)
bibdata={}
retdata={}
fieldlist=self.standardMD.fieldList
for referenceTypeF in self.referencetypes:
#print referenceType,referenceTypeF[1].title
if referenceTypeF[1].title == referenceType:
bibdata[referenceTypeF[1].title]=referenceTypeF[1].fields
bibdata['data']=referenceTypeF[1]
self.fields=bibdata[referenceType]
for field in fieldlist:
if referenceTypeF[1].getValue(field)[0]==None:
retdata[field]=field
else:
retdata[field]=referenceTypeF[1].getValue(field)[0]
return retdata,fieldlist
def findLabelsFromMapping(self,referenceType):
"""gib hash mit label -> generic zurueck"""
self.referencetypes=self.ZopeFind(self.standardMD)
bibdata={}
retdata={}
fieldlist=self.standardMD.fieldList
for referenceTypeF in self.referencetypes:
#print referenceType,referenceTypeF[1].title
if referenceTypeF[1].title == referenceType:
bibdata[referenceTypeF[1].title]=referenceTypeF[1].fields
bibdata['data']=referenceTypeF[1]
self.fields=bibdata[referenceType]
for field in fieldlist:
retdata[field]=referenceTypeF[1].getValue(field)[1]
return retdata,fieldlist
def createRDFTag(self,tag,content,namespace="cdli"):
"""create RDF"""
if content:
tag=namespace+":"+tag
if (type(content) is StringType) or (type(content) is UnicodeType):
ret=""" <%s>%s</%s>"""%(tag,escape(content),tag)
else:
ret=""" <%s>%s</%s>"""%(tag,content,tag)
return ret.decode('latin-1')
else:
return ""
def createIndexTag(self,tag,content):
"""create tag"""
if content:
if (type(content) is StringType) or (type(content) is UnicodeType):
ret=""" <%s>%s</%s>"""%(tag,escape(content),tag)
else:
ret=""" <%s>%s</%s>"""%(tag,content,tag)
return ret.decode('latin-1')
else:
return ""
def getXML2(self):
"""crate index meta"""
fn=os.path.splitext(self.REQUEST['fn'])[0]+"."
self.REQUEST['fn']=fn
pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','record2.xml')).__of__(self)
pt.content_type="text/xml"
return pt()
def generateRDFTemplate(self,REQUEST=None):
"""generateRDFtemplate"""
zt=ZopePageTemplate('record.rdf')
self._setObject('record.rdf',zt)
default_content_fn = os.path.join(package_home(globals()),
'zpt','record.rdf')
text = open(default_content_fn).read()
zt.pt_edit(text, 'text/xml')
if REQUEST is not None:
return self.manage_main(self, REQUEST)
def generateXMLTemplate(self,REQUEST=None):
"""generateXMLtemplate"""
zt=ZopePageTemplate('record.xml')
self._setObject('record.xml',zt)
default_content_fn = os.path.join(package_home(globals()),
'zpt','record.xml')
text = open(default_content_fn).read()
zt.pt_edit(text, 'text/xml')
if REQUEST is not None:
return self.manage_main(self, REQUEST)
def getMetaDataRDF(self):
"""crate index meta"""
find=self.ZopeFind(self,obj_ids=["record.rdf"])
if not find:
pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','record.rdf')).__of__(self)
pt.content_type="text/xml"
return pt()
else:
return find[0][1]()
def getMetaDataXML(self):
"""crate index meta"""
find=self.ZopeFind(self,obj_ids=["record.xml"])
if not find:
pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','record.xml')).__of__(self)
pt.content_type="text/xml"
return pt()
else:
return find[0][1]()
def getMetaDatasXML(self):
"""index"""
# check if the request's host part was OK
http_host = self.REQUEST['HTTP_HOST']
host_port = self.REQUEST['SERVER_PORT']
fix_host = None
if http_host and http_host.rfind(host_port) == -1:
#print "HTTP_HOST needs fixing!"
fix_host = http_host + ":" + host_port
ret="""<?xml version="1.0" ?>
<index>"""
for found in self.ZSQLSimpleSearch("select oid from %s limit ALL"%self.tableName):
base_url = self.absolute_url()
if fix_host:
#print "replacing ", http_host, " by ", fix_host
base_url = string.replace(base_url, http_host, fix_host, 1)
link=base_url+"/"+"record.html?oid=%i"%found.oid
metalink=base_url+"/"+"getMetaDataXML?oid=%i"%found.oid
ret+="""<resource resourceLink="%s" metaLink="%s"/>\n"""%(link,metalink)
return ret+"\n</index>"
manage_addZSQLBibliographyForm=DTMLFile('ZSQLBibliographyAdd', globals())
def manage_addZSQLBibliography(self, id, tableName,label,description,title='',
createPublic=0,
createUserF=0,
connection_id=None,
REQUEST=None):
"""Add a new Folder object with id *id*.
If the 'createPublic' and 'createUserF' parameters are set to any true
value, an 'index_html' and a 'UserFolder' objects are created respectively
in the new folder.
"""
ob=ZSQLBibliography()
ob.id=str(id)
ob.title=title
self._setObject(id, ob)
ob=self._getOb(id)
setattr(ob,'tableName',tableName)
setattr(ob,'label',label)
setattr(ob,'description',description)
setattr(ob,'connection_id',connection_id)
checkPermission=getSecurityManager().checkPermission
if createUserF:
if not checkPermission('Add User Folders', ob):
raise Unauthorized, (
'You are not authorized to add User Folders.'
)
ob.manage_addUserFolder()
if createPublic:
if not checkPermission('Add Page Templates', ob):
raise Unauthorized, (
'You are not authorized to add Page Templates.'
)
ob.manage_addProduct['PageTemplates'].manage_addPageTemplate(
id='index_html', title='')
if REQUEST is not None:
return self.manage_main(self, REQUEST, update_menu=1)
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>