Update file management-related logic
This commit is contained in:
parent
a0eba19b91
commit
0ab1ac4168
10 changed files with 28 additions and 40 deletions
19
core/Helpers.py
Normal file
19
core/Helpers.py
Normal 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)
|
||||||
|
|
@ -87,9 +87,7 @@ class ApplicationController:
|
||||||
Path(initialization_file_path).touch(exist_ok=True, mode=0o600 | stat.S_IEXEC)
|
Path(initialization_file_path).touch(exist_ok=True, mode=0o600 | stat.S_IEXEC)
|
||||||
|
|
||||||
with open(initialization_file_path, 'w') as initialization_file:
|
with open(initialization_file_path, 'w') as initialization_file:
|
||||||
|
|
||||||
initialization_file.write(initialization_file_contents)
|
initialization_file.write(initialization_file_contents)
|
||||||
initialization_file.close()
|
|
||||||
|
|
||||||
if asynchronous:
|
if asynchronous:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -99,14 +99,10 @@ class ApplicationVersionController:
|
||||||
raise FileIntegrityError('Application version file integrity could not be verified.')
|
raise FileIntegrityError('Application version file integrity could not be verified.')
|
||||||
|
|
||||||
with tarfile.open(fileobj=response_buffer, mode = 'r:gz') as tar_file:
|
with tarfile.open(fileobj=response_buffer, mode = 'r:gz') as tar_file:
|
||||||
|
|
||||||
tar_file.extractall(application_version.get_installation_path())
|
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:
|
with open(f'{application_version.get_installation_path()}/.sha3-512', 'w') as hash_file:
|
||||||
|
|
||||||
hash_file.write(f'{file_hash}\n')
|
hash_file.write(f'{file_hash}\n')
|
||||||
hash_file.close()
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise ConnectionError('The application version could not be downloaded.')
|
raise ConnectionError('The application version could not be downloaded.')
|
||||||
|
|
|
||||||
|
|
@ -340,9 +340,7 @@ class ConnectionController:
|
||||||
Path(wireproxy_configuration_file_path).touch(exist_ok=True, mode=0o600)
|
Path(wireproxy_configuration_file_path).touch(exist_ok=True, mode=0o600)
|
||||||
|
|
||||||
with open(wireproxy_configuration_file_path, 'w') as wireproxy_configuration_file:
|
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.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)
|
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)
|
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:
|
with open(proxychains_configuration_file_path, 'w') as proxychains_configuration_file:
|
||||||
|
|
||||||
proxychains_configuration_file.write(proxychains_configuration_file_contents)
|
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)
|
return subprocess.Popen(('proxychains4', '-f', proxychains_configuration_file_path, 'microsocks', '-p', str(proxy_port_number)), stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
from core.Constants import Constants
|
from core.Constants import Constants
|
||||||
|
from core.Helpers import write_atomically
|
||||||
from core.models.Location import Location
|
from core.models.Location import Location
|
||||||
from core.models.Subscription import Subscription
|
from core.models.Subscription import Subscription
|
||||||
from core.models.session.ApplicationVersion import ApplicationVersion
|
from core.models.session.ApplicationVersion import ApplicationVersion
|
||||||
from dataclasses import dataclass, field, asdict
|
from dataclasses import dataclass, field, asdict
|
||||||
from dataclasses_json import config, Exclude, dataclass_json
|
from dataclasses_json import config, Exclude, dataclass_json
|
||||||
from json import JSONDecodeError
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Optional, Self
|
from typing import Optional, Self
|
||||||
import json
|
import json
|
||||||
|
|
@ -59,11 +59,7 @@ class BaseProfile(ABC):
|
||||||
os.makedirs(self.get_data_path(), exist_ok=True)
|
os.makedirs(self.get_data_path(), exist_ok=True)
|
||||||
|
|
||||||
config_file_path = f'{self.get_config_path()}/config.json'
|
config_file_path = f'{self.get_config_path()}/config.json'
|
||||||
|
write_atomically(config_file_path, config_file_contents)
|
||||||
with open(config_file_path, 'w') as config_file:
|
|
||||||
|
|
||||||
config_file.write(config_file_contents)
|
|
||||||
config_file.close()
|
|
||||||
|
|
||||||
def delete_data(self):
|
def delete_data(self):
|
||||||
shutil.rmtree(self.get_data_path(), ignore_errors=True)
|
shutil.rmtree(self.get_data_path(), ignore_errors=True)
|
||||||
|
|
@ -160,7 +156,7 @@ class BaseProfile(ABC):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
profile = json.loads(config_file_contents)
|
profile = json.loads(config_file_contents)
|
||||||
except JSONDecodeError:
|
except ValueError:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
profile['id'] = id
|
profile['id'] = id
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
from core.Constants import Constants
|
from core.Constants import Constants
|
||||||
|
from core.Helpers import write_atomically
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
from dataclasses_json import dataclass_json, config
|
from dataclasses_json import dataclass_json, config
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from json import JSONDecodeError
|
|
||||||
from marshmallow import fields
|
from marshmallow import fields
|
||||||
from typing import Optional, Self
|
from typing import Optional, Self
|
||||||
from zoneinfo import ZoneInfo
|
from zoneinfo import ZoneInfo
|
||||||
|
|
@ -53,11 +53,7 @@ class Configuration:
|
||||||
os.makedirs(Constants.HV_CONFIG_HOME, exist_ok=True)
|
os.makedirs(Constants.HV_CONFIG_HOME, exist_ok=True)
|
||||||
|
|
||||||
config_file_path = f'{Constants.HV_CONFIG_HOME}/config.json'
|
config_file_path = f'{Constants.HV_CONFIG_HOME}/config.json'
|
||||||
|
write_atomically(config_file_path, config_file_contents)
|
||||||
with open(config_file_path, 'w') as config_file:
|
|
||||||
|
|
||||||
config_file.write(config_file_contents)
|
|
||||||
config_file.close()
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get():
|
def get():
|
||||||
|
|
@ -69,7 +65,7 @@ class Configuration:
|
||||||
|
|
||||||
try:
|
try:
|
||||||
configuration = json.loads(config_file_contents)
|
configuration = json.loads(config_file_contents)
|
||||||
except JSONDecodeError:
|
except ValueError:
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
# noinspection PyUnresolvedReferences
|
# noinspection PyUnresolvedReferences
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ from core.models.session.ApplicationVersion import ApplicationVersion
|
||||||
from core.models.session.ProxyConfiguration import ProxyConfiguration
|
from core.models.session.ProxyConfiguration import ProxyConfiguration
|
||||||
from core.models.session.SessionConnection import SessionConnection
|
from core.models.session.SessionConnection import SessionConnection
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from json import JSONDecodeError
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
import json
|
import json
|
||||||
|
|
@ -46,18 +45,14 @@ class SessionProfile(BaseProfile):
|
||||||
proxy_configuration_file_path = self.get_proxy_configuration_path()
|
proxy_configuration_file_path = self.get_proxy_configuration_path()
|
||||||
|
|
||||||
with open(proxy_configuration_file_path, 'w') as proxy_configuration_file:
|
with open(proxy_configuration_file_path, 'w') as proxy_configuration_file:
|
||||||
|
|
||||||
proxy_configuration_file.write(proxy_configuration_file_contents)
|
proxy_configuration_file.write(proxy_configuration_file_contents)
|
||||||
proxy_configuration_file.close()
|
|
||||||
|
|
||||||
def attach_wireguard_configuration(self, wireguard_configuration):
|
def attach_wireguard_configuration(self, wireguard_configuration):
|
||||||
|
|
||||||
wireguard_configuration_file_path = self.get_wireguard_configuration_path()
|
wireguard_configuration_file_path = self.get_wireguard_configuration_path()
|
||||||
|
|
||||||
with open(wireguard_configuration_file_path, 'w') as wireguard_configuration_file:
|
with open(wireguard_configuration_file_path, 'w') as wireguard_configuration_file:
|
||||||
|
|
||||||
wireguard_configuration_file.write(wireguard_configuration)
|
wireguard_configuration_file.write(wireguard_configuration)
|
||||||
wireguard_configuration_file.close()
|
|
||||||
|
|
||||||
def get_proxy_configuration_path(self):
|
def get_proxy_configuration_path(self):
|
||||||
return f'{self.get_config_path()}/proxy.json'
|
return f'{self.get_config_path()}/proxy.json'
|
||||||
|
|
@ -74,7 +69,7 @@ class SessionProfile(BaseProfile):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
proxy_configuration = json.loads(config_file_contents)
|
proxy_configuration = json.loads(config_file_contents)
|
||||||
except JSONDecodeError:
|
except ValueError:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
proxy_configuration = ProxyConfiguration.from_dict(proxy_configuration)
|
proxy_configuration = ProxyConfiguration.from_dict(proxy_configuration)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ from core.Constants import Constants
|
||||||
from core.models.session.NetworkPortNumbers import NetworkPortNumbers
|
from core.models.session.NetworkPortNumbers import NetworkPortNumbers
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
from dataclasses_json import config, Exclude, dataclass_json
|
from dataclasses_json import config, Exclude, dataclass_json
|
||||||
from json import JSONDecodeError
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Self
|
from typing import Self
|
||||||
import json
|
import json
|
||||||
|
|
@ -33,9 +32,7 @@ class SessionState:
|
||||||
Path(session_state_file_path).touch(exist_ok=True, mode=0o600)
|
Path(session_state_file_path).touch(exist_ok=True, mode=0o600)
|
||||||
|
|
||||||
with open(session_state_file_path, 'w') as session_state_file:
|
with open(session_state_file_path, 'w') as session_state_file:
|
||||||
|
|
||||||
session_state_file.write(session_state_file_contents)
|
session_state_file.write(session_state_file_contents)
|
||||||
session_state_file.close()
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def find_by_id(id: int):
|
def find_by_id(id: int):
|
||||||
|
|
@ -55,7 +52,7 @@ class SessionState:
|
||||||
# noinspection PyUnresolvedReferences
|
# noinspection PyUnresolvedReferences
|
||||||
return SessionState.from_dict(session_state)
|
return SessionState.from_dict(session_state)
|
||||||
|
|
||||||
except (JSONDecodeError, AttributeError):
|
except (ValueError, AttributeError):
|
||||||
|
|
||||||
shutil.rmtree(Path(state_path), ignore_errors=True)
|
shutil.rmtree(Path(state_path), ignore_errors=True)
|
||||||
return None
|
return None
|
||||||
|
|
|
||||||
|
|
@ -31,9 +31,7 @@ class SystemProfile(BaseProfile):
|
||||||
wireguard_configuration_file_backup_path = f'{self.get_config_path()}/wg.conf.bak'
|
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:
|
with open(wireguard_configuration_file_backup_path, 'w') as wireguard_configuration_file:
|
||||||
|
|
||||||
wireguard_configuration_file.write(wireguard_configuration)
|
wireguard_configuration_file.write(wireguard_configuration)
|
||||||
wireguard_configuration_file.close()
|
|
||||||
|
|
||||||
wireguard_configuration_is_attached = False
|
wireguard_configuration_is_attached = False
|
||||||
failed_attempt_count = 0
|
failed_attempt_count = 0
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
from core.Constants import Constants
|
from core.Constants import Constants
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from dataclasses_json import dataclass_json
|
from dataclasses_json import dataclass_json
|
||||||
from json import JSONDecodeError
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Self
|
from typing import Self
|
||||||
import json
|
import json
|
||||||
|
|
@ -22,9 +21,7 @@ class SystemState:
|
||||||
Path(system_state_file_path).touch(exist_ok=True, mode=0o600)
|
Path(system_state_file_path).touch(exist_ok=True, mode=0o600)
|
||||||
|
|
||||||
with open(system_state_file_path, 'w') as system_state_file:
|
with open(system_state_file_path, 'w') as system_state_file:
|
||||||
|
|
||||||
system_state_file.write(system_state_file_contents)
|
system_state_file.write(system_state_file_contents)
|
||||||
system_state_file.close()
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get():
|
def get():
|
||||||
|
|
@ -37,7 +34,7 @@ class SystemState:
|
||||||
# noinspection PyUnresolvedReferences
|
# noinspection PyUnresolvedReferences
|
||||||
return SystemState.from_dict(system_state_dict)
|
return SystemState.from_dict(system_state_dict)
|
||||||
|
|
||||||
except (FileNotFoundError, JSONDecodeError, KeyError):
|
except (FileNotFoundError, ValueError, KeyError):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue