async def remove_pin(req: web.Request) -> web.Response: channel_id = req["match_info"]["channel_id"] message_id = req["match_info"]["message_id"] async with req.config_dict["pg_conn"].acquire() as conn: async with conn.transaction(): unpin_success = await conn.fetchval( "SELECT * FROM remove_channel_pin($1, $2)", message_id, channel_id, ) if not unpin_success: raise web.HTTPBadRequest( reason="Failed to unpin message. Does it belong to channel?" ) message = await conn.fetchrow( f"SELECT {MESSAGE} FROM create_message($1, $2, $3, $4, type:=$5)", req.config_dict["sf_gen"].gen_id(), channel_id, req["access_token"].user_id, "", MessageTypes.CHANNEL_PIN_REMOVE.value, ) req.config_dict["emitter"].emit( events.MESSAGE_CREATE(payload=MESSAGE.to_json(message)) ) raise web.HTTPNoContent()
async def create_channel(req: web.Request) -> web.Response: query = req["body"] user_id = req["access_token"].user_id recipients = set(query["recipients"]) channel_id = req.config_dict["sf_gen"].gen_id() async with req.config_dict["pg_conn"].acquire() as conn: async with conn.transaction(): channel = await conn.fetchrow( f"SELECT {CHANNEL} FROM create_channel($1, $2, $3, $4)", channel_id, user_id, query["name"], recipients, ) message = await conn.fetchrow( f"SELECT {MESSAGE} FROM create_message($1, $2, $3, $4, type:=$5)", req.config_dict["sf_gen"].gen_id(), channel_id, user_id, "", MessageTypes.CHANNEL_CREATE.value, ) req.config_dict["emitter"].emit( events.MESSAGE_CREATE(payload=MESSAGE.to_json(message)) ) return web.json_response(CHANNEL.to_json(channel))
async def delete_message(req: web.Request) -> web.Response: channel_id = req["match_info"]["channel_id"] message_id = req["match_info"]["message_id"] message = await req.config_dict["pg_conn"].fetchrow( f"SELECT {MESSAGE} FROM messages_with_author WHERE channel_id = $1 AND id = $2", channel_id, message_id, ) if message is None: raise web.HTTPNotFound(reason="Unknown message") message_data = MESSAGE.to_json(message) if int(message_data["author"]["id"]) != req["access_token"].user_id: await helpers.ensure_permissions( Permissions.DELETE_MESSAGES, request=req ) await req.config_dict["pg_conn"].fetch( f"SELECT FROM delete_message($1, $2)", channel_id, message_id ) req.config_dict["emitter"].emit( events.MESSAGE_DELETE(payload=message_data) ) raise web.HTTPNoContent()
async def add_channel_recipient(req: web.Request) -> web.Response: await helpers.ensure_permissions(Permissions.INVITE_MEMBERS, request=req) channel_id = req["match_info"]["channel_id"] user_id = req["match_info"]["user_id"] await ensure_existance(req, "users", user_id, "User") async with req.config_dict["pg_conn"].acquire() as conn: async with conn.transaction(): success = await conn.fetchval( "SELECT * FROM add_channel_user($1, $2)", channel_id, user_id ) if not success: raise web.HTTPNotModified(reason="Is user already in channel?") message = await conn.fetchrow( f"SELECT {MESSAGE} FROM create_message($1, $2, $3, $4, type:=$5)", req.config_dict["sf_gen"].gen_id(), channel_id, user_id, "", MessageTypes.RECIPIENT_ADD.value, ) req.config_dict["emitter"].emit( events.MESSAGE_CREATE(payload=MESSAGE.to_json(message)) ) raise web.HTTPNoContent()
async def get_messages(req: web.Request) -> web.Response: channel_id = req["match_info"]["channel_id"] offset = req["query"]["offset"] limit = req["query"]["limit"] records = await req.config_dict["pg_conn"].fetch( f"SELECT {MESSAGE} FROM messages_with_author WHERE channel_id=$1 ORDER BY id LIMIT $2 OFFSET $3", channel_id, limit, offset, ) return web.json_response([MESSAGE.to_json(record) for record in records])
async def get_message(req: web.Request) -> web.Response: channel_id = req["match_info"]["channel_id"] message_id = req["match_info"]["message_id"] record = await req.config_dict["pg_conn"].fetchrow( f"SELECT {MESSAGE} FROM messages_with_author WHERE channel_id=$1 AND id=$2", channel_id, message_id, ) if record is None: raise web.HTTPNotFound(reason="Message not found") return web.json_response(MESSAGE.to_json(record))
async def create_message(req: web.Request) -> web.Response: message = await req.config_dict["pg_conn"].fetchrow( f"SELECT {MESSAGE} FROM create_message($1, $2, $3, $4)", req.config_dict["sf_gen"].gen_id(), req["match_info"]["channel_id"], req["access_token"].user_id, req["body"]["content"], ) data = MESSAGE.to_json(message) req.config_dict["emitter"].emit(events.MESSAGE_CREATE(payload=data)) return web.json_response(data)
async def get_pins(req: web.Request) -> web.Response: channel_id = req["match_info"]["channel_id"] async with req.config_dict["pg_conn"].acquire() as conn: async with conn.transaction(): pin_ids = await conn.fetchval( "SELECT pinned_ids FROM channels WHERE id = $1", channel_id ) records = await conn.fetch( f"SELECT {MESSAGE} FROM messages_with_author WHERE id = ANY($1)", pin_ids, ) return web.json_response([MESSAGE.to_json(record) for record in records])
async def edit_channel(req: web.Request) -> web.Response: await helpers.ensure_permissions(Permissions.MODIFY_CHANNEL, request=req) channel_id = req["match_info"]["channel_id"] async with req.config_dict["pg_conn"].acquire() as conn: async with conn.transaction(): old_channel = await conn.fetchrow( f"SELECT {CHANNEL} FROM channels WHERE id = $1", channel_id ) channel = await req.config_dict["pg_conn"].fetchrow( CHANNEL.update_query_for( "channels", channel_id, req["body"].keys() ), req["body"]["name"], ) if channel is None: raise web.HTTPNotModified message = await conn.fetchrow( f"SELECT {MESSAGE} FROM create_message($1, $2, $3, $4, type:=$5)", req.config_dict["sf_gen"].gen_id(), channel_id, req["access_token"].user_id, "", MessageTypes.CHANNEL_NAME_UPDATE.value, ) diff = CHANNEL.diff_to_json(old_channel, channel) req.config_dict["emitter"].emit(events.CHANNEL_UPDATE(payload=diff)) req.config_dict["emitter"].emit( events.MESSAGE_CREATE(payload=MESSAGE.to_json(message)) ) return web.json_response(diff)
async def add_pin(req: web.Request) -> web.Response: channel_id = req["match_info"]["channel_id"] message_id = req["match_info"]["message_id"] async with req.config_dict["pg_conn"].acquire() as conn: async with conn.transaction(): pins_ids = await conn.fetchval( "SELECT pinned_ids FROM channels WHERE id = $1", channel_id ) if len(pins_ids) >= 50: raise web.HTTPBadRequest(reason="Too many pins (>= 50)") if message_id in pins_ids: raise web.HTTPNotModified(reason="Already pinned") pin_success = await conn.fetchval( "SELECT * FROM add_channel_pin($1, $2)", message_id, channel_id ) if not pin_success: raise web.HTTPBadRequest( reason="Failed to pin message. Does it belong to channel?" ) message = await conn.fetchrow( f"SELECT {MESSAGE} FROM create_message($1, $2, $3, $4, type:=$5)", req.config_dict["sf_gen"].gen_id(), channel_id, req["access_token"].user_id, "", MessageTypes.CHANNEL_PIN_ADD.value, ) req.config_dict["emitter"].emit( events.MESSAGE_CREATE(payload=MESSAGE.to_json(message)) ) raise web.HTTPNoContent()