Passed
Push — master ( aaa290...76ee5c )
by Guangyu
07:18 queued 11s
created

core.costfile.CostFileCollection.on_get()   B

Complexity

Conditions 5

Size

Total Lines 29
Code Lines 23

Duplication

Lines 29
Ratio 100 %

Importance

Changes 0
Metric Value
eloc 23
dl 29
loc 29
rs 8.8613
c 0
b 0
f 0
cc 5
nop 2
1
import falcon
2
import json
3
import mysql.connector
4
import config
5
import uuid
6
from datetime import datetime, timezone, timedelta
7
import os
8
from core.userlogger import user_logger
9
10
11 View Code Duplication
class CostFileCollection:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
12
    @staticmethod
13
    def __init__():
14
        """"Initializes CostFileCollection"""
15
        pass
16
17
    @staticmethod
18
    def on_options(req, resp):
19
        resp.status = falcon.HTTP_200
20
21
    @staticmethod
22
    def on_get(req, resp):
23
        cnx = mysql.connector.connect(**config.myems_historical_db)
24
        cursor = cnx.cursor()
25
26
        query = (" SELECT id, file_name, uuid, upload_datetime_utc, status "
27
                 " FROM tbl_cost_files "
28
                 " ORDER BY upload_datetime_utc desc ")
29
        cursor.execute(query)
30
        rows = cursor.fetchall()
31
        cursor.close()
32
        cnx.disconnect()
33
34
        timezone_offset = int(config.utc_offset[1:3]) * 60 + int(config.utc_offset[4:6])
35
        if config.utc_offset[0] == '-':
36
            timezone_offset = -timezone_offset
37
38
        result = list()
39
        if rows is not None and len(rows) > 0:
40
            for row in rows:
41
                upload_datetime_local = row[3].replace(tzinfo=timezone.utc) + timedelta(minutes=timezone_offset)
42
                meta_result = {"id": row[0],
43
                               "file_name": row[1],
44
                               "uuid": row[2],
45
                               "upload_datetime": upload_datetime_local.strftime('%Y-%m-%dT%H:%M:%S'),
46
                               "status": row[4]}
47
                result.append(meta_result)
48
49
        resp.body = json.dumps(result)
50
51
    @staticmethod
52
    @user_logger
53
    def on_post(req, resp):
54
        """Handles POST requests"""
55
        try:
56
            upload = req.get_param('file')
57
            # Read upload file as binary
58
            raw_blob = upload.file.read()
59
            # Retrieve filename
60
            filename = upload.filename
61
            file_uuid = str(uuid.uuid4())
62
63
            # Define file_path
64
            file_path = os.path.join(config.upload_path, file_uuid)
65
66
            # Write to a temporary file to prevent incomplete files from
67
            # being used.
68
            temp_file_path = file_path + '~'
69
70
            open(temp_file_path, 'wb').write(raw_blob)
71
72
            # Now that we know the file has been fully saved to disk
73
            # move it into place.
74
            os.rename(temp_file_path, file_path)
75
        except Exception as ex:
76
            raise falcon.HTTPError(falcon.HTTP_400, title='API.ERROR',
77
                                   description='API.FAILED_TO_UPLOAD_COST_FILE')
78
79
        # Verify User Session
80
        token = req.headers.get('TOKEN')
81
        user_uuid = req.headers.get('USER-UUID')
82
        if token is None:
83
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
84
                                   description='API.TOKEN_NOT_FOUND_IN_HEADERS_PLEASE_LOGIN')
85
        if user_uuid is None:
86
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
87
                                   description='API.USER_UUID_NOT_FOUND_IN_HEADERS_PLEASE_LOGIN')
88
89
        cnx_user_db = mysql.connector.connect(**config.myems_user_db)
90
        cursor_user_db = cnx_user_db.cursor()
91
92
        query = (" SELECT utc_expires "
93
                 " FROM tbl_sessions "
94
                 " WHERE user_uuid = %s AND token = %s")
95
        cursor_user_db.execute(query, (user_uuid, token,))
96
        row = cursor_user_db.fetchone()
97
98
        if row is None:
99
            if cursor_user_db:
100
                cursor_user_db.close()
101
            if cnx_user_db:
102
                cnx_user_db.disconnect()
103
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
104
                                   description='API.INVALID_SESSION_PLEASE_RE_LOGIN')
105
        else:
106
            utc_expires = row[0]
107
            if datetime.utcnow() > utc_expires:
108
                if cursor_user_db:
109
                    cursor_user_db.close()
110
                if cnx_user_db:
111
                    cnx_user_db.disconnect()
112
                raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
113
                                       description='API.USER_SESSION_TIMEOUT')
114
115
        cursor_user_db.execute(" SELECT id "
116
                               " FROM tbl_users "
117
                               " WHERE uuid = %s ",
118
                               (user_uuid,))
119
        row = cursor_user_db.fetchone()
120
        if row is None:
121
            if cursor_user_db:
122
                cursor_user_db.close()
123
            if cnx_user_db:
124
                cnx_user_db.disconnect()
125
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
126
                                   description='API.INVALID_USER_PLEASE_RE_LOGIN')
127
128
        cnx_historical_db = mysql.connector.connect(**config.myems_historical_db)
129
        cursor_historical_db = cnx_historical_db.cursor()
130
131
        add_values = (" INSERT INTO tbl_cost_files "
132
                      " (file_name, uuid, upload_datetime_utc, status, file_object ) "
133
                      " VALUES (%s, %s, %s, %s, %s) ")
134
        cursor_historical_db.execute(add_values, (filename,
135
                                                  file_uuid,
136
                                                  datetime.utcnow(),
137
                                                  'new',
138
                                                  raw_blob))
139
        new_id = cursor_historical_db.lastrowid
140
        cnx_historical_db.commit()
141
        cursor_historical_db.close()
142
        cnx_historical_db.disconnect()
143
144
        resp.status = falcon.HTTP_201
145
        resp.location = '/costfiles/' + str(new_id)
146
147
148 View Code Duplication
class CostFileItem:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
149
    @staticmethod
150
    def __init__():
151
        """"Initializes CostFileItem"""
152
        pass
153
154
    @staticmethod
155
    def on_options(req, resp, id_):
156
        resp.status = falcon.HTTP_200
157
158
    @staticmethod
159
    def on_get(req, resp, id_):
160
        if not id_.isdigit() or int(id_) <= 0:
161
            raise falcon.HTTPError(falcon.HTTP_400,
162
                                   title='API.BAD_REQUEST',
163
                                   description='API.INVALID_COST_FILE_ID')
164
165
        cnx = mysql.connector.connect(**config.myems_historical_db)
166
        cursor = cnx.cursor()
167
168
        query = (" SELECT id, file_name, uuid, upload_datetime_utc, status "
169
                 " FROM tbl_cost_files "
170
                 " WHERE id = %s ")
171
        cursor.execute(query, (id_,))
172
        row = cursor.fetchone()
173
        cursor.close()
174
        cnx.disconnect()
175
        if row is None:
176
            raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
177
                                   description='API.COST_FILE_NOT_FOUND')
178
179
        timezone_offset = int(config.utc_offset[1:3]) * 60 + int(config.utc_offset[4:6])
180
        if config.utc_offset[0] == '-':
181
            timezone_offset = -timezone_offset
182
183
        upload_datetime_local = row[3].replace(tzinfo=timezone.utc) + timedelta(minutes=timezone_offset)
184
        result = {"id": row[0],
185
                  "file_name": row[1],
186
                  "uuid": row[2],
187
                  "upload_datetime": upload_datetime_local.strftime('%Y-%m-%dT%H:%M:%S'),
188
                  "status": row[4]}
189
        resp.body = json.dumps(result)
190
191
    @staticmethod
192
    @user_logger
193
    def on_delete(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_COST_FILE_ID')
197
198
        cnx = mysql.connector.connect(**config.myems_historical_db)
199
        cursor = cnx.cursor()
200
201
        cursor.execute(" SELECT uuid "
202
                       " FROM tbl_cost_files "
203
                       " WHERE id = %s ", (id_,))
204
        row = cursor.fetchone()
205
        if row is None:
206
            cursor.close()
207
            cnx.disconnect()
208
            raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
209
                                   description='API.COST_FILE_NOT_FOUND')
210
211
        try:
212
            file_uuid = row[0]
213
            # Define file_path
214
            file_path = os.path.join(config.upload_path, file_uuid)
215
216
            # remove the file from disk
217
            os.remove(file_path)
218
        except Exception as ex:
219
            # ignore exception and don't return API.COST_FILE_NOT_FOUND error
220
            pass
221
222
        # Note: the energy data imported from the deleted file will not be deleted
223
        cursor.execute(" DELETE FROM tbl_cost_files WHERE id = %s ", (id_,))
224
        cnx.commit()
225
226
        cursor.close()
227
        cnx.disconnect()
228
229
        resp.status = falcon.HTTP_204
230
231
232 View Code Duplication
class CostFileRestore:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
233
    @staticmethod
234
    def __init__():
235
        """"Initializes CostFileRestore"""
236
        pass
237
238
    @staticmethod
239
    def on_options(req, resp, id_):
240
        resp.status = falcon.HTTP_200
241
242
    @staticmethod
243
    def on_get(req, resp, id_):
244
        if not id_.isdigit() or int(id_) <= 0:
245
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
246
                                   description='API.INVALID_COST_FILE_ID')
247
248
        cnx = mysql.connector.connect(**config.myems_historical_db)
249
        cursor = cnx.cursor()
250
251
        query = (" SELECT uuid, file_object "
252
                 " FROM tbl_cost_files "
253
                 " WHERE id = %s ")
254
        cursor.execute(query, (id_,))
255
        row = cursor.fetchone()
256
        cursor.close()
257
        cnx.disconnect()
258
259
        if row is None:
260
            raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
261
                                   description='API.COST_FILE_NOT_FOUND')
262
263
        result = {"uuid": row[0],
264
                  "file_object": row[1]}
265
        try:
266
            raw_blob = result["file_object"]
267
            file_uuid = result["uuid"]
268
269
            # Define file_path
270
            file_path = os.path.join(config.upload_path, file_uuid)
271
272
            # Write to a temporary file to prevent incomplete files from
273
            # being used.
274
            temp_file_path = file_path + '~'
275
276
            open(temp_file_path, 'wb').write(raw_blob)
277
278
            # Now that we know the file has been fully saved to disk
279
            # move it into place.
280
            os.replace(temp_file_path, file_path)
281
        except Exception as ex:
282
            raise falcon.HTTPError(falcon.HTTP_400, title='API.ERROR',
283
                                   description='API.FAILED_TO_RESTORE_COST_FILE')
284
        resp.body = json.dumps('success')
285