Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from tkinter import *
- from tkinter.ttk import Combobox # импортируем только то что надо
- from tkinter import messagebox
- import json, os, time, copy, ctypes, subprocess, psutil
- import keyboard as keyb
- from selenium import webdriver
- from selenium.webdriver.common.keys import Keys
- from selenium.webdriver.chrome.options import Options
- from selenium.webdriver.chrome.service import Service
- from threading import *
- import pydirectinput as pyinput
- from deepdiff import DeepDiff
- data = "settings for voice control in the game.json" # файл настроек.
- KEYS = {"LBUTTON": 0x01, "RBUTTON": 0x02, "WHEEL_MOUSE_BUTTON": 0x03, "MBUTTON": 0x04, "XBUTTON1": 0x05,
- "XBUTTON2": 0x06, "BACK": 0x08, "TAB": 0x09, "CLEAR": 0x0C, "RETURN": 0x0D,
- "SHIFT": 0x10, "CONTROL": 0x11, "MENU": 0x12, "PAUSE": 0x13, "CAPITAL": 0x14,
- "KANA": 0x15, "JUNJA": 0x17, "FINAL": 0x18, "KANJI": 0x19, "ESCAPE": 0x1B,
- "CONVERT": 0x1C, "NONCONVERT": 0x1D, "ACCEPT": 0x1E, "MODECHANGE": 0x1F, "SPACE": 0x20,
- "PRIOR": 0x21, "NEXT": 0x22, "END": 0x23, "HOME": 0x24, "LEFT": 0x25, "UP": 0x26,
- "RIGHT": 0x27, "DOWN": 0x28, "SELECT": 0x29, "PRINT": 0x2A, "EXECUTE": 0x2B,
- "SNAPSHOT": 0x2C, "INSERT": 0x2D, "DELETE": 0x2E, "HELP": 0x2F, "KEY0": 0x30,
- "KEY1": 0x31, "KEY2": 0x32, "KEY3": 0x33, "KEY4": 0x34, "KEY5": 0x35, "KEY6": 0x36,
- "key7": 0x37, "KEY8": 0x38, "KEY9": 0x39, "A": 0x41, "B": 0x42, "C": 0x43, "D": 0x44,
- "E": 0x45, "F": 0x46, "G": 0x47, "H": 0x48, "I": 0x49,
- "J": 0x4A, "K": 0x4B, "L": 0x4C, "M": 0x4D, "N": 0x4E, "O": 0x4F, "P": 0x50, "Q": 0x51, "R": 0x52,
- "S": 0x53, "T": 0x54, "U": 0x55, "V": 0x56, "W": 0x57, "X": 0x58, "Y": 0x59,
- "Z": 0x5A, "LWIN": 0x5B, "RWIN": 0x5C, "APPS": 0x5D, "SLEEP": 0x5F, "NUMPAD0": 0x60, "NUMPAD1": 0x61,
- "NUMPAD2": 0x62, "NUMPAD3": 0x63, "NUMPAD4": 0x64, "NUMPAD5": 0x65,
- "NUMPAD6": 0x66, "NUMPAD7": 0x67, "NUMPAD8": 0x68, "NUMPAD9": 0x69, "MULTIPLY": 0x6A, "ADD": 0x6B,
- "SEPARATOR": 0x6C, "SUBTRACT": 0x6D, "DECIMAL": 0x6E, "DIVIDE": 0x6F, "F1": 0x70, "F2": 0x71,
- "F3": 0x72, "F4": 0x73, "F5": 0x74, "F6": 0x75, "F7": 0x76, "F8": 0x77, "F9": 0x78, "F10": 0x79,
- "F11": 0x7A, "F12": 0x7B, "F13": 0x7C, "F14": 0x7D,
- "F15": 0x7E, "F16": 0x7F, "F17": 0x80, "F18": 0x81, "F19": 0x82, "F20": 0x83, "F21": 0x84,
- "F22": 0x85, "F23": 0x86, "F24": 0x87, "NUMLOCK": 0x90, "SCROLL": 0x91, "OEM_FJ_JISHO": 0x92, "OEM_FJ_MASSHOU": 0x93,
- "OEM_FJ_TOUROKU": 0x94, "OEM_FJ_LOYA": 0x95, "OEM_FJ_ROYA": 0x96, "LSHIFT": 0xA0, "RSHIFT": 0xA1, "LCONTROL": 0xA2,
- "RCONTROL": 0xA3, "LMENU": 0xA4, "RMENU": 0xA5, "BROWSER_BACK": 0xA6,
- "BROWSER_FORWARD": 0xA7, "BROWSER_REFRESH": 0xA8, "BROWSER_STOP": 0xA9, "BROWSER_SEARCH": 0xAA, "BROWSER_FAVORITES": 0xAB, "BROWSER_HOME": 0xAC, "VOLUME_MUTE": 0xAD, "VOLUME_DOWN": 0xAE,
- "VOLUME_UP": 0xAF, "MEDIA_NEXT_TRACK": 0xB0, "MEDIA_PREV_TRACK": 0xB1, "MEDIA_STOP": 0xB2, "MEDIA_PLAY_PAUSE": 0xB3, "LAUNCH_MAIL": 0xB4, "LAUNCH_MEDIA_SELECT": 0xB5, "LAUNCH_APP1": 0xB6,
- "LAUNCH_APP2": 0xB7, "OEM_1": 0xBA, "OEM_PLUS": 0xBB, "OEM_COMMA": 0xBC, "OEM_MINUS": 0xBD, "OEM_PERIOD": 0xBE, " OEM_2": 0xBF, "OEM_3": 0xC0, "ABNT_C1": 0xC1, "ABNT_C2": 0xC2, "OEM_4": 0xDB, "OEM_5": 0xDC, "OEM_6": 0xDD, "OEM_7": 0xDE, "OEM_8": 0xDF, "OEM_AX": 0xE1,
- "OEM_102": 0xE2, "ICO_HELP": 0xE3, "PROCESSKEY": 0xE5, "ICO_CLEAR": 0xE6, "PACKET": 0xE7, "OEM_RESET": 0xE9, "OEM_JUMP": 0xEA, "OEM_PA1": 0xEB, "OEM_PA2": 0xEC, "OEM_PA3": 0xED,
- "OEM_WSCTRL": 0xEE, "OEM_CUSEL": 0xEF, "OEM_ATTN": 0xF0, "OEM_FINISH": 0xF1, "OEM_COPY": 0xF2, "OEM_AUTO": 0xF3, "OEM_ENLW": 0xF4, "OEM_BACKTAB": 0xF5, "ATTN": 0xF6, "CRSEL": 0xF7, "EXSEL": 0xF8, " EREOF": 0xF9, "PLAY": 0xFA, "ZOOM": 0xFB, "PA1": 0xFD, " OEM_CLEAR": 0xFE
- }
- def check(driver):
- url = driver.current_url
- driver.implicitly_wait(3)
- try:
- return 0
- except Exception as ex:
- check(driver)
- class save_dict:
- def __init__(self):
- self.jnson = {}
- self.old_data = {}
- self.chrome_pid = 0# id процесса chrome
- self. chrome_processes = [] # список всех процессов Chrome
- self.driver=0
- def save_old_data(self, jnson):
- self.old_data= copy.deepcopy(jnson)
- def save_jnson(self, jn):
- self.jnson= jn
- def return_jnson(self):
- return self.jnson
- def return_old_data(self):
- return self.old_data
- def write_to_file(self, new_data):
- json_string = json.dumps(new_data, ensure_ascii=False, indent=2)
- with open(data, "w", encoding="cp1251") as w:
- w.write(json_string) # сохранить изменения в файле настроек.
- return self
- def find_chromedrive(self): # Поиск всех процессов Chrome
- for proc in psutil.process_iter():
- try:
- if 'chromedriver' in proc.name():
- self.chrome_processes.append(proc.pid)
- except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
- pass
- def define_chromedrive_id(self, driver):# определить id текущего chromedriver.
- self.driver=driver
- for proc in psutil.process_iter():
- try:
- if 'chromedriver' in proc.name() and proc.pid not in self.chrome_processes:
- self.chrome_pid=proc.pid
- except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
- pass
- def kill_chromedrive_id(self):
- if self.chrome_pid > 0:
- for proc in psutil.process_iter():
- if proc.pid ==self.chrome_processes:
- process = psutil.Process(proc.pid)
- process.terminate() # Завершение текущего id процесса chromedriver.
- # print(self.chrome_pid)
- if 'chrome' in proc.name():
- process = psutil.Process(proc.pid)
- process.terminate()
- # self.driver.close()
- # self.driver.quit()
- def prease_on_key(driver, d):
- timestamp = time.time()
- while 1:
- try:
- time.sleep(0.65)
- # driver.find_element("class","p_edit dir_LTR").clear() # удалить старый текст.
- text = driver.find_element("id", "speech-display").text
- text = str(text)
- if len(text) != 0 and text != None:
- text = str(text).lower()
- for key in d:
- word1=str(d[key])
- words=word1.rsplit(",")
- x=[ i.lstrip() for i in words]
- for word1 in x:
- word= str(word1).lower()
- if word == text:
- key1=key.upper()
- key2=KEYS[key1]
- driver.find_element("id", "mic").click()
- pyinput.keyDown(str(key1).replace("KEY","").lower())
- time.sleep(0.35)
- pyinput.keyUp(str(key1).replace("KEY","").lower())
- driver.find_element("id","mic").click()#
- timestamp = time.time()
- break
- if time.time() - timestamp > 10:
- # print(time.time())
- driver.find_element("id", "mic").click()
- time.sleep(0.35)
- driver.find_element("id","mic").click()#
- timestamp = time.time()
- except Exception as ex:
- # print(ex)
- pass
- def web():
- options = Options()
- home =r"C:\Program Files (x86)\Google\Chrome"
- options.add_argument("--use-fake-ui-for-media-stream")# звук
- options.add_experimental_option("excludeSwitches", ['enable-automation']) # убрать окно
- options.binary_location = home +r"\Application\chrome.exe"
- options.add_argument(r"--user-data-dir=C:\Users\egor\AppData\Local\Google\Chrome\User Data")
- options.add_argument("--disable-extensions") # отключить расширения.
- dict_save.find_chromedrive() # Поиск всех процессов Chrome
- try:
- s = Service(home + r'\chromedriver\chromedriver.exe')
- driver = webdriver.Chrome(service=s, options=options)
- driver.set_window_position(600, 650)
- driver.set_window_size(624, 368) # optiol
- dict_save.define_chromedrive_id(driver) # определить id текущего chromedriver.
- driver.get("https://www.speechtexter.com")# открыть сайт
- check(driver)
- driver.find_element("id", "mic").click() # включить запись голоса
- driver.minimize_window()
- return driver
- except Exception as ex:
- # print(ex)
- dict_save.kill_chromedrive_id()
- pass
- finally:
- pass
- # добавление нового элемента
- list_profiles = ["default"] # список профилей.
- def start_voice():
- user32 = ctypes.WinDLL('user32', use_last_error=True)
- curr_window = user32.GetForegroundWindow()
- thread_id = user32.GetWindowThreadProcessId(curr_window, 0)
- klid = user32.GetKeyboardLayout(thread_id)
- if klid == 68748313: # приключения на английский раскладку.
- keyb.press_and_release('win+space') # subprocess.run(["powershell.exe", "-Command", "& Set-WinUserLanguageList -LanguageList '+en-EN+' -Force}"])
- driver = web()# запуск браузер.
- d={}
- for i in range(len(arg)):
- value=(str(arg[i].get()))
- key= str(values[i].get())
- d[key]=value
- try:
- if key=="":
- messagebox.showerror("Erorr","key emrty")
- dict_save.kill_chromedrive_id()# Убить текущей процесс.
- break
- return
- if value == "":
- messagebox.showerror("Erorr", "Value emrty")
- dict_save.kill_chromedrive_id()# Убить текущей процесс.
- break
- return
- except Exception as ex:
- pass
- t1 = Thread(target = prease_on_key, args =(driver, d,))
- t1.start()
- def save_keys_and_values(event=0):
- d,d1={},{}
- d=dict_save.return_jnson()# старый словарь.
- d["last_pfofile"]=str(profile_current.get())
- d["start_startup"]=start_startup.get()
- d1=d["profiles"]
- d=d1[str(profile_current.get())]
- d.clear()
- for i in range(len(arg)):
- key = str(arg[i].get())
- value = str(values[i].get())
- d[key]=value# обновления словаря.
- d1[str(profile_current.get())]=d
- def on_close():
- dict_save.kill_chromedrive_id()# Убить текущей процесс.
- save_keys_and_values()
- old_data =dict_save.return_old_data()# старые значения настроек.
- new_data= dict_save.return_jnson() # новые значения настроек.
- d= old_data['profiles']
- n = new_data['profiles']
- diff = DeepDiff(d, n) # res=(dict(diff)) # print(new_data) # print(old_data)
- if new_data != old_data: # if old_data['profiles'] != new_data['profiles'] :
- if (messagebox.askokcancel("Quit", "Do you want to save the changes?")):
- dict_save.write_to_file(new_data)# записать настройки в файл.
- else:
- pass
- # else:
- # dict_save.write_to_file(new_data) # записать настройки в файл.
- root.destroy()
- # удаления записи и значения.
- def remove_box_and_entry(ent_arr, box_arr):
- if len(values)>0:
- r = len(arg)
- values[r-1].set("")
- arg[r-1].set("")
- ent_arr[r-1].destroy()
- box_arr[r-1].destroy()
- ent_arr.pop()
- box_arr.pop()
- values.pop()
- arg.pop()
- return ent_arr, box_arr
- else:
- return ent_arr, box_arr
- class iter_counter:
- def __init__(self):
- self._value = -1
- self.box_arr = []
- self.ent_arr = []
- def add_new_command(self, scrollable_frame, entry_value=0, box_value=0):
- self._value += 1
- value= self._value # print(value)
- a = list(KEYS.keys()), arg.append(StringVar()), values.append(StringVar())
- entry = Entry(scrollable_frame, width=25,textvariable=arg[value]) # текстовое поле и кнопка для добавления в список
- entry.grid(column=0, row=value+1, padx=10, pady=8, sticky=W)
- box = Combobox(scrollable_frame, width=12, textvariable=values[value], values=a[0])
- box.grid(column=1, row=value+1, padx=22, pady=0) # поле со списком
- key=str(profile_current.get())
- if entry_value != 0 and box_value != 0:
- arg[value].set(entry_value)
- values[value].set(box_value)
- else:
- arg[value].set("")
- values[value].set("")
- return self.ent_arr.append(entry), self.box_arr.append(box),self._value,
- def del_command(self):
- value = self._value
- ent_arr, box_arr= self.box_arr, self.ent_arr
- ent_arr, box_arr=remove_box_and_entry(ent_arr, box_arr)
- self._value -= 1
- return self._value, self.box_arr, self.ent_arr
- def remove_all_command(self, scrollable_frame):
- self._value=-1
- ent_arr, box_arr, value = self.box_arr, self.ent_arr, self._value
- for i in range(len(box_arr)):
- ent_arr, box_arr = remove_box_and_entry(ent_arr, box_arr)
- new.add_new_command(scrollable_frame)
- return self._value, self.box_arr, self.ent_arr
- def remove_all_command_without_adding(self):
- value = self._value
- ent_arr, box_arr= self.box_arr, self.ent_arr
- for i in range(len(box_arr)):
- ent_arr, box_arr = remove_box_and_entry(ent_arr, box_arr)
- self._value=-1
- return self._value, self.box_arr, self.ent_arr
- def filling_fields(dict_save, last_pfofile):# Заполнения полей.
- d=dict_save.return_jnson()# получить словарь со всеми значениями.
- d=d["profiles"]
- for k, v in d.items():
- if k not in list_profiles:
- list_profiles.append(k)
- if k== last_pfofile:
- for k1, v1 in v.items():
- v1=v[k1]
- new.add_new_command(scrollable_frame,k1,v1)
- def update(event):
- new.remove_all_command_without_adding()
- filling_fields(dict_save, profile_current.get())
- def create_box():
- box = Combobox(root, width=12, textvariable=profile_current, values=list_profiles, state='readonly')
- box.grid(column=1, row=0, padx=3, pady=0) # поле со списком.
- box.bind('<Button-1>', save_keys_and_values) # при нажатии на выпадающий список.
- box.bind('<<ComboboxSelected>>', update)# при изменения профиля.
- return box
- def add1(root,window, new, scrollable_frame):
- value= new_profile.get()
- if value != '':
- list_profiles.append(str(value))
- box = Combobox(root, width=12, textvariable=profile_current, values=list_profiles, state='readonly')
- box.bind('<<ComboboxSelected>>', update)
- box.grid(column=1, row=0, padx=3, pady=0) # поле со списком
- add_button = Button(text="Добавить профиль", command= lambda:add_new_profile(root, box)).grid(column=2, row=0, padx=10, pady=6)
- box.current(len(list_profiles)-1)
- window.destroy()
- new_profile.set('')
- new.remove_all_command(scrollable_frame)
- def add_new_profile(root,box,new,scrollable_frame):
- window = Toplevel(root)# основа
- window.title("add new profile") # заголовок
- window.geometry("500x150+750+400") # Первые 2 определяют ширину высоту. Пос 2 x и y координаты на экране.
- window.configure(bg='DimGray') # Цвет фона окна
- e=Entry(window, width=30, textvariable=new_profile) #строка ввода профиля.
- e.grid(column=2, row=0, padx=50, pady=5)
- e.focus_set()
- Button(window, text="Добавить профиль", command= lambda:add1(root,window,new,scrollable_frame))\
- .grid(column=2, row=1, padx=50, pady=30) # кнопка добавить профиль, откроется новое окно.
- def del_profile_box(root, window, box, profile_for_del):
- profile =profile_for_del.get()
- if profile=="":
- messagebox.showerror("Erorr", "profile not selected")
- if profile=="default":
- messagebox.showerror("Erorr", "this profile cannot be deleted")
- else:
- last_pfofile = list_profiles.index(profile)-1
- list_profiles.remove(profile)
- res= dict_save.return_jnson()['profiles']
- del res[profile]
- box = Combobox(root, width=12, textvariable=profile_current, values=list_profiles, state='readonly')
- box.current(last_pfofile)
- box.bind('<<ComboboxSelected>>', update)
- box.grid(column=1, row=0, padx=3, pady=0) # поле со списком
- add_button = Button(text="Добавить профиль", command=lambda: add_new_profile(root, box)).grid(column=2, row=0, padx=10, pady=6)
- new.remove_all_command(scrollable_frame)
- box = create_box() # Создания выпадающего списка.
- box.current(last_pfofile)
- new.remove_all_command_without_adding()
- filling_fields(dict_save, list_profiles[last_pfofile]) # запол полей
- window.destroy()
- def del_profile(root,box):
- window = Toplevel(root)# основа
- window.title("Delete profile") # заголовок
- window.geometry("500x150+750+400") # Первые 2 определяют ширину высоту. Пос 2 x и y координаты на экране.
- window.configure(bg='DimGray') # Цвет фона окна
- profile_for_del = StringVar()
- box1 = Combobox(window, width=30, textvariable=profile_for_del, values=list_profiles, state='readonly') # box с профилями.
- box1.grid(column=2, row=1, padx=50, pady=5)
- Button(window, text="Удалить профиль", command= lambda:del_profile_box(root, window, box, profile_for_del))\
- .grid(column=2, row=2, padx=50, pady=30) # кнопка добавить профиль, откроется новое окно.
- def start(new, scrollable_frame,box):
- if os.path.exists(data): # есть ли этот файл.
- with open(data) as json_file:
- res= json.load(json_file)
- dict_save.save_jnson(res)# соранить начальные настройки.
- dict_save.save_old_data(res)
- last_pfofile = res["last_pfofile"] # последний исполь профиль.
- for name in res["profiles"]:
- if not name in list_profiles:
- list_profiles.append(name)
- box =create_box() # Создания выпадающего списка.
- box.current(list_profiles.index(last_pfofile))
- start_startup.set(res["start_startup"])
- filling_fields(dict_save, last_pfofile)# запол полей
- else:
- box.current(0)
- new.add_new_command(scrollable_frame)
- def delayed_launch(start_startup):
- if start_startup.get(): # Запуск при открытий.
- start_voice()
- dict_save=save_dict()
- root = Tk()
- root.geometry("580x250+650+400")
- root.title("voice control in the game")
- root.resizable(width=False, height=False)
- start_startup = BooleanVar()
- profile_current, new_profile=StringVar(),StringVar()
- lb = Label(root, text="Голосовое управления в играх",width=25).grid(column=0, row=0) # текстовое поле и кнопка для добавления в список
- arg, values = [], []# списки для слов и значений.
- container = Frame(root)
- canvas = Canvas(container,width=320, height=200)
- scrollbar = Scrollbar(container, orient="vertical", command=canvas.yview)
- scrollable_frame = Frame(canvas)
- scrollable_frame.bind( "<Configure>",
- lambda e: canvas.configure( scrollregion=canvas.bbox("all")
- ))
- canvas.create_window((0, 0), window=scrollable_frame, anchor="n")
- canvas.configure(yscrollcommand=scrollbar.set)
- container.grid()
- canvas.grid(sticky=N+S)
- scrollbar.grid(column=0, row=0,sticky=N+S+E)# полоса прокрутки.
- box = create_box() # Создания выпадающего списка.
- new=iter_counter()# объект класса.
- add_button = Button(text="Добавить профиль", command= lambda:add_new_profile(root, box, new,scrollable_frame))\
- .grid(column=2, row=0, padx=10, pady=6,sticky=NE)
- add_button = Button(text="Удалить профиль", command= lambda:del_profile(root, box))\
- .grid(column=2, row=1, padx=10, pady=16,sticky=N)
- add_key_button = Button(text="Добавить команду", command= lambda:new.add_new_command(scrollable_frame))\
- .grid(column=1, row=1, padx=1, pady=30,sticky=N)
- del_key_button_1 = Button(text="Удалить команду", command= lambda:new.del_command())\
- .grid(column=1, row=1,padx=1,pady=90,sticky=N)
- go_button_2 = Button(text=" Старт ", command= lambda:start_voice())\
- .grid(column=2, row=1,padx=0,pady=10,sticky=SE)# Запуск управления.
- root.protocol("WM_DELETE_WINDOW", on_close)
- box.grid(column=1, row=0, padx=3, pady=0) # поле со списком
- r1 = Checkbutton(text='Запускать при открытий',
- variable=start_startup, command=lambda:save_keys_and_values())
- r1.place(x=323, y=190)
- start(new, scrollable_frame,box)# запуск всего.
- t2 = Thread(target=delayed_launch, args=(start_startup,))
- t2.start()
- root.mainloop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement