view dpp page

This commit is contained in:
Cayo Puigdefabregas 2024-11-20 18:06:52 +01:00 committed by sergio-gimenez
parent 0bbc3475c2
commit 3d0527edf1
4 changed files with 149 additions and 180 deletions

View file

@ -95,6 +95,15 @@ class Device:
if self.last_evidence:
return
if self.uuid:
import pdb; pdb.set_trace()
self.last_evidence = Evidence(self.uuid)
return
annotations = self.get_annotations()
if not annotations.count():
return
if self.uuid:
self.last_evidence = Evidence(self.uuid)
return

View file

@ -1,5 +1,4 @@
import json
import logging
from django.http import JsonResponse
from django.http import JsonResponse
from django.conf import settings
@ -20,6 +19,7 @@ from dashboard.mixins import DashboardView, Http403
from evidence.models import UserProperty, SystemProperty
from lot.models import LotTag
from dpp.models import Proof
from dpp.api_dlt import PROOF_TYPE
from device.models import Device
from device.forms import DeviceFormSet
from device.environmental_impact.calculator import get_device_environmental_impact
@ -91,7 +91,10 @@ class DetailsView(DashboardView, TemplateView):
context = super().get_context_data(**kwargs)
self.object.initial()
lot_tags = LotTag.objects.filter(owner=self.request.user.institution)
dpps = Proof.objects.filter(uuid__in=self.object.uuids)
dpps = Proof.objects.filter(
uuid__in=self.object.uuids,
type=PROOF_TYPE["IssueDPP"]
)
context.update({
'object': self.object,
'snapshot': last_evidence,

View file

@ -1,171 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{{ object.type }}</title>
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.1.3/css/bootstrap.min.css" rel="stylesheet" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.1/font/bootstrap-icons.css" />
<style>
body {
font-size: 0.875rem;
background-color: #f8f9fa;
display: flex;
flex-direction: column;
min-height: 100vh;
}
.custom-container {
background-color: #ffffff;
border-radius: 10px;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);
padding: 30px;
margin-top: 30px;
flex-grow: 1;
}
.section-title {
color: #7a9f4f;
border-bottom: 2px solid #9cc666;
padding-bottom: 10px;
margin-bottom: 20px;
font-size: 1.5em;
}
.info-row {
margin-bottom: 10px;
}
.info-label {
font-weight: bold;
color: #545f71;
}
.info-value {
color: #333;
}
.component-card {
background-color: #f8f9fa;
border-left: 4px solid #9cc666;
margin-bottom: 15px;
transition: all 0.3s ease;
}
.component-card:hover {
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
transform: translateY(-2px);
}
.hash-value {
word-break: break-all;
background-color: #f3f3f3;
padding: 5px;
border-radius: 4px;
font-family: monospace;
font-size: 0.9em;
border: 1px solid #e0e0e0;
}
.card-title {
color: #9cc666;
}
.btn-primary {
background-color: #9cc666;
border-color: #9cc666;
padding: 0.1em 2em;
font-weight: 700;
}
.btn-primary:hover {
background-color: #8ab555;
border-color: #8ab555;
}
.btn-green-user {
background-color: #c7e3a3;
}
.btn-grey {
background-color: #f3f3f3;
}
footer {
background-color: #545f71;
color: #ffffff;
text-align: center;
padding: 10px 0;
margin-top: 20px;
}
</style>
</head>
<body>
<div class="container custom-container">
<h1 class="text-center mb-4" style="color: #545f71;">{{ object.manufacturer }} {{ object.type }} {{ object.model }}</h1>
<div class="row">
<div class="col-lg-6">
<h2 class="section-title">Details</h2>
<div class="info-row row">
<div class="col-md-4 info-label">Phid</div>
<div class="col-md-8 info-value">
<div class="hash-value">{{ object.id }}</div>
</div>
</div>
<div class="info-row row">
<div class="col-md-4 info-label">Type</div>
<div class="col-md-8 info-value">{{ object.type }}</div>
</div>
{% if object.is_websnapshot %}
{% for snapshot_key, snapshot_value in object.last_user_evidence %}
<div class="info-row row">
<div class="col-md-4 info-label">{{ snapshot_key }}</div>
<div class="col-md-8 info-value">{{ snapshot_value|default:'' }}</div>
</div>
{% endfor %}
{% else %}
<div class="info-row row">
<div class="col-md-4 info-label">Manufacturer</div>
<div class="col-md-8 info-value">{{ object.manufacturer|default:'' }}</div>
</div>
<div class="info-row row">
<div class="col-md-4 info-label">Model</div>
<div class="col-md-8 info-value">{{ object.model|default:'' }}</div>
</div>
{% if user.is_authenticated %}
<div class="info-row row">
<div class="col-md-4 info-label">Serial Number</div>
<div class="col-md-8 info-value">{{ object.serial_number|default:'' }}</div>
</div>
{% endif %}
{% endif %}
</div>
<div class="col-lg-6">
<h2 class="section-title">Identifiers</h2>
{% for chid in object.hids %}
<div class="info-row">
<div class="hash-value">{{ chid|default:'' }}</div>
</div>
{% endfor %}
</div>
</div>
<h2 class="section-title mt-5">Components</h2>
<div class="row">
{% for component in object.components %}
<div class="col-md-6 mb-3">
<div class="card component-card">
<div class="card-body">
<h5 class="card-title">{{ component.type }}</h5>
<p class="card-text">
{% for component_key, component_value in component.items %}
{% if component_key not in 'actions,type' %}
{% if component_key != 'serialNumber' or user.is_authenticated %}
<strong>{{ component_key }}:</strong> {{ component_value }}<br />
{% endif %}
{% endif %}
{% endfor %}
</p>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
<footer>
<p>
&copy;{% now 'Y' %}eReuse. All rights reserved.
</p>
</footer>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.1.3/js/bootstrap.bundle.min.js"></script>
</body>
</html>

View file

@ -1,14 +1,26 @@
import json
import logging
from django.http import JsonResponse, Http404
from django.views.generic.base import TemplateView
from device.models import Device
from dpp.models import Proof
logger = logging.getLogger('django')
class PublicDeviceWebView(TemplateView):
template_name = "device_web.html"
template_name = "device_did.html"
def get(self, request, *args, **kwargs):
self.pk = kwargs['pk']
self.object = Device(id=self.pk)
chid = self.pk.split(":")[0]
proof = Proof.objects.filter(signature=self.pk).first()
if proof:
self.object = Device(id=chid, uuid=proof.uuid)
else:
self.object = Device(id=chid)
if not self.object.last_evidence:
raise Http404
@ -18,12 +30,24 @@ class PublicDeviceWebView(TemplateView):
return super().get(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
self.context = super().get_context_data(**kwargs)
self.object.initial()
context.update({
'object': self.object
roles = [("Operator", "Operator")]
role = "Operator"
if self.request.user.is_anonymous:
roles = []
role = None
self.context.update({
'object': self.object,
'role': role,
'roles': roles,
'path': self.request.path,
'last_dpp': "",
'before_dpp': "",
})
return context
if not self.request.user.is_anonymous:
self.get_manuals()
return self.context
@property
def public_fields(self):
@ -58,3 +82,107 @@ class PublicDeviceWebView(TemplateView):
device_data = self.get_device_data()
return JsonResponse(device_data)
def get_manuals(self):
manuals = {
'ifixit': [],
'icecat': [],
'details': {},
'laer': [],
'energystar': {},
}
try:
params = {
"manufacturer": self.object.manufacturer,
"model": self.object.model,
}
self.params = json.dumps(params)
manuals['ifixit'] = self.request_manuals('ifixit')
manuals['icecat'] = self.request_manuals('icecat')
manuals['laer'] = self.request_manuals('laer')
manuals['energystar'] = self.request_manuals('energystar') or {}
if manuals['icecat']:
manuals['details'] = manuals['icecat'][0]
except Exception as err:
logger.error("Error: {}".format(err))
self.context['manuals'] = manuals
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
def request_manuals(self, prefix):
#TODO reimplement manuals service
response = {
"laer": [{"metal": 40, "plastic_post_consumer": 27, "plastic_post_industry": 34}],
"energystar": [{
'functional_adder_allowances_kwh': 180,
"long_idle_watts": 240,
"short_idle_watts": 120,
"sleep_mode_watts": 30,
"off_mode_watts": 3,
"tec_allowance_kwh": 180,
"tec_of_model_kwh": 150,
"tec_requirement_kwh": 220,
"work_off_mode_watts": 70,
"work_weighted_power_of_model_watts": 240
}],
"ifixit": [
{
"image": "https://guide-images.cdn.ifixit.com/igi/156EpI4YdQeVfVPa.medium",
"url": "https://es.ifixit.com/Gu%C3%ADa/HP+ProBook+450+G4+Back+Panel+Replacement/171196?lang=en",
"title": "HP ProBook 450 G4 Back Panel Replacement"
},
{
"image": "https://guide-images.cdn.ifixit.com/igi/usTIqCKpuxVWC3Ix.140x105",
"url": "https://es.ifixit.com/Gu%C3%ADa/HP+ProBook+450+G4+Display+Assembly+Replacement/171101?lang=en",
"title": "Display Assembly Replacement"
}
],
"icecat": [
{
"logo": "https://images.icecat.biz/img/brand/thumb/1_cf8603f6de7b4c4d8ac4f5f0ef439a05.jpg",
"image": "https://guide-images.cdn.ifixit.com/igi/Q2nYjTIQfG6GaI5B.standard",
"pdf": "https://icecat.biz/rest/product-pdf?productId=32951710&lang=en",
"title": "HP ProBook 450 G3"
}
]
}
return response.get(prefix, {})