Changeset 7727


Ignore:
Timestamp:
12/11/10 16:56:54 (7 years ago)
Author:
pjkersha
Message:

0.4.0 Release

  • Adds trailing slash to sub-dir links in dir listing.
  • Filled out epydoc
Location:
ceda_http_fileserver/trunk/ceda_http_fileserver
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • ceda_http_fileserver/trunk/ceda_http_fileserver/ceda/server/wsgi/fileserver/app.py

    r7040 r7727  
    2121#   See the License for the specific language governing permissions and 
    2222#   limitations under the License. 
    23  
    24 from urlparse import urlparse 
    2523import httplib 
    2624import urllib 
     
    197195 
    198196class FileServerApp(object): 
    199     """Application to serve static content""" 
     197    """Application to serve static content 
     198     
     199    @cvar PARAM_PREFIX: default configuration parameters prefix 
     200    @type PARAM_PREFIX: string 
     201    @cvar FILE_SYS_ROOT_PATH_OPTNAME: option name for setting the file system 
     202    root from which files will be exposed by this service 
     203    @type FILE_SYS_ROOT_PATH_OPTNAME: string 
     204    @cvar DEFAULT_READ_BLK_SIZE: default block size for read operations 
     205    @type DEFAULT_READ_BLK_SIZE: int 
     206    @cvar DEFAULT_WRITE_BLK_SIZE: default block size for write operations 
     207    @type DEFAULT_WRITE_BLK_SIZE: int 
     208    @cvar DEFAULT_CONTENT_TYPE: default HTML content type for responses 
     209    @type DEFAULT_CONTENT_TYPE: string 
     210    @cvar DEFAULT_MOUNT_POINT: default URI path to mount the application 
     211    @type DEFAULT_MOUNT_POINT: string 
     212    @cvar DEFAULT_HTTP_METHOD_MAP: dictionary maps HTTP method string keys to 
     213    methods in this class 
     214    @type DEFAULT_HTTP_METHOD_MAP: dict 
     215    @cvar FILE_ACCESS_ERROR_MAP: Map HTTP status string to a given file system  
     216    file access error 
     217    @type FILE_ACCESS_ERROR_MAP: dict 
     218    """ 
    200219    PARAM_PREFIX = 'fileserver.' 
    201220    FILE_SYS_ROOT_PATH_OPTNAME = 'fileSysRootPath' 
     
    208227    statusCode2Msg = staticmethod(_statusCode2Msg) 
    209228     
    210     # Map HTTP status string to a given file system file access error 
    211229    FILE_ACCESS_ERROR_MAP = { 
    212230         errno.ENOENT: _statusCode2Msg(httplib.NOT_FOUND), 
     
    231249                 fileFilterRegEx=None, 
    232250                 mimeTypesFilePath=None): 
    233          
    234         # Initialise all attributes here 
     251        '''Initialise all attributes here 
     252         
     253        @param fileSysRootPath: file system root from which files will be  
     254        exposed by this service 
     255        @type fileSysRootPath: string 
     256        @param mountPoint: URI path to mount the application 
     257        @type mountPoint: string 
     258        @param readBlkSize: block size for read operations 
     259        @type mountPoint: string 
     260        @param writeBlkSize: block size for write operations 
     261        @type writeBlkSize: int 
     262        @param fileFilterRegEx: 
     263        @type fileFilterRegEx: string / None type 
     264        @param mimeTypesFilePath: file path for file defining the MIME types 
     265        for files served by the application 
     266        @type mimeTypesFilePath: string / None type 
     267        ''' 
     268         
    235269        self.__readBlkSize = None 
    236270        self.__writeBlkSize = None 
     
    398432        """Translate URI path to local file system path and map correct  
    399433        callback from the HTTP request method 
     434         
     435        @param environ: environment dict 
     436        @type environ: dict-like object 
     437        @param start_response: WSGI start response function 
     438        @type start_response: function/callable 
     439        @return: response - file or directory listing 
     440        @rtype: iterable type  
    400441        """ 
    401442        if self.mountPoint: 
     
    440481         
    441482    def do_get(self, fileSysSubDir, environ, start_response): 
    442         """HTTP GET callback""" 
     483        """HTTP GET callback 
     484         
     485        @param fileSysSubDir: sub-directory from file system root mount point 
     486        to do GET for. 
     487        @type fileSysSubDir: string 
     488        @param environ: environment dict 
     489        @type environ: dict-like object 
     490        @param start_response: WSGI start response function 
     491        @type start_response: function/callable 
     492        @return: response - file or directory listing 
     493        @rtype: iterable type  
     494        """ 
    443495        filePath = os.path.join(self.fileSysRoot, fileSysSubDir) 
    444496         
     
    483535            # a generic regular expression for filtering out both  
    484536            # sub-directories - see above - and file names as here 
    485             lines = [ 
    486                 '<a href="%s%s/%s">%s</a>' %  
    487                 (scriptName, 
    488                  mountPoint, 
    489                  urllib.pathname2url(os.path.join(fileSysSubDir, filename)), 
    490                  filename)  
    491                 for filename in dirContents if _allowFile('/' + filename) 
    492             ] 
     537            lines = [] 
     538            for filename in dirContents: 
     539                if _allowFile('/' + filename): 
     540                    absFilePath = os.path.join(filePath, filename) 
     541                    if os.path.isdir(absFilePath): 
     542                        filename += '/' 
     543                         
     544                    uri = urllib.pathname2url(os.path.join(fileSysSubDir,  
     545                                                           filename)) 
     546                     
     547                    line = '<a href="%s%s/%s">%s</a>' % (scriptName, 
     548                                                         mountPoint, 
     549                                                         uri, 
     550                                                         filename) 
     551                    lines.append(line) 
    493552 
    494553            response = ('<html><head/><body>%s</body></html>' %  
     
    563622         
    564623    def do_put(self, fileSysSubDir, environ, start_response): 
    565         """HTTP PUT callback""" 
     624        """HTTP PUT callback 
     625         
     626        @param environ: environment dict 
     627        @type environ: dict-like object 
     628        @param start_response: WSGI start response function 
     629        @type start_response: function/callable 
     630        @return: response 
     631        @rtype: iterable type  
     632        """ 
    566633        try: 
    567634            filePath = os.path.join(self.fileSysRoot, fileSysSubDir) 
     
    590657            inputBlk = inputStream.read(length) 
    591658            fileObj.write(inputBlk) 
    592  
     659             
     660        return [] 
     661 
     662    DEFAULT_HTTP_METHOD_MAP = { 
     663        'GET':          do_get,  
     664        'PUT':          do_put,  
     665    } 
     666     
    593667    @classmethod 
    594668    def mapFileAccessError2HttpStatus(cls, errno): 
    595         """Map file access error to a standard HTTP response status message""" 
     669        """Map file access error to a standard HTTP response status message 
     670         
     671        @param errno: error number returned fcrom file system 
     672        @type errno: int 
     673        @return: message string corresponding to error number 
     674        @rtype: string 
     675        """ 
    596676        return cls.FILE_ACCESS_ERROR_MAP.get(errno,  
    597677                            cls.statusCode2Msg(httplib.INTERNAL_SERVER_ERROR)) 
    598678                                                         
    599679    def getContentType(self, path_info): 
    600         """Make a best guess at the content type""" 
     680        """Make a best guess at the content type for the given path 
     681         
     682        @param path_info: path to guess type for 
     683        @type path_info: string 
     684        @return: HTML content type for the given path 
     685        @rtype: string 
     686        """ 
    601687        contentType = self.mimeTypes.guess_type(path_info)[0] 
    602688        if contentType is not None: 
     
    606692             
    607693    def __call__(self, environ, start_response): 
     694        """Make objects of this class callable to fit WSGI signature 
     695         
     696        @param environ: environment dict 
     697        @type environ: dict-like object 
     698        @param start_response: WSGI start response function 
     699        @type start_response: function/callable 
     700        @return: response 
     701        @rtype: iterable type  
     702        """ 
    608703        return self.handler(environ, start_response) 
    609          
    610     DEFAULT_HTTP_METHOD_MAP = { 
    611         'GET':          do_get,  
    612         'PUT':          do_put,  
    613     } 
     704 
  • ceda_http_fileserver/trunk/ceda_http_fileserver/setup.py

    r7675 r7727  
    2020setup( 
    2121    name =              'ceda_http_file_server', 
    22     version =           '0.3.0', 
     22    version =           '0.4.0', 
    2323    description =       'CEDA HTTP File Server WSGI Application', 
    2424    long_description =  '''\ 
Note: See TracChangeset for help on using the changeset viewer.