Updated e911_helper.py

This commit is contained in:
Ben D
2022-01-24 23:11:21 -08:00
parent 92a43d2b20
commit 3f0b7fb35a

View File

@@ -1,10 +1,11 @@
#!/usr/bin/env python3
#
#
# (C) 2020 VOICE1 LLC
#
import datetime
from dis import dis
import requests
import json
import sys
@@ -12,60 +13,55 @@ import os
try:
from loguru import logger
logger.add("app.log", rotation="1 month", level="DEBUG")
except ImportError:
import logging
logger = logging.getLogger(__name__)
# TODO: Set to config file.
class bcolors:
HEADER = "\033[95m"
OKBLUE = "\033[94m"
OKCYAN = "\033[96m"
OKGREEN = "\033[92m"
WARNING = "\033[93m"
FAIL = "\033[91m"
ENDC = "\033[0m"
BOLD = "\033[1m"
UNDERLINE = "\033[4m"
# Show and confirm disclaimer
disclaimer_accepted = False
def show_disclaimer():
print(
f"""
{bcolors.BOLD}
WARNING - This script is provided as a DEMO ONLY. It is intended to illistrate how to use the Voice1 APIs. By using this script, you agree to the terms of use and acknowledge that you are responsible for any actions taken.
Neither VOICE1 nor VOICE1s resellers, contractors, or associates shall be responsible for providing Services to the extent that the issue is caused by (a) Customers misuse, improper use, mis-configuration, alteration, or damage to the Software; (b) Customers use of the Software with any hardware or software not supplied or supported by VOICE1; (c) Customers failure to install an update to the Software if such update would have resolved the issue; or (d) uses in a manner not in accordance with the Agreement. VOICE1 shall have no responsibility for loss of or damage to Customers data or loss of business, regardless of the cause of any such loss or damage.
TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, VOICE1 AND ITS RESELLERS DISCLAIM ALL WARRANTIES AND CONDITIONS, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND TITLE AND NON-INFRINGEMENT, WITH REGARD TO THE SOFTWARE. AND SERVICES. VOICE1 AND RESELLERS DO NOT GUARANTEE THAT THE OPERATION OF THE SOFTWARE OR ANY OTHER CODE WILL BE UNINTERRUPTED OR ERROR-FREE, AND CUSTOMER ACKNOWLEDGE THAT IT IS NOT TECHNICALLY PRACTICABLE FOR US TO DO SO.
TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL VOICE1 OR ITS RESELLERS BE LIABLE UNDER ANY LEGAL OR EQUITABLE THEORY FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION OR ANY OTHER PECUNIARY LAW) ARISING OUT OF THE USE OF OR INABILITY TO USE THE SOFTWARE OR THE SERVICES OR ANY OTHER SUBJECT MATTER RELATING TO THIS AGREEMENT, EVEN IF VOICE1 OR RESELLERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. IN ANY CASE, VOICE 1'S AND RESELLER'S ENTIRE LIABILITY WITH RESPECT TO ANY SUBJECT MATTER RELATING TO THIS AGREEMENT SHALL BE LIMITED TO THE AMOUNT ACTUALLY PAID FOR THE SERVICES
{bcolors.ENDC}
"""
)
# TODO: Set to config file.
config_file = "config.json"
if os.path.isfile(config_file):
with open(config_file) as f:
config_data = json.load(f)
else:
logger.critical(f"Unable to load config.json. Aborting.")
# Generate empty config.json
with open('config.json', 'w') as config:
config.write(
"""
[
{
"regcode": "",
"company": "",
"username": "",
"password": "",
"provider_username": "",
"provider_password": "",
"911_callrule_id": 0,
"out_call_rule_id": 0,
"redirect_ivr_id": "",
"tenant": {
"tenant1": {
"username": "",
"password": "",
"provider_username": "",
"provider_password": "",
"911_callrule_id": 0,
"out_call_rule_id": 0,
"redirect_ivr_id": "0"
}
}
}
]
"""
)
logger.info(f"Generated empty config.json file. Besure to populate it with required details before proceeding.")
sys.exit()
# Check and update current file to latest version.
def write_file(filename, content):
# put the content into the file
with open(filename, 'wb') as fp:
fp.write(content)
# End update check
add_type_list = [
"",
@@ -345,23 +341,38 @@ def format_address(address, fmt="human"):
"""Prettifies address for display."""
if fmt == "human":
address_type = ' '.join(part for part in (address.get('address_type'), address.get('address_type_number')) if part)
address_type = ' '.join(filter(None, (address.get('address_type'), address.get('address_type_number'))))
address_type = " ".join(
part
for part in (
address.get("address_type"),
address.get("address_type_number"),
)
if part
)
address_type = " ".join(
filter(
None, (address.get("address_type"), address.get("address_type_number"))
)
)
return f"{address['street_number']} {address['street_name']} {address_type} {address['city']}, {address['state']} {address['zip']} {address['country']}"
if fmt == "usps":
name = ' '.join(part for part in (address.get('first_name'), address.get('last_name')) if part)
name = " ".join(
part
for part in (address.get("first_name"), address.get("last_name"))
if part
)
return {
'name': name,
'company': '',
'address_1': f"{address['street_number']} {address['street_name']} {address.get('address_type', '')} {address.get('address_type_number', '')}",
'address_2': '',
'city': address['city'],
'state': address['state'],
'zipcode': address['zip'],
'zipcode_ext': '',
'phone': ''
"name": name,
"company": "",
"address_1": f"{address['street_number']} {address['street_name']} {address.get('address_type', '')} {address.get('address_type_number', '')}",
"address_2": "",
"city": address["city"],
"state": address["state"],
"zipcode": address["zip"],
"zipcode_ext": "",
"phone": "",
}
return address
@@ -395,7 +406,9 @@ def add_e911_address(address, extension, auto_correct=True):
if auto_correct:
n_address = result["errors"][0]["detail"]
logger.warning(f"Submitting updated address change:\n{json.dumps(n_address, indent=4)}")
logger.warning(
f"Submitting updated address change:\n{json.dumps(n_address, indent=4)}"
)
result = add_e911_address(n_address, extension, auto_correct=False)
return result
@@ -405,7 +418,9 @@ def add_e911_address(address, extension, auto_correct=True):
logger.error(f"Error processing request: \n{json.dumps(result, indent=4)}")
return result
if r.status_code == 201:
logger.info(f"Successfully added E911 Address: {r.status_code} {r.reason} | {r.request.body}.")
logger.info(
f"Successfully added E911 Address: {r.status_code} {r.reason} | {r.request.body}."
)
logger.info(f"Be sure to associate the number with the address.")
except Exception as e:
logger.critical(f"Exception: {e}")
@@ -839,7 +854,7 @@ def menu():
account_name = account["display"]
account_id = account["account_id"]
if str(extension) == "7001":
x_pos = 736 # TODO: Set to last position / before ranged numbers.
x_pos = 736 # TODO: Set to last position / before ranged numbers.
position = input(f"What position to add new record to: [{x_pos}] ") or x_pos
if extension == "7001":
label = "Available"
@@ -1156,8 +1171,54 @@ def menu():
get_e911_info(e911_id)
def prompt_credentials(config):
"""Prompt for credentials"""
print(f"{bcolors.HEADER}DO NOT SHARE YOUR CREDENTIALS WITH ANYONE.{bcolors.ENDC}")
config["username"] = input("Enter your api.switchvoxuc.com username: ")
config["password"] = input("Enter your api.switchvoxuc.com password: ")
config["provider_username"] = input("Enter your api.nwsip.com username: ")
config["provider_password"] = input("Enter your api.nwsip.com password: ")
print(f"{bcolors.HEADER}Configure additoinal tenant credentials.{bcolors.ENDC}")
tenant = input("Enter your tenant name or enter for None: ") or None
if tenant is not None:
tenant = tenant.upper()
config["tenant"] = {tenant: {}}
config["tenant"][tenant]["username"] = input(
f"Enter your {bcolors.OKBLUE}{tenant}{bcolors.ENDC} api.switchvoxuc.com username: "
)
config["tenant"][tenant]["password"] = input(
f"Enter your {bcolors.OKBLUE}{tenant}{bcolors.ENDC} api.switchvoxuc.com password: "
)
config["tenant"][tenant]["provider_username"] = input(
f"Enter your {bcolors.OKBLUE}{tenant}{bcolors.ENDC} api.nwsip.com username: "
)
config["tenant"][tenant]["provider_password"] = input(
f"Enter your {bcolors.OKBLUE}{tenant}{bcolors.ENDC} api.nwsip.com password: "
)
return config
if __name__ == "__main__":
try:
config_data = [prompt_credentials(config_data[0])]
show_disclaimer()
disclaimer_accepted = (
input(
"Do you accept the disclaimer? You must enter 'ACCEPT' in all capitals: "
)
or disclaimer_accepted
)
if disclaimer_accepted != "ACCEPT":
logger.info(
f"The user {config_data[0]['username']} for regcode {config_data[0]['regcode']} did not accept the use and terms your rejections has been logged."
)
sys.exit(0)
set_tenant()
while True:
menu()