Delete main.py

This commit is contained in:
Ninnjah 2021-01-02 16:17:04 +03:00 committed by GitHub
parent da8ea99ed6
commit bcd72f473c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

522
main.py
View file

@ -1,522 +0,0 @@
import os
import sys
import json
from time import time
import threading
import soundfile as sf
import sounddevice as sd
from pynput.keyboard import Listener
from PyQt5 import QtWidgets, QtGui, QtCore
from PyQt5.QtCore import QFile, QTextStream
from PyQt5.QtWidgets import QApplication
import ui_preferences
import ui_hotkeys
import ui_sundpood
import ui_overlay
import themes
import keys
###! UI !###
class OverlayUi(QtWidgets.QMainWindow, ui_overlay.Ui_MainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.WindowStaysOnTopHint)
self.setGeometry(QtCore.QRect(0, 0, 250, 20))
self.setupUi(self)
def keyPressEvent(self, e):
if e.key() == QtCore.Qt.Key_F1:
self.hide()
win.show()
class PreferencesUi(QtWidgets.QMainWindow, ui_preferences.Ui_MainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
self.setupUi(self)
def mousePressEvent(self, event):
self.offset = event.pos()
def mouseMoveEvent(self, event):
x = event.globalX()
y = event.globalY()
x_w = self.offset.x()
y_w = self.offset.y()
self.move(x-x_w, y-y_w)
class HotkeysUi(QtWidgets.QMainWindow, ui_hotkeys.Ui_MainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
self.setupUi(self)
def mousePressEvent(self, event):
self.offset = event.pos()
def mouseMoveEvent(self, event):
x = event.globalX()
y = event.globalY()
x_w = self.offset.x()
y_w = self.offset.y()
self.move(x-x_w, y-y_w)
class MainUi(QtWidgets.QMainWindow, ui_sundpood.Ui_MainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
self.setupUi(self)
def mousePressEvent(self, event):
self.offset = event.pos()
def mouseMoveEvent(self, event):
x = event.globalX()
y = event.globalY()
x_w = self.offset.x()
y_w = self.offset.y()
self.move(x-x_w, y-y_w)
def keyPressEvent(self, e):
if e.key() == QtCore.Qt.Key_F1:
pref.close()
self.hide()
over.show()
def closeEvent(self, event):
hotk.close()
pref.close()
###! JSON !###
def jsonread(file):
'''
Чтение JSON файла file
file - имя JSON файла, может содержать полный или относительный путь
'''
with open(file, "r", encoding='utf-8') as read_file:
data = json.load(read_file)
return data
def jsonwrite(file, data):
'''
Запись в JSON файл file данные data
file - имя JSON файла, может содержать полный или относительный путь
data - данные, может быть словарем/списком/кортежем/строкой/числом
'''
with open(file, 'w', encoding='utf-8') as write_file:
write_file.write(json.dumps(data))
###! FUNCTIONS !###
def toggle_stylesheet(path):
'''
Toggle the stylesheet to use the desired path in the Qt resource
system (prefixed by `:/`) or generically (a path to a file on
system).
:path: A full path to a resource or file on system
'''
# get the QApplication instance, or crash if not set
app = QApplication.instance()
if app is None:
raise RuntimeError("No Qt Application found.")
path = os.path.join('themes', path)
file = QFile(path)
file.open(QFile.ReadOnly | QFile.Text)
stream = QTextStream(file)
theme = stream.readAll()
pref.setStyleSheet(theme)
win.setStyleSheet(theme)
hotk.setStyleSheet(theme)
save()
def find_device():
'''
Ищем устройство device и возвращаем его индекс
'''
list_ = list(sd.query_devices()) # Список устройств вывода звука
device = 'VoiceMeeter Input' # Имя искомого устройства
msg = QtWidgets.QMessageBox() # Окно ошибки (Устройство не найдено)
msg.setIcon(QtWidgets.QMessageBox.Critical)
msg.setText("You don't install VoiceMeeter")
msg.setInformativeText('install VoiceMetter from "redist" folder or download it from \nvb-audio.com/Voicemeeter')
msg.setWindowTitle('Error')
for i in list_:
if device in i['name']:
return i['name']
msg.exec_()
exit()
def sound_convert(dir_, format_):
'''
Конвертация файла name в папке path в формат format_
по средством ffmpeg.exe
path - папка с файлом, может содержать полный или относительный путь
name - название файла, может только название файла
format_ - формат в который нужно конвертировать
'''
if os.path.exists('ffmpeg.exe'):
path, name = os.path.split(dir_)
old_name = name
if os.path.splitext(dir_)[1] in ['.mp3', '.m4a']:
name = os.path.splitext(name)[0] + format_
os.system(f'ffmpeg.exe -i "{os.path.join(path, old_name)}" "play.wav" -hide_banner -y')
return "play.wav"
else:
return dir_
def get_files(dir_, config):
'''
Сбор всех аудифайлов
dir_ - Путь к папке со звуками
config - Имя файла настроек
'''
msg = QtWidgets.QMessageBox() # Окно ошибки (Не найдены файлы в папке 'sound')
msg.setIcon(QtWidgets.QMessageBox.Critical)
msg.setText("You don't have any sounds in 'sound' folder")
msg.setInformativeText('download sound in .wav / .mp3 / .m4a format')
msg.setWindowTitle('Error')
ffmsg = QtWidgets.QMessageBox() # Окно ошибки (Не найден ffmpeg.exe)
ffmsg.setIcon(QtWidgets.QMessageBox.Critical)
ffmsg.setText("You don't have ffmpeg.exe in the program root folder")
ffmsg.setInformativeText('download ffmpeg from ffmpeg.org for converting sound files')
ffmsg.setWindowTitle('Error')
if os.path.exists(dir_):
if len(os.listdir(dir_)) == 0:
msg.exec_()
sounds = [] # Все аудио файлы
sounds_list = [f'{dir_}\\'] # Начальная категория
if not os.path.exists('ffmpeg.exe'):
ffmsg.exec_()
exit()
for i in os.listdir(dir_):
if os.path.isfile(os.path.join(dir_, i)):
name = os.path.join(dir_, i)
if name == None:
sounds_list.append(i)
elif os.path.splitext(i)[1] in ['.mp3', '.m4a', '.wav']:
sounds_list.append(i)
else:
sounds_list_cat = [os.path.join(dir_, i)]
for x in os.listdir(os.path.join(dir_, i)):
if os.path.isfile(os.path.join(dir_, i, x)):
if name == None:
sounds_list_cat.append(x)
elif os.path.splitext(x)[1] in ['.mp3', '.m4a', '.wav']:
sounds_list_cat.append(x)
sounds.append(sounds_list_cat)
sounds.append(sounds_list)
if os.path.exists(config):
hotkeys = jsonread(config)['hotkeys']
KEYS_CMD = jsonread(config)['KEYS_CMD']
sounds_list = { 'hotkeys':hotkeys,
'sounds':sounds,
'Theme':'None',
'KEYS_CMD':KEYS_CMD}
else:
sounds_list = { 'hotkeys':{},
'sounds':sounds,
'Theme':'None',
'KEYS_CMD':{
'select_move_up' :' ',# вверх
'select_move_down' :' ',# вниз
'select_move_left' :' ',# влево
'select_move_right' :' ',# вправо
'play_sound' :' ',# Играть
'stop_sound' :' ',# Остановить
}}
jsonwrite(config, sounds_list)
else:
sounds_list = { 'hotkeys':{},
'sounds':'',
'Theme':'None',
'KEYS_CMD':{
'select_move_up' :' ',# вверх
'select_move_down' :' ',# вниз
'select_move_left' :' ',# влево
'select_move_right' :' ',# вправо
'play_sound' :' ',# Играть
'stop_sound' :' ',# Остановить
}}
jsonwrite(config, sounds_list)
os.mkdir(dir_)
msg.exec_()
def play_sound(*argv):
if False in argv:
try:
sound = os.path.join(win.soundList.item(0).text(),
win.soundList.currentItem().text())
except AttributeError:
return False
else:
sound = argv[0]
try:
sound = sound_convert(sound, '.wav')
data, fs = sf.read(sound, dtype='float32')
sd.play(data, fs)
#os.remove(sound)
except RuntimeError:
pass
def cat_select(cat):
win.soundList.clear()
for i in menu:
if cat == i[0]:
win.soundList.addItems(i)
def hotkey_remap():
'''
Переназначение хоткея
btn - индекс кнопки хоткея в списке HOTKEYS
'''
def check(key):
key = str(key).replace("'",'')
try:
sound = os.path.join(win.soundList.item(0).text(),
win.soundList.currentItem().text())
except AttributeError:
win.hkset.setEnabled(True)
return False
if key not in keys.forbidden:
hotkeys.update({key:sound})
elif key == 'Key.backspace':
del hotkeys[find_key(hotkeys, sound)]
save()
hotk.hotkeyList.clear()
for i in sound_get_dict['sounds']:
for x in i:
x = os.path.join(i[0], x)
if x in hotkeys.values():
hotk.hotkeyList.addItem(f'{find_key(hotkeys, x)}\t:{x}')
win.hkset.setEnabled(True)
return False
win.hkset.setEnabled(False)
hotkey_remap_Listener = Listener(
on_release=check)
hotkey_remap_Listener.start()
def hotkey_delete():
key = hotk.hotkeyList.currentItem().text().split(':')[0].replace('\t', '')
hotkeys.pop(key)
save()
hotk.hotkeyList.clear()
for i in sound_get_dict['sounds']:
for x in i:
x = os.path.join(i[0], x)
if x in hotkeys.values():
hotk.hotkeyList.addItem(f'{find_key(hotkeys, x)}\t:{x}')
def pref_remap(btn, func_):
'''
Переназначение клавиши в окно Preference
btn - PyQt5 кнопка
func_ - строковое значени функции из словаря KEYS_CMD
'''
def check(key):
'''
Проверка кнопки btn на не участие
в списке запрещенных клавиш keys.forbidden
если это клавиша 'Key.backspace' то стираем значение
key - pynput код клавиши
'''
key = str(key).replace("'",'')
if key not in keys.forbidden:
KEYS_CMD.update({find_key(COMMAND_DICT, func_) : key})
btn.setText(keys.dict_[key])
elif key == 'Key.backspace':
KEYS_CMD.update({find_key(COMMAND_DICT, func_) : ' '})
btn.setText(' ')
for i in PREF_BTN:
i.setEnabled(True)
save()
return False
for i in PREF_BTN:
i.setEnabled(False)
hotkey_remap_Listener = Listener(
on_release=check)
hotkey_remap_Listener.start()
def find_key(dict, val):
'''
Поиск ключа в словаре dict по значению val
dict - словарь
val - значение
'''
return next((key for key, value in dict.items() if value == val), None)
def save():
'''
Сохранение настроек оверлея и глобальных хоткеев
'''
sounds = jsonread(config)['sounds']# Все аудиофайлы
KEYS_JSON = {} # Настроенные клавиши
for i in KEYS_CMD.keys():
KEYS_JSON.setdefault(COMMAND_DICT[i], KEYS_CMD[i])
theme = pref.themesList.currentItem().text()
sounds_list = {'sounds':sounds, 'hotkeys':hotkeys, 'Theme':theme, 'KEYS_CMD':KEYS_JSON}
jsonwrite(config, sounds_list)
###! CONTROL !###
def select_move(mode):
'''
Перемешение по оверлейному меню
mode - кортеж из двух цифр
(смещение по категории, смещение по списку)
'''
select[0] += mode[0] # Категории
select[1] += mode[1] # Файлы в категории
if select[0] > len(menu)-1 or select[0] < -len(menu)+1:
select[0] = 0
if select[1] > len(menu[select[0]])-1 or select[1] < -len(menu[select[0]])+1:
select[1] = 0
if mode[0] != 0:
select[1] = 0
over.label.setText(menu[select[0]][select[1]])
win.select_label.setText(menu[select[0]][select[1]])
def key_check(key):
key = str(key).replace("'",'') # Преобразование кода в строку
key_n = '' # Переведенное значение клавиши
try:
key_n = keys.dict_[key]
except KeyError:
pass
if key in hotkeys.keys():
play_sound(hotkeys[key])
elif key in KEYS_CMD.values():
find_key(KEYS_CMD, key)()
def main():
key_check_Listener = Listener(
on_release=key_check)
key_check_Listener.start()
win.exit_button.clicked.connect(win.close)
win.min_button.clicked.connect(win.showMinimized)
pref.exit_button.clicked.connect(pref.close)
pref.min_button.clicked.connect(pref.showMinimized)
hotk.exit_button.clicked.connect(hotk.close)
hotk.min_button.clicked.connect(hotk.showMinimized)
win.hkset.clicked.connect(hotkey_remap)
win.pref_button.clicked.connect(pref.show)
win.hotkeys_button.clicked.connect(hotk.show)
win.catList.currentTextChanged.connect(cat_select)
win.stop_button.clicked.connect(lambda: sd.stop())
win.play_button.clicked.connect(play_sound)
pref.play_sound.clicked.connect(
lambda: pref_remap(pref.play_sound, 'play_sound'))
pref.stop_sound.clicked.connect(
lambda: pref_remap(pref.stop_sound, 'stop_sound'))
pref.select_move_up.clicked.connect(
lambda: pref_remap(pref.select_move_up, 'select_move_up'))
pref.select_move_down.clicked.connect(
lambda: pref_remap(pref.select_move_down, 'select_move_down'))
pref.select_move_left.clicked.connect(
lambda: pref_remap(pref.select_move_left, 'select_move_left'))
pref.select_move_right.clicked.connect(
lambda: pref_remap(pref.select_move_right, 'select_move_right'))
pref.themesList.currentTextChanged.connect(toggle_stylesheet)
hotk.delete_button.clicked.connect(hotkey_delete)
win.show()
if __name__ == '__main__':
### Создание окна ###
app = QApplication([]) # Приложение
over = OverlayUi() # Окно оверлея
pref = PreferencesUi() # Окно настроек
hotk = HotkeysUi() # Окно хоткеев
win = MainUi() # Основное окно
PREF_BTN = [ # Список кнопок настроек клавиш в pref
pref.select_move_up,
pref.select_move_down,
pref.select_move_left,
pref.select_move_right,
pref.play_sound,
pref.stop_sound,]
### Поиск устроства ввода ###
sd.default.device = find_device() # Установка устройства вывода по умолчанию
### Глобальные переменные ###
dir_ = 'sound'
config = 'settings.json'
get_files(dir_, config) # Сбор всех аудиофайлов
sound_get_dict = jsonread(config) # Загрузка данных
hotkeys = sound_get_dict['hotkeys'] # Загрузка словаря хоткеев
theme = sound_get_dict['Theme'] # Загрузка темы
menu = sound_get_dict['sounds'] # Загрузка оверлейного меню
select = [0, 0] # Установка курсора оверлея в нулевую позицию
if theme != 'None':
toggle_stylesheet(theme)
pref.themesList.addItems(os.listdir('themes'))
for i in sound_get_dict['sounds']:
win.catList.addItem(i[0])
for x in i:
x = os.path.join(i[0], x)
if x in hotkeys.values():
hotk.hotkeyList.addItem(f'{find_key(hotkeys, x)}\t: {x}')
COMMAND_DICT = { # Словарь функций к строковому значению
lambda: select_move((0, -1)):'select_move_up', # вверх
lambda: select_move((0, 1)) :'select_move_down', # вниз
lambda: select_move((-1, 0)):'select_move_left', # влево
lambda: select_move((1, 0)) :'select_move_right', # вправо
lambda: play_sound(os.path.join(menu[select[0]][0],
menu[select[0]][select[1]])):'play_sound', # Играть
lambda: sd.stop() :'stop_sound', # Остановить
}
KEYS_JSON = sound_get_dict['KEYS_CMD']# Загрузка настроенных клавиш
KEYS_CMD = COMMAND_DICT.copy() # Настроенные клавиши
### Установка настроенных клавиш ###
for i in KEYS_CMD.keys():
KEYS_CMD.update({i:KEYS_JSON[COMMAND_DICT[i]]})
KEYS_JSON = None
combo = 0
for i in KEYS_CMD.values():
PREF_BTN[combo].setText(keys.dict_[i])
combo += 1
main()
sys.exit(app.exec())