Beispiel #1
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)
 def test_metagroup_assignment_does_not_fail_if_groups_are_not_found_in_db(self):
     DBSession.delete(self.anonymous)
     DBSession.delete(self.authenticated)
     DBSession.flush()
     
     user = User.example()
     self.assert_user_groups([], user)
Beispiel #3
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 save_fields(**result):
    """Save SEO settings to the database on a Media item save.

    When the :attr:`mediacore.plugin.events.Admin.MediaController.save`
    event is triggered it receives the dict of values returned by
    :meth:`mediacore.controllers.admin.media.MediaController.save`.

    The SEO values are extracted from tmpl_context.form_values and if
    a value was entered it is saved. If a valid setting was found, but
    it does not have a value, we remove it form the given media item.

    :param result: A dict of form values for the Media item
    :param type: dict
    :returns: A dict of form values for the Media item
    :rtpye: dict

    """

    media = Media.query.get(result['media_id'])
    for key, value in tmpl_context.form_values['seo'].iteritems():
        meta_key = u'seo_%s' % key
        if value:
            media.meta[meta_key] = value
        elif meta_key in media.meta:
            DBSession.delete(media._meta[meta_key])
    return result
Beispiel #5
0
def save_fields(**result):
    """Save SEO settings to the database on a Media item save.

    When the :attr:`mediacore.plugin.events.Admin.MediaController.save`
    event is triggered it receives the dict of values returned by
    :meth:`mediacore.controllers.admin.media.MediaController.save`.

    The SEO values are extracted from tmpl_context.form_values and if
    a value was entered it is saved. If a valid setting was found, but
    it does not have a value, we remove it form the given media item.

    :param result: A dict of form values for the Media item
    :param type: dict
    :returns: A dict of form values for the Media item
    :rtpye: dict

    """

    media = Media.query.get(result['media_id'])
    for key, value in tmpl_context.form_values['seo'].iteritems():
        meta_key = u'seo_%s' % key
        if value:
            media.meta[meta_key] = value
        elif meta_key in media.meta:
            DBSession.delete(media._meta[meta_key])
    return result
Beispiel #6
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)
Beispiel #7
0
 def disassociate_video_id(self, media_file, video_id):
     # Create a meta_key for this MediaCore::MediaFile -> Panda::Video pairing.
     # This is sort of a perversion of the meta table, but hey, it works.
     meta_key = u"%s%s" % (META_VIDEO_PREFIX, video_id)
     mfm = DBSession.query(MediaFilesMeta)\
             .filter(MediaFilesMeta.media_files_id==media_file.id)\
             .filter(MediaFilesMeta.key==meta_key)
     for x in mfm:
         DBSession.delete(x)
Beispiel #8
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 #9
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 #10
0
    def delete(self, id, **kwargs):
        """Delete a group.

        :param id: Group ID.
        :type id: ``int``
        :returns: Redirect back to :meth:`index` after successful delete.
        """
        group = fetch_row(Group, id)
        DBSession.delete(group)

        if request.is_xhr:
            return dict(success=True)
        redirect(action='index', id=None)
Beispiel #11
0
    def delete(self, id, **kwargs):
        """Delete a user.

        :param id: User ID.
        :type id: ``int``
        :returns: Redirect back to :meth:`index` after successful delete.
        """
        user = fetch_row(User, id)
        DBSession.delete(user)

        if request.is_xhr:
            return dict(success=True)
        redirect(action='index', id=None)
    def delete(self, id, **kwargs):
        """Delete a group.

        :param id: Group ID.
        :type id: ``int``
        :returns: Redirect back to :meth:`index` after successful delete.
        """
        group = fetch_row(Group, id)
        DBSession.delete(group)

        if request.is_xhr:
            return dict(success=True)
        redirect(action='index', id=None)
Beispiel #13
0
 def _delete_media(self, media):
     # FIXME: Ensure that if the first file is deleted from the file system,
     #        then the second fails, the first file is deleted from the
     #        and not not linking to a nonexistent file.
     # Delete every file from the storage engine
     for file in media.files:
         file.storage.delete(file.unique_id)
         # Remove this item from the DBSession so that the foreign key
         # ON DELETE CASCADE can take effect.
         DBSession.expunge(file)
     # Delete the media
     DBSession.delete(media)
     DBSession.flush()
     # Cleanup the thumbnails
     delete_thumbs(media)
Beispiel #14
0
 def _delete_media(self, media):
     # FIXME: Ensure that if the first file is deleted from the file system,
     #        then the second fails, the first file is deleted from the
     #        file system and not linking to a nonexistent file.
     # Delete every file from the storage engine
     for file in media.files:
         file.storage.delete(file.unique_id)
         # Remove this item from the DBSession so that the foreign key
         # ON DELETE CASCADE can take effect.
         DBSession.expunge(file)
     # Delete the media
     DBSession.delete(media)
     DBSession.flush()
     # Cleanup the thumbnails
     delete_thumbs(media)
Beispiel #15
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
Beispiel #16
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 #17
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 #18
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 #19
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 #20
0
    def uploadThumb(self, thumb_file, podcastid, reviewed=False, **kwargs):
        """Save a thumbnail uploaded with :class:`~mediacore.forms.admin.ThumbForm`.
 
        :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.

        """ 
        media = Media() 
	media.author =  Author('user', '*****@*****.**')
	media.title = os.path.basename(thumb_file.filename)
	media.slug = get_available_slug(Media, '_stub_' + media.title)
	media.reviewed = reviewed
	media.views = podcastid
	DBSession.add(media)
	DBSession.flush() 
	
        try:
            # Create JPEG thumbs
            create_thumbs_for(media, thumb_file.file, thumb_file.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_file.filename)[1].lstrip('.')
            elif e.message == 'cannot read interlaced PNG files':
                message = _('Interlaced PNGs are not supported.')
            else:
                raise
    def save(self, id, display_name, group_name, 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

        DBSession.add(group)

        redirect(action='index', id=None)
Beispiel #22
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 #23
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 #24
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 #25
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:
            DBSession.delete(podcast)
            DBSession.commit()
            delete_thumbs(podcast)
            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 #26
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["groups"]:
            query = DBSession.query(Group).filter(Group.group_id.in_(login_details["groups"]))
            user.groups = list(query.all())
        else:
            user.groups = []

        DBSession.add(user)

        # Check if we're changing the logged in user's own password
        if user.id == request.perm.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)
    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 #28
0
    def merge_stubs(self, orig_id, input_id, **kwargs):
        """Merge in a newly created media item.

        This is merges media that has just been created. It must have:
            1. a non-default thumbnail, or
            2. a file, or
            3. a title, description, etc

        :param orig_id: Media ID to copy data to
        :type orig_id: ``int``
        :param input_id: Media ID to source files, thumbs, etc from
        :type input_id: ``int``
        :returns: JSON dict

        """
        orig = fetch_row(Media, orig_id)
        input = fetch_row(Media, input_id)
        merged_files = []

        # Merge in the file(s) from the input stub
        if input.slug.startswith('_stub_') and input.files:
            for file in input.files[:]:
                # XXX: The filename will still use the old ID
                file.media = orig
                merged_files.append(file)
            DBSession.delete(input)

        # The original is a file or thumb stub, copy in the new values
        elif orig.slug.startswith('_stub_') \
        and not input.slug.startswith('_stub_'):
            DBSession.delete(input)
            DBSession.flush()
            orig.podcast = input.podcast
            orig.title = input.title
            orig.subtitle = input.subtitle
            orig.slug = input.slug
            orig.author = input.author
            orig.description = input.description
            orig.notes = input.notes
            orig.duration = input.duration
            orig.views = input.views
            orig.likes = input.likes
            orig.publish_on = input.publish_on
            orig.publish_until = input.publish_until
            orig.categories = input.categories
            orig.tags = input.tags
            orig.update_popularity()

        # Copy the input thumb over the default thumbnail
        elif input.slug.startswith('_stub_') \
        and has_default_thumbs(orig) \
        and not has_default_thumbs(input):
            for key, dst_path in thumb_paths(orig).iteritems():
                src_path = thumb_path(input, key)
                # This will raise an OSError on Windows, but not *nix
                os.rename(src_path, dst_path)
            DBSession.delete(input)

        # Report an error
        else:
            return dict(
                success = False,
                message = u'No merge operation fits.',
            )

        orig.update_status()

        status_form_xhtml = unicode(update_status_form.display(
            action=url_for(action='update_status', id=orig.id),
            media=orig))

        file_xhtml = {}
        for file in merged_files:
            file_xhtml[file.id] = unicode(edit_file_form.display(
                action=url_for(action='edit_file', id=orig.id),
                file=file))

        return dict(
            success = True,
            media_id = orig.id,
            title = orig.title,
            link = url_for(action='edit', id=orig.id),
            status_form = status_form_xhtml,
            file_forms = file_xhtml,
        )
Beispiel #29
0
    def edit_file(self, id, file_id, file_type=None, duration=None, delete=None, bitrate=None, width_height=None, **kwargs):
        """Save action for the :class:`~mediacore.forms.admin.media.EditFileForm`.

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

        XXX: We do NOT use the @validate decorator due to complications with
             partial validation. The JS sends only the value it wishes to
             change, so we only want to validate that one value.
             FancyValidator.if_missing seems to eat empty values and assign
             them None, but there's an important difference to us between
             None (no value from the user) and an empty value (the user
             is clearing the value of a field).

        :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)
        file_id = int(file_id) # Just in case validation failed somewhere.

        for file in media.files:
            if file.id == file_id:
                break
        else:
            file = None

        fields = edit_file_form.c
        try:
            if file is None:
                data['message'] = _('File "%s" does not exist.') % file_id
            elif file_type:
                file.type = fields.file_type.validate(file_type)
                data['success'] = True
            elif duration is not None:
                media.duration = duration = fields.duration.validate(duration)
                data['success'] = True
                data['duration'] = helpers.duration_from_seconds(media.duration)
            elif width_height is not None:
                width_height = fields.width_height.validate(width_height)
                file.width, file.height = width_height or (0, 0)
                data['success'] = True
            elif bitrate is not None:
                file.bitrate = fields.bitrate.validate(bitrate)
                data['success'] = True
            elif delete:
                file.storage.delete(file.unique_id)
                DBSession.delete(file)
                DBSession.flush()
                media = fetch_row(Media, id)
                data['success'] = True
            else:
                data['message'] = _('No action to perform.')
        except Invalid, e:
            data['success'] = False
            data['message'] = unicode(e)
Beispiel #30
0
        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
        except Exception:
            if id == 'new':
                DBSession.delete(media)
            raise

        return dict(
            success = success,
            message = message,
            id = media.id,
            title = media.title,
            slug = media.slug,
            link = url_for(action='edit', id=media.id),
        )


    @expose('json', request_method='POST')
    @validate(update_status_form, error_handler=edit)
    @autocommit
Beispiel #31
0
    def merge_stubs(self, orig_id, input_id, **kwargs):
        """Merge in a newly created media item.

        This is merges media that has just been created. It must have:
            1. a non-default thumbnail, or
            2. a file, or
            3. a title, description, etc

        :param orig_id: Media ID to copy data to
        :type orig_id: ``int``
        :param input_id: Media ID to source files, thumbs, etc from
        :type input_id: ``int``
        :returns: JSON dict

        """
        orig = fetch_row(Media, orig_id)
        input = fetch_row(Media, input_id)
        merged_files = []

        # Merge in the file(s) from the input stub
        if input.slug.startswith('_stub_') and input.files:
            for file in input.files[:]:
                # XXX: The filename will still use the old ID
                file.media = orig
                merged_files.append(file)
            DBSession.delete(input)

        # The original is a file or thumb stub, copy in the new values
        elif orig.slug.startswith('_stub_') \
        and not input.slug.startswith('_stub_'):
            DBSession.delete(input)
            DBSession.flush()
            orig.podcast = input.podcast
            orig.title = input.title
            orig.subtitle = input.subtitle
            orig.slug = input.slug
            orig.author = input.author
            orig.description = input.description
            orig.notes = input.notes
            orig.duration = input.duration
            orig.views = input.views
            orig.likes = input.likes
            orig.publish_on = input.publish_on
            orig.publish_until = input.publish_until
            orig.categories = input.categories
            orig.tags = input.tags
            orig.update_popularity()

        # Copy the input thumb over the default thumbnail
        elif input.slug.startswith('_stub_') \
        and has_default_thumbs(orig) \
        and not has_default_thumbs(input):
            for key, dst_path in thumb_paths(orig).iteritems():
                src_path = thumb_path(input, key)
                # This will raise an OSError on Windows, but not *nix
                os.rename(src_path, dst_path)
            DBSession.delete(input)

        # Report an error
        else:
            return dict(
                success = False,
                message = u'No merge operation fits.',
            )

        orig.update_status()

        status_form_xhtml = unicode(update_status_form.display(
            action=url_for(action='update_status', id=orig.id),
            media=orig))

        file_xhtml = {}
        for file in merged_files:
            file_xhtml[file.id] = unicode(edit_file_form.display(
                action=url_for(action='edit_file', id=orig.id),
                file=file))

        return dict(
            success = True,
            media_id = orig.id,
            title = orig.title,
            link = url_for(action='edit', id=orig.id),
            status_form = status_form_xhtml,
            file_forms = file_xhtml,
        )
Beispiel #32
0
    def edit_file(self, id, file_id, file_type=None, duration=None, delete=None, bitrate=None, width_height=None, **kwargs):
        """Save action for the :class:`~mediacore.forms.admin.media.EditFileForm`.

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

        XXX: We do NOT use the @validate decorator due to complications with
             partial validation. The JS sends only the value it wishes to
             change, so we only want to validate that one value.
             FancyValidator.if_missing seems to eat empty values and assign
             them None, but there's an important difference to us between
             None (no value from the user) and an empty value (the user
             is clearing the value of a field).

        :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)
        file_id = int(file_id) # Just in case validation failed somewhere.

        for file in media.files:
            if file.id == file_id:
                break
        else:
            file = None

        fields = edit_file_form.c
        try:
            if file is None:
                data['message'] = _('File "%s" does not exist.') % file_id
            elif file_type:
                file.type = fields.file_type.validate(file_type)
                data['success'] = True
            elif duration is not None:
                media.duration = duration = fields.duration.validate(duration)
                data['success'] = True
                data['duration'] = helpers.duration_from_seconds(media.duration)
            elif width_height is not None:
                width_height = fields.width_height.validate(width_height)
                file.width, file.height = width_height or (0, 0)
                data['success'] = True
            elif bitrate is not None:
                file.bitrate = fields.bitrate.validate(bitrate)
                data['success'] = True
            elif delete:
                file.storage.delete(file.unique_id)
                DBSession.delete(file)
                DBSession.flush()
                media = fetch_row(Media, id)
                data['success'] = True
            else:
                data['message'] = _('No action to perform.')
        except Invalid, e:
            data['success'] = False
            data['message'] = unicode(e)
Beispiel #33
0
    def edit_file(self, id, file_id, file_type=None, duration=None, delete=None, **kwargs):
        """Save action for the :class:`~mediacore.forms.admin.media.EditFileForm`.

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

        TODO: Use the form validators to validate this form. We only
              POST one field at a time, so the validate decorator doesn't
              work, because it doesn't work for partial validation, because
              none of the kwargs are updated if an Invalid exception is
              raised by any validator.

        :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 == file_id][0]
        except IndexError:
            file = None

        if file is None:
            data['message'] = 'File "%s" does not exist.' % file_id
        elif file_type:
            file.type = file_type
            DBSession.add(file)
            data['success'] = True
        elif duration is not None:
            try:
                duration = helpers.duration_to_seconds(duration)
            except ValueError:
                data['message'] = 'Bad duration formatting, use Hour:Min:Sec'
            else:
                media.duration = duration
                DBSession.add(media)
                data['success'] = True
                data['duration'] = helpers.duration_from_seconds(duration)
        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_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 #34
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:
            file_paths = thumb_paths(media).values()
            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)
            DBSession.commit()
            helpers.delete_files(file_paths, Media._thumb_dir)
            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':
            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)
    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)
Beispiel #36
0
            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('.')
            else:
                raise
        except Exception:
            if id == 'new':
                DBSession.delete(media)
            raise

        return dict(
            success = success,
            message = message,
            id = media.id,
            title = media.title,
            slug = media.slug,
            link = url_for(action='edit', id=media.id),
        )


    @expose('json', request_method='POST')
    @validate(update_status_form, error_handler=edit)
    @autocommit