Merged in feature/device-documentation (pull request #59)

Feature/device documentation
develop
Ensar Sarajcic 2018-11-04 14:08:24 +00:00
commit 8745c5e783
8 changed files with 197 additions and 1 deletions

View File

@ -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,

View File

@ -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):

View File

@ -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'

View File

@ -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'

View File

@ -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

View File

@ -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'

View File

@ -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:

View File

@ -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 ###