Exemple #1
0
 def __init__(self, fileaccessor=None, filehandler=None, segments=None):
     log.debug('formish.FileResource: initialising FileResource')
     if fileaccessor is None:
         self.fileaccessor = FileAccessor()
     else:
         self.fileaccessor = fileaccessor
     if filehandler is None:
         self.filehandler = TempFileHandler()
     else:
         self.filehandler = filehandler
     self.segments = segments
Exemple #2
0
class FileResource(resource.Resource):
    """
    A simple file serving utility
    """

    def __init__(self, fileaccessor=None, filehandler=None, segments=None):
        log.debug('formish.FileResource: initialising FileResource')
        if fileaccessor is None:
            self.fileaccessor = FileAccessor()
        else:
            self.fileaccessor = fileaccessor
        if filehandler is None:
            self.filehandler = TempFileHandler()
        else:
            self.filehandler = filehandler
        self.segments = segments

    @resource.child(resource.any)
    def child(self, request, segments):
        return FileResource(fileaccessor=self.fileaccessor, filehandler=self.filehandler, segments=segments), []


    def __call__(self, request):
        log.debug('formish.FileResource: in File Resource')
        if not self.segments:    
            return None

        # This is our input filepath
        requested_filepath = self._get_requested_filepath()
        log.debug('formish.FileResource: requested_filepath=%s',requested_filepath)
 
        # Get the raw cache file path and mtime
        raw_cached_filepath = self._get_cachefile_path(requested_filepath)
        log.debug('formish.FileResource: raw_cached_filepath=%s',raw_cached_filepath)
        raw_cached_mtime = self._get_file_mtime(raw_cached_filepath)

        # Check to see if fa and temp exist
        tempfile_path = self._get_tempfile_path(requested_filepath)
        log.debug('formish.FileResource: tempfile_path=%s',tempfile_path)

        # work out which has changed most recently (if either is newer than cache)
        fileaccessor_mtime = self._get_fileaccessor_mtime(requested_filepath)
        tempfile_mtime = self._get_file_mtime(tempfile_path)
        source_mtime = max(fileaccessor_mtime, tempfile_mtime)

        # unfound files return a 1970 timestamp for simplicity, if we don't have files newer than 1971, bugout
        if source_mtime < datetime(1971,1,1,0,0):
            return None

        if source_mtime > raw_cached_mtime:
            if fileaccessor_mtime > tempfile_mtime:
                log.debug('formish.FileResource: fileaccessor resource is newer. rebuild raw cache')
                filedata = self.fileaccessor.get_file(requested_filepath)
                mimetype = self.fileaccessor.get_mimetype(requested_filepath)
            else:
                log.debug('formish.FileResource: tempfile resource is newer. rebuilding raw cache')
                filedata = open(tempfile_path).read()
                mimetype = get_mimetype(tempfile_path)
            open(raw_cached_filepath,'w').write(filedata)
        else:
            log.debug('formish.FileResource: raw cache file is valid')
            mimetype = get_mimetype(raw_cached_filepath)

        # If we're trying to resize, check mtime on resized_cache
        size_suffix = self._get_size_suffix(request)
        if size_suffix:
            log.debug('formish.FileResource: size_suffix=%s',size_suffix)
            cached_filepath = self._get_cachefile_path(requested_filepath, size_suffix)
            cached_mtime = self._get_file_mtime(cached_filepath)
            log.debug('formish.FileResource: cached_filepath=%s',cached_filepath)

            if not os.path.exists(cached_filepath) or source_mtime > cached_mtime:
                width, height = get_size_from_dict(request.GET)
                log.debug('formish.FileResource: cache invalid. resizing image')
                resize_image(raw_cached_filepath, cached_filepath, width, height)
        else:
            log.debug('formish.FileResource: resized cache file is valid.')
            cached_filepath = raw_cached_filepath

        return http.ok([('content-type', mimetype )], open(cached_filepath, 'rb').read())
         

    def _get_requested_suffix(self):
        if '.' in self.segments[-1]:
            return self.segments[-1].split('.')[-1]
        return ''

    def _get_requested_filepath(self):
        return '/'.join(self.segments)

    def _get_cachefile_path(self,filepath,size_suffix=''):
        return 'cache/%s%s'% (filepath.replace('/','-'),size_suffix)

    def _get_tempfile_path(self, filepath):
        return self.filehandler.get_path_for_file(urllib.unquote_plus(filepath))

    def _get_file_mtime(self, filepath,size_suffix=''):
        if os.path.exists(filepath):
            return datetime.utcfromtimestamp(os.path.getmtime(filepath))
        return datetime(1970, 1, 1, 0, 0)

    def _get_fileaccessor_mtime(self, filepath):
        try:
            return self.fileaccessor.get_mtime(filepath)
        except KeyError:
            return datetime(1970, 1, 1, 0, 0)

    def _get_size_suffix(self, request):
        log.debug('formish.FileResource: request.GET args=%s',request.GET)
        width, height = get_size_from_dict(request.GET)
        if height or width:
            return '-%sx%s'% (width, height)
        return ''