示例#1
0
    def save_media_obj(self, name, email, title, description, tags,
                       uploaded_file, url):
        # create our media object as a status-less placeholder initially
        media_obj = Media()
        media_obj.author = Author(name, email)
        media_obj.title = title
        media_obj.slug = get_available_slug(Media, title)
        media_obj.description = description
        if request.settings['wording_display_administrative_notes']:
            media_obj.notes = request.settings['wording_administrative_notes']
        media_obj.set_tags(tags)

        # Give the Media object an ID.
        DBSession.add(media_obj)
        DBSession.flush()

        # Create a MediaFile object, add it to the media_obj, and store the file permanently.
        media_file = add_new_media_file(media_obj, file=uploaded_file, url=url)

        # The thumbs may have been created already by add_new_media_file
        if not has_thumbs(media_obj):
            create_default_thumbs_for(media_obj)

        media_obj.update_status()
        DBSession.flush()

        return media_obj
示例#2
0
    def edit(self, id, engine_type=None, **kwargs):
        """Display the :class:`~mediacore.lib.storage.StorageEngine` for editing or adding.

        :param id: Storage ID
        :type id: ``int`` or ``"new"``
        :rtype: dict
        :returns:

        """
        if id != 'new':
            engine = fetch_row(StorageEngine, id)
        else:
            types = dict((cls.engine_type, cls) for cls in StorageEngine)
            engine_cls = types.get(engine_type, None)
            if not engine_cls:
                redirect(controller='/admin/storage', action='index')
            engine = engine_cls()

            if not engine.settings_form:
                # XXX: If this newly created storage engine has no settings,
                #      just save it. This isn't RESTful (as edit is a GET
                #      action), but it simplifies the creation process.
                DBSession.add(engine)
                redirect(controller='/admin/storage', action='index')

        return {
            'engine': engine,
            'form': engine.settings_form,
            'form_action': url_for(action='save', engine_type=engine_type),
            'form_values': kwargs,
        }
示例#3
0
    def _update_settings(self, values):
        """Modify the settings associated with the given dictionary."""
        for name, value in values.iteritems():
            if name in tmpl_context.settings:
                setting = tmpl_context.settings[name]
            else:
                setting = Setting(key=name, value=value)
            if value is None:
                value = u''
            else:
                value = unicode(value)
            if setting.value != value:
                setting.value = value
                DBSession.add(setting)
        DBSession.flush()

        # Clear the settings cache unless there are multiple processes.
        # We have no way of notifying the other processes that they need
        # to clear their caches too, so we've just gotta let it play out
        # until all the caches expire.
        if not request.environ.get('wsgi.multiprocess', False):
            app_globals.settings_cache.clear()
        else:
            # uWSGI provides an automagically included module
            # that we can use to call a graceful restart of all
            # the uwsgi processes.
            # http://projects.unbit.it/uwsgi/wiki/uWSGIReload
            try:
                import uwsgi
                uwsgi.reload()
            except ImportError:
                pass
示例#4
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)
示例#5
0
    def _update_settings(self, values):
        """Modify the settings associated with the given dictionary."""
        for name, value in values.iteritems():
            if name in tmpl_context.settings:
                setting = tmpl_context.settings[name]
            else:
                setting = Setting(key=name, value=value)
            if value is None:
                value = u''
            else:
                value = unicode(value)
            if setting.value != value:
                setting.value = value
                DBSession.add(setting)
        DBSession.flush()

        # Clear the settings cache unless there are multiple processes.
        # We have no way of notifying the other processes that they need
        # to clear their caches too, so we've just gotta let it play out
        # until all the caches expire.
        if not request.environ.get('wsgi.multiprocess', False):
            app_globals.settings_cache.clear()
        else:
            # uWSGI provides an automagically included module
            # that we can use to call a graceful restart of all
            # the uwsgi processes.
            # http://projects.unbit.it/uwsgi/wiki/uWSGIReload
            try:
                import uwsgi
                uwsgi.reload()
            except ImportError:
                pass
 def test_audiodesc_video_url_media(self):
     """Media with both Audio files and Video files attatched should be
     Video type."""
     try:
         # Create the media object
         media = self._new_publishable_media(u'description-video',
                 u'(Audio Description + Video)')
         DBSession.add(media)
         # Add an audio description
         media_file = add_new_media_file(media, None,
                 u'http://fakesite.com/fakefile.mp3')
         media_file.type = AUDIO_DESC
         media.update_status()
         # Add a video file
         media_file = add_new_media_file(media, None,
                 u'http://fakesite.com/fakefile.m4v')
         media.update_status()
         # Commit + test
         DBSession.commit()
         assert media.type == VIDEO, \
             "A Media object with a .m4v file and an Audio Description " \
             "was not labelled as a video type; it was labelled %s" % \
             (t, media.type)
     except SQLAlchemyError, e:
         DBSession.rollback()
         raise e
示例#7
0
    def rate(self, slug, rating=1, **kwargs):
        """Rate up or down the given media.

        :param slug: The media :attr:`~mediacore.model.media.Media.slug`
        :param rating: ``1`` or ``0`` if the rating is up or down.
        :rtype: JSON dict
        :returns:
            succcess
                bool
            upRating
                Pluralized count of up raters, "# people" or "1 person"
            downRating
                Pluralized count of down raters, "# people" or "1 person"

        """
        media = fetch_row(Media, slug=slug)

        if rating > 0:
            media.rating.add_vote(1)
        else:
            media.rating.add_vote(0)
        DBSession.add(media)

        if request.is_xhr:
            return dict(
                success = True,
                upRating = helpers.text.plural(media.rating.sum, 'person', 'people'),
                downRating = None,
            )
        else:
            redirect(action='view')
示例#8
0
 def test_audiodesc_video_url_media(self):
     """Media with both Audio files and Video files attatched should be
     Video type."""
     try:
         # Create the media object
         media = self._new_publishable_media(
             u'description-video', u'(Audio Description + Video)')
         DBSession.add(media)
         # Add an audio description
         media_file = add_new_media_file(
             media, None, u'http://fakesite.com/fakefile.mp3')
         media_file.type = AUDIO_DESC
         media.update_status()
         # Add a video file
         media_file = add_new_media_file(
             media, None, u'http://fakesite.com/fakefile.m4v')
         media.update_status()
         # Commit + test
         DBSession.commit()
         assert media.type == VIDEO, \
             "A Media object with a .m4v file and an Audio Description " \
             "was not labelled as a video type; it was labelled %s" % \
             (t, media.type)
     except SQLAlchemyError, e:
         DBSession.rollback()
         raise e
示例#9
0
def _add_new_media_file(media, original_filename, file):
    # FIXME: I think this will raise a KeyError if the uploaded
    #        file doesn't have an extension.
    file_ext = os.path.splitext(original_filename)[1].lower()[1:]

    # set the file paths depending on the file type
    media_file = MediaFile()
    media_file.type = file_ext
    media_file.url = 'dummy_url' # model requires that url not NULL
    media_file.is_original = True
    media_file.enable_player = media_file.is_playable
    media_file.enable_feed = not media_file.is_embeddable
    media_file.size = os.fstat(file.fileno())[6]

    # update media relations
    media.files.append(media_file)

    # add the media file (and its media, if new) to the database to get IDs
    DBSession.add(media_file)
    DBSession.flush()

    # copy the file to its permanent location
    file_name = '%d_%d_%s.%s' % (media.id, media_file.id, media.slug, file_ext)
    file_url = _store_media_file(file, file_name)
    media_file.url = file_url

    return media_file
示例#10
0
    def comment(self, slug, **values):
        """Post a comment from :class:`~mediacore.forms.media.PostCommentForm`.

        :param slug: The media :attr:`~mediacore.model.media.Media.slug`
        :returns: Redirect to :meth:`view` page for media.

        """
        if tmpl_context.form_errors:
            if request.is_xhr:
                return dict(
                    success = False,
                    errors = tmpl_context.form_errors
                )
            else:
                redirect(action='view')

        media = fetch_row(Media, slug=slug)
        c = Comment()
        c.status = 'unreviewed'
        c.author = AuthorWithIP(values['name'], None, request.environ['REMOTE_ADDR'])
        c.subject = 'Re: %s' % media.title
        c.body = helpers.clean_xhtml(values['body'])

        media.comments.append(c)
        DBSession.add(media)
        email.send_comment_notification(media, c)

        if request.is_xhr:
            return dict(success = True)
        else:
            redirect(action='view')
def main(parser, options, args):
    app_globs = app_globals._current_obj()
    app_id = app_globals.settings['facebook_appid']
    if not app_id:
        print 'No Facebook app_id configured, exiting'
        sys.exit(3)

    app_secret = options.app_secret
    fb = FacebookAPI(app_id, app_secret)

    from mediacore.model import DBSession, Media
    # eager loading of 'meta' to speed up later check.
    all_media = Media.query.options(joinedload('_meta')).all()

    print 'Checking all media for existing Facebook comments'
    progress = ProgressBar(maxval=len(all_media)).start()
    for i, media in enumerate(all_media):
        progress.update(i + 1)
        if 'facebook-comment-xid' not in media.meta:
            continue
        if not fb.has_xid_comments(media):
            continue
        media.meta[u'facebook-comment-xid'] = unicode(media.id)
        DBSession.add(media)
        DBSession.commit()

    progress.finish()
def main(parser, options, args):
    app_globs = app_globals._current_obj()
    app_id = app_globals.settings['facebook_appid']
    if not app_id:
        print 'No Facebook app_id configured, exiting'
        sys.exit(3)
    
    app_secret = options.app_secret
    fb = FacebookAPI(app_id, app_secret)
    
    from mediacore.model import DBSession, Media
    # eager loading of 'meta' to speed up later check.
    all_media = Media.query.options(joinedload('_meta')).all()
    
    print 'Checking all media for existing Facebook comments'
    progress = ProgressBar(maxval=len(all_media)).start()
    for i, media in enumerate(all_media):
        progress.update(i+1)
        if 'facebook-comment-xid' not in media.meta:
            continue
        if not fb.has_xid_comments(media):
            continue
        media.meta[u'facebook-comment-xid'] = unicode(media.id)
        DBSession.add(media)
        DBSession.commit()

    progress.finish()
示例#13
0
    def save_media_obj(self, name, email, title, description, tags, uploaded_file, url):
        # create our media object as a status-less placeholder initially
        media_obj = Media()
        media_obj.author = Author(name, email)
        media_obj.title = title
        media_obj.slug = get_available_slug(Media, title)
        media_obj.description = description
        if request.settings['wording_display_administrative_notes']:
            media_obj.notes = request.settings['wording_administrative_notes']
        media_obj.set_tags(tags)

        # Give the Media object an ID.
        DBSession.add(media_obj)
        DBSession.flush()

        # Create a MediaFile object, add it to the media_obj, and store the file permanently.
        media_file = add_new_media_file(media_obj, file=uploaded_file, url=url)

        # The thumbs may have been created already by add_new_media_file
        if not has_thumbs(media_obj):
            create_default_thumbs_for(media_obj)

        media_obj.update_status()
        DBSession.flush()

        return media_obj
示例#14
0
    def edit(self, id, engine_type=None, **kwargs):
        """Display the :class:`~mediacore.lib.storage.StorageEngine` for editing or adding.

        :param id: Storage ID
        :type id: ``int`` or ``"new"``
        :rtype: dict
        :returns:

        """
        if id != "new":
            engine = fetch_row(StorageEngine, id)
        else:
            types = dict((cls.engine_type, cls) for cls in StorageEngine)
            engine_cls = types.get(engine_type, None)
            if not engine_cls:
                redirect(controller="/admin/storage", action="index")
            engine = engine_cls()

            if not engine.settings_form:
                # XXX: If this newly created storage engine has no settings,
                #      just save it. This isn't RESTful (as edit is a GET
                #      action), but it simplifies the creation process.
                DBSession.add(engine)
                redirect(controller="/admin/storage", action="index")

        return {
            "engine": engine,
            "form": engine.settings_form,
            "form_action": url_for(action="save", engine_type=engine_type),
            "form_values": kwargs,
        }
示例#15
0
    def save(self, id, delete, category='topics', **kwargs):
        """Save changes or create a topic or tag.

        See :class:`~mediacore.forms.categories.EditCategoryForm` for POST vars.

        :param id: Topic or tag ID
        :param category: ``topics`` or ``tags``
        :param delete: If true the category is deleted rather than saved.
        :type delete: bool
        :rtype: JSON dict
        :returns:
            success
                bool
            category
                ``topics`` or ``tags``

        """
        model = self.select_model(category)
        item = fetch_row(model, id)

        if delete:
            DBSession.delete(item)
            item = None
        else:
            item.name = kwargs['name']
            item.slug = get_available_slug(model, kwargs['slug'], item)

            DBSession.add(item)

        if request.is_xhr:
            return dict(success=True, category=item)
        else:
            redirect(action='index', category=category)
 def _create_user_without_groups(self):
     user = User()
     user.user_name = u'joe'
     user.email_address = u'*****@*****.**'
     user.display_name = u'Joe'
     user.groups = []
     DBSession.add(user)
     DBSession.flush()
     return user
 def _create_user_without_groups(self):
     user = User()
     user.user_name = u'joe'
     user.email_address = u'*****@*****.**'
     user.display_name = u'Joe'
     user.groups = []
     DBSession.add(user)
     DBSession.flush()
     return user
def save_media_obj(author_name, author_email, title, description, tags, file, url):
    media = Media()
    media.author = Author(author_name, author_email)
    media.title = title
    media.description = description
    media.tags = tags
    add_new_media_file(media, file=file, url=url)
    DBSession.add(media)
    DBSession.commit()
    return media
示例#19
0
    def save_album_art(self, id, album_art, **kwargs):
        """Save album art uploaded with :class:`~mediacore.forms.media.AlbumArtForm`.

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

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

        im_path = os.path.join(config.image_dir, 'media/%s%s.%s')

        try:
            # Create thumbnails
            im = Image.open(album_art.file)

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

            # TODO: Allow other formats?
            for key, dimensions in config.album_art_sizes.iteritems():
                file_path = im_path % (media.id, key, 'jpg')
                im.resize(dimensions, 1).save(file_path)

            # Backup the original image just for kicks
            orig_type = os.path.splitext(album_art.filename)[1].lower()[1:]
            backup_file = open(im_path % (media.id, 'orig', orig_type), 'w')
            copyfileobj(album_art.file, backup_file)
            album_art.file.close()
            backup_file.close()

            success = True
            message = None
        except IOError:
            success = False
            message = 'Unsupported image type'
        except Exception, e:
            success = False
            message = e.message
示例#20
0
文件: media.py 项目: 86me/mediacore
    def comment(self, slug, **values):
        """Post a comment from :class:`~mediacore.forms.comments.PostCommentForm`.

        :param slug: The media :attr:`~mediacore.model.media.Media.slug`
        :returns: Redirect to :meth:`view` page for media.

        """
        akismet_key = helpers.fetch_setting('akismet_key')
        akismet_url = helpers.fetch_setting('akismet_url')
        if akismet_key:
            akismet = Akismet(agent='MediaCore/%s' % MEDIACORE_VERSION)
            akismet.key = akismet_key
            akismet.blog_url = akismet_url or url_for('/', qualified=True)
            akismet.verify_key()
            data = {'comment_author': values['name'].encode('utf-8'),
                    'user_ip': request.environ.get('REMOTE_ADDR'),
                    'user_agent': request.environ.get('HTTP_USER_AGENT'),
                    'referrer': request.environ.get('HTTP_REFERER',  'unknown'),
                    'HTTP_ACCEPT': request.environ.get('HTTP_ACCEPT')}

            if akismet.comment_check(values['body'].encode('utf-8'), data):
                title = "Comment Rejected"
                text = "Your comment appears to be spam and has been rejected."
                add_transient_message('comment_posted', title, text)
                redirect(action='view', anchor='top')

        media = fetch_row(Media, slug=slug)

        c = Comment()
        c.author = AuthorWithIP(
            values['name'], values['email'], request.environ['REMOTE_ADDR']
        )
        c.subject = 'Re: %s' % media.title
        c.body = values['body']

        require_review = asbool(helpers.fetch_setting('req_comment_approval'))
        if not require_review:
            c.reviewed = True
            c.publishable = True

        media.comments.append(c)
        DBSession.add(media)
        email.send_comment_notification(media, c)

        if require_review:
            title = "Thanks for your comment!"
            text = "We will post it just as soon as a moderator approves it."
            add_transient_message('comment_posted', title, text)
            redirect(action='view', anchor='top')
        else:
            redirect(action='view', anchor='comment-%s' % c.id)
示例#21
0
文件: media.py 项目: 86me/mediacore
    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.increment_views()
        DBSession.add(media)

        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.fulltext:
            related = Media.query.published()\
                .options(orm.undefer('comment_count_published'))\
                .filter(Media.id != media.id)\
                .search('>(%s) <(%s)' % (media.title, media.fulltext.tags))[:6]
        else:
            related = []

        return dict(
            media = media,
            related_media = related,
            comments = media.comments.published().all(),
            comment_form = post_comment_form,
            comment_form_action = url_for(action='comment', anchor=post_comment_form.id),
            comment_form_values = kwargs,
        )
    def test_add_file_url(self):
        slug = u'test-add-file-url'
        title = u'Test Adding File by URL on Media Edit Page.'

        try:
            media = self._new_publishable_media(slug, title)
            media.publishable = False
            media.reviewed = False
            DBSession.add(media)
            DBSession.commit()
            media_id = media.id
        except SQLAlchemyError, e:
            DBSession.rollback()
            raise e
    def test_add_file_url(self):
        slug = u'test-add-file-url'
        title = u'Test Adding File by URL on Media Edit Page.'

        try:
            media = self._new_publishable_media(slug, title)
            media.publishable = False
            media.reviewed = False
            DBSession.add(media)
            DBSession.commit()
            media_id = media.id
        except SQLAlchemyError, e:
            DBSession.rollback()
            raise e
示例#24
0
    def save(self, id, **kwargs):
        player = fetch_row(PlayerPrefs, id)
        form = player.settings_form

        if id == 'new':
            DBSession.add(player)

        @validate(form, error_handler=self.edit)
        def save(id, **kwargs):
            # Allow the form to modify the player directly
            # since each can have radically different fields.
            save_func = getattr(form, 'save_data')
            save_func(player, **tmpl_context.form_values)
            redirect(controller='/admin/players', action='index')

        return save(id, **kwargs)
    def save(self, id, **kwargs):
        player = fetch_row(PlayerPrefs, id)
        form = player.settings_form

        if id == 'new':
            DBSession.add(player)

        @validate(form, error_handler=self.edit)
        def save(id, **kwargs):
            # Allow the form to modify the player directly
            # since each can have radically different fields.
            save_func = getattr(form, 'save_data')
            save_func(player, **tmpl_context.form_values)
            redirect(controller='/admin/players', action='index')

        return save(id, **kwargs)
示例#26
0
文件: media.py 项目: 86me/mediacore
    def rate(self, slug, **kwargs):
        """Say 'I like this' for the given media.

        :param slug: The media :attr:`~mediacore.model.media.Media.slug`
        :rtype: unicode
        :returns:
            The new number of likes

        """
        media = fetch_row(Media, slug=slug)
        likes = media.increment_likes()
        DBSession.add(media)

        if request.is_xhr:
            return unicode(likes)
        else:
            redirect(action='view')
    def _get_media(self, unique):
        """Return the media/mediafiles required for the Helpers tests"""
        try:
            media = self._new_publishable_media(u'media-selection-%s' % unique,
                    u'Media Selection Test (%s)' % unique)
            DBSession.add(media)

            media_files = {}
            for t in ['oga', 'ogv', 'm4a', 'm4v', 'flv', 'mp3', 'xml']:
                media_files[t] = add_new_media_file(media, None,
                    u'http://fakesite.com/fakefile.%s' % t)
            media_files['youtube'] = add_new_media_file(media, None,
                    u'http://www.youtube.com/watch?v=3RsbmjNLQkc')
            media.update_status()
            DBSession.commit()
        except SQLAlchemyError, e:
            DBSession.rollback()
            raise e
示例#28
0
 def test_captioned_url_media(self):
     """Media with only subtitles attatched should be None type."""
     try:
         for t in self.caption_types:
             media = self._new_publishable_media(u'caption-%s' % t,
                     u'%s (Captioned)' % t.upper())
             DBSession.add(media)
             media_file = add_new_media_file(media, None,
                     u'http://fakesite.com/fakefile.%s' % t)
             media.update_status()
             DBSession.commit()
             assert media.type == None, \
                 "A Media object with only an .%s file associated was " \
                 "not labelled as a 'None' type; it was labelled %s" % \
                 (t, media.type)
     except SQLAlchemyError, e:
         DBSession.rollback()
         raise e
示例#29
0
 def test_captioned_url_media(self):
     """Media with only subtitles attatched should be None type."""
     try:
         for t in self.caption_types:
             media = self._new_publishable_media(
                 u'caption-%s' % t, u'%s (Captioned)' % t.upper())
             DBSession.add(media)
             media_file = add_new_media_file(
                 media, None, u'http://fakesite.com/fakefile.%s' % t)
             media.update_status()
             DBSession.commit()
             assert media.type == None, \
                 "A Media object with only an .%s file associated was " \
                 "not labelled as a 'None' type; it was labelled %s" % \
                 (t, media.type)
     except SQLAlchemyError, e:
         DBSession.rollback()
         raise e
示例#30
0
    def rate(self, slug, up=None, down=None, **kwargs):
        """Say 'I like this' for the given media.

        :param slug: The media :attr:`~mediacore.model.media.Media.slug`
        :rtype: unicode
        :returns:
            The new number of likes

        """
        # we have to check if current user is anonymous or authenticated
        userid = check_user_authentication(request)
        if not userid:
            log.warn('Anonymous user cannot rate media')
            raise HTTPUnauthorized().exception
            
        media = fetch_row(Media, slug=slug)
        
        # check if current user has already voted this media object
        votes = Vote.query.get_votes(media_id=media.id, user_name = userid)
        if votes.count():
            # if true redirect to 'view'
            log.warn('User %s already voted this media')
            redirect(action='view')

        # create new vote object mapping current media and user
        vote = Vote()
        vote.media_id = media.id
        vote.user_name = userid

        # Give the Vote object an ID.
        DBSession.add(vote)
        DBSession.flush()

        if up:
            vote.increment_likes()
            media.increment_likes()
        elif down:
            vote.increment_dislikes()
            media.increment_dislikes()
        
        if request.is_xhr:
            return u''
        else:
            redirect(action='view')
示例#31
0
    def rate(self, slug, up=None, down=None, **kwargs):
        """Say 'I like this' for the given media.

        :param slug: The media :attr:`~mediacore.model.media.Media.slug`
        :rtype: unicode
        :returns:
            The new number of likes

        """
        # we have to check if current user is anonymous or authenticated
        userid = check_user_authentication(request)
        if not userid:
            log.warn('Anonymous user cannot rate media')
            raise HTTPUnauthorized().exception

        media = fetch_row(Media, slug=slug)

        # check if current user has already voted this media object
        votes = Vote.query.get_votes(media_id=media.id, user_name=userid)
        if votes.count():
            # if true redirect to 'view'
            log.warn('User %s already voted this media')
            redirect(action='view')

        # create new vote object mapping current media and user
        vote = Vote()
        vote.media_id = media.id
        vote.user_name = userid

        # Give the Vote object an ID.
        DBSession.add(vote)
        DBSession.flush()

        if up:
            vote.increment_likes()
            media.increment_likes()
        elif down:
            vote.increment_dislikes()
            media.increment_dislikes()

        if request.is_xhr:
            return u''
        else:
            redirect(action='view')
 def test_audio_description_url_media(self):
     """Media with only Audio Descriptions attatched should be None type."""
     try:
         for t in self.audio_types:
             media = self._new_publishable_media(u'description-%s' % t,
                     u'%s (Audio Description)' % t.upper())
             DBSession.add(media)
             media_file = add_new_media_file(media, None,
                     u'http://fakesite.com/fakefile.%s' % t)
             media_file.type = AUDIO_DESC
             media.update_status()
             DBSession.commit()
             assert media.type == None, \
                 "A Media object with only an Audio Description file " \
                 "associated was not labelled as a None type; it " \
                 "was labelled %s" % (t, media.type)
     except SQLAlchemyError, e:
         DBSession.rollback()
         raise e
示例#33
0
    def reorder_file(self, id, file_id, budge_infront_id, **kwargs):
        """Change the position of the given file relative to the 2nd file.

        :param file_id: The file to move
        :type file_id: ``int``
        :param budge_infront_id: The file whos position the first file takes.
            All files behind/after this file are bumped back as well.
        :type budge_infront_id: ``int`` or ``None``
        :rtype: JSON dict
        :returns:
            success
                bool

        """
        media = fetch_row(Media, id, incl_trash=True)
        media.reposition_file(file_id, budge_infront_id)
        DBSession.add(media)
        DBSession.flush()
        return dict(success=True)
示例#34
0
    def save(self, id, engine_type=None, **kwargs):
        if id == 'new':
            assert engine_type is not None, 'engine_type must be specified when saving a new StorageEngine.'

        engine = self.fetch_engine(id, engine_type)
        form = engine.settings_form

        if id == 'new':
            DBSession.add(engine)

        @validate(form, error_handler=self.edit)
        def save_engine_params(id, general, **kwargs):
            # Allow the form to modify the StorageEngine directly
            # since each can have radically different fields.
            save_func = getattr(form, 'save_engine_params')
            save_func(engine, **tmpl_context.form_values)
            redirect(controller='/admin/storage', action='index')

        return save_engine_params(id, **kwargs)
示例#35
0
    def save(self, id, engine_type=None, **kwargs):
        if id == 'new':
            assert engine_type is not None, 'engine_type must be specified when saving a new StorageEngine.'

        engine = self.fetch_engine(id, engine_type)
        form = engine.settings_form

        if id == 'new':
            DBSession.add(engine)

        @validate(form, error_handler=self.edit)
        def save_engine_params(id, general, **kwargs):
            # Allow the form to modify the StorageEngine directly
            # since each can have radically different fields.
            save_func = getattr(form, 'save_engine_params')
            save_func(engine, **tmpl_context.form_values)
            redirect(controller='/admin/storage', action='index')

        return save_engine_params(id, **kwargs)
示例#36
0
文件: players.py 项目: isaleem/cumin
    def inject_in_db(cls, enable_player=False):
        from mediacore.model import DBSession
        from mediacore.model.players import players as players_table, PlayerPrefs

        prefs = PlayerPrefs()
        prefs.name = cls.name
        prefs.enabled = enable_player
        # didn't get direct SQL expression to work with SQLAlchemy
        # player_table = sql.func.max(player_table.c.priority)
        query = sql.select([sql.func.max(players_table.c.priority)])
        max_priority = DBSession.execute(query).first()[0]
        if max_priority is None:
            max_priority = -1
        prefs.priority = max_priority + 1
        prefs.created_on = datetime.now()
        prefs.modified_on = datetime.now()
        prefs.data = cls.default_data
        DBSession.add(prefs)
        DBSession.commit()
示例#37
0
 def inject_in_db(cls, enable_player=False):
     from mediacore.model import DBSession
     from mediacore.model.players import players as players_table, PlayerPrefs
     
     prefs = PlayerPrefs()
     prefs.name = cls.name
     prefs.enabled = enable_player
     # didn't get direct SQL expression to work with SQLAlchemy
     # player_table = sql.func.max(player_table.c.priority)
     query = sql.select([sql.func.max(players_table.c.priority)])
     max_priority = DBSession.execute(query).first()[0]
     if max_priority is None:
         max_priority = -1
     prefs.priority = max_priority + 1
     prefs.created_on = datetime.now()
     prefs.modified_on = datetime.now()
     prefs.data = cls.default_data
     DBSession.add(prefs)
     DBSession.commit()
示例#38
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')
示例#39
0
    def update_status(self, id, update_button=None, publish_on=None, **values):
        """Update the publish status for the given media.

        :param id: Media ID
        :type id: ``int``
        :param update_status: The text of the submit button which indicates
            that the :attr:`~mediacore.model.media.Media.status` should change.
        :type update_status: ``unicode`` or ``None``
        :param publish_on: A date to set to
            :attr:`~mediacore.model.media.Media.publish_on`
        :type publish_on: :class:`datetime.datetime` or ``None``
        :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, incl_trash=True)

        # Make the requested change assuming it will be allowed
        if update_button == 'Review Complete':
            media.status.discard('unreviewed')
        elif update_button == 'Publish Now':
            media.status.discard('draft')
            media.status.add('publish')
            media.publish_on = publish_on or datetime.now()
        elif publish_on:
            media.publish_on = publish_on

        try:
            # Verify the change is valid by re-determining the status
            media.update_status()
            DBSession.add(media)
            DBSession.flush()
            data = dict(success=True)
        except Exception, e:
            data = dict(success=False, message=e.message)
示例#40
0
    def save_edit(self, id, body, **kwargs):
        """Save an edit from :class:`~mediacore.forms.comments.EditCommentForm`.

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

        """
        comment = fetch_row(Comment, id)
        comment.body = helpers.clean_xhtml(body)
        DBSession.add(comment)
        return dict(
            success = True,
            body = comment.body,
        )
    def test_edit_media(self):
        title = u'Edit Existing Media Test'
        slug = u'edit-existing-media-test' # this should be unique

        # Values that we will change during the edit process
        name = u'Frederick Awesomeson'
        email = u'*****@*****.**'
        description = u'This media item was created to test the "admin/media/edit/someID" method'
        htmlized_description = '<p>This media item was created to test the &quot;admin/media/edit/someID&quot; method</p>'
        notes = u'Some Notes!'

        try:
            media = self._new_publishable_media(slug, title)
            media.publishable = False
            media.reviewed = False
            DBSession.add(media)
            DBSession.commit()
            media_id = media.id
        except SQLAlchemyError, e:
            DBSession.rollback()
            raise e
    def test_edit_media(self):
        title = u'Edit Existing Media Test'
        slug = u'edit-existing-media-test'  # this should be unique

        # Values that we will change during the edit process
        name = u'Frederick Awesomeson'
        email = u'*****@*****.**'
        description = u'This media item was created to test the "admin/media/edit/someID" method'
        htmlized_description = '<p>This media item was created to test the &quot;admin/media/edit/someID&quot; method</p>'
        notes = u'Some Notes!'

        try:
            media = self._new_publishable_media(slug, title)
            media.publishable = False
            media.reviewed = False
            DBSession.add(media)
            DBSession.commit()
            media_id = media.id
        except SQLAlchemyError, e:
            DBSession.rollback()
            raise e
示例#43
0
    def save(self, id, engine_type=None, **kwargs):
        if id == "new":
            assert engine_type is not None, "engine_type must be specified when saving a new StorageEngine."
            engine_class = [x for x in StorageEngine if x.engine_type == engine_type][0]
        else:
            engine_class = StorageEngine

        engine = fetch_row(engine_class, id)
        form = engine.settings_form

        if id == "new":
            DBSession.add(engine)

        @validate(form, error_handler=self.edit)
        def save_engine_params(id, general, **kwargs):
            # Allow the form to modify the StorageEngine directly
            # since each can have radically different fields.
            save_func = getattr(form, "save_engine_params")
            save_func(engine, **tmpl_context.form_values)
            redirect(controller="/admin/storage", action="index")

        return save_engine_params(id, **kwargs)
示例#44
0
def add_default_data():
    log.info('Adding default data')

    settings = [
        (u'email_media_uploaded', None),
        (u'email_comment_posted', None),
        (u'email_support_requests', None),
        (u'email_send_from', u'noreply@localhost'),
        (u'wording_user_uploads',
         N_(u"Upload your media using the form below. We'll review it and get back to you."
            )),
        (u'wording_administrative_notes', None),
        (u'wording_display_administrative_notes', u''),
        (u'popularity_decay_exponent', u'4'),
        (u'popularity_decay_lifetime', u'36'),
        (u'rich_text_editor', u'tinymce'),
        (u'google_analytics_uacct', u''),
        (u'featured_category', u'1'),
        (u'max_upload_size', u'314572800'),
        (u'ftp_storage', u'false'),
        (u'ftp_server', u'ftp.someserver.com'),
        (u'ftp_user', u'username'),
        (u'ftp_password', u'password'),
        (u'ftp_upload_directory', u'media'),
        (u'ftp_download_url',
         u'http://www.someserver.com/web/accessible/media/'),
        (u'ftp_upload_integrity_retries', u'10'),
        (u'akismet_key', u''),
        (u'akismet_url', u''),
        (u'req_comment_approval', u''),
        (u'use_embed_thumbnails', u'true'),
        (u'api_secret_key_required', u'true'),
        (u'api_secret_key', random_string(20)),
        (u'api_media_max_results', u'50'),
        (u'api_tree_max_depth', u'10'),
        (u'general_site_name', u'MediaCore'),
        (u'general_site_title_display_order', u'prepend'),
        (u'sitemaps_display', u'True'),
        (u'rss_display', u'True'),
        (u'vulgarity_filtered_words', u''),
        (u'primary_language', u'en'),
        (u'advertising_banner_html', u''),
        (u'advertising_sidebar_html', u''),
        (u'comments_engine', u'mediacore'),
        (u'facebook_appid', u''),
    ]
    settings.extend(appearance_settings)

    for key, value in settings:
        s = Setting()
        s.key = key
        s.value = value
        DBSession.add(s)

    admin_user = User()
    admin_user.user_name = u'admin'
    admin_user.display_name = u'Admin'
    admin_user.email_address = u'*****@*****.**'
    admin_user.password = u'admin'
    DBSession.add(admin_user)

    admin_group = Group()
    admin_group.group_name = u'admins'
    admin_group.display_name = u'Admins'
    admin_group.users.append(admin_user)
    DBSession.add(admin_group)

    editor_group = Group()
    editor_group.group_name = u'editors'
    editor_group.display_name = u'Editors'
    DBSession.add(editor_group)

    admin_perm = Permission()
    admin_perm.permission_name = u'admin'
    admin_perm.description = u'Grants access to the admin panel'
    admin_perm.groups.append(admin_group)
    DBSession.add(admin_perm)

    edit_perm = Permission()
    edit_perm.permission_name = u'edit'
    edit_perm.description = u'Grants access to edit site content'
    edit_perm.groups.append(admin_group)
    edit_perm.groups.append(editor_group)
    DBSession.add(edit_perm)

    category = Category()
    category.name = u'Featured'
    category.slug = u'featured'
    DBSession.add(category)

    category2 = Category()
    category2.name = u'Instructional'
    category2.slug = u'instructional'
    DBSession.add(category2)

    podcast = Podcast()
    podcast.slug = u'hello-world'
    podcast.title = u'Hello World'
    podcast.subtitle = u'My very first podcast!'
    podcast.description = u"""<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>"""
    podcast.category = u'Technology'
    podcast.author = Author(admin_user.display_name, admin_user.email_address)
    podcast.explicit = None
    podcast.copyright = u'Copyright 2009 Xyz'
    podcast.itunes_url = None
    podcast.feedburner_url = None
    DBSession.add(podcast)

    comment = Comment()
    comment.subject = u'Re: New Media'
    comment.author = AuthorWithIP(name=u'John Doe', ip=2130706433)
    comment.body = u'<p>Hello to you too!</p>'
    DBSession.add(comment)

    media = Media()
    media.type = None
    media.slug = u'new-media'
    media.reviewed = True
    media.encoded = False
    media.publishable = False
    media.title = u'New Media'
    media.subtitle = None
    media.description = u"""<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>"""
    media.description_plain = u"""Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."""
    media.author = Author(admin_user.display_name, admin_user.email_address)
    media.categories.append(category)
    media.comments.append(comment)
    DBSession.add(media)

    #XXX The list of default players is actually defined in model.players
    # and should at some point be moved here to avoid inconsistency
    # between the default storage engines and default players.
    remote_url_storage = RemoteURLStorage()
    default_engines = [
        LocalFileStorage(),
        remote_url_storage,
        YoutubeStorage(),
        VimeoStorage(),
        BlipTVStorage(),
        DailyMotionStorage(),
        GoogleVideoStorage(),
    ]
    for engine in default_engines:
        DBSession.add(engine)

    import datetime
    instructional_media = [
        (
            u'workflow-in-mediacore',
            u'Workflow in MediaCore',
            u'<p>This sceencast explains the publish status feature in MediaCore.</p><p>Initially all videos uploaded through the front-end or admin panel are placed under &quot;awaiting review&quot; status. Once the administrator hits the &quot;review complete&quot; button, they can upload media. Videos can be added in any format, however, they can only be published if they are in a web-ready format such as FLV, M4V, MP3, or MP4. Alternatively, if they are published through Youtube or Vimeo the encoding step is skipped</p><p>Once uploaded and encoded the administrator can then publish the video.</p>',
            u'This sceencast explains the publish status feature in MediaCore.\nInitially all videos uploaded through the front-end or admin panel are placed under \"awaiting review\" status. Once the administrator hits the \"review complete\" button, they can upload media. Videos can be added in any format, however, they can only be published if they are in a web-ready format such as FLV, M4V, MP3, or MP4. Alternatively, if they are published through Youtube or Vimeo the encoding step is skipped\nOnce uploaded and encoded the administrator can then publish the video.',
            datetime.datetime(2010, 5, 13, 2, 29, 40),
            218,
            u'http://getmediacore.com/files/tutorial-workflow-in-mediacore.mp4',
            u'video',
            u'mp4',
        ),
        (
            u'creating-a-podcast-in-mediacore',
            u'Creating a Podcast in MediaCore',
            u'<p>This describes the process an administrator goes through in creating a podcast in MediaCore. An administrator can enter information that will automatically generate the iTunes/RSS feed information. Any episodes published to a podcast will automatically publish to iTunes/RSS.</p>',
            u'This describes the process an administrator goes through in creating a podcast in MediaCore. An administrator can enter information that will automatically generate the iTunes/RSS feed information. Any episodes published to a podcast will automatically publish to iTunes/RSS.',
            datetime.datetime(2010, 5, 13, 2, 33, 44),
            100,
            u'http://getmediacore.com/files/tutorial-create-podcast-in-mediacore.mp4',
            u'video',
            u'mp4',
        ),
        (
            u'adding-a-video-in-mediacore',
            u'Adding a Video in MediaCore',
            u'<p>This screencast shows how video or audio can be added in MediaCore.</p><p>MediaCore supports a wide range of formats including (but not limited to): YouTube, Vimeo, Google Video, Amazon S3, Bits on the Run, BrightCove, Kaltura, and either your own server or someone else\'s.</p><p>Videos can be uploaded in any format, but can only be published in web-ready formats such as FLV, MP3, M4V, MP4 etc.</p>',
            u'This screencast shows how video or audio can be added in MediaCore.\nMediaCore supports a wide range of formats including (but not limited to): YouTube, Vimeo, Google Video, Amazon S3, Bits on the Run, BrightCove, Kaltura, and either your own server or someone else\'s.\nVideos can be uploaded in any format, but can only be published in web-ready formats such as FLV, MP3, M4V, MP4 etc.',
            datetime.datetime(2010, 5, 13, 02, 37, 36),
            169,
            u'http://getmediacore.com/files/tutorial-add-video-in-mediacore.mp4',
            u'video',
            u'mp4',
        ),
    ]

    name = u'MediaCore Team'
    email = u'*****@*****.**'
    for slug, title, desc, desc_plain, publish_on, duration, url, type_, container in instructional_media:
        media = Media()
        media.author = Author(name, email)
        media.description = desc
        media.description_plain = desc_plain
        media.duration = duration
        media.publish_on = publish_on
        media.slug = slug
        media.title = title
        media.type = type_

        media_file = MediaFile()
        media_file.container = container
        media_file.created_on = publish_on
        media_file.display_name = os.path.basename(url)
        media_file.duration = duration
        media_file.type = type_
        media_file.storage = remote_url_storage
        media_file.unique_id = url

        DBSession.add(media)
        DBSession.add(media_file)

        media.files.append(media_file)
        media.categories.append(category2)

        media.encoded = True
        media.reviewed = True
        media.publishable = True