示例#1
0
    def parse(self, file=None, url=None):
        """Return metadata for the given file or raise an error.

        :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: dict
        :returns: Any extracted metadata.
        :raises UnsuitableEngineError: If file information cannot be parsed.

        """
        if file is None:
            raise UnsuitableEngineError

        filename = os.path.basename(file.filename)
        name, ext = os.path.splitext(filename)
        ext = ext.lstrip('.').lower()
        container = guess_container_format(ext)

        return {
            'type': guess_media_type(container),
            'container': container,
            'display_name': u'%s.%s' % (name, container or ext),
            'size': get_file_size(file.file),
        }
示例#2
0
文件: upload.py 项目: 86me/mediacore
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
示例#3
0
    def parse(self, file=None, url=None):
        """Return metadata for the given file or raise an error.

        :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: dict
        :returns: Any extracted metadata.
        :raises UnsuitableEngineError: If file information cannot be parsed.

        """
        if file is None:
            raise UnsuitableEngineError

        filename = os.path.basename(file.filename)
        name, ext = os.path.splitext(filename)
        ext = ext.lstrip('.').lower()
        container = guess_container_format(ext)

        return {
            'type': guess_media_type(container),
            'container': container,
            'display_name': u'%s.%s' % (name, container or ext),
            'size': get_file_size(file.file),
        }
示例#4
0
    def parse(self, file=None, url=None):
        """Return metadata for the given file or raise an error.

        :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: dict
        :returns: Any extracted metadata.
        :raises UnsuitableEngineError: If file information cannot be parsed.

        """
        if url is None:
            raise UnsuitableEngineError

        if url.startswith('rtmp://'):
            known_server_uris = self._data.setdefault(RTMP_SERVER_URIS, ())

            if RTMP_URI_DIVIDER in url:
                # Allow the user to explicitly mark the server/file separation
                parts = url.split(RTMP_URI_DIVIDER)
                server_uri = parts[0].rstrip('/')
                file_uri = ''.join(parts[1:]).lstrip('/')
                if server_uri not in known_server_uris:
                    known_server_uris.append(server_uri)
            else:
                # Get the rtmp server from our list of known servers or fail
                for server_uri in known_server_uris:
                    if url.startswith(server_uri):
                        file_uri = url[len(server_uri.rstrip('/') + '/'):]
                        break
                else:
                    raise UserStorageError(
                        _('This RTMP server has not been configured. Add it '
                          'by going to Settings > Storage Engines > '
                          'Remote URLs.'))
            unique_id = ''.join((server_uri, RTMP_URI_DIVIDER, file_uri))
        else:
            unique_id = url

        filename = os.path.basename(url)
        name, ext = os.path.splitext(filename)
        ext = ext.lstrip('.').lower()

        container = guess_container_format(ext)

        # FIXME: Replace guess_container_format with something that takes
        #        into consideration the supported formats of all the custom
        #        players that may be installed.
        #        if not container or container == 'unknown':
        #            raise UnsuitableEngineError

        return {
            'type': guess_media_type(ext),
            'container': container,
            'display_name': u'%s.%s' % (name, container or ext),
            'unique_id': unique_id,
        }
    def parse(self, file=None, url=None):
        """Return metadata for the given file or raise an error.

        :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: dict
        :returns: Any extracted metadata.
        :raises UnsuitableEngineError: If file information cannot be parsed.

        """
        if url is None:
            raise UnsuitableEngineError

        if url.startswith('rtmp://'):
            known_server_uris = self._data.setdefault(RTMP_SERVER_URIS, ())

            if RTMP_URI_DIVIDER in url:
                # Allow the user to explicitly mark the server/file separation
                parts = url.split(RTMP_URI_DIVIDER)
                server_uri = parts[0].rstrip('/')
                file_uri = ''.join(parts[1:]).lstrip('/')
                if server_uri not in known_server_uris:
                    known_server_uris.append(server_uri)
            else:
                # Get the rtmp server from our list of known servers or fail
                for server_uri in known_server_uris:
                    if url.startswith(server_uri):
                        file_uri = url[len(server_uri.rstrip('/') + '/'):]
                        break
                else:
                    raise UserStorageError(
                        _('This RTMP server has not been configured. Add it '
                          'by going to Settings > Storage Engines > '
                          'Remote URLs.'))
            unique_id = ''.join((server_uri, RTMP_URI_DIVIDER, file_uri))
        else:
            unique_id = url

        filename = os.path.basename(url)
        name, ext = os.path.splitext(filename)
        ext = unicode(ext).lstrip('.').lower()

        container = guess_container_format(ext)

        # FIXME: Replace guess_container_format with something that takes
        #        into consideration the supported formats of all the custom
        #        players that may be installed.
#        if not container or container == 'unknown':
#            raise UnsuitableEngineError

        return {
            'type': guess_media_type(ext),
            'container': container,
            'display_name': u'%s.%s' % (name, container or ext),
            'unique_id': unique_id,
        }
示例#6
0
def base_ext_container_from_uri(uri):
    """Returns a 3-tuple of strings:

    - Base of the filename (without extension)
    - Normalized file extension (without preceding dot)
    - Best-guess container format.

    Raises a formencode.Invalid exception if a useful container isn't found.
    """
    name, file_ext = os.path.splitext(uri)
    ext = file_ext[1:].lower()
    container = guess_container_format(ext)
    if container is None:
        error_msg = _('File extension "%s" is not supported.') % file_ext
        raise formencode.Invalid(error_msg, None, None)
    return name, ext, container
示例#7
0
    def _to_python(self, value, state):
        if value == '':
            return value

        embed = parse_embed_url(value)
        if embed:
            return value

        ext = os.path.splitext(value)[1].lower()[1:]
        container = guess_container_format(ext)
        if container in accepted_extensions():
            return value

        raise formencode.Invalid(
            "This isn't a valid YouTube, Google Video, Vimeo or direct link.",
            value, state
        )
示例#8
0
    def _save_media_obj(self, name, email, title, description, tags, file, url):
        # create our media object as a status-less placeholder initially
        media_obj = Media()
        media_obj.author = Author(name, email)
        media_obj.title = title
        media_obj.slug = get_available_slug(Media, title)
        media_obj.description = description
        media_obj.notes = fetch_setting('wording_additional_notes')
        media_obj.set_tags(tags)

        # Create a media object, add it to the media_obj, and store the file permanently.
        if file is not None:
            media_file = _add_new_media_file(media_obj, file.filename, file.file)
        else:
            media_file = MediaFile()
            url = unicode(url)
            embed = parse_embed_url(url)
            if embed:
                media_file.type = embed['type']
                media_file.container = embed['container']
                media_file.embed = embed['id']
                media_file.display_name = '%s ID: %s' % \
                    (embed['container'].capitalize(), media_file.embed)
            else:
                # Check for types we can play ourselves
                ext = os.path.splitext(url)[1].lower()[1:]
                container = guess_container_format(ext)
                if container in accepted_extensions():
                    media_file.type = guess_media_type(container)
                    media_file.container = container
                    media_file.url = url
                    media_file.display_name = os.path.basename(url)
                else:
                    # Trigger a validation error on the whole form.
                    raise formencode.Invalid('Please specify a URL or upload a file below.', None, None)
            media_obj.files.append(media_file)

        # Add the final changes.
        media_obj.update_status()
        DBSession.add(media_obj)
        DBSession.flush()

        create_default_thumbs_for(media_obj)

        return media_obj
示例#9
0
    def parse(self, file=None, url=None):
        """Return metadata for the given file or raise an error.

        :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: dict
        :returns: Any extracted metadata.
        :raises UnsuitableEngineError: If file information cannot be parsed.

        """
        if not url or not url.startswith(PANDA_URL_PREFIX):
            raise UnsuitableEngineError()

        offset = len(PANDA_URL_PREFIX)
        # 'd' is the dict representing a Panda encoding or video
        # with an extra key: 'display_name'
        d = simplejson.loads(url[offset:])

        # MediaCore uses extensions without prepended .
        ext = d['extname'].lstrip('.').lower()

        # XXX: Panda doesn't actually populate these fields yet.
        ba = d.get('audio_bitrate', None) or 0
        bv = d.get('video_bitrate', None) or 0
        bitrate = (ba + bv) or None

        return {
            'unique_id': d['id'] + d['extname'],
            'container': guess_container_format(ext),
            'display_name': d['display_name'],
            'type': VIDEO, # only video files get panda encoded, so it's video Q.E.D.
            'height': d['height'],
            'width': d['width'],
            'size': d['file_size'],
            'bitrate': bitrate,
            'duration': d['duration'] / 1000.0,
            'thumbnail_url': "%s%s_1.jpg" % (self.base_urls[0][1], d['id']),
        }
示例#10
0
文件: media.py 项目: 86me/mediacore
    def add_file(self, id, file=None, url=None, **kwargs):
        """Save action for the :class:`~mediacore.forms.admin.media.AddFileForm`.

        Creates a new :class:`~mediacore.model.media.MediaFile` from the
        uploaded file or the local or remote URL.

        :param id: Media ID. If ``"new"`` a new Media stub is created with
            :func:`~mediacore.model.media.create_media_stub`.
        :type id: :class:`int` or ``"new"``
        :param file: The uploaded file
        :type file: :class:`cgi.FieldStorage` or ``None``
        :param url: A URL to a recognizable audio or video file
        :type url: :class:`unicode` or ``None``
        :rtype: JSON dict
        :returns:
            success
                bool
            message
                Error message, if unsuccessful
            media_id
                The :attr:`~mediacore.model.media.Media.id` which is
                important if new media has just been created.
            file_id
                The :attr:`~mediacore.model.media.MediaFile.id` for the newly
                created file.
            edit_form
                The rendered XHTML :class:`~mediacore.forms.admin.media.EditFileForm`
                for this file.
            status_form
                The rendered XHTML :class:`~mediacore.forms.admin.media.UpdateStatusForm`

        """
        if id == 'new':
            media = create_media_stub()
        else:
            media = fetch_row(Media, id)

        data = dict(success=False)

        if file is not None:
            # Create a media object, add it to the video, and store the file permanently.
            media_file = _add_new_media_file(media, file.filename, file.file)
            data['success'] = True
        elif url:
            media_file = MediaFile()
            # Parse the URL checking for known embeddables like YouTube
            for type, info in external_embedded_containers.iteritems():
                match = info['pattern'].match(url)
                if match:
                    media_file.type = guess_media_type(type)
                    media_file.container = type
                    media_file.embed = match.group('id')
                    media_file.display_name = type.capitalize() + ' ID: ' + media_file.embed
                    data['success'] = True
                    break
            else:
                # Check for types we can play ourselves
                try:
                    ext = os.path.splitext(url)[1].lower()[1:]
                    container = guess_container_format(ext)
                except KeyError:
                    container = None
                for conts in playable_containers.itervalues():
                    if container in conts:
                        media_file.type = guess_media_type(container)
                        media_file.container = container
                        media_file.url = url
                        media_file.display_name = os.path.basename(url)
                        data['success'] = True
                        break
                else:
                    data['message'] = 'Unsupported URL'
        else:
            data['message'] = 'No action to perform.'

        if data['success']:
            media.files.append(media_file)
            media.update_type()
            media.update_status()
            DBSession.add(media)
            DBSession.flush()

            if id == 'new':
                helpers.create_default_thumbs_for(media)

            # Render some widgets so the XHTML can be injected into the page
            edit_form_xhtml = unicode(edit_file_form.display(
                action=url_for(action='edit_file', id=media.id),
                file=media_file))
            status_form_xhtml = unicode(update_status_form.display(
                action=url_for(action='update_status', id=media.id),
                media=media))

            data.update(dict(
                media_id = media.id,
                file_id = media_file.id,
                file_type = media_file.type,
                edit_form = edit_form_xhtml,
                status_form = status_form_xhtml,
            ))

        return data