示例#1
0
    def index(self, page=1, **kwargs):
        """List podcasts and podcast media.

        Our custom paginate decorator allows us to have fewer podcast episodes
        display on the first page than on the rest with the ``items_first_page``
        param. See :class:`mediacore.lib.custompaginate.CustomPage`.

        :param page: Page number, defaults to 1.
        :type page: int
        :rtype: dict
        :returns:
            podcasts
                The :class:`~mediacore.model.podcasts.Podcast` instance
            episodes
                The list of :class:`~mediacore.model.media.Media` instances
                for this page.

        """
        episodes = (
            DBSession.query(Media)
            .filter(Media.podcast_id != None)
            .order_by(Media.publish_on.desc())
            .options(orm.undefer("comment_count_published"))
        )
        episodes = self._filter(episodes)

        podcasts = DBSession.query(Podcast).options(orm.undefer("published_media_count")).all()

        return dict(podcasts=podcasts, episodes=episodes)
示例#2
0
    def index(self, page=1, search=None, podcast_filter=None, **kwargs):
        """List media with pagination and filtering.

        :param page: Page number, defaults to 1.
        :type page: int
        :param search: Optional search term to filter by
        :type search: unicode or None
        :param podcast_filter: Optional podcast to filter by
        :type podcast_filter: int or None
        :rtype: dict
        :returns:
            media
                The list of :class:`~mediacore.model.media.Media` instances
                for this page.
            search
                The given search term, if any
            search_form
                The :class:`~mediacore.forms.admin.SearchForm` instance
            podcast_filter
                The given podcast ID to filter by, if any
            podcast_filter_title
                The podcast name for rendering if a ``podcast_filter`` was specified.
            podcast_filter_form
                The :class:`~mediacore.forms.media.PodcastFilterForm` instance.


        """
        media = DBSession.query(Media)\
            .filter(Media.status.excludes('trash'))\
            .options(orm.undefer('comment_count_published'))\
            .options(orm.undefer('comment_count_unreviewed'))\
            .order_by(Media.status.desc(),
                      Media.publish_on.desc(),
                      Media.modified_on.desc())

        if search is not None:
            like_search = '%' + search + '%'
            media = media.filter(sql.or_(
                Media.title.like(like_search),
                Media.description.like(like_search),
                Media.notes.like(like_search),
                Media.tags.any(Tag.name.like(like_search)),
            ))

        podcast_filter_title = podcast_filter
        if podcast_filter == 'Unfiled':
            media = media.filter(~Media.podcast.has())
        elif podcast_filter is not None and podcast_filter != 'All Media':
            media = media.filter(Media.podcast.has(Podcast.id == podcast_filter))
            podcast_filter_title = DBSession.query(Podcast.title).get(podcast_filter)
            podcast_filter = int(podcast_filter)

        return dict(
            media = media,
            podcast_filter = podcast_filter,
            podcast_filter_title = podcast_filter_title,
            podcast_filter_form = podcast_filter_form,
            search = search,
            search_form = search_form,
        )
示例#3
0
class MediaForm(ListForm):
    template = 'admin/box-form.html'
    id = 'media-form'
    css_class = 'form'
    submit_text = None
    show_children_errors = True
    _name = 'media-form'  # TODO: Figure out why this is required??

    fields = [
        SingleSelectField('podcast',
                          label_text=N_('Include in the Podcast'),
                          css_classes=['dropdown-select'],
                          help_text=N_('Optional'),
                          options=lambda: [(None, None)] + DBSession.query(
                              Podcast.id, Podcast.title).all()),
        TextField('slug', label_text=N_('Permalink'), maxlength=50),
        TextField('title',
                  label_text=N_('Title'),
                  validator=TextField.validator(not_empty=True),
                  maxlength=255),
        TextField('author_name', label_text=N_('Author Name'), maxlength=50),
        TextField('author_email',
                  label_text=N_('Author Email'),
                  validator=email_validator(not_empty=True),
                  maxlength=255),
        XHTMLTextArea('description',
                      label_text=N_('Description'),
                      attrs=dict(rows=5, cols=25)),
        CategoryCheckBoxList(
            'categories',
            label_text=N_('Categories'),
            options=lambda: DBSession.query(Category.id, Category.name).all()),
        TextArea('tags',
                 label_text=N_('Tags'),
                 attrs=dict(rows=3, cols=15),
                 help_text=N_(u'e.g.: puppies, great dane, adorable')),
        TextArea('notes',
                 label_text=N_('Administrative Notes'),
                 attrs=dict(rows=3, cols=25),
                 container_attrs=lambda: ({
                     'class': 'hidden'
                 }, {})[bool(
                     app_globals.settings.get(
                         'wording_display_administrative_notes', ''))],
                 default=lambda: app_globals.settings[
                     'wording_administrative_notes']),
        SubmitButton('save',
                     default=N_('Save'),
                     named_button=True,
                     css_classes=['btn', 'blue', 'f-rgt']),
        SubmitButton('delete',
                     default=N_('Delete'),
                     named_button=True,
                     css_classes=['btn', 'f-lft']),
    ]

    def post_init(self, *args, **kwargs):
        events.Admin.MediaForm(self)
示例#4
0
    def index(self, page=1, search=None, media_filter=None, **kwargs):
        """List comments with pagination and filtering.

        :param page: Page number, defaults to 1.
        :type page: int
        :param search: Optional search term to filter by
        :type search: unicode or None
        :param media_filter: Optional media ID to filter by
        :type media_filter: int or None
        :rtype: dict
        :returns:
            comments
                The list of :class:`~mediacore.model.comments.Comment` instances
                for this page.
            edit_form
                The :class:`mediacore.forms.comments.EditCommentForm` instance,
                to be rendered for each instance in ``comments``.
            search
                The given search term, if any
            search_form
                The :class:`~mediacore.forms.admin.SearchForm` instance
            media_filter
                The given podcast ID to filter by, if any
            media_filter_title
                The media title for rendering if a ``media_filter`` was specified.

        """
        comments = DBSession.query(Comment)\
            .filter(Comment.status.excludes('trash'))\
            .order_by(Comment.status.desc(), Comment.created_on.desc())

        if search is not None:
            like_search = '%' + search + '%'
            comments = comments.filter(sql.or_(
                Comment.subject.like(like_search),
                Comment.body.like(like_search),
            ))

        media_filter_title = media_filter
        if media_filter is not None:
            comments = comments.filter(Comment.media.has(Media.id == media_filter))
            media_filter_title = DBSession.query(Media.title).get(media_filter)
            media_filter = int(media_filter)

        return dict(
            comments = comments,
            edit_form = edit_form,
            media_filter = media_filter,
            media_filter_title = media_filter_title,
            search = search,
            search_form = search_form,
        )
示例#5
0
def fetch_and_create_tags(tag_names):
    tag_dict = dict()
    for t in tag_names:
        tag_dict[slugify(t)] = t

    existing_tags = DBSession.query(Tag).filter(Tag.slug.in_(tag_dict.keys())).all()
    existing_slugs = [t.slug for t in existing_tags]
    new_slugs = [s for s in tag_dict.keys() if s not in existing_slugs]
    new_tags = [{'name': tag_dict[s], 'slug': s} for s in new_slugs]

    if new_tags:
        DBSession.connection().execute(tags.insert(), new_tags)
        DBSession.flush()
        existing_tags += DBSession.query(Tag).filter(Tag.slug.in_(new_slugs)).all()
    return existing_tags
示例#6
0
    def index(self, page=1, **kwargs):
        """List storage engines with pagination.

        :rtype: Dict
        :returns:
            engines
                The list of :class:`~mediacore.lib.storage.StorageEngine`
                instances for this page.

        """
        engines = DBSession.query(StorageEngine)\
            .options(orm.undefer('file_count'),
                     orm.undefer('file_size_sum'))\
            .all()
        engines = list(sort_engines(engines))
        existing_types = set(ecls.engine_type for ecls in engines)
        addable_engines = [
            ecls for ecls in StorageEngine
            if not ecls.is_singleton or ecls.engine_type not in existing_types
        ]

        return {
            'engines': engines,
            'addable_engines': addable_engines,
        }
示例#7
0
    def feed(self, slug, **kwargs):
        """Serve the feed as RSS 2.0.

        If :attr:`~mediacore.model.podcasts.Podcast.feedburner_url` is
        specified for this podcast, we redirect there.

        :param slug: A :attr:`~mediacore.model.podcasts.Podcast.slug`
        :param page: Page number, defaults to 1.
        :type page: int
        :rtype: dict
        :returns:
            podcast
                A :class:`~mediacore.model.podcasts.Podcast` instance.
            episodes
                A list of :class:`~mediacore.model.media.Media` instances
                that belong to the ``podcast``.
            podcasts
                A list of all the other podcasts

        """
        podcast = fetch_row(Podcast, slug=slug)
        episodes = self._filter(podcast.media).order_by(Media.publish_on.desc())

        podcasts = DBSession.query(Podcast).options(orm.undefer("published_media_count")).all()

        return dict(podcast=podcast, episodes=episodes, podcasts=podcasts)
 def test_can_fake_logged_in_user(self):
     admin = DBSession.query(User).filter(User.user_name==u'admin').one()
     assert_true(admin.has_permission(u'admin'))
     self.init_fake_request()
     self.set_authenticated_user(admin)
     
     assert_true(has_permission(u'admin'))
示例#9
0
    def index(self, page=1, category='topics', **kwargs):
        """List topics or tags with pagination.

        :param category: ``topics`` or ``tags``
        :param page: Page number, defaults to 1.
        :type page: int
        :rtype: Dict
        :returns:
            categories
                The list of :class:`~mediacore.model.tags.Tag`
                or :class:`~mediacore.model.topics.Topic`
                instances for this page.
            category
                ``topics`` or ``tags``
            category_name
                ``Topics`` or ``Tags``
            edit_form
                The :class:`~mediacore.forms.categories.EditCategoryForm` instance.

        """
        model = self.select_model(category)
        categories = DBSession.query(model).order_by(model.name)

        return dict(
            categories = categories,
            category = category,
            category_name = category.capitalize(),
            edit_form = edit_form,
        )
示例#10
0
    def test_can_fake_logged_in_user(self):
        admin = DBSession.query(User).filter(User.user_name == u'admin').one()
        assert_true(admin.has_permission(u'admin'))
        self.init_fake_request()
        self.set_authenticated_user(admin)

        assert_true(has_permission(u'admin'))
示例#11
0
 def _published_media_query(self):
     """Helper method for getting published media"""
     return DBSession.query(Media)\
         .filter(Media.status >= 'publish')\
         .filter(Media.publish_on <= datetime.now())\
         .filter(Media.status.excludes('trash'))\
         .order_by(Media.publish_on.desc())
示例#12
0
    def index(self, page=1, **kwargs):
        """List storage engines with pagination.

        :rtype: Dict
        :returns:
            engines
                The list of :class:`~mediacore.lib.storage.StorageEngine`
                instances for this page.

        """
        engines = DBSession.query(StorageEngine)\
            .options(orm.undefer('file_count'),
                     orm.undefer('file_size_sum'))\
            .all()
        engines = list(sort_engines(engines))
        existing_types = set(ecls.engine_type for ecls in engines)
        addable_engines = [
            ecls
            for ecls in StorageEngine
            if not ecls.is_singleton or ecls.engine_type not in existing_types
        ]

        return {
            'engines': engines,
            'addable_engines': addable_engines,
        }
 def permissions_for_request(cls, environ, config):
     identity = environ.get('repoze.who.identity', {})
     user_id = identity.get('repoze.who.userid')
     user = None
     if user_id is not None:
         user = DBSession.query(User).filter(User.user_id==user_id).first()
     return cls.permissions_for_user(user, config)
 def permissions_for_request(cls, environ, config):
     identity = environ.get('repoze.who.identity', {})
     user_id = identity.get('repoze.who.userid')
     user = None
     if user_id is not None:
         user = DBSession.query(User).filter(User.id==user_id).first()
     return cls.permissions_for_user(user, config)
示例#15
0
class GroupForm(ListForm):
    template = 'admin/box-form.html'
    id = 'group-form'
    css_class = 'form'
    submit_text = None
    show_children_errors = True

    event = events.Admin.GroupForm

    fields = [
        TextField('display_name',
                  label_text=N_('Display Name'),
                  validator=TextField.validator(not_empty=True),
                  maxlength=255),
        TextField('group_name',
                  label_text=N_('Groupname'),
                  validator=All(PlainText(not_empty=True), UniqueGroupname()),
                  maxlength=16),
        CheckBoxList(
            'permissions',
            label_text=N_('Group Permissions'),
            css_classes=['details_fieldset'],
            options=lambda: DBSession.query(Permission.permission_id,
                                            Permission.description).all()),
        SubmitButton('save',
                     default=N_('Save'),
                     named_button=True,
                     css_classes=['btn', 'btn-save', 'blue', 'f-rgt']),
        SubmitButton('delete',
                     default=N_('Delete'),
                     named_button=True,
                     css_classes=['btn', 'btn-delete']),
    ]
 def test_can_restrict_query_if_user_does_not_have_the_required_permission(self):
     query = Media.query
     permission = u'view'
     perm = self.perm()
     view_permission = DBSession.query(Permission).filter(Permission.permission_name == permission).one()
     view_permission.groups = []
     DBSession.flush()
     
     assert_none(self.policy.access_condition_for_query(query, permission, perm))
示例#17
0
    def _to_python(self, value, state):
        id = request.environ["pylons.routes_dict"]["id"]

        query = DBSession.query(User).filter_by(user_name=value)
        if id != "new":
            query = query.filter(User.user_id != id)

        if query.count() != 0:
            raise Invalid(_("User name already exists"), value, state)
        return value
示例#18
0
    def _to_python(self, value, state):
        id = request.environ['pylons.routes_dict']['id']

        query = DBSession.query(User).filter_by(user_name=value)
        if id != 'new':
            query = query.filter(User.user_id != id)

        if query.count() != 0:
            raise Invalid(_('User name already exists'), value, state)
        return value
示例#19
0
 def _create_user_with_admin_permission_only(self):
     admin_perm = DBSession.query(Permission).filter(Permission.permission_name == u'admin').one()
     second_admin_group = Group.example(name=u'Second admin group')
     admin_perm.groups.append(second_admin_group)
     admin = User.example(groups=[second_admin_group])
     DBSession.commit()
     perm = MediaCorePermissionSystem.permissions_for_user(admin, config)
     assert_true(perm.contains_permission(u'admin'))
     assert_false(perm.contains_permission(u'edit'))
     return admin
示例#20
0
def add_custom_profiles():
    # Add all the custom profiles to the first existing PandaStorage instance.
    from mediacore.model import DBSession
    from mediacoreext.simplestation.panda.lib.storage import PandaStorage
    ps = DBSession.query(PandaStorage).all()[0]
    profiles = ps.panda_helper().client.get_profiles()
    pnames = [p['name'] for p in profiles]
    for x in custom_profiles:
        if x['name'] not in pnames:
            ps.panda_helper().client.add_profile_from_preset(**x)
示例#21
0
    def _to_python(self, value, state):
        id = request.environ['pylons.routes_dict']['id']

        query = DBSession.query(User).filter_by(user_name=value)
        if id != 'new':
            query = query.filter(User.user_id != id)

        if query.count() != 0:
            raise Invalid(_('User name already exists'), value, state)
        return value
示例#22
0
 def _create_user_with_admin_permission_only(self):
     admin_perm = DBSession.query(Permission).filter(
         Permission.permission_name == u'admin').one()
     second_admin_group = Group.example(name=u'Second admin group')
     admin_perm.groups.append(second_admin_group)
     admin = User.example(groups=[second_admin_group])
     DBSession.commit()
     perm = MediaCorePermissionSystem.permissions_for_user(admin, config)
     assert_true(perm.contains_permission(u'admin'))
     assert_false(perm.contains_permission(u'edit'))
     return admin
示例#23
0
文件: players.py 项目: isaleem/cumin
def update_enabled_players():
    """Ensure that the encoding status of all media is up to date with the new
    set of enabled players.

    The encoding status of Media objects is dependent on there being an
    enabled player that supports that format. Call this method after changing
    the set of enabled players, to ensure encoding statuses are up to date.
    """
    from mediacore.model import DBSession, Media
    media = DBSession.query(Media)
    for m in media:
        m.update_status()
    def test_can_restrict_query_if_user_does_not_have_the_required_permission(
            self):
        query = Media.query
        permission = u'view'
        perm = self.perm()
        view_permission = DBSession.query(Permission).filter(
            Permission.permission_name == permission).one()
        view_permission.groups = []
        DBSession.flush()

        assert_none(
            self.policy.access_condition_for_query(query, permission, perm))
示例#25
0
def update_enabled_players():
    """Ensure that the encoding status of all media is up to date with the new
    set of enabled players.

    The encoding status of Media objects is dependent on there being an
    enabled player that supports that format. Call this method after changing
    the set of enabled players, to ensure encoding statuses are up to date.
    """
    from mediacore.model import DBSession, Media
    media = DBSession.query(Media)
    for m in media:
        m.update_status()
示例#26
0
    def __init__(self, *args, **kwargs):
        """Populate the :obj:`pylons.tmpl_context` with topics.

        Used by :data:`mediacore.templates.helpers` to render the
        topic index flyout slider.

        """
        super(MediaController, self).__init__(*args, **kwargs)
        tmpl_context.topics = DBSession.query(Topic)\
            .options(orm.undefer('published_media_count'))\
            .having(sql.text('published_media_count >= 1'))\
            .order_by(Topic.name)\
            .all()
示例#27
0
    def view(self, slug, podcast_slug=None, **kwargs):
        """Display the media player, info and comments.

        :param slug: The :attr:`~mediacore.models.media.Media.slug` to lookup
        :param podcast_slug: The :attr:`~mediacore.models.podcasts.Podcast.slug`
            for podcast this media belongs to. Although not necessary for
            looking up the media, it tells us that the podcast slug was
            specified in the URL and therefore we reached this action by the
            preferred route.
        :rtype dict:
        :returns:
            media
                The :class:`~mediacore.model.media.Media` instance for display.
            comment_form
                The :class:`~mediacore.forms.comments.PostCommentForm` instance.
            comment_form_action
                ``str`` comment form action
            comment_form_values
                ``dict`` form values
            next_episode
                The next episode in the podcast series, if this media belongs to
                a podcast, another :class:`~mediacore.model.media.Media`
                instance.

        """
        media = fetch_row(Media, slug=slug)
        media.views += 1

        next_episode = None
        if media.podcast_id is not None:
            # Always view podcast media from a URL that shows the context of the podcast
            if url_for() != url_for(podcast_slug=media.podcast.slug):
               redirect(podcast_slug=media.podcast.slug)

            if media.is_published:
                next_episode = DBSession.query(Media)\
                    .filter(Media.podcast_id == media.podcast.id)\
                    .filter(Media.publish_on > media.publish_on)\
                    .filter(Media.publish_on < datetime.now())\
                    .filter(Media.status >= 'publish')\
                    .filter(Media.status.excludes('trash'))\
                    .order_by(Media.publish_on)\
                    .first()

        return dict(
            media = media,
            comment_form = post_comment_form,
            comment_form_action = url_for(action='comment'),
            comment_form_values = kwargs,
            next_episode = next_episode,
        )
示例#28
0
    def index(self, page=1, **kwargs):
        """List users with pagination.

        :param page: Page number, defaults to 1.
        :type page: int
        :rtype: Dict
        :returns:
            users
                The list of :class:`~mediacore.model.auth.User`
                instances for this page.

        """
        users = DBSession.query(User).order_by(User.display_name, User.email_address)
        return dict(users=users)
示例#29
0
 def random(self, **kwargs):
     """Redirect to a randomly selected media item."""
     # TODO: Implement something more efficient than ORDER BY RAND().
     #       This method does a full table scan every time.
     media = Media.query.published()\
         .order_by(sql.func.random())\
         .first()
     if media is None:
         redirect(action='explore')
     if media.podcast_id:
         podcast_slug = DBSession.query(Podcast.slug).get(media.podcast_id)
     else:
         podcast_slug = None
     redirect(action='view', slug=media.slug, podcast_slug=podcast_slug)
示例#30
0
    def random(self, **kwargs):
        """Redirect to a randomly selected media item."""
        # TODO: Implement something more efficient than ORDER BY RAND().
        #       This method does a full table scan every time.
        random_query = Media.query.published().order_by(sql.func.random())
        media = viewable_media(random_query).first()

        if media is None:
            redirect(action='explore')
        if media.podcast_id:
            podcast_slug = DBSession.query(Podcast.slug).get(media.podcast_id)
        else:
            podcast_slug = None
        redirect(action='view', slug=media.slug, podcast_slug=podcast_slug)
示例#31
0
    def _fetch_page(self, type='awaiting_review', page=1, items_per_page=6):
        """Helper method for paginating media results"""
        query = DBSession.query(Media).order_by(Media.modified_on.desc())

        if type == 'awaiting_review':
            query = query.filter(Media.status.intersects('unreviewed'))\
                         .filter(Media.status.excludes('trash'))
        elif type == 'awaiting_encoding':
            query = query.filter(Media.status.intersects('unencoded'))\
                         .filter(Media.status.excludes('trash,unreviewed'))
        elif type == 'awaiting_publishing':
            query = query.filter(Media.status.issubset('draft'))

        return webhelpers.paginate.Page(query, page, items_per_page)
示例#32
0
    def __init__(self, *args, **kwargs):
        """Populate the :obj:`pylons.tmpl_context`` with topics.

        Used by :data:`mediacore.templates.helpers` to render the
        topic index flyout slider.

        """
        super(PodcastsController, self).__init__(*args, **kwargs)
        tmpl_context.topics = (
            DBSession.query(Topic)
            .options(orm.undefer("published_media_count"))
            .filter(Topic.published_media_count >= 1)
            .order_by(Topic.name)
            .all()
        )
示例#33
0
    def most_popular(self, **kwargs):
        """Expose basic info of the latest media object.

        .. todo:: Work this into a more general, documented API scheme.

        :rtype: JSON dict

        """
        media_query = DBSession.query(Media)\
            .filter(Media.status >= 'publish')\
            .filter(Media.publish_on <= datetime.now())\
            .filter(Media.status.excludes('trash'))\
            .order_by(Media.views.desc())

        media = media_query.first()
        return self._jsonify(media)
示例#34
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 ids: An optional string of IDs separated by commas.
        :type ids: ``unicode`` or ``None``
        :param status: ``"approve"`` or ``"trash"`` depending on what action
            the user requests.
        :rtype: JSON dict
        :returns:
            success
                bool
            ids
                A list of :attr:`~mediacore.model.comments.Comment.id`
                that have changed.

        """
        if id == 'bulk':
            ids = ids.split(',')
        else:
            ids = [id]

        approve = status == 'approve'
        comments = DBSession.query(Comment)\
            .filter(Comment.id.in_(ids))\
            .all()

        for comment in comments:
            if approve:
                comment.status.discard('unreviewed')
                comment.status.add('publish')
            else:
                comment.status.add('trash')
            DBSession.add(comment)

        if request.is_xhr:
            return dict(success=True, ids=ids)
        else:
            redirect(action='index')
示例#35
0
    def tags(self, slug=None, page=1, **kwargs):
        if slug:
            tag = fetch_row(Tag, slug=slug)
            media_query = self._published_media_query\
                .filter(Media.tags.contains(tag))\
                .options(orm.undefer('comment_count_published'))
            media = media_query
            tags = None
        else:
            tag = None
            media = []
            tags = DBSession.query(Tag)\
                .options(orm.undefer('published_media_count'))\
                .having(sql.text('published_media_count >= 1'))\
                .order_by(Tag.name)\
                .all()

        return dict(
            media = media,
            tag = tag,
            tags = tags,
        )
示例#36
0
class ImportVideosForm(ListForm):
    template = 'admin/box-form.html'
    id = 'settings-form'
    css_class = 'form'
    submit_text = None
    fields = [
        ListFieldSet(
            'youtube',
            suppress_label=True,
            legend='',
            css_classes=['details_fieldset'],
            children=[
                TextArea(
                    'channel_names',
                    attrs=dict(rows=3, cols=20),
                    label_text=_('Channel Name(s)'),
                    help_text=
                    _('One or more channel names (separated by commas) to import. Please enter only the channel/user name, not the full URL. Please be aware that it may take several minutes for the import to complete. When all videos have been imported, you will be returned to the Media page to manage your new videos.'
                      ),
                    validator=NotEmpty),
                CheckBox(
                    'auto_publish',
                    label_text=_('Publish Videos'),
                    help_text=
                    _('When this is selected, videos are published automatically when they are imported. Otherwise the videos will be added, but will be waiting for review before being published.'
                      )),
                CategoryCheckBoxList('categories',
                                     label_text=_('Categories'),
                                     options=lambda: DBSession.query(
                                         Category.id, Category.name).all()),
                TextArea('tags',
                         label_text=_('Tags'),
                         attrs=dict(rows=3, cols=15),
                         help_text=_(u'e.g.: puppies, great dane, adorable')),
                SubmitButton('save',
                             default=_('Import'),
                             css_classes=['btn', 'btn-save', 'blue', 'f-rgt']),
            ])
    ]
示例#37
0
    def view(self, slug, page=1, **kwargs):
        """View a podcast and the media that belongs to it.

        :param slug: A :attr:`~mediacore.model.podcasts.Podcast.slug`
        :param page: Page number, defaults to 1.
        :type page: int
        :rtype: dict
        :returns:
            podcast
                A :class:`~mediacore.model.podcasts.Podcast` instance.
            episodes
                A list of :class:`~mediacore.model.media.Media` instances
                that belong to the ``podcast``.
            podcasts
                A list of all the other podcasts

        """
        podcast = fetch_row(Podcast, slug=slug)
        episodes = self._filter(podcast.media).order_by(Media.publish_on.desc())

        podcasts = DBSession.query(Podcast).options(orm.undefer("published_media_count")).all()

        return dict(podcast=podcast, episodes=episodes, podcasts=podcasts)
示例#38
0
文件: api.py 项目: isaleem/cumin
def enabled_engines():
    from mediacore.model import DBSession
    engines = DBSession.query(StorageEngine)\
        .filter(StorageEngine.enabled == True)\
        .all()
    return list(sort_engines(engines))
示例#39
0
 def __before__(self, *args, **kwargs):
     """Load all our settings before each request."""
     BaseController.__before__(self, *args, **kwargs)
     from mediacore.model import Setting
     tmpl_context.settings = dict(DBSession.query(Setting.key, Setting))
示例#40
0
def setup_app(command, conf, vars):
    """Called by ``paster setup-app``.

    This script is responsible for:

        * Creating the initial database schema and loading default data.
        * Executing any migrations necessary to bring an existing database
          up-to-date. Your data should be safe but, as always, be sure to
          make backups before using this.
        * Re-creating the default database for every run of the test suite.

    XXX: All your data will be lost IF you run the test suite with a
         config file named 'test.ini'. Make sure you have this configured
         to a different database than in your usual deployment.ini or
         development.ini file because all database tables are dropped a
         and recreated every time this script runs.

    XXX: If you are upgrading from MediaCore v0.7.2 or v0.8.0, run whichever
         one of these that applies:
           ``python batch-scripts/upgrade/upgrade_from_v072.py deployment.ini``
           ``python batch-scripts/upgrade/upgrade_from_v080.py deployment.ini``

    XXX: For search to work, we depend on a number of MySQL triggers which
         copy the data from our InnoDB tables to a MyISAM table for its
         fulltext indexing capability. Triggers can only be installed with
         a mysql superuser like root, so you must run the setup_triggers.sql
         script yourself.

    """
    config = load_environment(conf.global_conf, conf.local_conf)
    plugin_manager = config['pylons.app_globals'].plugin_mgr
    mediacore_migrator = MediaCoreMigrator.from_config(conf, log=log)
    
    engine = metadata.bind
    db_connection = engine.connect()
    # simplistic check to see if MediaCore tables are present, just check for
    # the media_files table and assume that all other tables are there as well
    from mediacore.model.media import media_files
    mediacore_tables_exist = engine.dialect.has_table(db_connection, media_files.name)
    
    run_migrations = True
    if not mediacore_tables_exist:
        head_revision = mediacore_migrator.head_revision()
        log.info('Initializing new database with version %r' % head_revision)
        metadata.create_all(bind=DBSession.bind, checkfirst=True)
        mediacore_migrator.init_db(revision=head_revision)
        run_migrations = False
        add_default_data()
        for migrator in plugin_manager.migrators():
            migrator.init_db()
        events.Environment.database_initialized()
    elif not mediacore_migrator.migrate_table_exists():
        log.error('No migration table found, probably your MediaCore install '
            'is too old (< 0.9?). Please upgrade to MediaCore CE 0.9 first.')
        raise AssertionError('no migration table found')
    elif not mediacore_migrator.alembic_table_exists():
        alembic_revision = mediacore_migrator.map_migrate_version()
        mediacore_migrator.stamp(alembic_revision)
    if run_migrations:
        mediacore_migrator.migrate_db()
        for migrator in plugin_manager.migrators():
            migrator.migrate_db()
        events.Environment.database_migrated()
    
    cleanup_players_table(enabled=True)
    
    # Save everything, along with the dummy data if applicable
    DBSession.commit()
    events.Environment.database_ready()

    log.info('Generating appearance.css from your current settings')
    settings = DBSession.query(Setting.key, Setting.value)
    generate_appearance_css(settings, cache_dir=conf['cache_dir'])

    log.info('Successfully setup')
示例#41
0
def add_new_media_file(media, file=None, url=None):
    """Create a MediaFile instance from the given file or URL.

    This function MAY modify the given media object.

    :type media: :class:`~mediacore.model.media.Media` instance
    :param media: The media object that this file or URL will belong to.
    :type file: :class:`cgi.FieldStorage` or None
    :param file: A freshly uploaded file object.
    :type url: unicode or None
    :param url: A remote URL string.
    :rtype: :class:`~mediacore.model.media.MediaFile`
    :returns: A newly created media file instance.
    :raises StorageError: If the input file or URL cannot be
        stored with any of the registered storage engines.

    """
    from mediacore.model import DBSession, MediaFile
    engines = DBSession.query(StorageEngine)\
        .filter(StorageEngine.enabled == True)\
        .all()
    sorted_engines = list(sort_engines(engines))

    for engine in sorted_engines:
        try:
            meta = engine.parse(file=file, url=url)
            log.debug('Engine %r returned meta %r', engine, meta)
            break
        except UnsuitableEngineError:
            log.debug('Engine %r unsuitable for %r/%r', engine, file, url)
            continue
    else:
        raise StorageError(_('Unusable file or URL provided.'), None, None)

    mf = MediaFile()
    mf.storage = engine
    mf.media = media

    mf.type = meta['type']
    mf.display_name = meta.get('display_name', default_display_name(file, url))
    mf.unique_id = meta.get('unique_id', None)

    mf.container = meta.get('container', None)
    mf.size = meta.get('size', None)
    mf.bitrate = meta.get('bitrate', None)
    mf.width = meta.get('width', None)
    mf.height = meta.get('height', None)

    media.files.append(mf)
    DBSession.flush()

    unique_id = engine.store(media_file=mf, file=file, url=url, meta=meta)

    if unique_id:
        mf.unique_id = unique_id
    elif not mf.unique_id:
        raise StorageError('Engine %r returned no unique ID.', engine)

    if not media.duration and meta.get('duration', 0):
        media.duration = meta['duration']
    if not media.description and meta.get('description'):
        media.description = clean_xhtml(meta['description'])
    if not media.title:
        media.title = meta.get('title', None) or mf.display_name
    if media.type is None:
        media.type = mf.type

    if ('thumbnail_url' in meta or 'thumbnail_file' in meta) \
    and (not has_thumbs(media) or has_default_thumbs(media)):
        thumb_file = meta.get('thumbnail_file', None)

        if thumb_file is not None:
            thumb_filename = thumb_file.filename
        else:
            thumb_url = meta['thumbnail_url']
            thumb_filename = os.path.basename(thumb_url)

            # Download the image to a buffer and wrap it as a file-like object
            try:
                temp_img = urlopen(thumb_url)
                thumb_file = StringIO(temp_img.read())
                temp_img.close()
            except URLError, e:
                log.exception(e)

        if thumb_file is not None:
            create_thumbs_for(media, thumb_file, thumb_filename)
            thumb_file.close()
 def fetch_settings():
     from mediacore.model import DBSession, Setting
     settings_dict = dict(DBSession.query(Setting.key, Setting.value))
     return settings_dict
示例#43
0
 def fetch_settings():
     from mediacore.model import DBSession, Setting
     settings_dict = dict(DBSession.query(Setting.key, Setting.value))
     return settings_dict
示例#44
0
 def editor_group(self):
     return DBSession.query(Group).filter(
         Group.group_name == u'editors').one()
示例#45
0
 def permissions(self):
     db_permissions = DBSession.query(Permission).all()
     return tuple(
         [permission.permission_name for permission in db_permissions])
示例#46
0
 def __before__(self, *args, **kwargs):
     """Load all our settings before each request."""
     BaseController.__before__(self, *args, **kwargs)
     from mediacore.model import Setting
     tmpl_context.settings = dict(DBSession.query(Setting.key, Setting))
示例#47
0
 def editor_group(self):
     return DBSession.query(Group).filter(Group.group_name == u'editors').one()
示例#48
0
def enabled_engines():
    from mediacore.model import DBSession
    engines = DBSession.query(StorageEngine)\
        .filter(StorageEngine.enabled == True)\
        .all()
    return list(sort_engines(engines))
    def perm(self):
        system = MediaCorePermissionSystem(self.pylons_config)
        system.policies = [self.policy]

        user = DBSession.query(User).filter(User.user_name == u'admin').one()
        return UserPermissions(user, system)
示例#50
0
def setup_app(command, conf, vars):
    """Called by ``paster setup-app``.

    This script is responsible for:

        * Creating the initial database schema and loading default data.
        * Executing any migrations necessary to bring an existing database
          up-to-date. Your data should be safe but, as always, be sure to
          make backups before using this.
        * Re-creating the default database for every run of the test suite.

    XXX: All your data will be lost IF you run the test suite with a
         config file named 'test.ini'. Make sure you have this configured
         to a different database than in your usual deployment.ini or
         development.ini file because all database tables are dropped a
         and recreated every time this script runs.

    XXX: If you are upgrading from MediaCore v0.7.2 or v0.8.0, run whichever
         one of these that applies:
           ``python batch-scripts/upgrade/upgrade_from_v072.py deployment.ini``
           ``python batch-scripts/upgrade/upgrade_from_v080.py deployment.ini``

    XXX: For search to work, we depend on a number of MySQL triggers which
         copy the data from our InnoDB tables to a MyISAM table for its
         fulltext indexing capability. Triggers can only be installed with
         a mysql superuser like root, so you must run the setup_triggers.sql
         script yourself.

    """
    if pylons.test.pylonsapp:
        # NOTE: This extra filename check may be unnecessary, the example it is
        # from did not check for pylons.test.pylonsapp. Leaving it in for now
        # to make it harder for someone to accidentally delete their database.
        filename = os.path.split(conf.filename)[-1]
        if filename == 'test.ini':
            log.info('Dropping existing tables...')
            metadata.drop_all(checkfirst=True)
            drop_version_control(conf.local_conf['sqlalchemy.url'],
                                 migrate_repository)
    else:
        # Don't reload the app if it was loaded under the testing environment
        config = load_environment(conf.global_conf, conf.local_conf)

    # Create the migrate_version table if it doesn't exist.
    # If the table doesn't exist, we assume the schema was just setup
    # by this script and therefore must be the latest version.
    latest_version = version(migrate_repository)
    try:
        version_control(conf.local_conf['sqlalchemy.url'],
                        migrate_repository,
                        version=latest_version)
    except DatabaseAlreadyControlledError:
        log.info('Running any new migrations, if there are any')
        upgrade(conf.local_conf['sqlalchemy.url'],
                migrate_repository,
                version=latest_version)
    else:
        log.info('Initializing new database with version %r' % latest_version)
        metadata.create_all(bind=DBSession.bind, checkfirst=True)
        add_default_data()

    cleanup_players_table(enabled=True)

    # Save everything, along with the dummy data if applicable
    DBSession.commit()

    log.info('Generating appearance.css from your current settings')
    settings = DBSession.query(Setting.key, Setting.value)
    generate_appearance_css(settings, cache_dir=conf['cache_dir'])

    log.info('Successfully setup')
示例#51
0
class UserForm(ListForm):
    template = 'admin/box-form.html'
    id = 'user-form'
    css_class = 'form'
    submit_text = None
    show_children_errors = True
    _name = 'user-form'  # TODO: Figure out why this is required??

    fields = [
        TextField('display_name',
                  label_text=N_('Display Name'),
                  validator=TextField.validator(not_empty=True),
                  maxlength=255),
        TextField('email_address',
                  label_text=N_('Email Address'),
                  validator=email_validator(not_empty=True),
                  maxlength=255),
        ListFieldSet(
            'login_details',
            suppress_label=True,
            legend=N_('Login Details:'),
            css_classes=['details_fieldset'],
            validator=Schema(chained_validators=[
                FieldsMatch('password',
                            'confirm_password',
                            messages={
                                'invalidNoMatch': N_("Passwords do not match"),
                            })
            ]),
            children=[
                SingleSelectField(
                    'group',
                    label_text=N_('Group'),
                    options=lambda: DBSession.query(Group.group_id, Group.
                                                    display_name).all()),
                TextField('user_name',
                          label_text=N_('Username'),
                          maxlength=16,
                          validator=All(PlainText(),
                                        UniqueUsername(not_empty=True))),
                PasswordField('password',
                              label_text=N_('Password'),
                              validators=NotEmpty,
                              maxlength=80,
                              attrs={'autocomplete': 'off'}),
                PasswordField('confirm_password',
                              label_text=N_('Confirm password'),
                              validators=NotEmpty,
                              maxlength=80,
                              attrs={'autocomplete': 'off'}),
            ]),
        SubmitButton('save',
                     default=N_('Save'),
                     named_button=True,
                     css_classes=['btn', 'btn-save', 'blue', 'f-rgt']),
        SubmitButton('delete',
                     default=N_('Delete'),
                     named_button=True,
                     css_classes=['btn', 'btn-delete']),
    ]

    def post_init(self, *args, **kwargs):
        events.Admin.UserForm(self)