def tsubmit(self, **kwargs): """ """ tlocalfile = tfile[kwargs['environ']['HTTP_COOKIE']] notify_to_author = True if not kwargs['email'] : notify_to_author = False kwargs['email'] = "*****@*****.**" # Save the media_obj! media_obj = self.save_media_obj( kwargs['name'], kwargs['email'], kwargs['title'], kwargs['description'], None, tlocalfile, kwargs['url'], ) """ FIXED: creation notification email will now go to the authurs email also """ #if notify_to_author: # email.send_media_notification_to_author(media_obj) email.send_media_notification(media_obj) #delete the key del tfile[kwargs['environ']['HTTP_COOKIE']] #redirect to success page redirect(action='success')
def index(self, **kwargs): """List podcasts and podcast media. :rtype: dict :returns: podcasts The :class:`~mediadrop.model.podcasts.Podcast` instance """ podcasts = Podcast.query\ .options(orm.undefer('media_count_published'))\ .all() if len(podcasts) == 1: redirect(action='view', slug=podcasts[0].slug) podcast_episodes = {} for podcast in podcasts: episode_query = podcast.media.published().order_by(Media.publish_on.desc()) podcast_episodes[podcast] = viewable_media(episode_query)[:4] return dict( podcasts = podcasts, podcast_episodes = podcast_episodes, )
def rate(self, slug, up=None, down=None, **kwargs): """Say 'I like this' for the given media. :param slug: The media :attr:`~mediadrop.model.media.Media.slug` :rtype: unicode :returns: The new number of likes """ media = fetch_row(Media, slug=slug) request.perm.assert_permission(u'view', media.resource) if up: if not request.settings['appearance_show_like']: abort(status_code=403) media.increment_likes() elif down: if not request.settings['appearance_show_dislike']: abort(status_code=403) media.increment_dislikes() if request.is_xhr: return u'' else: redirect(action='view')
def save(self, id, delete=None, **kwargs): """Save changes or create a category. See :class:`~mediadrop.forms.admin.settings.categories.CategoryForm` for POST vars. :param id: Category ID :param delete: If true the category is to be deleted rather than saved. :type delete: bool :rtype: JSON dict :returns: success bool """ if tmpl_context.form_errors: if request.is_xhr: return dict(success=False, errors=tmpl_context.form_errors) else: # TODO: Add error reporting for users with JS disabled? return redirect(action="edit") cat = fetch_row(Category, id) if delete: DBSession.delete(cat) data = dict(success=True, id=cat.id, parent_options=unicode(category_form.c["parent_id"].display())) else: cat.name = kwargs["name"] cat.slug = get_available_slug(Category, kwargs["slug"], cat) if kwargs["parent_id"]: parent = fetch_row(Category, kwargs["parent_id"]) if parent is not cat and cat not in parent.ancestors(): cat.parent = parent else: cat.parent = None DBSession.add(cat) DBSession.flush() data = dict( success=True, id=cat.id, name=cat.name, slug=cat.slug, parent_id=cat.parent_id, parent_options=unicode(category_form.c["parent_id"].display()), depth=cat.depth(), row=unicode( category_row_form.display( action=url_for(id=cat.id), category=cat, depth=cat.depth(), first_child=True ) ), ) if request.is_xhr: return data else: redirect(action="index", id=None)
def view(self, slug, podcast_slug=None, **kwargs): """Display the media player, info and comments. :param slug: The :attr:`~mediadrop.models.media.Media.slug` to lookup :param podcast_slug: The :attr:`~mediadrop.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:`~mediadrop.model.media.Media` instance for display. related_media A list of :class:`~mediadrop.model.media.Media` instances that rank as topically related to the given media item. comments A list of :class:`~mediadrop.model.comments.Comment` instances associated with the selected media item. 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:`~mediadrop.model.media.Media` instance. """ media = fetch_row(Media, slug=slug) request.perm.assert_permission(u'view', media.resource) 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) try: media.increment_views() DBSession.commit() except OperationalError: DBSession.rollback() if request.settings['comments_engine'] == 'facebook': response.facebook = Facebook(request.settings['facebook_appid']) related_media = viewable_media(Media.query.related(media))[:6] # TODO: finish implementation of different 'likes' buttons # e.g. the default one, plus a setting to use facebook. return dict( media = media, related_media = related_media, comments = media.comments.published().all(), comment_form_action = url_for(action='comment'), comment_form_values = kwargs, )
def disable(self, id, **kwargs): """Disable a StorageEngine. :param id: engine ID. :type id: ``int`` :returns: Redirect back to :meth:`index` after success. """ engine = fetch_row(StorageEngine, id) engine.enabled = False redirect(action='index', id=None)
def fetch_engine(self, id, engine_type=None): 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() return engine
def update_status(self, id, status=None, publish_on=None, publish_until=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:`~mediadrop.model.media.Media.status` should change. :type update_status: ``unicode`` or ``None`` :param publish_on: A date to set to :attr:`~mediadrop.model.media.Media.publish_on` :type publish_on: :class:`datetime.datetime` or ``None`` :param publish_until: A date to set to :attr:`~mediadrop.model.media.Media.publish_until` :type publish_until: :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) new_slug = None # Make the requested change assuming it will be allowed if status == 'unreviewed': media.reviewed = True elif status == 'draft': self._publish_media(media, publish_on) elif publish_on: media.publish_on = publish_on media.update_popularity() elif publish_until: media.publish_until = publish_until # Verify the change is valid by re-determining the status media.update_status() DBSession.flush() if request.is_xhr: # Return the rendered widget for injection status_form_xhtml = unicode(update_status_form.display( action=url_for(action='update_status'), media=media)) return dict( success = True, status_form = status_form_xhtml, slug = new_slug, ) else: redirect(action='edit')
def disable(self, id, **kwargs): """Disable a PlayerPref. :param id: Player ID. :type id: ``int`` :returns: Redirect back to :meth:`index` after success. """ player = fetch_row(PlayerPrefs, id) player.enabled = False update_enabled_players() redirect(action='index', id=None)
def comments_save(self, **kwargs): """Save :class:`~mediadrop.forms.admin.settings.CommentsForm`.""" old_vulgarity_filter = c.settings['vulgarity_filtered_words'].value self._save(comments_form, values=kwargs) # Run the filter now if it has changed if old_vulgarity_filter != c.settings['vulgarity_filtered_words'].value: for comment in DBSession.query(Comment): comment.body = filter_vulgarity(comment.body) redirect(action='comments')
def save(self, id, slug, title, author_name, author_email, description, notes, podcast, tags, categories, delete=None, **kwargs): """Save changes or create a new :class:`~mediadrop.model.media.Media` instance. Form handler the :meth:`edit` action and the :class:`~mediadrop.forms.admin.media.MediaForm`. Redirects back to :meth:`edit` after successful editing and :meth:`index` after successful deletion. """ media = fetch_row(Media, id) if delete: self._delete_media(media) redirect(action='index', id=None) if not slug: slug = slugify(title) elif slug.startswith('_stub_'): slug = slug[len('_stub_'):] if slug != media.slug: media.slug = get_available_slug(Media, slug, media) media.title = title media.author = Author(author_name, author_email) media.description = description media.notes = notes media.podcast_id = podcast media.set_tags(tags) media.set_categories(categories) media.update_status() DBSession.add(media) DBSession.flush() if id == 'new' and not has_thumbs(media): create_default_thumbs_for(media) if request.is_xhr: status_form_xhtml = unicode(update_status_form.display( action=url_for(action='update_status', id=media.id), media=media)) return dict( media_id = media.id, values = {'slug': slug}, link = url_for(action='edit', id=media.id), status_form = status_form_xhtml, ) else: redirect(action='edit', id=media.id)
def submit(self, **kwargs): """ """ kwargs.setdefault("name") # Save the media_obj! media_obj = self.save_media_obj( kwargs["name"], kwargs["email"], kwargs["title"], kwargs["description"], None, kwargs["file"], kwargs["url"] ) email.send_media_notification(media_obj) # Redirect to success page! redirect(action="success")
def delete(self, id, **kwargs): """Delete a StorageEngine. :param id: Storage ID. :type id: ``int`` :returns: Redirect back to :meth:`index` after successful delete. """ engine = fetch_row(StorageEngine, id) files = engine.files for f in files: engine.delete(f.unique_id) DBSession.delete(engine) redirect(action='index', id=None)
def delete(self, id, **kwargs): """Delete a group. :param id: Group ID. :type id: ``int`` :returns: Redirect back to :meth:`index` after successful delete. """ group = fetch_row(Group, id) DBSession.delete(group) if request.is_xhr: return dict(success=True) redirect(action='index', id=None)
def delete(self, id, **kwargs): """Delete a user. :param id: User ID. :type id: ``int`` :returns: Redirect back to :meth:`index` after successful delete. """ user = fetch_row(User, id) DBSession.delete(user) if request.is_xhr: return dict(success=True) redirect(action='index', id=None)
def 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)
def submit(self, **kwargs): """ """ kwargs.setdefault('name') # Save the media_obj! media_obj = self.save_media_obj( kwargs['name'], kwargs['email'], kwargs['title'], kwargs['description'], None, kwargs['file'], kwargs['url'], ) email.send_media_notification(media_obj) # Redirect to success page! redirect(action='success')
def report(self, email='', description='', **kwargs): """Email a support request that's been submitted on :meth:`document`. Redirects back to the root URL ``/``. """ url = '' get_vars = post_vars = {} for x in kwargs: if x.startswith('GET_'): get_vars[x] = kwargs[x] elif x.startswith('POST_'): post_vars[x] = kwargs[x] libemail.send_support_request(email, url, description, get_vars, post_vars) redirect('/')
def save_status(self, id, status, ids=None, **kwargs): """Approve or delete a comment or comments. :param id: A :attr:`~mediadrop.model.comments.Comment.id` if we are acting on a single comment, or ``"bulk"`` if we should refer to ``ids``. :type id: ``int`` or ``"bulk"`` :param status: ``"approve"`` or ``"trash"`` depending on what action the user requests. :param ids: An optional string of IDs separated by commas. :type ids: ``unicode`` or ``None`` :rtype: JSON dict :returns: success bool ids A list of :attr:`~mediadrop.model.comments.Comment.id` that have changed. """ if id != 'bulk': ids = [id] if not isinstance(ids, list): ids = [ids] if status == 'approve': publishable = True elif status == 'trash': publishable = False else: # XXX: This form should never be submitted without a valid status. raise AssertionError('Unexpected status: %r' % status) comments = Comment.query.filter(Comment.id.in_(ids)).all() for comment in comments: comment.reviewed = True comment.publishable = publishable DBSession.add(comment) DBSession.flush() if request.is_xhr: return dict(success=True, ids=ids) else: redirect(action='index')
def delete(self, id, **kwargs): """Delete a PlayerPref. After deleting the PlayerPref, cleans up the players table, ensuring that each Player class is represented--if the deleted PlayerPref is the last example of that Player class, creates a new disabled PlayerPref for that Player class with the default settings. :param id: Player ID. :type id: ``int`` :returns: Redirect back to :meth:`index` after successful delete. """ player = fetch_row(PlayerPrefs, id) DBSession.delete(player) DBSession.flush() cleanup_players_table() redirect(action='index', id=None)
def save(self, id, email_address, display_name, login_details, delete=None, **kwargs): """Save changes or create a new :class:`~mediadrop.model.auth.User` instance. :param id: User ID. If ``"new"`` a new user is created. :type id: ``int`` or ``"new"`` :returns: Redirect back to :meth:`index` after successful save. """ user = fetch_row(User, id) if delete: DBSession.delete(user) redirect(action='index', id=None) user.display_name = display_name user.email_address = email_address user.user_name = login_details['user_name'] password = login_details['password'] if password is not None and password != '': user.password = password if login_details['groups']: query = DBSession.query(Group).filter( Group.group_id.in_(login_details['groups'])) user.groups = list(query.all()) else: user.groups = [] DBSession.add(user) # Check if we're changing the logged in user's own password if user.id == request.perm.user.id \ and password is not None and password != '': DBSession.commit() # repoze.who sees the Unauthorized response and clears the cookie, # forcing a fresh login with the new password raise webob.exc.HTTPUnauthorized().exception redirect(action='index', id=None)
def popularity_save(self, **kwargs): """Save :class:`~mediadrop.forms.admin.settings.PopularityForm`. Updates the popularity for every media item based on the submitted values. """ self._save(popularity_form, values=kwargs) # ".util.calculate_popularity()" uses the popularity settings from # the request.settings which are only updated when a new request # comes in. # update the settings manually so the popularity is actually updated # correctly. for key in ('popularity_decay_exponent', 'popularity_decay_lifetime'): request.settings[key] = kwargs['popularity.' + key] for m in Media.query: m.update_popularity() DBSession.add(m) redirect(action='popularity')
def popularity_save(self, **kwargs): """Save :class:`~mediadrop.forms.admin.settings.PopularityForm`. Updates the popularity for every media item based on the submitted values. """ self._save(popularity_form, values=kwargs) # ".util.calculate_popularity()" uses the popularity settings from # the request.settings which are only updated when a new request # comes in. # update the settings manually so the popularity is actually updated # correctly. for key in ('popularity_decay_exponent', 'popularity_decay_lifetime'): request.settings[key] = kwargs['popularity.'+key] for m in Media.query: m.update_popularity() DBSession.add(m) redirect(action='popularity')
def submit(self, **kwargs): """ """ kwargs.setdefault('name') name = request.perm.user.display_name email_X = request.perm.user.email_address podcasts = DBSession.query(Podcast.id).filter(Podcast.author_name == name)\ .filter(Podcast.id == kwargs['podcast'])\ .all() if not podcasts: redirect(action='failure') # Save the media_obj! media_obj = self.save_media_obj(name, email_X, kwargs['title'], kwargs['description'], None, kwargs['file'], kwargs['podcast']) email.send_media_notification(media_obj) # Redirect to success page! redirect(action='success')
def save(self, id, delete=False, **kwargs): """Save changes or create a tag. See :class:`~mediadrop.forms.admin.settings.tags.TagForm` for POST vars. :param id: Tag ID :rtype: JSON dict :returns: success bool """ if tmpl_context.form_errors: if request.is_xhr: return dict(success=False, errors=tmpl_context.form_errors) else: # TODO: Add error reporting for users with JS disabled? return redirect(action='edit') tag = fetch_row(Tag, id) if delete: DBSession.delete(tag) data = dict(success=True, id=tag.id) else: tag.name = kwargs['name'] tag.slug = get_available_slug(Tag, kwargs['slug'], tag) DBSession.add(tag) DBSession.flush() data = dict( success = True, id = tag.id, name = tag.name, slug = tag.slug, row = unicode(tag_row_form.display(tag=tag)), ) if request.is_xhr: return data else: redirect(action='index', id=None)
def feed(self, slug, limit=None, **kwargs): """Serve the feed as RSS 2.0. If :attr:`~mediadrop.model.podcasts.Podcast.feedburner_url` is specified for this podcast, we redirect there if the useragent does not contain 'feedburner', as described here: http://www.google.com/support/feedburner/bin/answer.py?hl=en&answer=78464 :param feedburner_bypass: If true, the redirect to feedburner is disabled. :rtype: Dict :returns: podcast A :class:`~mediadrop.model.podcasts.Podcast` instance. episodes A list of :class:`~mediadrop.model.media.Media` instances that belong to the ``podcast``. Renders: :data:`podcasts/feed.xml` XML """ podcast = fetch_row(Podcast, slug=slug) if (podcast.feedburner_url and not 'feedburner' in request.environ.get( 'HTTP_USER_AGENT', '').lower() and not kwargs.get('feedburner_bypass', False)): redirect(podcast.feedburner_url.encode('utf-8')) response.content_type = content_type_for_response( ['application/rss+xml', 'application/xml', 'text/xml']) episode_query = podcast.media.published().order_by( Media.publish_on.desc()) episodes = viewable_media(episode_query) if limit is not None: episodes = episodes.limit(limit) return dict( podcast=podcast, episodes=episodes, )
def save(self, id, email_address, display_name, login_details, delete=None, **kwargs): """Save changes or create a new :class:`~mediadrop.model.auth.User` instance. :param id: User ID. If ``"new"`` a new user is created. :type id: ``int`` or ``"new"`` :returns: Redirect back to :meth:`index` after successful save. """ user = fetch_row(User, id) if delete: DBSession.delete(user) redirect(action='index', id=None) user.display_name = display_name user.email_address = email_address user.user_name = login_details['user_name'] password = login_details['password'] if password is not None and password != '': user.password = password if login_details['groups']: query = DBSession.query(Group).filter(Group.group_id.in_(login_details['groups'])) user.groups = list(query.all()) else: user.groups = [] DBSession.add(user) # Check if we're changing the logged in user's own password if user.id == request.perm.user.id \ and password is not None and password != '': DBSession.commit() # repoze.who sees the Unauthorized response and clears the cookie, # forcing a fresh login with the new password raise webob.exc.HTTPUnauthorized().exception redirect(action='index', id=None)
def post_login(self, came_from=None, **kwargs): if not request.identity: # The FriendlyForm plugin will always issue a redirect to # /login/continue (post login url) even for failed logins. # If 'came_from' is a protected page (i.e. /admin) we could just # redirect there and the login form will be displayed again with # our login error message. # However if the user tried to login from the front page, this # mechanism doesn't work so go to the login method directly here. self._increase_number_of_failed_logins() return self.login(came_from=came_from) if came_from: url_mapper = request.environ['routes.url'].mapper target = dispatch_info_for_url(came_from, url_mapper) if not is_url_for_mediadrop_domain(came_from): log.debug('no redirect to %r because target url does match our hostname (prevents parameter base redirection attacks)' % came_from) came_from = None elif (target is not None) and getattr(target.action, '_request_method', None) not in ('GET', None): log.debug('no redirect to %r because target url does not allow GET requests' % came_from) came_from = None if came_from: redirect(came_from) # It is important to return absolute URLs (if app mounted in subdirectory) if request.perm.contains_permission(u'edit') or request.perm.contains_permission(u'admin'): redirect(url_for('/admin', qualified=True)) redirect(url_for('/', qualified=True))
def post_login(self, came_from=None, **kwargs): if not request.identity: # The FriendlyForm plugin will always issue a redirect to # /login/continue (post login url) even for failed logins. # If 'came_from' is a protected page (i.e. /admin) we could just # redirect there and the login form will be displayed again with # our login error message. # However if the user tried to login from the front page, this # mechanism doesn't work so go to the login method directly here. self._increase_number_of_failed_logins() return self.login(came_from=came_from) if came_from: url_mapper = request.environ['routes.url'].mapper target = dispatch_info_for_url(came_from, url_mapper) if not is_url_for_mediadrop_domain(came_from): log.debug( 'no redirect to %r because target url does match our hostname (prevents parameter base redirection attacks)' % came_from) came_from = None elif (target is not None) and getattr(target.action, '_request_method', None) not in ('GET', None): log.debug( 'no redirect to %r because target url does not allow GET requests' % came_from) came_from = None if came_from: redirect(came_from) # It is important to return absolute URLs (if app mounted in subdirectory) if request.perm.contains_permission( u'edit') or request.perm.contains_permission(u'admin'): redirect(url_for('/admin', qualified=True)) redirect(url_for('/', qualified=True))
def save( self, id, slug, title, subtitle, author_name, author_email, description, details, feed, delete=None, **kwargs ): """Save changes or create a new :class:`~mediadrop.model.podcasts.Podcast` instance. Form handler the :meth:`edit` action and the :class:`~mediadrop.forms.admin.podcasts.PodcastForm`. Redirects back to :meth:`edit` after successful editing and :meth:`index` after successful deletion. """ podcast = fetch_row(Podcast, id) if delete: DBSession.delete(podcast) DBSession.commit() delete_thumbs(podcast) redirect(action="index", id=None) if not slug: slug = title if slug != podcast.slug: podcast.slug = get_available_slug(Podcast, slug, podcast) podcast.title = title podcast.subtitle = subtitle podcast.author = Author(author_name, author_email) podcast.description = description podcast.copyright = details["copyright"] podcast.category = details["category"] podcast.itunes_url = feed["itunes_url"] podcast.feedburner_url = feed["feedburner_url"] podcast.explicit = {"yes": True, "clean": False}.get(details["explicit"], None) if id == "new": DBSession.add(podcast) DBSession.flush() create_default_thumbs_for(podcast) redirect(action="edit", id=podcast.id)
def feed(self, slug, limit=None, **kwargs): """Serve the feed as RSS 2.0. If :attr:`~mediadrop.model.podcasts.Podcast.feedburner_url` is specified for this podcast, we redirect there if the useragent does not contain 'feedburner', as described here: http://www.google.com/support/feedburner/bin/answer.py?hl=en&answer=78464 :param feedburner_bypass: If true, the redirect to feedburner is disabled. :rtype: Dict :returns: podcast A :class:`~mediadrop.model.podcasts.Podcast` instance. episodes A list of :class:`~mediadrop.model.media.Media` instances that belong to the ``podcast``. Renders: :data:`podcasts/feed.xml` XML """ podcast = fetch_row(Podcast, slug=slug) if (podcast.feedburner_url and not 'feedburner' in request.environ.get('HTTP_USER_AGENT', '').lower() and not kwargs.get('feedburner_bypass', False)): redirect(podcast.feedburner_url.encode('utf-8')) response.content_type = content_type_for_response( ['application/rss+xml', 'application/xml', 'text/xml']) episode_query = podcast.media.published().order_by(Media.publish_on.desc()) episodes = viewable_media(episode_query) if limit is not None: episodes = episodes.limit(limit) return dict( podcast = podcast, episodes = episodes, )
def appearance_save(self, **kwargs): """Save :class:`~mediadrop.forms.admin.settings.appearanceForm`.""" settings = request.settings accepted_extensions = ('.png', '.jpg', '.jpeg', '.gif') upload_field_filenames = [ ('appearance_logo', 'logo'), ('appearance_background_image', 'bg_image'), ] #Handle a reset to defaults request first if kwargs.get('reset', None): self._update_settings(dict(appearance_settings)) generate_appearance_css(appearance_settings) return redirect(controller='admin/settings', action='appearance') appearance_dir = os.path.join(config['pylons.cache_dir'], 'appearance') for field_name, file_name in upload_field_filenames: field = kwargs['general'].pop(field_name) if isinstance(field, FieldStorage): extension = os.path.splitext(field.filename)[1].lower() if extension in accepted_extensions: #TODO: Need to sanitize manually here? full_name = '%s%s' % (file_name, extension) permanent_file = open(os.path.join(appearance_dir, full_name), 'w') shutil.copyfileobj(field.file, permanent_file) permanent_file.close() field.file.close() kwargs['general'][field_name] = full_name continue # Preserve existing setting kwargs['general'][field_name] = settings.get(field_name, '') self._save(appearance_form, values=kwargs) generate_appearance_css( [(key, setting.value) for key, setting in c.settings.iteritems()], ) redirect(action='appearance')
def result(success, message=None, comment=None): if request.is_xhr: result = dict(success=success, message=message) if comment: result['comment'] = render('comments/_list.html', {'comment_to_render': comment}, method='xhtml') return result elif success: return redirect(action='view') else: return self.view(slug, name=name, email=email, body=body, **kwargs)
def login(self, came_from=None, **kwargs): if request.environ.get('repoze.who.identity'): redirect(came_from or '/') # the friendlyform plugin requires that these values are set in the # query string form_url = url_for('/login/submit', came_from=(came_from or '').encode('utf-8'), __logins=str(self._is_failed_login())) login_errors = None if self._is_failed_login(): login_errors = Invalid('dummy', None, {}, error_dict={ '_form': Invalid(_('Invalid username or password.'), None, {}), 'login': Invalid('dummy', None, {}), 'password': Invalid('dummy', None, {}), }) return dict( login_form = login_form, form_action = form_url, form_values = kwargs, login_errors = login_errors, )
def save(self, id, display_name, group_name, permissions, delete=None, **kwargs): """Save changes or create a new :class:`~mediadrop.model.auth.Group` instance. :param id: Group ID. If ``"new"`` a new group is created. :type id: ``int`` or ``"new"`` :returns: Redirect back to :meth:`index` after successful save. """ group = fetch_row(Group, id) if delete: DBSession.delete(group) redirect(action='index', id=None) group.display_name = display_name group.group_name = group_name if permissions: query = DBSession.query(Permission).filter(Permission.permission_id.in_(permissions)) group.permissions = list(query.all()) else: group.permissions = [] DBSession.add(group) redirect(action='index', id=None)
def delete(self, id, **kwargs): """Delete a user. :param id: User ID. :type id: ``int`` :returns: Redirect back to :meth:`index` after successful delete. """ user = fetch_row(User, id) all_deletes = dict( comments=Comment.query.filter( Comment.author_name == user.user_name), podcasts=Podcast.query.filter( Podcast.author_name == user.user_name), medias=Media.query.filter(Media.author_name == user.user_name)) for need_delete in all_deletes: print(need_delete) for element in all_deletes[need_delete]: DBSession.delete(element) DBSession.delete(user) if request.is_xhr: return dict(success=True) redirect(action='index', id=None)
def post_login(self, came_from=None, **kwargs): if not request.identity: # The FriendlyForm plugin will always issue a redirect to # /login/continue (post login url) even for failed logins. # If 'came_from' is a protected page (i.e. /admin) we could just # redirect there and the login form will be displayed again with # our login error message. # However if the user tried to login from the front page, this # mechanism doesn't work so go to the login method directly here. self._increase_number_of_failed_logins() return self.login(came_from=came_from) if came_from: redirect(came_from) # It is important to return absolute URLs (if app mounted in subdirectory) if request.perm.contains_permission( u'edit') or request.perm.contains_permission(u'admin'): redirect(url_for('/admin', qualified=True)) redirect(url_for('/', qualified=True))
def save(self, id, delete=None, **kwargs): """Save changes or create a category. See :class:`~mediadrop.forms.admin.settings.categories.CategoryForm` for POST vars. :param id: Category ID :param delete: If true the category is to be deleted rather than saved. :type delete: bool :rtype: JSON dict :returns: success bool """ if tmpl_context.form_errors: if request.is_xhr: return dict(success=False, errors=tmpl_context.form_errors) else: # TODO: Add error reporting for users with JS disabled? return redirect(action='edit') cat = fetch_row(Category, id) if delete: DBSession.delete(cat) data = dict( success=True, id=cat.id, parent_options=unicode(category_form.c['parent_id'].display()), ) else: cat.name = kwargs['name'] cat.slug = get_available_slug(Category, kwargs['slug'], cat) if kwargs['parent_id']: parent = fetch_row(Category, kwargs['parent_id']) if parent is not cat and cat not in parent.ancestors(): cat.parent = parent else: cat.parent = None DBSession.add(cat) DBSession.flush() data = dict( success=True, id=cat.id, name=cat.name, slug=cat.slug, parent_id=cat.parent_id, parent_options=unicode(category_form.c['parent_id'].display()), depth=cat.depth(), row=unicode( category_row_form.display( action=url_for(id=cat.id), category=cat, depth=cat.depth(), first_child=True, )), ) if request.is_xhr: return data else: redirect(action='index', id=None)
def save(self, id, slug, title, subtitle, description, details, feed, delete=None, **kwargs): """ Save changes or create a new :class:`~mediadrop.model.podcasts.Podcast` instance. Form handler the :meth:`edit` action and the :class:`~mediadrop.forms.admin.podcasts.PodcastForm`. Redirects back to :meth:`edit` after successful editing and :meth:`index` after successful deletion. """ user = request.perm.user.display_name group = request.perm.user.groups[0].group_name podcast = fetch_row(Podcast, id) if id != 'new' and author in podcast: if group != 'admins' and podcast.author.name != user: redirect(action='index') if delete: DBSession.delete(podcast) DBSession.commit() delete_thumbs(podcast) redirect(action='index', id=None) user = request.perm.user.display_name group = request.perm.user.groups[0].group_name user_email = request.perm.user.email_address if not slug: slug = title if slug != podcast.slug: podcast.slug = get_available_slug(Podcast, slug, podcast) podcast.title = title podcast.subtitle = subtitle podcast.description = description podcast.copyright = details['copyright'] podcast.category = details['category'] podcast.itunes_url = feed['itunes_url'] podcast.feedburner_url = feed['feedburner_url'] podcast.explicit = { 'yes': True, 'clean': False }.get(details['explicit'], None) if id == 'new': podcast.author = Author(user, user_email) DBSession.add(podcast) DBSession.flush() create_default_thumbs_for(podcast) else: podcast.author = Author(podcast.author.name, podcast.author.email) redirect(action='edit', id=podcast.id)
def view(self, slug, podcast_slug=None, **kwargs): """Display the media player, info and comments. :param slug: The :attr:`~mediadrop.models.media.Media.slug` to lookup :param podcast_slug: The :attr:`~mediadrop.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:`~mediadrop.model.media.Media` instance for display. related_media A list of :class:`~mediadrop.model.media.Media` instances that rank as topically related to the given media item. comments A list of :class:`~mediadrop.model.comments.Comment` instances associated with the selected media item. 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:`~mediadrop.model.media.Media` instance. """ media = fetch_row(Media, slug=slug) request.perm.assert_permission(u'view', media.resource) 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) views = Views_Counter.query.filter(Views_Counter.media_id == media.id) #csrf = kwargs['environ']['paste.cookies'][0]['csrftoken'].value #views = views.filter(Views_Counter.csrftoken == csrf) views = views.all() if not views: try: temp = Views_Counter() temp.media_id = media.id temp.csrftoken = csrf print(temp) print(vars(temp)) DBSession.add(temp) DBSession.commit() except: DBSession.rollback() if request.settings['comments_engine'] == 'facebook': response.facebook = Facebook(request.settings['facebook_appid']) related_media = viewable_media(Media.query.related(media))[:6] # TODO: finish implementation of different 'likes' buttons # e.g. the default one, plus a setting to use facebook. return dict( media=media, related_media=related_media, comments=media.comments.published().all(), comment_form_action=url_for(action='comment'), comment_form_values=kwargs, )
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')
class PlayersController(BaseController): """Admin player preference actions""" allow_only = has_permission('admin') @expose('admin/players/index.html') @observable(events.Admin.PlayersController.index) def index(self, **kwargs): """List players. :rtype: Dict :returns: players The list of :class:`~mediadrop.model.players.PlayerPrefs` instances for this page. """ players = PlayerPrefs.query.order_by(PlayerPrefs.priority).all() return { 'players': players, } @expose('admin/players/edit.html') @observable(events.Admin.PlayersController.edit) def edit(self, id, name=None, **kwargs): """Display the :class:`~mediadrop.model.players.PlayerPrefs` for editing or adding. :param id: PlayerPrefs ID :type id: ``int`` or ``"new"`` :rtype: dict :returns: """ playerp = fetch_row(PlayerPrefs, id) return { 'player': playerp, 'form': playerp.settings_form, 'form_action': url_for(action='save'), 'form_values': kwargs, } @expose(request_method='POST') @autocommit 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) @expose(request_method='POST') @autocommit @observable(events.Admin.PlayersController.delete) def delete(self, id, **kwargs): """Delete a PlayerPref. After deleting the PlayerPref, cleans up the players table, ensuring that each Player class is represented--if the deleted PlayerPref is the last example of that Player class, creates a new disabled PlayerPref for that Player class with the default settings. :param id: Player ID. :type id: ``int`` :returns: Redirect back to :meth:`index` after successful delete. """ player = fetch_row(PlayerPrefs, id) DBSession.delete(player) DBSession.flush() cleanup_players_table() redirect(action='index', id=None) @expose(request_method='POST') @autocommit @observable(events.Admin.PlayersController.enable) def enable(self, id, **kwargs): """Enable a PlayerPref. :param id: Player ID. :type id: ``int`` :returns: Redirect back to :meth:`index` after success. """ player = fetch_row(PlayerPrefs, id) player.enabled = True update_enabled_players() redirect(action='index', id=None) @expose(request_method='POST') @autocommit @observable(events.Admin.PlayersController.disable) def disable(self, id, **kwargs): """Disable a PlayerPref. :param id: Player ID. :type id: ``int`` :returns: Redirect back to :meth:`index` after success. """ player = fetch_row(PlayerPrefs, id) player.enabled = False update_enabled_players() redirect(action='index', id=None) @expose(request_method='POST') @autocommit @observable(events.Admin.PlayersController.reorder) def reorder(self, id, direction, **kwargs): """Reorder a PlayerPref. :param id: Player ID. :type id: ``int`` :param direction: ``"up"`` for higher priority, ``"down"`` for lower priority :type direction: ``unicode`` :returns: Redirect back to :meth:`index` after success. """ if direction == 'up': offset = -1 elif direction == 'down': offset = 1 else: return player1 = fetch_row(PlayerPrefs, id) new_priority = player1.priority + offset try: player2 = fetch_row(PlayerPrefs, priority=new_priority) player2.priority = player1.priority player1.priority = new_priority except HTTPException, e: if e.code != 404: raise redirect(action='index', id=None)
def save(self, id, slug, title, author_name, author_email, description, notes, podcast, tags, categories, delete=None, **kwargs): """Save changes or create a new :class:`~mediadrop.model.media.Media` instance. Form handler the :meth:`edit` action and the :class:`~mediadrop.forms.admin.media.MediaForm`. Redirects back to :meth:`edit` after successful editing and :meth:`index` after successful deletion. """ media = fetch_row(Media, id) if delete: self._delete_media(media) redirect(action='index', id=None) if not slug: slug = slugify(title) elif slug.startswith('_stub_'): slug = slug[len('_stub_'):] if slug != media.slug: media.slug = get_available_slug(Media, slug, media) media.title = title media.author = Author(author_name, author_email) media.description = description media.notes = notes media.podcast_id = podcast media.set_tags(tags) media.set_categories(categories) media.update_status() DBSession.add(media) DBSession.flush() if id == 'new' and not has_thumbs(media): create_default_thumbs_for(media) if request.is_xhr: status_form_xhtml = unicode( update_status_form.display(action=url_for( action='update_status', id=media.id), media=media)) return dict( media_id=media.id, values={'slug': slug}, link=url_for(action='edit', id=media.id), status_form=status_form_xhtml, ) else: redirect(action='edit', id=media.id)
def post_logout(self, came_from=None, **kwargs): redirect('/')
def _save(self, form, redirect_action=None, values=None): """Save the values from the passed in form instance.""" values = self._flatten_settings_from_form(form, values) self._update_settings(values) if redirect_action: helpers.redirect(action=redirect_action)
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')
def index(self, **kwargs): redirect(action='general')