'''Main menu for BRE''' import sys import os import logging from datetime import datetime from enum import IntEnum, unique import portal as bre _CONFIG_FOLDER = 'configs/' _CONFIG_MAIN = '!Menu.ini' _CONFIG_APPDATA = '!AppData.ini' _CONFIG_OPTIONS = '!Options.ini' _SYSTEM_CONFIGS = [_CONFIG_MAIN, _CONFIG_APPDATA, _CONFIG_OPTIONS] _TEXT_MAIN_MENU = '''Системное меню [{}] 0. Выбрать пользователя 1. Шифровать пароль пользователя 2. Проверить наличие контента 3. Завести карт-слоты 4. Ввести метаданные 5. Обновить метаданные 6. Загрузить тексты 8. Выгрузить список задач 9. Завершить работу ''' '''Pairs of flags to indicate if actions needs input / output setup''' _ACCTIONS_REQUIREMENTS= [ (False, False), # 0 (False, False), # 1 (True, True), # 2 (True, True), # 3 (True, False), # 4 (True, False), # 5 (True, False), # 6 (False, False), # 7 (False, True), # 8 (False, False), # 9 ] @unique class MenuAction(IntEnum): '''Действие в главном меню''' choose_user = 0 encrypt_password = 1 check_existence = 2 import_cards = 3 import_meta = 4 update_meta = 5 load_content_text = 6 export_tasks = 8 exit = 9 def needs_input(self) -> bool: '''Get text label for field''' return _ACCTIONS_REQUIREMENTS[self.value][0] def needs_output(self) -> bool: '''Get text label for field''' return _ACCTIONS_REQUIREMENTS[self.value][1] def _list_configs() -> list[str]: filenames = next(os.walk(_CONFIG_FOLDER), (None, None, []))[2] return [item.split('.')[0] for item in filenames if item not in _SYSTEM_CONFIGS] class Menu: '''Portal menu UI''' def __init__(self): self._config = bre.read_config(_CONFIG_FOLDER + _CONFIG_MAIN) self._password = '' def __del__(self): pass def start(self): '''Entry point''' password = input('Введите пароль: ') if not self._unlock(password): print('Пароль не прошел проверку') sys.exit() self._main_loop() def _unlock(self, password: str) -> bool: if not bre.validate_password(password): return False self._password = password return True def _main_loop(self): while True: os.system('cls') print(_TEXT_MAIN_MENU.format(self._config['Launch']['User'])) action = MenuAction(int(input('Введите число: '))) self._process_action(action) def _process_action(self, action: MenuAction): if action == MenuAction.exit: sys.exit(0) elif action == MenuAction.choose_user: self._change_user() return elif action == MenuAction.encrypt_password: self._encrypt() return portal = self._setup_action(action) if portal is None: return if action == MenuAction.import_meta: result = portal.import_meta() == 0 elif action == MenuAction.update_meta: result = portal.update_meta() == 0 elif action == MenuAction.export_tasks: result = portal.export_tasks() == 0 elif action == MenuAction.check_existence: result = portal.check_existence() == 0 elif action == MenuAction.import_cards: result = portal.import_cardslots() == 0 elif action == MenuAction.load_content_text: result = portal.load_texts() == 0 del portal if result: print('Действие завершено успешно') else: print('Действие не выполнено') print('Введите любой символ для возврата в основное меню') input() def _setup_action(self, action: MenuAction) -> bre.PortalAPI: user_config = self._prepare_config() portal = bre.PortalAPI(user_config) if not portal.validate(user_config['AppData']['Password']): print('Portal API invalid...') input() return None if action.needs_input() and not portal.set_input(user_config['UserData']['Input']): print('Input init failed...') input() return None if action.needs_output() and not portal.set_output_tasks(self._config['Launch']['Output']): print('Output init failed...') input() return None return portal def _change_user(self): os.system('cls') print('Текущий пользователь: {}'.format(self._config['Launch']['User'])) print('0. Вернуться в основное меню') user_configs = _list_configs() for idx, name in enumerate(user_configs): print('{}. {}'.format(idx + 1, name)) action = int(input('Введите число: ')) if action == 0: return self._config['Launch']['User'] = user_configs[action - 1] def _encrypt(self): os.system('cls') user = input('Введите логин пользователя: ') password = input('Введите пароль пользователя: ') cypher = bre.encrypt_user(user, password, self._password) print('Шифрограмма пароля: {}\nСкопируйте этот текст в конфиг-файл пользователя\n'.format(cypher)) input('Ввдеите любой символ для возврата в основное меню\n') def _prepare_config(self) -> bre.Config: file_name = self._config['Launch']['Config'] output = open(file_name, 'w', encoding='UTF-8') inputs = [_CONFIG_APPDATA, _CONFIG_OPTIONS, self._config['Launch']['User'] + '.ini'] for input_name in inputs: with open(_CONFIG_FOLDER + input_name, 'r', encoding='UTF-8') as infile: output.write(infile.read()) output.write('\n') output.close() config = bre.read_config(file_name) os.remove(file_name) config['AppData']['Password'] = self._password return config if __name__ == '__main__': if not os.path.exists("logs/"): os.makedirs("logs/") logging.basicConfig( filename=datetime.now().strftime('logs/%Y%m%d_%H%M menu.log'), encoding='utf-8', level=logging.INFO, format='%(asctime)s %(levelname)s %(funcName)s: %(message)s', datefmt='%Y%m%d_%H:%M:%S' ) logging.getLogger().addHandler(logging.StreamHandler()) try: Menu().start() except SystemExit as e: sys.exit(e) except: # pylint: disable=bare-except logging.exception("message") raise