def _add_new_media_file(media, original_filename, file): # FIXME: I think this will raise a KeyError if the uploaded # file doesn't have an extension. file_ext = os.path.splitext(original_filename)[1].lower()[1:] # set the file paths depending on the file type media_file = MediaFile() media_file.display_name = original_filename media_file.container = guess_container_format(file_ext) media_file.type = guess_media_type(media_file.container) # Small files are stored in memory and do not have a tmp file w/ fileno if hasattr(file, 'fileno'): media_file.size = os.fstat(file.fileno())[6] else: # The file may contain multi-byte characters, so we must seek instead of count chars file.seek(0, os.SEEK_END) media_file.size = file.tell() file.seek(0) # update media relations media.files.append(media_file) # add the media file (and its media, if new) to the database to get IDs DBSession.add(media_file) DBSession.flush() # copy the file to its permanent location file_name = '%d_%d_%s.%s' % (media.id, media_file.id, media.slug, file_ext) file_url = _store_media_file(file, file_name) media_file.file_name = file_name return media_file
def _add_new_media_file(media, original_filename, file): # FIXME: I think this will raise a KeyError if the uploaded # file doesn't have an extension. file_ext = os.path.splitext(original_filename)[1].lower()[1:] # set the file paths depending on the file type media_file = MediaFile() media_file.type = file_ext media_file.url = 'dummy_url' # model requires that url not NULL media_file.is_original = True media_file.enable_player = media_file.is_playable media_file.enable_feed = not media_file.is_embeddable media_file.size = os.fstat(file.fileno())[6] # update media relations media.files.append(media_file) # add the media file (and its media, if new) to the database to get IDs DBSession.add(media_file) DBSession.flush() # copy the file to its permanent location file_name = '%d_%d_%s.%s' % (media.id, media_file.id, media.slug, file_ext) file_url = _store_media_file(file, file_name) media_file.url = file_url return media_file
def prepareForUpload(self, environ, media_id, content_type, filename, filesize, meta=None, **kwargs): STORAGE_ENGINE = getStorageEngine() log.info("{self}.prepareForUpload({media_id},{content_type},{filename},{filesize})".format(**vars())) if not meta: meta = {} else: try: meta = json.loads(meta) except Exception as e: return {"success": False, "message": "Invalid JSON object given for `meta`"} media = fetch_row(Media, media_id) mediaFile = MediaFile() mediaFile.storage = STORAGE_ENGINE mediaFile.media = media mediaFile.media_id = media_id mediaFile.type = content_type mediaFile.meta = meta media.type = content_type mediaFile.display_name = filename mediaFile.size = filesize media.files.append(mediaFile) DBSession.add(media) DBSession.add(mediaFile) DBSession.flush() # This is to ensure that we don't allow any uploads that haven't been prepared for with prepareForUpload token = "".join(random.choice(string.ascii_uppercase + string.digits) for x in range(13)) upload_tokens[str(mediaFile.id)] = token return { "success": True, "id": mediaFile.id, "upload_url": "http://{host}{path}".format( host=environ["HTTP_HOST"], path=url_for( controller="upload_api/api/uploader", action="uploadFile", media_id=media_id, file_id=mediaFile.id ), ), "upload_headers": { "Content-Type": "application/octet-stream", "Cache-Control": "none", "X-File-Name": filename, "X-Upload-Token": token, }, "postprocess_url": "http://{host}{path}".format( host=environ["HTTP_HOST"], path=url_for( controller="upload_api/api/uploader", action="postprocessFile", media_id=media_id, file_id=mediaFile.id, ), ), }
def add_new_media_file(media, file=None, url=None): """Create a MediaFile instance from the given file or URL. This function MAY modify the given media object. :type media: :class:`~mediacore.model.media.Media` instance :param media: The media object that this file or URL will belong to. :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. :rtype: :class:`~mediacore.model.media.MediaFile` :returns: A newly created media file instance. :raises StorageError: If the input file or URL cannot be stored with any of the registered storage engines. """ engines = DBSession.query(StorageEngine)\ .filter(StorageEngine.enabled == True)\ .all() sorted_engines = list(sort_engines(engines)) for engine in sorted_engines: try: meta = engine.parse(file=file, url=url) log.debug('Engine %r returned meta %r', engine, meta) break except UnsuitableEngineError: log.debug('Engine %r unsuitable for %r/%r', engine, file, url) continue else: raise StorageError(_('Unusable file or URL provided.'), None, None) mf = MediaFile() mf.storage = engine mf.media = media mf.type = meta['type'] mf.display_name = meta.get('display_name', default_display_name(file, url)) mf.unique_id = meta.get('unique_id', None) mf.container = meta.get('container', None) mf.size = meta.get('size', None) mf.bitrate = meta.get('bitrate', None) mf.width = meta.get('width', None) mf.height = meta.get('height', None) media.files.append(mf) DBSession.flush() unique_id = engine.store(media_file=mf, file=file, url=url, meta=meta) if unique_id: mf.unique_id = unique_id elif not mf.unique_id: raise StorageError('Engine %r returned no unique ID.', engine) if not media.duration and meta.get('duration', 0): media.duration = meta['duration'] if not media.description and meta.get('description'): media.description = clean_xhtml(meta['description']) if not media.title: media.title = meta.get('title', None) or mf.display_name if media.type is None: media.type = mf.type if ('thumbnail_url' in meta or 'thumbnail_file' in meta) \ and (not has_thumbs(media) or has_default_thumbs(media)): thumb_file = meta.get('thumbnail_file', None) if thumb_file is not None: thumb_filename = thumb_file.filename else: thumb_url = meta['thumbnail_url'] thumb_filename = os.path.basename(thumb_url) # Download the image to a buffer and wrap it as a file-like object try: temp_img = urlopen(thumb_url) thumb_file = StringIO(temp_img.read()) temp_img.close() except URLError, e: log.exception(e) if thumb_file is not None: create_thumbs_for(media, thumb_file, thumb_filename) thumb_file.close()
def prepareForUpload(self, environ, media_id, content_type, filename, filesize, meta=None, **kwargs): STORAGE_ENGINE = getStorageEngine() log.info( "prepareForUpload({media_id},{content_type},{filename},{filesize})" .format(**vars())) if not meta: meta = {} else: try: meta = json.loads(meta) except Exception as e: return { "success": False, "message": "Invalid JSON object given for `meta`" } media = fetch_row(Media, media_id) mediaFile = MediaFile() mediaFile.storage = STORAGE_ENGINE mediaFile.media = media mediaFile.media_id = media_id mediaFile.type = content_type mediaFile.meta = meta media.type = content_type mediaFile.display_name = filename mediaFile.size = filesize media.files.append(mediaFile) DBSession.add(media) DBSession.add(mediaFile) DBSession.flush() # This is to ensure that we don't allow any uploads that haven't been prepared for with prepareForUpload token = ''.join( random.choice(string.ascii_uppercase + string.digits) for x in range(13)) upload_tokens[str(mediaFile.id)] = token return { "success": True, "id": mediaFile.id, "upload_url": "http://{host}{path}".format( host=environ['HTTP_HOST'], path=url_for(controller='upload_api/api/uploader', action='uploadFile', media_id=media_id, file_id=mediaFile.id)), "upload_headers": { "Content-Type": "application/octet-stream", "Cache-Control": "none", "X-File-Name": filename, "X-Upload-Token": token }, "postprocess_url": "http://{host}{path}".format( host=environ['HTTP_HOST'], path=url_for(controller='upload_api/api/uploader', action='postprocessFile', media_id=media_id, file_id=mediaFile.id)) }