Passed
Push — master ( bc2901...844492 )
by
unknown
11:09
created

core.sensor.SensorItem.on_put()   D

Complexity

Conditions 12

Size

Total Lines 66
Code Lines 50

Duplication

Lines 66
Ratio 100 %

Importance

Changes 0
Metric Value
eloc 50
dl 66
loc 66
rs 4.8
c 0
b 0
f 0
cc 12
nop 3

How to fix   Long Method    Complexity   

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:

Complexity

Complex classes like core.sensor.SensorItem.on_put() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

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