Beispiel #1
0
    def _update_settings(self, values):
        """Modify the settings associated with the given dictionary."""
        for name, value in values.iteritems():
            setting = tmpl_context.settings[name]
            if value is None:
                value = u''
            else:
                value = unicode(value)
            if setting.value != value:
                setting.value = value
                DBSession.add(setting)
        DBSession.flush()

        # Clear the settings cache unless there are multiple processes.
        # We have no way of notifying the other processes that they need
        # to clear their caches too, so we've just gotta let it play out
        # until all the caches expire.
        if not request.environ.get('wsgi.multiprocess', False):
            app_globals.settings_cache.clear()
        else:
            # uWSGI provides an automagically included module
            # that we can use to call a graceful restart of all
            # the uwsgi processes.
            # http://projects.unbit.it/uwsgi/wiki/uWSGIReload
            try:
                import uwsgi
                uwsgi.reload()
            except ImportError:
                pass
Beispiel #2
0
def insert_settings(defaults):
    """Insert the given setting if they don't exist yet.

    XXX: Does not include any support for MultiSetting. This approach
         won't work for that. We'll need to use sqlalchemy-migrate.

    :type defaults: list
    :param defaults: Key and value pairs
    :rtype: list
    :returns: Any settings that have just been created.
    """
    inserted = []
    existing_settings = set(x[0] for x in DBSession.query(Setting.key) \
                                     .filter(Setting.key \
                                     .in_(key for key, value in defaults)))

    for key, value in defaults:
        if key in existing_settings:
            continue
        transaction = DBSession.begin_nested()
        try:
            s = Setting(key, value)
            DBSession.add(s)
            transaction.commit()
            inserted.append(s)
        except IntegrityError:
            transaction.rollback()
    if inserted:
        DBSession.commit()
    return inserted
Beispiel #3
0
    def save(self,
             id,
             display_name,
             group_name,
             permissions,
             delete=None,
             **kwargs):
        """Save changes or create a new :class:`~mediacore.model.auth.Group` instance.

        :param id: Group ID. If ``"new"`` a new group is created.
        :type id: ``int`` or ``"new"``
        :returns: Redirect back to :meth:`index` after successful save.

        """
        group = fetch_row(Group, id)

        if delete:
            DBSession.delete(group)
            redirect(action='index', id=None)

        group.display_name = display_name
        group.group_name = group_name
        if permissions:
            query = DBSession.query(Permission).filter(
                Permission.permission_id.in_(permissions))
            group.permissions = list(query.all())
        else:
            group.permissions = []
        DBSession.add(group)

        redirect(action='index', id=None)
Beispiel #4
0
def insert_settings(defaults):
    """Insert the given setting if they don't exist yet.

    XXX: Does not include any support for MultiSetting. This approach
         won't work for that. We'll need to use sqlalchemy-migrate.

    :type defaults: list
    :param defaults: Key and value pairs
    :rtype: list
    :returns: Any settings that have just been created.
    """
    inserted = []
    existing_settings = set(x[0] for x in DBSession.query(Setting.key) \
                                     .filter(Setting.key \
                                     .in_(key for key, value in defaults)))

    for key, value in defaults:
        if key in existing_settings:
            continue
        transaction = DBSession.begin_nested()
        try:
            s = Setting(key, value)
            DBSession.add(s)
            transaction.commit()
            inserted.append(s)
        except IntegrityError:
            transaction.rollback()
    if inserted:
        DBSession.commit()
    return inserted
Beispiel #5
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
Beispiel #6
0
    def save(self, id, email_address, display_name, login_details,
             delete=None, **kwargs):
        """Save changes or create a new :class:`~mediacore.model.auth.User` instance.

        :param id: User ID. If ``"new"`` a new user is created.
        :type id: ``int`` or ``"new"``
        :returns: Redirect back to :meth:`index` after successful save.

        """
        user = fetch_row(User, id)

        if delete:
            DBSession.delete(user)
            redirect(action='index', id=None)

        user.display_name = display_name
        user.email_address = email_address
        user.user_name = login_details['user_name']

        password = login_details['password']
        if password is not None and password != '':
            user.password = password

        if login_details['group']:
            group = fetch_row(Group, login_details['group'])
            user.groups = [group]
        else:
            user.groups = []

        DBSession.add(user)
        DBSession.flush()
        redirect(action='index', id=None)
    def _update_settings(self, values):
        """Modify the settings associated with the given dictionary."""
        for name, value in values.iteritems():
            setting = tmpl_context.settings[name]
            if value is None:
                value = u''
            else:
                value = unicode(value)
            if setting.value != value:
                setting.value = value
                DBSession.add(setting)
        DBSession.flush()

        # Clear the settings cache unless there are multiple processes.
        # We have no way of notifying the other processes that they need
        # to clear their caches too, so we've just gotta let it play out
        # until all the caches expire.
        if not request.environ.get('wsgi.multiprocess', False):
            app_globals.settings_cache.clear()
        else:
            # uWSGI provides an automagically included module
            # that we can use to call a graceful restart of all
            # the uwsgi processes.
            # http://projects.unbit.it/uwsgi/wiki/uWSGIReload
            try:
                import uwsgi
                uwsgi.reload()
            except ImportError:
                pass
Beispiel #8
0
def attach_and_store_media_file(media, media_file, file):
    """Given a Media object, a MediaFile object, and a file handle,
    attaches the MediaFile to the Media object, and saves the file to permanent
    storage.

    Adds the MediaFile to the database.
    """
    # 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, media_file.container)
    file_url = store_media_file(file, file_name)

    if file_url:
        # The file has been stored remotely
        media_file.url = file_url
    else:
        # The file is stored locally and we just need its name
        media_file.file_name = file_name
Beispiel #9
0
    def save(self, id, delete=None, **kwargs):
        """Save changes or create a category.

        See :class:`~mediacore.forms.admin.settings.categories.CategoryForm` for POST vars.

        :param id: Category ID
        :param delete: If true the category is to be deleted rather than saved.
        :type delete: bool
        :rtype: JSON dict
        :returns:
            success
                bool

        """
        if tmpl_context.form_errors:
            if request.is_xhr:
                return dict(success=False, errors=tmpl_context.form_errors)
            else:
                # TODO: Add error reporting for users with JS disabled?
                return redirect(action="edit")

        cat = fetch_row(Category, id)

        if delete:
            DBSession.delete(cat)
            data = dict(success=True, id=cat.id, parent_options=unicode(category_form.c["parent_id"].display()))
        else:
            cat.name = kwargs["name"]
            cat.slug = get_available_slug(Category, kwargs["slug"], cat)

            if kwargs["parent_id"]:
                parent = fetch_row(Category, kwargs["parent_id"])
                if parent is not cat and cat not in parent.ancestors():
                    cat.parent = parent
            else:
                cat.parent = None

            DBSession.add(cat)
            DBSession.flush()

            data = dict(
                success=True,
                id=cat.id,
                name=cat.name,
                slug=cat.slug,
                parent_id=cat.parent_id,
                parent_options=unicode(category_form.c["parent_id"].display()),
                depth=cat.depth(),
                row=unicode(
                    category_row_form.display(
                        action=url_for(id=cat.id), category=cat, depth=cat.depth(), first_child=True
                    )
                ),
            )

        if request.is_xhr:
            return data
        else:
            redirect(action="index", id=None)
def podcast_from_feed(d, tags=False, save_files=False):
    # Assume not explicit
    explicit = False
    if 'itunes_explicit' in d['feed']:
        explicit = bool(d['feed']['itunes_explicit'])

    image = None
    if 'image' in d['feed']:
        image = d['feed']['image']['href']

    title = u''
    if 'title' in d['feed']:
        title = d['feed']['title']

    description = u''
    if 'summary' in d['feed']:
        description = d['feed']['summary']

    subtitle = u''
    if 'subtitle' in d['feed']:
        subtitle = d['feed']['subtitle']

    slug = slugify(title)
    author_name = u"PLACEHOLDER NAME"
    author_email = u"*****@*****.**"

    podcast = Podcast()
    podcast.slug = get_available_slug(Podcast, slug, podcast)
    podcast.title = title
    podcast.subtitle = subtitle
    podcast.author = Author(author_name, author_email)
    podcast.description = description
    podcast.explicit = explicit

    DBSession.add(podcast)
    DBSession.flush()

    # Create thumbs from image, or default thumbs
    created_images = False
    if image:
        temp_imagefile = tempfile.TemporaryFile()
        imagefile = urllib2.urlopen(image)
        temp_imagefile.write(imagefile.read())
        temp_imagefile.seek(0)
        filename = urlparse.urlparse(image)[2]
        create_thumbs_for(podcast, temp_imagefile, filename)
        created_images = True

    if not created_images:
        create_default_thumbs_for(podcast)

    # Now add all of the entries
    for entry in d['entries']:
        media = media_from_entry(entry, tags, save_files)
        media.podcast = podcast

    return podcast
    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,
                ),
            ),
        }
Beispiel #12
0
 def import_videos_from_feed(self, feed):
     for entry in feed.entry:
         youtube_id = self.id_for_entry(entry)
         if not self._should_import_video(youtube_id):
             continue
         media = self._import_video(entry)
         self._video_notifcation(youtube_id)
         if media:
             DBSession.add(media)
             DBSession.flush()
Beispiel #13
0
def fetch_and_create_multi_setting(key, value):
    multisettings = MultiSetting.query\
        .filter(MultiSetting.key==key)\
        .all()
    for ms in multisettings:
        if ms.value == value:
            return ms
    ms = MultiSetting(key, value)
    DBSession.add(ms)
    return ms
Beispiel #14
0
 def example(cls, **kwargs):
     defaults = dict(
         name=u'baz_users',
         display_name=u'Baz Users',
     )
     defaults.update(kwargs)
     group = Group(**defaults)
     DBSession.add(group)
     DBSession.flush()
     return group
Beispiel #15
0
 def example(cls, **kwargs):
     defaults = dict(
         name = u'baz_users',
         display_name = u'Baz Users',
     )
     defaults.update(kwargs)
     group = Group(**defaults)
     DBSession.add(group)
     DBSession.flush()
     return group
Beispiel #16
0
def fetch_and_create_multi_setting(key, value):
    multisettings = MultiSetting.query\
        .filter(MultiSetting.key==key)\
        .all()
    for ms in multisettings:
        if ms.value == value:
            return ms
    ms = MultiSetting(key, value)
    DBSession.add(ms)
    return ms
Beispiel #17
0
    def save_thumb(self, id, thumb, **kwargs):
        """Save a thumbnail uploaded with :class:`~mediacore.forms.admin.ThumbForm`.

        :param id: Media ID. If ``"new"`` a new Media stub is created with
            :func:`~mediacore.model.media.create_media_stub`.
        :type id: ``int`` or ``"new"``
        :param file: The uploaded file
        :type file: :class:`cgi.FieldStorage` or ``None``
        :rtype: JSON dict
        :returns:
            success
                bool
            message
                Error message, if unsuccessful
            id
                The :attr:`~mediacore.model.media.Media.id` which is
                important if a new media has just been created.

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

        try:
            # Create thumbs
            img = Image.open(thumb.file)

            if id == 'new':
                DBSession.add(media)
                DBSession.flush()

            # TODO: Allow other formats?
            for key, xy in config['thumb_sizes'][media._thumb_dir].iteritems():
                thumb_path = helpers.thumb_path(media, key)
                thumb_img = helpers.resize_thumb(img, xy)
                thumb_img.save(thumb_path)

            # Backup the original image just for kicks
            backup_type = os.path.splitext(thumb.filename)[1].lower()[1:]
            backup_path = helpers.thumb_path(media, 'orig', ext=backup_type)
            backup_file = open(backup_path, 'w+b')
            thumb.file.seek(0)
            shutil.copyfileobj(thumb.file, backup_file)
            thumb.file.close()
            backup_file.close()

            success = True
            message = None
        except IOError:
            success = False
            message = 'Unsupported image type'
        except Exception, e:
            success = False
            message = e.message
Beispiel #18
0
 def example(cls, **kwargs):
     defaults = dict(
         name=u'foo',
         description=u'foo permission',
         groups=None,
     )
     defaults.update(kwargs)
     permission = Permission(**defaults)
     DBSession.add(permission)
     DBSession.flush()
     return permission
Beispiel #19
0
    def popularity_save(self, **kwargs):
        """Save :class:`~mediacore.forms.admin.settings.PopularityForm`.

        Updates the popularity for every media item based on the submitted
        values.
        """
        self._save(popularity_form, values=kwargs)
        for m in Media.query:
            m.update_popularity()
            DBSession.add(m)
        redirect(action='popularity')
Beispiel #20
0
 def _update_settings(self, values):
     """Modify the settings associated with the given dictionary."""
     for name, value in values.iteritems():
         if value is None:
             value = u''
         else:
             value = unicode(value)
         if self.settings[name].value != value:
             self.settings[name].value = value
             DBSession.add(self.settings[name])
     DBSession.flush()
Beispiel #21
0
 def example(cls, **kwargs):
     defaults = dict(
         name=u'foo',
         description = u'foo permission',
         groups = None,
     )
     defaults.update(kwargs)
     permission = Permission(**defaults)
     DBSession.add(permission)
     DBSession.flush()
     return permission
Beispiel #22
0
    def popularity_save(self, **kwargs):
        """Save :class:`~mediacore.forms.admin.settings.PopularityForm`.

        Updates the popularity for every media item based on the submitted
        values.
        """
        self._save(popularity_form, values=kwargs)
        for m in Media.query:
            m.update_popularity()
            DBSession.add(m)
        redirect(action='popularity')
Beispiel #23
0
 def example(cls, **kwargs):
     media = Media()
     defaults = dict(title=u"Foo Media", author=Author(u"Joe", u"*****@*****.**"), type=VIDEO)
     defaults.update(kwargs)
     defaults.setdefault("slug", get_available_slug(Media, defaults["title"]))
     for key, value in defaults.items():
         assert hasattr(media, key)
         setattr(media, key, value)
     DBSession.add(media)
     DBSession.flush()
     return media
Beispiel #24
0
    def save(self, id, slug, title, author_name, author_email,
             description, notes, podcast, tags, categories,
             delete=None, **kwargs):
        """Save changes or create a new :class:`~mediacore.model.media.Media` instance.

        Form handler the :meth:`edit` action and the
        :class:`~mediacore.forms.admin.media.MediaForm`.

        Redirects back to :meth:`edit` after successful editing
        and :meth:`index` after successful deletion.

        """
        media = fetch_row(Media, id)

        if delete:
            self._delete_media(media)
            DBSession.commit()
            redirect(action='index', id=None)

        if not slug:
            slug = title
        elif slug.startswith('_stub_'):
            slug = slug[len('_stub_'):]
        if slug != media.slug:
            media.slug = get_available_slug(Media, slug, media)
        media.title = title
        media.author = Author(author_name, author_email)
        media.description = description
        media.notes = notes
        media.podcast_id = podcast
        media.set_tags(tags)
        media.set_categories(categories)

        media.update_status()
        DBSession.add(media)
        DBSession.flush()

        if id == 'new' and not has_thumbs(media):
            create_default_thumbs_for(media)

        if request.is_xhr:
            status_form_xhtml = unicode(update_status_form.display(
                action=url_for(action='update_status', id=media.id),
                media=media))

            return dict(
                media_id = media.id,
                values = {'slug': slug},
                link = url_for(action='edit', id=media.id),
                status_form = status_form_xhtml,
            )
        else:
            redirect(action='edit', id=media.id)
Beispiel #25
0
 def save_display(self, **kwargs):
     """Save :class:`~mediacore.forms.admin.settings.DisplayForm`."""
     player_type = c.settings['player_type'].value
     self._save(display_form, **kwargs)
     # If the player_type changes, we must update the Media.encoded flag,
     # since some things may play now and/or not play anymore with the
     # new setting.
     if player_type != c.settings['player_type'].value:
         for m in Media.query.options(orm.eagerload('files')):
             m.update_status()
             DBSession.add(m)
     redirect(action='display')
Beispiel #26
0
    def save(self,
             id,
             slug,
             title,
             subtitle,
             author_name,
             author_email,
             description,
             details,
             feed,
             delete=None,
             **kwargs):
        """Save changes or create a new :class:`~mediacore.model.podcasts.Podcast` instance.

        Form handler the :meth:`edit` action and the
        :class:`~mediacore.forms.admin.podcasts.PodcastForm`.

        Redirects back to :meth:`edit` after successful editing
        and :meth:`index` after successful deletion.

        """
        podcast = fetch_row(Podcast, id)

        if delete:
            file_paths = thumb_paths(podcast).values()
            DBSession.delete(podcast)
            DBSession.commit()
            helpers.delete_files(file_paths, Podcast._thumb_dir)
            redirect(action='index', id=None)

        if not slug:
            slug = title
        if slug != podcast.slug:
            podcast.slug = get_available_slug(Podcast, slug, podcast)
        podcast.title = title
        podcast.subtitle = subtitle
        podcast.author = Author(author_name, author_email)
        podcast.description = description
        podcast.copyright = details['copyright']
        podcast.category = details['category']
        podcast.itunes_url = feed['itunes_url']
        podcast.feedburner_url = feed['feedburner_url']
        podcast.explicit = {
            'yes': True,
            'clean': False
        }.get(details['explicit'], None)

        if id == 'new':
            DBSession.add(podcast)
            DBSession.flush()
            create_default_thumbs_for(podcast)

        redirect(action='edit', id=podcast.id)
Beispiel #27
0
    def edit_file(self, id, file_id, file_type=None, delete=None, **kwargs):
        """Save action for the :class:`~mediacore.forms.admin.media.EditFileForm`.

        Changes or delets a :class:`~mediacore.model.media.MediaFile`.

        :param id: Media ID
        :type id: :class:`int`
        :rtype: JSON dict
        :returns:
            success
                bool
            message
                Error message, if unsuccessful
            status_form
                Rendered XHTML for the status form, updated to reflect the
                changes made.

        """
        media = fetch_row(Media, id)
        data = dict(success=False)

        try:
            file = [file for file in media.files if file.id == int(file_id)][0]
        except IndexError:
            data['message'] = 'File no longer exists.'

        if file_type:
            file.type = file_type
            DBSession.add(file)
            data['success'] = True
        elif delete:
            file_path = file.file_path
            DBSession.delete(file)
            transaction.commit()
            if file_path:
                helpers.delete_files([file_path], 'media')
            media = fetch_row(Media, id)
            data['success'] = True
        else:
            data['message'] = 'No action to perform.'

        if data['success']:
            data['file_type'] = file.type
            media.update_type()
            media.update_status()
            DBSession.add(media)
            DBSession.flush()

            # Return the rendered widget for injection
            status_form_xhtml = unicode(update_status_form.display(
                action=url_for(action='update_status'), media=media))
            data['status_form'] = status_form_xhtml
        return data
Beispiel #28
0
    def save(self, id, slug, title, author_name, author_email,
             description, notes, podcast, tags, categories,
             delete=None, **kwargs):
        """Save changes or create a new :class:`~mediacore.model.media.Media` instance.

        Form handler the :meth:`edit` action and the
        :class:`~mediacore.forms.admin.media.MediaForm`.

        Redirects back to :meth:`edit` after successful editing
        and :meth:`index` after successful deletion.

        """
        media = fetch_row(Media, id)

        if delete:
            self._delete_media(media)
            DBSession.commit()
            redirect(action='index', id=None)

        if not slug:
            slug = title
        elif slug.startswith('_stub_'):
            slug = slug[len('_stub_'):]
        if slug != media.slug:
            media.slug = get_available_slug(Media, slug, media)
        media.title = title
        media.author = Author(author_name, author_email)
        media.description = description
        media.notes = notes
        media.podcast_id = podcast
        media.set_tags(tags)
        media.set_categories(categories)

        media.update_status()
        DBSession.add(media)
        DBSession.flush()

        if id == 'new' and not has_thumbs(media):
            create_default_thumbs_for(media)

        if request.is_xhr:
            status_form_xhtml = unicode(update_status_form.display(
                action=url_for(action='update_status', id=media.id),
                media=media))

            return dict(
                media_id = media.id,
                values = {'slug': slug},
                link = url_for(action='edit', id=media.id),
                status_form = status_form_xhtml,
            )
        else:
            redirect(action='edit', id=media.id)
Beispiel #29
0
    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.
        :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 = Media()
            user = request.environ['repoze.who.identity']['user']
            media.author = Author(user.display_name, user.email_address)
            # Create a temp stub until we can set it to something meaningful
            timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            media.title = u'Temporary stub %s' % timestamp
            media.slug = get_available_slug(Media, '_stub_' + timestamp)
            DBSession.add(media)
            DBSession.flush()
        else:
            media = fetch_row(Media, id)

        try:
            media_file = add_new_media_file(media, file, url)
        except Invalid, e:
            DBSession.rollback()
            data = dict(
                success = False,
                message = e.message,
            )
    def example(cls, **kwargs):
        category = Category()
        defaults = dict(name=u'Foo', parent_id=0)
        defaults.update(kwargs)
        defaults.setdefault('slug',
                            get_available_slug(Category, defaults['name']))

        for key, value in defaults.items():
            assert hasattr(category, key)
            setattr(category, key, value)

        DBSession.add(category)
        DBSession.flush()
        return category
Beispiel #31
0
        def get_videos_from_feed(feed):
            for entry in feed.entry:
                # Occasionally, there are issues with a video in a feed
                # not being available (region restrictions, etc)
                # If this happens, just move along.
                if not entry.media.player:
                    log.debug('Video Feed Error: No player URL? %s' % entry)
                    continue
                video_url = unicode(entry.media.player.url, "utf-8")
                if video_already_has_media_file(video_url):
                    continue
                categories = kwargs.get('youtube.categories', None)
                tags = kwargs.get('youtube.tags', None)
                media = fetch_row(Media, u'new')
                user = request.environ['repoze.who.identity']['user']
                media.author = Author(user.display_name, user.email_address)
                media.reviewed = True
                media.title = unicode(entry.media.title.text, "utf-8")
                if entry.media.description.text:
                    encoded_description = unicode(entry.media.description.text,
                                                "utf-8")
                    media.description = clean_xhtml(encoded_description)
                media.slug = get_available_slug(Media, media.title, media)

                if tags:
                    media.set_tags(unicode(tags))
                if categories:
                    if not isinstance(categories, list):
                        categories = [categories]
                    media.set_categories(categories)
                try:
                    media_file = add_new_media_file(media,
                        url=video_url)
                except StorageError, e:
                    log.debug('Video Feed Error: Error storing video: %s at %s' \
                        % e.message, video_url)
                    continue
                if not has_thumbs(media):
                    create_default_thumbs_for(media)
                media.title = media_file.display_name
                media.update_status()
                if auto_publish:
                    media.reviewed = 1
                    media.encoded = 1
                    media.publishable = 1
                    media.created_on = datetime.now()
                    media.modified_on = datetime.now()
                    media.publish_on = datetime.now()
                DBSession.add(media)
                DBSession.flush()
    def createMediaItem(self,
                        title,
                        author_email=None,
                        author_name=None,
                        slug=None,
                        tags=None,
                        podcast_id=None,
                        category_ids=None,
                        meta=None,
                        **kwargs):
        mediaItem = Media()
        log.info("createMediaItem({title})".format(title=title))

        if not slug:
            slug = title
        elif slug.startswith('_stub_'):
            slug = slug[len('_stub_'):]
        if slug != mediaItem.slug:
            mediaItem.slug = get_available_slug(Media, slug, mediaItem)

        if podcast_id:
            podcast_id = int(podcast_id)
        else:
            podcast_id = 0

        if not meta:
            meta = {}
        else:
            try:
                meta = json.loads(meta)
            except Exception as e:
                return {
                    "success": False,
                    "message": "Invalid JSON object given for `meta`"
                }

        mediaItem.title = title
        mediaItem.author = Author(author_name or "No Author", author_email
                                  or "No Email")
        mediaItem.podcast_id = podcast_id or None
        mediaItem.set_tags(tags)
        mediaItem.set_categories(category_ids)
        mediaItem.update_status()
        mediaItem.meta = meta

        DBSession.add(mediaItem)
        DBSession.flush()

        return {"success": True, "id": mediaItem.id}
Beispiel #33
0
 def example(cls, **kwargs):
     user = User()
     defaults = dict(
         user_name = u'joe',
         email_address = u'*****@*****.**',
         display_name = u'Joe Smith',
         created = datetime.now(),
     )
     defaults.update(kwargs)
     for key, value in defaults.items():
         setattr(user, key, value)
     
     DBSession.add(user)
     DBSession.flush()
     return user
Beispiel #34
0
    def example(cls, **kwargs):
        user = User()
        defaults = dict(
            user_name=u'joe',
            email_address=u'*****@*****.**',
            display_name=u'Joe Smith',
            created=datetime.now(),
        )
        defaults.update(kwargs)
        for key, value in defaults.items():
            setattr(user, key, value)

        DBSession.add(user)
        DBSession.flush()
        return user
Beispiel #35
0
 def example(cls, **kwargs):
     media = Media()
     defaults = dict(
         title=u'Foo Media',
         author=Author(u'Joe', u'*****@*****.**'),
         
         type = None,
     )
     defaults.update(kwargs)
     defaults.setdefault('slug', get_available_slug(Media, defaults['title']))
     for key, value in defaults.items():
         assert hasattr(media, key)
         setattr(media, key, value)
     DBSession.add(media)
     DBSession.flush()
     return media
Beispiel #36
0
    def example(cls, **kwargs):
        category = Category()
        defaults = dict(
            name=u'Foo',
            parent_id=0
        )
        defaults.update(kwargs)
        defaults.setdefault('slug', get_available_slug(Category, defaults['name']))

        for key, value in defaults.items():
            assert hasattr(category, key)
            setattr(category, key, value)

        DBSession.add(category)
        DBSession.flush()
        return category
Beispiel #37
0
 def example(cls, **kwargs):
     media = Media()
     defaults = dict(
         title=u'Foo Media',
         author=Author(u'Joe', u'*****@*****.**'),
         type=None,
     )
     defaults.update(kwargs)
     defaults.setdefault('slug', get_available_slug(Media,
                                                    defaults['title']))
     for key, value in defaults.items():
         assert hasattr(media, key)
         setattr(media, key, value)
     DBSession.add(media)
     DBSession.flush()
     return media
Beispiel #38
0
    def save_thumb(self, id, thumb, **kwargs):
        """Save a thumbnail uploaded with :class:`~mediacore.forms.admin.ThumbForm`.

        :param id: Media ID. If ``"new"`` a new Media stub is created.
        :type id: ``int`` or ``"new"``
        :param file: The uploaded file
        :type file: :class:`cgi.FieldStorage` or ``None``
        :rtype: JSON dict
        :returns:
            success
                bool
            message
                Error message, if unsuccessful
            id
                The :attr:`~mediacore.model.media.Media.id` which is
                important if a new media has just been created.

        """
        if id == 'new':
            media = Media()
            user = req.perm.user
            media.author = Author(user.display_name, user.email_address)
            media.title = os.path.basename(thumb.filename)
            media.slug = get_available_slug(Media, '_stub_' + media.title)
            DBSession.add(media)
            DBSession.flush()
        else:
            media = fetch_row(Media, id)

        try:
            # Create JPEG thumbs
            create_thumbs_for(media, thumb.file, thumb.filename)
            success = True
            message = None
        except IOError, e:
            success = False
            if id == 'new':
                DBSession.delete(media)
            if e.errno == 13:
                message = _('Permission denied, cannot write file')
            elif e.message == 'cannot identify image file':
                message = _('Unsupported image type: %s') \
                    % os.path.splitext(thumb.filename)[1].lstrip('.')
            elif e.message == 'cannot read interlaced PNG files':
                message = _('Interlaced PNGs are not supported.')
            else:
                raise
Beispiel #39
0
    def save_thumb(self, id, thumb, **kwargs):
        """Save a thumbnail uploaded with :class:`~mediacore.forms.admin.ThumbForm`.

        :param id: Media ID. If ``"new"`` a new Media stub is created.
        :type id: ``int`` or ``"new"``
        :param file: The uploaded file
        :type file: :class:`cgi.FieldStorage` or ``None``
        :rtype: JSON dict
        :returns:
            success
                bool
            message
                Error message, if unsuccessful
            id
                The :attr:`~mediacore.model.media.Media.id` which is
                important if a new media has just been created.

        """
        if id == 'new':
            media = Media()
            user = request.environ['repoze.who.identity']['user']
            media.author = Author(user.display_name, user.email_address)
            media.title = os.path.basename(thumb.filename)
            media.slug = get_available_slug(Media, '_stub_' + media.title)
            DBSession.add(media)
            DBSession.flush()
        else:
            media = fetch_row(Media, id)

        try:
            # Create JPEG thumbs
            create_thumbs_for(media, thumb.file, thumb.filename)
            success = True
            message = None
        except IOError, e:
            success = False
            if id == 'new':
                DBSession.delete(media)
            if e.errno == 13:
                message = _('Permission denied, cannot write file')
            elif e.message == 'cannot identify image file':
                message = _('Unsupport image type: %s') \
                    % os.path.splitext(thumb.filename)[1].lstrip('.')
            elif e.message == 'cannot read interlaced PNG files':
                message = _('Interlaced PNGs are not supported.')
            else:
                raise
    def createMediaItem(
        self,
        title,
        author_email=None,
        author_name=None,
        slug=None,
        tags=None,
        podcast_id=None,
        category_ids=None,
        meta=None,
        **kwargs
    ):
        mediaItem = Media()
        log.info("createMediaItem({title})".format(title=title))

        if not slug:
            slug = title
        elif slug.startswith("_stub_"):
            slug = slug[len("_stub_") :]
        if slug != mediaItem.slug:
            mediaItem.slug = get_available_slug(Media, slug, mediaItem)

        if podcast_id:
            podcast_id = int(podcast_id)
        else:
            podcast_id = 0

        if not meta:
            meta = {}
        else:
            try:
                meta = json.loads(meta)
            except Exception as e:
                return {"success": False, "message": "Invalid JSON object given for `meta`"}

        mediaItem.title = title
        mediaItem.author = Author(author_name or "No Author", author_email or "No Email")
        mediaItem.podcast_id = podcast_id or None
        mediaItem.set_tags(tags)
        mediaItem.set_categories(category_ids)
        mediaItem.update_status()
        mediaItem.meta = meta

        DBSession.add(mediaItem)
        DBSession.flush()

        return {"success": True, "id": mediaItem.id}
    def save_edit(self, id, body, **kwargs):
        """Save an edit from :class:`~mediacore.forms.admin.comments.EditCommentForm`.

        :param id: Comment ID
        :type id: ``int``
        :rtype: JSON dict
        :returns:
            success
                bool
            body
                The edited comment body after validation/filtering

        """
        comment = fetch_row(Comment, id)
        comment.body = body
        DBSession.add(comment)
        return dict(success=True, body=comment.body)
Beispiel #42
0
    def save(self,
             id,
             email_address,
             display_name,
             login_details,
             delete=None,
             **kwargs):
        """Save changes or create a new :class:`~mediacore.model.auth.User` instance.

        :param id: User ID. If ``"new"`` a new user is created.
        :type id: ``int`` or ``"new"``
        :returns: Redirect back to :meth:`index` after successful save.

        """
        user = fetch_row(User, id)

        if delete:
            DBSession.delete(user)
            redirect(action='index', id=None)

        user.display_name = display_name
        user.email_address = email_address
        user.user_name = login_details['user_name']

        password = login_details['password']
        if password is not None and password != '':
            user.password = password

        if login_details['group']:
            group = fetch_row(Group, login_details['group'])
            user.groups = [group]
        else:
            user.groups = []

        DBSession.add(user)

        # Check if we're changing the logged in user's own password
        logged_in_user = request.environ['repoze.who.identity']['user']
        if user.user_id == logged_in_user.user_id \
        and password is not None and password != '':
            DBSession.commit()
            # repoze.who sees the Unauthorized response and clears the cookie,
            # forcing a fresh login with the new password
            raise webob.exc.HTTPUnauthorized().exception

        redirect(action='index', id=None)
Beispiel #43
0
    def save_status(self, id, status, ids=None, **kwargs):
        """Approve or delete a comment or comments.

        :param id: A :attr:`~mediacore.model.comments.Comment.id` if we are
            acting on a single comment, or ``"bulk"`` if we should refer to
            ``ids``.
        :type id: ``int`` or ``"bulk"``
        :param status: ``"approve"`` or ``"trash"`` depending on what action
            the user requests.
        :param ids: An optional string of IDs separated by commas.
        :type ids: ``unicode`` or ``None``
        :rtype: JSON dict
        :returns:
            success
                bool
            ids
                A list of :attr:`~mediacore.model.comments.Comment.id`
                that have changed.

        """
        if id != 'bulk':
            ids = [id]
        if not isinstance(ids, list):
            ids = [ids]

        if status == 'approve':
            publishable = True
        elif status == 'trash':
            publishable = False
        else:
            # XXX: This form should never be submitted without a valid status.
            raise AssertionError('Unexpected status: %r' % status)

        comments = Comment.query.filter(Comment.id.in_(ids)).all()

        for comment in comments:
            comment.reviewed = True
            comment.publishable = publishable
            DBSession.add(comment)

        DBSession.flush()

        if request.is_xhr:
            return dict(success=True, ids=ids)
        else:
            redirect(action='index')
Beispiel #44
0
    def save(self,
             id,
             email_address,
             display_name,
             login_details,
             delete=None,
             **kwargs):
        """Save changes or create a new :class:`~mediacore.model.auth.User` instance.

        :param id: User ID. If ``"new"`` a new user is created.
        :type id: ``int`` or ``"new"``
        :returns: Redirect back to :meth:`index` after successful save.

        """
        user = fetch_row(User, id)

        if delete:
            DBSession.delete(user)
            redirect(action='index', id=None)

        user.display_name = display_name
        user.email_address = email_address
        user.user_name = login_details['user_name']

        password = login_details['password']
        if password is not None and password != '':
            user.password = password

        if login_details['group']:
            group = fetch_row(Group, login_details['group'])
            user.groups = [group]
        else:
            user.groups = []

        DBSession.add(user)

        # Check if we're changing the logged in user's own password
        logged_in_user = request.environ['repoze.who.identity']['user']
        if user.user_id == logged_in_user.user_id \
        and password is not None and password != '':
            DBSession.commit()
            # repoze.who sees the Unauthorized response and clears the cookie,
            # forcing a fresh login with the new password
            raise webob.exc.HTTPUnauthorized().exception

        redirect(action='index', id=None)
Beispiel #45
0
    def save_status(self, id, status, ids=None, **kwargs):
        """Approve or delete a comment or comments.

        :param id: A :attr:`~mediacore.model.comments.Comment.id` if we are
            acting on a single comment, or ``"bulk"`` if we should refer to
            ``ids``.
        :type id: ``int`` or ``"bulk"``
        :param status: ``"approve"`` or ``"trash"`` depending on what action
            the user requests.
        :param ids: An optional string of IDs separated by commas.
        :type ids: ``unicode`` or ``None``
        :rtype: JSON dict
        :returns:
            success
                bool
            ids
                A list of :attr:`~mediacore.model.comments.Comment.id`
                that have changed.

        """
        if id != 'bulk':
            ids = [id]
        if not isinstance(ids, list):
            ids = [ids]

        if status == 'approve':
            publishable = True
        elif status == 'trash':
            publishable = False
        else:
            # XXX: This form should never be submitted without a valid status.
            raise AssertionError('Unexpected status: %r' % status)

        comments = Comment.query.filter(Comment.id.in_(ids)).all()

        for comment in comments:
            comment.reviewed = True
            comment.publishable = publishable
            DBSession.add(comment)

        DBSession.flush()

        if request.is_xhr:
            return dict(success=True, ids=ids)
        else:
            redirect(action='index')
Beispiel #46
0
    def save(self, id, slug, title, author_name, author_email,
             description, notes, details, podcast, tags, categories,
             delete=None, **kwargs):
        """Save changes or create a new :class:`~mediacore.model.media.Media` instance.

        Form handler the :meth:`edit` action and the
        :class:`~mediacore.forms.admin.media.MediaForm`.

        Redirects back to :meth:`edit` after successful editing
        and :meth:`index` after successful deletion.

        """
        media = fetch_row(Media, id)

        if delete:
            file_paths = helpers.thumb_paths(media)
            for f in media.files:
                file_paths.append(f.file_path)
                # Remove the file from the session so that SQLAlchemy doesn't
                # try to issue an UPDATE to set the MediaFile.media_id to None.
                # The database ON DELETE CASCADE handles everything for us.
                DBSession.expunge(f)
            DBSession.delete(media)
            transaction.commit()
            helpers.delete_files(file_paths, 'media')
            redirect(action='index', id=None)

        media.slug = get_available_slug(Media, slug, media)
        media.title = title
        media.author = Author(author_name, author_email)
        media.description = description
        media.notes = notes
        media.duration = details['duration'] # validator converts hh:mm:ss to secs
        media.podcast_id = podcast
        media.set_tags(tags)
        media.set_categories(categories)

        media.update_status()
        DBSession.add(media)
        DBSession.flush()

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

        redirect(action='edit', id=media.id)
Beispiel #47
0
    def popularity_save(self, **kwargs):
        """Save :class:`~mediacore.forms.admin.settings.PopularityForm`.

        Updates the popularity for every media item based on the submitted
        values.
        """
        self._save(popularity_form, values=kwargs)
        # ".util.calculate_popularity()" uses the popularity settings from
        # the request.settings which are only updated when a new request
        # comes in.
        # update the settings manually so the popularity is actually updated
        # correctly.
        for key in ('popularity_decay_exponent', 'popularity_decay_lifetime'):
            request.settings[key] = kwargs['popularity.'+key]
        for m in Media.query:
            m.update_popularity()
            DBSession.add(m)
        redirect(action='popularity')
    def uploadFile(self, environ, media_id, file_id, **kwargs):
        log.info("uploadFile({media_id},{file_id})".format(**vars()))

        media = fetch_row(Media, media_id)
        mediaFile = fetch_row(MediaFile, file_id)

        # Requests not carrying a valid X-Upload-Token must be rejected immediately
        if 'HTTP_X_UPLOAD_TOKEN' not in environ or str(
                file_id) not in upload_tokens.keys():
            raise webob.exc.HTTPForbidden().exception
        elif not environ['HTTP_X_UPLOAD_TOKEN'] == upload_tokens[str(file_id)]:
            raise webob.exc.HTTPForbidden().exception

        STORAGE_ENGINE = getStorageEngine()

        class FileEntry(object):
            def __init__(self, file, name=None):
                self.file = file
                self.filename = name if name else file.name

        unique_id = STORAGE_ENGINE.store(media_file=mediaFile,
                                         file=FileEntry(
                                             environ['wsgi.input'],
                                             mediaFile.display_name))

        try:
            STORAGE_ENGINE.transcode(mediaFile)
        except Exception:
            log.debug('Engine %r unsuitable for transcoding %r',
                      STORAGE_ENGINE, mediaFile)

        mediaFile.container = os.path.splitext(mediaFile.display_name)[1][1:]
        if unique_id:
            mediaFile.unique_id = unique_id

        DBSession.add(mediaFile)
        DBSession.flush()

        del upload_tokens[str(file_id)]

        # Ideally we'd determine information about the uploaded media file and return it here.
        return {}
Beispiel #49
0
    def save_edit(self, id, body, **kwargs):
        """Save an edit from :class:`~mediacore.forms.admin.comments.EditCommentForm`.

        :param id: Comment ID
        :type id: ``int``
        :rtype: JSON dict
        :returns:
            success
                bool
            body
                The edited comment body after validation/filtering

        """
        comment = fetch_row(Comment, id)
        comment.body = body
        DBSession.add(comment)
        return dict(
            success=True,
            body=comment.body,
        )
Beispiel #50
0
    def save(self, id, delete=False, **kwargs):
        """Save changes or create a tag.

        See :class:`~mediacore.forms.admin.settings.tags.TagForm` for POST vars.

        :param id: Tag ID
        :rtype: JSON dict
        :returns:
            success
                bool

        """
        if tmpl_context.form_errors:
            if request.is_xhr:
                return dict(success=False, errors=tmpl_context.form_errors)
            else:
                # TODO: Add error reporting for users with JS disabled?
                return redirect(action='edit')

        tag = fetch_row(Tag, id)

        if delete:
            DBSession.delete(tag)
            data = dict(success=True, id=tag.id)
        else:
            tag.name = kwargs['name']
            tag.slug = get_available_slug(Tag, kwargs['slug'], tag)
            DBSession.add(tag)
            DBSession.flush()
            data = dict(
                success = True,
                id = tag.id,
                name = tag.name,
                slug = tag.slug,
                row = unicode(tag_row_form.display(tag=tag)),
            )

        if request.is_xhr:
            return data
        else:
            redirect(action='index', id=None)
Beispiel #51
0
def insert_settings(defaults):
    """Insert the given setting if they don't exist yet.

    XXX: Does not include any support for MultiSetting. This approach
         won't work for that. We'll need to use sqlalchemy-migrate.

    :type defaults: list
    :param defaults: Key and value pairs
    :rtype: list
    :returns: Any settings that have just been created.
    """
    inserted = []
    try:
        settings_query = DBSession.query(Setting.key)\
            .filter(Setting.key.in_([key for key, value in defaults]))
        existing_settings = set(x[0] for x in settings_query)
    except ProgrammingError:
        # If we are running paster setup-app on a fresh database with a
        # plugin which tries to use this function every time the
        # Environment.loaded event fires, the settings table will not
        # exist and this exception will be thrown, but its safe to ignore.
        # The settings will be created the next time the event fires,
        # which will likely be the first time the app server starts up.
        return inserted
    for key, value in defaults:
        if key in existing_settings:
            continue
        transaction = DBSession.begin_nested()
        try:
            s = Setting(key, value)
            DBSession.add(s)
            transaction.commit()
            inserted.append(s)
        except IntegrityError:
            transaction.rollback()
    if inserted:
        DBSession.commit()
    return inserted
    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))
        }
def media_from_entry(e, tags=False, save_files=False):
    # Get tags as a list of unicode objects.
    tags = [t['term'] for t in e['tags']]

    # Assume not explicit.
    explicit = 0
    if 'itunes_explicit' in e:
        explicit = e['itunes_explicit']

    # Find the duration, if it exists
    duration = u''
    if 'itunes_duration' in e:
        try:
            duration = e['itunes_duration']
            duration = duration_to_seconds(duration)
        except ValueError:
            duration = None

    # Find the first <img> tag in the summary, if there is one
    image = None
    m = img_regex.match(e['summary'])
    if m is not None:
        image = m.group(1)[1:-1]

    title = e['title']

    slug = slugify(title)
    author_name = u"PLACEHOLDER NAME"
    author_email = u"*****@*****.**"
    if 'author_detail' in e:
        if 'name' in e['author_detail']:
            author_name = e['author_detail']['name']
        if 'email' in e['author_detail']:
            author_email = e['author_detail']['email']
    year, month, day, hour, minute, second = e['updated_parsed'][:6]
    updated = datetime(year, month, day, hour, minute, second)

    media = Media()
    media.slug = get_available_slug(Media, slug, media)
    media.title = e['title']
    media.author = Author(author_name, author_email)
    media.description = e['summary']
    media.notes = u''
    if tags:
        media.set_tags(tags)
    else:
        media.set_categories(tags)
    media.publish_on = updated
    media.created_on = updated
    media.publishable = True
    media.reviewed = True
    media.duration = duration

    DBSession.add(media)
    DBSession.flush()

    # Create thumbs from image, or default thumbs
    created_images = False
    if image:
        temp_imagefile = tempfile.TemporaryFile()
        imagefile = urllib2.urlopen(image)
        temp_imagefile.write(imagefile.read())
        temp_imagefile.seek(0)
        filename = urlparse.urlparse(image)[2]
        create_thumbs_for(media, temp_imagefile, filename)
        created_images = True

    if not created_images:
        create_default_thumbs_for(media)

    print "Loaded episode:", media

    # now add all of the files.
    for enc in e['enclosures']:
        mf = media_file_from_enclosure(enc, media, save_files)
        print "Loaded media file:", mf

    media.update_status()

    return media
Beispiel #54
0
    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.
        :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 = Media()
            user = request.environ['repoze.who.identity']['user']
            media.author = Author(user.display_name, user.email_address)
            # Create a temp stub until we can set it to something meaningful
            timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            media.title = u'Temporary stub %s' % timestamp
            media.slug = get_available_slug(Media, '_stub_' + timestamp)
            media.reviewed = True
            DBSession.add(media)
            DBSession.flush()
        else:
            media = fetch_row(Media, id)

        media_file = add_new_media_file(media, file, url)
        if media.slug.startswith('_stub_'):
            media.title = media_file.display_name
            media.slug = get_available_slug(Media, '_stub_' + media.title)

        # The thumbs may have been created already by add_new_media_file
        if id == 'new' and not has_thumbs(media):
            create_default_thumbs_for(media)

        media.update_status()

        # 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 = dict(
            success = True,
            media_id = media.id,
            file_id = media_file.id,
            file_type = media_file.type,
            edit_form = edit_form_xhtml,
            status_form = status_form_xhtml,
            title = media.title,
            slug = media.slug,
            description = media.description,
            link = url_for(action='edit', id=media.id),
            duration = helpers.duration_from_seconds(media.duration),
        )

        return data
    def save(self, id, delete=None, **kwargs):
        """Save changes or create a category.

        See :class:`~mediacore.forms.admin.settings.categories.CategoryForm` for POST vars.

        :param id: Category ID
        :param delete: If true the category is to be deleted rather than saved.
        :type delete: bool
        :rtype: JSON dict
        :returns:
            success
                bool

        """
        if tmpl_context.form_errors:
            if request.is_xhr:
                return dict(success=False, errors=tmpl_context.form_errors)
            else:
                # TODO: Add error reporting for users with JS disabled?
                return redirect(action='edit')

        cat = fetch_row(Category, id)

        if delete:
            DBSession.delete(cat)
            data = dict(
                success = True,
                id = cat.id,
                parent_options = unicode(category_form.c['parent_id'].display()),
            )
        else:
            cat.name = kwargs['name']
            cat.slug = get_available_slug(Category, kwargs['slug'], cat)

            if kwargs['parent_id']:
                parent = fetch_row(Category, kwargs['parent_id'])
                if parent is not cat and cat not in parent.ancestors():
                    cat.parent = parent
            else:
                cat.parent = None

            DBSession.add(cat)
            DBSession.flush()

            data = dict(
                success = True,
                id = cat.id,
                name = cat.name,
                slug = cat.slug,
                parent_id = cat.parent_id,
                parent_options = unicode(category_form.c['parent_id'].display()),
                depth = cat.depth(),
                row = unicode(category_row_form.display(
                    action = url_for(id=cat.id),
                    category = cat,
                    depth = cat.depth(),
                    first_child = True,
                )),
            )

        if request.is_xhr:
            return data
        else:
            redirect(action='index', id=None)