diff --git a/ceo/members.py b/ceo/members.py index fc8dd01..a61bd1a 100644 --- a/ceo/members.py +++ b/ceo/members.py @@ -150,6 +150,12 @@ def create_member(username, password, name, program): addmember = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = addmember.communicate(password) status = addmember.wait() + + # # If the user was created, consider adding them to the mailing list + # if not status: + # listadmin_cfg_file = "/path/to/the/listadmin/config/file" + # mail = subprocess.Popen(["/usr/bin/listadmin", "-f", listadmin_cfg_file, "--add-member", username + "@csclub.uwaterloo.ca"]) + # status2 = mail.wait() # Fuck if I care about errors! except OSError, e: raise MemberException(e) diff --git a/ceo/pymazon.py b/ceo/pymazon.py new file mode 100644 index 0000000..47fe6df --- /dev/null +++ b/ceo/pymazon.py @@ -0,0 +1,134 @@ +#!/usr/bin/python + +from xml.dom import minidom, Node +import urllib +import time + +class PyMazonError(Exception): + """Holds information about an error that occured during a pymazon request""" + def __init__(self, messages): + self.__message = '\n'.join(messages) + + def __get_message(self): + return self.__message + + def __str__(self): + return repr(self.__message) + + message = property(fget=__get_message) + + +class PyMazonBook: + """Stores information about a book retrieved via PyMazon.""" + def __init__(self, title, authors, publisher, year, isbn10, isbn13, edition): + self.__title = title + self.__authors = authors + self.__publisher = publisher + self.__year = year + self.__isbn10 = isbn10 + self.__isbn13 = isbn13 + self.__edition = edition + + def __str__(self): + return 'Title: ' + self.title + '\n' + \ + 'Author(s): ' + ', '.join(self.authors) + '\n' \ + 'Publisher: ' + self.publisher + '\n' + \ + 'Year: ' + self.year + '\n' + \ + 'ISBN-10: ' + self.isbn10 + '\n' + \ + 'ISBN-13: ' + self.isbn13 + '\n' + \ + 'Edition: ' + self.edition + + def __get_title(self): + return self.__title + + def __get_authors(self): + return self.__authors + + def __get_publisher(self): + return self.__publisher + + def __get_year(self): + return self.__year + + def __get_isbn10(self): + return self.__isbn10 + + def __get_isbn13(self): + return self.__isbn13 + + def __get_edition(self): + return self.__edition + + title = property(fget=__get_title) + authors = property(fget=__get_authors) + publisher = property(fget=__get_publisher) + year = property(fget=__get_year) + isbn10 = property(fget=__get_isbn10) + isbn13 = property(fget=__get_isbn13) + edition = property(fget=__get_edition) + + +class PyMazon: + """A method of looking up book information on Amazon.""" + def __init__(self, accesskey): + self.__key = accesskey + self.__last_query_time = 0 + + def __form_request(self, isbn): + return 'http://webservices.amazon.com/onca/xml?' + \ + 'Service=AWSECommerceService' + \ + '&Version=2008-08-19' + \ + '&AWSAccessKeyId=' + self.__key + \ + '&Operation=ItemLookup' + \ + '&ResponseGroup=ItemAttributes' + \ + '&IdType=ISBN' + \ + '&SearchIndex=Books' + \ + '&ItemId=' + isbn + + def __elements_text(self, element, name): + result = [] + matching = element.getElementsByTagName(name) + for match in matching: + if len(match.childNodes) != 1: + continue + child = match.firstChild + if child.nodeType != Node.TEXT_NODE: + continue + result.append(child.nodeValue.strip()) + return result + + def __format_errors(self, errors): + error_list = [] + for error in errors: + error_list.extend(self.__elements_text(error, 'Message')) + return error_list + + def __extract_single(self, element, name): + matches = self.__elements_text(element, name) + if len(matches) == 0: + return '' + return matches[0] + + def lookup(self, isbn): + file = urllib.urlretrieve(self.__form_request(isbn))[0] + xmldoc = minidom.parse(file) + + cur_time = time.time() + while cur_time - self.__last_query_time < 1.0: + sleep(cur_time - self.__last_query_time) + cur_time = time.time() + self.__last_query_time = cur_time + + errors = xmldoc.getElementsByTagName('Errors') + if len(errors) != 0: + raise PyMazonError, self.__format_errors(errors) + + title = self.__extract_single(xmldoc, 'Title') + authors = self.__elements_text(xmldoc, 'Author') + publisher = self.__extract_single(xmldoc, 'Publisher') + year = self.__extract_single(xmldoc, 'PublicationDate')[0:4] + isbn10 = self.__extract_single(xmldoc, 'ISBN') + isbn13 = self.__extract_single(xmldoc, 'EAN') + edition = self.__extract_single(xmldoc, 'Edition') + + return PyMazonBook(title, authors, publisher, year, isbn10, isbn13, edition) diff --git a/ceo/urwid/library.py b/ceo/urwid/library.py index 3cc02e8..4d6118f 100644 --- a/ceo/urwid/library.py +++ b/ceo/urwid/library.py @@ -5,12 +5,26 @@ from ceo.urwid.widgets import * from ceo.urwid.window import * from sqlobject.sqlbuilder import * from datetime import datetime, timedelta +from ceo.pymazon import PyMazon +from ceo.pymazon import PyMazonError +from ceo import conf from ceo import terms import ceo.library as lib +CONFIG_FILE = "/etc/csc/library.cf" +cfg = {} + +def configure(): + """ + Load configuration + """ + cfg_fields = [ "aws_account_key" ] + temp_cfg = conf.read(CONFIG_FILE) + conf.check_string_fields(CONFIG_FILE, cfg_fields, temp_cfg) + cfg.update(temp_cfg) def library(data): """ @@ -20,7 +34,7 @@ def library(data): ("Checkout Book", checkout_book, None), ("Return Book", return_book, None), ("Search Books", search_books, None), -# ("Add Book", add_book, None), + ("Add Book", add_book, None), ("Back", raise_back, None), ]) push_window(menu, "Library") @@ -35,12 +49,18 @@ def search_books(data): ]) push_window(menu, "Book Search") +def add_book(data): + """ + Add book to library. Also stab Sapphyre. + """ + push_wizard("Add Book", [BookAddPage]) + def overdue_books(data): """ Display a list of all books that are overdue. """ oldest = datetime.today() - timedelta(weeks=2) - overdue = lib.Signout.select(lib.Signout.q.outdate Wed, 29 Jul 2009 07:31:24 -0400 +ceo (0.4.23) stable testing; urgency=low + + * CEO library now only finds books that are signed out as being overdue. + + -- Michael Gregson Wed, 11 Mar 2009 03:30:01 -0500 + +ceo (0.4.22) stable testing; urgency=low + + * CEO now closes window when it should. (Sorry) + + -- Michael Gregson Wed, 11 Mar 2009 02:25:01 -0500 + +ceo (0.4.21) stable testing; urgency=low + + * CEO Library can now add boox. + + -- Michael Gregson Wed, 11 Mar 2009 02:09:01 -0500 + +ceo (0.4.20) stable testing; urgency=low + + * Update kadmin headers + + -- David Bartley Tue, 24 Feb 2009 16:08:12 -0500 + +ceo (0.4.19) stable testing; urgency=low + + * Rebuild for lenny. + + -- Michael Spang Tue, 17 Feb 2009 22:23:30 -0500 ceo (0.4.18) stable testing; urgency=low