diff --git a/gui/v2/actions/menu_coordinator.py b/gui/v2/actions/menu_coordinator.py index 83516a9..c71b864 100644 --- a/gui/v2/actions/menu_coordinator.py +++ b/gui/v2/actions/menu_coordinator.py @@ -4,17 +4,13 @@ from core.services.prepare_tickets.ticket_tracker import get_a_random_ticket from core.services.profiles.profile_connections import enable_profile #, disable_profile from core.controllers.ProfileController import ProfileController from core.models.Configuration import Configuration, ConnectionChoice -from core.services.subscriptions.subscriptions_by_protocol import get_profile_subscription, start_new_payment_cycle, wipe_subscription, wipe_billing_cycle +from core.services.subscriptions.subscriptions_by_protocol import get_profile_subscription, start_new_payment_cycle, wipe_subscription from core.utils.check_if_time_lapsed import check_if_time_lapsed from core.models.enum_models import PaymentCategory from core.utils.type_checker import type_checker from core.models.Result import Result, ResultError from core.errors.logger import logger -from core.Errors import ( - CommandNotFoundError, EndpointVerificationError, FileIntegrityError, - InvalidSubscriptionError, MissingSubscriptionError, ProfileActivationError, - ProfileModificationError, ProfileStateConflictError, UnsupportedApplicationVersionError, -) +from core.errors.translate_error import translate_error, get_ignored_exceptions # gui from gui.v2.actions.ticket_actions import get_ticket_data, use_a_ticket @@ -26,17 +22,8 @@ from gui.v2.infrastructure.setup_observers import ( profile_observer, ticket_observer, ) - - # generic -from typing import Callable, Optional, Type - -ERROR_TO_UI_MESSAGE = { - ProfileActivationError: "The profile could not be enabled", - UnsupportedApplicationVersionError: "The application version in question is not supported", - FileIntegrityError: "Application version file integrity could not be verified.", - ProfileModificationError: "WireGuard configuration could not be attached.", -} +from typing import Callable, Optional def get_profile(profile_id: int): @@ -47,21 +34,6 @@ def get_profile(profile_id: int): return Result(valid=True, data=profile) -def get_ignored_exceptions(ignore_state_conflict: Optional[bool] = False): - ignored_as_list = [] - config = Configuration.get() - endpoint_verification_enabled = config.endpoint_verification_enabled - - if endpoint_verification_enabled: - ignored_as_list.append(EndpointVerificationError) - - if ignore_state_conflict: - ignored_as_list.append(ProfileStateConflictError) - - ignored = tuple(ignored_as_list) - return ignored - - @register_action(ResultError.SUBSCRIPTION) def navigate_to_new_sub_page() -> Result: return Result(valid=False, error_type=ResultError.NAVIGATE_TO, navigate_to="id", message="No subscription. Pick a payment method.") @@ -89,6 +61,7 @@ def start_and_navigate_to_ticketing(): return start_result + def random_ticket_dispatch(profile_id: int, passed_ui_caller: Callable) -> Result: """ User explicitly wants a random ticket. @@ -113,7 +86,7 @@ def random_ticket_dispatch(profile_id: int, passed_ui_caller: Callable) -> Resul def dispatch_ticketing(profile_id: int, passed_ui_caller: Callable) -> Result: """Evaluate if a random ticket will be used.""" - use_random_setting = ConfigurationController.use_random + use_random_setting = ConfigurationController.use_random() if use_random_setting: return random_ticket_dispatch(profile_id=profile_id, passed_ui_caller=passed_ui_caller) @@ -125,7 +98,7 @@ def dispatch_ticketing(profile_id: int, passed_ui_caller: Callable) -> Result: return Result(valid=False, error_type=ResultError.NAVIGATE_TO, navigate_to="ticket_or_billing_choice") else: - # user can pick between tickets or individual: + # user can decide if they want to setup tickets or do an individual profile: return navigate_to_new_sub_page() @@ -178,12 +151,9 @@ def filter_subscription(profile_id: int, passed_ui_caller: Callable) -> Result: return Result(valid=True) - @register_action(ResultError.TOR_NEEDED) def switch_to_tor_connection() -> Result: - config = Configuration.get() - config.connection = ConnectionChoice.TOR - config.save() + ConfigurationController.set_connection_enum(ConnectionChoice.TOR) return Result(valid=True) @@ -221,6 +191,7 @@ def NOT_need_tor_warnings(profile_id: int) -> Result: return Result(valid=False, error_type=ResultError.TOR_NEEDED, message=error_msg) + @register_action(ResultError.ENDPOINT_VERIFICATION) def literally_connect( profile_id: int, @@ -255,78 +226,32 @@ def literally_connect( else: return Result(valid=True) except Exception as error: - return enable_error(error=error, profile_id=profile_id) + return translate_error(error=error, profile_id=profile_id) -def enable_error(error: Type[Exception], profile_id: int) -> Result: - """Translate core errors into actions and/or messages via Result Objects.""" - logger.error(str(error)) - #---------------------- - # PURE MESSAGES (NO SOLUTION FUNCTION) - #---------------------- - if error in ERROR_TO_UI_MESSAGE: - error_msg = ERROR_TO_UI_MESSAGE[error] - return Result(valid=False, error_type=ResultError.UNKNOWN, message=error_msg) - - #---------------------- - # ENDPOINT VERIFICATION - #---------------------- - if isinstance(error, EndpointVerificationError): - return Result(valid=False, error_type=ResultError.ENDPOINT_VERIFICATION, message="Operator verification failed. Do you want to continue anyway?") - - #---------------------- - # STATE CONFLICT - #---------------------- - if isinstance(error, ProfileStateConflictError): - function_choice = literally_connect( - profile_id=profile_id, - ignore_state_conflict=True - ) - error_msg = "The profile is already enabled. Do you want to force enable it anyway?" - return Result(valid=False, function_choice=function_choice, error_type=ResultError.STATE_CONFLICT, message=error_msg) - - #---------------------- - # SUBSCRIPTION - #---------------------- - if isinstance(error, (InvalidSubscriptionError, MissingSubscriptionError)): - error_msg = f"Subscription missing or invalid for profile {profile_id}. Do you want to get a new sub?" - return Result(valid=False, error_type=ResultError.SUBSCRIPTION, message=error_msg) - - #---------------------- - # COMMAND NOT FOUND - #---------------------- - if isinstance(error, CommandNotFoundError): - # add install later!! - name_of_package = str(error.subject) - error_msg = f"You're missing the {name_of_package} package. Please install it." - return Result(valid=False, error_type=ResultError.MISSING_SOFTWARE, message=error_msg) - - else: - return Result(valid=False, error_type=ResultError.UNKNOWN, message="An unknown error occured.") +@register_action(ResultError.STATE_CONFLICT) +def ignore_state_conflict(profile_id: int) -> Result: + return literally_connect( + profile_id=profile_id, + ignore_state_conflict=True + ) def _connect_profile(profile_id: int, passed_ui_caller: Callable) -> Result: """Background Threaded Orchestration to Start a Connection""" - # # Step 1: Get the Profile - # profile_result = get_profile(profile_id) - # if not profile_result: - # return Result(valid=False, error_type=ResultError.INVALID_INPUT, message="This profile does not match one of your configuration files.") - - # profile = profile_result.data - - # Step 2: Subscription filter: + # Step 1: Subscription filter: sub_result = filter_subscription(profile_id=profile_id, passed_ui_caller=passed_ui_caller) if not sub_result.valid: return sub_result - # Step 3: Tor filter check: + # Step 2: Tor filter check: result = NOT_need_tor_warnings(profile_id=profile_id) if not result.valid: return result - # Actual Connection: + # Step 3: Actual Connection: logger.info(f"Profile id {profile_id} is ready to connect..") return literally_connect(profile_id=profile_id) @@ -343,3 +268,4 @@ def connect_profile(profile_id: int, ui_caller: Callable) -> Result: return Result(valid=True) + diff --git a/gui/v2/actions/ticket_actions.py b/gui/v2/actions/ticket_actions.py index 24be8bb..fac026d 100644 --- a/gui/v2/actions/ticket_actions.py +++ b/gui/v2/actions/ticket_actions.py @@ -35,46 +35,6 @@ def fetch_ticket_invoice(ui_caller: Callable) -> str | None: ) -# def fetch_ticket_invoice(invoice_ui_caller: Callable, timer_resume_caller: Callable) -> str | None: -# """Start the Ticketing process on the background thread with the relevant billing data.""" - -# logger.info("fetching ticket invoice..") - -# payment_cycle = OverallPaymentCycle() - -# if not payment_cycle: -# "No payment cycle, and therefore no data." - -# # already existing but wrong format: -# if payment_cycle.category != PaymentCategory.TICKET: -# return "Wrong payment cycle category." - -# billing_data = payment_cycle.instance - -# if not billing_data: -# return "No billing data" - -# # if not isinstance(billing_data, TicketPaymentData): -# # return "Billing data in the wrong format." - -# which_key = billing_data.which_key -# currency = billing_data.currency -# how_many_profiles = billing_data.how_many_profiles - -# # Fetch (this function will complain if missing data): -# take_action( -# action=initiate_payment, -# ui_caller=invoice_ui_caller, -# how_many_profiles=how_many_profiles, -# which_key=which_key, -# which_cryptocurrency=currency, -# ticket_observer=ticket_observer, -# connection_observer=connection_observer, -# bypass_existing=True, -# ) -# logger.info("Initiated payment") - - def get_ticket_data() -> Result: """This is running in the background ALREADY. Get & format a list of unused tickets from core""" @@ -159,4 +119,9 @@ class TicketUser(): self.ui_caller(new_result) logger.info("Saved sub, returning to UI layer..") - self.ui_caller(result) \ No newline at end of file + self.ui_caller(result) + + +def wipe_ticket_billing(): + """Wipe existing data and start over.""" + \ No newline at end of file