Esempio n. 1
0
def active(token, channel_id):
    '''
    Requirements: correct channel_id.

    Checks whether a standup with channel_id exists in standup_list.
    It will simply retrieve from data.py and return it in a neat package.

    #Raises 1 possible InputError
    '''
    # check for valid token
    common.token_valid(token)

    # check for valid channel
    if common.ch_id_exists(channel_id) == -1:
        raise InputError('This channel does not exist.')

    is_active = False
    time_finish = None

    for channel in data.standup_list:
        if channel["channel_id"] == channel_id:
            is_active = True
            time_finish = int(channel["time_finish"].replace(
                tzinfo=datetime.timezone.utc).timestamp())

    return {'is_active': is_active, 'time_finish': time_finish}
Esempio n. 2
0
def start(token, channel_id, length):
    '''
    Requirements: correct channel_id and token

    This will start a standup session for 'length' seconds. Messages sent to this session must be
    through 'send'.
    A message sent will be appended to the final message using send.
    At time = length, the message package will be sent over to message_data.

    #Raises 2 possible InputErrors
    '''
    # preliminary checks
    if common.ch_id_exists(channel_id) == -1:
        raise InputError('Invalid Channel. Cannot start standup.')

    if active(token, channel_id)['is_active']:
        raise InputError(
            'A standup is active. Only 1 standup may be running at a time.')

    authorized_caller = common.decode_token(token)
    if authorized_caller["u_id"] == {
            "u_id": "error_invalid_token"
    } or not common.user_in_channel(authorized_caller["u_id"], channel_id):
        raise AccessError('You do not have permission to do this.')

    # check if length is valid. Assuming that a standup lasts for at least 1 second.
    if length < 1:
        raise InputError(
            description=
            'You cannot start a standup for a time less than 1 second.')

    # keep start and finish for better accuracy
    time_start = datetime.datetime.utcnow()

    time_finish = time_start + datetime.timedelta(seconds=length)

    discrete.standup_data(time_start, time_finish, channel_id,
                          authorized_caller['u_id'])

    index = discrete.find_standup(channel_id)
    # at length = length seconds, sends all the messages from the queue as a complete package
    Timer(length, discrete.send_standup, [token, channel_id, index]).start()
    Timer(length + 1, data.standup_list.pop, [index]).start()
    return {
        'time_finish':
        int(time_finish.replace(tzinfo=datetime.timezone.utc).timestamp())
    }
Esempio n. 3
0
def send(token, channel_id, message):
    '''
    Requirements: correct token, channel_id and len(message) <= 1000

    Appends a message to the standup_messages list. It will depend on an aux_ function buffering it
    first before appending at the end of the list.

    #Raises 3 Possible InputErrors, 1 Access Error
    '''

    # ch_id is invalid -> InputError
    index = common.ch_id_exists(channel_id)
    if index == -1:
        raise InputError('Channel does not exist.')

    # message > 1000 characters
    if len(message) > 1000 or len(message) == 0:
        raise InputError(
            description=
            f'Your message is {len(message)-1000} over the limit. Your message cannot be over 1000 \
                characters')

    # user is not authorized -> AccessError
    authorized_caller = common.decode_token(token)
    if authorized_caller == {"u_id": "error_invalid_token"} or \
            not common.user_in_channel(authorized_caller["u_id"], channel_id):
        raise AccessError(
            'You cannot send a standup message in this channel which you are not part of.'
        )

    # active standup false -> InputError
    if not active(token, channel_id)['is_active']:
        raise InputError('Standup not active.')

    index = discrete.find_standup(channel_id)
    u_index = discrete.find_user(authorized_caller['u_id'])
    data.standup_list[index][
        'message'] += f"\n{data.user_data[u_index]['handle']}: {message}"
    print(f"message now {data.standup_list[index]['message']}", flush=True)
    return {}
Esempio n. 4
0
def start(token, channel_id, word):
    '''
    Input - valid token, channel_id and word.

    Word validity is handled in the frontend.

    Behavior:

    Starts a hangman session in a channel.
    Takes a word from the random_word mod, and parses
    it so that it only contains alphabetical characters.

    All hangman sessions are stored in a hangman data structure.

    Output - {}
    '''
    # ch_id is invalid -> InputError
    index = common.ch_id_exists(channel_id)
    if index == -1:
        raise InputError(
            description='The channel you are attempting to start a hangman in does not exist.')

    # check if token is valid
    authorized_caller = common.decode_token(token)
    if authorized_caller == {"u_id": "error_invalid_token"} or \
            not common.user_in_channel(authorized_caller["u_id"], channel_id):
        raise AccessError(
            description='You do not have permission to start hangman.')

    # check if a hangman session is ongoing
    for session in hangman_sessions:
        if session["channel_id"] == channel_id:
            raise InputError(
                description='A hangman session is already ongoing in this channel')

    final_word = word[0].split(' ')

    # if word not specified (is list), generate a random word
    if len(final_word) == 1:
        _site = "http://svnweb.freebsd.org/csrg/share/dict/words?view=co&content-type=text/plain"
        response = requests.get(_site)
        _words = response.content.splitlines()
        final_word = random.choice(_words).decode()
    else:
        final_word = final_word[1].strip()
    # add to hangman sessions
    hangman_sessions.append({
        "channel_id": channel_id,
        "word": final_word.lower(),
        "decrement_word": final_word.lower(),
        "guesses": [],
        "remaining_guesses": 8,
        "bad_attempts": 0
    })

    # send message as the bot
    idX = discrete.find_user(authorized_caller["u_id"])
    starter_name = user_data[idX]["first_name"]
    bot_message = f"{starter_name} has just started a hangman!"
    bot_message += _missing([], final_word)
    bot_send(bot_message, channel_id)

    return {}
Esempio n. 5
0
def guess(token, channel_id, X):
    '''
    Input - valid token, channel ID and a guess X.

    Behavior:
    Given a message with some 2nd string 'X', determines
    whether the guess is correct or not.

    Output - {}
    '''
    # ch_id is invalid -> InputError

    index = common.ch_id_exists(channel_id)
    if index == -1:
        raise InputError(
            description='The channel you are guessing on does not exist.')

    # check if token is valid
    authorized_caller = common.decode_token(token)
    if authorized_caller == {"u_id": "error_invalid_token"} or \
            not common.user_in_channel(authorized_caller["u_id"], channel_id):
        raise AccessError(
            description='You do not have permission to do this.')
    # ensure channel has a hangman session
    # NOTE YOU must abstract these functions ASAP.
    index = None
    for session in hangman_sessions:
        if session["channel_id"] == channel_id:
            index = hangman_sessions.index(session)
    if index == None:
        raise InputError(description='A hangman session is not running right now')

    X = X[0].split(' ')

    # if word not specified (is list), generate a random word
    if len(X) != 1:
        X = X[1]

    # check if X has been guessed already
    if X in hangman_sessions[index]['guesses']:
        raise InputError(description='Your guess has already been guessed.')

    # catch empty input error
    if not isinstance(X, str):
        raise InputError(description='Usage: /guess [letter]')
    # SEND THE /guess X as a message to message data.
    message.send(token, channel_id, '/guess ' + X)

    # check if the guess results in the complete answer
    hm_word = hangman_sessions[index]['word']
    guesses = hangman_sessions[index]['guesses']
    guesses.append(X)
    prev_word = hangman_sessions[index]['decrement_word']
    hangman_sessions[index]['decrement_word'] = hangman_sessions[index]['decrement_word'].replace(X, '')
    word_decrement = hangman_sessions[index]['decrement_word']
    if prev_word == word_decrement:
        hangman_sessions[index]["bad_attempts"] += 1

    # render ASCII or some image art.
    bot_message = _render_ascii(
        hangman_sessions[index]["bad_attempts"], channel_id, guesses, hm_word)

    if hm_word.replace(X, '') == hm_word:
        hangman_sessions[index]['remaining_guesses'] -= 1

    # if guess results in complete answer, then done and send congratulations
    if word_decrement == '':
        hangman_sessions.pop(index)
        bot_message += "\n\(^O^)/\nYou've correctly guessed the word!"
    # decrement the amount of guesses available, and if no more guesses,
    # remove hangman session and send taunting message
    else:
        if hangman_sessions[index]['remaining_guesses'] == 0:
            hangman_sessions.pop(index)
            bot_message += f"\n(✖╭╮✖)\nThe word is {hm_word}, you have lost\nF to pay respects"
        else:
            bot_message += "\nLetters guessed:"
            for word in hangman_sessions[index]['guesses']:
                bot_message += f" {word}"
    # send message as the bot
    bot_send(bot_message, channel_id)

    return {}