Example #1
0
def sync_loan(identifier, loan=NOT_INITIALIZED):
    """Updates the loan info stored in openlibrary.

    The loan records are stored at the Internet Archive. There is no way for
    OL to know when a loan is deleted. To handle that situation, the loan info
    is stored in the ebook document and the deletion is detected by comparing
    the current loan id and loan id stored in the ebook.

    This function is called whenever the loan is updated.
    """
    logger.info("BEGIN sync_loan %s %s", identifier, loan)

    if loan is NOT_INITIALIZED:
        loan = get_loan(identifier)

    # The data of the loan without the user info.
    loan_data = loan and dict(
        uuid=loan['uuid'],
        loaned_at=loan['loaned_at'],
        resource_type=loan['resource_type'],
        ocaid=loan['ocaid'],
        book=loan['book'],
    )

    responses = get_availability_of_ocaid(identifier)
    response = responses[identifier] if responses else {}
    if response:
        num_waiting = int(response.get('num_waitlist', 0) or 0)

    ebook = EBookRecord.find(identifier)

    # The loan known to us is deleted
    is_loan_completed = ebook.get("loan") and ebook.get("loan") != loan_data

    # When the current loan is a OL loan, remember the loan_data
    if loan and loan.is_ol_loan():
        ebook_loan_data = loan_data
    else:
        ebook_loan_data = None

    kwargs = {
        "type": "ebook",
        "identifier": identifier,
        "loan": ebook_loan_data,
        "borrowed": str(response['status'] not in ['open', 'borrow_available']).lower(),
        "wl_size": num_waiting,
    }
    try:
        ebook.update(**kwargs)
    except Exception:  # TODO: Narrow exception scope
        # updating ebook document is sometimes failing with
        # "Document update conflict" error.
        # Log the error in such cases, don't crash.
        logger.exception("failed to update ebook for %s", identifier)

    # fire loan-completed event
    if is_loan_completed and ebook.get('loan'):
        _d = dict(ebook['loan'], returned_at=time.time())
        eventer.trigger("loan-completed", _d)
    logger.info("END sync_loan %s", identifier)
Example #2
0
def trigger_offline_event(event, *a, **kw):
    logger.info("trigger_offline_event %s %s %s", event, a, kw)
    
    # Importing events to add an offline event to eventer. 
    # TODO: load the plugins from OL configuration
    from openlibrary.plugins.openlibrary import events
    
    eventer.trigger(event, *a, **kw)
Example #3
0
    def save(self):
        # loans stored at IA are not supposed to be saved at OL.
        # This call must have been made in mistake.
        if self.get("stored_at") == "ia":
            return

        web.ctx.site.store[self['_key']] = self

        # Inform listers that a loan is created/updated
        eventer.trigger("loan-created", self)
Example #4
0
def trigger_subevents(event):
    """Trigger infobase.edit event for edits.
    """
    if event.name in ['save', 'save_many']:
        changeset = event.data['changeset']

        author = changeset['author'] or changeset['ip']
        keys = [c['key'] for c in changeset['changes']]
        logger.info("Edit by %s, changeset_id=%s, changes=%s", author, changeset["id"], keys)
        
        eventer.trigger("infobase.edit", changeset)
Example #5
0
def create_loan(identifier, resource_type, user_key, book_key=None):
    """Creates a loan and returns it."""
    ia_loan = ia_lending_api.create_loan(
        identifier=identifier, format=resource_type, userid=user_key, ol_key=book_key
    )

    if ia_loan:
        loan = Loan.from_ia_loan(ia_loan)
        eventer.trigger("loan-created", loan)
        sync_loan(identifier)
        return loan
Example #6
0
def trigger_subevents(event):
    """Trigger infobase.edit event for edits."""
    if event.name in ['save', 'save_many']:
        changeset = event.data['changeset']

        author = changeset['author'] or changeset['ip']
        keys = [c['key'] for c in changeset['changes']]
        logger.info("Edit by %s, changeset_id=%s, changes=%s", author,
                    changeset["id"], keys)

        eventer.trigger("infobase.edit", changeset)
Example #7
0
    def delete(self):
        loan = dict(self, returned_at=time.time())
        user_key = self['user']
        account = OpenLibraryAccount.get(key=user_key)
        if self.get("stored_at") == 'ia':
            ia_lending_api.delete_loan(self['ocaid'], userkey2userid(user_key))
            if account.itemname:
                ia_lending_api.delete_loan(self['ocaid'], account.itemname)
        else:
            web.ctx.site.store.delete(self['_key'])

        sync_loan(self['ocaid'])
        # Inform listers that a loan is completed
        eventer.trigger("loan-completed", loan)
Example #8
0
def setup_event_listener():
    logger.info("setting up infobase events for Open Library")

    ol = server.get_site('openlibrary.org')
    ib = server._infobase

    # Convert infobase event into generic eventer event
    ib.add_event_listener(lambda event: eventer.trigger("infobase.all", event))
Example #9
0
def setup_event_listener():
    logger.info("setting up infobase events for Open Library")
    
    ol = server.get_site('openlibrary.org')
    ib = server._infobase

    # Convert infobase event into generic eventer event
    ib.add_event_listener(lambda event: eventer.trigger("infobase.all", event))
Example #10
0
 def on_new_version(self, page):
     """Fires page.edit event using msg broker."""
     # The argument passes by Infobase is not a thing object.
     # Create a thing object to pass to event listeners.
     page = web.ctx.site.get(page['key'])
     eventer.trigger("page.edit", page)
Example #11
0
def on_page_edit(page):
    if page.key.startswith("/libraries/"):
        eventer.trigger("page.edit.libraries", page)
Example #12
0
 def on_new_version(self, page):
     """Fires page.edit event using msg broker."""
     # The argument passes by Infobase is not a thing object. 
     # Create a thing object to pass to event listeners.
     page = web.ctx.site.get(page['key'])
     eventer.trigger("page.edit", page)
Example #13
0
def on_page_edit(page):
    if page.key.startswith("/libraries/"):
        eventer.trigger("page.edit.libraries", page)