Created temporary file is not accessable in production
I have written a custom filefield AudioFileField. For this i created a check if a file really is a valid audiofile. To be able to do that, i use the sox commandlinetool, so i have to create a file on disk first. As sox depends on the suffix to do that validation, i needed to write my own TemporaryUploadedAudioFile, using the original suffix (instead of .upload):
class TemporaryUploadedAudioFile(TemporaryUploadedFile):
"""
A file uploaded to a temporary location (i.e. stream-to-disk).
"""
def __init__(self, name, content_type, size, charset, suffi开发者_如何学Cx='.upload'):
"""
The init method overrides the name creation to allow passing
an extension, so that sox is able to test the file
"""
if settings.FILE_UPLOAD_TEMP_DIR:
file = tempfile.NamedTemporaryFile(suffix=suffix,
dir=settings.FILE_UPLOAD_TEMP_DIR)
else:
file = tempfile.NamedTemporaryFile(suffix=suffix)
super(TemporaryUploadedFile, self).__init__(file, name, content_type, size, charset)
That file i use to do the audiovalidation in the AudioFileForm to_python method:
def to_python(self, data):
"""
checks that the file-upload field data contains a valid audio file.
"""
f = super(AudioFileForm, self).to_python(data)
if f is None:
return None
# get the file suffix, sox needs this to be able to test the file
suffix = os.path.splitext(data.name)[1]
# We need to get a temporary file for sox. Even if we allready have a temporary
# file, we have to create a new one ending with the correct suffix
file = TemporaryUploadedAudioFile(data.name, data.content_type, 0, data.charset,suffix = suffix)
with open(file.temporary_file_path(), 'w') as f:
f.write(data.read())
# Do the validation of the audiofile.
filetype=subprocess.Popen([sox,'--i','-t','%s'%file.temporary_file_path()], shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
filetype=filetype.communicate()[0]
filetype=filetype.replace('\n','')
if not filetype in ['wav','aiff','flac']:
raise forms.ValidationError('Not a valid audiofile (valid are: aif, flac & wav | 16 or 24 bit | 44.1 or 48 kHz)')
return data
Now to the strange things happening: this works like a charm on the development server, but as soon as i switch to apache2/mod_wsgi it stops working. sox returns an error telling me that the file is missing.
I have allready checked rights, tmp-location on the production server is /tmp, all rights are granted there (777). What else could be happening here?
mod-wsgi is known to have problems with standard output and this subprocess thingy with django. There are already lot of questions answered about this in stackoverflow.com.
A quick Google search should help you!
精彩评论