Skip to content

Commit

Permalink
bug fix: non-code values for item/value were breaking
Browse files Browse the repository at this point in the history
bug fix: code values for non item/value properties were not being parsed
  • Loading branch information
devowit committed May 10, 2020
1 parent c1bb209 commit db6dd41
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 64 deletions.
119 changes: 71 additions & 48 deletions backend_code/handler.py
Original file line number Diff line number Diff line change
@@ -1,32 +1,44 @@
import json
import warnings
from types import CodeType

from etk.wikidata.utils import parse_datetime_string
from SPARQLWrapper.SPARQLExceptions import QueryBadFormed

import backend_code.t2wml_exceptions as T2WMLExceptions
from backend_code.parsing.classes import ReturnClass
from backend_code.parsing.constants import char_dict
from backend_code.parsing.t2wml_parser import iter_on_n_for_code
from backend_code.spreadsheets.conversions import to_excel
from backend_code.t2wml_exceptions import T2WMLException
import backend_code.t2wml_exceptions as T2WMLExceptions
from backend_code.triple_generator import generate_triples
from backend_code.utility_functions import translate_precision_to_integer
from backend_code.wikidata_property import get_property_type
from backend_code.spreadsheets.conversions import to_excel
from backend_code.parsing.t2wml_parser import iter_on_n
from backend_code.triple_generator import generate_triples


def parse_time_for_dict(response, sparql_endpoint):
if "property" in response and get_property_type(response["property"], sparql_endpoint)=="Time":
if "format" in response:
with warnings.catch_warnings(record=True) as w: #use this line to make etk stop harassing us with "no lang features detected" warnings
try:
datetime_string, precision = parse_datetime_string(str(response["value"]),
additional_formats=[
response["format"]])
except ValueError:
#This is a workaround for a separatte bug, WIP, that is sending the wrong dictionaries to this function
print("attempting to parse datetime string that isn't a datetime:", str(response["value"]))
return
if "precision" not in response:
response["precision"] = int(precision.value.__str__())
else:
response["precision"] = translate_precision_to_integer(response["precision"])
response["value"] = datetime_string

if "property" in response:
try:
prop_type= get_property_type(response["property"], sparql_endpoint)
except QueryBadFormed:
raise ValueError("The value given for property is not a valid property:" +str(response["property"]))

if prop_type=="Time":
if "format" in response:
with warnings.catch_warnings(record=True) as w: #use this line to make etk stop harassing us with "no lang features detected" warnings
try:
datetime_string, precision = parse_datetime_string(str(response["value"]),
additional_formats=[
response["format"]])
except ValueError:
raise ValueError("Attempting to parse datetime string that isn't a datetime:" + str(response["value"]))

if "precision" not in response:
response["precision"] = int(precision.value.__str__())
else:
response["precision"] = translate_precision_to_integer(response["precision"])
response["value"] = datetime_string

def resolve_cell(yaml_object, col, row, sparql_endpoint):
context={"row":int(row), "col":char_dict[col]}
Expand All @@ -51,20 +63,21 @@ def get_template_statement(template, item_parsed, value_parsed, qualifiers_parse
if value_parsed:
template["value"]=value_parsed.value
if qualifiers_parsed:
new_quals=[]
for q_i, qualifier_dict in enumerate(template["qualifier"]):
try:
new_dict=dict(qualifier_dict)
qualifier_parsed=qualifiers_parsed[q_i]
#check if item/value are not None
if qualifier_parsed: #TODO: maybe this check needs to be moved elsewhere, or maybe it should raise an error?
new_dict["value"]=qualifier_parsed.value
new_dict["cell"]=to_excel(qualifier_parsed.col, qualifier_parsed.row)
parse_time_for_dict(new_dict, sparql_endpoint)
new_quals.append(new_dict)
except Exception as e:
raise e
template["qualifier"]=new_quals
for qualifier_dict in qualifiers_parsed:
q_val=qualifier_dict.pop("value") #deal with value last
for key in qualifier_dict:
if isinstance(qualifier_dict[key], ReturnClass):
qualifier_dict[key]=qualifier_dict[key].value

qualifier_dict["value"]=q_val #return q_value, then deal with it
if q_val:
if isinstance(q_val, ReturnClass):
qualifier_dict["value"]=q_val.value
qualifier_dict["cell"]=to_excel(q_val.col, q_val.row)

parse_time_for_dict(qualifier_dict, sparql_endpoint)

template["qualifier"]=qualifiers_parsed
parse_time_for_dict(template, sparql_endpoint)
return template

Expand All @@ -76,29 +89,39 @@ def evaluate_template(template, context):

item_parsed=value_parsed=qualifiers_parsed=None

if item:
item_parsed= iter_on_n(item, context)
try:
if item:
item_parsed= iter_on_n_for_code(item, context)

if value:
value_parsed= iter_on_n(value, context)
if value:
value_parsed= iter_on_n_for_code(value, context)

if qualifiers:
qualifiers_parsed=[]
for qualifier in qualifiers:
new_qual=dict(qualifier)
for key in qualifier:
if isinstance(qualifier[key], CodeType):
q_parsed=iter_on_n_for_code(qualifier[key], context)
new_qual[key]=q_parsed
qualifiers_parsed.append(new_qual)
return item_parsed, value_parsed, qualifiers_parsed
except Exception as e:
print(e)
raise e

if qualifiers:
qualifiers_parsed=[]
for qualifier in qualifiers:
q_parsed=iter_on_n(qualifier, context)
qualifiers_parsed.append(q_parsed)

return item_parsed, value_parsed, qualifiers_parsed

def update_highlight_data(data, item_parsed, qualifiers_parsed):
if item_parsed:
item_cell=to_excel(item_parsed.col, item_parsed.row)
data["item"].add(item_cell)
if item_cell:
data["item"].add(item_cell)
if qualifiers_parsed:
qualifier_cells = set()
for qualifier_parsed in qualifiers_parsed:
#check if item/value are not None
if qualifier_parsed: #TODO: maybe this check needs to be moved elsewhere, or maybe it should raise an error?
for qualifier in qualifiers_parsed:
qualifier_parsed=qualifier.get("value", None)
if qualifier_parsed and isinstance(qualifier_parsed, ReturnClass):
qualifier_cell=to_excel(qualifier_parsed.col, qualifier_parsed.row)
if qualifier_cell:
qualifier_cells.add(qualifier_cell)
Expand Down
10 changes: 8 additions & 2 deletions backend_code/parsing/t2wml_parser.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from backend_code import t2wml_exceptions as T2WMLExceptions
from backend_code.bindings import bindings
from backend_code.parsing.classes import CellExpression, ItemExpression
from backend_code.parsing.classes import (CellExpression, ItemExpression,
ReturnClass)
from backend_code.parsing.constants import char_dict
from backend_code.parsing.functions import functions_dict

Expand Down Expand Up @@ -33,4 +34,9 @@ def iter_on_n(expression, context={}):
if return_value:
return return_value
except IndexError:
break
break

def iter_on_n_for_code(input, context={}):
if isinstance(input, str):
return ReturnClass(None, None, input)
return iter_on_n(input, context)
53 changes: 39 additions & 14 deletions backend_code/parsing/yaml_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,6 @@ def fix_code_string(self, e_str):
return e_str



def fix_yaml(self, yaml):
if isinstance(yaml, str):
return self.fix_code_string(yaml)
Expand All @@ -191,20 +190,46 @@ def create_eval_template(self, template):
item=template.get("item", None)
value=template.get("value", None)
qualifiers=template.get("qualifier", None)
fake_context=dict(row=0, col=0, n=0)

if item:
new_template["item"]=compile(item, "<string>", "eval")

if value:
new_template["value"]=compile(value, "<string>", "eval")

if qualifiers:
qualifiers_parsed=[]
for qualifier in qualifiers:
q_parsed=compile(qualifier["value"], "<string>", "eval")
qualifiers_parsed.append(q_parsed)
new_template["qualifier"]=qualifiers_parsed
return new_template
try:
if item and not str(item).isalnum():
try:
test=compile(item, "<string>", "eval")
parse_expression(test, fake_context)
new_template["item"]=test
except:
raise T2WMLExceptions.InvalidYAMLFileException("Invalid expression: "+str(item))


if value and not str(value).isalnum():
try:
test=compile(value, "<string>", "eval")
parse_expression(test, fake_context)
new_template["value"]=test
except:
raise T2WMLExceptions.InvalidYAMLFileException("Invalid expression: "+str(value))


if qualifiers:
qualifiers_parsed=[]
for qualifier in qualifiers:
new_dict=dict(qualifier)
for key in qualifier:
if not str(qualifier[key]).isalnum() and key!="format":
try:
test=compile(qualifier[key], "<string>", "eval")
parse_expression(test, fake_context)
new_dict[key]=test
except:
raise T2WMLExceptions.InvalidYAMLFileException("Invalid expression: "+str(qualifier[key]))

qualifiers_parsed.append(new_dict)
new_template["qualifier"]=qualifiers_parsed
return new_template
except Exception as e:
print(e)
raise e



Expand Down

0 comments on commit db6dd41

Please sign in to comment.