Changeset 591

Show
Ignore:
Timestamp:
2007-07-30 11:35:06 (16 months ago)
Author:
alfonsoml
Message:

New Python connector from #575

Location:
FCKeditor/trunk
Files:
9 added
4 modified

Legend:

Unmodified
Added
Removed
  • FCKeditor/trunk/editor/filemanager/connectors/py/connector.py

    r413 r591  
    2121== END LICENSE == 
    2222 
    23 Connector for Python. 
     23Connector for Python (CGI and WSGI). 
    2424 
    25 Tested With: 
    26 Standard: 
    27         Python 2.3.3 
    28 Zope: 
    29         Zope Version: (Zope 2.8.1-final, python 2.3.5, linux2) 
    30         Python Version: 2.3.5 (#4, Mar 10 2005, 01:40:25) 
    31                 [GCC 3.3.3 20040412 (Red Hat Linux 3.3.3-7)] 
    32         System Platform: linux2 
    33 """ 
     25See config.py for configuration settings 
    3426 
    3527""" 
    36 Author Notes (04 December 2005): 
    37 This module has gone through quite a few phases of change.  Obviously, 
    38 I am only supporting that part of the code that I use.  Initially 
    39 I had the upload directory as a part of zope (ie. uploading files 
    40 directly into Zope), before realising that there were too many 
    41 complex intricacies within Zope to deal with.  Zope is one ugly piece 
    42 of code.  So I decided to complement Zope by an Apache server (which 
    43 I had running anyway, and doing nothing).  So I mapped all uploads 
    44 from an arbitrary server directory to an arbitrary web directory. 
    45 All the FCKeditor uploading occurred this way, and I didn't have to 
    46 stuff around with fiddling with Zope objects and the like (which are 
    47 terribly complex and something you don't want to do - trust me). 
     28import os 
    4829 
    49 Maybe a Zope expert can touch up the Zope components.  In the end, 
    50 I had FCKeditor loaded in Zope (probably a bad idea as well), and 
    51 I replaced the connector.py with an alias to a server module. 
    52 Right now, all Zope components will simple remain as is because 
    53 I've had enough of Zope. 
     30from fckutil import * 
     31from fckcommands import *       # default command's implementation 
     32from fckoutput import *         # base http, xml and html output mixins 
     33from fckconnector import FCKeditorConnectorBase # import base connector 
     34import config as Config 
    5435 
    55 See notes right at the end of this file for how I aliased out of Zope. 
     36class FCKeditorConnector(       FCKeditorConnectorBase, 
     37                                                        GetFoldersCommandMixin, 
     38                                                        GetFoldersAndFilesCommandMixin, 
     39                                                        CreateFolderCommandMixin, 
     40                                                        UploadFileCommandMixin,  
     41                                                        BaseHttpMixin, BaseXmlMixin, BaseHtmlMixin  ): 
     42        "The Standard connector class." 
     43        def doResponse(self): 
     44                "Main function. Process the request, set headers and return a string as response." 
     45                s = "" 
     46                # Check if this connector is disabled 
     47                if not(Config.Enabled): 
     48                        return self.sendError(1, "This connector is disabled.  Please check the connector configurations in \"editor/filemanager/connectors/py/config.py\" and try again.") 
     49                # Make sure we have valid inputs 
     50                for key in ("Command","Type","CurrentFolder"): 
     51                        if not self.request.has_key (key): 
     52                                return 
     53                # Get command, resource type and current folder 
     54                command = self.request.get("Command") 
     55                resourceType = self.request.get("Type") 
     56                currentFolder = getCurrentFolder(self.request.get("CurrentFolder")) 
     57                # Check for invalid paths 
     58                if currentFolder is None: 
     59                        return self.sendError(102, "") 
     60                 
     61                # Check if it is an allowed command 
     62                if ( not command in Config.ConfigAllowedCommands ): 
     63                        return self.sendError( 1, 'The %s command isn\'t allowed' % command )  
     64                 
     65                if ( not resourceType in Config.ConfigAllowedTypes  ): 
     66                        return self.sendError( 1, 'Invalid type specified' )  
    5667 
    57 Anyway, most of you probably wont use Zope, so things are pretty 
    58 simple in that regard. 
     68                # Setup paths 
     69                if command == "QuickUpload": 
     70                        self.userFilesFolder = Config.QuickUploadAbsolutePath[resourceType]  
     71                        self.webUserFilesFolder =  Config.QuickUploadPath[resourceType] 
     72                else: 
     73                        self.userFilesFolder = Config.FileTypesAbsolutePath[resourceType] 
     74                        self.webUserFilesFolder = Config.FileTypesPath[resourceType]     
     75                 
     76                if not self.userFilesFolder: # no absolute path given (dangerous...) 
     77                        self.userFilesFolder = mapServerPath(self.environ,  
     78                                                                        self.webUserFilesFolder) 
     79                # Ensure that the directory exists. 
     80                if not os.path.exists(self.userFilesFolder): 
     81                        try: 
     82                                self.createServerFoldercreateServerFolder( self.userFilesFolder )  
     83                        except: 
     84                                return self.sendError(1, "This connector couldn\'t access to local user\'s files directories.  Please check the UserFilesAbsolutePath in \"editor/filemanager/connectors/py/config.py\" and try again. ") 
    5985 
    60 Typically, SERVER_DIR is the root of WEB_DIR (not necessarily). 
    61 Most definitely, SERVER_USERFILES_DIR points to WEB_USERFILES_DIR. 
    62 """ 
    63  
    64 import cgi 
    65 import re 
    66 import os 
    67 import string 
    68  
    69 """ 
    70 escape 
    71  
    72 Converts the special characters '<', '>', and '&'. 
    73  
    74 RFC 1866 specifies that these characters be represented 
    75 in HTML as &lt; &gt; and &amp; respectively. In Python 
    76 1.5 we use the new string.replace() function for speed. 
    77 """ 
    78 def escape(text, replace=string.replace): 
    79     text = replace(text, '&', '&amp;') # must be done 1st 
    80     text = replace(text, '<', '&lt;') 
    81     text = replace(text, '>', '&gt;') 
    82     text = replace(text, '"', '&quot;') 
    83     return text 
    84  
    85 """ 
    86 getFCKeditorConnector 
    87  
    88 Creates a new instance of an FCKeditorConnector, and runs it 
    89 """ 
    90 def getFCKeditorConnector(context=None): 
    91         # Called from Zope.  Passes the context through 
    92         connector = FCKeditorConnector(context=context) 
    93         return connector.run() 
    94  
    95  
    96 """ 
    97 FCKeditorRequest 
    98  
    99 A wrapper around the request object 
    100 Can handle normal CGI request, or a Zope request 
    101 Extend as required 
    102 """ 
    103 class FCKeditorRequest(object): 
    104         def __init__(self, context=None): 
    105                 if (context is not None): 
    106                         r = context.REQUEST 
    107                 else: 
    108                         r = cgi.FieldStorage() 
    109                 self.context = context 
    110                 self.request = r 
    111  
    112         def isZope(self): 
    113                 if (self.context is not None): 
    114                         return True 
    115                 return False 
    116  
    117         def has_key(self, key): 
    118                 return self.request.has_key(key) 
    119  
    120         def get(self, key, default=None): 
    121                 value = None 
    122                 if (self.isZope()): 
    123                         value = self.request.get(key, default) 
    124                 else: 
    125                         if key in self.request.keys(): 
    126                                 value = self.request[key].value 
    127                         else: 
    128                                 value = default 
    129                 return value 
    130  
    131 """ 
    132 FCKeditorConnector 
    133  
    134 The connector class 
    135 """ 
    136 class FCKeditorConnector(object): 
    137         # Configuration for FCKEditor 
    138         # can point to another server here, if linked correctly 
    139         #WEB_HOST = "http://127.0.0.1/" 
    140         WEB_HOST = "" 
    141         SERVER_DIR = "/var/www/html/" 
    142  
    143         WEB_USERFILES_FOLDER = WEB_HOST + "upload/" 
    144         SERVER_USERFILES_FOLDER = SERVER_DIR + "upload/" 
    145  
    146         # Allow access (Zope) 
    147         __allow_access_to_unprotected_subobjects__ = 1 
    148         # Class Attributes 
    149         parentFolderRe = re.compile("[\/][^\/]+[\/]?$") 
    150  
    151         """ 
    152         Constructor 
    153         """ 
    154         def __init__(self, context=None): 
    155                 # The given root path will NOT be shown to the user 
    156                 # Only the userFilesPath will be shown 
    157  
    158                 # Instance Attributes 
    159                 self.context = context 
    160                 self.request = FCKeditorRequest(context=context) 
    161                 self.rootPath = self.SERVER_DIR 
    162                 self.userFilesFolder = self.SERVER_USERFILES_FOLDER 
    163                 self.webUserFilesFolder = self.WEB_USERFILES_FOLDER 
    164  
    165                 # Enables / Disables the connector 
    166                 self.enabled = False # Set to True to enable this connector 
    167  
    168                 # These are instance variables 
    169                 self.zopeRootContext = None 
    170                 self.zopeUploadContext = None 
    171  
    172                 # Copied from php module =) 
    173                 self.allowedExtensions = { 
    174                                 "File": None, 
    175                                 "Image": None, 
    176                                 "Flash": None, 
    177                                 "Media": None 
    178                                 } 
    179                 self.deniedExtensions = { 
    180                                 "File": [ "html","htm","php","php2","php3","php4","php5","phtml","pwml","inc","asp","aspx","ascx","jsp","cfm","cfc","pl","bat","exe","com","dll","vbs","js","reg","cgi","htaccess","asis","sh","shtml","shtm","phtm" ], 
    181                                 "Image": [ "html","htm","php","php2","php3","php4","php5","phtml","pwml","inc","asp","aspx","ascx","jsp","cfm","cfc","pl","bat","exe","com","dll","vbs","js","reg","cgi","htaccess","asis","sh","shtml","shtm","phtm" ], 
    182                                 "Flash": [ "html","htm","php","php2","php3","php4","php5","phtml","pwml","inc","asp","aspx","ascx","jsp","cfm","cfc","pl","bat","exe","com","dll","vbs","js","reg","cgi","htaccess","asis","sh","shtml","shtm","phtm" ], 
    183                                 "Media": [ "html","htm","php","php2","php3","php4","php5","phtml","pwml","inc","asp","aspx","ascx","jsp","cfm","cfc","pl","bat","exe","com","dll","vbs","js","reg","cgi","htaccess","asis","sh","shtml","shtm","phtm" ] 
    184                                 } 
    185  
    186         """ 
    187         Zope specific functions 
    188         """ 
    189         def isZope(self): 
    190                 # The context object is the zope object 
    191                 if (self.context is not None): 
    192                         return True 
    193                 return False 
    194  
    195         def getZopeRootContext(self): 
    196                 if self.zopeRootContext is None: 
    197                         self.zopeRootContext = self.context.getPhysicalRoot() 
    198                 return self.zopeRootContext 
    199  
    200         def getZopeUploadContext(self): 
    201                 if self.zopeUploadContext is None: 
    202                         folderNames = self.userFilesFolder.split("/") 
    203                         c = self.getZopeRootContext() 
    204                         for folderName in folderNames: 
    205                                 if (folderName <> ""): 
    206                                         c = c[folderName] 
    207                         self.zopeUploadContext = c 
    208                 return self.zopeUploadContext 
    209  
    210         """ 
    211         Generic manipulation functions 
    212         """ 
    213         def getUserFilesFolder(self): 
    214                 return self.userFilesFolder 
    215  
    216         def getWebUserFilesFolder(self): 
    217                 return self.webUserFilesFolder 
    218  
    219         def getAllowedExtensions(self, resourceType): 
    220                 return self.allowedExtensions[resourceType] 
    221  
    222         def getDeniedExtensions(self, resourceType): 
    223                 return self.deniedExtensions[resourceType] 
    224  
    225         def removeFromStart(self, string, char): 
    226                 return string.lstrip(char) 
    227  
    228         def removeFromEnd(self, string, char): 
    229                 return string.rstrip(char) 
    230  
    231         def convertToXmlAttribute(self, value): 
    232                 if (value is None): 
    233                         value = "" 
    234                 return escape(value) 
    235  
    236         def convertToPath(self, path): 
    237                 if (path[-1] <> "/"): 
    238                         return path + "/" 
    239                 else: 
    240                         return path 
    241  
    242         def getUrlFromPath(self, resourceType, path): 
    243                 if (resourceType is None) or (resourceType == ''): 
    244                         url = "%s%s" % ( 
    245                                         self.removeFromEnd(self.getUserFilesFolder(), '/'), 
    246                                         path 
    247                                         ) 
    248                 else: 
    249                         url = "%s%s%s" % ( 
    250                                         self.getUserFilesFolder(), 
    251                                         resourceType, 
    252                                         path 
    253                                         ) 
    254                 return url 
    255  
    256         def getWebUrlFromPath(self, resourceType, path): 
    257                 if (resourceType is None) or (resourceType == ''): 
    258                         url = "%s%s" % ( 
    259                                         self.removeFromEnd(self.getWebUserFilesFolder(), '/'), 
    260                                         path 
    261                                         ) 
    262                 else: 
    263                         url = "%s%s%s" % ( 
    264                                         self.getWebUserFilesFolder(), 
    265                                         resourceType, 
    266                                         path 
    267                                         ) 
    268                 return url 
    269  
    270         def removeExtension(self, fileName): 
    271                 index = fileName.rindex(".") 
    272                 newFileName = fileName[0:index] 
    273                 return newFileName 
    274  
    275         def getExtension(self, fileName): 
    276                 index = fileName.rindex(".") + 1 
    277                 fileExtension = fileName[index:] 
    278                 return fileExtension 
    279  
    280         def getParentFolder(self, folderPath): 
    281                 parentFolderPath = self.parentFolderRe.sub('', folderPath) 
    282                 return parentFolderPath 
    283  
    284         """ 
    285         serverMapFolder 
    286  
    287         Purpose: works out the folder map on the server 
    288         """ 
    289         def serverMapFolder(self, resourceType, folderPath): 
    290                 # Get the resource type directory 
    291                 resourceTypeFolder = "%s%s/" % ( 
    292                                 self.getUserFilesFolder(), 
    293                                 resourceType 
    294                                 ) 
    295                 # Ensure that the directory exists 
    296                 self.createServerFolder(resourceTypeFolder) 
    297  
    298                 # Return the resource type directory combined with the 
    299                 # required path 
    300                 return "%s%s" % ( 
    301                                 resourceTypeFolder, 
    302                                 self.removeFromStart(folderPath, '/') 
    303                                 ) 
    304  
    305         """ 
    306         createServerFolder 
    307  
    308         Purpose: physically creates a folder on the server 
    309         """ 
    310         def createServerFolder(self, folderPath): 
    311                 # Check if the parent exists 
    312                 parentFolderPath = self.getParentFolder(folderPath) 
    313                 if not(os.path.exists(parentFolderPath)): 
    314                         errorMsg = self.createServerFolder(parentFolderPath) 
    315                         if errorMsg is not None: 
    316                                 return errorMsg 
    317                 # Check if this exists 
    318                 if not(os.path.exists(folderPath)): 
    319                         os.mkdir(folderPath) 
    320                         os.chmod(folderPath, 0755) 
    321                         errorMsg = None 
    322                 else: 
    323                         if os.path.isdir(folderPath): 
    324                                 errorMsg = None 
    325                         else: 
    326                                 raise "createServerFolder: Non-folder of same name already exists" 
    327                 return errorMsg 
    328  
    329  
    330         """ 
    331         getRootPath 
    332  
    333         Purpose: returns the root path on the server 
    334         """ 
    335         def getRootPath(self): 
    336                 return self.rootPath 
    337  
    338         """ 
    339         setXmlHeaders 
    340  
    341         Purpose: to prepare the headers for the xml to return 
    342         """ 
    343         def setXmlHeaders(self): 
    344                 #now = self.context.BS_get_now() 
    345                 #yesterday = now - 1 
    346                 self.setHeader("Content-Type", "text/xml") 
    347                 #self.setHeader("Expires", yesterday) 
    348                 #self.setHeader("Last-Modified", now) 
    349                 #self.setHeader("Cache-Control", "no-store, no-cache, must-revalidate") 
    350                 self.printHeaders() 
    351                 return 
    352  
    353         def setHeader(self, key, value): 
    354                 if (self.isZope()): 
    355                         self.context.REQUEST.RESPONSE.setHeader(key, value) 
    356                 else: 
    357                         print "%s: %s" % (key, value) 
    358                 return 
    359  
    360         def printHeaders(self): 
    361                 # For non-Zope requests, we need to print an empty line 
    362                 # to denote the end of headers 
    363                 if (not(self.isZope())): 
    364                         print "" 
    365  
    366         """ 
    367         createXmlFooter 
    368  
    369         Purpose: returns the xml header 
    370         """ 
    371         def createXmlHeader(self, command, resourceType, currentFolder): 
    372                 self.setXmlHeaders() 
    373                 s = "" 
    374                 # Create the XML document header 
    375                 s += """<?xml version="1.0" encoding="utf-8" ?>""" 
    376                 # Create the main connector node 
    377                 s += """<Connector command="%s" resourceType="%s">""" % ( 
    378                                 command, 
    379                                 resourceType 
    380                                 ) 
    381                 # Add the current folder node 
    382                 s += """<CurrentFolder path="%s" url="%s" />""" % ( 
    383                                 self.convertToXmlAttribute(currentFolder), 
    384                                 self.convertToXmlAttribute( 
    385                                         self.getWebUrlFromPath( 
    386                                                 resourceType, 
    387                                                 currentFolder 
    388                                                 ) 
    389                                         ), 
    390                                 ) 
    391                 return s 
    392  
    393         """ 
    394         createXmlFooter 
    395  
    396         Purpose: returns the xml footer 
    397         """ 
    398         def createXmlFooter(self): 
    399                 s = """</Connector>""" 
    400                 return s 
    401  
    402         """ 
    403         sendError 
    404  
    405         Purpose: in the event of an error, return an xml based error 
    406         """ 
    407         def sendError(self, number, text): 
    408                 self.setXmlHeaders() 
    409                 s = "" 
    410                 # Create the XML document header 
    411                 s += """<?xml version="1.0" encoding="utf-8" ?>""" 
    412                 s += """<Connector>""" 
    413                 s += """<Error number="%s" text="%s" />""" % (number, text) 
    414                 s += """</Connector>""" 
    415                 return s 
    416  
    417         """ 
    418         getFolders 
    419  
    420         Purpose: command to recieve a list of folders 
    421         """ 
    422         def getFolders(self, resourceType, currentFolder): 
    423                 if (self.isZope()): 
    424                         return self.getZopeFolders(resourceType, currentFolder) 
    425                 else: 
    426                         return self.getNonZopeFolders(resourceType, currentFolder) 
    427  
    428         def getZopeFolders(self, resourceType, currentFolder): 
    429                 # Open the folders node 
    430                 s = "" 
    431                 s += """<Folders>""" 
    432                 zopeFolder = self.findZopeFolder(resourceType, currentFolder) 
    433                 for (name, o) in zopeFolder.objectItems(["Folder"]): 
    434                         s += """<Folder name="%s" />""" % ( 
    435                                         self.convertToXmlAttribute(name) 
    436                                         ) 
    437                 # Close the folders node 
    438                 s += """</Folders>""" 
    439                 return s 
    440  
    441         def getNonZopeFolders(self, resourceType, currentFolder): 
    442                 # Map the virtual path to our local server 
    443                 serverPath = self.serverMapFolder(resourceType, currentFolder) 
    444                 # Open the folders node 
    445                 s = "" 
    446                 s += """<Folders>""" 
    447                 for someObject in os.listdir(serverPath): 
    448                         someObjectPath = os.path.join(serverPath, someObject) 
    449                         if os.path.isdir(someObjectPath): 
    450                                 s += """<Folder name="%s" />""" % ( 
    451                                                 self.convertToXmlAttribute(someObject) 
    452                                                 ) 
    453                 # Close the folders node 
    454                 s += """</Folders>""" 
    455                 return s 
    456  
    457         """ 
    458         getFoldersAndFiles 
    459  
    460         Purpose: command to recieve a list of folders and files 
    461         """ 
    462         def getFoldersAndFiles(self, resourceType, currentFolder): 
    463                 if (self.isZope()): 
    464                         return self.getZopeFoldersAndFiles(resourceType, currentFolder) 
    465                 else: 
    466                         return self.getNonZopeFoldersAndFiles(resourceType, currentFolder) 
    467  
    468         def getNonZopeFoldersAndFiles(self, resourceType, currentFolder): 
    469                 # Map the virtual path to our local server 
    470                 serverPath = self.serverMapFolder(resourceType, currentFolder) 
    471                 # Open the folders / files node 
    472                 folders = """<Folders>""" 
    473                 files = """<Files>""" 
    474                 for someObject in os.listdir(serverPath): 
    475                         someObjectPath = os.path.join(serverPath, someObject) 
    476                         if os.path.isdir(someObjectPath): 
    477                                 folders += """<Folder name="%s" />""" % ( 
    478                                                 self.convertToXmlAttribute(someObject) 
    479                                                 ) 
    480                         elif os.path.isfile(someObjectPath): 
    481                                 size = os.path.getsize(someObjectPath) 
    482                                 files += """<File name="%s" size="%s" />""" % ( 
    483                                                 self.convertToXmlAttribute(someObject), 
    484                                                 os.path.getsize(someObjectPath) 
    485                                                 ) 
    486                 # Close the folders / files node 
    487                 folders += """</Folders>""" 
    488                 files += """</Files>""" 
    489                 # Return it 
    490                 s = folders + files 
    491                 return s 
    492  
    493         def getZopeFoldersAndFiles(self, resourceType, currentFolder): 
    494                 folders = self.getZopeFolders(resourceType, currentFolder) 
    495                 files = self.getZopeFiles(resourceType, currentFolder) 
    496                 s = folders + files 
    497                 return s 
    498  
    499         def getZopeFiles(self, resourceType, currentFolder): 
    500                 # Open the files node 
    501                 s = "" 
    502                 s += """<Files>""" 
    503                 zopeFolder = self.findZopeFolder(resourceType, currentFolder) 
    504                 for (name, o) in zopeFolder.objectItems(["File","Image"]): 
    505                         s += """<File name="%s" size="%s" />""" % ( 
    506                                         self.convertToXmlAttribute(name), 
    507                                         ((o.get_size() / 1024) + 1) 
    508                                         ) 
    509                 # Close the files node 
    510                 s += """</Files>""" 
    511                 return s 
    512  
    513         def findZopeFolder(self, resourceType, folderName): 
    514                 # returns the context of the resource / folder 
    515                 zopeFolder = self.getZopeUploadContext() 
    516                 folderName = self.removeFromStart(folderName, "/") 
    517                 folderName = self.removeFromEnd(folderName, "/") 
    518                 if (resourceType <> ""): 
    519                         try: 
    520                                 zopeFolder = zopeFolder[resourceType] 
    521                         except: 
    522                                 zopeFolder.manage_addProduct["OFSP"].manage_addFolder(id=resourceType, title=resourceType) 
    523                                 zopeFolder = zopeFolder[resourceType] 
    524                 if (folderName <> ""): 
    525                         folderNames = folderName.split("/") 
    526                         for folderName in folderNames: 
    527                                 zopeFolder = zopeFolder[folderName] 
    528                 return zopeFolder 
    529  
    530         """ 
    531         createFolder 
    532  
    533         Purpose: command to create a new folder 
    534         """ 
    535         def createFolder(self, resourceType, currentFolder): 
    536                 if (self.isZope()): 
    537                         return self.createZopeFolder(resourceType, currentFolder) 
    538                 else: 
    539                         return self.createNonZopeFolder(resourceType, currentFolder) 
    540  
    541         def createZopeFolder(self, resourceType, currentFolder): 
    542                 # Find out where we are 
    543                 zopeFolder = self.findZopeFolder(resourceType, currentFolder) 
    544                 errorNo = 0 
    545                 errorMsg = "" 
    546                 if self.request.has_key("NewFolderName"): 
    547                         newFolder = self.request.get("NewFolderName", None) 
    548                         zopeFolder.manage_addProduct["OFSP"].manage_addFolder(id=newFolder, title=newFolder) 
    549                 else: 
    550                         errorNo = 102 
    551                 error = """<Error number="%s" originalDescription="%s" />""" % ( 
    552                                 errorNo, 
    553                                 self.convertToXmlAttribute(errorMsg) 
    554                                 ) 
    555                 return error 
    556  
    557         def createNonZopeFolder(self, resourceType, currentFolder): 
    558                 errorNo = 0 
    559                 errorMsg = "" 
    560                 if self.request.has_key("NewFolderName"): 
    561                         newFolder = self.request.get("NewFolderName", None) 
    562                         currentFolderPath = self.serverMapFolder( 
    563                                         resourceType, 
    564                                         currentFolder 
    565                                         ) 
    566                         try: 
    567                                 newFolderPath = currentFolderPath + newFolder 
    568                                 errorMsg = self.createServerFolder(newFolderPath) 
    569                                 if (errorMsg is not None): 
    570                                         errorNo = 110 
    571                         except: 
    572                                 errorNo = 103 
    573                 else: