def run_scheduler(event: Dict, context, sqs_client: Boto3SQS,
                  consultants_model: PynamoDBConsultant,
                  checkin_model: PynamoDBCheckIn) -> None:
    '''
        Runs Scheduler Services
        -
        :param event: AWS event
        :param context: AWS context
        :param sqs_client: Boto3 SQS client
        :param consultants_model: PynamoDB Consultant Model
        :param checkin_model: PynamoDB Checkin Model
    '''
    print("context:", context)
    print("event", event)

    today = datetime.today()
    print("UTC: ", today)
    today = today.replace(tzinfo=timezone.utc).astimezone(
        pytz.timezone('Europe/Berlin'))
    print("EU: ", today)

    if 'httpMethod' in event:
        consultants = consultants_model.scan()
        for consultant in consultants:
            scheduler_start_checkin(consultant, sqs_client, checkin_model)
    else:
        if today.weekday() < 5:
            consultants = consultants_model.scan()
            for consultant in consultants:
                if consultant.time_for_checkin is None:
                    checkin_normal_time(today, consultant, sqs_client,\
                        checkin_model, consultants_model)
                else:
                    checkin_custom_time(today, consultant, sqs_client,\
                        checkin_model, consultants_model)
def create_home_tap(consultant_uuid: str,
                    consultant_model: PynamoDBConsultant):
    '''
        Creates Home tap with correct time from Consultant
        -
        :param consultant_uuid: Uuid of Consultant
        :param consultant_model: Consultant Model
    '''
    consultant = consultant_model.get(consultant_uuid)

    with open("src/templates/{0}.json".format('home_tap_template_signedup'),
              "r") as body:
        home_tap = json.load(body)

        if consultant.time_for_checkin is not None:
            home_tap['blocks'][4]['elements'][0][
                'initial_time'] = consultant.time_for_checkin

        if consultant_model.same_day_checkin is not None:
            print(consultant.same_day_checkin)
            if str(consultant.same_day_checkin) == 'True':
                home_tap['blocks'][5]['elements'][0]['initial_options'] =\
                        [home_tap['blocks'][5]['elements'][0]['options'][0]]

    print(home_tap)
    return home_tap
Exemple #3
0
def consultant_update(message: Dict, consultant_model: PynamoDBConsultant,\
        request_client: Requests) -> PynamoDBCheckIn:
    '''
        Method for user input. Updates checkin in database
        with user inputs from slack.
        -
        :param message: The message with user input needed for updating database.
        :param checkin_model: PynamoDB CheckIn Model
        :param request_client: Request Client
    '''
    if message['payload']['type'] == 'sign_up':
        response = sign_up(message['payload']['value'], request_client,\
                            consultant_model)
    elif message['payload']['type'] == 'checkin_time':
        consultant = consultant_model.get(message['consultant'])
        if message['payload']['action_id'] == 'time_for_checkin':
            consultant.update(
                actions=[
                    consultant_model.time_for_checkin.set(message['payload']['value'])
                ]
            )
        elif message['payload']['action_id'] == 'same_day_checkin':
            consultant.update(
                actions=[
                    consultant_model.same_day_checkin.set(message['payload']['value'])
                ]
            )
        response = "Consultant updated with ({0})".format(message['payload']['value'])
    else:
        response = "Unkown Type"

    return response
Exemple #4
0
def run_scheduler(checkin_model: PynamoDBCheckIn,
                  consultants_model: PynamoDBConsultant,
                  customers_model: PynamoDBCustomers,
                  requests_client: Requests) -> None:
    '''
        Runs Scheduler Services
        -
        :param checkin_model: Checkin model
        :param consultants_model: Consultant model
        :param customers_model: Customer model
        :param requests_client: Request client
    '''
    auth_token = os.environ['SlackAuth']
    hed = {'Authorization': 'Bearer ' + auth_token}

    today = datetime.datetime.today()
    first_date = datetime.datetime(today.year, today.month,
                                   1) - datetime.timedelta(days=1)
    last_date = datetime.datetime(today.year, today.month,\
                                  calendar.monthrange(today.year, today.month)[1])

    consultants_list = list(consultants_model.scan())
    customers_list = list(customers_model.scan())
    checkins_list = list(checkin_model.scan(checkin_model.date.between(str(first_date),\
                         str(last_date)) & (checkin_model.completed == 'True')))

    for con in consultants_list:
        con_data = list(
            filter(lambda x: con.uuid == x.consultant_uuid, checkins_list))
        cust_time = {}
        for data in con_data:
            customers = next((x for x in json.loads(data.user_input) if\
                              x['action_id'] == 'customers'), None)
            if customers is not None:
                customers = list(
                    filter(lambda x: not x['unchecked'], customers['value']))
                times = [x for x in json.loads(data.user_input)\
                         if x['action_id'].startswith('time_desc_input')]
                for cust in customers:
                    time = next(
                        (z for z in times if z['customer'] == cust['value']),
                        None)
                    if time is not None:
                        name = next((c for c in customers_list if\
                                     c.uuid == cust['value']), None).friendlyName
                        cust_time[name] = cust_time.get(
                            name, 0) + time['value']['time']
        print("Cust_time: ", cust_time)
        report = '{0}:'.format(today.strftime("%B"))
        for key in cust_time:
            report += '\n• {0} - {1} h'.format(key, (cust_time[key]))

        data = {"channel": con.slack_id, "text": report}
        requests_client.post('https://slack.com/api/chat.postMessage',
                             json=data,
                             headers=hed)
Exemple #5
0
def get_standups_for_consultant(consultant: str, today: bool,
                                consultants_model: PynamoDBConsultant,
                                requests_client: Requests) -> Tuple:
    '''
        Get standups for today and yesterday
        -
        :param consultant: consultant uuid
        :param today: is it today or yesterday true/false
        :param consultants_model: PynamoDB Consultants Model
        :param requests_client: Requests Client
    '''
    date_today = datetime.today()
    if today:
        date = date_today
    else:
        date = date_today - timedelta(days=1) \
            if date_today.weekday() != 0 \
            else date_today - timedelta(days=3)

    date = datetime(date.year, date.month, date.day, 0, 0).timestamp()

    auth_token = os.environ['SlackAuth']
    hed = {'Authorization': 'Bearer ' + auth_token}

    url = 'https://slack.com/api/conversations.history?channel={0}&oldest={1}'\
        .format('C6NEF8SQ2', date)
    response = requests_client.post(url, headers=hed)

    response_data = response.json()

    consultant_data = consultants_model.get(consultant)

    def iterator_func(item):
        if 'user' in item:
            if item['user'] == consultant_data.slack_id:
                return True
        return False

    consultent_messages = list(filter(iterator_func,
                                      response_data['messages']))
    print(consultent_messages)

    if len(consultent_messages) > 0:
        message = "_{0}:_ {1}".format(
            "Todays DSU" if today else "Yesterdays DSU",
            consultent_messages[-1]['text'].split('\n')[0 if today else 1][3:])
    else:
        message = None

    return message
def consume_sqs(event: Dict, context, consultants_model: PynamoDBConsultant,
                checkin_model: PynamoDBCheckIn,
                request_client: Requests) -> None:
    '''
        Combines CheckInId with Start Modal Button
        -
        :param event: AWS event
        :param context: AWS Lambda Context
        :param consultants_model: PynamoDB Consultants Model
        :param checkin_model: PynamoDB Checkin Model
        :param request_client: Requests Client
    '''
    print("Context: ", context)
    print("Event: ", event)

    message = load_message(event['Records'][0]['messageAttributes'])
    checkin = checkin_model.get(message['checkin-id'])

    last_bus_day = datetime.datetime.strptime(checkin.date, '%Y-%m-%d')
    # last_bus_day = last_bus_day -\
    #     datetime.timedelta(max(1,(last_bus_day.weekday() + 6) % 7 - 3))

    with open('src/templates/modal_start_button.json', 'r') as start_button:
        start_button = json.load(start_button)
        if message['type'] == Types.Slack_Reminder:
            start_button[0]['text']['text'] = 'You forgot to Checkin the {0}\'th of {1}'\
                .format(last_bus_day.day, last_bus_day.strftime("%B"))
        else:
            start_button[0]['text']['text'] = 'Make Checkin for the {0}\'th of {1}'\
                .format(last_bus_day.day, last_bus_day.strftime("%B"))
        start_button[0]['accessory']['value'] = 'start;{0}'.format(message['checkin-id'])
        print("Body: ", start_button)

        consultant = consultants_model.get(message['consultant'])

        hed = {'Authorization': 'Bearer ' + os.environ['SlackAuth']}

        data = {
            "channel": consultant.slack_id,
            "text": "Start Checkin",
            "blocks": start_button
        }

        url = 'https://slack.com/api/chat.postMessage'
        response = request_client.post(url, json=data, headers=hed)
        print(response)
Exemple #7
0
def run(event: Dict, context, consultants_model: PynamoDBConsultant,
        online_status_model: PynamoDBOnlineStatuses,
        requests_client: Requests) -> None:
    '''
        Function for running the status getter
        -
        :param event: AWS event
        :param context: AWS Lambda Context
        :param consultants_model: PynamoDB Consultants Model
        :param online_status_model: PynamoDB Online Statuses Model
        :param requests_client: Requests Client
    '''
    print("context:", context)
    print("event", event)

    consultants = consultants_model.scan()

    for consultant in consultants:
        slack_status = get_status(consultant.slack_id, requests_client).content
        status = {
            "time": str(datetime.datetime.now()),
            "status": json.loads(slack_status)['presence']
        }
        print(slack_status)
        try:
            found_status = online_status_model.get(hash_key=consultant.uuid,
                                                   range_key=str(
                                                       datetime.date.today()))
            user_status = json.loads(found_status.statuses)
            sorted_user_status = sorted(user_status,
                                        key=lambda x: x['time'],
                                        reverse=True)
            print(sorted_user_status)
            if sorted_user_status[0]['status'] != status['status']:
                user_status.append(status)
                found_status.update(actions=[
                    online_status_model.statuses.set(json.dumps(user_status))
                ])
        except DoesNotExist:
            new_status = online_status_model(consultant_uuid=consultant.uuid,
                                             date=str(datetime.date.today()),
                                             statuses=json.dumps([status]))
            new_status.save()
Exemple #8
0
def user_input(message: Dict, checkin_model: PynamoDBCheckIn,\
               consultant_model: PynamoDBConsultant) -> PynamoDBCheckIn:
    '''
        Method for user input. Updates checkin in database
        with user inputs from slack.
        -
        :param message: The message with user input needed for updating database.
        :param checkin_model: PynamoDB CheckIn Model
    '''
    user = checkin_model.get(message['checkin-id'])
    incoming = message['payload']['value']
    current = get_current(user)
    actions = list(filter(lambda x: x['action_id'] == message['payload']['action_id'], current))
    if message['payload']['type'] == 'checkboxes':
        if len(actions) == 0:
            create_checkbox_template(message, current, actions)
        add_customers(actions, incoming)
        save_to_user(user, checkin_model, current)
    elif message['payload']['type'] == 'radio_buttons':
        incoming = incoming['value'].split(';')[1]
        if len(actions) == 0:
            create_template_other(message, incoming, current)
        else:
            actions[0]['value'] = incoming
        save_to_user(user, checkin_model, current)
    elif message['payload']['type'] == 'button' or message['payload']['type'] == 'input':
        new_actions = list(
            filter(lambda x: x['customer'] == message['payload']['customer'], actions))
        if len(new_actions) > 0:
            new_actions[0]['value'] = incoming
        else:
            create_template_other(message, incoming, current)

        if message['payload']['action_id'] == 'absence_to_date':
            consultant = consultant_model.get(user.consultant_uuid)
            consultant.update(
                actions=[
                    consultant_model.absence_till.set(message['payload']['value'])
                ]
            )

        save_to_user(user, checkin_model, current)
    return user