Пример #1
0
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)
Пример #2
0
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)
Пример #3
0
    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')
Пример #4
0
    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')
Пример #5
0
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)
    }
Пример #6
0
def get_edition_loans(edition):
    if edition.ocaid:
        loan = lending.get_loan(edition.ocaid)
        if loan:
            return [loan]
    return []
Пример #7
0
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) }
Пример #8
0
def get_edition_loans(edition):
    if edition.ocaid:
        loan = lending.get_loan(edition.ocaid)
        if loan:
            return [loan]
    return []