def save(self, db_conn): """ Overwrite save method to add to Elasticsearch. """ # TODO-2 should we validate the save worked before going to ES? from database.topic import get_topic, deliver_topic from database.user import get_user, deliver_user data = json_prep(self.deliver()) topic = get_topic({'id': self['topic_id']}, db_conn) if topic: data['topic'] = json_prep(deliver_topic(topic)) user = get_user({'id': self['user_id']}, db_conn) if user: data['user'] = json_prep(deliver_user(user)) es.index( index='entity', doc_type='post', body=data, id=self['id'], ) return super().save(db_conn)
def test_add_topic_to_es(db_conn): create_test_topics(db_conn) params = { 'id': test_topic_id, } topic = get_topic(db_conn, params) assert add_topic_to_es(topic)
def update_topic_route(request, topic_id): """ Update the topic. - Only the name can be changed. - Only by original author. """ db_conn = request['db_conn'] current_user = get_current_user(request) if not current_user: return abort(401) # ## STEP 1) Find existing topic instance ## # topic = get_topic({'id': topic_id}, db_conn) if not topic: return abort(404) if topic['user_id'] != current_user['id']: return abort(403) # ## STEP 2) Limit the scope of changes ## # topic_data = request['params']['topic'] topic_data = pick(topic_data, ('name', )) # ## STEP 3) Validate and save topic instance ## # topic, errors = update_topic(topic, topic_data, db_conn) if errors: errors = prefix_error_names('topic.', errors) return 400, { 'errors': errors, 'ref': 'k7ItNedf0I0vXfiIUcDtvHgQ', } # ## STEP 4) Return response ## # return 200, {'topic': deliver_topic(topic)}
def update_topic_route(request, topic_id): """ Update the topic. - Only the name can be changed. - Only by original author. """ db_conn = request['db_conn'] current_user = get_current_user(request) if not current_user: return abort(401, 'ZUiN62FFR3OcBM6s8UJSmg') # ## STEP 1) Find existing topic instance ## # topic = get_topic(db_conn, {'id': topic_id}) if not topic: return abort(404, 'MXzNqBU6SN28tNtRXW9rNw') if topic['user_id'] != current_user['id']: return abort(403, 'MZZbJNt3RK-4kVMo2rROWA') # ## STEP 2) Validate and save topic instance ## # topic_data = request['params'] topic, errors = update_topic(db_conn, topic, topic_data) if errors: return 400, { 'errors': errors, 'ref': 'zu7VABcJT5qCzF7BHNCH5w', } # ## STEP 3) Return response ## # return 200, {'topic': deliver_topic(topic)}
def test_get_topic(db_conn): create_test_topics(db_conn) params = { 'id': test_topic_id, } topic = get_topic(db_conn, params) assert topic assert topic['id'] == test_topic_id
def test_deliver_topic(db_conn): create_test_topics(db_conn) params = { 'id': test_topic_id, } topic = get_topic(db_conn, params) topic = deliver_topic(topic, access=None) assert topic
def test_update_topic(db_conn): create_test_topics(db_conn) params = { 'id': test_topic_id, } prev_data = get_topic(db_conn, params) assert prev_data data = { 'name': 'a', } topic, errors = update_topic(db_conn, prev_data, data) assert not errors assert topic
def get_topic_route(request, topic_id): """ Get a topic """ db_conn = request['db_conn'] topic = get_topic(db_conn, {'id': topic_id}) if not topic: return 404, { 'errors': [{ 'name': 'topic_id', 'message': c('no_topic'), }], 'ref': 'o5V4uBFXQC6WNeyKrhn5kA', } return 200, {'topic': deliver_topic(topic)}
def is_valid_entity(db_conn, follow): """ Check that the entity ID of the follow is valid. """ kind = follow['entity_kind'] stuff = None if kind == 'topic': stuff = get_topic(db_conn, {'id': follow['entity_id']}) else: stuff = list_one_entity_versions(db_conn, kind, follow['entity_id']) if not stuff: return [{ 'name': 'entity_id', 'message': 'Not a valid entity', 'ref': '_ubTBizJQDuBfS5f0Xb5qQ', }] return []
def add_post_to_es(db_conn, post): """ Upsert the post data into elasticsearch. """ from database.topic import get_topic, deliver_topic from database.user import get_user, deliver_user data = json_prep(deliver_post(post)) topic = get_topic(db_conn, {'id': post['topic_id']}) if topic: data['topic'] = json_prep(deliver_topic(topic)) user = get_user(db_conn, {'id': post['user_id']}) if user: data['user'] = json_prep(deliver_user(user)) return es.index( index='entity', doc_type='post', body=data, id=convert_uuid_to_slug(post['id']), )
def create_post_route(request, topic_id): """ Create a new post on a given topic. Proposal: must include entity (card, unit, or set) information. Vote: must refer to a valid proposal. """ db_conn = request['db_conn'] current_user = get_current_user(request) if not current_user: return abort(401) topic = get_topic({'id': topic_id}, db_conn) if not topic: return 404, { 'errors': [{ 'name': 'topic_id', 'message': c('no_topic'), }], 'ref': 'PCSFCxsJtnlP0x9WzbPoKcwM', } # ## STEP 1) Create post (and entity) instances post_data = request['params'].get('post') if not post_data: return 400, { 'errors': [{ 'name': 'post', 'message': 'Missing post data.', }], 'ref': 'ykQpZwJKq54MTCxgkx0p6baW' } post_data = omit(post_data, ( 'id', 'created', 'modified', )) post_data['user_id'] = current_user['id'] post_data['topic_id'] = topic_id post_ = instance_post_facade(post_data) post_kind = post_['kind'] if post_kind == 'proposal': entity = instance_new_entity(request['params']) entity_kind = get_kind(request['params']) post_['entity_version'] = { 'id': entity['id'], 'kind': entity_kind, } # ## STEP 2) Validate post (and entity) instances errors = prefix_error_names('post.', post_.validate(db_conn)) if post_kind == 'proposal': errors = (errors + prefix_error_names('entity.', entity.validate(db_conn))) if len(errors): return 400, {'errors': errors, 'ref': 'tux33ztgFj9ittSpS7WKIkq7'} # ## STEP 3) Save post (and entity) post_.save(db_conn) if post_kind == 'proposal': entity.save(db_conn) # ## STEP 4) Add author as a follower insert_follow( { 'user_id': current_user['id'], 'entity': { 'id': topic['id'], 'kind': 'topic', } }, db_conn) # TODO-2 also follow the entity # ## STEP 5) Make updates based on proposal / vote status if post_kind == 'proposal': update_entity_status(db_conn, post_) if post_kind == 'vote': proposal = Proposal.get(db_conn, id=post_['replies_to_id']) update_entity_status(db_conn, proposal) # ## STEP 6) Send notices if post_kind == 'proposal': send_notices(db_conn, entity_id=topic['entity']['id'], entity_kind=topic['entity']['kind'], notice_kind='create_proposal', notice_data={ 'user_name': current_user['name'], 'topic_name': topic['name'], 'entity_kind': topic['entity']['kind'], 'entity_name': topic['entity']['id'], }) # ## STEP 7) Return response return 200, {'post': post_.deliver()}
def get_posts_route(request, topic_id): """ Get a reverse chronological listing of posts for given topic. Includes topic meta data and posts (or proposals or votes). Paginates. """ db_conn = request['db_conn'] # Is the topic valid? topic = get_topic({'id': topic_id}, db_conn) if not topic: return 404, { 'errors': [{ 'name': 'topic_id', 'message': c('no_topic'), }], 'ref': 'pgnNbqSP1VUWkOYq8MVGPrSS', } # Pull the entity entity_kind = topic['entity']['kind'] entity = get_latest_accepted(db_conn, entity_kind, topic['entity']['id']) # Pull all kinds of posts posts = get_posts_facade(db_conn, limit=request['params'].get('limit') or 10, skip=request['params'].get('skip') or 0, topic_id=topic_id) # For proposals, pull up the proposal entity version # ...then pull up the previous version # ...make a diff between the previous and the proposal entity version diffs = {} entity_versions = {} for post_ in posts: if post_['kind'] == 'proposal': entity_version = entity_versions[post_['id']] = get_version( db_conn, post_['entity_version']['kind'], post_['entity_version']['id']) previous_version = get_version(db_conn, post_['entity_version']['kind'], entity_version['previous_id']) if previous_version: diffs[post_['id']] = object_diff(previous_version.deliver(), entity_version.deliver()) # TODO-2 SPLITUP create new endpoint for this instead users = {} for post_ in posts: user_id = post_['user_id'] if user_id not in users: user = get_user({'id': user_id}, db_conn) if user: users[user_id] = { 'name': user['name'], 'avatar': get_avatar(user['email'], 48), } # TODO-2 SPLITUP create new endpoints for these instead output = { 'topic': deliver_topic(topic), 'posts': [p.deliver() for p in posts], 'entity_versions': {p: ev.deliver('view') for p, ev in entity_versions.items()}, # 'diffs': diffs, TODO-2 this causes a circular dependency 'users': users, } if entity: output[entity_kind] = entity.deliver() return 200, output