FileExplorer.py :  » IDE » Boa-Constructor » boa-constructor-0.6.1 » Explorers » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » IDE » Boa Constructor 
Boa Constructor » boa constructor 0.6.1 » Explorers » FileExplorer.py
#-----------------------------------------------------------------------------
# Name:        FileExplorer.py
# Purpose:     Classes for filesystem exploring
#
# Author:      Riaan Booysen
#
# Created:     2001/03/06
# RCS-ID:      $Id: FileExplorer.py,v 1.31 2007/07/02 15:01:10 riaan Exp $
# Copyright:   (c) 2001 - 2007 Riaan Booysen
# Licence:     GPL
#-----------------------------------------------------------------------------
print 'importing Explorers.FileExplorer'

import os, time, stat, sys

import wx

import Preferences, Utils
from Utils import _

import ExplorerNodes
from Models import Controllers,EditorHelper
from PropEdit import PropertyEditors,InspectorEditorControls

class FileSysCatNode(ExplorerNodes.CategoryNode):
#    protocol = 'config.file'
    itemProtocol = 'file'
    defName, defaultStruct = Preferences.explorerFileSysRootDefault
    def __init__(self, clipboard, config, parent, bookmarks):
        ExplorerNodes.CategoryNode.__init__(self, _('Filesystem'), ('explorer', 'file'),
              clipboard, config, parent)
        self.bookmarks = bookmarks

        if not self.entries and wx.Platform == '__WXMSW__':
            drives = {}
            for x in range(ord('C'), ord('Z')+1):
                driveName = '%s:\\'%(chr(x))
                if os.path.exists(driveName):
                    drives[driveName] = driveName

            self.entries = drives
            self.updateConfig()
            wx.LogMessage(_('%d drives added to the filesystem definition.')%len(drives))

    def createParentNode(self):
        return self.parent

    def createCatCompanion(self, catNode):
        comp = ExplorerNodes.CategoryStringCompanion(catNode.treename, self)
        return comp

    def createChildNode(self, entry, value, forceFolder=True):
        if forceFolder: Node = NonCheckPyFolderNode
        else: Node = FileSysNode

        node = Node(entry, value, self.clipboard, -1, self, self.bookmarks)
        if node.isFolderish():
            node.imgIdx = EditorHelper.imgFSDrive
        else:
            node.imgIdx = Controllers.identifyFile(value #localfs=node.filter == 'BoaFiles'
                                                  )[0].imgIdx
        return node

##    def newItem(self):
##        name = ExplorerNodes.CategoryNode.newItem()
##        self.entries[name] = copy.copy(self.defaultStruct)
##        self.updateConfig()
##        return name

    def renameItem(self, name, newName):
        if self.entries.has_key(newName):
            raise Exception, _('Name exists')
        self.entries[newName] = newName
        del self.entries[name]
        self.updateConfig()

    def getNodeFromPath(self, respath, forceFolder=True):
        cn = self.createChildNode(os.path.basename(respath), respath, forceFolder)
        return cn


(wxID_FSOPEN, wxID_FSTEST, wxID_FSNEW, wxID_FSNEWFOLDER, wxID_FSCVS, wxID_FSSVN,
 wxID_FSBOOKMARK, wxID_FSFINDINFILES, wxID_FSFINDFILES, wxID_FSFILTERIMAGES,
 wxID_FSSETASCWD, wxID_FSNEWZIP, wxID_FSINSPECT,
) = Utils.wxNewIds(13)

(wxID_FSFILTER, wxID_FSFILTERBOAMODULES, wxID_FSFILTERSTDMODULES,
 wxID_FSFILTERINTMODULES, wxID_FSFILTERALLMODULES,
) = Utils.wxNewIds(5)

filterDescrOrd = ['BoaFiles', 'StdFiles', 'BoaIntFiles', 'ImageFiles', 'AllFiles']

filterDescr = {'BoaFiles': (_('Boa files'), wxID_FSFILTERBOAMODULES),
               'StdFiles': (_('Standard files'), wxID_FSFILTERSTDMODULES),
               'BoaIntFiles': (_('Internal files'), wxID_FSFILTERINTMODULES),
               'ImageFiles': (_('Image files'), wxID_FSFILTERIMAGES),
               'AllFiles': (_('All files'), wxID_FSFILTERALLMODULES)}

# XXX CVS and Zip support must also move to registering
class FileSysController(ExplorerNodes.Controller, ExplorerNodes.ClipboardControllerMix):
    bookmarkBmp = 'Images/Shared/Bookmark.png'
    findBmp = 'Images/Shared/Find.png'
    inspectBmp = 'Images/Shared/Inspector.png'

    def __init__(self, editor, list, inspector, controllers):
        ExplorerNodes.Controller.__init__(self, editor)
        ExplorerNodes.ClipboardControllerMix.__init__(self)
        self.editor = editor
        self.inspector = inspector

        self.list = list
##        if controllers.has_key('cvs'):
##            self.cvsController = controllers['cvs']
##        else:
##            self.cvsController = None

        self.menu = wx.Menu()

        self.fileMenuDef = [
              (wxID_FSOPEN, _('Open'), self.OnOpenItems, '-'),
              (-1, '-', None, ''),
              (wxID_FSINSPECT, _('Inspect'), self.OnInspectItem, self.inspectBmp),
              (-1, '-', None, ''),
        ] + self.clipMenuDef + [
              (wxID_FSSETASCWD, _('Set as os.cwd'), self.OnSetAsSysCwd, '-'),
              (-1, '-', None, ''),
              (wxID_FSFINDINFILES, _('Find'), self.OnFindFSItem, self.findBmp),
        ]

        if controllers.has_key('zip'):
            self.newMenuDef.append(
             (wxID_FSNEWZIP, _('Empty zip archive'), self.OnEmptyZipArchive, '-') )
        if controllers.has_key('tar.gz'):
            self.newMenuDef.append(
             (wxID_FSNEWZIP, _('Empty tar.gz archive'), self.OnEmptyTarGzipArchive, '-') )

        self.setupMenu(self.menu, self.list, self.fileMenuDef)

        filters = []
        for filter in filterDescrOrd:
            descr, wid = filterDescr[filter]
            filters.append( (wid, '+'+descr, self.OnFilterFSItems , '-') )

        self.fileFilterMenuDef = filters
        self.fileFilterMenu = wx.Menu()
        self.setupMenu(self.fileFilterMenu, self.list, self.fileFilterMenuDef, False)

        # Check default option
        self.fileFilterMenu.Check(wxID_FSFILTERBOAMODULES, True)

        self.menu.AppendMenu(wxID_FSFILTER, _('Filter'), self.fileFilterMenu)

        # XXX this should not be done here
        if controllers.has_key('cvs'):
            self.menu.AppendMenu(wxID_FSCVS, 'CVS', controllers['cvs'].fileCVSMenu)
        if controllers.has_key('svn'):
            self.menu.AppendMenu(wxID_FSSVN, 'SVN', controllers['svn'].fileSVNMenu)

        self.toolbarMenus = [self.fileMenuDef]

    def destroy(self):
        ExplorerNodes.ClipboardControllerMix.destroy(self)
        self.fileFilterMenuDef = []
        self.fileMenuDef = []
        self.toolbarMenus = []
        self.menu.Destroy()

    def OnTest(self, event):
        print self.list.node.clipboard.globClip.currentClipboard

    def OnFilterFSItems(self, event):
        evtid = event.GetId()
        self.groupCheckMenu(self.fileFilterMenu, self.fileFilterMenuDef, evtid, True)
        for filter in filterDescrOrd:
            descr, wid = filterDescr[filter]
            if wid == evtid:
                self.list.node.setFilter(filter)
                self.list.refreshCurrent()
                break

    def addFindResults(self, pattern, mapResults):
        """ mapResult is map of tuples in this form
            {'Module':  ('Line no', 'Col', 'Text'), ...}
        """
        nd = self.list.node
        if not isinstance( self.list.node, ResultsFolderNode ):
            self.list.node = ResultsFolderNode(_('Results'), nd.resourcepath,
                  nd.clipboard, -1, nd, nd.bookmarks)

        mapFindInFileCount = {}
        for oFindRes in mapResults.keys():
            if len( mapResults[oFindRes] ):
                mapFindInFileCount[oFindRes] = len( mapResults[oFindRes] )
        self.list.node.results = map(None, mapFindInFileCount.values(),
                                           mapFindInFileCount.keys() )
        self.list.node.lastSearch = pattern
        self.list.refreshCurrent()

    def OnFindFSItem(self, event):
        # XXX This is nasty, redesign
        self.list.addFindResults = self.addFindResults

        import FindReplaceDlg
        dlg = FindReplaceDlg.FindReplaceDlg(self.list, self.editor.finder, self.list, 0)
        dlg.SetWorkingFolder(self.list.node.resourcepath)
        try:
            dlg.ShowModal()
        finally:
            dlg.Destroy()

    def OnSetAsSysCwd(self, event):
        node = self.list.getSelection()
        if node: path = node.resourcepath
        else: path  = self.list.node.resourcepath

        if os.path.isfile(path): path = os.path.split(path)[0]
        os.chdir(path)

        self.editor.setStatus(_('Updated os.cwd to %s')%path, ringBell=True)

    def OnEmptyZipArchive(self, event):
        # must move to zip
        files = os.listdir(self.list.node.resourcepath)
        newName = Utils.getValidName(files, 'archive', 'zip')
        import zipfile
        zipfile.ZipFile(os.path.join(self.list.node.resourcepath, newName), 'w',
              zipfile.ZIP_DEFLATED).close()

        self.list.refreshCurrent()
        self.list.selectItemNamed(newName)
        self.list.EnsureVisible(self.list.selected)

    def OnEmptyTarGzipArchive(self, event):
        pass

    def OnInspectItem(self, event):
        if self.list.node:
            item = self.list.getSelection()
            if item:
                comp = FileSysCompanion(item.name, item)
                comp.updateProps()
                self.inspector.selectObject(comp, False, focusPage=1)



class FileSysAttrPropEdit(PropertyEditors.PropertyEditor):
    def inspectorEdit(self):
        self.editorCtrl = InspectorEditorControls.BeveledLabelIEC(self,
              self.getValue())
        self.editorCtrl.createControl(self.parent, self.idx, self.width)
        self.editorCtrl.setValue(self.getValue())

    def getDisplayValue(self):
        return self.value


class FileSysCompanion(ExplorerNodes.ExplorerCompanion):
    def __init__(self, name, fsNode):
        ExplorerNodes.ExplorerCompanion.__init__(self, name)
        self.fsNode = fsNode

    def getPropEditor(self, prop):
        return FileSysAttrPropEdit

    timeFmt = '%a, %d %b %Y %H:%M:%S'
    def getPropertyItems(self):
        res = []
        attrs = self.fsNode.stdAttrs

        for date in ('creation-date', 'modify-date', 'access-date'):
            value = attrs[date]
            if value:
                res.append( (date,
                             time.strftime(self.timeFmt, time.localtime(value))) )

        value = attrs['read-only']
        res.append( ('read-only', value and 'True' or 'False') )

        value = attrs['size']
        if value:
            res.append( ('size', str(value)) )

        return res


class FileSysExpClipboard(ExplorerNodes.ExplorerClipboard):
    def clipPaste_FileSysExpClipboard(self, node, nodes, mode):
        # XXX Delayed cut (delete on paste or move) should clear the clipboard
        # XXX or refresh clipboard with new paths and clear 'cut' mode
        for clipnode in nodes:
            if mode == 'cut':
                node.moveFileFrom(clipnode)
                self.clipNodes = []
            elif mode == 'copy':
                node.copyFileFrom(clipnode)

    clipPaste_DefaultClipboard = clipPaste_FileSysExpClipboard

    def _genericFSPaste(self, node, nodes, mode):
        for other in nodes:
            other.copyToFS(node)

    def clipPaste_ZopeEClip(self, node, nodes, mode):
        # XXX Pasting a cut from Zope does not delete the cut items from Zope
        for zopeNode in nodes:
            zopeNode.downloadToFS(os.path.join(node.resourcepath, zopeNode.name))

    def clipPaste_FTPExpClipboard(self, node, nodes, mode):
        # XXX Pasting a cut from FTP does not delete the cut items from FTP
        for file in nodes:
            file.ftpConn.download(file.resourcepath,
                  os.path.join(node.resourcepath, file.name))

    clipPaste_SSHExpClipboard = _genericFSPaste
    clipPaste_ZipExpClipboard = _genericFSPaste
    clipPaste_DAVExpClipboard = _genericFSPaste

class FileSysNode(ExplorerNodes.ExplorerNode):
    protocol = 'file'
    filter = 'BoaFiles'
    lastSearch = ''
    subExplorerReg = {'file': [], 'folder': []}
    connection = False
    pathSep = os.sep
    def __init__(self, name, resourcepath, clipboard, imgIdx, parent=None,
          bookmarks=None, properties={}):
        ExplorerNodes.ExplorerNode.__init__(self, name, resourcepath, clipboard,
              imgIdx, parent, properties or {})
        self.bookmarks = bookmarks
        self.exts = EditorHelper.extMap.keys() + EditorHelper.inspectableFilesReg.keys()
        self.entries = []

        # XXX not used ?
        self.doCVS = True
        self.doZip = True
        self.allowedProtocols = ['*']
        self.updateStdAttrs()

    def destroy(self):
        self.entries = []

    def isDir(self):
        return os.path.isdir(self.resourcepath)

    def isFolderish(self):
        return self.isDir() or filter(lambda se, rp=self.resourcepath,
              ap=self.allowedProtocols : (ap == ['*'] or se[0].protocol in ap) and se[1](rp),
              self.subExplorerReg['file'])

    def createParentNode(self):
        parent = os.path.abspath(os.path.join(self.resourcepath, '..'))
        if parent[-2:] == '..':
            parent = parent[:-2]
        return FileSysNode(os.path.basename(parent), parent, self.clipboard,
                  EditorHelper.imgFolder, self, self.bookmarks)

    def createChildNode(self, file, filename = ''):
        if not filename:
            filename = os.path.join(self.resourcepath, file)

        ext = os.path.splitext(filename)[1].lower()
        exts, extSubTypes = self.getFilterExts()
        # Files
        if ('.*' in exts or ext in exts) and os.path.isfile(filename):
            for Other, otherIdFunc, imgIdx in self.subExplorerReg['file']:
                if '*' in self.allowedProtocols or \
                      Other.protocol in self.allowedProtocols:
                    if otherIdFunc(filename):
                        return 'fol', Other(file, filename, self.clipboard,
                              imgIdx, self, self.bookmarks)
            Model = Controllers.identifyFile(filename)[0]
            if extSubTypes.has_key(ext):
                for SubTypeModel in extSubTypes[ext]:
                    if issubclass(Model, SubTypeModel):
                        break
                else:
                    return '', None
            return 'mod', FileSysNode(file, filename, self.clipboard,
              Model.imgIdx, self, self.bookmarks, {})
              #{'datetime': time.strftime('%a %b %d %H:%M:%S %Y',
              #             time.gmtime(os.stat(filename)[stat.ST_MTIME]))})
        # Directories
        elif os.path.isdir(filename):
            for other, otherIdFunc, imgIdx in self.subExplorerReg['folder']:
                if self.filter == 'BoaFiles' and \
                  '*' in self.allowedProtocols or '*' in self.allowedProtocols or \
                      other.protocol in self.allowedProtocols:
                    if otherIdFunc(filename):
                        return 'fol', other(file, filename, self.clipboard,
                              imgIdx, self, self.bookmarks)
            return 'fol', FileSysNode(file, filename, self.clipboard,
                  EditorHelper.imgFolder, self, self.bookmarks)
        else:
            return '', None

    def openList(self):
        try:
            #----------------------------------------
            # A hack for locally-encoded filesystems:
            # We need to convert filesystem names
            # from local encoding to unicode
            if type(self.resourcepath) is str:
                files = os.listdir(self.resourcepath.decode(
                      sys.getfilesystemencoding()))
            else: # unicode or other
                files = os.listdir(self.resourcepath)
            #---------------------------------------- 
        except Exception, err:
            raise ExplorerNodes.TransportError(err)
        files.sort()
        entries = {'mod': [], 'fol': []}

        for file in files:
            tp, node = self.createChildNode(file)
            if node:
                entries[tp].append(node)

        self.entries = entries['fol'] + entries['mod']
        return self.entries

    def deleteItems(self, names):
        for name in names:
            path = os.path.join(self.resourcepath, name)
            if os.path.isdir(path):
                os.rmdir(path)
            else:
                os.remove(path)

    def renameItem(self, name, newName):
        oldfile = os.path.join(self.resourcepath, name)
        newfile = os.path.join(self.resourcepath, newName)
        os.rename(oldfile, newfile)

    def newFolder(self, name):
        os.mkdir(os.path.join(self.resourcepath, name))
        return name

    def newBlankDocument(self, name=''):
        newpath = os.path.join(self.resourcepath, name)
        if not os.path.exists(newpath):
            open(newpath, 'w').write(' ')
        return name

    def copyFileFrom(self, node):
        """ Copy node into self (only called for folders)"""
        import shutil
        if not node.isDir():
            if node.resourcepath == os.path.join(self.resourcepath, node.name):
                newNameBase = os.path.join(self.resourcepath, 'copy%s_of_'+node.name)
                num = ''
                while 1:
                    newName = newNameBase%num
                    if os.path.exists(newName):
                        try: num = str(int(num) + 1)
                        except: num = '2'
                    else:
                        shutil.copy(node.resourcepath, newName)
                        break
            else:
                shutil.copy(node.resourcepath, self.resourcepath)
##                names = map(lambda n: n.name, self.entries)
##                dir, name = os.path.split(self.resourcepath)
##                name, ext = os.path.splitext(name)
##                name = Util.getValidName(names, name, ext)
##                shutil.copy(node.resourcepath, name)
##            else:
##            shutil.copy(node.resourcepath, self.resourcepath)
        else:
            shutil.copytree(node.resourcepath, os.path.join(self.resourcepath, node.name))

    def moveFileFrom(self, node):
        # Moving into directory being moved should not be allowed
        sp = os.path.normpath(node.resourcepath)
        dp = os.path.normpath(self.resourcepath)
        if dp[:len(sp)] == sp:
            raise Exception('Cannot move into itself')

        self.copyFileFrom(node)
        if not node.isFolderish():
            os.remove(node.resourcepath)
        else:
            import shutil
            shutil.rmtree(node.resourcepath)

    def setFilter(self, filter):
        self.__class__.filter = filter

    def getFilterExts(self):
        return {'BoaFiles': (self.exts, {}),
                'StdFiles': (self.exts, {}),
                'BoaIntFiles': (EditorHelper.internalFilesReg, {}),
                'ImageFiles': (EditorHelper.imageExtReg,
                               EditorHelper.imageSubTypeExtReg),
                'AllFiles': (['.*'], {})}.get(self.filter, (self.exts, {}))

    def load(self, mode='rb'):
        try:
            data = open(self.resourcepath, mode).read()
            self.updateStdAttrs()
            return data
        except IOError, error:
            raise ExplorerNodes.TransportLoadError(error, self.resourcepath)

    def save(self, filename, data, mode='wb', overwriteNewer=False):
        if self.resourcepath != filename:
            self.resourcepath = filename
            self.name = os.path.basename(self.resourcepath)
        try:
            if not overwriteNewer and self.fileIsNewer():
                raise ExplorerNodes.TransportModifiedSaveError(_('This file has '
                  'been saved by someone else since it was loaded'),
                  self.resourcepath)
            open(self.resourcepath, mode).write(data)
        except IOError, error:
            raise ExplorerNodes.TransportSaveError(error, self.resourcepath)
        self.updateStdAttrs()

    def getNodeFromPath(self, respath):
        name = os.path.basename(respath)
        return self.createChildNode(name, respath)

    def updateStdAttrs(self):
        exists = os.path.exists(self.resourcepath)
        self.stdAttrs['read-only'] = exists and \
              not os.access(self.resourcepath, os.W_OK)
        self.stdAttrs['modify-date'] = exists and \
              os.stat(self.resourcepath)[stat.ST_MTIME] or 0.0
        self.stdAttrs['creation-date'] = exists and \
              os.stat(self.resourcepath)[stat.ST_CTIME] or 0.0
        self.stdAttrs['access-date'] = exists and \
              os.stat(self.resourcepath)[stat.ST_ATIME] or 0.0
        self.stdAttrs['size'] = exists and \
              os.stat(self.resourcepath)[stat.ST_SIZE] or 0

    def setStdAttr(self, attr, value=None):
        if attr == 'read-only':
            os.chmod(self.resourcepath, value and 0444 or 0666)

        self.updateStdAttrs()

    def fileIsNewer(self):
        return (os.path.exists(self.resourcepath) and \
            os.stat(self.resourcepath)[stat.ST_MTIME] or 0.0) > \
            self.stdAttrs['modify-date']

class ResultsFolderNode(FileSysNode):
    results = []
    def openList(self):
        self.parentOpensChildren = True
        self.results.sort()
        self.results.reverse()
        entries = []

        for occrs, filename in self.results:
            tp, node = self.createChildNode('(%d) %s'%(occrs, filename),
                  os.path.join(self.resourcepath, filename))
            if node:
                entries.append(node)

        self.entries = entries
        return self.entries

    def openParent(self, editor):
        editor.explorer.tree.SelectItem(editor.explorer.tree.GetSelection())
        return True

    def open(self, node, editor):
        mod, cntrl = node.open(editor)
        view = mod.getSourceView()
        if view:
            view.doFind(self.lastSearch)
            view.doNextMatch()
        return mod, cntrl

    def getTitle(self):
        return _('Find results for %s in %s') % (self.lastSearch, self.resourcepath)

class NonCheckPyFolderNode(FileSysNode):
    def isFolderish(self):
        return True

class CurWorkDirNode(FileSysNode):
    protocol = 'os.cwd'
    def __init__(self, clipboard, parent, bookmarks):
        self.cwd = os.path.abspath(os.getcwd())
        FileSysNode.__init__(self, 'os.cwd', self.cwd, clipboard,
              EditorHelper.imgPathFolder, parent)
        self.bookmarks = bookmarks
        self.bold = True
        #self.setFilter('AllFiles')

    def openList(self):
        self.cwd = self.resourcepath = os.path.abspath(os.getcwd())
        return FileSysNode.openList(self)

    def getTitle(self):
        return 'os.cwd://%s'%self.cwd
    def getURI(self):
        return self.getTitle()

def uriSplitFile(filename, filepath):
    return 'file', '', filepath, filename

def findFileExplorerNode(category, respath, transports):
    for tp in transports.entries:
        if tp.itemProtocol == 'file':
            return tp.getNodeFromPath(respath, forceFolder=False)
    raise ExplorerNodes.TransportError(
          _('FileSysCatNode not found in transports %s')%transports.entries)

#-------------------------------------------------------------------------------
ExplorerNodes.register(FileSysNode, clipboard=FileSysExpClipboard,
      confdef=('explorer', 'file'), controller=FileSysController,
      category=FileSysCatNode)
ExplorerNodes.register(CurWorkDirNode, clipboard='file', controller='file',
      root=True)
ExplorerNodes.fileOpenDlgProtReg.append('file')
ExplorerNodes.uriSplitReg[('file', 2)] = uriSplitFile
ExplorerNodes.uriSplitReg[('os.cwd', 2)] = uriSplitFile
ExplorerNodes.transportFindReg['file'] = findFileExplorerNode
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.