Skip to content

Commit

Permalink
#62 true support for Facets in List predicates
Browse files Browse the repository at this point in the history
  • Loading branch information
mrwunderbar666 committed Jun 15, 2024
1 parent ce0768b commit 594794e
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 17 deletions.
7 changes: 1 addition & 6 deletions meteor/api/sanitizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,12 +229,7 @@ def _preprocess_facets(self):
self.facets[predicate].update({facet: self.data[key]})
else:
self.facets[predicate] = {facet: self.data[key]}

# for list predicates, we track facets via the value
if '@' in key:
val, facet = key.split('@')
self.facets[val] = {facet: self.data[key]}


def _postprocess_list_facets(self):
for ll in self.entry.values():
if isinstance(ll, list):
Expand Down
69 changes: 65 additions & 4 deletions meteor/flaskdgraph/dgraph_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -455,12 +455,28 @@ def validate(self, data, facets: dict=None, **kwargs):
# preferably this method should return a Scalar object

if not self.overwrite and data is None:
raise InventoryValidationError(f"Tried to delete predicate <{self.label}> by supplying null value.")
raise InventoryValidationError(f"Tried to delete predicate <{self.predicate}> by supplying null value.")

data = self.validation_hook(data)

if isinstance(data, (list, set, tuple)):
return [Scalar(item, facets=facets) if isinstance(item, (str, int, datetime.datetime, datetime.date)) else item for item in data]
_data = []
for item in data:
if isinstance(item, (str, int, datetime.datetime, datetime.date)):
_data.append(Scalar(item))
else:
_data.append(item)

if facets:
assert isinstance(facets, dict), InventoryValidationError(f"Error in <{self.predicate}>: Facets provided in wrong format!")
for key, val in facets.items():
assert isinstance(val, dict), InventoryValidationError(f"Error in <{self.predicate}>: Facets provided in wrong format!")
for counter, subval in val.items():
_data[int(counter)].update_facets({key: subval})

return _data

# return [Scalar(item, facets=facets) if isinstance(item, (str, int, datetime.datetime, datetime.date)) else item for item in data]
elif isinstance(data, (str, int, datetime.datetime, datetime.date)):
return Scalar(data, facets=facets)
else:
Expand Down Expand Up @@ -1609,6 +1625,51 @@ def openapi_component(self) -> dict:
o['description'] = self.description
return o


class ListDatetime(DateTime):

dgraph_predicate_type = "[datetime]"
_type = list

def validation_hook(self, data):
if data is None:
return None
if isinstance(data, (list, tuple, set)):
_data = []
for val in data:
try:
_data.append(dateparser.parse(val))
except:
raise InventoryValidationError(
f'Error in <{self.predicate}> Cannot parse provided value to date: {data}')
return _data
if isinstance(data, (datetime.date, datetime.datetime)):
return data
elif isinstance(data, int):
try:
return datetime.date(year=data, month=1, day=1)
except:
pass
try:
return dateparser.parse(data)
except:
raise InventoryValidationError(
f'Error in <{self.predicate}> Cannot parse provided value to date: {data}')


@property
def openapi_component(self) -> dict:
o = {'type': "array",
'items': {
'type': 'string',
'format': "date-time"
}
}
if self.description:
o['description'] = self.description
return o


class Year(DateTime):

dgraph_predicate_type = 'datetime'
Expand All @@ -1622,7 +1683,7 @@ def validation_hook(self, data):
return datetime.datetime(year=int(data), month=1, day=1)
except:
raise InventoryValidationError(
f'Cannot parse provided value to year: {data}')
f'Error in <{self.predicate}>: Cannot parse provided value to year: {data}')

@property
def wtf_field(self) -> IntegerField:
Expand Down Expand Up @@ -1694,7 +1755,7 @@ def validation_hook(self, data):
return data > 0
else:
raise InventoryValidationError(
f'Cannot evaluate provided value as bool: {data}!')
f'Error in <{self.predicate}>: Cannot evaluate provided value as bool: {data}!')

def query_filter(self, vals, **kwargs) -> str:
if isinstance(vals, list):
Expand Down
3 changes: 1 addition & 2 deletions meteor/main/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -553,8 +553,7 @@ class NewsSource(Entry):
queryable=True,
)

audience_size = ListYear(
edit=False,
audience_size = ListDatetime(
facets=[
Facet(
"unit",
Expand Down
20 changes: 15 additions & 5 deletions tests/test_api_sanitizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,11 @@ def test_new_entry(self):
def test_list_facets(self):
mock_data = {
'name': 'Test',
'alternate_names': 'Jay Jay,Jules,JB',
'Jay Jay@kind': 'first',
'Jules@kind': 'official',
'JB@kind': 'CS-GO'
'alternate_names': ['Jay Jay' , 'Jules', 'JB'],
'alternate_names|kind': {"0": 'first',
"1": 'official',
"2": "CS-GO"
}
}

with self.app.app_context():
Expand Down Expand Up @@ -298,7 +299,16 @@ def test_draft_source(self):
'contains_ads': 'non subscribers',
'publishes_org': self.derstandard_mbh_uid,
'related_news_sources': [self.falter_print_uid],
'entry_review_status': 'pending'}
'entry_review_status': 'pending',
'audience_size': ["2024-06-15T21:20:13",
"2023-05-14",
"2022-04"],
'audience_size|unit': {"0": "subscribers",
"1": "subscribers",
"2": "subscribers"},
'audience_size|count': {"0": 100,
"1": 200,
"2": 300}}

with self.app.app_context():
# test if random user can edit
Expand Down

0 comments on commit 594794e

Please sign in to comment.