Update file management-related logic

This commit is contained in:
codeking 2026-02-11 09:48:08 +01:00
parent a0eba19b91
commit 0ab1ac4168
10 changed files with 28 additions and 40 deletions

19
core/Helpers.py Normal file
View file

@ -0,0 +1,19 @@
import os
def write_atomically(file_path, contents):
staging_file_path = f'{file_path}~'
try:
with open(staging_file_path, 'w') as config_staging_file:
config_staging_file.write(contents)
config_staging_file.flush()
os.fsync(config_staging_file.fileno())
os.replace(staging_file_path, file_path)
finally:
if os.path.exists(staging_file_path):
os.remove(staging_file_path)

View file

@ -87,9 +87,7 @@ class ApplicationController:
Path(initialization_file_path).touch(exist_ok=True, mode=0o600 | stat.S_IEXEC)
with open(initialization_file_path, 'w') as initialization_file:
initialization_file.write(initialization_file_contents)
initialization_file.close()
if asynchronous:

View file

@ -99,14 +99,10 @@ class ApplicationVersionController:
raise FileIntegrityError('Application version file integrity could not be verified.')
with tarfile.open(fileobj=response_buffer, mode = 'r:gz') as tar_file:
tar_file.extractall(application_version.get_installation_path())
tar_file.close()
with open(f'{application_version.get_installation_path()}/.sha3-512', 'w') as hash_file:
hash_file.write(f'{file_hash}\n')
hash_file.close()
else:
raise ConnectionError('The application version could not be downloaded.')

View file

@ -340,9 +340,7 @@ class ConnectionController:
Path(wireproxy_configuration_file_path).touch(exist_ok=True, mode=0o600)
with open(wireproxy_configuration_file_path, 'w') as wireproxy_configuration_file:
wireproxy_configuration_file.write(f'WGConfig = {profile.get_wireguard_configuration_path()}\n\n[Socks5]\nBindAddress = 127.0.0.1:{str(port_number)}\n')
wireproxy_configuration_file.close()
return subprocess.Popen((f'{Constants.HV_RUNTIME_DATA_HOME}/wireproxy/wireproxy', '-c', wireproxy_configuration_file_path), stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)
@ -379,9 +377,7 @@ class ConnectionController:
proxychains_configuration_file_contents = proxychains_template_file.read().format(proxy_list=proxychains_proxy_list)
with open(proxychains_configuration_file_path, 'w') as proxychains_configuration_file:
proxychains_configuration_file.write(proxychains_configuration_file_contents)
proxychains_configuration_file.close()
return subprocess.Popen(('proxychains4', '-f', proxychains_configuration_file_path, 'microsocks', '-p', str(proxy_port_number)), stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)

View file

@ -1,11 +1,11 @@
from abc import ABC, abstractmethod
from core.Constants import Constants
from core.Helpers import write_atomically
from core.models.Location import Location
from core.models.Subscription import Subscription
from core.models.session.ApplicationVersion import ApplicationVersion
from dataclasses import dataclass, field, asdict
from dataclasses_json import config, Exclude, dataclass_json
from json import JSONDecodeError
from pathlib import Path
from typing import Optional, Self
import json
@ -59,11 +59,7 @@ class BaseProfile(ABC):
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()
write_atomically(config_file_path, config_file_contents)
def delete_data(self):
shutil.rmtree(self.get_data_path(), ignore_errors=True)
@ -160,7 +156,7 @@ class BaseProfile(ABC):
try:
profile = json.loads(config_file_contents)
except JSONDecodeError:
except ValueError:
return None
profile['id'] = id

View file

@ -1,8 +1,8 @@
from core.Constants import Constants
from core.Helpers import write_atomically
from dataclasses import dataclass, field
from dataclasses_json import dataclass_json, config
from datetime import datetime
from json import JSONDecodeError
from marshmallow import fields
from typing import Optional, Self
from zoneinfo import ZoneInfo
@ -53,11 +53,7 @@ class Configuration:
os.makedirs(Constants.HV_CONFIG_HOME, exist_ok=True)
config_file_path = f'{Constants.HV_CONFIG_HOME}/config.json'
with open(config_file_path, 'w') as config_file:
config_file.write(config_file_contents)
config_file.close()
write_atomically(config_file_path, config_file_contents)
@staticmethod
def get():
@ -69,7 +65,7 @@ class Configuration:
try:
configuration = json.loads(config_file_contents)
except JSONDecodeError:
except ValueError:
sys.exit(1)
# noinspection PyUnresolvedReferences

View file

@ -5,7 +5,6 @@ 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 pathlib import Path
from typing import Optional
import json
@ -46,18 +45,14 @@ class SessionProfile(BaseProfile):
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'
@ -74,7 +69,7 @@ class SessionProfile(BaseProfile):
try:
proxy_configuration = json.loads(config_file_contents)
except JSONDecodeError:
except ValueError:
return None
proxy_configuration = ProxyConfiguration.from_dict(proxy_configuration)

View file

@ -2,7 +2,6 @@ from core.Constants import Constants
from core.models.session.NetworkPortNumbers import NetworkPortNumbers
from dataclasses import dataclass, field
from dataclasses_json import config, Exclude, dataclass_json
from json import JSONDecodeError
from pathlib import Path
from typing import Self
import json
@ -33,9 +32,7 @@ class SessionState:
Path(session_state_file_path).touch(exist_ok=True, mode=0o600)
with open(session_state_file_path, 'w') as session_state_file:
session_state_file.write(session_state_file_contents)
session_state_file.close()
@staticmethod
def find_by_id(id: int):
@ -55,7 +52,7 @@ class SessionState:
# noinspection PyUnresolvedReferences
return SessionState.from_dict(session_state)
except (JSONDecodeError, AttributeError):
except (ValueError, AttributeError):
shutil.rmtree(Path(state_path), ignore_errors=True)
return None

View file

@ -31,9 +31,7 @@ class SystemProfile(BaseProfile):
wireguard_configuration_file_backup_path = f'{self.get_config_path()}/wg.conf.bak'
with open(wireguard_configuration_file_backup_path, 'w') as wireguard_configuration_file:
wireguard_configuration_file.write(wireguard_configuration)
wireguard_configuration_file.close()
wireguard_configuration_is_attached = False
failed_attempt_count = 0

View file

@ -1,7 +1,6 @@
from core.Constants import Constants
from dataclasses import dataclass
from dataclasses_json import dataclass_json
from json import JSONDecodeError
from pathlib import Path
from typing import Self
import json
@ -22,9 +21,7 @@ class SystemState:
Path(system_state_file_path).touch(exist_ok=True, mode=0o600)
with open(system_state_file_path, 'w') as system_state_file:
system_state_file.write(system_state_file_contents)
system_state_file.close()
@staticmethod
def get():
@ -37,7 +34,7 @@ class SystemState:
# noinspection PyUnresolvedReferences
return SystemState.from_dict(system_state_dict)
except (FileNotFoundError, JSONDecodeError, KeyError):
except (FileNotFoundError, ValueError, KeyError):
return None
@staticmethod