Я написал собственное файловое поле AudioFileField. Для этого я создал проверку, действительно ли файл является допустимым аудиофайлом. Чтобы сделать это, я использую инструмент командной строки sox, поэтому сначала мне нужно создать файл на диске. Поскольку sox зависит от суффикса для выполнения этой проверки, мне нужно было написать свой собственный TemporaryUploadedAudioFile, используя исходный суффикс (вместо .upload):
class TemporaryUploadedAudioFile(TemporaryUploadedFile):
"""
A file uploaded to a temporary location (i.e. stream-to-disk).
"""
def __init__(self, name, content_type, size, charset, suffix='.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)
Этот файл я использую для аудиопроверки в методе AudioFileForm to_python:
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
Теперь о странных вещах: это прекрасно работает на сервере разработки, но как только я переключаюсь на apache2/mod_wsgi, оно перестает работать. sox возвращает ошибку, говорящую мне, что файл отсутствует.
Я уже проверил права, tmp-location на рабочем сервере /tmp, там все права даны (777). Что еще здесь может происходить?