예제 #1
0
    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)
예제 #2
0
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)
예제 #3
0
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)}
예제 #4
0
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)}
예제 #5
0
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
예제 #6
0
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
예제 #7
0
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
예제 #8
0
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)}
예제 #9
0
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 []
예제 #10
0
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']),
    )
예제 #11
0
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()}
예제 #12
0
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