Skip to content
Open
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
59 changes: 59 additions & 0 deletions application/bsdd_utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
import database
import json
import functools
import collections

from collections import defaultdict
from urllib.parse import urlparse

import ifcopenshell
import ifcopenshell.template

import checks.check_bsdd_v2

def get_hierarchical_bsdd(id):
with database.Session() as session:
Expand Down Expand Up @@ -42,4 +51,54 @@ def get_inst(instance_id):

return hierarchical_bsdd_results

def get_processed_bsdd_table(bsdd_results, session, schema):
"""
The function returns data for the 'bsdd data' table in a file metrics report.
More specifically,it returns a list of dictionaries containing the classifications (ifc instances, in this case)
and their valid/invalid counts.
"""
bsdd_instances = [bsdd_table(result, session, schema) for result in bsdd_results]
bsdd_data = defaultdict(lambda: {'valid': 0, 'invalid': 0, 'domain_source': 'classification not found'})

for item in bsdd_instances:
classification = item['classification']
validity = item['validity']
bsdd_data[classification][validity] += 1

bsdd_data = [{**{'classification': k}, **v} for k, v in bsdd_data.items()]
return bsdd_data

def bsdd_table(bsdd_result, session, schema):
inst = get_inst(session, bsdd_result['instance_id'])
observed_type = inst.ifc_type
domain_source = bsdd_result['bsdd_classification_uri']

if all(bsdd_result[key] == 1 for key in ['val_ifc_type', 'val_property_set', 'val_property_name', 'val_property_type', 'val_property_value']):
validity = 'valid'
else:
validity = 'invalid'

return {'classification': observed_type, 'validity': validity, 'domain_source': domain_source}

def get_inst(session, instance_id):
return session.query(database.ifc_instance).filter(database.ifc_instance.id == instance_id).all()[0]

def get_classification_name(bsdd_results):
default = 'name not found'
names = list(filter(lambda x: x != default, [r['classification_name'] for r in bsdd_results]))
return {item: names.count(item) for item in names} if names else default


def domain_sources(bsdd_results):
uri = 'bsdd_classification_uri'
domain_sources = [
checks.check_bsdd_v2.get_domain(result[uri]).json()[0]['namespaceUri'] if result[uri] != 'classification not found'
else result[uri]
for result in bsdd_results
]
sources = [source for source in domain_sources if source != 'classification not found']
return collections.Counter(sources) if sources else 'classification not found'


def bsdd_report_quantity(bsdd_results, item):
return sum(bool(bsdd_result.get(item)) for bsdd_result in bsdd_results)
27 changes: 27 additions & 0 deletions application/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import os
import json
import ast
import sys

import threading
from functools import wraps
Expand All @@ -45,6 +46,8 @@
from requests_oauthlib import OAuth2Session
from authlib.jose import jwt

sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), 'checks')))

import utils
import bsdd_utils
import database
Expand Down Expand Up @@ -794,6 +797,30 @@ def get_model(fn):
return response
else:
return send_file(path)

@application.route('/api/bsdd_statistics/<id>', methods=['GET'])
@login_required
def preprocess_bsdd(user_data, id):
with database.Session() as session:
model = session.query(database.model).filter(
database.model.code == id).first()
if model.user_id != user_data["sub"]:
abort(403)
bsdd_task = [task for task in model.tasks if task.task_type == "bsdd_validation_task"][0]
bsdd_results = [result.serialize() for result in bsdd_task.results]

if model.status_bsdd != 'n':
preprocessed_bsdd_data = {
'bSDD classification found': {
'name' : bsdd_utils.get_classification_name(bsdd_results),
'classification_count' : bsdd_utils.bsdd_report_quantity(bsdd_results, 'classification_code'),
'properties_count': bsdd_utils.bsdd_report_quantity(bsdd_results, 'ifc_property_set'),
'domain_source' : bsdd_utils.domain_sources(bsdd_results)
},
'bSDD data': bsdd_utils.get_processed_bsdd_table(bsdd_results, session, model.schema)
}

return jsonify(preprocessed_bsdd_data)

"""
# Create a file called routes.py with the following
Expand Down