Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions src/core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -881,6 +881,10 @@ class Operation(models.TextChoices):
"remove_reference",
pgettext_lazy("batchcommand-py-operation-remove-reference", "Remove reference"),
)
REMOVE_REFERENCE_BLOCK = (
"remove_reference_block",
pgettext_lazy("batchcommand-py-operation-remove-reference-block", "Remove reference block"),
)
#
SET_SITELINK = (
"set_sitelink",
Expand Down Expand Up @@ -1535,6 +1539,7 @@ def operation_is_combinable(self):
self.Operation.REMOVE_STATEMENT_BY_VALUE,
self.Operation.REMOVE_QUALIFIER,
self.Operation.REMOVE_REFERENCE,
self.Operation.REMOVE_REFERENCE_BLOCK,
self.Operation.ADD_ALIAS,
self.Operation.SET_LABEL,
self.Operation.SET_DESCRIPTION,
Expand Down Expand Up @@ -1686,6 +1691,7 @@ def update_entity_json(self, entity: dict):
elif self.operation in (
self.Operation.REMOVE_QUALIFIER,
self.Operation.REMOVE_REFERENCE,
self.Operation.REMOVE_REFERENCE_BLOCK,
):
self._remove_qualifier_or_reference(entity)
elif self.operation == self.Operation.SET_SITELINK:
Expand Down Expand Up @@ -1747,7 +1753,7 @@ def _update_entity_statements(self, entity: dict):

def _remove_qualifier_or_reference(self, entity: dict):
"""
Removes a qualifier or a reference from the entity.
Removes a qualifier, a reference part or a reference block from the entity.
"""
statements = self._get_statements(entity)
found_qualifier = False
Expand All @@ -1768,9 +1774,9 @@ def _remove_qualifier_or_reference(self, entity: dict):
found_ref_part = True
break
if found_ref_part:
if self.operation == self.Operation.REMOVE_REFERENCE_BLOCK:
statement["references"].pop(i)
break
# any better way to do this? :P
# (without refactoring into a different function...)
if found_ref_part:
break
if not found_qualifier and len(self.qualifiers_for_api()) > 0:
Expand Down
14 changes: 9 additions & 5 deletions src/core/parsers/v1.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,17 +94,19 @@ def parse_remove_qualifier(self, elements):
return data

def parse_remove_reference(self, elements):
oprt = str(elements[0])
is_block = oprt == "REMOVE_REF_BLOCK"
llen = len(elements)
if llen != 6:
raise ParserException("REMOVE_REF command must be Qid|Pid|value|Sid|value")
raise ParserException(f"{oprt} command must be Qid|Pid|value|Sid|value")
elements.pop(0)
data = self.parse_statement(elements, elements[0].upper())
data["action"] = "remove"
data["what"] = "reference"
data["what"] = "reference_block" if is_block else "reference"
if len(data.get("references", [])) != 1:
raise ParserException("REMOVE_REF command must have 1 reference")
raise ParserException(f"{oprt} command must have 1 reference")
if len(data.get("qualifiers", [])) != 0:
raise ParserException("REMOVE_REF command must have no qualifiers")
raise ParserException(f"{oprt} command must have no qualifiers")
return data

def parse_statement_by_id(self, elements):
Expand Down Expand Up @@ -354,7 +356,7 @@ def parse_command(self, raw_command):
elif first_command == "REMOVE_QUAL":
logger.debug(f"parsing remove qualifier: {elements}")
data = self.parse_remove_qualifier(elements)
elif first_command == "REMOVE_REF":
elif first_command in ("REMOVE_REF", "REMOVE_REF_BLOCK"):
logger.debug(f"parsing remove reference: {elements}")
data = self.parse_remove_reference(elements)
elif first_command == "SWITCH_VALUE":
Expand Down Expand Up @@ -447,6 +449,8 @@ def restore_placeholders(command):
bc.operation = bc.Operation.REMOVE_QUALIFIER
elif what == "reference":
bc.operation = bc.Operation.REMOVE_REFERENCE
elif what == "reference_block":
bc.operation = bc.Operation.REMOVE_REFERENCE_BLOCK
elif command["action"] == "create":
bc.action = BatchCommand.ACTION_CREATE
what_or_type = command.get("type", command.get("what"))
Expand Down
43 changes: 43 additions & 0 deletions src/core/tests/test_entity_patching.py
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,49 @@ def test_remove_reference(self):
prop = entity["statements"]["P31"][0]["references"][1]["parts"][0]["property"]
self.assertEqual(prop["id"], "P74")

def test_remove_reference_block(self):
text = """
REMOVE_REF_BLOCK|Q12345678|P65|42|S31|somevalue
REMOVE_REF_BLOCK|Q12345678|P31|somevalue|S93|"https://www.mediawiki.org/"
REMOVE_REF_BLOCK|Q12345678|P31|somevalue|S84267|42
REMOVE_REF_BLOCK|Q12345678|P31|somevalue|S84267|42
"""
batch = self.parse(text)
entity = copy.deepcopy(self.INITIAL)
# -----
remove_nothing = batch.commands()[0]
self.assertRefCount(entity, "P65", 0)
with self.assertRaises(NoReferenceParts):
remove_nothing.update_entity_json(entity)
self.assertRefCount(entity, "P65", 0)
# ---
prop = entity["statements"]["P31"][0]["references"][0]["parts"][0]["property"]
self.assertEqual(prop["id"], "P93")
prop = entity["statements"]["P31"][0]["references"][1]["parts"][0]["property"]
self.assertEqual(prop["id"], "P93")
# -----
remove_part_mediawiki = batch.commands()[1]
self.assertRefCount(entity, "P31", 2)
self.assertRefPartsCount(entity, "P31", 2, ipart=0)
self.assertRefPartsCount(entity, "P31", 3, ipart=1)
remove_part_mediawiki.update_entity_json(entity)
self.assertRefCount(entity, "P31", 1)
self.assertRefPartsCount(entity, "P31", 2, ipart=0)
with self.assertRaises(NoReferenceParts):
# try to remove it again
remove_part_mediawiki.update_entity_json(entity)
# -----
remove_42 = batch.commands()[2]
self.assertRefCount(entity, "P31", 1)
self.assertRefPartsCount(entity, "P31", 2, ipart=0)
remove_42.update_entity_json(entity)
self.assertRefCount(entity, "P31", 0)
# -----
remove_42_again = batch.commands()[3]
with self.assertRaises(NoReferenceParts):
# try to remove it again
remove_42_again.update_entity_json(entity)

def test_add_reference(self):
text = """
Q12345678|P31|somevalue|S93|"https://example.com/"
Expand Down
1 change: 1 addition & 0 deletions translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"batchcommand-py-operation-remove-statement-by-value": "Remove statement by value",
"batchcommand-py-operation-remove-qualifier": "Remove qualifier",
"batchcommand-py-operation-remove-reference": "Remove reference",
"batchcommand-py-operation-remove-reference-block": "Remove reference block",
"batchcommand-py-operation-set-sitelink": "Set sitelink",
"batchcommand-py-operation-set-label": "Set label",
"batchcommand-py-operation-set-description": "Set description",
Expand Down
1 change: 1 addition & 0 deletions translations/pt-br.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"batchcommand-py-operation-remove-statement-by-value": "Remover declaração por valor",
"batchcommand-py-operation-remove-qualifier": "Remover qualificador",
"batchcommand-py-operation-remove-reference": "Remover referência",
"batchcommand-py-operation-remove-reference-block": "Remover bloco de referência",
"batchcommand-py-operation-set-sitelink": "Definir hiperligação de site",
"batchcommand-py-operation-set-label": "Definir rótulo",
"batchcommand-py-operation-set-description": "Definir descrição",
Expand Down
1 change: 1 addition & 0 deletions translations/qqq.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"batchcommand-py-operation-remove-statement-by-value": "Individual command operation type displayed in command list",
"batchcommand-py-operation-remove-qualifier": "Individual command operation type displayed in command list",
"batchcommand-py-operation-remove-reference": "Individual command operation type displayed in command list",
"batchcommand-py-operation-remove-reference-block": "Individual command operation type displayed in command list",
"batchcommand-py-operation-set-sitelink": "Individual command operation type displayed in command list",
"batchcommand-py-operation-set-label": "Individual command operation type displayed in command list",
"batchcommand-py-operation-set-description": "Individual command operation type displayed in command list",
Expand Down
Loading