commit
8745c5e783
|
@ -24,6 +24,7 @@ def add_resources():
|
|||
DeviceTypeResource,
|
||||
DeviceTypeListResource,
|
||||
DeviceConfigurationResource,
|
||||
DeviceDocumentationResource,
|
||||
DeviceSecretResource,
|
||||
DeviceSecretResetResource,
|
||||
DeviceShareResource,
|
||||
|
@ -56,6 +57,8 @@ def add_resources():
|
|||
api.add_resource(DeviceTypeListResource, '/v1/devices/types')
|
||||
api.add_resource(DeviceConfigurationResource,
|
||||
'/v1/devices/<int:device_id>/configuration')
|
||||
api.add_resource(DeviceDocumentationResource,
|
||||
'/v1/devices/<int:device_id>/documentation')
|
||||
api.add_resource(DeviceSecretResource,
|
||||
'/v1/devices/<int:device_id>/secret')
|
||||
api.add_resource(DeviceSecretResetResource,
|
||||
|
|
|
@ -45,6 +45,11 @@ class RecordingsQuerySchema(Schema):
|
|||
orders = fields.Raw()
|
||||
|
||||
|
||||
class DeviceDocumentationSchema(BaseTimestampedResourceSchema):
|
||||
device_id = fields.Integer(dump_only=True)
|
||||
text = fields.String(required=True)
|
||||
|
||||
|
||||
class DeviceSecretSchema(BaseResourceSchema):
|
||||
device_secret = fields.String(dump_only=True)
|
||||
secret_algorithm = fields.String(required=True)
|
||||
|
@ -167,6 +172,23 @@ class DeviceConfigurationResource(ProtectedResource):
|
|||
return devices.get_device_configuration(device_id), 200
|
||||
|
||||
|
||||
class DeviceDocumentationResource(ProtectedResource):
|
||||
@use_args(DeviceDocumentationSchema(), locations=('json',))
|
||||
@swag_from('swagger/update_device_documentation_spec.yaml')
|
||||
def put(self, args, device_id):
|
||||
validate_device_ownership(device_id)
|
||||
update_device_documentation = devices.update_device_documentation(
|
||||
device_id, args['text'])
|
||||
return DeviceDocumentationSchema().dump(
|
||||
update_device_documentation), 200
|
||||
|
||||
@swag_from('swagger/get_device_documentation_spec.yaml')
|
||||
def get(self, device_id):
|
||||
validate_device_ownership(device_id)
|
||||
return DeviceDocumentationSchema().dump(
|
||||
devices.get_device_documentation(device_id)), 200
|
||||
|
||||
|
||||
class DeviceSecretResource(ProtectedResource):
|
||||
@swag_from('swagger/get_device_secret_spec.yaml')
|
||||
def get(self, device_id):
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
Gets a device documentation
|
||||
---
|
||||
tags:
|
||||
- Device
|
||||
- Docs
|
||||
parameters:
|
||||
- in: path
|
||||
name: device_id
|
||||
required: true
|
||||
type: integer
|
||||
description: Id of the device
|
||||
responses:
|
||||
200:
|
||||
description: Success
|
||||
schema:
|
||||
$ref: '#/definitions/DeviceDocumentation'
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
Updates a device documentation
|
||||
---
|
||||
tags:
|
||||
- Device
|
||||
- Docs
|
||||
parameters:
|
||||
- in: path
|
||||
name: device_id
|
||||
required: true
|
||||
type: integer
|
||||
description: Id of the device
|
||||
- in: body
|
||||
name: body
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/DeviceDocumentation'
|
||||
responses:
|
||||
200:
|
||||
description: Success
|
||||
schema:
|
||||
type: object
|
||||
required:
|
||||
- content
|
||||
properties:
|
||||
content:
|
||||
$ref: '#/definitions/DeviceDocumentation'
|
|
@ -8,7 +8,8 @@ from .models import (Device,
|
|||
Recording,
|
||||
DeviceAssociation,
|
||||
DeviceType,
|
||||
AccessLevel)
|
||||
AccessLevel,
|
||||
DeviceDocumentation)
|
||||
from itsdangerous import URLSafeSerializer
|
||||
from app.core import app
|
||||
from app.errors import NotPresentError
|
||||
|
@ -238,6 +239,29 @@ def get_devices(account_id):
|
|||
return Device.get_many_for_user(account_id)
|
||||
|
||||
|
||||
def get_device_documentation(device_id):
|
||||
"""
|
||||
Tries to get device documentation associated to given device.
|
||||
|
||||
:returns: DeviceDocumentation
|
||||
"""
|
||||
if not Device.exists(id=device_id):
|
||||
raise NotPresentError("Device with id %s does not exist" % device_id)
|
||||
return DeviceDocumentation.get_for_device(device_id)
|
||||
|
||||
|
||||
def update_device_documentation(device_id, new_text):
|
||||
"""
|
||||
Tries to update device documentation
|
||||
"""
|
||||
if not Device.exists(id=device_id):
|
||||
raise NotPresentError("Device with id %s does not exist" % device_id)
|
||||
device_documentation = DeviceDocumentation.get_for_device(device_id)
|
||||
device_documentation.text = new_text
|
||||
device_documentation.save()
|
||||
return device_documentation
|
||||
|
||||
|
||||
def get_device_types():
|
||||
"""
|
||||
Tries to get all device types. Raises error on failure
|
||||
|
|
|
@ -137,6 +137,8 @@ class Device(db.Model):
|
|||
cascade="save-update, merge, delete")
|
||||
widgets = db.relationship("DashboardWidget",
|
||||
cascade="save-update, merge, delete")
|
||||
documentations = db.relationship("DeviceDocumentation",
|
||||
cascade="save-update, merge, delete")
|
||||
|
||||
def __init__(self, name, configuration=None, device_type=1):
|
||||
self.name = name
|
||||
|
@ -341,6 +343,54 @@ class DeviceType(db.Model):
|
|||
return '<DeviceType (name %s)>' % self.name
|
||||
|
||||
|
||||
class DeviceDocumentation(db.Model):
|
||||
__tablename__ = 'device_documentations'
|
||||
|
||||
device_id = db.Column(db.Integer, db.ForeignKey('devices.id'),
|
||||
primary_key=True)
|
||||
text = db.Column(db.Text, nullable=False)
|
||||
created_at = db.Column(db.DateTime,
|
||||
nullable=False,
|
||||
default=db.func.current_timestamp())
|
||||
modified_at = db.Column(db.DateTime,
|
||||
nullable=False,
|
||||
default=db.func.current_timestamp(),
|
||||
onupdate=db.func.current_timestamp())
|
||||
|
||||
def __init__(self, device_id, text):
|
||||
self.device_id = device_id
|
||||
self.text = text
|
||||
|
||||
def save(self):
|
||||
"""
|
||||
Stores this device documentation to database
|
||||
This may raise errors
|
||||
"""
|
||||
db.session.add(self)
|
||||
db.session.commit()
|
||||
|
||||
@staticmethod
|
||||
def get(**kwargs):
|
||||
"""
|
||||
Get device documentation with given filters
|
||||
|
||||
Available filters:
|
||||
* device_id
|
||||
"""
|
||||
return DeviceDocumentation.query.filter_by(**kwargs).first()
|
||||
|
||||
@staticmethod
|
||||
def get_for_device(device_id):
|
||||
"""
|
||||
Get documentation for device with device id passed in
|
||||
parameter
|
||||
"""
|
||||
return (DeviceDocumentation.get(device_id=device_id) or
|
||||
DeviceDocumentation(device_id, ""))
|
||||
|
||||
def __repr__(self):
|
||||
return '<DeviceDocumentation (device_id %s)>' % self.device_id
|
||||
|
||||
class AccessLevel(db.Model):
|
||||
__tablename__ = 'access_levels'
|
||||
|
||||
|
|
|
@ -233,6 +233,25 @@ definitions:
|
|||
modified_at:
|
||||
$ref: '#/definitions/datetime'
|
||||
|
||||
DeviceDocumentation:
|
||||
type: object
|
||||
required:
|
||||
- device_id
|
||||
- text
|
||||
- created_at
|
||||
- modified_at
|
||||
properties:
|
||||
device_id:
|
||||
$ref: '#/definitions/id'
|
||||
text:
|
||||
type: string
|
||||
description: Text of documentation
|
||||
example: This device is used for ...
|
||||
created_at:
|
||||
$ref: '#/definitions/datetime'
|
||||
modified_at:
|
||||
$ref: '#/definitions/datetime'
|
||||
|
||||
DeviceShareTokenCreation:
|
||||
type: object
|
||||
required:
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
"""empty message
|
||||
|
||||
Revision ID: 9f71f5a68c53
|
||||
Revises: 3cf41808886b
|
||||
Create Date: 2018-11-04 15:00:35.383875
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '9f71f5a68c53'
|
||||
down_revision = '3cf41808886b'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.create_table('device_documentations',
|
||||
sa.Column('device_id', sa.Integer(), nullable=False),
|
||||
sa.Column('text', sa.Text(), nullable=False),
|
||||
sa.Column('created_at', sa.DateTime(), nullable=False),
|
||||
sa.Column('modified_at', sa.DateTime(), nullable=False),
|
||||
sa.ForeignKeyConstraint(['device_id'], ['devices.id'], ),
|
||||
sa.PrimaryKeyConstraint('device_id')
|
||||
)
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_table('device_documentations')
|
||||
# ### end Alembic commands ###
|
Loading…
Reference in New Issue