diff --git a/myems-api/MyEMS.postman_collection.json b/myems-api/MyEMS.postman_collection.json index c3bd20a9..cf23dbdf 100644 --- a/myems-api/MyEMS.postman_collection.json +++ b/myems-api/MyEMS.postman_collection.json @@ -2904,6 +2904,105 @@ } ] }, + { + "name": "Menu", + "item": [ + { + "name": "GET All Menus", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{base_url}}/menus", + "host": [ + "{{base_url}}" + ], + "path": [ + "menus" + ] + } + }, + "response": [] + }, + { + "name": "GET Menu by ID", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{base_url}}/menus/1", + "host": [ + "{{base_url}}" + ], + "path": [ + "menus", + "1" + ] + } + }, + "response": [] + }, + { + "name": "PUT Update a Menu", + "request": { + "method": "PUT", + "header": [], + "body": { + "mode": "raw", + "raw": "{\"data\":{\"is_hidden\":true}}" + }, + "url": { + "raw": "{{base_url}}/menus/1", + "host": [ + "{{base_url}}" + ], + "path": [ + "menus", + "1" + ] + } + }, + "response": [] + }, + { + "name": "GET All Children of Menu by ID", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{base_url}}/menus/100/children", + "host": [ + "{{base_url}}" + ], + "path": [ + "menus", + "100", + "children" + ] + } + }, + "response": [] + }, + { + "name": "GET All Menus for Web UI", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{base_url}}/menus/web", + "host": [ + "{{base_url}}" + ], + "path": [ + "menus", + "web" + ] + } + }, + "response": [] + } + ] + }, { "name": "Meter", "item": [ diff --git a/myems-api/README.md b/myems-api/README.md index 3467f663..2851ba11 100644 --- a/myems-api/README.md +++ b/myems-api/README.md @@ -159,7 +159,7 @@ View in Postman: import the file MyEMS.postman_collection.json with Postman [Data Source](#Data-Source) | [Point](#Point) -[Tariff](#Tariff) | [Cost Center](#Cost-Center) | [Cost File](#Offline-Cost-File) +[Tariff](#Tariff) | [Cost Center](#Cost-Center) | [Cost File](#Cost-File) [Meter](#Meter) | [Virtual Meter](#Virtual-Meter) | [Offline Meter](#Offline-Meter) | [Offline Meter File](#Offline-Meter-File) @@ -179,6 +179,8 @@ View in Postman: import the file MyEMS.postman_collection.json with Postman [Timezone](#Timezone) +[Menu](#Menu) + [Knowledge File](#Knowledge-File) [Reports](#Reports) @@ -953,6 +955,39 @@ $ curl -i -H "Content-Type: application/TBD" -X POST -d 'file: (binary)' {{base_ $ curl -i -X GET {{base_url}}/knowledgefiles/{id}/restore ``` +### Menu +* GET Menu by ID +```bash +$ curl -i -X GET {{base_url}}/menus/{id} +``` +Result + +| Name | Data Type | Description | +|---------------|-----------|-------------------------------------------| +| id | integer | Menu ID | +| name | string | Menu name | +| path | string | Menu path | +| parent_menu_id| integer | Parent Menu ID | +| is_hidden | boolean | The menu status| | + +* GET All Menus +```bash +$ curl -i -X GET {{base_url}}/menus +``` +* PUT Update a Menu +```bash +$ curl -i -H "Content-Type: application/json" -X PUT -d '{"data":{"is_hidden": false}}' {{base_url}}/menus/{id} +``` +* Get All Menus for Web UI +```bash +$ curl -i -X GET {{base_url}}/menus/web +``` +* GET All Children of Menu by ID +```bash +$ curl -i -X GET {{base_url}}/menus/{id}/children +``` + + ### Meter * GET Meter by ID diff --git a/myems-api/app.py b/myems-api/app.py index 0537ea8b..5f90d078 100644 --- a/myems-api/app.py +++ b/myems-api/app.py @@ -5,7 +5,7 @@ from core import energyflowdiagram, privilege, textmessage, distributioncircuit, costcenter, point, knowledgefile, meter, gsmmodem, tariff, user, storetype, timezone, \ costfile, offlinemeterfile, version, contact, emailserver, combinedequipment, datasource, equipment, tenant, shopfloor, \ webmessage, distributionsystem, store, emailmessage, tenanttype, wechatmessage, space, gateway, offlinemeter, \ - rule, energycategory, sensor, energyitem, notification + rule, energycategory, sensor, energyitem, notification, menu from reports import advancedreport from reports import distributionsystem as distributionsystemreport from reports import energyflowdiagram as energyflowdiagramreport @@ -244,6 +244,15 @@ api.add_route('/knowledgefiles/{id_}', api.add_route('/knowledgefiles/{id_}/restore', knowledgefile.KnowledgeFileRestore()) +api.add_route('/menus', + menu.MenuCollection()) +api.add_route('/menus/{id_}', + menu.MenuItem()) +api.add_route('/menus/{id_}/children', + menu.MenuChildrenCollection()) +api.add_route('/menus/web', + menu.MenuWebCollection()) + api.add_route('/meters', meter.MeterCollection()) api.add_route('/meters/{id_}', diff --git a/myems-api/core/menu.py b/myems-api/core/menu.py new file mode 100644 index 00000000..1673f33f --- /dev/null +++ b/myems-api/core/menu.py @@ -0,0 +1,238 @@ +import falcon +import simplejson as json +import mysql.connector +import config +import uuid +from datetime import datetime +from anytree import AnyNode +from anytree.exporter import JsonExporter + + +class MenuCollection: + @staticmethod + def __init__(): + pass + + @staticmethod + def on_options(req, resp): + resp.status = falcon.HTTP_200 + + @staticmethod + def on_get(req, resp): + cnx = mysql.connector.connect(**config.myems_system_db) + cursor = cnx.cursor(dictionary=True) + + query = (" SELECT id, path, name, parent_menu_id, is_hidden " + " FROM tbl_menus ") + cursor.execute(query) + rows_menus = cursor.fetchall() + + result = list() + if rows_menus is not None and len(rows_menus) > 0: + for row in rows_menus: + temp = {"id": row['id'], + "path": row['path'], + "name": row['name'], + "parent_menu_id": row['parent_menu_id'], + "is_hidden": row['is_hidden']} + + result.append(temp) + + cursor.close() + cnx.disconnect() + resp.body = json.dumps(result) + + +class MenuItem: + @staticmethod + def __init__(): + pass + + @staticmethod + def on_options(req, resp, id_): + resp.status = falcon.HTTP_200 + + @staticmethod + def on_get(req, resp, id_): + if not id_.isdigit() or int(id_) <= 0: + raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST', + description='API.INVALID_MENU_ID') + + cnx = mysql.connector.connect(**config.myems_system_db) + cursor = cnx.cursor(dictionary=True) + + query = (" SELECT id, path, name, parent_menu_id, is_hidden " + " FROM tbl_menus " + " WHERE id=%s ") + cursor.execute(query, (id_,)) + rows_menu = cursor.fetchone() + + result = None + if rows_menu is not None and len(rows_menu) > 0: + result = {"id": rows_menu['id'], + "path": rows_menu['path'], + "name": rows_menu['name'], + "parent_menu_id": rows_menu['parent_menu_id'], + "is_hidden": rows_menu['is_hidden']} + + cursor.close() + cnx.disconnect() + resp.body = json.dumps(result) + + @staticmethod + def on_put(req, resp, id_): + """Handles PUT requests""" + try: + raw_json = req.stream.read().decode('utf-8') + except Exception as ex: + raise falcon.HTTPError(falcon.HTTP_400, title='API.EXCEPTION', description=ex) + + if not id_.isdigit() or int(id_) <= 0: + raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST', + description='API.INVALID_MENU_ID') + + new_values = json.loads(raw_json) + + if 'is_hidden' not in new_values['data'].keys() or \ + not isinstance(new_values['data']['is_hidden'], bool): + raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST', + description='API.INVALID_IS_HIDDEN') + is_hidden = new_values['data']['is_hidden'] + + cnx = mysql.connector.connect(**config.myems_system_db) + cursor = cnx.cursor() + update_row = (" UPDATE tbl_menus " + " SET is_hidden = %s " + " WHERE id = %s ") + cursor.execute(update_row, (is_hidden, + id_)) + cnx.commit() + + cursor.close() + cnx.disconnect() + + resp.status = falcon.HTTP_200 + + +class MenuChildrenCollection: + @staticmethod + def __init__(): + pass + + @staticmethod + def on_options(req, resp, id_): + resp.status = falcon.HTTP_200 + + @staticmethod + def on_get(req, resp, id_): + if not id_.isdigit() or int(id_) <= 0: + raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST', + description='API.INVALID_MENU_ID') + + cnx = mysql.connector.connect(**config.myems_system_db) + cursor = cnx.cursor(dictionary=True) + + query = (" SELECT id, path, name, parent_menu_id, is_hidden " + " FROM tbl_menus " + " WHERE id = %s ") + cursor.execute(query, (id_,)) + row_current_menu = cursor.fetchone() + if row_current_menu is None: + cursor.close() + cnx.disconnect() + raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND', + description='API.MENU_NOT_FOUND') + current_menu = None + current_menu_id = None + if row_current_menu is not None and len(row_current_menu) > 0: + current_menu = {"id": row_current_menu['id'], + "path": row_current_menu['path'], + "name": row_current_menu['name'], + "parent_menu_id": row_current_menu['parent_menu_id'], + "is_hidden": row_current_menu['is_hidden']} + current_menu_id = row_current_menu['id'] + + query = (" SELECT id, path, name, parent_menu_id, is_hidden" + " FROM tbl_menus " + " WHERE parent_menu_id = %s") + cursor.execute(query, (current_menu_id,)) + rows_menus = cursor.fetchall() + + children_menus = [] + if rows_menus is not None and len(rows_menus) > 0: + for row in rows_menus: + children_menus.append( + { + "id": row['id'], + "path": row['path'], + "name": row['name'], + "parent_menu": current_menu, + "is_hidden": row['is_hidden'] + } + ) + + result = { + "current": current_menu, + "children": children_menus, + } + + cursor.close() + cnx.disconnect() + resp.body = json.dumps(result) + + +class MenuWebCollection: + @staticmethod + def __init__(): + pass + + @staticmethod + def on_options(req, resp): + resp.status = falcon.HTTP_200 + + @staticmethod + def on_get(req, resp): + cnx = mysql.connector.connect(**config.myems_system_db) + cursor = cnx.cursor(dictionary=True) + + query = (" SELECT id, path, parent_menu_id, is_hidden " + " FROM tbl_menus " + " WHERE parent_menu_id is NULL " + " AND is_hidden=0 ") + cursor.execute(query) + rows_menus = cursor.fetchall() + + first_paths = {} + if rows_menus is not None and len(rows_menus) > 0: + for row in rows_menus: + _id = row['id'] + path = row['path'] + first_paths[_id] = { + 'path': path, + 'children': [] + } + + query = (" SELECT id, path, parent_menu_id, is_hidden " + " FROM tbl_menus " + " WHERE parent_menu_id is not NULL " + " AND is_hidden=0 ") + cursor.execute(query) + rows_menus = cursor.fetchall() + + if rows_menus is not None and len(rows_menus) > 0: + for row in rows_menus: + _id = row['id'] + parent_menu_id = row['parent_menu_id'] + path = row['path'] + if parent_menu_id in first_paths.keys(): + first_paths[parent_menu_id]['children'].append(path) + + result = dict() + for _id, item in first_paths.items(): + first_path = item['path'] + children = item['children'] + result[first_path] = children + + cursor.close() + cnx.disconnect() + resp.body = json.dumps(result)