Add device account associations
parent
1ae5d1a2b8
commit
cb0e61c906
|
@ -1,6 +1,7 @@
|
|||
from marshmallow import Schema, fields
|
||||
from webargs.flaskparser import use_args
|
||||
from flasgger import swag_from
|
||||
from flask import g
|
||||
import app.devices as devices
|
||||
from app.api import ProtectedResource
|
||||
|
||||
|
@ -13,6 +14,9 @@ class DeviceSchema(Schema):
|
|||
class DeviceWrapperSchema(Schema):
|
||||
device = fields.Nested(DeviceSchema, required=True, location='json')
|
||||
|
||||
class DevicesWrapperSchema(Schema):
|
||||
devices = fields.Nested(DeviceSchema, required=True,
|
||||
location='json', many=True)
|
||||
|
||||
class RecordingsSchema(Schema):
|
||||
recorded_at = fields.DateTime()
|
||||
|
@ -45,6 +49,12 @@ class DeviceListResource(ProtectedResource):
|
|||
def post(self, args):
|
||||
args = args['device']
|
||||
success = devices.create_device(
|
||||
args['name'])
|
||||
args['name'],
|
||||
g.current_account.id)
|
||||
if success:
|
||||
return '', 201
|
||||
|
||||
@swag_from('swagger/get_devices_spec.yaml')
|
||||
def get(self):
|
||||
return DevicesWrapperSchema().dump(
|
||||
{'devices': devices.get_devices(g.current_account.id)}), 200
|
||||
|
|
|
@ -14,7 +14,7 @@ responses:
|
|||
schema:
|
||||
type: object
|
||||
required:
|
||||
-device
|
||||
- device
|
||||
properties:
|
||||
device:
|
||||
$ref: '#/definitions/Device'
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
Gets all associated devices
|
||||
---
|
||||
tags:
|
||||
- Device
|
||||
parameters:
|
||||
responses:
|
||||
200:
|
||||
description: Success
|
||||
schema:
|
||||
type: object
|
||||
required:
|
||||
- devices
|
||||
properties:
|
||||
devices:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/definitions/Device'
|
||||
|
|
@ -1,13 +1,13 @@
|
|||
import sys
|
||||
from flask import Blueprint
|
||||
from .models import Device, Recording
|
||||
from .models import Device, Recording, DeviceAssociation
|
||||
from app import app
|
||||
|
||||
devices_bp = Blueprint('devices', __name__)
|
||||
|
||||
|
||||
# Public interface
|
||||
def create_device(name, device_type=1):
|
||||
def create_device(name, account_id, device_type=1):
|
||||
"""
|
||||
Tries to create device with given parameters
|
||||
|
||||
|
@ -21,6 +21,8 @@ def create_device(name, device_type=1):
|
|||
"""
|
||||
device = Device(name, None, device_type)
|
||||
device.save()
|
||||
device_association = DeviceAssociation(device.id, account_id)
|
||||
device_association.save()
|
||||
|
||||
|
||||
def get_device_recordings(device_id):
|
||||
|
@ -56,6 +58,16 @@ def get_device(device_id):
|
|||
return Device.get(id=device_id)
|
||||
|
||||
|
||||
def get_devices(account_id):
|
||||
"""
|
||||
Tries to get all devices associated to account. Raises error on
|
||||
failure
|
||||
|
||||
:returns: List of Devices associated to this account
|
||||
:rtype: List of Devices
|
||||
"""
|
||||
return Device.get_many_for_user(account_id)
|
||||
|
||||
def create_recording(device_id, raw_json):
|
||||
"""
|
||||
Tries to create recording with given parameters. Raises error on failure
|
||||
|
|
|
@ -92,6 +92,8 @@ class Device(db.Model):
|
|||
device_type = db.relationship("DeviceType", foreign_keys=[device_type_id])
|
||||
configuration = db.Column(JSON, nullable=True)
|
||||
|
||||
users = db.relationship("DeviceAssociation")
|
||||
|
||||
def __init__(self, name, configuration=None, device_type=1):
|
||||
self.name = name
|
||||
self.configuration = configuration
|
||||
|
@ -121,6 +123,13 @@ class Device(db.Model):
|
|||
"""
|
||||
return Device.query.filter_by(**kwargs).all()
|
||||
|
||||
@staticmethod
|
||||
def get_many_for_user(account_id):
|
||||
"""
|
||||
Get many devices which are associated to account
|
||||
"""
|
||||
return Device.query.filter(Device.users.any(account_id=account_id)).all()
|
||||
|
||||
@staticmethod
|
||||
def get(**kwargs):
|
||||
"""
|
||||
|
@ -150,6 +159,58 @@ class Device(db.Model):
|
|||
return '<Device (name=%s, type=%s)>' % (
|
||||
self.name, self.device_type_id)
|
||||
|
||||
|
||||
class DeviceAssociation(db.Model):
|
||||
__tablename__ = 'device_associations'
|
||||
|
||||
device_id = db.Column(db.Integer, db.ForeignKey('devices.id'), primary_key=True)
|
||||
account_id = db.Column(db.Integer, db.ForeignKey('accounts.id'), primary_key=True)
|
||||
access_level = db.Column(db.Integer, db.ForeignKey('access_levels.id'),
|
||||
nullable=False)
|
||||
|
||||
def __init__(self, device_id, account_id, access_level=1):
|
||||
self.device_id = device_id
|
||||
self.account_id = account_id
|
||||
self.access_level = access_level
|
||||
|
||||
def save(self):
|
||||
"""
|
||||
Stores this device association to database
|
||||
This may raise errors
|
||||
"""
|
||||
db.session.add(self)
|
||||
db.session.commit()
|
||||
|
||||
@staticmethod
|
||||
def get_many(**kwargs):
|
||||
"""
|
||||
Get many device associations with given filters as a list
|
||||
|
||||
Available filters:
|
||||
* device_id
|
||||
* account_id
|
||||
"""
|
||||
return DeviceAssociation.query.filter_by(**kwargs).all()
|
||||
|
||||
@staticmethod
|
||||
def get_for_user(account_id):
|
||||
"""
|
||||
Get many device associations for user with account id passed in
|
||||
parameter
|
||||
"""
|
||||
return get_many(account_id=account_id)
|
||||
|
||||
@staticmethod
|
||||
def get_for_device(device_id):
|
||||
"""
|
||||
Get many device associations for device with account id passed in
|
||||
parameter
|
||||
"""
|
||||
return get_many(device_id=device_id)
|
||||
|
||||
def __repr__(self):
|
||||
return '<DeviceAssociation (device_id=%s, accoount_id=%s)>' % (self.device_id, self.account_id)
|
||||
|
||||
|
||||
class DeviceType(db.Model):
|
||||
__tablename__ = 'device_types'
|
||||
|
@ -162,3 +223,16 @@ class DeviceType(db.Model):
|
|||
|
||||
def __repr__(self):
|
||||
return '<DeviceType (name %s)>' % self.name
|
||||
|
||||
|
||||
class AccessLevel(db.Model):
|
||||
__tablename__ = 'access_levels'
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
name = db.Column(db.String, nullable=False)
|
||||
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
|
||||
def __repr__(self):
|
||||
return '<AccessLevel (name %s)>' % self.name
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
"""empty message
|
||||
|
||||
Revision ID: efbd47fca2fd
|
||||
Revises: 6b444e5e2eef
|
||||
Create Date: 2018-08-24 14:23:01.904259
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = 'efbd47fca2fd'
|
||||
down_revision = '6b444e5e2eef'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.create_table('access_levels',
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('name', sa.String(), nullable=False),
|
||||
sa.PrimaryKeyConstraint('id')
|
||||
)
|
||||
op.create_table('device_associations',
|
||||
sa.Column('device_id', sa.Integer(), nullable=False),
|
||||
sa.Column('account_id', sa.Integer(), nullable=False),
|
||||
sa.Column('access_level', sa.Integer(), nullable=False),
|
||||
sa.ForeignKeyConstraint(['access_level'], ['access_levels.id'], ),
|
||||
sa.ForeignKeyConstraint(['account_id'], ['accounts.id'], ),
|
||||
sa.ForeignKeyConstraint(['device_id'], ['devices.id'], ),
|
||||
sa.PrimaryKeyConstraint('device_id', 'account_id')
|
||||
)
|
||||
|
||||
access_levels_table = sa.Table('access_levels', sa.MetaData(),
|
||||
sa.Column('id', sa.Integer),
|
||||
sa.Column('name', sa.String))
|
||||
|
||||
op.bulk_insert(access_levels_table,
|
||||
[
|
||||
{'id':1, 'name':'FULL'}
|
||||
]
|
||||
)
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_table('device_associations')
|
||||
op.drop_table('access_levels')
|
||||
# ### end Alembic commands ###
|
Loading…
Reference in New Issue