docs: def detect_events(self, max_attempts=3):
          """Returns a list of `Event`s detected from differences in state
          between the current snapshot and the Kindle Library.
  
          `books` and `progress` attributes will be set with the latest API
          results upon successful completion of the function.
  
          Returns:
              If failed to retrieve progress, None
              Else, the list of `Event`s
          """
          # Attempt to retrieve current state from KindleAPI
          for _ in xrange(max_attempts):
              try:
                  with KindleCloudReaderAPI\
                          .get_instance(self.uname, self.pword) as kcr:
                      self.books = kcr.get_library_metadata()
                      self.progress = kcr.get_library_progress()
              except KindleAPIError:
                  continue
              else:
                  break
          else:
              return None
  
          # Calculate diffs from new progress
          progress_map = {book.asin: self.progress[book.asin].locs[1]
                                                  for book in self.books}
          new_events = self._snapshot.calc_update_events(progress_map)
  
          update_event = UpdateEvent(datetime.now().replace(microsecond=0))
          new_events.append(update_event)
  
          self._event_buf.extend(new_events)
          return new_events