Skip to content

Commit

Permalink
Split model classes in its own file
Browse files Browse the repository at this point in the history
  • Loading branch information
LeMyst committed Jul 27, 2022
1 parent 9bc5882 commit 07a031d
Show file tree
Hide file tree
Showing 30 changed files with 700 additions and 651 deletions.
2 changes: 1 addition & 1 deletion test/test_wbi_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
Sense, String, TabularData, Time)
from wikibaseintegrator.datatypes.extra import EDTF, LocalMedia
from wikibaseintegrator.entities import ItemEntity
from wikibaseintegrator.models import Descriptions
from wikibaseintegrator.models.descriptions import Descriptions
from wikibaseintegrator.wbi_config import config as wbi_config
from wikibaseintegrator.wbi_enums import ActionIfExists, WikibaseDatePrecision, WikibaseRank, WikibaseSnakType
from wikibaseintegrator.wbi_helpers import generate_entity_instances, search_entities
Expand Down
2 changes: 1 addition & 1 deletion wikibaseintegrator/datatypes/basedatatype.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import re
from typing import Any, List, Type, Union

from wikibaseintegrator.models import Claim
from wikibaseintegrator.models.claim import Claim


class BaseDataType(Claim):
Expand Down
2 changes: 1 addition & 1 deletion wikibaseintegrator/datatypes/globecoordinate.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from typing import Any

from wikibaseintegrator.datatypes.basedatatype import BaseDataType
from wikibaseintegrator.models import Claim
from wikibaseintegrator.models.claim import Claim
from wikibaseintegrator.wbi_config import config


Expand Down
3 changes: 2 additions & 1 deletion wikibaseintegrator/entities/baseentity.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@

from wikibaseintegrator import wbi_fastrun
from wikibaseintegrator.datatypes import BaseDataType
from wikibaseintegrator.models.claims import Claim, Claims
from wikibaseintegrator.models.claim import Claim
from wikibaseintegrator.models.claims import Claims
from wikibaseintegrator.wbi_enums import ActionIfExists
from wikibaseintegrator.wbi_exceptions import MissingEntityException, ModificationFailed, MWApiError
from wikibaseintegrator.wbi_helpers import delete_page, mediawiki_api_call_helper
Expand Down
2 changes: 1 addition & 1 deletion wikibaseintegrator/entities/item.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
from typing import Any, Dict, Union

from wikibaseintegrator.entities.baseentity import BaseEntity
from wikibaseintegrator.models import LanguageValues
from wikibaseintegrator.models.aliases import Aliases
from wikibaseintegrator.models.descriptions import Descriptions
from wikibaseintegrator.models.labels import Labels
from wikibaseintegrator.models.language_values import LanguageValues
from wikibaseintegrator.models.sitelinks import Sitelinks


Expand Down
3 changes: 2 additions & 1 deletion wikibaseintegrator/entities/mediainfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@
from typing import Any, Dict, List, Union

from wikibaseintegrator.entities.baseentity import BaseEntity
from wikibaseintegrator.models import Claims, LanguageValues
from wikibaseintegrator.models.aliases import Aliases
from wikibaseintegrator.models.claims import Claims
from wikibaseintegrator.models.descriptions import Descriptions
from wikibaseintegrator.models.labels import Labels
from wikibaseintegrator.models.language_values import LanguageValues
from wikibaseintegrator.wbi_helpers import mediawiki_api_call_helper


Expand Down
13 changes: 0 additions & 13 deletions wikibaseintegrator/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,13 +0,0 @@
from .aliases import Alias, Aliases
from .basemodel import BaseModel
from .claims import Claim, Claims
from .descriptions import Descriptions
from .forms import Form, Forms
from .labels import Labels
from .language_values import LanguageValue, LanguageValues
from .lemmas import Lemmas
from .qualifiers import Qualifiers
from .references import Reference, References
from .senses import Glosses, Sense, Senses
from .sitelinks import Sitelink, Sitelinks
from .snaks import Snak, Snaks
5 changes: 5 additions & 0 deletions wikibaseintegrator/models/alias.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import wikibaseintegrator.models.language_value as language_value


class Alias(language_value.LanguageValue):
pass
6 changes: 1 addition & 5 deletions wikibaseintegrator/models/aliases.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

from typing import Dict, List, Optional, Union

from wikibaseintegrator.models.alias import Alias
from wikibaseintegrator.models.basemodel import BaseModel
from wikibaseintegrator.models.language_values import LanguageValue
from wikibaseintegrator.wbi_config import config
from wikibaseintegrator.wbi_enums import ActionIfExists

Expand Down Expand Up @@ -91,7 +91,3 @@ def from_json(self, json_data: Dict[str, List]) -> Aliases:
# def __contains__(self, item):
# all_aliases = [item for sublist in list(self.aliases.values()) for item in sublist]
# return item in list(map(lambda x: x.value, all_aliases))


class Alias(LanguageValue):
pass
251 changes: 251 additions & 0 deletions wikibaseintegrator/models/claim.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
from __future__ import annotations

import copy
from typing import Any, Callable, Dict, List, Optional, Union

import wikibaseintegrator.models.basemodel
from wikibaseintegrator.models.qualifiers import Qualifiers
from wikibaseintegrator.models.reference import Reference
from wikibaseintegrator.models.references import References
from wikibaseintegrator.models.snak import Snak
from wikibaseintegrator.models.snaks import Snaks
from wikibaseintegrator.wbi_enums import WikibaseRank


class Claim(wikibaseintegrator.models.basemodel.BaseModel):
DTYPE = 'claim'

def __init__(self, qualifiers: Qualifiers = None, rank: WikibaseRank = None, references: Union[References, List[Union[Claim, List[Claim]]]] = None) -> None:
"""
:param qualifiers:
:param rank:
:param references: A References object, a list of Claim object or a list of list of Claim object
"""
self.mainsnak = Snak(datatype=self.DTYPE)
self.type = 'statement'
self.qualifiers = qualifiers or Qualifiers()
self.qualifiers_order = []
self.id = None
self.rank = rank or WikibaseRank.NORMAL
self.removed = False

self.references = References()

if isinstance(references, References):
self.references = references
elif isinstance(references, list):
for ref_list in references:
ref = Reference()
if isinstance(ref_list, list):
snaks = Snaks()
for ref_claim in ref_list:
if isinstance(ref_claim, Claim):
snaks.add(Snak().from_json(ref_claim.get_json()['mainsnak']))
else:
raise ValueError("The references must be a References object or a list of Claim object")
ref.snaks = snaks
elif isinstance(ref_list, Claim):
ref.snaks = Snaks().add(Snak().from_json(ref_list.get_json()['mainsnak']))
elif isinstance(ref_list, Reference):
ref = ref_list
self.references.add(reference=ref)
elif references is not None:
raise ValueError("The references must be a References object or a list of Claim object")

@property
def mainsnak(self) -> Snak:
return self.__mainsnak

@mainsnak.setter
def mainsnak(self, value: Snak):
self.__mainsnak = value

@property
def type(self) -> Union[str, Dict]:
return self.__type

@type.setter
def type(self, value: Union[str, Dict]):
self.__type = value

@property
def qualifiers(self) -> Qualifiers:
return self.__qualifiers

@qualifiers.setter
def qualifiers(self, value: Qualifiers) -> None:
assert isinstance(value, (Qualifiers, list))
self.__qualifiers: Qualifiers = Qualifiers().set(value) if isinstance(value, list) else value

@property
def qualifiers_order(self) -> List[str]:
return self.__qualifiers_order

@qualifiers_order.setter
def qualifiers_order(self, value: List[str]):
self.__qualifiers_order = value

@property
def id(self) -> Optional[str]:
return self.__id

@id.setter
def id(self, value: Optional[str]):
self.__id = value

@property
def rank(self) -> WikibaseRank:
return self.__rank

@rank.setter
def rank(self, value: WikibaseRank):
"""Parse the rank. The enum thows an error if it is not one of the recognized values"""
self.__rank = WikibaseRank(value)

@property
def references(self) -> References:
return self.__references

@references.setter
def references(self, value: References):
self.__references = value

@property
def removed(self) -> bool:
return self.__removed

@removed.setter
def removed(self, value: bool):
self.__removed = value

def remove(self, remove=True) -> None:
self.removed = remove

def update(self, claim: Claim) -> None:
self.mainsnak = claim.mainsnak
self.qualifiers = claim.qualifiers
self.qualifiers_order = claim.qualifiers_order
self.rank = claim.rank
self.references = claim.references

def from_json(self, json_data: Dict[str, Any]) -> Claim:
"""
:param json_data: a JSON representation of a Claim
"""
self.mainsnak = Snak().from_json(json_data['mainsnak'])
self.type = str(json_data['type'])
if 'qualifiers' in json_data:
self.qualifiers = Qualifiers().from_json(json_data['qualifiers'])
if 'qualifiers-order' in json_data:
self.qualifiers_order = list(json_data['qualifiers-order'])
self.id = str(json_data['id'])
self.rank: WikibaseRank = WikibaseRank(json_data['rank'])
if 'references' in json_data:
self.references = References().from_json(json_data['references'])

return self

def get_json(self) -> Dict[str, Any]:
json_data: Dict[str, Union[str, List[Dict], List[str], Dict[str, str], Dict[str, List], None]] = {
'mainsnak': self.mainsnak.get_json(),
'type': self.type,
'id': self.id,
'rank': self.rank.value
}
# Remove id if it's a temporary one
if not self.id:
del json_data['id']
if len(self.qualifiers) > 0:
json_data['qualifiers'] = self.qualifiers.get_json()
json_data['qualifiers-order'] = list(self.qualifiers_order)
if len(self.references) > 0:
json_data['references'] = self.references.get_json()
if self.removed:
if self.id:
json_data['remove'] = ''
return json_data

def has_equal_qualifiers(self, other: Claim) -> bool:
# check if the qualifiers are equal with the 'other' object
self_qualifiers = copy.deepcopy(self.qualifiers)
other_qualifiers = copy.deepcopy(other.qualifiers)

if len(self_qualifiers) != len(other_qualifiers):
return False

for property_number in self_qualifiers.qualifiers:
if property_number not in other_qualifiers.qualifiers:
return False

if len(self_qualifiers.qualifiers[property_number]) != len(other_qualifiers.qualifiers[property_number]):
return False

flg = [False for _ in range(len(self_qualifiers.qualifiers[property_number]))]
for count, i in enumerate(self_qualifiers.qualifiers[property_number]):
for q in other_qualifiers:
if i == q:
flg[count] = True
if not all(flg):
return False

return True

# TODO: rewrite this?
def __contains__(self, item):
if isinstance(item, Claim):
return self == item

if isinstance(item, str):
return self.mainsnak.datavalue == item

return super().__contains__(item)

def __eq__(self, other):
if isinstance(other, Claim):
return self.mainsnak.datavalue == other.mainsnak.datavalue and self.mainsnak.property_number == other.mainsnak.property_number and self.has_equal_qualifiers(other)

if isinstance(other, str):
return self.mainsnak.property_number == other

raise super().__eq__(other)

def equals(self, that: Claim, include_ref: bool = False, fref: Callable = None) -> bool:
"""
Tests for equality of two statements.
If comparing references, the order of the arguments matters!!!
self is the current statement, the next argument is the new statement.
Allows passing in a function to use to compare the references 'fref'. Default is equality.
fref accepts two arguments 'oldrefs' and 'newrefs', each of which are a list of references,
where each reference is a list of statements
"""

if not include_ref:
# return the result of BaseDataType.__eq__, which is testing for equality of value and qualifiers
return self == that

if self != that:
return False

if fref is None:
return Claim.refs_equal(self, that)

return fref(self, that)

@staticmethod
def refs_equal(olditem: Claim, newitem: Claim) -> bool:
"""
tests for exactly identical references
"""

oldrefs = olditem.references
newrefs = newitem.references

def ref_equal(oldref: References, newref: References) -> bool:
return (len(oldref) == len(newref)) and all(x in oldref for x in newref)

return len(oldrefs) == len(newrefs) and all(any(ref_equal(oldref, newref) for oldref in oldrefs) for newref in newrefs)

def get_sparql_value(self) -> str:
pass
Loading

0 comments on commit 07a031d

Please sign in to comment.