forked from Support/sp-hydra-veil-gui
205 lines
9.1 KiB
Python
205 lines
9.1 KiB
Python
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
|
|
from core.Constants import Constants
|
|
from core.models.DatabaseOperation import DatabaseOperation, DBErrorType
|
|
from core.models.manage.migrations import migrate_sql
|
|
from core.models.manage.clear_sql_model import clear_sql_model
|
|
|
|
# generic
|
|
import os
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
|
|
# ============================================================================
|
|
# UTIL FUNCTIONS AND RECOVERY UI
|
|
# ============================================================================
|
|
def clear_sync_cache():
|
|
"""
|
|
Purpose:
|
|
Clear CachedSync
|
|
If that fails, prompt for a database wipe.
|
|
|
|
Why:
|
|
If they migrated, they have new schemas, but old data.
|
|
The problem with that, is the newest CachedSync entry will fool the sync data functions into thinking they don't need to sync new data,
|
|
Even though they do need to sync with the new schema.
|
|
"""
|
|
from core.models.orm_models.CachedSync import CachedSync
|
|
result = clear_sql_model(CachedSync)
|
|
if result:
|
|
logger.info(f"[DB MANAGEMENT] After Migration cleared the CachedSync table: {result}.")
|
|
else:
|
|
custom_error = "There were issues with clearing the Sync Cache in your database. Please delete the old version and fetch the new public data (what locations, browsers, ect) This will NOT affect your profiles or browser sessions."
|
|
recovery_dialog(custom_error, "CachedSync Issue")
|
|
|
|
def failed_migration(db_version_you_have):
|
|
close_session() # shut down db connection
|
|
custom_error = "There were issues with migrating your database. 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."
|
|
recovery_dialog(custom_error, db_version_you_have)
|
|
|
|
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."""
|
|
|
|
from gui.v2.ui.popups.Database_version import show_recovery_dialog
|
|
choice = show_recovery_dialog({"message": custom_error, "db_version": db_version_you_have, "status": "version_mismatch"})
|
|
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}. Now putting lock on for forced sync..")
|
|
lock_file.touch()
|
|
logger.info(f"[DB MANAGEMENT] Closing the app gracefully, for them to reboot..")
|
|
sys.exit()
|
|
|
|
elif choice == 2:
|
|
logger.info(f"[DB MANAGEMENT] User opted to move the DB file.")
|
|
from gui.v2.ui.popups.pick_folder_to_move import launch_file_picker
|
|
launch_file_picker(database_path)
|
|
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
|
|
# ============================================================================
|
|
logger.info("Welcome, checking assets..")
|
|
if not assets_folder_setup():
|
|
from gui.v2.ui.popups.generic_error_popup import show_error
|
|
custom_error = "Unable to Setup your Assets Folder. Please create an assets directory at ~/.local/share/hydra-veil/assets"
|
|
show_error(custom_error, "Critical Error")
|
|
|
|
# ============================================================================
|
|
# INITIALIZE DATABASE
|
|
# ============================================================================
|
|
lock_file = Path(f"{Constants.HV_DATA_HOME}/deleted_db.lock")
|
|
logger.info("[DB MANAGEMENT] Starting DB init..")
|
|
try:
|
|
# 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()
|
|
except:
|
|
logger.error("Critical Error with database initialization!")
|
|
sys.exit()
|
|
|
|
# ============================================================================
|
|
# LEGACY DATABASE CHECKS
|
|
# ============================================================================
|
|
migration_happened = False
|
|
|
|
# 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.")
|
|
|
|
migration = migrate_sql()
|
|
|
|
logger.info(f"[DB MANAGEMENT] Migration result is {migration.valid}.")
|
|
if migration.valid:
|
|
migration_happened = True
|
|
force_sync = True
|
|
clear_sync_cache()
|
|
else:
|
|
# THEN DISPLAY CHOICES AND RECOVERY UI
|
|
db_version_you_have = "Old System"
|
|
failed_migration(db_version_you_have)
|
|
|
|
# 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:
|
|
try:
|
|
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()
|
|
from gui.v2.ui.popups.Database_version import show_recovery_dialog
|
|
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()
|
|
|
|
except:
|
|
logger.info(f"[DB MANAGEMENT] create ALL tables failed. Running migrations...")
|
|
migration = migrate_sql()
|
|
logger.info(f"[DB MANAGEMENT] Results of migration is {migration.valid}")
|
|
|
|
if not migration.valid:
|
|
db_version_you_have = 0
|
|
failed_migration(db_version_you_have)
|
|
|
|
# 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:
|
|
from gui.main_ui import start_ui
|
|
|
|
# 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..")
|
|
if migration_happened:
|
|
force_sync = True
|
|
clear_sync_cache()
|
|
else:
|
|
force_sync = False
|
|
|
|
# if we deleted their DB, we want to force sync,
|
|
if lock_file.exists():
|
|
force_sync = True
|
|
lock_file.unlink() # unlock for next time
|
|
|
|
# Start GUI either way:
|
|
logger.info(f"[DB MANAGEMENT] Starting GUI..")
|
|
start_ui(force_sync)
|
|
|
|
# ============================================================================
|
|
# 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)
|
|
|