diff --git a/bookwyrm/management/commands/deduplicate_book_data.py b/bookwyrm/management/commands/deduplicate_book_data.py index d2f4ef936..74475a00b 100644 --- a/bookwyrm/management/commands/deduplicate_book_data.py +++ b/bookwyrm/management/commands/deduplicate_book_data.py @@ -30,7 +30,8 @@ def dedupe_model(model): print(f"merging into {canonical.remote_id} based on {field.name} {value}:") for obj in objs[1:]: print(f"- {obj.remote_id}") - obj.merge_into(canonical) + absorbed_fields = obj.merge_into(canonical) + print(f" absorbed fields: {absorbed_fields}") class Command(BaseCommand): diff --git a/bookwyrm/management/merge_command.py b/bookwyrm/management/merge_command.py index 2f3f90c86..0c464600a 100644 --- a/bookwyrm/management/merge_command.py +++ b/bookwyrm/management/merge_command.py @@ -25,4 +25,6 @@ class MergeCommand(BaseCommand): print("other book doesn’t exist!") return - other.merge_into(canonical) + absorbed_fields = other.merge_into(canonical) + print(f"{other.remote_id} has been merged into {canonical.remote_id}") + print(f"absorbed fields: {absorbed_fields}") diff --git a/bookwyrm/models/book.py b/bookwyrm/models/book.py index c7235a3f5..d7193cbbe 100644 --- a/bookwyrm/models/book.py +++ b/bookwyrm/models/book.py @@ -2,7 +2,7 @@ from itertools import chain import re -from typing import Any +from typing import Any, Dict from typing_extensions import Self from django.contrib.postgres.search import SearchVectorField @@ -110,12 +110,12 @@ class BookDataModel(ObjectMixin, BookWyrmModel): """only send book data updates to other bookwyrm instances""" super().broadcast(activity, sender, software=software, **kwargs) - def merge_into(self, canonical: Self) -> None: + def merge_into(self, canonical: Self) -> Dict[str, Any]: """merge this entity into another entity""" if canonical.id == self.id: raise ValueError(f"Cannot merge {self} into itself") - canonical.absorb_data_from(self) + absorbed_fields = canonical.absorb_data_from(self) canonical.save() self.merged_model.objects.create(deleted_id=self.id, merged_into=canonical) @@ -147,9 +147,11 @@ class BookDataModel(ObjectMixin, BookWyrmModel): getattr(related_obj, related_field).remove(self) self.delete() + return absorbed_fields - def absorb_data_from(self, other: Self) -> None: + def absorb_data_from(self, other: Self) -> Dict[str, Any]: """fill empty fields with values from another entity""" + absorbed_fields = {} for data_field in self._meta.get_fields(): if not hasattr(data_field, "activitypub_field"): continue @@ -158,6 +160,8 @@ class BookDataModel(ObjectMixin, BookWyrmModel): continue if not getattr(self, data_field.name): setattr(self, data_field.name, data_value) + absorbed_fields[data_field.name] = data_value + return absorbed_fields class MergedBookDataModel(models.Model):