Passed
Push — master ( faba06...81555f )
by Guangyu
08:00 queued 11s
created

core.textmessage   F

Complexity

Total Complexity 63

Size/Duplication

Total Lines 302
Duplicated Lines 37.42 %

Importance

Changes 0
Metric Value
wmc 63
eloc 232
dl 113
loc 302
rs 3.36
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A TextMessageCollection.__init__() 0 4 1
F TextMessageCollection.on_get() 0 71 14
A TextMessageCollection.on_options() 0 3 1
A TextMessageItem.on_options() 3 3 1
B TextMessageItem.on_delete() 31 31 8
F TextMessageCollection.on_post() 35 131 29
B TextMessageItem.on_get() 36 36 8
A TextMessageItem.__init__() 4 4 1

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.textmessage 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 View Code Duplication
class TextMessageItem:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
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
    @staticmethod
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_delete(req, resp, id_):
274
        access_control(req)
275
        if not id_.isdigit() or int(id_) <= 0:
276
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
277
                                   description='API.INVALID_TEXT_MESSAGE_ID')
278
279
        cnx = mysql.connector.connect(**config.myems_fdd_db)
280
        cursor = cnx.cursor()
281
282
        cursor.execute(" SELECT id FROM tbl_text_messages_outbox WHERE id = %s ", (id_,))
283
        row = cursor.fetchone()
284
285
        if row is None:
286
            if cursor:
287
                cursor.close()
288
            if cnx:
289
                cnx.disconnect()
290
            raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
291
                                   description='API.TEXT_MESSAGE_NOT_FOUND')
292
293
        cursor.execute(" DELETE FROM tbl_text_messages_outbox WHERE id = %s ", (id_,))
294
        cnx.commit()
295
296
        if cursor:
297
            cursor.close()
298
        if cnx:
299
            cnx.disconnect()
300
301
        resp.status = falcon.HTTP_204
302