Skip to content

Commit 786ad58

Browse files
authored
v0.7.0
- Возможность подключения сторонних навыков. - Изменён навык плеера. - Отдельный загрузчик для "старых" навыков. - Пример "нового" навыка - Hello, World. - Оптимизация кода. - Изменён навык скриншота для Андроид.
1 parent 665cf1e commit 786ad58

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+642
-313
lines changed

main.py

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
#!/usr/bin/env python3
2+
# -*- coding: utf-8 -*-
3+
4+
# GUI
5+
from .ui import design
6+
from PyQt5 import QtWidgets
7+
import sys
8+
from qt_material import apply_stylesheet
9+
10+
# Core
11+
from .core import (speak, talk, recognise)
12+
import random
13+
14+
# Skills
15+
from .skills import (skill_loader, time_date, exit, joke, weather, music, open, screenshot, search, poweroff, ytvideo,
16+
resay, map, wiki, location, weather_no_city, translate, news, coin, upd_upg, shoplist, todolist,
17+
netconnection, record, guess_num, rulette, math, audio, crystal_ball, random_num, timer,
18+
show_about, show_settings, old_skills)
19+
20+
21+
# Ответы на неизвестную команду.
22+
wrong = ("Прости, я тебя не понимаю.", "Мне кажется ты несёшь какой-то бред.", "Что?",
23+
"Ты, наверное, ошибаешься. Я тебя не понимаю.",
24+
"Извини, я появился совсем недавно, я пока понимаю очень мало слов.",
25+
"Чего?", "А? Что? Я тебя не понимаю.", "Пожалуйста, не говори слов, которых я незнаю.",
26+
"Ты пытаешься оскорбить меня этим?", "Не издевайся надо мной, я знаю не так много слов.",
27+
"Извини, я не могу тебя понять.", "А?", "Объясни попроще.",
28+
"Пожалуйста, прочитай моё описание. Скорее всего я не умею делать то, что ты меня просишь или попробуй использовать синонимы.",
29+
"Ты ошибаешься.", "Я не понимаю твоего вопроса.", "Мне не понятен твой вопрос.",
30+
"Не могу понять о чём ты говоришь.", "Я не понимаю.", "О чём ты?", "Я не могу распознать вопрос.")
31+
32+
randnum = -1
33+
isGuessNum = False
34+
isRuLette = False
35+
36+
37+
class Main(QtWidgets.QMainWindow, design.Ui_MainWindow):
38+
def __init__(self):
39+
# Инициализация графического интерфейса
40+
super().__init__()
41+
self.setupUi(self)
42+
43+
self.lineEdit.setFocus()
44+
# Передача информации, которую нужно озвучить и вывести на экран, модулю speak
45+
speak.speak("Привет, меня зовут Васисуалий. Чем могу быть полезен?", self.listWidget)
46+
47+
skill_loader.load() # Импорт "новых" навыков
48+
49+
self.lineEdit.editingFinished.connect(self.vasmsg)
50+
self.pushButton.clicked.connect(self.recogniser)
51+
self.aboutMenu.triggered.connect(self.showAboutDialog)
52+
self.settingsMenu.triggered.connect(self.showSettingsDialog)
53+
54+
def showAboutDialog(self):
55+
self.dialog = show_about.ShowAboutWindow()
56+
self.dialog.show()
57+
58+
def showSettingsDialog(self):
59+
self.dialog = show_settings.ShowSettingsWindow()
60+
self.dialog.show()
61+
62+
def vasmsg(self):
63+
# Функция берёт переданный в виджет lineEdit текст, очищает виджет и запускает программу
64+
self.say = self.lineEdit.text()
65+
self.lineEdit.clear()
66+
self.listWidget.scrollToBottom()
67+
self.say = self.say.capitalize()
68+
self.program()
69+
70+
def recogniser(self):
71+
self.say = recognise.recognise(self, self.listWidget) # Вызов функции распознавания речи
72+
self.program()
73+
74+
def program(self):
75+
say = self.say
76+
skillUse = False
77+
78+
if say == '' or say == ' ':
79+
pass
80+
else:
81+
# Вывод сообщения пользователя
82+
item = QtWidgets.QListWidgetItem(say)
83+
item.setTextAlignment(0x0002)
84+
self.listWidget.addItem(item)
85+
86+
if old_skills.old_skills_activate(say, self.listWidget, self):
87+
skillUse = True
88+
89+
elif guess_num.isTriggered(say):
90+
skillUse = True
91+
global randnum, isGuessNum
92+
randnum = guess_num.getRandomNum()
93+
isGuessNum = guess_num.startGame(self.listWidget)
94+
95+
elif rulette.isTriggered(say):
96+
skillUse = True
97+
global isRuLette
98+
isRuLette = rulette.startGame(self.listWidget)
99+
100+
elif skill_loader.run_skills(say, self.listWidget):
101+
skillUse = True
102+
103+
elif say == 'stop' or say == 'Stop' or say == 'Стоп' or say == 'стоп':
104+
speak.tts_d.stop()
105+
106+
elif isGuessNum:
107+
isGuessNum = guess_num.game(say, randnum, self.listWidget)
108+
109+
elif isRuLette:
110+
isRuLette = rulette.game(say, self.listWidget)
111+
112+
else:
113+
if talk.talk(say) != "" and not skillUse:
114+
speak.speak(talk.talk(say), self.listWidget)
115+
elif not skillUse:
116+
if say != "":
117+
# Фразы для ответа на несуществующие команды
118+
randwrong = random.choice(wrong)
119+
speak.speak(randwrong, self.listWidget)
120+
121+
122+
def main():
123+
app = QtWidgets.QApplication(sys.argv)
124+
window = Main()
125+
apply_stylesheet(app, theme='dark_red.xml')
126+
window.show()
127+
app.exec_()
128+
speak.tts_d.close()
129+
130+
131+
if __name__ == '__main__':
132+
main()

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
setup(
99
name='Vasisualy',
1010

11-
version='0.6.5',
11+
version='0.7.0',
1212

1313
description='Russian voice assistant for GNU/Linux.',
1414

vasisualy/core/recognise.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,16 @@
22
import speech_recognition
33
from PyQt5 import QtGui
44

5-
def recognise(cls, widget):
6-
mic_on = QtGui.QIcon.fromTheme("mic-on") # Иконка для состояния распознавания речи
7-
mic_off = QtGui.QIcon.fromTheme("mic-off") # Иконка для состояния покоя
8-
cls.pushButton.setIcon(mic_on) # Установка иконки во время распознавания речи
5+
6+
def recognise(_cls, widget):
7+
'''Распознаёт речь пользователя.
8+
:param _cls: класс UI
9+
:param widget: виджет, в который выводятся сообщения об ошибках
10+
:return: возвращает распознанный текст
11+
'''
12+
mic_on = QtGui.QIcon.fromTheme("mic-on") # Иконка для состояния распознавания речи
13+
mic_off = QtGui.QIcon.fromTheme("mic-off") # Иконка для состояния покоя
14+
_cls.pushButton.setIcon(mic_on) # Установка иконки во время распознавания речи
915

1016
# Настройки распознавания речи
1117
recognizer = speech_recognition.Recognizer()
@@ -15,7 +21,7 @@ def recognise(cls, widget):
1521
print("[sys] Говорите...")
1622

1723
with mph as source:
18-
say = recognizer.listen(source) # Прослушка микрофона
24+
say = recognizer.listen(source) # Прослушка микрофона
1925

2026
print("[sys] Речь распознаётся...")
2127

@@ -28,5 +34,5 @@ def recognise(cls, widget):
2834
say = ''
2935
print("[sys] Не удалось распознать речь. Нет подключения к интернету или не подключен микрофон.")
3036
speak.speak("Речь не распознана.", widget)
31-
cls.pushButton.setIcon(mic_off) # Установка иконки спокойствия
37+
_cls.pushButton.setIcon(mic_off) # Установка иконки спокойствия
3238
return say

vasisualy/core/speak.py

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,37 @@
11
import speechd
2-
from ..ui import design
3-
from PyQt5 import QtWidgets
2+
from . import defaults
3+
import os
44

55
# Настройка синтезатора речи
66
tts_d = speechd.SSIPClient('Vasisya')
77
tts_d.set_output_module('rhvoice')
88
tts_d.set_language('ru')
9-
tts_d.set_synthesis_voice('Artemiy')
10-
tts_d.set_rate(30)
9+
try:
10+
appDir = os.path.dirname(os.path.realpath(__file__))
11+
os.chdir(f"{appDir}/../../")
12+
config = open("vasisualy.conf", "r")
13+
for line in config:
14+
if "voice:" in line:
15+
voice = line.replace("voice:", "")
16+
elif "speed:" in line:
17+
speed = int(line.replace("speed:", ""))
18+
elif "pitch:" in line:
19+
pitch = int(line.replace("pitch:", ""))
20+
except Exception:
21+
voice = defaults.defaults["voice"]
22+
speed = defaults.defaults["speed"]
23+
pitch = defaults.defaults["pitch"]
24+
25+
tts_d.set_synthesis_voice(voice)
26+
tts_d.set_rate(speed)
1127
tts_d.set_punctuation(speechd.PunctuationMode.NONE)
12-
tts_d.set_pitch(0)
28+
tts_d.set_pitch(pitch)
1329

14-
def speak(string, widget):
15-
tts_d.speak(string) # Озвучка переданного сообщения с помощью синтеза речи
16-
widget.addItem(string) # Вывод переданного сообщения в графический интерфейс
17-
widget.scrollToBottom() # Прокрутка виджета с сообщениями до конца
30+
def speak(message, widget):
31+
'''Выводит сообщение пользователю и озвучивает его.
32+
:param message: сообщение, которое нужно вывести и озвучить (string).
33+
:param widget: виджет, в который нужно вывести сообщение (QWidget).
34+
'''
35+
tts_d.speak(message) # Озвучка переданного сообщения с помощью синтеза речи
36+
widget.addItem(message) # Вывод переданного сообщения в графический интерфейс
37+
widget.scrollToBottom() # Прокрутка виджета с сообщениями до конца

0 commit comments

Comments
 (0)