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

OfflineMeterFileItem.on_get()   B

Complexity

Conditions 5

Size

Total Lines 33
Code Lines 26

Duplication

Lines 33
Ratio 100 %

Importance

Changes 0
Metric Value
eloc 26
dl 33
loc 33
rs 8.7893
c 0
b 0
f 0
cc 5
nop 3
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 OfflineMeterFileCollection:
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 OfflineMeterFileCollection"""
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_offline_meter_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_OFFLINE_METER_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 = mysql.connector.connect(**config.myems_user_db)
90
        cursor = cnx.cursor()
91
92
        query = (" SELECT utc_expires "
93
                 " FROM tbl_sessions "
94
                 " WHERE user_uuid = %s AND token = %s")
95
        cursor.execute(query, (user_uuid, token,))
96
        row = cursor.fetchone()
97
98
        if row is None:
99
            if cursor:
100
                cursor.close()
101
            if cnx:
102
                cnx.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:
109
                    cursor.close()
110
                if cnx:
111
                    cnx.disconnect()
112
                raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
113
                                       description='API.USER_SESSION_TIMEOUT')
114
115
        cursor.execute(" SELECT id "
116
                       " FROM tbl_users "
117
                       " WHERE uuid = %s ",
118
                       (user_uuid,))
119
        row = cursor.fetchone()
120
        if row is None:
121
            if cursor:
122
                cursor.close()
123
            if cnx:
124
                cnx.disconnect()
125
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
126
                                   description='API.INVALID_USER_PLEASE_RE_LOGIN')
127
        else:
128
            user_id = row[0]
129
130
        cnx = mysql.connector.connect(**config.myems_historical_db)
131
        cursor = cnx.cursor()
132
133
        add_values = (" INSERT INTO tbl_offline_meter_files "
134
                      " (file_name, uuid, upload_datetime_utc, status, file_object ) "
135
                      " VALUES (%s, %s, %s, %s, %s) ")
136
        cursor.execute(add_values, (filename,
137
                                    file_uuid,
138
                                    datetime.utcnow(),
139
                                    'new',
140
                                    raw_blob))
141
        new_id = cursor.lastrowid
142
        cnx.commit()
143
        cursor.close()
144
        cnx.disconnect()
145
146
        resp.status = falcon.HTTP_201
147
        resp.location = '/offlinemeterfiles/' + str(new_id)
148
149
150 View Code Duplication
class OfflineMeterFileItem:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
151
    @staticmethod
152
    def __init__():
153
        """"Initializes OfflineMeterFileItem"""
154
        pass
155
156
    @staticmethod
157
    def on_options(req, resp, id_):
158
        resp.status = falcon.HTTP_200
159
160
    @staticmethod
161
    def on_get(req, resp, id_):
162
        if not id_.isdigit() or int(id_) <= 0:
163
            raise falcon.HTTPError(falcon.HTTP_400,
164
                                   title='API.BAD_REQUEST',
165
                                   description='API.INVALID_OFFLINE_METER_FILE_ID')
166
167
        cnx = mysql.connector.connect(**config.myems_historical_db)
168
        cursor = cnx.cursor()
169
170
        query = (" SELECT id, file_name, uuid, upload_datetime_utc, status "
171
                 " FROM tbl_offline_meter_files "
172
                 " WHERE id = %s ")
173
        cursor.execute(query, (id_,))
174
        row = cursor.fetchone()
175
        cursor.close()
176
        cnx.disconnect()
177
        if row is None:
178
            raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
179
                                   description='API.OFFLINE_METER_FILE_NOT_FOUND')
180
181
        timezone_offset = int(config.utc_offset[1:3]) * 60 + int(config.utc_offset[4:6])
182
        if config.utc_offset[0] == '-':
183
            timezone_offset = -timezone_offset
184
185
        upload_datetime_local = row[3].replace(tzinfo=timezone.utc) + timedelta(minutes=timezone_offset)
186
187
        result = {"id": row[0],
188
                  "file_name": row[1],
189
                  "uuid": row[2],
190
                  "upload_datetime": upload_datetime_local.strftime('%Y-%m-%dT%H:%M:%S'),
191
                  "status": row[4]}
192
        resp.body = json.dumps(result)
193
194
    @staticmethod
195
    @user_logger
196
    def on_delete(req, resp, id_):
197
        if not id_.isdigit() or int(id_) <= 0:
198
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
199
                                   description='API.INVALID_OFFLINE_METER_FILE_ID')
200
201
        cnx = mysql.connector.connect(**config.myems_historical_db)
202
        cursor = cnx.cursor()
203
204
        cursor.execute(" SELECT uuid "
205
                       " FROM tbl_offline_meter_files "
206
                       " WHERE id = %s ", (id_,))
207
        row = cursor.fetchone()
208
        if row is None:
209
            cursor.close()
210
            cnx.disconnect()
211
            raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
212
                                   description='API.OFFLINE_METER_FILE_NOT_FOUND')
213
214
        try:
215
            file_uuid = row[0]
216
            # Define file_path
217
            file_path = os.path.join(config.upload_path, file_uuid)
218
219
            # remove the file from disk
220
            os.remove(file_path)
221
        except Exception as ex:
222
            # ignore exception and don't return API.OFFLINE_METER_FILE_NOT_FOUND error
223
            pass
224
225
        # Note: the energy data imported from the deleted file will not be deleted
226
        cursor.execute(" DELETE FROM tbl_offline_meter_files WHERE id = %s ", (id_,))
227
        cnx.commit()
228
229
        cursor.close()
230
        cnx.disconnect()
231
232
        resp.status = falcon.HTTP_204
233
234
235 View Code Duplication
class OfflineMeterFileRestore:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
236
    @staticmethod
237
    def __init__():
238
        """"Initializes OfflineMeterFileRestore"""
239
        pass
240
241
    @staticmethod
242
    def on_options(req, resp, id_):
243
        resp.status = falcon.HTTP_200
244
245
    @staticmethod
246
    def on_get(req, resp, id_):
247
        if not id_.isdigit() or int(id_) <= 0:
248
            raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
249
                                   description='API.INVALID_OFFLINE_METER_FILE_ID')
250
251
        cnx = mysql.connector.connect(**config.myems_historical_db)
252
        cursor = cnx.cursor()
253
254
        query = (" SELECT uuid, file_object "
255
                 " FROM tbl_offline_meter_files "
256
                 " WHERE id = %s ")
257
        cursor.execute(query, (id_,))
258
        row = cursor.fetchone()
259
        cursor.close()
260
        cnx.disconnect()
261
262
        if row is None:
263
            raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
264
                                   description='API.OFFLINE_METER_FILE_NOT_FOUND')
265
266
        result = {"uuid": row[0],
267
                  "file_object": row[1]}
268
        try:
269
            raw_blob = result["file_object"]
270
            file_uuid = result["uuid"]
271
272
            # Define file_path
273
            file_path = os.path.join(config.upload_path, file_uuid)
274
275
            # Write to a temporary file to prevent incomplete files from
276
            # being used.
277
            temp_file_path = file_path + '~'
278
279
            open(temp_file_path, 'wb').write(raw_blob)
280
281
            # Now that we know the file has been fully saved to disk
282
            # move it into place.
283
            os.replace(temp_file_path, file_path)
284
        except Exception as ex:
285
            raise falcon.HTTPError(falcon.HTTP_400, title='API.ERROR',
286
                                   description='API.FAILED_TO_RESTORE_OFFLINE_METER_FILE')
287
        resp.body = json.dumps('success')
288