예제 #1
0
    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)
예제 #2
0
    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)
예제 #3
0
    def POST(self, key):
        """Called when the user wants to borrow the edition"""

        i = web.input(action='borrow', format=None, ol_host=None, _autoReadAloud=None, q="")

        ol_host = i.ol_host or 'openlibrary.org'
        action = i.action
        edition = web.ctx.site.get(key)
        if not edition:
            raise web.notfound()

        archive_url = get_bookreader_stream_url(edition.ocaid) + '?ref=ol'
        if i._autoReadAloud is not None:
            archive_url += '&_autoReadAloud=show'

        if i.q:
            _q = urllib.parse.quote(i.q, safe='')
            archive_url += "#page/-/mode/2up/search/%s" % _q

        # 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(archive_url)

        error_redirect = (archive_url)
        user = accounts.get_current_user()

        if user:
            account = OpenLibraryAccount.get_by_email(user.email)
            ia_itemname = account.itemname if account else None
            s3_keys = web.ctx.site.store.get(account._key).get('s3_keys')
        if not user or not ia_itemname or not s3_keys:
            web.setcookie(config.login_cookie_name, "", expires=-1)
            redirect_url = "/account/login?redirect=%s/borrow?action=%s" % (
                edition.url(), action)
            if i._autoReadAloud is not None:
                redirect_url += '&_autoReadAloud=' + i._autoReadAloud
            raise web.seeother(redirect_url)

        if action == 'return':
            lending.s3_loan_api(edition.ocaid, s3_keys, action='return_loan')
            stats.increment('ol.loans.return')
            raise web.seeother(edition.url())
        elif action == 'join-waitinglist':
            lending.s3_loan_api(edition.ocaid, s3_keys, action='join_waitlist')
            stats.increment('ol.loans.joinWaitlist')
            raise web.redirect(edition.url())
        elif action == 'leave-waitinglist':
            lending.s3_loan_api(edition.ocaid, s3_keys, action='leave_waitlist')
            stats.increment('ol.loans.leaveWaitlist')
            raise web.redirect(edition.url())

        # 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.
        elif user.has_borrowed(edition):
            action = 'read'

        elif action in ('borrow', 'browse'):
            borrow_access = user_can_borrow_edition(user, edition)

            if not (s3_keys or borrow_access):
                raise web.seeother(error_redirect)

            lending.s3_loan_api(edition.ocaid, s3_keys, action='%s_book' % borrow_access)
            stats.increment('ol.loans.bookreader')
            stats.increment('ol.loans.%s' % borrow_access)
            action = 'read'

        if action == 'read':
            bookPath = '/stream/' + edition.ocaid
            if i._autoReadAloud is not None:
                bookPath += '?_autoReadAloud=show'

            # 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, bookPath,
                        ol_host, ia_userid=ia_itemname
                    ))

        # Action not recognized
        raise web.seeother(error_redirect)