class CommandHandler:
    def __init__(self):
        self.speaker = AssistantSpeaker()
        self.weatherCommand = WeatherCommand()
        self.meetingCommand = MeetingCommand()
        self.remindMeetingsCommand = RemindMeetingsCommand()
        self.allCommandsCommand = AllCommandsCommand()
        self.changeParameterCommand = ChangeParametersCommand()
        self.helpCommand = HelpCommand()
        self.timeCommand = TimeCommand()

    def executeCommand(self, sentenceSaidByUser):
        print(sentenceSaidByUser)
        # for testing purposes, we're just using the default API key
        # to use another API key, use `r.recognize_google(audio, key="GOOGLE_SPEECH_RECOGNITION_API_KEY")`
        # instead of `r.recognize_google(audio)`
        if (sentenceSaidByUser == "weather"):
            self.weatherCommand.executeCommand()
        elif (sentenceSaidByUser == "all commands"):
            self.allCommandsCommand.executeCommand()
        elif (sentenceSaidByUser == "save meeting"):
            self.meetingCommand.executeCommand()
        elif (sentenceSaidByUser == "remind meetings"):
            self.remindMeetingsCommand.executeCommand()
        elif (sentenceSaidByUser == "change parameters"):
            self.changeParameterCommand.executeCommand()
        elif (sentenceSaidByUser == "help"):
            self.helpCommand.executeCommand()
        elif (sentenceSaidByUser == "time"):
            self.timeCommand.executeCommand()
        else:
            self.speaker.say(
                "Sorry, I don't recognize this command. To get all the available commands, say all commands."
            )
            print("I don't understand")
class WeatherCommand:
    def __init__(self):
        self.speaker = AssistantSpeaker()

    def executeCommand(self):
        self.speaker.say("Looking for the current temperature in Montreal")

        # Need to specify the headless option otherwise selenium will open
        # a chrome window and we don't want that
        # Cannot use urllib here because span content is dynamic
        options = webdriver.ChromeOptions()
        options.add_argument(Constants.DRIVER_ARGUMENT)
        driver = webdriver.Chrome(executable_path=Constants.DRIVER_EXEC_PATH,
                                  chrome_options=options)
        driver.get(Constants.WEATHER_URL)

        # Use beautiful soup to parse the html page to speed up the process
        # Beautiful soup has a faster parser than Selenium
        beautiful_soup = BeautifulSoup(driver.page_source,
                                       Constants.BEAUTIFUL_SOUP_PARSER)
        spanWithTemperature = beautiful_soup.find_all('span',
                                                      {'class': 'temp'})[0]
        print(spanWithTemperature.text)

        self.speaker.say("The temperature is currently " +
                         spanWithTemperature.text + "degree")
        print('Quit driver')
        # Important to close the driver to avoid having multiple chrome tasks
        # opened at the same time
        driver.quit()
class AllCommandsCommand:
    
    def __init__(self):
        self.speaker = AssistantSpeaker()
            
    def executeCommand(self):
        self.speaker.say("The available commands are : All commands, Change parameters, Help, Time, Save meeting, Remind meetings and Weather. For more informations about a command, say help.")
        

        
Пример #4
0
class StartActionThread(QThread):
    signal = pyqtSignal('PyQt_PyObject')

    def __init__(self, command=None):
        QThread.__init__(self)
        self.speaker = AssistantSpeaker()
        self.listener = AssistantListener()
        self.commandHandler = CommandHandler()
        self.command = command

    def run(self):

        if self.command is None:
            self.speaker.say("Tell me your command")
            self.command = self.listener.listen()

        # -1 means a WaitTimeoutException occured
        if (self.command == -1):
            self.speaker.say("Sorry, I could not understand the command")
        else:
            self.commandHandler.executeCommand(self.command)

        self.signal.emit("finished")
Пример #5
0
class TimeCommand:
    def __init__(self):
        self.speaker = AssistantSpeaker()
        self.listener = AssistantListener()

    def executeCommand(self):
        self.speaker.say("For which city do you want the current time ?")
        city = self.listener.listen()
        if city == -1:
            self.speaker.say(
                "Sorry I did not understand the name of the city.")
            return -1
        print(city)
        self.speaker.say(
            "Please wait while I'm looking for the current time in " + city)
        print("Prepare Selenium webdriver to get the time")

        string_current_time_city = self.getTimeFromWebSite(city)

        self.speaker.say("In " + city + " it is " + string_current_time_city +
                         " o'clock.")

    def getTimeFromWebSite(self, city):

        options = webdriver.ChromeOptions()
        options.add_argument(Constants.DRIVER_ARGUMENT)
        driver = webdriver.Chrome(executable_path=Constants.DRIVER_EXEC_PATH,
                                  chrome_options=options)
        driver.get(Constants.TIME_URL + city)

        # Use beautifulSoup to parse the source page for better performance
        soup = BeautifulSoup(driver.page_source,
                             Constants.BEAUTIFUL_SOUP_PARSER)
        answer = soup.find('td', id='p0')

        print('Quit driver')
        # Important to close the driver to avoid having multiple chrome tasks
        # opened at the same time
        driver.quit()

        # Date is with format 'Day Hour:Minute AM'
        splited_answer = answer.text.split()
        return splited_answer[1] + ' ' + splited_answer[2]
Пример #6
0
class RemindMeetingsCommand:
    def __init__(self):
        self.speaker = AssistantSpeaker()
        self.listener = AssistantListener()
        self.dateFormat = Constants.MEETING_DATE_FORMAT
        self.appJsonFile = JsonFileUtil(Constants.APP_PROPERTIES_FILENAME,
                                        Constants.APP_PROPERTIES_PATH)
        self.meetingJsonFile = JsonFileUtil(Constants.MEETING_FILENAME,
                                            Constants.MEETING_FILEPATH)
        self.intervalMeetingReminderKey = Constants.APP_PROP_INTERVALMEETING_PARAM

    # The app_properties file contain all the properties for the app
    # Return the number of days before a meeting we want the reminder to be triggered
    def getIntervalMeetingReminder(self):
        appProperties = self.getJsonDataFromJsonFile(self.jsonAppFilePath,
                                                     self.jsonAppFileName)
        return appProperties[self.intervalMeetingReminderKey]

    def remindScheduledMeetings(self, numberOfDaysBeforeMeetingReminder):
        currentDate = datetime.date.today()
        maximumDateForReminder = currentDate + datetime.timedelta(
            days=int(numberOfDaysBeforeMeetingReminder))
        meetings = self.meetingJsonFile.getData()
        for meetingKey in meetings:
            meetingDateTime = datetime.datetime.strptime(
                meetingKey, self.dateFormat)
            meetingDate = meetingDateTime.date()
            # The date comparison can only be made on datetime.date objects and not on datetime.datetime!
            if (maximumDateForReminder >= meetingDate
                    and meetingDate >= currentDate):
                meetingValue = self.meetingJsonFile.getValue(meetingKey)
                self.speaker.say(meetingValue + ' is due for ' + meetingKey)
        self.speaker.say("All the meetings coming in the next " +
                         numberOfDaysBeforeMeetingReminder +
                         " days have been said")

    def executeCommand(self):
        self.speaker.say("Reminding the upcoming meetings.")
        numberOfDaysBeforeMeetingReminder = self.appJsonFile.getValue(
            self.intervalMeetingReminderKey)
        self.remindScheduledMeetings(numberOfDaysBeforeMeetingReminder)
Пример #7
0
class HelpCommand:
    
    def __init__(self):
        self.speaker = AssistantSpeaker()
        self.listener = AssistantListener()
            
    def executeCommand(self):
        self.speaker.say("For which command do you need help ?")
        command_for_help = self.listener.listen()

        if command_for_help == 'weather':
            self.speaker.say("Simply say weather and you will have the current temperature in Montreal.")
        elif command_for_help == 'change parameters':
            self.speaker.say("After saying the command name, you will be ask to say the parameter name and the parameter value.")
        elif command_for_help == 'time':
            self.speaker.say("After saying the command name, you will be ask to say the name of the city. You will then hear the current time of the most likely city found.")
        elif command_for_help == 'all commands':
            self.speaker.say("Give all the available commands in the application.")
        elif command_for_help == 'remind meetings':
            self.speaker.say("The assistant will say all the upcoming meetings the the user. All the meetings from today plus the days interval specified in the interval meeting reminder application parameter will be reminded.")
        elif command_for_help == 'save meeting':
            self.speaker.say("For saving a meeting, you need too give, when it is asked, the year, the month (using number from 1 to 12), the day (using number from 1 to 31), the hour (using number from 0 to 24), the minute (using number from 0 to 60) and the meeting content")
        else:
            self.speaker.say("Sorry this command doesn't exist. For a list of all available commands, say All commands.")
class MeetingCommand:
    
    def __init__(self):
        self.speaker = AssistantSpeaker()
        self.listener = AssistantListener()
        self.dateFormat = Constants.MEETING_DATE_FORMAT
        self.meetingJsonFile = JsonFileUtil(Constants.MEETING_FILENAME, Constants.MEETING_FILEPATH)
    
    
    def getMeetingDateFromUser(self):
        
        dateIsValid = False
        while(dateIsValid is not True):
            year = self.getDateElement("year");
            month = self.getDateElement("month");
            day = self.getDateElement("day");
            hour = self.getDateElement("hour");
            minute = self.getDateElement("minute");
            
            try:
                dateOfMeeting = datetime.datetime(year, month, day, hour, minute)
                dateIsValid = True
            except ValueError:
                self.speaker.say("The given date was invalid, please record it again")
                dateIsValid = False
            
        print(dateOfMeeting)
        return dateOfMeeting
    
    def getDateElement(self, elementOfDate):
        dateElement = -1
        # listener.listen return -1 if there is a Waittimeout error
        while(dateElement == -1):
            self.speaker.say("What is the number of the " + elementOfDate + " for the meeting ?")
            dateElement = self.listener.listen()
            try:
                dateElement = int(dateElement)
            except ValueError:
                self.speaker.say("The given " + elementOfDate + " is not valid.")
                dateElement = -1
        print("Element of date is " + str(dateElement))
        return dateElement
    
    
    def getMeetingSubjectFromUser(self):
        # listener.listen return -1 if there is a Waittimeout error
        subjectOfMeeting = -1
        while(subjectOfMeeting == -1):
            self.speaker.say("Please say what you want to remember at this date")
            subjectOfMeeting = self.listener.listen()
            print(subjectOfMeeting)
        return subjectOfMeeting
    
    
    def saveNewMeeting(self, dateOfMeeting, subjectOfMeeting):
        currentJsonData = self.meetingJsonFile.getData()
        dateOfMeetingInString = dateOfMeeting.strftime(self.dateFormat)

        if dateOfMeetingInString not in currentJsonData:
            currentJsonData[dateOfMeetingInString] = subjectOfMeeting
        else:
            currentMeetingsForDate = currentJsonData[dateOfMeetingInString]
            currentJsonData[dateOfMeetingInString] = currentMeetingsForDate + " and you also have " + subjectOfMeeting
        
        with open(Constants.MEETING_FILENAME, 'w+') as file:
            json.dump(currentJsonData, file, ensure_ascii=False)
                
        self.speaker.say("Meeting successfully saved")
        
        
    def executeCommand(self):
        
        self.speaker.say("Let's save a meeting!")
        
        dateOfMeeting = self.getMeetingDateFromUser()

        subjectOfMeeting = self.getMeetingSubjectFromUser()
        
        self.saveNewMeeting(dateOfMeeting, subjectOfMeeting)