Add support for conditional persistent state preservation

This commit is contained in:
codeking 2025-03-12 02:11:44 +01:00
parent 43866a0807
commit 7f9c6ab1a9
4 changed files with 44 additions and 35 deletions

View file

@ -30,7 +30,7 @@ class ProfileController:
@staticmethod
def create(profile: Union[SessionProfile, SystemProfile], profile_observer: ProfileObserver = None):
Profile.save(profile)
profile.save()
if profile_observer is not None:
profile_observer.notify('created', profile)
@ -38,7 +38,7 @@ class ProfileController:
@staticmethod
def update(profile: Union[SessionProfile, SystemProfile], profile_observer: ProfileObserver = None):
Profile.save(profile)
profile.save()
if profile_observer is not None:
profile_observer.notify('updated', profile)
@ -136,7 +136,7 @@ class ProfileController:
def attach_subscription(profile: Union[SessionProfile, SystemProfile], subscription: Subscription):
profile.subscription = subscription
profile.save(profile)
profile.save()
@staticmethod
def activate_subscription(profile: Union[SessionProfile, SystemProfile], connection_observer: Optional[ConnectionObserver] = None):
@ -150,7 +150,7 @@ class ProfileController:
if subscription is not None:
profile.subscription = subscription
profile.save(profile)
profile.save()
else:
raise InvalidSubscriptionError()

View file

@ -2,10 +2,10 @@ 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 import dataclass, field, asdict
from dataclasses_json import config, Exclude, dataclass_json
from json import JSONDecodeError
from typing import Optional
from typing import Optional, Self
import json
import os
import re
@ -37,17 +37,36 @@ class BaseProfile:
def is_system_profile(self):
return type(self).__name__ == 'SystemProfile'
def save(self: Self):
config_file_contents = f'{self.to_json(indent=4)}\n'
os.makedirs(self.get_config_path(), exist_ok=True)
os.makedirs(self.get_data_path(), exist_ok=True)
config_file_path = f'{self.get_config_path()}/config.json'
with open(config_file_path, 'w') as config_file:
config_file.write(config_file_contents)
config_file.close()
def delete_data(self):
shutil.rmtree(BaseProfile.__get_data_path(self.id), ignore_errors=True)
shutil.rmtree(self.get_data_path(), ignore_errors=True)
def delete(self):
self._delete()
def _delete(self):
shutil.rmtree(BaseProfile.__get_config_path(self.id), ignore_errors=True)
shutil.rmtree(self.get_config_path(), ignore_errors=True)
self.delete_data()
def _get_dirty_keys(self: Self):
reference = BaseProfile.find_by_id(self.id)
if type(reference) != type(self):
return list(self.__dataclass_fields__.keys())
return list([key for key, value in asdict(self).items() if value != asdict(reference).get(key)])
@staticmethod
def find_by_id(id: int):
@ -119,28 +138,6 @@ class BaseProfile:
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)}'

View file

@ -8,6 +8,7 @@ from json import JSONDecodeError
from typing import Optional
import json
import os
import shutil
@dataclass
@ -16,6 +17,17 @@ class SessionProfile(BaseProfile):
application_version: Optional[ApplicationVersion]
connection: Optional[SessionConnection]
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'

View file

@ -61,7 +61,7 @@ class SystemProfile(BaseProfile):
if not completed_successfully:
raise ProfileDeletionError('The profile could not be deleted.')
self._delete()
super().delete()
@staticmethod
def __get_system_config_path(id: int):