Trees | Indices | Help |
---|
|
1 # -*- Mode: Python; test-case-name: flumotion.test.test_component_providers -*- 2 # vi:si:et:sw=4:sts=4:ts=4 3 4 # Flumotion - a streaming media server 5 # Copyright (C) 2004,2005,2006,2007,2008,2009 Fluendo, S.L. 6 # Copyright (C) 2010,2011 Flumotion Services, S.A. 7 # All rights reserved. 8 # 9 # This file may be distributed and/or modified under the terms of 10 # the GNU Lesser General Public License version 2.1 as published by 11 # the Free Software Foundation. 12 # This file is distributed without any warranty; without even the implied 13 # warranty of merchantability or fitness for a particular purpose. 14 # See "LICENSE.LGPL" in the source distribution for more information. 15 # 16 # Headers in this file shall remain intact. 17 18 import os 19 import stat 20 import errno 21 22 from twisted.internet import defer 23 24 from flumotion.common import log 25 from flumotion.component.misc.httpserver import fileprovider, localpath 26 from flumotion.component.misc.httpserver.fileprovider import FileError 27 from flumotion.component.misc.httpserver.fileprovider import FileClosedError 28 29 # os.SEEK_SET is not definied in python 2.4 30 SEEK_SET = 0 31 32 LOG_CATEGORY = "fileprovider-local" 33 3436 """ 37 I am a plug that provide local files directly, 38 faking the file access is asynchronous. 39 """ 40 41 logcategory = LOG_CATEGORY 42 46 50 5358 59 64 6567 """ 68 I offer a fake asynchronous wrapper around a synchronous file. 69 I'm not thread-safe, I should only be used to read small blocks 70 from a local file system and I don't support cloning. 71 """ 72 73 logCategory = LOG_CATEGORY 74 75 _errorLookup = {errno.ENOENT: fileprovider.NotFoundError, 76 errno.ENOTDIR: fileprovider.NotFoundError, 77 errno.EISDIR: fileprovider.CannotOpenError, 78 errno.EACCES: fileprovider.AccessError} 79 80 # Overriding parent class properties to become attribute 81 mimeType = None 82 83 # Default values 84 _file = None 85 _info = None 8616888 self._path = path 89 self.mimeType = mimeType 90 try: 91 self._file = open(path, 'rb') 92 self.debug("%s opened [fd %5d]", self, self._file.fileno()) 93 except IOError, e: 94 cls = self._errorLookup.get(e[0], FileError) 95 raise cls("Failed to open file '%s': %s" % (path, str(e))) 96 try: 97 self._info = os.fstat(self._file.fileno()) 98 except OSError, e: 99 cls = self._errorLookup.get(e[0], FileError) 100 raise cls("Failed to stat file '%s': %s" % (path, str(e)))101 104106 if self._file is None: 107 raise FileClosedError("File closed") 108 # The size is not supposed to change over time 109 return self._info[stat.ST_SIZE]110112 if self._file is None: 113 raise FileClosedError("File closed") 114 # The modification time is not supposed to change over time 115 return self._info[stat.ST_MTIME]116118 if self._file is None: 119 raise FileClosedError("File closed") 120 try: 121 return self._file.tell() 122 except IOError, e: 123 cls = self._errorLookup.get(e[0], FileError) 124 raise cls("Failed to tell position in file '%s': %s" 125 % (self._path, str(e)))126128 if self._file is None: 129 raise FileClosedError("File closed") 130 try: 131 self._file.seek(offset, SEEK_SET) 132 except IOError, e: 133 cls = self._errorLookup.get(e[0], FileError) 134 raise cls("Failed to seek in file '%s': %s" 135 % (self._path, str(e)))136138 if self._file is None: 139 raise FileClosedError("File closed") 140 try: 141 data = self._file.read(size) 142 return defer.succeed(data) 143 except IOError, e: 144 cls = self._errorLookup.get(e[0], FileError) 145 return defer.fail(cls("Failed to read data from %s: %s" 146 % (self._path, str(e)))) 147 except: 148 return defer.fail()149151 if self._file is not None: 152 try: 153 try: 154 self._file.close() 155 finally: 156 self._file = None 157 self._info = None 158 except IOError, e: 159 cls = self._errorLookup.get(e[0], FileError) 160 raise cls("Failed to close file '%s': %s" 161 % (self._path, str(e)))162164 self.close()165
Trees | Indices | Help |
---|
Generated by Epydoc 3.0.1 on Tue Aug 13 06:17:13 2013 | http://epydoc.sourceforge.net |