-
Notifications
You must be signed in to change notification settings - Fork 0
/
bot.py
131 lines (100 loc) · 3.9 KB
/
bot.py
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
import os
import webbrowser
import subprocess
from gtts import gTTS
from playsound import playsound
import speech_recognition as sr
# Default audio file name.
AUDIO_FILE = 'audio.mp3'
# Command prefix. You can define your function with this prefix and it will count as a command.
COMMAND_PREFIX = 'command_'
# Searching platform urls.
URLS = {
'google': 'https://www.google.com/search?q={}',
'github': 'https://github.com/search?q={}',
'youtube': 'https://www.youtube.com/results?search_query={}'
}
# Bot speechs.
AVAILABLE_COMMANDS = 'Available commands are {}.'
EXAMPLE_COMMANDS = 'For example you can say the word "Search" for details, or "Search Amazon on Google" for a quick search.'
ASK_COMMAND = 'What is your command?'
INVALID_COMMAND = 'Invalid command received.'
AVAILABLE_PLATFORMS = 'Available platforms are {}.'
ASK_SEARCH = 'What would you like to search on which platform?'
INVALID_PLATFORM = 'Invalid platform received.'
ASK_OPEN = 'What would you like to open?'
class Bot:
def _speak(self, text):
# Converts text to speech.
tts = gTTS(text)
# Saves speech as mp3.
tts.save(AUDIO_FILE)
# Plays speech.
playsound(AUDIO_FILE)
# Deletes created mp3 file.
os.remove(AUDIO_FILE)
def speak(self, *args):
# Supports multiple arguments.
self._speak(' '.join(args))
def listen(self) -> str:
# Creates `Recognizer` object.
rec = sr.Recognizer()
# Listens microphone.
with sr.Microphone() as mic:
audio = rec.listen(mic)
# Converts speech to text.
return rec.recognize_google(audio).lower()
def get_commands(self):
# Looks for each attribute and yields if callable starts with `COMMAND_PREFIX`.
for name, func in self.__class__.__dict__.items():
if callable(func) and name.startswith(COMMAND_PREFIX):
yield name.replace(COMMAND_PREFIX, '')
def command_search(self, speech: list[str]):
# If there is no speech, takes input from user.
if not speech:
# Gives information about search command.
self.speak(
AVAILABLE_PLATFORMS.format(', '.join(URLS.keys())),
ASK_SEARCH
)
# Listens and splits given input to words.
speech = self.listen().split()
# Fetches platform from splitted words.
platform = speech[-1]
# Gets related url of platform.
url = URLS.get(platform)
# If there is no such a platform, returns invalid.
if url is None:
return self.speak(INVALID_PLATFORM)
# Converts splitted speech to string.
query = ' '.join(speech)
# Removes "on platform_name" from string.
query = query.replace(f'on {platform}', '')
# Opens related url with given query.
return webbrowser.open(url.format(query))
def command_open(self, speech: list[str]):
# If there is no speech, takes input from user.
if not speech:
# Asks what to open.
self.speak(ASK_OPEN)
# Listens what to open.
speech = self.listen()
# Tries to open what you asked for.
return subprocess.Popen(speech)
def take_command(self):
# Says available commands.
self.speak(
AVAILABLE_COMMANDS.format(', '.join(self.get_commands())),
EXAMPLE_COMMANDS,
ASK_COMMAND
)
# Listens and splits given input to words.
speech = self.listen().split()
# Extracts command from speech.
command = speech.pop(0)
# Checks if command is valid.
if not command in self.get_commands():
return self.speak(INVALID_COMMAND)
# Runs related function for command.
func = getattr(self, COMMAND_PREFIX + command)
return func(speech)