BRE/webapi/menu.py

204 lines
6.9 KiB
Python
Raw Permalink Normal View History

2024-06-07 19:50:21 +03:00
'''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