Passed
Push — master ( cb176a...4b8481 )
by
unknown
13:30
created

core.sensor.SensorPointCollection.on_post()   C

Complexity

Conditions 8

Size

Total Lines 64
Code Lines 50

Duplication

Lines 64
Ratio 100 %

Importance

Changes 0
Metric Value
eloc 50
dl 64
loc 64
rs 6.7696
c 0
b 0
f 0
cc 8
nop 3

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
import uuid
2
from datetime import datetime, timedelta
3
import falcon
4
import mysql.connector
5
import simplejson as json
6
from core.useractivity import user_logger, admin_control, access_control, api_key_control
7
import config
8
9
10
class SensorCollection:
11
    """
12
    Sensor Collection Resource
13
14
    This class handles CRUD operations for sensor collection.
15
    It provides endpoints for listing all sensors and creating new sensors.
16
    Sensors represent data collection devices in the energy management system.
17
    """
18
19
    def __init__(self):
20
        """Initialize SensorCollection"""
21
        pass
22
23
    @staticmethod
24
    def on_options(req, resp):
25
        """Handle OPTIONS requests for CORS preflight"""
26
        _ = req
27
        resp.status = falcon.HTTP_200
28
29
    @staticmethod
30
    def on_get(req, resp):
31
        if 'API-KEY' not in req.headers or \
32
                not isinstance(req.headers['API-KEY'], str) or \
33
                len(str.strip(req.headers['API-KEY'])) == 0:
34
            access_control(req)
35
        else:
36
            api_key_control(req)
37
38
        search_query = req.get_param('q', default=None)
39
        if search_query is not None:
40
            search_query = search_query.strip()
41
        else:
42
            search_query = ''
43
44
        cnx = mysql.connector.connect(**config.myems_system_db)
45
        cursor = cnx.cursor()
46
47
        query = (" SELECT id, name, uuid, description "
48
                 " FROM tbl_sensors ")
49
50
        params = []
51
        if search_query:
52
            query += " WHERE name LIKE %s   OR  description LIKE %s "
53
            params = [f'%{search_query}%', f'%{search_query}%']
54
        query += " ORDER BY id "
55
        cursor.execute(query, params)
56
57
        rows_sensors = cursor.fetchall()
58
59
        result = list()
60
        if rows_sensors is not None and len(rows_sensors) > 0:
61
            for row in rows_sensors:
62
                meta_result = {"id": row[0],
63
                               "name": row[1],
64
                               "uuid": row[2],
65
                               "description": row[3]}
66
                result.append(meta_result)
67
68
        cursor.close()
69
        cnx.close()
70
        resp.text = json.dumps(result)
71
72 View Code Duplication
    @staticmethod
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
73
    @user_logger
74
    def on_post(req, resp):
75
        """Handles POST requests"""
76
        admin_control(req)
77
        try:
78
            raw_json = req.stream.read().decode('utf-8')
79
        except UnicodeDecodeError as ex:
80
            print("Failed to decode request")
81
            raise falcon.HTTPError(status=falcon.HTTP_400,
82
                                   title='API.BAD_REQUEST',
83
                                   description='API.INVALID_ENCODING')
84
        except Exception as ex:
85
            print("Unexpected error reading request stream")
86
            raise falcon.HTTPError(status=falcon.HTTP_400,
87
                                   title='API.BAD_REQUEST',
88
                                   description='API.FAILED_TO_READ_REQUEST_STREAM')
89
90
        new_values = json.loads(raw_json)
91
92
        if 'name' not in new_values['data'].keys() or \
93
                not isinstance(new_values['data']['name'], str) or \
94
                len(str.strip(new_values['data']['name'])) == 0:
95
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
96
                                   description='API.INVALID_SENSOR_NAME')
97
        name = str.strip(new_values['data']['name'])
98
99
        if 'description' in new_values['data'].keys() and \
100
                new_values['data']['description'] is not None and \
101
                len(str(new_values['data']['description'])) > 0:
102
            description = str.strip(new_values['data']['description'])
103
        else:
104
            description = None
105
106
        cnx = mysql.connector.connect(**config.myems_system_db)
107
        cursor = cnx.cursor()
108
109
        cursor.execute(" SELECT name "
110
                       " FROM tbl_sensors "
111
                       " WHERE name = %s ", (name,))
112
        if cursor.fetchone() is not None:
113
            cursor.close()
114
            cnx.close()
115
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
116
                                   description='API.SENSOR_NAME_IS_ALREADY_IN_USE')
117
118
        add_values = (" INSERT INTO tbl_sensors "
119
                      "    (name, uuid, description) "
120
                      " VALUES (%s, %s, %s) ")
121
        cursor.execute(add_values, (name,
122
                                    str(uuid.uuid4()),
123
                                    description))
124
        new_id = cursor.lastrowid
125
        cnx.commit()
126
        cursor.close()
127
        cnx.close()
128
129
        resp.status = falcon.HTTP_201
130
        resp.location = '/sensors/' + str(new_id)
131
132
133
class SensorItem:
134
    def __init__(self):
135
        pass
136
137
    @staticmethod
138
    def on_options(req, resp, id_):
139
        _ = req
140
        resp.status = falcon.HTTP_200
141
        _ = id_
142
143
    @staticmethod
144
    def on_get(req, resp, id_):
145
        if 'API-KEY' not in req.headers or \
146
                not isinstance(req.headers['API-KEY'], str) or \
147
                len(str.strip(req.headers['API-KEY'])) == 0:
148
            access_control(req)
149
        else:
150
            api_key_control(req)
151
        if not id_.isdigit() or int(id_) <= 0:
152
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
153
                                   description='API.INVALID_SENSOR_ID')
154
155
        cnx = mysql.connector.connect(**config.myems_system_db)
156
        cursor = cnx.cursor()
157
158
        query = (" SELECT id, name, uuid, description "
159
                 " FROM tbl_sensors "
160
                 " WHERE id = %s ")
161
        cursor.execute(query, (id_,))
162
        row = cursor.fetchone()
163
        cursor.close()
164
        cnx.close()
165
166
        if row is None:
167
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
168
                                   description='API.SENSOR_NOT_FOUND')
169
        else:
170
            meta_result = {"id": row[0],
171
                           "name": row[1],
172
                           "uuid": row[2],
173
                           "description": row[3]}
174
175
        resp.text = json.dumps(meta_result)
176
177 View Code Duplication
    @staticmethod
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
178
    @user_logger
179
    def on_delete(req, resp, id_):
180
        admin_control(req)
181
        if not id_.isdigit() or int(id_) <= 0:
182
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
183
                                   description='API.INVALID_SENSOR_ID')
184
185
        cnx = mysql.connector.connect(**config.myems_system_db)
186
        cursor = cnx.cursor()
187
188
        cursor.execute(" SELECT name "
189
                       " FROM tbl_sensors "
190
                       " WHERE id = %s ", (id_,))
191
        if cursor.fetchone() is None:
192
            cursor.close()
193
            cnx.close()
194
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
195
                                   description='API.SENSOR_NOT_FOUND')
196
197
        # check relation with spaces
198
        cursor.execute(" SELECT id "
199
                       " FROM tbl_spaces_sensors "
200
                       " WHERE sensor_id = %s ", (id_,))
201
        rows_spaces = cursor.fetchall()
202
        if rows_spaces is not None and len(rows_spaces) > 0:
203
            cursor.close()
204
            cnx.close()
205
            raise falcon.HTTPError(status=falcon.HTTP_400,
206
                                   title='API.BAD_REQUEST',
207
                                   description='API.THERE_IS_RELATION_WITH_SPACES')
208
209
        # check relation with tenants
210
        cursor.execute(" SELECT id "
211
                       " FROM tbl_tenants_sensors "
212
                       " WHERE sensor_id = %s ", (id_,))
213
        rows_tenants = cursor.fetchall()
214
        if rows_tenants is not None and len(rows_tenants) > 0:
215
            cursor.close()
216
            cnx.close()
217
            raise falcon.HTTPError(status=falcon.HTTP_400,
218
                                   title='API.BAD_REQUEST',
219
                                   description='API.THERE_IS_RELATION_WITH_TENANTS')
220
221
        # check relation with stores
222
        cursor.execute(" SELECT store_id "
223
                       " FROM tbl_stores_sensors "
224
                       " WHERE sensor_id = %s ", (id_,))
225
        rows_stores = cursor.fetchall()
226
        if rows_stores is not None and len(rows_stores) > 0:
227
            cursor.close()
228
            cnx.close()
229
            raise falcon.HTTPError(status=falcon.HTTP_400,
230
                                   title='API.BAD_REQUEST',
231
                                   description='API.THERE_IS_RELATION_WITH_STORES')
232
233
        # check relation with microgrid
234
        cursor.execute(" SELECT id "
235
                       " FROM tbl_microgrids_sensors "
236
                       " WHERE sensor_id = %s ", (id_,))
237
        rows_microgrid = cursor.fetchall()
238
        if rows_microgrid is not None and len(rows_microgrid) > 0:
239
            cursor.close()
240
            cnx.close()
241
            raise falcon.HTTPError(status=falcon.HTTP_400,
242
                                   title='API.BAD_REQUEST',
243
                                   description='API.THERE_IS_RELATION_WITH_MICROGRIDS')
244
245
        # check relation with shopfloors
246
        cursor.execute(" SELECT id "
247
                       " FROM tbl_shopfloors_sensors "
248
                       " WHERE sensor_id = %s ", (id_,))
249
        rows_shopfloor = cursor.fetchall()
250
        if rows_shopfloor is not None and len(rows_shopfloor) > 0:
251
            cursor.close()
252
            cnx.close()
253
            raise falcon.HTTPError(status=falcon.HTTP_400,
254
                                   title='API.BAD_REQUEST',
255
                                   description='API.THERE_IS_RELATION_WITH_SHOPFLOORS')
256
257
        # delete relation with points
258
        cursor.execute(" DELETE FROM tbl_sensors_points WHERE sensor_id = %s ", (id_,))
259
260
        cursor.execute(" DELETE FROM tbl_sensors WHERE id = %s ", (id_,))
261
        cnx.commit()
262
263
        cursor.close()
264
        cnx.close()
265
266
        resp.status = falcon.HTTP_204
267
268 View Code Duplication
    @staticmethod
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
269
    @user_logger
270
    def on_put(req, resp, id_):
271
        """Handles PUT requests"""
272
        admin_control(req)
273
        try:
274
            raw_json = req.stream.read().decode('utf-8')
275
        except UnicodeDecodeError as ex:
276
            print("Failed to decode request")
277
            raise falcon.HTTPError(status=falcon.HTTP_400,
278
                                   title='API.BAD_REQUEST',
279
                                   description='API.INVALID_ENCODING')
280
        except Exception as ex:
281
            print("Unexpected error reading request stream")
282
            raise falcon.HTTPError(status=falcon.HTTP_400,
283
                                   title='API.BAD_REQUEST',
284
                                   description='API.FAILED_TO_READ_REQUEST_STREAM')
285
286
        if not id_.isdigit() or int(id_) <= 0:
287
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
288
                                   description='API.INVALID_SENSOR_ID')
289
290
        new_values = json.loads(raw_json)
291
292
        if 'name' not in new_values['data'].keys() or \
293
                not isinstance(new_values['data']['name'], str) or \
294
                len(str.strip(new_values['data']['name'])) == 0:
295
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
296
                                   description='API.INVALID_SENSOR_NAME')
297
        name = str.strip(new_values['data']['name'])
298
299
        if 'description' in new_values['data'].keys() and \
300
                new_values['data']['description'] is not None and \
301
                len(str(new_values['data']['description'])) > 0:
302
            description = str.strip(new_values['data']['description'])
303
        else:
304
            description = None
305
306
        cnx = mysql.connector.connect(**config.myems_system_db)
307
        cursor = cnx.cursor()
308
309
        cursor.execute(" SELECT name "
310
                       " FROM tbl_sensors "
311
                       " WHERE id = %s ", (id_,))
312
        if cursor.fetchone() is None:
313
            cursor.close()
314
            cnx.close()
315
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
316
                                   description='API.SENSOR_NOT_FOUND')
317
318
        cursor.execute(" SELECT name "
319
                       " FROM tbl_sensors "
320
                       " WHERE name = %s AND id != %s ", (name, id_))
321
        if cursor.fetchone() is not None:
322
            cursor.close()
323
            cnx.close()
324
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
325
                                   description='API.SENSOR_NAME_IS_ALREADY_IN_USE')
326
327
        update_row = (" UPDATE tbl_sensors "
328
                      " SET name = %s, description = %s "
329
                      " WHERE id = %s ")
330
        cursor.execute(update_row, (name,
331
                                    description,
332
                                    id_,))
333
        cnx.commit()
334
335
        cursor.close()
336
        cnx.close()
337
338
        resp.status = falcon.HTTP_200
339
340
341
class SensorPointCollection:
342
    def __init__(self):
343
        pass
344
345
    @staticmethod
346
    def on_options(req, resp, id_):
347
        _ = req
348
        resp.status = falcon.HTTP_200
349
        _ = id_
350
351 View Code Duplication
    @staticmethod
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
352
    def on_get(req, resp, id_):
353
        if 'API-KEY' not in req.headers or \
354
                not isinstance(req.headers['API-KEY'], str) or \
355
                len(str.strip(req.headers['API-KEY'])) == 0:
356
            access_control(req)
357
        else:
358
            api_key_control(req)
359
        if not id_.isdigit() or int(id_) <= 0:
360
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
361
                                   description='API.INVALID_SENSOR_ID')
362
363
        cnx = mysql.connector.connect(**config.myems_system_db)
364
        cursor = cnx.cursor()
365
366
        cursor.execute(" SELECT name "
367
                       " FROM tbl_sensors "
368
                       " WHERE id = %s ", (id_,))
369
        if cursor.fetchone() is None:
370
            cursor.close()
371
            cnx.close()
372
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
373
                                   description='API.SENSOR_NOT_FOUND')
374
375
        query = (" SELECT p.id, p.name, "
376
                 "        ds.id, ds.name, ds.uuid, "
377
                 "        p.address "
378
                 " FROM tbl_points p, tbl_sensors_points sp, tbl_data_sources ds "
379
                 " WHERE sp.sensor_id = %s AND p.id = sp.point_id AND p.data_source_id = ds.id "
380
                 " ORDER BY p.name ")
381
        cursor.execute(query, (id_,))
382
        rows = cursor.fetchall()
383
384
        result = list()
385
        if rows is not None and len(rows) > 0:
386
            for row in rows:
387
                meta_result = {"id": row[0], "name": row[1],
388
                               "data_source": {"id": row[2], "name": row[3], "uuid": row[4]},
389
                               "address": row[5]}
390
                result.append(meta_result)
391
392
        resp.text = json.dumps(result)
393
394 View Code Duplication
    @staticmethod
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
395
    @user_logger
396
    def on_post(req, resp, id_):
397
        """Handles POST requests"""
398
        admin_control(req)
399
        try:
400
            raw_json = req.stream.read().decode('utf-8')
401
        except UnicodeDecodeError as ex:
402
            print("Failed to decode request")
403
            raise falcon.HTTPError(status=falcon.HTTP_400,
404
                                   title='API.BAD_REQUEST',
405
                                   description='API.INVALID_ENCODING')
406
        except Exception as ex:
407
            print("Unexpected error reading request stream")
408
            raise falcon.HTTPError(status=falcon.HTTP_400,
409
                                   title='API.BAD_REQUEST',
410
                                   description='API.FAILED_TO_READ_REQUEST_STREAM')
411
412
        if not id_.isdigit() or int(id_) <= 0:
413
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
414
                                   description='API.INVALID_SENSOR_ID')
415
416
        new_values = json.loads(raw_json)
417
418
        cnx = mysql.connector.connect(**config.myems_system_db)
419
        cursor = cnx.cursor()
420
421
        cursor.execute(" SELECT name "
422
                       " from tbl_sensors "
423
                       " WHERE id = %s ", (id_,))
424
        if cursor.fetchone() is None:
425
            cursor.close()
426
            cnx.close()
427
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
428
                                   description='API.SENSOR_NOT_FOUND')
429
430
        cursor.execute(" SELECT name "
431
                       " FROM tbl_points "
432
                       " WHERE id = %s ", (new_values['data']['point_id'],))
433
        if cursor.fetchone() is None:
434
            cursor.close()
435
            cnx.close()
436
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
437
                                   description='API.POINT_NOT_FOUND')
438
439
        query = (" SELECT id "
440
                 " FROM tbl_sensors_points "
441
                 " WHERE sensor_id = %s AND point_id = %s")
442
        cursor.execute(query, (id_, new_values['data']['point_id'],))
443
        if cursor.fetchone() is not None:
444
            cursor.close()
445
            cnx.close()
446
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.ERROR',
447
                                   description='API.SENSOR_POINT_RELATION_EXISTS')
448
449
        add_row = (" INSERT INTO tbl_sensors_points (sensor_id, point_id) "
450
                   " VALUES (%s, %s) ")
451
        cursor.execute(add_row, (id_, new_values['data']['point_id'],))
452
        cnx.commit()
453
        cursor.close()
454
        cnx.close()
455
456
        resp.status = falcon.HTTP_201
457
        resp.location = '/sensors/' + str(id_) + '/points/' + str(new_values['data']['point_id'])
458
459
460
class SensorPointItem:
461
    def __init__(self):
462
        pass
463
464
    @staticmethod
465
    def on_options(req, resp, id_, pid):
466
        _ = req
467
        resp.status = falcon.HTTP_200
468
        _ = id_
469
470
    @staticmethod
471
    @user_logger
472
    def on_delete(req, resp, id_, pid):
473
        admin_control(req)
474
        if not id_.isdigit() or int(id_) <= 0:
475
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
476
                                   description='API.INVALID_SENSOR_ID')
477
478
        if not pid.isdigit() or int(pid) <= 0:
479
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
480
                                   description='API.INVALID_POINT_ID')
481
482
        cnx = mysql.connector.connect(**config.myems_system_db)
483
        cursor = cnx.cursor()
484
485
        cursor.execute(" SELECT name "
486
                       " FROM tbl_sensors "
487
                       " WHERE id = %s ", (id_,))
488
        if cursor.fetchone() is None:
489
            cursor.close()
490
            cnx.close()
491
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
492
                                   description='API.SENSOR_NOT_FOUND')
493
494
        cursor.execute(" SELECT name "
495
                       " FROM tbl_points "
496
                       " WHERE id = %s ", (pid,))
497
        if cursor.fetchone() is None:
498
            cursor.close()
499
            cnx.close()
500
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
501
                                   description='API.POINT_NOT_FOUND')
502
503
        cursor.execute(" SELECT id "
504
                       " FROM tbl_sensors_points "
505
                       " WHERE sensor_id = %s AND point_id = %s ", (id_, pid))
506
        if cursor.fetchone() is None:
507
            cursor.close()
508
            cnx.close()
509
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
510
                                   description='API.SENSOR_POINT_RELATION_NOT_FOUND')
511
512
        cursor.execute(" DELETE FROM tbl_sensors_points WHERE sensor_id = %s AND point_id = %s ", (id_, pid))
513
        cnx.commit()
514
515
        cursor.close()
516
        cnx.close()
517
518
        resp.status = falcon.HTTP_204
519
520
521
class SensorExport:
522
    def __init__(self):
523
        pass
524
525
    @staticmethod
526
    def on_options(req, resp, id_):
527
        _ = req
528
        resp.status = falcon.HTTP_200
529
        _ = id_
530
531
    @staticmethod
532
    def on_get(req, resp, id_):
533
        if 'API-KEY' not in req.headers or \
534
                not isinstance(req.headers['API-KEY'], str) or \
535
                len(str.strip(req.headers['API-KEY'])) == 0:
536
            access_control(req)
537
        else:
538
            api_key_control(req)
539
        if not id_.isdigit() or int(id_) <= 0:
540
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
541
                                   description='API.INVALID_SENSOR_ID')
542
543
        cnx = mysql.connector.connect(**config.myems_system_db)
544
        cursor = cnx.cursor()
545
546
        query = (" SELECT id, name, uuid, description "
547
                 " FROM tbl_sensors "
548
                 " WHERE id = %s ")
549
        cursor.execute(query, (id_,))
550
        row = cursor.fetchone()
551
552 View Code Duplication
        if row is None:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
553
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
554
                                   description='API.SENSOR_NOT_FOUND')
555
        else:
556
            meta_result = {"id": row[0],
557
                           "name": row[1],
558
                           "uuid": row[2],
559
                           "description": row[3],
560
                           "points": None}
561
            query = (" SELECT p.id, p.name "
562
                     " FROM tbl_points p, tbl_sensors_points sp "
563
                     " WHERE sp.sensor_id = %s AND p.id = sp.point_id "
564
                     " ORDER BY p.id ")
565
            cursor.execute(query, (id_,))
566
            rows = cursor.fetchall()
567
            result = list()
568
            if rows is not None and len(rows) > 0:
569
                for row in rows:
570
                    point_result = {"id": row[0], "name": row[1]}
571
                    result.append(point_result)
572
                meta_result['points'] = result
573
            cursor.close()
574
            cnx.close()
575
        resp.text = json.dumps(meta_result)
576
577
578
class SensorImport:
579
    def __init__(self):
580
        pass
581
582
    @staticmethod
583
    def on_options(req, resp):
584
        _ = req
585
        resp.status = falcon.HTTP_200
586
587
    @staticmethod
588
    @user_logger
589
    def on_post(req, resp):
590
        """Handles POST requests"""
591
        admin_control(req)
592
        try:
593
            raw_json = req.stream.read().decode('utf-8')
594
        except UnicodeDecodeError as ex:
595
            print("Failed to decode request")
596
            raise falcon.HTTPError(status=falcon.HTTP_400,
597
                                   title='API.BAD_REQUEST',
598
                                   description='API.INVALID_ENCODING')
599
        except Exception as ex:
600
            print("Unexpected error reading request stream")
601
            raise falcon.HTTPError(status=falcon.HTTP_400,
602
                                   title='API.BAD_REQUEST',
603
                                   description='API.FAILED_TO_READ_REQUEST_STREAM')
604
605
        new_values = json.loads(raw_json)
606
607
        if 'name' not in new_values.keys() or \
608
                not isinstance(new_values['name'], str) or \
609
                len(str.strip(new_values['name'])) == 0:
610
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
611
                                   description='API.INVALID_SENSOR_NAME')
612
        name = str.strip(new_values['name'])
613
614
        if 'description' in new_values.keys() and \
615
                new_values['description'] is not None and \
616
                len(str(new_values['description'])) > 0:
617
            description = str.strip(new_values['description'])
618
        else:
619
            description = None
620
621
        cnx = mysql.connector.connect(**config.myems_system_db)
622
        cursor = cnx.cursor()
623
624
        cursor.execute(" SELECT name "
625
                       " FROM tbl_sensors "
626
                       " WHERE name = %s ", (name,))
627
        if cursor.fetchone() is not None:
628
            cursor.close()
629
            cnx.close()
630
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
631
                                   description='API.SENSOR_NAME_IS_ALREADY_IN_USE')
632
633
        add_values = (" INSERT INTO tbl_sensors "
634
                      "    (name, uuid, description) "
635
                      " VALUES (%s, %s, %s) ")
636
        cursor.execute(add_values, (name,
637
                                    str(uuid.uuid4()),
638
                                    description))
639
        new_id = cursor.lastrowid
640
        if 'points' in new_values.keys() and \
641
                new_values['points'] is not None and \
642
                len(new_values['points']) > 0:
643
            for point in new_values['points']:
644
                if 'id' in point and isinstance(point['id'], int):
645
                    cursor.execute(" SELECT name "
646
                                   " FROM tbl_points "
647
                                   " WHERE id = %s ", (point['id'],))
648
                    if cursor.fetchone() is None:
649
                        cursor.close()
650
                        cnx.close()
651
                        raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
652
                                               description='API.POINT_NOT_FOUND')
653
654
                    add_row = (" INSERT INTO tbl_sensors_points (sensor_id, point_id) "
655
                               " VALUES (%s, %s) ")
656
                    cursor.execute(add_row, (new_id, point['id'],))
657
                else:
658
                    raise falcon.HTTPError(status=falcon.HTTP_400, title='API.NOT_FOUND',
659
                                           description='API.INVALID_POINT_ID')
660
        cnx.commit()
661
        cursor.close()
662
        cnx.close()
663
664
        resp.status = falcon.HTTP_201
665
        resp.location = '/sensors/' + str(new_id)
666
667
668
class SensorClone:
669
670
    def __init__(self):
671
        pass
672
673
    @staticmethod
674
    def on_options(req, resp, id_):
675
        _ = req
676
        resp.status = falcon.HTTP_200
677
        _ = id_
678
679
    @staticmethod
680
    @user_logger
681
    def on_post(req, resp, id_):
682
        admin_control(req)
683
        if not id_.isdigit() or int(id_) <= 0:
684
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
685
                                   description='API.INVALID_SENSOR_ID')
686
687
        cnx = mysql.connector.connect(**config.myems_system_db)
688
        cursor = cnx.cursor()
689
690
        query = (" SELECT id, name, uuid, description "
691
                 " FROM tbl_sensors "
692
                 " WHERE id = %s ")
693
        cursor.execute(query, (id_,))
694
        row = cursor.fetchone()
695 View Code Duplication
        if row is None:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
696
            cursor.close()
697
            cnx.close()
698
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
699
                                   description='API.SENSOR_NOT_FOUND')
700
        else:
701
            meta_result = {"id": row[0],
702
                           "name": row[1],
703
                           "uuid": row[2],
704
                           "description": row[3],
705
                           "points": None}
706
707
            query = (" SELECT p.id, p.name "
708
                     " FROM tbl_points p, tbl_sensors_points sp "
709
                     " WHERE sp.sensor_id = %s AND p.id = sp.point_id "
710
                     " ORDER BY p.id ")
711
            cursor.execute(query, (id_,))
712
            rows = cursor.fetchall()
713
            result = list()
714
            if rows is not None and len(rows) > 0:
715
                for row in rows:
716
                    point_result = {"id": row[0], "name": row[1]}
717
                    result.append(point_result)
718
                meta_result['points'] = result
719
        timezone_offset = int(config.utc_offset[1:3]) * 60 + int(config.utc_offset[4:6])
720
        if config.utc_offset[0] == '-':
721
            timezone_offset = -timezone_offset
722
        new_name = (str.strip(meta_result['name']) +
723
                    (datetime.utcnow() + timedelta(minutes=timezone_offset)).isoformat(sep='-', timespec='seconds'))
724
725
        add_values = (" INSERT INTO tbl_sensors "
726
                      "    (name, uuid, description) "
727
                      " VALUES (%s, %s, %s) ")
728
        cursor.execute(add_values, (new_name,
729
                                    str(uuid.uuid4()),
730
                                    meta_result['description']))
731
        new_id = cursor.lastrowid
732
        if meta_result['points'] is not None and len(meta_result['points']) > 0:
733
            for point in meta_result['points']:
734
                cursor.execute(" SELECT name "
735
                               " FROM tbl_points "
736
                               " WHERE id = %s ", (point['id'],))
737
                if cursor.fetchone() is None:
738
                    cursor.close()
739
                    cnx.close()
740
                    raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
741
                                           description='API.POINT_NOT_FOUND')
742
743
                add_row = (" INSERT INTO tbl_sensors_points (sensor_id, point_id) "
744
                           " VALUES (%s, %s) ")
745
                cursor.execute(add_row, (new_id, point['id'],))
746
747
        cnx.commit()
748
        cursor.close()
749
        cnx.close()
750
751
        resp.status = falcon.HTTP_201
752
        resp.location = '/sensors/' + str(new_id)
753