Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix 387,313 #400

Merged
merged 26 commits into from Jun 12, 2023
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Expand Up @@ -15,6 +15,8 @@ This changelog was started for release 4.2.0.
- These enable 'anonymous query' mode, allowing anonymous users to send 'full queries'. See documentation
- Added 'overview' button in the query page. This button will show all 'selected' attributes, and allow users to quickly select the related entity.
- Added 'Abstraction' tab on the navbar. This will print the whole abstraction as a 2d/3d graph.
- Added 'distance' notion, using attribute link. This allows user to filter a value based on another value, with an optional modifier.
- Added 'custom distance' option for faldo relation (instead of just 'included_in' and 'overlap_with')

### Fixed

Expand All @@ -23,6 +25,7 @@ This changelog was started for release 4.2.0.
- Fixed profile update & password reset tab in user profile page
- Fixed Gff Faldo integration (was only integrating the last selected entity)
- Fixed an issue when using filters and an 'UNION' node
- Fixed an issue when launching a query with a 'linked' attribute toggled but unselected

### Changed

Expand Down
74 changes: 60 additions & 14 deletions askomics/libaskomics/SparqlQuery.py
Expand Up @@ -1116,7 +1116,7 @@ def build_query_from_json(self, preview=False, for_editor=False):
pblock_ids = link["source"]["specialPreviousIds"]

# Position
if link["uri"] in ('included_in', 'overlap_with'):
if link["uri"] in ('included_in', 'overlap_with', 'distance_from'):

# If source of target is a special node, replace the id with the id of the concerned node
source_id = link["source"]["id"]
Expand Down Expand Up @@ -1192,6 +1192,16 @@ def build_query_from_json(self, preview=False, for_editor=False):
end2=end_2,
equalsign=equal_sign
), block_id, sblock_id, pblock_ids)
else:
for filter in link.get('faldoFilters', []):
modifier_string = ""
if filter['filterValue']:
modifier_string = " {} {}".format(filter['filterModifier'], filter['filterValue'])

start = start_1 if filter['filterStart'] == "start" else end_1
end = start_2 if filter['filterEnd'] == "start" else end_2
filter_string = "FILTER ( {} {} {} {} ) .".format(start, filter['filterSign'], end, modifier_string)
self.store_filter(filter_string, block_id, sblock_id, pblock_ids)

# Classic relation
else:
Expand Down Expand Up @@ -1225,7 +1235,7 @@ def build_query_from_json(self, preview=False, for_editor=False):
"entity_label": attribute["entityLabel"],
"entity_id": attribute["nodeId"]
}
if attribute["linked"]:
if attribute["linked"] and attribute["linkedWith"]:
linked_attributes.extend((attribute["id"], attribute["linkedWith"]))

# Browse attributes
Expand Down Expand Up @@ -1269,7 +1279,7 @@ def build_query_from_json(self, preview=False, for_editor=False):
else:
self.store_value("VALUES {} {{ {} }} .".format(subject, filter_value), block_id, sblock_id, pblock_ids)

if attribute["linked"]:
if attribute["linked"] and attribute["linkedWith"]:
var_2 = self.format_sparql_variable("{}{}_uri".format(
attributes[attribute["linkedWith"]]["entity_label"],
attributes[attribute["linkedWith"]]["entity_id"]
Expand Down Expand Up @@ -1305,13 +1315,17 @@ def build_query_from_json(self, preview=False, for_editor=False):

if uri_val_list:
self.store_value("VALUES {} {{ {} }}".format(value_var, ' '.join(uri_val_list)), block_id, sblock_id, pblock_ids)
if attribute["linked"]:
if attribute["linked"] and attribute["linkedWith"]:
var_2 = self.format_sparql_variable("{}{}_{}".format(
attributes[attribute["linkedWith"]]["entity_label"],
attributes[attribute["linkedWith"]]["entity_id"],
attributes[attribute["linkedWith"]]["label"]
))
var_to_replace.append((obj, var_2))
if not attribute.get('linkedNegative', False):
var_to_replace.append((obj, var_2))
else:
filter_string = "FILTER ( {} {} {} ) .".format(obj, "!=", var_2)
self.store_filter(filter_string, block_id, sblock_id, pblock_ids)

# Text
if attribute["type"] == "text":
Expand Down Expand Up @@ -1346,13 +1360,21 @@ def build_query_from_json(self, preview=False, for_editor=False):
self.store_filter("FILTER (str({}) != '{}') .".format(obj, attribute["filterValue"]), block_id, sblock_id, pblock_ids)
else:
self.store_value("VALUES {} {{ '{}' }} .".format(obj, attribute["filterValue"]), block_id, sblock_id, pblock_ids)
if attribute["linked"]:
if attribute["linked"] and attribute["linkedWith"]:
var_2 = self.format_sparql_variable("{}{}_{}".format(
attributes[attribute["linkedWith"]]["entity_label"],
attributes[attribute["linkedWith"]]["entity_id"],
attributes[attribute["linkedWith"]]["label"]
))
var_to_replace.append((obj, var_2))
if not (attribute.get('linkedNegative', False) or attribute.get('linkedFilterValue')):
var_to_replace.append((obj, var_2))
else:
filter = "!" if attribute.get('linkedNegative', False) else ""
regex_clause = "{} = {}".format(obj, var_2)
if attribute.get('linkedFilterValue'):
regex_clause = r"REGEX({}, REPLACE('{}', '\\$1', {}), 'i')".format(obj, attribute.get('linkedFilterValue', "$1"), var_2)
filter_string = "FILTER ( {} {} ) .".format(filter, regex_clause)
self.store_filter(filter_string, block_id, sblock_id, pblock_ids)

# Numeric
if attribute["type"] == "decimal":
Expand All @@ -1379,13 +1401,21 @@ def build_query_from_json(self, preview=False, for_editor=False):
else:
filter_string = "FILTER ( {} {} {} ) .".format(obj, filtr["filterSign"], filtr["filterValue"])
self.store_filter(filter_string, block_id, sblock_id, pblock_ids)
if attribute["linked"]:
if attribute["linked"] and attribute["linkedWith"]:
var_2 = self.format_sparql_variable("{}{}_{}".format(
attributes[attribute["linkedWith"]]["entity_label"],
attributes[attribute["linkedWith"]]["entity_id"],
attributes[attribute["linkedWith"]]["label"]
))
var_to_replace.append((obj, var_2))
if any([filter['filterSign'] == "=" and not filter['filterValue'] for filter in attribute.get('linkedFilters', [])]):
var_to_replace.append((obj, var_2))
else:
for filter in attribute.get('linkedFilters', []):
modifier_string = ""
if filter['filterValue']:
modifier_string = " {} {}".format(filter['filterModifier'], filter['filterValue'])
filter_string = "FILTER ( {} {} {} {} ) .".format(obj, filter['filterSign'], var_2, modifier_string)
self.store_filter(filter_string, block_id, sblock_id, pblock_ids)

if attribute["type"] == "date":
if attribute["visible"] or Utils.check_key_in_list_of_dict(attribute["filters"], "filterValue") or attribute["id"] in linked_attributes:
Expand All @@ -1410,14 +1440,25 @@ def build_query_from_json(self, preview=False, for_editor=False):
else:
filter_string = "FILTER ( {} {} '{}'^^xsd:date ) .".format(obj, filtr["filterSign"], val)
self.store_filter(filter_string, block_id, sblock_id, pblock_ids)
if attribute["linked"]:
if attribute["linked"] and attribute["linkedWith"]:
var_2 = self.format_sparql_variable("{}{}_{}".format(
attributes[attribute["linkedWith"]]["entity_label"],
attributes[attribute["linkedWith"]]["entity_id"],
attributes[attribute["linkedWith"]]["label"]
))
var_to_replace.append((obj, var_2))

if any([filter['filterSign'] == "=" and not filter['filterValue'] for filter in attribute.get('linkedFilters', [])]):
var_to_replace.append((obj, var_2))
else:
for filter in attribute.get('linkedFilters', []):
modifier_string = ""
if filter['filterValue']:
# Issue with virtuoso: engine-specific syntax for now (convert days to seconds)
if self.settings.get('triplestore', 'triplestore') == "virtuoso":
modifier_string = " {} {}".format(filter['filterModifier'], 24 * 3600 * int(filter['filterValue']))
else:
modifier_string = ' {} "P{}D"xsd:duration'.format(filter['filterModifier'], filter['filterValue'])
filter_string = "FILTER ( {} {} {} {} ) .".format(obj, filter['filterSign'], var_2, modifier_string)
self.store_filter(filter_string, block_id, sblock_id, pblock_ids)
# Category
if attribute["type"] == "category":
if attribute["visible"] or attribute["filterSelectedValues"] != [] or attribute["id"] in strands or attribute["id"] in linked_attributes:
Expand Down Expand Up @@ -1499,13 +1540,18 @@ def build_query_from_json(self, preview=False, for_editor=False):
else:
self.store_value("VALUES {} {{ {} }}".format(value_var, ' '.join(uri_val_list)), block_id, sblock_id, pblock_ids)

if attribute["linked"]:
if attribute["linked"] and attribute["linkedWith"]:
var_2 = self.format_sparql_variable("{}{}_{}Category".format(
attributes[attribute["linkedWith"]]["entity_label"],
attributes[attribute["linkedWith"]]["entity_id"],
attributes[attribute["linkedWith"]]["label"]
))
var_to_replace.append((category_value_uri, var_2))

if not attribute.get('linkedNegative', False):
var_to_replace.append((category_value_uri, var_2))
else:
filter_string = "FILTER ( {} {} {} ) .".format(category_value_uri, "!=", var_2)
self.store_filter(filter_string, block_id, sblock_id, pblock_ids)

from_string = "" if self.settings.getboolean("askomics", "single_tenant", fallback=False) else self.get_froms_from_graphs(self.graphs)
federated_from_string = self.get_federated_froms_from_graphs(self.graphs)
Expand Down
4 changes: 3 additions & 1 deletion askomics/react/src/navbar.jsx
Expand Up @@ -44,6 +44,7 @@ export default class AskoNavbar extends Component {

links = (
<>
{overviewLink}
{contactLink}
<NavItem><Link className="nav-link" to="/about"><i className="fas fa-info"></i> About</Link></NavItem>
<NavItem><Link className="nav-link" to="/login"><i className="fas fa-sign-in-alt"></i> Login</Link></NavItem>
Expand Down Expand Up @@ -75,6 +76,7 @@ export default class AskoNavbar extends Component {
<>
<NavItem><Link className="nav-link" to="/results"><i className="fas fa-tasks"></i> Results</Link></NavItem>
{integrationLinks}
{overviewLink}
{contactLink}
<NavItem><Link className="nav-link" to="/about"><i className="fas fa-info"></i> About</Link></NavItem>
<NavItem>
Expand All @@ -100,6 +102,7 @@ export default class AskoNavbar extends Component {
links = (
<>
<NavItem><Link className="nav-link" to="/results"><i className="fas fa-tasks"></i> Results</Link></NavItem>
{overviewLink}
{contactLink}
<NavItem><Link className="nav-link" to="/about"><i className="fas fa-info"></i> About</Link></NavItem>
<NavItem><Link className="nav-link" to="/login"><i className="fas fa-sign-in-alt"></i> Login</Link></NavItem>
Expand All @@ -116,7 +119,6 @@ export default class AskoNavbar extends Component {
<Collapse navbar>
<Nav className="ml-auto" navbar>
{askLink}
{overviewLink}
{links}
</Nav>
</Collapse>
Expand Down