2018-06-14 13:14:23 +00:00
|
|
|
from flask import current_app, current_app as app, jsonify
|
|
|
|
from flask_sqlalchemy import Pagination
|
2018-06-12 14:50:05 +00:00
|
|
|
from marshmallow import Schema as MarshmallowSchema
|
2018-06-14 13:14:23 +00:00
|
|
|
from marshmallow.fields import Float, Integer, Nested, Str
|
|
|
|
from marshmallow.validate import Range
|
|
|
|
from sqlalchemy import Column
|
2018-06-12 14:50:05 +00:00
|
|
|
|
|
|
|
from ereuse_devicehub.resources.device.models import Device
|
|
|
|
from ereuse_devicehub.resources.event.models import Rate
|
2018-06-14 13:14:23 +00:00
|
|
|
from ereuse_devicehub.resources.schemas import Thing
|
2018-06-12 14:50:05 +00:00
|
|
|
from ereuse_devicehub.resources.tag import Tag
|
2018-06-14 13:14:23 +00:00
|
|
|
from teal.query import Between, FullTextSearch, ILike, Join, Or, Query, Sort, SortField
|
|
|
|
from teal.resource import Resource, View
|
2018-06-12 14:50:05 +00:00
|
|
|
|
|
|
|
|
2018-06-14 13:14:23 +00:00
|
|
|
class Inventory(Thing):
|
2018-06-12 14:50:05 +00:00
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
class RateQ(Query):
|
|
|
|
rating = Between(Rate.rating, Float())
|
|
|
|
appearance = Between(Rate.appearance, Float())
|
|
|
|
functionality = Between(Rate.functionality, Float())
|
|
|
|
|
|
|
|
|
|
|
|
class TagQ(Query):
|
|
|
|
id = Or(ILike(Tag.id), required=True)
|
|
|
|
org = ILike(Tag.org)
|
|
|
|
|
|
|
|
|
2018-06-14 13:14:23 +00:00
|
|
|
class OfType(Str):
|
|
|
|
def __init__(self, column: Column, *args, **kwargs):
|
|
|
|
super().__init__(*args, **kwargs)
|
|
|
|
self.column = column
|
|
|
|
|
|
|
|
def _deserialize(self, value, attr, data):
|
|
|
|
v = super()._deserialize(value, attr, data)
|
|
|
|
return self.column.in_(current_app.resources[v].subresources_types)
|
|
|
|
|
|
|
|
|
2018-06-12 14:50:05 +00:00
|
|
|
class Filters(Query):
|
2018-06-14 13:14:23 +00:00
|
|
|
type = Or(OfType(Device.type))
|
2018-06-12 14:50:05 +00:00
|
|
|
model = ILike(Device.model)
|
|
|
|
manufacturer = ILike(Device.manufacturer)
|
|
|
|
serialNumber = ILike(Device.serial_number)
|
2018-06-14 13:14:23 +00:00
|
|
|
rating = Join(Device.id == Rate.device_id, RateQ)
|
|
|
|
tag = Join(Device.id == Tag.id, TagQ)
|
|
|
|
|
|
|
|
|
|
|
|
class Sorting(Sort):
|
|
|
|
created = SortField(Device.created)
|
2018-06-12 14:50:05 +00:00
|
|
|
|
|
|
|
|
|
|
|
class InventoryView(View):
|
|
|
|
class FindArgs(MarshmallowSchema):
|
2018-06-14 13:14:23 +00:00
|
|
|
search = FullTextSearch() # todo Develop this. See more at docs/inventory.
|
|
|
|
filter = Nested(Filters, missing=[])
|
|
|
|
sort = Nested(Sorting, missing=[Device.created.desc()])
|
|
|
|
page = Integer(validate=Range(min=1), missing=1)
|
|
|
|
|
|
|
|
def find(self, args: dict):
|
|
|
|
"""
|
|
|
|
Supports the inventory view of ``devicehub-client``; returns
|
|
|
|
all the devices, groups and widgets of this Devicehub instance.
|
2018-06-12 14:50:05 +00:00
|
|
|
|
2018-06-14 13:14:23 +00:00
|
|
|
The result can be filtered, sorted, and paginated.
|
|
|
|
"""
|
|
|
|
devices = Device.query \
|
|
|
|
.filter(*args['filter']) \
|
|
|
|
.order_by(*args['sort']) \
|
|
|
|
.paginate(page=args['page'], per_page=30) # type: Pagination
|
2018-06-12 14:50:05 +00:00
|
|
|
inventory = {
|
2018-06-14 13:14:23 +00:00
|
|
|
'devices': app.resources[Device.t].schema.dump(devices.items, many=True),
|
|
|
|
'groups': [],
|
|
|
|
'widgets': {},
|
|
|
|
'pagination': {
|
|
|
|
'page': devices.page,
|
|
|
|
'perPage': devices.per_page,
|
|
|
|
'total': devices.total,
|
|
|
|
}
|
2018-06-12 14:50:05 +00:00
|
|
|
}
|
|
|
|
return jsonify(inventory)
|
|
|
|
|
|
|
|
|
|
|
|
class InventoryDef(Resource):
|
|
|
|
SCHEMA = Inventory
|
|
|
|
VIEW = InventoryView
|
|
|
|
AUTH = True
|