Source code for fireblog.comments

'Functionality for adding, viewing and deleting comments.'
import fireblog.utils as utils
import fireblog.events as events
from fireblog.utils import urlify as u
from fireblog.views import invalidate_current_post
from fireblog.settings import settings_dict
from fireblog.theme import render_to_response
import requests
import logging
from pyramid.view import view_config
from pyramid.httpexceptions import (
    HTTPFound,
    HTTPNotFound,
)
from fireblog.models import (
    DBSession,
    Post,
    Comments,
    Users,
)


log = logging.getLogger(__name__)


[docs]def add_comment_section_below_posts(event) -> None: """This function should be passed an instance of :py:class:`fireblog.events.RenderingPost`. It adds a comment section onto the event parameter.""" comments_list = render_comments_list_from_event(event) comment_add_url = event.request.route_url('comment_add') html = render_to_response('comments.mako', {'comments': comments_list, 'comment_add_url': comment_add_url, 'post_title': event.post.name, 'post_id': event.post.id}, event.request).text event.sections.append(html)
[docs]def render_comments_list_from_event(event) -> list: """This function should be passed an instance of :py:class:`fireblog.events.RenderingPost`. It returns a list of comments associated with that post.""" comments = event.post.comments comments_list = [] for comment in comments: to_append = {} to_append['created'] = utils.format_datetime(comment.created) to_append['author'] = comment.author.username to_append['comment'] = comment.comment to_append['uuid'] = comment.uuid comments_list.append(to_append) return comments_list
@view_config(route_name='comment_add', request_param='form.submitted')
[docs]def comment_add(request): '''Add a comment to a post. We allow anyone to have access to this view. But we check whether a person is authenticated or not within this view. This is because we are allowing people to add comments anonymously ie not under an individual userid/username. If a person is not authenticated, ie they are adding a comment anonymously, we run a Recaptcha test to try and avoid spam comments.''' post_id = request.params.get('post-id', None) comment_text = request.params.get('comment', None) if not request.authenticated_userid: recaptcha = request.params.get('g-recaptcha-response', '') recaptcha_site_secret = settings_dict['fireblog.recaptcha_secret'] payload = dict(secret=recaptcha_site_secret, response=recaptcha) result = requests.post( 'https://www.google.com/recaptcha/api/siteverify', data=payload) try: if not result.json()['success']: log.info('Failed recaptcha: {}'.format(recaptcha)) return HTTPNotFound() except Exception: log.warn('Malformed response from Google recaptcha') log.warn(result) return HTTPNotFound() author = request.authenticated_userid or utils.get_anonymous_userid() if not all((post_id, comment_text, author)): log.info('Some required params for adding a comment are missing:') log.info('Post id: '.format(post_id)) log.info('Comment text: '.format(comment_text)) log.info('Author: '.format(author)) return HTTPNotFound() post = DBSession.query(Post).filter_by(id=post_id).one() author = DBSession.query(Users).filter_by(userid=author).one() comment = Comments(comment=comment_text) comment.author = author post.comments.append(comment) log.info('Added new comment written by {}'.format(author)) log.debug('Firing CommentAdded event') request.registry.notify(events.CommentAdded(post=post, comment=comment)) return HTTPFound(location=request.route_url('view_post', id=post_id, postname=u(post.name)))
@view_config(route_name='comment_del', permission='comment-del')
[docs]def comment_delete(request): """Delete a comment and redirect back to the post associated with the comment.""" comment_uuid = request.params.get('comment-uuid', None) post_id = request.params.get('post-id', None) if not all((comment_uuid, post_id)): log.info('Some required params for deleting a comment are missing:') log.info('Post id: '.format(post_id)) log.info('Comment uuid: '.format(comment_uuid)) return HTTPNotFound() comment = DBSession.query(Comments).filter_by(uuid=comment_uuid).first() if not comment: log.debug('No comment found for comment uuid: {}'.format(comment_uuid)) return HTTPNotFound() log.debug('Firing CommentDeleted event') request.registry.notify(events.CommentDeleted( post=comment.post, comment=comment)) DBSession.delete(comment) log.info('Comment with uuid {} deleted'.format(comment_uuid)) return HTTPFound(location=request.route_url('view_post', id=post_id, postname=u(comment.post.name)))
[docs]def includeme(config): """Add views for adding and deleting comments. Also, invalidate a cached post when we add or delete a comment on it.""" log.debug('Including comment routes, views.') config.add_route('comment_add', '/add') config.add_route('comment_del', '/del') config.add_subscriber(add_comment_section_below_posts, events.RenderingPost) log.debug('Subscribing to comment add/delete events to invalidate ' 'corresponding post') config.add_subscriber(invalidate_current_post, events.CommentAdded) config.add_subscriber(invalidate_current_post, events.CommentDeleted)