def get_or_create_book(self, remote_id): """ translate arbitrary json into an Activitypub dataclass """ # first, check if we have the origin_id saved existing = models.Edition.find_existing_by_remote_id( remote_id) or models.Work.find_existing_by_remote_id(remote_id) if existing: if hasattr(existing, "get_default_editon"): return existing.get_default_editon() return existing # load the json data = get_data(remote_id) mapped_data = dict_from_mappings(data, self.book_mappings) if self.is_work_data(data): try: edition_data = self.get_edition_from_work_data(data) except (KeyError, ConnectorException): # hack: re-use the work data as the edition data # this is why remote ids aren't necessarily unique edition_data = data work_data = mapped_data else: try: work_data = self.get_work_from_edition_data(data) work_data = dict_from_mappings(work_data, self.book_mappings) except (KeyError, ConnectorException): work_data = mapped_data edition_data = data if not work_data or not edition_data: raise ConnectorException("Unable to load book data: %s" % remote_id) with transaction.atomic(): # create activitypub object work_activity = activitypub.Work(**work_data) # this will dedupe automatically work = work_activity.to_model(model=models.Work) for author in self.get_authors_from_data(data): work.authors.add(author) edition = self.create_edition_from_data(work, edition_data) load_more_data.delay(self.connector.id, work.id) return edition
def handle_update_work(activity): ''' a remote instance changed a book (Document) ''' activitypub.Work(**activity['object']).to_model(models.Work)