from core.Constants import Constants from core.Errors import UnknownTimeZoneError from core.models.BaseProfile import BaseProfile from core.models.session.ApplicationVersion import ApplicationVersion from core.models.session.ProxyConfiguration import ProxyConfiguration from core.models.session.SessionConnection import SessionConnection from dataclasses import dataclass from json import JSONDecodeError from typing import Optional import json import os import re import shutil @dataclass class SessionProfile(BaseProfile): resolution: str application_version: Optional[ApplicationVersion] connection: Optional[SessionConnection] def has_connection(self): return self.connection is not None def save(self): if 'application_version' in self._get_dirty_keys(): persistent_state_path = f'{self.get_data_path()}/persistent-state' if os.path.isdir(persistent_state_path): shutil.rmtree(persistent_state_path, ignore_errors=True) super().save() def attach_proxy_configuration(self, proxy_configuration): proxy_configuration_file_contents = f'{proxy_configuration.to_json(indent=4)}\n' os.makedirs(Constants.HV_CONFIG_HOME, exist_ok=True) proxy_configuration_file_path = self.get_proxy_configuration_path() with open(proxy_configuration_file_path, 'w') as proxy_configuration_file: proxy_configuration_file.write(proxy_configuration_file_contents) proxy_configuration_file.close() def attach_wireguard_configuration(self, wireguard_configuration): wireguard_configuration_file_path = self.get_wireguard_configuration_path() with open(wireguard_configuration_file_path, 'w') as wireguard_configuration_file: wireguard_configuration_file.write(wireguard_configuration) wireguard_configuration_file.close() def get_proxy_configuration_path(self): return f'{self.get_config_path()}/proxy.json' def get_wireguard_configuration_path(self): return f'{self.get_config_path()}/wg.conf' def get_proxy_configuration(self): try: config_file_contents = open(self.get_proxy_configuration_path(), 'r').read() except FileNotFoundError: return None try: proxy_configuration = json.loads(config_file_contents) except JSONDecodeError: return None proxy_configuration = ProxyConfiguration.from_dict(proxy_configuration) return proxy_configuration def has_proxy_configuration(self): return os.path.isfile(f'{self.get_config_path()}/proxy.json') def has_wireguard_configuration(self): return os.path.isfile(f'{self.get_config_path()}/wg.conf') def determine_timezone(self): time_zone = None if self.has_connection(): if self.connection.needs_proxy_configuration(): if self.has_proxy_configuration(): time_zone = self.get_proxy_configuration().time_zone elif self.connection.needs_wireguard_configuration(): if self.has_wireguard_configuration(): time_zone = self.__get_wireguard_configuration_metadata('TZ') if time_zone is None and self.has_location(): time_zone = self.location.time_zone if time_zone is None: raise UnknownTimeZoneError('The preferred time zone could not be determined.') return time_zone def __get_wireguard_configuration(self): try: with open(self.get_wireguard_configuration_path(), 'r') as file: return file.readlines() except FileNotFoundError: return None def __get_wireguard_configuration_metadata(self, key): for line in self.__get_wireguard_configuration(): match = re.match(r'^# {} = (.*)$'.format(re.escape(key)), line) if match: return re.sub(r'[^a-zA-Z0-9+\-_ /]', '', match.group(1).strip())