diff --git a/assets/colors.json b/assets/colors.json new file mode 100644 index 0000000..2996f1e --- /dev/null +++ b/assets/colors.json @@ -0,0 +1,27 @@ +{ + "utility": { + "reset": "\u001b[0m", + "underline": "\u001b[4m", + "reverse": "\u001b[7m" + }, + "default": { + "black": "\u001b[30m", + "blue": "\u001b[34m", + "green": "\u001b[32m", + "red": "\u001b[31m", + "yellow": "\u001b[33m", + "magenta": "\u001b[35m", + "cyan": "\u001b[36m", + "white": "\u001b[37m" + }, + "bright": { + "black": "\u001b[30;1m", + "blue": "\u001b[34;1m", + "green": "\u001b[32;1m", + "red": "\u001b[31;1m", + "yellow": "\u001b[33;1m", + "magenta": "\u001b[35;1m", + "cyan": "\u001b[36;1m", + "white": "\u001b[37;1m" + } +} \ No newline at end of file diff --git a/icon.ico b/assets/icon.ico similarity index 100% rename from icon.ico rename to assets/icon.ico diff --git a/daemon.bat b/daemon.bat index 939bf15..a3c9d9d 100644 --- a/daemon.bat +++ b/daemon.bat @@ -1 +1,2 @@ -python daemon.py \ No newline at end of file +echo AutoZoom needs Python 3 to work. Please read README.md! +python3 daemon.py \ No newline at end of file diff --git a/daemon.py b/daemon.py index 2ea8eda..f77e191 100644 --- a/daemon.py +++ b/daemon.py @@ -14,10 +14,10 @@ from random import randint from pathlib import Path from datetime import datetime, date, timedelta -from functions import * +from modules.functions import * if getConfig("use_colors"): - from colors import * + from modules.colors import * appendLog('Colors imported') else: RESET = '' @@ -32,8 +32,7 @@ clear() setTitle("Загрузка daemon...", sysname) appendLog('daemon.py start initialized', startup=True) -import libinstaller -import rpc +import modules.rpc as rpc if sysname == "windows": import easygui @@ -109,7 +108,7 @@ def getLessons(): return lessons_list -def tgsend(enabled, message): +def tgsend(enabled, message, video=None): if enabled: if os.path.exists(files_folder+'telegram.conf'): tg_file = open(files_folder+'telegram.conf', 'r', encoding="utf-8") @@ -118,7 +117,10 @@ def tgsend(enabled, message): if tg_text != 'Not Configured': try: - telegram_send.send(messages=[f"{message}"], parse_mode="markdown", conf=files_folder+"telegram.conf") + if video is not None: + telegram_send.send(messages=[f"{message}"], videos=[f"{video}"], parse_mode="markdown", conf=files_folder+"telegram.conf") + else: + 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}') @@ -126,6 +128,14 @@ def tgsend(enabled, message): print(f'{nowtime()} Не удалось отправить Telegram сообщение "{message}" (Ошибка: {exp})') +async def tgsendVideo(msg, video, video_new): + print(f"{nowtime()} Отправка записи конференции {CYAN}{msg}{RESET}.") + try: + tgsend(getConfig("telegram_enabled"), msg, video=video) + os.rename(video, video_new) + except Exception as exp: + tgsend(getConfig("telegram_enabled"), f"⚠ Отправка видео `{video}` прошла с ошибкой `{exp}`") + def main(source='deamon'): global sysname @@ -532,6 +542,7 @@ def main(source='deamon'): 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}.)') + fire_and_forget(tgsendVideo(f"{lesson_name}", "C:\\Users\\PC-Admin\\AutoZoom\\lessons\\meeting.mp4", f'C:\\Users\\PC-Admin\\AutoZoom\\lessons\\meeting_{datetime.now().strftime("%d.%m.%Y_%H-%M-%S")}.mp4')) 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}.)') @@ -709,7 +720,7 @@ def main(source='deamon'): return if __name__ == '__main__': - from functions import getOS, setTitle + from modules.functions import getOS, setTitle setTitle("AutoZoom (Демон)", getOS()) import sys clear() diff --git a/daemon.sh b/daemon.sh index 057f5b1..5ef26cd 100644 --- a/daemon.sh +++ b/daemon.sh @@ -1,4 +1,4 @@ #!/bin/bash -echo "Running AutoZoom daemon with Python 3. Please read README.md!" +echo "AutoZoom needs Python 3 to work. Please read README.md!" python3 daemon.py \ No newline at end of file diff --git a/install.bat b/install.bat new file mode 100644 index 0000000..073b6da --- /dev/null +++ b/install.bat @@ -0,0 +1,5 @@ +echo AutoZoom needs Python 3 to work. Please read README.md! +python3 .\modules\install.py +python3 -m pip install -r requirements.txt +echo Run start.bat to proceed to AutoZoom. +pause \ No newline at end of file diff --git a/install.sh b/install.sh new file mode 100644 index 0000000..cc78e92 --- /dev/null +++ b/install.sh @@ -0,0 +1,4 @@ +echo "AutoZoom needs Python 3 to work. Please read README.md!" +python3 ./modules/install.py +python3 -m pip install -r requirements.txt +echo "Run start.sh to proceed to AutoZoom." \ No newline at end of file diff --git a/libinstaller.py b/libinstaller.py deleted file mode 100644 index 5b9a16c..0000000 --- a/libinstaller.py +++ /dev/null @@ -1,196 +0,0 @@ -# -*- coding: utf-8 -*- - -import os, sys -from colors import * -from functions import getConfig, setConfig, getOS, yes_list, no_list -from functions import appendLog -from subprocess import check_output - -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 = [] -################################### -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 -except ModuleNotFoundError: - appendLog("No module keyboard") - libs.append("keyboard") -################################### -try: - import ast -except ModuleNotFoundError: - appendLog("No module ast") - libs.append("ast") -################################### -try: - import inputimeout -except ModuleNotFoundError: - appendLog("No module inputimeout") - libs.append("inputimeout") -################################### -try: - import telegram_send -except ModuleNotFoundError: - appendLog("No module telegram_send") - libs.append("telegram_send") -################################### -try: - import wget -except ModuleNotFoundError: - appendLog("No module wget") - libs.append("wget") -################################### -try: - import requests -except ModuleNotFoundError: - appendLog("No module requests") - libs.append("requests") -################################### -if getOS() != "android": - try: - from playsound import playsound - except ModuleNotFoundError: - appendLog("No module playsound") - libs.append("playsound") -else: - try: - if not "play-audio" in os.popen('pkg list-all').read(): - os.system('pkg install play-audio') - except: - appendLog("Could not install play-audio") -################################### -try: - from zipfile import ZipFile -except ModuleNotFoundError: - appendLog("No module zipfile") - libs.append("zipfile") -################################### -try: - import asyncio -except ModuleNotFoundError: - appendLog("No module asyncio") - libs.append("asyncio") -################################### -try: - import getpass -except ModuleNotFoundError: - appendLog("No module getpass") - libs.append("getpass") -################################### -try: - from pypresence import Presence -except ModuleNotFoundError: - appendLog("No module pypresence") - libs.append("pypresence") -################################### - -if len(libs) > 0: - print("Не хватает нужных модулей, пробуем установить...\nЭто может занять некоторое время. Пожалуйста, не закрывайте программу.") - appendLog('Missing some modules, trying to install them') - - for each in libs: - try: - if getConfig("debug"): - response = os.system('"{}" -m pip install -U '.format(sys.executable) + each) - else: - response = os.system('"{}" -m pip install -U '.format(sys.executable) + each + " -q --no-warn-script-location") - except: - response = os.system('"{}" -m pip install -U '.format(sys.executable) + each + " -q --no-warn-script-location") - - print(f"{RESET}[{BGREEN}OK{RESET}] Установлен модуль {YELLOW}{each}{RESET}.") - - appendLog(f'Module {each} installed') - - if response != 0: - appendLog(f'Failed to install {each}') - sys.exit(f"{RESET}[{BRED}ERR{RESET}] Установка {YELLOW}{each} {RESET}провалилась.") - - appendLog('Everything seems to be installed') - print(f"{RESET}[{BGREEN}OK{RESET}] Все модули были успешно установлены.") - - try: - 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 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/locales/_default.json b/locales/_default.json new file mode 100644 index 0000000..6b273c3 --- /dev/null +++ b/locales/_default.json @@ -0,0 +1,4 @@ +{ + "avail_de": "AutoZoom ist auf Deutsch verfügbar. Sprache von Englisch auf Deutsch ändern?", + "avail_uk": "AutoZoom доступний українською. Змінити мову з англійської на українську?" +} \ No newline at end of file diff --git a/locales/de.json b/locales/de.json new file mode 100644 index 0000000..e69de29 diff --git a/locales/en.json b/locales/en.json new file mode 100644 index 0000000..41ded43 --- /dev/null +++ b/locales/en.json @@ -0,0 +1,74 @@ +{ + "answer_yes": ["y", "yes", "yep"], + "answer_no": ["n", "no", "nope"], + "functions": { + "compatability": "For Windows only!", + "winsound_error": "{0} Could not play winsound sound \"{1}\" (Error: {2})", + "playsound_error": "{0} Could not play playsound sound \"{1}\" (Error: {2})" + }, + "rpc": { + "connection_error": "Module {0}Discord RPC {1}could not connect.\nYour {2}Discord {3}client might be closed.", + "connection_error_detailed": "Module {0}Discord RPC {1}could not connect.\nYour {2}Discord {3}client might be closed.\nError: {4}{5}", + "presence": { + "waiting": { + "smalltext": "Waiting", + "state": "Awaiting meeting «{0}»", + "details": "Meeting hasn't started" + }, + "meeting": { + "smalltext": "Meeting", + "state": "Listening to «{0}»", + "details": "Ongoing meeting" + }, + "menu": { + "smalltext": "Main menu", + "state": "Options list opened", + "details": "In the menus" + }, + "shutdown": { + "smalltext": "Shutting down", + "state": "Countdown before auto-shutdown", + "details": "PC shutdown" + }, + "sleep": { + "smalltext": "Sleeping mode", + "state": "Countdown before auto-sleep", + "details": "PC sleep mode" + }, + "settings": { + "smalltext": "Settings", + "state": "Settings opened", + "details": "In the menus" + }, + "debugmenu": { + "smalltext": "Debug", + "state": "Debug menu opened", + "details": "In the dev menu" + }, + "editor": { + "smalltext": "Editor", + "state": "Meetings editor opened", + "details": "In the menus" + }, + "updating": { + "smalltext": "Updater", + "state": "Updates center opened", + "details": "In the menus" + }, + "support": { + "smalltext": "Support", + "state": "Help menu opened", + "details": "In the menus" + }, + "ended": { + "smalltext": "Waiting", + "state": "Awaiting instructions", + "details": "All metings are over" + }, + "debug": { + "smalltext": "Debug", + "state": "Discord RPC module is running in testing mode", + "details": "Debug mode"} + } + } +} \ No newline at end of file diff --git a/locales/uk.json b/locales/uk.json new file mode 100644 index 0000000..e69de29 diff --git a/main.py b/main.py index d2b3d8b..18182df 100644 --- a/main.py +++ b/main.py @@ -9,21 +9,63 @@ import platform import subprocess from pathlib import Path -import libinstaller - -from functions import * +from modules.functions import * appendLog('main.py start initialized', startup=True) setTitle("", getOS()) +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) + from daemon import main -import settings -import editor -import rpc +import modules.settings as settings +import modules.editor as editor +import modules.rpc as rpc if getConfig("use_colors"): - from colors import * + from modules.colors import * else: RESET = '' BLACK = RED = GREEN = YELLOW = BLUE = MAGENTA = CYAN = WHITE = '' @@ -36,7 +78,7 @@ import keyboard import getpass from zipfile import ZipFile -version = 2.6 +version = 2.7 path = Path(__file__).resolve().parent def mainMenu(): @@ -489,7 +531,7 @@ def updater(serv_ver, version): return if __name__ == '__main__': - from functions import getConfig + from modules.functions import getConfig from daemon import clear, getOS, setTitle import time setTitle("Загрузка main...", getOS()) diff --git a/colors.py b/modules/colors.py similarity index 67% rename from colors.py rename to modules/colors.py index 7afb7e6..72c048d 100644 --- a/colors.py +++ b/modules/colors.py @@ -1,5 +1,13 @@ # -*- coding: utf-8 -*- +# def col(color, type="util"): +# if type is "util": +# type="utility" +# elif type is "br": +# type="bright" +# elif type is "def": +# type="default" + RESET = '\u001b[0m' BLACK = '\u001b[30m' diff --git a/editor.py b/modules/editor.py similarity index 99% rename from editor.py rename to modules/editor.py index fe19561..6e4f7c1 100644 --- a/editor.py +++ b/modules/editor.py @@ -1,10 +1,10 @@ -import rpc -from functions import * +import modules.rpc as rpc +from modules.functions import * from datetime import datetime, date, timedelta from daemon import getLessons, getConfig if getConfig("use_colors"): - from colors import * + from modules.colors import * appendLog('Colors imported') else: RESET = '' diff --git a/functions.py b/modules/functions.py similarity index 66% rename from functions.py rename to modules/functions.py index 3ec4348..be44bdc 100644 --- a/functions.py +++ b/modules/functions.py @@ -1,14 +1,17 @@ # -*- coding: utf-8 -*- -import pip +from socket import send_fds import time import json import os import shutil import gzip import getpass +import keyboard +from modules.telegram import telegramSendText from datetime import datetime from pathlib import Path +import asyncio, threading from subprocess import check_output path = Path(__file__).resolve().parent @@ -16,36 +19,120 @@ 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', 'н', 'нет'] +yes_list = ['y', 'yes', 'т', 'так', 'j', 'ja'] +no_list = ['n', 'no', 'н', 'ні', 'nein'] default_config = { - "firstboot": True, + "firstrun": True, "debug": False, - "shutdown_timeout": 30, - "shutdown_enabled": False, - "start": "shift+f7", - "stop": "shift+f8", - "telegram_enabled": False, - "use_colors": True, - "run_fullscreen": False, - "rpc_use": True, - "rpc_id": "800049969960058882", - "sounds": True, - "remove_old": True, - "end_mode": "shutdown", - "obs_exe": None, - "obs_core": None, - "obs_delay": 10, "update_check": True, - "write_logs": True, - "log_size": 512, - "sound_ended": "ended", - "sound_recordstart": "recordstart", - "sound_recordstop": "recordstop", - "sound_shutdown": "shutdown", - "sound_started": "started", - "sound_warning": "warning" + "logging": { + "enabled": True, + "rotate_size": 512 + }, + "meetings": { + "remove_old": True + }, + "meeting_end": { + "mode": "shutdown", + "shutdown": { + "timeout": 30 + } + }, + "obs": { + "enabled": False, + "path_bin": None, + "path_core": None, + "delay": 10, + "video": { + "send": False, + "path": None, + "filename": None + }, + "keybinds": { + "record_start": "shift+f7", + "record_stop": "shift+f8" + } + }, + "telegram": { + "enabled": False, + "token": None, + "user_id": None + }, + "appearance": { + "theme": "dark", + "colors": True, + "fullscreen": False + }, + "rpc": { + "enabled": True, + "app_id": "800049969960058882" + }, + "sounds": { + "enabled": True, + "sounds": { + "meeting_ended": "ended", + "record_start": "recordstart", + "record_stop": "recordstop", + "shutdown": "shutdown", + "meeting_started": "started", + "meeting_warning": "warning" + } + }, + "binds": { + "app_start": { + "commands": [], + "keymaps": [], + "messages": [] + }, + "app_end": { + "commands": [], + "keymaps": [], + "messages": [] + }, + "queue_start": { + "commands": [], + "keymaps": [], + "messages": [] + }, + "queue_end": { + "commands": [], + "keymaps": [], + "messages": [] + }, + "meeting_start": { + "commands": [], + "keymaps": [], + "messages": [] + }, + "meeting_end": { + "commands": [], + "keymaps": [], + "messages": [] + } + } + # "start": "shift+f7", + # "stop": "shift+f8", + # "telegram_enabled": False, + # "use_colors": True, + # "run_fullscreen": False, + # "rpc_use": True, + # "rpc_id": "800049969960058882", + # "sounds": True, + # "end_mode": "shutdown", + # "obs_exe": None, + # "obs_core": None, + # "obs_delay": 10, + # "write_logs": True, + # "log_size": 512, + # "sound_ended": "ended", + # "sound_recordstart": "recordstart", + # "sound_recordstop": "recordstop", + # "sound_shutdown": "shutdown", + # "sound_started": "started", + # "sound_warning": "warning" + # "shutdown_timeout": 30, + # "shutdown_enabled": False, } @@ -116,15 +203,15 @@ def checkSize(): log = os.stat(logs_folder + 'latest.log') if (log.st_size / 1024) > getConfig("log_size"): - with open(logs_folder + 'latest.log', 'rb') as f_in: + with open(logs_folder + 'latest.log', 'rb', encoding='utf-8') as f_in: with gzip.open(f'{logs_folder}{datetime.now().strftime("%d.%m.%Y_%H:%M:%S")}.zip', 'wb') as f_out: shutil.copyfileobj(f_in, f_out) if getConfig("debug"): print(f'Copied {logs_folder}{datetime.now().strftime("%d.%m.%Y_%H:%M:%S")}.zip') - - open(logs_folder + 'latest.log', 'w').close() + open(logs_folder + 'latest.log', 'w', encoding='utf-8').close() + i = 2 except FileNotFoundError: @@ -133,13 +220,13 @@ def checkSize(): time.sleep(2) try: - log = open(logs_folder + 'latest.log', 'a') - open(logs_folder + 'latest.log', 'a').close() + log = open(logs_folder + 'latest.log', 'a', encoding='utf-8') + open(logs_folder + 'latest.log', 'a', encoding='utf-8').close() except: try: os.mkdir(logs_folder) - log = open(logs_folder + 'latest.log', 'a') - open(logs_folder + 'latest.log', 'a').close() + log = open(logs_folder + 'latest.log', 'a', encoding='utf-8') + open(logs_folder + 'latest.log', 'a', encoding='utf-8').close() except: if getConfig("debug"): time.sleep(2) @@ -158,13 +245,13 @@ def appendLog(message, startup=False, shutdown=False): checkSize() try: - log = open(logs_folder + 'latest.log', 'a') - open(logs_folder + 'latest.log', 'a').close() + log = open(logs_folder + 'latest.log', 'a', encoding='utf-8') + open(logs_folder + 'latest.log', 'a', encoding='utf-8').close() except: try: os.mkdir(logs_folder) - log = open(logs_folder + 'latest.log', 'a') - open(logs_folder + 'latest.log', 'a').close() + log = open(logs_folder + 'latest.log', 'a', encoding='utf-8') + open(logs_folder + 'latest.log', 'a', encoding='utf-8').close() except: time.sleep(2) print('Log file could not be created') @@ -236,6 +323,23 @@ def strCleaner(string): return output +# Load json to dict +def jsonLoad(filename): + """Loads arg1 as json and returns its contents""" + with open(filename, "r", encoding='utf8') as file: + output = json.load(file) + file.close() + return output + +# Save json dict to filename +def jsonSave(contents, filename): + """Dumps dict/list arg1 to file arg2""" + with open(filename, "w", encoding='utf8') as file: + json.dump(contents, file, ensure_ascii=False, indent=4) + file.close() + return + + # Функция добавления переменных, если их нет def repairConfig(some_dic): @@ -279,7 +383,7 @@ def setConfig(some_var, some_val): try: config_list[some_var] = some_val saveJson(files_folder+'config.json', config_list) - appendLog(f'Changed variable "{somevar}" to {some_val}') + appendLog(f'Changed variable "{some_var}" to {some_val}') except: @@ -289,7 +393,7 @@ def setConfig(some_var, some_val): json_file.close() config_list[some_var] = some_val saveJson(files_folder+'config.json', config_list) - appendLog(f'Changed variable "{somevar}" to {some_val}') + appendLog(f'Changed variable "{some_var}" to {some_val}') except: pass @@ -326,12 +430,12 @@ def setConfig(some_var, some_val): json_file.close() config_list[some_var] = some_val saveJson(files_folder+'config.json', config_list) - appendLog(f'Changed variable "{somevar}" to {some_val}') + appendLog(f'Changed variable "{some_var}" 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}') + appendLog(f'Changed variable "{some_var}" to {some_val}') except: return "Error" @@ -433,4 +537,68 @@ def getState(process="CptHost.exe"): def saveJson(filename, value): with open(filename, 'w', encoding="utf-8") as f: json.dump(value, f, indent=4, ensure_ascii=False) - f.close() \ No newline at end of file + f.close() + +# Fire some function +_loop = None +def fire_and_forget(coro): + global _loop + if _loop is None: + _loop = asyncio.new_event_loop() + threading.Thread(target=_loop.run_forever, daemon=True).start() + _loop.call_soon_threadsafe(asyncio.create_task, coro) + + +def configSet(key: str, value, *args: str): + """Set key to a value + + Args: + * key (str): The last key of the keys path. + * value (str/int/float/list/dict/None): Some needed value. + * *args (str): Path to key like: dict[args][key]. + """ + this_dict = jsonLoad(f"{files_folder}config.json") + string = "this_dict" + + for arg in args: + string += f'["{arg}"]' + + if type(value) in [str]: + string += f'["{key}"] = "{value}"' + else: + string += f'["{key}"] = {value}' + + exec(string) + jsonSave(this_dict, f"{files_folder}config.json") + return + +def configGet(key: str, *args: str): + """Get value of the config key + + Args: + * key (str): The last key of the keys path. + * *args (str): Path to key like: dict[args][key]. + + Returns: + * any: Value of provided key + """ + this_dict = jsonLoad(f"{files_folder}config.json") + this_key = this_dict + for dict_key in args: + this_key = this_key[dict_key] + return this_key[key] + +async def execBind(action: str, kind="command"): + """Execute binded action + + Args: + * action (str): Bind, command or message. + * kind (str, optional): "keybind", "command" or "message". Defaults to "command". + """ + if kind == "message": + telegramSendText(message=action) + elif kind == "keybind": + keyboard.press_and_release(action) + else: + os.system(action) + return \ No newline at end of file diff --git a/modules/install.py b/modules/install.py new file mode 100644 index 0000000..c730577 --- /dev/null +++ b/modules/install.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- + +import os +from modules.functions import getOS, appendLog + +libs = ["keyboard", "ast", "inputimeout", "telegram_send", "wget", "requests", "zipfile", "asyncio", "getpass", "pypresence"] + +if getOS() == "windows": + libs.append("easygui") + libs.append("tkinter") + libs.append("swinlnk") + +if getOS() != "android": + libs.append("playsound") +else: + try: + if not "play-audio" in os.popen('pkg list-all').read(): + os.system('pkg install play-audio') + except: + appendLog("Could not install play-audio") + +with open('requirements.txt', 'w', encoding='utf-8') as f: + f.writelines('\n'.join(libs)) \ No newline at end of file diff --git a/rpc.py b/modules/rpc.py similarity index 91% rename from rpc.py rename to modules/rpc.py index 1ff4601..68ca6e9 100644 --- a/rpc.py +++ b/modules/rpc.py @@ -3,12 +3,11 @@ import time import os import sys -from colors import * -from functions import * +from modules.colors import * +from modules.functions import * -version = '2.6' +version = '2.7' -import libinstaller from pypresence import Presence client_id = getConfig("rpc_id") @@ -27,7 +26,7 @@ rpc_dict = { "large_image": "1024_cover", "small_image": { "waiting": "status_waiting", - "conference": "status_lesson", + "meeting": "status_lesson", "menu": "status_menu", "shutdown": "status_shutdown", "settings": "status_settings", @@ -108,11 +107,11 @@ def changePresence(sml_img, sml_txt, stt, dtls, start=None, end=None): time.sleep(1) -def waitLesson(conference, start): - changePresence("waiting", "Ожидание", f"Ждём начала «{conference}»", "Конференция не началась", start=start) +def waitLesson(meeting, start): + changePresence("waiting", "Ожидание", f"Ждём начала «{meeting}»", "Конференция не началась", start=start) -def onLesson(conference, start): - changePresence("conference", "Конференция", f"Слушаем «{conference}»", "Идёт конференция", start=start) +def onLesson(meeting, start): + changePresence("meeting", "Конференция", f"Слушаем «{meeting}»", "Идёт конференция", start=start) def inMenu(): changePresence("menu", "Главное меню", "Открыт список опций", "В главном меню") diff --git a/settings.py b/modules/settings.py similarity index 97% rename from settings.py rename to modules/settings.py index 0bac79f..a1f38bd 100644 --- a/settings.py +++ b/modules/settings.py @@ -1,12 +1,12 @@ -import rpc +import modules.rpc as rpc import pathlib import shutil -from functions import * -#from daemon import +import telegram_send +from modules.functions import * if getConfig("use_colors"): - from colors import * + from modules.colors import * appendLog('Colors imported') else: RESET = '' @@ -152,6 +152,7 @@ def settings(): if obs_choice.lower() in yes_list: while True: try: + import easygui filename = easygui.fileopenbox('Выберите путь до obs32.exe или obs64.exe') if filename.find("obs64.exe") != -1: setConfig("obs_exe", filename) @@ -174,6 +175,11 @@ def settings(): else: easygui.msgbox("Неверный путь") break + except NameError: + appendLog(f'Module "easygui" is not imported') + none = input('Модуль "easygui" не импортирован.\n\n > ') + clear() + break except Exception as exp: appendLog(f'Could not select OBS path: {exp}') none = input('Вы не выбрали верный путь для OBS.\n\n > ') @@ -532,7 +538,7 @@ def settings3(): elif settings_choose == '6': appendLog('Going to customize page') clear() - customize() + #customize() elif settings_choose == '7': appendLog('Resetting configuration') @@ -543,7 +549,7 @@ def settings3(): if reset_decision.lower() in yes_list: - from functions import default_config + from modules.functions import default_config saveJson(files_folder+'config.json', default_config) appendLog('Configuration dropped to default') diff --git a/modules/telegram.py b/modules/telegram.py new file mode 100644 index 0000000..1b96253 --- /dev/null +++ b/modules/telegram.py @@ -0,0 +1,27 @@ +import time +import requests + +from modules.functions import configGet, configSet + +def telegramSendText(message, force=False, token=configGet("token", "telegram")): + if configGet("enabled", "telegram") or force: + try: + requests.post(f'https://api.telegram.org/bot{token}/sendMessage?chat_id={configGet("user_id", "telegram")}&text={message}&parse_mode=markdown') + except: + pass + +def telegramLink(token): + try: + code = + while True: + answer = requests.post(f"https://api.telegram.org/bot{token}/getUpdates").json() + for entry in answer["result"]: + if "message" in entry: + if str(code) in entry["message"]["text"]: + telegramSendText("Бот успешно привязан к AutoZoom!", force=True, token=token) + configSet("user_id", entry["message"]["from"]["id"], "telegram") + print(f"Бот успешно привязан к аккаунту {entry['message']['from']['first_name']}!") + return {"success": True, "user_id": entry["message"]["from"]["id"]} + time.sleep(1) + except KeyboardInterrupt: + return {"success": False, "user_id": None} \ No newline at end of file diff --git a/start.bat b/start.bat index 4f4b79d..2739075 100644 --- a/start.bat +++ b/start.bat @@ -1,3 +1,3 @@ echo AutoZoom needs Python 3 to work. Please read README.md! -python main.py +python3 main.py pause \ No newline at end of file diff --git a/start.sh b/start.sh index 1b23950..adba630 100644 --- a/start.sh +++ b/start.sh @@ -1,4 +1,4 @@ #!/bin/bash echo "AutoZoom needs Python 3 to work. Please read README.md!" -python3 main.py +python3 main.py \ No newline at end of file diff --git a/themes/dark.json b/themes/dark.json new file mode 100644 index 0000000..3a62a7f --- /dev/null +++ b/themes/dark.json @@ -0,0 +1,10 @@ +{ + "windows": { + "foreground": "7", + "background": "0" + }, + "linux": { + "foreground": "white", + "background": "black" + } +} \ No newline at end of file diff --git a/themes/light.json b/themes/light.json new file mode 100644 index 0000000..6da4435 --- /dev/null +++ b/themes/light.json @@ -0,0 +1,10 @@ +{ + "windows": { + "foreground": "0", + "background": "f" + }, + "linux": { + "foreground": "black", + "background": "white" + } +} \ No newline at end of file