File:  [Repository] / OSA_system2 / OSAS_browser.py
Revision 1.3: download - view: text, annotated - select for diffs - revision graph
Thu Dec 23 10:48:28 2004 UTC (19 years, 4 months ago) by dwinter
Branches: MAIN
CVS tags: HEAD
added cache for indexmetafiles

""" Classes for displaying, browsing and organizing the archive
"""


import OSAS_helpers
from AccessControl import ClassSecurityInfo
from Products.PageTemplates.PageTemplateFile import PageTemplateFile
from OFS.Folder import Folder
from OFS.SimpleItem import SimpleItem
from Globals import InitializeClass,package_home
import zLOG
import os
import os.path
import stat
import xml.dom.minidom
from types import *

class OSAS_storeOnline(SimpleItem):
    """Webfrontend für das Storagesystem
    liefert Browserumgebung 
    """
    meta_type="OSAS_StoreOnline__neu"
    
    security=ClassSecurityInfo()

    _v_fileSystem={} #chache fuer filesystem
    _v_metaFiles={} #chache fuer indexMeta
    
    def __init__(self,id):
        """initialize a new instance"""
        self.id = id

    

    security.declareProtected('View','index_html')
    def index_html(self):
        """main view either standard template zpt/storeOnline_index_html.zpt or storeOnline_index.html in tree"""
        if hasattr(self,'storeOnline_index.html'):
            return getattr(self,'storeOnline_index.html')()
        else:
            pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','storeOnline_index_html.zpt')).__of__(self)
            return pt()


    def findIndexMeta(self,path=""):
        """finde index_meta fuer diesen eventuell virtuellen Pfad
        @param path: optional, default ist "", Pfad auf das Object relativ zum rootFolderName
        @return: None falls kein index.meta existiert sonst Pfad auf das index.meta
        """
        realPath=os.path.normpath(os.path.join(self.rootFolderName,path))
        #suche index.meta
        while (not os.path.exists(os.path.join(realPath,'index.meta'))) and (not ((realPath=="") or (realPath=="/"))):
            realPath=os.path.split(realPath)[0]
        if realPath=='' or realPath=='/':
            return None
        else:
            return os.path.join(realPath,'index.meta')

    def findEntryInIndexMeta(self,path):
        """fragm xml zum path
        @param path: Pfad auf das Object relativ zum rootFolderName
        @return: den Teil von Index.meta der Informationen zu path enthaelt, None wenn error.
        """

        indexMeta=self.findIndexMeta(path)
        if not indexMeta:
            return None
        realPath=os.path.split(indexMeta)[0]
        path=os.path.normpath(os.path.join(self.rootFolderName,path))
        
        dom=xml.dom.minidom.parse(indexMeta)

        #ist path ein directory?
        dirs=dom.getElementsByTagName('dir')
        for dir in dirs:
            pathes=dir.getElementsByTagName('path')
            if pathes:
                pathX=OSAS_helpers.getText(pathes[0].childNodes)
            else:
                pathX=""
            names=dir.getElementsByTagName('name')
            if names:
                name=OSAS_helpers.getText(names[0].childNodes)
            else:
                name=""

            checkpath=os.path.normpath(os.path.join(realPath,pathX,name))
            if checkpath==path:
                
                return dir.toxml()

        #ist path ein file?
        files=dom.getElementsByTagName('file')
        for dir in dirs:
            pathes=dir.getElementsByTagName('path')
            if pathes:
                pathX=OSAS_helpers.getText(pathes[0].childNodes)
            else:
                pathX=""
            names=dir.getElementsByTagName('name')
            if names:
                name=OSAS_helpers.getText(names[0].childNodes)
            else:
                name=""

            checkpath=os.path.normpath(os.path.join(realPath,pathX,name))
            if checkpath==path:
                
                return dir.toxml()

        
        return None

    def getSubDirsFromIndexMeta(self,path):
        
        """Gebe alle path untergeordenten Objekte aus
        @param path: optional, default ist "", Pfad auf das Object relativ zum rootFolderName
        @return: Directory [pfad auf das Objekt]->(fileType,''), fileType ist hierbei OSAS_dir_archive falls Object ein directory und OSAS_file_archive falls das Object ein File ist,der zweite Eintrag des Tupels ist zur Zeit immer '', spaeter wird hier die Beschreibung gemaess Metadaten stehen, wie bei readObjectsFromPath.
        """
        ret={}
        indexMeta=self.findIndexMeta(path)
        if not indexMeta:
            return ret
        realPath=os.path.split(indexMeta)[0]
        path=path.replace(realPath,"")
        if path and (path[0]==os.sep):
            path=path[1:]

        stats=os.stat(indexMeta)

        #teste ob schon im cache
        if self._v_metaFiles.has_key(indexMeta) and (self._v_metaFiles[indexMeta][0]==stats[stat.ST_MTIME]):
            
            return self._v_metaFiles[indexMeta][1]

        dom=xml.dom.minidom.parse(indexMeta)

        dirs=[]
        dirs=dom.getElementsByTagName('dir')+dom.getElementsByTagName('file')
    
        for dir in dirs:
            pathes=dir.getElementsByTagName('path')
            if pathes:
                pathX=OSAS_helpers.getText(pathes[0].childNodes)
            else:
                pathX=""
            names=dir.getElementsByTagName('name')
            if names:
                name=OSAS_helpers.getText(names[0].childNodes)
            else:
                name=""

        
            if pathX==path:
                if dir.tagName=="dir":
                    fileType="OSAS_dir_archive"
                else:
                    fileType="OSAS_file_archive"

                object=os.path.join(realPath,pathX,name)
                ret[object]=(fileType,'')

        self._v_metaFiles[indexMeta]=(stats[stat.ST_MTIME],ret) # speicher im chache
        return ret

        
    def getMetaInfoFromIndexMeta(self,path):
        """metadaten zu path als html aus dem index.meta file zu path
        @param path: optional, default ist "", Pfad auf das Object relativ zum rootFolderName
        @return: metadata als html
        """
        xmlInfos=self.findEntryInIndexMeta(path)
        if xmlInfos:
            return OSAS_helpers.getMetaInfoFromXML(path,xmlInfos)
        else:
            return ""
   

    def readObjectsFromPath(self,path=""):
        """Liest files aus dem path und speichert im cache _v_filesystem.

        @param path : path relativ zum root folder des Storagesystems
        @return: directory der Form [pfad zum Objekt] -> (fileType,metadatum als String)
        """
                       
        realPath=os.path.normpath(os.path.join(self.rootFolderName,path))
        metaData=self.testmd #test
        
        if realPath.find(self.rootFolderName) <0: #versuch auf Pfad unterhalb des Rootfolder zuzugreifen
            return {}
            
        
        if not os.path.exists(realPath):
            #return None,"(ERROR) path %s does not exist."%path
            return None
        
        stats=os.stat(realPath)

        #teste ob schon im cache
        if self._v_fileSystem.has_key(realPath) and (self._v_fileSystem[realPath][0]==stats[stat.ST_MTIME]):
            
            return self._v_fileSystem[realPath][1]

        dir=os.listdir(realPath)
        ret={}
        for filename in dir:
            object=os.path.join(realPath,filename)
            fileType=OSAS_helpers.checkOSASFileType(object)
            
            if fileType:
                
                ret[object]=(fileType,metaData.getDisplayFieldsAsStr(object))
            
        self._v_fileSystem[realPath]=(stats[stat.ST_MTIME],ret) # speicher im chache
        
        return ret

    def giveHandlers(self,path,type):
        """teste ob fuer diesen Typ, viewer definiert sind und gibt einen entsprechenden Link zurueck, der das Object mit diesem Handler ausfuehrt.
        @param path: Pfad auf das Objekt
        @param type: Typ des Objektes
        @return: (string) html-Fragment, link der das Objekt mit diesem Handler anzeigt.
        """
        ret=[]
        
        for viewer in self.ZopeFind(self.aq_parent,obj_metatypes=['OSAS_ViewerObject__neu'],search_sub=1):
            if type in viewer[1].objectTypes:
                path=path.replace(getattr(viewer[1],'ignorePath',''),'')
                url=viewer[1].prefix%path
                text=viewer[1].title
                string="""<a target="_blank" href="%s">%s</a>"""%(url,text)
                ret.append(string)
        return ret
                      
        
    def generateTree(self,path=""):
        """erzeuge liest die Objekte aus die im Pfad gespeichert sind
        @param path: optional mit default='', Pfad relativ zu rootFolderName
        @return: List von Tripeln, (link_html,array of handlers,metainformationen) hierbei ist
        - (string) link_html ein html-Fragement, falls das Objekt vom Typ OSAS_dir ist, ist dies ein Link auf dieses Verzeichnis, sonst der Dateiname
        - (string) handler sind die Ergebnisse von giveHandlers fuer dieses Objekt
        - (string) metainformationen die Metainformationen zum Objekt als Ergebnis von readObjectsFromPath
        """
        objects=self.readObjectsFromPath(path)
        if not objects:
            objects={}
        im=self.getSubDirsFromIndexMeta(path)
        for key in im.keys():
            #virtuelle pfade hinzufuegen
            
            if not objects.has_key(key):
                objects[key]=im[key]
                
        
        def sortLow(x,y):
            return cmp(x.lower(),y.lower())
        
        ret=[]
        
        objectSorted=objects.keys()
        objectSorted.sort(sortLow)
        for object in objectSorted:
            handler=self.giveHandlers(object,objects[object][0])
            if objects[object][0]=="OSAS_dir":
                
                string="""<a href="?path=%s">%s</a>"""%(object,os.path.split(object)[1])
                
                ret.append((string,handler,objects[object][1]))
            elif objects[object][0]=="OSAS_dir_archive":
                string="""<a href="?path=%s">%s (A)</a>"""%(object,os.path.split(object)[1])
                
                ret.append((string,handler,objects[object][1]))
            else:
                ret.append((os.path.split(object)[1],handler,objects[object][1]))

                     
        return ret


    def path_to_link(self,pathTmp=""):
        """generates navigation bar for viewfiles"""

        path=os.path.normpath(os.path.join(self.rootFolderName,pathTmp))
        
        URL=self.absolute_url()
        string=""
        
        tmppath=os.path.dirname(path)
        i=0
        pathes=[[path, os.path.basename(path)]]

        while not (len(tmppath)==1):

              i=i+1
              if i>20: break

              pathes.append([tmppath, os.path.basename(tmppath)])
              tmppath=os.path.dirname(tmppath)

        while i>=0:
            if pathes[i][0].find(self.rootFolderName) <0: #versuch auf Pfad unterhalb des Rootfolder zuzugreifen
                string=string+"<a>"+pathes[i][1]+"</a>/"
            else:
                string=string+"<a href="+URL+"?path="+pathes[i][0]+">"+pathes[i][1]+"</a>/"
            
            i=i-1
        return string

    def getMetaFile(self,path):
        """Lese Metafile ein"""
        tmp=OSAS_helpers.getMetaFile(self,path)
        #zLOG.LOG("EE",zLOG.INFO,type(tmp))
        
        return tmp

InitializeClass(OSAS_storeOnline)
	
def manage_addOSAS_storeOnlineForm(self):
    """interface for adding the OSAS_root"""
    pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','addStoreOnline.zpt')).__of__(self)
    return pt()

def manage_addOSAS_storeOnline(self,id,RESPONSE=None):
    """add the OSAS_root"""
    newObj=OSAS_storeOnline(id)
    self._setObject(id,newObj)
    if RESPONSE is not None:
        RESPONSE.redirect('manage_main')


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