Exemple #1
0
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
Exemple #2
0
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()
Exemple #5
0
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))
        }