Database Logistical Checks

This commit is contained in:
SimplifiedPrivacy 2026-07-14 20:55:42 -04:00
parent 33551a3b6b
commit 14693e1023

View file

@ -1,4 +1,149 @@
from core.Constants import Constants from core.Constants import Constants
from core.errors.logger import logger
from core.models.manage.session_management import init_session, get_session, close_session, create_ALL_tables, create_ONLY_db_version_table, get_path, does_it_exist, does_db_version_table_exist
from core.models.manage.version_check import check_database_compatibility, insert_new_version, get_custom_message
from core.services.helpers.manage_assets import assets_folder_setup
import os
import sys
# ============================================================================
# DISPLAY CHOICES AND RECOVERY UI
# ============================================================================
def recovery_dialog(custom_error, db_version_you_have):
"""This ends the app by forcing them to delete the database, move it, or just quit."""
print(custom_error)
print("""
1) Delete old database (won't harm existing profiles.)
2) Do nothing. Exit.
"""
)
try:
choice = int(input("Enter your choice (1 or 2):"))
except:
print("must enter a number")
sys.exit()
logger.info(f"[DB MANAGEMENT] From the database error options, the user picked {choice}")
if choice == 1:
if os.path.exists(database_path):
os.remove(database_path)
logger.info(f"[DB MANAGEMENT] Deleted the DB file at {database_path}")
logger.info(f"[DB MANAGEMENT] Closing the app gracefully, for them to reboot..")
sys.exit()
else:
logger.error(f"[DB MANAGEMENT] User opted to close the app WITHOUT wiping the database, even though they need to.")
sys.exit()
# ============================================================================
# ASSETS FOLDER
# ============================================================================
if not assets_folder_setup():
custom_error = "Unable to Setup your Assets Folder. Please create an assets directory at ~/.local/share/hydra-veil/assets"
print(custom_error)
sys.exit()
# ============================================================================
# INITIALIZE DATABASE
# ============================================================================
# Does the database exist?
system_path = get_path()
database_path = system_path / "storage.db"
main_db_exists = does_it_exist(database_path)
# Setup operations on the main DB which create it
init_session() # (engine, Session, _session all initialized from session_management)
session = get_session()
# does the version checker table exist?
version_table_exists = does_db_version_table_exist()
# are they upgrading from a legacy version?
# that would mean the table existed, but not the version table,
if not version_table_exists and main_db_exists:
logger.info(f"[DB MANAGEMENT] We are dealing with a legacy database, we need to transition the user.")
# shut down db connection
close_session()
# THEN DISPLAY CHOICES AND RECOVERY UI
custom_error = "Upgrade Time! We transitioned to a new Database format for new features! Please delete the old version and fetch the new public data (what locations, browsers, ect) This will NOT affect your profiles or browser sessions."
db_version_you_have = "Old System"
recovery_dialog(custom_error, db_version_you_have)
sys.exit()
# If they're still here, then if it's NOT a legacy version,
# and the new version table doesn't exist, then create it:
if not version_table_exists:
create_ONLY_db_version_table()
# ============================================================================
# COMPARE DB VERISONS
# ============================================================================
compatability_dict = check_database_compatibility(session)
reason = compatability_dict.get("reason", "error")
is_compatable = compatability_dict.get("result", False)
logger.info(f"[DB MANAGEMENT] The result of the check is {is_compatable} and the reason is {reason}")
# ============================================================================
# IF THE VERSIONS MATCH
# ============================================================================
if is_compatable:
made_tables = create_ALL_tables()
# SCREEN FAILED TABLES
if not made_tables:
custom_error = "Critical Failure with starting the models of the database."
logger.error(f"[DB MANAGEMENT] {custom_error}")
close_session()
choice = show_recovery_dialog({"message": custom_error, "db_version": 0, "status": "cant_make"})
logger.info(f"[DB MANAGEMENT] From the database error options, the user picked {choice}")
sys.exit()
# ASSUME TABLES CREATED
logger.info("[DB MANAGEMENT] Tables successfully made or initialized if pre-existing")
# UPDATE DATA
did_it_insert = insert_new_version(session, Constants.DB_VERSION_THIS_APP_WANTS)
if not did_it_insert:
logger.error(f"[DB MANAGEMENT] Critical Failure with updating/inserting the new DB version into the database.")
# Load GUI either way:
# If the user lacks a database, we want to force them to sync the new data, to avoid NoneType errors when enabling existing profiles,
if reason == "no_database":
logger.info(f"[DB MANAGEMENT] User had no database to begin with, so now we're entering GUI with sync on..")
force_sync = True
else:
logger.info(f"[DB MANAGEMENT] Launcher is now passing it off to launch the main GUI window WITHOUT force sync..")
force_sync = False
# ============================================================================
# but IF the versions do NOT match
# ============================================================================
else:
logger.error(f"[DB MANAGEMENT] The App is expecting a different DB version than the real database. The reason is {reason}")
db_version_you_have = compatability_dict.get("old_db_version", "Error getting the Version")
# WHAT IS THE REASON?
custom_error = get_custom_message(reason, compatability_dict)
# shut down db connection
close_session()
# THEN DISPLAY CHOICES AND RECOVERY UI
recovery_dialog(custom_error, db_version_you_have)
if force_sync:
print("You have to sync to avoid errors. Please run ./hydra-veil-x86_64.AppImage --cli sync")
# continue with old flow:
# from core.Constants import Constants
from core.Errors import MissingSubscriptionError, InvalidSubscriptionError, UnknownConnectionTypeError, ConnectionUnprotectedError, EndpointVerificationError, ProfileStateConflictError from core.Errors import MissingSubscriptionError, InvalidSubscriptionError, UnknownConnectionTypeError, ConnectionUnprotectedError, EndpointVerificationError, ProfileStateConflictError
from core.controllers.ApplicationController import ApplicationController from core.controllers.ApplicationController import ApplicationController
from core.controllers.ApplicationVersionController import ApplicationVersionController from core.controllers.ApplicationVersionController import ApplicationVersionController
@ -122,10 +267,18 @@ if __name__ == '__main__':
profile_state_protection_parser = argparse.ArgumentParser(add_help=False) profile_state_protection_parser = argparse.ArgumentParser(add_help=False)
profile_state_protection_parser.add_argument('--without-profile-state-protection', action='store_true') profile_state_protection_parser.add_argument('--without-profile-state-protection', action='store_true')
# Get the distribution object
distribution = metadata.distribution('sp-hydra-veil-cli')
main_parser = argparse.ArgumentParser(prog=distribution.name) main_parser = argparse.ArgumentParser(prog=distribution.name)
main_parser.add_argument('--version', '-v', action='version', version=f'{distribution.name} v{distribution.version}') main_parser.add_argument('--version', '-v', action='version',
version=f'{distribution.name} v{distribution.version}')
main_subparsers = main_parser.add_subparsers(title='commands', dest='command') main_subparsers = main_parser.add_subparsers(title='commands', dest='command')
# main_parser = argparse.ArgumentParser(prog=distribution.name)
# main_parser.add_argument('--version', '-v', action='version', version=f'{distribution.name} v{distribution.version}')
# main_subparsers = main_parser.add_subparsers(title='commands', dest='command')
profile_parser = main_subparsers.add_parser('profile') profile_parser = main_subparsers.add_parser('profile')
profile_subparsers = profile_parser.add_subparsers(title='subcommands', dest='subcommand') profile_subparsers = profile_parser.add_subparsers(title='subcommands', dest='subcommand')