def POST(self, key): """Called when the user wants to borrow the edition""" i = web.input(action='borrow', format=None, ol_host=None) if i.ol_host: ol_host = i.ol_host else: ol_host = 'openlibrary.org' edition = web.ctx.site.get(key) if not edition: raise web.notfound() error_redirect = edition.url("/borrow") user = accounts.get_current_user() if not user: raise web.seeother(error_redirect) if i.action == 'borrow': resource_type = i.format if resource_type not in ['epub', 'pdf', 'bookreader']: raise web.seeother(error_redirect) if resource_type == 'bookreader': #ab.convert("borrow-layout") pass if user_can_borrow_edition(user, edition, resource_type): # XXX-Anand - Sept 2014: # Extra check to avoid book being given to someone when people are already # waiting on it. There are some reports of this happening. # Redirect back to the same page if there is waitinglist. wl = edition.get_waitinglist() if wl and (wl[0].get_user_key() != user.key or wl[0]['status'] != 'available'): raise web.seeother(error_redirect) loan = lending.create_loan( identifier=edition.ocaid, resource_type=resource_type, user_key=user.key, book_key=key) loan_link = loan['loan_link'] if resource_type == 'bookreader': stats.increment('ol.loans.bookreader') elif resource_type == 'pdf': stats.increment('ol.loans.pdf') elif resource_type == 'epub': stats.increment('ol.loans.epub') if resource_type == 'bookreader': raise web.seeother(make_bookreader_auth_link(loan.get_key(), edition.ocaid, '/stream/' + edition.ocaid, ol_host)) else: raise web.seeother(loan_link) else: # Send to the borrow page raise web.seeother(error_redirect) elif i.action == 'return': # Check that this user has the loan user.update_loan_status() loans = get_loans(user) # We pick the first loan that the user has for this book that is returnable. # Assumes a user can't borrow multiple formats (resource_type) of the same book. user_loan = None for loan in loans: # Handle the case of multiple edition records for the same # ocaid and the user borrowed from one and returning from another has_loan = (loan['book'] == edition.key or loan['ocaid'] == edition.ocaid) if has_loan and can_return_resource_type(loan['resource_type']): user_loan = loan break if not user_loan: # $$$ add error message raise web.seeother(error_redirect) user_loan.return_loan() # Show the page with "you've returned this" # $$$ this would do better in a session variable that can be cleared # after the message is shown once raise web.seeother(edition.url('/borrow?r=t')) elif i.action == 'read': # Look for loans for this book user.update_loan_status() loans = get_loans(user) for loan in loans: if loan['book'] == edition.key: raise web.seeother(make_bookreader_auth_link(loan['_key'], edition.ocaid, '/stream/' + edition.ocaid, ol_host)) elif i.action == 'join-waitinglist': return self.POST_join_waitinglist(edition, user) elif i.action == 'leave-waitinglist': return self.POST_leave_waitinglist(edition, user, i) # Action not recognized raise web.seeother(error_redirect)
def POST(self, key): """Called when the user wants to borrow the edition""" i = web.input(action='borrow', format=None, ol_host=None) if i.ol_host: ol_host = i.ol_host else: ol_host = 'openlibrary.org' edition = web.ctx.site.get(key) if not edition: raise web.notfound() # Make a call to availability v2 update the subjects according # to result if `open`, redirect to bookreader response = lending.get_availability_of_ocaid(edition.ocaid) availability = response[edition.ocaid] if response else {} if availability and availability['status'] == 'open': raise web.seeother('https://archive.org/stream/' + edition.ocaid + '?ref=ol') error_redirect = ('https://archive.org/stream/' + edition.ocaid + '?ref=ol') user = accounts.get_current_user() if user: account = OpenLibraryAccount.get_by_email(user.email) ia_itemname = account.itemname if account else None if not user or not ia_itemname: web.setcookie(config.login_cookie_name, "", expires=-1) raise web.seeother("/account/login?redirect=%s/borrow?action=%s" % (edition.url(), i.action)) action = i.action # Intercept a 'borrow' action if the user has already # borrowed the book and convert to a 'read' action. # Added so that direct bookreader links being routed through # here can use a single action of 'borrow', regardless of # whether the book has been checked out or not. if action == 'borrow' and user.has_borrowed(edition): action = 'read' if action == 'borrow': resource_type = i.format or 'bookreader' if resource_type not in ['epub', 'pdf', 'bookreader']: raise web.seeother(error_redirect) user_meets_borrow_criteria = user_can_borrow_edition( user, edition, resource_type) if user_meets_borrow_criteria: # This must be called before the loan is initiated, # otherwise the user's waitlist status will be cleared # upon loan creation track_loan = False if is_users_turn_to_borrow( user, edition) else True loan = lending.create_loan(identifier=edition.ocaid, resource_type=resource_type, user_key=ia_itemname, book_key=key) if loan: loan_link = loan['loan_link'] if resource_type == 'bookreader': if track_loan: # As of 2017-12-14, Petabox will be # responsible for tracking borrows which # are the result of waitlist redemptions, # so we don't want to track them here to # avoid double accounting. When a reader # is at the head of a waitlist and goes to # claim their loan, Petabox now checks # whether the waitlist was initiated from # OL, and if it was, petabox tracks # ol.loans.bookreader accordingly via # lending.create_loan. stats.increment('ol.loans.bookreader') raise web.seeother( make_bookreader_auth_link( loan.get_key(), edition.ocaid, '/stream/' + edition.ocaid, ol_host)) elif resource_type == 'pdf': stats.increment('ol.loans.pdf') raise web.seeother(loan_link) elif resource_type == 'epub': stats.increment('ol.loans.epub') raise web.seeother(loan_link) else: raise web.seeother(error_redirect) else: raise web.seeother(error_redirect) elif action == 'return': # Check that this user has the loan user.update_loan_status() loans = get_loans(user) # We pick the first loan that the user has for this book that is returnable. # Assumes a user can't borrow multiple formats (resource_type) of the same book. user_loan = None for loan in loans: # Handle the case of multiple edition records for the same # ocaid and the user borrowed from one and returning from another has_loan = (loan['book'] == edition.key or loan['ocaid'] == edition.ocaid) if has_loan: user_loan = loan break if not user_loan: # $$$ add error message raise web.seeother(error_redirect) user_loan.return_loan() # Show the page with "you've returned this". Use a dummy slug. # $$$ this would do better in a session variable that can be cleared # after the message is shown once raise web.seeother(edition.url()) elif action == 'read': # Look for loans for this book user.update_loan_status() loans = get_loans(user) for loan in loans: if loan['book'] == edition.key: raise web.seeother( make_bookreader_auth_link(loan['_key'], edition.ocaid, '/stream/' + edition.ocaid, ol_host)) elif action == 'join-waitinglist': return self.POST_join_waitinglist(edition, user) elif action == 'leave-waitinglist': return self.POST_leave_waitinglist(edition, user, i) # Action not recognized raise web.seeother(error_redirect)
def POST(self, key): """Called when the user wants to borrow the edition""" i = web.input(action='borrow', format=None, ol_host=None) if i.ol_host: ol_host = i.ol_host else: ol_host = 'openlibrary.org' edition = web.ctx.site.get(key) if not edition: raise web.notfound() # Make a call to availability v2 update the subjects according # to result if `open`, redirect to bookreader response = lending.get_availability_of_ocaid(edition.ocaid) availability = response[edition.ocaid] if response else {} if availability and availability['status'] == 'open': raise web.seeother('https://archive.org/stream/' + edition.ocaid + '?ref=ol') error_redirect = ('https://archive.org/stream/' + edition.ocaid + '?ref=ol') user = accounts.get_current_user() if user: account = OpenLibraryAccount.get_by_email(user.email) ia_itemname = account.itemname if account else None if not user or not ia_itemname: web.setcookie(config.login_cookie_name, "", expires=-1) raise web.seeother("/account/login?redirect=%s/borrow?action=%s" % ( edition.url(), i.action)) action = i.action # Intercept a 'borrow' action if the user has already # borrowed the book and convert to a 'read' action. # Added so that direct bookreader links being routed through # here can use a single action of 'borrow', regardless of # whether the book has been checked out or not. if action == 'borrow' and user.has_borrowed(edition): action = 'read' if action == 'borrow': resource_type = i.format or 'bookreader' if resource_type not in ['epub', 'pdf', 'bookreader']: raise web.seeother(error_redirect) user_meets_borrow_criteria = user_can_borrow_edition(user, edition, resource_type) if user_meets_borrow_criteria: # This must be called before the loan is initiated, # otherwise the user's waitlist status will be cleared # upon loan creation track_loan = False if is_users_turn_to_borrow(user, edition) else True loan = lending.create_loan( identifier=edition.ocaid, resource_type=resource_type, user_key=ia_itemname, book_key=key) if loan: loan_link = loan['loan_link'] if resource_type == 'bookreader': if track_loan: # As of 2017-12-14, Petabox will be # responsible for tracking borrows which # are the result of waitlist redemptions, # so we don't want to track them here to # avoid double accounting. When a reader # is at the head of a waitlist and goes to # claim their loan, Petabox now checks # whether the waitlist was initiated from # OL, and if it was, petabox tracks # ol.loans.bookreader accordingly via # lending.create_loan. stats.increment('ol.loans.bookreader') raise web.seeother(make_bookreader_auth_link( loan.get_key(), edition.ocaid, '/stream/' + edition.ocaid, ol_host, ia_userid=ia_itemname)) elif resource_type == 'pdf': stats.increment('ol.loans.pdf') raise web.seeother(loan_link) elif resource_type == 'epub': stats.increment('ol.loans.epub') raise web.seeother(loan_link) else: raise web.seeother(error_redirect) else: raise web.seeother(error_redirect) elif action == 'return': # Check that this user has the loan user.update_loan_status() loans = get_loans(user) # We pick the first loan that the user has for this book that is returnable. # Assumes a user can't borrow multiple formats (resource_type) of the same book. user_loan = None for loan in loans: # Handle the case of multiple edition records for the same # ocaid and the user borrowed from one and returning from another has_loan = (loan['book'] == edition.key or loan['ocaid'] == edition.ocaid) if has_loan: user_loan = loan break if not user_loan: # $$$ add error message raise web.seeother(error_redirect) user_loan.return_loan() # Show the page with "you've returned this". Use a dummy slug. # $$$ this would do better in a session variable that can be cleared # after the message is shown once raise web.seeother(edition.url()) elif action == 'read': # Look for loans for this book user.update_loan_status() loans = get_loans(user) for loan in loans: if loan['book'] == edition.key: raise web.seeother(make_bookreader_auth_link( loan['_key'], edition.ocaid, '/stream/' + edition.ocaid, ol_host, ia_userid=ia_itemname )) elif action == 'join-waitinglist': return self.POST_join_waitinglist(edition, user) elif action == 'leave-waitinglist': return self.POST_leave_waitinglist(edition, user, i) # Action not recognized raise web.seeother(error_redirect)