def standup_send(token, channel_id, message): '''Sending a message to get buffered in the standup queue, assuming a standup is currently active''' data = getData() user_id = getUserFromToken(token) user = data['users'][user_id] right_channel_index = find_channel(channel_id) if right_channel_index is None: raise Value_Error(f"Channel ID: {channel_id} is not a valid channel") right_channel = data['channels_list'][right_channel_index] if len(message) > 1000: raise Value_Error("Message is more than 1000 characters") if right_channel['standup']['finish_time'] < dt.utcnow(): raise Value_Error( 'An active standup is not currently running in this channel') if not inChannel(token, channel_id): raise AccessError( 'The authorised user is not a member of the channel that the message is within' ) message_id = right_channel['standup']['message_id'] msg_id = find_message(message_id) old_message = data['messages'][msg_id]['message'] old_message += str(user['handle']) + ': ' + message + ' ' edit(token, message_id, old_message) # update data after edit data = getData() save(data) return {}
def sendlater(token, channel_id, message, time_sent): ''' Send a message from authorised_user to the channel specified by channel_id automatically at a specified time in the future ''' data = getData() user_id = getUserFromToken(token) user = data['users'][user_id] right_channel_index = find_channel(channel_id) if type(time_sent) != dt: time_sent = dt.utcfromtimestamp(int(time_sent)) if right_channel_index is None: raise Value_Error(f"Channel ID: {channel_id} is not a valid channel") message_id = get_new_message_id() if len(message) > 1000: raise Value_Error("Message is more than 1000 characters") if not inChannel(token, channel_id): raise AccessError( "the authorised user has not joined the channel they are trying to post to" ) now = dt.utcnow() if now > time_sent: raise Value_Error("Time sent is a time in the past") data = add_message(channel_id, message_id, user['u_id'], message, time_sent) save(data) return {'message_id': message_id}
def invite(token, channel_id, u_id): ''' Invites a user (with user id u_id) to join a channel with ID channel_id. Once invited the user is added to the channel immediately ''' data = getData() right_channel_index = find_channel(channel_id) if right_channel_index is None: raise Value_Error(f"Channel ID: {channel_id} is not a valid channel") right_channel = data['channels_list'][right_channel_index] if int(u_id) >= len(data['users']): raise Value_Error(f"u_id: {u_id} does not refer to a valid user.") if not inChannel(token, channel_id): raise AccessError("the authorised user is not already a member of the channel.") invitee = data['users'][int(u_id)] invitee_info = user_detail(u_id, invitee['name_first'], invitee['name_last'], invitee['profile_img_url']) if invitee_info not in right_channel['members']: right_channel['members'].append(invitee_info) invitee['user_channel'].append(right_channel['channel']) save(data) return {}
def standup_start(token, channel_id, length): '''For a given channel, start the standup period whereby for the next 15 minutes if someone calls "standup_send" with a message, it is buffered during the 15 minute window then at the end of the 15 minute window a message will be added to the message queue in the channel from the user who started the standup.''' data = getData() right_channel_index = find_channel(channel_id) now_time = dt.utcnow() if right_channel_index is None: raise Value_Error(f"Channel ID: {channel_id} is not a valid channel") right_channel = data['channels_list'][right_channel_index] if not inChannel(token, channel_id): raise AccessError( 'The authorised user is not a member of the channel that the message is within' ) if standup_active(token, channel_id)['is_active'] is False: time_finish = now_time + timedelta(seconds=int(length)) message = sendlater(token, channel_id, '', time_finish) # update data data = getData() right_channel_index = find_channel(channel_id) right_channel = data['channels_list'][right_channel_index] right_channel['standup']['finish_time'] = time_finish right_channel['standup']['message_id'] = message['message_id'] else: raise Value_Error( 'An active standup is currently running in this channel') save(data) return { 'time_finish': time_finish.replace(tzinfo=timezone.utc).timestamp() }
def details(token, channel_id): ''' Given a Channel with ID channel_id that the authorised user is part of, provide basic details about the channel ''' data = getData() right_channel_index = find_channel(channel_id) if right_channel_index is None: raise Value_Error(f"Channel ID: {channel_id} is not a valid channel") right_channel = data['channels_list'][right_channel_index] if not inChannel(token, channel_id): raise AccessError("Authorised user is not a member of channel with channel_id.") return { 'name': right_channel['channel']['name'], 'owner_members': right_channel['owners'], 'all_members': right_channel['members'] }
def standup_active(token, channel_id): ''' For a given channel, return whether a standup is active in it, and what time the standup finishes. If no standup is active, then time_finish returns None ''' data = getData() right_channel_index = find_channel(channel_id) if right_channel_index is None: raise Value_Error(f"Channel ID: {channel_id} is not a valid channel") right_channel = data['channels_list'][right_channel_index] finish_time = right_channel['standup']['finish_time'] is_active = True if right_channel['standup']['finish_time'] < dt.utcnow(): is_active = False return { 'is_active': is_active, 'time_finish': finish_time.replace(tzinfo=timezone.utc).timestamp() }
def leave(token, channel_id): ''' Given a channel ID, the user removed as a member of this channel ''' data = getData() user_id = getUserFromToken(token) right_channel_index = find_channel(channel_id) if right_channel_index is None: raise Value_Error(f"Channel ID: {channel_id} is not a valid channel") right_channel = data['channels_list'][right_channel_index] # remove channel from user's channel list if right_channel['channel'] in data['users'][user_id]['user_channel']: data['users'][user_id]['user_channel'].remove(right_channel['channel']) # remove user from channel's member list for member in right_channel['members']: if data['users'][user_id]['u_id'] == member['u_id'] and member in right_channel['members']: right_channel['members'].remove(member) break save(data) return {}
def removeowner(token, channel_id, u_id): ''' Remove user with user id u_id an owner of this channel ''' data = getData() maker_id = getUserFromToken(token) maker = data['users'][maker_id] unlucky = data['users'][int(u_id)] right_channel_index = find_channel(channel_id) if right_channel_index is None: raise Value_Error(f"Channel ID: {channel_id} is not a valid channel") right_channel = data['channels_list'][right_channel_index] unlucky_detail = user_detail(unlucky['u_id'], unlucky['name_first'], unlucky['name_last'], unlucky['profile_img_url']) maker_detail = user_detail(maker['u_id'], maker['name_first'], maker['name_last'], maker['profile_img_url']) if (maker_detail not in right_channel['owners']) and (maker['permission'] != 1): raise AccessError("you don't have the right to access") if unlucky_detail in right_channel['owners']: if len(right_channel['owners']) > 1: right_channel['owners'].remove(unlucky_detail) save(data) return {}
def addowner(token, channel_id, u_id): ''' Make user with user id u_id an owner of this channel ''' data = getData() maker_id = getUserFromToken(token) maker = data['users'][maker_id] joiner = data['users'][int(u_id)] right_channel_index = find_channel(channel_id) if right_channel_index is None: raise Value_Error(f"Channel ID: {channel_id} is not a valid channel") right_channel = data['channels_list'][right_channel_index] joiner_detail = user_detail(joiner['u_id'], joiner['name_first'], joiner['name_last'], joiner['profile_img_url']) maker_detail = user_detail(maker['u_id'], maker['name_first'], maker['name_last'], maker['profile_img_url']) if (maker_detail not in right_channel['owners']) and (maker['permission'] != 1): raise AccessError("you don't have the right to access") if joiner_detail in right_channel['owners']: raise Value_Error("the user id is already an owner") right_channel['owners'].append(joiner_detail) save(data) return {}
def messages(token, channel_id, start): '''Given a Channel with ID channel_id that the authorised user is part of, return up to 50 messages between index "start" and "start + 50". Message with index 0 is the most recent message in the channel. This function returns a new index "end" which is the value of "start + 50", or, if this function has returned the least recent messages in the channel, returns -1 in "end" to indicate there are no more messages to load after this return.''' data = getData() u_id = getUserFromToken(token) right_channel_index = find_channel(channel_id) if right_channel_index is None: raise Value_Error(f"Channel ID: {channel_id} is not a valid channel") right_channel = data['channels_list'][right_channel_index] now = dt.utcnow() message_list = [] total_message = 0 for message in data['messages']: if int(message['channel_id']) == int(channel_id) and now >= message['time_created']: tmp = message tmp['time_created'] = message['time_created'].replace(tzinfo=timezone.utc).timestamp() for reaction in tmp['reacts']: reaction['is_this_user_reacted'] = (u_id in reaction['u_ids']) message_list.append(tmp) total_message += 1 if message['message'] == '': data['messages'].remove(message) if int(start) != 0 and int(start) >= total_message: raise Value_Error("start is greater than or equal to the total number of messages in the channel") if not inChannel(token, channel_id): raise AccessError("Authorised user is not a member of channel with channel_id") end = int(start) + 50 if end > total_message: end = -1 return {'messages': message_list[int(start):int(start)+50], 'start': int(start), 'end': end}
def join(token, channel_id): ''' Given a channel_id of a channel that the authorised user can join, adds them to that channel ''' data = getData() joiner_id = getUserFromToken(token) joiner = data['users'][joiner_id] right_channel_index = find_channel(channel_id) if right_channel_index is None: raise Value_Error(f"Channel ID: {channel_id} is not a valid channel") right_channel = data['channels_list'][right_channel_index] if not right_channel['is_public']: raise AccessError("a private channel can only be joined by invitation") if right_channel['channel'] not in joiner['user_channel']: joiner['user_channel'].append(right_channel['channel']) joiner_info = user_detail(joiner['u_id'], joiner['name_first'], joiner['name_last'], joiner['profile_img_url']) if joiner_info not in right_channel['members']: right_channel['members'].append(joiner_info) save(data) return {}