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)
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)
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)
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)
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
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)
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)
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))
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)
def on_page_edit(page): if page.key.startswith("/libraries/"): eventer.trigger("page.edit.libraries", page)