Diff for /ImageArchive/ImageArchive.py between versions 1.69 and 1.109

version 1.69, 2005/10/25 19:42:59 version 1.109, 2012/08/28 09:46:32
Line 1 Line 1
 genericServerPath="http://www.mpiwg-berlin.mpg.de/zogilib_images" #can be changed with main config  """version 1 des Imageservers, wird ersetzt durch version2"""
   
   genericServerPath="http://www.mpiwg-berlin.mpg.de/zogilib_images" #can be changed with main config
   
   
   #from Ft.Xml.Domlette import NonvalidatingReader
 from OFS.Folder import Folder  from OFS.Folder import Folder
   from OFS.OrderedFolder import OrderedFolder
 from OFS.SimpleItem import SimpleItem  from OFS.SimpleItem import SimpleItem
 from Globals import Persistent,package_home  from Globals import Persistent,package_home
 from Acquisition import Implicit  from Acquisition import Implicit
Line 22  import time Line 25  import time
 from threading import Thread  from threading import Thread
 import Queue  import Queue
 import cgi  import cgi
   import sys
   
   import shutil
   
   import logging
   
   #ersetzt logging
   def logger(txt,method,txt2):
       """logging"""
       logging.info(txt+ txt2)
   
   def logTime(msg=""):
       """log the time"""
       logging.info("%s %s"%(msg,time.clock()))
       
   
 from AccessControl import ClassSecurityInfo, getSecurityManager  from AccessControl import ClassSecurityInfo, getSecurityManager
   
Line 30  try: Line 48  try:
 except:  except:
     print "ZSQL Extend Folder nicht importiert"      print "ZSQL Extend Folder nicht importiert"
     print "Metadatendfolder funktioniert nicht!!!"      print "Metadatendfolder funktioniert nicht!!!"
       class ZSQLExtendFolder:
           """leer"""
           manage_options=()
   
   
   
Line 42  except: Line 63  except:
   
         manage_options=()          manage_options=()
   
   tdir="tmp"
 tdir = "/mpiwg/temp/tmp/archivesImageServer/"  #tdir = "/mpiwg/temp/tmp/archivesImageServer/"
 #tdir="/tmp/archivesImageServer/"  #tdir="/tmp/archivesImageServer/"
   
   imageExtensions=['.jpg','.jpeg','.tif','.tiff','.png','.gif']
   
 def splitPath(str):  def splitPath(str):
         str2=str.replace("\\","/")          str2=str.replace("\\","/")
         return os.path.split(str2)[1]          return os.path.split(str2)[1]
Line 71  class generateSet: Line 94  class generateSet:
     """generateSetThread"""      """generateSetThread"""
   
                   
     def __init__(self,filenames,filenamesIds,ImageViewerPath,ids,url,local=None,version="working"):      def __init__(self,filenames,filenamesIds,ImageViewerPath,ImageStoragePath,destBasis,ids,url,local=None,version="working"):
         """init generateSet"""          """init generateSet"""
         self.filenames=filenames          self.filenames=filenames
         self.filenamesIds=filenamesIds          self.filenamesIds=filenamesIds
         self.ImageViewerPath=ImageViewerPath          self.ImageViewerPath=ImageViewerPath
           self.ImageStoragePath=ImageStoragePath
           self.destBasis=destBasis
         self.ids=ids          self.ids=ids
         self.local=local          self.local=local
         self.url=url          self.url=url
         self.version=version          self.version=version
         self.done=None          self.done=None
           self.response=""
                   
   
     def __call__(self):      def __call__(self):
Line 106  class generateSet: Line 132  class generateSet:
   
         for id in self.filenames:          for id in self.filenames:
   
                     if self.filenamesIds.has_key(id[0]):                      if self.filenamesIds.has_key(id[0]) and self.filenamesIds[id[0]][0]:
                             filename=self.filenamesIds[id[0]][0]+"_"+id[0]                              filename=self.filenamesIds[id[0]][0]+"_"+id[0]
                     else:                      else:
                             filename=id[0]                              filename=id[0]
   
                     self.response+=str("<p>Get File: %s<br>\n"%filename)                      self.response+=str("<p>Get File: %s<br>\n"%filename)
   
                       toggle=False
   
                     if self.local:                      if self.local:
                                                           
                             if self.version=="working":                              if self.version=="working":
   
                                     sourcePath="/mpiwg/temp/online/scaled/small/"+self.ImageViewerPath+"/"+os.path.splitext(id[0])[0]+".jpg"                                      sourcePath=self.destBasis+"/"+self.ImageViewerPath+"/"+os.path.splitext(id[0])[0]+".jpg"
                             else:                                      if not os.path.exists(sourcePath):
                                     sourcePath="/mpiwg/online/"+self.ImageViewerPath+"/"+id[0]                                              self.response+=str("<p>%s doesn't exist I'll try the non scaled image</p>"%sourcePath)
                                               toggle=True
                               if (self.version!="working") or toggle:
                                       toggle=False
                                       sourcePath=self.ImageStoragePath+"/"+id[0]
                                       if not os.path.exists(sourcePath):
                                           sourcePath=self.ImageStoragePath+"/"+os.path.splitext(id[0])[0]+".jpg"
                                                         
                             targetPath=tmpPath+"/"+filename                              targetPath=tmpPath+"/"+filename
                             try:                              try:
                                 shutil.copyfile(sourcePath,targetPath)                                  shutil.copyfile(sourcePath,targetPath)
                             except:                              except:
                                 self.response+=(str("<p>Error in File: %s (possible missing)<br>\n"%filename))                                  self.response+=(str("<p>Error in File: %s (possible missing)<br>\n"%sourcePath))
                     else:                      else:
                             if self.version=="working":                              if self.version=="working":
                                     requestString=self.ImageViewerPath+"/"+os.path.splitext(urllib.quote(id[0]))[0]+"&dh=2000&dw=2000"                                      requestString=self.ImageViewerPath+"/"+os.path.splitext(urllib.quote(id[0]))[0]+"&dh=2000&dw=2000"
Line 274  class ImageDigilib(Folder,Persistent,Imp Line 308  class ImageDigilib(Folder,Persistent,Imp
     manage_options = Folder.manage_options+(      manage_options = Folder.manage_options+(
                   
         {'label':'Add Metadata','action':'addMetaObjectForm'},          {'label':'Add Metadata','action':'addMetaObjectForm'},
                   {'label':'View Info','action':'editImageDigilib'},
         )          )
   
       def editImageDigilib(self):
           """edit image date"""
           pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','editImageDigilib.zpt')).__of__(self)
           return pt()        
   
   
           
     def getAccessRight(self):      def getAccessRight(self):
         """get the accessright, return is string "extern" or "intern" """          """get the accessright, return is string "extern" or "intern" """
         return self.getRights(self.filename.split('.')[0])          return self.getRights(self.filename.split('.')[0])
                     
       security.declarePublic('isAccessible')
     
     def isAccessible(self):      def isAccessible(self):
         """gives true if obejct is accessible taking the rights of the user into account"""          """gives true if obejct is accessible taking the rights of the user into account"""
                   logTime("isaccessible")
         #TODO: implement rights, currently  true if external and false if internal, and true if user has role authenticated          #TODO: implement rights, currently  true if external and false if internal, and true if user has role authenticated
           
         username=self.REQUEST['AUTHENTICATED_USER']          username=self.REQUEST['AUTHENTICATED_USER']
Line 293  class ImageDigilib(Folder,Persistent,Imp Line 335  class ImageDigilib(Folder,Persistent,Imp
         user=getSecurityManager().getUser()          user=getSecurityManager().getUser()
   
         roles=user.getRoles()          roles=user.getRoles()
   
           
           if self.getRightsQuery()=="":
               #query empty then always true
               return True
   
   
         if 'Authenticated' in roles:          if 'Authenticated' in roles:
             return True              return True
                   
Line 330  class ImageDigilib(Folder,Persistent,Imp Line 379  class ImageDigilib(Folder,Persistent,Imp
         self.filename=filename          self.filename=filename
         self.meta=meta          self.meta=meta
   
       def getBasename(self):
           """returns base filename (sans extension)"""
           return os.path.splitext(self.filename)[0]
   
     def getMeta(self):      def getMeta(self):
         """ausgabe der metadaten"""          """ausgabe der metadaten"""
Line 357  class ImageDigilib(Folder,Persistent,Imp Line 409  class ImageDigilib(Folder,Persistent,Imp
     def uploadImage(self,fileupload,path_name):      def uploadImage(self,fileupload,path_name):
         """upload an Image from an Requast"""          """upload an Image from an Requast"""
         #path_name=self.ImageStoragePath          #path_name=self.ImageStoragePath
         fn=splitPath(fileupload.filename)          fn = self.filename or splitPath(fileupload.filename)
           fn = os.path.splitext(fn)[0]+os.path.splitext(fileupload.filename)[1] # Extensions des gespeicherten Files sollte gleich dem hochgeladenen File sein.
         filename=path_name+"/"+fn          filename=path_name+"/"+fn
         filedata=fileupload.read()          filedata=fileupload.read()
         f=open(filename,"w")          f=open(filename,"w")
         f.write(filedata)          f.write(filedata)
         f.close()          f.close()
           self.filename = fn
           
         try:          try:
             os.chmod(filename,0664)              os.chmod(filename,0664)
         except:          except:
             """hack"""              """hack"""
         #scale thumb          #< thumb
                   
         self.scaleThumbs()          self.scaleThumbs()
   
Line 427  class ImageDigilib(Folder,Persistent,Imp Line 482  class ImageDigilib(Folder,Persistent,Imp
             self.title=newname[0:]              self.title=newname[0:]
             self.filename=newname[0:]                 self.filename=newname[0:]   
             #umbennen des files auf dem server              #umbennen des files auf dem server
             oldpath=os.path.join(self.ImageStoragePath,oldname)              oldpath=os.path.join(self.getImageStoragePath(),oldname)
             newpath=os.path.join(self.ImageStoragePath,newname)              newpath=os.path.join(self.getImageStoragePath(),newname)
             os.rename(oldpath,newpath)              os.rename(oldpath,newpath)
                           
             #umbenennen des versionsfolders              #umbenennen des versionsfolders
             oldfolder=os.path.join(self.ImageStoragePath,"."+oldname+".dir")              oldfolder=os.path.join(self.getImageStoragePath(),"."+oldname+".dir")
             newfolder=os.path.join(self.ImageStoragePath,"."+newname+".dir")              newfolder=os.path.join(self.getImageStoragePath(),"."+newname+".dir")
             if os.path.exists(oldfolder):              if os.path.exists(oldfolder):
                 os.rename(oldfolder,newfolder)                  os.rename(oldfolder,newfolder)
             else:              else:
Line 465  class ImageDigilib(Folder,Persistent,Imp Line 520  class ImageDigilib(Folder,Persistent,Imp
   
             self.scaleWorkingVersions()              self.scaleWorkingVersions()
   
               #self.scaleToJpg()
             if RESPONSE:              if RESPONSE:
                     RESPONSE.redirect(self.aq_parent.absolute_url()+"?filename="+self.filename)                      RESPONSE.redirect(self.aq_parent.absolute_url()+"?filename="+self.filename)
                   
       def scaleToJpg(self,RESPONSE=None):
           """create a  jpg"""
           
           #create backup of the original file
           
           imagePath=os.path.join(self.getImageStoragePath(),self.filename)
           path=os.path.join(self.getImageStoragePath(),"."+self.getId()+".dir")
                   
           if not os.path.exists(path):
               os.mkdir(path,0775)
               os.chmod(path,0775)
               
           newName=os.path.join(path,self.getId()+str(time.time()))
   
           if os.path.exists(newName):
               logger("ImageArchive:scaleToJpg", logging.INFO, "%s already exists"%newName)
           else:
               try:
                   os.rename(imagePath,newName)
               except:
                   logger("ImageArchive:scaleToJpg", logging.ERROR, "%s "%newName)
                   return False
               
           ext= os.path.splitext(imagePath)[1].lower()
           if ext.rstrip()==".jpg":
                   shutil.copy(newName,imagePath)
                   print "copy",imagePath
                   return True
   
     def updateImage(self,file,rename=None,RESPONSE=None):  
   
           dir=self.getId()
           src=path
           self.scale(dest=self.getImageStoragePath(),dir=dir,src=path,scaleBy=1,RESPONSE=RESPONSE)
           return True
       
       def updateImage(self,_fileupload,_rename=None,RESPONSE=None):
             """lade neues Version des Bildes"""              """lade neues Version des Bildes"""
             #teste ob Dokumenten ordner schon vorhanden              #teste ob Dokumenten ordner schon vorhanden
             imagePath=os.path.join(self.ImageStoragePath,self.getId())          #imagePath=os.path.join(self.getImageStoragePath(),self.getId())
             path=os.path.join(self.ImageStoragePath,"."+self.getId()+".dir")          
           logging.error("updateImage:"+self.filename)
           identifyField="filename"
           
           if _fileupload and _fileupload.filename!="":
               imagePath=os.path.join(self.getImageStoragePath(),self.filename)
               idWithoutSuffix= os.path.splitext(self.getId())[0]
               path=os.path.join(self.getImageStoragePath(),"."+self.getId()+".dir")
                           
             if not os.path.exists(path):              if not os.path.exists(path):
                     os.mkdir(path,0775)                      os.mkdir(path,0775)
Line 484  class ImageDigilib(Folder,Persistent,Imp Line 581  class ImageDigilib(Folder,Persistent,Imp
   
             #teste ob version schon existiert              #teste ob version schon existiert
   
             while os.path.exists(os.path.join(path,"V%i_%s"%(versionNumber,self.getId()))):              while os.path.exists(os.path.join(path,"V%i_%s"%(versionNumber,self.filename))):
                     versionNumber+=1                      versionNumber+=1
   
             #kopieren der bestehenden Version in den Versions ordner.              #kopieren der bestehenden Version in den Versions ordner.
             imageNewPath=os.path.join(path,"V%i_%s"%(versionNumber,self.getId()))              imageNewPath=os.path.join(path,"V%i_%s"%(versionNumber,self.filename))
               try:    
                       #logger("ImageArchive:updateImage", logging.INFO, "rename: %s -> %s"%(imagePath,imageNewPath))
             os.rename(imagePath,imageNewPath)              os.rename(imagePath,imageNewPath)
               except:
                   logger("ImageArchive:updateImage ", logging.ERROR, "rename: %s -> %s didn't work!"%(imagePath,imageNewPath))      
   
             #lesen des upload files und schreiben              #lesen des upload files und schreiben
             filedata=file.read()              filedata=_fileupload.read()
             f=open(imagePath,"w")              
               #passe suffix an
               oldNameBase=os.path.splitext(imagePath)[0]
               uploadFileExt=os.path.splitext(_fileupload.filename)[1]
               
               newImagePath=oldNameBase+uploadFileExt
               
               f=open(newImagePath,"w") # if we wanted to have filename=id we should do it here!
               logging.error("saving:"+newImagePath)
             f.write(filedata)              f.write(filedata)
             f.close()              f.close()
             try:              try:
                     os.chmod(imagePath,0664)                  os.chmod(newImagePath,0664)
             except:              except:
                     """hack"""                  pass
             #scale thumb              #scale thumb
                   
             self.scaleThumbs()              self.scaleThumbs()
Line 507  class ImageDigilib(Folder,Persistent,Imp Line 616  class ImageDigilib(Folder,Persistent,Imp
             #scale standard              #scale standard
   
             self.scaleWorkingVersions()              self.scaleWorkingVersions()
               #self.scaleToJpg()
               if _rename:
                   self.renameImage(_fileupload.filename)
   
             if rename:              else: 
                 self.renameImage(file.filename)                  self.filename=os.path.splitext(self.filename)[0]+uploadFileExt # Aendere zumindest die Extensiion
                   
           try: #todo: sollte nur aufgerufen werden, wenn eine Datenbank dahinter liegt.
               args=self.REQUEST.form
          
               args['-identify']=identifyField+"="+args['_identifyField']
            
               self.ZSQLChange(args=args)
            
           except:
               pass
                   
             if RESPONSE:              if RESPONSE:
                     RESPONSE.redirect(self.aq_parent.absolute_url()+"?filename="+self.filename)                      RESPONSE.redirect(self.aq_parent.absolute_url()+"?filename="+self.filename)
Line 518  class ImageDigilib(Folder,Persistent,Imp Line 639  class ImageDigilib(Folder,Persistent,Imp
   
             return "done"              return "done"
                           
       security.declarePublic('thumb')
     def thumb(self,url=None):      def thumb(self,url=None):
         """show thumb"""          """show thumb"""
         thumbname=os.path.splitext(self.filename)[0]+".jpg"          thumbname=os.path.splitext(self.filename)[0]+".jpg"
Line 543  class ImageDigilib(Folder,Persistent,Imp Line 665  class ImageDigilib(Folder,Persistent,Imp
                   
   
           
         self.REQUEST.SESSION['string']="<img border=\"0\" src=\"%s\">"% path          imageString="<img border=\"0\" src=\"%s\">"% path
           self.REQUEST.SESSION['string']=imageString
         if url:          if url:
             return "<img border=\"0\" src=\"%s\">"% path              return "<img border=\"0\" src=\"%s\">"% path
         else:          else:
Line 553  class ImageDigilib(Folder,Persistent,Imp Line 676  class ImageDigilib(Folder,Persistent,Imp
                 return getattr(self,overview[0][0])()                  return getattr(self,overview[0][0])()
             else:              else:
                 pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','thumbMD.zpt')).__of__(self)                  pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','thumbMD.zpt')).__of__(self)
                 return pt()                  return pt(imageString=imageString)
   
   
     def image(self,dw=None,dh=None):      def image(self,dw=None,dh=None):
Line 591  def manage_AddImageDigilib(self,id,fileu Line 714  def manage_AddImageDigilib(self,id,fileu
     """Add ImageCollection"""      """Add ImageCollection"""
           
     #fileupload=self.REQUEST['fileupload']      #fileupload=self.REQUEST['fileupload']
     fn=splitPath(fileupload.filename)      #fn=splitPath(fileupload.filename)
       fn = id # filename is the same as id
     newObj=ImageDigilib(id,fn,meta)      newObj=ImageDigilib(id,fn,meta)
           
     self._setObject(id,newObj)      self._setObject(id,newObj)
     getattr(self,id).uploadImage(fileupload,self.ImageStoragePath)      getattr(self,id).uploadImage(fileupload,self.getImageStoragePath())
           
     if RESPONSE is not None:      if RESPONSE is not None:
         RESPONSE.redirect('manage_main')          RESPONSE.redirect('manage_main')
   
                                     
   
 class ImageCollection(Folder, Persistent, Implicit,ECHO_basis):  class ImageCollection(OrderedFolder, Persistent, Implicit,ECHO_basis):
     """Sammelordner fuer Bilder"""      """Sammelordner fuer Bilder"""
     meta_type="ImageCollection"      meta_type="ImageCollection"
   
Line 622  class ImageCollection(Folder, Persistent Line 746  class ImageCollection(Folder, Persistent
           
     defaultMetaString="http://fm-web.mpiwg-berlin.mpg.de:8050/FMRes/FMPJS?-db=Wissenschaftlerportraits.fp5&-layID=69&-token=25&-max=1&-format=formvwcss.htm&-mode=browse&images::filename=%s&-find" ## TEST FUER IMAGEDATENBANK WP      defaultMetaString="http://fm-web.mpiwg-berlin.mpg.de:8050/FMRes/FMPJS?-db=Wissenschaftlerportraits.fp5&-layID=69&-token=25&-max=1&-format=formvwcss.htm&-mode=browse&images::filename=%s&-find" ## TEST FUER IMAGEDATENBANK WP
   
       imgcoll_main = PageTemplateFile('zpt/overview', globals())
       imgcoll_mainMD = PageTemplateFile('zpt/overviewMD', globals())
       imgcoll_thumb = PageTemplateFile('zpt/thumb', globals())
       imgcoll_thumbMD = PageTemplateFile('zpt/thumbMD', globals())    
   
       destBasis="/docuserver/scaled/"
       scaledBasis=destBasis
       srcBasis="/docuserver/images"
       scaleomatStr="/docuserver/libs/scaleomat/scaleomat.pl"
       
       #dest="/Volumes/paviaExtern/docuserver/images/exhibitionImages/"
       
       def configScaleForm(self):
           """configure the scaler form"""
           pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','configScale.zpt')).__of__(self)
           return pt()        
   
       def configScale(self,scaleomatStr,RESPONSE=None):
           """config the scaler"""
           self.scaleomatStr=scaleomatStr
           
               
           if RESPONSE is not None:
               RESPONSE.redirect('manage_main')
   
       def scale(self,dest=None,dir=None,src=None,scaleTo=None,scaleBy=None,RESPONSE=None):
           """scaler"""
           #scaleomatStr="ssh nausikaa2.rz-berlin.mpg.de /usr/local/mpiwg/scripts/scaleomat.pl -src=/mpiwg/online/ %s"
           scaleomatStr=self.scaleomatStr
   
           destBasis=self.destBasis
           srcBasis=self.srcBasis
           
           
           if src:
                srcStr=" -src=%s"%src
           else:
                srcStr=" -src=%s"%srcBasis
   
           scaleStr=scaleomatStr+srcStr
           if dir:
               dirTmp=dir.replace(srcBasis,'')
               dirStr=" -dir=%s"%dirTmp
               scaleStr=scaleStr+dirStr
           elif filename:
               fileTmp=filename.replace(srcBasis,'')
               fileStr=" -dir=%s"%fileTmp
               scaleStr=scaleStr+fileStr
           else:
               logger("ImageCollection:scale",logging.ERROR,"no directory or filename given")
               return False
           
           if dest is not None:
               destStr=" -dest=%s"%os.path.join(destBasis,dest)
               scaleStr=scaleStr+destStr
           else:
               logger("ImageCollection:scale",logging.ERROR,"no destionation given")
               return False
           
           if scaleTo:
               scaleToStr=" -scaleto=%s"%scaleTo
               scaleStr=scaleStr+scaleToStr
           elif scaleBy:
               scaleByStr=" -scaleby=%s"%scaleBy
               scaleStr=scaleStr+scaleByStr
           else:
               logger("ImageCollection:scale",logging.ERROR,"no destionation given")
               return False
        
          
           #ret=scaleStr
           logger("ImageCollection:scale",logging.INFO,scaleStr)
           ret=os.popen2(scaleStr,1)[1].read()
    
           if RESPONSE:
                RESPONSE.write(ret)
           return True
    
       def getImageObject(self,name):
           """gibt objeckt name zurueck"""
           if hasattr(self,name):
               return getattr(self,name)
           
           name=os.path.splitext(name)[0]
           for extension in imageExtensions:
               nameExt=name+extension
   
               if hasattr(self,nameExt):
                   return getattr(self,nameExt)
               
               nameExt=name+"_"+extension
               if hasattr(self,nameExt):
                   return getattr(self,nameExt)
           
           return getattr(self,"defaultImg")
           
     def getServerPath(self):      def getServerPath(self):
         """get Server path"""          """get Server path"""
         return getattr(self,'serverPath',genericServerPath)          return getattr(self,'serverPath',genericServerPath)
Line 636  class ImageCollection(Folder, Persistent Line 856  class ImageCollection(Folder, Persistent
   
     def getImageStoragePath(self):      def getImageStoragePath(self):
         """get ImageStoragePath"""          """get ImageStoragePath"""
         return self.ImageStoragePath          if self.ImageViewerPath[0]=="/":
               if len(self.ImageViewerPath)>1:
                   iv=self.ImageViewerPath[1:]
               else:
                   iv=""
           else:
                   iv=self.ImageViewerPath
   
           return os.path.join(self.srcBasis,iv)
           
     def refreshTxt(self):      def refreshTxt(self):
         """txt fuer refresh"""          """txt fuer refresh"""
Line 650  class ImageCollection(Folder, Persistent Line 878  class ImageCollection(Folder, Persistent
                   
                                                 
             if not threadName or threadName=="":              if not threadName or threadName=="":
                 threadStart=generateSet(self.REQUEST.SESSION['filenames'],self.REQUEST.SESSION['filenamesIds'],self.ImageViewerPath,self.show_thumbs(),self.absolute_url(),local=local,version=version)                  threadStart=generateSet(self.REQUEST.SESSION['filenames'],self.REQUEST.SESSION['filenamesIds'],self.ImageViewerPath,self.ImageStoragePath,self.destBasis,self.show_thumbs(),self.absolute_url(),local=local,version=version)
                 thread=Thread(target=threadStart)                  thread=Thread(target=threadStart)
                                   
                 thread.start()                  thread.start()
Line 723  class ImageCollection(Folder, Persistent Line 951  class ImageCollection(Folder, Persistent
             self.REQUEST.RESPONSE.close()              self.REQUEST.RESPONSE.close()
   
                                           
       def scaleToJpgs(self,RESPONSE=None):
           """scale all tifs to jps"""
   
           for x in self._objects:
                   
                   if (not hasattr(getattr(self,x['id']),'scaleToJpg')) or (not getattr(self,x['id']).scaleToJpg()):
                       if RESPONSE:
                           RESPONSE.write('error:%s'%x)
                   
                   
                                           
     def scaleThumbs(self,RESPONSE=None):      def scaleThumbs(self,RESPONSE=None):
         """scale thumbs"""          """scale thumbs"""
                   
         #scale thumbs          #scale thumbs
         ret=os.popen("ssh nausikaa2.rz-berlin.mpg.de /usr/local/mpiwg/scripts/scaleomat.pl -src=/mpiwg/online/ -dir=%s -dest=/mpiwg/temp/online/scaled/thumb -scaleto=100 &"% self.ImageViewerPath)          dest=os.path.join(self.scaledBasis,'thumb')
         if RESPONSE:          self.scale(dir=self.getImageStoragePath(),dest=dest,scaleTo=100,RESPONSE=RESPONSE)
                 RESPONSE.write(ret.read())          #ret=os.popen("ssh nausikaa2.rz-berlin.mpg.de /usr/local/mpiwg/scripts/scaleomat.pl -src=/mpiwg/online/ -dir=%s -dest=/mpiwg/temp/online/scaled/thumb -scaleto=100 &"% self.ImageViewerPath)
                 RESPONSE.write("\n")          #if RESPONSE:
           #        RESPONSE.write(ret.read())
           #        RESPONSE.write("\n")
                                   
         return "RESCALING STARTED"          return "RESCALING STARTED"
   
Line 740  class ImageCollection(Folder, Persistent Line 980  class ImageCollection(Folder, Persistent
                   
         #scale standard          #scale standard
   
         ret=os.popen("ssh nausikaa2.rz-berlin.mpg.de /usr/local/mpiwg/scripts/scaleomat.pl -src=/mpiwg/online/ -dir=%s -dest=/mpiwg/temp/online/scaled/small -scaleto=2000 &"% self.ImageViewerPath)          dest=os.path.join(self.scaledBasis,'small')
           self.scale(dir=self.getImageStoragePath(),dest=dest,scaleTo=1000,RESPONSE=RESPONSE)
           
           dest=os.path.join(self.scaledBasis,'medium')
           self.scale(dir=self.getImageStoragePath(),dest=dest,scaleTo=2000,RESPONSE=RESPONSE)
          
           #ret=os.popen("ssh nausikaa2.rz-berlin.mpg.de /usr/local/mpiwg/scripts/scaleomat.pl -src=/mpiwg/online/ -dir=%s -dest=/mpiwg/temp/online/scaled/small -scaleto=2000 &"% self.ImageViewerPath)
         if RESPONSE:          if RESPONSE:
                 RESPONSE.write(ret.read())                  RESPONSE.write(ret.read())
                 RESPONSE.write("\n")                  RESPONSE.write("\n")
         return "rescaling started"          return "rescaling started"
   
   
           def __init__(self,id,title,ImageViewerPath,defaultMetaString,destBasis,srcBasis,serverPath=genericServerPath):
     def __init__(self,id,title,ImageStoragePath,ImageViewerPath,defaultMetaString,serverPath=genericServerPath):  
         self.id=id          self.id=id
         self.title=title          self.title=title
         self.ImageStoragePath=ImageStoragePath  
         self.ImageViewerPath=ImageViewerPath          self.ImageViewerPath=ImageViewerPath
         self.defaultMetaString=defaultMetaString          self.defaultMetaString=defaultMetaString
         self.serverPath=serverPath          self.serverPath=serverPath
           self.destBasis=destBasis
           self.srcBasis=srcBasis
           self.defaultrows = 6
           self.defaultcols = 2
   
     optTMP= Folder.manage_options      optTMP= Folder.manage_options
   
     manage_options = optTMP+(      manage_options = optTMP+(
         {'label':'Main Config','action':'ImageCollection_config'},          {'label':'Main Config','action':'ImageCollection_config'},
           {'label':'Config Scaler','action':'configScaleForm'},
         {'label':'Import','action':'ImportFiles'},          {'label':'Import','action':'ImportFiles'},
         {'label':'Recalculate MetadataLink','action':'recalculateMetaLink'},          {'label':'Recalculate MetadataLink','action':'recalculateMetaLink'},
         {'label':'Import Metadata File','action':'importMetaFileForm'},          {'label':'Import Metadata File','action':'importMetaFileForm'},
Line 774  class ImageCollection(Folder, Persistent Line 1023  class ImageCollection(Folder, Persistent
         """import metadata, if strict ist not None then only metadata will be rebuild where metadata is empty"""          """import metadata, if strict ist not None then only metadata will be rebuild where metadata is empty"""
                   
         for image in self.ZopeFind(self,obj_metatypes=["ImageDigilib"]):          for image in self.ZopeFind(self,obj_metatypes=["ImageDigilib"]):
             print image[1].getId()             
             image[1].manageMetaData(strict)              image[1].manageMetaData(strict)
         return "ok"          return "ok"
                   
Line 887  class ImageCollection(Folder, Persistent Line 1136  class ImageCollection(Folder, Persistent
                   
                           
     def xmlinput(self,url):      def xmlinput(self,url):
         """Anzeige <n ausgewaehlten thumbs"""          """Anzeige von ausgewaehlten thumbs"""
         #return url          #return url
                   
         url=urllib.unquote(url)          url=urllib.unquote(url)
Line 896  class ImageCollection(Folder, Persistent Line 1145  class ImageCollection(Folder, Persistent
         try:          try:
                 dom=xml.dom.minidom.parseString(xmldoc)                  dom=xml.dom.minidom.parseString(xmldoc)
         except:          except:
                 return xmldoc                  return "ERROR: (%s %s) %s"%(sys.exc_info()[0],sys.exc_info()[1],xmldoc)
   
         images=dom.getElementsByTagName('image')          images=dom.getElementsByTagName('image')
   
         rc=[]          rc=[]
Line 906  class ImageCollection(Folder, Persistent Line 1156  class ImageCollection(Folder, Persistent
                                   
                                   
                                   
                   
                 idnr=image.getElementsByTagName('idnr')[0]                  idnr=image.getElementsByTagName('idnr')[0]
                 id=getText(idnr.childNodes)                  id=getText(idnr.childNodes)
                   try:
                 numberOfPages=image.getElementsByTagName('numberOfPages')[0]                  numberOfPages=image.getElementsByTagName('numberOfPages')[0]
                   except:
                       numberOfPages=None
                       
                   if numberOfPages:
                 nopT=getText(numberOfPages.childNodes)                  nopT=getText(numberOfPages.childNodes)
                 try:                  try:
                         nop=int(nopT)                          nop=int(nopT)
                 except:                  except:
                         nop=0                          nop=0
                   else:
                       nop=0
                               
                 texts=getText(imagename.childNodes).split("\n") #mehrere bilder in return getrennter liste                  texts=getText(imagename.childNodes).split("\n") #mehrere bilder in return getrennter liste
                 for text in texts:                  for text in texts:
                     if not text=="":                      if not text=="":
                           text=self.getImageByName(text,onlyName="yes")
                         try:                          try:
                                 rc.append((str(text),id,nop))                                  rc.append((str(text),id,nop))
                                 fnIds[str(text)]=(id,nop)                                  fnIds[str(text)]=(id,nop)
Line 929  class ImageCollection(Folder, Persistent Line 1189  class ImageCollection(Folder, Persistent
         self.REQUEST.SESSION['filenames']=rc          self.REQUEST.SESSION['filenames']=rc
         self.REQUEST.SESSION['filenamesIds']=fnIds          self.REQUEST.SESSION['filenamesIds']=fnIds
                   
           overview=self.ZopeFind(self,obj_ids=['overview_selected.html'])
               
           if overview:
                   return overview[0][1]()
           else:
                   pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','overview_selected.zpt')).__of__(self)
                   return pt()        
           
         pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','overview_selected.zpt')).__of__(self)          pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','overview_selected.zpt')).__of__(self)
         return pt()                  return pt()        
   
Line 962  class ImageCollection(Folder, Persistent Line 1230  class ImageCollection(Folder, Persistent
         else:          else:
             meta=None              meta=None
                   
         if fileName:          fn=fileName or splitPath(fileupload.filename)
             fn=fileName  
         else:  
             fn=splitPath(fileupload.filename)  
                   
         manage_AddImageDigilib(self,fn,fileupload,meta=meta)          manage_AddImageDigilib(self,fn,fileupload,meta=meta)
                   
Line 975  class ImageCollection(Folder, Persistent Line 1240  class ImageCollection(Folder, Persistent
   
     def ImportFiles2(self,RESPONSE=None):      def ImportFiles2(self,RESPONSE=None):
         """Import the existing files of a folder"""          """Import the existing files of a folder"""
         files=os.listdir(self.ImageStoragePath)          files=os.listdir(self.getImageStoragePath())
         ret=""          ret=""
         #print self.__dict__          #print self.__dict__
         for file in files:          for file in files:
             if not file[0]==".":              fn=os.path.splitext(file)[0]
                 if self.__dict__.has_key(file):              if not (file[0]=="."):
                   if self.__dict__.has_key(file) or self.__dict__.has_key(fn+'.tif') or self.__dict__.has_key(fn+'.tiff') :
   
                     ret=ret+"<br>"+file+" already exists!"                      ret=ret+"<br>"+file+" already exists!"
                 else:                  else:
Line 992  class ImageCollection(Folder, Persistent Line 1258  class ImageCollection(Folder, Persistent
                     self._setObject(file,newObj)                      self._setObject(file,newObj)
         #print ret          #print ret
         #pt=PageTemplateFile('Products/ImageArchive/out.zpt')).__of__(self)          #pt=PageTemplateFile('Products/ImageArchive/out.zpt')).__of__(self)
         #print self.ImageStoragePath          #print self.getImageStoragePath()
   
         #scale thumb          #scale thumb
                   
Line 1016  class ImageCollection(Folder, Persistent Line 1282  class ImageCollection(Folder, Persistent
   
     def ImportStructure(self,RESPONSE=None):      def ImportStructure(self,RESPONSE=None):
         """Import the existing files of a folder"""          """Import the existing files of a folder"""
         files=os.listdir(self.ImageStoragePath)          files=os.listdir(self.getImageStoragePath())
         ret=""          ret=""
         #print self.__dict__          #print self.__dict__
   
   
         for file in files:          for file in files:
                           
             if os.path.isdir(os.path.join(self.ImageStoragePath,file)):              if os.path.isdir(os.path.join(self.getImageStoragePath(),file)):
                 imageStoragePath=os.path.join(self.ImageStoragePath,file)                  ImageStoragePath=os.path.join(self.getImageStoragePath(),file)
                 imageViewerPath=os.path.join(self.ImageViewerPath,file)                  imageViewerPath=os.path.join(self.ImageViewerPath,file)
                 manage_AddImageCollection(self,file,file,imageStoragePath,imageViewerPath,self.defaultMetaString)                  #manage_AddImageCollection(self,file,file,self.getImageStoragePath(),imageViewerPath,self.defaultMetaString)
                               manage_AddImageCollection(self,file,file,imageViewerPath,self.defaultMetaString,self.destBasis,self.srcBasis,self.serverPath)
                 obj=getattr(self,file)                  obj=getattr(self,file)
                 obj.ImportStructure()                  obj.ImportStructure()
             else:              else:
Line 1046  class ImageCollection(Folder, Persistent Line 1312  class ImageCollection(Folder, Persistent
                             """nothing yet"""                              """nothing yet"""
         #print ret          #print ret
         #pt=PageTemplateFile('Products/ImageArchive/out.zpt')).__of__(self)          #pt=PageTemplateFile('Products/ImageArchive/out.zpt')).__of__(self)
         #print self.ImageStoragePath          #print self.getImageStoragePath()
   
                 #scale thumb                  #scale thumb
                   
         #self.scaleThumbs()          self.scaleThumbs()
   
         #scale standard          #scale standard
   
         #self.scaleWorkingVersions()          self.scaleWorkingVersions()
                   
         if RESPONSE:          if RESPONSE:
                 RESPONSE.redirect('manage_main')                  RESPONSE.redirect('manage_main')
           
     def ImportFiles(self,RESPONSE=None):      def ImportFiles(self,RESPONSE=None):
         """Import the existing files of a folder"""          """Import the existing files of a folder"""
         files=os.listdir(self.ImageStoragePath)          files=os.listdir(self.getImageStoragePath())
         ret=""          ret=""
         #print self.__dict__          #print self.__dict__
         for file in files:          for file in files:
             if not file[0]==".":              fn=os.path.splitext(file)[0]
                 if self.__dict__.has_key(file):              if not (file[0]=="."):
                   if self.__dict__.has_key(file) or self.__dict__.has_key(fn+'.tif') or self.__dict__.has_key(fn+'.tiff') :
   
                     ret=ret+"<br>"+file+" already exists!"                      ret=ret+"<br>"+file+" already exists!"
   
                 else:                  else:
                     ret=ret+"<br>"+file+" created!"                      ret=ret+"<br>"+file+" created!"
                     newObj=ImageDigilib(file,file)                      newObj=ImageDigilib(file,file)
Line 1080  class ImageCollection(Folder, Persistent Line 1348  class ImageCollection(Folder, Persistent
                         """nothing yet"""                          """nothing yet"""
         #print ret          #print ret
         #pt=PageTemplateFile('Products/ImageArchive/out.zpt')).__of__(self)          #pt=PageTemplateFile('Products/ImageArchive/out.zpt')).__of__(self)
         #print self.ImageStoragePath          #print self.getImageStoragePath()
   
                 #scale thumb                  #scale thumb
                   
Line 1101  class ImageCollection(Folder, Persistent Line 1369  class ImageCollection(Folder, Persistent
         pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','ChangeImageCollectionForm.zpt')).__of__(self)          pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','ChangeImageCollectionForm.zpt')).__of__(self)
         return pt()          return pt()
   
     def ChangeImageCollection(self,title,ImageStoragePath,ImageViewerPath,defaultMetaString,serverPath,RESPONSE=None):      def ChangeImageCollection(self,title,ImageViewerPath,defaultMetaString,serverPath,destBasis,srcBasis,RESPONSE=None):
         """Change"""          """Change"""
         self.title=title          self.title=title
         self.ImageStoragePath=ImageStoragePath  
         self.ImageViewerPath=ImageViewerPath          self.ImageViewerPath=ImageViewerPath
         self.defaultMetaString=defaultMetaString          self.defaultMetaString=defaultMetaString
         self.serverPath=serverPath          self.serverPath=serverPath
           self.destBasis=destBasis
           self.srcBasis=srcBasis
                   
         if RESPONSE is not None:          if RESPONSE is not None:
             RESPONSE.redirect('manage_main')              RESPONSE.redirect('manage_main')
Line 1129  class ImageCollection(Folder, Persistent Line 1398  class ImageCollection(Folder, Persistent
         ids.sort()          ids.sort()
         return ids          return ids
   
     def firstSets(self,selected=None):      def firstSets(self,selected=None,text='first set'):
         ids=self.show_thumbs()          ids=self.show_thumbs()
         if ids:          if ids:
             if selected:              if selected:
                 return "<a href=\""+self.REQUEST['URL1']+"/selection?filename="+ids[0]+"\" target=\"_top\">first sets</a>"                  return "<a href=\""+self.REQUEST['URL1']+"/selection?filename="+ids[0]+"\" target=\"_top\">"+text+"</a>"
             else:              else:
                 return "<a href=\""+self.REQUEST['URL1']+"?filename="+ids[0]+"\" target=\"_top\">first sets</a>"                  return "<a href=\""+self.REQUEST['URL1']+"?filename="+ids[0]+"\" target=\"_top\">"+text+"</a>"
   
     def lastSets(self,selected=None):      def lastSets(self,selected=None,text='last set'):
         ids=self.show_thumbs()          ids=self.show_thumbs()
         if ids:          if ids:
             colRows=self.getColTimesRow()              colRows=self.getColTimesRow()
Line 1151  class ImageCollection(Folder, Persistent Line 1420  class ImageCollection(Folder, Persistent
                 nr=0                  nr=0
   
             if selected:              if selected:
                 return "<a href=\""+self.REQUEST['URL1']+"/selection?filename="+ids[nr]+"\" target=\"_top\">last set</a>"                  return "<a href=\""+self.REQUEST['URL1']+"/selection?filename="+ids[nr]+"\" target=\"_top\">"+text+"</a>"
             else:              else:
                 return "<a href=\""+self.REQUEST['URL1']+"?filename="+ids[nr]+"\" target=\"_top\">last sets</a>"                  return "<a href=\""+self.REQUEST['URL1']+"?filename="+ids[nr]+"\" target=\"_top\">"+text+"</a>"
   
                   
                                   
     def nextSets(self,selected=None):      def nextSets(self,selected=None,text='next set'):
         """show nextimage"""          """show nextimage"""
         ids=self.show_thumbs()          ids=self.show_thumbs()
         colRows=self.getColTimesRow()          colRows=self.getColTimesRow()
           pagesize = colRows[0] * colRows[1]
         if ids:          if ids:
             if colRows[1]:              if colRows[1]:
   
                 if self.REQUEST.SESSION.has_key("filename"):                  if self.REQUEST.SESSION.has_key("filename"):
                     filename=self.REQUEST.SESSION["filename"]                      filename=self.REQUEST.SESSION["filename"]
                     try:                      try:
                         nr=ids.index(filename)+colRows[0]*colRows[1]                          nr=ids.index(filename)+pagesize
                         if nr>=len(ids):                          if nr>=len(ids):
                             nr=len(ids)-1                              return ""
                     except:                      except:
                         nr=0                          nr=pagesize
                 else:                  else:
                     nr=0                      nr = pagesize
   
                 if nr==len(ids)-1:                  if nr>=len(ids)-1:
                     return ""                      return ""
                 else:                  else:
                     if selected:                      if selected:
                         return "<a href=\""+self.REQUEST['URL1']+"/selection?filename="+ids[nr]+"\" target=\"_top\">next set</a>"                          return "<a href=\""+self.REQUEST['URL1']+"/selection?filename="+ids[nr]+"\" target=\"_top\">"+text+"</a>"
                     else:                      else:
                         return "<a href=\""+self.REQUEST['URL1']+"?filename="+ids[nr]+"\" target=\"_top\">next set</a>"                          return "<a href=\""+self.REQUEST['URL1']+"?filename="+ids[nr]+"\" target=\"_top\">"+text+"</a>"
   
     def prevSets(self,selected=None):      def prevSets(self,selected=None,text='previous sets'):
                   
         """show nextimage"""          """show nextimage"""
         #return self.getId()          #return self.getId()
Line 1210  class ImageCollection(Folder, Persistent Line 1479  class ImageCollection(Folder, Persistent
                     return ""                      return ""
                 else:                  else:
                     if selected:                      if selected:
                         return "<a href=\""+self.REQUEST['URL1']+"/selection?filename="+ids[nr]+"\" target=\"_top\">previous sets</a>"                          return "<a href=\""+self.REQUEST['URL1']+"/selection?filename="+ids[nr]+"\" target=\"_top\">"+text+"</a>"
                     else:                      else:
                         return "<a href=\""+self.REQUEST['URL1']+"?filename="+ids[nr]+"\" target=\"_top\">previous sets</a>"                          return "<a href=\""+self.REQUEST['URL1']+"?filename="+ids[nr]+"\" target=\"_top\">"+text+"</a>"
             else:              else:
                 return ""                  return ""
   
   
     def showFolders(self):      def showFolders(self):
         """show subfolders"""          """show subfolders"""
         ret=""          ret=""
Line 1234  class ImageCollection(Folder, Persistent Line 1505  class ImageCollection(Folder, Persistent
                 ret+=link%(iC[1].absolute_url(),iC[0])                  ret+=link%(iC[1].absolute_url(),iC[0])
             ret+="<br>"              ret+="<br>"
             return ret              return ret
   
   
       def getSetSelector(self, selected=None):
           """returns the HTML select element for the sets"""
           actualNr=0
           ids=self.show_thumbs()
           colRows=self.getColTimesRow()
           pagesize = colRows[0]*colRows[1]
           numpages = int(len(ids)/pagesize)
           if not ((len(ids) % pagesize)==0):
               numpages+=1
       
           ret=""
           if numpages>1:
               if selected:
                   ret+="""<select onChange="parent.location.href='"""+self.REQUEST['URL1']+"""/selection?filename='+this.options[this.selectedIndex].value">"""
               else:
                   ret+="""<select onChange="parent.location.href='"""+self.REQUEST['URL1']+"""?filename='+this.options[this.selectedIndex].value">"""
                   
               for i in range(numpages):
                   try:
                     nr=ids.index(self.REQUEST.SESSION['filename'])
                   except:
                     nr=0
                   k=i * pagesize
                   if (k <= nr) and (nr < i*(pagesize+1)):
                      actualNr=i
                      ret+="""<option value="%s" selected>%i</option>"""%(ids[k], i + 1)
                   else:
                      ret+="""<option value="%s">%i</option>"""%(ids[k], i + 1)
                      
               ret+="</select>"
               
           return ret
   
       def isAllSets(self, showall=None):
           """returns if there are any sets"""
           ids=self.show_thumbs()
           colRows=self.getColTimesRow(showall=showall)
           pagesize = colRows[0]*colRows[1]
           return (len(ids) <= pagesize)
           
   
       def allSets(self, texton='show all', textoff='show groups'):
           """returns HTML to toggle 'show all'"""
           if self.isAllSets(showall='No'):
               return ""
           showall=self.REQUEST.SESSION.get('showall','no')
           if showall=='no':
               ret='<a href="'+self.REQUEST['URL1']+'?showall=yes" target="_top">'+texton+'</a>'
           else:
               ret='<a href="'+self.REQUEST['URL1']+'?showall=no" target="_top">'+textoff+'</a>'
           return ret
   
   
     def showRuler(self,selected=None):      def showRuler(self,selected=None):
         """show ruler"""          """show ruler"""
         showall =self.REQUEST.SESSION.get('showall','no')          showall =self.REQUEST.SESSION.get('showall','no')
Line 1316  class ImageCollection(Folder, Persistent Line 1642  class ImageCollection(Folder, Persistent
   
         return ret          return ret
           
     def show_thumbs_selected_rows(self,numberOfColumns):      
       def show_thumbs_selected_rows(self,numberOfColumns,start=0,max=10000):
         """Ausgabe anzahl"""          """Ausgabe anzahl"""
         ids=self.show_selected_thumbs()          ids=self.show_selected_thumbs()
   
         if not ids:          if not ids:
                 return None                  return None
         self.REQUEST.SESSION['ids']=ids          self.REQUEST.SESSION['ids']=ids
         number=int(len(ids)/numberOfColumns)+1          number=min(start+int(len(ids)/numberOfColumns)+1,max)
         self.REQUEST.SESSION['number']=range(number)          
         return range(number+1)          self.REQUEST.SESSION['number']=range(start,number)
           return range(start,number+1)
   
     def setColTimesRowForm(self):      def setColTimesRowForm(self):
         """form for matrix setting"""          """form for matrix setting"""
Line 1352  class ImageCollection(Folder, Persistent Line 1680  class ImageCollection(Folder, Persistent
   
         RESPONSE.redirect(self.REQUEST['URL1']+"/setDone")          RESPONSE.redirect(self.REQUEST['URL1']+"/setDone")
                   
       def setDefaultColTimesRow(self, cols, rows):
           """sets default columns and rows"""
           self.defaultcols = cols
           self.defaultrows = rows
   
     def getColTimesRow(self,showall='No'):      def getColTimesRow(self,showall='No'):
         """coltimesrow"""          """coltimesrow"""
                   
         REQUEST=self.REQUEST          REQUEST=self.REQUEST
         """matrix"""          """matrix"""
         if REQUEST.cookies.has_key("ImageViewerRows"):          if REQUEST.cookies.has_key("ImageViewerRows"):
               
             try:              try:
                 rows=int(REQUEST.cookies["ImageViewerRows"])                  rows=int(REQUEST.cookies["ImageViewerRows"])
             except:              except:
                 rows=6                  rows=getattr(self,'defaultrows',6)
         else:          else:
             rows=6              rows=getattr(self,'defaultrows',6)
                           
         if REQUEST.cookies.has_key("ImageViewerCols"):          if REQUEST.cookies.has_key("ImageViewerCols"):
             #print "COLS",REQUEST.cookies["ImageViewerCols"]              #print "COLS",REQUEST.cookies["ImageViewerCols"]
             cols=int(REQUEST.cookies["ImageViewerCols"])              cols=int(REQUEST.cookies["ImageViewerCols"])
         else:          else:
             cols=2              cols=getattr(self,'defaultcols',3)
   
   
         idsnumber=len(self.show_thumbs())          idsnumber=len(self.show_thumbs())
         if rows:          if rows:
             if cols*rows >idsnumber:              if cols*rows >idsnumber:
                 rows=int(idsnumber/cols)+1                  rows=int(idsnumber/cols)+1
   
         #print cols,rows          if showall is None:
               showall=self.REQUEST.SESSION.get('showall', 'No')
         if showall=='yes':          if showall=='yes':
             rows=int(idsnumber/cols)+1              rows=int(idsnumber/cols)+1
                           
           logTime("getColTimesRow finished")
         return (cols,rows)          return (cols,rows)
                                   
                   
Line 1388  class ImageCollection(Folder, Persistent Line 1723  class ImageCollection(Folder, Persistent
         """Ausgabe anzahl"""          """Ausgabe anzahl"""
   
         idsAll=self.show_thumbs()          idsAll=self.show_thumbs()
         if len(idsAll)==0: #keine Einträge          if len(idsAll)==0: #keine Eintraege
             return 0              return 0
         if self.REQUEST.SESSION.has_key("filename") and not (showall=="yes"):          if self.REQUEST.SESSION.has_key("filename") and not (showall=="yes"):
             filename=self.REQUEST.SESSION["filename"]              filename=self.REQUEST.SESSION["filename"]
Line 1424  class ImageCollection(Folder, Persistent Line 1759  class ImageCollection(Folder, Persistent
         self.REQUEST.SESSION['ids']=ids          self.REQUEST.SESSION['ids']=ids
         number=int(len(ids)/numberOfColumns)+1          number=int(len(ids)/numberOfColumns)+1
           
           logTime("show_thumbs_rows finished (%s)"%str(number))
         return range(number+1)          return range(number+1)
   
     def show_thumbs_columns(self,row,numberOfColumns):      def show_thumbs_columns(self,row,numberOfColumns):
         """Ausgabe einer Liste der Reihe"""          """Ausgabe einer Liste der Reihe"""
         ids=self.REQUEST.SESSION['ids']          ids=self.REQUEST.SESSION['ids']
         max=len(ids)          max=len(ids)
           logTime("show_thumb_columns finishes row: %s"%row)
         if (row*numberOfColumns)<max:          if (row*numberOfColumns)<max:
             return ids[(row-1)*numberOfColumns:row*numberOfColumns]              return ids[(row-1)*numberOfColumns:row*numberOfColumns]
         else:          else:
             return ids[(row-1)*numberOfColumns:]              return ids[(row-1)*numberOfColumns:]
                   
     def thumblistSelected_old(self):  
         """main template collection"""  
         pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','thumbselected.zpt')).__of__(self)  
         return pt()  
   
     def thumblistSelected(self):      def thumblistSelected(self):
         """main template collection"""          """main template collection"""
         pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','thumbselected2.zpt')).__of__(self)          pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','thumbselected2.zpt')).__of__(self)
         return pt()          return pt()
           
     def thumblist_old(self):  
         """main template collection"""  
         pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','thumbs.zpt')).__of__(self)  
         return pt()  
   
     def thumblist(self):      def thumblist(self):
         """main template collection"""          """main template collection"""
Line 1465  class ImageCollection(Folder, Persistent Line 1794  class ImageCollection(Folder, Persistent
         """navigation"""          """navigation"""
         #self.REQUEST.SESSION['URL']=self.REQUEST['URL0']          #self.REQUEST.SESSION['URL']=self.REQUEST['URL0']
         pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','navigation_selected.zpt')).__of__(self)          pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','navigation_selected.zpt')).__of__(self)
         return pt()  
           return pt().data
   
     def navig_html(self):      def navig_html(self):
         """navigation"""          """navigation"""
Line 1487  class ImageCollection(Folder, Persistent Line 1817  class ImageCollection(Folder, Persistent
   
     def getImageByName(self,filename,onlyName=None):      def getImageByName(self,filename,onlyName=None):
         """get filename"""          """get filename"""
                   #print repr(filename)
         fn=getattr(self,filename,None)          #FIXME: umlaute in filename
           fn=getattr(self,repr(filename),None)
         if not fn:          if not fn:
             filenameM=filename.split(".")[0]  
           if os.path.splitext(filename)[1].lower() in imageExtensions:
                   filenameM=os.path.splitext(filename)[0]
               else:                    
              filenameM=filename
   
   
   
             founds=self.ZopeFind(self,obj_metatypes=['ImageDigilib'])              founds=self.ZopeFind(self,obj_metatypes=['ImageDigilib'])
   
           
             for found in founds:              for found in founds:
                 foundM=found[0].split(".")[0]          if os.path.splitext(found[0])[1].lower() in imageExtensions:
                       foundM=os.path.splitext(found[0])[0]
           else:   
               foundM=found[0]
   
                   if filenameM.lower()==foundM.lower():
                       if onlyName:
                           return found[0]
                       else:
                           return found[1]   
                   #HACK teste noch ob am ende des filenames eventuell ein "_" und loesche das.    
                   if foundM[-1]=="_":
                       foundM=foundM[0:-1]
   
                 if filenameM.lower()==foundM.lower():                  if filenameM.lower()==foundM.lower():
                     if onlyName:                      if onlyName:
                         return found[0]                          return found[0]
                     else:                      else:
                         return found[1]                          return found[1]
                   
         if onlyName:          if onlyName:
             return filename              return filename
         else:          else:
Line 1506  class ImageCollection(Folder, Persistent Line 1860  class ImageCollection(Folder, Persistent
                   
                   
     security.declareProtected('View','index_html')      security.declareProtected('View','index_html')
     def index_html(self,fn=None):      def index_html(self,fn=None,generic='No'):
         """main template collection"""          """main template collection"""
           
         if fn:          if fn:
Line 1523  class ImageCollection(Folder, Persistent Line 1877  class ImageCollection(Folder, Persistent
             self.REQUEST.SESSION['filenames']=ret              self.REQUEST.SESSION['filenames']=ret
                 #self.REQUEST.SESSION['filenamesIds']=fnIds                  #self.REQUEST.SESSION['filenamesIds']=fnIds
   
               overview=self.ZopeFind(self,obj_ids=['overview_selected.html'])
               
   
               if overview and (generic =='No'):
                   return overview[0][1]()
               else:
             pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','overview_selected.zpt')).__of__(self)              pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','overview_selected.zpt')).__of__(self)
             return pt()                      return pt()        
   
Line 1541  class ImageCollection(Folder, Persistent Line 1901  class ImageCollection(Folder, Persistent
                           
   
         overview=self.ZopeFind(self,obj_ids=['overview.html'])          overview=self.ZopeFind(self,obj_ids=['overview.html'])
         if overview:          if overview and (generic == 'No'):
             return overview[0][1]()              return overview[0][1]()
           elif hasattr(self,'templates'):
               pt=self.templates.imgcoll_main.__of__(self)
               return pt()
         else:          else:
             pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','overview.zpt')).__of__(self)              pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','overview.zpt')).__of__(self)
             return pt()              return pt()
           
       def navigation(self):
           """generate navigation bar"""
           
           pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','navigation_fragment')).__of__(self)
           return pt()    
       
 def manage_AddImageCollectionForm(self):  def manage_AddImageCollectionForm(self):
     """Nothing yet"""      """Nothing yet"""
     pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','AddImageCollectionForm.zpt')).__of__(self)      pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','AddImageCollectionForm.zpt')).__of__(self)
     return pt()      return pt()
           
 def manage_AddImageCollection(self,id,title,ImageStoragePath,ImageViewerPath,defaultMetaString,RESPONSE=None):  def manage_AddImageCollection(self,id,title,ImageViewerPath,defaultMetaString,destBasis,srcBasis,serverPath,RESPONSE=None):
   
     """Add ImageCollection"""      """Add ImageCollection"""
     newObj=ImageCollection(id,title,ImageStoragePath,ImageViewerPath,defaultMetaString)      newObj=ImageCollection(id,title,ImageViewerPath,defaultMetaString,destBasis,srcBasis,serverPath=genericServerPath)
     self._setObject(id,newObj)      self._setObject(id,newObj)
           
     if RESPONSE is not None:      if RESPONSE is not None:
Line 1580  class ImageCollectionMD(ImageCollection, Line 1950  class ImageCollectionMD(ImageCollection,
     except:      except:
       pass        pass
   
       
       def ImportFiles(self,RESPONSE=None):
           """Import the existing files of a folder"""
           files=os.listdir(self.getImageStoragePath())
           ret=""
           #print self.__dict__
           for file in files:
   
               if not (file[0]=="."):
                   fn=os.path.splitext(file)[0]
                   if self.__dict__.has_key(file) or self.__dict__.has_key(fn+'.tif') or self.__dict__.has_key(fn+'.tiff') :
   
                       ret=ret+"<br>"+file+" already exists!"
   
                   else:
                       logger("ImageArchiveMD:import", logging.INFO, "adding ZOPE: %s"%file)
                       ret=ret+"<br>"+file+" created!"
                       newObj=ImageDigilib(file,file)
                       #print newObj,file
                       #print newObj
                       try:
                           self._setObject(file,newObj)
                       except:
                           """nothing yet"""
                           
                   # check entry in database
                   args={}
                   args['_table']=self.imageCollectionConfig.getTable()
                   args[self.imageCollectionConfig.getKey()]=file
   
                   if not self.ZSQLInline(args=args):
                       logger("ImageArchiveMD:import", logging.INFO, "adding DB: %s"%file)
                       self.ZSQLAdd(args=args)
    
           #print ret
           #pt=PageTemplateFile('Products/ImageArchive/out.zpt')).__of__(self)
           #print self.ImageStoragePath
   
                   #scale thumb
           
           
           self.scaleThumbs()
   
           #scale standard
   
           self.scaleWorkingVersions()
           
           #self.scaleToJpgs()
           
           if RESPONSE:
                   RESPONSE.redirect('manage_main')
     
       def addImage(self):
           """Add an Image"""
                   
           pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','addImageMD.zpt')).__of__(self)
           return pt()
       
       def addImage2(self,_fileupload,_fileName=None,_meta=None,_use_default=None,RESPONSE=None):
           """Add"""
   
           filenameKey="filename"
           #print "FU",fileupload
   
           if _use_default:
               try:
                   meta=self.meta_default(_fileupload.filename)
               except:
                   meta=None
           else:
               meta=None
           
           fn=_fileName or splitPath(_fileupload.filename)
           
           manage_AddImageDigilib(self,fn,_fileupload,meta=meta)
           
           args=self.REQUEST.form
           args[filenameKey]=fn
           
           self.ZSQLAdd(args=args)
           
           self.scaleThumbs()
           self.scaleWorkingVersions()
           
           getattr(self,fn).scaleToJpg()
           if RESPONSE:
               return RESPONSE.redirect(self.REQUEST['URL1']+'/'+fn)
           #return  self.REQUEST['URL1']+'/'+fileupload.filename
   
       def navig_html(self):
           """navigation"""
           #self.REQUEST.SESSION['URL']=self.REQUEST['URL0']
          
           pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','navigationMD.zpt')).__of__(self)
           return pt()
           
       def navig_selected_html(self):
           """navigation"""
           #self.REQUEST.SESSION['URL']=self.REQUEST['URL0']
           pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','navigation_selectedMD.zpt')).__of__(self)
   
           return pt()
   
       def decode(self,str):
           """decoder"""
           if not str:
               return ""
           if type(str) is StringType:
               try:            
                   return str.decode('utf-8')
               except:
                   return str.decode('latin-1')
           else:
               
               return str
   
       def standardSearch(self):
           """standard search page"""
           pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','standardSearchPage.zpt')).__of__(self)
           return pt()        
           
       def searchResultXML(self):
           """xmlformat"""
           pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','searchResultXML.zpt')).__of__(self)
           return pt()        
   
       def searchDB(self,REQUEST=None,RESPONSE=None,xml=None):
           """search"""
           
           rc=[]
           fnIds={}
   
           for found in self.ZSQLInlineSearch(args=self.REQUEST.form):
               key=getattr(found,self.imageCollectionConfig.getKey())
               key=self.getImageByName(key,onlyName="yes")        
               rc.append((key,'',0))
               fnIds[key]=('',0)
                   
           rc.sort()
           self.REQUEST.SESSION['filenames']=rc
           self.REQUEST.SESSION['filenamesIds']=fnIds
           
           overview=self.ZopeFind(self,obj_ids=['overview_selectedMD.html'])
               
           if overview:
                   return overview[0][1]()
           else:
                   pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','overview_selectedMD.zpt')).__of__(self)
                   return pt()        
           
           pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','overview_selectedMD.zpt')).__of__(self)
           return pt()        
           
           #urlTmp=REQUEST['URL1']
           
           #url=urlTmp+'/searchResultXML?-table=%s&'%self.imageCollectionConfig.getTable()+REQUEST['QUERY_STRING']
           
           #if xml is None:
           #    RESPONSE.redirect('xmlinput?url='+urllib.quote(url))
           #else:
           #    RESPONSE.redirect(url)
               
       def index_html(self,fn=None,selection=None,generic='No',REQUEST=None,RESPONSE=None):
           """main template collection"""
   
           logTime("index_html %s"%self.REQUEST['QUERY_STRING'])
           mode=self.REQUEST.get('mode','view')
           if fn:
               ret=[]
   
               if type(fn) is ListType:
                   """experimentell mehr als ein filename"""
                   for filename in fn:
                       if not (filename == ""):
                           ret.append((filename,'',1))
               else:
                   ret.append((fn,'',1))
   
               self.REQUEST.SESSION['filenames']=ret
                   #self.REQUEST.SESSION['filenamesIds']=fnIds
             
               overview=self.ZopeFind(self,obj_ids=['overview_selected.html'])
               
   
               if overview and (generic =='No'):
                   return overview[0][1]()
               else:
                   pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','overview_selectedMD.zpt')).__of__(self)
                   return pt()        
   
           
           # filename given, then only display this file
           if self.REQUEST.has_key('filename'):
   
               filen=self.REQUEST['filename']
           else:
               filen=""
   
   
           self.REQUEST.SESSION['filename']=filen[0:]
           
   #        if not self.REQUEST.SESSION['filename']=="":
   #            url=getattr(self.getImageByName(self.REQUEST.SESSION['filename']),'absolute_url')()
   #            if mode=="view":
   #                self.REQUEST.RESPONSE.redirect(url)
   #            elif mode=="download":
   #                self.REQUEST.RESPONSE.redirect(url+"/download")
   #                
           if self.REQUEST.has_key('showall'):
   
               self.REQUEST.SESSION['showall']=self.REQUEST.get('showall')
           else:
               self.REQUEST.SESSION['showall']=self.REQUEST.SESSION.get('showall','no')
               
               
           if selection:
               #selection i.e. selection already stored at self.REQUEST.SESSION['filenames']
               overview=self.ZopeFind(self,obj_ids=['overview_selected.html'])
               
   
               if overview and (generic =='No'):#
                 
                   return overview[0][1]()
               else:
                   pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','overview_selectedMD.zpt')).__of__(self)
                   return pt()   
               
               
           #no filename then show overview
   
           overview=self.ZopeFind(self,obj_ids=['overview.html'])
           if overview and (generic == 'No'):
   
             
               return overview[0][1]()
           elif hasattr(self,'templates'):
             
               pt=self.templates.imgcoll_mainMD.__of__(self)
               return pt()
           else:
             
               pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','overviewMD.zpt')).__of__(self)
               return pt()
           
       def nextImage(self,request,selected=None,returnFn=None):
           """show nextimage"""
       
           if not selected and self.REQUEST.has_key('fn'):
               imagename=self.REQUEST['fn'].split('/')[-1]
               
               imagename=self.getImageByName(imagename,onlyName=True)
               
               nr=self.getObjectPosition(imagename)
       
               objects=self.objectIds()
               if len(objects)==nr+1:
                   return ""
               else:
                   fn="/".join(self.REQUEST['fn'].split('/')[0:-1])+"/"+objects[nr+1]
                   return "<a href=\""+self.REQUEST['URL0']+"?fn="+fn+"\" target=\"_top\">next image</a>"                
   
       def prevImage(self,request,selected=None,returnFn=None):
           """show nextimage"""
       
           if not selected and self.REQUEST.has_key('fn'):
               imagename=self.REQUEST['fn'].split('/')[-1]
               
               imagename=self.getImageByName(imagename,onlyName=True)
               
               nr=self.getObjectPosition(imagename)
       
               objects=self.objectIds()
               if nr==0:
                   return ""
               else:
                   fn="/".join(self.REQUEST['fn'].split('/')[0:-1])+"/"+objects[nr-1]
                   return "<a href=\""+self.REQUEST['URL0']+"?fn="+fn+"\" target=\"_top\">prev image</a>"                
       
           
     def changeRightsQueryForm(self):      def changeRightsQueryForm(self):
         """change Rights Query"""          """change Rights Query"""
         pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','ChangeRightsQueryForm.zpt')).__of__(self)          pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','ChangeRightsQueryForm.zpt')).__of__(self)
Line 1617  class ImageCollectionMD(ImageCollection, Line 2266  class ImageCollectionMD(ImageCollection,
   
     def thumblistMD(self):      def thumblistMD(self):
         """main template collection"""          """main template collection"""
           logTime("thumbList MD %s"%self.REQUEST['QUERY_STRING'])
           
         pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','thumbListMD.zpt')).__of__(self)          pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','thumbListMD.zpt')).__of__(self)
           self.REQUEST.RESPONSE.setHeader('Cache-Control','max-age=3600')
           self.REQUEST.RESPONSE.setHeader('Last-Modified',self.bobobase_modification_time().toZone('GMT').rfc822())
         return pt()          return pt()
           
       
     def getRights(self,id):      def getRights(self,id):
         """get the rights from a database"""          """get the rights from a database"""
         #print self.rightsQuery%id          #print self.rightsQuery%id
         results=self.ZSQLSimpleSearch(self.getRightsQuery()%id)          results=self.ZSQLSimpleSearch(self.getRightsQuery()%id)
           logging.error("rightsQuery: %s"%(self.getRightsQuery()%id))
         if results:          if results:
             result = getattr(results[0],self.getRightsQueryField())              result = getattr(results[0],self.getRightsQueryField())
         else:          else:
             result = ''              result = ''
         return result          return result
                   
       def xmlinput(self,url):
           """Anzeige von ausgewaehlten thumbs"""
           #return url
           
           url=urllib.unquote(url)
        
           url=url.replace(" ","+") # ersetze Leerzeichen in der URL durch "+"
           print url
           xmldoc=urllib.urlopen(url).read()
           #return xmldoc
           try:
                   #dom=NonvalidatingReader.parseUri(url)
                   pass
   
           except:
                   return "ERROR: (%s %s) %s"%(sys.exc_info()[0],sys.exc_info()[1],xmldoc)
   
   
           imagenames=dom.xpath("//imagename")
           rc=[]
           fnIds={}
           for imagename in imagenames:
   
                   #imagename=image.xpath('./imagename')[0]
                   #print "im",imagename
                   
                   
                   
                   idnr=imagename.xpath('../idnr')[0]
                   id=getText(idnr.childNodes)
                   try:
                       numberOfPages=imagename.xpath('../numberOfPages')[0]
                   except:
                       numberOfPages=None
                       
                   if numberOfPages:
                       nopT=getText(numberOfPages.childNodes)
                       try:
                               nop=int(nopT)
                       except:
                               nop=0
                   else:
                       nop=0
                               
                   texts=getText(imagename.childNodes).split("\n") #mehrere bilder in return getrennter liste
                   for text in texts:
                       if not text=="":
                           #print "a"
                           text=self.getImageByName(text,onlyName="yes")
                           #print "b"
                           try:
                                   rc.append((str(text),id,nop))
                                   fnIds[str(text)]=(id,nop)
                           except:
                                   rc.append((repr(text),id,nop))
                                   fnIds[repr(text)]=(id,nop)
                   
           #print "done"
           rc.sort()
           self.REQUEST.SESSION['filenames']=rc
           self.REQUEST.SESSION['filenamesIds']=fnIds
           
           overview=self.ZopeFind(self,obj_ids=['overview_selectedMD.html'])
               
           if overview:
                   return overview[0][1]()
           else:
                   pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','overview_selectedMD.zpt')).__of__(self)
                   return pt()        
           
           
       def selection(self):
           """show only selected"""
           if self.REQUEST.has_key('filename'):
               filen=self.REQUEST['filename']
           else:
               filen=""
           self.REQUEST.SESSION['filename']=filen
           pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','overview_selectedMD.zpt')).__of__(self)
           return pt()  
           
       def thumblistSelectedMD(self):
           """main template collection"""
           pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','thumbselectedMD.zpt')).__of__(self)
           return pt()
   
 def manage_AddImageCollectionMDForm(self):  def manage_AddImageCollectionMDForm(self):
     """Nothing yet"""      """Nothing yet"""
     pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','AddImageCollectionFormMD.zpt')).__of__(self)      pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','AddImageCollectionFormMD.zpt')).__of__(self)
     return pt()      return pt()
           
 def manage_AddImageCollectionMD(self,id,title,ImageStoragePath,ImageViewerPath,defaultMetaString,RESPONSE=None):  def manage_AddImageCollectionMD(self,id,title,ImageViewerPath,defaultMetaString,destBasis,srcBasis,serverPath,RESPONSE=None):
     """Add ImageCollection"""      """Add ImageCollection"""
     newObj=ImageCollectionMD(id,title,ImageStoragePath,ImageViewerPath,defaultMetaString)      newObj=ImageCollectionMD(id,title,ImageViewerPath,defaultMetaString,destBasis,srcBasis,serverPath)
     self._setObject(id,newObj)      self._setObject(id,newObj)
           
     if RESPONSE is not None:      if RESPONSE is not None:
Line 1776  def manage_AddImageZogiLib(self,id=None, Line 2516  def manage_AddImageZogiLib(self,id=None,
     self._setObject(id,newObj)      self._setObject(id,newObj)
     getattr(self,id).caption=caption[0:]      getattr(self,id).caption=caption[0:]
     if fileUpload:      if fileUpload:
         getattr(self,id).uploadImage(fileupload,self.ImageStoragePath)          getattr(self,id).uploadImage(fileupload,self.getImageStoragePath())
           
     if RESPONSE is not None:      if RESPONSE is not None:
         RESPONSE.redirect('manage_main')          RESPONSE.redirect('manage_main')

Removed from v.1.69  
changed lines
  Added in v.1.109


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>