PEP-8 compliance for text-based

This commit is contained in:
Christoffer Viken 2017-02-10 17:09:22 +00:00
parent ba8f80e4aa
commit 4d254c612f
1 changed files with 228 additions and 223 deletions

View File

@ -1,17 +1,17 @@
#!/usr/bin/python #!/usr/bin/python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import sqlalchemy
from sqlalchemy import distinct
from sqlalchemy.sql import func
from sqlalchemy import desc
import re, sys, os, traceback, signal, readline
from select import select
import os
from helpers import *
import random import random
import re
import sys
import traceback
from select import select
import sqlalchemy
from helpers import *
from sqlalchemy import desc
from sqlalchemy.sql import func
from statistikkHelpers import statisticsTextOnly from statistikkHelpers import statisticsTextOnly
from math import ceil
random.seed() random.seed()
exit_commands = ['exit', 'abort', 'quit', 'bye', 'eat flaming death', 'q'] exit_commands = ['exit', 'abort', 'quit', 'bye', 'eat flaming death', 'q']
@ -25,13 +25,14 @@ restart_commands = ['restart']
class ExitMenu(Exception): class ExitMenu(Exception):
pass pass
class Menu():
def __init__(self, name, items=[], prompt='> ', class Menu(object):
def __init__(self, name, items=None, prompt='> ',
return_index=True, return_index=True,
exit_msg=None, exit_confirm_msg=None, exit_disallowed_msg=None, exit_msg=None, exit_confirm_msg=None, exit_disallowed_msg=None,
help_text=None, uses_db=False): help_text=None, uses_db=False):
self.name = name self.name = name
self.items = items self.items = items if items is not None else []
self.prompt = prompt self.prompt = prompt
self.return_index = return_index self.return_index = return_index
self.exit_msg = exit_msg self.exit_msg = exit_msg
@ -44,10 +45,10 @@ class Menu():
self.session = None self.session = None
def exit_menu(self): def exit_menu(self):
if self.exit_disallowed_msg != None: if self.exit_disallowed_msg is not None:
print self.exit_disallowed_msg print self.exit_disallowed_msg
return return
if self.exit_confirm_msg != None: if self.exit_confirm_msg is not None:
if not self.confirm(self.exit_confirm_msg, default=True): if not self.confirm(self.exit_confirm_msg, default=True):
return return
raise ExitMenu() raise ExitMenu()
@ -58,7 +59,7 @@ class Menu():
def set_context(self, string, display=True): def set_context(self, string, display=True):
self.context = string self.context = string
if self.context != None and display: if self.context is not None and display:
print self.context print self.context
def add_to_context(self, string): def add_to_context(self, string):
@ -66,14 +67,14 @@ class Menu():
def printc(self, string): def printc(self, string):
print string print string
if self.context == None: if self.context is None:
self.context = string self.context = string
else: else:
self.context += '\n' + string self.context += '\n' + string
def show_context(self): def show_context(self):
print self.header_format % self.name print self.header_format % self.name
if self.context != None: if self.context is not None:
print self.context print self.context
def item_is_submenu(self, i): def item_is_submenu(self, i):
@ -96,20 +97,20 @@ class Menu():
def input_str(self, prompt=None, regex=None, length_range=(None, None), def input_str(self, prompt=None, regex=None, length_range=(None, None),
empty_string_is_none=False, timeout=None): empty_string_is_none=False, timeout=None):
if prompt == None: if prompt is None:
prompt = self.prompt prompt = self.prompt
if regex != None: if regex is not None:
while True: while True:
result = self.input_str(prompt, length_range=length_range, result = self.input_str(prompt, length_range=length_range,
empty_string_is_none=empty_string_is_none) empty_string_is_none=empty_string_is_none)
if result == None or re.match(regex+'$', result): if result is None or re.match(regex + '$', result):
return result return result
else: else:
print 'Value must match regular expression "%s"' % regex print 'Value must match regular expression "%s"' % regex
if length_range != (None, None): if length_range != (None, None):
while True: while True:
result = self.input_str(prompt, empty_string_is_none=empty_string_is_none) result = self.input_str(prompt, empty_string_is_none=empty_string_is_none)
if result == None: if result is None:
length = 0 length = 0
else: else:
length = len(result) length = len(result)
@ -125,7 +126,8 @@ class Menu():
return result return result
while True: while True:
try: try:
result = None # result = None
# It is replaced either way
if timeout: if timeout:
# assuming line buffering # assuming line buffering
sys.stdout.write(safe_str(prompt)) sys.stdout.write(safe_str(prompt))
@ -166,18 +168,18 @@ class Menu():
return None return None
return result return result
def special_input_choice(self, str): def special_input_choice(self, in_str):
''' """
Handle choices which are not simply menu items. Handle choices which are not simply menu items.
Override this in subclasses to implement magic menu Override this in subclasses to implement magic menu
choices. Return True if str was some valid magic menu choices. Return True if str was some valid magic menu
choice, False otherwise. choice, False otherwise.
''' """
return False return False
def input_choice(self, number_of_choices, prompt=None): def input_choice(self, number_of_choices, prompt=None):
if prompt == None: if prompt is None:
prompt = self.prompt prompt = self.prompt
while True: while True:
result = self.input_str(prompt) result = self.input_str(prompt)
@ -198,18 +200,18 @@ class Menu():
else: else:
if result.isdigit(): if result.isdigit():
choice = int(result) choice = int(result)
if (choice == 0 and 10 <= number_of_choices): if choice == 0 and 10 <= number_of_choices:
return 10 return 10
if (choice > 0 and choice <= number_of_choices): if choice > 0 and choice <= number_of_choices:
return choice return choice
if not self.special_input_choice(result): if not self.special_input_choice(result):
self.invalid_menu_choice(result) self.invalid_menu_choice(result)
def invalid_menu_choice(self, str): def invalid_menu_choice(self, in_str):
print 'Please enter a valid choice.' print 'Please enter a valid choice.'
def input_int(self, prompt=None, allowed_range=(None, None), null_allowed=False, default=None): def input_int(self, prompt=None, allowed_range=(None, None), null_allowed=False, default=None):
if prompt == None: if prompt is None:
prompt = self.prompt prompt = self.prompt
if default is not None: if default is not None:
prompt += ("[%s] " % default) prompt += ("[%s] " % default)
@ -237,7 +239,7 @@ class Menu():
def input_user(self, prompt=None): def input_user(self, prompt=None):
user = None user = None
while user == None: while user is None:
user = self.retrieve_user(self.input_str(prompt)) user = self.retrieve_user(self.input_str(prompt))
return user return user
@ -246,7 +248,7 @@ class Menu():
def input_product(self, prompt=None): def input_product(self, prompt=None):
product = None product = None
while product == None: while product is None:
product = self.retrieve_product(self.input_str(prompt)) product = self.retrieve_product(self.input_str(prompt))
return product return product
@ -256,7 +258,7 @@ class Menu():
def input_thing(self, prompt=None, permitted_things=('user', 'product'), def input_thing(self, prompt=None, permitted_things=('user', 'product'),
add_nonexisting=(), empty_input_permitted=False, find_hidden_products=True): add_nonexisting=(), empty_input_permitted=False, find_hidden_products=True):
result = None result = None
while result == None: while result is None:
search_str = self.input_str(prompt) search_str = self.input_str(prompt)
if search_str == '' and empty_input_permitted: if search_str == '' and empty_input_permitted:
return None return None
@ -266,7 +268,8 @@ class Menu():
def input_multiple(self, prompt=None, permitted_things=('user', 'product'), def input_multiple(self, prompt=None, permitted_things=('user', 'product'),
add_nonexisting=(), empty_input_permitted=False, find_hidden_products=True): add_nonexisting=(), empty_input_permitted=False, find_hidden_products=True):
result = None result = None
while result == None: num = 0
while result is None:
search_str = self.input_str(prompt) search_str = self.input_str(prompt)
search_lst = search_str.split(" ") search_lst = search_str.split(" ")
if search_str == '' and empty_input_permitted: if search_str == '' and empty_input_permitted:
@ -275,17 +278,17 @@ class Menu():
result = self.search_for_thing(search_str, permitted_things, add_nonexisting, find_hidden_products) result = self.search_for_thing(search_str, permitted_things, add_nonexisting, find_hidden_products)
num = 1 num = 1
if (result == None) and (len(search_lst) > 1): if (result is None) and (len(search_lst) > 1):
print 'Interpreting input as "<number> <product>"' print 'Interpreting input as "<number> <product>"'
try: try:
num = int(search_lst[0]) num = int(search_lst[0])
result = self.search_for_thing(" ".join(search_lst[1:]), permitted_things,add_nonexisting, find_hidden_products) result = self.search_for_thing(" ".join(search_lst[1:]), permitted_things, add_nonexisting,
find_hidden_products)
# Her kan det legges inn en except ValueError, # Her kan det legges inn en except ValueError,
# men da blir det fort mye plaging av brukeren # men da blir det fort mye plaging av brukeren
except Exception as e: except Exception as e:
print(e) print(e)
return (result,num) return result, num
def search_for_thing(self, search_str, permitted_things=('user', 'product'), def search_for_thing(self, search_str, permitted_things=('user', 'product'),
add_nonexisting=(), find_hidden_products=True): add_nonexisting=(), find_hidden_products=True):
@ -297,18 +300,18 @@ class Menu():
results[thing] = search_fun[thing](search_str, self.session, find_hidden_products) results[thing] = search_fun[thing](search_str, self.session, find_hidden_products)
result_values[thing] = self.search_result_value(results[thing]) result_values[thing] = self.search_result_value(results[thing])
selected_thing = argmax(result_values) selected_thing = argmax(result_values)
if results[selected_thing] == []: if not results[selected_thing]:
thing_for_type = {'card': 'user', 'username': 'user', thing_for_type = {'card': 'user', 'username': 'user',
'bar_code': 'product', 'rfid': 'rfid'} 'bar_code': 'product', 'rfid': 'rfid'}
type_guess = guess_data_type(search_str) type_guess = guess_data_type(search_str)
if type_guess != None and thing_for_type[type_guess] in add_nonexisting: if type_guess is not None and thing_for_type[type_guess] in add_nonexisting:
return self.search_add(search_str) return self.search_add(search_str)
# print 'No match found for "%s".' % search_str # print 'No match found for "%s".' % search_str
return None return None
return self.search_ui2(search_str, results[selected_thing], selected_thing) return self.search_ui2(search_str, results[selected_thing], selected_thing)
def search_result_value(self, result): def search_result_value(self, result):
if result == None: if result is None:
return 0 return 0
if not isinstance(result, list): if not isinstance(result, list):
return 3 return 3
@ -349,7 +352,6 @@ class Menu():
print '"%s" looks like the bar code for a product, but no such product exists.' % string print '"%s" looks like the bar code for a product, but no such product exists.' % string
return None return None
def search_ui(self, search_fun, search_str, thing): def search_ui(self, search_fun, search_str, thing):
result = search_fun(search_str, self.session) result = search_fun(search_str, self.session)
return self.search_ui2(search_str, result, thing) return self.search_ui2(search_str, result, thing)
@ -379,13 +381,11 @@ class Menu():
return_index=False) return_index=False)
return selector.execute() return selector.execute()
def confirm(self, prompt, default=None, timeout=None): def confirm(self, prompt, default=None, timeout=None):
return ConfirmMenu(prompt, default, timeout).execute() return ConfirmMenu(prompt, default, timeout).execute()
def print_header(self): def print_header(self):
print print ""
print self.header_format % self.name print self.header_format % self.name
def pause(self): def pause(self):
@ -416,10 +416,10 @@ it by putting money in the box and using the "Adjust credit" menu.
''' '''
def local_help(self): def local_help(self):
if self.help_text == None: if self.help_text is None:
print 'no help here' print 'no help here'
else: else:
print print ''
print 'Help for %s:' % (self.header_format % self.name) print 'Help for %s:' % (self.header_format % self.name)
print self.help_text print self.help_text
@ -433,11 +433,11 @@ it by putting money in the box and using the "Adjust credit" menu.
self.at_exit() self.at_exit()
return None return None
finally: finally:
if self.session != None: if self.session is not None:
self.session.close() self.session.close()
self.session = None self.session = None
def _execute(self): def _execute(self, **kwargs):
line_format = '%' + str(len(str(len(self.items)))) + 'd ) %s' line_format = '%' + str(len(str(len(self.items)))) + 'd ) %s'
while True: while True:
self.print_header() self.print_header()
@ -456,10 +456,10 @@ it by putting money in the box and using the "Adjust credit" menu.
class Selector(Menu): class Selector(Menu):
def __init__(self, name, items=[], prompt='select> ', def __init__(self, name, items=None, prompt='select> ', return_index=True, exit_msg=None, exit_confirm_msg=None,
return_index=True,
exit_msg=None, exit_confirm_msg=None,
help_text=None): help_text=None):
if items is None:
items = []
Menu.__init__(self, name, items, prompt, return_index, exit_msg) Menu.__init__(self, name, items, prompt, return_index, exit_msg)
self.header_format = '%s' self.header_format = '%s'
@ -467,11 +467,11 @@ class Selector(Menu):
print self.header_format % self.name print self.header_format % self.name
def local_help(self): def local_help(self):
if self.help_text == None: if self.help_text is None:
print 'This is a selection menu. Enter one of the listed numbers, or' print 'This is a selection menu. Enter one of the listed numbers, or'
print '\'exit\' to go out and do something else.' print '\'exit\' to go out and do something else.'
else: else:
print print ''
print 'Help for selector (%s):' % self.name print 'Help for selector (%s):' % self.name
print self.help_text print self.help_text
@ -492,7 +492,7 @@ class ConfirmMenu(Menu):
return True return True
elif result in ['n', 'no']: elif result in ['n', 'no']:
return False return False
elif self.default != None and result == '': elif self.default is not None and result == '':
return self.default return self.default
else: else:
print 'Please answer yes or no' print 'Please answer yes or no'
@ -506,7 +506,7 @@ class MessageMenu(Menu):
def _execute(self): def _execute(self):
self.print_header() self.print_header()
print print ''
print self.message print self.message
if self.pause_after_message: if self.pause_after_message:
self.pause() self.pause()
@ -608,7 +608,6 @@ class FAQMenu(Menu):
''')] ''')]
class TransferMenu(Menu): class TransferMenu(Menu):
def __init__(self): def __init__(self):
Menu.__init__(self, 'Transfer credit between users', Menu.__init__(self, 'Transfer credit between users',
@ -676,7 +675,7 @@ user, then rfid (write an empty line to remove the card number or rfid).
user = self.input_user('User> ') user = self.input_user('User> ')
self.printc('Editing user %s' % user.name) self.printc('Editing user %s' % user.name)
card_str = '"%s"' % user.card card_str = '"%s"' % user.card
if user.card == None: if user.card is None:
card_str = 'empty' card_str = 'empty'
user.card = self.input_str('Card number (currently %s)> ' % card_str, user.card = self.input_str('Card number (currently %s)> ' % card_str,
User.card_re, (0, 10), User.card_re, (0, 10),
@ -685,7 +684,7 @@ user, then rfid (write an empty line to remove the card number or rfid).
user.card = user.card.lower() user.card = user.card.lower()
rfid_str = '"%s"' % user.rfid rfid_str = '"%s"' % user.rfid
if user.rfid == None: if user.rfid is None:
rfid_str = 'empty' rfid_str = 'empty'
user.rfid = self.input_str('RFID (currently %s)> ' % rfid_str, user.rfid = self.input_str('RFID (currently %s)> ' % rfid_str,
User.rfid_re, (0, 10), User.rfid_re, (0, 10),
@ -749,7 +748,7 @@ class EditProductMenu(Menu):
print 'Could not store product %s: %s' % (product.name, e) print 'Could not store product %s: %s' % (product.name, e)
self.pause() self.pause()
return return
elif what == None: elif what is None:
print 'Edit aborted' print 'Edit aborted'
return return
else: else:
@ -768,7 +767,8 @@ class ShowUserMenu(Menu):
print 'RFID: %s' % user.rfid print 'RFID: %s' % user.rfid
print 'Credit: %s kr' % user.credit print 'Credit: %s kr' % user.credit
selector = Selector('What do you want to know about %s?' % user.name, selector = Selector('What do you want to know about %s?' % user.name,
items=[('transactions', 'Recent transactions (List of last ' + str(conf.user_recent_transaction_limit) + ')'), items=[('transactions', 'Recent transactions (List of last ' + str(
conf.user_recent_transaction_limit) + ')'),
('products', 'Which products %s has bought, and how many' % user.name), ('products', 'Which products %s has bought, and how many' % user.name),
('transactions-all', 'Everything (List of all transactions)')]) ('transactions-all', 'Everything (List of all transactions)')])
what = selector.execute() what = selector.execute()
@ -832,7 +832,7 @@ class ShowUserMenu(Menu):
products.append((product, count)) products.append((product, count))
num_products = len(products) num_products = len(products)
if num_products == 0: if num_products == 0:
print('No products purchased yet') print 'No products purchased yet'
else: else:
text = '' text = ''
text += 'Products purchased:\n' text += 'Products purchased:\n'
@ -877,6 +877,7 @@ addition, and you can type 'what' at any time to redisplay it.
When finished, write an empty line to confirm the purchase. When finished, write an empty line to confirm the purchase.
''' '''
def credit_check(self, user): def credit_check(self, user):
""" """
@ -893,7 +894,7 @@ When finished, write an empty line to confirm the purchase.
print "***********************************************************************" print "***********************************************************************"
print "***********************************************************************" print "***********************************************************************"
print print ""
print "$$\ $$\ $$$$$$\ $$$$$$$\ $$\ $$\ $$$$$$\ $$\ $$\ $$$$$$\\" print "$$\ $$\ $$$$$$\ $$$$$$$\ $$\ $$\ $$$$$$\ $$\ $$\ $$$$$$\\"
print "$$ | $\ $$ |$$ __$$\ $$ __$$\ $$$\ $$ |\_$$ _|$$$\ $$ |$$ __$$\\" print "$$ | $\ $$ |$$ __$$\ $$ __$$\ $$$\ $$ |\_$$ _|$$$\ $$ |$$ __$$\\"
print "$$ |$$$\ $$ |$$ / $$ |$$ | $$ |$$$$\ $$ | $$ | $$$$\ $$ |$$ / \__|" print "$$ |$$$\ $$ |$$ / $$ |$$ | $$ |$$$$\ $$ | $$ | $$$$\ $$ |$$ / \__|"
@ -902,14 +903,14 @@ When finished, write an empty line to confirm the purchase.
print "$$$ / \$$$ |$$ | $$ |$$ | $$ |$$ |\$$$ | $$ | $$ |\$$$ |$$ | $$ |" print "$$$ / \$$$ |$$ | $$ |$$ | $$ |$$ |\$$$ | $$ | $$ |\$$$ |$$ | $$ |"
print "$$ / \$$ |$$ | $$ |$$ | $$ |$$ | \$$ |$$$$$$\ $$ | \$$ |\$$$$$$ |" print "$$ / \$$ |$$ | $$ |$$ | $$ |$$ | \$$ |$$$$$$\ $$ | \$$ |\$$$$$$ |"
print "\__/ \__|\__| \__|\__| \__|\__| \__|\______|\__| \__| \______/" print "\__/ \__|\__| \__|\__| \__|\__| \__|\______|\__| \__| \______/"
print print ""
print "***********************************************************************" print "***********************************************************************"
print "***********************************************************************" print "***********************************************************************"
print print ""
print "USER %s HAS LOWER CREDIT THAN %d." % (user.name, conf.low_credit_warning_limit) print "USER %s HAS LOWER CREDIT THAN %d." % (user.name, conf.low_credit_warning_limit)
print "THIS PURCHASE WILL CHARGE YOUR CREDIT TWICE AS MUCH." print "THIS PURCHASE WILL CHARGE YOUR CREDIT TWICE AS MUCH."
print "CONSIDER PUTTING MONEY IN THE BOX TO AVOID THIS." print "CONSIDER PUTTING MONEY IN THE BOX TO AVOID THIS."
print print ""
print "Do you want to continue with this purchase?" print "Do you want to continue with this purchase?"
if timeout: if timeout:
@ -918,7 +919,6 @@ When finished, write an empty line to confirm the purchase.
else: else:
return self.confirm(prompt=">", default=True) return self.confirm(prompt=">", default=True)
def add_thing_to_purchase(self, thing): def add_thing_to_purchase(self, thing):
if isinstance(thing, User): if isinstance(thing, User):
if thing.is_anonymous(): if thing.is_anonymous():
@ -938,18 +938,20 @@ When finished, write an empty line to confirm the purchase.
PurchaseEntry(self.purchase, thing, 1) PurchaseEntry(self.purchase, thing, 1)
return True return True
def _execute(self, initial_contents=None):
def _execute(self, initialContents=[]):
self.print_header() self.print_header()
self.purchase = Purchase() self.purchase = Purchase()
self.exit_confirm_msg = None self.exit_confirm_msg = None
self.superfast_mode = False self.superfast_mode = False
for thing in initialContents: if initial_contents is None:
initial_contents = []
for thing in initial_contents:
self.add_thing_to_purchase(thing) self.add_thing_to_purchase(thing)
isproduct = lambda t: isinstance(t, Product) isproduct = lambda t: isinstance(t, Product)
if len(initialContents) > 0 and all(map(isproduct, initialContents)): if len(initial_contents) > 0 and all(map(isproduct, initial_contents)):
self.superfast_mode = True self.superfast_mode = True
print '***********************************************' print '***********************************************'
print '****** Buy menu is in SUPERFASTmode[tm]! ******' print '****** Buy menu is in SUPERFASTmode[tm]! ******'
@ -972,7 +974,7 @@ When finished, write an empty line to confirm the purchase.
find_hidden_products=False) find_hidden_products=False)
# Possibly exit from the menu: # Possibly exit from the menu:
if thing == None: if thing is None:
if not self.complete_input(): if not self.complete_input():
if self.confirm('Not enough information entered. Abort purchase?', if self.confirm('Not enough information entered. Abort purchase?',
default=True): default=True):
@ -1006,8 +1008,8 @@ When finished, write an empty line to confirm the purchase.
if not t.user.is_anonymous(): if not t.user.is_anonymous():
print 'User %s\'s credit is now %d kr' % (t.user.name, t.user.credit) print 'User %s\'s credit is now %d kr' % (t.user.name, t.user.credit)
if t.user.credit < conf.low_credit_warning_limit: if t.user.credit < conf.low_credit_warning_limit:
print ('USER %s HAS LOWER CREDIT THAN %d, AND SHOULD CONSIDER PUTTING SOME MONEY IN THE BOX.' print 'USER %s HAS LOWER CREDIT THAN %d, AND SHOULD CONSIDER PUTTING SOME MONEY IN THE BOX.'\
% (t.user.name, conf.low_credit_warning_limit)) % (t.user.name, conf.low_credit_warning_limit)
# skriver til log # skriver til log
# print Product.price # print Product.price
# with open("dibbler-out.txt", "a") as f: # with open("dibbler-out.txt", "a") as f:
@ -1029,7 +1031,8 @@ When finished, write an empty line to confirm the purchase.
if len(transactions) == 0: if len(transactions) == 0:
string += '(empty)' string += '(empty)'
else: else:
string += ', '.join(map(lambda t: t.user.name + ("*" if t.user.credit < conf.user_recent_transaction_limit else ""), string += ', '.join(
map(lambda t: t.user.name + ("*" if t.user.credit < conf.user_recent_transaction_limit else ""),
transactions)) transactions))
string += '\n products: ' string += '\n products: '
if len(entries) == 0: if len(entries) == 0:
@ -1045,15 +1048,17 @@ When finished, write an empty line to confirm the purchase.
string += '\n total price: %d kr' % self.purchase.price string += '\n total price: %d kr' % self.purchase.price
if any(t.penalty > 1 for t in transactions): if any(t.penalty > 1 for t in transactions):
string += '\n *total with penalty: %d kr' % sum(self.purchase.price_per_transaction() * t.penalty for t in transactions) string += '\n *total with penalty: %d kr' % sum(
self.purchase.price_per_transaction() * t.penalty for t in transactions)
return string return string
def print_purchase(self): def print_purchase(self):
info = self.format_purchase() info = self.format_purchase()
if info != None: if info is not None:
self.set_context(info) self.set_context(info)
class AdjustStockMenu(Menu): class AdjustStockMenu(Menu):
def __init__(self): def __init__(self):
Menu.__init__(self, 'Adjust stock', uses_db=True) Menu.__init__(self, 'Adjust stock', uses_db=True)
@ -1062,7 +1067,6 @@ class AdjustStockMenu(Menu):
self.print_header() self.print_header()
product = self.input_product('Product> ') product = self.input_product('Product> ')
print 'The stock of this product is: %d ' % (product.stock) print 'The stock of this product is: %d ' % (product.stock)
print 'Write the number of products you have added to the stock' print 'Write the number of products you have added to the stock'
print 'Alternatively, correct the stock for any mistakes' print 'Alternatively, correct the stock for any mistakes'
@ -1109,7 +1113,6 @@ class CleanupStockMenu(Menu):
if oldstock != product.stock: if oldstock != product.stock:
changed_products.append((product, oldstock)) changed_products.append((product, oldstock))
try: try:
self.session.commit() self.session.commit()
print 'New stocks are now stored.' print 'New stocks are now stored.'
@ -1123,7 +1126,6 @@ class CleanupStockMenu(Menu):
print p[0].name, ".", p[1], "->", p[0].stock print p[0].name, ".", p[1], "->", p[0].stock
class AdjustCreditMenu(Menu): # reimplements ChargeMenu; these should be combined to one class AdjustCreditMenu(Menu): # reimplements ChargeMenu; these should be combined to one
def __init__(self): def __init__(self):
Menu.__init__(self, 'Adjust credit', uses_db=True) Menu.__init__(self, 'Adjust credit', uses_db=True)
@ -1205,7 +1207,7 @@ class ProductPopularityMenu(Menu):
self.session.query(Product, sub.c.purchase_count) \ self.session.query(Product, sub.c.purchase_count) \
.outerjoin((sub, Product.product_id == sub.c.product_id)) \ .outerjoin((sub, Product.product_id == sub.c.product_id)) \
.order_by(desc(sub.c.purchase_count)) \ .order_by(desc(sub.c.purchase_count)) \
.filter(sub.c.purchase_count != None) \ .filter(sub.c.purchase_count is not None) \
.all() .all()
line_format = '%10s | %-' + str(Product.name_length) + 's\n' line_format = '%10s | %-' + str(Product.name_length) + 's\n'
text += line_format % ('items sold', 'product') text += line_format % ('items sold', 'product')
@ -1214,6 +1216,7 @@ class ProductPopularityMenu(Menu):
text += line_format % (number, product.name) text += line_format % (number, product.name)
less(text) less(text)
class ProductRevenueMenu(Menu): class ProductRevenueMenu(Menu):
def __init__(self): def __init__(self):
Menu.__init__(self, 'Products by revenue', uses_db=True) Menu.__init__(self, 'Products by revenue', uses_db=True)
@ -1230,7 +1233,7 @@ class ProductRevenueMenu(Menu):
self.session.query(Product, sub.c.purchase_count) \ self.session.query(Product, sub.c.purchase_count) \
.outerjoin((sub, Product.product_id == sub.c.product_id)) \ .outerjoin((sub, Product.product_id == sub.c.product_id)) \
.order_by(desc(sub.c.purchase_count * Product.price)) \ .order_by(desc(sub.c.purchase_count * Product.price)) \
.filter(sub.c.purchase_count != None) \ .filter(sub.c.purchase_count is not None) \
.all() .all()
line_format = '%7s | %10s | %5s | %-' + str(Product.name_length) + 's\n' line_format = '%7s | %10s | %5s | %-' + str(Product.name_length) + 's\n'
text += line_format % ('revenue', 'items sold', 'price', 'product') text += line_format % ('revenue', 'items sold', 'price', 'product')
@ -1239,6 +1242,7 @@ class ProductRevenueMenu(Menu):
text += line_format % (number * product.price, number, product.price, product.name) text += line_format % (number * product.price, number, product.price, product.name)
less(text) less(text)
class BalanceMenu(Menu): class BalanceMenu(Menu):
def __init__(self): def __init__(self):
Menu.__init__(self, 'Total balance of PVVVV', uses_db=True) Menu.__init__(self, 'Total balance of PVVVV', uses_db=True)
@ -1246,7 +1250,7 @@ class BalanceMenu(Menu):
def _execute(self): def _execute(self):
self.print_header() self.print_header()
text = '' text = ''
total_value = 0; total_value = 0
product_list = self.session.query(Product).all() product_list = self.session.query(Product).all()
for p in product_list: for p in product_list:
total_value += p.stock * p.price total_value += p.stock * p.price
@ -1261,12 +1265,16 @@ class BalanceMenu(Menu):
text += 24 * '-' + '\n' text += 24 * '-' + '\n'
text += line_format % ('Total balance', total_balance) text += line_format % ('Total balance', total_balance)
less(text) less(text)
class LoggedStatisticsMenu(Menu): class LoggedStatisticsMenu(Menu):
def __init__(self): def __init__(self):
Menu.__init__(self, 'Statistics from log', uses_db=True) Menu.__init__(self, 'Statistics from log', uses_db=True)
def _execute(self): def _execute(self):
statisticsTextOnly() statisticsTextOnly()
def restart(): def restart():
# Does not work if the script is not executable, or if it was # Does not work if the script is not executable, or if it was
# started by searching $PATH. # started by searching $PATH.
@ -1280,21 +1288,19 @@ if not conf.stop_allowed:
signal.signal(signal.SIGTSTP, signal.SIG_IGN) signal.signal(signal.SIGTSTP, signal.SIG_IGN)
class MainMenu(Menu): class MainMenu(Menu):
def special_input_choice(self, str): def special_input_choice(self, in_str):
buy_menu = BuyMenu(Session()) buy_menu = BuyMenu(Session())
thing = buy_menu.search_for_thing(str) thing = buy_menu.search_for_thing(in_str)
if thing: if thing:
buy_menu.execute(initialContents=[thing]) buy_menu.execute(initialContents=[thing])
print print self.show_context()
self.show_context()
return True return True
return False return False
def invalid_menu_choice(self, str): def invalid_menu_choice(self, in_str):
print print self.show_context()
self.show_context()
class AddStockMenu(Menu): class AddStockMenu(Menu):
def __init__(self): def __init__(self):
@ -1322,14 +1328,16 @@ much money you're due in credits for the purchase when prompted.
thing_price = 0 thing_price = 0
# Read in a 'thing' (product or user): # Read in a 'thing' (product or user):
line = self.input_multiple(add_nonexisting=('user','product'), empty_input_permitted=True, find_hidden_products=False) line = self.input_multiple(add_nonexisting=('user', 'product'), empty_input_permitted=True,
find_hidden_products=False)
if line: if line:
(thing, amount) = line (thing, amount) = line
if isinstance(thing, Product): if isinstance(thing, Product):
self.printc("%d of %s registered" % (amount, thing.name)) self.printc("%d of %s registered" % (amount, thing.name))
thing_price = self.input_int('What did you pay a piece? ', (1,100000), default=thing.price) * amount thing_price = self.input_int('What did you pay a piece? ', (1, 100000),
default=thing.price) * amount
self.price += thing_price self.price += thing_price
# once we get something in the # once we get something in the
@ -1372,7 +1380,6 @@ much money you're due in credits for the purchase when prompted.
print('%' + str(-Product.name_length) + 's %5i') % (product.name, self.products[product][0]) print('%' + str(-Product.name_length) + 's %5i') % (product.name, self.products[product][0])
print(6 + Product.name_length) * '-' print(6 + Product.name_length) * '-'
def add_thing_to_pending(self, thing, amount, price): def add_thing_to_pending(self, thing, amount, price):
if isinstance(thing, User): if isinstance(thing, User):
if self.user: if self.user:
@ -1414,8 +1421,6 @@ much money you're due in credits for the purchase when prompted.
print 'Could not perform transaction: %s' % e print 'Could not perform transaction: %s' % e
main = MainMenu('Dibbler main menu', main = MainMenu('Dibbler main menu',
items=[BuyMenu(), items=[BuyMenu(),
ProductListMenu(), ProductListMenu(),
@ -1447,11 +1452,11 @@ while True:
try: try:
main.execute() main.execute()
except KeyboardInterrupt: except KeyboardInterrupt:
print print ''
print 'Interrupted.' print 'Interrupted.'
except: except:
print 'Something went wrong.' print 'Something went wrong.'
print '%s: %s' % sys.exc_info()[0:2] print '%s: %s' % sys.exc_info()[0], sys.exc_info()[1]
if conf.show_tracebacks: if conf.show_tracebacks:
traceback.print_tb(sys.exc_info()[2]) traceback.print_tb(sys.exc_info()[2])
else: else: