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()}
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)
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
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)
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. """ 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()}
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)
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())
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
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
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)
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
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
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
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
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)
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
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
'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',
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)
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(
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()}
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()
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)
'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,
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}