Checkout and Return system complete
This commit is contained in:
parent
84548f5332
commit
e057e0ec21
38
browser.py
38
browser.py
|
@ -4,6 +4,10 @@ import db_layer as db
|
||||||
from form import BookForm,CategoryForm
|
from form import BookForm,CategoryForm
|
||||||
|
|
||||||
class browserWindow:
|
class browserWindow:
|
||||||
|
# These are actually class variables, not member variables? :<
|
||||||
|
_default_height=25
|
||||||
|
_default_width=60
|
||||||
|
|
||||||
hl=0
|
hl=0
|
||||||
topline = 0
|
topline = 0
|
||||||
entries = []
|
entries = []
|
||||||
|
@ -18,13 +22,21 @@ class browserWindow:
|
||||||
last_search = ""
|
last_search = ""
|
||||||
found_index = 0
|
found_index = 0
|
||||||
|
|
||||||
def __init__(self,window,helpbar, height=50, width=80):
|
def __init__(self,window,helpbar, height=0, width=0):
|
||||||
|
if not(height and width):
|
||||||
|
height = browserWindow._default_height
|
||||||
|
width = browserWindow._default_width
|
||||||
|
sys.stderr.write(str(height)+', '+str(width)+'\n')
|
||||||
self.w = window
|
self.w = window
|
||||||
self.hb = helpbar
|
self.hb = helpbar
|
||||||
self.w.resize(height,width)
|
self.w.resize(height,width)
|
||||||
self.updateGeometry()
|
self.updateGeometry()
|
||||||
self.commands = self.cs+self.commands
|
self.commands = self.cs+self.commands
|
||||||
|
|
||||||
|
def load_data(self, data=[]):
|
||||||
|
self.entries = data
|
||||||
|
self.selected = list(map(lambda x:False, self.entries))
|
||||||
|
|
||||||
def sortByColumn(self, col):
|
def sortByColumn(self, col):
|
||||||
self.entries.sort(key=lambda k: k.get(col,"")) # key=dict.get(col))
|
self.entries.sort(key=lambda k: k.get(col,"")) # key=dict.get(col))
|
||||||
self.selected = list(map(lambda x: False, self.selected))
|
self.selected = list(map(lambda x: False, self.selected))
|
||||||
|
@ -256,6 +268,7 @@ class trashBrowser(browserWindow):
|
||||||
|
|
||||||
cs = [(' r', 'restore selected'), (' d', 'delete selected')]
|
cs = [(' r', 'restore selected'), (' d', 'delete selected')]
|
||||||
|
|
||||||
|
|
||||||
# redefinable functions
|
# redefinable functions
|
||||||
def viewSelection(self,book):
|
def viewSelection(self,book):
|
||||||
bookid = book['id']
|
bookid = book['id']
|
||||||
|
@ -282,8 +295,7 @@ class trashBrowser(browserWindow):
|
||||||
db.deleteBooks(books)
|
db.deleteBooks(books)
|
||||||
|
|
||||||
def refreshBooks(self):
|
def refreshBooks(self):
|
||||||
self.entries = db.getRemovedBooks()
|
self.load_data(db.getRemovedBooks())
|
||||||
self.selected = list(map(lambda x:False, self.entries))
|
|
||||||
|
|
||||||
def handleInput(self,ch):
|
def handleInput(self,ch):
|
||||||
browserWindow.handleInput(self,ch)
|
browserWindow.handleInput(self,ch)
|
||||||
|
@ -321,6 +333,7 @@ class bookBrowser(browserWindow):
|
||||||
|
|
||||||
cs = [(' u', 'update'), (' d', 'delete selected')]
|
cs = [(' u', 'update'), (' d', 'delete selected')]
|
||||||
|
|
||||||
|
|
||||||
# redefinable functions
|
# redefinable functions
|
||||||
def updateSelection(self,book):
|
def updateSelection(self,book):
|
||||||
bookid = book['id']
|
bookid = book['id']
|
||||||
|
@ -362,19 +375,17 @@ class bookBrowser(browserWindow):
|
||||||
db.removeBooks(books)
|
db.removeBooks(books)
|
||||||
|
|
||||||
def refreshBooks(self):
|
def refreshBooks(self):
|
||||||
self.entries = db.getBooks()
|
self.load_data(db.get_books())
|
||||||
self.selected = list(map(lambda x:False, self.entries))
|
|
||||||
|
|
||||||
def refreshBooksInCategory(self,cat):
|
def refreshBooksInCategory(self,cat):
|
||||||
self.entries = db.getBooksByCategory(cat)
|
self.load_data(db.getBooksByCategory(cat))
|
||||||
self.selected = list(map(lambda x:False, self.entries))
|
|
||||||
|
|
||||||
def handleInput(self,ch):
|
def handleInput(self,ch):
|
||||||
browserWindow.handleInput(self,ch)
|
browserWindow.handleInput(self,ch)
|
||||||
if ch == 117: #update on 'u'
|
if ch == 117: #update on 'u'
|
||||||
book = self.entries[self.hl]
|
book = self.entries[self.hl]
|
||||||
self.updateSelection(book)
|
self.updateSelection(book)
|
||||||
self.entries[self.hl]=db.getBookByID(book['id'])
|
self.entries[self.hl]=db.get_book(book['id'])
|
||||||
self.refresh()
|
self.refresh()
|
||||||
elif ch == 10:
|
elif ch == 10:
|
||||||
book = self.entries[self.hl]
|
book = self.entries[self.hl]
|
||||||
|
@ -400,23 +411,20 @@ class categoryBrowser(browserWindow):
|
||||||
columnDefs = [('Category',100,None)]
|
columnDefs = [('Category',100,None)]
|
||||||
cs = [(' a', 'add category'), (' d', 'delete selected')]
|
cs = [(' a', 'add category'), (' d', 'delete selected')]
|
||||||
|
|
||||||
|
|
||||||
def refreshCategories(self):
|
def refreshCategories(self):
|
||||||
self.entries = db.getCategories()
|
self.load_data(db.getCategories())
|
||||||
self.sortByColumn('category')
|
self.sortByColumn('category')
|
||||||
self.selected = list(map(lambda x:False, self.entries))
|
|
||||||
|
|
||||||
def addCategory(self):
|
def addCategory(self):
|
||||||
w = curses.newwin(1,1,10,10)
|
w = curses.newwin(1,1,10,10)
|
||||||
cf = CategoryForm(w,self.hb)
|
cf = CategoryForm(w,self.hb)
|
||||||
self.centreChild(w)
|
self.centreChild(w)
|
||||||
cats = cf.event_loop()
|
cat = cf.event_loop()
|
||||||
for c in cats:
|
db.addCategory(cat)
|
||||||
db.addCategory(c)
|
|
||||||
cf.clear()
|
cf.clear()
|
||||||
|
|
||||||
def viewCategory(self):
|
def viewCategory(self):
|
||||||
w = curses.newwin(20,80,20,20)
|
w = curses.newwin(3,5)
|
||||||
b = bookBrowser(w,self.hb)
|
b = bookBrowser(w,self.hb)
|
||||||
self.centreChild(w)
|
self.centreChild(w)
|
||||||
b.refreshBooksInCategory(self.entries[self.hl])
|
b.refreshBooksInCategory(self.entries[self.hl])
|
||||||
|
|
|
@ -0,0 +1,99 @@
|
||||||
|
import sys
|
||||||
|
import curses
|
||||||
|
from form import FormWindow,BookForm
|
||||||
|
import db_layer as db
|
||||||
|
|
||||||
|
|
||||||
|
class BookIDForm(FormWindow):
|
||||||
|
caption = "Enter the book ID"
|
||||||
|
blabel = "Check"
|
||||||
|
labels = ["Book ID"]
|
||||||
|
|
||||||
|
def _return_values(self):
|
||||||
|
if self._confirm_book():
|
||||||
|
return self.entries[0].value
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def _confirm_book(self):
|
||||||
|
self.clear()
|
||||||
|
bookid = self.entries[0].value
|
||||||
|
book = db.get_book(bookid)
|
||||||
|
bf = BookForm(self.w, self.hb, book, width=self.mx-10)
|
||||||
|
(y,x) = self.w.getbegyx()
|
||||||
|
(r,c) = self.w.getmaxyx()
|
||||||
|
self.w.mvwin( y+(self.my-r)//2,x+(self.mx-c)//2)
|
||||||
|
bf.caption='Confirm the Book '+str(bookid)
|
||||||
|
bf.blabel='Correct'
|
||||||
|
result = bf.event_loop()
|
||||||
|
bf.clear()
|
||||||
|
if result:
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
class UWIDForm(FormWindow):
|
||||||
|
caption = "Enter the Patron's username"
|
||||||
|
blabel = "Next"
|
||||||
|
labels = ["Username"]
|
||||||
|
|
||||||
|
def _return_values(self):
|
||||||
|
return self.entries[0].value
|
||||||
|
|
||||||
|
class FinalCheck(FormWindow):
|
||||||
|
caption = "Is this information correct?"
|
||||||
|
blabel = "Check Out"
|
||||||
|
labels = ["Username", "Book ID"]
|
||||||
|
|
||||||
|
def _return_values(self):
|
||||||
|
return True
|
||||||
|
|
||||||
|
def checkout_procedure(w, hb, cy, cx, mx):
|
||||||
|
"""Procedure to check out a book
|
||||||
|
|
||||||
|
w: ncurses window for the routine
|
||||||
|
cy,cx: centre coordinates of the screen
|
||||||
|
mx: max width of screen
|
||||||
|
"""
|
||||||
|
# Get the book ID
|
||||||
|
step1 = BookIDForm(w,hb,width=mx-20)
|
||||||
|
(r,c)=w.getmaxyx()
|
||||||
|
w.mvwin(cy-r//2,cx-c//2)
|
||||||
|
book_id = step1.event_loop()
|
||||||
|
step1.clear()
|
||||||
|
if not(book_id):
|
||||||
|
return
|
||||||
|
|
||||||
|
# Get the uwid
|
||||||
|
step2 = UWIDForm(w,hb,width=mx-20)
|
||||||
|
(r,c)=w.getmaxyx()
|
||||||
|
w.mvwin(cy-r//2,cx-c//2)
|
||||||
|
username = step2.event_loop()
|
||||||
|
step2.clear()
|
||||||
|
if not(username):
|
||||||
|
return
|
||||||
|
|
||||||
|
# Confirm the result
|
||||||
|
step3 = FinalCheck(w,hb,book={"username":username,"book id":book_id}, width=mx-20)
|
||||||
|
(r,c)=w.getmaxyx()
|
||||||
|
w.mvwin(cy-r//2,cx-c//2)
|
||||||
|
correct = step3.event_loop()
|
||||||
|
step3.clear()
|
||||||
|
if correct:
|
||||||
|
db.checkout_book(book_id,username)
|
||||||
|
|
||||||
|
def return_procedure(w, hb, cy, cx, mx):
|
||||||
|
"""Procedure to return a book
|
||||||
|
|
||||||
|
w: ncurses window for the routine
|
||||||
|
cy,cx: centre coordinates of the screen
|
||||||
|
mx: max width of screen
|
||||||
|
"""
|
||||||
|
# Get the book ID
|
||||||
|
step1 = BookIDForm(w,hb,width=mx-20)
|
||||||
|
(r,c)=w.getmaxyx()
|
||||||
|
w.mvwin(cy-r//2,cx-c//2)
|
||||||
|
book_id = step1.event_loop()
|
||||||
|
step1.clear()
|
||||||
|
if book_id:
|
||||||
|
db.return_book(book_id)
|
||||||
|
|
|
@ -111,7 +111,7 @@ def updateBook(book, bookID):
|
||||||
conn.commit()
|
conn.commit()
|
||||||
c.close()
|
c.close()
|
||||||
|
|
||||||
def getBooks():
|
def get_books():
|
||||||
conn = sqlite3.connect(_catalogue_db_file)
|
conn = sqlite3.connect(_catalogue_db_file)
|
||||||
c = conn.cursor()
|
c = conn.cursor()
|
||||||
query = "SELECT * FROM "+_book_table+" WHERE deleted=0;"
|
query = "SELECT * FROM "+_book_table+" WHERE deleted=0;"
|
||||||
|
@ -144,7 +144,7 @@ def getRemovedBooks():
|
||||||
c.close()
|
c.close()
|
||||||
return books
|
return books
|
||||||
|
|
||||||
def getBookByID(bookid):
|
def get_book(bookid):
|
||||||
conn = sqlite3.connect(_catalogue_db_file)
|
conn = sqlite3.connect(_catalogue_db_file)
|
||||||
c = conn.cursor()
|
c = conn.cursor()
|
||||||
query = "SELECT * FROM "+_book_table+" WHERE id = "+str(bookid)+";"
|
query = "SELECT * FROM "+_book_table+" WHERE id = "+str(bookid)+";"
|
||||||
|
@ -346,7 +346,7 @@ def get_onshelf_books():
|
||||||
" LEFT JOIN co."+_checkout_table+
|
" LEFT JOIN co."+_checkout_table+
|
||||||
" USING (id) WHERE uwid ISNULL;")
|
" USING (id) WHERE uwid ISNULL;")
|
||||||
c.execute(query)
|
c.execute(query)
|
||||||
books = [_query_to_book_checkout(b) for b in c]
|
books = [_query_to_book(b) for b in c]
|
||||||
c.close()
|
c.close()
|
||||||
return books
|
return books
|
||||||
|
|
||||||
|
|
2
form.py
2
form.py
|
@ -322,4 +322,4 @@ class CategoryForm(FormWindow):
|
||||||
labels = ["Category"]
|
labels = ["Category"]
|
||||||
|
|
||||||
def _return_values(self):
|
def _return_values(self):
|
||||||
return self.entries
|
return self.entries[0].value
|
||||||
|
|
63
librarian.py
63
librarian.py
|
@ -8,6 +8,8 @@ import help_bar as helpBar
|
||||||
|
|
||||||
import book_data
|
import book_data
|
||||||
|
|
||||||
|
import checkout as co
|
||||||
|
|
||||||
|
|
||||||
stdscr=0
|
stdscr=0
|
||||||
hb=0
|
hb=0
|
||||||
|
@ -20,11 +22,14 @@ def menutest(s, l):
|
||||||
stdscr=s
|
stdscr=s
|
||||||
curses.curs_set(0)
|
curses.curs_set(0)
|
||||||
(rows,cols)=stdscr.getmaxyx()
|
(rows,cols)=stdscr.getmaxyx()
|
||||||
|
# set the default for the browser windows
|
||||||
|
browser.browserWindow._default_height = rows-10
|
||||||
|
browser.browserWindow._default_width = cols-10
|
||||||
bar = curses.newwin(1,cols-2,rows-1,1)
|
bar = curses.newwin(1,cols-2,rows-1,1)
|
||||||
hb = helpBar.helpBar(bar)
|
hb = helpBar.helpBar(bar)
|
||||||
hb.command=menu_commands
|
hb.command=menu_commands
|
||||||
hb.refresh()
|
hb.refresh()
|
||||||
w = curses.newwin(10,40,(rows-10)//2, (cols-40)//2)
|
w = curses.newwin(15,40,(rows-10)//2, (cols-40)//2)
|
||||||
|
|
||||||
menu(w, l)
|
menu(w, l)
|
||||||
|
|
||||||
|
@ -94,31 +99,61 @@ def addForm():
|
||||||
if len(book)!=0:
|
if len(book)!=0:
|
||||||
db.addBook(book)
|
db.addBook(book)
|
||||||
|
|
||||||
def updateMenu():
|
def browseMenu():
|
||||||
w=curses.newwin(1,50,10,10)
|
w=curses.newwin(3,5)
|
||||||
w.addstr("I will be used to update or modify book records")
|
b = browser.bookBrowser(w,hb)
|
||||||
w.refresh()
|
(r,c) = w.getmaxyx()
|
||||||
|
(my,mx)=stdscr.getmaxyx()
|
||||||
|
w.mvwin((my-r)//2 -2, (mx-c)//2)
|
||||||
|
b.refreshBooks()
|
||||||
|
b.eventLoop()
|
||||||
|
b.clear()
|
||||||
|
|
||||||
def trashMenu():
|
def trashMenu():
|
||||||
(my,mx)=stdscr.getmaxyx()
|
|
||||||
w=curses.newwin(3,5)
|
w=curses.newwin(3,5)
|
||||||
b = browser.trashBrowser(w,hb,my-10,mx-10)
|
b = browser.trashBrowser(w,hb)
|
||||||
(r,c) = w.getmaxyx()
|
(r,c) = w.getmaxyx()
|
||||||
|
(my,mx)=stdscr.getmaxyx()
|
||||||
w.mvwin((my-r)//2 -2, (mx-c)//2)
|
w.mvwin((my-r)//2 -2, (mx-c)//2)
|
||||||
b.refreshBooks()
|
b.refreshBooks()
|
||||||
b.eventLoop()
|
b.eventLoop()
|
||||||
b.clear()
|
b.clear()
|
||||||
|
|
||||||
def browseMenu():
|
def checkedout_menu():
|
||||||
(my,mx)=stdscr.getmaxyx()
|
|
||||||
w=curses.newwin(3,5)
|
w=curses.newwin(3,5)
|
||||||
b = browser.bookBrowser(w,hb, my-10, mx-10)
|
b = browser.bookBrowser(w,hb)
|
||||||
(r,c) = w.getmaxyx()
|
(r,c) = w.getmaxyx()
|
||||||
|
(my,mx)=stdscr.getmaxyx()
|
||||||
w.mvwin((my-r)//2 -2, (mx-c)//2)
|
w.mvwin((my-r)//2 -2, (mx-c)//2)
|
||||||
b.refreshBooks()
|
b.load_data(db.get_checkedout_books())
|
||||||
|
b.columnDefs = [("id",0,3),
|
||||||
|
("uwid",0,8),
|
||||||
|
("date",0,10),
|
||||||
|
("title",100,None)]
|
||||||
|
b.calcColWidths()
|
||||||
b.eventLoop()
|
b.eventLoop()
|
||||||
b.clear()
|
b.clear()
|
||||||
|
|
||||||
|
def onshelf_menu():
|
||||||
|
w=curses.newwin(3,5)
|
||||||
|
b = browser.bookBrowser(w,hb)
|
||||||
|
(r,c) = w.getmaxyx()
|
||||||
|
(my,mx)=stdscr.getmaxyx()
|
||||||
|
w.mvwin((my-r)//2 -2, (mx-c)//2)
|
||||||
|
b.load_data(db.get_onshelf_books())
|
||||||
|
b.eventLoop()
|
||||||
|
b.clear()
|
||||||
|
|
||||||
|
def co_menu():
|
||||||
|
w=curses.newwin(1,1)
|
||||||
|
(my,mx)=stdscr.getmaxyx()
|
||||||
|
co.checkout_procedure(w,hb,my//2,mx//2,mx)
|
||||||
|
|
||||||
|
def return_menu():
|
||||||
|
w=curses.newwin(1,1)
|
||||||
|
(my,mx)=stdscr.getmaxyx()
|
||||||
|
co.return_procedure(w,hb,my//2,mx//2,mx)
|
||||||
|
|
||||||
def catMenu():
|
def catMenu():
|
||||||
(my,mx)=stdscr.getmaxyx()
|
(my,mx)=stdscr.getmaxyx()
|
||||||
w=curses.newwin(3,5)
|
w=curses.newwin(3,5)
|
||||||
|
@ -138,6 +173,12 @@ if __name__ == "__main__":
|
||||||
("Categories", catMenu),
|
("Categories", catMenu),
|
||||||
("View Trash", trashMenu),
|
("View Trash", trashMenu),
|
||||||
("",exit),
|
("",exit),
|
||||||
|
("Check Out a Book", co_menu),
|
||||||
|
("Return a Book", return_menu),
|
||||||
|
("",exit),
|
||||||
|
("View Checked Out Books", checkedout_menu),
|
||||||
|
("View On Shelf Books", onshelf_menu),
|
||||||
|
("",exit),
|
||||||
("Exit", exit)]
|
("Exit", exit)]
|
||||||
curses.wrapper(menutest, m)
|
curses.wrapper(menutest, m)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue