示例#1
0
def update_post_route(request, topic_id, post_id):
    """
    Update an existing post. Must be one's own post.

    For post:
    - Only the body field may be changed.

    For proposals:
    - Only the name, body, and status fields can be changed.
    - The status can only be changed to declined, and only when
      the current status is pending or blocked.

    For votes:
    - The only fields that can be updated are body and response.
    """

    db_conn = request['db_conn']

    current_user = get_current_user(request)
    if not current_user:
        return abort(401)

    # ## STEP 1) Find existing post instance ## #
    post_ = get_post_facade(db_conn, post_id)
    if not post_:
        return abort(404)
    if post_['user_id'] != current_user['id']:
        return abort(403)
    post_kind = post_['kind']

    # ## STEP 2) Limit the scope of changes ## #
    post_data = request['params']['post']
    if post_kind is 'post':
        post_data = pick(post_data, ('body',))
    elif post_kind is 'proposal':
        post_data = pick(post_data, ('name', 'body', 'status',))
        if (post_data.get('status') != 'declined' or
                post_data.get('status') not in ('pending', 'blocked',)):
            del post_data['status']
    elif post_kind is 'vote':
        post_data = pick(post_data, ('body', 'response',))

    # ## STEP 3) Validate and save post instance ## #
    post_, errors = post_.update(db_conn, post_data)
    if errors:
        errors = prefix_error_names('post.', errors)
        return 400, {
            'errors': errors,
            'ref': 'E4LFwRv2WEJZks7use7TCpww'
        }

    # ## STEP 4) 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 5) Return response ## #
    return 200, {'post': post_.deliver()}
示例#2
0
def test_update_document(db_conn):
    schema = vases_schema
    data1 = {
        'name': 'celestial',
        'plants': [
            {'species': 'zzplant', 'quantity': 2},
            {'species': 'rubbertree', 'quantity': 1},
        ],
        'soil': {'color': 'black'}
    }
    document1, errors1 = util.insert_document(schema, data1, db_conn)
    subdoc1 = pick(document1, ('name', 'plants', 'soil'))
    subdata1 = pick(data1, ('name', 'plants', 'soil'))
    data2 = {
        'id': 'haxxor',
        'name': 'zen',
    }
    document2, errors2 = util.update_document(schema,
                                              document1, data2, db_conn)
    subdoc2 = pick(document2, ('name', 'plants', 'soil'))
    subdata2 = pick(data2, ('name', 'plants', 'soil'))
    assert len(errors1) == 0
    assert subdoc1 == subdata1
    assert document1['id'] == document2['id']
    assert len(errors2) == 0
    assert subdoc2 == extend({}, subdata1, subdata2)
示例#3
0
def test_insert_document(db_conn, vases_table):
    schema = vases_schema
    data = {
        'id':
        'haxxor',
        'name':
        'celestial',
        'plants': [
            {
                'species': 'zzplant',
                'quantity': 2
            },
            {
                'species': 'rubbertree',
                'quantity': 1
            },
        ],
        'soil': {
            'color': 'black'
        }
    }
    document, errors = util.insert_document(schema, data, db_conn)
    subdoc = pick(document, ('name', 'plants', 'soil'))
    subdata = pick(data, ('name', 'plants', 'soil'))
    assert document['id'] != data['id']
    assert len(errors) == 0
    assert subdoc == subdata
示例#4
0
def test_update_document(db_conn):
    schema = vases_schema
    data1 = {
        'name':
        'celestial',
        'plants': [
            {
                'species': 'zzplant',
                'quantity': 2
            },
            {
                'species': 'rubbertree',
                'quantity': 1
            },
        ],
        'soil': {
            'color': 'black'
        }
    }
    document1, errors1 = util.insert_document(schema, data1, db_conn)
    subdoc1 = pick(document1, ('name', 'plants', 'soil'))
    subdata1 = pick(data1, ('name', 'plants', 'soil'))
    data2 = {
        'id': 'haxxor',
        'name': 'zen',
    }
    document2, errors2 = util.update_document(schema, document1, data2,
                                              db_conn)
    subdoc2 = pick(document2, ('name', 'plants', 'soil'))
    subdata2 = pick(data2, ('name', 'plants', 'soil'))
    assert len(errors1) == 0
    assert subdoc1 == subdata1
    assert document1['id'] == document2['id']
    assert len(errors2) == 0
    assert subdoc2 == extend({}, subdata1, subdata2)
示例#5
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)}
示例#6
0
文件: topic.py 项目: Folashade/sagefy
def update_topic_route(request, topic_id):
    """
    Update the topic.
    - Only the name can be changed.
    - Only by original author.
    """

    current_user = get_current_user(request)
    if not current_user:
        return abort(401)

    # ## STEP 1) Find existing topic instance ## #
    topic = Topic.get(id=topic_id)
    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 = topic.update(topic_data)
    if errors:
        errors = prefix_error_names('topic.', errors)
        return 400, {
            'errors': errors,
            'ref': 'k7ItNedf0I0vXfiIUcDtvHgQ',
        }

    # ## STEP 4) Return response ## #
    return 200, {'topic': topic.deliver()}
示例#7
0
    def update(self, db_conn, data):
        """
        Only allow changes to the status on update.
        """

        data = pick(data, ('status', 'available'))
        return super().update(db_conn, data)
示例#8
0
文件: util.py 项目: wincax88/sagefy
 def _(data, schema):
     for name, field_schema in schema.items():
         if 'embed' in field_schema and name in data:
             data[name] = _(data[name], field_schema['embed'])
         elif 'embed_many' in field_schema and name in data:
             for i, d in enumerate(data[name]):
                 data[name][i] = _(d, field_schema['embed_many'])
     return pick(data, schema.keys())
示例#9
0
def test_insert_document(db_conn, vases_table):
    schema = vases_schema
    data = {
        'id': 'haxxor',
        'name': 'celestial',
        'plants': [
            {'species': 'zzplant', 'quantity': 2},
            {'species': 'rubbertree', 'quantity': 1},
        ],
        'soil': {'color': 'black'}
    }
    document, errors = util.insert_document(schema, data, db_conn)
    subdoc = pick(document, ('name', 'plants', 'soil'))
    subdata = pick(data, ('name', 'plants', 'soil'))
    assert document['id'] != data['id']
    assert len(errors) == 0
    assert subdoc == subdata
示例#10
0
def update_user_password(prev_data, data, db_conn):
    """
    Overwrite update method to add password.
    """

    schema = user_schema
    data = pick(data, ('password',))
    data, errors = update_document(schema, prev_data, data, db_conn)
    return data, errors
示例#11
0
def update_user_password(prev_data, data, db_conn):
    """
    Overwrite update method to add password.
    """

    schema = user_schema
    data = pick(data, ('password',))
    data, errors = update_document(schema, prev_data, data, db_conn)
    return data, errors
示例#12
0
def list_posts_by_user(db_conn, params):
    """
  Get a list of posts in Sagefy.
  """

    query = """
    SELECT *
    FROM posts
    WHERE user_id = %(user_id)s
    ORDER BY created ASC;
    /* TODO OFFSET LIMIT */
  """
    params = pick(params, ('user_id', ))
    return list_rows(db_conn, query, params)
示例#13
0
def set_learning_context(user, **d):
    """
    Update the learning context of the user.

    Keys: `card`, `unit`, `subject`
        `next`: `method` and `path`
    """

    context = get_learning_context(user)
    d = pick(d, ('card', 'unit', 'subject', 'next'))
    context.update(d)
    context = compact_dict(context)
    key = 'learning_context_{id}'.format(id=user['id'])
    redis.setex(key, 10 * 60, json.dumps(context, default=json_serial))
    return context
示例#14
0
def set_learning_context(user, **d):
    """
    Update the learning context of the user.

    Keys: `card`, `unit`, `set`
        `next`: `method` and `path`
    """

    context = get_learning_context(user)
    d = pick(d, ('card', 'unit', 'set', 'next'))
    context.update(d)
    context = compact_dict(context)
    key = 'learning_context_{id}'.format(id=user['id'])
    redis.setex(key, 10 * 60, json.dumps(context, default=json_serial))
    return context
示例#15
0
文件: user.py 项目: Folashade/sagefy
    def set_learning_context(self, **d):
        """
        Update the learning context of the user.

        Keys: `card`, `unit`, `set`
            `next`: `method` and `path`
        """

        context = self.get_learning_context()
        d = pick(d, ("card", "unit", "set", "next"))
        context.update(d)
        context = compact_dict(context)
        key = "learning_context_{id}".format(id=self["id"])
        redis.setex(key, 10 * 60, json.dumps(context, default=json_serial))
        return context
示例#16
0
def insert_notice(db_conn, data):
    """
  Create a new notice.
  """

    schema = notice_schema
    query = """
    INSERT INTO notices
    (  user_id  ,   kind  ,   data  )
    VALUES
    (%(user_id)s, %(kind)s, %(data)s)
    RETURNING *;
  """
    data = pick(data, ('user_id', 'kind', 'data'))
    data, errors = insert_row(db_conn, schema, query, data)
    return data, errors
示例#17
0
def insert_response(db_conn, data):
    """
  Create a new response.
  """

    schema = response_schema
    query = """
    INSERT INTO responses
    (  user_id  ,   card_id  ,   unit_id  ,
       response  ,   score  ,   learned  )
    VALUES
    (%(user_id)s, %(card_id)s, %(unit_id)s,
     %(response)s, %(score)s, %(learned)s)
    RETURNING *;
  """
    data = pick(
        data,
        ('user_id', 'card_id', 'unit_id', 'response', 'score', 'learned'))
    return insert_row(db_conn, schema, query, data)
示例#18
0
def insert_topic(db_conn, data):
    """
  Create a new topic.
  """

    schema = topic_schema
    query = """
    INSERT INTO topics
    (  user_id  ,   entity_id  ,   entity_kind  ,   name  )
    VALUES
    (%(user_id)s, %(entity_id)s, %(entity_kind)s, %(name)s)
    RETURNING *;
  """
    data = pick(data, ('user_id', 'entity_id', 'entity_kind', 'name'))
    if data.get('entity_id'):
        data['entity_id'] = convert_slug_to_uuid(data['entity_id'])
    data, errors = insert_row(db_conn, schema, query, data)
    if not errors:
        add_topic_to_es(data)
    return data, errors
def insert_card_parameters(db_conn, data):
    """
  Insert Card Parameters [hidden]
  """

    schema = card_parameters_schema
    query = """
    INSERT INTO cards_parameters
    (  entity_id  ,   guess_distribution  ,   slip_distribution  )
    VALUES
    (%(entity_id)s, %(guess_distribution)s, %(slip_distribution)s)
    RETURNING *;
  """
    data = pick(data, (
        'entity_id',
        'guess_distribution',
        'slip_distribution',
    ))
    data, errors = insert_row(db_conn, schema, query, data)
    return data, errors
示例#20
0
def insert_follow(db_conn, data):
    """
  Create a new follow (user <-> entity).
  """

    already_has = get_follow(db_conn,
                             convert_slug_to_uuid(data.get('user_id')),
                             convert_slug_to_uuid(data.get('entity_id')))
    if already_has:
        return {}, [{
            'name': 'entity_id',
            'message': 'You already followed this entity.',
            'ref': 'EqvXy6p0TneEnB1qD__fdg',
        }]

    schema = follow_schema
    query = """
    INSERT INTO follows
    (  user_id  ,   entity_id  ,   entity_kind  )
    VALUES
    (%(user_id)s, %(entity_id)s, %(entity_kind)s)
    RETURNING *;
  """
    data = pick(data, ('user_id', 'entity_id', 'entity_kind'))
    data = {
        'user_id': convert_slug_to_uuid(data.get('user_id')),
        'entity_id': convert_slug_to_uuid(data.get('entity_id')),
        'entity_kind': data.get('entity_kind'),
    }
    errors = is_valid_entity(db_conn, data)
    if errors:
        return None, [{
            'name': 'entity_id',
            'message': 'invalid entity',
            'ref': 'ph-XrElITuyixCzqu_OTTA',
        }]
    data, errors = insert_row(db_conn, schema, query, data)
    return data, errors
示例#21
0
    'id': 'eileen',
    'created': r.time(2014, 1, 1, 'Z'),
    'modified': r.time(2014, 1, 1, 'Z'),
    'name': 'eileen',
    'email': '*****@*****.**',
    'password': bcrypt.encrypt('example1'),
    'settings': {
        'email_frequency': 'daily',
        'view_sets': 'public',
        'view_follows': 'public',
    }
}]).run(database.db_conn))

users = database.db.table('users').run(database.db_conn)
for user in users:
    data = pick(json_prep(user), ('id', 'name'))
    data['avatar'] = get_avatar(user['email'])
    es.index(
        index='entity',
        doc_type='user',
        body=data,
        id=user['id'],
    )

(database.db.table('units').insert([{
    'id': 'plus-1',
    'created': r.time(2014, 1, 1, 'Z'),
    'modified': r.time(2014, 1, 1, 'Z'),
    'entity_id': 'plus',
    'previous_id': None,
    'language': 'en',
示例#22
0
def es_populate():
  db_conn = make_db_connection()

  # Empty the database
  es.indices.delete(index='entity', ignore=[400, 404])

  # Add users
  cur = db_conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor)
  with cur:
    cur.execute("SELECT * FROM users;")
    data = cur.fetchall()
    users = [row for row in data]
    db_conn.commit()
  for user in users:
    data = pick(json_prep(user), ('id', 'name'))
    data['avatar'] = get_avatar(user['email'])
    es.index(
      index='entity',
      doc_type='user',
      body=data,
      id=convert_uuid_to_slug(user['id']),
    )

  # Add units
  cur = db_conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor)
  with cur:
    cur.execute("""
      SELECT DISTINCT ON (entity_id) *
      FROM units
      WHERE status = 'accepted'
      ORDER BY entity_id, created DESC;
    """)
    data = cur.fetchall()
    units = [row for row in data]
    db_conn.commit()
  for unit in units:
    es.index(
      index='entity',
      doc_type='unit',
      body=json_prep(unit),
      id=convert_uuid_to_slug(unit['entity_id']),
    )

  # Add cards
  cur = db_conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor)
  with cur:
    cur.execute("""
      SELECT DISTINCT ON (entity_id) *
      FROM cards
      WHERE status = 'accepted'
      ORDER BY entity_id, created DESC;
    """)
    data = cur.fetchall()
    cards = [row for row in data]
    db_conn.commit()
  for card in cards:
    es.index(
      index='entity',
      doc_type='card',
      body=json_prep(card),
      id=convert_uuid_to_slug(card['entity_id']),
    )

  # Add subjects
  cur = db_conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor)
  with cur:
    cur.execute("""
      SELECT DISTINCT ON (entity_id) *
      FROM subjects
      WHERE status = 'accepted'
      ORDER BY entity_id, created DESC;
    """)
    data = cur.fetchall()
    subjects = [row for row in data]
    db_conn.commit()
  for subject in subjects:
    es.index(
      index='entity',
      doc_type='subject',
      body=json_prep(subject),
      id=convert_uuid_to_slug(subject['entity_id']),
    )

  """
  TODO-1 fix these
  # Add topics
  topics = r.table('topics').run(db_conn)
  for topic in topics:
    es.index(
      index='entity',
      doc_type='topic',
      body=json_prep(topic),
      id=topic['id'],
    )

  # Add posts
  posts = r.table('posts').run(db_conn)
  for post in posts:
    data = json_prep(post)
    topic = (r.table('topics')
         .get(data['topic_id'])
         .run(db_conn))
    user = (r.table('users')
         .get(data['user_id'])
         .run(db_conn))
    data['topic'] = json_prep(topic)
    data['user'] = pick(json_prep(user), ('id', 'name'))
    es.index(
      index='entity',
      doc_type='post',
      body=data,
      id=post['id'],
    )
  """

  close_db_connection(db_conn)
示例#23
0
from framework.database import setup_db, make_db_connection, \
    close_db_connection
from framework.elasticsearch import es
from modules.util import json_prep, pick
from database.user import get_avatar

setup_db()
db_conn = make_db_connection()

# Empty the database
es.indices.delete(index='entity', ignore=[400, 404])

# Add users
users = r.table('users').run(db_conn)
for user in users:
    data = pick(json_prep(user), ('id', 'name'))
    data['avatar'] = get_avatar(user['email'])
    es.index(
        index='entity',
        doc_type='user',
        body=data,
        id=user['id'],
    )

# Add units
units = (r.table('units').filter(r.row['status'].eq('accepted')).group(
    'entity_id').max('created').default(None).ungroup().map(
        r.row['reduction']).run(db_conn))

for unit in units:
    es.index(
示例#24
0
def update_post_route(request, topic_id, post_id):
    """
    Update an existing post. Must be one's own post.

    For post:
    - Only the body field may be changed.

    For proposals:
    - Only the name, body, and status fields can be changed.
    - The status can only be changed to declined, and only when
      the current status is pending or blocked.

    For votes:
    - The only fields that can be updated are body and response.
    """

    db_conn = request['db_conn']

    current_user = get_current_user(request)
    if not current_user:
        return abort(401)

    # ## STEP 1) Find existing post instance ## #
    post_ = get_post_facade(db_conn, post_id)
    if not post_:
        return abort(404)
    if post_['user_id'] != current_user['id']:
        return abort(403)
    post_kind = post_['kind']

    # ## STEP 2) Limit the scope of changes ## #
    post_data = request['params']['post']
    if post_kind is 'post':
        post_data = pick(post_data, ('body', ))
    elif post_kind is 'proposal':
        post_data = pick(post_data, (
            'name',
            'body',
            'status',
        ))
        if (post_data.get('status') != 'declined'
                or post_data.get('status') not in (
                    'pending',
                    'blocked',
                )):
            del post_data['status']
    elif post_kind is 'vote':
        post_data = pick(post_data, (
            'body',
            'response',
        ))

    # ## STEP 3) Validate and save post instance ## #
    post_, errors = post_.update(db_conn, post_data)
    if errors:
        errors = prefix_error_names('post.', errors)
        return 400, {'errors': errors, 'ref': 'E4LFwRv2WEJZks7use7TCpww'}

    # ## STEP 4) 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 5) Return response ## #
    return 200, {'post': post_.deliver()}
示例#25
0
from framework.database import setup_db, make_db_connection, \
    close_db_connection
from framework.elasticsearch import es
from modules.util import json_prep, pick
from database.user import get_avatar

setup_db()
db_conn = make_db_connection()

# Empty the database
es.indices.delete(index='entity', ignore=[400, 404])

# Add users
users = r.table('users').run(db_conn)
for user in users:
    data = pick(json_prep(user), ('id', 'name'))
    data['avatar'] = get_avatar(user['email'])
    es.index(
        index='entity',
        doc_type='user',
        body=data,
        id=user['id'],
    )

# Add units
units = (r.table('units')
          .filter(r.row['status'].eq('accepted'))
          .group('entity_id')
          .max('created')
          .default(None)
          .ungroup()
示例#26
0
def es_populate():
    setup_db()
    db_conn = make_db_connection()

    # Empty the database
    es.indices.delete(index='entity', ignore=[400, 404])

    # Add users
    users = r.table('users').run(db_conn)
    for user in users:
        data = pick(json_prep(user), ('id', 'name'))
        data['avatar'] = get_avatar(user['email'])
        es.index(
            index='entity',
            doc_type='user',
            body=data,
            id=user['id'],
        )

    # Add units
    units = (r.table('units')
              .filter(r.row['status'].eq('accepted'))
              .group('entity_id')
              .max('created')
              .default(None)
              .ungroup()
              .map(r.row['reduction'])
              .run(db_conn))

    for unit in units:
        es.index(
            index='entity',
            doc_type='unit',
            body=json_prep(unit),
            id=unit['entity_id'],
        )

    # Add cards
    cards = (r.table('cards')
              .filter(r.row['status'].eq('accepted'))
              .group('entity_id')
              .max('created')
              .default(None)
              .ungroup()
              .map(r.row['reduction'])
              .run(db_conn))
    for card in cards:
        es.index(
            index='entity',
            doc_type='card',
            body=json_prep(card),
            id=card['entity_id'],
        )

    # Add subjects
    subjects = (r.table('subjects')
                 .filter(r.row['status'].eq('accepted'))
                 .group('entity_id')
                 .max('created')
                 .default(None)
                 .ungroup()
                 .map(r.row['reduction'])
                 .run(db_conn))
    for subject in subjects:
        es.index(
            index='entity',
            doc_type='subject',
            body=json_prep(subject),
            id=subject['entity_id'],
        )

    # Add topics
    topics = r.table('topics').run(db_conn)
    for topic in topics:
        es.index(
            index='entity',
            doc_type='topic',
            body=json_prep(topic),
            id=topic['id'],
        )

    # Add posts
    posts = r.table('posts').run(db_conn)
    for post in posts:
        data = json_prep(post)
        topic = (r.table('topics')
                 .get(data['topic_id'])
                 .run(db_conn))
        user = (r.table('users')
                 .get(data['user_id'])
                 .run(db_conn))
        data['topic'] = json_prep(topic)
        data['user'] = pick(json_prep(user), ('id', 'name'))
        es.index(
            index='entity',
            doc_type='post',
            body=data,
            id=post['id'],
        )

    close_db_connection(db_conn)
示例#27
0
        'created': r.time(2014, 1, 1, 'Z'),
        'modified': r.time(2014, 1, 1, 'Z'),
        'name': 'eileen',
        'email': '*****@*****.**',
        'password': bcrypt.encrypt('example1'),
        'settings': {
            'email_frequency': 'daily',
            'view_sets': 'public',
            'view_follows': 'public',
        }
    }])
    .run(database.db_conn))

users = database.db.table('users').run(database.db_conn)
for user in users:
    data = pick(json_prep(user), ('id', 'name'))
    data['avatar'] = get_avatar(user['email'])
    es.index(
        index='entity',
        doc_type='user',
        body=data,
        id=user['id'],
    )

(database.db.table('units')
    .insert([{
        'id': 'plus-1',
        'created': r.time(2014, 1, 1, 'Z'),
        'modified': r.time(2014, 1, 1, 'Z'),
        'entity_id': 'plus',
        'previous_id': None,
示例#28
0
def test_pick():
    # Expect pick to make a new dict with only keys presented
    d = {'a': 1, 'b': 2}
    keys = ('a',)
    assert util.pick(d, keys) == {'a': 1}
    assert d == {'a': 1, 'b': 2}