--- cdli/cdli_files.py 2007/03/22 19:56:22 1.72
+++ cdli/cdli_files.py 2007/08/31 14:22:52 1.79
@@ -26,7 +26,64 @@ import logging
import transaction
import copy
import codecs
+import sys
+def unicodify(s):
+ """decode str (utf-8 or latin-1 representation) into unicode object"""
+ if not s:
+ return u""
+ if isinstance(s, str):
+ try:
+ return s.decode('utf-8')
+ except:
+ return s.decode('latin-1')
+ else:
+ return s
+
+def utf8ify(s):
+ """encode unicode object or string into byte string in utf-8 representation.
+ assumes string objects to be utf-8"""
+ if not s:
+ return ""
+ if isinstance(s, str):
+ return s
+ else:
+ return s.encode('utf-8')
+
+
+def generateXMLReturn(hash):
+ """erzeugt das xml file als returnwert fuer uploadATFRPC"""
+
+ ret=""
+
+ ret+=""
+ for error in hash['errors']:
+ ret+="""%s"""%error
+
+ ret+=""
+
+ ret+=""
+ for changed in hash['changed']:
+ ret+="""%s"""%changed
+ ret+=""
+
+ ret+=""
+ for new in hash['newPs']:
+ ret+=""""""%new
+ ret+=""
+
+ ret+=""
+ return ret
+
+
+
+
+
+
+
+
+
+
def unique(s):
"""Return a list of the elements in s, but without duplicates.
@@ -99,7 +156,7 @@ def unique(s):
class BasketContent(SimpleItem):
"""classe fuer den Inhalt eines Baskets"""
-
+
def __init__(self,content=[]):
"""content"""
self.contentList=content[0:]
@@ -196,6 +253,7 @@ class uploadATFfinallyThread(Thread):
self.result+="
Start processing
"
#shall I only upload the changed files?
+ logging.info("uploadATFfinally procedure: %s"%procedure)
if procedure=="uploadchanged":
changed=[x[0] for x in SESSION.get('changed',[])]
uploadFns=changed+SESSION.get('newPs',[])
@@ -341,6 +399,7 @@ class uploadATFThread(Thread):
ctx = self.getContext(app,serverport=self.serverport)
logging.info("run intern")
try:
+ logging.info("created: %s"%idTmp)
ctx.temp_folder._setObject(idTmp,tmpStore(idTmp))
except:
logging.error("thread upload: %s %s"%sys.exc_info()[0:2])
@@ -355,6 +414,7 @@ class uploadATFThread(Thread):
conn.close()
+ return getattr(ctx.temp_folder,idTmp)
def getResult(self):
"""method for accessing result"""
@@ -479,6 +539,46 @@ class CDLIBasketContainer(OrderedFolder)
security=ClassSecurityInfo()
meta_type="CDLIBasketContainer"
+ def getPNumbersOfBasket(self,basketName):
+ """get all pnumbers of a basket as a list, returns an empty list if basket not found
+ @param basketName: name of the basket
+ """
+ ret=[]
+ basketId=self.getBasketIdfromName(basketName)
+ if not basketId:
+ return []
+
+ ob=getattr(self,basketId).getContent()
+
+ ret=[x[0].split(".")[0] for x in ob]
+
+ return ret
+
+ security.declareProtected('manage','getBasketAsOneFile')
+ def getBasketAsOneFile(self,basketName,current="no"):
+ """returns all files of the basket combined in one file
+ @param basketName: Name of the basket
+ @param current: (optional) if current is set to "yes" then the most current version of
+ all files are downloaded and not the versions of the files as stored in the basket
+ """
+ ret=""
+ basketId=self.getBasketIdfromName(basketName)
+ if not basketId:
+ return ""
+
+ ob=getattr(self,basketId).getLastVersion()
+ for object in ob.getContent():
+ if current=="no": #version as they are in the basket
+ ret+=str(object[0].getData())+"\n"
+ elif current=="yes":
+ #search current object
+ logging.info("crrent: %s"%object[1].getId().split(".")[0])
+ founds=self.CDLICatalog.search({'title':object[1].getId().split(".")[0]})
+ if len(founds)>0:
+ ret+=str(founds[0].getObject().getLastVersion().getData())+"\n"
+ return ret
+
+ security.declareProtected('manage','upDateBaskets')
def upDateBaskets(self):
"""update content in to objects"""
@@ -506,18 +606,18 @@ class CDLIBasketContainer(OrderedFolder)
trash.manage_pasteObjects(cut)
security.declareProtected('manage','manageBaskets')
- def manageBaskets(self,submit,ids=None,basket1="",basket2="",REQUEST=None,RESPONSE=None):
+ def manageBaskets(self,submit,ids=None,basket1="",basket2="",joinBasket="",subtractBasket="",REQUEST=None,RESPONSE=None):
"""manage baskets, delete or copy"""
if submit=="delete":
self.deleteBaskets(ids)
elif submit=="join":
- flag,msg=self.joinBasket("joinedBasket", ids)
+ flag,msg=self.joinBasket(joinBasket, ids)
logging.info("joining %s %s"%(flag,msg))
elif submit=="subtract":
logging.info("BBBb %s %s"%(basket1,basket2))
- flag,msg=self.subtractBasket("subtractedBasket", basket1,basket2)
+ flag,msg=self.subtractBasket(subtractBasket, basket1,basket2)
logging.info("subtract %s %s"%(flag,msg))
if RESPONSE:
@@ -549,7 +649,7 @@ class CDLIBasketContainer(OrderedFolder)
return pt(basketId=basketId,basketName=basketName)
- security.declareProtected('View','index_html')
+ security.declareProtected('manage','index_html')
def index_html(self):
"""stanadard ansicht"""
@@ -753,7 +853,7 @@ class CDLIBasketContainer(OrderedFolder)
"""get name of the actualuser"""
return str(self.REQUEST['AUTHENTICATED_USER'])
-
+ security.declareProtected('manage','addBasket')
def addBasket(self,newBasketName):
"""add a new basket"""
@@ -809,7 +909,43 @@ class CDLIBasket(Folder,CatalogAware):
meta_type="CDLIBasket"
default_catalog="CDLIBasketCatalog"
+ def searchInBasket(self,indexName,searchStr,regExp=False):
+ """searchInBasket"""
+
+ lst=self.searchInLineIndexDocs(indexName,searchStr,uniq=True,regExp=regExp)
+ ret={}
+
+ lv=self.getLastVersion()
+
+ for obj in lv.content.getContent():
+ id=obj[1].getId().split(".")[0]
+ if id in lst:
+
+ ret[id]=self.showWordInFile(id,searchStr,lineList=self.getLinesFromIndex(indexName,searchStr,id,regExp=regExp),regExp=regExp,indexName=indexName)
+
+
+ pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','searchResultsInBasket')).__of__(self)
+ return pt(result=ret,indexName=indexName,regExp=regExp,word=searchStr)
+
+
+
+
+ def searchInBasket_v1(self,searchStr):
+ """search occurences of searchStr in files im basket"""
+ ret=[]
+ lv=self.getLastVersion()
+ logging.info("searching")
+ for obj in lv.content.getContent():
+ txt=obj[0].getData()
+ for x in txt.split("\n"):
+ logging.info("search %s"%x)
+ if re.match(searchStr,x):
+ ret.append(x)
+
+ return "\n".join(ret)
+
+
def getFile(self,obj):
return obj[1]
@@ -1130,7 +1266,7 @@ class CDLIBasketVersion(Implicit,Persist
self.REQUEST.RESPONSE.setHeader("Content-Length",length)
self.REQUEST.RESPONSE.write(ret)
- security.declareProtected('View','downloadObjectsAsOneFile')
+ security.declareProtected('manage','downloadObjectsAsOneFile')
def downloadObjectsAsOneFile(self,lock=None,procedure=None,REQUEST=None,check="yes",current="no"):
"""download all selected files in one file"""
@@ -1202,7 +1338,7 @@ class CDLIBasketVersion(Implicit,Persist
ret+=str(object[0].getData())+"\n"
elif current=="yes":
#search current object
- founds=self.CDLICatalog.search({'title':object[0].getId()})
+ founds=self.CDLICatalog.search({'title':object[1].getId().split(".")[0]})
if len(founds)>0:
ret+=str(founds[0].getObject().getLastVersion().getData())+"\n"
@@ -1248,7 +1384,7 @@ class CDLIBasketVersion(Implicit,Persist
def __init__(self,id,user,comment="",basketContent=[]):
""" init a basket version"""
self.id=id
- self.coment=comment
+ self.comment=comment
self._setObject('content',BasketContent(basketContent))
#self.basketContent=basketContent[0:]a
self.user=user
@@ -1262,7 +1398,7 @@ class CDLIBasketVersion(Implicit,Persist
"""get Comment"""
return self.comment
- security.declareProtected('View','index_html')
+ security.declareProtected('manage','index_html')
def index_html(self):
"""view the basket"""
@@ -1317,6 +1453,7 @@ class CDLIFileObject(CatalogAware,extVer
security.declarePublic('makeThisVersionCurrent')
+ security.declareProtected('manage','index_html')
def PrincipiaSearchSource(self):
"""Return cataloguable key for ourselves."""
return str(self)
@@ -1425,9 +1562,10 @@ def manage_addCDLIFileObject(self,id,vC=
class CDLIFile(extVersionedFile,CatalogAware):
"""CDLI file"""
+ security=ClassSecurityInfo()
meta_type="CDLI file"
default_catalog='CDLICatalog'
-
+ security.declareProtected('manage','index_html')
#security.declarePublic('history')
def getLastVersionData(self):
"""get last version data"""
@@ -1613,7 +1751,12 @@ def splitatf(fh,dir=None,ext=None):
nf=None
i=0
- for lineTmp in fh.readlines():
+ if (type(fh) is StringType) or (type(fh) is UnicodeType):
+ iter=fh.split("\n")
+ else:
+ iter=fh.readlines()
+
+ for lineTmp in iter:
lineTmp=lineTmp.replace(codecs.BOM_UTF8,'') # make sure that all BOM are removed..
for line in lineTmp.split("\r"):
#logging.log("Deal with: %s"%line)
@@ -1650,7 +1793,9 @@ def splitatf(fh,dir=None,ext=None):
nf.close()
except:
pass
- fh.close()
+
+ if not((type(fh) is StringType) or (type(fh) is UnicodeType)):
+ fh.close()
return ret,len(os.listdir(dir))
@@ -1705,7 +1850,7 @@ class CDLIFileFolder(extVersionedFileFol
"""get the content of the file fn"""
founds=self.CDLICatalog.search({'title':fn})
if not founds:
- return []
+ return ""
else:
obj=founds[0].getObject().getLastVersion()
@@ -1872,7 +2017,7 @@ class CDLIFileFolder(extVersionedFileFol
return ret
- security.declareProtected('View','index_html')
+ security.declareProtected('manage','index_html')
def index_html(self):
"""main"""
ext=self.ZopeFind(self,obj_ids=["index.html"])
@@ -1921,6 +2066,30 @@ class CDLIRoot(Folder):
meta_type="CDLIRoot"
downloadCounterBaskets=0# counts the current basket downloads if counter > 10 no downloads are possible
+ def deleteFiles(self,ids):
+ """delete files (resp. move into .trash folder)"""
+ # find or generete trash folder
+
+ found=self.ZopeFind(self,obj_ids=['.trash'])
+
+ if len(found)<1:
+ manage_addCDLIFileFolder(self, '.trash',title="Trash")
+ trash=self._getOb('.trash')
+ else:
+ logging.info(found)
+ trash=found[0][1]
+
+
+ for id in ids:
+ founds=self.CDLICatalog.search({'title':id.split(".")[0]})
+ if founds:
+ logging.info(founds)
+ folder=founds[0].getObject().aq_parent #get the parent folder of the object
+ logging.info(folder)
+ cut=folder.manage_cutObjects([founds[0].getId]) #cut it out
+ trash.manage_pasteObjects(cut) #paste it in the trash
+
+
def findWordRegExp(self,indexName,searchTerm):
"""find all words in index which match regexp in SearchTerm
@param indexName: name of the index to be searched in
@@ -1943,10 +2112,14 @@ class CDLIRoot(Folder):
words=self.findWordRegExp(indexName,searchTerm) # suche nach allen Treffern
logging.info("wd:%s"%words)
for word in words:
+
ret+=self.searchInLineIndexDocs(indexName,word)
-
- return unique(ret)
-
+
+
+ x= unique(ret)
+ logging.info("words_done")
+ return x
+
def showInLineIndex(self):
"""get the index for debug purposes"""
print "show"
@@ -2050,7 +2223,7 @@ class CDLIRoot(Folder):
transaction.get().commit()
- def showFile(self,fileId):
+ def showFile(self,fileId,wholePage=False):
"""show a file
@param fileId: P-Number of the document to be displayed
"""
@@ -2058,14 +2231,18 @@ class CDLIRoot(Folder):
if not f:
return ""
- return f[0].getObject().getLastVersionFormattedData()
+ if wholePage:
+ logging.info("whole")
+ return f[0].getObject().getLastVersion().view()
+ else:
+ return f[0].getObject().getLastVersionFormattedData()
def showWordInFile(self,fileId,word,lineList=None,regExp=True,indexName=""):
"""get lines with word fromFileId"""
file=self.showFile(fileId)
-
+ logging.info("regEXP %s"%regExp)
ret=[]
if regExp: # wenn regexp dann generiere alle worte aus der list die der regexp entsprechen
wordlist=self.findWordRegExp(indexName,word)
@@ -2075,7 +2252,8 @@ class CDLIRoot(Folder):
for line in file.split("\n"):
found=False
for word in wordlist:
- if line.find(word)>-1:
+ try: # just a hack because of possible unicode errors in line
+ if line.find(word)>-1:
if lineList: #liste of moeglichen Zeilennummern
num=line.split(".")[0] #Zeilenummer ist alles vor dem . in der Zeile
@@ -2086,13 +2264,15 @@ class CDLIRoot(Folder):
ret.append(line)
break;
+ except:
+ pass
return ret
def tagWordInFile(self,fileId,word,lineList=None,regExp=True,indexName=""):
"""get lines with word fromFileId"""
file=self.showFile(fileId)
- tagStr="""%s"""
+ tagStr=u'%s'
ret=[]
if regExp: # wenn regexp dann generiere alle worte aus der list die der regexp entsprechen
@@ -2101,6 +2281,7 @@ class CDLIRoot(Folder):
wordlist=[word]
for line in file.split("\n"):
+ line = unicodify(line)
found=False
for word in wordlist:
if line.find(word)>-1: #word ist gefunden dann makiere und breche die Schleife ab
@@ -2118,7 +2299,7 @@ class CDLIRoot(Folder):
if not found: #word wurde nicht gefunden keine makierung
ret.append(line)
- return "
\n".join(ret)
+ return u'
\n'.join(ret)
def URLquote(self,str):
"""quote url"""
@@ -2210,7 +2391,35 @@ class CDLIRoot(Folder):
return ret
-
+ def uploadATFRPC(self,data,username):
+ """upload an atffile via xml-rpc"""
+ uploader=uploadATFThread()
+
+ #generate an random id for the upload object
+ from random import randint
+ if (not self.REQUEST.SESSION.get('idTmp',None)):
+
+ idTmp=str(randint(0,1000000000))
+ self.REQUEST.SESSION['idTmp']=idTmp
+ else:
+ idTmp=self.REQUEST.SESSION.get('idTmp',None)
+
+
+ uploader.set(data,0,username,idTmp)
+
+ stObj=uploader.run()
+
+ processor=uploadATFfinallyThread()
+
+ basketname=stObj.returnValue['basketNameFromFile']
+
+ processor.set("uploadchanged",basketname=basketname,SESSION=stObj.returnValue,username=username,serverport=self.REQUEST['SERVER_PORT'])
+
+ processor.run()
+
+
+ return generateXMLReturn(stObj.returnValue)
+
def uploadATF(self,repeat=None,upload=None,basketId=0,RESPONSE=None):
"""upload an atf file / basket file"""
#self._v_uploadATF.returnValue=None