@@ -224,6 +224,16 @@ def save_batch_and_preview_commands(self):
224224 batch_command .batch = self
225225 batch_command .save ()
226226
227+ def wikibase_url (self ):
228+ """
229+ Returns the wikibase url of this batch.
230+
231+ In the future this could be a field, so that batches targeting
232+ different wikibases (like wikidata and test.wikidata) are
233+ possible in the same server.
234+ """
235+ return settings .BASE_REST_URL .replace ("https://" , "http://" ).split ("/w/rest.php" )[0 ]
236+
227237
228238class BatchCommand (models .Model ):
229239 """
@@ -477,10 +487,10 @@ def parser_value_to_api_value(self, parser_value):
477487 def statement_api_value (self ):
478488 value = self .json ["value" ]
479489 if value ["type" ] == "quantity" and value ["value" ]["unit" ] != "1" :
480- # TODO: the unit is an entity and we need to put the
481- # full entity URL... so we need the client
482- # to process the URL
483- raise NotImplementedError ()
490+ base = self . batch . wikibase_url ()
491+ unit_id = value [ "value" ][ "unit" ]
492+ full_unit = f" { base } /entity/Q { unit_id } "
493+ value [ "value" ][ "unit" ] = full_unit
484494 return self .parser_value_to_api_value (value )
485495
486496 def update_statement (self , st ):
@@ -651,12 +661,17 @@ def edit_summary(self):
651661
652662 It joins the user supplied summary with
653663 the identification necessary for EditGroups.
664+
665+ Also joins the summary from the previous combined commands.
654666 """
667+ summaries = [self .user_summary ]
668+ summaries .extend ([c .user_summary for c in getattr (self , "previous_commands" , [])])
669+ combined = " | " .join ([s for s in summaries [::- 1 ] if bool (s )])
655670 editgroups = self .editgroups_summary ()
656671 if editgroups :
657- return f"{ editgroups } : { self . user_summary } " if self . user_summary else editgroups
672+ return f"{ editgroups } : { combined } " if combined else editgroups
658673 else :
659- return self . user_summary if self . user_summary else ""
674+ return combined
660675
661676 def editgroups_summary (self ):
662677 """
@@ -685,6 +700,7 @@ def is_entity_json_patch(self):
685700 self .Operation .SET_LABEL ,
686701 self .Operation .SET_DESCRIPTION ,
687702 self .Operation .SET_SITELINK ,
703+ self .Operation .REMOVE_ALIAS ,
688704 self .Operation .REMOVE_LABEL ,
689705 self .Operation .REMOVE_DESCRIPTION ,
690706 self .Operation .REMOVE_SITELINK ,
@@ -775,13 +791,10 @@ def update_entity_json(self, entity: dict):
775791 self ._update_entity_statements (entity )
776792 elif self .operation == self .Operation .REMOVE_STATEMENT_BY_VALUE :
777793 self ._remove_entity_statement (entity )
794+ elif self .operation in (self .Operation .ADD_ALIAS , self .Operation .REMOVE_ALIAS ):
795+ self ._update_entity_aliases (entity )
778796 elif self .operation in (self .Operation .REMOVE_QUALIFIER , self .Operation .REMOVE_REFERENCE ):
779797 self ._remove_qualifier_or_reference (entity )
780- elif self .operation == self .Operation .ADD_ALIAS :
781- entity ["aliases" ].setdefault (self .language , [])
782- for alias in self .value_value :
783- if alias not in entity ["aliases" ][self .language ]:
784- entity ["aliases" ][self .language ].append (alias )
785798 elif self .operation == self .Operation .SET_SITELINK :
786799 entity ["sitelinks" ][self .sitelink ] = {"title" : self .value_value }
787800 elif self .operation in (self .Operation .SET_LABEL , self .Operation .SET_DESCRIPTION ):
@@ -840,6 +853,24 @@ def _remove_entity_statement(self, entity: dict):
840853 return entity ["statements" ][self .prop ].pop (i )
841854 raise NoStatementsWithThatValue (self .entity_id (), self .prop , self .statement_api_value )
842855
856+ def _update_entity_aliases (self , entity : dict ):
857+ """
858+ Update the entity's aliases, adding or removing.
859+ """
860+ entity ["aliases" ].setdefault (self .language , [])
861+ aliases = entity ["aliases" ][self .language ]
862+ if self .operation == self .Operation .ADD_ALIAS :
863+ for alias in self .value_value :
864+ if alias not in aliases :
865+ aliases .append (alias )
866+ elif self .operation == self .Operation .REMOVE_ALIAS :
867+ new = [a for a in aliases if a not in self .value_value ]
868+ if len (new ) > 0 :
869+ entity ["aliases" ][self .language ] = new
870+ else :
871+ # It is not possible to leave a language with 0 aliases
872+ entity ["aliases" ].pop (self .language )
873+
843874 def entity_patch (self , client : Client ):
844875 """
845876 Calculates the entity json patch to send to the API.
@@ -851,13 +882,9 @@ def entity_patch(self, client: Client):
851882 TODO: maybe cache that original as well to not make
852883 two requests?
853884 """
854- logger .debug (f"[{ self } ] BEFORE ORIGINAL..." )
855885 original = self .get_original_entity_json (client )
856- logger .debug (f"[{ self } ] BEFORE PREVIOUS..." )
857886 entity = self .get_previous_entity_json (client )
858- logger .debug (f"[{ self } ] AFTER BOTH..." )
859887 self .update_entity_json (entity )
860- logger .debug (f"[{ self } ] AFTER UPDATE..." )
861888 return jsonpatch .JsonPatch .from_diff (original , entity ).patch
862889
863890 def api_payload (self , client : Client ):
@@ -893,7 +920,7 @@ def send_to_api(self, client: Client) -> dict:
893920 is not implemented.
894921 """
895922 match self .operation :
896- case self .Operation .CREATE_PROPERTY | self . Operation . REMOVE_ALIAS :
923+ case self .Operation .CREATE_PROPERTY :
897924 raise NotImplementedError ()
898925 case _:
899926 return self .send_basic (client )
0 commit comments