def changelog(self, old_state, action): """Creates a ChangeLog model out of old and current state of a comment """ record = ChangeLog() record.user_id = self.user_id record.comment_id = self.id record.before = old_state record.after = helpers.orm_to_json(self) record.action = action return record
def comment_api(comment_id): """handler for all commands for comment-related RESTful API PUT or POST /comment/ args: user_id, value, entity_id, parent_id creates a comment owned by `user_id` with value `value` `parent_id` is an optional arg, if present, decides parent comment (for nested comments) `entity_id` ties comment to some specific external entity entity should match the one from parent. It is mandatory, and can be omitted only if parent_id was specified. PUT or POST /comment/COMMENT_ID/ args: user_id, value updates comment with value. Comment user_id should match the one specified DELETE /comment/COMMENT_ID/ args: user_id deletes comment. Should not have subcomments to work. GET /comment/COMMENT_ID/ returns a json-encoded comment data along with some additional useful information, such as creation date """ #comment identification #depending on it we'll create or fetch an object from db if not comment_id and request.method in ('DELETE', 'GET'): abort(403) if comment_id: comment = models.Comment.query.get_or_404(comment_id) else: comment = models.Comment() parent_id = request.form.get('parent_id') entity_id = request.form.get('entity_id') if parent_id: try: comment.parent_id = int(parent_id) except ValueError: abort(400) parent = models.Comment.query.get_or_404(parent_id) #sanity_check that parent linked to the same entity if entity_id and parent.entity_id != entity_id: abort(400) comment.entity_id = parent.entity_id else: #no parent specified, top-level comment comment.entity_id = entity_id or abort(400) current_app.db.session.add(comment) #user validation if request.method in ('POST', 'PUT', 'DELETE'): user_id = request.form.get('user_id') or abort(400) #400 bad request try: user_id = int(user_id) except ValueError: abort(400) if comment.id and comment.user_id != user_id: abort(403) #user tried to alter comment he doesnt own comment.user_id = user_id #end of various validation and sanitychecks old_state = helpers.orm_to_json(comment) if request.method == 'DELETE': if comment.has_children(): abort(403) current_app.db.session.delete(comment) elif request.method in ('POST', 'PUT'): new_value = request.form.get('value') if new_value is not None: comment.value = new_value if request.method in ('DELETE', 'POST', 'PUT'): current_app.db.session.commit() #flush changes to db changelog = comment.changelog(old_state, request.method) current_app.db.session.add(changelog) current_app.db.session.commit() if request.method == 'DELETE': comment.wipe_parents() if not comment_id: #newly added comment comment.rebuild_parents() rendered_data = helpers.orm_to_json(comment) tasks.trigger_subscriptions.delay(comment.entity_id, rendered_data) return make_response(rendered_data)