Linter bug fixes. Mostly undeclared, unused, or missing imports. One or two outright typos. There's still issues with undeclared types that need to be fixed after api connection refactor is fully implemented.
This commit is contained in:
parent
a5f57f4f5e
commit
8da4978498
34 changed files with 228 additions and 150 deletions
|
|
@ -59,86 +59,86 @@ class ClientController:
|
|||
|
||||
return not ClientVersionController.is_latest(version)
|
||||
|
||||
@staticmethod
|
||||
def legacy_sync(client_observer: ClientObserver = None, connection_observer: ConnectionObserver = None):
|
||||
if client_observer is not None:
|
||||
client_observer.notify('synchronizing', "Fetching list of new data ..")
|
||||
# @staticmethod
|
||||
# def legacy_sync(client_observer: ClientObserver = None, connection_observer: ConnectionObserver = None):
|
||||
# if client_observer is not None:
|
||||
# client_observer.notify('synchronizing', "Fetching list of new data ..")
|
||||
|
||||
result = coordinate_cache_sync(client_observer, connection_observer)
|
||||
# result = coordinate_cache_sync(client_observer, connection_observer)
|
||||
|
||||
# Outright Error:
|
||||
if not result["success"]:
|
||||
error_msg = result["error"]
|
||||
if client_observer is not None:
|
||||
client_observer.notify('synchronizing', f'Error! {error_msg}')
|
||||
return
|
||||
# # Outright Error:
|
||||
# if not result["success"]:
|
||||
# error_msg = result["error"]
|
||||
# if client_observer is not None:
|
||||
# client_observer.notify('synchronizing', f'Error! {error_msg}')
|
||||
# return
|
||||
|
||||
# Same:
|
||||
changed_tables = result["changed_tables"]
|
||||
if not changed_tables:
|
||||
if client_observer is not None:
|
||||
client_observer.notify('synchronized')
|
||||
return
|
||||
# # Same:
|
||||
# changed_tables = result["changed_tables"]
|
||||
# if not changed_tables:
|
||||
# if client_observer is not None:
|
||||
# client_observer.notify('synchronized')
|
||||
# return
|
||||
|
||||
# We only make it past this point if there's New Data
|
||||
# # We only make it past this point if there's New Data
|
||||
|
||||
# flag for after the save,
|
||||
data_was_saved = False
|
||||
# # flag for after the save,
|
||||
# data_was_saved = False
|
||||
|
||||
# Fetch and update the real data (no longer metadata)...
|
||||
# # Fetch and update the real data (no longer metadata)...
|
||||
|
||||
# =================== ORM BASED MODELS ==================
|
||||
"""
|
||||
Note: for the new ORM based models,
|
||||
it does the Tor/system check in the API call itself.
|
||||
"""
|
||||
# # =================== ORM BASED MODELS ==================
|
||||
# """
|
||||
# Note: for the new ORM based models,
|
||||
# it does the Tor/system check in the API call itself.
|
||||
# """
|
||||
|
||||
if "locations" in changed_tables:
|
||||
logger.info("Sync of Locations")
|
||||
if client_observer is not None:
|
||||
client_observer.notify('synchronizing', 'Fetching Locations List..')
|
||||
# if "locations" in changed_tables:
|
||||
# logger.info("Sync of Locations")
|
||||
# if client_observer is not None:
|
||||
# client_observer.notify('synchronizing', 'Fetching Locations List..')
|
||||
|
||||
final_result = sync_one_orm_model(Location, "locations")
|
||||
evaluate_errors(final_result)
|
||||
# final_result = sync_one_orm_model(Location, "locations")
|
||||
# evaluate_errors(final_result)
|
||||
|
||||
|
||||
if "operators" in changed_tables:
|
||||
logger.info("Sync of Operators")
|
||||
if client_observer is not None:
|
||||
client_observer.notify('synchronizing', 'Fetching Operators List..')
|
||||
# if "operators" in changed_tables:
|
||||
# logger.info("Sync of Operators")
|
||||
# if client_observer is not None:
|
||||
# client_observer.notify('synchronizing', 'Fetching Operators List..')
|
||||
|
||||
final_result_two = sync_one_orm_model(Operator, "operators")
|
||||
evaluate_errors(final_result_two)
|
||||
# final_result_two = sync_one_orm_model(Operator, "operators")
|
||||
# evaluate_errors(final_result_two)
|
||||
|
||||
# =================== MANUAL-SQL BASED MODELS ==================
|
||||
try:
|
||||
from core.controllers.ConnectionController import ConnectionController
|
||||
ConnectionController.with_preferred_connection(task=ClientController.__sync, changed_tables=changed_tables, client_observer=client_observer, connection_observer=connection_observer)
|
||||
# # =================== MANUAL-SQL BASED MODELS ==================
|
||||
# try:
|
||||
# from core.controllers.ConnectionController import ConnectionController
|
||||
# ConnectionController.with_preferred_connection(task=ClientController.__sync, changed_tables=changed_tables, client_observer=client_observer, connection_observer=connection_observer)
|
||||
|
||||
# We set the flag to true,
|
||||
# the reason we use a flag, and don't just save it right here,
|
||||
# is because we want to isolate the success (or failure) of the real data,
|
||||
# from the potential failure of the ORM session metadata.
|
||||
data_was_saved = True
|
||||
# # We set the flag to true,
|
||||
# # the reason we use a flag, and don't just save it right here,
|
||||
# # is because we want to isolate the success (or failure) of the real data,
|
||||
# # from the potential failure of the ORM session metadata.
|
||||
# data_was_saved = True
|
||||
|
||||
except:
|
||||
# sync failed here,
|
||||
if client_observer is not None:
|
||||
client_observer.notify('synchronizing', 'Fetch Failed, but you can use old data.')
|
||||
finally:
|
||||
if data_was_saved:
|
||||
filtered_metadata = result["filtered_metadata"] # from the top of the function
|
||||
save_successful = save_metadata(filtered_metadata) # the "save_data" function is inside sync_service
|
||||
# except:
|
||||
# # sync failed here,
|
||||
# if client_observer is not None:
|
||||
# client_observer.notify('synchronizing', 'Fetch Failed, but you can use old data.')
|
||||
# finally:
|
||||
# if data_was_saved:
|
||||
# filtered_metadata = result["filtered_metadata"] # from the top of the function
|
||||
# save_successful = save_metadata(filtered_metadata) # the "save_data" function is inside sync_service
|
||||
|
||||
if client_observer is None:
|
||||
logger.error("Error: No client_observer to update the UI, the final part of the sync function skipped")
|
||||
return # can't update their UI
|
||||
# if client_observer is None:
|
||||
# logger.error("Error: No client_observer to update the UI, the final part of the sync function skipped")
|
||||
# return # can't update their UI
|
||||
|
||||
if save_successful:
|
||||
logger.info("Metadata Saved Successfully")
|
||||
client_observer.notify('synchronized', "Fetch & Save Complete!")
|
||||
else:
|
||||
client_observer.notify('synchronizing', "Saving List of Metadata Failed.")
|
||||
# if save_successful:
|
||||
# logger.info("Metadata Saved Successfully")
|
||||
# client_observer.notify('synchronized', "Fetch & Save Complete!")
|
||||
# else:
|
||||
# client_observer.notify('synchronizing', "Saving List of Metadata Failed.")
|
||||
|
||||
|
||||
@staticmethod
|
||||
|
|
|
|||
|
|
@ -136,12 +136,10 @@ class ConnectionController:
|
|||
try:
|
||||
tor_module = TorModule(Constants.HV_TOR_STATE_HOME)
|
||||
tor_module.create_session(port_number, connection_observer)
|
||||
except TorServiceInitializationError as e:
|
||||
logger.error(f"TorServiceInitializationError. Tor Can't Start: {e}")
|
||||
if connection_observer is not None:
|
||||
connection_observer.notify('custom_message', "Tor Can't Initialize")
|
||||
except Exception as e:
|
||||
logger.error(f"Tor Can't Start: {e}")
|
||||
if connection_observer is not None:
|
||||
connection_observer.notify('custom_message', "Tor Can't Initialize")
|
||||
|
||||
@staticmethod
|
||||
def terminate_tor_session_connection(port_number: int):
|
||||
|
|
|
|||
|
|
@ -165,12 +165,19 @@ def new_sync(client_observer: ClientObserver, connection_observer: ConnectionObs
|
|||
|
||||
if total_skipped == 0:
|
||||
client_observer.notify('synchronized', "Fetch & Save Complete!")
|
||||
save_successful = save_metadata(filtered_metadata) # the "save_data" function is inside sync_service
|
||||
return Result(valid=True, message="Finshed sync.")
|
||||
save_successful = save_metadata(filtered_metadata)
|
||||
if save_successful:
|
||||
return Result(valid=True, message="Finshed sync.")
|
||||
else:
|
||||
error_msg = "Finshed sync, but had issues with the saving of metadata for next time."
|
||||
logger.error(error_msg)
|
||||
return Result(valid=True, message=error_msg)
|
||||
|
||||
elif total_skipped < quantity_of_entries:
|
||||
error_msg = f"Partial Success. {total_skipped} skipped."
|
||||
client_observer.notify('synchronized', error_msg)
|
||||
return Result(valid=True, data=skipped, message=error_msg)
|
||||
|
||||
else:
|
||||
error_msg = f"Sync Failed. All {total_skipped} entries were skipped!"
|
||||
client_observer.notify('synchronized', error_msg)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@ from core.observers.BaseObserver import BaseObserver
|
|||
from core.services.payment_phase.save_and_send_intitial_billing import save_and_send_intitial_billing
|
||||
from core.services.networking.api_requests.ApiResponseModel import ApiResponse, ErrorType
|
||||
from core.services.networking.api_requests.step5_solve_api_problems import solve_api_problems
|
||||
|
||||
from core.errors.logger import logger
|
||||
from core.errors.exceptions import ServerSideError, NetworkingError
|
||||
|
||||
from core.services.prepare_tickets.ticket_tracker import does_ticket_tracker_exist
|
||||
|
||||
|
|
@ -132,7 +133,7 @@ def initiate_payment(
|
|||
|
||||
return invoice_data_object
|
||||
|
||||
except InvalidData as e:
|
||||
except ValueError as e:
|
||||
error_msg = "Invalid Data."
|
||||
ticket_observer.notify("failed_input", subject=error_msg)
|
||||
invoice_data_object.add_error_code("invalid_data")
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ from core.services.helpers.get_value_from_config import get_value_from_config
|
|||
from core.utils.basic_operations.does_file_exist import does_file_exist
|
||||
from core.utils.basic_operations.write_or_read_from_json import update_json
|
||||
from core.services.prepare_tickets.ticket_tracker import get_all_unused_tickets
|
||||
from core.errors.logger import logger
|
||||
import random
|
||||
|
||||
|
||||
|
|
@ -162,8 +163,10 @@ def use_ticket(
|
|||
error_msg = f"Ticket is already tied to {location} with the subscription {subscription}"
|
||||
ticket_observer.notify("failed_input", subject=error_msg)
|
||||
return {"valid": False, "message": error_msg}
|
||||
except:
|
||||
except ValueError as e:
|
||||
error_msg = f"Your local ticket tracker has no value for ticket {which_ticket}"
|
||||
logger.error(error_msg)
|
||||
logger.error(str(e))
|
||||
return {"valid": False, "message": error_msg}
|
||||
|
||||
# the actual work here, everything else is just handling:
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ class Result():
|
|||
def user_message(self) -> str:
|
||||
"""Human-readable error for the UI."""
|
||||
messages = {
|
||||
DBErrorType.SUCCESS: "Operation completed successfully.",
|
||||
DBErrorType.UNKNOWN: f"Error: {self.message}",
|
||||
ResultError.SUCCESS: "Operation completed successfully.",
|
||||
ResultError.UNKNOWN: f"Error: {self.message}",
|
||||
}
|
||||
return messages.get(self.error_type, "Unknown error")
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
from core.Constants import Constants
|
||||
from core.models.ClientVersion import ClientVersion
|
||||
# from core.models.Location import Location
|
||||
# from core.models.Operator import Operator
|
||||
from core.models.orm_models.Location import Location
|
||||
from core.models.orm_models.Operator import Operator
|
||||
from core.models.Subscription import Subscription
|
||||
from core.models.SubscriptionPlan import SubscriptionPlan
|
||||
from core.models.invoice.Invoice import Invoice
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ from core.services.failed_verification.test_if_new_key_works import test_if_new_
|
|||
from core.services.networking.make_url import make_url
|
||||
from core.services.networking.api_requests.step1_get_or_post import get_data_from_api
|
||||
|
||||
from core.services.networking.httpx import connect
|
||||
from core.services.networking.api_requests.ApiResponseModel import ApiResponse, ErrorType
|
||||
|
||||
# utils
|
||||
from core.utils.basic_operations.write_or_read_from_json import get_value_from_json_file
|
||||
|
|
@ -72,12 +74,21 @@ def get_new_pubkey_from_api(connection_observer: ConnectionObserver) -> dict | N
|
|||
url = make_url(which_key_plan)
|
||||
|
||||
# the result of this is a python dictionary with single '
|
||||
api_results = get_data_from_server(url, None, connection_observer)
|
||||
# api_results = get_data_from_server(url, None, connection_observer)
|
||||
api_results = connect.single_endpoint(
|
||||
method="get",
|
||||
url=url,
|
||||
observer=connection_observer,
|
||||
payload=None
|
||||
)
|
||||
|
||||
if "data" in api_results:
|
||||
new_public_key = api_results["data"]
|
||||
if api_results.valid:
|
||||
new_public_key = api_results.data
|
||||
return new_public_key
|
||||
else:
|
||||
logger.error(f"API Results returned were invalid for that key.")
|
||||
return None
|
||||
|
||||
return new_public_key
|
||||
|
||||
|
||||
def are_keys_different(old_public_key, new_public_key) -> bool:
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ from core.errors.logger import logger
|
|||
|
||||
# generic
|
||||
import json, os
|
||||
from typing import Any
|
||||
from typing import Any, Optional
|
||||
import time
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -174,6 +174,7 @@ def quad9_proxy_dns_lookup(
|
|||
domain: str,
|
||||
custom_proxy: str,
|
||||
timeout: int = 10,
|
||||
client_observer: ClientObserver = None
|
||||
) -> str:
|
||||
|
||||
logger.debug("Doing a Proxy Quad9 DNS lookup")
|
||||
|
|
|
|||
|
|
@ -11,10 +11,11 @@ from core.services.subscriptions.subscriptions import activate_subscription
|
|||
|
||||
from core.errors.logger import logger
|
||||
from core.errors.exceptions import *
|
||||
from core.errors.exceptions import FirewallError
|
||||
from typing import Union, Optional, Callable
|
||||
from core.models.session.SessionProfile import SessionProfile
|
||||
from core.models.system.SystemProfile import SystemProfile
|
||||
from core.Errors import ConnectionTerminationError, InvalidSubscriptionError
|
||||
from core.Errors import ConnectionTerminationError, InvalidSubscriptionError, MissingSubscriptionError
|
||||
from core.services.WebServiceApiService import WebServiceApiService
|
||||
from core.controllers.ConnectionController import ConnectionController
|
||||
from core.models.BaseProfile import ProfileType
|
||||
|
|
|
|||
|
|
@ -182,4 +182,4 @@ async def switch_get_and_post(method: str, url: str, client: httpx.Client, paylo
|
|||
else:
|
||||
# nevermind,
|
||||
logger.info("Our strategy of switching GET/POST did NOT work.")
|
||||
return initial_result
|
||||
return second_result
|
||||
|
|
|
|||
|
|
@ -34,9 +34,7 @@ def single_endpoint(method: str, url: str, observer: ConnectionObserver, payload
|
|||
Purpose:
|
||||
Try a request to a single endpoint using either an existing client, or creating a new one, then error handling.
|
||||
"""
|
||||
|
||||
global _port_used
|
||||
|
||||
|
||||
connection_type = ConfigurationController.get_connection_enum()
|
||||
|
||||
client = httpx_client.get_http_session()
|
||||
|
|
@ -62,9 +60,6 @@ def single_endpoint(method: str, url: str, observer: ConnectionObserver, payload
|
|||
########################################################
|
||||
# FROM THIS POINT ON, WE HAVE A CLIENT
|
||||
########################################################
|
||||
# #### SPOOF
|
||||
# _port_used = 9050
|
||||
# initial_result = ApiResponse(valid=False, error_type=ErrorType.DNS_TEMPORARY)
|
||||
|
||||
initial_result = make_request(
|
||||
method=method,
|
||||
|
|
@ -367,3 +362,7 @@ def custom_dns_resolver_for_SINGLE_ENDPOINT(method: str, url: str, observer: Con
|
|||
# """Merge two dictionaries. dict1 values take precedence on key collision."""
|
||||
# return {**dict2, **dict1}
|
||||
|
||||
def replace_http_with_https(url):
|
||||
if url.startswith("http://"):
|
||||
return url.replace("http://", "https://", 1)
|
||||
return url
|
||||
|
|
|
|||
|
|
@ -176,4 +176,4 @@ def switch_get_and_post(method: str, url: str, client: httpx.Client, payload: di
|
|||
else:
|
||||
# nevermind,
|
||||
logger.info("Our strategy of switching GET/POST did NOT work.")
|
||||
return initial_result
|
||||
return second_result
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ from core.services.networking.regular_get_request import regular_get_request
|
|||
from core.errors.exceptions import *
|
||||
from core.errors.logger import logger
|
||||
import traceback
|
||||
from typing import Optional
|
||||
|
||||
|
||||
# Generic GET request to an endpoint, filtered by the user's preference of connection type (Tor or Not)
|
||||
|
|
|
|||
|
|
@ -84,13 +84,13 @@ def orchestrate_dns_check(target_interface: str) -> Result:
|
|||
else:
|
||||
logger.info(f"[DNS Orchestrator] Some of the DNS checks did NOT work. But this might be because the tunnel is down.")
|
||||
|
||||
targets_not_found = 0
|
||||
target_not_found = 0
|
||||
|
||||
for each_object in list_of_results_as_objects:
|
||||
if each_object.error_type == SearchError.TARGET_MISSING:
|
||||
target_not_found = target_not_found + 1
|
||||
|
||||
return Result(valid=False, data=targets_not_found)
|
||||
return Result(valid=False, data=target_not_found)
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
from core.services.networking.systemwide.systemwide_errors import systemwide_hell_raiser
|
||||
from core.utils.basic_operations.wrap_with import wrap_with
|
||||
from core.utils.run_commands import run_generic_command import run_generic_command
|
||||
from core.utils.run_commands import run_generic_command
|
||||
from core.models.Result import Result, ResultError
|
||||
from core.errors.logger import logger
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ from core.services.networking.systemwide.systemwide_utils import get_firewall_se
|
|||
from core.services.networking.systemwide import dns
|
||||
from core.services.networking.systemwide.general_connection_tools.general_firewall_dns_tools import generic_enable_firewall_w_retry
|
||||
from core.errors.exceptions import FirewallError, DNSError
|
||||
from essentials.observers.ConnectionObserver import ConnectionObserver
|
||||
|
||||
|
||||
# generic
|
||||
import subprocess
|
||||
|
|
@ -106,7 +108,7 @@ def start_singbox(
|
|||
if not activation_result.valid:
|
||||
error_msg = f"Singbox failed to start after {QUANTITY_OF_ATTEMPTS} attempts"
|
||||
logger.error(f"[{function_name}] {error_msg}")
|
||||
return Result(valid=False, error_type=ResultError=PROCESS_WONT_START, message=error_msg)
|
||||
return Result(valid=False, error_type=ResultError.PROCESS_WONT_START, message=error_msg)
|
||||
|
||||
process_id = activation_result.data
|
||||
time.sleep(2)
|
||||
|
|
@ -129,7 +131,7 @@ def start_singbox(
|
|||
)
|
||||
|
||||
# ============= FIREWALL =============
|
||||
logger.info(f"[{function_name}] Attempting to enable the Firewall for {SINGBOX_TUN_IF} and {Constants.SINGBOX_INTERNAL_SUBNET}...")
|
||||
logger.info(f"[{function_name}] Attempting to enable the Firewall for {Constants.SINGBOX_TUN_IF} and {Constants.SINGBOX_INTERNAL_SUBNET}...")
|
||||
# this is labeled "generic" for being protocol neutral
|
||||
firewall_result = generic_enable_firewall_w_retry(
|
||||
interface_name=Constants.SINGBOX_TUN_IF,
|
||||
|
|
|
|||
|
|
@ -230,6 +230,7 @@ def _establish_connection_with_retry(
|
|||
|
||||
except ConnectionError as e:
|
||||
# Unrecoverable error, fail immediately
|
||||
logger.error(str(e))
|
||||
raise
|
||||
|
||||
except CalledProcessError as e:
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
from core.utils.run_commands import run_generic_command
|
||||
from core.models.Result import Result, ResultError
|
||||
from core.errors.logger import logger
|
||||
|
||||
from subprocess import CalledProcessError
|
||||
import os
|
||||
import re
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
from core.services.networking.tor_tools.monitor_bootstrap import monitor_bootstrap_progress
|
||||
from core.services.networking.tor_tools.install_tor import install_tor
|
||||
from core.services.networking.api_requests.ApiResponseModel import ApiResponse, ErrorType
|
||||
from core.services.networking.tor_tools import ports
|
||||
from core.Constants import Constants
|
||||
|
|
@ -89,7 +90,7 @@ def bootstrap(
|
|||
current_port = ports.get_random_available_port()
|
||||
use_new_folder = True
|
||||
elif strategy == BootstrapStrategy.REINSTALL_AND_RETRY:
|
||||
if not install_tor().valid:
|
||||
if not install_tor(observer).valid:
|
||||
return ApiResponse(valid=False, error_type=ErrorType.INSTALL_FAILED)
|
||||
use_new_folder = True
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ def get_distro_package_manager() -> Optional[str]:
|
|||
return None
|
||||
|
||||
|
||||
async def install_tor() -> ApiResponse:
|
||||
async def install_tor(observer: ConnectionObserver) -> ApiResponse:
|
||||
"""
|
||||
Prompt user to install Tor with pkexec, detecting distro for correct package manager.
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -7,13 +7,13 @@ from core.Constants import Constants
|
|||
from typing import Optional
|
||||
import subprocess
|
||||
import asyncio
|
||||
import subprocess
|
||||
import socket
|
||||
import httpx
|
||||
from httpx_socks import AsyncProxyTransport
|
||||
import json
|
||||
import re
|
||||
|
||||
import os
|
||||
import signal
|
||||
|
||||
def is_port_in_use(port: int) -> bool:
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ def get_bootstrap_port(port_tried: int, observer: ConnectionObserver):
|
|||
def diagnose_tor_port(port_tried: int, observer: ConnectionObserver) -> ApiResponse:
|
||||
# Step 1) Is Tor Installed?
|
||||
if not is_installed('tor'):
|
||||
installed = install_tor()
|
||||
installed = install_tor(observer)
|
||||
if installed:
|
||||
return ApiResponse(valid=True, error_type=ErrorType.TOR_NOT_INSTALLED, port=Constants.DEFAULT_TOR_PORT)
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ def establish_tor_connection(observer: ConnectionObserver) -> ApiResponse:
|
|||
|
||||
# Step 2) Install Tor if needed.
|
||||
if result.error_type == ErrorType.TOR_NOT_INSTALLED:
|
||||
installed = install_tor()
|
||||
installed = install_tor(observer)
|
||||
if not installed:
|
||||
return ApiResponse(valid=False, error_type=ErrorType.REFUSAL_TO_INSTALL_TOR)
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ from core.services.networking.api_requests.step1_get_or_post import send_data_to
|
|||
from core.services.networking.api_requests.ApiResponseModel import ApiResponse, ErrorType
|
||||
from core.services.networking.api_requests.step5_solve_api_problems import solve_api_problems
|
||||
|
||||
from core.services.networking.httpx import connect
|
||||
|
||||
from core.services.networking.make_url import make_url
|
||||
from core.services.payment_phase.extract_payment_details import extract_payment_details
|
||||
|
|
@ -42,24 +43,35 @@ def save_and_send_intitial_billing(
|
|||
"""
|
||||
|
||||
# Save choices:
|
||||
save_billing_choices(payload)
|
||||
saved_choices = save_billing_choices(payload)
|
||||
if not saved_choices:
|
||||
error_msg = "Unable to save billing choices locally. Check file permissions and storage space."
|
||||
logger.error(error_msg)
|
||||
return TicketInvoice(is_valid=False, final_error_msg=error_msg)
|
||||
|
||||
# send them:
|
||||
which_endpoint = "start_payment"
|
||||
url = make_url(which_endpoint)
|
||||
api_reply_object = send_data_to_server(payload, url, connection_observer)
|
||||
# api_reply_object = send_data_to_server(payload, url, connection_observer)
|
||||
|
||||
api_reply_object = connect.single_endpoint(
|
||||
method="post",
|
||||
url=url,
|
||||
observer=connection_observer,
|
||||
payload=payload
|
||||
)
|
||||
|
||||
# if not api_reply_object.valid:
|
||||
# api_reply_object = solve_api_problems(
|
||||
# api_reply_object=api_reply_object,
|
||||
# get_or_post="post",
|
||||
# url=url,
|
||||
# payload=payload,
|
||||
# connection_observer=connection_observer,
|
||||
# client_observer=None
|
||||
# )
|
||||
if not api_reply_object.valid:
|
||||
api_reply_object = solve_api_problems(
|
||||
api_reply_object=api_reply_object,
|
||||
get_or_post="post",
|
||||
url=url,
|
||||
payload=payload,
|
||||
connection_observer=connection_observer,
|
||||
client_observer=None
|
||||
)
|
||||
if not api_reply_object.valid:
|
||||
return api_reply_object
|
||||
return api_reply_object
|
||||
|
||||
reply_dict_data = api_reply_object.data
|
||||
|
||||
|
|
|
|||
|
|
@ -8,4 +8,4 @@ def save_billing_choices(payload: dict) -> None:
|
|||
billing_folder = Constants.HV_TICKETING_CONFIG_HOME
|
||||
filepath = f"{billing_folder}/billing_choices.json"
|
||||
|
||||
write_json_to_file(payload, filepath)
|
||||
return write_json_to_file(payload, filepath)
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ from typing import Any
|
|||
# services
|
||||
from core.services.networking.make_url import make_url
|
||||
from core.services.networking.api_requests.step1_get_or_post import get_data_from_api
|
||||
from core.services.networking.httpx import connect
|
||||
from core.services.networking.api_requests.ApiResponseModel import ApiResponse, ErrorType
|
||||
|
||||
# utils
|
||||
from core.utils.basic_operations.does_file_exist import does_file_exist
|
||||
|
|
@ -30,18 +32,20 @@ def get_from_server_and_save(
|
|||
|
||||
url = make_url(string_form_of_key_name)
|
||||
|
||||
# the result of this is a python dictionary with single '
|
||||
public_key_results = get_data_from_server(url, connection_observer)
|
||||
# public_key_results = get_data_from_server(url, connection_observer)
|
||||
public_key_results = connect.single_endpoint(
|
||||
method="get",
|
||||
url=url,
|
||||
observer=connection_observer,
|
||||
payload=None
|
||||
)
|
||||
|
||||
if public_key_results.valid:
|
||||
# extract:
|
||||
public_key = public_key_results.data
|
||||
|
||||
if isinstance(public_key_results, dict) and "valid" in public_key_results:
|
||||
status = public_key_results.get("valid", False)
|
||||
|
||||
if status == True:
|
||||
# extract:
|
||||
public_key = public_key_results.get("data", False)
|
||||
|
||||
# save it:
|
||||
did_it_save = write_string_to_text_file(public_key, file_path)
|
||||
# save it:
|
||||
did_it_save = write_string_to_text_file(public_key, file_path)
|
||||
|
||||
return public_key_results
|
||||
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ def get_public_key_by_config(connection_observer: ConnectionObserver) -> dict:
|
|||
if reply in list_of_failures:
|
||||
return complete_failure_msg
|
||||
|
||||
if not instance(reply, dict):
|
||||
if not isinstance(reply, dict):
|
||||
return {
|
||||
"status": False,
|
||||
"message": f"Server returned an invalid format, and even accessing via local files. Please check {filepath}",
|
||||
|
|
@ -141,7 +141,7 @@ def get_public_key_from_LOCAL_files_only(
|
|||
if reply in list_of_failures:
|
||||
return complete_failure_msg
|
||||
|
||||
if not instance(reply, dict):
|
||||
if not isinstance(reply, dict):
|
||||
return {
|
||||
"status": False,
|
||||
"message": f"Server returned an invalid format, and even accessing via local files. Please check {filepath}",
|
||||
|
|
|
|||
|
|
@ -21,4 +21,4 @@ def setup_ticket_tracker(how_many_profiles: int) -> None:
|
|||
}
|
||||
counter += 1
|
||||
|
||||
write_json_to_file(ticket_data, ticket_tracker_path)
|
||||
return write_json_to_file(ticket_data, ticket_tracker_path)
|
||||
|
|
|
|||
|
|
@ -94,9 +94,9 @@ def ticket_prep_orchestrator(
|
|||
)
|
||||
|
||||
# make a json to keep track of which tickets are used:
|
||||
setup_ticket_tracker(how_many_profiles)
|
||||
setup_tracker = setup_ticket_tracker(how_many_profiles)
|
||||
|
||||
if did_prep_work:
|
||||
if did_prep_work and setup_tracker:
|
||||
# this means it unblinded, & setup the tracker without erroring out,
|
||||
# but it does NOT mean that verification of the blind sigs worked.
|
||||
return {"valid": True, "message": "worked"}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,4 @@
|
|||
from core.utils.basic_operations.write_or_read_from_json import (
|
||||
write_json_to_file,
|
||||
read_entire_json,
|
||||
)
|
||||
from core.utils.basic_operations.write_or_read_from_json import read_entire_json
|
||||
from core.errors.exceptions import *
|
||||
from core.errors.logger import logger
|
||||
from core.Constants import Constants
|
||||
|
|
@ -62,7 +59,7 @@ def get_data_for_a_single_ticket(which_ticket_as_int: int) -> tuple:
|
|||
error_msg = f"Entire file of tickets does not exist. Check the location {ticket_tracker_path}"
|
||||
logger.error(error_msg, exc_info=True)
|
||||
print(error_msg)
|
||||
raise InvalidData(error_msg)
|
||||
raise ValueError(error_msg)
|
||||
|
||||
# the data is a string for lookups:
|
||||
which_ticket = str(which_ticket_as_int)
|
||||
|
|
@ -74,6 +71,6 @@ def get_data_for_a_single_ticket(which_ticket_as_int: int) -> tuple:
|
|||
subscription = data.get(which_ticket, {}).get("subscription")
|
||||
return status, location, subscription
|
||||
else:
|
||||
raise InvalidData(
|
||||
raise ValueError(
|
||||
f"Key '{which_ticket}' does not exist in JSON file {ticket_tracker_path}"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
from core.errors.exceptions import *
|
||||
from core.errors.logger import logger
|
||||
|
||||
import json
|
||||
|
|
@ -6,7 +5,7 @@ import os
|
|||
from pathlib import Path
|
||||
|
||||
|
||||
def write_json_to_file(data: dict, filepath: str) -> None:
|
||||
def write_json_to_file(data: dict, filepath: str) -> bool:
|
||||
try:
|
||||
# Create directory if it doesn't exist
|
||||
directory = os.path.dirname(filepath)
|
||||
|
|
@ -16,10 +15,20 @@ def write_json_to_file(data: dict, filepath: str) -> None:
|
|||
with open(filepath, "w") as f:
|
||||
json.dump(data, f, indent=4)
|
||||
|
||||
return True
|
||||
|
||||
except TypeError as e:
|
||||
raise TypeError(f"Data is not JSON serializable: {e}")
|
||||
logger.error(f"Data is not JSON serializable: {e}")
|
||||
return False
|
||||
except FileNotFoundError:
|
||||
logger.error(f"File not found: {filepath}")
|
||||
return False
|
||||
except IsADirectoryError:
|
||||
logger.error(f"Path is a directory, not a file: {filepath}")
|
||||
return False
|
||||
except IOError as e:
|
||||
raise IOError(f"Error writing to file {filepath}: {e}")
|
||||
logger.error(f"Error reading file {filepath}: {e}")
|
||||
return False
|
||||
|
||||
|
||||
def read_entire_json(filepath: str) -> dict:
|
||||
|
|
@ -43,13 +52,13 @@ def read_entire_json(filepath: str) -> dict:
|
|||
f"Invalid JSON in file {filepath}: {e.msg}", e.doc, e.pos
|
||||
)
|
||||
except FileNotFoundError:
|
||||
raise FileNotFoundError(f"File not found: {filepath}")
|
||||
logger.error(f"File not found: {filepath}")
|
||||
return False
|
||||
except IsADirectoryError:
|
||||
raise IsADirectoryError(f"Path is a directory, not a file: {filepath}")
|
||||
logger.error(f"Path is a directory, not a file: {filepath}")
|
||||
return False
|
||||
except IOError as e:
|
||||
raise IOError(f"Error reading file {filepath}: {e}")
|
||||
logger.error(f"Error reading file {filepath}: {e}")
|
||||
return False
|
||||
|
||||
|
||||
|
|
@ -103,8 +112,14 @@ def update_value_in_json_with_two_values(
|
|||
|
||||
return True
|
||||
|
||||
except:
|
||||
raise InvalidData(f"Error reading file {filepath}")
|
||||
except FileNotFoundError:
|
||||
logger.error(f"File not found: {filepath}")
|
||||
return False
|
||||
except IsADirectoryError:
|
||||
logger.error(f"Path is a directory, not a file: {filepath}")
|
||||
return False
|
||||
except IOError as e:
|
||||
logger.error(f"Error reading file {filepath}: {e}")
|
||||
return False
|
||||
|
||||
|
||||
|
|
@ -122,6 +137,12 @@ def update_json(filepath, key_to_add, value_to_update):
|
|||
write_json_to_file(data, filepath)
|
||||
return True
|
||||
|
||||
except:
|
||||
raise InvalidData(f"Error reading file {filepath}")
|
||||
except FileNotFoundError:
|
||||
logger.error(f"File not found: {filepath}")
|
||||
return False
|
||||
except IsADirectoryError:
|
||||
logger.error(f"Path is a directory, not a file: {filepath}")
|
||||
return False
|
||||
except IOError as e:
|
||||
logger.error(f"Error reading file {filepath}: {e}")
|
||||
return False
|
||||
|
|
|
|||
|
|
@ -131,14 +131,14 @@ def run_generic_command(
|
|||
|
||||
try:
|
||||
returncode, stdout = _run_command_via_terminal(command, timeout)
|
||||
output_data = stdout
|
||||
# output_data = stdout
|
||||
|
||||
if returncode == 0:
|
||||
logger.info(f"{human_readable_goal} was successful")
|
||||
return Result(valid=True, data=output_data)
|
||||
return Result(valid=True, data=stdout)
|
||||
else:
|
||||
# Try stderr first, fallback to stdout for error parsing
|
||||
error_output = (stderr or stdout).strip()
|
||||
error_output = stdout.strip()
|
||||
error_enum = parse_errors(error_output)
|
||||
logger.error(f"{human_readable_goal} Failed, error type is {error_enum}.")
|
||||
return Result(valid=False, error_type=error_enum, goal=human_readable_goal, message=error_output)
|
||||
|
|
@ -147,3 +147,19 @@ def run_generic_command(
|
|||
return Result(valid=False, error_type=ResultError.TIMEOUT, goal=human_readable_goal, data=output_data, message=f"Command timed out {e}")
|
||||
except Exception as e:
|
||||
return Result(valid=False, error_type=ResultError.UNKNOWN, goal=human_readable_goal, data=output_data, message=str(e))
|
||||
|
||||
|
||||
def parse_errors(error_output: str) -> ResultError:
|
||||
# Interface missing
|
||||
if "No such device" in error_output:
|
||||
error_enum = ResultError.INTERFACE
|
||||
# Permission error
|
||||
elif "No permissions" in error_output:
|
||||
error_enum = ResultError.PERMISSION
|
||||
elif "sudo: a password is required" or "password is required" in error_output:
|
||||
error_enum = ResultError.PERMISSION
|
||||
elif "command not found" in error_output:
|
||||
error_enum = ResultError.MISSING_DEPENDENCY
|
||||
else:
|
||||
error_enum = ResultError.UNKNOWN
|
||||
return error_enum
|
||||
|
|
|
|||
Loading…
Reference in a new issue