Passed
Push — master ( 42322a...183c79 )
by
unknown
10:22 queued 16s
created

core.svg.SVGItem.on_delete()   F

Complexity

Conditions 18

Size

Total Lines 103
Code Lines 89

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 89
dl 0
loc 103
rs 1.2
c 0
b 0
f 0
cc 18
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.svg.SVGItem.on_delete() 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 SVGCollection:
11
    def __init__(self):
12
        """Initializes SVGCollection"""
13
        pass
14
15
    @staticmethod
16
    def on_options(req, resp):
17
        _ = req
18
        resp.status = falcon.HTTP_200
19
20
    @staticmethod
21
    def on_get(req, resp):
22
        if 'API-KEY' not in req.headers or \
23
                not isinstance(req.headers['API-KEY'], str) or \
24
                len(str.strip(req.headers['API-KEY'])) == 0:
25
            access_control(req)
26
        else:
27
            api_key_control(req)
28
        # if turn quick mode on, do not return source code
29
        is_quick_mode = False
30
        if 'QUICKMODE' in req.headers and \
31
            isinstance(req.headers['QUICKMODE'], str) and \
32
                len(str.strip(req.headers['QUICKMODE'])) > 0 and \
33
                str.lower(req.headers['QUICKMODE']) in ('true', 't', 'on', 'yes', 'y'):
34
            is_quick_mode = True
35
36
        cnx = mysql.connector.connect(**config.myems_system_db)
37
        cursor = cnx.cursor()
38
        if is_quick_mode:
39
            query = (" SELECT id, name, uuid "
40
                     " FROM tbl_svgs "
41
                     " ORDER BY id ")
42
            cursor.execute(query)
43
            rows_svgs = cursor.fetchall()
44
45
            result = list()
46
            if rows_svgs is not None and len(rows_svgs) > 0:
47
                for row in rows_svgs:
48
49
                    meta_result = {"id": row[0],
50
                                   "name": row[1],
51
                                   "uuid": row[2]}
52
                    result.append(meta_result)
53
        else:
54
            query = (" SELECT id, name, uuid, source_code, description "
55
                     " FROM tbl_svgs "
56
                     " ORDER BY id ")
57
            cursor.execute(query)
58
            rows_svgs = cursor.fetchall()
59
60
            result = list()
61
            if rows_svgs is not None and len(rows_svgs) > 0:
62
                for row in rows_svgs:
63
                    meta_result = {"id": row[0],
64
                                   "name": row[1],
65
                                   "uuid": row[2],
66
                                   "source_code": row[3],
67
                                   "description": row[4]}
68
                    result.append(meta_result)
69
70
        cursor.close()
71
        cnx.close()
72
        resp.text = json.dumps(result)
73
74
    @staticmethod
75
    @user_logger
76
    def on_post(req, resp):
77
        """Handles POST requests"""
78
        admin_control(req)
79
        try:
80
            raw_json = req.stream.read().decode('utf-8')
81
        except Exception as ex:
82
            print(str(ex))
83
            raise falcon.HTTPError(status=falcon.HTTP_400,
84
                                   title='API.BAD_REQUEST',
85
                                   description='API.FAILED_TO_READ_REQUEST_STREAM')
86
87
        new_values = json.loads(raw_json)
88
89
        if 'name' not in new_values['data'].keys() or \
90
                not isinstance(new_values['data']['name'], str) or \
91
                len(str.strip(new_values['data']['name'])) == 0:
92
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
93
                                   description='API.INVALID_SVG_NAME')
94
        name = str.strip(new_values['data']['name'])
95
96
        if 'source_code' not in new_values['data'].keys() or \
97
                not isinstance(new_values['data']['source_code'], str) or \
98
                len(str.strip(new_values['data']['source_code'])) == 0:
99
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
100
                                   description='API.INVALID_SVG_SOURCE_CODE')
101
        source_code = str.strip(new_values['data']['source_code'])
102
103
        if 'description' in new_values['data'].keys() and \
104
                new_values['data']['description'] is not None and \
105
                len(str(new_values['data']['description'])) > 0:
106
            description = str.strip(new_values['data']['description'])
107
        else:
108
            description = None
109
110
        cnx = mysql.connector.connect(**config.myems_system_db)
111
        cursor = cnx.cursor()
112
113
        cursor.execute(" SELECT name "
114
                       " FROM tbl_svgs "
115
                       " WHERE name = %s ", (name,))
116
        if cursor.fetchone() is not None:
117
            cursor.close()
118
            cnx.close()
119
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
120
                                   description='API.SVG_NAME_IS_ALREADY_IN_USE')
121
122
        add_values = (" INSERT INTO tbl_svgs "
123
                      "    (name, uuid, source_code, description) "
124
                      " VALUES (%s, %s, %s, %s) ")
125
        cursor.execute(add_values, (name,
126
                                    str(uuid.uuid4()),
127
                                    source_code,
128
                                    description))
129
        new_id = cursor.lastrowid
130
        cnx.commit()
131
        cursor.close()
132
        cnx.close()
133
134
        resp.status = falcon.HTTP_201
135
        resp.location = '/svgs/' + str(new_id)
136
137
138
class SVGItem:
139
    def __init__(self):
140
        """Initializes SVGItem"""
141
        pass
142
143
    @staticmethod
144
    def on_options(req, resp, id_):
145
        _ = req
146
        resp.status = falcon.HTTP_200
147
        _ = id_
148
149
    @staticmethod
150
    def on_get(req, resp, id_):
151
        if 'API-KEY' not in req.headers or \
152
                not isinstance(req.headers['API-KEY'], str) or \
153
                len(str.strip(req.headers['API-KEY'])) == 0:
154
            access_control(req)
155
        else:
156
            api_key_control(req)
157
        if not id_.isdigit() or int(id_) <= 0:
158
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
159
                                   description='API.INVALID_SVG_ID')
160
161
        cnx = mysql.connector.connect(**config.myems_system_db)
162
        cursor = cnx.cursor()
163
164
        query = (" SELECT id, name, uuid, source_code, description "
165
                 " FROM tbl_svgs "
166
                 " WHERE id = %s ")
167
        cursor.execute(query, (id_,))
168
        row = cursor.fetchone()
169
        cursor.close()
170
        cnx.close()
171
172
        if row is None:
173
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
174
                                   description='API.SVG_NOT_FOUND')
175
        else:
176
            meta_result = {"id": row[0],
177
                           "name": row[1],
178
                           "uuid": row[2],
179
                           "source_code": row[3],
180
                           "description": row[4]}
181
182
        resp.text = json.dumps(meta_result)
183
184
    @staticmethod
185
    @user_logger
186
    def on_delete(req, resp, id_):
187
        admin_control(req)
188
        if not id_.isdigit() or int(id_) <= 0:
189
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
190
                                   description='API.INVALID_SVG_ID')
191
        cnx = mysql.connector.connect(**config.myems_system_db)
192
        cursor = cnx.cursor()
193
194
        cursor.execute(" SELECT name "
195
                       " FROM tbl_svgs "
196
                       " WHERE id = %s ", (id_,))
197
        if cursor.fetchone() is None:
198
            cursor.close()
199
            cnx.close()
200
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
201
                                   description='API.SVG_NOT_FOUND')
202
        # check if any equipment is bound to this SVG
203
        cursor.execute("SELECT id FROM tbl_equipments WHERE svg_id = %s", (id_,))
204
        if cursor.fetchone() is not None:
205
            cursor.close()
206
            cnx.close()
207
            raise falcon.HTTPError(status=falcon.HTTP_400,
208
                                   title='API.BAD_REQUEST',
209
                                   description='API.THERE_IS_RELATION_WITH_EQUIPMENTS')
210
        # check if any combined equipment is bound to this SVG
211
        cursor.execute("SELECT id FROM tbl_combined_equipments WHERE svg_id = %s", (id_,))
212
        if cursor.fetchone() is not None:
213
            cursor.close()
214
            cnx.close()
215
            raise falcon.HTTPError(status=falcon.HTTP_400,
216
                                   title='API.BAD_REQUEST',
217
                                   description='API.THERE_IS_RELATION_WITH_COMBINED_EQUIPMENTS')
218
        # check if any distribution system is bound to this SVG
219
        cursor.execute("SELECT id FROM tbl_distribution_systems WHERE svg_id = %s", (id_,))
220
        if cursor.fetchone() is not None:
221
            cursor.close()
222
            cnx.close()
223
            raise falcon.HTTPError(status=falcon.HTTP_400,
224
                                   title='API.BAD_REQUEST',
225
                                   description='API.THERE_IS_RELATION_WITH_DISTRIBUTION_SYSTEMS')
226
        # check if any energy storage power station is bound to this SVG
227
        for col in ['svg_id', 'svg2_id', 'svg3_id', 'svg4_id', 'svg5_id']:
228
            cursor.execute(f"SELECT id FROM tbl_energy_storage_power_stations WHERE {col} = %s", (id_,))
229
            if cursor.fetchone() is not None:
230
                cursor.close()
231
                cnx.close()
232
                raise falcon.HTTPError(status=falcon.HTTP_400,
233
                                       title='API.BAD_REQUEST',
234
                                       description='API.THERE_IS_RELATION_WITH_ENERGY_STORAGE_POWER_STATIONS')
235
        # check if any photovoltaic power station is bound to this SVG
236
        for col in ['svg_id', 'svg2_id', 'svg3_id', 'svg4_id', 'svg5_id']:
237
            cursor.execute(f"SELECT id FROM tbl_photovoltaic_power_stations WHERE {col} = %s", (id_,))
238
            if cursor.fetchone() is not None:
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_PHOTOVOLTAIC_POWER_STATIONS')
244
        # check if any microgrid is bound to this SVG
245
        for col in ['svg_id', 'svg2_id', 'svg3_id', 'svg4_id', 'svg5_id']:
246
            cursor.execute(f"SELECT id FROM tbl_microgrids WHERE {col} = %s", (id_,))
247
            if cursor.fetchone() is not None:
248
                cursor.close()
249
                cnx.close()
250
                raise falcon.HTTPError(status=falcon.HTTP_400,
251
                                       title='API.BAD_REQUEST',
252
                                       description='API.THERE_IS_RELATION_WITH_MICROGRIDS')
253
        # check if any virtual power plant is bound to this SVG
254
        cursor.execute("SELECT id FROM tbl_virtual_power_plants WHERE svg_id = %s", (id_,))
255
        if cursor.fetchone() is not None:
256
            cursor.close()
257
            cnx.close()
258
            raise falcon.HTTPError(status=falcon.HTTP_400,
259
                                   title='API.BAD_REQUEST',
260
                                   description='API.THERE_IS_RELATION_WITH_VIRTUAL_POWER_PLANTS')
261
        # check if any wind farm is bound to this SVG
262
        for col in ['svg_id', 'svg2_id', 'svg3_id', 'svg4_id', 'svg5_id']:
263
            cursor.execute(f"SELECT id FROM tbl_wind_farms WHERE {col} = %s", (id_,))
264
            if cursor.fetchone() is not None:
265
                cursor.close()
266
                cnx.close()
267
                raise falcon.HTTPError(status=falcon.HTTP_400,
268
                                       title='API.BAD_REQUEST',
269
                                       description='API.THERE_IS_RELATION_WITH_WIND_FARMS')
270
        # check if any charging station is bound to this SVG
271
        for col in ['svg_id', 'svg2_id', 'svg3_id', 'svg4_id', 'svg5_id']:
272
            cursor.execute(f"SELECT id FROM tbl_charging_stations WHERE {col} = %s", (id_,))
273
            if cursor.fetchone() is not None:
274
                cursor.close()
275
                cnx.close()
276
                raise falcon.HTTPError(status=falcon.HTTP_400,
277
                                       title='API.BAD_REQUEST',
278
                                       description='API.THERE_IS_RELATION_WITH_CHARGING_STATIONS')
279
280
        cursor.execute(" DELETE FROM tbl_svgs WHERE id = %s ", (id_,))
281
        cnx.commit()
282
283
        cursor.close()
284
        cnx.close()
285
286
        resp.status = falcon.HTTP_204
287
288
    @staticmethod
289
    @user_logger
290
    def on_put(req, resp, id_):
291
        """Handles PUT requests"""
292
        admin_control(req)
293
        try:
294
            raw_json = req.stream.read().decode('utf-8')
295
        except Exception as ex:
296
            print(str(ex))
297
            raise falcon.HTTPError(status=falcon.HTTP_400,
298
                                   title='API.BAD_REQUEST',
299
                                   description='API.FAILED_TO_READ_REQUEST_STREAM')
300
301
        if not id_.isdigit() or int(id_) <= 0:
302
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
303
                                   description='API.INVALID_SVG_ID')
304
305
        new_values = json.loads(raw_json)
306
307
        if 'name' not in new_values['data'].keys() or \
308
                not isinstance(new_values['data']['name'], str) or \
309
                len(str.strip(new_values['data']['name'])) == 0:
310
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
311
                                   description='API.INVALID_SVG_NAME')
312
        name = str.strip(new_values['data']['name'])
313
314
        if 'source_code' not in new_values['data'].keys() or \
315
                not isinstance(new_values['data']['source_code'], str) or \
316
                len(str.strip(new_values['data']['source_code'])) == 0:
317
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
318
                                   description='API.INVALID_SVG_SOURCE_CODE')
319
        source_code = str.strip(new_values['data']['source_code'])
320
321
        if 'description' in new_values['data'].keys() and \
322
                new_values['data']['description'] is not None and \
323
                len(str(new_values['data']['description'])) > 0:
324
            description = str.strip(new_values['data']['description'])
325
        else:
326
            description = None
327
328
        cnx = mysql.connector.connect(**config.myems_system_db)
329
        cursor = cnx.cursor()
330
331
        cursor.execute(" SELECT name "
332
                       " FROM tbl_svgs "
333
                       " WHERE name = %s AND id != %s ", (name, id_))
334
        if cursor.fetchone() is not None:
335
            cursor.close()
336
            cnx.close()
337
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
338
                                   description='API.SVG_NAME_IS_ALREADY_IN_USE')
339
340
        update_row = (" UPDATE tbl_svgs "
341
                      " SET name = %s, source_code = %s, description = %s "
342
                      " WHERE id = %s ")
343
        cursor.execute(update_row, (name,
344
                                    source_code,
345
                                    description,
346
                                    id_))
347
        cnx.commit()
348
349
        cursor.close()
350
        cnx.close()
351
352
        resp.status = falcon.HTTP_200
353
354
355
class SVGExport:
356
    def __init__(self):
357
        """Initializes SVGExport"""
358
        pass
359
360
    @staticmethod
361
    def on_options(req, resp, id_):
362
        _ = req
363
        resp.status = falcon.HTTP_200
364
        _ = id_
365
366
    @staticmethod
367
    def on_get(req, resp, id_):
368
        if 'API-KEY' not in req.headers or \
369
                not isinstance(req.headers['API-KEY'], str) or \
370
                len(str.strip(req.headers['API-KEY'])) == 0:
371
            access_control(req)
372
        else:
373
            api_key_control(req)
374
        if not id_.isdigit() or int(id_) <= 0:
375
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
376
                                   description='API.INVALID_SVG_ID')
377
378
        cnx = mysql.connector.connect(**config.myems_system_db)
379
        cursor = cnx.cursor()
380
381
        query = (" SELECT id, name, uuid, source_code, description "
382
                 " FROM tbl_svgs "
383
                 " WHERE id = %s ")
384
        cursor.execute(query, (id_,))
385
        row = cursor.fetchone()
386
387
        if row is None:
388
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
389
                                   description='API.SVG_NOT_FOUND')
390
        else:
391
            meta_result = {"id": row[0],
392
                           "name": row[1],
393
                           "uuid": row[2],
394
                           "source_code": row[3],
395
                           "description": row[4]}
396
        cursor.close()
397
        cnx.close()
398
        resp.text = json.dumps(meta_result)
399
400
401
class SVGImport:
402
    def __init__(self):
403
        """Initializes SVGImport"""
404
        pass
405
406
    @staticmethod
407
    def on_options(req, resp):
408
        _ = req
409
        resp.status = falcon.HTTP_200
410
411
    @staticmethod
412
    @user_logger
413
    def on_post(req, resp):
414
        """Handles POST requests"""
415
        admin_control(req)
416
        try:
417
            raw_json = req.stream.read().decode('utf-8')
418
        except Exception as ex:
419
            print(str(ex))
420
            raise falcon.HTTPError(status=falcon.HTTP_400,
421
                                   title='API.BAD_REQUEST',
422
                                   description='API.FAILED_TO_READ_REQUEST_STREAM')
423
424
        new_values = json.loads(raw_json)
425
426
        if 'name' not in new_values.keys() or \
427
                not isinstance(new_values['name'], str) or \
428
                len(str.strip(new_values['name'])) == 0:
429
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
430
                                   description='API.INVALID_SVG_NAME')
431
        name = str.strip(new_values['name'])
432
433
        if 'source_code' not in new_values.keys() or \
434
                not isinstance(new_values['source_code'], str) or \
435
                len(str.strip(new_values['source_code'])) == 0:
436
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
437
                                   description='API.INVALID_SVG_SOURCE_CODE')
438
        source_code = str.strip(new_values['source_code'])
439
440
        if 'description' in new_values.keys() and \
441
                new_values['description'] is not None and \
442
                len(str(new_values['description'])) > 0:
443
            description = str.strip(new_values['description'])
444
        else:
445
            description = None
446
447
        cnx = mysql.connector.connect(**config.myems_system_db)
448
        cursor = cnx.cursor()
449
450
        cursor.execute(" SELECT name "
451
                       " FROM tbl_svgs "
452
                       " WHERE name = %s ", (name,))
453
        if cursor.fetchone() is not None:
454
            cursor.close()
455
            cnx.close()
456
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
457
                                   description='API.SVG_NAME_IS_ALREADY_IN_USE')
458
459
        add_values = (" INSERT INTO tbl_svgs "
460
                      "    (name, uuid, source_code, description) "
461
                      " VALUES (%s, %s, %s, %s) ")
462
        cursor.execute(add_values, (name,
463
                                    str(uuid.uuid4()),
464
                                    source_code,
465
                                    description))
466
        new_id = cursor.lastrowid
467
        cnx.commit()
468
        cursor.close()
469
        cnx.close()
470
471
        resp.status = falcon.HTTP_201
472
        resp.location = '/svgs/' + str(new_id)
473
474
475
class SVGClone:
476
    def __init__(self):
477
        """Initializes SVGClone"""
478
        pass
479
480
    @staticmethod
481
    def on_options(req, resp, id_):
482
        _ = req
483
        resp.status = falcon.HTTP_200
484
        _ = id_
485
486
    @staticmethod
487
    @user_logger
488
    def on_post(req, resp, id_):
489
        admin_control(req)
490
        if not id_.isdigit() or int(id_) <= 0:
491
            raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
492
                                   description='API.INVALID_SVG_ID')
493
494
        cnx = mysql.connector.connect(**config.myems_system_db)
495
        cursor = cnx.cursor()
496
497
        query = (" SELECT id, name, uuid, source_code, description "
498
                 " FROM tbl_svgs "
499
                 " WHERE id = %s ")
500
        cursor.execute(query, (id_,))
501
        row = cursor.fetchone()
502
503
        if row is None:
504
            raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
505
                                   description='API.SVG_NOT_FOUND')
506
        else:
507
            meta_result = {"id": row[0],
508
                           "name": row[1],
509
                           "uuid": row[2],
510
                           "source_code": row[3],
511
                           "description": row[4]}
512
513
            timezone_offset = int(config.utc_offset[1:3]) * 60 + int(config.utc_offset[4:6])
514
            if config.utc_offset[0] == '-':
515
                timezone_offset = -timezone_offset
516
            new_name = (str.strip(meta_result['name']) +
517
                        (datetime.utcnow() + timedelta(minutes=timezone_offset)).isoformat(sep='-', timespec='seconds'))
518
            add_values = (" INSERT INTO tbl_svgs "
519
                          "    (name, uuid, source_code, description) "
520
                          " VALUES (%s, %s, %s, %s) ")
521
            cursor.execute(add_values, (new_name,
522
                                        str(uuid.uuid4()),
523
                                        meta_result['source_code'],
524
                                        meta_result['description']))
525
            new_id = cursor.lastrowid
526
            cnx.commit()
527
            cursor.close()
528
            cnx.close()
529
530
            resp.status = falcon.HTTP_201
531
            resp.location = '/svgs/' + str(new_id)
532