100 lines
3.4 KiB
Python
100 lines
3.4 KiB
Python
""" The backend for the library-tracking system
|
|
|
|
This uses shelve which is pretty simplistic, but which should be sufficient for our (extremely minimal) use of the library.
|
|
|
|
There is a booklist (book=(Author, Title, Year, Signout)) where signout is None for "Checked In" or a (userid, date) to give who and when that book was signed out.
|
|
"""
|
|
|
|
import shelve
|
|
import time
|
|
import re
|
|
|
|
LIBRARY_DB = "./csc_library.db"
|
|
|
|
class Book:
|
|
def __init__(self, author, title, year):
|
|
"""Any of these may be None to indicate 'unknown'."""
|
|
self.author =author
|
|
self.title = title
|
|
self.year = year
|
|
self.signout = None
|
|
def sign_out(self, username):
|
|
if self.signout is None:
|
|
self.signout = Signout(username)
|
|
else:
|
|
raise Exception("Book already signed out to %s" % self.signout.name, b)
|
|
def sign_in(self):
|
|
if self.signout is not None:
|
|
self.signout = None
|
|
else:
|
|
raise Exception("Book was not signed out, no need to sign it in")
|
|
|
|
def __str__(self):
|
|
return "Book(author=%r, title=%r, year=%r, signout=%r)" % (self.author, self.title, self.year, self.signout)
|
|
|
|
class Signout:
|
|
"""Represents a sign-out of a book to someone. Automatically records when the signout occured"""
|
|
def __init__(self, name):
|
|
#in theory we could check that the name given to us is in LDAP
|
|
self.name = str(name)
|
|
self.date = time.time()
|
|
def __repr__(self):
|
|
return "Signout(%r, %s)" % (self.name, time.ctime(self.date))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def reset():
|
|
"""make a fresh database"""
|
|
shelve.open(LIBRARY_DB,'n').close()
|
|
|
|
|
|
def add(author, title, year):
|
|
db = shelve.open(LIBRARY_DB,'w') #use w here (not c) to ensure a crash if the DB file got erased (is this a good idea?)
|
|
i = len(db)
|
|
db[str(i)] = Book(author, title, year)
|
|
db.close()
|
|
|
|
def search(author=None, title=None, year=None):
|
|
"""search for a title
|
|
author and title are regular expressions
|
|
year is a single number or a list of numbers (so use range() to search the DB)
|
|
whichever ones passed in that aren't None are the restrictions used in the search
|
|
possibly-useful side effect of this design is that search() just gets the list of everything
|
|
this is extraordinarily inefficient, but whatever (I don't think that without having an indexer run inthe background we can improve this any?)
|
|
returns: a list of Book objects
|
|
"""
|
|
db = shelve.open(LIBRARY_DB, 'w', writeback=True) #open it for writing so that changes to books get saved
|
|
all = db.values() #this should pull out the ID numbers somehow too.. bah
|
|
if author is not None:
|
|
all = [book for book in all if book.author and re.match(author, book.author)] #should factor this out
|
|
if title is not None:
|
|
all = [book for book in all if book.title and re.match(title, book.title)] #should factor this out
|
|
if year is not None:
|
|
if type(year) == int:
|
|
year = [year]
|
|
#now assume year is a list
|
|
all = [book for book in all if book.year and book.year in year]
|
|
db.close()
|
|
return all
|
|
|
|
|
|
#def delete(....):
|
|
# """must think about how to do this one; it'll have to be tied to the DB ID somehow"""
|
|
# pass
|
|
|
|
if __name__ == '__main__':
|
|
#print "Making database"
|
|
#reset()
|
|
#print
|
|
#print "Filling database"
|
|
#add("Bob McBob", "My Life Of Crime", None)
|
|
print
|
|
print "Listing database"
|
|
for b in search():
|
|
#b.sign_out("nguenthe")
|
|
print b
|