now scanning model difinietons and updating db entries
This commit is contained in:
1
Pipfile
1
Pipfile
@@ -22,6 +22,7 @@ python-jose = "*"
|
||||
flask-jwt-extended = "*"
|
||||
ssh2-python = "*"
|
||||
update = "*"
|
||||
flask-cors = "*"
|
||||
|
||||
[dev-packages]
|
||||
|
||||
|
||||
146
Pipfile.lock
generated
146
Pipfile.lock
generated
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "0b4fd0972054dfeecdd89492b1128706d5c26dc7dcdf85f35b9261ccc8b02c7a"
|
||||
"sha256": "79518b33814e3afda968f02d6de17856076a2d7a81183eb7ee1c219eccc114cc"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
@@ -38,10 +38,10 @@
|
||||
},
|
||||
"apispec": {
|
||||
"hashes": [
|
||||
"sha256:427293594699c77753b8fdc6d78d8dfe267c394df5186c236d57f6ef1af95027",
|
||||
"sha256:edad7a67fae5576fd3e97888b05d228573bf75b2dc0d2714d7cea0480662ac19"
|
||||
"sha256:11d1aaf620a80f67ded7688fcaf14fa4fd975d566876b5db69b067ffbfe4d1d9",
|
||||
"sha256:2f4734203e53f6ae6499d1f2168d19e62f04f071d6e4b86c6d6014ebf2ebdf6b"
|
||||
],
|
||||
"version": "==2.0.1"
|
||||
"version": "==2.0.2"
|
||||
},
|
||||
"asn1crypto": {
|
||||
"hashes": [
|
||||
@@ -119,40 +119,41 @@
|
||||
},
|
||||
"coverage": {
|
||||
"hashes": [
|
||||
"sha256:3684fabf6b87a369017756b551cef29e505cb155ddb892a7a29277b978da88b9",
|
||||
"sha256:39e088da9b284f1bd17c750ac672103779f7954ce6125fd4382134ac8d152d74",
|
||||
"sha256:3c205bc11cc4fcc57b761c2da73b9b72a59f8d5ca89979afb0c1c6f9e53c7390",
|
||||
"sha256:465ce53a8c0f3a7950dfb836438442f833cf6663d407f37d8c52fe7b6e56d7e8",
|
||||
"sha256:48020e343fc40f72a442c8a1334284620f81295256a6b6ca6d8aa1350c763bbe",
|
||||
"sha256:5296fc86ab612ec12394565c500b412a43b328b3907c0d14358950d06fd83baf",
|
||||
"sha256:5f61bed2f7d9b6a9ab935150a6b23d7f84b8055524e7be7715b6513f3328138e",
|
||||
"sha256:68a43a9f9f83693ce0414d17e019daee7ab3f7113a70c79a3dd4c2f704e4d741",
|
||||
"sha256:6b8033d47fe22506856fe450470ccb1d8ba1ffb8463494a15cfc96392a288c09",
|
||||
"sha256:7ad7536066b28863e5835e8cfeaa794b7fe352d99a8cded9f43d1161be8e9fbd",
|
||||
"sha256:7bacb89ccf4bedb30b277e96e4cc68cd1369ca6841bde7b005191b54d3dd1034",
|
||||
"sha256:839dc7c36501254e14331bcb98b27002aa415e4af7ea039d9009409b9d2d5420",
|
||||
"sha256:8f9a95b66969cdea53ec992ecea5406c5bd99c9221f539bca1e8406b200ae98c",
|
||||
"sha256:932c03d2d565f75961ba1d3cec41ddde00e162c5b46d03f7423edcb807734eab",
|
||||
"sha256:988529edadc49039d205e0aa6ce049c5ccda4acb2d6c3c5c550c17e8c02c05ba",
|
||||
"sha256:998d7e73548fe395eeb294495a04d38942edb66d1fa61eb70418871bc621227e",
|
||||
"sha256:9de60893fb447d1e797f6bf08fdf0dbcda0c1e34c1b06c92bd3a363c0ea8c609",
|
||||
"sha256:9e80d45d0c7fcee54e22771db7f1b0b126fb4a6c0a2e5afa72f66827207ff2f2",
|
||||
"sha256:a545a3dfe5082dc8e8c3eb7f8a2cf4f2870902ff1860bd99b6198cfd1f9d1f49",
|
||||
"sha256:a5d8f29e5ec661143621a8f4de51adfb300d7a476224156a39a392254f70687b",
|
||||
"sha256:aca06bfba4759bbdb09bf52ebb15ae20268ee1f6747417837926fae990ebc41d",
|
||||
"sha256:bb23b7a6fd666e551a3094ab896a57809e010059540ad20acbeec03a154224ce",
|
||||
"sha256:bfd1d0ae7e292105f29d7deaa9d8f2916ed8553ab9d5f39ec65bcf5deadff3f9",
|
||||
"sha256:c62ca0a38958f541a73cf86acdab020c2091631c137bd359c4f5bddde7b75fd4",
|
||||
"sha256:c709d8bda72cf4cd348ccec2a4881f2c5848fd72903c185f363d361b2737f773",
|
||||
"sha256:c968a6aa7e0b56ecbd28531ddf439c2ec103610d3e2bf3b75b813304f8cb7723",
|
||||
"sha256:df785d8cb80539d0b55fd47183264b7002077859028dfe3070cf6359bf8b2d9c",
|
||||
"sha256:f406628ca51e0ae90ae76ea8398677a921b36f0bd71aab2099dfed08abd0322f",
|
||||
"sha256:f46087bbd95ebae244a0eda01a618aff11ec7a069b15a3ef8f6b520db523dcf1",
|
||||
"sha256:f8019c5279eb32360ca03e9fac40a12667715546eed5c5eb59eb381f2f501260",
|
||||
"sha256:fc5f4d209733750afd2714e9109816a29500718b32dd9a5db01c0cb3a019b96a"
|
||||
"sha256:08907593569fe59baca0bf152c43f3863201efb6113ecb38ce7e97ce339805a6",
|
||||
"sha256:0be0f1ed45fc0c185cfd4ecc19a1d6532d72f86a2bac9de7e24541febad72650",
|
||||
"sha256:141f08ed3c4b1847015e2cd62ec06d35e67a3ac185c26f7635f4406b90afa9c5",
|
||||
"sha256:19e4df788a0581238e9390c85a7a09af39c7b539b29f25c89209e6c3e371270d",
|
||||
"sha256:23cc09ed395b03424d1ae30dcc292615c1372bfba7141eb85e11e50efaa6b351",
|
||||
"sha256:245388cda02af78276b479f299bbf3783ef0a6a6273037d7c60dc73b8d8d7755",
|
||||
"sha256:331cb5115673a20fb131dadd22f5bcaf7677ef758741312bee4937d71a14b2ef",
|
||||
"sha256:386e2e4090f0bc5df274e720105c342263423e77ee8826002dcffe0c9533dbca",
|
||||
"sha256:3a794ce50daee01c74a494919d5ebdc23d58873747fa0e288318728533a3e1ca",
|
||||
"sha256:60851187677b24c6085248f0a0b9b98d49cba7ecc7ec60ba6b9d2e5574ac1ee9",
|
||||
"sha256:63a9a5fc43b58735f65ed63d2cf43508f462dc49857da70b8980ad78d41d52fc",
|
||||
"sha256:6b62544bb68106e3f00b21c8930e83e584fdca005d4fffd29bb39fb3ffa03cb5",
|
||||
"sha256:6ba744056423ef8d450cf627289166da65903885272055fb4b5e113137cfa14f",
|
||||
"sha256:7494b0b0274c5072bddbfd5b4a6c6f18fbbe1ab1d22a41e99cd2d00c8f96ecfe",
|
||||
"sha256:826f32b9547c8091679ff292a82aca9c7b9650f9fda3e2ca6bf2ac905b7ce888",
|
||||
"sha256:93715dffbcd0678057f947f496484e906bf9509f5c1c38fc9ba3922893cda5f5",
|
||||
"sha256:9a334d6c83dfeadae576b4d633a71620d40d1c379129d587faa42ee3e2a85cce",
|
||||
"sha256:af7ed8a8aa6957aac47b4268631fa1df984643f07ef00acd374e456364b373f5",
|
||||
"sha256:bf0a7aed7f5521c7ca67febd57db473af4762b9622254291fbcbb8cd0ba5e33e",
|
||||
"sha256:bf1ef9eb901113a9805287e090452c05547578eaab1b62e4ad456fcc049a9b7e",
|
||||
"sha256:c0afd27bc0e307a1ffc04ca5ec010a290e49e3afbe841c5cafc5c5a80ecd81c9",
|
||||
"sha256:dd579709a87092c6dbee09d1b7cfa81831040705ffa12a1b248935274aee0437",
|
||||
"sha256:df6712284b2e44a065097846488f66840445eb987eb81b3cc6e4149e7b6982e1",
|
||||
"sha256:e07d9f1a23e9e93ab5c62902833bf3e4b1f65502927379148b6622686223125c",
|
||||
"sha256:e2ede7c1d45e65e209d6093b762e98e8318ddeff95317d07a27a2140b80cfd24",
|
||||
"sha256:e4ef9c164eb55123c62411f5936b5c2e521b12356037b6e1c2617cef45523d47",
|
||||
"sha256:eca2b7343524e7ba246cab8ff00cab47a2d6d54ada3b02772e908a45675722e2",
|
||||
"sha256:eee64c616adeff7db37cc37da4180a3a5b6177f5c46b187894e633f088fb5b28",
|
||||
"sha256:ef824cad1f980d27f26166f86856efe11eff9912c4fed97d3804820d43fa550c",
|
||||
"sha256:efc89291bd5a08855829a3c522df16d856455297cf35ae827a37edac45f466a7",
|
||||
"sha256:fa964bae817babece5aa2e8c1af841bebb6d0b9add8e637548809d040443fee0",
|
||||
"sha256:ff37757e068ae606659c28c3bd0d923f9d29a85de79bf25b2b34b148473b5025"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==4.5.3"
|
||||
"version": "==4.5.4"
|
||||
},
|
||||
"cryptography": {
|
||||
"hashes": [
|
||||
@@ -191,11 +192,19 @@
|
||||
},
|
||||
"flask": {
|
||||
"hashes": [
|
||||
"sha256:ad7c6d841e64296b962296c2c2dabc6543752985727af86a975072dea984b6f3",
|
||||
"sha256:e7d32475d1de5facaa55e3958bc4ec66d3762076b074296aa50ef8fdc5b9df61"
|
||||
"sha256:13f9f196f330c7c2c5d7a5cf91af894110ca0215ac051b5844701f2bfd934d52",
|
||||
"sha256:45eb5a6fd193d6cf7e0cf5d8a5b31f83d5faae0293695626f539a823e93b13f6"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.0.3"
|
||||
"version": "==1.1.1"
|
||||
},
|
||||
"flask-cors": {
|
||||
"hashes": [
|
||||
"sha256:72170423eb4612f0847318afff8c247b38bd516b7737adfc10d1c2cdbb382d16",
|
||||
"sha256:f4d97201660e6bbcff2d89d082b5b6d31abee04b1b3003ee073a6fd25ad1d69a"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==3.0.8"
|
||||
},
|
||||
"flask-httpauth": {
|
||||
"hashes": [
|
||||
@@ -207,10 +216,10 @@
|
||||
},
|
||||
"flask-jwt-extended": {
|
||||
"hashes": [
|
||||
"sha256:583a6e363ea51434c4189e35d3832a23949cfa5203d60a8287b6be137a75528d"
|
||||
"sha256:d671b24981a1d09d8f21c7b2681ce7b4bde33e2dfcb98be50ae412fc5908ec79"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==3.19.0"
|
||||
"version": "==3.21.0"
|
||||
},
|
||||
"flask-login": {
|
||||
"hashes": [
|
||||
@@ -236,10 +245,10 @@
|
||||
},
|
||||
"flask-pyoidc": {
|
||||
"hashes": [
|
||||
"sha256:6a8fac4459ae5c65f710ec77877391d55b338068405b89f1f4a4394770ef1114"
|
||||
"sha256:fb95c452c62de7ec6290fbb5ab8590753541c399e7b817d7d8badd0e9ad6fd52"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.0.0"
|
||||
"version": "==2.2.0"
|
||||
},
|
||||
"flask-restplus": {
|
||||
"hashes": [
|
||||
@@ -306,16 +315,16 @@
|
||||
},
|
||||
"jsonschema": {
|
||||
"hashes": [
|
||||
"sha256:0c0a81564f181de3212efa2d17de1910f8732fa1b71c42266d983cd74304e20d",
|
||||
"sha256:a5f6559964a3851f59040d3b961de5e68e70971afb88ba519d27e6a039efff1a"
|
||||
"sha256:5f9c0a719ca2ce14c5de2fd350a64fd2d13e8539db29836a86adc990bb1a068f",
|
||||
"sha256:8d4a2b7b6c2237e0199c8ea1a6d3e05bf118e289ae2b9d7ba444182a2959560d"
|
||||
],
|
||||
"version": "==3.0.1"
|
||||
"version": "==3.0.2"
|
||||
},
|
||||
"mako": {
|
||||
"hashes": [
|
||||
"sha256:95ee720cc3453063788515d55bd7ce4a2a77b7b209e4ac70ec5c86091eb02541"
|
||||
"sha256:a36919599a9b7dc5d86a7a8988f23a9a3a3d083070023bab23d64f7f1d1e0a4b"
|
||||
],
|
||||
"version": "==1.0.13"
|
||||
"version": "==1.1.0"
|
||||
},
|
||||
"markupsafe": {
|
||||
"hashes": [
|
||||
@@ -373,20 +382,21 @@
|
||||
},
|
||||
"pbr": {
|
||||
"hashes": [
|
||||
"sha256:9181e2a34d80f07a359ff1d0504fad3a47e00e1cf2c475b0aa7dcb030af54c40",
|
||||
"sha256:94bdc84da376b3dd5061aa0c3b6faffe943ee2e56fa4ff9bd63e1643932f34fc"
|
||||
"sha256:56e52299170b9492513c64be44736d27a512fa7e606f21942160b68ce510b4bc",
|
||||
"sha256:9b321c204a88d8ab5082699469f52cc94c5da45c51f114113d01b3d993c24cdf"
|
||||
],
|
||||
"version": "==5.3.1"
|
||||
"version": "==5.4.2"
|
||||
},
|
||||
"pyasn1": {
|
||||
"hashes": [
|
||||
"sha256:da2420fe13a9452d8ae97a0e478adde1dee153b11ba832a95b223a2ba01c10f7",
|
||||
"sha256:da6b43a8c9ae93bc80e2739efb38cc776ba74a886e3e9318d65fe81a8b8a2c6e"
|
||||
"sha256:3bb81821d47b17146049e7574ab4bf1e315eb7aead30efe5d6a9ca422c9710be",
|
||||
"sha256:b773d5c9196ffbc3a1e13bdf909d446cad80a039aa3340bcad72f395b76ebc86"
|
||||
],
|
||||
"version": "==0.4.5"
|
||||
"version": "==0.4.6"
|
||||
},
|
||||
"pycparser": {
|
||||
"hashes": [
|
||||
"sha256:50f84b9531cf541192a39303722ea4d69cab456fc1104ca47f66b9b8dd7be740",
|
||||
"sha256:a988718abfad80b6b157acce7bf130a30876d27603738ac39f140993246b25b3"
|
||||
],
|
||||
"version": "==2.19"
|
||||
@@ -447,9 +457,9 @@
|
||||
},
|
||||
"pyrsistent": {
|
||||
"hashes": [
|
||||
"sha256:16692ee739d42cf5e39cef8d27649a8c1fdb7aa99887098f1460057c5eb75c3a"
|
||||
"sha256:34b47fa169d6006b32e99d4b3c4031f155e6e68ebcc107d6454852e8e0ee6533"
|
||||
],
|
||||
"version": "==0.15.2"
|
||||
"version": "==0.15.4"
|
||||
},
|
||||
"python-dateutil": {
|
||||
"hashes": [
|
||||
@@ -476,10 +486,10 @@
|
||||
},
|
||||
"pytz": {
|
||||
"hashes": [
|
||||
"sha256:303879e36b721603cc54604edcac9d20401bdbe31e1e4fdee5b9f98d5d31dfda",
|
||||
"sha256:d747dd3d23d77ef44c6a3526e274af6efeb0a6f1afd5a69ba4d5be4098c8e141"
|
||||
"sha256:26c0b32e437e54a18161324a2fca3c4b9846b74a8dccddd843113109e1116b32",
|
||||
"sha256:c894d57500a4cd2d5c71114aaab77dbab5eabd9022308ce5ac9bb93a60a6f0c7"
|
||||
],
|
||||
"version": "==2019.1"
|
||||
"version": "==2019.2"
|
||||
},
|
||||
"requests": {
|
||||
"hashes": [
|
||||
@@ -504,10 +514,10 @@
|
||||
},
|
||||
"sqlalchemy": {
|
||||
"hashes": [
|
||||
"sha256:c30925d60af95443458ebd7525daf791f55762b106049ae71e18f8dd58084c2f"
|
||||
"sha256:217e7fc52199a05851eee9b6a0883190743c4fb9c8ac4313ccfceaffd852b0ff"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.3.5"
|
||||
"version": "==1.3.6"
|
||||
},
|
||||
"sqlalchemy-migrate": {
|
||||
"hashes": [
|
||||
@@ -579,18 +589,18 @@
|
||||
},
|
||||
"webargs": {
|
||||
"hashes": [
|
||||
"sha256:6b81ce44572d4f345104aa41c734fdc01165f054a061a8ebb1b46e89851e1170",
|
||||
"sha256:713bd63440ee078ce48ca953d254d51e5f1a6fa0c76fb521fc596306c78d95a5",
|
||||
"sha256:e2394ea7e422c1e795681cee5e8b1c6083bab7db6d7a380841130cbbae173d29"
|
||||
"sha256:132216236980316da205a4cfb571913109a07a2e014bcc2313b72d0b83dce507",
|
||||
"sha256:538c9f333f1f7ce06a1eb14b3daf640351057907be71b58d2b5a23c7d6d026be",
|
||||
"sha256:63cecd4dc79f504c31c33a8470624f79f54c1b35a23141cc52c5a3fa37dc674b"
|
||||
],
|
||||
"version": "==5.3.2"
|
||||
"version": "==5.4.0"
|
||||
},
|
||||
"werkzeug": {
|
||||
"hashes": [
|
||||
"sha256:865856ebb55c4dcd0630cdd8f3331a1847a819dda7e8c750d3db6f2aa6c0209c",
|
||||
"sha256:a0b915f0815982fb2a09161cb8f31708052d0951c3ba433ccc5e1aa276507ca6"
|
||||
"sha256:87ae4e5b5366da2347eb3116c0e6c681a0e939a33b2805e2c0cbd282664932c4",
|
||||
"sha256:a13b74dd3c45f758d4ebdb224be8f1ab8ef58b3c0ffc1783a8c7d9f4f50227e6"
|
||||
],
|
||||
"version": "==0.15.4"
|
||||
"version": "==0.15.5"
|
||||
}
|
||||
},
|
||||
"develop": {}
|
||||
|
||||
@@ -10,6 +10,7 @@ from flask_httpauth import HTTPTokenAuth, HTTPBasicAuth, MultiAuth
|
||||
from flask_jwt_extended import JWTManager, decode_token
|
||||
from flask_login import LoginManager
|
||||
from flask_sqlalchemy import SQLAlchemy
|
||||
from flask_cors import CORS
|
||||
|
||||
app = Flask(__name__)
|
||||
app.config.from_object('backend.config.Config')
|
||||
@@ -62,6 +63,9 @@ app.register_blueprint(auth_api_bp)
|
||||
app.register_blueprint(api_bp)
|
||||
app.register_blueprint(fe_bp)
|
||||
|
||||
CORS(app)
|
||||
CORS(api_bp)
|
||||
|
||||
# Fix flask-restplus by duck typing error handlers
|
||||
jwt_extended._set_error_handler_callbacks(api_v1)
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import ssl
|
||||
|
||||
from jinja2.exceptions import TemplateNotFound
|
||||
|
||||
from backend import app
|
||||
from backend import app, db
|
||||
|
||||
|
||||
def main():
|
||||
@@ -23,6 +23,12 @@ def main():
|
||||
except FileNotFoundError:
|
||||
app.run(debug=True, threaded=True)
|
||||
|
||||
try:
|
||||
db.create_all()
|
||||
except Exception as e:
|
||||
logging.CRITICAL(e)
|
||||
|
||||
|
||||
app.run(debug=True)
|
||||
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ Login through API does not start a new session, but instead returns JWT.
|
||||
"""
|
||||
import inspect
|
||||
import pkgutil
|
||||
from pprint import pprint
|
||||
|
||||
from flask_jwt_extended import jwt_required
|
||||
from flask_restplus import fields, Resource
|
||||
@@ -44,6 +45,30 @@ recorder_model = api_recorder.model('Recorder', {
|
||||
description='Room in which the recorder is located.')
|
||||
})
|
||||
|
||||
recorder_command_model = api_recorder.model('Recorder Command', {
|
||||
'id': fields.String(required=False, description='The recorder command\'s identifier'),
|
||||
'name': fields.String(required=True, description='The recorder command\'s name'),
|
||||
'last_time_modified': fields.DateTime(required=False),
|
||||
'description': fields.String(required=False, description='The recorder command\'s description'),
|
||||
'parameters': fields.String(required=True, description='The recorder parameters'),
|
||||
'recorder_model': fields.Nested(api_recorder.model('recorder_command_models',
|
||||
{'id': fields.Integer(), 'name': fields.String()})),
|
||||
})
|
||||
|
||||
recorder_model_model = api_recorder.model('Recorder Model', {
|
||||
'id': fields.String(required=False, description='The recorder model\'s identifier'),
|
||||
'name': fields.String(attribute="model_name", required=True, description='The recorder model\'s name'),
|
||||
'last_time_modified': fields.DateTime(required=False),
|
||||
'notes': fields.String(required=False, description='The recorder model\'s notes'),
|
||||
|
||||
'recorders': fields.List(fields.Nested(api_recorder.model('recorder_model',
|
||||
{'id': fields.Integer(), 'name': fields.String(),
|
||||
'network_name': fields.String(),
|
||||
'ip': fields.String()})), required=False,
|
||||
description='Model of the recorder.'),
|
||||
'commands': fields.List(fields.Nested(recorder_command_model), attribute="recorder_commands")
|
||||
})
|
||||
|
||||
|
||||
# ==
|
||||
|
||||
@@ -119,30 +144,14 @@ class RecorderList(Resource):
|
||||
if rec_model is not None:
|
||||
api_recorder.payload["recorder_model"] = rec_model
|
||||
else:
|
||||
return "specified recorder model (id: {}) does not exist!".format(api_recorder.payload["recorder_model_id"]), 404
|
||||
return "specified recorder model (id: {}) does not exist!".format(
|
||||
api_recorder.payload["recorder_model_id"]), 404
|
||||
recorder = Recorder(**api_recorder.payload)
|
||||
db.session.add(recorder)
|
||||
db.session.commit()
|
||||
return recorder
|
||||
|
||||
|
||||
recorder_model_model = api_recorder.model('Recorder Model', {
|
||||
'id': fields.String(required=False, description='The recorder model\'s identifier'),
|
||||
'name': fields.String(required=True, description='The recorder model\'s name'),
|
||||
'notes': fields.String(required=False, description='The recorder model\'s notes'),
|
||||
|
||||
'recorders': fields.List(fields.Nested(api_recorder.model('recorder_model',
|
||||
{'id': fields.Integer(), 'name': fields.String(),
|
||||
'network_name': fields.String(),
|
||||
'ip': fields.String()})), required=False,
|
||||
description='Model of the recorder.'),
|
||||
'commands': fields.List(fields.Nested(api_recorder.model('recorder_model_commands',
|
||||
{'id': fields.Integer(), 'name': fields.String()})),
|
||||
required=False,
|
||||
description='Room in which the recorder is located.')
|
||||
})
|
||||
|
||||
|
||||
@api_recorder.route('/model/<int:id>')
|
||||
@api_recorder.response(404, 'Recorder Model not found')
|
||||
@api_recorder.param('id', 'The recorder model identifier')
|
||||
@@ -157,10 +166,12 @@ class RecorderModelResource(Resource):
|
||||
return recorder_model
|
||||
api_recorder.abort(404)
|
||||
|
||||
recorder_model_parser = api_recorder.parser()
|
||||
recorder_model_parser.add_argument('notes', type=str, required=True)
|
||||
|
||||
@jwt_required
|
||||
@api_recorder.doc('update_recorder_model')
|
||||
@api_recorder.expect(recorder_model_model)
|
||||
@api_recorder.expect(recorder_model_parser)
|
||||
@api_recorder.marshal_with(recorder_model_model)
|
||||
def put(self, id):
|
||||
"""Update a recorder_model given its identifier"""
|
||||
@@ -173,32 +184,11 @@ class RecorderModelResource(Resource):
|
||||
|
||||
@api_recorder.route('/model')
|
||||
class RecorderModelList(Resource):
|
||||
#@jwt_required
|
||||
@jwt_required
|
||||
@api_recorder.doc('recorders')
|
||||
@api_recorder.marshal_list_with(recorder_model_model)
|
||||
def get(self):
|
||||
models = r_a.get_defined_recorder_adapters()
|
||||
return models
|
||||
"""
|
||||
List all recorder models
|
||||
:return: recorder models
|
||||
"""
|
||||
return Recorder.get_all()
|
||||
|
||||
|
||||
# ==
|
||||
|
||||
|
||||
recorder_command_model = api_recorder.model('Recorder Command', {
|
||||
'id': fields.String(required=False, description='The recorder command\'s identifier'),
|
||||
'name': fields.String(required=True, description='The recorder command\'s name'),
|
||||
'description': fields.String(required=False, description='The recorder command\'s description'),
|
||||
'command': fields.String(required=True, description='The recorder command\'s name'),
|
||||
'recorder_models': fields.List(fields.Nested(api_recorder.model('recorder_command_models',
|
||||
{'id': fields.Integer(), 'name': fields.String()})),
|
||||
required=False,
|
||||
description='Recorder models associated with the command.'),
|
||||
})
|
||||
return RecorderModel.get_all()
|
||||
|
||||
|
||||
@api_recorder.route('/command/<int:id>')
|
||||
|
||||
@@ -5,44 +5,49 @@ Models for lecture recorder
|
||||
import json
|
||||
|
||||
from sqlalchemy import MetaData
|
||||
from sqlalchemy.ext.hybrid import hybrid_property
|
||||
|
||||
from backend import db, app, login_manager
|
||||
import re
|
||||
from sqlalchemy import or_
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from backend.models.virtual_command_model import virtual_command_recorder_command_table
|
||||
from backend.models.virtual_command_model import virtual_command_recorder_command_table, virtual_command_recorder_table
|
||||
|
||||
metadata = MetaData()
|
||||
|
||||
# This is the association table for the many-to-many relationship between
|
||||
# groups and permissions.
|
||||
recorder_model_recorder_command_table = db.Table('recorder_model_recorder_command',
|
||||
db.Column('recorder_model_id', db.Integer,
|
||||
db.ForeignKey('recorder_model.id',
|
||||
onupdate="CASCADE",
|
||||
ondelete="CASCADE"),
|
||||
primary_key=True),
|
||||
db.Column('recorder_command_id', db.Integer,
|
||||
db.ForeignKey('recorder_command.id',
|
||||
onupdate="CASCADE",
|
||||
ondelete="CASCADE"),
|
||||
primary_key=True))
|
||||
|
||||
|
||||
class RecorderModel(db.Model):
|
||||
id = db.Column(db.Integer, autoincrement=True, primary_key=True)
|
||||
last_time_modified = db.Column(db.DateTime, nullable=True, default=None)
|
||||
record_adapter_id = db.Column(db.Unicode(63), unique=True, nullable=False)
|
||||
model_name = db.Column(db.Unicode(63), unique=True, nullable=False)
|
||||
model_checksum = db.Column(db.String(63), unique=True, nullable=True)
|
||||
notes = db.Column(db.Unicode(255), unique=False, nullable=True, default=None)
|
||||
recorder_commands = db.relationship('RecorderCommand', secondary=recorder_model_recorder_command_table,
|
||||
back_populates='recorder_models')
|
||||
recorder_commands = db.relationship('RecorderCommand', back_populates='recorder_model')
|
||||
recorders = db.relationship('Recorder', back_populates='recorder_model')
|
||||
checksum = db.Column(db.String(63), unique=True, nullable=False)
|
||||
|
||||
@staticmethod
|
||||
def get_all():
|
||||
return RecorderModel.query.all()
|
||||
|
||||
@staticmethod
|
||||
def get_by_name(name):
|
||||
return RecorderModel.query.filter(RecorderModel.model_name == name).first()
|
||||
|
||||
@staticmethod
|
||||
def get_by_adapter_id(name):
|
||||
return RecorderModel.query.filter(RecorderModel.record_adapter_id == name).first()
|
||||
|
||||
@staticmethod
|
||||
def get_by_checksum(md5_sum):
|
||||
return RecorderModel.query.filter(RecorderModel.checksum == md5_sum).first()
|
||||
|
||||
|
||||
class Recorder(db.Model):
|
||||
id = db.Column(db.Integer, autoincrement=True, primary_key=True)
|
||||
created_at = db.Column(db.DateTime, nullable=False, default=datetime.utcnow())
|
||||
last_time_modified = db.Column(db.DateTime, nullable=False, default=datetime.utcnow())
|
||||
name = db.Column(db.Unicode(63), unique=True, nullable=False)
|
||||
description = db.Column(db.Unicode(255), unique=False, nullable=True, default="")
|
||||
room_id = db.Column(db.Integer, db.ForeignKey('room.id'))
|
||||
@@ -53,27 +58,17 @@ class Recorder(db.Model):
|
||||
ssh_port = db.Column(db.Integer, unique=False, nullable=False, default=22)
|
||||
recorder_model_id = db.Column(db.Integer, db.ForeignKey('recorder_model.id'))
|
||||
recorder_model = db.relationship('RecorderModel', back_populates='recorders')
|
||||
virtual_commands = db.relationship('VirtualCommand', back_populates='recorders')
|
||||
virtual_commands = db.relationship('VirtualCommand', secondary=virtual_command_recorder_table, back_populates='recorders')
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(Recorder, self).__init__(**kwargs)
|
||||
|
||||
|
||||
@staticmethod
|
||||
def get_by_name(name):
|
||||
"""
|
||||
Find group by name
|
||||
:param name:
|
||||
:return:
|
||||
"""
|
||||
return Recorder.query.filter(Recorder.name == name).first()
|
||||
|
||||
@staticmethod
|
||||
def get_all():
|
||||
"""
|
||||
Return all groups
|
||||
:return:
|
||||
"""
|
||||
return Recorder.query.all()
|
||||
|
||||
def __str__(self):
|
||||
@@ -90,11 +85,26 @@ class Recorder(db.Model):
|
||||
class RecorderCommand(db.Model):
|
||||
"""Table containing permissions associated with groups."""
|
||||
id = db.Column(db.Integer, autoincrement=True, primary_key=True)
|
||||
last_time_modified = db.Column(db.DateTime, nullable=True, default=None)
|
||||
name = db.Column(db.Unicode(63), unique=True, nullable=False)
|
||||
description = db.Column(db.Unicode(511), nullable=True, default=None)
|
||||
parameters = db.Column(db.String(2047), nullable=True)
|
||||
recorder_models = db.relationship('RecorderModel', secondary=recorder_model_recorder_command_table,
|
||||
back_populates='recorder_commands')
|
||||
|
||||
parameters_string = db.Column(db.String(2047), nullable=True)
|
||||
recorder_model = db.relationship('RecorderModel', back_populates='recorder_commands')
|
||||
recorder_model_id = db.Column(db.Integer, db.ForeignKey('recorder_model.id'))
|
||||
virtual_commands = db.relationship('VirtualCommand', secondary=virtual_command_recorder_command_table,
|
||||
back_populates='recorder_commands')
|
||||
|
||||
@staticmethod
|
||||
def get_all():
|
||||
return RecorderCommand.query.all()
|
||||
|
||||
@hybrid_property
|
||||
def parameters(self):
|
||||
if self.parameters_string is None:
|
||||
return []
|
||||
print(self.parameters_string)
|
||||
return json.loads(self.parameters_string)
|
||||
|
||||
@parameters.setter
|
||||
def parameters(self, parameters_dict: dict):
|
||||
self.parameters_string = json.dumps(parameters_dict)
|
||||
|
||||
@@ -460,4 +460,5 @@ class Permission(db.Model):
|
||||
@event.listens_for(Permission.__table__, 'after_create')
|
||||
def insert_initial_permissions(*args, **kwargs):
|
||||
for p in app.config.get("PERMISSIONS", []):
|
||||
db.session.add(p)
|
||||
db.session.add(Permission(name=p))
|
||||
db.session.commit()
|
||||
|
||||
@@ -2,37 +2,37 @@ import json
|
||||
from datetime import datetime
|
||||
|
||||
from sqlalchemy.ext.hybrid import hybrid_property
|
||||
from sqlalchemy.orm import backref
|
||||
|
||||
from backend import db
|
||||
|
||||
# This is the association table for the many-to-many relationship between
|
||||
# virtual commands and recorder commands.
|
||||
virtual_command_recorder_command_table = db.Table('virtual_command_recorder_command',
|
||||
db.Column('virtual_command_id', db.Integer,
|
||||
db.ForeignKey('virtual_command.id',
|
||||
onupdate="CASCADE",
|
||||
ondelete="CASCADE"),
|
||||
primary_key=True),
|
||||
db.Column('recorder_command_id', db.Integer,
|
||||
db.ForeignKey('recorder_command.id',
|
||||
onupdate="CASCADE",
|
||||
ondelete="CASCADE"),
|
||||
primary_key=True))
|
||||
|
||||
db.Column('virtual_command_id', db.Integer,
|
||||
db.ForeignKey('virtual_command.id',
|
||||
onupdate="CASCADE",
|
||||
ondelete="CASCADE"),
|
||||
primary_key=True),
|
||||
db.Column('recorder_command_id', db.Integer,
|
||||
db.ForeignKey('recorder_command.id',
|
||||
onupdate="CASCADE",
|
||||
ondelete="CASCADE"),
|
||||
primary_key=True))
|
||||
|
||||
# This is the association table for the many-to-many relationship between
|
||||
# virtual commands and recorder commands.
|
||||
virtual_command_recorder_table = db.Table('virtual_command_recorder',
|
||||
db.Column('virtual_command_id', db.Integer,
|
||||
db.ForeignKey('virtual_command.id',
|
||||
onupdate="CASCADE",
|
||||
ondelete="CASCADE"),
|
||||
primary_key=True),
|
||||
db.Column('recorder_id', db.Integer,
|
||||
db.ForeignKey('recorder.id',
|
||||
onupdate="CASCADE",
|
||||
ondelete="CASCADE"),
|
||||
primary_key=True))
|
||||
db.Column('virtual_command_id', db.Integer,
|
||||
db.ForeignKey('virtual_command.id',
|
||||
onupdate="CASCADE",
|
||||
ondelete="CASCADE"),
|
||||
primary_key=True),
|
||||
db.Column('recorder_id', db.Integer,
|
||||
db.ForeignKey('recorder.id',
|
||||
onupdate="CASCADE",
|
||||
ondelete="CASCADE"),
|
||||
primary_key=True))
|
||||
|
||||
|
||||
class VirtualCommand(db.Model):
|
||||
@@ -47,9 +47,10 @@ class VirtualCommand(db.Model):
|
||||
recorder_commands = db.relationship('RecorderCommand', secondary=virtual_command_recorder_command_table,
|
||||
back_populates='virtual_commands')
|
||||
|
||||
parent_virtual_command = db.relationship('VirtualCommand', back_populates='child_virtual_commands',
|
||||
nullable=True, default=None)
|
||||
child_virtual_commands = db.relationship('VirtualCommand', back_populates='parent_virtual_command')
|
||||
# parent_virtual_command = db.relationship('VirtualCommand', back_populates='child_virtual_commands')
|
||||
parent_virtual_command_id = db.Column(db.Integer, db.ForeignKey('virtual_command.id'))
|
||||
child_virtual_commands = db.relationship('VirtualCommand',
|
||||
backref=backref('parent_virtual_command', remote_side=[id]))
|
||||
|
||||
command_order_string = db.Column(db.String)
|
||||
|
||||
|
||||
@@ -5,8 +5,6 @@ import telnetlib
|
||||
from abc import ABC, abstractmethod
|
||||
|
||||
# monkey patching of telnet lib
|
||||
from pprint import pprint
|
||||
|
||||
original_read_until = telnetlib.Telnet.read_until
|
||||
original_write = telnetlib.Telnet.write
|
||||
|
||||
@@ -131,8 +129,4 @@ def get_defined_recorder_adapters():
|
||||
commands[method_name] = parameters
|
||||
rec_model["commands"] = commands
|
||||
models.append(rec_model)
|
||||
pprint(models)
|
||||
return models
|
||||
|
||||
|
||||
get_defined_recorder_adapters()
|
||||
|
||||
2
tools/__init__.py
Normal file
2
tools/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
||||
# Copyright (c) 2019. Tobias Kurze, KIT
|
||||
|
||||
69
tools/model_updater.py
Normal file
69
tools/model_updater.py
Normal file
@@ -0,0 +1,69 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (c) 2019. Tobias Kurze
|
||||
|
||||
import hashlib
|
||||
import logging
|
||||
from datetime import datetime
|
||||
from json import dumps
|
||||
from pprint import pprint
|
||||
|
||||
from sqlalchemy import and_
|
||||
|
||||
from backend import db
|
||||
from backend.models.recorder_model import RecorderModel, RecorderCommand
|
||||
from backend.recorder_adapters import get_defined_recorder_adapters
|
||||
|
||||
|
||||
def calculate_md5_checksum(string_to_md5_sum: str):
|
||||
return hashlib.md5(string_to_md5_sum.encode('utf-8')).hexdigest()
|
||||
|
||||
|
||||
def create_recorder_commands_for_recorder_adapter(command_definitions: dict, recorder_model: RecorderModel):
|
||||
existing_recorder_commands = RecorderCommand.query.filter(and_(RecorderCommand.name.in_(command_definitions.keys())),
|
||||
RecorderCommand.recorder_model == recorder_model)
|
||||
existing_commands = set()
|
||||
for existing_command in existing_recorder_commands:
|
||||
existing_commands.add(existing_command.name)
|
||||
args = command_definitions.get(existing_command.name)
|
||||
if dumps(existing_command.parameters) != dumps(args):
|
||||
logging.warning(
|
||||
"The function definition {} collides with an existing definition of the same name "
|
||||
"but different parameters!".format(
|
||||
existing_command.name))
|
||||
existing_command.last_time_modified = datetime.utcnow()
|
||||
existing_command.parameters = args
|
||||
db.session.commit()
|
||||
|
||||
for c_d in set(command_definitions.keys()) - existing_commands:
|
||||
# print(c_d)
|
||||
args = command_definitions.get(c_d)
|
||||
# create new recorder command(s)
|
||||
r_c = RecorderCommand(name=c_d, parameters=args, recorder_model=recorder_model)
|
||||
db.session.add(r_c)
|
||||
db.session.commit()
|
||||
|
||||
|
||||
def update_recorder_models_database():
|
||||
r_as = get_defined_recorder_adapters()
|
||||
for r_a in r_as:
|
||||
r_m = RecorderModel.get_by_adapter_id(r_a["id"])
|
||||
model_checksum = calculate_md5_checksum(dumps(r_a["commands"]))
|
||||
if r_m is None:
|
||||
r_m = RecorderModel(record_adapter_id=r_a["id"], model_name=r_a["name"], checksum=model_checksum)
|
||||
db.session.add(r_m)
|
||||
db.session.flush()
|
||||
db.session.refresh(r_m)
|
||||
else:
|
||||
if not model_checksum == r_m.checksum:
|
||||
r_m.model_name = r_a["name"]
|
||||
r_m.model_name = r_a["name"]
|
||||
r_m.checksum = model_checksum
|
||||
create_recorder_commands_for_recorder_adapter(r_a["commands"], r_m)
|
||||
db.session.commit()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
db.create_all()
|
||||
update_recorder_models_database()
|
||||
Reference in New Issue
Block a user