diff --git a/README.md b/README.md index b4293312..53164936 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,9 @@ call the new file ``app.py``. Create a PostgreSQL database called *devicehub* by running [create-db](examples/create-db.sh): -- In Debian 9: `sudo su - postgres; examples/create-db.sh devicehub` +- In a Debian 9 terminal, execute the following two commands: + 1. `sudo su - postgres`. + 2. `bash examples/create-db.sh devicehub`. - In MacOS: `examples/create-db.sh devicehub`. Create the tables in the database by executing in the same directory diff --git a/ereuse_devicehub/dummy/dummy.py b/ereuse_devicehub/dummy/dummy.py index 5aba1421..1b59aa05 100644 --- a/ereuse_devicehub/dummy/dummy.py +++ b/ereuse_devicehub/dummy/dummy.py @@ -58,16 +58,28 @@ class Dummy: '-o', org_id ], catch_exceptions=False) + # create tag for pc-laudem + runner.invoke(args=[ + 'create-tag', 'tagA', + '-p', 'https://t.devicetag.io', + '-s', 'tagA-secondary' + ], + catch_exceptions=False) files = tuple(Path(__file__).parent.joinpath('files').iterdir()) print('done.') + sample_pc = None # We treat this one as a special sample for demonstrations pcs = set() # type: Set[int] with click.progressbar(files, label='Creating devices...'.ljust(28)) as bar: for path in bar: with path.open() as f: snapshot = yaml.load(f) s, _ = user.post(res=m.Snapshot, data=snapshot) - pcs.add(s['device']['id']) - + if s.get('uuid', None) == 'ec23c11b-80b6-42cd-ac5c-73ba7acddbc4': + sample_pc = s['device']['id'] + else: + pcs.add(s['device']['id']) + assert sample_pc + print('PC sample is', sample_pc) # Link tags and eTags for tag, pc in zip((self.TAGS[1], self.TAGS[2], self.ET[0][0], self.ET[1][1]), pcs): user.put({}, res=Tag, item='{}/device/{}'.format(tag, pc), status=204) @@ -105,9 +117,29 @@ class Dummy: assert len(inventory['items']) i, _ = user.get(res=Device, query=[('search', 'intel')]) - assert len(i['items']) == 10 - i, _ = user.get(res=Device, query=[('search', 'pc')]) assert len(i['items']) == 11 + i, _ = user.get(res=Device, query=[('search', 'pc')]) + assert len(i['items']) == 12 + + # Let's create a set of events for the pc device + # Make device Ready + + user.post({'type': m.ToPrepare.t, 'devices': [sample_pc]}, res=m.Event) + user.post({'type': m.Prepare.t, 'devices': [sample_pc]}, res=m.Event) + user.post({'type': m.ReadyToUse.t, 'devices': [sample_pc]}, res=m.Event) + user.post({'type': m.Price.t, 'device': sample_pc, 'currency': 'EUR', 'price': 85}, + res=m.Event) + # todo test reserve + user.post( # Sell device + { + 'type': m.Sell.t, + 'to': user.user['individuals'][0]['id'], + 'devices': [sample_pc] + }, + res=m.Event) + # todo Receive + + # For netbook: to preapre -> torepair -> to dispose -> disposed print('⭐ Done.') def user_client(self, email: str, password: str): diff --git a/ereuse_devicehub/dummy/files/pc-laudem.snapshot.11.yaml b/ereuse_devicehub/dummy/files/pc-laudem.snapshot.11.yaml new file mode 100644 index 00000000..cf2c6749 --- /dev/null +++ b/ereuse_devicehub/dummy/files/pc-laudem.snapshot.11.yaml @@ -0,0 +1,146 @@ +{ + "closed": true, + "components": [ + { + "events": [], + "manufacturer": "Intel Corporation", + "model": "82567LM-3 Gigabit Network Connection", + "serialNumber": "00:23:7d:49:5e:31", + "speed": 1000, + "type": "NetworkAdapter", + "wireless": false + }, + { + "events": [], + "manufacturer": "Intel Corporation", + "model": "82801JD/DO HD Audio Controller", + "serialNumber": null, + "type": "SoundCard" + }, + { + "events": [], + "format": "DIMM", + "interface": "DDR2", + "manufacturer": null, + "model": "HYMP125U64CP8-S6", + "serialNumber": null, + "size": 2048, + "speed": 800.0, + "type": "RamModule" + }, + { + "address": 64, + "cores": 2, + "events": [ + { + "elapsed": 0, + "rate": 11970.54, + "type": "BenchmarkProcessor" + }, + { + "elapsed": 20, + "rate": 19.6233, + "type": "BenchmarkProcessorSysbench" + } + ], + "manufacturer": "Intel Corp.", + "model": "Intel Core2 Duo CPU E8400 @ 3.00GHz", + "serialNumber": null, + "speed": 3.0, + "threads": 2, + "type": "Processor" + }, + { + "events": [ + { + "elapsed": 16, + "readSpeed": 76.8, + "type": "BenchmarkDataStorage", + "writeSpeed": 21.1 + }, + { + "assessment": true, + "currentPendingSectorCount": 0, + "elapsed": 134, + "error": false, + "length": "Short", + "lifetime": 19549, + "offlineUncorrectable": 0, + "powerCycleCount": 3354, + "reallocatedSectorCount": 33, + "reportedUncorrectableErrors": 0, + "status": "Completed without error", + "type": "TestDataStorage" + } + ], + "interface": "ATA", + "manufacturer": "Seagate", + "model": "ST3160815AS", + "serialNumber": "6RX7AWEZ", + "size": 152627, + "type": "HardDrive" + }, + { + "events": [], + "manufacturer": "Intel Corporation", + "memory": 256.0, + "model": "4 Series Chipset Integrated Graphics Controller", + "serialNumber": null, + "type": "GraphicCard" + }, + { + "events": [], + "firewire": 0, + "manufacturer": "Hewlett-Packard", + "model": "3031h", + "pcmcia": 0, + "serial": 0, + "serialNumber": "CZC901381R", + "slots": 0, + "type": "Motherboard", + "usb": 8 + } + ], + "device": { + "chassis": "Tower", + "events": [ + { + "elapsed": 60, + "error": false, + "type": "StressTest" + }, + { + "elapsed": 6, + "rate": 5.7674, + "type": "BenchmarkRamSysbench" + }, + { + "appearanceRange": "A", + "biosRange": "A", + "functionalityRange": "A", + "type": "WorkbenchRate" + } + ], + "manufacturer": "Hewlett-Packard", + "model": "HP Compaq dc7900 Small Form Factor", + "serialNumber": "CZC901381R", + "tags": [ + { + "id": "tagA-secondary", + "type": "Tag" + } + ], + "type": "Desktop" + }, + "elapsed": 238, + "endTime": "2018-10-15T13:59:37.431309+00:00", + "expectedEvents": [ + "Benchmark", + "TestDataStorage", + "StressTest" + ], + "software": "Workbench", + "type": "Snapshot", + "uuid": "ec23c11b-80b6-42cd-ac5c-73ba7acddbc4", + "version": "11.0a6" +} diff --git a/ereuse_devicehub/resources/device/definitions.py b/ereuse_devicehub/resources/device/definitions.py index e888c988..b0224bc3 100644 --- a/ereuse_devicehub/resources/device/definitions.py +++ b/ereuse_devicehub/resources/device/definitions.py @@ -14,7 +14,8 @@ class DeviceDef(Resource): AUTH = False # We manage this at each view def __init__(self, app, - import_name=__name__, static_folder=None, + import_name=__name__, + static_folder='static', static_url_path=None, template_folder='templates', url_prefix=None, @@ -30,6 +31,12 @@ class ComputerDef(DeviceDef): VIEW = None SCHEMA = schemas.Computer + def __init__(self, app, import_name=__name__, static_folder=None, static_url_path=None, + template_folder=None, url_prefix=None, subdomain=None, url_defaults=None, + root_path=None, cli_commands: Iterable[Tuple[Callable, str or None]] = tuple()): + super().__init__(app, import_name, static_folder, static_url_path, template_folder, + url_prefix, subdomain, url_defaults, root_path, cli_commands) + class DesktopDef(ComputerDef): VIEW = None @@ -50,6 +57,12 @@ class MonitorDef(DeviceDef): VIEW = None SCHEMA = schemas.Monitor + def __init__(self, app, import_name=__name__, static_folder=None, static_url_path=None, + template_folder=None, url_prefix=None, subdomain=None, url_defaults=None, + root_path=None, cli_commands: Iterable[Tuple[Callable, str or None]] = tuple()): + super().__init__(app, import_name, static_folder, static_url_path, template_folder, + url_prefix, subdomain, url_defaults, root_path, cli_commands) + class ComputerMonitorDef(MonitorDef): VIEW = None @@ -65,6 +78,12 @@ class MobileDef(DeviceDef): VIEW = None SCHEMA = schemas.Mobile + def __init__(self, app, import_name=__name__, static_folder=None, static_url_path=None, + template_folder=None, url_prefix=None, subdomain=None, url_defaults=None, + root_path=None, cli_commands: Iterable[Tuple[Callable, str or None]] = tuple()): + super().__init__(app, import_name, static_folder, static_url_path, template_folder, + url_prefix, subdomain, url_defaults, root_path, cli_commands) + class SmartphoneDef(MobileDef): VIEW = None @@ -85,6 +104,12 @@ class ComponentDef(DeviceDef): VIEW = None SCHEMA = schemas.Component + def __init__(self, app, import_name=__name__, static_folder=None, static_url_path=None, + template_folder=None, url_prefix=None, subdomain=None, url_defaults=None, + root_path=None, cli_commands: Iterable[Tuple[Callable, str or None]] = tuple()): + super().__init__(app, import_name, static_folder, static_url_path, template_folder, + url_prefix, subdomain, url_defaults, root_path, cli_commands) + class GraphicCardDef(ComponentDef): VIEW = None diff --git a/ereuse_devicehub/resources/device/models.py b/ereuse_devicehub/resources/device/models.py index 9e47b557..cc57ed74 100644 --- a/ereuse_devicehub/resources/device/models.py +++ b/ereuse_devicehub/resources/device/models.py @@ -187,7 +187,9 @@ class Device(Thing): if 't' in format_spec: v += '{0.t} {0.model}'.format(self) if 's' in format_spec: - v += '({0.manufacturer}) S/N {0.serial_number}'.format(self) + v += '({0.manufacturer})'.format(self) + if self.serial_number: + v += ' S/N ' + self.serial_number.upper() return v @@ -272,7 +274,9 @@ class Computer(Device): if 't' in format_spec: v += '{0.chassis} {0.model}'.format(self) elif 's' in format_spec: - v += '({0.manufacturer}) S/N {0.serial_number}'.format(self) + v += '({0.manufacturer})'.format(self) + if self.serial_number: + v += ' S/N ' + self.serial_number.upper() return v diff --git a/ereuse_devicehub/resources/device/states.py b/ereuse_devicehub/resources/device/states.py index d10ce52f..809e0a64 100644 --- a/ereuse_devicehub/resources/device/states.py +++ b/ereuse_devicehub/resources/device/states.py @@ -1,5 +1,7 @@ from enum import Enum +import inflection + from ereuse_devicehub.resources.event import models as e @@ -9,6 +11,9 @@ class State(Enum): """Events participating in this state.""" return (s.value for s in cls) + def __str__(self): + return inflection.humanize(inflection.underscore(self.name)) + class Trading(State): Reserved = e.Reserve diff --git a/ereuse_devicehub/resources/device/static/ereuse-logo.svg b/ereuse_devicehub/resources/device/static/ereuse-logo.svg new file mode 100644 index 00000000..9c9608ab --- /dev/null +++ b/ereuse_devicehub/resources/device/static/ereuse-logo.svg @@ -0,0 +1,3 @@ + + diff --git a/ereuse_devicehub/resources/device/static/magrama.svg b/ereuse_devicehub/resources/device/static/magrama.svg new file mode 100644 index 00000000..b792c830 --- /dev/null +++ b/ereuse_devicehub/resources/device/static/magrama.svg @@ -0,0 +1,3 @@ + +PlataformaRAEE08006417910000001670001COCINAS41*Grandesaparatosconcomponentespeligrosos diff --git a/ereuse_devicehub/resources/device/static/photochromic-alone.svg b/ereuse_devicehub/resources/device/static/photochromic-alone.svg new file mode 100644 index 00000000..95cf4353 --- /dev/null +++ b/ereuse_devicehub/resources/device/static/photochromic-alone.svg @@ -0,0 +1,3 @@ + + diff --git a/ereuse_devicehub/resources/device/static/photochromic-tag-web.svg b/ereuse_devicehub/resources/device/static/photochromic-tag-web.svg new file mode 100644 index 00000000..82ffafca --- /dev/null +++ b/ereuse_devicehub/resources/device/static/photochromic-tag-web.svg @@ -0,0 +1,3 @@ + +6s diff --git a/ereuse_devicehub/resources/device/templates/devices/layout.html b/ereuse_devicehub/resources/device/templates/devices/layout.html index ef1fa6fb..0f7d0957 100644 --- a/ereuse_devicehub/resources/device/templates/devices/layout.html +++ b/ereuse_devicehub/resources/device/templates/devices/layout.html @@ -10,87 +10,212 @@ crossorigin="anonymous"> Devicehub | {{ device.__format__('t') }} - + -