Passed
Push — master ( fadf13...ffa5b9 )
by Guangyu
07:19 queued 11s
created

core.textmessage.TextMessageItem.on_put()   F

Complexity

Conditions 36

Size

Total Lines 151
Code Lines 118

Duplication

Lines 35
Ratio 23.18 %

Importance

Changes 0
Metric Value
eloc 118
dl 35
loc 151
rs 0
c 0
b 0
f 0
cc 36
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.textmessage.TextMessageItem.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 falcon
2
import simplejson as json
3
import mysql.connector
4
import config
5
from datetime import datetime, timedelta, timezone
6
from core.useractivity import user_logger, access_control
7
8
9
class TextMessageCollection:
10
    @staticmethod
11
    def __init__():
12
        """"Initializes TextMessageCollection"""
13
        pass
14
15
    @staticmethod
16
    def on_options(req, resp):
17
        resp.status = falcon.HTTP_200
18
19
    @staticmethod
20
    def on_get(req, resp):
21
        access_control(req)
22
23
        start_datetime_local = req.params.get('startdatetime')
24
        end_datetime_local = req.params.get('enddatetime')
25
26
        timezone_offset = int(config.utc_offset[1:3]) * 60 + int(config.utc_offset[4:6])
27
        if config.utc_offset[0] == '-':
28
            timezone_offset = -timezone_offset
29
30
        if start_datetime_local is None:
31
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
32
                                   description="API.INVALID_START_DATETIME_FORMAT")
33
        else:
34
            start_datetime_local = str.strip(start_datetime_local)
35
            try:
36
                start_datetime_utc = datetime.strptime(start_datetime_local,
37
                                                       '%Y-%m-%dT%H:%M:%S').replace(tzinfo=timezone.utc) - \
38
                                     timedelta(minutes=timezone_offset)
39
            except ValueError:
40
                raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
41
                                       description="API.INVALID_START_DATETIME_FORMAT")
42
43
        if end_datetime_local is None:
44
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
45
                                   description="API.INVALID_END_DATETIME_FORMAT")
46
        else:
47
            end_datetime_local = str.strip(end_datetime_local)
48
            try:
49
                end_datetime_utc = datetime.strptime(end_datetime_local,
50
                                                     '%Y-%m-%dT%H:%M:%S').replace(tzinfo=timezone.utc) - \
51
                                   timedelta(minutes=timezone_offset)
52
            except ValueError:
53
                raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
54
                                       description="API.INVALID_END_DATETIME_FORMAT")
55
56
        if start_datetime_utc >= end_datetime_utc:
57
            raise falcon.HTTPError(falcon.HTTP_400,
58
                                   title='API.BAD_REQUEST',
59
                                   description='API.START_DATETIME_MUST_BE_EARLIER_THAN_END_DATETIME')
60
        cnx = mysql.connector.connect(**config.myems_fdd_db)
61
        cursor = cnx.cursor()
62
63
        query = (" SELECT id, recipient_name, recipient_mobile, "
64
                 "        message, created_datetime_utc, scheduled_datetime_utc, acknowledge_code, status "
65
                 " FROM tbl_text_messages_outbox "
66
                 " WHERE created_datetime_utc >= %s AND created_datetime_utc < %s "
67
                 " ORDER BY created_datetime_utc DESC ")
68
        cursor.execute(query, (start_datetime_utc, end_datetime_utc))
69
        rows = cursor.fetchall()
70
71
        if cursor:
72
            cursor.close()
73
        if cnx:
74
            cnx.disconnect()
75
76
        result = list()
77
        if rows is not None and len(rows) > 0:
78
            for row in rows:
79
                meta_result = {"id": row[0],
80
                               "recipient_name": row[1],
81
                               "recipient_mobile": row[2],
82
                               "message": row[3],
83
                               "created_datetime": row[4].timestamp() * 1000 if isinstance(row[4], datetime) else None,
84
                               "scheduled_datetime": row[5].timestamp() * 1000 if isinstance(row[5], datetime) else None,
85
                               "acknowledge_code": row[6],
86
                               "status": row[7]}
87
                result.append(meta_result)
88
89
        resp.text = json.dumps(result)
90
91
    @staticmethod
92
    @user_logger
93
    def on_post(req, resp):
94
        """Handles POST requests"""
95
        access_control(req)
96
97
        try:
98
            raw_json = req.stream.read().decode('utf-8')
99
        except Exception as ex:
100
            raise falcon.HTTPError(falcon.HTTP_400, title='API.ERROR', description=ex)
101
102
        new_values = json.loads(raw_json)
103
104
        if 'rule_id' in new_values['data'].keys():
105
            if new_values['data']['rule_id'] <= 0:
106
                raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
107
                                       description='API.INVALID_RULE_ID')
108
            rule_id = new_values['data']['rule_id']
109
        else:
110
            rule_id = None
111
112
        if 'recipient_name' not in new_values['data'].keys() or \
113
                not isinstance(new_values['data']['recipient_name'], str) or \
114
                len(str.strip(new_values['data']['recipient_name'])) == 0:
115
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
116
                                   description='API.INVALID_RECIPIENT_NAME')
117
        recipient_name = str.strip(new_values['data']['recipient_name'])
118
119
        if 'recipient_mobile' not in new_values['data'].keys() or \
120
                not isinstance(new_values['data']['recipient_mobile'], str) or \
121
                len(str.strip(new_values['data']['recipient_mobile'])) == 0:
122
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
123
                                   description='API.INVALID_RECIPIENT_MOBILE')
124
        recipient_mobile = str.strip(new_values['data']['recipient_mobile'])
125
126
        if 'message' not in new_values['data'].keys() or \
127
                not isinstance(new_values['data']['message'], str) or \
128
                len(str.strip(new_values['data']['message'])) == 0:
129
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
130
                                   description='API.INVALID_MESSAGE_VALUE')
131
        message = str.strip(new_values['data']['message'])
132
133
        if 'acknowledge_code' not in new_values['data'].keys() or \
134
                not isinstance(new_values['data']['acknowledge_code'], str) or \
135
                len(str.strip(new_values['data']['acknowledge_code'])) == 0:
136
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
137
                                   description='API.INVALID_ACKNOWLEDGE_CODE')
138
        acknowledge_code = str.strip(new_values['data']['acknowledge_code'])
139
140
        if 'created_datetime' not in new_values['data'].keys() or \
141
                not isinstance(new_values['data']['created_datetime'], str) or \
142
                len(str.strip(new_values['data']['created_datetime'])) == 0:
143
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
144
                                   description='API.INVALID_CREATED_DATETIME')
145
        created_datetime_local = str.strip(new_values['data']['created_datetime'])
146
147
        if 'scheduled_datetime' not in new_values['data'].keys() or \
148
                not isinstance(new_values['data']['scheduled_datetime'], str) or \
149
                len(str.strip(new_values['data']['scheduled_datetime'])) == 0:
150
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
151
                                   description='API.INVALID_SCHEDULED_DATETIME')
152
        scheduled_datetime_local = str.strip(new_values['data']['scheduled_datetime'])
153
154
        timezone_offset = int(config.utc_offset[1:3]) * 60 + int(config.utc_offset[4:6])
155
        if config.utc_offset[0] == '-':
156
            timezone_offset = -timezone_offset
157
158 View Code Duplication
        if created_datetime_local is None:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
159
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
160
                                   description="API.INVALID_CREATED_DATETIME")
161
        else:
162
            created_datetime_local = str.strip(created_datetime_local)
163
            try:
164
                created_datetime_utc = datetime.strptime(created_datetime_local,
165
                                                         '%Y-%m-%dT%H:%M:%S').replace(tzinfo=timezone.utc) - \
166
                                     timedelta(minutes=timezone_offset)
167
            except ValueError:
168
                raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
169
                                       description="API.INVALID_CREATED_DATETIME")
170
171 View Code Duplication
        if scheduled_datetime_local is None:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
172
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
173
                                   description="API.INVALID_SCHEDULED_DATETIME")
174
        else:
175
            scheduled_datetime_local = str.strip(scheduled_datetime_local)
176
            try:
177
                scheduled_datetime_utc = datetime.strptime(scheduled_datetime_local,
178
                                                           '%Y-%m-%dT%H:%M:%S').replace(tzinfo=timezone.utc) - \
179
                                     timedelta(minutes=timezone_offset)
180
            except ValueError:
181
                raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
182
                                       description="API.INVALID_SCHEDULED_DATETIME")
183
184
        status = 'new'
185
186
        cnx = mysql.connector.connect(**config.myems_fdd_db)
187
        cursor = cnx.cursor()
188
189 View Code Duplication
        if rule_id is not None:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
190
            cursor.execute(" SELECT name "
191
                           " FROM tbl_rules "
192
                           " WHERE id = %s ",
193
                           (new_values['data']['rule_id'],))
194
            row = cursor.fetchone()
195
            if row is None:
196
                cursor.close()
197
                cnx.disconnect()
198
                raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
199
                                       description='API.RULE_NOT_FOUND')
200
201
        add_row = (" INSERT INTO tbl_text_messages_outbox"
202
                   "             (rule_id, recipient_name, recipient_mobile, message, "
203
                   "              acknowledge_code, created_datetime_utc,"
204
                   "              scheduled_datetime_utc, status) "
205
                   " VALUES (%s, %s, %s, %s, %s, %s, %s, %s) ")
206
207
        cursor.execute(add_row, (rule_id,
208
                                 recipient_name,
209
                                 recipient_mobile,
210
                                 message,
211
                                 acknowledge_code,
212
                                 created_datetime_utc,
213
                                 scheduled_datetime_utc,
214
                                 status))
215
        new_id = cursor.lastrowid
216
        cnx.commit()
217
        cursor.close()
218
        cnx.disconnect()
219
220
        resp.status = falcon.HTTP_201
221
        resp.location = '/textmessages/' + str(new_id)
222
223
224
class TextMessageItem:
225
    @staticmethod
226
    def __init__():
227
        """"Initializes TextMessageItem"""
228
        pass
229
230
    @staticmethod
231
    def on_options(req, resp, id_):
232
        resp.status = falcon.HTTP_200
233
234 View Code Duplication
    @staticmethod
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
235
    def on_get(req, resp, id_):
236
        access_control(req)
237
        if not id_.isdigit() or int(id_) <= 0:
238
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
239
                                   description='API.INVALID_TEXT_MESSAGE_ID')
240
241
        cnx = mysql.connector.connect(**config.myems_fdd_db)
242
        cursor = cnx.cursor()
243
244
        query = (" SELECT id, recipient_name, recipient_mobile, "
245
                 "        message, created_datetime_utc, scheduled_datetime_utc, acknowledge_code, status "
246
                 " FROM tbl_text_messages_outbox "
247
                 " WHERE id = %s ")
248
        cursor.execute(query, (id_,))
249
        row = cursor.fetchone()
250
251
        if cursor:
252
            cursor.close()
253
        if cnx:
254
            cnx.disconnect()
255
256
        if row is None:
257
            raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
258
                                   description='API.TEXT_MESSAGE_NOT_FOUND')
259
260
        result = {"id": row[0],
261
                  "recipient_name": row[1],
262
                  "recipient_mobile": row[2],
263
                  "message": row[3],
264
                  "created_datetime": row[4].timestamp() * 1000 if isinstance(row[4], datetime) else None,
265
                  "scheduled_datetime": row[5].timestamp() * 1000 if isinstance(row[5], datetime) else None,
266
                  "acknowledge_code": row[6],
267
                  "status": row[7]}
268
269
        resp.text = json.dumps(result)
270
271
    @staticmethod
272
    @user_logger
273
    def on_put(req, resp, id_):
274
        """Handles PUT requests"""
275
        access_control(req)
276
277
        if not id_.isdigit() or int(id_) <= 0:
278
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
279
                                   description='API.INVALID_TEXT_MESSAGE_ID')
280
281
        try:
282
            raw_json = req.stream.read().decode('utf-8')
283
        except Exception as ex:
284
            raise falcon.HTTPError(falcon.HTTP_400, title='API.ERROR', description=ex)
285
286
        new_values = json.loads(raw_json)
287
288
        if 'rule_id' in new_values['data'].keys():
289
            if new_values['data']['rule_id'] <= 0:
290
                raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
291
                                       description='API.INVALID_RULE_ID')
292
            rule_id = new_values['data']['rule_id']
293
        else:
294
            rule_id = None
295
296
        if 'recipient_name' not in new_values['data'].keys() or \
297
                not isinstance(new_values['data']['recipient_name'], str) or \
298
                len(str.strip(new_values['data']['recipient_name'])) == 0:
299
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
300
                                   description='API.INVALID_RECIPIENT_NAME')
301
        recipient_name = str.strip(new_values['data']['recipient_name'])
302
303
        if 'recipient_mobile' not in new_values['data'].keys() or \
304
                not isinstance(new_values['data']['recipient_mobile'], str) or \
305
                len(str.strip(new_values['data']['recipient_mobile'])) == 0:
306
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
307
                                   description='API.INVALID_RECIPIENT_MOBILE')
308
        recipient_mobile = str.strip(new_values['data']['recipient_mobile'])
309
310
        if 'message' not in new_values['data'].keys() or \
311
                not isinstance(new_values['data']['message'], str) or \
312
                len(str.strip(new_values['data']['message'])) == 0:
313
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
314
                                   description='API.INVALID_MESSAGE_VALUE')
315
        message = str.strip(new_values['data']['message'])
316
317
        if 'acknowledge_code' not in new_values['data'].keys() or \
318
                not isinstance(new_values['data']['acknowledge_code'], str) or \
319
                len(str.strip(new_values['data']['acknowledge_code'])) == 0:
320
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
321
                                   description='API.INVALID_ACKNOWLEDGE_CODE')
322
        acknowledge_code = str.strip(new_values['data']['acknowledge_code'])
323
324
        if 'status' not in new_values['data'].keys() or \
325
                not isinstance(new_values['data']['status'], str) or \
326
                len(str.strip(new_values['data']['status'])) == 0 or \
327
                str.strip(new_values['data']['status']) not in ('new', 'acknowledged', 'timeout'):
328
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
329
                                   description='API.INVALID_STATUS')
330
        status = str.strip(new_values['data']['status'])
331
332
        if 'created_datetime' not in new_values['data'].keys() or \
333
                not isinstance(new_values['data']['created_datetime'], str) or \
334
                len(str.strip(new_values['data']['created_datetime'])) == 0:
335
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
336
                                   description='API.INVALID_CREATED_DATETIME')
337
        created_datetime_local = str.strip(new_values['data']['created_datetime'])
338
339
        if 'scheduled_datetime' not in new_values['data'].keys() or \
340
                not isinstance(new_values['data']['scheduled_datetime'], str) or \
341
                len(str.strip(new_values['data']['scheduled_datetime'])) == 0:
342
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
343
                                   description='API.INVALID_SCHEDULED_DATETIME')
344
        scheduled_datetime_local = str.strip(new_values['data']['scheduled_datetime'])
345
346
        timezone_offset = int(config.utc_offset[1:3]) * 60 + int(config.utc_offset[4:6])
347
        if config.utc_offset[0] == '-':
348
            timezone_offset = -timezone_offset
349
350 View Code Duplication
        if created_datetime_local is None:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
351
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
352
                                   description="API.INVALID_CREATED_DATETIME")
353
        else:
354
            created_datetime_local = str.strip(created_datetime_local)
355
            try:
356
                created_datetime_utc = datetime.strptime(created_datetime_local,
357
                                                         '%Y-%m-%dT%H:%M:%S').replace(tzinfo=timezone.utc) - \
358
                                     timedelta(minutes=timezone_offset)
359
            except ValueError:
360
                raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
361
                                       description="API.INVALID_CREATED_DATETIME")
362
363 View Code Duplication
        if scheduled_datetime_local is None:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
364
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
365
                                   description="API.INVALID_SCHEDULED_DATETIME")
366
        else:
367
            scheduled_datetime_local = str.strip(scheduled_datetime_local)
368
            try:
369
                scheduled_datetime_utc = datetime.strptime(scheduled_datetime_local,
370
                                                           '%Y-%m-%dT%H:%M:%S').replace(tzinfo=timezone.utc) - \
371
                                     timedelta(minutes=timezone_offset)
372
            except ValueError:
373
                raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
374
                                       description="API.INVALID_SCHEDULED_DATETIME")
375
376
        cnx = mysql.connector.connect(**config.myems_fdd_db)
377
        cursor = cnx.cursor()
378
379
        cursor.execute(" SELECT recipient_name "
380
                       " FROM tbl_text_messages_outbox "
381
                       " WHERE id = %s ", (id_,))
382
383
        if cursor.fetchone() is None:
384
            cursor.close()
385
            cnx.disconnect()
386
            raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
387
                                   description='API.TEXT_MESSAGE_NOT_FOUND')
388
389 View Code Duplication
        if rule_id is not None:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
390
            cursor.execute(" SELECT name "
391
                           " FROM tbl_rules "
392
                           " WHERE id = %s ",
393
                           (new_values['data']['rule_id'],))
394
            row = cursor.fetchone()
395
            if row is None:
396
                cursor.close()
397
                cnx.disconnect()
398
                raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
399
                                       description='API.RULE_NOT_FOUND')
400
401
        update_row = (" UPDATE tbl_text_messages_outbox "
402
                      " SET rule_id = %s, recipient_name = %s, recipient_mobile = %s, message = %s,"
403
                      "     acknowledge_code = %s, created_datetime_utc = %s,"
404
                      "     scheduled_datetime_utc = %s, status = %s"
405
                      " WHERE id = %s ")
406
407
        cursor.execute(update_row, (rule_id,
408
                                    recipient_name,
409
                                    recipient_mobile,
410
                                    message,
411
                                    acknowledge_code,
412
                                    created_datetime_utc,
413
                                    scheduled_datetime_utc,
414
                                    status,
415
                                    id_))
416
417
        cnx.commit()
418
        cursor.close()
419
        cnx.disconnect()
420
421
        resp.status = falcon.HTTP_200
422
423 View Code Duplication
    @staticmethod
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
424
    @user_logger
425
    def on_delete(req, resp, id_):
426
        access_control(req)
427
        if not id_.isdigit() or int(id_) <= 0:
428
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
429
                                   description='API.INVALID_TEXT_MESSAGE_ID')
430
431
        cnx = mysql.connector.connect(**config.myems_fdd_db)
432
        cursor = cnx.cursor()
433
434
        cursor.execute(" SELECT id FROM tbl_text_messages_outbox WHERE id = %s ", (id_,))
435
        row = cursor.fetchone()
436
437
        if row is None:
438
            if cursor:
439
                cursor.close()
440
            if cnx:
441
                cnx.disconnect()
442
            raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
443
                                   description='API.TEXT_MESSAGE_NOT_FOUND')
444
445
        cursor.execute(" DELETE FROM tbl_text_messages_outbox WHERE id = %s ", (id_,))
446
        cnx.commit()
447
448
        if cursor:
449
            cursor.close()
450
        if cnx:
451
            cnx.disconnect()
452
453
        resp.status = falcon.HTTP_204
454