Я написал собственный файл 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)
Этот файл, который я использую для аудиовалидации в методе to_python AudioFileForm:
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). Что еще здесь может происходить?