2021-01-27 22:14:03 +00:00
#!/usr/bin/env python3
# Hydrus is released under WTFPL
# You just DO WHAT THE FUCK YOU WANT TO.
# https://github.com/sirkris/WTFPL/blob/master/WTFPL.md
import locale
try : locale . setlocale ( locale . LC_ALL , ' ' )
except : pass
2022-08-03 20:59:51 +00:00
import sys
2021-01-27 22:14:03 +00:00
try :
import os
import argparse
from hydrus . core import HydrusBoot
HydrusBoot . AddBaseDirToEnvPath ( )
# initialise Qt here, important it is done early
2022-08-01 00:45:12 +00:00
from hydrus . client . gui import QtInit
2021-01-27 22:14:03 +00:00
from hydrus . core import HydrusConstants as HC
2022-11-09 22:24:07 +00:00
2022-12-18 21:06:34 +00:00
HC . RUNNING_CLIENT = True
2021-01-27 22:14:03 +00:00
from hydrus . core import HydrusData
2021-10-27 21:12:33 +00:00
from hydrus . core import HydrusGlobals as HG
2021-01-27 22:14:03 +00:00
from hydrus . core import HydrusLogger
from hydrus . core import HydrusPaths
2021-10-27 21:12:33 +00:00
from hydrus . core import HydrusTemp
2023-04-19 20:38:13 +00:00
from hydrus . core import HydrusTime
2021-01-27 22:14:03 +00:00
argparser = argparse . ArgumentParser ( description = ' hydrus network client ' )
argparser . add_argument ( ' -d ' , ' --db_dir ' , help = ' set an external db location ' )
argparser . add_argument ( ' --temp_dir ' , help = ' override the program \' s temporary directory ' )
argparser . add_argument ( ' --db_journal_mode ' , default = ' WAL ' , choices = [ ' WAL ' , ' TRUNCATE ' , ' PERSIST ' , ' MEMORY ' ] , help = ' change db journal mode (default=WAL) ' )
2021-12-08 22:40:59 +00:00
argparser . add_argument ( ' --db_cache_size ' , type = int , help = ' override SQLite cache_size per db file, in MB (default=256) ' )
2021-04-20 22:01:22 +00:00
argparser . add_argument ( ' --db_transaction_commit_period ' , type = int , help = ' override how often (in seconds) database changes are saved to disk (default=30,min=10) ' )
2021-01-27 22:14:03 +00:00
argparser . add_argument ( ' --db_synchronous_override ' , type = int , choices = range ( 4 ) , help = ' override SQLite Synchronous PRAGMA (default=2) ' )
argparser . add_argument ( ' --no_db_temp_files ' , action = ' store_true ' , help = ' run db temp operations entirely in memory ' )
argparser . add_argument ( ' --boot_debug ' , action = ' store_true ' , help = ' print additional bootup information to the log ' )
2022-07-27 21:18:33 +00:00
argparser . add_argument ( ' --profile_mode ' , action = ' store_true ' , help = ' start the program with profile mode on, capturing boot performance ' )
2022-11-16 21:34:30 +00:00
argparser . add_argument ( ' --win_qt_darkmode_test ' , action = ' store_true ' , help = ' Try Qt \' s automatic darkmode recognition. ' )
2021-01-27 22:14:03 +00:00
argparser . add_argument ( ' --no_wal ' , action = ' store_true ' , help = ' OBSOLETE: run using TRUNCATE db journaling ' )
argparser . add_argument ( ' --db_memory_journaling ' , action = ' store_true ' , help = ' OBSOLETE: run using MEMORY db journaling (DANGEROUS) ' )
result = argparser . parse_args ( )
if result . db_dir is None :
db_dir = HC . DEFAULT_DB_DIR
2021-02-17 18:22:44 +00:00
if not HydrusPaths . DirectoryIsWriteable ( db_dir ) or HC . RUNNING_FROM_MACOS_APP :
2021-01-27 22:14:03 +00:00
2021-03-17 21:59:28 +00:00
if HC . USERPATH_DB_DIR is None :
raise Exception ( ' The default db path " {} " was not writeable, and the userpath could not be determined! ' . format ( HC . DEFAULT_DB_DIR ) )
2021-01-27 22:14:03 +00:00
db_dir = HC . USERPATH_DB_DIR
else :
db_dir = result . db_dir
db_dir = HydrusPaths . ConvertPortablePathToAbsPath ( db_dir , HC . BASE_DIR )
2021-02-17 18:22:44 +00:00
if not HydrusPaths . DirectoryIsWriteable ( db_dir ) :
2022-07-13 21:35:17 +00:00
message = ' The given db path " {} " is not a writeable-to! ' . format ( db_dir )
db_dir = HC . USERPATH_DB_DIR
raise Exception ( message )
2021-02-17 18:22:44 +00:00
2021-01-27 22:14:03 +00:00
try :
HydrusPaths . MakeSureDirectoryExists ( db_dir )
except :
2022-07-13 21:35:17 +00:00
message = ' Could not ensure db path " {} " exists! Check the location is correct and that you have permission to write to it! ' . format ( db_dir )
db_dir = HC . USERPATH_DB_DIR
raise Exception ( message )
2021-01-27 22:14:03 +00:00
if not os . path . isdir ( db_dir ) :
2022-07-13 21:35:17 +00:00
message = ' The given db path " {} " is not a directory! ' . format ( db_dir )
db_dir = HC . USERPATH_DB_DIR
raise Exception ( message )
2021-01-27 22:14:03 +00:00
HG . db_journal_mode = result . db_journal_mode
if result . no_wal :
HG . db_journal_mode = ' TRUNCATE '
2022-11-16 21:34:30 +00:00
2021-01-27 22:14:03 +00:00
if result . db_memory_journaling :
HG . db_journal_mode = ' MEMORY '
if result . db_cache_size is not None :
HG . db_cache_size = result . db_cache_size
else :
2021-12-08 22:40:59 +00:00
HG . db_cache_size = 256
2021-01-27 22:14:03 +00:00
2021-04-20 22:01:22 +00:00
if result . db_transaction_commit_period is not None :
HG . db_transaction_commit_period = max ( 10 , result . db_transaction_commit_period )
else :
HG . db_transaction_commit_period = 30
2021-01-27 22:14:03 +00:00
if result . db_synchronous_override is not None :
HG . db_synchronous = int ( result . db_synchronous_override )
else :
if HG . db_journal_mode == ' WAL ' :
HG . db_synchronous = 1
else :
HG . db_synchronous = 2
HG . no_db_temp_files = result . no_db_temp_files
HG . boot_debug = result . boot_debug
2022-07-27 21:18:33 +00:00
HG . profile_mode = result . profile_mode
2023-04-19 20:38:13 +00:00
HG . profile_start_time = HydrusTime . GetNow ( )
2022-07-27 21:18:33 +00:00
2022-11-16 21:34:30 +00:00
if HC . PLATFORM_WINDOWS and result . win_qt_darkmode_test :
QtInit . DoWinDarkMode ( )
2021-01-27 22:14:03 +00:00
try :
from twisted . internet import reactor
2023-05-09 21:56:03 +00:00
except Exception as e :
import traceback
2021-01-27 22:14:03 +00:00
2023-05-09 21:56:03 +00:00
HG . twisted_is_broke_exception = traceback . format_exc ( )
2021-01-27 22:14:03 +00:00
HG . twisted_is_broke = True
2022-07-27 21:18:33 +00:00
if result . temp_dir is not None :
HydrusTemp . SetEnvTempDir ( result . temp_dir )
2021-01-27 22:14:03 +00:00
except Exception as e :
try :
HydrusData . DebugPrint ( ' Critical boot error occurred! Details written to crash.log! ' )
HydrusData . PrintException ( e )
except :
pass
import traceback
error_trace = traceback . format_exc ( )
print ( error_trace )
if ' db_dir ' in locals ( ) and os . path . exists ( db_dir ) :
emergency_dir = db_dir
else :
emergency_dir = os . path . expanduser ( ' ~ ' )
possible_desktop = os . path . join ( emergency_dir , ' Desktop ' )
if os . path . exists ( possible_desktop ) and os . path . isdir ( possible_desktop ) :
emergency_dir = possible_desktop
dest_path = os . path . join ( emergency_dir , ' hydrus_crash.log ' )
with open ( dest_path , ' w ' , encoding = ' utf-8 ' ) as f :
f . write ( error_trace )
print ( ' Critical boot error occurred! Details written to hydrus_crash.log in either db dir or user dir! ' )
sys . exit ( 1 )
def boot ( ) :
controller = None
with HydrusLogger . HydrusLogger ( db_dir , ' client ' ) as logger :
try :
HydrusData . Print ( ' hydrus client started ' )
if not HG . twisted_is_broke :
import threading
threading . Thread ( target = reactor . run , name = ' twisted ' , kwargs = { ' installSignalHandlers ' : 0 } ) . start ( )
from hydrus . client import ClientController
controller = ClientController . Controller ( db_dir )
controller . Run ( )
except :
HydrusData . Print ( ' hydrus client failed ' )
import traceback
HydrusData . Print ( traceback . format_exc ( ) )
finally :
2022-01-19 21:28:59 +00:00
HG . started_shutdown = True
2021-01-27 22:14:03 +00:00
HG . view_shutdown = True
HG . model_shutdown = True
if controller is not None :
controller . pubimmediate ( ' wake_daemons ' )
if not HG . twisted_is_broke :
reactor . callFromThread ( reactor . stop )
HydrusData . Print ( ' hydrus client shut down ' )
HG . shutdown_complete = True
if HG . restart :
HydrusData . RestartProcess ( )