review pr 212 mv schemas, refactor forms and clean code

This commit is contained in:
Cayo Puigdefabregas 2022-03-30 18:29:15 +02:00
parent 3be389c23f
commit 90ad7afdc8
4 changed files with 61 additions and 32 deletions

View File

@ -27,9 +27,9 @@ from wtforms.fields import FormField
from ereuse_devicehub.db import db from ereuse_devicehub.db import db
from ereuse_devicehub.parser.parser import ParseSnapshotLsHw from ereuse_devicehub.parser.parser import ParseSnapshotLsHw
from ereuse_devicehub.parser.schemas import Snapshot_lite
from ereuse_devicehub.resources.action.models import Snapshot, Trade from ereuse_devicehub.resources.action.models import Snapshot, Trade
from ereuse_devicehub.resources.action.schemas import Snapshot as SnapshotSchema from ereuse_devicehub.resources.action.schemas import Snapshot as SnapshotSchema
from ereuse_devicehub.resources.action.schemas import Snapshot_lite
from ereuse_devicehub.resources.action.views.snapshot import move_json, save_json from ereuse_devicehub.resources.action.views.snapshot import move_json, save_json
from ereuse_devicehub.resources.device.models import ( from ereuse_devicehub.resources.device.models import (
SAI, SAI,
@ -233,6 +233,13 @@ class UploadSnapshotForm(FlaskForm):
return True return True
def is_wb_lite_snapshot(self, version: str) -> bool:
is_lite = False
if version in app.config['WORKBENCH_LITE']:
is_lite = True
return is_lite
def save(self, commit=True): def save(self, commit=True):
if any([x == 'Error' for x in self.result.values()]): if any([x == 'Error' for x in self.result.values()]):
return return
@ -243,7 +250,8 @@ class UploadSnapshotForm(FlaskForm):
for filename, snapshot_json in self.snapshots: for filename, snapshot_json in self.snapshots:
path_snapshot = save_json(snapshot_json, self.tmp_snapshots, g.user.email) path_snapshot = save_json(snapshot_json, self.tmp_snapshots, g.user.email)
snapshot_json.pop('debug', None) snapshot_json.pop('debug', None)
if snapshot_json.get('version') in ["2022.03"]: version = snapshot_json.get('version')
if self.is_wb_lite_snapshot(version):
self.snapshot_json = schema_lite.load(snapshot_json) self.snapshot_json = schema_lite.load(snapshot_json)
snap = ParseSnapshotLsHw(self.snapshot_json) snap = ParseSnapshotLsHw(self.snapshot_json)
snapshot_json = snap.snapshot_json snapshot_json = snap.snapshot_json

View File

@ -7,8 +7,7 @@ from math import hypot
from typing import Iterator, List, Optional, Type, TypeVar from typing import Iterator, List, Optional, Type, TypeVar
import dateutil.parser import dateutil.parser
from ereuse_utils import getter as g from ereuse_utils import getter, text
from ereuse_utils import text
from ereuse_utils.nested_lookup import ( from ereuse_utils.nested_lookup import (
get_nested_dicts_with_key_containing_value, get_nested_dicts_with_key_containing_value,
get_nested_dicts_with_key_value, get_nested_dicts_with_key_value,
@ -33,15 +32,15 @@ class Device(Dumpeable):
super().__init__() super().__init__()
def from_lshw(self, lshw_node: dict): def from_lshw(self, lshw_node: dict):
self.manufacturer = g.dict(lshw_node, 'vendor', default=None, type=str) self.manufacturer = getter.dict(lshw_node, 'vendor', default=None, type=str)
self.model = g.dict( self.model = getter.dict(
lshw_node, lshw_node,
'product', 'product',
remove={self.manufacturer} if self.manufacturer else set(), remove={self.manufacturer} if self.manufacturer else set(),
default=None, default=None,
type=str, type=str,
) )
self.serial_number = g.dict(lshw_node, 'serial', default=None, type=str) self.serial_number = getter.dict(lshw_node, 'serial', default=None, type=str)
def __str__(self) -> str: def __str__(self) -> str:
return ' '.join(x for x in (self.model, self.serial_number) if x) return ' '.join(x for x in (self.model, self.serial_number) if x)
@ -208,7 +207,7 @@ class Motherboard(Component):
bios_node = next(get_nested_dicts_with_key_value(lshw, 'id', 'firmware')) bios_node = next(get_nested_dicts_with_key_value(lshw, 'id', 'firmware'))
# bios_node = '1' # bios_node = '1'
memory_array = next( memory_array = next(
g.indents(hwinfo, 'Physical Memory Array', indent=' '), None getter.indents(hwinfo, 'Physical Memory Array', indent=' '), None
) )
return cls(node, bios_node, memory_array) return cls(node, bios_node, memory_array)
@ -234,8 +233,8 @@ class Motherboard(Component):
self.version = bios_node['version'] self.version = bios_node['version']
self.ram_slots = self.ram_max_size = None self.ram_slots = self.ram_max_size = None
if memory_array: if memory_array:
self.ram_slots = g.kv(memory_array, 'Slots', default=None) self.ram_slots = getter.kv(memory_array, 'Slots', default=None)
self.ram_max_size = g.kv(memory_array, 'Max. Size', default=None) self.ram_max_size = getter.kv(memory_array, 'Max. Size', default=None)
if self.ram_max_size: if self.ram_max_size:
self.ram_max_size = next(text.numbers(self.ram_max_size)) self.ram_max_size = next(text.numbers(self.ram_max_size))
@ -306,33 +305,34 @@ class Display(Component):
@classmethod @classmethod
def new(cls, lshw, hwinfo, **kwargs) -> Iterator[C]: def new(cls, lshw, hwinfo, **kwargs) -> Iterator[C]:
for node in g.indents(hwinfo, 'Monitor'): for node in getter.indents(hwinfo, 'Monitor'):
yield cls(node) yield cls(node)
def __init__(self, node: dict) -> None: def __init__(self, node: dict) -> None:
super().__init__(node) super().__init__(node)
self.model = g.kv(node, 'Model') self.model = getter.kv(node, 'Model')
self.manufacturer = g.kv(node, 'Vendor') self.manufacturer = getter.kv(node, 'Vendor')
self.serial_number = g.kv(node, 'Serial ID', default=None, type=str) self.serial_number = getter.kv(node, 'Serial ID', default=None, type=str)
self.resolution_width, self.resolution_height, refresh_rate = text.numbers( self.resolution_width, self.resolution_height, refresh_rate = text.numbers(
g.kv(node, 'Resolution') getter.kv(node, 'Resolution')
) )
self.refresh_rate = unit.Quantity(refresh_rate, 'Hz').m self.refresh_rate = unit.Quantity(refresh_rate, 'Hz').m
with suppress(StopIteration): with suppress(StopIteration):
# some monitors can have several resolutions, and the one # some monitors can have several resolutions, and the one
# in "Detailed Timings" seems the highest one # in "Detailed Timings" seems the highest one
timings = next(g.indents(node, 'Detailed Timings', indent=' ')) timings = next(getter.indents(node, 'Detailed Timings', indent=' '))
self.resolution_width, self.resolution_height = text.numbers( self.resolution_width, self.resolution_height = text.numbers(
g.kv(timings, 'Resolution') getter.kv(timings, 'Resolution')
) )
x, y = ( x, y = (
unit.convert(v, 'millimeter', 'inch') unit.convert(v, 'millimeter', 'inch')
for v in text.numbers(g.kv(node, 'Size')) for v in text.numbers(getter.kv(node, 'Size'))
) )
self.size = hypot(x, y) self.size = hypot(x, y)
self.technology = next((t for t in self.TECHS if t in node[0]), None) self.technology = next((t for t in self.TECHS if t in node[0]), None)
d = '{} {} 0'.format( d = '{} {} 0'.format(
g.kv(node, 'Year of Manufacture'), g.kv(node, 'Week of Manufacture') getter.kv(node, 'Year of Manufacture'),
getter.kv(node, 'Week of Manufacture'),
) )
# We assume it has been produced the first day of such week # We assume it has been produced the first day of such week
self.production_date = datetime.strptime(d, '%Y %W %w').isoformat() self.production_date = datetime.strptime(d, '%Y %W %w').isoformat()
@ -413,8 +413,8 @@ class Computer(Device):
self.chassis = next( self.chassis = next(
t for t, values in self.CHASSIS_DH.items() if chassis in values t for t, values in self.CHASSIS_DH.items() if chassis in values
) )
self.sku = g.dict(node, ('configuration', 'sku'), default=None, type=str) self.sku = getter.dict(node, ('configuration', 'sku'), default=None, type=str)
self.version = g.dict(node, 'version', default=None, type=str) self.version = getter.dict(node, 'version', default=None, type=str)
self._ram = None self._ram = None
@classmethod @classmethod

View File

@ -0,0 +1,32 @@
from flask import current_app as app
from marshmallow import Schema as MarshmallowSchema
from marshmallow import ValidationError, validates_schema
from marshmallow.fields import Nested, String
class Snapshot_lite_data(MarshmallowSchema):
dmidecode = String(required=False)
hwinfo = String(required=False)
smart = String(required=False)
lshw = String(required=False)
class Snapshot_lite(MarshmallowSchema):
uuid = String(required=True)
version = String(required=True)
software = String(required=True)
wbid = String(required=True)
type = String(required=True)
timestamp = String(required=True)
data = Nested(Snapshot_lite_data)
@validates_schema
def validate_workbench_version(self, data: dict):
if data['version'] not in app.config['WORKBENCH_LITE']:
raise ValidationError(
'Min. supported Workbench version is '
'{} but yours is {}.'.format(
app.config['WORKBENCH_LITE'][0], data['version']
),
field_names=['version'],
)

View File

@ -1,21 +1,10 @@
from datetime import datetime, timezone from datetime import datetime, timezone
from enum import Enum, unique
from typing import List from typing import List
from ereuse_workbench.computer import Component, Computer, DataStorage from ereuse_workbench.computer import Component, Computer, DataStorage
from ereuse_workbench.utils import Dumpeable from ereuse_workbench.utils import Dumpeable
@unique
class SnapshotSoftware(Enum):
"""The algorithm_software used to perform the Snapshot."""
Workbench = 'Workbench'
AndroidApp = 'AndroidApp'
Web = 'Web'
DesktopApp = 'DesktopApp'
class Snapshot(Dumpeable): class Snapshot(Dumpeable):
""" """
Generates the Snapshot report for Devicehub by obtaining the Generates the Snapshot report for Devicehub by obtaining the