204 lines
6.9 KiB
Python
204 lines
6.9 KiB
Python
![]() |
'''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
|