1#!/usr/bin/env python 2 3""" 4FCKeditor - The text editor for Internet - http://www.fckeditor.net 5Copyright (C) 2003-2007 Frederico Caldeira Knabben 6 7== BEGIN LICENSE == 8 9Licensed under the terms of any of the following licenses at your 10choice: 11 12- GNU General Public License Version 2 or later (the "GPL") 13http://www.gnu.org/licenses/gpl.html 14 15- GNU Lesser General Public License Version 2.1 or later (the "LGPL") 16http://www.gnu.org/licenses/lgpl.html 17 18- Mozilla Public License Version 1.1 or later (the "MPL") 19http://www.mozilla.org/MPL/MPL-1.1.html 20 21== END LICENSE == 22 23Connector for Python (CGI and WSGI). 24 25""" 26 27import os 28try: # Windows needs stdio set for binary mode for file upload to work. 29 import msvcrt 30 msvcrt.setmode (0, os.O_BINARY) # stdin = 0 31 msvcrt.setmode (1, os.O_BINARY) # stdout = 1 32except ImportError: 33 pass 34 35from fckutil import * 36from fckoutput import * 37import config as Config 38 39class GetFoldersCommandMixin (object): 40 def getFolders(self, resourceType, currentFolder): 41 """ 42 Purpose: command to recieve a list of folders 43 """ 44 # Map the virtual path to our local server 45 serverPath = mapServerFolder(self.userFilesFolder,currentFolder) 46 s = """<Folders>""" # Open the folders node 47 for someObject in os.listdir(serverPath): 48 someObjectPath = mapServerFolder(serverPath, someObject) 49 if os.path.isdir(someObjectPath): 50 s += """<Folder name="%s" />""" % ( 51 convertToXmlAttribute(someObject) 52 ) 53 s += """</Folders>""" # Close the folders node 54 return s 55 56class GetFoldersAndFilesCommandMixin (object): 57 def getFoldersAndFiles(self, resourceType, currentFolder): 58 """ 59 Purpose: command to recieve a list of folders and files 60 """ 61 # Map the virtual path to our local server 62 serverPath = mapServerFolder(self.userFilesFolder,currentFolder) 63 # Open the folders / files node 64 folders = """<Folders>""" 65 files = """<Files>""" 66 for someObject in os.listdir(serverPath): 67 someObjectPath = mapServerFolder(serverPath, someObject) 68 if os.path.isdir(someObjectPath): 69 folders += """<Folder name="%s" />""" % ( 70 convertToXmlAttribute(someObject) 71 ) 72 elif os.path.isfile(someObjectPath): 73 size = os.path.getsize(someObjectPath) 74 files += """<File name="%s" size="%s" />""" % ( 75 convertToXmlAttribute(someObject), 76 os.path.getsize(someObjectPath) 77 ) 78 # Close the folders / files node 79 folders += """</Folders>""" 80 files += """</Files>""" 81 return folders + files 82 83class CreateFolderCommandMixin (object): 84 def createFolder(self, resourceType, currentFolder): 85 """ 86 Purpose: command to create a new folder 87 """ 88 errorNo = 0; errorMsg =''; 89 if self.request.has_key("NewFolderName"): 90 newFolder = self.request.get("NewFolderName", None) 91 newFolder = sanitizeFolderName (newFolder) 92 try: 93 newFolderPath = mapServerFolder(self.userFilesFolder, combinePaths(currentFolder, newFolder)) 94 self.createServerFolder(newFolderPath) 95 except Exception, e: 96 errorMsg = str(e).decode('iso-8859-1').encode('utf-8') # warning with encodigns!!! 97 if hasattr(e,'errno'): 98 if e.errno==17: #file already exists 99 errorNo=0 100 elif e.errno==13: # permission denied 101 errorNo = 103 102 elif e.errno==36 or e.errno==2 or e.errno==22: # filename too long / no such file / invalid name 103 errorNo = 102 104 else: 105 errorNo = 110 106 else: 107 errorNo = 102 108 return self.sendErrorNode ( errorNo, errorMsg ) 109 110 def createServerFolder(self, folderPath): 111 "Purpose: physically creates a folder on the server" 112 # No need to check if the parent exists, just create all hierachy 113 oldumask = os.umask(0) 114 os.makedirs(folderPath,mode=0755) 115 os.umask( oldumask ) 116 117class UploadFileCommandMixin (object): 118 def uploadFile(self, resourceType, currentFolder): 119 """ 120 Purpose: command to upload files to server (same as FileUpload) 121 """ 122 errorNo = 0 123 if self.request.has_key("NewFile"): 124 # newFile has all the contents we need 125 newFile = self.request.get("NewFile", "") 126 # Get the file name 127 newFileName = newFile.filename 128 newFileName = sanitizeFileName( newFileName ) 129 newFileNameOnly = removeExtension(newFileName) 130 newFileExtension = getExtension(newFileName).lower() 131 allowedExtensions = Config.AllowedExtensions[resourceType] 132 deniedExtensions = Config.DeniedExtensions[resourceType] 133 134 if (allowedExtensions): 135 # Check for allowed 136 isAllowed = False 137 if (newFileExtension in allowedExtensions): 138 isAllowed = True 139 elif (deniedExtensions): 140 # Check for denied 141 isAllowed = True 142 if (newFileExtension in deniedExtensions): 143 isAllowed = False 144 else: 145 # No extension limitations 146 isAllowed = True 147 148 if (isAllowed): 149 # Upload to operating system 150 # Map the virtual path to the local server path 151 currentFolderPath = mapServerFolder(self.userFilesFolder, currentFolder) 152 i = 0 153 while (True): 154 newFilePath = os.path.join (currentFolderPath,newFileName) 155 if os.path.exists(newFilePath): 156 i += 1 157 newFileName = "%s(%04d).%s" % ( 158 newFileNameOnly, i, newFileExtension 159 ) 160 errorNo= 201 # file renamed 161 else: 162 # Read file contents and write to the desired path (similar to php's move_uploaded_file) 163 fout = file(newFilePath, 'wb') 164 while (True): 165 chunk = newFile.file.read(100000) 166 if not chunk: break 167 fout.write (chunk) 168 fout.close() 169 170 if os.path.exists ( newFilePath ): 171 oldumask = os.umask(0) 172 os.chmod( newFilePath, 0755 ) 173 os.umask( oldumask ) 174 175 newFileUrl = self.webUserFilesFolder + currentFolder + newFileName 176 177 return self.sendUploadResults( errorNo , newFileUrl, newFileName ) 178 else: 179 return self.sendUploadResults( errorNo = 203, customMsg = "Extension not allowed" ) 180 else: 181 return self.sendUploadResults( errorNo = 202, customMsg = "No File" ) 182