This repository has been archived on 2024-05-31. You can view files and clone it, but cannot push or open issues or pull requests.
devicehub-teal/ereuse_devicehub/modules/did/views.py

285 lines
8.1 KiB
Python
Raw Normal View History

2023-07-06 15:49:54 +00:00
import json
2023-07-17 15:13:55 +00:00
import logging
2023-07-06 15:49:54 +00:00
2023-05-31 14:30:49 +00:00
import flask
2023-07-05 09:54:58 +00:00
import requests
2023-05-31 14:30:49 +00:00
from ereuseapi.methods import API
from flask import Blueprint
from flask import current_app as app
2023-06-02 09:00:05 +00:00
from flask import g, render_template, request, session
2023-05-31 14:30:49 +00:00
from flask.json import jsonify
from flask.views import View
from ereuse_devicehub import __version__
2023-10-03 12:37:49 +00:00
from ereuse_devicehub.modules.dpp.models import Dpp, ALGORITHM
2023-05-31 14:30:49 +00:00
from ereuse_devicehub.resources.device.models import Device
2023-07-17 15:13:55 +00:00
logger = logging.getLogger(__name__)
did = Blueprint('did', __name__, url_prefix='/did', template_folder='templates')
2023-05-31 14:30:49 +00:00
class DidView(View):
methods = ['GET', 'POST']
2023-06-23 08:22:46 +00:00
template_name = 'anonymous.html'
2023-05-31 14:30:49 +00:00
def dispatch_request(self, id_dpp):
2023-06-02 09:00:05 +00:00
self.dpp = None
self.device = None
2023-05-31 14:30:49 +00:00
self.get_ids(id_dpp)
self.context = {
'version': __version__,
'oidc': 'oidc' in app.blueprints.keys(),
'user': g.user,
'path': request.path,
2023-06-02 09:00:05 +00:00
'last_dpp': None,
'before_dpp': None,
'rols': [],
'rol': None,
2023-05-31 14:30:49 +00:00
}
self.get_rols()
self.get_rol()
self.get_device()
2023-06-02 09:00:05 +00:00
self.get_last_dpp()
self.get_before_dpp()
2023-05-31 14:30:49 +00:00
2023-06-05 14:00:10 +00:00
if self.accept_json():
2023-05-31 14:30:49 +00:00
return jsonify(self.get_result())
2024-01-30 20:54:34 +00:00
self.get_manuals()
2023-06-23 08:22:46 +00:00
self.get_template()
2023-05-31 14:30:49 +00:00
return render_template(self.template_name, **self.context)
2023-06-23 08:22:46 +00:00
def get_template(self):
rol = self.context.get('rol')
if not rol:
return
tlmp = {
"isOperator": "operator.html",
"isVerifier": "verifier.html",
2023-12-12 19:40:11 +00:00
"operator": "operator.html",
"verifier": "verifier.html",
2023-06-23 08:22:46 +00:00
}
self.template_name = tlmp.get(rol, self.template_name)
2023-06-05 14:00:10 +00:00
def accept_json(self):
if 'json' in request.headers.get('Accept', []):
return True
if "application/json" in request.headers.get("Content-Type", []):
return True
return False
2023-05-31 14:30:49 +00:00
def get_ids(self, id_dpp):
self.id_dpp = None
self.chid = id_dpp
if len(id_dpp.split(":")) == 2:
self.id_dpp = id_dpp
self.chid = id_dpp.split(':')[0]
def get_rols(self):
rols = session.get('rols')
if not g.user.is_authenticated and not rols:
return []
if rols:
2023-06-02 09:00:05 +00:00
self.context['rols'] = rols
2023-05-31 14:30:49 +00:00
2023-06-02 09:42:38 +00:00
if 'dpp' not in app.blueprints.keys():
2023-05-31 14:30:49 +00:00
return []
if not session.get('token_dlt'):
return []
2024-01-29 17:49:02 +00:00
role = session.get('iota_abac_attributes', {}).get('role', '')
if not role:
2023-05-31 14:30:49 +00:00
return []
2024-01-29 17:49:02 +00:00
self.context['rols'] = [(x.strip(), x.strip()) for x in role.split(",")]
2023-05-31 14:30:49 +00:00
def get_rol(self):
rols = self.context.get('rols', [])
rol = len(rols) == 1 and rols[0][0] or None
if 'rol' in request.args and not rol:
rol = dict(rols).get(request.args.get('rol'))
self.context['rol'] = rol
def get_device(self):
if self.id_dpp:
self.dpp = Dpp.query.filter_by(key=self.id_dpp).one()
2023-06-02 09:00:05 +00:00
device = self.dpp.device
else:
device = Device.query.filter_by(chid=self.chid, active=True).first()
2023-05-31 14:30:49 +00:00
if not device:
return flask.abort(404)
2023-06-02 09:00:05 +00:00
2023-05-31 14:30:49 +00:00
placeholder = device.binding or device.placeholder
device_abstract = placeholder and placeholder.binding or device
device_real = placeholder and placeholder.device or device
self.device = device_abstract
2023-06-02 09:00:05 +00:00
components = self.device.components
if self.dpp:
components = self.dpp.snapshot.components
2023-05-31 14:30:49 +00:00
self.context.update(
{
'placeholder': placeholder,
'device': self.device,
'device_abstract': device_abstract,
'device_real': device_real,
2023-06-02 09:00:05 +00:00
'components': components,
2023-05-31 14:30:49 +00:00
}
)
2023-06-02 09:00:05 +00:00
def get_last_dpp(self):
dpps = sorted(self.device.dpps, key=lambda x: x.created)
self.context['last_dpp'] = dpps and dpps[-1] or ''
return self.context['last_dpp']
def get_before_dpp(self):
if not self.dpp:
self.context['before_dpp'] = ''
return ''
dpps = sorted(self.device.dpps, key=lambda x: x.created)
before_dpp = ''
for dpp in dpps:
if dpp == self.dpp:
break
before_dpp = dpp
2023-05-31 14:30:49 +00:00
2023-06-02 09:00:05 +00:00
self.context['before_dpp'] = before_dpp
return before_dpp
2023-05-31 14:30:49 +00:00
def get_result(self):
2023-07-11 14:39:04 +00:00
components = []
2023-05-31 14:30:49 +00:00
data = {
2023-07-06 10:54:18 +00:00
'document': {},
2023-05-31 14:30:49 +00:00
'dpp': self.id_dpp,
2023-10-03 12:37:49 +00:00
'algorithm': ALGORITHM,
2023-07-11 14:39:04 +00:00
'components': components,
2023-09-26 15:32:42 +00:00
'manufacturer DPP': '',
2023-05-31 14:30:49 +00:00
}
2023-09-18 14:20:55 +00:00
result = {
'@context': ['https://ereuse.org/dpp0.json'],
'data': data,
}
2023-05-31 14:30:49 +00:00
if self.dpp:
2023-07-06 10:54:18 +00:00
data['document'] = self.dpp.snapshot.json_hw
2023-06-02 09:00:05 +00:00
last_dpp = self.get_last_dpp()
2023-05-31 14:30:49 +00:00
url_last = ''
if last_dpp:
2023-06-05 14:00:10 +00:00
url_last = 'https://{host}/{did}'.format(
2023-06-05 14:03:35 +00:00
did=last_dpp.key, host=app.config.get('HOST')
2023-06-05 14:00:10 +00:00
)
2023-05-31 14:30:49 +00:00
data['url_last'] = url_last
2023-07-11 14:39:04 +00:00
for c in self.dpp.snapshot.components:
components.append({c.type: c.chid})
2023-05-31 14:30:49 +00:00
return result
dpps = []
for d in self.device.dpps:
2023-07-06 10:54:18 +00:00
rr = {
'dpp': d.key,
'document': d.snapshot.json_hw,
2023-10-03 12:37:49 +00:00
'algorithm': ALGORITHM,
2023-09-26 15:32:42 +00:00
'manufacturer DPP': '',
2023-07-06 10:54:18 +00:00
}
2023-05-31 14:30:49 +00:00
dpps.append(rr)
2023-09-18 14:35:30 +00:00
return {
'@context': ['https://ereuse.org/dpp0.json'],
'data': dpps,
}
2023-05-31 14:30:49 +00:00
2023-07-05 09:54:58 +00:00
def get_manuals(self):
2023-07-17 15:13:55 +00:00
manuals = {
'ifixit': [],
'icecat': [],
'details': {},
'laer': [],
2023-08-10 14:43:45 +00:00
'energystar': {},
2023-07-06 09:39:37 +00:00
}
2023-07-17 15:13:55 +00:00
try:
params = {
"manufacturer": self.device.manufacturer,
"model": self.device.model,
}
self.params = json.dumps(params)
manuals['ifixit'] = self.request_manuals('ifixit')
manuals['icecat'] = self.request_manuals('icecat')
manuals['laer'] = self.request_manuals('laer')
2023-08-10 14:43:45 +00:00
manuals['energystar'] = self.request_manuals('energystar') or {}
2023-07-17 15:13:55 +00:00
if manuals['icecat']:
manuals['details'] = manuals['icecat'][0]
except Exception as err:
logger.error("Error: {}".format(err))
2023-07-06 09:39:37 +00:00
self.context['manuals'] = manuals
2023-08-10 14:43:45 +00:00
self.parse_energystar()
def parse_energystar(self):
if not self.context.get('manuals', {}).get('energystar'):
return
# Defined in:
# https://dev.socrata.com/foundry/data.energystar.gov/j7nq-iepp
energy_types = [
'functional_adder_allowances_kwh',
'tec_allowance_kwh',
'long_idle_watts',
'short_idle_watts',
'off_mode_watts',
'sleep_mode_watts',
'tec_of_model_kwh',
'tec_requirement_kwh',
'work_off_mode_watts',
'work_weighted_power_of_model_watts',
]
energy = {}
for field in energy_types:
energy[field] = []
for e in self.context['manuals']['energystar']:
for field in energy_types:
for k, v in e.items():
if not v:
continue
if field in k:
energy[field].append(v)
for k, v in energy.items():
if not v:
energy[k] = 0
continue
tt = sum([float(i) for i in v])
energy[k] = round(tt / len(v), 2)
self.context['manuals']['energystar'] = energy
2023-07-05 09:54:58 +00:00
def request_manuals(self, prefix):
2023-07-06 09:39:37 +00:00
url = app.config['URL_MANUALS']
2023-07-05 09:54:58 +00:00
if not url:
return {}
res = requests.post(url + "/" + prefix, self.params)
if res.status_code > 299:
return {}
try:
response = res.json()
except Exception:
response = {}
return response
2023-05-31 14:30:49 +00:00
did.add_url_rule('/<string:id_dpp>', view_func=DidView.as_view('did'))