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

core.emailmessage.EmailMessageCollection.on_post()   F

Complexity

Conditions 31

Size

Total Lines 145
Code Lines 116

Duplication

Lines 35
Ratio 24.14 %

Importance

Changes 0
Metric Value
eloc 116
dl 35
loc 145
rs 0
c 0
b 0
f 0
cc 31
nop 2

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.emailmessage.EmailMessageCollection.on_post() 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
import re
6
from datetime import datetime, timedelta, timezone
7
from core.useractivity import user_logger, access_control
8
9
10
class EmailMessageCollection:
11
    @staticmethod
12
    def __init__():
13
        """"Initializes EmailMessageCollection"""
14
        pass
15
16
    @staticmethod
17
    def on_options(req, resp):
18
        resp.status = falcon.HTTP_200
19
20 View Code Duplication
    @staticmethod
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
21
    def on_get(req, resp):
22
        access_control(req)
23
        print(req.params)
24
        start_datetime_local = req.params.get('startdatetime')
25
        end_datetime_local = req.params.get('enddatetime')
26
27
        timezone_offset = int(config.utc_offset[1:3]) * 60 + int(config.utc_offset[4:6])
28
        if config.utc_offset[0] == '-':
29
            timezone_offset = -timezone_offset
30
31
        if start_datetime_local is None:
32
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
33
                                   description="API.INVALID_START_DATETIME_FORMAT")
34
        else:
35
            start_datetime_local = str.strip(start_datetime_local)
36
            try:
37
                start_datetime_utc = datetime.strptime(start_datetime_local,
38
                                                       '%Y-%m-%dT%H:%M:%S').replace(tzinfo=timezone.utc) - \
39
                    timedelta(minutes=timezone_offset)
40
            except ValueError:
41
                raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
42
                                       description="API.INVALID_START_DATETIME_FORMAT")
43
44
        if end_datetime_local is None:
45
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
46
                                   description="API.INVALID_END_DATETIME_FORMAT")
47
        else:
48
            end_datetime_local = str.strip(end_datetime_local)
49
            try:
50
                end_datetime_utc = datetime.strptime(end_datetime_local,
51
                                                     '%Y-%m-%dT%H:%M:%S').replace(tzinfo=timezone.utc) - \
52
                    timedelta(minutes=timezone_offset)
53
            except ValueError:
54
                raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
55
                                       description="API.INVALID_END_DATETIME_FORMAT")
56
57
        if start_datetime_utc >= end_datetime_utc:
58
            raise falcon.HTTPError(falcon.HTTP_400,
59
                                   title='API.BAD_REQUEST',
60
                                   description='API.START_DATETIME_MUST_BE_EARLIER_THAN_END_DATETIME')
61
62
        cnx = mysql.connector.connect(**config.myems_fdd_db)
63
        cursor = cnx.cursor()
64
65
        query = (" SELECT id, recipient_name, recipient_email, "
66
                 "        subject, message, attachment_file_name, "
67
                 "        created_datetime_utc, scheduled_datetime_utc, status "
68
                 " FROM tbl_email_messages "
69
                 " WHERE created_datetime_utc >= %s AND created_datetime_utc < %s "
70
                 " ORDER BY created_datetime_utc ")
71
        cursor.execute(query, (start_datetime_utc, end_datetime_utc))
72
        rows = cursor.fetchall()
73
74
        if cursor:
75
            cursor.close()
76
        if cnx:
77
            cnx.disconnect()
78
79
        result = list()
80
        if rows is not None and len(rows) > 0:
81
            for row in rows:
82
                meta_result = {"id": row[0],
83
                               "recipient_name": row[1],
84
                               "recipient_email": row[2],
85
                               "subject": row[3],
86
                               "message": row[4].replace("<br>", ""),
87
                               "attachment_file_name": row[5],
88
                               "created_datetime": row[6].timestamp() * 1000 if isinstance(row[6], datetime) else None,
89
                               "scheduled_datetime":
90
                                   row[7].timestamp() * 1000 if isinstance(row[7], datetime) else None,
91
                               "status": row[8]}
92
                result.append(meta_result)
93
94
        resp.text = json.dumps(result)
95
96
    @staticmethod
97
    @user_logger
98
    def on_post(req, resp):
99
        """Handles POST requests"""
100
        access_control(req)
101
        try:
102
            upload = req.get_param('file')
103
            # Read upload file as binary
104
            attachment_file_object = upload.file.read()
105
            # Retrieve filename
106
            attachment_file_name = upload.filename
107
        except Exception as ex:
108
            raise falcon.HTTPError(falcon.HTTP_400, title='API.ERROR',
109
                                   description='API.FAILED_TO_UPLOAD_ATTACHMENT_FILE')
110
        try:
111
            raw_json = req.get_param('req')
112
        except Exception as ex:
113
            raise falcon.HTTPError(falcon.HTTP_400, title='API.ERROR', description=ex)
114
115
        new_values = json.loads(raw_json)
116
117
        if 'rule_id' in new_values['data'].keys():
118
            if new_values['data']['rule_id'] <= 0:
119
                raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
120
                                       description='API.INVALID_RULE_ID')
121
            rule_id = new_values['data']['rule_id']
122
        else:
123
            rule_id = None
124
125
        if 'recipient_name' not in new_values['data'].keys() or \
126
                not isinstance(new_values['data']['recipient_name'], str) or \
127
                len(str.strip(new_values['data']['recipient_name'])) == 0:
128
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
129
                                   description='API.INVALID_RECIPIENT_NAME')
130
        recipient_name = str.strip(new_values['data']['recipient_name'])
131
132
        if 'recipient_email' not in new_values['data'].keys() or \
133
                not isinstance(new_values['data']['recipient_email'], str) or \
134
                len(str.strip(new_values['data']['recipient_email'])) == 0:
135
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
136
                                   description='API.INVALID_RECIPIENT_EMAIL')
137
        recipient_email = str.strip(new_values['data']['recipient_email'])
138
        match = re.match(r'^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$', recipient_email)
139
        if match is None:
140
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
141
                                   description='API.INVALID_EMAIL')
142
143
        if 'subject' not in new_values['data'].keys() or \
144
                not isinstance(new_values['data']['subject'], str) or \
145
                len(str.strip(new_values['data']['subject'])) == 0:
146
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
147
                                   description='API.INVALID_SUBJECT_VALUE')
148
        subject = str.strip(new_values['data']['subject'])
149
150
        if 'message' not in new_values['data'].keys() or \
151
                not isinstance(new_values['data']['message'], str) or \
152
                len(str.strip(new_values['data']['message'])) == 0:
153
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
154
                                   description='API.INVALID_MESSAGE_VALUE')
155
        message = str.strip(new_values['data']['message'])
156
157
        if 'created_datetime' not in new_values['data'].keys() or \
158
                not isinstance(new_values['data']['created_datetime'], str) or \
159
                len(str.strip(new_values['data']['created_datetime'])) == 0:
160
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
161
                                   description='API.INVALID_CREATED_DATETIME')
162
        created_datetime_local = str.strip(new_values['data']['created_datetime'])
163
164
        if 'scheduled_datetime' not in new_values['data'].keys() or \
165
                not isinstance(new_values['data']['scheduled_datetime'], str) or \
166
                len(str.strip(new_values['data']['scheduled_datetime'])) == 0:
167
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
168
                                   description='API.INVALID_SCHEDULED_DATETIME')
169
        scheduled_datetime_local = str.strip(new_values['data']['scheduled_datetime'])
170
171
        timezone_offset = int(config.utc_offset[1:3]) * 60 + int(config.utc_offset[4:6])
172
        if config.utc_offset[0] == '-':
173
            timezone_offset = -timezone_offset
174
175 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...
176
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
177
                                   description="API.INVALID_CREATED_DATETIME")
178
        else:
179
            created_datetime_local = str.strip(created_datetime_local)
180
            try:
181
                created_datetime_utc = datetime.strptime(created_datetime_local,
182
                                                         '%Y-%m-%dT%H:%M:%S').replace(tzinfo=timezone.utc) - \
183
                                     timedelta(minutes=timezone_offset)
184
            except ValueError:
185
                raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
186
                                       description="API.INVALID_CREATED_DATETIME")
187
188 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...
189
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
190
                                   description="API.INVALID_SCHEDULED_DATETIME")
191
        else:
192
            scheduled_datetime_local = str.strip(scheduled_datetime_local)
193
            try:
194
                scheduled_datetime_utc = datetime.strptime(scheduled_datetime_local,
195
                                                           '%Y-%m-%dT%H:%M:%S').replace(tzinfo=timezone.utc) - \
196
                                     timedelta(minutes=timezone_offset)
197
            except ValueError:
198
                raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
199
                                       description="API.INVALID_SCHEDULED_DATETIME")
200
201
        status = 'new'
202
203
        cnx = mysql.connector.connect(**config.myems_fdd_db)
204
        cursor = cnx.cursor()
205
206 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...
207
            cursor.execute(" SELECT name "
208
                           " FROM tbl_rules "
209
                           " WHERE id = %s ",
210
                           (new_values['data']['rule_id'],))
211
            row = cursor.fetchone()
212
            if row is None:
213
                cursor.close()
214
                cnx.disconnect()
215
                raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
216
                                       description='API.RULE_NOT_FOUND')
217
218
        add_row = (" INSERT INTO tbl_email_messages "
219
                   "             (rule_id, recipient_name, recipient_email, subject, message, "
220
                   "              attachment_file_name, attachment_file_object, created_datetime_utc,"
221
                   "              scheduled_datetime_utc, status) "
222
                   " VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s) ")
223
224
        cursor.execute(add_row, (rule_id,
225
                                 recipient_name,
226
                                 recipient_email,
227
                                 subject,
228
                                 message,
229
                                 attachment_file_name,
230
                                 attachment_file_object,
231
                                 created_datetime_utc,
232
                                 scheduled_datetime_utc,
233
                                 status))
234
        new_id = cursor.lastrowid
235
        cnx.commit()
236
        cursor.close()
237
        cnx.disconnect()
238
239
        resp.status = falcon.HTTP_201
240
        resp.location = '/emailmessages/' + str(new_id)
241
242
243 View Code Duplication
class EmailMessageItem:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
244
    @staticmethod
245
    def __init__():
246
        """"Initializes EmailMessageItem"""
247
        pass
248
249
    @staticmethod
250
    def on_options(req, resp, id_):
251
        resp.status = falcon.HTTP_200
252
253
    @staticmethod
254
    def on_get(req, resp, id_):
255
        access_control(req)
256
        if not id_.isdigit() or int(id_) <= 0:
257
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
258
                                   description='API.INVALID_EMAIL_MESSAGE_ID')
259
260
        cnx = mysql.connector.connect(**config.myems_fdd_db)
261
        cursor = cnx.cursor()
262
263
        query = (" SELECT id, recipient_name, recipient_email, "
264
                 "        subject, message, attachment_file_name, "
265
                 "        created_datetime_utc, scheduled_datetime_utc, status "
266
                 " FROM tbl_email_messages "
267
                 " WHERE id = %s ")
268
        cursor.execute(query, (id_,))
269
        row = cursor.fetchone()
270
271
        if cursor:
272
            cursor.close()
273
        if cnx:
274
            cnx.disconnect()
275
276
        if row is None:
277
            raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
278
                                   description='API.EMAIL_MESSAGE_NOT_FOUND')
279
280
        result = {"id": row[0],
281
                  "recipient_name": row[1],
282
                  "recipient_email": row[2],
283
                  "subject": row[3],
284
                  "message": row[4].replace("<br>", ""),
285
                  "attachment_file_name": row[5],
286
                  "created_datetime": row[6].timestamp() * 1000 if isinstance(row[6], datetime) else None,
287
                  "scheduled_datetime": row[7].timestamp() * 1000 if isinstance(row[7], datetime) else None,
288
                  "status": row[8]}
289
290
        resp.text = json.dumps(result)
291
292
    @staticmethod
293
    @user_logger
294
    def on_delete(req, resp, id_):
295
        access_control(req)
296
        if not id_.isdigit() or int(id_) <= 0:
297
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
298
                                   description='API.INVALID_EMAIL_MESSAGE_ID')
299
300
        cnx = mysql.connector.connect(**config.myems_fdd_db)
301
        cursor = cnx.cursor()
302
303
        cursor.execute(" SELECT id "
304
                       " FROM tbl_email_messages "
305
                       " WHERE id = %s ", (id_,))
306
        row = cursor.fetchone()
307
308
        if row is None:
309
            if cursor:
310
                cursor.close()
311
            if cnx:
312
                cnx.disconnect()
313
            raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
314
                                   description='API.EMAIL_MESSAGE_NOT_FOUND')
315
316
        cursor.execute(" DELETE FROM tbl_email_messages WHERE id = %s ", (id_,))
317
        cnx.commit()
318
319
        if cursor:
320
            cursor.close()
321
        if cnx:
322
            cnx.disconnect()
323
324
        resp.status = falcon.HTTP_204
325