def get_borrow_status(itemid, include_resources=True, include_ia=True, edition=None): """Returns borrow status for each of the sources and formats. If the optinal argument editions is provided, it uses that edition instead of finding edition from itemid. This is added for performance reasons. """ loan = lending.get_loan(itemid) has_loan = bool(loan) if edition: editions = [edition] else: edition_keys = web.ctx.site.things({ "type": "/type/edition", "ocaid": itemid }) editions = web.ctx.site.get_many(edition_keys) has_waitinglist = editions and any(e.get_waitinglist_size() > 0 for e in editions) d = { 'identifier': itemid, 'checkedout': has_loan or has_waitinglist, 'has_loan': has_loan, 'has_waitinglist': has_waitinglist, } if include_ia: ia_checkedout = lending.is_loaned_out_on_ia(itemid) d['checkedout'] = d['checkedout'] or ia_checkedout d['checkedout_on_ia'] = ia_checkedout if include_resources: d.update({ 'resource_bookreader': 'absent', 'resource_pdf': 'absent', 'resource_epub': 'absent', }) if editions: resources = editions[0].get_lending_resources() resource_pattern = r'acs:(\w+):(.*)' for resource_urn in resources: if resource_urn.startswith('acs:'): (resource_type, resource_id) = re.match(resource_pattern, resource_urn).groups() else: resource_type, resource_id = "bookreader", resource_urn resource_type = "resource_" + resource_type if is_loaned_out(resource_id): d[resource_type] = 'checkedout' else: d[resource_type] = 'available' return web.storage(d)
def get_borrow_status(itemid, include_resources=True, include_ia=True, edition=None): """Returns borrow status for each of the sources and formats. If the optinal argument editions is provided, it uses that edition instead of finding edition from itemid. This is added for performance reasons. """ loan = lending.get_loan(itemid) has_loan = bool(loan) if edition: editions = [edition] else: edition_keys = web.ctx.site.things({"type": "/type/edition", "ocaid": itemid}) editions = web.ctx.site.get_many(edition_keys) has_waitinglist = editions and any(e.get_waitinglist_size() > 0 for e in editions) d = { 'identifier': itemid, 'checkedout': has_loan or has_waitinglist, 'has_loan': has_loan, 'has_waitinglist': has_waitinglist, } if include_ia: ia_checkedout = lending.is_loaned_out_on_ia(itemid) d['checkedout'] = d['checkedout'] or ia_checkedout d['checkedout_on_ia'] = ia_checkedout if include_resources: d.update({ 'resource_bookreader': 'absent', 'resource_pdf': 'absent', 'resource_epub': 'absent', }) if editions: resources = editions[0].get_lending_resources() resource_pattern = r'acs:(\w+):(.*)' for resource_urn in resources: if resource_urn.startswith('acs:'): (resource_type, resource_id) = re.match(resource_pattern, resource_urn).groups() else: resource_type, resource_id = "bookreader", resource_urn resource_type = "resource_" + resource_type if is_loaned_out(resource_id): d[resource_type] = 'checkedout' else: d[resource_type] = 'available' return web.storage(d)
def POST(self, key): if not is_admin(): return render_template('permission_denied', web.ctx.path, "Permission denied.") edition = web.ctx.site.get(key) if not edition: raise web.notfound() if not edition.ocaid: raise web.seeother(edition.url("/borrow_admin")) lending.sync_loan(edition.ocaid) i = web.input(action=None, loan_key=None) if i.action == 'delete' and i.loan_key: loan = lending.get_loan(edition.ocaid) if loan and loan['_key'] == i.loan_key: loan.delete() raise web.seeother(web.ctx.path + '/borrow_admin')
def POST(self, key): if not is_admin(): return render_template('permission_denied', web.ctx.path, "Permission denied.") edition = web.ctx.site.get(key) if not edition: raise web.notfound() if not edition.ocaid: raise web.seeother(edition.url("/borrow_admin")) lending.sync_loan(edition.ocaid) i = web.input(action=None, loan_key=None) if i.action == 'delete' and i.loan_key: loan = lending.get_loan(edition.ocaid) if loan and loan['_key'] == i.loan_key: loan.delete() elif i.action == 'update_loan_info': waitinglist.update_waitinglist(edition.ocaid) raise web.seeother(web.ctx.path + '/borrow_admin')
def get_ia_auth_dict(user, item_id, user_specified_loan_key, access_token): """Returns response similar to one of these: {'success':true,'token':'1287185207-fa72103dd21073add8f87a5ad8bce845','borrowed':true} {'success':false,'msg':'Book is checked out','borrowed':false, 'resolution': 'You can visit <a href="http://openlibary.org/ia/someid">this book\'s page on Open Library</a>.'} """ base_url = 'http://' + web.ctx.host resolution_dict = {'base_url': base_url, 'item_id': item_id} error_message = None user_has_current_loan = False # Sanity checks if not ia_identifier_is_valid(item_id): return { 'success': False, 'msg': 'Invalid item id', 'resolution': 'This book does not appear to have a valid item identifier.' } # Lookup loan information loan = lending.get_loan(item_id) loan_key = loan and loan.get_key() if loan_key is None: # Book is not checked out as a BookReader loan - may still be checked out in ACS4 error_message = 'Lending Library Book' resolution_message = 'This book is part of the <a href="%(base_url)s/subjects/Lending_library">lending library</a>. Please <a href="%(base_url)s/ia/%(item_id)s/borrow">visit this book\'s page on Open Library</a> to access the book.' % resolution_dict else: # If we know who this user is, from third-party cookies and they are logged into openlibrary.org, check if they have the loan if user: if loan['user'] != user.key: # Borrowed by someone else - OR possibly came in through ezproxy and there's a stale login in on openlibrary.org error_message = 'This book is checked out' resolution_message = 'This book is currently checked out. You can <a href="%(base_url)s/ia/%(item_id)s">visit this book\'s page on Open Library</a> or <a href="%(base_url)s/subjects/Lending_library">look at other books available to borrow</a>.' % resolution_dict elif loan['expiry'] < datetime.datetime.utcnow().isoformat(): # User has the loan, but it's expired error_message = 'Your loan has expired' resolution_message = 'Your loan for this book has expired. You can <a href="%(base_url)s/ia/%(item_id)s">visit this book\'s page on Open Library</a>.' % resolution_dict else: # User holds the loan - win! user_has_current_loan = True else: # Don't have user context - not logged in or third-party cookies disabled # Check if the loan id + token is valid if user_specified_loan_key and access_token and ia_token_is_current( item_id, access_token): # Win! user_has_current_loan = True else: # Couldn't validate using token - they need to go to Open Library error_message = "Lending Library Book" resolution_message = 'This book is part of the <a href="%(base_url)s/subjects/Lending_library" title="Open Library Lending Library">lending library</a>. Please <a href="%(base_url)s/ia/%(item_id)s/borrow" title="Borrow book page on Open Library">visit this book\'s page on Open Library</a> to access the book. You must have cookies enabled for archive.org and openlibrary.org to access borrowed books.' % resolution_dict if error_message: return { 'success': False, 'msg': error_message, 'resolution': resolution_message } else: # No error message, make sure we thought the loan was current as sanity check if not user_has_current_loan: raise Exception( 'lending: no current loan for this user found but no error condition specified' ) return { 'success': True, 'token': make_ia_token(item_id, bookreader_auth_seconds) }
def get_edition_loans(edition): if edition.ocaid: loan = lending.get_loan(edition.ocaid) if loan: return [loan] return []
def get_ia_auth_dict(user, item_id, resource_id, user_specified_loan_key, access_token): """Returns response similar to one of these: {'success':true,'token':'1287185207-fa72103dd21073add8f87a5ad8bce845','borrowed':true} {'success':false,'msg':'Book is checked out','borrowed':false, 'resolution': 'You can visit <a href="http://openlibary.org/ia/someid">this book\'s page on Open Library</a>.'} """ base_url = 'http://' + web.ctx.host resolution_dict = { 'base_url': base_url, 'item_id': item_id } error_message = None user_has_current_loan = False # Sanity checks if not ia_identifier_is_valid(item_id): return {'success': False, 'msg': 'Invalid item id', 'resolution': 'This book does not appear to have a valid item identifier.' } if not resource_id.startswith('bookreader'): error_message = 'Bad resource id type' resolution_message = 'This book cannot be borrowed for in-browser loan. You can <a href="%(base_url)s/ia/%(item_id)s">visit this book\'s page</a> on openlibrary.org to learn more about the book.' % resolution_dict return {'success': False, 'msg': error_message, 'resolution': resolution_message } # Lookup loan information #loan_key = get_loan_key(resource_id) loan = lending.get_loan(item_id) loan_key = loan and loan.get_key() if loan_key is None: # Book is not checked out as a BookReader loan - may still be checked out in ACS4 error_message = 'Lending Library Book' resolution_message = 'This book is part of the <a href="%(base_url)s/subjects/Lending_library">lending library</a>. Please <a href="%(base_url)s/ia/%(item_id)s/borrow">visit this book\'s page on Open Library</a> to access the book.' % resolution_dict else: # Book is checked out (by someone) - get the loan information #loan = web.ctx.site.store.get(loan_key) # Check that this is a bookreader loan if loan['resource_type'] != 'bookreader': error_message = 'No BookReader loan' resolution_message = 'This book was borrowed as ' + loan['resource_type'] + '. You can <a href="%(base_url)s/ia/%(item_id)s">visit this book\'s page</a> on openlibrary.org to access the book in that format.' % resolution_dict return {'success': False, 'msg': error_message, 'resolution': resolution_message } # If we know who this user is, from third-party cookies and they are logged into openlibrary.org, check if they have the loan if user: if loan['user'] != user.key: # Borrowed by someone else - OR possibly came in through ezproxy and there's a stale login in on openlibrary.org error_message = 'This book is checked out' resolution_message = 'This book is currently checked out. You can <a href="%(base_url)s/ia/%(item_id)s">visit this book\'s page on Open Library</a> or <a href="%(base_url)s/subjects/Lending_library">look at other books available to borrow</a>.' % resolution_dict elif loan['expiry'] < datetime.datetime.utcnow().isoformat(): # User has the loan, but it's expired error_message = 'Your loan has expired' resolution_message = 'Your loan for this book has expired. You can <a href="%(base_url)s/ia/%(item_id)s">visit this book\'s page on Open Library</a>.' % resolution_dict else: # User holds the loan - win! user_has_current_loan = True else: # Don't have user context - not logged in or third-party cookies disabled # Check if the loan id + token is valid if user_specified_loan_key and access_token and ia_token_is_current(item_id, access_token): # Win! user_has_current_loan = True else: # Couldn't validate using token - they need to go to Open Library error_message = "Lending Library Book" resolution_message = 'This book is part of the <a href="%(base_url)s/subjects/Lending_library" title="Open Library Lending Library">lending library</a>. Please <a href="%(base_url)s/ia/%(item_id)s/borrow" title="Borrow book page on Open Library">visit this book\'s page on Open Library</a> to access the book. You must have cookies enabled for archive.org and openlibrary.org to access borrowed books.' % resolution_dict if error_message: return { 'success': False, 'msg': error_message, 'resolution': resolution_message } else: # No error message, make sure we thought the loan was current as sanity check if not user_has_current_loan: raise Exception('lending: no current loan for this user found but no error condition specified') return { 'success': True, 'token': make_ia_token(item_id, bookreader_auth_seconds) }