示例#1
0
 def buildingInformation(self):
     content = self.dorf2
     soup = BeautifulSoup(content, 'lxml')
     divs = soup.find_all("area")
     #print (divs[0])
     for i in range(int(divs.__len__()) - 1):
         #print(divs[i])
         ele = divs[i]
         text = str(ele)
         try:
             name = str(self.getElement(text, '.*?title=\'(.*?) &lt.*?')[0])
             href = str(self.getElement(text, '.*?href="(.*?)".*?')[0])
             level = int(self.getElement(text, '.*?Level (.*?)&lt.*?')[0])
             #print (level)
             updateWood = int(
                 self.getElement(
                     text,
                     '.*?<img class="r1" src="img/x.gif" />(.*?)\\n.*?'
                 )[0])
             updateClay = int(
                 self.getElement(
                     text,
                     '.*?<img class="r2" src="img/x.gif" />(.*?)\\n.*?'
                 )[0])
             updateIron = int(
                 self.getElement(
                     text,
                     '.*?<img class="r3" src="img/x.gif" />(.*?)\\n.*?'
                 )[0])
             updateCrop = int(
                 self.getElement(
                     text,
                     '.*?<img class="r4" src="img/x.gif" />(.*?)\\n.*?'
                 )[0])
             try:
                 self.resourceList[i + 18].update(updateWood, updateClay,
                                                  updateIron, updateCrop,
                                                  level)
             except:
                 # self, session, id, href, name = '', level = 0, needLumber = 0, needClay = 0, needIron = 0, needCrop = 0)
                 self.resourceList.append(
                     resource.resource(self.session, i + 18, href, name,
                                       level, updateWood, updateClay,
                                       updateIron, updateCrop))
                 print(globalVar.LOGINFO + 'Creat id: ' + str(i + 18) +
                       '\t' + ' Type: ' + name + '\t' + ' Level: ' +
                       str(level) + '\t' + ' Href: ' + href)
         except:
             self.resourceList.append(
                 resource.resource(self.session,
                                   i + 18,
                                   href='',
                                   name='Building site',
                                   level=0))
             print(globalVar.LOGINFO + 'Creat id: ' + str(i + 18) + '\t' +
                   ' Type: ' + 'Building site' + '\t' + ' Level: ' +
                   str(0) + '\t' + ' Href: ' + '')
示例#2
0
 def getRelevantResources(self,modname,ltype,reslist,pstyle):
   print("GETTING RESOURCES FROM " + self.name )
   tree = ET.parse( "Topics/" + self.name + ".xml" )
   resources, intro_table = tree.findall("RESOURCE"), ""
   for res in resources :
       res_obj = resource.resource( res )
       if (res_obj.ofModAndLevel( modname, ltype )) & (res_obj.linkb not in reslist) : 
           reslist.append(res_obj.linkb) 
           intro_table += res_obj.getResourceHTML( pstyle )  
   return intro_table, reslist
示例#3
0
    def __init__( self, pos, size, **keys ):

        # set initial values
        self.pos = pos
        self.size = size
        self.area = size[0] * size[1]
        
        self.potential = resource.resource()
        self.used = resource.resource()

        # per faction factors [0,100]
        self.faction_control = [0] * global_info.num_factions
        self.faction_importance = [0] * global_info.num_factions

        #distance to faction territory
        self.faction_distance = [0] * global_info.num_factions

        # update based on passed parameter
        super(area, self).__init__( keys )
示例#4
0
 def getRelevantResources(self, modname, ltype, reslist, pstyle):
     print("GETTING RESOURCES FROM " + self.name)
     tree = ET.parse("Topics/" + self.name + ".xml")
     resources, intro_table = tree.findall("RESOURCE"), ""
     for res in resources:
         res_obj = resource.resource(res)
         if (res_obj.ofModAndLevel(modname, ltype)) & (res_obj.linkb
                                                       not in reslist):
             reslist.append(res_obj.linkb)
             intro_table += res_obj.getResourceHTML(pstyle)
     return intro_table, reslist
示例#5
0
    def crawl(self,url):
        logging.info("Starting crawl at {0}.".format(url))
        resource.set_domain(DOMAIN)
        pid=os.getpid()
        create_scan_sql="""INSERT INTO scans(start_time,pid) 
            VALUES (NOW(), %s) RETURNING scan_id;"""
        self.cur.execute(create_scan_sql, (pid,))
        scan_row=self.cur.fetchone()
        self.scan_id=scan_row[0]
        resource_list={}
        pending=deque()
        pending.append(url)
        resource_list[url]=resource(url,self.scan_id)

        while (len(pending) > 0):
            cur_url=pending.popleft()

            assert cur_url in resource_list, "{0} ".format(cur_url) + \
                 "was placed in the pending queue, but no resource was created"
            cur_resource=resource_list[cur_url]

            assert not resource_list[cur_url].visited, \
                "Already visited resource {0} was requeued".format(cur_url)

            logging.info("Processing \"{0}\"".format(cur_url))

            cur_resource.fetch()
            #makes all data on creation
            cur_resource.Sql_Call(self.cur)

            for child_url in cur_resource.children:
                if (child_url in resource_list):
                    logging.debug(
                        "Skipping existing URL \"{0}\"".format(child_url))
                    continue
                logging.debug("Queueing \"{0}\"".format(child_url))
                new_resource=resource(child_url,self.scan_id)
                new_resource.parent=cur_resource
                pending.append(child_url)
                resource_list[child_url]=new_resource
        logging.info("All queued items have been scanned.");
    def __init__(self, ident, out, **keys):

        self.out = out
        self.ident = ident

        # set initial values
        self.name = ""
        self.cities = []
        self.areas = []
        self.potential_cities = []

        self.actions = []
        self.potential_actions = [ (self.create_citizen,
                                    person.person,
                                    [ city.city ])
                                 ]
        self.goals = {}

        # our resources, just contain sum of cities needs
        self.stockpile = resource.resource()
        self.consumption = resource.resource()
        self.production = resource.resource()
        self.change = resource.resource()

        # population (military and youth are subsets
        self.population = 0
        self.military = 0
        self.youth = 0

        # current expansion term
        self.expansion = 0

        #civilization characteristics [0,100]
        self.morality = 0
        self.nobility = 0
        self.xenophobia = 0
        self.militaristic = 0
        self.expansionism = 0

        # update based on passed parameter
        super(faction, self).__init__( keys )
示例#7
0
    def __init__( self, pos, out, **keys ):

        #simulation important things
        self.out = out
        self.pos = pos
        
        #general information about city
        self.area = None
        self.name = ""
        self.faction_ident = -1

        ################################################################
        #primary qualities modified by simulations
        self.growth_rate = 0.0
        self.work_factor = 1.0

        self.morality = 0
        
        self.population = 0
        self.military = 0
        self.youth = 0

        ################################################################
        #secondary qualities, determined by primaries
        self.controlled_area = 0

        # our resources
        self.stockpile = resource.resource()
        self.consumption = resource.resource()
        self.production = resource.resource()
        self.change = resource.resource()

        self.security = 0
        self.happiness = 0
        self.violence = 0
        self.sexuality = 0
        self.graft = 0

        # update based on passed parameter
        super(city, self).__init__( keys )
示例#8
0
def getSwarms(apikey):
    """Retrieve a list of all swarms associated with this api key

    @param apikey: an apikey object containing a valid configuration key

    @return: Returns a list containing all swarm objects owned by the user
    """
    conn = httplib.HTTPConnection(apikey.server, apikey.port)
    conn.request("GET", "/swarms", None,
                 {"x-bugswarmapikey":apikey.configuration})
    resp = conn.getresponse()
    txt = resp.read()
    conn.close()
    if resp.status >= 400:
        logging.debug('Swarm info response: ('+str(resp.status)+'): '+txt)
    else:
        logging.warning('Swarm info response: ('+str(resp.status)+'): '+txt)
    items = json.loads(txt)
    swarms = []
    for item in items:
        resources = {}
        if (item.has_key("resources")):
            for res_data in item["resources"]:
                #retrieve resource_type and convert it into an enum'd permission
                permission = resource.PERM_NONE
                if res_data.has_key("resource_type"):
                    if (res_data["resource_type"] == resource.TYPE_PRODUCER):
                        permission = resource.PERM_PRODUCER
                    elif (res_data["resource_type"] == resource.TYPE_CONSUMER):
                        permission = resource.PERM_CONSUMER
                    else:
                        logging.warning('unknown resource_type '+str(item["resource_type"])+
                            ', assuming maximum permissions')
                        permission = resource.PERM_PROSUMER
                #If item is not already in the resources map, add it
                if not resources.has_key(res_data["resource_id"]):
                    resources[res_data["resource_id"]] = resource.resource(apikey, res_data["resource_id"],
                        res_data["name"] if res_data.has_key("name") else False,
                        res_data["description"] if res_data.has_key("description") else False,
                        res_data["created_at"] if res_data.has_key("created_at") else False,
                        permission)
                #if item is already in the resources map, logically OR it's permissions
                else:
                    resources[res_data["resource_id"]].permission = resources[res_data["resource_id"]].permission | permission
        swrm = swarm(apikey, item["id"],
            item["name"] if item.has_key("name") else False,
            item["description"] if item.has_key("description") else False,
            item["created_at"] if item.has_key("created_at") else False,
            item["public"] if item.has_key("public") else False,
            resources)
        swarms.append(swrm)
    return swarms
示例#9
0
    def getResources(self, resource_type=None):
        """Returns a list of all participant resources

        @param resource_type: (optional) only return resources of a given type, EG
                     TYPE_PRODUCER
                     TYPE_CONSUMER

        @return: returns a dict of resources, indexed by resource_id
        """
        conn = httplib.HTTPConnection(self.apikey.server, self.apikey.port)
        if resource_type != None:
            conn.request("GET", "/swarms/%s/resources?type=%s"%(self.id,resource_type),
                    None, {"x-bugswarmapikey":self.apikey.configuration})
        else:
            conn.request("GET", "/swarms/%s/resources"%(self.id), None,
                     {"x-bugswarmapikey":self.apikey.configuration})
        resp = conn.getresponse()
        txt = resp.read()
        conn.close()
        if resp.status >= 400:
            logging.warning('Swarm get_resource response: ('+str(resp.status)+'): '+txt)
        else:
            logging.debug('Swarm get_resource response: ('+str(resp.status)+'): '+txt)
        res_list = {}
        item = json.loads(txt)
        for res_data in item:
            #retrieve resource_type and convert it into an enum'd permission
            permission = resource.PERM_NONE
            if res_data.has_key("resource_type"):
                if (res_data["resource_type"] == resource.TYPE_PRODUCER):
                    permission = resource.PERM_PRODUCER
                elif (res_data["resource_type"] == resource.TYPE_CONSUMER):
                    permission = resource.PERM_CONSUMER
                else:
                    logging.warning('unknown resource_type '+str(item["resource_type"])+
                        ', assuming maximum permissions')
                    permission = resource.PERM_PROSUMER
            #If item is not already in the resources map, add it
            if not res_list.has_key(res_data["resource_id"]):
                res_list[res_data["resource_id"]] = resource.resource(self.apikey, res_data["resource_id"],
                    res_data["name"] if res_data.has_key("name") else False,
                    res_data["description"] if res_data.has_key("description") else False,
                    res_data["created_at"] if res_data.has_key("created_at") else False,
                    permission)
            #if item is already in the resources map, logically OR it's permissions
            else:
                res_list[res_data["resource_id"]].permission = res_list[res_data["resource_id"]].permission | permission
        return res_list
示例#10
0
    def getInfo(self):
        """Retrieve a swarm's information from the swarm server"""
        conn = httplib.HTTPConnection(self.apikey.server, self.apikey.port)
        conn.request("GET", "/swarms/%s"%(self.id), None,
                     {"x-bugswarmapikey":self.apikey.configuration})
        resp = conn.getresponse()
        txt = resp.read()
        conn.close()
        if resp.status >= 400:
            logging.warning('Swarm info response: ('+str(resp.status)+'): '+txt)
        else:
            logging.debug('Swarm info response: ('+str(resp.status)+'): '+txt)
        item = json.loads(txt)
        if (item.has_key("name")):
            self.name = item["name"]
        if (item.has_key("description")):
            self.description = item["description"]
        if (item.has_key("created_at")):
            self.created_at = item["created_at"]
        if (item.has_key("public")):
            self.public = item["public"]
        if (item.has_key("resources")):
            self.resources = {}
            for res_data in item["resources"]:
                #retrieve resource_type and convert it into an enum'd permission
                permission = resource.PERM_NONE
                if res_data.has_key("resource_type"):

                    if (res_data["resource_type"] == resource.TYPE_PRODUCER):
                        permission = resource.PERM_PRODUCER
                    elif (res_data["resource_type"] == resource.TYPE_CONSUMER):
                        permission = resource.PERM_CONSUMER
                    else:
                        logging.warning('unknown resource_type '+str(item["resource_type"])+
                            ', assuming maximum permissions')
                        permission = resource.PERM_PROSUMER
                #If item is not already in the resources map, add it
                if not self.resources.has_key(res_data["resource_id"]):
                    self.resources[res_data["resource_id"]] = resource.resource(self.apikey, res_data["resource_id"],
                        res_data["name"] if res_data.has_key("name") else False,
                        res_data["description"] if res_data.has_key("description") else False,
                        res_data["created_at"] if res_data.has_key("created_at") else False,
                        permission)
                #if item is already in the resources map, logically OR it's permissions
                else:
                    self.resources[res_data["resource_id"]].permission = self.resources[res_data["resource_id"]].permission | permission
        return self
示例#11
0
    def from_json(self, config_json, clusterName):
        with open(config_json, 'r') as f:
            params = json.load(f)
            if clusterName is None:
                for item in params["default"]:
                    clusterName = item["name"]

            for item in params["Resource"]:
                if(clusterName == item['name']):
                    subScheduler = item["scheduler"]
                    userName = item["userName"]
                    hostName =  item["hostName"]
                    remoteTmp = item["RemoteTmp"]
                    transferType = item["transferType"]

                    resource_ = resource(userName, hostName, remoteTmp, transferType)
                    return resource_, subScheduler
示例#12
0
    def __init__( self, out, screen, tile_size, generator ):

        #avoid our attribute management system
        self.recurse_attributes = False
        
        self.screen = screen
        
        self.window = screen.get_size()

        self.tile_size = tile_size
        self.tile_dim = ( self.window[0]/tile_size[0],
                          self.window[1]/tile_size[1] )
        
        self.window = ( self.tile_dim[0] * tile_size[0],
                        self.tile_dim[1] * tile_size[1] )
        
        self.start_rect = Rect( (0,0), tile_size)

        self.ts = ts = tile_size
        self.hts = hts = (ts[0]/2, ts[1]/2)

        self.areas = [ [ area.area( vector3( x*ts[0] + hts[0],
                                             y*ts[1] + hts[1],
                                             0 ),
                                    ts,
                                    potential = resource.resource(
                                                    food = generator(x, y),
                                                    wood = generator(x, y),
                                                    gold = generator(x, y),
                                                    stone = generator(x, y)
                                                                 )
                                   ) for y in range( self.tile_dim[1] )
                       ] for x in range( self.tile_dim[0] )
                     ]

        self.cities = [ city.city( vector3( x + (hts[0]-5) * random.random(),
                                            y + (hts[1]-5) * random.random(),
                                            0.0 ),
                                   out,
                                   area = self.get_area_at( x/ts[0], y/ts[1] ) )
                        for x in range(0, self.window[0], hts[0])
                        for y in range(0, self.window[1], ts[1])
                      ]
示例#13
0
 def get_resources(self):
     # Get the resource day rates
     print("Getting resource rates")
     with open("src/charge_rates.csv") as csv_file:
         csv_reader = csv.reader(csv_file, delimiter=',')
         line_count = 0
         for row in csv_reader:
             if line_count == 0:
                 pass
             else:
                 if len(row) > 1:
                     res = resource()
                     res.project_id = row[0]
                     res.resource_name = row[1]
                     res.day_rate = int(row[2])
                     res.resource_type = row[3]
                     res.charge_under = row[4]
                     res.get_hours_per_day()
                     if res.charge_under == "":
                         res.charge_under = res.resource_name
                     self.resources.append(res)
             line_count += 1
示例#14
0
    def recrawl(self,id):
        logging.info("Starting difference scan at {0}.".format(id))
        pid=os.getpid()
        
        create_scan_sql="""INSERT INTO scans(start_time,pid) 
            VALUES (NOW(), %s) RETURNING scan_id;"""    
        self.cur.execute(create_scan_sql, (pid,))#creates the new scan ID
        scan_row=self.cur.fetchone()
        self.scan_id=scan_row[0]

        create_list_sql="""SELECT url FROM resources 
            WHERE scan_id = %s AND http_response != 200 ;"""
        self.cur.execute(create_list_sql,(id,))#retreaves old scan data
        
        resource_list={}
        scan_results=self.cur.fetchall()
       
        for x in scan_results:
            cur_resource=resource(x[0],self.scan_id)
            cur_resource.fetch()
            cur_resource.Sql_Call(self.cur)
        
        logging.info("All queued items have been scanned.");    
示例#15
0
def botprogram():
    ############Defining date variables to handle capturing the project roll off date user experience###############
    day = [['1'],['2'],['3'],['4'],['5'],['6'],['7'],['8'],['9'],['10'],['11'],['12'],['13'],['14'],['15'],['16'],['17'],['18'],['19'],['20'],['21'],['22'],['23'],['24'],['25'],['26'],['27'],['28'],['29'],['30'],['31']]
    month = [['January'],['February'],['March'],['April'],['May'],['June'],['July'],['August'],['September'],['October'],['November'],['December']]
    year = [['2016'],['2017'],['2018'],['2019'],['2020']]
    ################################################################################################################

    telegram_result = "" #Empty variable for storing a received telegram message
    Resource = [] #Array to store all resource objects which are instantiated
    index = -1 #Variable to represent the index value of the resource within the Resource array
    offset = 0 #Variable to store the index value of the received message

    #######################API.AI setup#########################
    Resource_ACCESS_TOKEN = 'd15e157632014d57951ff2ec164ed4f1'
    ai = apiai.ApiAI(Resource_ACCESS_TOKEN)
    ############################################################

    #######################Heroku Postgres setup#########################
    url = urlparse.urlparse(os.environ.get('DATABASE_URL'))
    db = "dbname=%s user=%s password=%s host=%s " % (url.path[1:], url.username, url.password, url.hostname)
    schema = "schema.sql"
    con = psycopg2.connect(db)
    cur = con.cursor()
    #####################################################################

    schedule.every().thursday.at("11:40").do(postit,Resource) #Schedule library function to run postit function at friday at 10am (8am GMT). The Resource array is passed as a parameter to the postit function.

    cur.execute('SELECT telegram_user_id__c, name FROM salesforce.resource__c') #Read resource information from Salesforce
    rows = cur.fetchall()
    for row in rows:
        Resource.append(resource(row[0],row[1])) #Instantiating resource objects using the Salesforce data and appending these objects to the Resource array.
        print str('adding ' + row[1] + ' to RAM')

    while True: #'Runtime infinite loop'
        while True: #'Receive message loop'
            cur.execute('SELECT telegram_user_id__c, name FROM salesforce.resource__c') #Read resource information from Salesforce
            rows = cur.fetchall()
            for row in rows: #loop through resources from Salesforce
                found = 0
                for element in Resource: #loop through resources in the Resources array (RAM)
                    if str(element.name) == str(row[1]): #if resource is in both Salesforce and the Resources array, do nothing.
                        found = 1
                if found == 0: # if the resource was added on Salesforce but has not yet been added to the Resources array, add it to the Resources array.
                    Resource.append(resource(row[0],row[1]))
                    print str('adding ' + row[1] + ' to RAM')

            schedule.run_pending() #Check to see if it is the right day and time for the Schedule library function to run the postit function
            telegram_response = get(offset) #wait to receive telegram response
            for result in telegram_response['result']: #if the telegram response contains a 'result' component, then a message has been received.
                telegram_result = result
                break #break out of the 'Recieve message loop'
            if not telegram_result == "": #if the telegram_result is equal to something, then a message has been received.
                break #break out of the 'Recieve message loop'
            #if no message has been received then loop back to the 'Recieve message loop' and wait to receive a message again.

        try: #check to see if the result component of the telegram_response contains an update_id
            update_id = result['update_id']
            print 'message received'
        except KeyError: #except the error so the program doesn't crash
            pass
        try: #check to see if the result component of the telegram_response contains text
            text = result['message']['text']
        except KeyError: #except the error so the program doesn't crash
            pass
        try: #check to see if the result component of the telegram_response contains a first and last name
            first_name = result['message']['from']['first_name']
            last_name = result['message']['from']['last_name']
            name = str(first_name + " " + last_name)
        except KeyError: #except the error so the program doesn't crash
            pass
        try: #check to see if the result component of the telegram_response contains a user id
            user_id = result['message']['from']['id']
        except KeyError: #except the error so the program doesn't crash
            pass
        try: #check to see if the result component of the telegram_response contains a chat id
            chat_id = result['message']['chat']['id']
        except KeyError: #except the error so the program doesn't crash
            pass

        if len(Resource) > 0: #if there are resource objects in the Resource array
            for i in range (0,len(Resource)): #loop through the Resource array
                if str(Resource[i].user_id) == str(user_id): #if the user id of the resource from the Resource array is equal to the user id of the current telegram user
                    index = i #set the index variable equal the index of the resource in the Resource array
                    print 'from old user'
                elif str(Resource[i].name) == str(name): #if the name of the resource from the Resource array is equal to the name of the current telegram user (User's name was loaded from Salesforce but not their Telegram I.D)
                    index = i #set the index variable equal the index of the resource in the Resource array
                    Resource[i].user_id = user_id #set the resource user id equal the user id of the current telegram user
                    cur.execute("UPDATE salesforce.resource__c SET telegram_user_id__c = '%s' WHERE name = '%s'" % (user_id, name)) #update Salesforce to include the resource's telegram id on their record
                    con.commit() #commit the previous SQL query to the Postgres database
                    print 'from old user with no telegram id'

        if index == -1: #if the telegram user does not have an associated resource object in the Resource array, their index is defaulted to -1
            Resource.append(resource(user_id,name)) #a new resource object is created and appended to the Resource array
            index = len(Resource)-1 #The index variable is set to the index of the new resource in the Resourece array
            cur.execute("INSERT INTO salesforce.resource__c (telegram_user_id__c,name,Employee_Status__c) VALUES ('%s', '%s','Active')" % (user_id, name)) #A new resource record is created on Salesforce
            con.commit()
            print 'from new user'
            print str('adding ' + str(Resource[index].name) + ' to RAM')

        cur.execute("SELECT name, awaiting_schedule_response__c FROM salesforce.resource__c WHERE name = '%s'" % (Resource[index].name)) #Read the name and awaiting_schedule_response check box for the current telegram user from Salesforce
        query_result = cur.fetchone()
        try: #if there is no result (the telegram user was deleted off Salesforce at some point), this will cause an error
            if query_result[1] == True: #if the awaiting_schedule_response checkbox is checked
                if Resource[index].phase == 0: #set the resource phase attribute to 0
                    if text in ['Yes','No']: #if the telegram_response text is yes or no
                        if text == 'No':
                            keybHide(Resource[index].user_id,'Thank you for your time. Hopefully you will be billable next time we speak!')
                            cur.execute("UPDATE salesforce.resource__c SET on_project__c = 'false', awaiting_schedule_response__c = 'false', engagement_roll_off_date__c = NULL, engagement__c = '' WHERE telegram_user_id__c = '%s'" % (user_id))
                            con.commit()
                        else:
                            cur.execute("UPDATE salesforce.resource__c SET on_project__c = 'true' WHERE telegram_user_id__c = '%s'" % (user_id))
                            con.commit()
                            ########################Processing the list of Engagements from Salesforce###########################
                            Engagement_Names = []
                            Engagement_Objects = []
                            cur.execute("SELECT name, sfid, project_status__c FROM salesforce.engagement__c WHERE project_status__c = 'In Progress'")
                            rows = cur.fetchall()
                            for row in rows:
                                Engagement_Names.append([row[0]])
                                Engagement_Objects.append([row])
                            keyb (Resource[index].user_id,"Which project are you currently on?", Engagement_Names)
                            Resource[index].phase = 1 #set the resource phase attribute to 1 - next phase of the conversation
                            ######################################################################################################

                    else: #if the telegram_response is not yes or no
                        post (Resource[index].user_id, 'Invalid response. Try again.')

                elif Resource[index].phase == 1: #if the resource phase is 1
                    if [text] in Engagement_Names: #check the telegram user's response was one of the options on the list
                        for element in Engagement_Objects: #loop through the engagement objects
                            if text in element[0]: #if telegram response text is an element of the an engagement object
                                cur.execute("UPDATE salesforce.resource__c SET engagement__c = '%s' WHERE telegram_user_id__c = '%s'" % (str(element[0][1]),user_id)) #set engagement__c = engagement id of Engagment object
                                con.commit()
                        post(chat_id,"What date will you be rolling off?")
                        keyb(chat_id,"Enter the day (dd/mm/yyyy):",day)
                        Resource[index].phase = 2 #set the resource phase attribute to 2 - next phase of the conversation
                    else: #if telegram user's response was not an option on the list
                        post (Resource[index].user_id, 'Invalid response. Try again.')

                elif Resource[index].phase == 2:
                    if [text] in day:
                        Resource[index].date = str(Resource[index].date) + text
                        keyb(chat_id,"Enter the month:",month)
                        Resource[index].phase =3
                    else:
                        post(Resource[index].user_id,'Invalid response. Try again.')

                elif Resource[index].phase == 3:
                    if [text] in month:
                        month_num = ['January','February','March','April','May','June','July','August','September','October','November','December'].index(text)+1
                        Resource[index].date = str(month_num) +  '-'+str(Resource[index].date)
                        keyb(chat_id,"Enter the year:",year)
                        Resource[index].phase =4
                    else:
                        post(Resource[index].user_id,'Invalid response. Try again.')

                elif Resource[index].phase == 4:
                    if [text] in year:
                        Resource[index].date = text + '-'+str(Resource[index].date)
                        keybHide(Resource[index].user_id,'Thank you for you time. Keep up the good work!')
                        Resource[index].phase = 0
                        cur.execute("UPDATE salesforce.resource__c SET engagement_roll_off_date__c = '%s', awaiting_schedule_response__c = 'false' WHERE telegram_user_id__c = '%s'" % (str(Resource[index].date),user_id))
                        con.commit()
                    else:
                        post(Resource[index].user_id,'Invalid response. Try again.')

            else: #if the awaiting_schedule_response checkbox is unchecked
                request = ai.text_request() #initiate Api.ai text request object
                request.query = text
                response = request.getresponse() #post text to the api.ai engine store the response a response object.
                API_AI_Response = response.read() #read the contents of the response object
                if '"intentName": "Greeting"' in API_AI_Response: #if the response contains the term 'greeting'
                        post(Resource[index].user_id,"Hello, I am DeloitteScheduleBot. I am currently still a noob as I've still got lots to learn. \n\nMy job is to help schedule resources. Ask me who is on the bench or who is on a project.")
                elif '"intentName": "System Query"' in API_AI_Response: #if the response contains the term 'system query'
                    if '"SystemObject": "Bench"' in API_AI_Response: #if the response contains the term 'bench'
                        temp_string = "Here's a list of employees on the bench:\n\n"
                        cur.execute("SELECT name, on_project__c FROM salesforce.resource__c WHERE on_project__c = 'false' AND Employee_Status__c = 'Active'")
                        rows = cur.fetchall()
                        for row in rows:
                            temp_string = temp_string + str(row[0]) + '\n'
                        post(Resource[index].user_id,temp_string)
                    elif '"SystemObject": "Project"' in API_AI_Response: #if the response contains the term 'project'
                        temp_string = "Here's a list of employees who are on billable projects:\n\n"
                        cur.execute("SELECT name, on_project__c FROM salesforce.resource__c WHERE on_project__c = 'true' AND Employee_Status__c = 'Active'")
                        rows = cur.fetchall()
                        for row in rows:
                            temp_string = temp_string + str(row[0]) + '\n'
                        post(Resource[index].user_id,temp_string)
                else: #if the response does not contain any known terms
                    post(Resource[index].user_id,"I didn't quite understand that. I will be posting this to my database to learn from at a later stage.")
                    cur.execute("INSERT INTO salesforce.new__c (New_Headline__c,News_Text__c) VALUES ('%s', '%s')" % (str('Unrecognised post by: ' + name),text.replace("'", "")))
                    con.commit()

        except TypeError: #if an error is caused, delete the telegram user from the Resources object and then loop back to the 'Receive message loop'. Don't increment the offset variable so the previously received message is recieved again so that a new resource record can be created for the user in RAM and on Salesforce.
            print str(Resource[index].user_id + " " + Resource[index].name)
            del Resource[index]
            print 'deleting old resource'
            break

        offset = update_id + 1 #increment the offset variable to receive the next message
        telegram_result = "" #refresh the telegram_result variable
        index = -1 #refresh the index variable
示例#16
0
def botprogram():
    ############Defining date variables to handle capturing the project roll off date user experience###############
    day_31 = [['1'], ['2'], ['3'], ['4'], ['5'], ['6'], ['7'], ['8'], ['9'],
              ['10'], ['11'], ['12'], ['13'], ['14'], ['15'], ['16'], ['17'],
              ['18'], ['19'], ['20'], ['21'], ['22'], ['23'], ['24'], ['25'],
              ['26'], ['27'], ['28'], ['29'], ['30'], ['31']]
    day_30 = [['1'], ['2'], ['3'], ['4'], ['5'], ['6'], ['7'], ['8'], ['9'],
              ['10'], ['11'], ['12'], ['13'], ['14'], ['15'], ['16'], ['17'],
              ['18'], ['19'], ['20'], ['21'], ['22'], ['23'], ['24'], ['25'],
              ['26'], ['27'], ['28'], ['29'], ['30']]
    day_28 = [['1'], ['2'], ['3'], ['4'], ['5'], ['6'], ['7'], ['8'], ['9'],
              ['10'], ['11'], ['12'], ['13'], ['14'], ['15'], ['16'], ['17'],
              ['18'], ['19'], ['20'], ['21'], ['22'], ['23'], ['24'], ['25'],
              ['26'], ['27'], ['28']]
    month = [['January'], ['February'], ['March'], ['April'], ['May'],
             ['June'], ['July'], ['August'], ['September'], ['October'],
             ['November'], ['December']]
    year = [['2016'], ['2017'], ['2018'], ['2019'], ['2020']]
    ################################################################################################################
    #################################Dynamically assigning resource service lines###################################
    sf_version = '32.0'
    sf_instance = ""
    headers = ""
    soap_url = 'https://login.salesforce.com/services/Soap/u/32.0'
    sf_version = 32.0
    session_id = ""
    service_lines = []

    login_soap_request_body = """<?xml version="1.0" encoding="utf-8" ?>
    <env:Envelope
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
        <env:Body>
            <n1:login xmlns:n1="urn:partner.soap.sforce.com">
                <n1:username>{username}</n1:username>
                <n1:password>{password}{token}</n1:password>
            </n1:login>
        </env:Body>
    </env:Envelope>""".format(username='', password='', token='')

    login_soap_request_headers = {
        'content-type': 'text/xml',
        'charset': 'UTF-8',
        'SOAPAction': 'login'
    }

    response = requests.post(soap_url,
                             login_soap_request_body,
                             headers=login_soap_request_headers)

    if response.status_code < 300:
        session_id = getUniqueElementValueFromXmlString(
            response.content, 'sessionId')
        server_url = getUniqueElementValueFromXmlString(
            response.content, 'serverUrl')

        sf_instance = (server_url.replace('http://', '').replace(
            'https://', '').split('/')[0].replace('-api', ''))

        sf_headers = {
            'Content-Type': 'application/json',
            'Authorization': 'Bearer ' + session_id,
            'X-PrettyPrint': '1'
        }

    for element in describeObject(sf_instance, sf_headers)["fields"]:
        if str(element["label"]) == 'Service Line':
            for picklist_values in element["picklistValues"]:
                if "-" in picklist_values["label"]:
                    service_lines.append([str(picklist_values["label"])])

    ##################################################################################################################

    telegram_result = ""  #Empty variable for storing a received telegram message
    Resource = []  #Array to store all resource objects which are instantiated
    index = -1  #Variable to represent the index value of the resource within the Resource array
    offset = 0  #Variable to store the index value of the received message

    #######################API.AI setup#########################
    Resource_ACCESS_TOKEN = 'd15e157632014d57951ff2ec164ed4f1'
    ai = apiai.ApiAI(Resource_ACCESS_TOKEN)
    ############################################################

    #######################Heroku Postgres setup#########################
    url = urlparse.urlparse(os.environ.get('DATABASE_URL'))
    db = "dbname=%s user=%s password=%s host=%s " % (
        url.path[1:], url.username, url.password, url.hostname)
    schema = "schema.sql"
    con = psycopg2.connect(db)
    cur = con.cursor()

    ##################Assigning Deloitte Teams to Engagments###########################
    cur.execute(
        "SELECT sfid, DeloitteTeamsInvolved__c from salesforce.opportunity")
    Opportunity_Objects = cur.fetchall()

    Global_Engagement_Names = []
    Engagement_Objects = []
    cur.execute(
        "SELECT name, sfid, project_status__c, opportunity__c FROM salesforce.engagement__c WHERE project_status__c = 'In Progress'"
    )
    Engagements = cur.fetchall()
    for engagement in Engagements:
        Global_Engagement_Names.append(engagement[0])
        for opportunity in Opportunity_Objects:
            if engagement[3] == opportunity[0]:
                Engagement_Objects.append(
                    [engagement[0], engagement[1],
                     opportunity[1]])  #[name,sfid,teamsinvolved]

    #####################################################################################

    schedule.every().friday.at("08:00").do(
        postit, Resource
    )  #Schedule library function to run postit function at friday at 10am (8am GMT). The Resource array is passed as a parameter to the postit function.

    cur.execute(
        "SELECT telegram_user_id__c, name, Bot_State__c,on_project__c,ServiceLine__c, engagement__c, SchedularBotAccess__c FROM salesforce.resource__c WHERE SchedularBotAccess__c = 'Approved'"
    )  #Read resource information from Salesforce
    rows = cur.fetchall()
    for row in rows:
        Resource.append(
            resource(row[0], row[1], int(row[2]), row[3], row[4])
        )  #Instantiating resource objects using the Salesforce data and appending these objects to the Resource array.
        index = len(Resource) - 1
        for engagement in Engagement_Objects:
            if row[5] == engagement[1]:
                Resource[index].engagement_name = engagement[0]
        print str('adding ' + row[1] + ' to RAM')

    while True:  #'Runtime infinite loop'
        while True:  #'Receive message loop'
            cur.execute(
                "SELECT telegram_user_id__c, name, Bot_State__c,on_project__c,ServiceLine__c, engagement__c, SchedularBotAccess__c FROM salesforce.resource__c WHERE SchedularBotAccess__c = 'Approved'"
            )  #Read approved resource information from Salesforce
            rows = cur.fetchall()
            for row in rows:  #loop through resources from Salesforce
                found = 0
                for element in Resource:  #loop through resources in the Resources array (RAM)
                    if str(element.user_id) == str(
                            row[0]
                    ):  #if resource is in both Salesforce and the Resources array, do nothing.
                        found = 1
                        if element.approved == 0:  #if resource was not approved previously
                            element.approved = 1  #approve resource
                            print str(row[1] +
                                      ' has been approved on Salesforce')
                            keyb(
                                element.user_id,
                                "Your access to DeloitteScheduleBot has been approved. Please select your service line from the list of options below:",
                                service_lines
                            )  #prompting the telegram user to select their service line
                            element.state = 7
                            cur.execute(
                                "UPDATE salesforce.resource__c SET Bot_State__c = '%s' WHERE telegram_user_id__c = '%s'"
                                % (str(element.state), element.user_id))
                            con.commit()
                if found == 0:  # if the resource was added on Salesforce but has not yet been added to the Resources array, add it to the Resources array.
                    Resource.append(
                        resource(row[0], row[1], int(row[2]), row[3], row[4]))
                    index = len(Resource) - 1
                    for engagement in Engagement_Objects:
                        if row[5] == engagement[1]:
                            Resource[index].engagement_name = engagement[0]
                    print str(row[1] +
                              ' has been created and approved on Salesforce')
                    print str('adding ' + row[1] + ' to RAM')
                    keyb(
                        Resource[index].user_id,
                        "Your access to DeloitteScheduleBot has been approved. Please select your service line from the list of options below:",
                        service_lines
                    )  #prompting the telegram user to select their service line
                    Resource[index].state = 7
                    cur.execute(
                        "UPDATE salesforce.resource__c SET Bot_State__c = '%s' WHERE telegram_user_id__c = '%s'"
                        %
                        (str(Resource[index].state), Resource[index].user_id))
                    con.commit()

            schedule.run_pending(
            )  #Check to see if it is the right day and time for the Schedule library function to run the postit function
            telegram_response = get(offset)  #wait to receive telegram response

            try:
                for result in telegram_response[
                        'result']:  #if the telegram response contains a 'result' component, then a message has been received.
                    telegram_result = result
                    break  #break out of the 'Recieve message loop'
                if not telegram_result == "":  #if the telegram_result is equal to something, then a message has been received.
                    break  #break out of the 'Recieve message loop'
                #if no message has been received then loop back to the 'Recieve message loop' and wait to receive a message again.
            except KeyError:
                print "spam recieved"
                pass

        try:  #check to see if the result component of the telegram_response contains an update_id
            update_id = result['update_id']
            print 'message received'
        except KeyError:  #except the error so the program doesn't crash
            pass
        try:  #check to see if the result component of the telegram_response contains text
            text = result['message']['text']
        except KeyError:  #except the error so the program doesn't crash
            pass
        try:  #check to see if the result component of the telegram_response contains a first and last name
            first_name = result['message']['from']['first_name']
            last_name = result['message']['from']['last_name']
            name = str(first_name + " " + last_name)
        except KeyError:  #except the error so the program doesn't crash
            pass
        try:  #check to see if the result component of the telegram_response contains a user id
            user_id = result['message']['from']['id']
        except KeyError:  #except the error so the program doesn't crash
            pass
        try:  #check to see if the result component of the telegram_response contains a chat id
            chat_id = result['message']['chat']['id']
        except KeyError:  #except the error so the program doesn't crash
            pass

        if len(Resource
               ) > 0:  #if there are resource objects in the Resource array
            for i in range(0, len(Resource)):  #loop through the Resource array
                if str(Resource[i].user_id) == str(
                        user_id
                ):  #if the user id of the resource from the Resource array is equal to the user id of the current telegram user
                    index = i  #set the index variable equal the index of the resource in the Resource array
                    print 'from old user'

        if index == -1:  #if the telegram user does not have an associated resource object in the Resource array, their index is defaulted to -1
            try:
                cur.execute(
                    "SELECT telegram_user_id__c FROM salesforce.resource__c WHERE telegram_user_id__c = '%s'"
                    % (user_id)
                )  #check to see the telegram user is already on salesforce but hasn't been aproved yet
                query_result = cur.fetchone()
                if query_result[0] == str(user_id):
                    Resource.append(
                        resource(user_id, name, 0, False, '')
                    )  #a new resource object is created and appended to the Resource array
                    index = len(Resource) - 1
                    Resource[index].approved = 0
                    print 'from user who is on Salesforce but has not been approved yet'
                    print str('adding ' + str(Resource[index].name) +
                              ' to RAM')
            except TypeError:  #user was not identified using their telegram_user_id
                try:
                    cur.execute(
                        "SELECT name FROM salesforce.resource__c WHERE name = '%s'"
                        % (name)
                    )  #check to see if the user is on salesforce, doesn't have a telegram_id and isn't approved yet
                    query_result = cur.fetchone()
                    if query_result[0] == str(name):
                        Resource.append(
                            resource(user_id, name, 0, False, '')
                        )  #a new resource object is created and appended to the Resource array
                        index = len(Resource) - 1
                        Resource[index].approved = 0
                        print 'from user who is on Salesforce but does not have a telegram_id and has not been approved yet'
                        print str('adding ' + str(Resource[index].name) +
                                  ' to RAM')
                        cur.execute(
                            "UPDATE salesforce.resource__c SET telegram_user_id__c = '%s' WHERE name = '%s'"
                            % (user_id, name)
                        )  #update Salesforce to include the resource's telegram id on their record
                        con.commit(
                        )  #commit the previous SQL query to the Postgres database
                        print 'telegram id updated in Salesforce'
                except TypeError:  #if the user is not on salesforce yet..
                    Resource.append(
                        resource(user_id, name, 0, False, '')
                    )  #a new resource object is created and appended to the Resource array
                    index = len(
                        Resource
                    ) - 1  #The index variable is set to the index of the new resource in the Resourece array
                    Resource[index].approved = 0
                    cur.execute(
                        "INSERT INTO salesforce.resource__c (telegram_user_id__c,name,Employee_Status__c) VALUES ('%s', '%s','Active')"
                        % (user_id, name)
                    )  #A new resource record is created on Salesforce
                    con.commit()
                    print 'from new user'
                    print str('adding ' + str(Resource[index].name) +
                              ' to Salesforce')
                    print str('adding ' + str(Resource[index].name) +
                              ' to RAM')

        if Resource[index].state == 1:  #if the resource  attribute is 1
            if text in ['Yes',
                        'No']:  #if the telegram_response text is yes or no
                if Resource[
                        index].on_project == True:  #if the user was on a project
                    if text == 'Yes':  #if the user is still on that project
                        keybHide(
                            Resource[index].user_id,
                            'Thank you for your time. Keep up the good work!')
                        Resource[index].state = 0
                        cur.execute(
                            "UPDATE salesforce.resource__c SET Bot_State__c = '%s' WHERE telegram_user_id__c = '%s'"
                            % (str(Resource[index].state),
                               Resource[index].user_id))
                        con.commit()
                    else:  #if the user is no longer on that project
                        keyb(Resource[index].user_id,
                             "Are you on a billable project?",
                             [["Yes"], ["No"]])
                        Resource[index].engagement_name = ''
                        Resource[index].on_project = False
                        cur.execute(
                            "UPDATE salesforce.resource__c SET on_project__c = 'false', engagement_roll_off_date__c = NULL, engagement__c = '' WHERE telegram_user_id__c = '%s'"
                            % (Resource[index].user_id)
                        )  #refresh resource object so that new scheduled data can be recorded
                        con.commit()
                else:
                    if text == 'No':
                        keybHide(
                            Resource[index].user_id,
                            'Thank you for your time. Hopefully you will be billable next time we speak!'
                        )
                        Resource[index].state = 0
                        Resource[index].engagement_name = ''
                        cur.execute(
                            "UPDATE salesforce.resource__c SET on_project__c = 'false', engagement_roll_off_date__c = NULL, engagement__c = '', Bot_State__c = '%s' WHERE telegram_user_id__c = '%s'"
                            % (str(Resource[index].state),
                               Resource[index].user_id))
                        con.commit()
                    else:
                        Resource[index].on_project = True
                        cur.execute(
                            "UPDATE salesforce.resource__c SET on_project__c = 'true' WHERE telegram_user_id__c = '%s'"
                            % (user_id))
                        con.commit()
                        ########################Processing the list of Engagements###########################
                        Engagement_Names = []
                        for engagement in Engagement_Objects:
                            try:
                                try:
                                    if not (engagement[2]).index(
                                            Resource[index].service_line) < 0:
                                        Engagement_Names.append(
                                            [engagement[0]])
                                except AttributeError:
                                    pass
                            except ValueError:
                                pass
                        Engagement_Names.append(["Other"])
                        keyb(
                            Resource[index].user_id,
                            "Which project are you currently on? If your project is not on the list, please select 'Other'.",
                            Engagement_Names)
                        Resource[
                            index].state = 2  #set the resource state attribute to 1 - next state of the conversation
                        cur.execute(
                            "UPDATE salesforce.resource__c SET Bot_State__c = '%s' WHERE telegram_user_id__c = '%s'"
                            % (str(Resource[index].state),
                               Resource[index].user_id))
                        con.commit()
                        ######################################################################################

            else:  #if the telegram_response is not yes or no
                post(Resource[index].user_id, 'Invalid response. Try again.')

        elif Resource[index].state == 2:  #if the resource state is 1
            if text in Global_Engagement_Names:  #check the telegram user's response was one of the options on the list
                for element in Engagement_Objects:  #loop through the engagement objects
                    if text == element[
                            0]:  #if telegram response text is = engagement name
                        Resource[index].engagement_name = element[0]
                        cur.execute(
                            "UPDATE salesforce.resource__c SET engagement__c = '%s' WHERE telegram_user_id__c = '%s'"
                            % (str(element[1]), user_id)
                        )  #set engagement__c = engagement id of Engagment object
                        con.commit()
                keyb(chat_id, "Do you know what date you will be rolling off?",
                     [["Yes"], ["No"]])
                Resource[
                    index].state = 3  #set the resource state attribute to 2 - next state of the conversation
                cur.execute(
                    "UPDATE salesforce.resource__c SET Bot_State__c = '%s' WHERE telegram_user_id__c = '%s'"
                    % (str(Resource[index].state), Resource[index].user_id))
                con.commit()
            elif text == "Other":
                post(Resource[index].user_id,
                     'What is the name of the project you are currently on?')
                Resource[index].state = 8
                cur.execute(
                    "UPDATE salesforce.resource__c SET Bot_State__c = '%s' WHERE telegram_user_id__c = '%s'"
                    % (str(Resource[index].state), Resource[index].user_id))
                con.commit()
            else:  #if telegram user's response was not an option on the list
                post(Resource[index].user_id, 'Invalid response. Try again.')

        elif Resource[index].state == 3:
            if text in ['Yes', 'No']:
                if text == 'Yes':
                    Resource[index].date = ""
                    post(chat_id, "What date will you be rolling off?")
                    keyb(chat_id, "Enter the month:", month)
                    Resource[index].state = 4
                    cur.execute(
                        "UPDATE salesforce.resource__c SET Bot_State__c = '%s' WHERE telegram_user_id__c = '%s'"
                        %
                        (str(Resource[index].state), Resource[index].user_id))
                    con.commit()
                else:
                    keybHide(Resource[index].user_id,
                             'Thank you for you time. Keep up the good work!')
                    Resource[index].state = 0
                    cur.execute(
                        "UPDATE salesforce.resource__c SET engagement_roll_off_date__c = NULL, Bot_State__c = '%s' WHERE telegram_user_id__c = '%s'"
                        % (str(Resource[index].state), user_id))
                    con.commit()
            else:
                post(Resource[index].user_id, 'Invalid response. Try again.')

        elif Resource[index].state == 4:
            if [text] in month:
                month_num = [
                    'January', 'February', 'March', 'April', 'May', 'June',
                    'July', 'August', 'September', 'October', 'November',
                    'December'
                ].index(text) + 1
                Resource[index].date = str(month_num) + '-' + str(
                    Resource[index].date)
                if text in [
                        'January', 'March', 'May', 'July', 'August', 'October',
                        'December'
                ]:
                    keyb(chat_id, "Enter the day:", day_31)
                    Resource[index].date_capture_control = 0
                elif text in ['April', 'June', 'September', 'November']:
                    keyb(chat_id, "Enter the day:", day_30)
                    Resource[index].date_capture_control = 1
                else:
                    keyb(chat_id, "Enter the day:", day_28)
                    Resource[index].date_capture_control = 2
                Resource[index].state = 5
                cur.execute(
                    "UPDATE salesforce.resource__c SET Bot_State__c = '%s' WHERE telegram_user_id__c = '%s'"
                    % (str(Resource[index].state), Resource[index].user_id))
                con.commit()
            else:
                post(Resource[index].user_id, 'Invalid response. Try again.')

        elif Resource[index].state == 5:
            if ([text] in day_31 and Resource[index].date_capture_control == 0
                ) or ([text] in day_30 and Resource[index].date_capture_control
                      == 1) or ([text] in day_28
                                and Resource[index].date_capture_control == 2):
                Resource[index].date = str(Resource[index].date) + text
                keyb(chat_id, "Enter the year:", year)
                Resource[index].state = 6
                cur.execute(
                    "UPDATE salesforce.resource__c SET Bot_State__c = '%s' WHERE telegram_user_id__c = '%s'"
                    % (str(Resource[index].state), Resource[index].user_id))
                con.commit()
            else:
                post(Resource[index].user_id, 'Invalid response. Try again.')

        elif Resource[index].state == 6:
            if [text] in year:
                Resource[index].date = text + '-' + str(Resource[index].date)
                Resource[index].state = 0
                cur.execute(
                    "UPDATE salesforce.resource__c SET engagement_roll_off_date__c = '%s', Bot_State__c = '%s' WHERE telegram_user_id__c = '%s'"
                    % (str(Resource[index].date), str(
                        Resource[index].state), user_id))
                con.commit()
                keybHide(Resource[index].user_id,
                         'Thank you for you time. Keep up the good work!')
            else:
                post(Resource[index].user_id, 'Invalid response. Try again.')

        elif Resource[index].state == 7:  #receiving service line response
            if [text] in service_lines:
                Resource[index].state = 0
                Resource[index].service_line = text
                cur.execute(
                    "UPDATE salesforce.resource__c SET ServiceLine__c = '%s', Bot_State__c = '%s' WHERE telegram_user_id__c = '%s'"
                    % (text, str(Resource[index].state), user_id))
                con.commit()
                keybHide(
                    Resource[index].user_id,
                    'Thank you. You can now interact with the DeloitteScheduleBot!'
                )
            else:
                post(Resource[index].user_id, 'Invalid response. Try again.')

        elif Resource[index].state == 8:  #receiving service line response
            Resource[index].engagement_name = text
            post(
                Resource[index].user_id,
                'What is the name of the Opportunity that this project is associated with?'
            )
            Resource[index].state = 9
            cur.execute(
                "UPDATE salesforce.resource__c SET Bot_State__c = '%s' WHERE telegram_user_id__c = '%s'"
                % (str(Resource[index].state), Resource[index].user_id))
            con.commit()

        elif Resource[index].state == 9:  #receiving service line response
            cur.execute(
                "INSERT INTO salesforce.case (Subject, Priority, OwnerId, Description) VALUES ('Request to update Engagement information for Telegram Bot user %s','3 - Normal','00Gb0000001Wl73', '%s has updated his/her schedule with an Engagement titled %s which is associated with an Opportunity titled %s. Currently this Engagement is not available for schedule update selection for %s employees. There are two possible reasons for this: 1)This Engagement does not exist on Salesforce yet or 2)This Engagement does exist on Salesforce but it exists under an Opportunity where %s is not one of the Deloitte Teams Involved.\n\nTo resolve this case, it needs to be determined whether the Engagement that %s has described does already exist on Salesforce. If this Engagement exists on Salesforce, it needs to be determined whether or not it is appropriate to add %s to the Opportunity Splits associated with that Engagement. If it is appropriate to add %s to the Opportunity Splits associated with that Engagement, this should be done and the Resource record associated with %s should be updated accordingly.\n\nAlternatively, if this engagement does not exist on Salesforce, then it needs to be determined whether or not the Engagement should be created or not. If the Engagement should be created, it needs to be created under the Opportunity %s or any other appropriate Opportunity. %s must also be part of the Opportunity Split. The Resource record associated with %s should be updated with this Engagment information which then resolves the case.\n\nIf it is determined that an Engagement should not be created, then %s should be notified of this decision and the project information that was captured on his/her Resource record should be cleared accordingly.')"
                %
                (str(Resource[index].name), str(Resource[index].name),
                 str(Resource[index].engagement_name), str(text),
                 str(Resource[index].service_line),
                 str(Resource[index].service_line), str(
                     Resource[index].name), str(Resource[index].service_line),
                 str(Resource[index].service_line), str(Resource[index].name),
                 str(text), str(Resource[index].service_line),
                 str(Resource[index].name), str(Resource[index].name)))
            con.commit()
            keyb(chat_id, "Do you know what date you will be rolling off?",
                 [["Yes"], ["No"]])
            Resource[
                index].state = 3  #set the resource state attribute to 2 - next state of the conversation
            cur.execute(
                "UPDATE salesforce.resource__c SET Bot_State__c = '%s' WHERE telegram_user_id__c = '%s'"
                % (str(Resource[index].state), Resource[index].user_id))
            con.commit()

        elif Resource[
                index].state == 0:  #if the awaiting_schedule_response checkbox is unchecked and the state is not 5 or 6
            request = ai.text_request()  #initiate Api.ai text request object
            request.query = text
            response = request.getresponse(
            )  #post text to the api.ai engine store the response a response object.
            API_AI_Response = response.read(
            )  #read the contents of the response object
            if text == "/start":
                post(
                    Resource[index].user_id,
                    "Welcome to the DeloitteScheduleBot!\n\n*About:*\nDeloitteScheduleBot is a project that was started by the Customer Applications team in Deloitte Digital Africa. The DeloitteScheduleBot consists of a Telegram bot front-end which is integrated with Salesforce in the back-end. The purpose of the DeloitteScheduleBot is to seamlessly gather and organise information regarding the schedules of Deloitte Employees on a weekly basis. This schedule information can then used to report on the real-time utilization status of teams indicating who is on billable projects and who is on the bench.\n\n*How to use the DeloitteScheduleBot:*\nAfter initiating a conversation with the DeloitteScheduleBot, a request will be forwarded to the DeloitteScheduleBot support team to approve you as a verified user. Until you have been approved, you will only be able to engage in small-talk with bot. Once you have been approved, you will be asked to select your Deloitte service line from a list of all Deloitte service lines. After completing this step, you can begin using the DeloitteScheduleBot. The DeloitteScheduleBot is controlled using a Natural Language Processor that helps it to identify the meaning behind user requests. The following examples demonstrate how to use the DeloitteScheduleBot, however, the commands that are described in these examples are not hard-coded, so you can also communicate with the DeloitteScheduleBot using more natural variations of these commands.\n\n*Commands:*\n1)'I want to update my schedule.'\nThis command will activate the DeloitteScheduleBot's schedule update mechanism allowing you to update your schedule. The bot will ask you if you are on a billable project or not, which project you are currently on and when you are rolling off the current project. This schedule update mechanism is also automatically triggered once a week on a Friday morning at 10am.\n\n2)'Who is on the bench?'\nThis command will activate the DeloitteScheduleBot's reporting mechanism to give you a report of all employees within your service line who are currently not on billable projects. You can also query resources in a specific service line by asking something like 'Who is on the bench in Digital - Customer Applications?' for example.\n\n3)'Who is on a project?'\nThis command will activate the DeloitteScheduleBot's reporting mechanism to give you a report of all employees within your service line who are currently on billable projects whilst also indicating which projects each employee is currenlty on. You can also query resources in a specific service line by asking something like 'Who is on a project in Digital - Advisory?' for example.\n\n4)'I need help.'\nThe DeloitteScheduleBot will respond to this command with the 'How to use the DeloitteScheduleBot' information.\n\n*Contact Us:*\nIf there are any issues or if there is any feedback that you would like to report to us, please don't hesitate to email Steven Kimmel ([email protected]) and he will get back to you as soon as possible."
                )
            elif '"intentName": "Help"' in API_AI_Response:
                post(
                    Resource[index].user_id,
                    "*How to use the DeloitteScheduleBot:*\nAfter initiating a conversation with the DeloitteScheduleBot, a request will be forwarded to the DeloitteScheduleBot support team to approve you as a verified user. Until you have been approved, you will only be able to engage in small-talk with bot. Once you have been approved, you will be asked to select your Deloitte service line from a list of all Deloitte service lines. After completing this step, you can begin using the DeloitteScheduleBot. The DeloitteScheduleBot is controlled using a Natural Language Processor that helps it to identify the meaning behind user requests. The following examples demonstrate how to use the DeloitteScheduleBot, however, the commands that are described in these examples are not hard-coded, so you can also communicate with the DeloitteScheduleBot using more natural variations of these commands.\n\n*Commands:*\n1)'I want to update my schedule.'\nThis command will activate the DeloitteScheduleBot's schedule update mechanism allowing you to update your schedule. The bot will ask you if you are on a billable project or not, which project you are currently on and when you are rolling off the current project. This schedule update mechanism is also automatically triggered once a week on a Friday morning at 10am.\n\n2)'Who is on the bench?'\nThis command will activate the DeloitteScheduleBot's reporting mechanism to give you a report of all employees within your service line who are currently not on billable projects. You can also query resources in a specific service line by asking something like 'Who is on the bench in Digital - Customer Applications?' for example.\n\n3)'Who is on a project?'\nThis command will activate the DeloitteScheduleBot's reporting mechanism to give you a report of all employees within your service line who are currently on billable projects whilst also indicating which projects each employee is currenlty on. You can also query resources in a specific service line by asking something like 'Who is on a project in Digital - Advisory?' for example.\n\n4)'I need help.'\nThe DeloitteScheduleBot will respond to this command with the 'How to use the DeloitteScheduleBot' information.\n\n*Contact Us:*\nIf there are any issues or if there is any feedback that you would like to report to us, please don't hesitate to email Steven Kimmel ([email protected]) and he will get back to you as soon as possible."
                )
            elif '"intentName": "Greeting"' in API_AI_Response:  #if the response contains the term 'greeting'
                post(
                    Resource[index].user_id,
                    "Hello, I am DeloitteScheduleBot. My job is to help schedule resources. I am currently still a noob as I've still got lots to learn."
                )
            elif '"action": "smalltalk.' in API_AI_Response:  #API.AI identified an action from the  smalltalk domain
                parsed_response = json.loads(
                    API_AI_Response
                )  # lets parse the response from API.AI so that
                temp_string = parsed_response['result']['fulfillment'][
                    'speech']  # we can find the speech fulfilment and
                post(Resource[index].user_id, temp_string
                     )  # reply to the user with the associated result
            elif '"intentName": "System Query"' in API_AI_Response and Resource[
                    index].approved:  #if the response contains the term 'system query'
                if '"SystemObject": "Bench"' in API_AI_Response:  #if the response contains the term 'bench'
                    temp_string = "*Here's a list of " + str(
                        Resource[index].service_line
                    ) + " employees on the bench:*\n\n"
                    cur.execute(
                        "SELECT name, on_project__c,SchedularBotAccess__c FROM salesforce.resource__c WHERE on_project__c = 'false' AND Employee_Status__c = 'Active' AND SchedularBotAccess__c = 'Approved' AND ServiceLine__c = '%s'"
                        % (Resource[index].service_line))
                    rows = cur.fetchall()
                    for row in rows:
                        temp_string = temp_string + str(row[0]) + '\n'
                elif '"SystemObject": "Project"' in API_AI_Response:  #if the response contains the term 'project'
                    temp_string = "*Here's a list of " + str(
                        Resource[index].service_line
                    ) + " employees who are on billable projects:*\n\n"
                    cur.execute(
                        "SELECT name,engagement__c,engagement_roll_off_date__c, on_project__c,SchedularBotAccess__c FROM salesforce.resource__c WHERE on_project__c = 'true' AND Employee_Status__c = 'Active' AND SchedularBotAccess__c = 'Approved' AND ServiceLine__c = '%s'"
                        % (Resource[index].service_line))
                    rows = cur.fetchall()
                    for row in rows:
                        for element in Engagement_Objects:  #loop through the engagement objects
                            if row[1] == element[
                                    1]:  #if telegram response text is an element of the an engagement object
                                temp_string = temp_string + str(
                                    row[0]) + ': ' + str(element[0]) + '\n\n'
                post(Resource[index].user_id, temp_string)
            elif '"intentName": "Update Schedule"' in API_AI_Response and Resource[
                    index].approved:  #if the response contains the term 'system query'
                Resource[index].state = 1
                if Resource[
                        index].on_project == True:  #if user is on a project
                    keyb(
                        Resource[index].user_id, "Are you still on %s?" %
                        (Resource[index].engagement_name), [["Yes"], ["No"]])
                else:
                    keyb(Resource[index].user_id,
                         "Are you on a billable project?", [["Yes"], ["No"]])
            elif '"intentName": "Query Other Pod"' in API_AI_Response and Resource[
                    index].approved:
                parsed_response = json.loads(
                    API_AI_Response
                )  # lets parse the response from API.AI so that
                DigitalPod = parsed_response['result']['parameters'][
                    'DigitalPods']  # we can find the DigitalPod
                SystemObject = parsed_response['result']['parameters'][
                    'SystemObject']  # we can find the SystemObject
                if SystemObject == "Bench":
                    temp_string = "*Here's a list of " + str(
                        DigitalPod) + " employees on the bench:*\n\n"
                    cur.execute(
                        "SELECT name, on_project__c,SchedularBotAccess__c FROM salesforce.resource__c WHERE on_project__c = 'false' AND Employee_Status__c = 'Active' AND SchedularBotAccess__c = 'Approved' AND ServiceLine__c = '%s'"
                        % (str(DigitalPod)))
                    rows = cur.fetchall()
                    for row in rows:
                        temp_string = temp_string + str(row[0]) + '\n'
                elif SystemObject == "Project":
                    temp_string = "*Here's a list of " + str(
                        DigitalPod
                    ) + " employees who are on billable projects:*\n\n"
                    cur.execute(
                        "SELECT name,engagement__c,engagement_roll_off_date__c, on_project__c,SchedularBotAccess__c FROM salesforce.resource__c WHERE on_project__c = 'true' AND Employee_Status__c = 'Active' AND SchedularBotAccess__c = 'Approved' AND ServiceLine__c = '%s'"
                        % (str(DigitalPod)))
                    rows = cur.fetchall()
                    for row in rows:
                        for element in Engagement_Objects:  #loop through the engagement objects
                            if row[1] == element[
                                    1]:  #if telegram response text is an element of the an engagement object
                                temp_string = temp_string + str(
                                    row[0]) + ': ' + str(element[0]) + '\n\n'
                post(Resource[index].user_id, temp_string)
            elif Resource[
                    index].approved:  #if the response does not contain any known terms and the resource was approved
                post(
                    Resource[index].user_id,
                    "I didn't quite understand that. I will be posting this to my database to learn from at a later stage."
                )
                cur.execute(
                    "INSERT INTO salesforce.new__c (New_Headline__c,News_Text__c) VALUES ('%s', '%s')"
                    % (str('Unrecognised post by: ' + name),
                       text.replace("'", "")))
                con.commit()
            else:  #if the resource is not approved
                post(
                    Resource[index].user_id,
                    "Your access to the DeloitteScheduleBot is waiting for approval. Once approved, you will be able to interact with this bot. For now, you can enjoy some small talk with this bot."
                )

        offset = update_id + 1  #increment the offset variable to receive the next message
        telegram_result = ""  #refresh the telegram_result variable
        index = -1  #refresh the index variable