sp-hydra-veil-core/core/models/BaseProfile.py

150 lines
4.4 KiB
Python

from core.Constants import Constants
from core.models.Location import Location
from core.models.Subscription import Subscription
from core.models.session.ApplicationVersion import ApplicationVersion
from dataclasses import dataclass, field
from dataclasses_json import config, Exclude, dataclass_json
from json import JSONDecodeError
from typing import Optional
import json
import os
import re
import shutil
@dataclass_json
@dataclass
class BaseProfile:
id: int = field(
metadata=config(exclude=Exclude.ALWAYS)
)
name: str
subscription: Optional[Subscription]
location: Optional[Location]
def get_config_path(self):
return BaseProfile.__get_config_path(self.id)
def get_data_path(self):
return BaseProfile.__get_data_path(self.id)
def has_subscription(self):
return self.subscription is not None
def is_session_profile(self):
return type(self).__name__ == 'SessionProfile'
def is_system_profile(self):
return type(self).__name__ == 'SystemProfile'
def delete_data(self):
shutil.rmtree(BaseProfile.__get_data_path(self.id), ignore_errors=True)
def delete(self):
self._delete()
def _delete(self):
shutil.rmtree(BaseProfile.__get_config_path(self.id), ignore_errors=True)
self.delete_data()
@staticmethod
def find_by_id(id: int):
try:
config_file_contents = open(f'{BaseProfile.__get_config_path(id)}/config.json', 'r').read()
except FileNotFoundError:
return None
try:
profile = json.loads(config_file_contents)
except JSONDecodeError:
return None
profile['id'] = id
if profile['location'] is not None:
location = Location.find(profile['location']['code'] or None)
if location is not None:
if profile['location']['time_zone'] is not None:
location.time_zone = profile['location']['time_zone']
profile['location'] = location
if 'application_version' in profile:
if profile['application_version'] is not None:
application_version = ApplicationVersion.find(profile['application_version']['application_code'] or None, profile['application_version']['version_number'] or None)
if application_version is not None:
profile['application_version'] = application_version
from core.models.session.SessionProfile import SessionProfile
# noinspection PyUnresolvedReferences
profile = SessionProfile.from_dict(profile)
else:
from core.models.system.SystemProfile import SystemProfile
# noinspection PyUnresolvedReferences
profile = SystemProfile.from_dict(profile)
return profile
@staticmethod
def exists(id: int):
return re.match(r'^\d{1,2}$', str(id)) and os.path.isfile(f'{BaseProfile.__get_config_path(id)}/config.json')
@staticmethod
def all():
profiles = {}
for directory_entry in os.listdir(Constants.HV_PROFILE_CONFIG_HOME):
try:
id = int(directory_entry)
except ValueError:
continue
if BaseProfile.exists(id):
profile = BaseProfile.find_by_id(id)
if profile is not None:
profiles[id] = profile
return dict(sorted(profiles.items()))
@staticmethod
def save(profile):
if profile.is_session_profile() and profile.application_version is not None:
persistent_state_path = f'{BaseProfile.__get_data_path(profile.id)}/persistent-state'
if os.path.isdir(persistent_state_path):
shutil.rmtree(persistent_state_path, ignore_errors=True)
config_file_contents = f'{profile.to_json(indent=4)}\n'
os.makedirs(BaseProfile.__get_config_path(profile.id), exist_ok=True)
os.makedirs(BaseProfile.__get_data_path(profile.id), exist_ok=True)
config_file_path = f'{BaseProfile.__get_config_path(profile.id)}/config.json'
with open(config_file_path, 'w') as config_file:
config_file.write(config_file_contents)
config_file.close()
@staticmethod
def __get_config_path(id: int):
return f'{Constants.HV_PROFILE_CONFIG_HOME}/{str(id)}'
@staticmethod
def __get_data_path(id: int):
return f'{Constants.HV_PROFILE_DATA_HOME}/{str(id)}'