Convert most strings to fstrings for readability
Some are kept as-is because they wouldn't be more readable, or do insanity that i cannot bother deciphering right now
This commit is contained in:
parent
068015a972
commit
d5475b834f
9
db.py
9
db.py
|
@ -32,7 +32,7 @@ class User(Base):
|
|||
self.credit = credit
|
||||
|
||||
def __repr__(self):
|
||||
return "<User('%s')>" % self.name
|
||||
return f"<User('{self.name}')>"
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
@ -63,8 +63,7 @@ class Product(Base):
|
|||
self.hidden = hidden
|
||||
|
||||
def __repr__(self):
|
||||
return "<Product('%s', '%s', '%s', '%s', '%s')>" %\
|
||||
(self.name, self.bar_code, self.price, self.stock, self.hidden)
|
||||
return f"<Product('{self.name}', '{self.bar_code}', '{self.price}', '{self.stock}', '{self.hidden}')>"
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
@ -97,7 +96,7 @@ class PurchaseEntry(Base):
|
|||
self.amount = amount
|
||||
|
||||
def __repr__(self):
|
||||
return "<PurchaseEntry('%s', '%s')>" % (self.product.name, self.amount)
|
||||
return f"<PurchaseEntry('{self.product.name}', '{self.amount}')>"
|
||||
|
||||
|
||||
class Transaction(Base):
|
||||
|
@ -141,7 +140,7 @@ class Purchase(Base):
|
|||
pass
|
||||
|
||||
def __repr__(self):
|
||||
return "<Purchase(%d, %d, '%s')>" % (int(self.id), self.price, self.time.strftime('%c'))
|
||||
return f"<Purchase({int(self.id):d}, {self.price:d}, '{self.time.strftime('%c')}')>"
|
||||
|
||||
def is_complete(self):
|
||||
return len(self.transactions) > 0 and len(self.entries) > 0
|
||||
|
|
28
helpers.py
28
helpers.py
|
@ -5,30 +5,30 @@ import subprocess
|
|||
import os
|
||||
import signal
|
||||
|
||||
def search_user(string, session, ignorethisflag=None):
|
||||
string = string.lower()
|
||||
exact_match = session.query(User).filter(or_(User.name==string, User.card==string, User.rfid==string)).first()
|
||||
def search_user(str, session, ignorethisflag=None):
|
||||
str = str.lower()
|
||||
exact_match = session.query(User).filter(or_(User.name == str, User.card == str, User.rfid == str)).first()
|
||||
if exact_match:
|
||||
return exact_match
|
||||
user_list = session.query(User).filter(or_(User.name.ilike('%'+string+'%'),
|
||||
User.card.ilike('%'+string+'%'),
|
||||
User.rfid.ilike('%'+string+'%'))).all()
|
||||
user_list = session.query(User).filter(or_(User.name.ilike(f'%{str}%'),
|
||||
User.card.ilike(f'%{str}%'),
|
||||
User.rfid.ilike(f'%{str}%'))).all()
|
||||
return user_list
|
||||
|
||||
def search_product(string, session, find_hidden_products=True):
|
||||
def search_product(str, session, find_hidden_products=True):
|
||||
if find_hidden_products:
|
||||
exact_match = session.query(Product).filter(or_(Product.bar_code==string, Product.name==string)).first()
|
||||
exact_match = session.query(Product).filter(or_(Product.bar_code == str, Product.name == str)).first()
|
||||
else:
|
||||
exact_match = session.query(Product).filter(or_(Product.bar_code==string,
|
||||
and_(Product.name==string, Product.hidden == False))).first()
|
||||
exact_match = session.query(Product).filter(or_(Product.bar_code == str,
|
||||
and_(Product.name == str, Product.hidden == False))).first()
|
||||
if exact_match:
|
||||
return exact_match
|
||||
if find_hidden_products:
|
||||
product_list = session.query(Product).filter(or_(Product.bar_code.ilike('%'+string+'%'),
|
||||
Product.name.ilike('%'+string+'%'))).all()
|
||||
product_list = session.query(Product).filter(or_(Product.bar_code.ilike(f'%{str}%'),
|
||||
Product.name.ilike(f'%{str}%'))).all()
|
||||
else:
|
||||
product_list = session.query(Product).filter(or_(Product.bar_code.ilike('%' + string + '%'),
|
||||
and_(Product.name.ilike('%' + string + '%'),
|
||||
product_list = session.query(Product).filter(or_(Product.bar_code.ilike(f'%{str}%'),
|
||||
and_(Product.name.ilike(f'%{str}%'),
|
||||
Product.hidden == False))).all()
|
||||
return product_list
|
||||
|
||||
|
|
|
@ -6,4 +6,4 @@ session=Session()
|
|||
slabbedasker=session.query(User).filter(User.credit<0).all()
|
||||
|
||||
for slubbert in slabbedasker:
|
||||
print("%s, %s" % (slubbert.name, slubbert.credit))
|
||||
print(f"{slubbert.name}, {slubbert.credit}")
|
||||
|
|
|
@ -64,7 +64,7 @@ if __name__ == '__main__':
|
|||
print('Interrupted.')
|
||||
except:
|
||||
print('Something went wrong.')
|
||||
print('%s: %s' % (sys.exc_info()[0], sys.exc_info()[1]))
|
||||
print(f'{sys.exc_info()[0]}: {sys.exc_info()[1]}')
|
||||
if conf.show_tracebacks:
|
||||
traceback.print_tb(sys.exc_info()[2])
|
||||
else:
|
||||
|
|
|
@ -41,7 +41,7 @@ much money you're due in credits for the purchase when prompted.\n'''
|
|||
(thing, amount) = line
|
||||
|
||||
if isinstance(thing, Product):
|
||||
self.printc("%d of %s registered" % (amount, thing.name))
|
||||
self.printc(f"{amount:d} of {thing.name} registered")
|
||||
thing_price = self.input_int('What did you pay a piece? ', (1, 100000),
|
||||
default=thing.price) * amount
|
||||
self.price += thing_price
|
||||
|
@ -65,6 +65,7 @@ much money you're due in credits for the purchase when prompted.\n'''
|
|||
def complete_input(self):
|
||||
return bool(self.users) and len(self.products) and self.price
|
||||
|
||||
# TODO: Rewrite this madness
|
||||
def print_info(self):
|
||||
print((6 + Product.name_length) * '-')
|
||||
if self.price:
|
||||
|
@ -72,7 +73,7 @@ much money you're due in credits for the purchase when prompted.\n'''
|
|||
if self.users:
|
||||
print("Users to credit:")
|
||||
for user in self.users:
|
||||
print(" %s" % str(user.name))
|
||||
print(f" {str(user.name)}")
|
||||
print("\n{{0:s}}{{1:>{0}s}}".format(Product.name_length-1).format("Product", "Amount"))
|
||||
print((6 + Product.name_length) * '-')
|
||||
if len(self.products):
|
||||
|
@ -94,6 +95,7 @@ much money you're due in credits for the purchase when prompted.\n'''
|
|||
print('Did you pay a different price?')
|
||||
if self.confirm('>', default=False):
|
||||
price = self.input_int('How much did you pay?', default=self.price)
|
||||
# TODO: Loop until we get a valid answer instead of assuming default
|
||||
if price > self.price:
|
||||
print('Illegal action, total can not be higher than your total.')
|
||||
else:
|
||||
|
@ -109,9 +111,9 @@ much money you're due in credits for the purchase when prompted.\n'''
|
|||
product.price = int(ceil(float(value) / (max(product.stock, 0) + self.products[product][0])))
|
||||
product.stock = max(self.products[product][0], product.stock + self.products[product][0])
|
||||
product.hidden = False
|
||||
print("New stock for %s: %d" % (product.name, product.stock), \
|
||||
("- New price: " + str(product.price) if old_price != product.price else ""), \
|
||||
("- Removed hidden status" if old_hidden != product.hidden else ""))
|
||||
print(f"New stock for {product.name}: {product.stock:d}",
|
||||
f"- New price: {product.price}" if old_price != product.price else "",
|
||||
"- Removed hidden status" if old_hidden != product.hidden else "")
|
||||
|
||||
purchase = Purchase()
|
||||
for user in self.users:
|
||||
|
@ -127,6 +129,6 @@ much money you're due in credits for the purchase when prompted.\n'''
|
|||
print("Success! Transaction performed:")
|
||||
# self.print_info()
|
||||
for user in self.users:
|
||||
print("User %s's credit is now %i" % (user.name, user.credit))
|
||||
print(f"User {user.name}'s credit is now {user.credit:d}")
|
||||
except sqlalchemy.exc.SQLAlchemyError as e:
|
||||
print('Could not perform transaction: %s' % e)
|
||||
print(f'Could not perform transaction: {e}')
|
||||
|
|
|
@ -49,7 +49,7 @@ When finished, write an empty line to confirm the purchase.\n'''
|
|||
print("***********************************************************************")
|
||||
print("***********************************************************************")
|
||||
print("")
|
||||
print("USER %s HAS LOWER CREDIT THAN %d." % (user.name, conf.low_credit_warning_limit))
|
||||
print(f"USER {user.name} HAS LOWER CREDIT THAN {conf.low_credit_warning_limit:d}.")
|
||||
print("THIS PURCHASE WILL CHARGE YOUR CREDIT TWICE AS MUCH.")
|
||||
print("CONSIDER PUTTING MONEY IN THE BOX TO AVOID THIS.")
|
||||
print("")
|
||||
|
@ -149,16 +149,16 @@ When finished, write an empty line to confirm the purchase.\n'''
|
|||
try:
|
||||
self.session.commit()
|
||||
except sqlalchemy.exc.SQLAlchemyError as e:
|
||||
print('Could not store purchase: %s' % e)
|
||||
print(f'Could not store purchase: {e}')
|
||||
else:
|
||||
print('Purchase stored.')
|
||||
self.print_purchase()
|
||||
for t in self.purchase.transactions:
|
||||
if not t.user.is_anonymous():
|
||||
print('User %s\'s credit is now %d kr' % (t.user.name, t.user.credit))
|
||||
print(f"User {t.user.name}'s credit is now {t.user.credit:d} kr")
|
||||
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.' \
|
||||
% (t.user.name, conf.low_credit_warning_limit))
|
||||
print(f'USER {t.user.name} HAS LOWER CREDIT THAN {conf.low_credit_warning_limit:d},',
|
||||
'AND SHOULD CONSIDER PUTTING SOME MONEY IN THE BOX.')
|
||||
|
||||
return True
|
||||
|
||||
|
@ -183,15 +183,17 @@ When finished, write an empty line to confirm the purchase.\n'''
|
|||
string += '(empty)'
|
||||
else:
|
||||
string += "\n "
|
||||
string += '\n '.join(['%dx %s (%d kr)' % (e.amount, e.product.name, e.product.price) for e in entries])
|
||||
string += '\n '.join([f'{e.amount:d}x {e.product.name} ({e.product.price:d} kr)' for e in entries])
|
||||
if len(transactions) > 1:
|
||||
string += '\n price per person: %d kr' % self.purchase.price_per_transaction()
|
||||
string += f'\n price per person: {self.purchase.price_per_transaction():d} kr'
|
||||
if any(t.penalty > 1 for t in transactions):
|
||||
string += ' *(%d kr)' % (self.purchase.price_per_transaction() * 2)
|
||||
# TODO: Use penalty multiplier instead of 2
|
||||
string += f' *({self.purchase.price_per_transaction() * 2:d} kr)'
|
||||
|
||||
string += '\n total price: %d kr' % self.purchase.price
|
||||
string += f'\n total price: {self.purchase.price:d} kr'
|
||||
|
||||
if any(t.penalty > 1 for t in transactions):
|
||||
# TODO: Rewrite?
|
||||
string += '\n *total with penalty: %d kr' % sum(
|
||||
self.purchase.price_per_transaction() * t.penalty for t in transactions)
|
||||
|
||||
|
|
|
@ -19,9 +19,9 @@ class AddUserMenu(Menu):
|
|||
self.session.add(user)
|
||||
try:
|
||||
self.session.commit()
|
||||
print('User %s stored' % username)
|
||||
print(f'User {username} stored')
|
||||
except sqlalchemy.exc.IntegrityError as e:
|
||||
print('Could not store user %s: %s' % (username, e))
|
||||
print(f'Could not store user {username}: {e}')
|
||||
self.pause()
|
||||
|
||||
|
||||
|
@ -38,27 +38,29 @@ user, then rfid (write an empty line to remove the card number or rfid).
|
|||
def _execute(self):
|
||||
self.print_header()
|
||||
user = self.input_user('User> ')
|
||||
self.printc('Editing user %s' % user.name)
|
||||
card_str = '"%s"' % user.card
|
||||
self.printc(f'Editing user {user.name}')
|
||||
card_str = f'"{user.card}"'
|
||||
if user.card is None:
|
||||
card_str = 'empty'
|
||||
# TODO: Inconsistent with other defaulted strings. Redo.
|
||||
user.card = self.input_str('Card number (currently %s)> ' % card_str,
|
||||
User.card_re, (0, 10),
|
||||
empty_string_is_none=True)
|
||||
if user.card:
|
||||
user.card = user.card.lower()
|
||||
|
||||
rfid_str = '"%s"' % user.rfid
|
||||
rfid_str = f'"{user.rfid}"'
|
||||
if user.rfid is None:
|
||||
rfid_str = 'empty'
|
||||
user.rfid = self.input_str('RFID (currently %s)> ' % rfid_str,
|
||||
# TODO: Inconsistent with other defaulted strings. Redo.
|
||||
user.rfid = self.input_str(f'RFID (currently {rfid_str})> ',
|
||||
User.rfid_re, (0, 10),
|
||||
empty_string_is_none=True)
|
||||
try:
|
||||
self.session.commit()
|
||||
print('User %s stored' % user.name)
|
||||
print(f'User {user.name} stored')
|
||||
except sqlalchemy.exc.SQLAlchemyError as e:
|
||||
print('Could not store user %s: %s' % (user.name, e))
|
||||
print(f'Could not store user {user.name}: {e}')
|
||||
self.pause()
|
||||
|
||||
|
||||
|
@ -75,9 +77,9 @@ class AddProductMenu(Menu):
|
|||
self.session.add(product)
|
||||
try:
|
||||
self.session.commit()
|
||||
print('Product %s stored' % name)
|
||||
print(f'Product {name} stored')
|
||||
except sqlalchemy.exc.SQLAlchemyError as e:
|
||||
print('Could not store product %s: %s' % (name, e))
|
||||
print(f'Could not store product {name}: {e}')
|
||||
self.pause()
|
||||
|
||||
|
||||
|
@ -88,9 +90,9 @@ class EditProductMenu(Menu):
|
|||
def _execute(self):
|
||||
self.print_header()
|
||||
product = self.input_product('Product> ')
|
||||
self.printc('Editing product %s' % product.name)
|
||||
self.printc(f'Editing product {product.name}')
|
||||
while True:
|
||||
selector = Selector('Do what with %s?' % product.name,
|
||||
selector = Selector(f'Do what with {product.name}?',
|
||||
items=[('name', 'Edit name'),
|
||||
('price', 'Edit price'),
|
||||
('barcode', 'Edit barcode'),
|
||||
|
@ -98,19 +100,19 @@ class EditProductMenu(Menu):
|
|||
('store', 'Store')])
|
||||
what = selector.execute()
|
||||
if what == 'name':
|
||||
product.name = self.input_str('Name[%s]> ' % product.name, Product.name_re, (1, product.name_length))
|
||||
product.name = self.input_str(f'Name[{product.name}]> ', Product.name_re, (1, product.name_length))
|
||||
elif what == 'price':
|
||||
product.price = self.input_int('Price[%s]> ' % product.price, (1, 100000))
|
||||
product.price = self.input_int(f'Price[{product.price}]> ', (1, 100000))
|
||||
elif what == 'barcode':
|
||||
product.bar_code = self.input_str('Bar code[%s]> ' % product.bar_code, Product.bar_code_re, (8, 13))
|
||||
product.bar_code = self.input_str(f'Bar code[{product.bar_code}]> ', Product.bar_code_re, (8, 13))
|
||||
elif what == 'hidden':
|
||||
product.hidden = self.confirm('Hidden[%s]' % ("Y" if product.hidden else "N"), False)
|
||||
elif what == 'store':
|
||||
try:
|
||||
self.session.commit()
|
||||
print('Product %s stored' % product.name)
|
||||
print(f'Product {product.name} stored')
|
||||
except sqlalchemy.exc.SQLAlchemyError as e:
|
||||
print('Could not store product %s: %s' % (product.name, e))
|
||||
print(f'Could not store product {product.name}: {e}')
|
||||
self.pause()
|
||||
return
|
||||
elif what is None:
|
||||
|
@ -128,25 +130,26 @@ class AdjustStockMenu(Menu):
|
|||
self.print_header()
|
||||
product = self.input_product('Product> ')
|
||||
|
||||
print('The stock of this product is: %d ' % product.stock)
|
||||
print(f'The stock of this product is: {product.stock:d} ')
|
||||
print('Write the number of products you have added to the stock')
|
||||
print('Alternatively, correct the stock for any mistakes')
|
||||
add_stock = self.input_int('Added stock> ', (-1000, 1000))
|
||||
print('You added %d to the stock of %s' % (add_stock, product))
|
||||
# TODO: Print something else when adding negative stock?
|
||||
print(f'You added {add_stock:d} to the stock of {product}')
|
||||
|
||||
product.stock += add_stock
|
||||
|
||||
print('The stock is now %d' % product.stock)
|
||||
print(f'The stock is now {product.stock:d}')
|
||||
|
||||
try:
|
||||
self.session.commit()
|
||||
print('Stock is now stored')
|
||||
self.pause()
|
||||
except sqlalchemy.exc.SQLAlchemyError as e:
|
||||
print('Could not store stock: %s' % e)
|
||||
print(f'Could not store stock: {e}')
|
||||
self.pause()
|
||||
return
|
||||
print('The stock is now %d' % product.stock)
|
||||
print(f'The stock is now {product.stock:d}')
|
||||
|
||||
|
||||
class CleanupStockMenu(Menu):
|
||||
|
@ -179,7 +182,7 @@ class CleanupStockMenu(Menu):
|
|||
print('New stocks are now stored.')
|
||||
self.pause()
|
||||
except sqlalchemy.exc.SQLAlchemyError as e:
|
||||
print('Could not store stock: %s' % e)
|
||||
print(f'Could not store stock: {e}')
|
||||
self.pause()
|
||||
return
|
||||
|
||||
|
|
|
@ -87,6 +87,7 @@ class Menu(object):
|
|||
return i
|
||||
return self.items[i]
|
||||
|
||||
# TODO: Allow default
|
||||
def input_str(self, prompt=None, regex=None, length_range=(None, None),
|
||||
empty_string_is_none=False, timeout=None):
|
||||
if prompt is None:
|
||||
|
@ -98,7 +99,7 @@ class Menu(object):
|
|||
if result is None or re.match(regex + '$', result):
|
||||
return result
|
||||
else:
|
||||
print('Value must match regular expression "%s"' % regex)
|
||||
print(f'Value must match regular expression "{regex}"')
|
||||
if length_range != (None, None):
|
||||
while True:
|
||||
result = self.input_str(prompt, empty_string_is_none=empty_string_is_none)
|
||||
|
@ -109,11 +110,11 @@ class Menu(object):
|
|||
if ((length_range[0] and length < length_range[0]) or
|
||||
(length_range[1] and length > length_range[1])):
|
||||
if length_range[0] and length_range[1]:
|
||||
print('Value must have length in range [%d,%d]' % length_range)
|
||||
print(f'Value must have length in range [{length_range[0]:d}, {length_range[1]:d}]')
|
||||
elif length_range[0]:
|
||||
print('Value must have length at least %d' % length_range[0])
|
||||
print(f'Value must have length at least {length_range[0]:d}')
|
||||
else:
|
||||
print('Value must have length at most %d' % length_range[1])
|
||||
print(f'Value must have length at most {length_range[1]:d}')
|
||||
else:
|
||||
return result
|
||||
while True:
|
||||
|
@ -129,9 +130,9 @@ class Menu(object):
|
|||
# timeout occurred, simulate empty line
|
||||
result = ''
|
||||
else:
|
||||
result = str(input(), conf.input_encoding).strip()
|
||||
result = input().strip()
|
||||
else:
|
||||
result = str(input(safe_str(prompt)), conf.input_encoding).strip()
|
||||
result = input(safe_str(prompt)).strip()
|
||||
except EOFError:
|
||||
print('quit')
|
||||
self.exit_menu()
|
||||
|
@ -210,7 +211,7 @@ class Menu(object):
|
|||
if prompt is None:
|
||||
prompt = self.prompt
|
||||
if default is not None:
|
||||
prompt += ("[%s] " % default)
|
||||
prompt += (f"[{default}] ")
|
||||
while True:
|
||||
result = self.input_str(prompt)
|
||||
if result == '':
|
||||
|
@ -223,11 +224,11 @@ class Menu(object):
|
|||
if ((allowed_range[0] and value < allowed_range[0]) or
|
||||
(allowed_range[1] and value > allowed_range[1])):
|
||||
if allowed_range[0] and allowed_range[1]:
|
||||
print('Value must be in range [%d,%d]' % allowed_range)
|
||||
print(f'Value must be in range [{allowed_range[0]:d}, {allowed_range[1]:d}]')
|
||||
elif allowed_range[0]:
|
||||
print('Value must be at least %d' % allowed_range[0])
|
||||
print(f'Value must be at least {allowed_range[0]:d}')
|
||||
else:
|
||||
print('Value must be at most %d' % allowed_range[1])
|
||||
print(f'Value must be at most {allowed_range[1]:d}')
|
||||
else:
|
||||
return value
|
||||
except ValueError:
|
||||
|
@ -302,7 +303,7 @@ class Menu(object):
|
|||
type_guess = guess_data_type(search_str)
|
||||
if type_guess is not None and thing_for_type[type_guess] in add_non_existing:
|
||||
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 self.search_ui2(search_str, results[selected_thing], selected_thing)
|
||||
|
||||
|
@ -321,16 +322,16 @@ class Menu(object):
|
|||
def search_add(self, string):
|
||||
type_guess = guess_data_type(string)
|
||||
if type_guess == 'username':
|
||||
print('"%s" looks like a username, but no such user exists.' % string)
|
||||
if self.confirm('Create user %s?' % string):
|
||||
print(f'"{string}" looks like a username, but no such user exists.')
|
||||
if self.confirm(f'Create user {string}?'):
|
||||
user = User(string, None)
|
||||
self.session.add(user)
|
||||
return user
|
||||
return None
|
||||
if type_guess == 'card':
|
||||
selector = Selector('"%s" looks like a card number, but no user with that card number exists.' % string,
|
||||
[('create', 'Create user with card number %s' % string),
|
||||
('set', 'Set card number of an existing user to %s' % string)])
|
||||
selector = Selector(f'"{string}" looks like a card number, but no user with that card number exists.',
|
||||
[('create', f'Create user with card number {string}'),
|
||||
('set', f'Set card number of an existing user to {string}')])
|
||||
selection = selector.execute()
|
||||
if selection == 'create':
|
||||
username = self.input_str('Username for new user (should be same as PVV username)> ',
|
||||
|
@ -342,7 +343,7 @@ class Menu(object):
|
|||
user = self.input_user('User to set card number for> ')
|
||||
old_card = user.card
|
||||
user.card = string
|
||||
print('Card number of %s set to %s (was %s)' % (user.name, string, old_card))
|
||||
print(f'Card number of {user.name} set to {string} (was {old_card})')
|
||||
return user
|
||||
return None
|
||||
if type_guess == 'bar_code':
|
||||
|
@ -357,22 +358,19 @@ class Menu(object):
|
|||
if not isinstance(result, list):
|
||||
return result
|
||||
if len(result) == 0:
|
||||
print('No %ss matching "%s"' % (thing, search_str))
|
||||
print(f'No {thing}s matching "{search_str}"')
|
||||
return None
|
||||
if len(result) == 1:
|
||||
msg = 'One %s matching "%s": %s. Use this?' % \
|
||||
(thing, search_str, str(result[0]))
|
||||
msg = f'One {thing} matching "{search_str}": {str(result[0])}. Use this?'
|
||||
if self.confirm(msg, default=True):
|
||||
return result[0]
|
||||
return None
|
||||
limit = 9
|
||||
if len(result) > limit:
|
||||
select_header = '%d %ss matching "%s"; showing first %d' % \
|
||||
(len(result), thing, search_str, limit)
|
||||
select_header = f'{len(result):d} {thing}s matching "{search_str}"; showing first {limit:d}'
|
||||
select_items = result[:limit]
|
||||
else:
|
||||
select_header = '%d %ss matching "%s"' % \
|
||||
(len(result), thing, search_str)
|
||||
select_header = f'{len(result):d} {thing}s matching "{search_str}"'
|
||||
select_items = result
|
||||
selector = Selector(select_header, items=select_items,
|
||||
return_index=False)
|
||||
|
@ -419,7 +417,8 @@ class Menu(object):
|
|||
print('no help here')
|
||||
else:
|
||||
print('')
|
||||
print('Help for %s:' % (self.header_format % self.name))
|
||||
print('Help for %s:' % (self.header_format
|
||||
% self.name))
|
||||
print(self.help_text)
|
||||
|
||||
def execute(self, **kwargs):
|
||||
|
@ -437,6 +436,7 @@ class Menu(object):
|
|||
self.session = None
|
||||
|
||||
def _execute(self, **kwargs):
|
||||
# TODO: This is a very awkward line. Is there a better way of doing this?
|
||||
line_format = '%' + str(len(str(len(self.items)))) + 'd ) %s'
|
||||
while True:
|
||||
self.print_header()
|
||||
|
@ -478,7 +478,7 @@ class ConfirmMenu(Menu):
|
|||
def _execute(self):
|
||||
options = {True: '[y]/n', False: 'y/[n]', None: 'y/n'}[self.default]
|
||||
while True:
|
||||
result = self.input_str('%s (%s) ' % (self.prompt, options), timeout=self.timeout)
|
||||
result = self.input_str(f'{self.prompt} ({options}) ', timeout=self.timeout)
|
||||
result = result.lower().strip()
|
||||
if result in ['y', 'yes']:
|
||||
return True
|
||||
|
@ -507,5 +507,5 @@ class Selector(Menu):
|
|||
print('\'exit\' to go out and do something else.')
|
||||
else:
|
||||
print('')
|
||||
print('Help for selector (%s):' % self.name)
|
||||
print(f'Help for selector ({self.name}):')
|
||||
print(self.help_text)
|
||||
|
|
|
@ -13,30 +13,30 @@ class TransferMenu(Menu):
|
|||
def _execute(self):
|
||||
self.print_header()
|
||||
amount = self.input_int('Transfer amount> ', (1, 100000))
|
||||
self.set_context('Transfering %d kr' % amount, display=False)
|
||||
self.set_context(f'Transferring {amount:d} kr', display=False)
|
||||
user1 = self.input_user('From user> ')
|
||||
self.add_to_context(' from ' + user1.name)
|
||||
self.add_to_context(f' from {user1.name}')
|
||||
user2 = self.input_user('To user> ')
|
||||
self.add_to_context(' to ' + user2.name)
|
||||
self.add_to_context(f' to {user2.name}')
|
||||
comment = self.input_str('Comment> ')
|
||||
self.add_to_context(' (comment) ' + user2.name)
|
||||
self.add_to_context(f' (comment) {user2.name}')
|
||||
|
||||
t1 = Transaction(user1, amount,
|
||||
'transfer to ' + user2.name + ' "' + comment + '"')
|
||||
f'transfer to {user2.name} "{comment}"')
|
||||
t2 = Transaction(user2, -amount,
|
||||
'transfer from ' + user1.name + ' "' + comment + '"')
|
||||
f'transfer from {user1.name} "{comment}"')
|
||||
t1.perform_transaction()
|
||||
t2.perform_transaction()
|
||||
self.session.add(t1)
|
||||
self.session.add(t2)
|
||||
try:
|
||||
self.session.commit()
|
||||
print('Transfered %d kr from %s to %s' % (amount, user1, user2))
|
||||
print('User %s\'s credit is now %d kr' % (user1, user1.credit))
|
||||
print('User %s\'s credit is now %d kr' % (user2, user2.credit))
|
||||
print('Comment: %s' % comment)
|
||||
print(f"Transferred {amount:d} kr from {user1} to {user2}")
|
||||
print(f"User {user1}'s credit is now {user1.credit:d} kr")
|
||||
print(f"User {user2}'s credit is now {user2.credit:d} kr")
|
||||
print(f"Comment: {comment}")
|
||||
except sqlalchemy.exc.SQLAlchemyError as e:
|
||||
print('Could not perform transfer: %s' % e)
|
||||
print(f'Could not perform transfer: {e}')
|
||||
# self.pause()
|
||||
|
||||
|
||||
|
@ -47,14 +47,14 @@ class ShowUserMenu(Menu):
|
|||
def _execute(self):
|
||||
self.print_header()
|
||||
user = self.input_user('User name, card number or RFID> ')
|
||||
print('User name: %s' % user.name)
|
||||
print('Card number: %s' % user.card)
|
||||
print('RFID: %s' % user.rfid)
|
||||
print('Credit: %s kr' % user.credit)
|
||||
selector = Selector('What do you want to know about %s?' % user.name,
|
||||
print(f'User name: {user.name}')
|
||||
print(f'Card number: {user.card}')
|
||||
print(f'RFID: {user.rfid}')
|
||||
print(f'Credit: {user.credit} kr')
|
||||
selector = Selector(f'What do you want to know about {user.name}?',
|
||||
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', f'Which products {user.name} has bought, and how many'),
|
||||
('transactions-all', 'Everything (List of all transactions)')])
|
||||
what = selector.execute()
|
||||
if what == 'transactions':
|
||||
|
@ -66,21 +66,24 @@ class ShowUserMenu(Menu):
|
|||
else:
|
||||
print('What what?')
|
||||
|
||||
# TODO: This is almost identical to the print_transactions function. Reimplement using that one?
|
||||
@staticmethod
|
||||
def print_all_transactions(user):
|
||||
num_trans = len(user.transactions)
|
||||
string = '%s\'s transactions (%d):\n' % (user.name, num_trans)
|
||||
string = f"{user.name}'s transactions ({num_trans:d}):\n"
|
||||
for t in user.transactions[::-1]:
|
||||
string += ' * %s: %s %d kr, ' % \
|
||||
(t.time.strftime('%Y-%m-%d %H:%M'),
|
||||
{True: 'in', False: 'out'}[t.amount < 0],
|
||||
'in' if t.amount < 0 else 'out',
|
||||
abs(t.amount))
|
||||
if t.purchase:
|
||||
# TODO: Print purchased amount, not just product names
|
||||
# TODO: Print something other than "purchase" when user put products into dibbler?
|
||||
string += 'purchase ('
|
||||
string += ', '.join([e.product.name for e in t.purchase.entries])
|
||||
string += ')'
|
||||
if t.penalty > 1:
|
||||
string += ' * %dx penalty applied' % t.penalty
|
||||
string += f' * {t.penalty:d}x penalty applied'
|
||||
else:
|
||||
string += t.description
|
||||
string += '\n'
|
||||
|
@ -90,20 +93,20 @@ class ShowUserMenu(Menu):
|
|||
def print_transactions(user, limit=10):
|
||||
num_trans = len(user.transactions)
|
||||
if num_trans <= limit:
|
||||
string = '%s\'s transactions (%d):\n' % (user.name, num_trans)
|
||||
string = f"{user.name}'s transactions ({num_trans:d}):\n"
|
||||
else:
|
||||
string = '%s\'s transactions (%d, showing only last %d):\n' % (user.name, num_trans, limit)
|
||||
string = f"{user.name}'s transactions ({num_trans:d}, showing only last {limit:d}):\n"
|
||||
for t in user.transactions[-1:-limit - 1:-1]:
|
||||
string += ' * %s: %s %d kr, ' % \
|
||||
(t.time.strftime('%Y-%m-%d %H:%M'),
|
||||
{True: 'in', False: 'out'}[t.amount < 0],
|
||||
'in' if t.amount < 0 else 'out',
|
||||
abs(t.amount))
|
||||
if t.purchase:
|
||||
string += 'purchase ('
|
||||
string += ', '.join([e.product.name for e in t.purchase.entries])
|
||||
string += ')'
|
||||
if t.penalty > 1:
|
||||
string += ' * %dx penalty applied' % t.penalty
|
||||
string += f' * {t.penalty:d}x penalty applied'
|
||||
else:
|
||||
string += t.description
|
||||
string += '\n'
|
||||
|
@ -124,7 +127,7 @@ class ShowUserMenu(Menu):
|
|||
text = ''
|
||||
text += 'Products purchased:\n'
|
||||
for product, count in products:
|
||||
text += '{0:<47} {1:>3}\n'.format(product.name, count)
|
||||
text += f'{product.name:<47} {count:>3}\n'
|
||||
less(text)
|
||||
|
||||
|
||||
|
@ -148,16 +151,17 @@ class UserListMenu(Menu):
|
|||
text += line_format % ('total credit', total_credit)
|
||||
less(text)
|
||||
|
||||
|
||||
class AdjustCreditMenu(Menu): # reimplements ChargeMenu; these should be combined to one
|
||||
# reimplements ChargeMenu
|
||||
# TODO: these should be combined to one
|
||||
class AdjustCreditMenu(Menu):
|
||||
def __init__(self):
|
||||
Menu.__init__(self, 'Adjust credit', uses_db=True)
|
||||
|
||||
def _execute(self):
|
||||
self.print_header()
|
||||
user = self.input_user('User> ')
|
||||
print('User %s\'s credit is %d kr' % (user.name, user.credit))
|
||||
self.set_context('Adjusting credit for user %s' % user.name, display=False)
|
||||
print(f"User {user.name}'s credit is {user.credit:d} kr")
|
||||
self.set_context(f'Adjusting credit for user {user.name}', display=False)
|
||||
print('(Note on sign convention: Enter a positive amount here if you have')
|
||||
print('added money to the PVVVV money box, a negative amount if you have')
|
||||
print('taken money from it)')
|
||||
|
@ -173,9 +177,9 @@ class AdjustCreditMenu(Menu): # reimplements ChargeMenu; these should be combin
|
|||
self.session.add(transaction)
|
||||
try:
|
||||
self.session.commit()
|
||||
print('User %s\'s credit is now %d kr' % (user.name, user.credit))
|
||||
print(f"User {user.name}'s credit is now {user.credit:d} kr")
|
||||
except sqlalchemy.exc.SQLAlchemyError as e:
|
||||
print('Could not store transaction: %s' % e)
|
||||
print(f'Could not store transaction: {e}')
|
||||
# self.pause()
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue