Misc cli changes #1
|
@ -61,26 +61,6 @@ class WorblehatCli(NumberedCmd):
|
|||
exit(0)
|
||||
|
||||
|
||||
def do_list_bookcases(self, _: str):
|
||||
bookcase_shelfs = self.sql_session.scalars(
|
||||
select(BookcaseShelf)
|
||||
.join(Bookcase)
|
||||
.order_by(
|
||||
Bookcase.name,
|
||||
BookcaseShelf.column,
|
||||
BookcaseShelf.row,
|
||||
)
|
||||
).all()
|
||||
|
||||
bookcase_uid = None
|
||||
for shelf in bookcase_shelfs:
|
||||
if shelf.bookcase.uid != bookcase_uid:
|
||||
print(shelf.bookcase.short_str())
|
||||
bookcase_uid = shelf.bookcase.uid
|
||||
|
||||
print(f' {shelf.short_str()} - {sum(i.amount for i in shelf.items)} items')
|
||||
|
||||
|
||||
def do_show_bookcase(self, arg: str):
|
||||
bookcase_selector = InteractiveItemSelector(
|
||||
cls = Bookcase,
|
||||
|
@ -95,6 +75,35 @@ class WorblehatCli(NumberedCmd):
|
|||
print(f' {item.name} - {item.amount} copies')
|
||||
|
||||
|
||||
def do_show_borrowed_queued(self, _: str):
|
||||
borrowed_items = self.sql_session.scalars(
|
||||
select(BookcaseItemBorrowing)
|
||||
.where(BookcaseItemBorrowing.delivered.is_(None))
|
||||
.order_by(BookcaseItemBorrowing.end_time),
|
||||
).all()
|
||||
|
||||
if len(borrowed_items) == 0:
|
||||
print('No borrowed items found.')
|
||||
else:
|
||||
print('Borrowed items:')
|
||||
for item in borrowed_items:
|
||||
print(f'- {item.username} - {item.item.name} - to be delivered by {item.end_time.strftime("%Y-%m-%d")}')
|
||||
|
||||
print()
|
||||
|
||||
queued_items = self.sql_session.scalars(
|
||||
select(BookcaseItemBorrowingQueue)
|
||||
.order_by(BookcaseItemBorrowingQueue.entered_queue_time),
|
||||
).all()
|
||||
|
||||
if len(queued_items) == 0:
|
||||
print('No queued items found.')
|
||||
else:
|
||||
print('Users in queue:')
|
||||
for item in queued_items:
|
||||
print(f'- {item.username} - {item.item.name} - entered queue at {item.entered_queue_time.strftime("%Y-%m-%d")}')
|
||||
|
||||
|
||||
def _create_bookcase_item(self, isbn: str):
|
||||
bookcase_item = create_bookcase_item_from_isbn(isbn, self.sql_session)
|
||||
if bookcase_item is None:
|
||||
|
@ -149,6 +158,8 @@ class WorblehatCli(NumberedCmd):
|
|||
if (existing_item := self.sql_session.scalars(
|
||||
select(BookcaseItem)
|
||||
.where(BookcaseItem.isbn == isbn)
|
||||
.join(BookcaseItemBorrowing)
|
||||
.join(BookcaseItemBorrowingQueue)
|
||||
).one_or_none()) is not None:
|
||||
print(f'\nFound existing item for isbn "{isbn}"')
|
||||
BookcaseItemCli(
|
||||
|
@ -185,11 +196,12 @@ class WorblehatCli(NumberedCmd):
|
|||
).all()
|
||||
|
||||
if len(slubberter) == 0:
|
||||
print('No slubberts found. Yay!')
|
||||
print('No slubberts found. Life is good.')
|
||||
return
|
||||
|
||||
for slubbert in slubberter:
|
||||
print(f'{slubbert.username} - {slubbert.item.name} - {slubbert.end_time.strftime("%Y-%m-%d")}')
|
||||
print('Slubberter:')
|
||||
print(f'- {slubbert.username} - {slubbert.item.name} - {slubbert.end_time.strftime("%Y-%m-%d")}')
|
||||
|
||||
|
||||
def do_advanced(self, _: str):
|
||||
|
@ -225,20 +237,20 @@ class WorblehatCli(NumberedCmd):
|
|||
'doc': 'Choose / Add item with its ISBN',
|
||||
},
|
||||
1: {
|
||||
'f': do_list_bookcases,
|
||||
'doc': 'List all bookcases',
|
||||
},
|
||||
2: {
|
||||
'f': do_search,
|
||||
'doc': 'Search',
|
||||
},
|
||||
3: {
|
||||
2: {
|
||||
'f': do_show_bookcase,
|
||||
'doc': 'Show a bookcase, and its items',
|
||||
},
|
||||
3: {
|
||||
'f': do_show_borrowed_queued,
|
||||
'doc': 'Show borrowed/queued items',
|
||||
},
|
||||
4: {
|
||||
'f': do_show_slabbedasker,
|
||||
'doc': 'Show a slabbedasker, and their wicked ways',
|
||||
'doc': 'Show slabbedasker',
|
||||
},
|
||||
5: {
|
||||
'f': do_save,
|
||||
|
|
|
@ -58,6 +58,7 @@ class InteractiveItemSelector(Cmd):
|
|||
self.execute_selection = execute_selection
|
||||
self.complete_selection = complete_selection
|
||||
self.default_item = default
|
||||
self.result = None
|
||||
|
||||
if default is not None:
|
||||
self.prompt = f'Select {cls.__name__} [{default.name}]> '
|
||||
|
@ -197,6 +198,7 @@ class NumberedItemSelector(NumberedCmd):
|
|||
super().__init__()
|
||||
self.items = items
|
||||
self.stringify = stringify
|
||||
self.result = None
|
||||
self.funcs = {
|
||||
i: {
|
||||
'f': self._select_item,
|
||||
|
|
|
@ -91,6 +91,26 @@ class AdvancedOptionsCli(NumberedCmd):
|
|||
self.sql_session.flush()
|
||||
|
||||
|
||||
def do_list_bookcases(self, _: str):
|
||||
bookcase_shelfs = self.sql_session.scalars(
|
||||
select(BookcaseShelf)
|
||||
.join(Bookcase)
|
||||
.order_by(
|
||||
Bookcase.name,
|
||||
BookcaseShelf.column,
|
||||
BookcaseShelf.row,
|
||||
)
|
||||
).all()
|
||||
|
||||
bookcase_uid = None
|
||||
for shelf in bookcase_shelfs:
|
||||
if shelf.bookcase.uid != bookcase_uid:
|
||||
print(shelf.bookcase.short_str())
|
||||
bookcase_uid = shelf.bookcase.uid
|
||||
|
||||
print(f' {shelf.short_str()} - {sum(i.amount for i in shelf.items)} items')
|
||||
|
||||
|
||||
def do_done(self, _: str):
|
||||
return True
|
||||
|
||||
|
@ -104,6 +124,10 @@ class AdvancedOptionsCli(NumberedCmd):
|
|||
'f': do_add_bookcase_shelf,
|
||||
'doc': 'Add bookcase shelf',
|
||||
},
|
||||
3: {
|
||||
'f': do_list_bookcases,
|
||||
'doc': 'List all bookcases',
|
||||
},
|
||||
9: {
|
||||
'f': do_done,
|
||||
'doc': 'Done',
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from datetime import datetime
|
||||
from datetime import datetime, timedelta
|
||||
from textwrap import dedent
|
||||
from sqlalchemy import select
|
||||
|
||||
|
@ -7,6 +7,7 @@ from sqlalchemy.orm import Session
|
|||
from worblehat.cli.prompt_utils import (
|
||||
InteractiveItemSelector,
|
||||
NumberedCmd,
|
||||
NumberedItemSelector,
|
||||
format_date,
|
||||
prompt_yes_no,
|
||||
)
|
||||
|
@ -22,6 +23,7 @@ from worblehat.services.bookcase_item import (
|
|||
create_bookcase_item_from_isbn,
|
||||
is_valid_isbn,
|
||||
)
|
||||
from worblehat.services.config import Config
|
||||
|
||||
from .bookcase_shelf_selector import select_bookcase_shelf
|
||||
|
||||
|
@ -174,6 +176,50 @@ class BookcaseItemCli(NumberedCmd):
|
|||
print(f'Successfully delivered the item for {borrowing.username}')
|
||||
|
||||
|
||||
def do_extend_borrowing(self, _: str):
|
||||
borrowings = self.sql_session.scalars(
|
||||
select(BookcaseItemBorrowing)
|
||||
.join(BookcaseItem, BookcaseItem.uid == BookcaseItemBorrowing.fk_bookcase_item_uid)
|
||||
.where(BookcaseItem.isbn == self.bookcase_item.isbn)
|
||||
.order_by(BookcaseItemBorrowing.username)
|
||||
).all()
|
||||
|
||||
if len(borrowings) == 0:
|
||||
print('No one seems to have borrowed this item')
|
||||
return
|
||||
|
||||
borrowing_queue = self.sql_session.scalars(
|
||||
select(BookcaseItemBorrowingQueue)
|
||||
.where(
|
||||
BookcaseItemBorrowingQueue.item == self.bookcase_item,
|
||||
BookcaseItemBorrowingQueue.item_became_available_time == None,
|
||||
)
|
||||
.order_by(BookcaseItemBorrowingQueue.entered_queue_time)
|
||||
).all()
|
||||
|
||||
if len(borrowing_queue) != 0:
|
||||
print('Sorry, you cannot extend the borrowing because there are people waiting in the queue')
|
||||
print('Borrowing queue:')
|
||||
for i, b in enumerate(borrowing_queue):
|
||||
print(f' {i + 1}) {b.username}')
|
||||
return
|
||||
|
||||
print('Who are you?')
|
||||
selector = NumberedItemSelector(
|
||||
items = list(borrowings),
|
||||
stringify = lambda b: f'{b.username} - Until {format_date(b.end_time)}',
|
||||
)
|
||||
selector.cmdloop()
|
||||
if selector.result is None:
|
||||
return
|
||||
borrowing = selector.result
|
||||
|
||||
borrowing.end_time = datetime.now() + timedelta(days=int(Config['deadline_daemon.days_before_queue_position_expires']))
|
||||
self.sql_session.flush()
|
||||
|
||||
print(f'Successfully extended the borrowing for {borrowing.username} until {format_date(borrowing.end_time)}')
|
||||
|
||||
|
||||
def do_done(self, _: str):
|
||||
return True
|
||||
|
||||
|
@ -188,10 +234,14 @@ class BookcaseItemCli(NumberedCmd):
|
|||
'doc': 'Deliver',
|
||||
},
|
||||
3: {
|
||||
'f': do_extend_borrowing,
|
||||
'doc': 'Extend borrowing',
|
||||
},
|
||||
4: {
|
||||
'f': do_edit,
|
||||
'doc': 'Edit',
|
||||
},
|
||||
4: {
|
||||
5: {
|
||||
'f': do_update_data,
|
||||
'doc': 'Pull updated data from online databases',
|
||||
},
|
||||
|
|
|
@ -13,6 +13,7 @@ class SearchCli(NumberedCmd):
|
|||
def __init__(self, sql_session: Session):
|
||||
super().__init__()
|
||||
self.sql_session = sql_session
|
||||
self.result = None
|
||||
|
||||
|
||||
def do_search_all(self, _: str):
|
||||
|
@ -57,11 +58,11 @@ class SearchCli(NumberedCmd):
|
|||
elif len(author) == 1:
|
||||
selected_author = author[0]
|
||||
print('Found author:')
|
||||
print(f" {selected_author.name} ({sum(item.amount for item in selected_author.books)} items)")
|
||||
print(f" {selected_author.name} ({sum(item.amount for item in selected_author.items)} items)")
|
||||
else:
|
||||
selector = NumberedItemSelector(
|
||||
items = author,
|
||||
stringify = lambda author: f"{author.name} ({sum(item.amount for item in author.books)} items)",
|
||||
stringify = lambda author: f"{author.name} ({sum(item.amount for item in author.items)} items)",
|
||||
)
|
||||
selector.cmdloop()
|
||||
if selector.result is None:
|
||||
|
@ -69,7 +70,7 @@ class SearchCli(NumberedCmd):
|
|||
selected_author = selector.result
|
||||
|
||||
selector = NumberedItemSelector(
|
||||
items = selected_author.books,
|
||||
items = list(selected_author.items),
|
||||
stringify = lambda item: f"{item.name} ({item.isbn})",
|
||||
)
|
||||
selector.cmdloop()
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import csv
|
||||
from datetime import datetime, timedelta
|
||||
from pathlib import Path
|
||||
|
||||
from sqlalchemy.orm import Session
|
||||
|
@ -6,7 +7,11 @@ from sqlalchemy.orm import Session
|
|||
from worblehat.flaskapp.database import db
|
||||
|
||||
from ..models import (
|
||||
Author,
|
||||
Bookcase,
|
||||
BookcaseItem,
|
||||
BookcaseItemBorrowing,
|
||||
BookcaseItemBorrowingQueue,
|
||||
BookcaseShelf,
|
||||
Language,
|
||||
MediaType,
|
||||
|
@ -117,6 +122,100 @@ def seed_data(sql_session: Session = db.session):
|
|||
BookcaseShelf(row=0, column=4, bookcase=bookcases[4], description="Religion"),
|
||||
]
|
||||
|
||||
authors = [
|
||||
Author(name="Donald E. Knuth"),
|
||||
Author(name="J.K. Rowling"),
|
||||
Author(name="J.R.R. Tolkien"),
|
||||
Author(name="George R.R. Martin"),
|
||||
Author(name="Stephen King"),
|
||||
Author(name="Agatha Christie"),
|
||||
]
|
||||
|
||||
book1 = BookcaseItem(
|
||||
name = "The Art of Computer Programming",
|
||||
isbn = "9780201896831",
|
||||
)
|
||||
book1.authors.add(authors[0])
|
||||
book1.media_type = media_types[0]
|
||||
book1.shelf = shelfs[59]
|
||||
|
||||
book2 = BookcaseItem(
|
||||
name = "Harry Potter and the Philosopher's Stone",
|
||||
isbn = "9780747532743",
|
||||
)
|
||||
book2.authors.add(authors[1])
|
||||
book2.media_type = media_types[0]
|
||||
book2.shelf = shelfs[-1]
|
||||
|
||||
book_owned_by_other_user = BookcaseItem(
|
||||
name = "Book owned by other user",
|
||||
isbn = "9780747532744",
|
||||
)
|
||||
|
||||
book_owned_by_other_user.owner = "other_user"
|
||||
book_owned_by_other_user.authors.add(authors[4])
|
||||
book_owned_by_other_user.media_type = media_types[0]
|
||||
book_owned_by_other_user.shelf = shelfs[-2]
|
||||
|
||||
borrowed_book_more_available = BookcaseItem(
|
||||
name = "Borrowed book with more available",
|
||||
isbn = "9780747532745",
|
||||
)
|
||||
borrowed_book_more_available.authors.add(authors[5])
|
||||
borrowed_book_more_available.media_type = media_types[0]
|
||||
borrowed_book_more_available.shelf = shelfs[-3]
|
||||
borrowed_book_more_available.amount = 2
|
||||
|
||||
borrowed_book_no_more_available = BookcaseItem(
|
||||
name = "Borrowed book with no more available",
|
||||
isbn = "9780747532746",
|
||||
)
|
||||
borrowed_book_no_more_available.authors.add(authors[5])
|
||||
borrowed_book_no_more_available.media_type = media_types[0]
|
||||
borrowed_book_no_more_available.shelf = shelfs[-3]
|
||||
|
||||
borrowed_book_people_in_queue = BookcaseItem(
|
||||
name = "Borrowed book with people in queue",
|
||||
isbn = "9780747532747",
|
||||
)
|
||||
borrowed_book_people_in_queue.authors.add(authors[5])
|
||||
borrowed_book_people_in_queue.media_type = media_types[0]
|
||||
borrowed_book_people_in_queue.shelf = shelfs[-3]
|
||||
|
||||
borrowed_book_by_slabbedask = BookcaseItem(
|
||||
name = "Borrowed book by slabbedask",
|
||||
isbn = "9780747532748",
|
||||
)
|
||||
borrowed_book_by_slabbedask.authors.add(authors[5])
|
||||
borrowed_book_by_slabbedask.media_type = media_types[0]
|
||||
borrowed_book_by_slabbedask.shelf = shelfs[-3]
|
||||
|
||||
books = [
|
||||
book1,
|
||||
book2,
|
||||
book_owned_by_other_user,
|
||||
borrowed_book_more_available,
|
||||
borrowed_book_no_more_available,
|
||||
borrowed_book_people_in_queue,
|
||||
]
|
||||
|
||||
slabbedask_borrowing = BookcaseItemBorrowing(
|
||||
username="slabbedask",
|
||||
item=borrowed_book_more_available,
|
||||
)
|
||||
slabbedask_borrowing.end_time = datetime.now() - timedelta(days=1)
|
||||
|
||||
borrowings = [
|
||||
BookcaseItemBorrowing(username="user", item=borrowed_book_more_available),
|
||||
BookcaseItemBorrowing(username="user", item=borrowed_book_no_more_available),
|
||||
BookcaseItemBorrowing(username="user", item=borrowed_book_people_in_queue),
|
||||
slabbedask_borrowing,
|
||||
]
|
||||
|
||||
queue = [
|
||||
BookcaseItemBorrowingQueue(username="user", item=borrowed_book_people_in_queue),
|
||||
]
|
||||
|
||||
with open(Path(__file__).parent.parent.parent / 'data' / 'iso639_1.csv') as f:
|
||||
reader = csv.reader(f)
|
||||
languages = [Language(name, code) for (code, name) in reader]
|
||||
|
@ -125,5 +224,9 @@ def seed_data(sql_session: Session = db.session):
|
|||
sql_session.add_all(bookcases)
|
||||
sql_session.add_all(shelfs)
|
||||
sql_session.add_all(languages)
|
||||
sql_session.add_all(authors)
|
||||
sql_session.add_all(books)
|
||||
sql_session.add_all(borrowings)
|
||||
sql_session.add_all(queue)
|
||||
sql_session.commit()
|
||||
print("Added test media types, bookcases and shelfs.")
|
Loading…
Reference in New Issue