Merge branch 'PR' into develop

pull/103/head
13621160019@163.com 2021-12-24 18:10:16 +08:00
commit 2749a8670f
4 changed files with 466 additions and 4 deletions

View File

@ -1,6 +1,6 @@
{ {
"info": { "info": {
"_postman_id": "275f5f12-078c-421a-a050-f054e344dc2b", "_postman_id": "10c28155-4a57-4951-b80e-9893a2edb0d0",
"name": "MyEMS", "name": "MyEMS",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
}, },
@ -2205,6 +2205,21 @@
"description": "Login to get a valid token" "description": "Login to get a valid token"
} }
], ],
"body": {
"mode": "formdata",
"formdata": [
{
"key": "file",
"type": "file",
"src": "/home/zhongtianlin/offline_meter_data.xlsx"
},
{
"key": "req",
"value": "{\"data\":{\"rule_id\":1, \"recipient_name\":\"Yinghao Huang\", \"recipient_email\":\"yinghao.huang@qq.com\", \"subject\":\"report_01_2021年10月24日\", \"message\":\"report_01_2021年10月24日\", \"created_datetime\":\"2021-11-01T00:00:00\", \"scheduled_datetime\":\"2021-11-01T00:00:00\"}}",
"type": "text"
}
]
},
"url": { "url": {
"raw": "{{base_url}}/emailmessages", "raw": "{{base_url}}/emailmessages",
"host": [ "host": [
@ -8876,6 +8891,10 @@
"description": "Login to get a valid token" "description": "Login to get a valid token"
} }
], ],
"body": {
"mode": "raw",
"raw": "{\"data\":{\"rule_id\":1, \"recipient_name\":\"Yinghao Huang\", \"recipient_mobile\":\"12345678912\", \"message\":\"report_01_2021年10月24日\", \"acknowledge_code\":\"9e52ad6d-3d80-403c-a525-40\", \"created_datetime\":\"2021-11-01T00:00:00\", \"scheduled_datetime\":\"2021-11-01T00:00:00\"}}"
},
"url": { "url": {
"raw": "{{base_url}}/textmessages", "raw": "{{base_url}}/textmessages",
"host": [ "host": [
@ -9831,6 +9850,10 @@
"description": "Login to get a valid token" "description": "Login to get a valid token"
} }
], ],
"body": {
"mode": "raw",
"raw": "{\"data\":{\"rule_id\":1, \"recipient_name\":\"SPACE01\", \"recipient_openid\":\"oia2TjuEGTNoeX76QEjQNrcURxG8\", \"message_template_id\":\"Doclyl5uP7Aciu-qZ7mJNPtWkbkYnWBWVja26EGbNyk\", \"message_data\":\"{\\\"space_id\\\":1, \\\"high_limit\\\":1000.000}\", \"acknowledge_code\":\"9e52ad6d\", \"created_datetime\":\"2021-11-01T00:00:00\", \"scheduled_datetime\":\"2021-11-01T00:00:00\"}}"
},
"url": { "url": {
"raw": "{{base_url}}/wechatmessages", "raw": "{{base_url}}/wechatmessages",
"host": [ "host": [
@ -12790,5 +12813,11 @@
] ]
} }
} }
],
"variable": [
{
"value": "",
"disabled": true
}
] ]
} }

View File

@ -2,6 +2,7 @@ import falcon
import simplejson as json import simplejson as json
import mysql.connector import mysql.connector
import config import config
import re
from datetime import datetime, timedelta, timezone from datetime import datetime, timedelta, timezone
from core.useractivity import user_logger, access_control from core.useractivity import user_logger, access_control
@ -34,7 +35,7 @@ class EmailMessageCollection:
start_datetime_local = str.strip(start_datetime_local) start_datetime_local = str.strip(start_datetime_local)
try: try:
start_datetime_utc = datetime.strptime(start_datetime_local, start_datetime_utc = datetime.strptime(start_datetime_local,
'%Y-%m-%dT%H:%M:%S').replace(tzinfo=timezone.utc) - \ '%Y-%m-%dT%H:%M:%S').replace(tzinfo=timezone.utc) - \
timedelta(minutes=timezone_offset) timedelta(minutes=timezone_offset)
except ValueError: except ValueError:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST', raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
@ -47,7 +48,7 @@ class EmailMessageCollection:
end_datetime_local = str.strip(end_datetime_local) end_datetime_local = str.strip(end_datetime_local)
try: try:
end_datetime_utc = datetime.strptime(end_datetime_local, end_datetime_utc = datetime.strptime(end_datetime_local,
'%Y-%m-%dT%H:%M:%S').replace(tzinfo=timezone.utc) - \ '%Y-%m-%dT%H:%M:%S').replace(tzinfo=timezone.utc) - \
timedelta(minutes=timezone_offset) timedelta(minutes=timezone_offset)
except ValueError: except ValueError:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST', raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
@ -92,6 +93,152 @@ class EmailMessageCollection:
resp.text = json.dumps(result) resp.text = json.dumps(result)
@staticmethod
@user_logger
def on_post(req, resp):
"""Handles POST requests"""
access_control(req)
try:
upload = req.get_param('file')
# Read upload file as binary
attachment_file_object = upload.file.read()
# Retrieve filename
attachment_file_name = upload.filename
except Exception as ex:
raise falcon.HTTPError(falcon.HTTP_400, title='API.ERROR',
description='API.FAILED_TO_UPLOAD_ATTACHMENT_FILE')
try:
raw_json = req.get_param('req')
except Exception as ex:
raise falcon.HTTPError(falcon.HTTP_400, title='API.ERROR', description=ex)
new_values = json.loads(raw_json)
if 'rule_id' in new_values['data'].keys():
if new_values['data']['rule_id'] <= 0:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_RULE_ID')
rule_id = new_values['data']['rule_id']
else:
rule_id = None
if 'recipient_name' not in new_values['data'].keys() or \
not isinstance(new_values['data']['recipient_name'], str) or \
len(str.strip(new_values['data']['recipient_name'])) == 0:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_RECIPIENT_NAME')
recipient_name = str.strip(new_values['data']['recipient_name'])
if 'recipient_email' not in new_values['data'].keys() or \
not isinstance(new_values['data']['recipient_email'], str) or \
len(str.strip(new_values['data']['recipient_email'])) == 0:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_RECIPIENT_EMAIL')
recipient_email = str.strip(new_values['data']['recipient_email'])
match = re.match(r'^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$', recipient_email)
if match is None:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_EMAIL')
if 'subject' not in new_values['data'].keys() or \
not isinstance(new_values['data']['subject'], str) or \
len(str.strip(new_values['data']['subject'])) == 0:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_SUBJECT_VALUE')
subject = str.strip(new_values['data']['subject'])
if 'message' not in new_values['data'].keys() or \
not isinstance(new_values['data']['message'], str) or \
len(str.strip(new_values['data']['message'])) == 0:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_MESSAGE_VALUE')
message = str.strip(new_values['data']['message'])
if 'created_datetime' not in new_values['data'].keys() or \
not isinstance(new_values['data']['created_datetime'], str) or \
len(str.strip(new_values['data']['created_datetime'])) == 0:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_CREATED_DATETIME')
created_datetime_local = str.strip(new_values['data']['created_datetime'])
if 'scheduled_datetime' not in new_values['data'].keys() or \
not isinstance(new_values['data']['scheduled_datetime'], str) or \
len(str.strip(new_values['data']['scheduled_datetime'])) == 0:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_SCHEDULED_DATETIME')
scheduled_datetime_local = str.strip(new_values['data']['scheduled_datetime'])
timezone_offset = int(config.utc_offset[1:3]) * 60 + int(config.utc_offset[4:6])
if config.utc_offset[0] == '-':
timezone_offset = -timezone_offset
if created_datetime_local is None:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description="API.INVALID_CREATED_DATETIME_FORMAT")
else:
created_datetime_local = str.strip(created_datetime_local)
try:
created_datetime_utc = datetime.strptime(created_datetime_local,
'%Y-%m-%dT%H:%M:%S').replace(tzinfo=timezone.utc) - \
timedelta(minutes=timezone_offset)
except ValueError:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description="API.INVALID_CREATED_DATETIME_FORMAT")
if scheduled_datetime_local is None:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description="API.INVALID_SCHEDULED_DATETIME_FORMAT")
else:
scheduled_datetime_local = str.strip(scheduled_datetime_local)
try:
scheduled_datetime_utc = datetime.strptime(scheduled_datetime_local,
'%Y-%m-%dT%H:%M:%S').replace(tzinfo=timezone.utc) - \
timedelta(minutes=timezone_offset)
except ValueError:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description="API.INVALID_SCHEDULED_DATETIME_FORMAT")
status = 'new'
cnx = mysql.connector.connect(**config.myems_fdd_db)
cursor = cnx.cursor()
if rule_id is not None:
cursor.execute(" SELECT name "
" FROM tbl_rules "
" WHERE id = %s ",
(new_values['data']['rule_id'],))
row = cursor.fetchone()
if row is None:
cursor.close()
cnx.disconnect()
raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
description='API.RULE_NOT_FOUND')
add_row = (" INSERT INTO tbl_email_messages "
" (rule_id, recipient_name, recipient_email, subject, message, "
" attachment_file_name, attachment_file_object, created_datetime_utc,"
" scheduled_datetime_utc, status) "
" VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s) ")
cursor.execute(add_row, (rule_id,
recipient_name,
recipient_email,
subject,
message,
attachment_file_name,
attachment_file_object,
created_datetime_utc,
scheduled_datetime_utc,
status))
new_id = cursor.lastrowid
cnx.commit()
cursor.close()
cnx.disconnect()
resp.status = falcon.HTTP_201
resp.location = '/emailmessages/' + str(new_id)
class EmailMessageItem: class EmailMessageItem:
@staticmethod @staticmethod
@ -175,4 +322,3 @@ class EmailMessageItem:
cnx.disconnect() cnx.disconnect()
resp.status = falcon.HTTP_204 resp.status = falcon.HTTP_204

View File

@ -88,6 +88,138 @@ class TextMessageCollection:
resp.text = json.dumps(result) resp.text = json.dumps(result)
@staticmethod
@user_logger
def on_post(req, resp):
"""Handles POST requests"""
access_control(req)
try:
raw_json = req.stream.read().decode('utf-8')
except Exception as ex:
raise falcon.HTTPError(falcon.HTTP_400, title='API.ERROR', description=ex)
new_values = json.loads(raw_json)
if 'rule_id' in new_values['data'].keys():
if new_values['data']['rule_id'] <= 0:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_RULE_ID')
rule_id = new_values['data']['rule_id']
else:
rule_id = None
if 'recipient_name' not in new_values['data'].keys() or \
not isinstance(new_values['data']['recipient_name'], str) or \
len(str.strip(new_values['data']['recipient_name'])) == 0:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_RECIPIENT_NAME')
recipient_name = str.strip(new_values['data']['recipient_name'])
if 'recipient_mobile' not in new_values['data'].keys() or \
not isinstance(new_values['data']['recipient_mobile'], str) or \
len(str.strip(new_values['data']['recipient_mobile'])) == 0:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_RECIPIENT_MOBILE')
recipient_mobile = str.strip(new_values['data']['recipient_mobile'])
if 'message' not in new_values['data'].keys() or \
not isinstance(new_values['data']['message'], str) or \
len(str.strip(new_values['data']['message'])) == 0:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_MESSAGE_VALUE')
message = str.strip(new_values['data']['message'])
if 'acknowledge_code' not in new_values['data'].keys() or \
not isinstance(new_values['data']['acknowledge_code'], str) or \
len(str.strip(new_values['data']['acknowledge_code'])) == 0:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_MESSAGE_ACKNOWLEDGE_CODE')
acknowledge_code = str.strip(new_values['data']['acknowledge_code'])
if 'created_datetime' not in new_values['data'].keys() or \
not isinstance(new_values['data']['created_datetime'], str) or \
len(str.strip(new_values['data']['created_datetime'])) == 0:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_CREATED_DATETIME')
created_datetime_local = str.strip(new_values['data']['created_datetime'])
if 'scheduled_datetime' not in new_values['data'].keys() or \
not isinstance(new_values['data']['scheduled_datetime'], str) or \
len(str.strip(new_values['data']['scheduled_datetime'])) == 0:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_SCHEDULED_DATETIME')
scheduled_datetime_local = str.strip(new_values['data']['scheduled_datetime'])
timezone_offset = int(config.utc_offset[1:3]) * 60 + int(config.utc_offset[4:6])
if config.utc_offset[0] == '-':
timezone_offset = -timezone_offset
if created_datetime_local is None:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description="API.INVALID_CREATED_DATETIME_FORMAT")
else:
created_datetime_local = str.strip(created_datetime_local)
try:
created_datetime_utc = datetime.strptime(created_datetime_local,
'%Y-%m-%dT%H:%M:%S').replace(tzinfo=timezone.utc) - \
timedelta(minutes=timezone_offset)
except ValueError:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description="API.INVALID_CREATED_DATETIME_FORMAT")
if scheduled_datetime_local is None:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description="API.INVALID_SCHEDULED_DATETIME_FORMAT")
else:
scheduled_datetime_local = str.strip(scheduled_datetime_local)
try:
scheduled_datetime_utc = datetime.strptime(scheduled_datetime_local,
'%Y-%m-%dT%H:%M:%S').replace(tzinfo=timezone.utc) - \
timedelta(minutes=timezone_offset)
except ValueError:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description="API.INVALID_SCHEDULED_DATETIME_FORMAT")
status = 'new'
cnx = mysql.connector.connect(**config.myems_fdd_db)
cursor = cnx.cursor()
if rule_id is not None:
cursor.execute(" SELECT name "
" FROM tbl_rules "
" WHERE id = %s ",
(new_values['data']['rule_id'],))
row = cursor.fetchone()
if row is None:
cursor.close()
cnx.disconnect()
raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
description='API.RULE_NOT_FOUND')
add_row = (" INSERT INTO tbl_text_messages_outbox"
" (rule_id, recipient_name, recipient_mobile, message, "
" acknowledge_code, created_datetime_utc,"
" scheduled_datetime_utc, status) "
" VALUES (%s, %s, %s, %s, %s, %s, %s, %s) ")
cursor.execute(add_row, (rule_id,
recipient_name,
recipient_mobile,
message,
acknowledge_code,
created_datetime_utc,
scheduled_datetime_utc,
status))
new_id = cursor.lastrowid
cnx.commit()
cursor.close()
cnx.disconnect()
resp.status = falcon.HTTP_201
resp.location = '/textmessages/' + str(new_id)
class TextMessageItem: class TextMessageItem:
@staticmethod @staticmethod

View File

@ -1,3 +1,4 @@
import re
import falcon import falcon
import simplejson as json import simplejson as json
import mysql.connector import mysql.connector
@ -90,6 +91,160 @@ class WechatMessageCollection(object):
resp.text = json.dumps(result) resp.text = json.dumps(result)
@staticmethod
@user_logger
def on_post(req, resp):
"""Handles POST requests"""
access_control(req)
try:
raw_json = req.stream.read().decode('utf-8')
except Exception as ex:
raise falcon.HTTPError(falcon.HTTP_400, title='API.ERROR', description=ex)
new_values = json.loads(raw_json)
if 'rule_id' in new_values['data'].keys():
if new_values['data']['rule_id'] <= 0:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_RULE_ID')
rule_id = new_values['data']['rule_id']
else:
rule_id = None
if 'recipient_name' not in new_values['data'].keys() or \
not isinstance(new_values['data']['recipient_name'], str) or \
len(str.strip(new_values['data']['recipient_name'])) == 0:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_RECIPIENT_NAME')
recipient_name = str.strip(new_values['data']['recipient_name'])
if 'recipient_openid' not in new_values['data'].keys() or \
not isinstance(new_values['data']['recipient_openid'], str) or \
len(str.strip(new_values['data']['recipient_openid'])) == 0:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_RECIPIENT_OPENID')
recipient_openid = str.strip(new_values['data']['recipient_openid'])
match = re.match(r'^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])[\da-zA-Z-_]{28}$', recipient_openid)
if match is None:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_OPENID')
if 'message_template_id' not in new_values['data'].keys() or \
not isinstance(new_values['data']['message_template_id'], str) or \
len(str.strip(new_values['data']['message_template_id'])) == 0:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_MESSAGE_TEMPLATE_ID')
message_template_id = str.strip(new_values['data']['message_template_id'])
match = re.match(r'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[\w-]{43}$', message_template_id)
if match is None:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_TEMPLATE_ID')
if 'message_data' not in new_values['data'].keys() or \
not isinstance(new_values['data']['message_data'], str) or \
len(str.strip(new_values['data']['message_data'])) == 0:
raise falcon.HTTPError(falcon.HTTP_400,
title='API.BAD_REQUEST',
description='API.INVALID_MESSAGE_DATA')
message_data = str.strip(new_values['data']['message_data'])
# validate expression in json
try:
json.loads(message_data)
except Exception as ex:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST', description=ex)
if 'acknowledge_code' not in new_values['data'].keys() or \
not isinstance(new_values['data']['acknowledge_code'], str) or \
len(str.strip(new_values['data']['acknowledge_code'])) == 0:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_MESSAGE_ACKNOWLEDGE_CODE')
acknowledge_code = str.strip(new_values['data']['acknowledge_code'])
if 'created_datetime' not in new_values['data'].keys() or \
not isinstance(new_values['data']['created_datetime'], str) or \
len(str.strip(new_values['data']['created_datetime'])) == 0:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_CREATED_DATETIME')
created_datetime_local = str.strip(new_values['data']['created_datetime'])
if 'scheduled_datetime' not in new_values['data'].keys() or \
not isinstance(new_values['data']['scheduled_datetime'], str) or \
len(str.strip(new_values['data']['scheduled_datetime'])) == 0:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_SCHEDULED_DATETIME')
scheduled_datetime_local = str.strip(new_values['data']['scheduled_datetime'])
timezone_offset = int(config.utc_offset[1:3]) * 60 + int(config.utc_offset[4:6])
if config.utc_offset[0] == '-':
timezone_offset = -timezone_offset
if created_datetime_local is None:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description="API.INVALID_CREATED_DATETIME_FORMAT")
else:
created_datetime_local = str.strip(created_datetime_local)
try:
created_datetime_utc = datetime.strptime(created_datetime_local,
'%Y-%m-%dT%H:%M:%S').replace(tzinfo=timezone.utc) - \
timedelta(minutes=timezone_offset)
except ValueError:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description="API.INVALID_CREATED_DATETIME_FORMAT")
if scheduled_datetime_local is None:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description="API.INVALID_SCHEDULED_DATETIME_FORMAT")
else:
scheduled_datetime_local = str.strip(scheduled_datetime_local)
try:
scheduled_datetime_utc = datetime.strptime(scheduled_datetime_local,
'%Y-%m-%dT%H:%M:%S').replace(tzinfo=timezone.utc) - \
timedelta(minutes=timezone_offset)
except ValueError:
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST',
description="API.INVALID_SCHEDULED_DATETIME_FORMAT")
status = 'new'
cnx = mysql.connector.connect(**config.myems_fdd_db)
cursor = cnx.cursor()
if rule_id is not None:
cursor.execute(" SELECT name "
" FROM tbl_rules "
" WHERE id = %s ",
(new_values['data']['rule_id'],))
row = cursor.fetchone()
if row is None:
cursor.close()
cnx.disconnect()
raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
description='API.RULE_NOT_FOUND')
add_row = (" INSERT INTO tbl_wechat_messages_outbox"
" (rule_id, recipient_name, recipient_openid, message_template_id, message_data,"
" acknowledge_code, created_datetime_utc, scheduled_datetime_utc, status) "
" VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s) ")
cursor.execute(add_row, (rule_id,
recipient_name,
recipient_openid,
message_template_id,
message_data,
acknowledge_code,
created_datetime_utc,
scheduled_datetime_utc,
status))
new_id = cursor.lastrowid
cnx.commit()
cursor.close()
cnx.disconnect()
resp.status = falcon.HTTP_201
resp.location = '/wechatmessages/' + str(new_id)
class WechatMessageItem: class WechatMessageItem:
@staticmethod @staticmethod