From 7be27a3c4399e23506971fcee540176144e89da3 Mon Sep 17 00:00:00 2001 From: Dylan Bolger Date: Sun, 15 Oct 2023 21:35:22 -0500 Subject: Further organize modules, rename request energy request method, provide tentative data in response --- app/constants/constants.py | 2 +- app/energy_request/energy_request.py | 78 ---------------------------------- app/energy_service.py | 6 +-- app/login/login.py | 53 ----------------------- app/request/energy/energy_request.py | 82 ++++++++++++++++++++++++++++++++++++ app/request/login/login_request.py | 53 +++++++++++++++++++++++ 6 files changed, 139 insertions(+), 135 deletions(-) delete mode 100644 app/energy_request/energy_request.py delete mode 100644 app/login/login.py create mode 100644 app/request/energy/energy_request.py create mode 100644 app/request/login/login_request.py diff --git a/app/constants/constants.py b/app/constants/constants.py index f3ab71d..4bdc5dd 100644 --- a/app/constants/constants.py +++ b/app/constants/constants.py @@ -1,4 +1,4 @@ -from app.login.credentials import * +from app.request.login.credentials import * # TODO: Organize this better diff --git a/app/energy_request/energy_request.py b/app/energy_request/energy_request.py deleted file mode 100644 index f6aac3f..0000000 --- a/app/energy_request/energy_request.py +++ /dev/null @@ -1,78 +0,0 @@ -import json -import requests -from ..constants.constants import usageRequestCookies, genericRequestHeaders, electricUsageRequestJson, waterUsageRequestJson, waterRequestEndpoint, electricRequestEndpoint - -# Electric - -def dayElectricRequest(): - electricUsageRequestJson['Mode'] = 'D' - return performElectricRequest() - -def monthElectricRequest(): - electricUsageRequestJson['Mode'] = 'M' - return performElectricRequest() - -def performElectricRequest(): - electricUsageResponse = requests.post( - electricRequestEndpoint, - cookies=usageRequestCookies, - headers=genericRequestHeaders, - json=electricUsageRequestJson - ) - return parseResponse(electricUsageResponse) - -def requestElectric(): - return { - "day": dayElectricRequest(), - "month": monthElectricRequest() - } - -# Water - -def dayWaterRequest(): - waterUsageRequestJson['Mode'] = 'D' - return performWaterRequest() - -def monthWaterRequest(): - waterUsageRequestJson['Mode'] = 'M' - return performWaterRequest() - -def performWaterRequest(): - waterUsageResponse = requests.post( - waterRequestEndpoint, - cookies=usageRequestCookies, - headers=genericRequestHeaders, - json=waterUsageRequestJson - ) - return parseResponse(waterUsageResponse) - -def requestWater(): - return { - "day": dayWaterRequest(), - "month": monthWaterRequest() - } - -# Utility methods - -def parseResponse(response): - # such an icky response from an endpoint - # TODO: Remove unneeded JSON entries? - return json.loads(response.text.replace("\\\"", "\"").replace("\\\"", "\"").replace("\"{\"", "{\"").replace("}\"}", "}}"))['d']['objUsageGenerationResultSetTwo'] - -def setupRequestParameters(parameters): - # Setup cookies and csrftoken to perform requests - usageRequestCookies['ApplicationGatewayAffinityCORS'] = parameters['aga'] - usageRequestCookies['ApplicationGatewayAffinity'] = parameters['aga'] - usageRequestCookies['ASP.NET_SessionId'] = parameters['asi'] - usageRequestCookies['SCP'] = parameters['lt'] - genericRequestHeaders['csrftoken'] = parameters['ct'] - -# Service calling method - -def request(requestParameters): - setupRequestParameters(requestParameters) - return { - "electric": requestElectric(), - "water": requestWater() - } - diff --git a/app/energy_service.py b/app/energy_service.py index 475939f..2eb6867 100644 --- a/app/energy_service.py +++ b/app/energy_service.py @@ -1,6 +1,6 @@ from fastapi import FastAPI -from app.login.login import login -from app.energy_request.energy_request import request +from app.request.login.login_request import login +from app.request.energy.energy_request import requestUsageData import os import json @@ -13,7 +13,7 @@ def get(): print('Debug file present') return getDebugResponse() sessionKeys = login() - return request(sessionKeys) + return requestUsageData(sessionKeys) def getDebugResponse(): with open(debugFilePath) as file: diff --git a/app/login/login.py b/app/login/login.py deleted file mode 100644 index 511be44..0000000 --- a/app/login/login.py +++ /dev/null @@ -1,53 +0,0 @@ -import requests -import re -from ..constants.constants import loginPageHeaders, loginRequestJson, genericRequestHeaders, loginPageUri, loginRequestEndpoint - -def login(): - # Grab generated session keys from viewing the webpage - aga, asi, ct = grabRequiredKeys() - # Perform a login request using keys found on the page and JSON data (credentials) - lt = performLoginRequest(aga, asi, ct) - # Return the keys required to make endpoint calls - return { - "lt": lt, - "aga": aga, - "asi": asi, - "ct": ct - } - - -def grabRequiredKeys(): - loginPageResponse = requests.get(loginPageUri, headers=loginPageHeaders) - affinityMatcher = re.compile("CORS=(.+?);") - affinityResults = affinityMatcher.search(loginPageResponse.headers['Set-Cookie']) - appGatewayAffinity = affinityResults.group(1) - - aspNetSessionIdMatcher = re.compile("ASP\.NET\_SessionId=(.+?);") - aspnetResults = aspNetSessionIdMatcher.search(loginPageResponse.headers['Set-Cookie']) - aspNetSessionId = aspnetResults.group(1) - - csrfMatcher = re.compile("id=\"hdnCSRFToken\" value=\"(.+)\"") - csrfResults = csrfMatcher.search(loginPageResponse.text) - csrfToken = csrfResults.group(1) - return appGatewayAffinity, aspNetSessionId, csrfToken - -def performLoginRequest(appGatewayAffinity, aspNetSessionId, csrfToken): - loginRequestCookies = { - 'ApplicationGatewayAffinityCORS': appGatewayAffinity, - 'ApplicationGatewayAffinity': appGatewayAffinity, - 'ASP.NET_SessionId': aspNetSessionId, - } - - genericRequestHeaders['csrftoken'] = csrfToken - - loginResponse = requests.post( - loginRequestEndpoint, - cookies=loginRequestCookies, - headers=genericRequestHeaders, - json=loginRequestJson, - ) - - scpMatcher = re.compile("SCP=(.{36});") - scpSearchResults = scpMatcher.search(loginResponse.headers['Set-Cookie']) - loginToken = scpSearchResults.group(1) - return loginToken diff --git a/app/request/energy/energy_request.py b/app/request/energy/energy_request.py new file mode 100644 index 0000000..5217b18 --- /dev/null +++ b/app/request/energy/energy_request.py @@ -0,0 +1,82 @@ +import json +import requests +from ...constants.constants import usageRequestCookies, genericRequestHeaders, electricUsageRequestJson, waterUsageRequestJson, waterRequestEndpoint, electricRequestEndpoint + +# Electric + +def dayElectricRequest(): + electricUsageRequestJson['Mode'] = 'D' + return performElectricRequest() + +def monthElectricRequest(): + electricUsageRequestJson['Mode'] = 'M' + return performElectricRequest() + +def performElectricRequest(): + electricUsageResponse = requests.post( + electricRequestEndpoint, + cookies=usageRequestCookies, + headers=genericRequestHeaders, + json=electricUsageRequestJson + ) + return parseResponse(electricUsageResponse) + +def requestElectric(): + return { + "day": dayElectricRequest(), + "month": monthElectricRequest() + } + +# Water + +def dayWaterRequest(): + waterUsageRequestJson['Mode'] = 'D' + return performWaterRequest() + +def monthWaterRequest(): + waterUsageRequestJson['Mode'] = 'M' + return performWaterRequest() + +def performWaterRequest(): + waterUsageResponse = requests.post( + waterRequestEndpoint, + cookies=usageRequestCookies, + headers=genericRequestHeaders, + json=waterUsageRequestJson + ) + return parseResponse(waterUsageResponse) + +def requestWater(): + return { + "day": dayWaterRequest(), + "month": monthWaterRequest() + } + +# Utility methods + +def parseResponse(response): + # such an icky response from an endpoint + jsonResponse = json.loads(response.text.replace("\\\"", "\"").replace("\\\"", "\"").replace("\"{\"", "{\"").replace("}\"}", "}}"))['d'] + # TODO: Remove useless data from response + return { + "usageData": jsonResponse['objUsageGenerationResultSetTwo'], # Raw usage data for each timeframe + "tentativeData": jsonResponse['getTentativeData'] # Accumulated usage data and predictions + } + +def setupRequestParameters(parameters): + # Setup cookies and csrftoken to perform requests + usageRequestCookies['ApplicationGatewayAffinityCORS'] = parameters['aga'] + usageRequestCookies['ApplicationGatewayAffinity'] = parameters['aga'] + usageRequestCookies['ASP.NET_SessionId'] = parameters['asi'] + usageRequestCookies['SCP'] = parameters['lt'] + genericRequestHeaders['csrftoken'] = parameters['ct'] + +# Service calling method + +def requestUsageData(requestParameters): + setupRequestParameters(requestParameters) + return { + "electric": requestElectric(), + "water": requestWater() + } + diff --git a/app/request/login/login_request.py b/app/request/login/login_request.py new file mode 100644 index 0000000..c74986e --- /dev/null +++ b/app/request/login/login_request.py @@ -0,0 +1,53 @@ +import requests +import re +from ...constants.constants import loginPageHeaders, loginRequestJson, genericRequestHeaders, loginPageUri, loginRequestEndpoint + +def login(): + # Grab generated session keys from viewing the webpage + aga, asi, ct = grabRequiredKeys() + # Perform a login request using keys found on the page and JSON data (credentials) + lt = performLoginRequest(aga, asi, ct) + # Return the keys required to make endpoint calls + return { + "lt": lt, + "aga": aga, + "asi": asi, + "ct": ct + } + + +def grabRequiredKeys(): + loginPageResponse = requests.get(loginPageUri, headers=loginPageHeaders) + affinityMatcher = re.compile("CORS=(.+?);") + affinityResults = affinityMatcher.search(loginPageResponse.headers['Set-Cookie']) + appGatewayAffinity = affinityResults.group(1) + + aspNetSessionIdMatcher = re.compile("ASP\.NET\_SessionId=(.+?);") + aspnetResults = aspNetSessionIdMatcher.search(loginPageResponse.headers['Set-Cookie']) + aspNetSessionId = aspnetResults.group(1) + + csrfMatcher = re.compile("id=\"hdnCSRFToken\" value=\"(.+)\"") + csrfResults = csrfMatcher.search(loginPageResponse.text) + csrfToken = csrfResults.group(1) + return appGatewayAffinity, aspNetSessionId, csrfToken + +def performLoginRequest(appGatewayAffinity, aspNetSessionId, csrfToken): + loginRequestCookies = { + 'ApplicationGatewayAffinityCORS': appGatewayAffinity, + 'ApplicationGatewayAffinity': appGatewayAffinity, + 'ASP.NET_SessionId': aspNetSessionId, + } + + genericRequestHeaders['csrftoken'] = csrfToken + + loginResponse = requests.post( + loginRequestEndpoint, + cookies=loginRequestCookies, + headers=genericRequestHeaders, + json=loginRequestJson, + ) + + scpMatcher = re.compile("SCP=(.{36});") + scpSearchResults = scpMatcher.search(loginResponse.headers['Set-Cookie']) + loginToken = scpSearchResults.group(1) + return loginToken -- cgit v1.2.3