예제 #1
0
def parse_request(data_form):
	'''
	Parses the request using the specified data_form.

	Args:
		data_form: The data form from the request

	Returns:
		A response object based off of how the request was parsed.
	'''

	# TODO: add try/except here

	# if exists, in the form of (proj_id, proj_name)
	proj_info = _filter_project(data_form)
	if proj_info is not None:
		proj_id, proj_name = proj_info

		# create repo info in database if doesn't exist
		if not repo.repo_exists(proj_id, proj_name):
			repo.set_repo(proj_id, proj_name)

		# if exists in the form of (sender_id, sender_name)
		sender_info = _filter_sender(data_form)
		if sender_info is not None:
			sender_id, sender_name = sender_info

			# make sure git info for this user is set in DB
			repo.check_git_user(sender_id, sender_name)
			
			# check their state, to notify them that they might be offline
			slack_uuid = repo.get_slack_uuid(sender_id, sender_name)
			if slack_uuid is not None:
				user_state = user_session.get_state(slack_uuid)
				if user_state == 'OFFLINE':
					# send slack message to channel
					settings.getSlack().send_message(contents='I see you sent a commit for the ' + str(proj_name) + ' repository. You know you are OFFLINE with Epoch right?', channel=str(slack_uuid), username='******', icon_emoji=':loudspeaker:')

			if 'commits' in data_form:
				commit_data = data_form['commits']

				# for each commit
				for c in commit_data:
					message_data = str(c['message'].encode('ascii', 'ignore'))
					commit_url = str(c['url'])

					repo.create_commit_log(repo_id=proj_id, user_id=slack_uuid, commit_text=message_data, commit_url=commit_url)
					
	return Response('Okay'), 200
예제 #2
0
def force_logout_users():
    '''
    Forces all the users to logout, sending them a notification.
    '''
    users = user.get_all_users()

    if users is not None and len(users) > 0:
        for uuid, username in users:

            state = user_session.get_state(uuid)
            if state != 'OFFLINE':

                print('Force logging out ' + str(username) +
                      ' as their state was ' + str(state))
                LOG.debug(
                    str(time.ctime(time.time())) + ': Force logging out ' +
                    str(username) + ' as their state was ' + str(state))

                # set the new state
                user_session.set_state(uuid, 'OFFLINE')
                user.log_state_change(uuid, 'OFFLINE', state)

                # get how long they worked
                msecs = user_session.get_work_time(uuid)
                start_time = user_session.get_session_timestamp(uuid)
                end_time = time.strftime('%Y-%m-%d %H:%M:%S')

                # create the session log
                user_session.create_user_session_log(uuid, msecs, start_time,
                                                     end_time)

                # reset their work time to 0
                user_session.set_work_time(uuid, 0)
                user_session.set_session_timestamp(uuid)

                # send slack message to channel
                slack_server.send_message(
                    contents=
                    'Epoch was restarted and you were logged out. Please use `/epoch start`.',
                    channel='@' + str(username),
                    username='******',
                    icon_emoji=':loudspeaker:')
예제 #3
0
def handle_list_command():
    '''
	Handles the parsing of the list command. This allows the user to see what 
	users we are tracking.
	'''

    # USER --- STATE --- LAST LOGIN --- HOURS WORKED --- GOAL HOURS
    all_users = user.get_all_users()
    if all_users is not None and len(all_users) > 0:
        for uuid, name in all_users:
            state = user_session.get_state(uuid)
            last_login = user_session.get_session_timestamp(uuid)
            total_hours = '%.2f' % user_session.get_total_worked(uuid)
            goal_hours = user.get_goal_total(uuid)

            data = (name, state, last_login, total_hours, goal_hours)

            print('[' + str(name) + '][' + str(state) + '] was last seen at ' +
                  str(last_login) + '. They are at ' + str(total_hours) +
                  ' / ' + str(goal_hours) + ' hours.')
def parse_request(data_form):
	'''
	Parses the request using the specified data_form.

	Args:
		data_form: The data form from the request

	Returns:
		A response object based off of how the request was parsed.
	'''

	# TODO: add try/except here

	# if exists, in the form of (repo_id, repo_name)
	repo_info = _filter_repository(data_form)
	if repo_info is not None:
		repo_id, repo_name = repo_info

		# create repo info in database if doesn't exist
		if not repo.repo_exists(repo_id, repo_name):
			repo.set_repo(repo_id, repo_name)


		valid = False
		# filter out for only UPDATEs else merging branches is hell
		if 'refChanges' in data_form:
			ref_changes = data_form['refChanges']
			if ref_changes is not None and len(ref_changes) > 0:
				for rc in ref_changes:
					if 'type' in rc:
						change_type = str(rc['type'])
						if change_type == 'UPDATE':
							valid = True
						else:
							print('Unable to validate this payload, as the ref change type was ' + str(change_type))

		if 'changesets' in data_form and valid:
			change_sets = data_form['changesets']

			if 'values' in change_sets:
				values = change_sets['values']

				if values is not None and len(values) > 0:
					for v in values:

						# extract the toCommit
						if 'toCommit' in v:
							to_commit = v['toCommit']

							committer_data = _filter_committer(to_commit)
							# if committer exists
							if committer_data is not None:
								committer_name, committer_email = committer_data

								# check their state, to notify them that they might be offline
								slack_uuid = _get_slack_uuid(committer_email)
								if slack_uuid is not None:

									user_state = user_session.get_state(slack_uuid)
									if user_state == 'OFFLINE':
										# send slack message to channel
										settings.getSlack().send_message(contents='I see you sent a commit for the ' + str(repo_name) + ' repository. You know you are OFFLINE with Epoch right?', channel=str(slack_uuid), username='******', icon_emoji=':loudspeaker:')

									commit_id = to_commit['id']
									message_data = str(to_commit['message'].encode('ascii', 'ignore'))

									# find the first commit url
									commit_url = _filter_url(v)

									# create the commit log
									repo.create_commit_log(repo_id=repo_id, user_id=slack_uuid, commit_text=message_data, commit_url=commit_url)
		else:
			print('Unable to validate this payload, as the form was not valid.')
					
	return Response('Okay'), 200
def handle_command(user_obj, command, data):
    '''
	Handles the command given by the request.

	Args:
		user_obj: The object that represents the user
		command: The command from the request
		data: The data form that is the request

	Returns:
		A response object based off of how the request's command was handled.
	'''

    # get the current state of the user
    state = user_session.get_state(user_obj.uuid)

    if command == 'START':
        if state == 'OFFLINE':

            # set the new state
            user_session.set_state(user_obj.uuid, 'ONLINE')
            user.log_state_change(user_obj.uuid, 'ONLINE', 'OFFLINE')

            # the timestamp needs updated
            user_session.set_work_time(user_obj.uuid, 0)
            user_session.set_session_timestamp(user_obj.uuid)

            # send slack message to channel
            slack_server.send_message(contents=str(user_obj.username) +
                                      ' is now online!',
                                      channel='#work-progress',
                                      username='******',
                                      icon_emoji=':green_heart:')

            return Response(response=json.dumps(
                build_login_response(user_obj)),
                            status=200,
                            mimetype='application/json')
        else:
            return Response(
                'In order to use [start], you must be in OFFLINE mode. You are in '
                + str(state) + ' mode!'), 200
    elif command == 'STOP':
        if state == 'ONLINE':

            # set the new state
            user_session.set_state(user_obj.uuid, 'OFFLINE')
            user.log_state_change(user_obj.uuid, 'OFFLINE', 'ONLINE')

            # get how long they worked
            msecs = user_session.get_work_time(user_obj.uuid)
            start_time = user_session.get_session_timestamp(user_obj.uuid)
            end_time = time.strftime('%Y-%m-%d %H:%M:%S')

            # get the user's goal hours
            goal_hours = user.determine_goal_hours_today(user_obj.uuid)
            worked_hours = '%.2f' % (msecs / 3600000.0)

            # create the session log
            user_session.create_user_session_log(user_obj.uuid, msecs,
                                                 start_time, end_time)

            # reset their work time to 0
            user_session.set_work_time(user_obj.uuid, 0)
            user_session.set_session_timestamp(user_obj.uuid)

            # send slack message to channel
            slack_server.send_message(contents=str(user_obj.username) +
                                      ' is now offline...',
                                      channel='#work-progress',
                                      username='******',
                                      icon_emoji=':broken_heart:')

            # construct a payload that shows the commit logs
            handle_logout_payload(user_obj, start_time, end_time, worked_hours,
                                  goal_hours)

            return Response(response=json.dumps(
                build_logout_response(user_obj)),
                            status=200,
                            mimetype='application/json')
        else:
            return Response(
                'In order to use [stop], you must be in ONLINE mode. You are in '
                + str(state) + ' mode!'), 200
    elif command == 'RESUME':
        if state == 'PAUSED':

            # set the new state
            user_session.set_state(user_obj.uuid, 'ONLINE')
            user.log_state_change(user_obj.uuid, 'ONLINE', 'PAUSED')

            # send slack message to channel
            slack_server.send_message(contents=str(user_obj.username) +
                                      ' is back from their break!',
                                      channel='#work-progress',
                                      username='******',
                                      icon_emoji=':green_heart:')

            return Response(response=json.dumps(
                build_resume_response(user_obj)),
                            status=200,
                            mimetype='application/json')
        else:
            return Response(
                'In order to use [resume], you must be in PAUSED mode. You are in '
                + str(state) + ' mode!'), 200
    elif command == 'PAUSE':
        if state == 'ONLINE':

            # set the new state
            user_session.set_state(user_obj.uuid, 'PAUSED')
            user.log_state_change(user_obj.uuid, 'PAUSED', 'ONLINE')

            # send slack message to channel
            slack_server.send_message(contents=str(user_obj.username) +
                                      ' went for a break!',
                                      channel='#work-progress',
                                      username='******',
                                      icon_emoji=':yellow_heart:')

            return Response(response=json.dumps(
                build_pause_response(user_obj)),
                            status=200,
                            mimetype='application/json')
        else:
            return Response(
                'In order to use [pause], you must be in ONLINE mode. You are in '
                + str(state) + ' mode!'), 200
    elif command == 'INFO':
        return Response(response=json.dumps(build_info_response(user_obj)),
                        status=200,
                        mimetype='application/json')
    elif command == 'STATUS':

        # temporarirly removes auth check
        # check if it's an authorized user
        if user_obj.username == 'stephen' or user_obj.username == 'peraldon' or 1 == 1:
            return Response(response=json.dumps(
                build_status_response(user_obj)),
                            status=200,
                            mimetype='application/json')
        else:
            return Response('You are not authorized for this command.'), 200

    return Response(
        'Unknown command! Try /epoch [start|stop|pause|resume|info]'), 200
def build_status_response(user_obj):
    '''
	Builds the status response for the specified user.

	Args:
		user_obj: The object representation for the specified user

	Returns:
		The Python dictionary that can be converted to JSON and sent as a response.
	'''

    # USER --- STATE --- LAST LOGIN --- HOURS WORKED --- GOAL HOURS
    all_users = user.get_all_users()
    if all_users is not None and len(all_users) > 0:

        # construct the response message with the attachment
        message = slack_api.Message()

        for uuid, name in all_users:
            state = user_session.get_state(uuid)
            last_login = user_session.get_session_timestamp(uuid)
            total_hours = '%.2f' % user_session.get_total_worked(uuid)
            goal_hours = user.get_goal_total(uuid)

            data = (name, state, last_login, total_hours, goal_hours)

            # create the attachment
            contents = {}
            contents['title'] = str(name)

            # TODO maybe a link to our workers page?
            contents['title_link'] = COMPANY_URL

            # color the attachment based off of state
            if state == 'ONLINE':
                contents['color'] = "good"
            elif state == 'OFFLINE':
                contents['color'] = "danger"
            elif state == 'PAUSED':
                contents['color'] = "warning"

            # Determine the text of the attachment
            #contents['text'] = 'Last state change at ' + str(last_login) + ' EST.'

            # build the hours
            fields = []
            f1 = {}
            f1['title'] = 'Total Hours (month)'
            f1['value'] = total_hours
            f1['short'] = True
            f2 = {}
            f2['title'] = 'Goal Hours (month)'
            f2['value'] = goal_hours
            f2['short'] = True
            fields.append(f1)
            fields.append(f2)
            contents['fields'] = fields

            if type(contents) is dict:

                # general footer
                contents['footer'] = 'Epoch API'
                contents['footer_icon'] = ICON_URL

                if last_login is not None:

                    # attach the timestamp
                    contents['ts'] = int(last_login.strftime('%s'))

            # add the attachment
            message.add_attachment(contents)

        return message.get_contents()
    else:
        return Response(
            'Unexpected error occurred locally when parsing STATE request.'
        ), 200
def build_info_response(user_obj):
    '''
	Builds the info response for the specified user.

	Args:
		user_obj: The object representation for the specified user

	Returns:
		The Python dictionary that can be converted to JSON and sent as a response.
	'''
    # get the state of the user
    state = user_session.get_state(user_obj.uuid)

    # create the attachment
    contents = {}
    contents['title'] = COMPANY_NAME
    contents['title_link'] = COMPANY_URL

    # color the attachment based off of state
    if state == 'ONLINE':
        contents['color'] = "good"
    elif state == 'OFFLINE':
        contents['color'] = "danger"
    elif state == 'PAUSED':
        contents['color'] = "warning"

    # Determine the text of the attachment
    contents['text'] = 'Your current state is ' + str(state) + '.'

    if state == 'ONLINE' or state == 'PAUSED':

        work_time = user_session.get_work_time(user_obj.uuid)

        # build the hours
        fields = []
        f1 = {}
        f1['title'] = 'Worked Time (session)'
        f1['value'] = '%.2f' % (work_time / 3600000.0)
        f1['short'] = True
        f2 = {}
        f2['title'] = 'Total Hours (month)'
        f2['value'] = user_session.get_total_worked(user_obj.uuid)
        f2['short'] = True
        fields.append(f1)
        fields.append(f2)
        contents['fields'] = fields
    elif state == 'OFFLINE':
        # build the hours
        fields = []
        f1 = {}
        f1['title'] = 'Total Hours (month)'
        f1['value'] = user_session.get_total_worked(user_obj.uuid)
        f1['short'] = True
        f2 = {}
        f2['title'] = 'Goal Hours (month)'
        f2['value'] = user.get_goal_total(user_obj.uuid)
        f2['short'] = True
        fields.append(f1)
        fields.append(f2)
        contents['fields'] = fields

    # attach the footer
    _attach_footer(contents)

    # construct the response message with the attachment
    message = slack_api.Message()
    message.add_attachment(contents)
    return message.get_contents()
예제 #8
0
    def work(self):
        '''
        This pulse works, serving the users, incrementing their times.
        '''

        # get the current time
        curr_time = time.time()

        if curr_time - self.credit_event > WORK_INTERVAL:

            # amount of milliseconds to credit to everyone working
            credit_amount = int((curr_time - self.credit_event) * 1000)

            # update timestamp for last time we credited
            self.credit_event = curr_time

            # load all users from db, if they dont exist in hash yet
            self.load_users()

            for key in self.users:
                user_obj = self.users[key]

                # get the state of the user
                state = user_session.get_state(user_obj.uuid)

                if state == 'ONLINE':
                    # update in the db their work time
                    user_session.update_work_time(user_obj.uuid, credit_amount)

                    user_obj.work_time_ms = user_obj.work_time_ms + credit_amount

                    # every hour notify them of how long they've worked
                    hours_worked = int(user_obj.work_time_ms / 3600000)
                    if hours_worked >= 1:

                        # when did we last notify them about their time
                        if user_obj.notify_hour < hours_worked:
                            user_obj.notify_hour = user_obj.notify_hour + 1

                            # send slack message to channel
                            slack_server.send_message(
                                contents='You have been working for ' +
                                str(hours_worked) + ' hours this session.',
                                channel='@' + str(user_obj.username),
                                username='******',
                                icon_emoji=':loudspeaker:')

                    # reset the pause time
                    user_obj.pause_time_ms = 0
                elif state == 'PAUSED':
                    user_obj.pause_time_ms = user_obj.pause_time_ms + credit_amount

                    # if 15 minutes have passed, send slack notification
                    if user_obj.pause_time_ms > 15 * 60 * 1000:
                        user_obj.pause_time_ms = 0
                        # send slack message to channel
                        slack_server.send_message(
                            contents=
                            'You have been idle/paused for 15 minutes. When you get back please use `/epoch resume`.',
                            channel='@' + str(user_obj.username),
                            username='******',
                            icon_emoji=':loudspeaker:')
                elif state == 'OFFLINE':
                    # reset their work time
                    user_obj.work_time_ms = 0
                    user_obj.pause_time_ms = 0
                    user_obj.notify_hour = 0