Passed
Push — master ( d9c3b0...8cd708 )
by Guangyu
02:16 queued 11s
created

core.point   F

Complexity

Total Complexity 97

Size/Duplication

Total Lines 513
Duplicated Lines 8.38 %

Importance

Changes 0
Metric Value
eloc 387
dl 43
loc 513
rs 2
c 0
b 0
f 0
wmc 97

9 Methods

Rating   Name   Duplication   Size   Complexity  
A PointItem.__init__() 0 3 1
A PointCollection.on_options() 0 3 1
B PointItem.on_get() 0 46 7
F PointItem.on_delete() 0 137 12
F PointCollection.on_post() 0 121 32
B PointCollection.on_get() 43 43 7
A PointCollection.__init__() 0 3 1
A PointItem.on_options() 0 3 1
F PointItem.on_put() 0 136 35

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complexity

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like core.point 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 falcon
2
import simplejson as json
3
import mysql.connector
4
import config
5
6
7
class PointCollection:
8
    @staticmethod
9
    def __init__():
10
        pass
11
12
    @staticmethod
13
    def on_options(req, resp):
14
        resp.status = falcon.HTTP_200
15
16 View Code Duplication
    @staticmethod
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
17
    def on_get(req, resp):
18
        cnx = mysql.connector.connect(**config.myems_system_db)
19
        cursor = cnx.cursor(dictionary=True)
20
21
        query = (" SELECT id, name, uuid "
22
                 " FROM tbl_data_sources ")
23
        cursor.execute(query)
24
        rows_data_sources = cursor.fetchall()
25
26
        data_source_dict = dict()
27
        if rows_data_sources is not None and len(rows_data_sources) > 0:
28
            for row in rows_data_sources:
29
                data_source_dict[row['id']] = {"id": row['id'],
30
                                               "name": row['name'],
31
                                               "uuid": row['uuid']}
32
33
        query = (" SELECT id, name, data_source_id, object_type, units, "
34
                 "        high_limit, low_limit, ratio, is_trend, address, description "
35
                 " FROM tbl_points ")
36
        cursor.execute(query)
37
        rows = cursor.fetchall()
38
        cursor.close()
39
        cnx.disconnect()
40
41
        result = list()
42
        if rows is not None and len(rows) > 0:
43
            for row in rows:
44
                data_source = data_source_dict.get(row['data_source_id'], None)
45
                meta_result = {"id": row['id'],
46
                               "name": row['name'],
47
                               "data_source": data_source,
48
                               "object_type": row['object_type'],
49
                               "units": row['units'],
50
                               "high_limit": row['high_limit'],
51
                               "low_limit": row['low_limit'],
52
                               "ratio": float(row['ratio']),
53
                               "is_trend": row['is_trend'],
54
                               "address": row['address'],
55
                               "description": row['description']}
56
                result.append(meta_result)
57
58
        resp.body = json.dumps(result)
59
60
    @staticmethod
61
    def on_post(req, resp):
62
        """Handles POST requests"""
63
        try:
64
            raw_json = req.stream.read().decode('utf-8')
65
        except Exception as ex:
66
            raise falcon.HTTPError(falcon.HTTP_400, 'API.ERROR', ex)
67
68
        new_values = json.loads(raw_json)
69
70
        if 'name' not in new_values['data'].keys() or \
71
                not isinstance(new_values['data']['name'], str) or \
72
                len(str.strip(new_values['data']['name'])) == 0:
73
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
74
                                   description='API.INVALID_POINT_NAME')
75
        name = str.strip(new_values['data']['name'])
76
77
        if 'data_source_id' not in new_values['data'].keys() or \
78
                not isinstance(new_values['data']['data_source_id'], int) or \
79
                new_values['data']['data_source_id'] <= 0:
80
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
81
                                   description='API.INVALID_DATA_SOURCE_ID')
82
        data_source_id = new_values['data']['data_source_id']
83
84
        if 'object_type' not in new_values['data'].keys() \
85
           or str.strip(new_values['data']['object_type']) not in ('ENERGY_VALUE', 'ANALOG_VALUE', 'DIGITAL_VALUE'):
86
            raise falcon.HTTPError(falcon.HTTP_400,
87
                                   title='API.BAD_REQUEST',
88
                                   description='API.INVALID_OBJECT_TYPE')
89
        object_type = str.strip(new_values['data']['object_type'])
90
91
        if 'units' not in new_values['data'].keys() or \
92
                not isinstance(new_values['data']['units'], str) or \
93
                len(str.strip(new_values['data']['units'])) == 0:
94
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
95
                                   description='API.INVALID_UNITS')
96
        units = str.strip(new_values['data']['units'])
97
98
        if 'high_limit' not in new_values['data'].keys() or \
99
                not (isinstance(new_values['data']['high_limit'], float) or
100
                     isinstance(new_values['data']['high_limit'], int)):
101
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
102
                                   description='API.INVALID_LOW_LIMIT_VALUE')
103
        high_limit = new_values['data']['high_limit']
104
105
        if 'low_limit' not in new_values['data'].keys() or \
106
                not (isinstance(new_values['data']['low_limit'], float) or
107
                     isinstance(new_values['data']['low_limit'], int)):
108
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
109
                                   description='API.INVALID_LOW_LIMIT_VALUE')
110
        low_limit = new_values['data']['low_limit']
111
112
        if 'ratio' not in new_values['data'].keys() or \
113
                not (isinstance(new_values['data']['ratio'], float) or
114
                     isinstance(new_values['data']['ratio'], int)):
115
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
116
                                   description='API.INVALID_RATIO_VALUE')
117
        ratio = new_values['data']['ratio']
118
119
        if 'is_trend' not in new_values['data'].keys() or \
120
                not isinstance(new_values['data']['is_trend'], bool):
121
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
122
                                   description='API.INVALID_IS_TREND_VALUE')
123
        is_trend = new_values['data']['is_trend']
124
125
        if 'address' not in new_values['data'].keys() or \
126
                not isinstance(new_values['data']['address'], str) or \
127
                len(str.strip(new_values['data']['address'])) == 0:
128
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
129
                                   description='API.INVALID_ADDRESS')
130
        address = str.strip(new_values['data']['address'])
131
132
        if 'description' in new_values['data'].keys() and \
133
                new_values['data']['description'] is not None and \
134
                len(str(new_values['data']['description'])) > 0:
135
            description = str.strip(new_values['data']['description'])
136
        else:
137
            description = None
138
139
        cnx = mysql.connector.connect(**config.myems_system_db)
140
        cursor = cnx.cursor()
141
142
        cursor.execute(" SELECT name "
143
                       " FROM tbl_points "
144
                       " WHERE name = %s AND data_source_id = %s ", (name, data_source_id))
145
        if cursor.fetchone() is not None:
146
            cursor.close()
147
            cnx.disconnect()
148
            raise falcon.HTTPError(falcon.HTTP_404, title='API.BAD_REQUEST',
149
                                   description='API.POINT_NAME_IS_ALREADY_IN_USE')
150
151
        cursor.execute(" SELECT name "
152
                       " FROM tbl_data_sources "
153
                       " WHERE id = %s ", (data_source_id,))
154
        if cursor.fetchone() is None:
155
            cursor.close()
156
            cnx.disconnect()
157
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
158
                                   description='API.INVALID_DATA_SOURCE_ID')
159
160
        add_value = (" INSERT INTO tbl_points (name, data_source_id, "
161
                     "                         object_type, units, high_limit, low_limit, ratio, "
162
                     "                         is_trend, address, description) "
163
                     " VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s) ")
164
        cursor.execute(add_value, (name,
165
                                   data_source_id,
166
                                   object_type,
167
                                   units,
168
                                   high_limit,
169
                                   low_limit,
170
                                   ratio,
171
                                   is_trend,
172
                                   address,
173
                                   description))
174
        new_id = cursor.lastrowid
175
        cnx.commit()
176
        cursor.close()
177
        cnx.disconnect()
178
179
        resp.status = falcon.HTTP_201
180
        resp.location = '/points/' + str(new_id)
181
182
183
class PointItem:
184
    @staticmethod
185
    def __init__():
186
        pass
187
188
    @staticmethod
189
    def on_options(req, resp, id_):
190
        resp.status = falcon.HTTP_200
191
192
    @staticmethod
193
    def on_get(req, resp, id_):
194
        if not id_.isdigit() or int(id_) <= 0:
195
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
196
                                   description='API.INVALID_POINT_ID')
197
198
        cnx = mysql.connector.connect(**config.myems_system_db)
199
        cursor = cnx.cursor(dictionary=True)
200
201
        query = (" SELECT id, name, uuid "
202
                 " FROM tbl_data_sources ")
203
        cursor.execute(query)
204
        rows_data_sources = cursor.fetchall()
205
206
        data_source_dict = dict()
207
        if rows_data_sources is not None and len(rows_data_sources) > 0:
208
            for row in rows_data_sources:
209
                data_source_dict[row['id']] = {"id": row['id'],
210
                                               "name": row['name'],
211
                                               "uuid": row['uuid']}
212
213
        query = (" SELECT id, name, data_source_id, object_type, units, "
214
                 "        high_limit, low_limit, ratio, is_trend, address, description "
215
                 " FROM tbl_points "
216
                 " WHERE id = %s ")
217
        cursor.execute(query, (id_,))
218
        row = cursor.fetchone()
219
        cursor.close()
220
        cnx.disconnect()
221
        if row is None:
222
            raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
223
                                   description='API.POINT_NOT_FOUND')
224
225
        data_source = data_source_dict.get(row['data_source_id'], None)
226
        result = {"id": row['id'],
227
                  "name": row['name'],
228
                  "data_source": data_source,
229
                  "object_type": row['object_type'],
230
                  "units": row['units'],
231
                  "high_limit": row['high_limit'],
232
                  "low_limit": row['low_limit'],
233
                  "ratio": float(row['ratio']),
234
                  "is_trend": bool(row['is_trend']),
235
                  "address": row['address'],
236
                  "description": row['description']}
237
        resp.body = json.dumps(result)
238
239
    @staticmethod
240
    def on_delete(req, resp, id_):
241
        if not id_.isdigit() or int(id_) <= 0:
242
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
243
                                   description='API.INVALID_POINT_ID')
244
245
        cnx = mysql.connector.connect(**config.myems_system_db)
246
        cursor = cnx.cursor()
247
248
        cursor.execute(" SELECT name "
249
                       " FROM tbl_points "
250
                       " WHERE id = %s ", (id_,))
251
        if cursor.fetchone() is None:
252
            cursor.close()
253
            cnx.disconnect()
254
            raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
255
                                   description='API.POINT_NOT_FOUND')
256
257
        # check if this point is being used by meters
258
        cursor.execute(" SELECT meter_id "
259
                       " FROM tbl_meters_points "
260
                       " WHERE point_id = %s "
261
                       " LIMIT 1 ",
262
                       (id_,))
263
        row_meter = cursor.fetchone()
264
        if row_meter is not None:
265
            cursor.close()
266
            cnx.disconnect()
267
            raise falcon.HTTPError(falcon.HTTP_400,
268
                                   title='API.BAD_REQUEST',
269
                                   description='API.THERE_IS_RELATION_WITH_METERS')
270
271
        # check if this point is being used by sensors
272
        cursor.execute(" SELECT sensor_id "
273
                       " FROM tbl_sensors_points "
274
                       " WHERE point_id = %s "
275
                       " LIMIT 1 ",
276
                       (id_,))
277
        row_sensor = cursor.fetchone()
278
        if row_sensor is not None:
279
            cursor.close()
280
            cnx.disconnect()
281
            raise falcon.HTTPError(falcon.HTTP_400,
282
                                   title='API.BAD_REQUEST',
283
                                   description='API.THERE_IS_RELATION_WITH_SENSORS')
284
285
        # check if this point is being used by shopfloors
286
        cursor.execute(" SELECT shopfloor_id "
287
                       " FROM tbl_shopfloors_points "
288
                       " WHERE point_id = %s "
289
                       " LIMIT 1 ",
290
                       (id_,))
291
        row_shopfloor = cursor.fetchone()
292
        if row_shopfloor is not None:
293
            cursor.close()
294
            cnx.disconnect()
295
            raise falcon.HTTPError(falcon.HTTP_400,
296
                                   title='API.BAD_REQUEST',
297
                                   description='API.THERE_IS_RELATION_WITH_SHOPFLOORS')
298
299
        # check if this point is being used by stores
300
        cursor.execute(" SELECT store_id "
301
                       " FROM tbl_stores_points "
302
                       " WHERE point_id = %s "
303
                       " LIMIT 1 ",
304
                       (id_,))
305
        row_store = cursor.fetchone()
306
        if row_store is not None:
307
            cursor.close()
308
            cnx.disconnect()
309
            raise falcon.HTTPError(falcon.HTTP_400,
310
                                   title='API.BAD_REQUEST',
311
                                   description='API.THERE_IS_RELATION_WITH_STORES')
312
313
        # check if this point is being used by spaces
314
        cursor.execute(" SELECT space_id "
315
                       " FROM tbl_spaces_points "
316
                       " WHERE point_id = %s "
317
                       " LIMIT 1 ",
318
                       (id_,))
319
        row_space = cursor.fetchone()
320
        if row_space is not None:
321
            cursor.close()
322
            cnx.disconnect()
323
            raise falcon.HTTPError(falcon.HTTP_400,
324
                                   title='API.BAD_REQUEST',
325
                                   description='API.THERE_IS_RELATION_WITH_SPACES')
326
327
        # check if this point is being used by tenants
328
        cursor.execute(" SELECT tenant_id "
329
                       " FROM tbl_tenants_points "
330
                       " WHERE point_id = %s "
331
                       " LIMIT 1 ",
332
                       (id_,))
333
        row_tenant = cursor.fetchone()
334
        if row_tenant is not None:
335
            cursor.close()
336
            cnx.disconnect()
337
            raise falcon.HTTPError(falcon.HTTP_400,
338
                                   title='API.BAD_REQUEST',
339
                                   description='API.THERE_IS_RELATION_WITH_TENANTS')
340
341
        # check if this point is being used by equipment parameters
342
        cursor.execute(" SELECT equipment_id "
343
                       " FROM tbl_equipments_parameters "
344
                       " WHERE point_id = %s "
345
                       " LIMIT 1 ",
346
                       (id_,))
347
        row_equipment = cursor.fetchone()
348
        if row_equipment is not None:
349
            cursor.close()
350
            cnx.disconnect()
351
            raise falcon.HTTPError(falcon.HTTP_400,
352
                                   title='API.BAD_REQUEST',
353
                                   description='API.THERE_IS_RELATION_WITH_EQUIPMENT_PARAMETERS')
354
355
        # check if this point is being used by combined equipment parameters
356
        cursor.execute(" SELECT combined_equipment_id "
357
                       " FROM tbl_combined_equipments_parameters "
358
                       " WHERE point_id = %s "
359
                       " LIMIT 1 ",
360
                       (id_,))
361
        row_combined_equipment = cursor.fetchone()
362
        if row_combined_equipment is not None:
363
            cursor.close()
364
            cnx.disconnect()
365
            raise falcon.HTTPError(falcon.HTTP_400,
366
                                   title='API.BAD_REQUEST',
367
                                   description='API.THERE_IS_RELATION_WITH_COMBINED_EQUIPMENT_PARAMETERS')
368
369
        cursor.execute(" DELETE FROM tbl_points WHERE id = %s ", (id_,))
370
        cnx.commit()
371
372
        cursor.close()
373
        cnx.disconnect()
374
375
        resp.status = falcon.HTTP_204
376
377
    @staticmethod
378
    def on_put(req, resp, id_):
379
        """Handles PUT requests"""
380
        try:
381
            raw_json = req.stream.read().decode('utf-8')
382
        except Exception as ex:
383
            raise falcon.HTTPError(falcon.HTTP_400, title='API.EXCEPTION', description=ex)
384
385
        if not id_.isdigit() or int(id_) <= 0:
386
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
387
                                   description='API.INVALID_POINT_ID')
388
389
        new_values = json.loads(raw_json)
390
391
        if 'name' not in new_values['data'].keys() or \
392
                not isinstance(new_values['data']['name'], str) or \
393
                len(str.strip(new_values['data']['name'])) == 0:
394
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
395
                                   description='API.INVALID_POINT_NAME')
396
        name = str.strip(new_values['data']['name'])
397
398
        if 'data_source_id' not in new_values['data'].keys() or \
399
                not isinstance(new_values['data']['data_source_id'], int) or \
400
                new_values['data']['data_source_id'] <= 0:
401
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
402
                                   description='API.INVALID_DATA_SOURCE_ID')
403
        data_source_id = new_values['data']['data_source_id']
404
405
        if 'object_type' not in new_values['data'].keys() \
406
           or str.strip(new_values['data']['object_type']) not in ('ENERGY_VALUE', 'ANALOG_VALUE', 'DIGITAL_VALUE'):
407
            raise falcon.HTTPError(falcon.HTTP_400,
408
                                   title='API.BAD_REQUEST',
409
                                   description='API.INVALID_OBJECT_TYPE')
410
        object_type = str.strip(new_values['data']['object_type'])
411
412
        if 'units' not in new_values['data'].keys() or \
413
                not isinstance(new_values['data']['units'], str) or \
414
                len(str.strip(new_values['data']['units'])) == 0:
415
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
416
                                   description='API.INVALID_UNITS')
417
        units = str.strip(new_values['data']['units'])
418
419
        if 'high_limit' not in new_values['data'].keys() or \
420
                not (isinstance(new_values['data']['high_limit'], float) or
421
                     isinstance(new_values['data']['high_limit'], int)):
422
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
423
                                   description='API.INVALID_LOW_LIMIT_VALUE')
424
        high_limit = new_values['data']['high_limit']
425
426
        if 'low_limit' not in new_values['data'].keys() or \
427
                not (isinstance(new_values['data']['low_limit'], float) or
428
                     isinstance(new_values['data']['low_limit'], int)):
429
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
430
                                   description='API.INVALID_LOW_LIMIT_VALUE')
431
        low_limit = new_values['data']['low_limit']
432
433
        if 'ratio' not in new_values['data'].keys() or \
434
                not (isinstance(new_values['data']['ratio'], float) or
435
                     isinstance(new_values['data']['ratio'], int)):
436
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
437
                                   description='API.INVALID_RATIO_VALUE')
438
        ratio = new_values['data']['ratio']
439
440
        if 'is_trend' not in new_values['data'].keys() or \
441
                not isinstance(new_values['data']['is_trend'], bool):
442
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
443
                                   description='API.INVALID_IS_TREND_VALUE')
444
        is_trend = new_values['data']['is_trend']
445
446
        if 'address' not in new_values['data'].keys() or \
447
                not isinstance(new_values['data']['address'], str) or \
448
                len(str.strip(new_values['data']['address'])) == 0:
449
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
450
                                   description='API.INVALID_ADDRESS')
451
        address = str.strip(new_values['data']['address'])
452
453
        if 'description' in new_values['data'].keys() and \
454
                new_values['data']['description'] is not None and \
455
                len(str(new_values['data']['description'])) > 0:
456
            description = str.strip(new_values['data']['description'])
457
        else:
458
            description = None
459
460
        cnx = mysql.connector.connect(**config.myems_system_db)
461
        cursor = cnx.cursor()
462
463
        cursor.execute(" SELECT name "
464
                       " FROM tbl_points "
465
                       " WHERE id = %s ", (id_,))
466
        if cursor.fetchone() is None:
467
            cursor.close()
468
            cnx.disconnect()
469
            raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
470
                                   description='API.POINT_NOT_FOUND')
471
472
        cursor.execute(" SELECT name "
473
                       " FROM tbl_data_sources "
474
                       " WHERE id = %s ", (data_source_id,))
475
        if cursor.fetchone() is None:
476
            cursor.close()
477
            cnx.disconnect()
478
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
479
                                   description='API.INVALID_DATA_SOURCE_ID')
480
481
        cursor.execute(" SELECT name "
482
                       " FROM tbl_points "
483
                       " WHERE name = %s AND data_source_id = %s AND id != %s ", (name, data_source_id, id_))
484
        if cursor.fetchone() is not None:
485
            cursor.close()
486
            cnx.disconnect()
487
            raise falcon.HTTPError(falcon.HTTP_404, title='API.BAD_REQUEST',
488
                                   description='API.POINT_NAME_IS_ALREADY_IN_USE')
489
490
        update_row = (" UPDATE tbl_points "
491
                      " SET name = %s, data_source_id = %s, "
492
                      "     object_type = %s, units = %s, "
493
                      "     high_limit = %s, low_limit = %s, ratio = %s, "
494
                      "     is_trend = %s, address = %s, description = %s "
495
                      " WHERE id = %s ")
496
        cursor.execute(update_row, (name,
497
                                    data_source_id,
498
                                    object_type,
499
                                    units,
500
                                    high_limit,
501
                                    low_limit,
502
                                    ratio,
503
                                    is_trend,
504
                                    address,
505
                                    description,
506
                                    id_,))
507
        cnx.commit()
508
509
        cursor.close()
510
        cnx.disconnect()
511
512
        resp.status = falcon.HTTP_200
513
514