diff --git a/daemon.py b/daemon.py index be0cf11..29d8a07 100644 --- a/daemon.py +++ b/daemon.py @@ -26,30 +26,29 @@ else: ULINE = REVERSE = '' appendLog('Loading without colors') -if os.name == 'nt': - clear = lambda: os.system('cls') -else: - clear = lambda: os.system('clear') - -if os.name == 'nt': - import winsound -else: - import playsound +sysname = getOS() clear() -os.system("title Загрузка daemon...") -appendLog('Loading daemon') +setTitle("Загрузка daemon...", sysname) +appendLog('daemon.py start initialized', startup=True) import libinstaller +import rpc + +if sysname == "windows": + import easygui + import tkinter -import easygui -import tkinter import keyboard import ast import inputimeout import telegram_send -import getpass +if getOS() == "windows": + import winsound + from playsound import playsound +else: + from playsound import playsound menu_choose = None @@ -115,565 +114,6 @@ def getLessons(): return lessons_list -def getState(): - - if os.name == 'nt': - - try: - output = os.popen(f'tasklist /fi "IMAGENAME eq CptHost.exe" /fi "USERNAME ne NT AUTHORITY\{getpass.getuser()}"').read() - - if "CptHost.exe" in output: - return True - else: - return False - - except Exception as exp: - appendLog(f'Failed to get state using tasklist: {exp}') - - output = os.popen('wmic process get description, processid').read() - - if "CptHost.exe" in output: - return True - else: - return False - -def listLessons(from_where='remove'): - - try: - - appendLog('Showing list of everything planned') - - if from_where == 'editor': - print(f'{RESET}Полный список запланированных конференций:\n') - - print(f'{BBLACK}================================================{RESET}') - for les in enumerate(getLessons()): - - if les[1]["repeat"]: - repeat = 'Вкл.' - else: - repeat = 'Выкл.' - - if les[1]["record"]: - record = 'Вкл.' - else: - record = 'Выкл.' - - try: - repeat_day = getDay(les[1]["repeat_day"]) - except: - repeat_day = 'Не повторяется' - - length = len(str(les[0])) - - spacer_all = 6 * ' ' - spacer_ind = (5 - length) * ' ' - - - print(f'{spacer_all}Имя: {YELLOW}{les[1]["name"]}{RESET}') - print(f'{spacer_all}Дата: {YELLOW}{les[1]["date"]}{RESET}') - print(f'{spacer_all}Время: {YELLOW}{les[1]["time"]}{RESET}') - print(f' {GREEN}{les[0]}{RESET}{spacer_ind}Ссылка: {YELLOW}{les[1]["link"]}{RESET}') - print(f'{spacer_all}Повтор: {YELLOW}{repeat}{RESET}') - print(f'{spacer_all}День: {YELLOW}{repeat_day}{RESET}') - print(f'{spacer_all}Запись: {YELLOW}{record}{RESET}') - print(f'{BBLACK}================================================{RESET}') - - if from_where == 'editor': - none = input('\n\n > ') - - except KeyboardInterrupt: - clear() - return - -def sortLessons(dictionary): - dictionary.sort(key = lambda x: datetime.strptime(x['time'], '%H:%M')) - dictionary.sort(key = lambda x: datetime.strptime(x['date'], '%d.%m.%Y')) - appendLog('Lessons dictionary sorted') - -def getDayNum(day): - output = datetime.strptime(day, "%d.%m.%Y").isoweekday() - return output - -def getDay(number): - if number == 1: - return 'Понедельник' - if number == 2: - return 'Вторник' - if number == 3: - return 'Среда' - if number == 4: - return 'Четверг' - if number == 5: - return 'Пятница' - if number == 6: - return 'Суббота' - if number == 7: - return 'Воскресенье' - -def addLesson(): - appendLog('Adding new lesson') - - try: - local_lessons = {} - lessons_got = getLessons() - - lessname = input(f'{RESET}Введите (своё) имя конференции:\n{BBLACK}Нужно лишь для отображения в Discord и самом AutoZoom{RESET}\n\n > {CYAN}') - local_lessons.update({"name": lessname}) - - while True: - clear() - today = date.today() - today_1 = date.today() + timedelta(days=1) - today_2 = date.today() + timedelta(days=2) - today_3 = date.today() + timedelta(days=3) - today_4 = date.today() + timedelta(days=4) - today_5 = date.today() + timedelta(days=5) - today_6 = date.today() + timedelta(days=6) - - print(f'{RESET}Введите дату конференции или номер дня ({BRED}ДД.ММ.ГГГГ{RESET}):\n') - print(f' {BRED}1.{RESET} {today.strftime("%d.%m.%Y")} ({BGREEN}{getDay(datetime.strptime(today.strftime("%d.%m.%Y"), "%d.%m.%Y").isoweekday())}{RESET})') - print(f' {BRED}2.{RESET} {today_1.strftime("%d.%m.%Y")} ({BGREEN}{getDay(datetime.strptime(today_1.strftime("%d.%m.%Y"), "%d.%m.%Y").isoweekday())}{RESET})') - print(f' {BRED}3.{RESET} {today_2.strftime("%d.%m.%Y")} ({BGREEN}{getDay(datetime.strptime(today_2.strftime("%d.%m.%Y"), "%d.%m.%Y").isoweekday())}{RESET})') - print(f' {BRED}4.{RESET} {today_3.strftime("%d.%m.%Y")} ({BGREEN}{getDay(datetime.strptime(today_3.strftime("%d.%m.%Y"), "%d.%m.%Y").isoweekday())}{RESET})') - print(f' {BRED}5.{RESET} {today_4.strftime("%d.%m.%Y")} ({BGREEN}{getDay(datetime.strptime(today_4.strftime("%d.%m.%Y"), "%d.%m.%Y").isoweekday())}{RESET})') - print(f' {BRED}6.{RESET} {today_5.strftime("%d.%m.%Y")} ({BGREEN}{getDay(datetime.strptime(today_5.strftime("%d.%m.%Y"), "%d.%m.%Y").isoweekday())}{RESET})') - print(f' {BRED}7.{RESET} {today_6.strftime("%d.%m.%Y")} ({BGREEN}{getDay(datetime.strptime(today_6.strftime("%d.%m.%Y"), "%d.%m.%Y").isoweekday())}{RESET})') - - try: - lessdate = input(f'\n > {BRED}') - if lessdate == '': - finallessdate = lessons_got[edi]["date"] - elif lessdate == '1': - finallessdate = today.strftime("%d.%m.%Y") - elif lessdate == '2': - finallessdate = today_1.strftime("%d.%m.%Y") - elif lessdate == '3': - finallessdate = today_2.strftime("%d.%m.%Y") - elif lessdate == '4': - finallessdate = today_3.strftime("%d.%m.%Y") - elif lessdate == '5': - finallessdate = today_4.strftime("%d.%m.%Y") - elif lessdate == '6': - finallessdate = today_5.strftime("%d.%m.%Y") - elif lessdate == '7': - finallessdate = today_6.strftime("%d.%m.%Y") - else: - try: - test = (datetime.strptime(lessdate, "%d.%m.%Y")) - finallessdate = lessdate - except: - continue - - local_lessons.update({"date": finallessdate}) - - break - except: - continue - - while True: - clear() - try: - lesstime = input(f'{RESET}Введите время конференции ({BRED}ЧЧ:ММ{RESET}):\n\n > {BRED}') - finallesstime = (datetime.strptime(lesstime, "%H:%M")) - local_lessons.update({"time": lesstime}) - break - except: - continue - - clear() - lesslink = input(f'{RESET}Введите ссылку на конференцию:\n{BBLACK}Формат: {BRED}https://us01web.zoom.us/j/ИДЕНТИФИКАТОР?pwd=ПАРОЛЬ{RESET}\n{BBLACK}Либо введите {YELLOW}1 {BBLACK}для добавления по номеру и паролю{RESET}\n\n > {BRED}').replace(" ", "") - - if lesslink.replace(' ', '') == '1': - clear() - lessid = input(f'{RESET}Введите идентификатор конференции:\n{BBLACK}Формат: {BRED}012 3456 7890 {BBLACK} либо {BRED}01234567890{RESET}\n\n > {BRED}') - clear() - lesspasswd = input(f'{RESET}Введите код доступа (пароль) конференции:\n\n > {BRED}') - lesslink = f'https://us01web.zoom.us/j/{lessid.replace(" ", "")}?pwd={lesspasswd.replace(" ", "")}' - - local_lessons.update({"link": lesslink}) - - while True: - clear() - repeat = input(f'{RESET}Повторять эту конференцию ({getDay(getDayNum(finallessdate))})? {RESET}({BGREEN}Да{RESET}/{BRED}Нет{RESET})\n\n > ') - - if repeat.lower() in ['y', 'yes', 'д', 'да']: - finalrepeat = True - finalrepeatday = getDayNum(finallessdate) - local_lessons.update({"repeat": finalrepeat}) - local_lessons.update({"repeat_day": finalrepeatday}) - break - elif repeat.lower() in ['n', 'no', 'н', 'нет']: - finalrepeat = False - finalrepeatday = None - local_lessons.update({"repeat": finalrepeat}) - local_lessons.update({"repeat_day": finalrepeatday}) - break - else: - continue - - while True: - clear() - lessrecord = input(f'Записать эту конференцию? {RESET}({BGREEN}Да{RESET}/{BRED}Нет{RESET})\n\n > ') - - if lessrecord.lower() in ['y', 'yes', 'д', 'да']: - finallessrecord = True - local_lessons.update({"record": finallessrecord}) - break - elif lessrecord.lower() in ['n', 'no', 'н', 'нет']: - finallessrecord = False - local_lessons.update({"record": finallessrecord}) - break - else: - continue - - - lessons_got.append(dict(local_lessons)) - sortLessons(lessons_got) - saveJson(files_folder+'lessons.json', lessons_got) - - clear() - print(f'Добавлена конференция {CYAN}{local_lessons["name"]}{RESET} за {BRED}{local_lessons["date"]}{RESET} на время {BRED}{local_lessons["time"]}{RESET}.') - appendLog(f'Added lesson {local_lessons["name"]} (Date: {local_lessons["date"]}, Time: {local_lessons["time"]}, Link: {local_lessons["link"]})') - none = input('\n > ') - - except KeyboardInterrupt: - appendLog('Lesson adding aborted') - clear() - return - - -def editLesson(): - appendLog(f'Editing existing lesson') - - try: - local_lessons = {} - lessons_got = getLessons() - - while True: - print(f'{RESET}Выберите номер (индекс) для изменения:\n') - listLessons() - lessons_got = getLessons() - - print(f'\nДля отмены операции введите {BRED}c{RESET} или {BRED}cancel{RESET}') - - edi = input(f'\n > {BGREEN}') - - if not isinstance(edi, int): - if edi.lower() == 'c' or edi.lower() == 'cancel': - clear() - return - try: - edi = int(edi) - except: - clear() - continue - - try: - probe = lessons_got[edi]["name"] - break - except: - clear() - print(f'{RESET}Выберите {ULINE}правильный{RESET} индекс (номер) для изменения.') - time.sleep(3) - clear() - continue - - break - - clear() - lessname = input(f'{RESET}Введите (своё) имя конференции:\n{BBLACK}Нужно лишь для отображения в Discord и самом AutoZoom{RESET}\n\nОригинальное имя: {CYAN}{lessons_got[edi]["name"]}{RESET}\n\n > {CYAN}') - if lessname == '': - lessname = lessons_got[edi]["name"] - local_lessons.update({"name": lessname}) - - while True: - clear() - today = date.today() - today_1 = date.today() + timedelta(days=1) - today_2 = date.today() + timedelta(days=2) - today_3 = date.today() + timedelta(days=3) - today_4 = date.today() + timedelta(days=4) - today_5 = date.today() + timedelta(days=5) - today_6 = date.today() + timedelta(days=6) - - print(f'{RESET}Введите дату конференции или номер дня ({BRED}ДД.ММ.ГГГГ{RESET}):\n') - print(f' {BRED}1.{RESET} {today.strftime("%d.%m.%Y")} ({BGREEN}{getDay(datetime.strptime(today.strftime("%d.%m.%Y"), "%d.%m.%Y").isoweekday())}{RESET})') - print(f' {BRED}2.{RESET} {today_1.strftime("%d.%m.%Y")} ({BGREEN}{getDay(datetime.strptime(today_1.strftime("%d.%m.%Y"), "%d.%m.%Y").isoweekday())}{RESET})') - print(f' {BRED}3.{RESET} {today_2.strftime("%d.%m.%Y")} ({BGREEN}{getDay(datetime.strptime(today_2.strftime("%d.%m.%Y"), "%d.%m.%Y").isoweekday())}{RESET})') - print(f' {BRED}4.{RESET} {today_3.strftime("%d.%m.%Y")} ({BGREEN}{getDay(datetime.strptime(today_3.strftime("%d.%m.%Y"), "%d.%m.%Y").isoweekday())}{RESET})') - print(f' {BRED}5.{RESET} {today_4.strftime("%d.%m.%Y")} ({BGREEN}{getDay(datetime.strptime(today_4.strftime("%d.%m.%Y"), "%d.%m.%Y").isoweekday())}{RESET})') - print(f' {BRED}6.{RESET} {today_5.strftime("%d.%m.%Y")} ({BGREEN}{getDay(datetime.strptime(today_5.strftime("%d.%m.%Y"), "%d.%m.%Y").isoweekday())}{RESET})') - print(f' {BRED}7.{RESET} {today_6.strftime("%d.%m.%Y")} ({BGREEN}{getDay(datetime.strptime(today_6.strftime("%d.%m.%Y"), "%d.%m.%Y").isoweekday())}{RESET})') - print(f'\nОригинальная дата: {BRED}{lessons_got[edi]["date"]}{RESET}') - - try: - lessdate = input(f'\n > {BRED}') - if lessdate == '': - finallessdate = lessons_got[edi]["date"] - elif lessdate == '1': - finallessdate = today.strftime("%d.%m.%Y") - elif lessdate == '2': - finallessdate = today_1.strftime("%d.%m.%Y") - elif lessdate == '3': - finallessdate = today_2.strftime("%d.%m.%Y") - elif lessdate == '4': - finallessdate = today_3.strftime("%d.%m.%Y") - elif lessdate == '5': - finallessdate = today_4.strftime("%d.%m.%Y") - elif lessdate == '6': - finallessdate = today_5.strftime("%d.%m.%Y") - elif lessdate == '7': - finallessdate = today_6.strftime("%d.%m.%Y") - else: - try: - test = (datetime.strptime(lessdate, "%d.%m.%Y")) - finallessdate = lessdate - except: - continue - - local_lessons.update({"date": finallessdate}) - - break - except: - continue - - while True: - clear() - try: - lesstime = input(f'{RESET}Введите время конференции ({BRED}ЧЧ:ММ{RESET}):\n\nОригинальное время: {BRED}{lessons_got[edi]["time"]}{RESET}\n\n > {BRED}') - - if lesstime == '': - finallesstime = lessons_got[edi]["time"] - lesstime = lessons_got[edi]["time"] - else: - try: - finallesstime = (datetime.strptime(lesstime, "%H:%M")) - finallesstime = lesstime - except: - continue - - local_lessons.update({"time": lesstime}) - break - except: - continue - - clear() - lesslink = input(f'{RESET}Введите ссылку на конференцию:\n{BBLACK}Формат: {BRED}https://us01web.zoom.us/j/ИДЕНТИФИКАТОР?pwd=ПАРОЛЬ{RESET}\n{BBLACK}Либо введите {YELLOW}1 {BBLACK}для добавления по номеру и паролю{RESET}\n\n > {BRED}').replace(" ", "") - - if lesslink.replace(' ', '') == '1': - clear() - lessid = input(f'{RESET}Введите идентификатор конференции:\n{BBLACK}Формат: {BRED}012 3456 7890 {BBLACK} либо {BRED}01234567890{RESET}\n\n > {BRED}') - clear() - lesspasswd = input(f'{RESET}Введите код доступа (пароль) конференции:\n\n > {BRED}') - lesslink = f'https://us01web.zoom.us/j/{lessid.replace(" ", "")}?pwd={lesspasswd.replace(" ", "")}' - - if lesslink == '': - lesslink = lessons_got[edi]["link"] - - local_lessons.update({"link": lesslink}) - - while True: - clear() - try: - lessrepeatday = getDay(lessons_got[edi]["repeat_day"]) - except: - lessrepeatday = 'Не повторяется' - - print(f'{RESET}Повторять эту конференцию ({YELLOW}{getDay(getDayNum(finallessdate))}{RESET})? {RESET}({BGREEN}Да{RESET}/{BRED}Нет{RESET})') - print(f'\nОригинальное значение: {BRED}{lessrepeatday}{RESET}') - repeat = input('\n > ') - - if repeat.lower() in ['y', 'yes', 'д', 'да']: - finalrepeat = True - finalrepeatday = getDayNum(finallessdate) - local_lessons.update({"repeat": finalrepeat}) - local_lessons.update({"repeat_day": finalrepeatday}) - break - elif repeat.lower() in ['n', 'no', 'н', 'нет']: - finalrepeat = False - local_lessons.update({"repeat": finalrepeat}) - break - elif repeat == '': - finalrepeat = lessons_got[edi]["repeat"] - local_lessons.update({"repeat": finalrepeat}) - try: - finalrepeatday = lessons_got[edi]["repeat_day"] - local_lessons.update({"repeat_day": finalrepeatday}) - except: - pass - break - else: - continue - - while True: - clear() - print(f'Записать эту конференцию? {RESET}({BGREEN}Да{RESET}/{BRED}Нет{RESET})') - print(f'\nОригинальное значение: {BRED}{lessons_got[edi]["record"]}{RESET}') - lessrecord = input('\n > ') - - if lessrecord.lower() in ['y', 'yes', 'д', 'да']: - finallessrecord = True - local_lessons.update({"record": finallessrecord}) - break - elif lessrecord.lower() in ['n', 'no', 'н', 'нет']: - finallessrecord = False - local_lessons.update({"record": finallessrecord}) - break - elif lessrecord == '': - finallessrecord = lessons_got[edi]["record"] - local_lessons.update({"record": finallessrecord}) - break - else: - continue - - del lessons_got[edi] - lessons_got.append(dict(local_lessons)) - sortLessons(lessons_got) - saveJson(files_folder+'lessons.json', lessons_got) - clear() - print(f'Изменена конференция {CYAN}{lessname}{RESET} за {BRED}{finallessdate}{RESET} на время {BRED}{finallesstime}{RESET}.') - appendLog(f'Edited lesson {lessname} (Date: {finallessdate}, Time: {finallesstime}, Link: {local_lessons["link"]})') - none = input('\n > ') - - except KeyboardInterrupt: - appendLog('Editing existing lesson aborted') - clear() - return - - -def removeLesson(): - appendLog(f'Removing existing lesson') - - try: - while True: - print(f'{RESET}Выберите номер (индекс) для удаления:\n') - listLessons() - lessons_local = getLessons() - print(f'\n{BBLACK}Для отмены операции введите {BRED}c{BBLACK} или {BRED}cancel{RESET}') - - rem = input(f'\n > {BRED}') - - if rem.lower() == 'c' or rem.lower() == 'cancel': - clear() - break - else: - try: - rem = int(rem) - except: - clear() - continue - - try: - del_name = lessons_local[rem]["name"] - del_date = lessons_local[rem]["date"] - del_time = lessons_local[rem]["time"] - del lessons_local[rem] - except: - clear() - print(f'{RESET}Выберите {ULINE}правильный{RESET} индекс (номер) для удаления.') - time.sleep(3) - clear() - continue - - sortLessons(lessons_local) - saveJson(files_folder+'lessons.json', lessons_local) - clear() - print(f'{RESET}Удалена конференция {CYAN}{del_name}{RESET} за {BRED}{del_date}{RESET} на время {BRED}{del_time}{RESET}.') - appendLog(f'Removed lesson {del_name} (Date: {del_date}, Time: {del_time})') - none = input('\n > ') - break - except KeyboardInterrupt: - appendLog('Lesson removal aborted') - clear() - return - -def removeAllLessons(): - appendLog('Removing all lessons') - - try: - while True: - clear() - removeall = input(f'{RESET}Вы уверены что хотите удалить все конференции? {RESET}({BGREEN}Да{RESET}/{BRED}Нет{RESET})\n{BRED}Внимание!{RESET} Это действие нельзя обратить!\nВаши настройки затронуты НЕ будут.\n\n > ') - - if removeall.lower() in ['y', 'yes', 'д', 'да']: - with open(files_folder+'lessons.json', 'w', encoding="utf-8") as f: - f.write("[]") - f.close() - - appendLog('All lessons removed') - clear() - none = input('Все конференции были удалены.\n\n > ') - clear() - break - elif removeall.lower() in ['n', 'no', 'н', 'нет']: - appendLog('All lessons removal aborted') - clear() - break - else: - continue - - except KeyboardInterrupt: - appendLog('All lessons removal aborted') - - clear() - return - -import rpc - -def editor(): - try: - os.system("title AutoZoom (Редактор)") - appendLog('Editor menu opened') - - from main import mainMenu - - while True: - clear() - - print(f'{BBLACK}»{RESET} Меню редактора\n') - print(f' {BRED}1.{RESET} Добавить конференцию') - print(f' {BRED}2.{RESET} Изменить конференцию') - print(f' {BRED}3.{RESET} Удалить конференцию') - print(f' {BRED}4.{RESET} Посмотреть конференции') - print(f' {BRED}5.{RESET} Удалить все конференции') - print(f' {BRED}6.{RESET} В главное меню') - editor_choose = input(f'\n > {BRED}') - - if editor_choose == '1': - appendLog('Went to lesson adding') - clear() - addLesson() - elif editor_choose == '2': - appendLog('Went to lesson editing') - clear() - editLesson() - elif editor_choose == '3': - appendLog('Went to lesson removal') - clear() - removeLesson() - elif editor_choose == '4': - appendLog('Went to lesson lising') - clear() - listLessons(from_where = 'editor') - elif editor_choose == '5': - appendLog('Went to all lessons removal') - clear() - removeAllLessons() - elif editor_choose == '6': - appendLog('Exiting back to main menu') - rpc.inMenu() - clear() - os.system("title AutoZoom (Главная)") - mainMenu() - else: - continue - - except KeyboardInterrupt: - appendLog('Exiting back to main menu') - rpc.inMenu() - clear() - return def tgsend(enabled, message): if enabled: @@ -682,540 +122,20 @@ def tgsend(enabled, message): tg_text = tg_file.read() if tg_text != 'Not Configured': + try: telegram_send.send(messages=[f"{message}"], parse_mode="markdown", conf=files_folder+"telegram.conf") + except Exception as excep: appendLog(f'Failed to send TG message "{message}": {exp}') + playSound("warning", nowtime()) print(f'{nowtime()} Не удалось отправить Telegram сообщение "{message}" (Ошибка: {exp})') -def playSound(soundname): - - if getConfig("sounds"): - - if os.name == 'nt': - winsound.PlaySound(sounds_folder+soundname+".wav", winsound.SND_FILENAME) - else: - playsound.playsound(sounds_folder+soundname+".wav") - -def settings(): - appendLog('Settings page 1 opened') - - try: - while True: - - os.system("title AutoZoom (Настройки)") - clear() - - if getConfig("debug"): - debug_val = f'{BGREEN}Вкл.{RESET}' - elif not getConfig("debug"): - debug_val = f'{BRED}Выкл.{RESET}' - else: - debug_val = f'{BRED}ERROR{RESET}' - - if getConfig("run_fullscreen"): - fullscreen_val = f'{BGREEN}Вкл.{RESET}' - elif not getConfig("run_fullscreen"): - fullscreen_val = f'{BRED}Выкл.{RESET}' - else: - fullscreen_val = f'{BRED}ERROR{RESET}' - - if getConfig("sounds"): - sounds_val = f'{BGREEN}Вкл.{RESET}' - elif not getConfig("sounds"): - sounds_val = f'{BRED}Выкл.{RESET}' - else: - sounds_val = f'{BRED}ERROR{RESET}' - - if getConfig("obs_exe") and getConfig("obs_core") not in [None, 'Disabled']: - obs_val = f'{BGREEN}Вкл.{RESET}' - else: - obs_val = f'{BRED}Выкл.{RESET}' - - if getConfig("use_colors"): - color_val = f'{BGREEN}Вкл.{RESET}' - elif not getConfig("use_colors"): - color_val = f'{BRED}Выкл.{RESET}' - else: - color_val = f'{BRED}ERROR{RESET}' - - if getConfig("shutdown_enabled"): - shutdown_en_val = f'{BGREEN}Вкл.{RESET}' - elif not getConfig("shutdown_enabled"): - shutdown_en_val = f'{BRED}Выкл.{RESET}' - else: - shutdown_en_val = f'{BRED}ERROR{RESET}' - - if os.path.exists(files_folder+'telegram.conf'): - tg_file = open(files_folder+'telegram.conf', 'r', encoding="utf-8") - tg_text = tg_file.read() - if tg_text != 'Not Configured': - tg_var = f'{BGREEN}Настроен{RESET}' - else: - tg_var = f'{BRED}Не настроен{RESET}' - else: - tg_var = f'{BRED}Не настроен{RESET}' - - if getConfig("telegram_enabled"): - telegram_en_val = f'{BGREEN}Вкл.{RESET}' - elif not getConfig("debug"): - telegram_en_val = f'{BRED}Выкл.{RESET}' - else: - telegram_en_val = f'{BRED}ERROR{RESET}' - - shutdown_time_val = getConfig("shutdown_timeout") - start_val = getConfig("start") - stop_val = getConfig("stop") - - print(f'{RESET}{BBLACK}»{RESET} Настройки (1 стр.)\n') - - print(f' {BRED}1.{RESET} Режим отладки ({debug_val})') - print(f' {BBLACK}Не рекомендуем включать его без необходимости\n') - - print(f' {BRED}2.{RESET} Цветной вывод ({color_val})') - print(f' {BBLACK}Отображение цветных текстов в меню и выводе (нужен перезапуск)\n') - - print(f' {BRED}3.{RESET} Полный экран ({fullscreen_val})') - print(f' {BBLACK}Эмулировать вызов полного экрана при запуске (окно должно быть в фокусе)\n') - - print(f' {BRED}4.{RESET} Звуковые сигналы ({sounds_val})') - print(f' {BBLACK}Воспроизводить звуки при начале/конце конференций и записи видео\n') - - - print(f' {BRED}5.{RESET} Запись через OBS ({obs_val})') - print(f' {BBLACK}Возможность записи конференций через OBS\n') - - print(f' {BRED}6.{RESET} Автовыключение ({shutdown_en_val})') - print(f' {BBLACK}Когда конференции закончатся компьютер выключится\n') - - print(f' {BRED}7.{RESET} Следующая страница') - print(f' {BBLACK}Перейти на вторую страницу настроек\n') - - print(f' {BRED}8.{RESET} В главное меню') - print(f' {BBLACK}Вернуться в основное меню{RESET}\n') - - print(f' {BBLACK}Для переключения параметров Вкл/Выкл просто введите номер{RESET}') #\n Если окно приложения слишком мелкое - увеличьте его или листайте это меню{RESET}') - settings_choose = input(f'\n > {BRED}') - - if settings_choose == '1': - with open(f"{files_folder}config.json", encoding="utf-8") as json_file: - config_list = json.load(json_file) - json_file.close() - - config_list["debug"] = not getConfig("debug") - saveJson(files_folder+'config.json', config_list) - appendLog(f'Changed option "debug" to {getConfig("debug")}') - - clear() - continue - - elif settings_choose == '2': - with open(f"{files_folder}config.json", encoding="utf-8") as json_file: - config_list = json.load(json_file) - json_file.close() - - config_list["use_colors"] = not getConfig("use_colors") - saveJson(files_folder+'config.json', config_list) - appendLog(f'Changed option "use_colors" to {getConfig("use_colors")}') - - clear() - continue - - elif settings_choose == '3': - with open(f"{files_folder}config.json", encoding="utf-8") as json_file: - config_list = json.load(json_file) - json_file.close() - - config_list["run_fullscreen"] = not getConfig("run_fullscreen") - saveJson(files_folder+'config.json', config_list) - appendLog(f'Changed option "run_fullscreen" to {getConfig("run_fullscreen")}') - - clear() - continue - - elif settings_choose == '4': - with open(f"{files_folder}config.json", encoding="utf-8") as json_file: - config_list = json.load(json_file) - json_file.close() - - config_list["sounds"] = not getConfig("sounds") - saveJson(files_folder+'config.json', config_list) - appendLog(f'Changed option "sounds" to {getConfig("sounds")}') - - clear() - continue - - elif settings_choose == '5': - with open(f"{files_folder}config.json", encoding="utf-8") as json_file: - config_list = json.load(json_file) - json_file.close() - - if getConfig("obs_core") and getConfig("obs_exe") not in [None, 'Disabled']: - config_list["obs_core"] = 'Disabled' - config_list["obs_exe"] = 'Disabled' - else: - clear() - obs_choice = input(f'{RESET}Хотите использовать запись через OBS? {RESET}({BGREEN}Да{RESET}/{BRED}Нет{RESET}): ') - if obs_choice.lower() in ['y', 'yes', 'д', 'да']: - while True: - try: - filename = easygui.fileopenbox('Выберите путь до obs32.exe или obs64.exe') - if filename.find("obs64.exe") != -1: - config_list["obs_exe"] = filename - config_list["obs_core"] = filename[:-9] - print(f'Сохранены пути для OBS:\nПриложение: {BRED}{filename}{RESET}\nКорневая папка: {BRED}{filename[:-9]}{RESET}') - time.sleep(3) - break - elif filename.find("obs32.exe") != -1: - config_list["obs_exe"] = filename - config_list["obs_core"] = filename[:-9] - print(f'Сохранены пути для OBS:\nПриложение: {BRED}{filename}{RESET}\nКорневая папка: {BRED}{filename[:-9]}{RESET}') - time.sleep(3) - break - elif filename.find("obs.exe") != -1: - f.write(filename) - config_list["obs_exe"] = filename - config_list["obs_core"] = filename[:-7] - print(f'Сохранены пути для OBS:\nПриложение: {BRED}{filename}{RESET}\nКорневая папка: {BRED}{filename[:-7]}{RESET}') - time.sleep(3) - break - else: - easygui.msgbox("Неверный путь") - break - except Exception as exp: - appendLog(f'Could not select OBS path: {exp}') - none = input('Вы не выбрали верный путь для OBS.\n\n > ') - clear() - break - saveJson(files_folder+'config.json', config_list) - appendLog(f'Changed option "obs_exe" to {getConfig("obs_exe")}') - appendLog(f'Changed option "obs_core" to {getConfig("obs_core")}') - - clear() - continue - - elif settings_choose == '6': - with open(f"{files_folder}config.json", encoding="utf-8") as json_file: - config_list = json.load(json_file) - json_file.close() - - config_list["shutdown_enabled"] = not getConfig("shutdown_enabled") - saveJson(files_folder+'config.json', config_list) - appendLog(f'Changed option "shutdown_enabled" to {getConfig("shutdown_enabled")}') - - clear() - continue - - elif settings_choose == '7': - clear() - settings2() - - elif settings_choose == '8': - rpc.inMenu() - clear() - os.system("title AutoZoom (Главная)") - return - - except KeyboardInterrupt: - rpc.inMenu() - clear() - return - -def settings2(): - appendLog('Settings page 2 opened') - - try: - while True: - - os.system("title AutoZoom (Настройки)") - clear() - - if getConfig("use_colors"): - color_val = f'{BGREEN}Вкл.{RESET}' - elif not getConfig("use_colors"): - color_val = f'{BRED}Выкл.{RESET}' - else: - color_val = f'{BRED}ERROR{RESET}' - - if os.path.exists(files_folder+'telegram.conf'): - tg_file = open(files_folder+'telegram.conf', 'r', encoding="utf-8") - tg_text = tg_file.read() - if tg_text != 'Not Configured': - tg_var = f'{BGREEN}Настроен{RESET}' - else: - tg_var = f'{BRED}Не настроен{RESET}' - else: - tg_var = f'{BRED}Не настроен{RESET}' - - if getConfig("telegram_enabled"): - telegram_en_val = f'{BGREEN}Вкл.{RESET}' - elif not getConfig("debug"): - telegram_en_val = f'{BRED}Выкл.{RESET}' - else: - telegram_en_val = f'{BRED}ERROR{RESET}' - - if getConfig("update_check"): - update_val = f'{BGREEN}Вкл.{RESET}' - elif not getConfig("update_check"): - update_val = f'{BRED}Выкл.{RESET}' - else: - update_val = f'{BRED}ERROR{RESET}' - - shutdown_time_val = getConfig("shutdown_timeout") - start_val = getConfig("start") - stop_val = getConfig("stop") - - print(f'{RESET}{BBLACK}»{RESET} Настройки (2 стр.)\n') - - print(f' {BRED}1.{RESET} Таймаут выключения ({YELLOW}{shutdown_time_val} мин.{RESET})') - print(f' {BBLACK}Время в минутах после которого ПК будет выключен\n') - - print(f' {BRED}2.{RESET} Начать запись ({YELLOW}{start_val}{RESET})') - print(f' {BBLACK}Комбинация клавиш для начала записи через OBS (см. документацию)\n') - - print(f' {BRED}3.{RESET} Остановить запись ({YELLOW}{stop_val}{RESET})') - print(f' {BBLACK}Комбинация клавиш для остановки записи через OBS (см. документацию)\n') - - print(f' {BRED}4.{RESET} Отправлять уведомления ({telegram_en_val})') - print(f' {BBLACK}Ваш бот отправит сообщениия о начале/конце конференции и выключении ПК\n') - - print(f' {BRED}5.{RESET} Настроить Telegram бота ({tg_var})') - print(f' {BBLACK}Настроить на вашем ПК бота для ЛС (см. документацию)\n') - - print(f' {BRED}6.{RESET} Проверка обновлений ({update_val})') - print(f' {BBLACK}Не рекомендуем выключать без необходимости\n') - - print(f' {BRED}7.{RESET} Следующая страница') - print(f' {BBLACK}Перейти на третью страницу настроек\n') - - print(f' {BRED}8.{RESET} Назад') - print(f' {BBLACK}Вернуться на предыдущую страницу{RESET}\n') - - print(f' {BBLACK}Для переключения параметров Вкл/Выкл просто введите номер{RESET}') #\n Если окно приложения слишком мелкое - увеличьте его или листайте это меню{RESET}') - settings_choose = input(f'\n > {BRED}') - - if settings_choose == '1': - with open(f"{files_folder}config.json", encoding="utf-8") as json_file: - config_list = json.load(json_file) - json_file.close() - - try: - clear() - config_list["shutdown_timeout"] = int(input(f'{RESET}Введите через сколько минут после конференции выключать ПК:\n\n > {BRED}')) - saveJson(files_folder+'config.json', config_list) - appendLog(f'Changed option "shutdown_timeout" to {getConfig("shutdown_timeout")}') - continue - except: - clear() - print(f'{RESET}Нужно использовать целое число.') - time.sleep(2) - continue - continue - - elif settings_choose == '2': - with open(f"{files_folder}config.json", encoding="utf-8") as json_file: - config_list = json.load(json_file) - json_file.close() - - try: - clear() - config_list["start"] = input(f'{RESET}Введите комбинацию клавиш для начала записи OBS:\nЭта комбинация должна быть идентична оной в самом OBS!\n\n > {YELLOW}') - saveJson(files_folder+'config.json', config_list) - appendLog(f'Changed option "start" to {getConfig("start")}') - continue - except: - clear() - print(f'{RESET}Нужно использовать комбинацию клавиш в виде текста.') - time.sleep(2) - continue - continue - - elif settings_choose == '3': - with open(f"{files_folder}config.json", encoding="utf-8") as json_file: - config_list = json.load(json_file) - json_file.close() - - try: - clear() - config_list["stop"] = input(f'{RESET}Введите комбинацию клавиш для остановки записи OBS:\nЭта комбинация должна быть идентична оной в самом OBS!\n\n > {YELLOW}') - saveJson(files_folder+'config.json', config_list) - appendLog(f'Changed option "stop" to {getConfig("stop")}') - continue - except: - clear() - print(f'{RESET}Нужно использовать комбинацию клавиш в виде текста.') - time.sleep(2) - continue - continue - - elif settings_choose == '4': - with open(f"{files_folder}config.json", encoding="utf-8") as json_file: - config_list = json.load(json_file) - json_file.close() - - config_list["telegram_enabled"] = not getConfig("telegram_enabled") - saveJson(files_folder+'config.json', config_list) - appendLog(f'Changed option "telegram_enabled" to {getConfig("telegram_enabled")}') - - clear() - continue - - elif settings_choose == '5': - clear() - print(f'{RESET}Пожалуйста, прочтите инструкцию по установке Telegram бота в {BRED}README.txt{RESET}') - print(f'или в документации/инструкции что в разделе {CYAN}Помощь{RESET} главного меню') - print(f'чтобы хорошо понимать что сейчас от вас нужно.') - none = input('\n > ') - - while True: - clear() - try: - telegram_send.configure(files_folder+'telegram.conf', channel=False, group=False, fm_integration=False) - break - except: - clear() - continue - telegram_send.send(messages=[f"🎊 Конфигурация правильна, всё работает!"], parse_mode="markdown", conf=f"{files_folder}telegram.conf") - appendLog('Telegram Send successfully configured') - clear() - continue - - elif settings_choose == '6': - with open(f"{files_folder}config.json", encoding="utf-8") as json_file: - config_list = json.load(json_file) - json_file.close() - - config_list["update_check"] = not getConfig("update_check") - saveJson(files_folder+'config.json', config_list) - appendLog(f'Changed option "update_check" to {getConfig("update_check")}') - - clear() - continue - - elif settings_choose == '7': - appendLog('Going to settings page 3') - clear() - settings3() - - elif settings_choose == '8': - appendLog('Returning to settings page 1') - clear() - return - - except KeyboardInterrupt: - rpc.inMenu() - clear() - return - -def settings3(): - appendLog('Settings page 3 opened') - - try: - while True: - - os.system("title AutoZoom (Настройки)") - clear() - - if getConfig("write_logs"): - logs_val = f'{BGREEN}Вкл.{RESET}' - elif not getConfig("write_logs"): - logs_val = f'{BRED}Выкл.{RESET}' - else: - logs_val = f'{BRED}ERROR{RESET}' - - shutdown_time_val = getConfig("shutdown_timeout") - start_val = getConfig("start") - stop_val = getConfig("stop") - - print(f'{RESET}{BBLACK}»{RESET} Настройки (3 стр.)\n') - - print(f' {BRED}1.{RESET} Запись действий в лог ({logs_val})') - print(f' {BBLACK}Запись каждого действия в файл для отладки (не выключайте без причин)\n') - - print(f' {BRED}2.{RESET} Размер лога действий ({YELLOW}{str(getConfig("log_size"))} Кб{RESET})') - print(f' {BBLACK}Размер файла лога превышая который он будет упакован в архив\n') - - print(f' {BRED}3.{RESET} Сбросить все настройки') - print(f' {BBLACK}Восстановить настройки по умолчанию\n') - - print(f' {BRED}4.{RESET} Назад') - print(f' {BBLACK}Вернуться на предыдущую страницу{RESET}\n') - - print(f' {BBLACK}Для переключения параметров Вкл/Выкл просто введите номер{RESET}') #\n Если окно приложения слишком мелкое - увеличьте его или листайте это меню{RESET}') - settings_choose = input(f'\n > {BRED}') - - if settings_choose == '1': - with open(f"{files_folder}config.json", encoding="utf-8") as json_file: - config_list = json.load(json_file) - json_file.close() - - config_list["write_logs"] = not getConfig("write_logs") - saveJson(files_folder+'config.json', config_list) - appendLog(f'Changed option "write_logs" to {getConfig("write_logs")}') - - if settings_choose == '2': - with open(f"{files_folder}config.json", encoding="utf-8") as json_file: - config_list = json.load(json_file) - json_file.close() - - try: - clear() - config_list["log_size"] = int(input(f'{RESET}Введите после скольки килобайт архивировать лог:\n\n > {BRED}')) - saveJson(files_folder+'config.json', config_list) - continue - except: - clear() - print(f'{RESET}Нужно использовать целое число.') - time.sleep(2) - continue - - appendLog(f'Changed option "log_size" to {getConfig["log_size"]}') - continue - - elif settings_choose == '3': - appendLog('Resetting configuration') - - while True: - clear() - reset_decision = input(f'{RESET}Вы уверены что хотите сбросить настройки? {RESET}({BGREEN}Да{RESET}/{BRED}Нет{RESET})\n\n{BRED}Внимание!{RESET} Это действие нельзя обратить!\nВаш список конференций затронут НЕ будет.\n\n > ') - - if reset_decision.lower() in ['y', 'yes', 'д', 'да']: - - from functions import default_config - - saveJson(files_folder+'config.json', default_config) - appendLog('Configuration dropped to default') - clear() - none = input(f'{RESET}Все настройки были сброшены до стандартных.\n\n > ') - clear() - break - - elif reset_decision.lower() in ['n', 'no', 'н', 'нет']: - appendLog('Configuration reset aborted') - clear() - break - - else: - clear() - continue - - continue - - clear() - continue - - elif settings_choose == '4': - appendLog('Returning to settings page 2') - clear() - return - - except KeyboardInterrupt: - rpc.inMenu() - clear() - return def main(source='deamon'): + global sysname + ########################################## # Возможность профилей сделана для себя @@ -1235,7 +155,7 @@ def main(source='deamon'): from main import mainMenu clear() - os.system("title AutoZoom (Демон)") + setTitle("AutoZoom (Демон)", sysname) appendLog('Main daemon opened') import webbrowser @@ -1244,7 +164,7 @@ def main(source='deamon'): clear() while True: obs_choice = input(f'{RESET}Хотите использовать запись через OBS? {RESET}({BGREEN}Да{RESET}/{BRED}Нет{RESET}): ') - if obs_choice.lower() in ['y', 'yes', 'д', 'да']: + if obs_choice.lower() in yes_list: with open(f"{files_folder}config.json", encoding="utf-8") as json_file: config_list = json.load(json_file) json_file.close() @@ -1252,50 +172,44 @@ def main(source='deamon'): try: filename = easygui.fileopenbox('Выберите путь до obs32.exe или obs64.exe') if filename.find("obs64.exe") != -1: - config_list["obs_exe"] = filename - config_list["obs_core"] = filename[:-9] - saveJson(files_folder+'config.json', config_list) + setConfig("obs_exe", filename) + setConfig("obs_core", filename[:-9]) print(f'Сохранены пути для OBS:\nПриложение: {BRED}{filename}{RESET}\nКорневая папка: {BRED}{filename[:-9]}{RESET}') time.sleep(3) break elif filename.find("obs32.exe") != -1: - config_list["obs_exe"] = filename - config_list["obs_core"] = filename[:-9] - saveJson(files_folder+'config.json', config_list) + setConfig("obs_exe", filename) + setConfig("obs_core", filename[:-9]) print(f'Сохранены пути для OBS:\nПриложение: {BRED}{filename}{RESET}\nКорневая папка: {BRED}{filename[:-9]}{RESET}') time.sleep(3) break elif filename.find("obs.exe") != -1: - config_list["obs_exe"] = filename - config_list["obs_core"] = filename[:-7] - saveJson(files_folder+'config.json', config_list) + setConfig("obs_exe", filename) + setConfig("obs_core", filename[:-7]) print(f'Сохранены пути для OBS:\nПриложение: {BRED}{filename}{RESET}\nКорневая папка: {BRED}{filename[:-7]}{RESET}') time.sleep(3) break else: easygui.msgbox("Неверный путь") - continue break + except Exception as exp: none = input('Вы не выбрали верный путь для OBS.\n\n > ') - config_list["obs_exe"] = 'Disabled' - config_list["obs_core"] = 'Disabled' - saveJson(files_folder+'config.json', config_list) + setConfig("obs_exe", "Disabled") + setConfig("obs_core", "Disabled") appendLog(f'Could not select path to OBS: {exp}') clear() break break - elif obs_choice.lower() in ['n', 'no', 'н', 'нет']: - with open(f"{files_folder}config.json", encoding="utf-8") as json_file: - config_list = json.load(json_file) - config_list["obs_exe"] = 'Disabled' - config_list["obs_core"] = 'Disabled' - saveJson(files_folder+'config.json', config_list) - json_file.close() + + elif obs_choice.lower() in no_list: + setConfig("obs_exe", "Disabled") + setConfig("obs_core", "Disabled") clear() break + else: clear() continue @@ -1303,7 +217,7 @@ def main(source='deamon'): if not os.path.exists(files_folder+'telegram.conf'): clear() tg_choice = input(f'{RESET}Хотите использовать Telegram бота? {RESET}({BGREEN}Да{RESET}/{BRED}Нет{RESET}): ') - if tg_choice.lower() in ['y', 'yes', 'д', 'да']: + if tg_choice.lower() in yes_list: clear() print(f'Пожалуйста, прочтите инструкцию по установке Telegram бота в {BRED}README.txt{RESET}') print(f'или в документации/инструкции что в разделе {CYAN}Помощь{RESET} главного меню') @@ -1326,7 +240,7 @@ def main(source='deamon'): appendLog('Telegram Send successfully configured') clear() - elif tg_choice.lower() in ['n', 'no', 'н', 'нет']: + elif tg_choice.lower() in no_list: with open(files_folder+'telegram.conf', 'w', encoding="utf-8") as f: f.write('Not Configured') f.close() @@ -1364,13 +278,15 @@ def main(source='deamon'): print(f'{nowtime()} Найдена конференция {CYAN}{lesson_name}{RESET} в {BRED}{lesson_time}{RESET}. Ждём начала...') + setTitle(f'Ждём начала "{lesson_name}"', sysname) + waiting_time_unix = int(time.time()) rpc.waitLesson(lesson_name, waiting_time_unix) waitStart(lesson_time, lambda: act(100)) try: - if os.name == 'nt': + if sysname == 'windows': i = 0 if i == 0: @@ -1387,7 +303,7 @@ def main(source='deamon'): print(f'{nowtime()} Ориг. ссылка: {BRED}{lesson_url_original}{RESET}') print(f'{nowtime()} Измен. ссылка: {BRED}{lesson_url}{RESET}') - appendLog(f'Replacing link {lesson_url_original} with {lesson_url}') + appendLog(f'Replaced link {lesson_url_original} with {lesson_url}') os.system(f'start {lesson_url}') else: @@ -1406,14 +322,19 @@ def main(source='deamon'): print(f'{nowtime()} Ориг. ссылка: {BRED}{lesson_url_original}{RESET}') print(f'{nowtime()} Измен. ссылка: {BRED}{lesson_url}{RESET}') - appendLog(f'Replacing link {lesson_url_original} with {lesson_url}') - - os.system(f'xdg-open "{lesson_url}"') + appendLog(f'Replaced link {lesson_url_original} with {lesson_url}') + + if sysname == "android": + os.system(f'xdg-open "{lesson_url_original}"') + else: + os.system(f'xdg-open "{lesson_url}"') + except Exception as exep: appendLog(f'Failed to open lesson {lesson_name} in Zoom: {exep}') try: - webbrowser.open(lesson_url) + webbrowser.open(lesson_url_original) + except Exception as exp: print(f'{nowtime()} Открыть конференцию {CYAN}{lesson_name}{RESET} не удалось ни напрямую, ни в браузере.') appendLog(f'Failed to open lesson {lesson_name} in both browser and Zoom: {exp}') @@ -1430,42 +351,189 @@ def main(source='deamon'): retries = 0 destroy = False - while not getState(): - if getConfig("debug"): - print(f'{nowtime()} Конференция задерживается, ждём... ({getState()})') - - appendLog('Lesson delay found') + if sysname == "windows": + + while not getState(): + setTitle(f'Конференция "{lesson_name}" задерживается', sysname) - time.sleep(5) - retries += 1 - - if retries == 36: - tgsend(getConfig("telegram_enabled"), f"⚠ Задержка конференции *{lesson_name}* превысила 3 минуты {profilename}") - print(f'{nowtime()} Задержка конференции {CYAN}{lesson_name}{RESET} превысила {BRED}3{RESET} минуты') - appendLog(f'Lesson delay exceeded: {retries} retries') - - if retries == 120: - tgsend(getConfig("telegram_enabled"), f"⚠ Задержка конференции *{lesson_name}* превысила 10 минут {profilename}") - print(f'{nowtime()} Задержка конференции {CYAN}{lesson_name}{RESET} превысила {BRED}10{RESET} минут') - appendLog(f'Lesson delay exceeded: {retries} retries') - - if retries == 360: - if getConfig("debug"): - tgsend(getConfig("telegram_enabled"), f"⚠ Задержка конференции *{lesson_name}* превысила 30 минут, конференция сбошена {profilename}") - print(f'{nowtime()} Задержка конференции {CYAN}{lesson_name}{RESET} превысила {BRED}30{RESET} минут, конференция сброшена') - else: - tgsend(getConfig("telegram_enabled"), f"⚠ Задержка конференции *{lesson_name}* превысила 30 минут, конференция сбошена {profilename}") - print(f'{nowtime()} Задержка конференции {CYAN}{lesson_name}{RESET} превысила {BRED}30{RESET} минут, конференция сброшена') - - appendLog(f'Lesson delay exceeded: {retries} retries') + print(f'{nowtime()} Конференция задерживается, ждём... ({getState()})') - playSound("ended") + if retries == 1: + appendLog('Lesson delay found') + + time.sleep(5) + retries += 1 + + if getConfig("debug"): + if retries == 2: + playSound("warning", nowtime()) + tgsend(getConfig("telegram_enabled"), f"⚠ Задержка конференции *{lesson_name}* обнаружена {profilename}") + + if retries == 36: + playSound("warning", nowtime()) + tgsend(getConfig("telegram_enabled"), f"⚠ Задержка конференции *{lesson_name}* превысила 3 минуты {profilename}") + print(f'{nowtime()} Задержка конференции {CYAN}{lesson_name}{RESET} превысила {BRED}3{RESET} минуты') + appendLog(f'Lesson delay exceeded: {retries} retries') + + if retries == 120: + playSound("warning", nowtime()) + tgsend(getConfig("telegram_enabled"), f"⚠ Задержка конференции *{lesson_name}* превысила 10 минут {profilename}") + print(f'{nowtime()} Задержка конференции {CYAN}{lesson_name}{RESET} превысила {BRED}10{RESET} минут') + appendLog(f'Lesson delay exceeded: {retries} retries') + + if retries == 360: + + if getConfig("debug"): + playSound("warning", nowtime()) + tgsend(getConfig("telegram_enabled"), f"⚠ Задержка конференции *{lesson_name}* превысила 30 минут, конференция сбошена {profilename}") + print(f'{nowtime()} Задержка конференции {CYAN}{lesson_name}{RESET} превысила {BRED}30{RESET} минут, конференция сброшена') + else: + playSound("warning", nowtime()) + tgsend(getConfig("telegram_enabled"), f"⚠ Задержка конференции *{lesson_name}* превысила 30 минут, конференция сбошена {profilename}") + print(f'{nowtime()} Задержка конференции {CYAN}{lesson_name}{RESET} превысила {BRED}30{RESET} минут, конференция сброшена') + + appendLog(f'Lesson delay exceeded: {retries} retries') + + playSound("ended", nowtime()) + + if lesson_obs: + + record_now = False + + time.sleep(3) + + try: + obs_process.terminate() + except Exception as exp: + appendLog(f'Failed to stop OBS process: {exp}') + + if getConfig("debug"): + print(f'{nowtime()} Не удалось остановить процесс OBS.') + + if not lesson_repeat: + del lessons_list[lessons_list.index(les)] + + saveJson(files_folder+'lessons.json', lessons_list) + + if getConfig("debug"): + print(f'{nowtime()} Конференция {CYAN}{lesson_name}{RESET} в {BRED}{lesson_time}{RESET} удалена.') + + print(f'\n{BBLACK}================================================{RESET}\n\n') + + firstshow = True + + lessons_count = lessons_count+1 + destroy = True + break + + continue + + record_now = False + lesson_duration = 0 + firstshow = True + + if lesson_obs and not destroy: + try: + if getConfig("debug"): + print(f'{nowtime()} Импортированы клавиши старта и остановки записи ({YELLOW}{getConfig("start")}{RESET} и {YELLOW}{getConfig("stop")}{RESET}).') + + start = getConfig("start") + stop = getConfig("stop") + except: + start = 'shift+f7' + stop = 'shift+f8' + if getConfig("debug"): + print(f'{nowtime()} Используем стандартные клавиши старта и остановки записи ({YELLOW}{start}{RESET} и {YELLOW}{stop}{RESET}).') + + i = 0 + + while True and not destroy: + while i < 3: + if getState(): + if firstshow: + try: + start_time_unix = int(time.time()) + lesson_start = datetime.now() + except: + pass + + print(f'{nowtime()} Захвачена текущая конференция в Zoom.') + + setTitle(f'Идёт конференция "{lesson_name}"', sysname) + + playSound("started", nowtime()) + tgsend(getConfig("telegram_enabled"), f"▶ Зашёл на конференцию *{lesson_name}* в *{nowtime(False, False, False)}* {profilename}") + + appendLog(f'Joined lesson {lesson_name} at {nowtime(False, False, False)}') + + rpc.onLesson(lesson_name, start_time_unix) + + if lesson_obs: + try: + obs_process = subprocess.Popen(getConfig("obs_exe"), cwd=getConfig("obs_core")) + appendLog(f'Sent instruction to open OBS') + time.sleep(5) + except Exception as exp: + appendLog(f'Failed to open OBS: {exp}') + print(f'{nowtime()} Не удалось открыть OBS для записи.') + else: + if getConfig("debug"): + print(f'{nowtime()} Не включаем OBS для записи.') + + firstshow = False + + if lesson_obs: + if not record_now: + keyboard.press(start) + time.sleep(.25) + keyboard.release(start) + record_now = True + print(f'{nowtime()} Сигнал записи OBS отправлен.') + playSound("recordstart", nowtime()) + + lesson_duration = (datetime.now() - lesson_start).total_seconds() + + if getConfig("debug"): + print(f'{nowtime()} Zoom подключён. Конференция идёт уже {BGREEN}{str(lesson_duration)} сек{RESET}. ({BGREEN}{str(round(lesson_duration/60, 2))} мин{RESET}.)') + + time.sleep(5) + continue + else: + i += 1 + appendLog(f'CptHost.exe not found, trying again in 10 seconds') + + if getConfig("debug"): + print(f'{nowtime()} {BRED}Конференция не обнаружена! {RESET}Повторная проверка через {BRED}10 {RESET}секунд...') + + time.sleep(10) + continue + + if getConfig("debug"): + print(f'{nowtime()} Zoom отключился. Процесс {BRED}CptHost.exe{RESET} более не существует.') + + appendLog(f'CptHost.exe not found, Zoom disconnected') + + setTitle(f'Конференция "{lesson_name}" завершилась', sysname) + + if getConfig("debug"): + tgsend(getConfig("telegram_enabled"), f"◀ Конференция *{lesson_name}* длилась *{str(round(lesson_duration/60, 2))}* мин.") + print(f'{nowtime()} Конференция длилась {BGREEN}{str(lesson_duration)} сек{RESET}. ({BGREEN}{str(round(lesson_duration/60, 2))} мин{RESET}.)') + else: + tgsend(getConfig("telegram_enabled"), f"◀ Конференция *{lesson_name}* длилась *{str(int(lesson_duration/60))}* мин.") + print(f'{nowtime()} Конференция длилась {BGREEN}{str(lesson_duration)} сек{RESET}. ({BGREEN}{str(int(lesson_duration/60))} мин{RESET}.)') + + appendLog(f'Lesson {lesson_name} duration was {str(int(lesson_duration/60))} m. ({str(lesson_duration)} s.)') + + playSound("ended", nowtime()) if lesson_obs: - + keyboard.press(stop) + time.sleep(.25) + keyboard.release(stop) + print(f'{nowtime()} Сигнал остановки записи через OBS отправлен.') + playSound("recordstop", nowtime()) record_now = False - time.sleep(3) try: @@ -1480,6 +548,7 @@ def main(source='deamon'): del lessons_list[lessons_list.index(les)] saveJson(files_folder+'lessons.json', lessons_list) + appendLog(f'Lesson named {lesson_name} removed') if getConfig("debug"): print(f'{nowtime()} Конференция {CYAN}{lesson_name}{RESET} в {BRED}{lesson_time}{RESET} удалена.') @@ -1489,122 +558,19 @@ def main(source='deamon'): firstshow = True lessons_count = lessons_count+1 - destroy = True break + + record_now = False + retries = 0 + destroy = False + lessons_list = getLessons() - continue - - record_now = False - lesson_duration = 0 - firstshow = True - - if lesson_obs and not destroy: - try: - if getConfig("debug"): - print(f'{nowtime()} Импортированы клавиши старта и остановки записи ({YELLOW}{getConfig("start")}{RESET} и {YELLOW}{getConfig("stop")}{RESET}).') - - start = getConfig("start") - stop = getConfig("stop") - except: - start = 'shift+f7' - stop = 'shift+f8' - if getConfig("debug"): - print(f'{nowtime()} Используем стандартные клавиши старта и остановки записи ({YELLOW}{start}{RESET} и {YELLOW}{stop}{RESET}).') + else: + playSound("started", nowtime()) + tgsend(getConfig("telegram_enabled"), f"▶ Присоединился к конференции *{lesson_name}* в *{nowtime(False, False, False)}* {profilename}") - i = 0 - - while True and not destroy: - while i < 3: - if getState(): - if firstshow: - try: - start_time_unix = int(time.time()) - lesson_start = datetime.now() - except: - pass - - print(f'{nowtime()} Захвачена текущая конференция в Zoom.') - - playSound("started") - tgsend(getConfig("telegram_enabled"), f"▶ Зашёл на конференцию *{lesson_name}* в *{nowtime(False, False, False)}* {profilename}") - - appendLog(f'joined lesson {lesson_name} at {nowtime(False, False, False)}') - - rpc.onLesson(lesson_name, start_time_unix) - - if lesson_obs: - try: - obs_process = subprocess.Popen(getConfig("obs_exe"), cwd=getConfig("obs_core")) - appendLog(f'Sent instruction to open OBS') - time.sleep(5) - except Exception as exp: - appendLog(f'Failed to open OBS: {exp}') - print(f'{nowtime()} Не удалось открыть OBS для записи.') - else: - if getConfig("debug"): - print(f'{nowtime()} Не включаем OBS для записи.') - - firstshow = False - - if lesson_obs: - if not record_now: - keyboard.press(start) - time.sleep(.25) - keyboard.release(start) - record_now = True - print(f'{nowtime()} Сигнал записи OBS отправлен.') - playSound("recordstart") - - lesson_duration = (datetime.now() - lesson_start).total_seconds() - - if getConfig("debug"): - print(f'{nowtime()} Zoom подключён. Конференция идёт уже {BGREEN}{str(lesson_duration)} сек{RESET}. ({BGREEN}{str(round(lesson_duration/60, 2))} мин{RESET}.)') - - time.sleep(5) - continue - else: - i += 1 - appendLog(f'CptHost.exe not found, trying again in 10 seconds') - - if getConfig("debug"): - print(f'{nowtime()} {BRED}Конференция не обнаружена! {RESET}Повторная проверка через {BRED}10 {RESET}секунд...') - - time.sleep(10) - continue - - if getConfig("debug"): - print(f'{nowtime()} Zoom отключился. Процесс {BRED}CptHost.exe{RESET} более не существует.') - - appendLog(f'CptHost.exe not found, Zoom disconnected') - - if getConfig("debug"): - tgsend(getConfig("telegram_enabled"), f"◀ Конференция *{lesson_name}* длилась *{str(round(lesson_duration/60, 2))}* мин.") - print(f'{nowtime()} Конференция длилась {BGREEN}{str(lesson_duration)} сек{RESET}. ({BGREEN}{str(round(lesson_duration/60, 2))} мин{RESET}.)') - else: - tgsend(getConfig("telegram_enabled"), f"◀ Конференция *{lesson_name}* длилась *{str(int(lesson_duration/60))}* мин.") - print(f'{nowtime()} Конференция длилась {BGREEN}{str(lesson_duration)} сек{RESET}. ({BGREEN}{str(int(lesson_duration/60))} мин{RESET}.)') - - appendLog(f'Lesson {lesson_name} duration was {str(int(lesson_duration/60))} m. ({str(lesson_duration)} s.)') - - playSound("ended") + appendLog(f'Joined lesson {lesson_name} at {nowtime(False, False, False)}') - if lesson_obs: - keyboard.press(stop) - time.sleep(.25) - keyboard.release(stop) - print(f'{nowtime()} Сигнал остановки записи через OBS отправлен.') - playSound("recordstop") - record_now = False - time.sleep(3) - - try: - obs_process.terminate() - except Exception as exp: - appendLog(f'Failed to stop OBS process: {exp}') - - if getConfig("debug"): - print(f'{nowtime()} Не удалось остановить процесс OBS.') - if not lesson_repeat: del lessons_list[lessons_list.index(les)] @@ -1614,21 +580,13 @@ def main(source='deamon'): if getConfig("debug"): print(f'{nowtime()} Конференция {CYAN}{lesson_name}{RESET} в {BRED}{lesson_time}{RESET} удалена.') - print(f'\n{BBLACK}================================================{RESET}\n\n') - - firstshow = True - - lessons_count = lessons_count+1 - break - - record_now = False - retries = 0 - destroy = False - lessons_list = getLessons() + lessons_list = getLessons() except KeyboardInterrupt: appendLog('Lessons waiting reset') + setTitle("Ожидание конференции сбошено", sysname) + if getConfig("debug"): print(f'{nowtime()} Ожидание конференции сброшено.') else: @@ -1640,6 +598,7 @@ def main(source='deamon'): time.sleep(3) appendLog('Could not find any more lessons today') print(f'{nowtime()} Конференций нет или же все в списке закончились.') + setTitle('Конференции закончились, режим ожидания', sysname) if lessons_count > 0: if getConfig("shutdown_enabled"): @@ -1650,7 +609,7 @@ def main(source='deamon'): appendLog(f'Shutting PC down in {str(getConfig("shutdown_timeout"))}') - playSound("shutdown") + playSound("shutdown", nowtime()) end_unix = int(time.time())+getConfig("shutdown_timeout")*60 rpc.shutdown(end_unix) shutdown = inputimeout(prompt=f'{nowtime()} Нажмите {CYAN}Enter{RESET} чтобы предотвратить выключение ПК...', timeout=getConfig("shutdown_timeout")*60) @@ -1691,7 +650,7 @@ def main(source='deamon'): exit = input(f'{nowtime()} Программа завершена! Нажмите {CYAN}Enter{RESET} чтобы вернуться в меню...') rpc.inMenu() clear() - os.system("title AutoZoom (Главная)") + setTitle("AutoZoom (Главная)", sysname) return except KeyboardInterrupt: if source == 'deamon': @@ -1712,7 +671,8 @@ def main(source='deamon'): return if __name__ == '__main__': - os.system("title AutoZoom (Демон)") + from functions import getOS, setTitle + setTitle("AutoZoom (Демон)", getOS()) import sys clear() diff --git a/editor.py b/editor.py new file mode 100644 index 0000000..652088d --- /dev/null +++ b/editor.py @@ -0,0 +1,642 @@ +import rpc +from functions import * +from datetime import datetime, date, timedelta +from daemon import getLessons, getConfig + +if getConfig("use_colors"): + from colors import * + appendLog('Colors imported') +else: + RESET = '' + BLACK = RED = GREEN = YELLOW = BLUE = MAGENTA = CYAN = WHITE = '' + BBLACK = BRED = BGREEN = BYELLOW = BBLUE = BMAGENTA = BCYAN = BWHITE = '' + ULINE = REVERSE = '' + appendLog('Loading without colors') + + +def listLessons(from_where='remove'): + + try: + + appendLog('Showing list of everything planned') + + if from_where == 'editor': + print(f'{RESET}Полный список запланированных конференций:\n') + + print(f'{BBLACK}================================================{RESET}') + for les in enumerate(getLessons()): + + if les[1]["repeat"]: + repeat = 'Вкл.' + else: + repeat = 'Выкл.' + + if les[1]["record"]: + record = 'Вкл.' + else: + record = 'Выкл.' + + try: + repeat_day = getDay(les[1]["repeat_day"]) + except: + repeat_day = 'Не повторяется' + + length = len(str(les[0])) + + spacer_all = 6 * ' ' + spacer_ind = (5 - length) * ' ' + + + print(f'{spacer_all}Имя: {YELLOW}{les[1]["name"]}{RESET}') + print(f'{spacer_all}Дата: {YELLOW}{les[1]["date"]}{RESET}') + print(f'{spacer_all}Время: {YELLOW}{les[1]["time"]}{RESET}') + print(f' {GREEN}{les[0]}{RESET}{spacer_ind}Ссылка: {YELLOW}{les[1]["link"]}{RESET}') + print(f'{spacer_all}Повтор: {YELLOW}{repeat}{RESET}') + print(f'{spacer_all}День: {YELLOW}{repeat_day}{RESET}') + print(f'{spacer_all}Запись: {YELLOW}{record}{RESET}') + print(f'{BBLACK}================================================{RESET}') + + if from_where == 'editor': + none = input('\n\n > ') + + except KeyboardInterrupt: + clear() + return + + +def sortLessons(dictionary): + dictionary.sort(key = lambda x: datetime.strptime(x['time'], '%H:%M')) + dictionary.sort(key = lambda x: datetime.strptime(x['date'], '%d.%m.%Y')) + appendLog('Lessons dictionary sorted') + + +def getDay(number): + if number == 1: + return 'Понедельник' + if number == 2: + return 'Вторник' + if number == 3: + return 'Среда' + if number == 4: + return 'Четверг' + if number == 5: + return 'Пятница' + if number == 6: + return 'Суббота' + if number == 7: + return 'Воскресенье' + + +def addLesson(): + appendLog('Adding new lesson') + + try: + local_lessons = {} + lessons_got = getLessons() + + lessname = input(f'{RESET}Введите (своё) имя конференции:\n{BBLACK}Нужно лишь для отображения в Discord и самом AutoZoom{RESET}\n\n > {CYAN}') + local_lessons.update({"name": lessname}) + + while True: + clear() + today = date.today() + today_1 = date.today() + timedelta(days=1) + today_2 = date.today() + timedelta(days=2) + today_3 = date.today() + timedelta(days=3) + today_4 = date.today() + timedelta(days=4) + today_5 = date.today() + timedelta(days=5) + today_6 = date.today() + timedelta(days=6) + + print(f'{RESET}Введите дату конференции или номер дня ({BRED}ДД.ММ.ГГГГ{RESET}):\n') + print(f' {BRED}1.{RESET} {today.strftime("%d.%m.%Y")} ({BGREEN}{getDay(datetime.strptime(today.strftime("%d.%m.%Y"), "%d.%m.%Y").isoweekday())}{RESET})') + print(f' {BRED}2.{RESET} {today_1.strftime("%d.%m.%Y")} ({BGREEN}{getDay(datetime.strptime(today_1.strftime("%d.%m.%Y"), "%d.%m.%Y").isoweekday())}{RESET})') + print(f' {BRED}3.{RESET} {today_2.strftime("%d.%m.%Y")} ({BGREEN}{getDay(datetime.strptime(today_2.strftime("%d.%m.%Y"), "%d.%m.%Y").isoweekday())}{RESET})') + print(f' {BRED}4.{RESET} {today_3.strftime("%d.%m.%Y")} ({BGREEN}{getDay(datetime.strptime(today_3.strftime("%d.%m.%Y"), "%d.%m.%Y").isoweekday())}{RESET})') + print(f' {BRED}5.{RESET} {today_4.strftime("%d.%m.%Y")} ({BGREEN}{getDay(datetime.strptime(today_4.strftime("%d.%m.%Y"), "%d.%m.%Y").isoweekday())}{RESET})') + print(f' {BRED}6.{RESET} {today_5.strftime("%d.%m.%Y")} ({BGREEN}{getDay(datetime.strptime(today_5.strftime("%d.%m.%Y"), "%d.%m.%Y").isoweekday())}{RESET})') + print(f' {BRED}7.{RESET} {today_6.strftime("%d.%m.%Y")} ({BGREEN}{getDay(datetime.strptime(today_6.strftime("%d.%m.%Y"), "%d.%m.%Y").isoweekday())}{RESET})') + + try: + lessdate = input(f'\n > {BRED}') + if lessdate == '': + finallessdate = lessons_got[edi]["date"] + elif lessdate == '1': + finallessdate = today.strftime("%d.%m.%Y") + elif lessdate == '2': + finallessdate = today_1.strftime("%d.%m.%Y") + elif lessdate == '3': + finallessdate = today_2.strftime("%d.%m.%Y") + elif lessdate == '4': + finallessdate = today_3.strftime("%d.%m.%Y") + elif lessdate == '5': + finallessdate = today_4.strftime("%d.%m.%Y") + elif lessdate == '6': + finallessdate = today_5.strftime("%d.%m.%Y") + elif lessdate == '7': + finallessdate = today_6.strftime("%d.%m.%Y") + else: + try: + test = (datetime.strptime(lessdate, "%d.%m.%Y")) + finallessdate = lessdate + except: + continue + + local_lessons.update({"date": finallessdate}) + + break + except: + continue + + while True: + clear() + try: + lesstime = input(f'{RESET}Введите время конференции ({BRED}ЧЧ:ММ{RESET}):\n\n > {BRED}') + finallesstime = (datetime.strptime(lesstime, "%H:%M")) + local_lessons.update({"time": lesstime}) + abort = "skip" + conflict = False + conflictles = '' + confstr = 'конференцией' + + try: + + for lesson in lessons_got: + + if lesson["date"] == finallessdate and lesson["time"] == lesstime: + conflict = True + + if conflictles == '': + conflictles = f'{CYAN}{lesson["name"]}{RESET}' + confstr = 'конференцией' + + else: + conflictles += f', {CYAN}{lesson["name"]}{RESET}' + confstr = 'конференциями' + + if conflict: + while True: + clear() + choice = input(f'{RESET}Время и дата конференции совпадают с {confstr} {conflictles}.\nДобавить ещё одну конференцию на то же время? ({BGREEN}Да{RESET}/{BRED}Нет{RESET})\n\n > ') + + if choice.lower() in yes_list: + abort = "bypass" + break + + elif choice.lower() in no_list: + abort = "restart" + break + + else: + continue + + if abort == "restart": + continue + else: + break + + except Exception as exp: + none = input(exp) + pass + + break + except: + continue + + clear() + lesslink = input(f'{RESET}Введите ссылку на конференцию:\n{BBLACK}Формат: {BRED}https://us01web.zoom.us/j/ИДЕНТИФИКАТОР?pwd=ПАРОЛЬ{RESET}\n{BBLACK}Либо введите {YELLOW}1 {BBLACK}для добавления по номеру и паролю{RESET}\n\n > {BRED}').replace(" ", "") + + if lesslink.replace(' ', '') == '1': + clear() + lessid = input(f'{RESET}Введите идентификатор конференции:\n{BBLACK}Формат: {BRED}012 3456 7890 {BBLACK} либо {BRED}01234567890{RESET}\n\n > {BRED}') + clear() + lesspasswd = input(f'{RESET}Введите код доступа (пароль) конференции:\n\n > {BRED}') + lesslink = f'https://us01web.zoom.us/j/{lessid.replace(" ", "")}?pwd={lesspasswd.replace(" ", "")}' + + local_lessons.update({"link": lesslink}) + + while True: + clear() + repeat = input(f'{RESET}Повторять эту конференцию ({getDay(getDayNum(finallessdate))})? {RESET}({BGREEN}Да{RESET}/{BRED}Нет{RESET})\n\n > ') + + if repeat.lower() in yes_list: + finalrepeat = True + finalrepeatday = getDayNum(finallessdate) + local_lessons.update({"repeat": finalrepeat}) + local_lessons.update({"repeat_day": finalrepeatday}) + break + elif repeat.lower() in no_list: + finalrepeat = False + finalrepeatday = None + local_lessons.update({"repeat": finalrepeat}) + local_lessons.update({"repeat_day": finalrepeatday}) + break + else: + continue + + while True: + if getOS() == "windows": + clear() + lessrecord = input(f'Записать эту конференцию? {RESET}({BGREEN}Да{RESET}/{BRED}Нет{RESET})\n\n > ') + + if lessrecord.lower() in yes_list: + finallessrecord = True + local_lessons.update({"record": finallessrecord}) + break + elif lessrecord.lower() in no_list: + finallessrecord = False + local_lessons.update({"record": finallessrecord}) + break + else: + continue + else: + finallessrecord = False + local_lessons.update({"record": finallessrecord}) + break + + + lessons_got.append(dict(local_lessons)) + sortLessons(lessons_got) + saveJson(files_folder+'lessons.json', lessons_got) + + clear() + print(f'Добавлена конференция {CYAN}{local_lessons["name"]}{RESET} за {BRED}{local_lessons["date"]}{RESET} на время {BRED}{local_lessons["time"]}{RESET}.') + appendLog(f'Added lesson {local_lessons["name"]} (Date: {local_lessons["date"]}, Time: {local_lessons["time"]}, Link: {local_lessons["link"]})') + none = input('\n > ') + + except KeyboardInterrupt: + appendLog('Lesson adding aborted') + clear() + return + + +def editLesson(): + appendLog(f'Editing existing lesson') + + try: + local_lessons = {} + lessons_got = getLessons() + + while True: + print(f'{RESET}Выберите номер (индекс) для изменения:\n') + listLessons() + lessons_got = getLessons() + + print(f'\nДля отмены операции введите {BRED}c{RESET} или {BRED}cancel{RESET}') + + edi = input(f'\n > {BGREEN}') + + if not isinstance(edi, int): + if edi.lower() == 'c' or edi.lower() == 'cancel': + clear() + return + try: + edi = int(edi) + except: + clear() + continue + + try: + probe = lessons_got[edi]["name"] + break + except: + clear() + print(f'{RESET}Выберите {ULINE}правильный{RESET} индекс (номер) для изменения.') + time.sleep(3) + clear() + continue + + break + + clear() + lessname = input(f'{RESET}Введите (своё) имя конференции:\n{BBLACK}Нужно лишь для отображения в Discord и самом AutoZoom{RESET}\n\nОригинальное имя: {CYAN}{lessons_got[edi]["name"]}{RESET}\n\n > {CYAN}') + if lessname == '': + lessname = lessons_got[edi]["name"] + local_lessons.update({"name": lessname}) + + while True: + clear() + today = date.today() + today_1 = date.today() + timedelta(days=1) + today_2 = date.today() + timedelta(days=2) + today_3 = date.today() + timedelta(days=3) + today_4 = date.today() + timedelta(days=4) + today_5 = date.today() + timedelta(days=5) + today_6 = date.today() + timedelta(days=6) + + print(f'{RESET}Введите дату конференции или номер дня ({BRED}ДД.ММ.ГГГГ{RESET}):\n') + print(f' {BRED}1.{RESET} {today.strftime("%d.%m.%Y")} ({BGREEN}{getDay(datetime.strptime(today.strftime("%d.%m.%Y"), "%d.%m.%Y").isoweekday())}{RESET})') + print(f' {BRED}2.{RESET} {today_1.strftime("%d.%m.%Y")} ({BGREEN}{getDay(datetime.strptime(today_1.strftime("%d.%m.%Y"), "%d.%m.%Y").isoweekday())}{RESET})') + print(f' {BRED}3.{RESET} {today_2.strftime("%d.%m.%Y")} ({BGREEN}{getDay(datetime.strptime(today_2.strftime("%d.%m.%Y"), "%d.%m.%Y").isoweekday())}{RESET})') + print(f' {BRED}4.{RESET} {today_3.strftime("%d.%m.%Y")} ({BGREEN}{getDay(datetime.strptime(today_3.strftime("%d.%m.%Y"), "%d.%m.%Y").isoweekday())}{RESET})') + print(f' {BRED}5.{RESET} {today_4.strftime("%d.%m.%Y")} ({BGREEN}{getDay(datetime.strptime(today_4.strftime("%d.%m.%Y"), "%d.%m.%Y").isoweekday())}{RESET})') + print(f' {BRED}6.{RESET} {today_5.strftime("%d.%m.%Y")} ({BGREEN}{getDay(datetime.strptime(today_5.strftime("%d.%m.%Y"), "%d.%m.%Y").isoweekday())}{RESET})') + print(f' {BRED}7.{RESET} {today_6.strftime("%d.%m.%Y")} ({BGREEN}{getDay(datetime.strptime(today_6.strftime("%d.%m.%Y"), "%d.%m.%Y").isoweekday())}{RESET})') + print(f'\nОригинальная дата: {BRED}{lessons_got[edi]["date"]}{RESET}') + + try: + lessdate = input(f'\n > {BRED}') + if lessdate == '': + finallessdate = lessons_got[edi]["date"] + elif lessdate == '1': + finallessdate = today.strftime("%d.%m.%Y") + elif lessdate == '2': + finallessdate = today_1.strftime("%d.%m.%Y") + elif lessdate == '3': + finallessdate = today_2.strftime("%d.%m.%Y") + elif lessdate == '4': + finallessdate = today_3.strftime("%d.%m.%Y") + elif lessdate == '5': + finallessdate = today_4.strftime("%d.%m.%Y") + elif lessdate == '6': + finallessdate = today_5.strftime("%d.%m.%Y") + elif lessdate == '7': + finallessdate = today_6.strftime("%d.%m.%Y") + else: + try: + test = (datetime.strptime(lessdate, "%d.%m.%Y")) + finallessdate = lessdate + except: + continue + + local_lessons.update({"date": finallessdate}) + + break + except: + continue + + while True: + clear() + try: + lesstime = input(f'{RESET}Введите время конференции ({BRED}ЧЧ:ММ{RESET}):\n\nОригинальное время: {BRED}{lessons_got[edi]["time"]}{RESET}\n\n > {BRED}') + finallesstime = (datetime.strptime(lesstime, "%H:%M")) + local_lessons.update({"time": lesstime}) + abort = "skip" + conflict = False + conflictles = '' + confstr = 'конференцией' + + try: + + for lesson in lessons_got: + + if lesson["date"] == finallessdate and lesson["time"] == lesstime: + conflict = True + + if conflictles == '': + conflictles = f'{CYAN}{lesson["name"]}{RESET}' + confstr = 'конференцией' + + else: + conflictles += f', {CYAN}{lesson["name"]}{RESET}' + confstr = 'конференциями' + + if conflict: + while True: + clear() + choice = input(f'{RESET}Время и дата конференции совпадают с {confstr} {conflictles}.\nДобавить ещё одну конференцию на то же время? ({BGREEN}Да{RESET}/{BRED}Нет{RESET})\n\n > ') + + if choice.lower() in yes_list: + abort = "bypass" + break + + elif choice.lower() in no_list: + abort = "restart" + break + + else: + continue + + if abort == "restart": + continue + else: + break + + except Exception as exp: + none = input(exp) + pass + + break + except: + continue + + clear() + lesslink = input(f'{RESET}Введите ссылку на конференцию:\n{BBLACK}Формат: {BRED}https://us01web.zoom.us/j/ИДЕНТИФИКАТОР?pwd=ПАРОЛЬ{RESET}\n{BBLACK}Либо введите {YELLOW}1 {BBLACK}для добавления по номеру и паролю{RESET}\n\n > {BRED}').replace(" ", "") + + if lesslink.replace(' ', '') == '1': + clear() + lessid = input(f'{RESET}Введите идентификатор конференции:\n{BBLACK}Формат: {BRED}012 3456 7890 {BBLACK} либо {BRED}01234567890{RESET}\n\n > {BRED}') + clear() + lesspasswd = input(f'{RESET}Введите код доступа (пароль) конференции:\n\n > {BRED}') + lesslink = f'https://us01web.zoom.us/j/{lessid.replace(" ", "")}?pwd={lesspasswd.replace(" ", "")}' + + if lesslink == '': + lesslink = lessons_got[edi]["link"] + + local_lessons.update({"link": lesslink}) + + while True: + clear() + try: + lessrepeatday = getDay(lessons_got[edi]["repeat_day"]) + except: + lessrepeatday = 'Не повторяется' + + print(f'{RESET}Повторять эту конференцию ({YELLOW}{getDay(getDayNum(finallessdate))}{RESET})? {RESET}({BGREEN}Да{RESET}/{BRED}Нет{RESET})') + print(f'\nОригинальное значение: {BRED}{lessrepeatday}{RESET}') + repeat = input('\n > ') + + if repeat.lower() in yes_list: + finalrepeat = True + finalrepeatday = getDayNum(finallessdate) + local_lessons.update({"repeat": finalrepeat}) + local_lessons.update({"repeat_day": finalrepeatday}) + break + elif repeat.lower() in no_list: + finalrepeat = False + local_lessons.update({"repeat": finalrepeat}) + break + elif repeat == '': + finalrepeat = lessons_got[edi]["repeat"] + local_lessons.update({"repeat": finalrepeat}) + try: + finalrepeatday = lessons_got[edi]["repeat_day"] + local_lessons.update({"repeat_day": finalrepeatday}) + except: + pass + break + else: + continue + + while True: + if getOS() == "windows": + clear() + print(f'Записать эту конференцию? {RESET}({BGREEN}Да{RESET}/{BRED}Нет{RESET})') + print(f'\nОригинальное значение: {BRED}{lessons_got[edi]["record"]}{RESET}') + lessrecord = input('\n > ') + + if lessrecord.lower() in yes_list: + finallessrecord = True + local_lessons.update({"record": finallessrecord}) + break + elif lessrecord.lower() in no_list: + finallessrecord = False + local_lessons.update({"record": finallessrecord}) + break + elif lessrecord == '': + finallessrecord = lessons_got[edi]["record"] + local_lessons.update({"record": finallessrecord}) + break + else: + continue + else: + finallessrecord = False + local_lessons.update({"record": finallessrecord}) + break + + del lessons_got[edi] + lessons_got.append(dict(local_lessons)) + sortLessons(lessons_got) + saveJson(files_folder+'lessons.json', lessons_got) + clear() + print(f'Изменена конференция {CYAN}{lessname}{RESET} за {BRED}{finallessdate}{RESET} на время {BRED}{finallesstime}{RESET}.') + appendLog(f'Edited lesson {lessname} (Date: {finallessdate}, Time: {finallesstime}, Link: {local_lessons["link"]})') + none = input('\n > ') + + except KeyboardInterrupt: + appendLog('Editing existing lesson aborted') + clear() + return + + +def removeLesson(): + appendLog(f'Removing existing lesson') + + try: + while True: + print(f'{RESET}Выберите номер (индекс) для удаления:\n') + listLessons() + lessons_local = getLessons() + print(f'\n{BBLACK}Для отмены операции введите {BRED}c{BBLACK} или {BRED}cancel{RESET}') + + rem = input(f'\n > {BRED}') + + if rem.lower() == 'c' or rem.lower() == 'cancel': + clear() + break + else: + try: + rem = int(rem) + except: + clear() + continue + + try: + del_name = lessons_local[rem]["name"] + del_date = lessons_local[rem]["date"] + del_time = lessons_local[rem]["time"] + del lessons_local[rem] + except: + clear() + print(f'{RESET}Выберите {ULINE}правильный{RESET} индекс (номер) для удаления.') + time.sleep(3) + clear() + continue + + sortLessons(lessons_local) + saveJson(files_folder+'lessons.json', lessons_local) + clear() + print(f'{RESET}Удалена конференция {CYAN}{del_name}{RESET} за {BRED}{del_date}{RESET} на время {BRED}{del_time}{RESET}.') + appendLog(f'Removed lesson {del_name} (Date: {del_date}, Time: {del_time})') + none = input('\n > ') + break + except KeyboardInterrupt: + appendLog('Lesson removal aborted') + clear() + return + + +def removeAllLessons(): + appendLog('Removing all lessons') + + try: + while True: + clear() + removeall = input(f'{RESET}Вы уверены что хотите удалить все конференции? {RESET}({BGREEN}Да{RESET}/{BRED}Нет{RESET})\n{BRED}Внимание!{RESET} Это действие нельзя обратить!\nВаши настройки затронуты НЕ будут.\n\n > ') + + if removeall.lower() in yes_list: + with open(files_folder+'lessons.json', 'w', encoding="utf-8") as f: + f.write("[]") + f.close() + + appendLog('All lessons removed') + clear() + none = input('Все конференции были удалены.\n\n > ') + clear() + break + elif removeall.lower() in no_list: + appendLog('All lessons removal aborted') + clear() + break + else: + continue + + except KeyboardInterrupt: + appendLog('All lessons removal aborted') + + clear() + return + + +def editor(): + try: + setTitle("AutoZoom (Редактор)", getOS()) + appendLog('Editor menu opened') + + from main import mainMenu + + while True: + clear() + + print(f'{BBLACK}»{RESET} Меню редактора\n') + print(f' {BRED}1.{RESET} Добавить конференцию') + print(f' {BRED}2.{RESET} Изменить конференцию') + print(f' {BRED}3.{RESET} Удалить конференцию') + print(f' {BRED}4.{RESET} Посмотреть конференции') + print(f' {BRED}5.{RESET} Удалить все конференции') + print(f' {BRED}6.{RESET} В главное меню') + editor_choose = input(f'\n > {BRED}') + + if editor_choose == '1': + appendLog('Went to lesson adding') + clear() + addLesson() + elif editor_choose == '2': + appendLog('Went to lesson editing') + clear() + editLesson() + elif editor_choose == '3': + appendLog('Went to lesson removal') + clear() + removeLesson() + elif editor_choose == '4': + appendLog('Went to lesson lising') + clear() + listLessons(from_where = 'editor') + elif editor_choose == '5': + appendLog('Went to all lessons removal') + clear() + removeAllLessons() + elif editor_choose == '6': + appendLog('Exiting back to main menu') + rpc.inMenu() + clear() + setTitle("AutoZoom (Главная)", getOS()) + mainMenu() + else: + continue + + except KeyboardInterrupt: + appendLog('Exiting back to main menu') + rpc.inMenu() + clear() + return \ No newline at end of file diff --git a/functions.py b/functions.py index 1dcca8c..ef16d6f 100644 --- a/functions.py +++ b/functions.py @@ -6,19 +6,24 @@ import json import os import shutil import gzip +import getpass from datetime import datetime from pathlib import Path +from subprocess import check_output path = Path(__file__).resolve().parent sounds_folder = str(Path(str(path)+"/sounds/")) + os.sep files_folder = str(Path(str(path)+"/files/")) + os.sep logs_folder = str(Path(str(path)+"/logs/")) + os.sep +yes_list = ['y', 'yes', 'д', 'да'] +no_list = ['n', 'no', 'н', 'нет'] default_config = { + "firstboot": True, "debug": False, "shutdown_timeout": 30, - "shutdown_enabled": True, + "shutdown_enabled": False, "start": "shift+f7", "stop": "shift+f8", "telegram_enabled": False, @@ -35,6 +40,51 @@ default_config = { } +# Функция возвращающая надпись Windows Only +def winOnly(color, reset, system, start='', end=''): + + if system != 'windows': + return f"{start}{color}Только для Windows!{reset}{end}" + + else: + return "" + + +# Функция возвращающая тип ОС +def getOS(): + + if os.name == 'nt': + return "windows" + + elif 'android' in str(check_output('uname -a', shell=True).lower()): + return "android" + + else: + return "unix" + + +# Функция отвечает за очищение командной строки +if getOS() == "windows": + clear = lambda: os.system('cls') +else: + clear = lambda: os.system('clear') + + +# Установка заголовка окна cmd.exe +def setTitle(title, system): + if system == "windows": + try: + os.system(f"title {title}") + except: + pass + + +# Получить номер дня недели +def getDayNum(day): + output = datetime.strptime(day, "%d.%m.%Y").isoweekday() + return output + + # Функция проверки размера файла def checkSize(): global logs_folder @@ -79,7 +129,7 @@ def checkSize(): # Функция добавления в лог -def appendLog(message): +def appendLog(message, startup=False, shutdown=False): if getConfig("write_logs"): @@ -99,42 +149,188 @@ def appendLog(message): time.sleep(2) print('Log file could not be created') - log.write(f'[{datetime.now().strftime("%H:%M:%S | %d.%m.%Y")}] {message}\n') + if startup: + log.write(f'[{datetime.now().strftime("%H:%M:%S | %d.%m.%Y")}] [STARTUP] {message}\n') + elif shutdown: + log.write(f'[{datetime.now().strftime("%H:%M:%S | %d.%m.%Y")}] [SHUTDOWN] {message}\n') + else: + log.write(f'[{datetime.now().strftime("%H:%M:%S | %d.%m.%Y")}] {message}\n') + log.close() +# Функция проигрывания звука +def playSound(soundname, timing=''): + + global sysname + + if getConfig("sounds"): + + if getOS() == "windows": + + try: + winsound.PlaySound(sounds_folder+soundname+".wav", winsound.SND_FILENAME) + + except Exception as exp: + appendLog(f'Could not play winsound: {exp}') + + if getConfig("debug"): + print(f'{timing} Не удалось проиграть winsound звук "{soundname}" (Ошибка: {exp})') + + try: + playsound(sounds_folder+soundname+".wav") + + except Exception as exp: + appendLog(f'Could not play playsound: {exp}') + + if getConfig("debug"): + print(f'{timing} Не удалось проиграть playsound звук "{soundname}" (Ошибка: {exp})') + + elif getOS() == "android": + + try: + os.system(f'play-audio {sounds_folder}{soundname}.wav') + + except Exception as exp: + appendLog(f'Could not play play-audio: {exp}') + + else: + + try: + playsound(sounds_folder+soundname+".wav") + + except Exception as exp: + appendLog(f'Could not play playsound: {exp}') + + if getConfig("debug"): + print(f'{timing} Не удалось проиграть playsound звук "{soundname}" (Ошибка: {exp})') + + # Функция добавления переменных, если их нет def repairConfig(some_dic): + global files_folder global default_config - for key in some_dic: + for key in default_config: + try: some_dic[key] - except NameError: - some_dic[key] = default_config[key] + except KeyError: + some_dic[key] = default_config[key] saveJson(files_folder+'config.json', some_dic) - -def getConfig(some_var): + +# Функция изменения переменной конфигурации +def setConfig(some_var, some_val): + global files_folder global default_config if os.path.exists(files_folder): + + if not os.path.exists(files_folder+'config.json'): + + temp_config_list = default_config + temp_config_list[some_var] = some_val + + saveJson(files_folder+'config.json', temp_config_list) + + else: + + try: + + with open(f"{files_folder}config.json", encoding="utf-8") as json_file: + + config_list = json.load(json_file) + json_file.close() + + try: + config_list[some_var] = some_val + saveJson(files_folder+'config.json', config_list) + appendLog(f'Changed variable "{somevar}" to {some_val}') + + except: + + try: + repairConfig(config_list) + config_list = json.load(json_file) + json_file.close() + config_list[some_var] = some_val + saveJson(files_folder+'config.json', config_list) + appendLog(f'Changed variable "{somevar}" to {some_val}') + + except: + pass + except: + + return "Error" + else: + os.mkdir(files_folder) + + if not os.path.exists(files_folder+'config.json'): + + temp_config_list = default_config + temp_config_list[some_var] = some_val + + saveJson(files_folder+'config.json', temp_config_list) + + else: + + try: + with open(f"{files_folder}config.json", encoding="utf-8") as json_file: + + config_list = json.load(json_file) + json_file.close() + + try: + config_list[some_var] = some_val + saveJson(files_folder+'config.json', config_list) + + except: + + try: + repairConfig(config_list) + config_list = json.load(json_file) + json_file.close() + config_list[some_var] = some_val + saveJson(files_folder+'config.json', config_list) + appendLog(f'Changed variable "{somevar}" to {some_val}') + + except: + config_list[some_var] = some_val + saveJson(files_folder+'config.json', config_list) + appendLog(f'Changed variable "{somevar}" to {some_val}') + + except: + return "Error" + + +# Функция получения переменной конфигурации +def getConfig(some_var): + + global files_folder + global default_config + + if os.path.exists(files_folder): + if not os.path.exists(files_folder+'config.json'): temp_config_list = default_config saveJson(files_folder+'config.json', temp_config_list) return temp_config_list[some_var] + else: try: with open(f"{files_folder}config.json", encoding="utf-8") as json_file: + config_list = json.load(json_file) json_file.close() try: return config_list[some_var] + except: try: repairConfig(config_list) @@ -153,6 +349,7 @@ def getConfig(some_var): saveJson(files_folder+'config.json', temp_config_list) return temp_config_list[some_var] else: + try: with open(f"{files_folder}config.json", encoding="utf-8") as json_file: config_list = json.load(json_file) @@ -160,19 +357,45 @@ def getConfig(some_var): try: return config_list[some_var] + except: try: repairConfig(config_list) config_list = json.load(json_file) json_file.close() return config_list[some_var] - except: - return default_config[some_var] + except: + return default_config[some_var] except: return "Error" +# Получить статус процесса +def getState(process="CptHost.exe"): + + if getOS() == 'windows': + + try: + output = os.popen(f'tasklist /fi "IMAGENAME eq {process}" /fi "USERNAME ne NT AUTHORITY\{getpass.getuser()}"').read() + + if process in output: + return True + else: + return False + + except Exception as exp: + appendLog(f'Failed to get state using tasklist: {exp}') + + output = os.popen('wmic process get description, processid').read() + + if "CptHost.exe" in output: + return True + else: + return False + + +# Функция сохранения информации в json файл def saveJson(filename, value): with open(filename, 'w', encoding="utf-8") as f: json.dump(value, f, indent=4, ensure_ascii=False) diff --git a/libinstaller.py b/libinstaller.py index 3b3c8be..c67344d 100644 --- a/libinstaller.py +++ b/libinstaller.py @@ -2,37 +2,75 @@ import os, sys from colors import * -from functions import getConfig +from functions import getConfig, setConfig, getOS, yes_list, no_list from functions import appendLog +from subprocess import check_output -# Работает не очень стабильно при отсутствии интернета -# try: - # if getConfig("debug"): - # updatepip = os.system('"{}" -m pip install -U '.format(sys.executable) + '--upgrade pip') - # print(f"{RESET}[{BGREEN}OK{RESET}] Обновлён {YELLOW}PIP{RESET}.") - # else: - # updatepip = os.system('"{}" -m pip install -U '.format(sys.executable) + '--upgrade pip' + " -q --no-warn-script-location") - # print(f"{RESET}[{BGREEN}OK{RESET}] Обновлён {YELLOW}PIP{RESET}.") -# except: - # updatepip = os.system('"{}" -m pip install -U '.format(sys.executable) + '--upgrade pip' + " -q --no-warn-script-location") - -# if updatepip != 0: - # sys.exit(f"{RESET}[{BRED}ERR{RESET}] Обновление {YELLOW}PIP {RESET}провалилось.") +if getConfig("firstboot"): + + if getOS() == "android": + while True: + os.system('clear') + confirmation = input(f'{BRED}Внимание! {RESET}AutoZoom практически не оптимизирован под {CYAN}Android{RESET}.\nПродолжая использовать программу на ОС кроме {CYAN}Windows {RESET}вы действуете на свой страх и риск.\nПолноценная поддержка операционной системы Android не планируется.\nДля хоть какой-то работы нужно установить Zoom\nи заранее его настроить.\n\nВведите {BGREEN}Да {RESET}если вас не пугает указанное выше.\nВведите {BRED}Нет {RESET}если вас это не устраивает, программа сама закроется.\n\n > ') + + if confirmation.lower() in yes_list: + setConfig("firstboot", False) + setConfig("obs_core", "Disabled") + setConfig("obs_exe", "Disabled") + setConfig("use_rpc", False) + break + + elif confirmation.lower() in no_list: + setConfig("firstboot", True) + sys.exit() + break + + else: + continue + + elif getOS() == "unix": + while True: + os.system('clear') + confirmation = input(f'{BRED}Внимание! {RESET}AutoZoom плохо оптимизирован под {CYAN}Linux {RESET}и {CYAN}MacOS{RESET}.\nПродолжая использовать программу на ОС кроме {CYAN}Windows {RESET}вы действуете на свой страх и риск.\nПолноценная поддержка UNIX систем реализована не будет.\nДля хоть какой-то работы нужно установить Zoom\nи заранее его настроить.\n\nВведите {BGREEN}Да {RESET}если вас не пугает указанное выше.\nВведите {BRED}Нет {RESET}если вас это не устраивает, программа сама закроется.\n\n > ') + + if confirmation.lower() in yes_list: + setConfig("firstboot", False) + setConfig("obs_core", "Disabled") + setConfig("obs_exe", "Disabled") + break + + elif confirmation.lower() in no_list: + setConfig("firstboot", True) + sys.exit() + break + + else: + continue + + elif getOS() == "windows": + setConfig("firstboot", False) ######################################################### libs = [] ################################### -try: - import easygui -except ModuleNotFoundError: - appendLog("No module easygui") - libs.append("easygui") -################################### -try: - import tkinter -except ModuleNotFoundError: - appendLog("No module tkinter") - libs.append("tkinter") +if getOS() == "windows": + try: + import easygui + except ModuleNotFoundError: + appendLog("No module easygui") + libs.append("easygui") + ################################### + try: + import tkinter + except ModuleNotFoundError: + appendLog("No module tkinter") + libs.append("tkinter") + ################################### + try: + from swinlnk.swinlnk import SWinLnk + except ModuleNotFoundError: + appendLog("No module swinlnk") + libs.append("swinlnk") ################################### try: import keyboard @@ -70,11 +108,17 @@ except ModuleNotFoundError: appendLog("No module requests") libs.append("requests") ################################### -try: - import playsound -except ModuleNotFoundError: - appendLog("No module playsound") - libs.append("playsound") +if getOS() != "android": + try: + from playsound import playsound + except ModuleNotFoundError: + appendLog("No module playsound") + libs.append("playsound") +else: + try: + os.system('pkg install play-audio') + except: + appendLog("Could not install play-audio") ################################### try: from zipfile import ZipFile @@ -100,6 +144,7 @@ except ModuleNotFoundError: appendLog("No module pypresence") libs.append("pypresence") ################################### + if len(libs) > 0: print("Не хватает нужных модулей, пробуем установить...\nЭто может занять некоторое время. Пожалуйста, не закрывайте программу.") appendLog('Missing some modules, trying to install them') @@ -125,19 +170,26 @@ if len(libs) > 0: print(f"{RESET}[{BGREEN}OK{RESET}] Все модули были успешно установлены.") try: - import easygui - import tkinter + if getOS() == "windows": + import easygui + import tkinter + from swinlnk.swinlnk import SWinLnk + import keyboard import ast import inputimeout import telegram_send import wget import requests - import playsound import asyncio import getpass + + if getOS() != "android": + from playsound import playsound + from zipfile import ZipFile from pypresence import Presence + except ModuleNotFoundError: sys.exit(f"\n#############################################################################\n{BGREEN} Пожалуйста, перезапустите программу для продолжения!{RESET}\n Если это сообщение видно не впервые - напишите {BRED}@profitroll {RESET}в {CYAN}Telegram {RESET}или\n включите {BRED}debug {RESET}в {BRED}files/config.json {RESET}и решите проблему самостоятельно.\n#############################################################################") ######################################################### \ No newline at end of file diff --git a/main.py b/main.py index be60ae3..83f8b85 100644 --- a/main.py +++ b/main.py @@ -11,9 +11,13 @@ from pathlib import Path from functions import * -os.system("title") +appendLog('main.py start initialized', startup=True) -from daemon import main, editor, settings, clear +setTitle("", getOS()) + +from daemon import main +import settings +import editor import rpc if getConfig("use_colors"): @@ -32,12 +36,12 @@ import keyboard import getpass from zipfile import ZipFile -version = 2.0 +version = 2.1 path = Path(__file__).resolve().parent def mainMenu(): try: - os.system("title AutoZoom (Главная)") + setTitle("AutoZoom (Главная)", getOS()) global version global path @@ -50,29 +54,41 @@ def mainMenu(): print(f'{RESET}Загрузка данных о последней версии...') try: - os.system("title Загрузка данных...") + setTitle("Загрузка данных...", getOS()) serv_ver = requests.get("https://www.end-play.xyz/AutoZoomVersion.txt").text - os.system("title AutoZoom (Главная)") + setTitle("AutoZoom (Главная)", getOS()) + ignore = False clear() except Exception as exp: appendLog(f'Version number load failed {exp}') - os.system("title Ошибка загрузки данных") + setTitle("Ошибка загрузки данных", getOS()) print(f'Не удалось загрузить данные о последней версии.\nПроверьте подключение к сети и повторите попытку.\n\nСтатус сервера центра обновлений:\n{BRED}https://status.end-play.xyz/786373747{RESET}') - none = input('\n > ') - rpc.disconnect() - sys.exit() + + todo = input(f'\nВведите {BRED}ignore {RESET}чтобы выключить проверку обновлений и продолжить\nлибо введите что угодно иное чтобы закрыть программу.\n\n > {BRED}') + + if todo.lower() == 'ignore': + setConfig("update_check", False) + serv_ver = '' + appendLog('Skipping update check') + setTitle("AutoZoom (Главная)", getOS()) + ignore = True + clear() + else: + rpc.disconnect() + sys.exit() - if float(serv_ver) > float(version): + if ignore == False and float(serv_ver) > float(version): show_version = f' ({BRED}!{RESET})' else: show_version = '' else: - os.system("title AutoZoom (Главная)") - show_version = '' + show_version = f' ({BRED}!{RESET})' + setTitle("AutoZoom (Главная)", getOS()) serv_ver = 'disabled' appendLog('Skipping update check') + clear() print(f'{BBLACK}»{RESET} Главное меню\n') print(f' {BRED}1.{RESET} Запуск') @@ -81,7 +97,11 @@ def mainMenu(): print(f' {BRED}4.{RESET} Обновление{show_version}') print(f' {BRED}5.{RESET} Помощь и связь') print(f' {BRED}6.{RESET} Закрыть приложение') - menu_choose = input(f'\n > {BRED}') + + if getConfig("debug"): + print(f' {BRED}10.{RESET} Меню разработчика') + + menu_choose = input(f'\n {RESET}> {BRED}') print(RESET) if menu_choose == '1': @@ -90,11 +110,11 @@ def mainMenu(): elif menu_choose == '2': appendLog('Went to editor') rpc.inEditor() - editor() + editor.editor() elif menu_choose == '3': appendLog('Went to settings') rpc.inSettings() - settings() + settings.settings() elif menu_choose == '4': appendLog('Went to updater') rpc.inUpdater() @@ -104,10 +124,17 @@ def mainMenu(): rpc.inHelp() helpMenu() elif menu_choose == '6': - appendLog('Exited AutoZoom') + appendLog('Exited AutoZoom from main menu', shutdown=True) rpc.disconnect() clear() sys.exit() + elif menu_choose == '10': + if getConfig("debug"): + appendLog('Went to help') + rpc.inDebug() + devMenu() + else: + clear() else: clear() continue @@ -128,7 +155,7 @@ def os_arch(): def helpMenu(): try: while True: - os.system("title AutoZoom (Помощь)") + setTitle("AutoZoom (Помощь)", getOS()) appendLog('Help menu opened') clear() global version @@ -142,6 +169,7 @@ def helpMenu(): print(f' {BRED}5.{RESET} Связаться с автором') print(f' {BRED}6.{RESET} Сводка информации') print(f' {BRED}7.{RESET} В главное меню') + help_choose = input(f'\n > {BRED}') if help_choose == '1': @@ -196,7 +224,18 @@ def helpMenu(): clear() if help_choose == '6': clear() - appendLog(f'Showing system information:\n=============================================\nHelpful data for fault search:\n\nOS: {platform.system()}\nRelease: {platform.release()}\nArch: {os_arch()}\nPy Ver: {platform.python_version()}\nPIP Ver: {pip.__version__}\nImpl: {platform.python_implementation()}\nRev: {platform.python_revision()}\nPy Path: {sys.path[4]}\nAZ Ver: {version}\nAZ User: {getpass.getuser()}\nAZ Path: {path}\n=============================================') + + if getState("RBTray.exe"): + rbtray = f'{BGREEN}Активен{RESET}' + else: + rbtray = f'{BRED}Неактивен{RESET}' + + if rpc.connected: + dsrpc = f'{BGREEN}Активен{RESET}' + else: + dsrpc = f'{BRED}Неактивен{RESET}' + + appendLog(f'Showing system information:\n=============================================\nHelpful data for fault search:\n\nOS: {platform.system()}\nRelease: {platform.release()}\nArch: {os_arch()}\nPy Ver: {platform.python_version()}\nPIP Ver: {pip.__version__}\nImpl: {platform.python_implementation()}\nRev: {platform.python_revision()}\nPy Path: {sys.path[4]}\nAZ Ver: {version}\nAZ User: {getpass.getuser()}\nAZ User Home: {Path.home()}\nAZ Path: {path}\nRBTray: {str(getState("RBTray.exe"))}\nRPC: {str(rpc.connected)}\n=============================================') print(f'{BBLACK}»{RESET} Информация о системе\n') print(' Система:') print(f' {BBLACK}•{RESET} ОС: {YELLOW}{platform.system()}{RESET}') @@ -211,13 +250,17 @@ def helpMenu(): print('\n AutoZoom:') print(f' {BBLACK}•{RESET} Версия: {YELLOW}{version}{RESET}') print(f' {BBLACK}•{RESET} Пользователь: {YELLOW}{getpass.getuser()}{RESET}') + print(f' {BBLACK}•{RESET} Папка пользователя: {BRED}{Path.home()}{RESET}') print(f' {BBLACK}•{RESET} Расположение: {BRED}{path}{RESET}') + print('\n Интеграции:') + print(f' {BBLACK}•{RESET} RBTray: {rbtray}') + print(f' {BBLACK}•{RESET} Discord RPC: {dsrpc}') none = input('\n > ') clear() elif help_choose == '7': rpc.inMenu() clear() - os.system("title AutoZoom (Главная)") + setTitle("AutoZoom (Главная)", getOS()) return else: clear() @@ -227,14 +270,84 @@ def helpMenu(): clear() return +def devMenu(): + try: + while True: + setTitle("AutoZoom (Отладка)", getOS()) + appendLog('Help menu opened') + + clear() + + print(f'{BBLACK}»{RESET} Меню отладки\n') + print(f' {BRED}1.{RESET} PlaySound test') + print(f' {BRED}2.{RESET} WinSound test') + print(f' {BRED}3.{RESET} Play-audio test') + print(f' {BRED}4.{RESET} OS check test') + print(f' {BRED}5.{RESET} Telegram test') + print(f' {BRED}6.{RESET} Color test') + print(f' {BRED}7.{RESET} Exit to menu') + + choose = input(f'\n > {BRED}') + + if choose == '1': + from playsound import playsound + playsound(sounds_folder+"debug.wav") + continue + + elif choose == '2': + import winsound + winsound.PlaySound(sounds_folder+"debug.wav", winsound.SND_FILENAME) + continue + + elif choose == '3': + os.system(f'play-audio {sounds_folder}debug.wav') + continue + + elif choose == '4': + clear() + none = input(f'{RESET}{getOS()}\n\n > ') + continue + + elif choose == '5': + clear() + import telegram_send + telegram_send.send(messages=["Telegram message test"], parse_mode="markdown", conf=files_folder+"telegram.conf") + continue + + elif choose == '6': + clear() + print(f'{BLACK}███{RED}███{GREEN}███{YELLOW}███{BLUE}███{MAGENTA}███{CYAN}███{WHITE}███') + print(f'{BBLACK}███{BRED}███{BGREEN}███{BYELLOW}███{BBLUE}███{BMAGENTA}███{BCYAN}███{BWHITE}███') + print(f'{RESET}RESET') + print(f'{REVERSE}REVERSE{RESET}') + print(f'{ULINE}UNDERLINE{RESET}') + none = input(RESET+'\n > ') + continue + + elif choose == '7': + rpc.inMenu() + clear() + setTitle("AutoZoom (Главная)", getOS()) + return + + else: + clear() + continue + + except KeyboardInterrupt: + rpc.inMenu() + clear() + return + + def updater(serv_ver, version): try: while True: - os.system("title AutoZoom (Обновления)") + setTitle("AutoZoom (Обновления)", getOS()) appendLog('Updater menu opened') clear() - if float(serv_ver) > float(version): + if getConfig("update_check") and float(serv_ver) > float(version): show_version = f' ({BRED}!{RESET})' serv_ver = serv_ver.rstrip('\n') show_action = f'Обновить до {BGREEN}{serv_ver}{RESET}' @@ -256,6 +369,8 @@ def updater(serv_ver, version): print(f' {BRED}1.{RESET} {show_action}') print(f' {BRED}2.{RESET} Список изменений') print(f' {BRED}3.{RESET} В главное меню') + if not getConfig("update_check"): + print(f'\n{BRED}Внимание!{RESET} У вас выключена проверка обновлений.\nЕсли это было сделанно временно - включите её в настройках.') updater_choose = input(f'\n > {BRED}') if updater_choose == '1': @@ -266,7 +381,7 @@ def updater(serv_ver, version): print(f'{RESET}Подтвердите действие:\n') print(f' {BRED}1.{RESET} Установить') print(f' {BRED}2.{RESET} Отменить') - updater_decide = input('\n > ') + updater_decide = input(f'\n > {BRED}') if updater_decide == '1': appendLog('Trying to update AutoZoom') @@ -276,14 +391,14 @@ def updater(serv_ver, version): wget.download('https://www.end-play.xyz/AutoZoomLatest.zip', out='AutoZoomLatest.zip') appendLog('Latest zip downloaded') except Exception as exp: - print(f'Не удалось загрузить архив с последней версией.\nПроверьте подключение к сети и повторите попытку.\n\nСтатус сервера центра обновлений:\n{BRED}https://status.end-play.xyz/786373747{RESET}') + print(f'{RESET}Не удалось загрузить архив с последней версией.\nПроверьте подключение к сети и повторите попытку.\n\nСтатус сервера центра обновлений:\n{BRED}https://status.end-play.xyz/786373747{RESET}') appendLog(f'Failed to download zip: {exp}') - none = input('\n > ') + none = input(f'\n > {BRED}') continue with ZipFile('AutoZoomLatest.zip', 'r') as zipObj: zipObj.extractall() - print('Все файлы были успешно загружены') + print(f'{RESET}Все файлы были успешно загружены') appendLog('Latest zip extracted') if os.path.exists("AutoZoomLatest.zip"): @@ -291,10 +406,10 @@ def updater(serv_ver, version): appendLog('Latest used zip deleted') clear() - none = input('Обновление завершено, перезапустите AutoZoom.\n\n > ') + none = input(f'{RESET}Обновление завершено, перезапустите AutoZoom.\n\n > ') rpc.disconnect() clear() - print(f'Закрываем приложение {BGREEN}AutoZoom{RESET}...') + print(f'{RESET}Закрываем приложение {BGREEN}AutoZoom{RESET}...') appendLog('Exiting AutoZoom after an update') sys.exit() elif updater_decide == '2': @@ -317,6 +432,7 @@ def updater(serv_ver, version): none = input('\n > ') continue except Exception as exp: + clear() print(f'{RESET}Не удалось загрузить чейнджлог.\nПроверьте подключение к сети и повторите попытку.\n\nСтатус сервера центра обновлений:\n{BRED}https://status.end-play.xyz/786373747{RESET}') appendLog(f'Failed to check changelog: {exp}') none = input('\n > ') @@ -326,7 +442,7 @@ def updater(serv_ver, version): rpc.inMenu() clear() appendLog('Returning to main menu') - os.system("title AutoZoom (Главная)") + setTitle("AutoZoom (Главная)", getOS()) return else: @@ -338,10 +454,10 @@ def updater(serv_ver, version): return if __name__ == '__main__': - os.system("title Загрузка main...") from functions import getConfig - from daemon import clear + from daemon import clear, getOS, setTitle import time + setTitle("Загрузка main...", getOS()) clear() if getConfig("run_fullscreen"): @@ -349,6 +465,6 @@ if __name__ == '__main__': time.sleep(.25) keyboard.release('alt, enter') - os.system("title AutoZoom (Главная)") + setTitle("AutoZoom (Главная)", getOS()) mainMenu() sys.exit() diff --git a/rpc.py b/rpc.py index 269d821..0c74ecb 100644 --- a/rpc.py +++ b/rpc.py @@ -6,7 +6,7 @@ import sys from colors import * from functions import * -version = '2.0' +version = '2.1' import libinstaller from pypresence import Presence @@ -17,7 +17,7 @@ RPC = Presence(client_id,pipe=0) connected = False -if getConfig("use_rpc"): +if getConfig("use_rpc") and getOS != "android": try: RPC.connect() connected = True @@ -29,7 +29,7 @@ else: def disconnect(): global connected - if getConfig("use_rpc"): + if getConfig("use_rpc") and getOS != "android": try: RPC.close() connected = False @@ -48,7 +48,7 @@ def connect(): appendLog('Discord RPC failed to connect') def reset(): - if getConfig("use_rpc"): + if getConfig("use_rpc") and getOS != "android": RPC.clear() appendLog('Discord RPC status cleared') @@ -56,7 +56,7 @@ def reset(): def waitLesson(lesson, start): try: - if getConfig("use_rpc"): + if getConfig("use_rpc") and getOS != "android": if connected == False: connect() RPC.update(large_image='1024_cover', small_image='status_waiting', large_text=f'AutoZoom • v{version}\nhttp://bit.ly/auto_zoom', small_text='Ожидание', state=f'Ждём начала «{lesson}»', details='Конференция не началась', start=start) @@ -74,7 +74,7 @@ def waitLesson(lesson, start): def onLesson(lesson, start): try: - if getConfig("use_rpc"): + if getConfig("use_rpc") and getOS != "android": if connected == False: connect() RPC.update(large_image='1024_cover', small_image='status_lesson', large_text=f'AutoZoom • v{version}\nhttp://bit.ly/auto_zoom', small_text='Конференция', state=f'Слушаем «{lesson}»', details='Идёт конференция', start=start) @@ -92,7 +92,7 @@ def onLesson(lesson, start): def inMenu(): try: - if getConfig("use_rpc"): + if getConfig("use_rpc") and getOS != "android": if connected == False: connect() RPC.update(large_image='1024_cover', small_image='status_menu', large_text=f'AutoZoom • v{version}\nhttp://bit.ly/auto_zoom', small_text='Главное меню', state='Открыт список опций', details='В главном меню') @@ -110,7 +110,7 @@ def inMenu(): def shutdown(end): try: - if getConfig("use_rpc"): + if getConfig("use_rpc") and getOS != "android": if connected == False: connect() RPC.update(large_image='1024_cover', small_image='status_shutdown', large_text=f'AutoZoom • v{version}\nhttp://bit.ly/auto_zoom', small_text='Выключение', state='Отсчёт до авто-выключения', details='Выключение ПК', end=end) @@ -128,7 +128,7 @@ def shutdown(end): def inSettings(): try: - if getConfig("use_rpc"): + if getConfig("use_rpc") and getOS != "android": if connected == False: connect() RPC.update(large_image='1024_cover', small_image='status_settings', large_text=f'AutoZoom • v{version}\nhttp://bit.ly/auto_zoom', small_text='Настройки', state='Открыты настройки', details='В главном меню') @@ -144,9 +144,27 @@ def inSettings(): print(f'{RESET}Модуль {BRED}Discord RPC {RESET}не смог подключиться.\nВозможно, ваш {CYAN}Discord {RESET}не открыт.') time.sleep(1) +def inDebug(): + try: + if getConfig("use_rpc") and getOS != "android": + if connected == False: + connect() + RPC.update(large_image='1024_cover', small_image='status_debug', large_text=f'AutoZoom • v{version}\nhttp://bit.ly/auto_zoom', small_text='Отладка', state='Открыто меню отладки', details='В меню разработчика') + appendLog('Discord RPC changed to inDebug') + except AttributeError: + appendLog('Discord RPC failed to change status') + if getConfig("debug"): + print(f'{RESET}Модуль {BRED}Discord RPC {RESET}не смог подключиться.\nВозможно, ваш {CYAN}Discord {RESET}не открыт.') + time.sleep(1) + except AssertionError: + appendLog('Discord RPC failed to change status') + if getConfig("debug"): + print(f'{RESET}Модуль {BRED}Discord RPC {RESET}не смог подключиться.\nВозможно, ваш {CYAN}Discord {RESET}не открыт.') + time.sleep(1) + def inEditor(): try: - if getConfig("use_rpc"): + if getConfig("use_rpc") and getOS != "android": if connected == False: connect() RPC.update(large_image='1024_cover', small_image='status_editing', large_text=f'AutoZoom • v{version}\nhttp://bit.ly/auto_zoom', small_text='Редактор', state='Открыт редактор', details='В главном меню') @@ -164,7 +182,7 @@ def inEditor(): def inUpdater(): try: - if getConfig("use_rpc"): + if getConfig("use_rpc") and getOS != "android": if connected == False: connect() RPC.update(large_image='1024_cover', small_image='status_updating', large_text=f'AutoZoom • v{version}\nhttp://bit.ly/auto_zoom', small_text='Обновление', state='Открыт центр обновлений', details='В главном меню') @@ -182,7 +200,7 @@ def inUpdater(): def inHelp(): try: - if getConfig("use_rpc"): + if getConfig("use_rpc") and getOS != "android": if connected == False: connect() RPC.update(large_image='1024_cover', small_image='status_support', large_text=f'AutoZoom • v{version}\nhttp://bit.ly/auto_zoom', small_text='Помощь', state='Открыта помощь', details='В главном меню') @@ -200,7 +218,7 @@ def inHelp(): def lessonEnded(): try: - if getConfig("use_rpc"): + if getConfig("use_rpc") and getOS != "android": if connected == False: connect() RPC.update(large_image='1024_cover', small_image='status_waiting', large_text=f'AutoZoom • v{version}\nhttp://bit.ly/auto_zoom', small_text='Ожидание', state=f'Ждём указаний', details='Все конференции закончились') diff --git a/settings.py b/settings.py new file mode 100644 index 0000000..6c0be3b --- /dev/null +++ b/settings.py @@ -0,0 +1,538 @@ +import rpc +import pathlib +import shutil +from functions import * +#from daemon import + + +if getConfig("use_colors"): + from colors import * + appendLog('Colors imported') +else: + RESET = '' + BLACK = RED = GREEN = YELLOW = BLUE = MAGENTA = CYAN = WHITE = '' + BBLACK = BRED = BGREEN = BYELLOW = BBLUE = BMAGENTA = BCYAN = BWHITE = '' + ULINE = REVERSE = '' + appendLog('Loading without colors') + + +sysname = getOS() + + +if sysname == "windows": + from swinlnk.swinlnk import SWinLnk + + swl = SWinLnk() + + +def settings(): + appendLog('Settings page 1 opened') + global sysname + + try: + while True: + + setTitle("AutoZoom (Настройки)", sysname) + clear() + + if getConfig("debug"): + debug_val = f'{BGREEN}Вкл.{RESET}' + elif not getConfig("debug"): + debug_val = f'{BRED}Выкл.{RESET}' + else: + debug_val = f'{BRED}ERROR{RESET}' + + if getConfig("run_fullscreen"): + fullscreen_val = f'{BGREEN}Вкл.{RESET}' + elif not getConfig("run_fullscreen"): + fullscreen_val = f'{BRED}Выкл.{RESET}' + else: + fullscreen_val = f'{BRED}ERROR{RESET}' + + if getConfig("sounds"): + sounds_val = f'{BGREEN}Вкл.{RESET}' + elif not getConfig("sounds"): + sounds_val = f'{BRED}Выкл.{RESET}' + else: + sounds_val = f'{BRED}ERROR{RESET}' + + if getConfig("obs_exe") and getConfig("obs_core") not in [None, 'Disabled']: + obs_val = f'{BGREEN}Вкл.{RESET}' + else: + obs_val = f'{BRED}Выкл.{RESET}' + + if getConfig("use_colors"): + color_val = f'{BGREEN}Вкл.{RESET}' + elif not getConfig("use_colors"): + color_val = f'{BRED}Выкл.{RESET}' + else: + color_val = f'{BRED}ERROR{RESET}' + + if getConfig("shutdown_enabled"): + shutdown_en_val = f'{BGREEN}Вкл.{RESET}' + elif not getConfig("shutdown_enabled"): + shutdown_en_val = f'{BRED}Выкл.{RESET}' + else: + shutdown_en_val = f'{BRED}ERROR{RESET}' + + shutdown_time_val = getConfig("shutdown_timeout") + start_val = getConfig("start") + stop_val = getConfig("stop") + + print(f'{RESET}{BBLACK}»{RESET} Настройки (1 стр.)\n') + + print(f' {BRED}1.{RESET} Режим отладки ({debug_val})') + print(f' {BBLACK}Не рекомендуем включать его без необходимости\n') + + print(f' {BRED}2.{RESET} Цветной вывод ({color_val})') + print(f' {BBLACK}Отображение цветных текстов в меню и выводе (нужен перезапуск)\n') + + print(f' {BRED}3.{RESET} Полный экран ({fullscreen_val})') + print(f' {BBLACK}{winOnly(BRED, BBLACK, sysname, end=" ")}Эмулировать вызов полного экрана при запуске (окно должно быть в фокусе)\n') + + print(f' {BRED}4.{RESET} Звуковые сигналы ({sounds_val})') + print(f' {BBLACK}Воспроизводить звуки при начале/конце конференций и записи видео\n') + + print(f' {BRED}5.{RESET} Запись через OBS ({obs_val})') + print(f' {BBLACK}{winOnly(BRED, BBLACK, sysname, end=" ")}Возможность записи конференций через OBS\n') + + print(f' {BRED}6.{RESET} Автовыключение ({shutdown_en_val})') + print(f' {BBLACK}Когда конференции закончатся компьютер выключится\n') + + print(f' {BRED}7.{RESET} Следующая страница') + print(f' {BBLACK}Перейти на вторую страницу настроек\n') + + print(f' {BRED}8.{RESET} В главное меню') + print(f' {BBLACK}Вернуться в основное меню{RESET}\n') + + print(f' {BBLACK}Для переключения параметров Вкл/Выкл просто введите номер{RESET}') #\n Если окно приложения слишком мелкое - увеличьте его или листайте это меню{RESET}') + + settings_choose = input(f'\n > {BRED}') + + if settings_choose == '1': + setConfig("debug", not getConfig("debug")) + appendLog(f'Changed option "debug" to {getConfig("debug")}') + + clear() + continue + + elif settings_choose == '2': + setConfig("use_colors", not getConfig("use_colors")) + appendLog(f'Changed option "use_colors" to {getConfig("use_colors")}') + + clear() + continue + + elif settings_choose == '3': + if sysname == 'windows': + setConfig("run_fullscreen", not getConfig("run_fullscreen")) + appendLog(f'Changed option "run_fullscreen" to {getConfig("run_fullscreen")}') + + clear() + continue + + elif settings_choose == '4': + setConfig("sounds", not getConfig("sounds")) + appendLog(f'Changed option "sounds" to {getConfig("sounds")}') + + clear() + continue + + elif settings_choose == '5': + + if sysname == 'windows': + if getConfig("obs_core") and getConfig("obs_exe") not in [None, 'Disabled']: + setConfig("obs_core", "Disabled") + setConfig("obs_exe", "Disabled") + + else: + clear() + obs_choice = input(f'{RESET}Хотите использовать запись через OBS? {RESET}({BGREEN}Да{RESET}/{BRED}Нет{RESET}): ') + + if obs_choice.lower() in yes_list: + while True: + try: + filename = easygui.fileopenbox('Выберите путь до obs32.exe или obs64.exe') + if filename.find("obs64.exe") != -1: + setConfig("obs_exe", filename) + setConfig("obs_core", filename[:-9]) + print(f'Сохранены пути для OBS:\nПриложение: {BRED}{filename}{RESET}\nКорневая папка: {BRED}{filename[:-9]}{RESET}') + time.sleep(3) + break + elif filename.find("obs32.exe") != -1: + setConfig("obs_exe", filename) + setConfig("obs_core", filename[:-9]) + print(f'Сохранены пути для OBS:\nПриложение: {BRED}{filename}{RESET}\nКорневая папка: {BRED}{filename[:-9]}{RESET}') + time.sleep(3) + break + elif filename.find("obs.exe") != -1: + setConfig("obs_exe", filename) + setConfig("obs_core", filename[:-7]) + print(f'Сохранены пути для OBS:\nПриложение: {BRED}{filename}{RESET}\nКорневая папка: {BRED}{filename[:-7]}{RESET}') + time.sleep(3) + break + else: + easygui.msgbox("Неверный путь") + break + except Exception as exp: + appendLog(f'Could not select OBS path: {exp}') + none = input('Вы не выбрали верный путь для OBS.\n\n > ') + clear() + break + + appendLog(f'Changed option "obs_exe" to {getConfig("obs_exe")}') + appendLog(f'Changed option "obs_core" to {getConfig("obs_core")}') + + clear() + continue + + elif settings_choose == '6': + setConfig("shutdown_enabled", not getConfig("shutdown_enabled")) + appendLog(f'Changed option "shutdown_enabled" to {getConfig("shutdown_enabled")}') + + clear() + continue + + elif settings_choose == '7': + clear() + settings2() + + elif settings_choose == '8': + rpc.inMenu() + clear() + setTitle("AutoZoom (Главная)", sysname) + return + + except KeyboardInterrupt: + rpc.inMenu() + clear() + return + + +def settings2(): + appendLog('Settings page 2 opened') + global sysname + + try: + while True: + + setTitle("AutoZoom (Настройки)", sysname) + clear() + + if getConfig("use_colors"): + color_val = f'{BGREEN}Вкл.{RESET}' + elif not getConfig("use_colors"): + color_val = f'{BRED}Выкл.{RESET}' + else: + color_val = f'{BRED}ERROR{RESET}' + + if os.path.exists(files_folder+'telegram.conf'): + tg_file = open(files_folder+'telegram.conf', 'r', encoding="utf-8") + tg_text = tg_file.read() + if tg_text != 'Not Configured': + tg_var = f'{BGREEN}Настроен{RESET}' + else: + tg_var = f'{BRED}Не настроен{RESET}' + else: + tg_var = f'{BRED}Не настроен{RESET}' + + if getConfig("telegram_enabled"): + telegram_en_val = f'{BGREEN}Вкл.{RESET}' + elif not getConfig("telegram_enabled"): + telegram_en_val = f'{BRED}Выкл.{RESET}' + else: + telegram_en_val = f'{BRED}ERROR{RESET}' + + if getConfig("update_check"): + update_val = f'{BGREEN}Вкл.{RESET}' + elif not getConfig("update_check"): + update_val = f'{BRED}Выкл.{RESET}' + else: + update_val = f'{BRED}ERROR{RESET}' + + shutdown_time_val = getConfig("shutdown_timeout") + start_val = getConfig("start") + stop_val = getConfig("stop") + + print(f'{RESET}{BBLACK}»{RESET} Настройки (2 стр.)\n') + + print(f' {BRED}1.{RESET} Таймаут выключения ({YELLOW}{shutdown_time_val} мин.{RESET})') + print(f' {BBLACK}Время в минутах после которого ПК будет выключен\n') + + print(f' {BRED}2.{RESET} Начать запись ({YELLOW}{start_val}{RESET})') + print(f' {BBLACK}{winOnly(BRED, BBLACK, sysname, end=" ")}Комбинация клавиш для начала записи через OBS (см. документацию)\n') + + print(f' {BRED}3.{RESET} Остановить запись ({YELLOW}{stop_val}{RESET})') + print(f' {BBLACK}{winOnly(BRED, BBLACK, sysname, end=" ")}Комбинация клавиш для остановки записи через OBS (см. документацию)\n') + + print(f' {BRED}4.{RESET} Отправлять уведомления ({telegram_en_val})') + print(f' {BBLACK}Ваш бот отправит сообщениия о начале/конце конференции и выключении ПК\n') + + print(f' {BRED}5.{RESET} Настроить Telegram бота ({tg_var})') + print(f' {BBLACK}Настроить на вашем ПК бота для ЛС (см. документацию)\n') + + print(f' {BRED}6.{RESET} Проверка обновлений ({update_val})') + print(f' {BBLACK}Ускоряет загрузку меню, но не рекомендуем выключать без необходимости\n') + + print(f' {BRED}7.{RESET} Следующая страница') + print(f' {BBLACK}Перейти на третью страницу настроек\n') + + print(f' {BRED}8.{RESET} Назад') + print(f' {BBLACK}Вернуться на предыдущую страницу{RESET}\n') + + print(f' {BBLACK}Для переключения параметров Вкл/Выкл просто введите номер{RESET}') #\n Если окно приложения слишком мелкое - увеличьте его или листайте это меню{RESET}') + + settings_choose = input(f'\n > {BRED}') + + if settings_choose == '1': + + try: + clear() + shutdown_timeout_val = int(input(f'{RESET}Введите через сколько минут после конференции выключать ПК:\n\n > {BRED}')) + setConfig("shutdown_timeout", shutdown_timeout_val) + appendLog(f'Changed option "shutdown_timeout" to {getConfig("shutdown_timeout")}') + continue + + except: + clear() + print(f'{RESET}Нужно использовать целое число.') + time.sleep(2) + continue + + continue + + elif settings_choose == '2': + + if sysname == 'windows': + + try: + clear() + start_value = input(f'{RESET}Введите комбинацию клавиш для начала записи OBS:\nЭта комбинация должна быть идентична оной в самом OBS!\n\n > {YELLOW}') + setConfig("start", start_value) + appendLog(f'Changed option "start" to {getConfig("start")}') + continue + + except: + clear() + print(f'{RESET}Нужно использовать комбинацию клавиш в виде текста.') + time.sleep(2) + continue + + clear() + continue + + elif settings_choose == '3': + + if sysname == 'windows': + + try: + clear() + stop_value = input(f'{RESET}Введите комбинацию клавиш для остановки записи OBS:\nЭта комбинация должна быть идентична оной в самом OBS!\n\n > {YELLOW}') + setConfig("stop", stop_value) + appendLog(f'Changed option "stop" to {getConfig("stop")}') + continue + + except: + clear() + print(f'{RESET}Нужно использовать комбинацию клавиш в виде текста.') + time.sleep(2) + continue + + clear() + continue + + elif settings_choose == '4': + + setConfig("telegram_enabled", not getConfig("telegram_enabled")) + appendLog(f'Changed option "telegram_enabled" to {getConfig("telegram_enabled")}') + + clear() + continue + + elif settings_choose == '5': + + clear() + print(f'{RESET}Пожалуйста, прочтите инструкцию по установке Telegram бота в {BRED}README.txt{RESET}') + print(f'или в документации/инструкции что в разделе {CYAN}Помощь{RESET} главного меню') + print(f'чтобы хорошо понимать что сейчас от вас нужно.') + none = input('\n > ') + + while True: + clear() + + try: + telegram_send.configure(files_folder+'telegram.conf', channel=False, group=False, fm_integration=False) + break + + except: + clear() + continue + + telegram_send.send(messages=[f"🎊 Конфигурация правильна, всё работает!"], parse_mode="markdown", conf=f"{files_folder}telegram.conf") + appendLog('Telegram Send successfully configured') + clear() + + continue + + elif settings_choose == '6': + setConfig("update_check", not getConfig("update_check")) + appendLog(f'Changed option "update_check" to {getConfig("update_check")}') + + clear() + continue + + elif settings_choose == '7': + appendLog('Going to settings page 3') + clear() + settings3() + + elif settings_choose == '8': + appendLog('Returned to settings page 1') + clear() + return + + except KeyboardInterrupt: + rpc.inMenu() + clear() + return + + +def settings3(): + appendLog('Settings page 3 opened') + + try: + while True: + + setTitle("AutoZoom (Настройки)", sysname) + clear() + + if getConfig("write_logs"): + logs_val = f'{BGREEN}Вкл.{RESET}' + elif not getConfig("write_logs"): + logs_val = f'{BRED}Выкл.{RESET}' + else: + logs_val = f'{BRED}ERROR{RESET}' + + shutdown_time_val = getConfig("shutdown_timeout") + start_val = getConfig("start") + stop_val = getConfig("stop") + + print(f'{RESET}{BBLACK}»{RESET} Настройки (3 стр.)\n') + + print(f' {BRED}1.{RESET} Запись действий в лог ({logs_val})') + print(f' {BBLACK}Запись каждого действия в файл для отладки (не выключайте без причин)\n') + + print(f' {BRED}2.{RESET} Размер лога действий ({YELLOW}{str(getConfig("log_size"))} Кб{RESET})') + print(f' {BBLACK}Размер файла лога превышая который он будет упакован в архив\n') + + print(f' {BRED}3.{RESET} Добавить в автозапуск') + print(f' {BBLACK}{winOnly(BRED, BBLACK, sysname, end=" ")}Автоматически запускать демона при входе в систему\n') + + print(f' {BRED}4.{RESET} Сбросить все настройки') + print(f' {BBLACK}Восстановить настройки по умолчанию\n') + + print(f' {BRED}5.{RESET} Назад') + print(f' {BBLACK}Вернуться на предыдущую страницу{RESET}\n') + + print(f' {BBLACK}Для переключения параметров Вкл/Выкл просто введите номер{RESET}') #\n Если окно приложения слишком мелкое - увеличьте его или листайте это меню{RESET}') + settings_choose = input(f'\n > {BRED}') + + if settings_choose == '1': + setConfig("write_logs", not getConfig("write_logs")) + appendLog(f'Changed option "write_logs" to {getConfig("write_logs")}') + + if settings_choose == '2': + + try: + clear() + log_size_value = int(input(f'{RESET}Введите после скольки килобайт архивировать лог:\n\n > {BRED}')) + setConfig("log_size", log_size_value) + continue + except: + clear() + print(f'{RESET}Нужно использовать целое число.') + time.sleep(2) + continue + + appendLog(f'Changed option "log_size" to {getConfig["log_size"]}') + continue + + if settings_choose == '3': + + if sysname == "windows": + + global swl + + try: + clear() + + shutil.copyfile('daemon.bat', 'startdaemon.bat') + + with open('startdaemon.bat', 'r') as f : + filedata = f.read() + filedata = filedata.replace('python daemon.py', f'python {path}\\daemon.py') + + with open('startdaemon.bat', 'w') as f: + f.write(filedata) + f.close() + + swl.create_lnk(f'{path}\\startdaemon.bat', f'{pathlib.Path.home()}\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\AutoZoomDaemon.lnk') + appendLog('Autorun script added') + + none = input(f'Демон AutoZoom был добавлен в автозапуск.\nПуть: {BRED}{pathlib.Path.home()}\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\AutoZoomDaemon.lnk{RESET}\n\n > ') + continue + + except Exception as exp: + clear() + none = input(f'Не удалось добавить в автозапуск:\n{BRED}{exp}{RESET}\n\n > ') + appendLog(f'Could not add autorun: {exp}') + continue + + continue + + else: + continue + + elif settings_choose == '4': + appendLog('Resetting configuration') + + while True: + clear() + reset_decision = input(f'{RESET}Вы уверены что хотите сбросить настройки? {RESET}({BGREEN}Да{RESET}/{BRED}Нет{RESET})\n\n{BRED}Внимание!{RESET} Это действие нельзя обратить!\nВаш список конференций затронут НЕ будет.\n\n > ') + + if reset_decision.lower() in yes_list: + + from functions import default_config + + saveJson(files_folder+'config.json', default_config) + appendLog('Configuration dropped to default') + clear() + + none = input(f'{RESET}Все настройки были сброшены до стандартных.\n\n > ') + + clear() + break + + elif reset_decision.lower() in no_list: + appendLog('Configuration reset aborted') + clear() + break + + else: + clear() + continue + + continue + + clear() + continue + + elif settings_choose == '5': + appendLog('Returned to settings page 2') + clear() + return + + except KeyboardInterrupt: + rpc.inMenu() + clear() + return \ No newline at end of file diff --git a/sounds/debug.wav b/sounds/debug.wav new file mode 100644 index 0000000..581fcc0 Binary files /dev/null and b/sounds/debug.wav differ diff --git a/sounds/warning.wav b/sounds/warning.wav new file mode 100644 index 0000000..e541620 Binary files /dev/null and b/sounds/warning.wav differ