Merged in develop (pull request #16)

Version 0.2.2 release
master
Ensar Sarajcic 2018-10-15 17:54:43 +00:00
commit 5b436df1ea
12 changed files with 143 additions and 18 deletions

View File

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

View File

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

View File

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

View File

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

View File

@ -1,4 +1,5 @@
Updates a dashboard Updates a dashboard
Updating active state disables previous active dashboard
--- ---
tags: tags:
- Dashboard - Dashboard

View File

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

View File

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

View File

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

View File

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

View File

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

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

View File

@ -1 +0,0 @@
python-2.7.15