ocp5/cli.py

233 lines
6.3 KiB
Python
Raw Normal View History

2018-08-04 15:48:58 +00:00
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Author: freezed <freezed@users.noreply.github.com> 2018-08-04
Version: 0.1
Licence: `GNU GPL v3` GNU GPL v3: http://www.gnu.org/licenses/
Command line interface to interact with local DB
Choose a product in a list of aivaiable categories['results_list'],
the system gives you an alternative with a better 'nutriscore'.
2018-08-04 15:48:58 +00:00
You can save this product to get it later.
"""
from os import system
from db import Db
from config import DB_REQUEST, CLI_MSG_DISCLAIMER, CLI_MSG_ASK_IDX, \
CLI_MSG_ASK_ERR, CLI_MSG_QUIT, CLI_MSG_CHOOSEN_CAT, CLI_MSG_PROD, \
CLI_MSG_SUBST, CLI_MSG_NO_SUBST, CLI_MSG_CAT, CLI_MSG_CHOOSEN_PROD, \
CLI_MSG_DETAILLED_SUB, CLI_MSG_CHOOSEN_SUBST, CLI_ITEM_MAX_LEN, \
CLI_ITEM_LIST
cli_end_msg = str()
2018-08-07 00:54:46 +00:00
product_asked = {'valid_item': False}
2018-08-04 15:48:58 +00:00
def ask_user(head_msg, item_list):
"""
Ask user to choose an item in the provided list, using numeric index
:head_msg: Text displayed in header
:item_list: Dict() containing all data about item (see `get_data_list()`)
:result:
- item:
- cli_end_msg:
- valid_item:
"""
valid_input = False
foot_msg = ""
while valid_input is False:
system('clear')
print(head_msg)
print(item_list['results_txt'])
print(foot_msg)
user_input = input(CLI_MSG_ASK_IDX.format(item_list['max_id']))
if user_input.lower() == "q":
valid_input = True
valid_item = False
item = ""
else:
try:
user_input = int(user_input)
# Response not int(), re-ask
except ValueError:
foot_msg += CLI_MSG_ASK_ERR.format(user_input)
else:
# Response is valid
if user_input <= item_list['max_id']:
valid_input = True
valid_item = True
item = item_list['results_list'][user_input]
# Response not in range, re-ask
else:
foot_msg += CLI_MSG_ASK_ERR.format(user_input)
return {
'item': item,
'cli_end_msg': foot_msg,
'valid_item': valid_item
}
def get_data_list(db_obj, sql):
"""
Gets data from DB & return them formated as a text list displayable on CLI
:db_obj: a database object [PyMySQL]
:sql: a SQL query
:Return: a dict containing details on requested data:
- max_id: maximum ID
- results_list: stored in a list of tuple (id, name, count)
- results_txt: in a string, text-formated
"""
db_obj.execute(sql)
max_id = int(db_obj.cursor.rowcount - 1)
results_list = [(idx, val['name'], val['option'], val['id'])
for idx, val in enumerate(db_obj.result)]
# Hacky results-split for rendering in 2 columns
res_even = [(
idx,
val['name'][:CLI_ITEM_MAX_LEN].ljust(CLI_ITEM_MAX_LEN),
val['option'], val['id']
) for idx, val in enumerate(db_obj.result) if idx % 2 == 0]
res_uneven = [(
idx,
val['name'][:CLI_ITEM_MAX_LEN],
val['option'],
val['id']
) for idx, val in enumerate(db_obj.result) if idx % 2 != 0]
# category list
results_txt = ""
for num, unused in enumerate(res_uneven):
results_txt += CLI_ITEM_LIST.format(
res_even[num][0],
res_even[num][1],
res_uneven[num][0],
res_uneven[num][1]
)
if len(res_uneven) < len(res_even):
num += 1
results_txt += "{} : {}\n".format(
res_even[num][0],
res_even[num][1]
)
return {
'max_id': max_id,
'results_list': results_list,
'results_txt': results_txt
}
# Starts a DB connection
LOCAL_DB = Db()
####################
# LISTS CATEGORIES #
####################
category_list = get_data_list(
LOCAL_DB,
DB_REQUEST['list_cat']
)
head_msg = CLI_MSG_DISCLAIMER
head_msg += CLI_MSG_CAT
# Asks the user to select a category
category_asked = ask_user(
head_msg,
category_list
)
##################
# LISTS PRODUCTS #
##################
if category_asked['valid_item']:
2018-08-07 00:54:46 +00:00
product_list = get_data_list(
LOCAL_DB, DB_REQUEST['list_prod'].format(category_asked['item'][3])
2018-08-07 00:54:46 +00:00
)
head_msg = CLI_MSG_DISCLAIMER
head_msg += CLI_MSG_CHOOSEN_CAT.format(category_asked['item'][1])
head_msg += CLI_MSG_PROD
2018-08-07 00:54:46 +00:00
# Asks the user to select a product
product_asked = ask_user(
head_msg,
product_list
)
2018-08-07 00:54:46 +00:00
####################
# LISTS SUBTITUTES #
####################
2018-08-07 00:54:46 +00:00
if product_asked['valid_item']:
substitute_list = get_data_list(
LOCAL_DB,
DB_REQUEST['list_substitute'].format(
category_asked['item'][3],
product_asked['item'][2]
)
)
head_msg = CLI_MSG_DISCLAIMER
head_msg += CLI_MSG_CHOOSEN_CAT.format(category_asked['item'][1])
head_msg += CLI_MSG_CHOOSEN_PROD.format(product_asked['item'][1])
head_msg += CLI_MSG_SUBST
# No substitute found
if substitute_list['max_id'] == -1:
cli_end_msg = CLI_MSG_NO_SUBST.format(
product_asked['item'][1],
product_asked['item'][2]
)
# Asks the user to select a substitute
elif substitute_list['max_id'] > 0:
substit_asked = ask_user(
head_msg,
substitute_list
)
2018-08-04 15:48:58 +00:00
##########################
# SHOW SUBTITUTE DETAILS #
##########################
if substit_asked['valid_item']:
LOCAL_DB.execute(DB_REQUEST['select_substitute'].format(
substit_asked['item'][3]
))
head_msg = CLI_MSG_DISCLAIMER
head_msg += CLI_MSG_CHOOSEN_CAT.format(category_asked['item'][1])
head_msg += CLI_MSG_CHOOSEN_PROD.format(product_asked['item'][1])
head_msg += CLI_MSG_CHOOSEN_SUBST.format(substit_asked['item'][1])
head_msg += CLI_MSG_DETAILLED_SUB.format(
code=LOCAL_DB.result[0]['code'],
nutri=LOCAL_DB.result[0]['nutrition_grades'],
url=LOCAL_DB.result[0]['url']
)
system('clear')
print(head_msg)
2018-08-04 15:48:58 +00:00
# Saves if user choose it
2018-08-04 15:48:58 +00:00
else:
cli_end_msg = CLI_MSG_QUIT
else:
cli_end_msg = CLI_MSG_QUIT
print(cli_end_msg)