Annotation of ZSQLExtend/ZSQLExtend.py, revision 1.14
1.1 dwinter 1: from OFS.Folder import Folder
2: from Globals import Persistent
3: from Acquisition import Implicit
4: from Globals import DTMLFile
5: import urllib
6: import re
7: import string
1.3 dwinter 8: from pyPgSQL import libpq
1.1 dwinter 9: from AccessControl import getSecurityManager
1.5 dwinter 10: import os.path
1.1 dwinter 11:
1.2 dwinter 12: def quoteString(name):
13: #return re.sub(r'([\(\)\?])',"\\\1",name)
14: #return "Euklid"
15: return name
16:
1.1 dwinter 17: class ZSQLExtendFolder(Persistent, Implicit, Folder):
18: """Folder"""
19: meta_type="ZSQLExtendFolder"
1.9 dwinter 20:
1.14 ! dwinter 21: def formatAscii(self,str,url=None):
! 22: """ersetze ascii umbrueche durch <br>"""
! 23: #url=None
! 24: if url:
! 25:
! 26: retStr=""
! 27: words=str.split("\n")
! 28:
! 29: for word in words:
! 30: strUrl=url%word
! 31: #print "str",strUrl
! 32: retStr+="""<a href="%s">%s</a><br/>"""%(strUrl,word)
! 33: str=retStr
! 34: if str:
! 35: return re.sub(r"[\n]","<br/>",str)
! 36: else:
! 37: return ""
! 38:
1.12 dwinter 39: def getSAttribute(self,obj,atribute,pref=''):
40: """get Attribute or emptystring"""
41:
1.13 dwinter 42: #print "obj",obj
1.12 dwinter 43: try:
44: return pref+getattr(obj,atribute)
45: except:
46: return ""
47:
48: def getS(self,str):
49: """make none to empty string"""
50: if str:
51: return str
52: else:
53: return ""
54:
1.9 dwinter 55: def actualPath(self,url=None):
56: """path"""
1.10 dwinter 57:
58: if self.REQUEST['HTTP_X_FORWARDED_SERVER']=='':
59: host=self.REQUEST['HTTP_HOST']
60: else:
61: host=self.REQUEST['HTTP_X_FORWARDED_SERVER']
1.9 dwinter 62: if not url:
1.10 dwinter 63: return "http://"+host+self.REQUEST['PATH_TRANSLATED']
1.9 dwinter 64: else:
65: temp=self.REQUEST[url].split("/")
1.10 dwinter 66: temp[2]=host
1.9 dwinter 67: return string.join(temp,"/")
68:
69: def getRequest(self):
70: """request"""
71: return self.REQUEST
1.5 dwinter 72:
73: def lowerEnd(self,path):
74: """oinly for demo"""
75: return os.path.splitext(path)[0]+".jpg"
76:
77: def ZSQLisEmpty(self,field):
78: """Teste ob Treffer leer"""
1.7 dwinter 79: #print "field",field
1.5 dwinter 80: if not field:
81: return 1
82: if field=="":
83: return 1
84: return 0
85:
1.6 dwinter 86: def ZSQLsearchOptions(self,fieldname=""):
1.5 dwinter 87: """return HTML Fragment with search options"""
1.6 dwinter 88:
89: ret="""<select name="-op_%s">
1.5 dwinter 90: <option value="bw">begins with</option> <!-- begins with / beginnt mit, "Wort*" -->
91: <option value="ew">ends with</option>
1.7 dwinter 92: <option value="ct" selected>contains</option> <!-- contains / enthaellt, "Wort" -->
1.5 dwinter 93: <option value="eq">equals</option> <!-- equals / ist, =Wort -->
1.6 dwinter 94: </select>"""%fieldname
1.5 dwinter 95: return ret
96:
97: def ZSQLInlineSearch(self,storename=None,**argv):
1.1 dwinter 98: """inlinesearch"""
99: qs=[]
1.5 dwinter 100: if storename:
101: """store"""
102: else:
103: storename="foundCount"
104:
1.2 dwinter 105:
106:
1.5 dwinter 107: #print "INLINE:",argv
1.1 dwinter 108: for a in argv.keys():
109: qs.append(a+"="+urllib.quote(str(argv[a])))
1.9 dwinter 110: #return []
1.5 dwinter 111: return self.parseQueryString(string.join(qs,","),"_",storename=storename)
1.1 dwinter 112:
1.5 dwinter 113: def ZSQLInlineSearch2(self,query):
114: """inlinesearch"""
115: qs=[]
116:
117:
118:
119: #print "INLINE:",query
120:
121: return self.search(var=query)
1.1 dwinter 122:
123: def ZSQLAdd(self):
124: """Neuer Eintrag"""
125: qs=self.REQUEST['QUERY_STRING']
126: addList={}
127: for q in qs.split("&"):
128: name=re.sub("r'+'"," ",q.split("=")[0].lower())
129: value=q.split("=")[1]
130: value=re.sub(r'\+'," ",value)
131: value=urllib.unquote(value)
132: if name=="-table":
133: table=urllib.unquote(value)
134: elif name=="-format":
135: format=urllib.unquote(value)
136: elif (not name[0]=="-") and (not len(value)==0):
137: addList[urllib.unquote(name)]=urllib.unquote(value)
138:
139: keyList=[]
140: valueList=[]
141: for x in addList.keys():
142: keyList.append("\""+x+"\"")
1.3 dwinter 143: valueList.append(libpq.PgQuoteString(addList[x]))
1.1 dwinter 144:
145: keyString=string.join(keyList,",")
146: valueString=string.join(valueList,",")
147:
148: queryString="INSERT INTO %s (%s) VALUES (%s)"%(table,keyString,valueString)
149: self.search(var=queryString)
150: return self.REQUEST.RESPONSE.redirect(format)
151:
1.4 dwinter 152: def ZSQLChange(self,**argv):
153: """Ändern von Einträgen"""
154: #qs=self.REQUEST['QUERY_STRING']
155: # very bad hack
156: qs_temp=[]
157:
158: for a in self.REQUEST.form.keys():
159: qs_temp.append(a+"="+urllib.quote(str(self.REQUEST.form[a])))
160:
161: qs=string.join(qs_temp,"&")
162:
163:
164: #print "CHANGE QS",self.REQUEST
165: #return self.REQUEST
166: changeList=[]
167: for q in qs.split("&"):
168: name=urllib.unquote(re.sub("r'+'"," ",q.split("=")[0].lower()))
169: value=q.split("=")[1]
170: value=re.sub(r'\+'," ",value)
171: value=urllib.unquote(value)
172: if name=="-table":
173: table=urllib.unquote(value)
174: elif name=="-identify":
175: identify=urllib.unquote(value)
176: identify=identify.split("=")[0]+"="+libpq.PgQuoteString(identify.split("=")[1])
177: elif name=="-format":
178: format=urllib.unquote(value)
179: elif (not name[0]=="-") and (not len(value)==0):
180: changeList.append("\""+name+"\"="+libpq.PgQuoteString(urllib.unquote(value)))
181: changeString=string.join(changeList,",")
182: queryString="UPDATE %s SET %s WHERE %s"%(table,changeString,identify)
183: self.search(var=queryString)
184: return self.REQUEST.RESPONSE.redirect(format)
185:
186: def ZSQLChange_old(self):
1.1 dwinter 187: """Ändern von Einträgen"""
188: qs=self.REQUEST['QUERY_STRING']
189: #print "CHANGE QS",self.REQUEST
190: #return self.REQUEST
191: changeList=[]
192: for q in qs.split("&"):
193: name=urllib.unquote(re.sub("r'+'"," ",q.split("=")[0].lower()))
194: value=q.split("=")[1]
195: value=re.sub(r'\+'," ",value)
196: value=urllib.unquote(value)
197: if name=="-table":
198: table=urllib.unquote(value)
199: elif name=="-identify":
200: identify=urllib.unquote(value)
1.3 dwinter 201: identify=identify.split("=")[0]+"="+libpq.PgQuoteString(identify.split("=")[1])
1.1 dwinter 202: elif name=="-format":
203: format=urllib.unquote(value)
204: elif (not name[0]=="-") and (not len(value)==0):
1.3 dwinter 205: changeList.append("\""+name+"\"="+libpq.PgQuoteString(urllib.unquote(value)))
1.1 dwinter 206: changeString=string.join(changeList,",")
207: queryString="UPDATE %s SET %s WHERE %s"%(table,changeString,identify)
208: self.search(var=queryString)
209: return self.REQUEST.RESPONSE.redirect(format)
210:
1.10 dwinter 211: def ZSQLFind(self,qs="",select="oid,*",storename=None):
1.1 dwinter 212: """Find"""
213:
214:
215: if qs=="":
216: if self.REQUEST['QUERY_STRING']:
217: qs=self.REQUEST['QUERY_STRING']
1.5 dwinter 218:
219:
1.1 dwinter 220: qs=string.join(qs.split("&"),",")
221: else:
1.5 dwinter 222:
1.1 dwinter 223: qs=self.REQUEST.SESSION['query']
224: else:
1.13 dwinter 225: self.REQUEST['QUERY_STRING']=qs
1.1 dwinter 226: qs=string.join(qs.split("&"),",")
1.13 dwinter 227:
1.1 dwinter 228:
1.5 dwinter 229: qs=re.sub("\\+"," ",qs)# Austauschen da Leerzeichen bei http-get durch + ersetzt wird, generell sollte alles auf post umgeschrieben werden. vom search formular.
1.13 dwinter 230:
1.5 dwinter 231: if storename:
232: """store"""
233: else:
234: storename="foundCount"
1.13 dwinter 235: #print "QS",qs
1.5 dwinter 236: ret=self.parseQueryString(qs,"-",select=select,storemax="yes",storename=storename)
237: #print self.REQUEST.SESSION["foundCount"]
238:
239: return ret
240:
241: def ZSQLFoundCountLen(self,var):
242: return len(var)
243:
244: def ZSQLFoundCount(self,qs="",select="*",storename=None):
245:
246: ## if qs=="":
247:
248: ## if self.REQUEST['QUERY_STRING']:
249:
250: ## qs=self.REQUEST['QUERY_STRING']
251: ## qs=string.join(qs.split("&"),",")
252: ## else:
253:
254: ## qs=self.REQUEST.SESSION['query']
255: ## else:
256: ## qs=string.join(qs.split("&"),",")
257:
258:
259: ## temp= self.parseQueryString(qs,"-",select=select,storemax="yes",nostore="yes")
260: if storename:
261: """store"""
262: else:
263: storename="foundCount"
264:
265: return self.REQUEST.SESSION[storename]['count']
266:
267: def ZSQLRangeStart(self,storename=None):
268:
269: if storename:
270: """store"""
271: else:
272: storename="foundCount"
273:
274: return self.REQUEST.SESSION[storename]['rangeStart']
275:
276: def ZSQLRangeSize(self,storename=None):
277:
278: if storename:
279: """store"""
280: else:
281: storename="foundCount"
282:
283: return self.REQUEST.SESSION[storename]['rangeSize']
1.1 dwinter 284:
1.5 dwinter 285: def ZSQLRangeEnd(self,storename=None):
286:
287: if storename:
288: """store"""
289: else:
290: storename="foundCount"
291:
292: return self.REQUEST.SESSION[storename]['rangeEnd']
293:
294: def parseQueryString(self,qs,iCT,storemax="no",select=None,nostore=None,storename=None):
295: """analysieren den QueryString"""
296: #print "NO",nostore
1.1 dwinter 297: lop="AND" # standardsuche mit and
298: max="ALL" #standard alle auswählen
1.11 dwinter 299: maxstr=""
1.1 dwinter 300: whereList=[]
301: sort=""
302: op="bw"
1.2 dwinter 303: opfields={}
1.5 dwinter 304: skip=""
305: rangeStart=0
1.11 dwinter 306: limit=0
307: searchFields={}
1.2 dwinter 308:
1.1 dwinter 309: if not select:
1.10 dwinter 310: select="oid,*"
1.5 dwinter 311: #print "Q",nostore,qs
1.2 dwinter 312: #check for op in the case of inline search
1.6 dwinter 313:
314: splitted=qs.split(",")
315:
316:
317: for q in splitted:
1.5 dwinter 318:
1.2 dwinter 319: name=re.sub("r'+'"," ",q.split("=")[0].lower())
1.14 ! dwinter 320: try:
! 321: value=urllib.unquote(q.split("=",1)[1])
! 322: except:
! 323: value=""
1.2 dwinter 324: if name[0:3]==iCT+"op":
325: op=value
1.14 ! dwinter 326:
1.2 dwinter 327: field=name[4:]
328: opfields[field]=op
1.14 ! dwinter 329: #print "HI",op,field
1.6 dwinter 330: #print opfieldsa
1.2 dwinter 331: #now analyse the querystring
1.1 dwinter 332: for q in qs.split(","):
1.5 dwinter 333:
334:
335: #try:
1.1 dwinter 336:
1.5 dwinter 337: name=re.sub("r'+'"," ",q.split("=")[0].lower())
1.14 ! dwinter 338: try:
! 339: value=urllib.unquote(q.split("=",1)[1])
! 340: except:
! 341: value=""
! 342:
1.5 dwinter 343: #value=libpq.PgQuoteString(value)
344:
345:
346: if name==iCT+"lop":
347: lop=value
348: elif name==iCT+"table":
349: table=value
350: elif name==iCT+"select":
351: select=value
352: elif name==iCT+"max":
1.11 dwinter 353: maxstr="LIMIT "+str(value)
1.5 dwinter 354: limit=str(value)
355: elif name==iCT+"skip":
356: skip="OFFSET "+str(value)
357: rangeStart=str(value)
358: elif name==iCT+"join":
359: whereList.append(value)
360: elif name==iCT+"sort":
361: sort="ORDER BY "+value
362: elif name==iCT+"token":
363: if not nostore=="yes":
1.1 dwinter 364: self.REQUEST.SESSION['token']=value
365:
1.5 dwinter 366: elif name==iCT+"op":
367: op=value
368:
369:
1.1 dwinter 370:
1.5 dwinter 371: elif (not name[0]==iCT) and (not len(value)==0):
1.6 dwinter 372:
373: #print "OP",op,name
1.5 dwinter 374: value=value.lower()
1.11 dwinter 375:
376: searchFields[name]=value
377:
1.5 dwinter 378: if opfields.has_key(name):
379: op=opfields[name]
1.6 dwinter 380: else:
381: op="ct"
382: name="LOWER("+name+")"
1.5 dwinter 383: if op=="ct":
384: whereList.append(name+" LIKE "+libpq.PgQuoteString("%"+value+"%"))
385: elif op=="gt":
386: whereList.append(name+">"+libpq.PgQuoteString(value))
387: elif op=="lt":
388: whereList.append(name+"<"+libpq.PgQuoteString(value))
389: elif op=="eq":
390: whereList.append(name+"="+libpq.PgQuoteString(value))
391: elif op=="bw":
392: whereList.append(name+" LIKE "+libpq.PgQuoteString(value+"%"))
393: elif op=="ew":
394: whereList.append(name+" LIKE "+libpq.PgQuoteString("%"+value))
1.6 dwinter 395: op="ct"
1.5 dwinter 396:
397: #except:
398: # print "END",value,name,Exception
1.1 dwinter 399: if len(whereList)>0:
400: where="WHERE "+string.join(whereList," "+lop+" ")
401: else:
402: where=""
403: #print "QE",table
404:
1.11 dwinter 405: query="SELECT %s FROM %s %s %s %s %s"%(select,table,where,sort,maxstr,skip)
1.13 dwinter 406:
1.5 dwinter 407: if not nostore=="yes":
408:
409: self.REQUEST.SESSION['qs']=opfields
1.7 dwinter 410: #print "IAMHERE again:", query
1.5 dwinter 411:
412: if storename:
1.7 dwinter 413: query2="SELECT count(*) FROM %s %s"%(table,where)
1.5 dwinter 414: #print "storing",query2
415: #print "QUERYSTRING:",self.REQUEST.SESSION[storename]['queryString2']
416: if not self.REQUEST.SESSION.has_key(storename):
417: self.REQUEST.SESSION[storename]={}
418: if self.REQUEST.SESSION[storename].has_key('queryString2'):
419: #print "HI",storename
420: if not self.REQUEST.SESSION[storename]['queryString2']==query2:
421: #print "HOOOOO",storename
422: self.REQUEST.SESSION[storename]['queryString2']=query2
423: self.REQUEST.SESSION[storename]['count']=self.search(var=query2)[0].count
424: #print "QUERY",query2,"::::",self.REQUEST.SESSION[storename]['queryString2']
425:
426: else:
427: self.REQUEST.SESSION[storename]['queryString2']=query2
428: self.REQUEST.SESSION[storename]['count']=self.search(var=query2)[0].count
429: #print "QUERYNEW",self.REQUEST.SESSION[storename]['queryString2']
430:
431:
432: self.REQUEST.SESSION[storename]['rangeStart']=rangeStart
433: if limit=="all":
434: self.REQUEST.SESSION[storename]['rangeEnd']=self.REQUEST.SESSION[storename]['count']
435: else:
436: self.REQUEST.SESSION[storename]['rangeEnd']=int(rangeStart)+int(limit)
437: self.REQUEST.SESSION[storename]['rangeSize']=limit
1.11 dwinter 438: self.REQUEST.SESSION[storename]['searchFields']=searchFields
1.5 dwinter 439:
1.13 dwinter 440: #print "Q",query
1.1 dwinter 441: return self.search(var=query)
1.11 dwinter 442:
1.1 dwinter 443:
444: def ZSQLSearch(self):
445: """To be done"""
446: rq=self.REQUEST['QUERY_STRING']
447: querys=rq.split("&")
448:
449:
450: for querytemp in querys:
451: query=querytemp.split("=")
452: try:
453: if query[0].lower()=="-format":
454: formatfile=query[1]
455: except:
456: """nothing"""
457: #print formatfile
458: self.REQUEST.SESSION['query']=string.join(self.REQUEST['QUERY_STRING'].split("&"),",")
459: return self.REQUEST.RESPONSE.redirect(urllib.unquote(formatfile))
460:
461:
462: def ZSQLint(self,string):
463: try:
464:
465: return(int(string))
466: except:
467: return 0
1.5 dwinter 468:
1.11 dwinter 469: def getZSQLSearchFieldsList(self,storename="foundCount"):
470: """get searchfieldList"""
1.13 dwinter 471: #print self.REQUEST.SESSION[storename]['searchFields'].keys()
1.11 dwinter 472: return self.REQUEST.SESSION[storename]['searchFields'].keys()
473:
474: def getZSQLSearchFields(self,storename="foundCount"):
475: """get searchfield"""
1.13 dwinter 476: #print "SF",self.REQUEST.SESSION[storename]['searchFields']
1.11 dwinter 477: return self.REQUEST.SESSION[storename]['searchFields']
478:
479:
1.5 dwinter 480: def nextLink(self,html,storename="foundCount"):
481: """nextLink"""
482: try:
483: limit=self.REQUEST.SESSION[storename]['rangeSize']
484: newRangeStart=int(self.REQUEST.SESSION[storename]['rangeStart'])+int(limit)
485: except:
486: limit=0
487: newRangeStart=0
488:
489: if newRangeStart>self.REQUEST.SESSION[storename]['count']:
490: newRangeStart=self.REQUEST.SESSION[storename]['count']-10
491:
492:
493: #create new query string
494:
495: if self.REQUEST['QUERY_STRING']=="":
496: qs=self.REQUEST.SESSION['query']
497:
498: queries=string.split(qs,",")
499:
500:
501: else:
502: qs=self.REQUEST['QUERY_STRING']
503: queries=string.split(qs,"&")
504:
505:
506:
507: newquery=[]
508:
509: skipFound=0
510:
511: for query in queries:
512: #print query.split("=")[0]
513: if query[0]=="_" : query[0]="-"
514:
515: if query.split("=")[0].lower()=="-skip":
516: skipFound=1
517: query="-skip=%i"%newRangeStart
518: newquery.append(query)
519:
520: if skipFound==0 :
521: query="-skip=%i"%newRangeStart
522: newquery.append(query)
523:
524: newquerystring=string.join(newquery,"&")
1.9 dwinter 525:
526: return "<a href='%s'>%s</a>"%(self.actualPath()+"?"+newquerystring,html)
1.5 dwinter 527:
528:
529: def prevLink(self,html,storename="foundCount"):
530: """prev link"""
531: try:
532: limit=self.REQUEST.SESSION[storename]['rangeSize']
533: newRangeStart=int(self.REQUEST.SESSION[storename]['rangeStart'])-int(limit)
534: except:
535: limit=0
536: newRangeStart=0
537:
538: #print "limit",limit,newRangeStart,int(self.REQUEST.SESSION[storename]['rangeStart'])
539:
540: if newRangeStart<0:
541: newRangeStart=0
542:
543: #create new query string
544:
545: if self.REQUEST['QUERY_STRING']=="":
546: qs=self.REQUEST.SESSION['query']
547: #qs=re.sub(r'_','-',qs) #aendern für query
548: queries=string.split(qs,",")
549:
550:
551: else:
552: qs=self.REQUEST['QUERY_STRING']
553: queries=string.split(qs,"&")
554:
555:
556:
557: newquery=[]
558:
559: skipFound=0
560:
561: for query in queries:
562: #print query.split("=")[0]
563:
564: if query[0]=="_" : query[0]="-"
565:
566: if query.split("=")[0].lower()=="-skip":
567: #print"HI"
568: query="-skip=%i"%newRangeStart
569: skipFound=1
570: newquery.append(query)
571:
572: if skipFound==0 :
573: query="-skip=%i"%newRangeStart
574: newquery.append(query)
575:
576: newquerystring=string.join(newquery,"&")
1.9 dwinter 577:
578: return "<a href='%s'>%s</a>"%(self.actualPath()+"?"+newquerystring,html)
579:
580:
1.5 dwinter 581:
582: def prevLink_old(self,html):
1.1 dwinter 583: """prev link"""
584: if self.REQUEST['QUERY_STRING']=="":
585: qs=self.REQUEST.SESSION['query']
586: else:
587: qs=self.REQUEST['QUERY_STRING']
588: max=re.search(r'max\=(.*)\,',qs.lower())
589: offset=re.search(r'offset\=(.*)\,',qs.lower())
590: if not offset:
591: offsetnew=0
592: else:
593: offsetnew=int(offset)-max
594: if offsetnew<0:
595: offsetnew=0
596: queries=string.split(qs,",")
597: newquery=[]
598: if offset:
599: for query in queries:
600: if query.split("=")[0].lower()=="offset":
601: query="-offset=%i"%offsetnew
602: newquery.append(query)
603: newquerystring=string.join(newquery,"&")
604: else:
605: queries.append("-offset=%i"%offsetnew)
606: newquerystring=string.join(queries,"&")
1.9 dwinter 607: return "<a href='%s'>%s</a>"%(self.actualPath()+"?"+newquerystring,html)
1.1 dwinter 608:
1.5 dwinter 609: def nextLink_old(self,html):
1.1 dwinter 610: """prev link"""
611: if self.REQUEST['QUERY_STRING']=="":
612: qs=self.REQUEST.SESSION['query']
613: else:
614: qs=self.REQUEST['QUERY_STRING']
615: max=re.search(r'max\=(.*)\,',qs.lower())
616:
617: offset=re.search(r'offset\=(.*)\,',qs.lower())
618: if not offset:
619: offsetnew=1
620: else:
621: offsetnew=int(offset)+int(max)
622: if offsetnew<0:
623: offsetnew=0
624: queries=string.split(qs,",")
625: newquery=[]
626: if offset:
627: for query in queries:
628:
629: if query.split("=")[0].lower()=="-offset":
630: query="-offset=%i"%offsetnew
631: newquery.append(query)
632: newquerystring=string.join(newquery,"&")
633: else:
634: queries.append("-offset=%i"%offsetnew)
635: newquerystring=string.join(queries,"&")
636:
1.9 dwinter 637: return "<a href='%s'>%s</a>"%(self.actualPath()+"?"+newquerystring,html)
1.1 dwinter 638:
1.5 dwinter 639:
1.1 dwinter 640: manage_addZSQLExtendFolderForm=DTMLFile('ZSQLExtendFolderAdd', globals())
641:
642: def manage_addZSQLExtendFolder(self, id, title='',
643: createPublic=0,
644: createUserF=0,
645: REQUEST=None):
646: """Add a new Folder object with id *id*.
647:
648: If the 'createPublic' and 'createUserF' parameters are set to any true
649: value, an 'index_html' and a 'UserFolder' objects are created respectively
650: in the new folder.
651: """
652:
653:
654: ob=ZSQLExtendFolder()
655: ob.id=str(id)
656: ob.title=title
657: self._setObject(id, ob)
658: ob=self._getOb(id)
659:
660: checkPermission=getSecurityManager().checkPermission
661:
662: if createUserF:
663: if not checkPermission('Add User Folders', ob):
664: raise Unauthorized, (
665: 'You are not authorized to add User Folders.'
666: )
667: ob.manage_addUserFolder()
668:
669: if createPublic:
670: if not checkPermission('Add Page Templates', ob):
671: raise Unauthorized, (
672: 'You are not authorized to add Page Templates.'
673: )
674: ob.manage_addProduct['PageTemplates'].manage_addPageTemplate(
675: id='index_html', title='')
676:
677: if REQUEST is not None:
678: return self.manage_main(self, REQUEST, update_menu=1)
679:
680:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>