Compare commits
No commits in common. "zenaku" and "master" have entirely different histories.
11 changed files with 473 additions and 530 deletions
501
cli/__main__.py
501
cli/__main__.py
|
|
@ -1,48 +1,491 @@
|
||||||
from core.Constants import Constants
|
from core.Constants import Constants
|
||||||
from core.Errors import UnknownConnectionTypeError
|
from core.Errors import MissingSubscriptionError, InvalidSubscriptionError, UnknownConnectionTypeError, ConnectionUnprotectedError, EndpointVerificationError, ProfileStateConflictError
|
||||||
from cli.helpers import get_distribution
|
from core.controllers.ApplicationController import ApplicationController
|
||||||
from cli.commands import all_commands
|
from core.controllers.ApplicationVersionController import ApplicationVersionController
|
||||||
from cli.commands import get_set, sync_update
|
from core.controllers.ClientController import ClientController
|
||||||
|
from core.controllers.ClientVersionController import ClientVersionController
|
||||||
|
from core.controllers.ConfigurationController import ConfigurationController
|
||||||
|
from core.controllers.InvoiceController import InvoiceController
|
||||||
|
from core.controllers.LocationController import LocationController
|
||||||
|
from core.controllers.PolicyController import PolicyController
|
||||||
|
from core.controllers.ProfileController import ProfileController
|
||||||
|
from core.controllers.SubscriptionController import SubscriptionController
|
||||||
|
from core.controllers.SubscriptionPlanController import SubscriptionPlanController
|
||||||
|
from core.models.session.Application import Application
|
||||||
|
from core.models.session.SessionConnection import SessionConnection
|
||||||
|
from core.models.session.SessionProfile import SessionProfile
|
||||||
|
from core.models.system.SystemConnection import SystemConnection
|
||||||
|
from core.models.system.SystemProfile import SystemProfile
|
||||||
|
from core.observers.ApplicationVersionObserver import ApplicationVersionObserver
|
||||||
|
from core.observers.ClientObserver import ClientObserver
|
||||||
|
from core.observers.ConnectionObserver import ConnectionObserver
|
||||||
|
from core.observers.InvoiceObserver import InvoiceObserver
|
||||||
|
from core.observers.ProfileObserver import ProfileObserver
|
||||||
|
from importlib import metadata
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from typing import Optional, Union
|
||||||
import argparse
|
import argparse
|
||||||
|
import pprint
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
|
||||||
def _handle_exception(identifier, message, traceback):
|
|
||||||
if issubclass(identifier, UnknownConnectionTypeError):
|
|
||||||
print('Please specify the desired connection method and try again.\n')
|
|
||||||
else:
|
|
||||||
sys.__excepthook__(identifier, message, traceback)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
||||||
Path(Constants.HV_CONFIG_HOME).mkdir(parents=True, exist_ok=True)
|
Path(Constants.HV_CONFIG_HOME).mkdir(parents=True, exist_ok=True)
|
||||||
Path(Constants.HV_DATA_HOME).mkdir(parents=True, exist_ok=True)
|
Path(Constants.HV_DATA_HOME).mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
sys.excepthook = _handle_exception
|
application_version_observer = ApplicationVersionObserver()
|
||||||
|
client_observer = ClientObserver()
|
||||||
|
connection_observer = ConnectionObserver()
|
||||||
|
invoice_observer = InvoiceObserver()
|
||||||
|
profile_observer = ProfileObserver()
|
||||||
|
|
||||||
distribution = get_distribution()
|
application_version_observer.subscribe('downloading', lambda event: print(f'Downloading {ApplicationController.get(event.subject.application_code).name}, version {event.subject.version_number}...'))
|
||||||
|
application_version_observer.subscribe('download_progressing', lambda event: print(f'Current progress: {event.meta.get('progress'):.2f}%', flush=True, end='\r'))
|
||||||
|
application_version_observer.subscribe('downloaded', lambda event: print('\n'))
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(prog=distribution.name)
|
client_observer.subscribe('synchronizing', lambda event: print('Synchronizing...\n'))
|
||||||
parser.add_argument('--version', '-v', action='version', version=f'{distribution.name} v{distribution.version}')
|
client_observer.subscribe('updating', lambda event: print('Updating client...'))
|
||||||
subparsers = parser.add_subparsers(title='commands', dest='command')
|
client_observer.subscribe('update_progressing', lambda event: print(f'Current progress: {event.meta.get('progress'):.2f}%', flush=True, end='\r'))
|
||||||
|
client_observer.subscribe('updated', lambda event: print('\n'))
|
||||||
|
|
||||||
for command in all_commands:
|
connection_observer.subscribe('connecting', lambda event: print(f'[{event.subject.get("attempt_count")}/{event.subject.get("maximum_number_of_attempts")}] Performing connection attempt...\n'))
|
||||||
command.register(subparsers)
|
connection_observer.subscribe('tor_bootstrapping', lambda event: print('Bootstrapping Tor...'))
|
||||||
|
connection_observer.subscribe('tor_bootstrap_progressing', lambda event: print(f'Current progress: {event.meta.get('progress'):.2f}%', flush=True, end='\r'))
|
||||||
|
connection_observer.subscribe('tor_bootstrapped', lambda event: print('\n'))
|
||||||
|
|
||||||
arguments = parser.parse_args()
|
invoice_observer.subscribe('retrieved', lambda event: print(f'\n{pprint.pp(event.subject)}\n'))
|
||||||
|
invoice_observer.subscribe('processing', lambda event: print('A payment has been detected and is being verified...\n'))
|
||||||
|
invoice_observer.subscribe('settled', lambda event: print('The payment has been successfully verified.\n'))
|
||||||
|
|
||||||
if arguments.command is None:
|
profile_observer.subscribe('created', lambda event: pprint.pp((__sanitize_profile(event.subject), 'Created')))
|
||||||
parser.print_help()
|
profile_observer.subscribe('destroyed', lambda event: pprint.pp((__sanitize_profile(event.subject), 'Destroyed')))
|
||||||
|
profile_observer.subscribe('disabled', lambda event: pprint.pp((__sanitize_profile(event.subject), 'Disabled')) if event.meta.get('explicitly') else None)
|
||||||
|
profile_observer.subscribe('enabled', lambda event: pprint.pp((__sanitize_profile(event.subject), 'Enabled')))
|
||||||
|
|
||||||
elif arguments.command in (get_set.NAME, get_set.NAME_SET):
|
def __get_distribution():
|
||||||
get_set.handle(arguments, parser)
|
|
||||||
|
|
||||||
elif arguments.command in (sync_update.NAME_SYNC, sync_update.NAME_UPDATE):
|
for candidate in metadata.distributions():
|
||||||
sync_update.handle(arguments, parser)
|
|
||||||
|
if 'cli' not in candidate.name:
|
||||||
|
continue
|
||||||
|
|
||||||
|
candidate_files = candidate.files
|
||||||
|
|
||||||
|
if candidate_files is None:
|
||||||
|
continue
|
||||||
|
|
||||||
|
for distribution_file in candidate_files:
|
||||||
|
|
||||||
|
if distribution_file.parts[0] == 'cli':
|
||||||
|
return candidate
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
def __parse_composite_argument(argument: str, first_key: str, second_key: str, separator: str = ':'):
|
||||||
|
return dict(zip([first_key, second_key], argument.split(separator) + ['']))
|
||||||
|
|
||||||
|
def __parse_application_argument(application_argument: str):
|
||||||
|
return __parse_composite_argument(application_argument, 'application_code', 'version_number')
|
||||||
|
|
||||||
|
def __parse_location_argument(location_argument: str):
|
||||||
|
return __parse_composite_argument(location_argument, 'country_code', 'code')
|
||||||
|
|
||||||
|
def __sanitize_profile(candidate: Optional[Union[SessionProfile, SystemProfile]]):
|
||||||
|
|
||||||
|
if candidate is not None and candidate.has_subscription():
|
||||||
|
|
||||||
|
sanitized_billing_code = candidate.subscription.get_sanitized_billing_code()
|
||||||
|
candidate.subscription.billing_code = sanitized_billing_code
|
||||||
|
|
||||||
|
return candidate
|
||||||
|
|
||||||
|
def __handle_exception(identifier, message, traceback):
|
||||||
|
|
||||||
|
if issubclass(identifier, UnknownConnectionTypeError):
|
||||||
|
print('Please specify the desired connection method and try again.\n')
|
||||||
|
|
||||||
else:
|
else:
|
||||||
command = next((c for c in all_commands if getattr(c, 'NAME', None) == arguments.command), None)
|
sys.__excepthook__(identifier, message, traceback)
|
||||||
if command:
|
|
||||||
command.handle(arguments, parser)
|
sys.excepthook = __handle_exception
|
||||||
|
distribution = __get_distribution()
|
||||||
|
|
||||||
|
pristine_parser = argparse.ArgumentParser(add_help=False)
|
||||||
|
pristine_parser.add_argument('--pristine', '-p', action='store_true')
|
||||||
|
|
||||||
|
connection_protection_parser = argparse.ArgumentParser(add_help=False)
|
||||||
|
connection_protection_parser.add_argument('--without-connection-protection', action='store_true')
|
||||||
|
|
||||||
|
endpoint_verification_parser = argparse.ArgumentParser(add_help=False)
|
||||||
|
endpoint_verification_parser.add_argument('--without-endpoint-verification', action='store_true')
|
||||||
|
|
||||||
|
profile_state_protection_parser = argparse.ArgumentParser(add_help=False)
|
||||||
|
profile_state_protection_parser.add_argument('--without-profile-state-protection', action='store_true')
|
||||||
|
|
||||||
|
main_parser = argparse.ArgumentParser(prog=distribution.name)
|
||||||
|
main_parser.add_argument('--version', '-v', action='version', version=f'{distribution.name} v{distribution.version}')
|
||||||
|
main_subparsers = main_parser.add_subparsers(title='commands', dest='command')
|
||||||
|
|
||||||
|
profile_parser = main_subparsers.add_parser('profile')
|
||||||
|
profile_subparsers = profile_parser.add_subparsers(title='subcommands', dest='subcommand')
|
||||||
|
|
||||||
|
profile_base_parser = argparse.ArgumentParser(add_help=False)
|
||||||
|
profile_base_parser.add_argument('--id', '-i', type=int, required=True)
|
||||||
|
|
||||||
|
profile_subparsers.add_parser('list')
|
||||||
|
|
||||||
|
profile_subparsers.add_parser('show', parents=[profile_base_parser])
|
||||||
|
|
||||||
|
profile_create_parser = profile_subparsers.add_parser('create')
|
||||||
|
profile_create_subparsers = profile_create_parser.add_subparsers(title='profile_types', dest='profile_type')
|
||||||
|
|
||||||
|
session_profile_create_parser = profile_create_subparsers.add_parser('session', parents=[profile_base_parser])
|
||||||
|
|
||||||
|
session_profile_create_parser.add_argument('--name', '-n', default='')
|
||||||
|
session_profile_create_parser.add_argument('--location', '-l', default='')
|
||||||
|
session_profile_create_parser.add_argument('--application', '-a', required=True)
|
||||||
|
session_profile_create_parser.add_argument('--connection', '-c', dest='connection_type', choices=['system', 'tor', 'wireguard'], default='system')
|
||||||
|
session_profile_create_parser.add_argument('--mask-connection', '-m', action='store_true')
|
||||||
|
session_profile_create_parser.add_argument('--resolution', '-r', default='1280x720')
|
||||||
|
|
||||||
|
system_profile_create_parser = profile_create_subparsers.add_parser('system', parents=[profile_base_parser])
|
||||||
|
|
||||||
|
system_profile_create_parser.add_argument('--name', '-n', default='')
|
||||||
|
system_profile_create_parser.add_argument('--location', '-l', default='')
|
||||||
|
system_profile_create_parser.add_argument('--connection', '-c', dest='connection_type', choices=['wireguard'], default='wireguard')
|
||||||
|
|
||||||
|
profile_subparsers.add_parser('destroy', parents=[profile_base_parser])
|
||||||
|
|
||||||
|
profile_subparsers.add_parser('enable', parents=[profile_base_parser, pristine_parser, connection_protection_parser, endpoint_verification_parser, profile_state_protection_parser])
|
||||||
|
profile_subparsers.add_parser('disable', parents=[profile_base_parser, connection_protection_parser])
|
||||||
|
|
||||||
|
application_parser = main_subparsers.add_parser('application')
|
||||||
|
application_subparsers = application_parser.add_subparsers(title='subcommands', dest='subcommand')
|
||||||
|
|
||||||
|
application_base_parser = argparse.ArgumentParser(add_help=False)
|
||||||
|
application_base_parser.add_argument('--application', '-a', required=True)
|
||||||
|
|
||||||
|
application_list_parser = application_subparsers.add_parser('list')
|
||||||
|
application_list_parser.add_argument('--code', '-c')
|
||||||
|
|
||||||
|
application_show_parser = application_subparsers.add_parser('show', parents=[application_base_parser])
|
||||||
|
|
||||||
|
application_install_parser = application_subparsers.add_parser('install', parents=[application_base_parser])
|
||||||
|
application_install_parser.add_argument('--reinstall', '-r', action='store_true')
|
||||||
|
|
||||||
|
application_uninstall_parser = application_subparsers.add_parser('uninstall', parents=[application_base_parser])
|
||||||
|
|
||||||
|
policy_parser = main_subparsers.add_parser('policy')
|
||||||
|
policy_subparsers = policy_parser.add_subparsers(title='subcommands', dest='subcommand')
|
||||||
|
|
||||||
|
policy_base_parser = argparse.ArgumentParser(add_help=False)
|
||||||
|
policy_base_parser.add_argument('--policy', '-p', choices=['capability', 'privilege'], required=True)
|
||||||
|
|
||||||
|
policy_preview_parser = policy_subparsers.add_parser('preview', parents=[policy_base_parser])
|
||||||
|
policy_instate_parser = policy_subparsers.add_parser('instate', parents=[policy_base_parser])
|
||||||
|
policy_inspect_parser = policy_subparsers.add_parser('inspect', parents=[policy_base_parser])
|
||||||
|
policy_revoke_parser = policy_subparsers.add_parser('revoke', parents=[policy_base_parser])
|
||||||
|
|
||||||
|
get_parser = main_subparsers.add_parser('get')
|
||||||
|
get_subparsers = get_parser.add_subparsers(title='subcommands', dest='subcommand')
|
||||||
|
|
||||||
|
get_connection_parser = get_subparsers.add_parser('connection')
|
||||||
|
get_endpoint_verification_parser = get_subparsers.add_parser('endpoint_verification')
|
||||||
|
|
||||||
|
set_parser = main_subparsers.add_parser('set')
|
||||||
|
set_subparsers = set_parser.add_subparsers(title='subcommands', dest='subcommand')
|
||||||
|
|
||||||
|
set_connection_parser = set_subparsers.add_parser('connection')
|
||||||
|
set_connection_parser.add_argument('connection_type', choices=['system', 'tor'])
|
||||||
|
|
||||||
|
set_endpoint_verification_parser = set_subparsers.add_parser('endpoint_verification')
|
||||||
|
set_endpoint_verification_parser.add_argument('endpoint_verification_state', choices=['enabled', 'disabled'])
|
||||||
|
|
||||||
|
sync_parser = main_subparsers.add_parser('sync')
|
||||||
|
|
||||||
|
update_parser = main_subparsers.add_parser('update')
|
||||||
|
|
||||||
|
arguments = main_parser.parse_args()
|
||||||
|
|
||||||
|
ignore = []
|
||||||
|
|
||||||
|
if getattr(arguments, 'without_connection_protection', False):
|
||||||
|
ignore.append(ConnectionUnprotectedError)
|
||||||
|
|
||||||
|
if getattr(arguments, 'without_endpoint_verification', False):
|
||||||
|
ignore.append(EndpointVerificationError)
|
||||||
|
|
||||||
|
if getattr(arguments, 'without_profile_state_protection', False):
|
||||||
|
ignore.append(ProfileStateConflictError)
|
||||||
|
|
||||||
|
ignore = tuple(ignore)
|
||||||
|
|
||||||
|
if arguments.command is None:
|
||||||
|
main_parser.print_help()
|
||||||
|
|
||||||
|
elif arguments.command == 'profile':
|
||||||
|
|
||||||
|
if arguments.subcommand is None:
|
||||||
|
profile_parser.print_help()
|
||||||
|
|
||||||
|
elif arguments.subcommand == 'list':
|
||||||
|
|
||||||
|
profiles = ProfileController.get_all()
|
||||||
|
|
||||||
|
for key, value in profiles.items():
|
||||||
|
profiles[key] = __sanitize_profile(value)
|
||||||
|
|
||||||
|
pprint.pp(profiles)
|
||||||
|
|
||||||
|
elif arguments.subcommand == 'show':
|
||||||
|
pprint.pp(ProfileController.get(arguments.id))
|
||||||
|
|
||||||
|
elif arguments.subcommand == 'create':
|
||||||
|
|
||||||
|
location_details = __parse_location_argument(arguments.location)
|
||||||
|
location = LocationController.get(location_details.get('country_code'), location_details.get('code'))
|
||||||
|
|
||||||
|
if location is None:
|
||||||
|
main_parser.error('the following argument should be a valid reference: --location/-l')
|
||||||
|
|
||||||
|
if arguments.profile_type == 'session':
|
||||||
|
|
||||||
|
application_version_details = __parse_application_argument(arguments.application)
|
||||||
|
application_version = ApplicationVersionController.get(application_version_details.get('application_code'), application_version_details.get('version_number'))
|
||||||
|
|
||||||
|
if application_version is None:
|
||||||
|
main_parser.error('the following argument should be a valid reference: --application/-a')
|
||||||
|
|
||||||
|
connection = SessionConnection(arguments.connection_type, arguments.mask_connection)
|
||||||
|
profile = SessionProfile(arguments.id, arguments.name, None, location, arguments.resolution, application_version, connection)
|
||||||
|
ProfileController.create(profile, profile_observer=profile_observer)
|
||||||
|
|
||||||
|
else:
|
||||||
|
|
||||||
|
connection = SystemConnection(arguments.connection_type)
|
||||||
|
profile = SystemProfile(arguments.id, arguments.name, None, location, connection)
|
||||||
|
ProfileController.create(profile, profile_observer=profile_observer)
|
||||||
|
|
||||||
|
elif arguments.subcommand == 'destroy':
|
||||||
|
|
||||||
|
profile = ProfileController.get(arguments.id)
|
||||||
|
|
||||||
|
if profile is not None:
|
||||||
|
ProfileController.destroy(profile, profile_observer=profile_observer)
|
||||||
|
|
||||||
|
else:
|
||||||
|
main_parser.error('the following argument should be a valid reference: --id/-i')
|
||||||
|
|
||||||
|
elif arguments.subcommand == 'enable':
|
||||||
|
|
||||||
|
profile = ProfileController.get(arguments.id)
|
||||||
|
|
||||||
|
if profile is not None:
|
||||||
|
|
||||||
|
try:
|
||||||
|
ProfileController.enable(profile, ignore=ignore, pristine=arguments.pristine, asynchronous=True, profile_observer=profile_observer, application_version_observer=application_version_observer, connection_observer=connection_observer)
|
||||||
|
|
||||||
|
except (InvalidSubscriptionError, MissingSubscriptionError) as exception:
|
||||||
|
|
||||||
|
if type(exception).__name__ == 'InvalidSubscriptionError':
|
||||||
|
print('The profile\'s subscription appears to be invalid.\n')
|
||||||
|
|
||||||
|
elif type(exception).__name__ == 'MissingSubscriptionError':
|
||||||
|
print('The profile is not tied to a subscription.\n')
|
||||||
|
|
||||||
|
manage_subscription_input = None
|
||||||
|
|
||||||
|
while manage_subscription_input not in ('1', '2', '3', ''):
|
||||||
|
|
||||||
|
print('Please select from the following:\n')
|
||||||
|
|
||||||
|
print(' 1) Request new subscription')
|
||||||
|
print(' 2) Enter billing code')
|
||||||
|
|
||||||
|
print('\n 3) Exit')
|
||||||
|
|
||||||
|
manage_subscription_input = input('\nEnter your choice [1]: ')
|
||||||
|
|
||||||
|
if manage_subscription_input == '1' or manage_subscription_input == '':
|
||||||
|
|
||||||
|
print('\nCreating subscription...\n')
|
||||||
|
|
||||||
|
subscription_plan = SubscriptionPlanController.get(profile.connection, 720)
|
||||||
|
|
||||||
|
if subscription_plan is None:
|
||||||
|
raise RuntimeError('No compatible subscription plan was found. Please contact support.')
|
||||||
|
|
||||||
|
potential_subscription = SubscriptionController.create(subscription_plan, profile, connection_observer=connection_observer)
|
||||||
|
|
||||||
|
if potential_subscription is not None:
|
||||||
|
ProfileController.attach_subscription(profile, potential_subscription)
|
||||||
|
|
||||||
|
else:
|
||||||
|
raise RuntimeError('The subscription could not be created. Please try again later.')
|
||||||
|
|
||||||
|
subscription = InvoiceController.handle_payment(potential_subscription.billing_code, invoice_observer=invoice_observer, connection_observer=connection_observer)
|
||||||
|
|
||||||
|
if subscription is not None:
|
||||||
|
ProfileController.attach_subscription(profile, subscription)
|
||||||
|
|
||||||
|
else:
|
||||||
|
raise RuntimeError('The subscription could not be activated. Please try again later.')
|
||||||
|
|
||||||
|
ProfileController.enable(profile, ignore=ignore, pristine=arguments.pristine, asynchronous=True, profile_observer=profile_observer, application_version_observer=application_version_observer, connection_observer=connection_observer)
|
||||||
|
|
||||||
|
elif manage_subscription_input == '2':
|
||||||
|
|
||||||
|
billing_code = input('\nEnter your billing code: ')
|
||||||
|
print()
|
||||||
|
|
||||||
|
subscription = SubscriptionController.get(billing_code, connection_observer=connection_observer)
|
||||||
|
|
||||||
|
if subscription is not None:
|
||||||
|
|
||||||
|
ProfileController.attach_subscription(profile, subscription)
|
||||||
|
ProfileController.enable(profile, ignore=ignore, pristine=arguments.pristine, asynchronous=True, profile_observer=profile_observer, application_version_observer=application_version_observer, connection_observer=connection_observer)
|
||||||
|
|
||||||
|
else:
|
||||||
|
|
||||||
|
print('\nThe billing code appears to be invalid.\n')
|
||||||
|
manage_subscription_input = None
|
||||||
|
|
||||||
|
elif manage_subscription_input == '3':
|
||||||
|
pass
|
||||||
|
|
||||||
|
else:
|
||||||
|
print('\nInput appears to be invalid. Please try again.\n')
|
||||||
|
|
||||||
|
else:
|
||||||
|
main_parser.error('the following argument should be a valid reference: --id/-i')
|
||||||
|
|
||||||
|
elif arguments.subcommand == 'disable':
|
||||||
|
|
||||||
|
profile = ProfileController.get(arguments.id)
|
||||||
|
|
||||||
|
if profile is not None:
|
||||||
|
ProfileController.disable(profile, ignore=ignore, profile_observer=profile_observer)
|
||||||
|
else:
|
||||||
|
main_parser.error('the following argument should be a valid reference: --id/-i')
|
||||||
|
|
||||||
|
elif arguments.command == 'application':
|
||||||
|
|
||||||
|
if arguments.subcommand is None:
|
||||||
|
application_parser.print_help()
|
||||||
|
|
||||||
|
elif arguments.subcommand == 'list':
|
||||||
|
|
||||||
|
if arguments.code:
|
||||||
|
|
||||||
|
application = Application.find(arguments.code)
|
||||||
|
|
||||||
|
if application is not None:
|
||||||
|
pprint.pp(ApplicationVersionController.get_all(application))
|
||||||
|
else:
|
||||||
|
main_parser.error('the following argument should be a valid reference: --code/-c')
|
||||||
|
|
||||||
|
else:
|
||||||
|
pprint.pp(ApplicationVersionController.get_all())
|
||||||
|
|
||||||
|
elif arguments.subcommand == 'show':
|
||||||
|
|
||||||
|
application_version_details = __parse_application_argument(arguments.application)
|
||||||
|
application_version = ApplicationVersionController.get(application_version_details.get('application_code'), application_version_details.get('version_number'))
|
||||||
|
|
||||||
|
if application_version is not None:
|
||||||
|
pprint.pp(application_version)
|
||||||
|
else:
|
||||||
|
main_parser.error('the following argument should be a valid reference: --application/-a')
|
||||||
|
|
||||||
|
elif arguments.subcommand == 'install':
|
||||||
|
|
||||||
|
application_version_details = __parse_application_argument(arguments.application)
|
||||||
|
application_version = ApplicationVersionController.get(application_version_details.get('application_code'), application_version_details.get('version_number'))
|
||||||
|
|
||||||
|
if application_version is not None:
|
||||||
|
ApplicationVersionController.install(application_version, arguments.reinstall, application_version_observer=application_version_observer, connection_observer=connection_observer)
|
||||||
|
else:
|
||||||
|
main_parser.error('the following argument should be a valid reference: --application/-a')
|
||||||
|
|
||||||
|
elif arguments.subcommand == 'uninstall':
|
||||||
|
|
||||||
|
application_version_details = __parse_application_argument(arguments.application)
|
||||||
|
application_version = ApplicationVersionController.get(application_version_details.get('application_code'), application_version_details.get('version_number'))
|
||||||
|
|
||||||
|
if application_version is not None:
|
||||||
|
ApplicationVersionController.uninstall(application_version)
|
||||||
|
else:
|
||||||
|
main_parser.error('the following argument should be a valid reference: --application/-a')
|
||||||
|
|
||||||
|
elif arguments.command == 'policy':
|
||||||
|
|
||||||
|
if arguments.subcommand is None:
|
||||||
|
policy_parser.print_help()
|
||||||
|
|
||||||
|
else:
|
||||||
|
|
||||||
|
policy = PolicyController.get(arguments.policy)
|
||||||
|
|
||||||
|
if policy is not None:
|
||||||
|
|
||||||
|
if arguments.subcommand == 'preview':
|
||||||
|
print(PolicyController.preview(policy))
|
||||||
|
|
||||||
|
elif arguments.subcommand == 'instate':
|
||||||
|
PolicyController.instate(policy)
|
||||||
|
|
||||||
|
elif arguments.subcommand == 'inspect':
|
||||||
|
|
||||||
|
if PolicyController.is_instated(policy):
|
||||||
|
pprint.pp({'status': 'Instated'})
|
||||||
|
|
||||||
|
elif PolicyController.is_suggestible(policy):
|
||||||
|
pprint.pp({'status': 'Suggested'})
|
||||||
|
|
||||||
|
else:
|
||||||
|
pprint.pp({'status': 'Uninstated'})
|
||||||
|
|
||||||
|
elif arguments.subcommand == 'revoke':
|
||||||
|
PolicyController.revoke(policy)
|
||||||
|
|
||||||
|
elif arguments.command == 'get':
|
||||||
|
|
||||||
|
if arguments.subcommand is None:
|
||||||
|
get_parser.print_help()
|
||||||
|
|
||||||
|
elif arguments.subcommand == 'connection':
|
||||||
|
print(ConfigurationController.get_connection())
|
||||||
|
|
||||||
|
elif arguments.subcommand == 'endpoint_verification':
|
||||||
|
|
||||||
|
if ConfigurationController.get_endpoint_verification_enabled():
|
||||||
|
print('enabled')
|
||||||
|
else:
|
||||||
|
print('disabled')
|
||||||
|
|
||||||
|
elif arguments.command == 'set':
|
||||||
|
|
||||||
|
if arguments.subcommand is None:
|
||||||
|
set_parser.print_help()
|
||||||
|
|
||||||
|
elif arguments.subcommand == 'connection':
|
||||||
|
ConfigurationController.set_connection(arguments.connection_type)
|
||||||
|
|
||||||
|
elif arguments.subcommand == 'endpoint_verification':
|
||||||
|
|
||||||
|
if arguments.endpoint_verification_state == 'enabled':
|
||||||
|
ConfigurationController.set_endpoint_verification_enabled(True)
|
||||||
|
elif arguments.endpoint_verification_state == 'disabled':
|
||||||
|
ConfigurationController.set_endpoint_verification_enabled(False)
|
||||||
|
|
||||||
|
elif arguments.command == 'sync':
|
||||||
|
ClientController.sync(client_observer=client_observer, connection_observer=connection_observer)
|
||||||
|
|
||||||
|
elif arguments.command == 'update':
|
||||||
|
|
||||||
|
client_version = ClientController.get_version()
|
||||||
|
|
||||||
|
if ClientVersionController.is_latest(client_version):
|
||||||
|
print('The client is already up to date.\n')
|
||||||
|
|
||||||
|
ClientController.update(client_observer=client_observer, connection_observer=connection_observer)
|
||||||
|
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
from cli.commands import profile
|
|
||||||
from cli.commands import application
|
|
||||||
from cli.commands import policy
|
|
||||||
from cli.commands import get_set
|
|
||||||
from cli.commands import sync_update
|
|
||||||
import importlib
|
|
||||||
operator_command = importlib.import_module('cli.commands.operator')
|
|
||||||
|
|
||||||
all_commands = [profile, application, operator_command, policy, get_set, sync_update]
|
|
||||||
|
|
@ -1,73 +0,0 @@
|
||||||
from core.controllers.ApplicationVersionController import ApplicationVersionController
|
|
||||||
from core.models.session.Application import Application
|
|
||||||
from cli.helpers import parse_application_argument
|
|
||||||
from cli.observers import application_version_observer, connection_observer
|
|
||||||
import pprint
|
|
||||||
|
|
||||||
NAME = 'application'
|
|
||||||
|
|
||||||
|
|
||||||
def register(subparsers):
|
|
||||||
parser = subparsers.add_parser(NAME)
|
|
||||||
subs = parser.add_subparsers(title='subcommands', dest='subcommand')
|
|
||||||
|
|
||||||
base = _base_parser()
|
|
||||||
|
|
||||||
list_parser = subs.add_parser('list')
|
|
||||||
list_parser.add_argument('--code', '-c')
|
|
||||||
|
|
||||||
subs.add_parser('show', parents=[base])
|
|
||||||
|
|
||||||
install_parser = subs.add_parser('install', parents=[base])
|
|
||||||
install_parser.add_argument('--reinstall', '-r', action='store_true')
|
|
||||||
|
|
||||||
subs.add_parser('uninstall', parents=[base])
|
|
||||||
|
|
||||||
return parser
|
|
||||||
|
|
||||||
|
|
||||||
def handle(arguments, main_parser):
|
|
||||||
if arguments.subcommand is None:
|
|
||||||
main_parser.parse_args(['application', '--help'])
|
|
||||||
return
|
|
||||||
|
|
||||||
if arguments.subcommand == 'list':
|
|
||||||
if arguments.code:
|
|
||||||
application = Application.find(arguments.code)
|
|
||||||
if application is not None:
|
|
||||||
pprint.pp(ApplicationVersionController.get_all(application))
|
|
||||||
else:
|
|
||||||
main_parser.error('the following argument should be a valid reference: --code/-c')
|
|
||||||
else:
|
|
||||||
pprint.pp(ApplicationVersionController.get_all())
|
|
||||||
|
|
||||||
elif arguments.subcommand == 'show':
|
|
||||||
details = parse_application_argument(arguments.application)
|
|
||||||
app_version = ApplicationVersionController.get(details.get('application_code'), details.get('version_number'))
|
|
||||||
if app_version is not None:
|
|
||||||
pprint.pp(app_version)
|
|
||||||
else:
|
|
||||||
main_parser.error('the following argument should be a valid reference: --application/-a')
|
|
||||||
|
|
||||||
elif arguments.subcommand == 'install':
|
|
||||||
details = parse_application_argument(arguments.application)
|
|
||||||
app_version = ApplicationVersionController.get(details.get('application_code'), details.get('version_number'))
|
|
||||||
if app_version is not None:
|
|
||||||
ApplicationVersionController.install(app_version, arguments.reinstall, application_version_observer=application_version_observer, connection_observer=connection_observer)
|
|
||||||
else:
|
|
||||||
main_parser.error('the following argument should be a valid reference: --application/-a')
|
|
||||||
|
|
||||||
elif arguments.subcommand == 'uninstall':
|
|
||||||
details = parse_application_argument(arguments.application)
|
|
||||||
app_version = ApplicationVersionController.get(details.get('application_code'), details.get('version_number'))
|
|
||||||
if app_version is not None:
|
|
||||||
ApplicationVersionController.uninstall(app_version)
|
|
||||||
else:
|
|
||||||
main_parser.error('the following argument should be a valid reference: --application/-a')
|
|
||||||
|
|
||||||
|
|
||||||
def _base_parser():
|
|
||||||
import argparse
|
|
||||||
p = argparse.ArgumentParser(add_help=False)
|
|
||||||
p.add_argument('--application', '-a', required=True)
|
|
||||||
return p
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
from core.controllers.ConfigurationController import ConfigurationController
|
|
||||||
|
|
||||||
NAME = 'get'
|
|
||||||
NAME_SET = 'set'
|
|
||||||
|
|
||||||
|
|
||||||
def register(subparsers):
|
|
||||||
get_parser = subparsers.add_parser(NAME)
|
|
||||||
get_subs = get_parser.add_subparsers(title='subcommands', dest='subcommand')
|
|
||||||
get_subs.add_parser('connection')
|
|
||||||
get_subs.add_parser('endpoint_verification')
|
|
||||||
|
|
||||||
set_parser = subparsers.add_parser(NAME_SET)
|
|
||||||
set_subs = set_parser.add_subparsers(title='subcommands', dest='subcommand')
|
|
||||||
|
|
||||||
set_connection = set_subs.add_parser('connection')
|
|
||||||
set_connection.add_argument('connection_type', choices=['system', 'tor'])
|
|
||||||
|
|
||||||
set_endpoint = set_subs.add_parser('endpoint_verification')
|
|
||||||
set_endpoint.add_argument('endpoint_verification_state', choices=['enabled', 'disabled'])
|
|
||||||
|
|
||||||
return get_parser
|
|
||||||
|
|
||||||
|
|
||||||
def handle(arguments, main_parser):
|
|
||||||
if arguments.command == NAME:
|
|
||||||
if arguments.subcommand is None:
|
|
||||||
main_parser.parse_args(['get', '--help'])
|
|
||||||
elif arguments.subcommand == 'connection':
|
|
||||||
print(ConfigurationController.get_connection())
|
|
||||||
elif arguments.subcommand == 'endpoint_verification':
|
|
||||||
print('enabled' if ConfigurationController.get_endpoint_verification_enabled() else 'disabled')
|
|
||||||
|
|
||||||
elif arguments.command == NAME_SET:
|
|
||||||
if arguments.subcommand is None:
|
|
||||||
main_parser.parse_args(['set', '--help'])
|
|
||||||
elif arguments.subcommand == 'connection':
|
|
||||||
ConfigurationController.set_connection(arguments.connection_type)
|
|
||||||
elif arguments.subcommand == 'endpoint_verification':
|
|
||||||
ConfigurationController.set_endpoint_verification_enabled(arguments.endpoint_verification_state == 'enabled')
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
from core.controllers.OperatorController import OperatorController
|
|
||||||
import pprint
|
|
||||||
|
|
||||||
NAME = 'operator'
|
|
||||||
|
|
||||||
|
|
||||||
def register(subparsers):
|
|
||||||
parser = subparsers.add_parser(NAME)
|
|
||||||
subs = parser.add_subparsers(title='subcommands', dest='subcommand')
|
|
||||||
|
|
||||||
subs.add_parser('list')
|
|
||||||
|
|
||||||
show_parser = subs.add_parser('show')
|
|
||||||
show_parser.add_argument('--id', '-i', type=int, required=True)
|
|
||||||
|
|
||||||
return parser
|
|
||||||
|
|
||||||
|
|
||||||
def handle(arguments, main_parser):
|
|
||||||
if arguments.subcommand is None:
|
|
||||||
main_parser.parse_args(['operator', '--help'])
|
|
||||||
return
|
|
||||||
|
|
||||||
if arguments.subcommand == 'list':
|
|
||||||
pprint.pp(OperatorController.get_all())
|
|
||||||
|
|
||||||
elif arguments.subcommand == 'show':
|
|
||||||
operator = OperatorController.get(arguments.id)
|
|
||||||
if operator is not None:
|
|
||||||
pprint.pp(operator)
|
|
||||||
else:
|
|
||||||
main_parser.error('the following argument should be a valid reference: --id/-i')
|
|
||||||
|
|
@ -1,53 +0,0 @@
|
||||||
from core.controllers.PolicyController import PolicyController
|
|
||||||
import pprint
|
|
||||||
|
|
||||||
NAME = 'policy'
|
|
||||||
|
|
||||||
|
|
||||||
def register(subparsers):
|
|
||||||
parser = subparsers.add_parser(NAME)
|
|
||||||
subs = parser.add_subparsers(title='subcommands', dest='subcommand')
|
|
||||||
|
|
||||||
base = _base_parser()
|
|
||||||
|
|
||||||
subs.add_parser('preview', parents=[base])
|
|
||||||
subs.add_parser('instate', parents=[base])
|
|
||||||
subs.add_parser('inspect', parents=[base])
|
|
||||||
subs.add_parser('revoke', parents=[base])
|
|
||||||
|
|
||||||
return parser
|
|
||||||
|
|
||||||
|
|
||||||
def handle(arguments, main_parser):
|
|
||||||
if arguments.subcommand is None:
|
|
||||||
main_parser.parse_args(['policy', '--help'])
|
|
||||||
return
|
|
||||||
|
|
||||||
policy = PolicyController.get(arguments.policy)
|
|
||||||
|
|
||||||
if policy is None:
|
|
||||||
main_parser.error('the following argument should be a valid reference: --policy/-p')
|
|
||||||
|
|
||||||
if arguments.subcommand == 'preview':
|
|
||||||
print(PolicyController.preview(policy))
|
|
||||||
|
|
||||||
elif arguments.subcommand == 'instate':
|
|
||||||
PolicyController.instate(policy)
|
|
||||||
|
|
||||||
elif arguments.subcommand == 'inspect':
|
|
||||||
if PolicyController.is_instated(policy):
|
|
||||||
pprint.pp({'status': 'Instated'})
|
|
||||||
elif PolicyController.is_suggestible(policy):
|
|
||||||
pprint.pp({'status': 'Suggested'})
|
|
||||||
else:
|
|
||||||
pprint.pp({'status': 'Uninstated'})
|
|
||||||
|
|
||||||
elif arguments.subcommand == 'revoke':
|
|
||||||
PolicyController.revoke(policy)
|
|
||||||
|
|
||||||
|
|
||||||
def _base_parser():
|
|
||||||
import argparse
|
|
||||||
p = argparse.ArgumentParser(add_help=False)
|
|
||||||
p.add_argument('--policy', '-p', choices=['capability', 'privilege'], required=True)
|
|
||||||
return p
|
|
||||||
|
|
@ -1,201 +0,0 @@
|
||||||
from core.Errors import MissingSubscriptionError, InvalidSubscriptionError, ConnectionUnprotectedError, EndpointVerificationError, ProfileStateConflictError
|
|
||||||
from core.controllers.ApplicationVersionController import ApplicationVersionController
|
|
||||||
from core.controllers.InvoiceController import InvoiceController
|
|
||||||
from core.controllers.LocationController import LocationController
|
|
||||||
from core.controllers.ProfileController import ProfileController
|
|
||||||
from core.controllers.SubscriptionController import SubscriptionController
|
|
||||||
from core.controllers.SubscriptionPlanController import SubscriptionPlanController
|
|
||||||
from core.models.session.SessionConnection import SessionConnection
|
|
||||||
from core.models.session.SessionProfile import SessionProfile
|
|
||||||
from core.models.system.SystemConnection import SystemConnection
|
|
||||||
from core.models.system.SystemProfile import SystemProfile
|
|
||||||
from cli.helpers import sanitize_profile, parse_application_argument, parse_location_argument
|
|
||||||
from cli.observers import profile_observer, application_version_observer, connection_observer, invoice_observer
|
|
||||||
import pprint
|
|
||||||
|
|
||||||
NAME = 'profile'
|
|
||||||
|
|
||||||
|
|
||||||
def register(subparsers):
|
|
||||||
parser = subparsers.add_parser(NAME)
|
|
||||||
subs = parser.add_subparsers(title='subcommands', dest='subcommand')
|
|
||||||
|
|
||||||
base = _base_parser()
|
|
||||||
pristine = _pristine_parser()
|
|
||||||
connection_protection = _connection_protection_parser()
|
|
||||||
endpoint_verification = _endpoint_verification_parser()
|
|
||||||
profile_state_protection = _profile_state_protection_parser()
|
|
||||||
|
|
||||||
subs.add_parser('list')
|
|
||||||
subs.add_parser('show', parents=[base])
|
|
||||||
subs.add_parser('destroy', parents=[base])
|
|
||||||
subs.add_parser('enable', parents=[base, pristine, connection_protection, endpoint_verification, profile_state_protection])
|
|
||||||
subs.add_parser('disable', parents=[base, connection_protection])
|
|
||||||
|
|
||||||
create_parser = subs.add_parser('create')
|
|
||||||
create_subs = create_parser.add_subparsers(title='profile_types', dest='profile_type')
|
|
||||||
|
|
||||||
session_parser = create_subs.add_parser('session', parents=[base])
|
|
||||||
session_parser.add_argument('--name', '-n', default='')
|
|
||||||
session_parser.add_argument('--location', '-l', default='')
|
|
||||||
session_parser.add_argument('--application', '-a', required=True)
|
|
||||||
session_parser.add_argument('--connection', '-c', dest='connection_type', choices=['system', 'tor', 'wireguard'], default='system')
|
|
||||||
session_parser.add_argument('--mask-connection', '-m', action='store_true')
|
|
||||||
session_parser.add_argument('--resolution', '-r', default='1280x720')
|
|
||||||
|
|
||||||
system_parser = create_subs.add_parser('system', parents=[base])
|
|
||||||
system_parser.add_argument('--name', '-n', default='')
|
|
||||||
system_parser.add_argument('--location', '-l', default='')
|
|
||||||
system_parser.add_argument('--connection', '-c', dest='connection_type', choices=['wireguard'], default='wireguard')
|
|
||||||
|
|
||||||
return parser
|
|
||||||
|
|
||||||
|
|
||||||
def handle(arguments, main_parser):
|
|
||||||
if arguments.subcommand is None:
|
|
||||||
main_parser.parse_args(['profile', '--help'])
|
|
||||||
return
|
|
||||||
|
|
||||||
ignore = _build_ignore(arguments)
|
|
||||||
|
|
||||||
if arguments.subcommand == 'list':
|
|
||||||
profiles = ProfileController.get_all()
|
|
||||||
for key, value in profiles.items():
|
|
||||||
profiles[key] = sanitize_profile(value)
|
|
||||||
pprint.pp(profiles)
|
|
||||||
|
|
||||||
elif arguments.subcommand == 'show':
|
|
||||||
pprint.pp(ProfileController.get(arguments.id))
|
|
||||||
|
|
||||||
elif arguments.subcommand == 'create':
|
|
||||||
location_details = parse_location_argument(arguments.location)
|
|
||||||
location = LocationController.get(location_details.get('country_code'), location_details.get('code'))
|
|
||||||
|
|
||||||
if location is None:
|
|
||||||
main_parser.error('the following argument should be a valid reference: --location/-l')
|
|
||||||
|
|
||||||
if arguments.profile_type == 'session':
|
|
||||||
app_details = parse_application_argument(arguments.application)
|
|
||||||
app_version = ApplicationVersionController.get(app_details.get('application_code'), app_details.get('version_number'))
|
|
||||||
if app_version is None:
|
|
||||||
main_parser.error('the following argument should be a valid reference: --application/-a')
|
|
||||||
connection = SessionConnection(arguments.connection_type, arguments.mask_connection)
|
|
||||||
profile = SessionProfile(arguments.id, arguments.name, None, location, arguments.resolution, app_version, connection)
|
|
||||||
else:
|
|
||||||
connection = SystemConnection(arguments.connection_type)
|
|
||||||
profile = SystemProfile(arguments.id, arguments.name, None, location, connection)
|
|
||||||
|
|
||||||
ProfileController.create(profile, profile_observer=profile_observer)
|
|
||||||
|
|
||||||
elif arguments.subcommand == 'destroy':
|
|
||||||
profile = ProfileController.get(arguments.id)
|
|
||||||
if profile is not None:
|
|
||||||
ProfileController.destroy(profile, profile_observer=profile_observer)
|
|
||||||
else:
|
|
||||||
main_parser.error('the following argument should be a valid reference: --id/-i')
|
|
||||||
|
|
||||||
elif arguments.subcommand == 'enable':
|
|
||||||
profile = ProfileController.get(arguments.id)
|
|
||||||
if profile is None:
|
|
||||||
main_parser.error('the following argument should be a valid reference: --id/-i')
|
|
||||||
try:
|
|
||||||
ProfileController.enable(profile, ignore=ignore, pristine=arguments.pristine, asynchronous=True, profile_observer=profile_observer, application_version_observer=application_version_observer, connection_observer=connection_observer)
|
|
||||||
except (InvalidSubscriptionError, MissingSubscriptionError) as exception:
|
|
||||||
_handle_subscription_error(exception, profile, ignore, arguments, main_parser)
|
|
||||||
|
|
||||||
elif arguments.subcommand == 'disable':
|
|
||||||
profile = ProfileController.get(arguments.id)
|
|
||||||
if profile is not None:
|
|
||||||
ProfileController.disable(profile, ignore=ignore, profile_observer=profile_observer)
|
|
||||||
else:
|
|
||||||
main_parser.error('the following argument should be a valid reference: --id/-i')
|
|
||||||
|
|
||||||
|
|
||||||
def _handle_subscription_error(exception, profile, ignore, arguments, main_parser):
|
|
||||||
if type(exception).__name__ == 'InvalidSubscriptionError':
|
|
||||||
print('The profile\'s subscription appears to be invalid.\n')
|
|
||||||
elif type(exception).__name__ == 'MissingSubscriptionError':
|
|
||||||
print('The profile is not tied to a subscription.\n')
|
|
||||||
|
|
||||||
manage_subscription_input = None
|
|
||||||
|
|
||||||
while manage_subscription_input not in ('1', '2', '3', ''):
|
|
||||||
print('Please select from the following:\n')
|
|
||||||
print(' 1) Request new subscription')
|
|
||||||
print(' 2) Enter billing code')
|
|
||||||
print('\n 3) Exit')
|
|
||||||
|
|
||||||
manage_subscription_input = input('\nEnter your choice [1]: ')
|
|
||||||
|
|
||||||
if manage_subscription_input in ('1', ''):
|
|
||||||
print('\nCreating subscription...\n')
|
|
||||||
subscription_plan = SubscriptionPlanController.get(profile.connection, 720)
|
|
||||||
if subscription_plan is None:
|
|
||||||
raise RuntimeError('No compatible subscription plan was found. Please contact support.')
|
|
||||||
potential_subscription = SubscriptionController.create(subscription_plan, profile, connection_observer=connection_observer)
|
|
||||||
if potential_subscription is None:
|
|
||||||
raise RuntimeError('The subscription could not be created. Please try again later.')
|
|
||||||
ProfileController.attach_subscription(profile, potential_subscription)
|
|
||||||
subscription = InvoiceController.handle_payment(potential_subscription.billing_code, invoice_observer=invoice_observer, connection_observer=connection_observer)
|
|
||||||
if subscription is None:
|
|
||||||
raise RuntimeError('The subscription could not be activated. Please try again later.')
|
|
||||||
ProfileController.attach_subscription(profile, subscription)
|
|
||||||
ProfileController.enable(profile, ignore=ignore, pristine=arguments.pristine, asynchronous=True, profile_observer=profile_observer, application_version_observer=application_version_observer, connection_observer=connection_observer)
|
|
||||||
|
|
||||||
elif manage_subscription_input == '2':
|
|
||||||
billing_code = input('\nEnter your billing code: ')
|
|
||||||
print()
|
|
||||||
subscription = SubscriptionController.get(billing_code, connection_observer=connection_observer)
|
|
||||||
if subscription is not None:
|
|
||||||
ProfileController.attach_subscription(profile, subscription)
|
|
||||||
ProfileController.enable(profile, ignore=ignore, pristine=arguments.pristine, asynchronous=True, profile_observer=profile_observer, application_version_observer=application_version_observer, connection_observer=connection_observer)
|
|
||||||
else:
|
|
||||||
print('\nThe billing code appears to be invalid.\n')
|
|
||||||
manage_subscription_input = None
|
|
||||||
|
|
||||||
elif manage_subscription_input == '3':
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
print('\nInput appears to be invalid. Please try again.\n')
|
|
||||||
|
|
||||||
|
|
||||||
def _build_ignore(arguments):
|
|
||||||
ignore = []
|
|
||||||
if getattr(arguments, 'without_connection_protection', False):
|
|
||||||
ignore.append(ConnectionUnprotectedError)
|
|
||||||
if getattr(arguments, 'without_endpoint_verification', False):
|
|
||||||
ignore.append(EndpointVerificationError)
|
|
||||||
if getattr(arguments, 'without_profile_state_protection', False):
|
|
||||||
ignore.append(ProfileStateConflictError)
|
|
||||||
return tuple(ignore)
|
|
||||||
|
|
||||||
|
|
||||||
def _base_parser():
|
|
||||||
import argparse
|
|
||||||
p = argparse.ArgumentParser(add_help=False)
|
|
||||||
p.add_argument('--id', '-i', type=int, required=True)
|
|
||||||
return p
|
|
||||||
|
|
||||||
def _pristine_parser():
|
|
||||||
import argparse
|
|
||||||
p = argparse.ArgumentParser(add_help=False)
|
|
||||||
p.add_argument('--pristine', '-p', action='store_true')
|
|
||||||
return p
|
|
||||||
|
|
||||||
def _connection_protection_parser():
|
|
||||||
import argparse
|
|
||||||
p = argparse.ArgumentParser(add_help=False)
|
|
||||||
p.add_argument('--without-connection-protection', action='store_true')
|
|
||||||
return p
|
|
||||||
|
|
||||||
def _endpoint_verification_parser():
|
|
||||||
import argparse
|
|
||||||
p = argparse.ArgumentParser(add_help=False)
|
|
||||||
p.add_argument('--without-endpoint-verification', action='store_true')
|
|
||||||
return p
|
|
||||||
|
|
||||||
def _profile_state_protection_parser():
|
|
||||||
import argparse
|
|
||||||
p = argparse.ArgumentParser(add_help=False)
|
|
||||||
p.add_argument('--without-profile-state-protection', action='store_true')
|
|
||||||
return p
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
from core.controllers.ClientController import ClientController
|
|
||||||
from core.controllers.ClientVersionController import ClientVersionController
|
|
||||||
from cli.observers import client_observer, connection_observer
|
|
||||||
|
|
||||||
NAME_SYNC = 'sync'
|
|
||||||
NAME_UPDATE = 'update'
|
|
||||||
|
|
||||||
|
|
||||||
def register(subparsers):
|
|
||||||
subparsers.add_parser(NAME_SYNC)
|
|
||||||
subparsers.add_parser(NAME_UPDATE)
|
|
||||||
|
|
||||||
|
|
||||||
def handle(arguments, main_parser):
|
|
||||||
if arguments.command == NAME_SYNC:
|
|
||||||
ClientController.sync(client_observer=client_observer, connection_observer=connection_observer)
|
|
||||||
|
|
||||||
elif arguments.command == NAME_UPDATE:
|
|
||||||
client_version = ClientController.get_version()
|
|
||||||
if ClientVersionController.is_latest(client_version):
|
|
||||||
print('The client is already up to date.\n')
|
|
||||||
ClientController.update(client_observer=client_observer, connection_observer=connection_observer)
|
|
||||||
|
|
@ -1,33 +0,0 @@
|
||||||
from importlib import metadata
|
|
||||||
|
|
||||||
|
|
||||||
def sanitize_profile(candidate):
|
|
||||||
if candidate is not None and candidate.has_subscription():
|
|
||||||
candidate.subscription.billing_code = candidate.subscription.get_sanitized_billing_code()
|
|
||||||
return candidate
|
|
||||||
|
|
||||||
|
|
||||||
def get_distribution():
|
|
||||||
for candidate in metadata.distributions():
|
|
||||||
if 'cli' not in candidate.name:
|
|
||||||
continue
|
|
||||||
candidate_files = candidate.files
|
|
||||||
if candidate_files is None:
|
|
||||||
continue
|
|
||||||
has_source_files = any(f.parts[0] == 'cli' for f in candidate_files)
|
|
||||||
is_editable = any('direct_url.json' in str(f) for f in candidate_files)
|
|
||||||
if has_source_files or is_editable:
|
|
||||||
return candidate
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
def parse_composite_argument(argument: str, first_key: str, second_key: str, separator: str = ':'):
|
|
||||||
return dict(zip([first_key, second_key], argument.split(separator) + ['']))
|
|
||||||
|
|
||||||
|
|
||||||
def parse_application_argument(application_argument: str):
|
|
||||||
return parse_composite_argument(application_argument, 'application_code', 'version_number')
|
|
||||||
|
|
||||||
|
|
||||||
def parse_location_argument(location_argument: str):
|
|
||||||
return parse_composite_argument(location_argument, 'country_code', 'code')
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
||||||
from core.controllers.ApplicationController import ApplicationController
|
|
||||||
from core.observers.ApplicationVersionObserver import ApplicationVersionObserver
|
|
||||||
from core.observers.ClientObserver import ClientObserver
|
|
||||||
from core.observers.ConnectionObserver import ConnectionObserver
|
|
||||||
from core.observers.InvoiceObserver import InvoiceObserver
|
|
||||||
from core.observers.ProfileObserver import ProfileObserver
|
|
||||||
from cli.helpers import sanitize_profile
|
|
||||||
import pprint
|
|
||||||
|
|
||||||
application_version_observer = ApplicationVersionObserver()
|
|
||||||
client_observer = ClientObserver()
|
|
||||||
connection_observer = ConnectionObserver()
|
|
||||||
invoice_observer = InvoiceObserver()
|
|
||||||
profile_observer = ProfileObserver()
|
|
||||||
|
|
||||||
application_version_observer.subscribe('downloading', lambda event: print(f'Downloading {ApplicationController.get(event.subject.application_code).name}, version {event.subject.version_number}...'))
|
|
||||||
application_version_observer.subscribe('download_progressing', lambda event: print(f'Current progress: {event.meta.get("progress"):.2f}%', flush=True, end='\r'))
|
|
||||||
application_version_observer.subscribe('downloaded', lambda event: print('\n'))
|
|
||||||
|
|
||||||
client_observer.subscribe('synchronizing', lambda event: print('Synchronizing...\n'))
|
|
||||||
client_observer.subscribe('updating', lambda event: print('Updating client...'))
|
|
||||||
client_observer.subscribe('update_progressing', lambda event: print(f'Current progress: {event.meta.get("progress"):.2f}%', flush=True, end='\r'))
|
|
||||||
client_observer.subscribe('updated', lambda event: print('\n'))
|
|
||||||
|
|
||||||
connection_observer.subscribe('connecting', lambda event: print(f'[{event.subject.get("attempt_count")}/{event.subject.get("maximum_number_of_attempts")}] Performing connection attempt...\n'))
|
|
||||||
connection_observer.subscribe('tor_bootstrapping', lambda event: print('Bootstrapping Tor...'))
|
|
||||||
connection_observer.subscribe('tor_bootstrap_progressing', lambda event: print(f'Current progress: {event.meta.get("progress"):.2f}%', flush=True, end='\r'))
|
|
||||||
connection_observer.subscribe('tor_bootstrapped', lambda event: print('\n'))
|
|
||||||
|
|
||||||
invoice_observer.subscribe('retrieved', lambda event: print(f'\n{pprint.pp(event.subject)}\n'))
|
|
||||||
invoice_observer.subscribe('processing', lambda event: print('A payment has been detected and is being verified...\n'))
|
|
||||||
invoice_observer.subscribe('settled', lambda event: print('The payment has been successfully verified.\n'))
|
|
||||||
|
|
||||||
profile_observer.subscribe('created', lambda event: pprint.pp((sanitize_profile(event.subject), 'Created')))
|
|
||||||
profile_observer.subscribe('destroyed', lambda event: pprint.pp((sanitize_profile(event.subject), 'Destroyed')))
|
|
||||||
profile_observer.subscribe('disabled', lambda event: pprint.pp((sanitize_profile(event.subject), 'Disabled')) if event.meta.get('explicitly') else None)
|
|
||||||
profile_observer.subscribe('enabled', lambda event: pprint.pp((sanitize_profile(event.subject), 'Enabled')))
|
|
||||||
|
|
@ -12,7 +12,7 @@ classifiers = [
|
||||||
"Operating System :: POSIX :: Linux",
|
"Operating System :: POSIX :: Linux",
|
||||||
]
|
]
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"sp-hydra-veil-core == 2.3.0",
|
"sp-hydra-veil-core == 2.2.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[project.urls]
|
[project.urls]
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue