#----------------------------------------------------------------------------- # Name: FTPExplorer.py # Purpose: # # Author: Riaan Booysen # # Created: 2001 # RCS-ID: $Id: FTPExplorer.py,v 1.17 2005/05/13 20:41:59 riaan Exp $ # Copyright: (c) 2001 - 2005 # Licence: GPL #----------------------------------------------------------------------------- print 'importing Explorers.FTPExplorer' import os import wx import Preferences, Utils import ExplorerNodes from Models import Controllers, EditorHelper import ftplib wxID_FTPOPEN = wx.NewId() class FTPController(ExplorerNodes.Controller, ExplorerNodes.ClipboardControllerMix): def __init__(self, editor, list, inspector, controllers): ExplorerNodes.ClipboardControllerMix.__init__(self) ExplorerNodes.Controller.__init__(self, editor) self.list = list self.menu = wx.Menu() self.setupMenu(self.menu, self.list, [ (wxID_FTPOPEN, 'Open', self.OnOpenItems, '-'), (-1, '-', None, '') ] + self.clipMenuDef) self.toolbarMenus = [self.clipMenuDef] def destroy(self): ExplorerNodes.ClipboardControllerMix.destroy(self) self.toolbarMenus = () self.menu.Destroy() class FTPCatNode(ExplorerNodes.CategoryNode): itemProtocol = 'ftp' defName = 'FTP' defaultStruct = {'username': 'anonymous', 'passwd': '', 'host': 'localhost', 'port': 21, 'path': '/', 'passive': 0} def __init__(self, clipboard, config, parent, bookmarks): ExplorerNodes.CategoryNode.__init__(self, 'FTP', ('explorer', 'ftp'), clipboard, config, parent) self.bookmarks = bookmarks def createParentNode(self): return self def createChildNode(self, name, props): ftpcn = FTPConnectionNode(name, props, props['path'], self.clipboard, self) ftpcn.bookmarks = self.bookmarks return ftpcn def createCatCompanion(self, catNode): comp = ExplorerNodes.CategoryDictCompanion(catNode.treename, self) return comp class FTPItemNode(ExplorerNodes.ExplorerNode): protocol = 'ftp' connection = True def __init__(self, name, props, resourcepath, clipboard, isFolder, imgIdx, parent, ftpConn, ftpObj, root): ExplorerNodes.ExplorerNode.__init__(self, name, resourcepath, clipboard, imgIdx, parent, props) self.isFolder = isFolder self.ftpConn = ftpConn self.ftpObj = ftpObj self.root = root self.cache = {} def destroy(self): pass#self.cache = {} def isFolderish(self): return self.ftpObj.isFolder() def getURI(self): return '%s://%s%s%s' %(self.protocol, self.category, self.ftpObj.whole_name(), self.isFolderish() and '/' or '') def createChildNode(self, obj, root, respath=None, createConnection=False): if respath is None: respath=self.resourcepath+'/'+obj.name elif respath[0] != '/': respath = '/'+respath if createConnection: item = FTPConnectionNode(obj.name, self.properties, respath, self.clipboard, self) else: item = FTPItemNode(obj.name, self.properties, respath, self.clipboard, False, -1 , self, self.ftpConn, obj, root) if item.isFolderish(): item.imgIdx = EditorHelper.imgFolder else: item.imgIdx = Controllers.identifyFile(obj.name, localfs=False)[0].imgIdx item.category = self.category item.bookmarks = self.bookmarks return item def openList(self, root=None): items = self.ftpConn.dir(self.ftpObj.whole_name()) if not root: root = self.root self.cache = {} result = [] for obj in items: if obj.name in ('', '.', '..'): continue z = self.createChildNode(obj, self.root) if z: result.append(z) self.cache[obj.name] = z return result def deleteItems(self, names): for item in names: self.ftpConn.delete(self.cache[item].ftpObj) def renameItem(self, name, newName): self.ftpConn.rename(self.cache[name].ftpObj, newName) def newFolder(self, name): self.ftpConn.add_folder(name, self.resourcepath) def newBlankDocument(self, name): self.ftpConn.upload(name, self.resourcepath, ' ') def load(self, mode='rb'): try: return self.ftpConn.load(self.ftpObj) except Exception, error: raise ExplorerNodes.TransportLoadError(error, self.ftpObj.whole_name()) def save(self, filename, data, mode='wb', overwriteNewer=False): if filename != self.currentFilename(): self.ftpObj.path = os.path.dirname(filename) self.ftpObj.name = os.path.basename(filename) try: self.ftpConn.save(self.ftpObj, data) except Exception, error: raise ExplorerNodes.TransportSaveError(error, self.ftpObj.whole_name()) def getNodeFromPath(self, respath): if not respath: respath = '/' isFolder = respath[-1] == '/' if isFolder: if respath != '/': respath = respath[:-1] return self.createChildNode(self.ftpConn.folder_item(os.path.dirname(respath), os.path.basename(respath)), self.root, respath) else: return self.createChildNode(self.ftpConn.add_doc(os.path.dirname(respath), os.path.basename(respath)), self.root, respath) class FTPConnectionNode(FTPItemNode): def __init__(self, name, properties, respath, clipboard, parent): from ZopeLib import ZopeFTP ftpConn = ZopeFTP.ZopeFTP() if respath and respath[-1] == '/': ftpObj = ftpConn.folder_item(os.path.basename(respath), os.path.dirname(respath)) isFolder = True else: ftpObj = ftpConn.add_doc(os.path.basename(respath), os.path.dirname(respath)) isFolder = False FTPItemNode.__init__(self, '', properties, ftpObj.path, clipboard, isFolder, EditorHelper.imgNetDrive, parent, ftpConn, ftpObj, self) self.connected = False self.treename = name self.category = name def openList(self): self.testConnect() return FTPItemNode.openList(self, self) def load(self, mode='rb'): self.testConnect() return FTPItemNode.load(self, mode) def save(self, filename, data, mode='wb', overwriteNewer=False): self.testConnect() FTPItemNode.save(self, filename, data, mode, overwriteNewer) def createChildNode(self, obj, root, respath=None): return FTPItemNode.createChildNode(self, obj, root, respath, not self.connected) def testConnect(self): if not self.connected: try: props = self.properties self.ftpConn.connect(props['username'], props['passwd'], props['host'], props['port'], props['passive']) except Exception, message: wx.MessageBox(`message.args`, 'Error on connect') raise else: self.connected = True class FTPExpClipboard(ExplorerNodes.ExplorerClipboard): def pasteFileSysFolder(self, folderpath, nodepath, ftpConn): ftpConn.add_folder(os.path.basename(folderpath), nodepath) files = os.listdir(folderpath) folder = os.path.basename(folderpath) newNodepath = nodepath+'/'+folder for file in files: file = os.path.join(folderpath, file) if os.path.isdir(file): self.pasteFileSysFolder(file, newNodepath, ftpConn) else: ftpConn.upload(file, newNodepath) def clipPaste_FileSysExpClipboard(self, node, nodes, mode): nodepath = node.resourcepath for file in nodes: if file.isDir(): self.pasteFileSysFolder(file.resourcepath, nodepath, node.ftpConn) else: node.ftpConn.upload(file.resourcepath, nodepath) #------------------------------------------------------------------------------- ExplorerNodes.register(FTPItemNode, clipboard=FTPExpClipboard, confdef=('explorer', 'ftp'), controller=FTPController, category=FTPCatNode) ExplorerNodes.fileOpenDlgProtReg.append('ftp')