def store(self, media_file, file=None, url=None, meta=None): """Store the given file or URL and return a unique identifier for it. :type media_file: :class:`~mediacore.model.media.MediaFile` :param media_file: The associated media file object. :type file: :class:`cgi.FieldStorage` or None :param file: A freshly uploaded file object. :type url: unicode or None :param url: A remote URL string. :type meta: dict :param meta: The metadata returned by :meth:`parse`. :rtype: unicode or None :returns: The unique ID string. Return None if not generating it here. """ file_name = safe_file_name(media_file, file.filename) file_path = self._get_path(file_name) temp_file = file.file temp_file.seek(0) permanent_file = open(file_path, 'wb') copyfileobj(temp_file, permanent_file) temp_file.close() permanent_file.close() return file_name
def prepare_for_upload(self, media_file, content_type, filename, filesize): if content_type != 'multipart/form-data': raise StorageError("Cannot direct upload without using multipart " "form data and we haven't implemented a file " "upload pass through.") media_file.storage = self media_file.unique_id = self._get_path(safe_file_name(media_file, filename)) access_key = self._data['aws_access_key'].encode('utf-8') secret_key = self._data['aws_secret_key'].encode('utf-8') bucket_name = self._data['s3_bucket_name'].encode('utf-8') acl = 'public-read' mimetype = media_file.mimetype success_action_status = 201 # Return XML instead of redirecting expiration = (datetime.utcnow() + timedelta(hours=4))\ .strftime('%Y-%m-%dT%H:%m:%S.000Z') policy_obj = { 'expiration': expiration, 'conditions': [ {'bucket': bucket_name}, # Prevent tampering with our POST data below {'key': media_file.unique_id}, {'acl': acl}, {'success_action_status': str(success_action_status)}, {'Content-Type': mimetype}, # Allow (and require) the extra Filename var added by Flash ['starts-with', '$Filename', ''], # Enforce the filesize we've been given, leaving some extra # room for the rest of the form data ['content-length-range', filesize, filesize + 1048576], ] } policy = b64encode(simplejson.dumps(policy_obj)).encode('utf-8') signature = b64encode(hmac.new(secret_key, policy, sha1).digest()) post_data = { 'AWSAccessKeyId': access_key, 'key': media_file.unique_id, 'acl': acl, 'success_action_status': success_action_status, 'Policy': policy, 'Signature': signature, 'Content-Type': mimetype, } return { 'upload_url': self.bucket_url, 'extra_post_data': post_data, 'file_post_var_name': 'file', }
def store(self, media_file, file=None, url=None, meta=None): """Store the given file or URL and return a unique identifier for it. :type media_file: :class:`~mediacore.model.media.MediaFile` :param media_file: The associated media file object. :type file: :class:`cgi.FieldStorage` or None :param file: A freshly uploaded file object. :type url: unicode or None :param url: A remote URL string. :type meta: dict :param meta: The metadata returned by :meth:`parse`. :rtype: unicode or None :returns: The unique ID string. Return None if not generating it here. :raises FTPUploadError: If storing the file fails. """ file_name = safe_file_name(media_file, file.filename) file_url = os.path.join(self._data[HTTP_DOWNLOAD_URI], file_name) upload_dir = self._data[FTP_UPLOAD_DIR] stor_cmd = 'STOR ' + file_name ftp = self._connect() try: if upload_dir: ftp.cwd(upload_dir) ftp.storbinary(stor_cmd, file.file) # Raise a FTPUploadError if the file integrity check fails # TODO: Delete the file if the integrity check fails self._verify_upload_integrity(file.file, file_url) ftp.quit() except ftp_errors, e: log.exception(e) ftp.quit() msg = _('Could not upload the file from your FTP server: %s')\ % e.message raise FTPUploadError(msg, None, None)