commit
5b436df1ea
|
@ -22,7 +22,8 @@ def add_resources():
|
||||||
DeviceTypeResource,
|
DeviceTypeResource,
|
||||||
DeviceTypeListResource,
|
DeviceTypeListResource,
|
||||||
DeviceConfigurationResource)
|
DeviceConfigurationResource)
|
||||||
from .resources.dashboard import DashboardResource, DashboardListResource
|
from .resources.dashboard import (DashboardResource,
|
||||||
|
DashboardListResource)
|
||||||
|
|
||||||
api.add_resource(AccountResource, '/v1/accounts/<int:account_id>')
|
api.add_resource(AccountResource, '/v1/accounts/<int:account_id>')
|
||||||
api.add_resource(AccountListResource, '/v1/accounts')
|
api.add_resource(AccountListResource, '/v1/accounts')
|
||||||
|
@ -44,9 +45,9 @@ def add_resources():
|
||||||
api.add_resource(DeviceTypeListResource, '/v1/devices/types')
|
api.add_resource(DeviceTypeListResource, '/v1/devices/types')
|
||||||
api.add_resource(DeviceConfigurationResource,
|
api.add_resource(DeviceConfigurationResource,
|
||||||
'/v1/devices/<int:device_id>/configuration')
|
'/v1/devices/<int:device_id>/configuration')
|
||||||
api.add_resource(DashboardListResource, '/v1/dashboards')
|
|
||||||
api.add_resource(DashboardResource,
|
api.add_resource(DashboardResource,
|
||||||
'/v1/dashboards/<int:dashboard_id>')
|
'/v1/dashboards/<int:dashboard_id>')
|
||||||
|
api.add_resource(DashboardListResource, '/v1/dashboards')
|
||||||
|
|
||||||
|
|
||||||
add_resources()
|
add_resources()
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from flask import g
|
from flask import g, request
|
||||||
from flask_restful import abort
|
from flask_restful import abort
|
||||||
from marshmallow import fields
|
from marshmallow import fields, Schema
|
||||||
from webargs.flaskparser import use_args
|
from webargs.flaskparser import use_args
|
||||||
from flasgger import swag_from
|
from flasgger import swag_from
|
||||||
import app.dashboards.api as dashboard
|
import app.dashboards.api as dashboard
|
||||||
|
@ -10,9 +10,14 @@ from app.api.schemas import BaseResourceSchema
|
||||||
|
|
||||||
class DashboardSchema(BaseResourceSchema):
|
class DashboardSchema(BaseResourceSchema):
|
||||||
id = fields.Integer(dump_only=True)
|
id = fields.Integer(dump_only=True)
|
||||||
|
active = fields.Boolean(required=False)
|
||||||
dashboard_data = fields.Raw()
|
dashboard_data = fields.Raw()
|
||||||
|
|
||||||
|
|
||||||
|
class DashboardIdSchema(Schema):
|
||||||
|
id = fields.Integer()
|
||||||
|
|
||||||
|
|
||||||
class DashboardResource(ProtectedResource):
|
class DashboardResource(ProtectedResource):
|
||||||
@swag_from('swagger/get_dashboard_spec.yaml')
|
@swag_from('swagger/get_dashboard_spec.yaml')
|
||||||
def get(self, dashboard_id):
|
def get(self, dashboard_id):
|
||||||
|
@ -29,9 +34,30 @@ class DashboardResource(ProtectedResource):
|
||||||
if requested_dashboard.account_id != g.current_account.id:
|
if requested_dashboard.account_id != g.current_account.id:
|
||||||
abort(403, message='You are not allowed to access this dashboard',
|
abort(403, message='You are not allowed to access this dashboard',
|
||||||
status='error')
|
status='error')
|
||||||
success = dashboard.update_dashboard(
|
if args.get('dashboard_data') is None:
|
||||||
|
abort(400, message='Missing dashboard_data', status='error')
|
||||||
|
if args.get('active') is None:
|
||||||
|
abort(400, message='Missing active', status='error')
|
||||||
|
success = dashboard.patch_dashboard(
|
||||||
|
g.current_account.id,
|
||||||
dashboard_id,
|
dashboard_id,
|
||||||
args['dashboard_data'])
|
args['dashboard_data'],
|
||||||
|
args['active'])
|
||||||
|
if success:
|
||||||
|
return '', 204
|
||||||
|
|
||||||
|
@use_args(DashboardSchema(), locations=('json',))
|
||||||
|
@swag_from('swagger/update_dashboard_spec.yaml')
|
||||||
|
def patch(self, args, dashboard_id):
|
||||||
|
requested_dashboard = dashboard.get_dashboard(dashboard_id)
|
||||||
|
if requested_dashboard.account_id != g.current_account.id:
|
||||||
|
abort(403, message='You are not allowed to access this dashboard',
|
||||||
|
status='error')
|
||||||
|
success = dashboard.patch_dashboard(
|
||||||
|
g.current_account.id,
|
||||||
|
dashboard_id,
|
||||||
|
args.get('dashboard_data'),
|
||||||
|
args.get('active'))
|
||||||
if success:
|
if success:
|
||||||
return '', 204
|
return '', 204
|
||||||
|
|
||||||
|
@ -57,5 +83,8 @@ class DashboardListResource(ProtectedResource):
|
||||||
|
|
||||||
@swag_from('swagger/get_dashboards_spec.yaml')
|
@swag_from('swagger/get_dashboards_spec.yaml')
|
||||||
def get(self):
|
def get(self):
|
||||||
|
request_args = request.args
|
||||||
return DashboardSchema().dump(
|
return DashboardSchema().dump(
|
||||||
dashboard.get_dashboards(g.current_account.id), many=True), 200
|
dashboard.get_dashboards(
|
||||||
|
g.current_account.id,
|
||||||
|
request_args.get('active')), many=True), 200
|
||||||
|
|
|
@ -2,6 +2,13 @@ Gets all associated dashboards
|
||||||
---
|
---
|
||||||
tags:
|
tags:
|
||||||
- Dashboard
|
- Dashboard
|
||||||
|
parameters:
|
||||||
|
- in: query
|
||||||
|
name: active
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: boolean
|
||||||
|
description: Filter for whether to display only active dashboard
|
||||||
responses:
|
responses:
|
||||||
200:
|
200:
|
||||||
description: Success
|
description: Success
|
||||||
|
|
|
@ -3,14 +3,14 @@ Gets all associated devices
|
||||||
tags:
|
tags:
|
||||||
- Device
|
- Device
|
||||||
parameters:
|
parameters:
|
||||||
- in: path
|
- in: query
|
||||||
name: page
|
name: page
|
||||||
required: false
|
required: false
|
||||||
schema:
|
schema:
|
||||||
type: integer
|
type: integer
|
||||||
minimum: 1
|
minimum: 1
|
||||||
description: requested page
|
description: requested page
|
||||||
- in: path
|
- in: query
|
||||||
name: per_page
|
name: per_page
|
||||||
required: false
|
required: false
|
||||||
schema:
|
schema:
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
Updates a dashboard
|
Updates a dashboard
|
||||||
|
Updating active state disables previous active dashboard
|
||||||
---
|
---
|
||||||
tags:
|
tags:
|
||||||
- Dashboard
|
- Dashboard
|
||||||
|
|
|
@ -23,7 +23,7 @@ class TokenResource(Resource):
|
||||||
args['password'])
|
args['password'])
|
||||||
if token:
|
if token:
|
||||||
return {'status': 'success', 'token': token}, 200
|
return {'status': 'success', 'token': token}, 200
|
||||||
except ValueError, e:
|
except ValueError as e:
|
||||||
abort(401, message=str(e), status='error')
|
abort(401, message=str(e), status='error')
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,8 @@ def get_dashboard(dashboard_id):
|
||||||
return Dashboard.get(id=dashboard_id)
|
return Dashboard.get(id=dashboard_id)
|
||||||
|
|
||||||
|
|
||||||
def update_dashboard(dashboard_id, dashboard_data):
|
def patch_dashboard(account_id, dashboard_id,
|
||||||
|
dashboard_data=None, active=None):
|
||||||
"""
|
"""
|
||||||
Tries to update dashboard with given parameters
|
Tries to update dashboard with given parameters
|
||||||
|
|
||||||
|
@ -38,9 +39,12 @@ def update_dashboard(dashboard_id, dashboard_data):
|
||||||
:type name: JSON
|
:type name: JSON
|
||||||
:type dashboard_id: int
|
:type dashboard_id: int
|
||||||
"""
|
"""
|
||||||
|
if dashboard_data is not None:
|
||||||
dashboard = Dashboard.get(id=dashboard_id)
|
dashboard = Dashboard.get(id=dashboard_id)
|
||||||
dashboard.dashboard_data = dashboard_data
|
dashboard.dashboard_data = dashboard_data
|
||||||
dashboard.save()
|
dashboard.save()
|
||||||
|
if active:
|
||||||
|
set_active_dashboard(account_id, dashboard_id)
|
||||||
|
|
||||||
|
|
||||||
def delete_dashboard(dashboard_id):
|
def delete_dashboard(dashboard_id):
|
||||||
|
@ -54,13 +58,42 @@ def delete_dashboard(dashboard_id):
|
||||||
dashboard.delete()
|
dashboard.delete()
|
||||||
|
|
||||||
|
|
||||||
def get_dashboards(account_id):
|
def set_active_dashboard(account_id, dashboard_id):
|
||||||
|
"""
|
||||||
|
Tries to set given dashboard as active
|
||||||
|
|
||||||
|
:param dashboard_id: Id of requested dashboard
|
||||||
|
:type name: int
|
||||||
|
:param dashboard_id: Id of owner account
|
||||||
|
:type name: int
|
||||||
|
"""
|
||||||
|
Dashboard.deactivate_all_for_user(account_id)
|
||||||
|
dashboard = Dashboard.get(id=dashboard_id)
|
||||||
|
dashboard.active = True
|
||||||
|
dashboard.save()
|
||||||
|
|
||||||
|
|
||||||
|
def get_active_dashboard(account_id):
|
||||||
|
"""
|
||||||
|
Tries to fetch active dashboard owned by account with given id
|
||||||
|
|
||||||
|
:param account_id: Id of owner account
|
||||||
|
:type name: int
|
||||||
|
:returns: active Dashboard object
|
||||||
|
:rtype: Dashboard
|
||||||
|
"""
|
||||||
|
return Dashboard.get(account_id=account_id, active=True)
|
||||||
|
|
||||||
|
|
||||||
|
def get_dashboards(account_id, active):
|
||||||
"""
|
"""
|
||||||
Tries to fetch dashboards owned by account with given id
|
Tries to fetch dashboards owned by account with given id
|
||||||
|
|
||||||
:param account_id: Id of owner account
|
:param account_id: Id of owner account
|
||||||
:type name: int
|
:type name: int
|
||||||
|
:param active: Whether to filter active only
|
||||||
|
:type name: bool
|
||||||
:returns: Dashboard list
|
:returns: Dashboard list
|
||||||
:rtype: List of Dashboard
|
:rtype: List of Dashboard
|
||||||
"""
|
"""
|
||||||
return Dashboard.get_many(account_id=account_id)
|
return Dashboard.get_many_filtered(account_id=account_id, active=active)
|
||||||
|
|
|
@ -9,6 +9,7 @@ class Dashboard(db.Model):
|
||||||
dashboard_data = db.Column(JSON, nullable=False)
|
dashboard_data = db.Column(JSON, nullable=False)
|
||||||
account_id = db.Column(db.Integer, db.ForeignKey('accounts.id'),
|
account_id = db.Column(db.Integer, db.ForeignKey('accounts.id'),
|
||||||
primary_key=True)
|
primary_key=True)
|
||||||
|
active = db.Column(db.Boolean, nullable=False, default=False)
|
||||||
created_at = db.Column(db.DateTime,
|
created_at = db.Column(db.DateTime,
|
||||||
nullable=False,
|
nullable=False,
|
||||||
default=db.func.current_timestamp())
|
default=db.func.current_timestamp())
|
||||||
|
@ -74,6 +75,28 @@ class Dashboard(db.Model):
|
||||||
"""
|
"""
|
||||||
return Dashboard.query.filter_by(**kwargs).all()
|
return Dashboard.query.filter_by(**kwargs).all()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_many_filtered(account_id, active):
|
||||||
|
"""
|
||||||
|
Get many dashboard with given filters
|
||||||
|
|
||||||
|
Available filters:
|
||||||
|
* active
|
||||||
|
"""
|
||||||
|
query = Dashboard.query.filter(Dashboard.account_id == account_id)
|
||||||
|
if active is not None:
|
||||||
|
query = query.filter(Dashboard.active == active)
|
||||||
|
return query.all()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def deactivate_all_for_user(account_id):
|
||||||
|
"""
|
||||||
|
Deactivates all dashboards for this user
|
||||||
|
"""
|
||||||
|
db.session.query(Dashboard).filter(account_id == account_id) \
|
||||||
|
.update({'active': False})
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get(**kwargs):
|
def get(**kwargs):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -224,10 +224,13 @@ definitions:
|
||||||
DashboardCreation:
|
DashboardCreation:
|
||||||
type: object
|
type: object
|
||||||
required:
|
required:
|
||||||
|
- active
|
||||||
- dashboard_data
|
- dashboard_data
|
||||||
properties:
|
properties:
|
||||||
dashboard_data:
|
dashboard_data:
|
||||||
$ref: '#/definitions/dashboarddata'
|
$ref: '#/definitions/dashboarddata'
|
||||||
|
active:
|
||||||
|
type: boolean
|
||||||
|
|
||||||
UnauthorizedError:
|
UnauthorizedError:
|
||||||
type: object
|
type: object
|
||||||
|
|
|
@ -2,7 +2,7 @@ import os
|
||||||
|
|
||||||
# App configuration
|
# App configuration
|
||||||
DEBUG = os.environ['DEBUG']
|
DEBUG = os.environ['DEBUG']
|
||||||
APP_VERSION = '0.2.1'
|
APP_VERSION = '0.2.2'
|
||||||
|
|
||||||
# Define the application directory
|
# Define the application directory
|
||||||
BASE_DIR = os.path.abspath(os.path.dirname(__file__))
|
BASE_DIR = os.path.abspath(os.path.dirname(__file__))
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
"""empty message
|
||||||
|
|
||||||
|
Revision ID: 4945e4c8fbca
|
||||||
|
Revises: ae43d7caad52
|
||||||
|
Create Date: 2018-10-10 22:50:41.087670
|
||||||
|
|
||||||
|
"""
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = '4945e4c8fbca'
|
||||||
|
down_revision = 'ae43d7caad52'
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.add_column('dashboards', sa.Column('active', sa.Boolean(),
|
||||||
|
nullable=False, server_default='False'))
|
||||||
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
op.drop_column('dashboards', 'active')
|
||||||
|
# ### end Alembic commands ###
|
|
@ -1 +0,0 @@
|
||||||
python-2.7.15
|
|
Loading…
Reference in New Issue